Commit 6a1d23e2 authored by Mark Rutland's avatar Mark Rutland Committed by Zheng Zengkai
Browse files

arm64: sdei: move uaccess logic to arch/arm64/

mainline inclusion
from mainline-v5.11-rc1
commit a0ccf2ba
category: performance
bugzilla: https://e.gitee.com/open_euler/issues/list?issue=I4SCW7


CVE: NA

-------------------------------------------------------------------------

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.com


Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
Signed-off-by: default avatarZhen Lei <thunder.leizhen@huawei.com>
Reviewed-by: default avatarHanjun Guo <guohanjun@huawei.com>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parent 430485ee
Loading
Loading
Loading
Loading
+12 −6
Original line number Diff line number Diff line
@@ -179,12 +179,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;
@@ -228,6 +222,16 @@ asmlinkage noinstr 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();

	arm64_enter_nmi(regs);

@@ -235,5 +239,7 @@ __sdei_handler(struct pt_regs *regs, struct sdei_registered_event *arg)

	arm64_exit_nmi(regs);

	force_uaccess_end(orig_addr_limit);

	return ret;
}
+0 −14
Original line number Diff line number Diff line
@@ -31,7 +31,6 @@
#include <linux/slab.h>
#include <linux/smp.h>
#include <linux/spinlock.h>
#include <linux/uaccess.h>

/*
 * The call to use to reach the firmware.
@@ -1114,26 +1113,13 @@ int sdei_event_handler(struct pt_regs *regs,
		       struct sdei_registered_event *arg)
{
	int err;
	mm_segment_t orig_addr_limit;
	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);
	if (err)
		pr_err_ratelimited("event %u on CPU %u failed with error: %d\n",
				   event_num, smp_processor_id(), err);

	force_uaccess_end(orig_addr_limit);

	return err;
}
NOKPROBE_SYMBOL(sdei_event_handler);