Commit 8fb37faa authored by Philippe Gerum's avatar Philippe Gerum
Browse files

arm64/ipipe: do not stall the root domain on fault entry

All data/insn abort exception handlers are expected to run with
interrupts enabled, so forcing the virtual state off causes havoc with
the mm context switching code in SMP, which has particular
requirements due to ASID handling. Other handlers don't care for the
virtual IRQ state.

Would some code start caring about this at some point, a proper
emulation based on the hw IRQ state on entry would be required, not an
arbitrary root stall.
parent 3c63e690
......@@ -39,39 +39,6 @@
static const char *fault_name(unsigned int esr);
#ifdef CONFIG_IPIPE
static inline unsigned long ipipe_fault_entry(void)
{
unsigned long flags;
int s;
flags = hard_local_irq_save();
s = __test_and_set_bit(IPIPE_STALL_FLAG, &__ipipe_root_status);
hard_local_irq_enable();
return arch_mangle_irq_bits(s, flags);
}
static inline void ipipe_fault_exit(unsigned long x)
{
if (!arch_demangle_irq_bits(&x))
local_irq_enable();
else
hard_local_irq_restore(x);
}
#else
static inline unsigned long ipipe_fault_entry(void)
{
return 0;
}
static inline void ipipe_fault_exit(unsigned long x) { }
#endif
/*
* Dump out the page tables associated with 'addr' in mm 'mm'.
*/
......@@ -238,13 +205,10 @@ static int __kprobes do_page_fault(unsigned long addr, unsigned int esr,
int fault, sig, code;
unsigned long vm_flags = VM_READ | VM_WRITE | VM_EXEC;
unsigned int mm_flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
unsigned long irqflags;
if (__ipipe_report_trap(IPIPE_TRAP_ACCESS, regs))
return 0;
irqflags = ipipe_fault_entry();
tsk = current;
mm = tsk->mm;
......@@ -378,7 +342,6 @@ retry:
no_context:
__do_kernel_fault(mm, addr, esr, regs);
out:
ipipe_fault_exit(irqflags);
return 0;
}
......@@ -404,20 +367,14 @@ static int __kprobes do_translation_fault(unsigned long addr,
unsigned int esr,
struct pt_regs *regs)
{
unsigned long irqflags;
if (addr < TASK_SIZE)
return do_page_fault(addr, esr, regs);
if (__ipipe_report_trap(IPIPE_TRAP_ACCESS, regs))
return 0;
irqflags = ipipe_fault_entry();
do_bad_area(addr, esr, regs);
ipipe_fault_exit(irqflags);
return 0;
}
......@@ -517,17 +474,16 @@ asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr,
struct pt_regs *regs)
{
const struct fault_info *inf = fault_info + (esr & 63);
unsigned long irqflags;
struct siginfo info;
IPIPE_WARN_ONCE(hard_irqs_disabled());
if (!inf->fn(addr, esr, regs))
return;
if (__ipipe_report_trap(IPIPE_TRAP_UNKNOWN, regs))
return;
irqflags = ipipe_fault_entry();
pr_alert("Unhandled fault: %s (0x%08x) at 0x%016lx\n",
inf->name, esr, addr);
......@@ -536,8 +492,6 @@ asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr,
info.si_code = inf->code;
info.si_addr = (void __user *)addr;
arm64_notify_die("", regs, &info, esr);
ipipe_fault_exit(irqflags);
}
/*
......@@ -548,20 +502,15 @@ asmlinkage void __exception do_sp_pc_abort(unsigned long addr,
struct pt_regs *regs)
{
struct siginfo info;
unsigned long irqflags;
if (__ipipe_report_trap(IPIPE_TRAP_ALIGNMENT, regs))
return;
irqflags = ipipe_fault_entry();
info.si_signo = SIGBUS;
info.si_errno = 0;
info.si_code = BUS_ADRALN;
info.si_addr = (void __user *)addr;
arm64_notify_die("", regs, &info, esr);
ipipe_fault_exit(irqflags);
}
static struct fault_info debug_fault_info[] = {
......@@ -592,7 +541,6 @@ asmlinkage int __exception do_debug_exception(unsigned long addr,
struct pt_regs *regs)
{
const struct fault_info *inf = debug_fault_info + DBG_ESR_EVT(esr);
unsigned long irqflags;
struct siginfo info;
if (!inf->fn(addr, esr, regs))
......@@ -601,8 +549,6 @@ asmlinkage int __exception do_debug_exception(unsigned long addr,
if (__ipipe_report_trap(IPIPE_TRAP_UNKNOWN, regs))
return 0;
irqflags = ipipe_fault_entry();
pr_alert("Unhandled debug exception: %s (0x%08x) at 0x%016lx\n",
inf->name, esr, addr);
......@@ -612,7 +558,5 @@ asmlinkage int __exception do_debug_exception(unsigned long addr,
info.si_addr = (void __user *)addr;
arm64_notify_die("", regs, &info, 0);
ipipe_fault_exit(irqflags);
return 0;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment