Thread (40 messages) 40 messages, 2 authors, 2021-05-25

Re: [PATCH v2 14/19] arm64: entry: handle all vectors with C

From: Mark Rutland <mark.rutland@arm.com>
Date: 2021-05-21 16:43:01

On Fri, May 21, 2021 at 04:59:52PM +0100, Joey Gouly wrote:
Hi Mark,

I like these clean ups to entry.S!

On Wed, May 19, 2021 at 01:38:57PM +0100, Mark Rutland wrote:
quoted
We have 16 architectural exception vectors, and depending on kernel
configuration we handle 8 or 12 of these with C code, and we handle 8 or
4 of these as sepcial cases in the entry assembly.

It would be nicer if the entry assembly were uniform for all exceptions,
and we deferred any specific handling of the exceptions to C code. This
way the entry assembly can be more easily templated without ifdeffery or
special cases, and it's easier to modify the handling of these cases in
future (e.g. to dump additional registers other context).

This patch reworks the entry code so that we always have a C handle for
s/handle/handler/
quoted
every architectural exception vector, with the entry assembly being
completely uniform. We now have to handle exceptions from EL1t and EL1h,
and also have to handle exceptions from AArch32 even when the kernel is
built without CONFIG_COMPAT. To make this clear and to simplify
templating, we rename the top-level exception handlers with a consistent
naming scheme:

  asm: <el>_<regsize>_<type>
  c:   <el>_<regsize>_<type>_handler

.. where:

  <el> is `el1t`, `el1h`, or `el0`
Is there a reason against using `el0t`? `el0t` is used in the Arm ARM.
It would get rid of the weird empty arguments in the `kernel_ventry`
and `entry_handler` macros.
To be honest, I simply hadn't thought about it, as I'd only needed to
distingish EL1h and EL1t. Now that you say it, it does make sense to me
do use `el0t` for consistency, so I'll take a look at that.
quoted
  <regsize> is `64` or `32`
  <type> is `sync`, `irq`, `fiq`, or `error`

... e.g.

  asm: el1h_64_sync
  c:   el1h_64_sync_handler

... with lower-level handlers simply using "el1" and "compat" as today.

For unexpected exceptions, this information is passed to
panic_unandled(), so it can report the specific vector an unexpected
exception was taken from, e.g.

| Unexpected 64-bit el1t sync exception

For vectors we never expect to enter legitimately, the C code is
gnerated using a macro to avoid code duplication.

The `kernel_ventry` and `entry_handler` assembly macros are update to
s/update/updated/
quoted
handle the new naming scheme. In theory it should be possible to
generate the entry functions at the same time as the vectors using a
single table, but this will require reworking the linker script to split
the two into separate sections, so for now we duplicate the two.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Marc Zyngier <maz@kernel.org>
Cc: Will Deacon <will@kernel.org>
---
 arch/arm64/include/asm/exception.h |  31 +++++---
 arch/arm64/kernel/entry-common.c   |  51 +++++++------
 arch/arm64/kernel/entry.S          | 146 ++++++++++++-------------------------
 3 files changed, 92 insertions(+), 136 deletions(-)
diff --git a/arch/arm64/include/asm/exception.h b/arch/arm64/include/asm/exception.h
index 4284ee57a9a5..40a3a20dca1c 100644
--- a/arch/arm64/include/asm/exception.h
+++ b/arch/arm64/include/asm/exception.h
@@ -31,18 +31,25 @@ static inline u32 disr_to_esr(u64 disr)
 	return esr;
 }
 
-asmlinkage void el1_sync_handler(struct pt_regs *regs);
-asmlinkage void el1_irq_handler(struct pt_regs *regs);
-asmlinkage void el1_fiq_handler(struct pt_regs *regs);
-asmlinkage void el1_error_handler(struct pt_regs *regs);
-asmlinkage void el0_sync_handler(struct pt_regs *regs);
-asmlinkage void el0_irq_handler(struct pt_regs *regs);
-asmlinkage void el0_fiq_handler(struct pt_regs *regs);
-asmlinkage void el0_error_handler(struct pt_regs *regs);
-asmlinkage void el0_sync_compat_handler(struct pt_regs *regs);
-asmlinkage void el0_irq_compat_handler(struct pt_regs *regs);
-asmlinkage void el0_fiq_compat_handler(struct pt_regs *regs);
-asmlinkage void el0_error_compat_handler(struct pt_regs *regs);
+asmlinkage void el1t_64_sync_handler(struct pt_regs *regs);
+asmlinkage void el1t_64_irq_handler(struct pt_regs *regs);
+asmlinkage void el1t_64_fiq_handler(struct pt_regs *regs);
+asmlinkage void el1t_64_error_handler(struct pt_regs *regs);
+
+asmlinkage void el1h_64_sync_handler(struct pt_regs *regs);
+asmlinkage void el1h_64_irq_handler(struct pt_regs *regs);
+asmlinkage void el1h_64_fiq_handler(struct pt_regs *regs);
+asmlinkage void el1h_64_error_handler(struct pt_regs *regs);
+
+asmlinkage void el0_64_sync_handler(struct pt_regs *regs);
+asmlinkage void el0_64_irq_handler(struct pt_regs *regs);
+asmlinkage void el0_64_fiq_handler(struct pt_regs *regs);
+asmlinkage void el0_64_error_handler(struct pt_regs *regs);
+
+asmlinkage void el0_32_sync_handler(struct pt_regs *regs);
+asmlinkage void el0_32_irq_handler(struct pt_regs *regs);
+asmlinkage void el0_32_fiq_handler(struct pt_regs *regs);
+asmlinkage void el0_32_error_handler(struct pt_regs *regs);
 
 asmlinkage void call_on_irq_stack(struct pt_regs *regs,
 				  void (*func)(struct pt_regs *));
Can you remove `bad_mode` from this header? (Further down, not shown here)

Also there is a reference to `bad_mode` in `traps.c`.
Sure; I'll rip both of those out.
quoted
 static void noinstr el1_abort(struct pt_regs *regs, unsigned long esr)
 {
 	unsigned long far = read_sysreg(far_el1);
@@ -271,7 +271,7 @@ static void noinstr el1_inv(struct pt_regs *regs, unsigned long esr)
 {
 	enter_from_kernel_mode(regs);
 	local_daif_inherit(regs);
-	bad_mode(regs, 0, esr);
+	__panic_unhandled(regs, "el1h sync", esr);
 	local_daif_mask();
 	exit_to_kernel_mode(regs);
This is never going to actually exit to kernel mode, is it? The panic
should stop that.
Correct.

Now that __panic_unhandled() does NMI entry work, we can remove
el1_inv() and have el1h_64_sync_handler() call __panic_unhandled()
directly.

I'll do that as a followup patch, since it's a slight (but deliberate)
behavioural change.
Minor comments / questions, but otherwise:

Reviewed-by: Joey Gouly <joey.gouly@arm.com>
Thanks!

Mark.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help