diff options
author | Mark Rutland <mark.rutland@arm.com> | 2021-06-07 10:46:21 +0100 |
---|---|---|
committer | Will Deacon <will@kernel.org> | 2021-06-07 11:35:56 +0100 |
commit | d60b228fd19985a903b8e8c599be0538a875d505 (patch) | |
tree | e9e82ae169edf49828f3c07c8be6f9c412fc7974 /arch/arm64/kernel/entry-common.c | |
parent | 8168f098867f6584295ea408c683f61e945c6ff1 (diff) | |
download | lwn-d60b228fd19985a903b8e8c599be0538a875d505.tar.gz lwn-d60b228fd19985a903b8e8c599be0538a875d505.zip |
arm64: entry: split SDEI entry
We'd like to keep all the entry sequencing in entry-common.c, as this
will allow us to ensure this is consistent, and free from any unsound
instrumentation.
Currently __sdei_handler() performs the NMI entry/exit sequences in
sdei.c. Let's split the low-level entry sequence from the event
handling, moving the former to entry-common.c and keeping the latter in
sdei.c. The event handling function is renamed to do_sdei_event(),
matching the do_${FOO}() pattern used for other exception handlers.
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Acked-by: Marc Zyngier <maz@kernel.org>
Reviewed-by: Joey Gouly <joey.gouly@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Will Deacon <will@kernel.org>
Link: https://lore.kernel.org/r/20210607094624.34689-18-mark.rutland@arm.com
Signed-off-by: Will Deacon <will@kernel.org>
Diffstat (limited to 'arch/arm64/kernel/entry-common.c')
-rw-r--r-- | arch/arm64/kernel/entry-common.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c index efe95edf10c0..1b32ca3848f5 100644 --- a/arch/arm64/kernel/entry-common.c +++ b/arch/arm64/kernel/entry-common.c @@ -20,6 +20,7 @@ #include <asm/kprobes.h> #include <asm/mmu.h> #include <asm/processor.h> +#include <asm/sdei.h> #include <asm/stacktrace.h> #include <asm/sysreg.h> #include <asm/system_misc.h> @@ -710,3 +711,39 @@ asmlinkage void noinstr handle_bad_stack(struct pt_regs *regs) panic_bad_stack(regs, esr, far); } #endif /* CONFIG_VMAP_STACK */ + +#ifdef CONFIG_ARM_SDE_INTERFACE +asmlinkage noinstr unsigned long +__sdei_handler(struct pt_regs *regs, struct sdei_registered_event *arg) +{ + unsigned long ret; + + /* + * We didn't take an exception to get here, so the HW hasn't + * set/cleared bits in PSTATE that we may rely on. + * + * The original SDEI spec (ARM DEN 0054A) can be read ambiguously as to + * whether PSTATE bits are inherited unchanged or generated from + * scratch, and the TF-A implementation always clears PAN and always + * clears UAO. There are no other known implementations. + * + * Subsequent revisions (ARM DEN 0054B) follow the usual rules for how + * PSTATE is modified upon architectural exceptions, and so PAN is + * either inherited or set per SCTLR_ELx.SPAN, and UAO is always + * cleared. + * + * We must explicitly reset PAN to the expected state, including + * clearing it when the host isn't using it, in case a VM had it set. + */ + if (system_uses_hw_pan()) + set_pstate_pan(1); + else if (cpu_has_pan()) + set_pstate_pan(0); + + arm64_enter_nmi(regs); + ret = do_sdei_event(regs, arg); + arm64_exit_nmi(regs); + + return ret; +} +#endif /* CONFIG_ARM_SDE_INTERFACE */ |