You need to sign in or sign up before continuing.
提交 1b954006 编写于 作者: M Mark Rutland 提交者: Yang Yingliang

arm64: syscall: exit userspace before unmasking exceptions

stable inclusion
from linux-4.19.164
commit 6abd3ab44001ff55ccff27793b925983cef23198

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

[ Upstream commit ca1314d7 ]

In el0_svc_common() we unmask exceptions before we call user_exit(), and
so there's a window where an IRQ or debug exception can be taken while
RCU is not watching. In do_debug_exception() we account for this in via
debug_exception_{enter,exit}(), but in the el1_irq asm we do not and we
call trace functions which rely on RCU before we have a guarantee that
RCU is watching.

Let's avoid this by having el0_svc_common() exit userspace before
unmasking exceptions, matching what we do for all other EL0 entry paths.
We can use user_exit_irqoff() to avoid the pointless save/restore of IRQ
flags while we're sure exceptions are masked in DAIF.

The workaround for Cortex-A76 erratum 1463225 may trigger a debug
exception before this point, but the debug code invoked in this case is
safe even when RCU is not watching.
Signed-off-by: NMark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Will Deacon <will@kernel.org>
Link: https://lore.kernel.org/r/20201130115950.22492-2-mark.rutland@arm.comSigned-off-by: NWill Deacon <will@kernel.org>
Signed-off-by: NSasha Levin <sashal@kernel.org>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
Signed-off-by: NCheng Jian <cj.chengjian@huawei.com>
上级 2e36b29e
...@@ -99,8 +99,8 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr, ...@@ -99,8 +99,8 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
regs->syscallno = scno; regs->syscallno = scno;
cortex_a76_erratum_1463225_svc_handler(); cortex_a76_erratum_1463225_svc_handler();
user_exit_irqoff();
local_daif_restore(DAIF_PROCCTX); local_daif_restore(DAIF_PROCCTX);
user_exit();
if (has_syscall_work(flags)) { if (has_syscall_work(flags)) {
/* set default errno for user-issued syscall(-1) */ /* set default errno for user-issued syscall(-1) */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册