Message ID | 20171019145807.23251-11-james.morse@arm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
James On 10/19/2017 10:57 AM, James Morse wrote: [..] > kernel_ventry el1_fiq_invalid // FIQ EL1h > - kernel_ventry el1_error_invalid // Error EL1h > + kernel_ventry el1_error // Error EL1h > > kernel_ventry el0_sync // Synchronous 64-bit EL0 > kernel_ventry el0_irq // IRQ 64-bit EL0 > kernel_ventry el0_fiq_invalid // FIQ 64-bit EL0 > - kernel_ventry el0_error_invalid // Error 64-bit EL0 > + kernel_ventry el0_error // Error 64-bit EL0 > > #ifdef CONFIG_COMPAT > kernel_ventry el0_sync_compat // Synchronous 32-bit EL0 > kernel_ventry el0_irq_compat // IRQ 32-bit EL0 > kernel_ventry el0_fiq_invalid_compat // FIQ 32-bit EL0 > - kernel_ventry el0_error_invalid_compat // Error 32-bit EL0 > + kernel_ventry el0_error_compat // Error 32-bit EL0 > #else > kernel_ventry el0_sync_invalid // Synchronous 32-bit EL0 > kernel_ventry el0_irq_invalid // IRQ 32-bit EL0 > @@ -455,10 +455,6 @@ ENDPROC(el0_error_invalid) > el0_fiq_invalid_compat: > inv_entry 0, BAD_FIQ, 32 > ENDPROC(el0_fiq_invalid_compat) > - > -el0_error_invalid_compat: > - inv_entry 0, BAD_ERROR, 32 > -ENDPROC(el0_error_invalid_compat) > #endif Perhaps I missed something quite obvious, but is there any reason to not also remove el1_error_invalid, since SError handling now jumps to el1_error? > el1_sync_invalid: > @@ -663,6 +659,10 @@ el0_svc_compat: > el0_irq_compat: > kernel_entry 0, 32 > b el0_irq_naked > + > +el0_error_compat: > + kernel_entry 0, 32 > + b el0_error_naked > #endif > > el0_da: > @@ -780,6 +780,28 @@ el0_irq_naked: > b ret_to_user > ENDPROC(el0_irq) > > +el1_error: > + kernel_entry 1 > + mrs x1, esr_el1 > + enable_dbg > + mov x0, sp > + bl do_serror > + kernel_exit 1 > +ENDPROC(el1_error) > + > +el0_error: > + kernel_entry 0 > +el0_error_naked: > + mrs x1, esr_el1 > + enable_dbg > + mov x0, sp > + bl do_serror > + enable_daif > + ct_user_exit > + b ret_to_user > +ENDPROC(el0_error) [..] Thanks Adam
Hi Adam, On 02/01/18 21:07, Adam Wallis wrote: > On 10/19/2017 10:57 AM, James Morse wrote: > [..] >> kernel_ventry el1_fiq_invalid // FIQ EL1h >> - kernel_ventry el1_error_invalid // Error EL1h >> + kernel_ventry el1_error // Error EL1h >> kernel_ventry el0_sync // Synchronous 64-bit EL0 >> kernel_ventry el0_irq // IRQ 64-bit EL0 >> kernel_ventry el0_fiq_invalid // FIQ 64-bit EL0 >> - kernel_ventry el0_error_invalid // Error 64-bit EL0 >> + kernel_ventry el0_error // Error 64-bit EL0 >> >> #ifdef CONFIG_COMPAT >> kernel_ventry el0_sync_compat // Synchronous 32-bit EL0 >> kernel_ventry el0_irq_compat // IRQ 32-bit EL0 >> kernel_ventry el0_fiq_invalid_compat // FIQ 32-bit EL0 >> - kernel_ventry el0_error_invalid_compat // Error 32-bit EL0 >> + kernel_ventry el0_error_compat // Error 32-bit EL0 >> #else >> kernel_ventry el0_sync_invalid // Synchronous 32-bit EL0 >> kernel_ventry el0_irq_invalid // IRQ 32-bit EL0 >> @@ -455,10 +455,6 @@ ENDPROC(el0_error_invalid) >> el0_fiq_invalid_compat: >> inv_entry 0, BAD_FIQ, 32 >> ENDPROC(el0_fiq_invalid_compat) >> - >> -el0_error_invalid_compat: >> - inv_entry 0, BAD_ERROR, 32 >> -ENDPROC(el0_error_invalid_compat) >> #endif > Perhaps I missed something quite obvious, but is there any reason to not also > remove el1_error_invalid, since SError handling now jumps to el1_error? There is still a caller for el1_error_invalid: depending on SPSel we are in thread or handler mode, which causes exceptions to use a different entry in the vectors. The kernel always uses handler mode, all the thread mode entries point at their '_invalid' versions. If we take an SError from EL1t, SPsel==0 then it uses vectors+0x180. (just cut off the top of this diff). The el1_error change above is for EL1h, SPsel==1, which uses vectors+0x380. Thanks for taking a look! James
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 0df64a6a56d4..70dfe4e9ccc5 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -98,7 +98,7 @@ config ARM64 select HAVE_IRQ_TIME_ACCOUNTING select HAVE_MEMBLOCK select HAVE_MEMBLOCK_NODE_MAP if NUMA - select HAVE_NMI if ACPI_APEI_SEA + select HAVE_NMI select HAVE_PATA_PLATFORM select HAVE_PERF_EVENTS select HAVE_PERF_REGS diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index df085ec003b0..e147c1d00b41 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -375,18 +375,18 @@ ENTRY(vectors) kernel_ventry el1_sync // Synchronous EL1h kernel_ventry el1_irq // IRQ EL1h kernel_ventry el1_fiq_invalid // FIQ EL1h - kernel_ventry el1_error_invalid // Error EL1h + kernel_ventry el1_error // Error EL1h kernel_ventry el0_sync // Synchronous 64-bit EL0 kernel_ventry el0_irq // IRQ 64-bit EL0 kernel_ventry el0_fiq_invalid // FIQ 64-bit EL0 - kernel_ventry el0_error_invalid // Error 64-bit EL0 + kernel_ventry el0_error // Error 64-bit EL0 #ifdef CONFIG_COMPAT kernel_ventry el0_sync_compat // Synchronous 32-bit EL0 kernel_ventry el0_irq_compat // IRQ 32-bit EL0 kernel_ventry el0_fiq_invalid_compat // FIQ 32-bit EL0 - kernel_ventry el0_error_invalid_compat // Error 32-bit EL0 + kernel_ventry el0_error_compat // Error 32-bit EL0 #else kernel_ventry el0_sync_invalid // Synchronous 32-bit EL0 kernel_ventry el0_irq_invalid // IRQ 32-bit EL0 @@ -455,10 +455,6 @@ ENDPROC(el0_error_invalid) el0_fiq_invalid_compat: inv_entry 0, BAD_FIQ, 32 ENDPROC(el0_fiq_invalid_compat) - -el0_error_invalid_compat: - inv_entry 0, BAD_ERROR, 32 -ENDPROC(el0_error_invalid_compat) #endif el1_sync_invalid: @@ -663,6 +659,10 @@ el0_svc_compat: el0_irq_compat: kernel_entry 0, 32 b el0_irq_naked + +el0_error_compat: + kernel_entry 0, 32 + b el0_error_naked #endif el0_da: @@ -780,6 +780,28 @@ el0_irq_naked: b ret_to_user ENDPROC(el0_irq) +el1_error: + kernel_entry 1 + mrs x1, esr_el1 + enable_dbg + mov x0, sp + bl do_serror + kernel_exit 1 +ENDPROC(el1_error) + +el0_error: + kernel_entry 0 +el0_error_naked: + mrs x1, esr_el1 + enable_dbg + mov x0, sp + bl do_serror + enable_daif + ct_user_exit + b ret_to_user +ENDPROC(el0_error) + + /* * This is the fast syscall return path. We do as little as possible here, * and this includes saving x0 back into the kernel stack. diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index 1808be65d22f..773aae69c376 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c @@ -709,6 +709,19 @@ asmlinkage void handle_bad_stack(struct pt_regs *regs) } #endif +asmlinkage void do_serror(struct pt_regs *regs, unsigned int esr) +{ + nmi_enter(); + + console_verbose(); + + pr_crit("SError Interrupt on CPU%d, code 0x%08x -- %s\n", + smp_processor_id(), esr, esr_get_class_string(esr)); + __show_regs(regs); + + panic("Asynchronous SError Interrupt"); +} + void __pte_error(const char *file, int line, unsigned long val) { pr_err("%s:%d: bad pte %016lx.\n", file, line, val);