summaryrefslogtreecommitdiff
path: root/arch/arm64/kernel/sdei.c
diff options
context:
space:
mode:
authorMark Rutland <mark.rutland@arm.com>2020-12-02 16:15:47 +0300
committerCatalin Marinas <catalin.marinas@arm.com>2020-12-02 22:46:14 +0300
commita0ccf2ba689f773f2882b9c1e79d8a43a19cb513 (patch)
tree1e934a4feafb46f63dcf394b4e224f51249bf718 /arch/arm64/kernel/sdei.c
parentd87a8e65b5101123a24cddeb7a8a2c7b45f7b60c (diff)
downloadlinux-a0ccf2ba689f773f2882b9c1e79d8a43a19cb513.tar.xz
arm64: sdei: move uaccess logic to arch/arm64/
The SDEI support code is split across arch/arm64/ and drivers/firmware/, largley this is split so that the arch-specific portions are under arch/arm64, and the management logic is under drivers/firmware/. However, exception entry fixups are currently under drivers/firmware. Let's move the exception entry fixups under arch/arm64/. This de-clutters the management logic, and puts all the arch-specific portions in one place. Doing this also allows the fixups to be applied earlier, so things like PAN and UAO will be in a known good state before we run other logic. This will also make subsequent refactoring easier. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Reviewed-by: James Morse <james.morse@arm.com> Cc: Christoph Hellwig <hch@lst.de> Cc: Will Deacon <will@kernel.org> Link: https://lore.kernel.org/r/20201202131558.39270-2-mark.rutland@arm.com Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'arch/arm64/kernel/sdei.c')
-rw-r--r--arch/arm64/kernel/sdei.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/arch/arm64/kernel/sdei.c b/arch/arm64/kernel/sdei.c
index 7689f2031c0c..4a5f24602aa0 100644
--- a/arch/arm64/kernel/sdei.c
+++ b/arch/arm64/kernel/sdei.c
@@ -178,12 +178,6 @@ static __kprobes unsigned long _sdei_handler(struct pt_regs *regs,
sdei_api_event_context(i, &regs->regs[i]);
}
- /*
- * We didn't take an exception to get here, set PAN. UAO will be cleared
- * by sdei_event_handler()s force_uaccess_begin() call.
- */
- __uaccess_enable_hw_pan();
-
err = sdei_event_handler(regs, arg);
if (err)
return SDEI_EV_FAILED;
@@ -227,6 +221,16 @@ asmlinkage __kprobes notrace unsigned long
__sdei_handler(struct pt_regs *regs, struct sdei_registered_event *arg)
{
unsigned long ret;
+ mm_segment_t orig_addr_limit;
+
+ /*
+ * We didn't take an exception to get here, so the HW hasn't set PAN or
+ * cleared UAO, and the exception entry code hasn't reset addr_limit.
+ * Set PAN, then use force_uaccess_begin() to clear UAO and reset
+ * addr_limit.
+ */
+ __uaccess_enable_hw_pan();
+ orig_addr_limit = force_uaccess_begin();
nmi_enter();
@@ -234,5 +238,7 @@ __sdei_handler(struct pt_regs *regs, struct sdei_registered_event *arg)
nmi_exit();
+ force_uaccess_end(orig_addr_limit);
+
return ret;
}