Commit a0ccf2ba authored by Mark Rutland's avatar Mark Rutland Committed by Catalin Marinas

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: default avatarMark Rutland <mark.rutland@arm.com>
Reviewed-by: default avatarJames 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.comSigned-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
parent d87a8e65
...@@ -178,12 +178,6 @@ static __kprobes unsigned long _sdei_handler(struct pt_regs *regs, ...@@ -178,12 +178,6 @@ static __kprobes unsigned long _sdei_handler(struct pt_regs *regs,
sdei_api_event_context(i, &regs->regs[i]); 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); err = sdei_event_handler(regs, arg);
if (err) if (err)
return SDEI_EV_FAILED; return SDEI_EV_FAILED;
...@@ -227,6 +221,16 @@ asmlinkage __kprobes notrace unsigned long ...@@ -227,6 +221,16 @@ asmlinkage __kprobes notrace unsigned long
__sdei_handler(struct pt_regs *regs, struct sdei_registered_event *arg) __sdei_handler(struct pt_regs *regs, struct sdei_registered_event *arg)
{ {
unsigned long ret; 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(); nmi_enter();
...@@ -234,5 +238,7 @@ __sdei_handler(struct pt_regs *regs, struct sdei_registered_event *arg) ...@@ -234,5 +238,7 @@ __sdei_handler(struct pt_regs *regs, struct sdei_registered_event *arg)
nmi_exit(); nmi_exit();
force_uaccess_end(orig_addr_limit);
return ret; return ret;
} }
...@@ -31,7 +31,6 @@ ...@@ -31,7 +31,6 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/uaccess.h>
/* /*
* The call to use to reach the firmware. * The call to use to reach the firmware.
...@@ -1092,26 +1091,13 @@ int sdei_event_handler(struct pt_regs *regs, ...@@ -1092,26 +1091,13 @@ int sdei_event_handler(struct pt_regs *regs,
struct sdei_registered_event *arg) struct sdei_registered_event *arg)
{ {
int err; int err;
mm_segment_t orig_addr_limit;
u32 event_num = arg->event_num; u32 event_num = arg->event_num;
/*
* Save restore 'fs'.
* The architecture's entry code save/restores 'fs' when taking an
* exception from the kernel. This ensures addr_limit isn't inherited
* if you interrupted something that allowed the uaccess routines to
* access kernel memory.
* Do the same here because this doesn't come via the same entry code.
*/
orig_addr_limit = force_uaccess_begin();
err = arg->callback(event_num, regs, arg->callback_arg); err = arg->callback(event_num, regs, arg->callback_arg);
if (err) if (err)
pr_err_ratelimited("event %u on CPU %u failed with error: %d\n", pr_err_ratelimited("event %u on CPU %u failed with error: %d\n",
event_num, smp_processor_id(), err); event_num, smp_processor_id(), err);
force_uaccess_end(orig_addr_limit);
return err; return err;
} }
NOKPROBE_SYMBOL(sdei_event_handler); NOKPROBE_SYMBOL(sdei_event_handler);
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