From: Mark Rutland <mark.rutland@arm.com>
To: linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, will.deacon@arm.com
Cc: catalin.marinas@arm.com, dave.martin@arm.com, hch@infradead.org,
james.morse@arm.com, linux@dominikbrodowski.net,
linux-fsdevel@vger.kernel.org, marc.zyngier@arm.com,
mark.rutland@arm.com, viro@zeniv.linux.org.uk
Subject: [PATCHv5 09/21] arm64: convert syscall trace logic to C
Date: Wed, 11 Jul 2018 14:56:44 +0100 [thread overview]
Message-ID: <20180711135656.20670-10-mark.rutland@arm.com> (raw)
In-Reply-To: <20180711135656.20670-1-mark.rutland@arm.com>
Currently syscall tracing is a tricky assembly state machine, which can
be rather difficult to follow, and even harder to modify. Before we
start fiddling with it for pt_regs syscalls, let's convert it to C.
This is not intended to have any functional change.
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
arch/arm64/kernel/entry.S | 53 ++---------------------------------------
arch/arm64/kernel/syscall.c | 57 ++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 56 insertions(+), 54 deletions(-)
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index c0392f78e392..05b9f03f3e00 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -896,24 +896,6 @@ el0_error_naked:
b ret_to_user
ENDPROC(el0_error)
-
-/*
- * This is the fast syscall return path. We do as little as possible here,
- * and this includes saving x0 back into the kernel stack.
- */
-ret_fast_syscall:
- disable_daif
- ldr x1, [tsk, #TSK_TI_FLAGS] // re-check for syscall tracing
- and x2, x1, #_TIF_SYSCALL_WORK
- cbnz x2, ret_fast_syscall_trace
- and x2, x1, #_TIF_WORK_MASK
- cbnz x2, work_pending
- enable_step_tsk x1, x2
- kernel_exit 0
-ret_fast_syscall_trace:
- enable_daif
- b __sys_trace_return_skipped // we already saved x0
-
/*
* Ok, we need to do extra processing, enter the slow path.
*/
@@ -969,44 +951,13 @@ alternative_else_nop_endif
#endif
el0_svc_naked: // compat entry point
- stp x0, xscno, [sp, #S_ORIG_X0] // save the original x0 and syscall number
- enable_daif
- ct_user_exit 1
-
- tst x16, #_TIF_SYSCALL_WORK // check for syscall hooks
- b.ne __sys_trace
mov x0, sp
mov w1, wscno
mov w2, wsc_nr
mov x3, stbl
- bl invoke_syscall
- b ret_fast_syscall
-ENDPROC(el0_svc)
-
- /*
- * This is the really slow path. We're going to be doing context
- * switches, and waiting for our parent to respond.
- */
-__sys_trace:
- cmp wscno, #NO_SYSCALL // user-issued syscall(-1)?
- b.ne 1f
- mov x0, #-ENOSYS // set default errno if so
- str x0, [sp, #S_X0]
-1: mov x0, sp
- bl syscall_trace_enter
- cmp w0, #NO_SYSCALL // skip the syscall?
- b.eq __sys_trace_return_skipped
-
- mov x0, sp
- mov w1, wscno
- mov w2, wsc_nr
- mov x3, stbl
- bl invoke_syscall
-
-__sys_trace_return_skipped:
- mov x0, sp
- bl syscall_trace_exit
+ bl el0_svc_common
b ret_to_user
+ENDPROC(el0_svc)
.popsection // .entry.text
diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
index 93d36f22647e..3e1df8ca1e79 100644
--- a/arch/arm64/kernel/syscall.c
+++ b/arch/arm64/kernel/syscall.c
@@ -1,11 +1,15 @@
// SPDX-License-Identifier: GPL-2.0
+#include <linux/compiler.h>
+#include <linux/context_tracking.h>
#include <linux/errno.h>
#include <linux/nospec.h>
#include <linux/ptrace.h>
#include <linux/syscalls.h>
+#include <asm/daifflags.h>
#include <asm/syscall.h>
+#include <asm/thread_info.h>
long compat_arm_syscall(struct pt_regs *regs);
@@ -29,9 +33,9 @@ static long __invoke_syscall(struct pt_regs *regs, syscall_fn_t syscall_fn)
regs->regs[3], regs->regs[4], regs->regs[5]);
}
-asmlinkage void invoke_syscall(struct pt_regs *regs, unsigned int scno,
- unsigned int sc_nr,
- const syscall_fn_t syscall_table[])
+static void invoke_syscall(struct pt_regs *regs, unsigned int scno,
+ unsigned int sc_nr,
+ const syscall_fn_t syscall_table[])
{
long ret;
@@ -45,3 +49,50 @@ asmlinkage void invoke_syscall(struct pt_regs *regs, unsigned int scno,
regs->regs[0] = ret;
}
+
+static inline bool has_syscall_work(unsigned long flags)
+{
+ return unlikely(flags & _TIF_SYSCALL_WORK);
+}
+
+int syscall_trace_enter(struct pt_regs *regs);
+void syscall_trace_exit(struct pt_regs *regs);
+
+asmlinkage void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
+ const syscall_fn_t syscall_table[])
+{
+ unsigned long flags = current_thread_info()->flags;
+
+ regs->orig_x0 = regs->regs[0];
+ regs->syscallno = scno;
+
+ local_daif_restore(DAIF_PROCCTX);
+ user_exit();
+
+ if (has_syscall_work(flags)) {
+ /* set default errno for user-issued syscall(-1) */
+ if (scno == NO_SYSCALL)
+ regs->regs[0] = -ENOSYS;
+ scno = syscall_trace_enter(regs);
+ if (scno == NO_SYSCALL)
+ goto trace_exit;
+ }
+
+ invoke_syscall(regs, scno, sc_nr, syscall_table);
+
+ /*
+ * The tracing status may have changed under our feet, so we have to
+ * check again. However, if we were tracing entry, then we always trace
+ * exit regardless, as the old entry assembly did.
+ */
+ if (!has_syscall_work(flags)) {
+ local_daif_mask();
+ flags = current_thread_info()->flags;
+ if (!has_syscall_work(flags))
+ return;
+ local_daif_restore(DAIF_PROCCTX);
+ }
+
+trace_exit:
+ syscall_trace_exit(regs);
+}
--
2.11.0
next prev parent reply other threads:[~2018-07-11 14:02 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-07-11 13:56 [PATCHv5 00/21] arm64: invoke syscalls with pt_regs Mark Rutland
2018-07-11 13:56 ` [PATCHv5 01/21] arm64: consistently use unsigned long for thread flags Mark Rutland
2018-07-11 13:56 ` [PATCHv5 02/21] arm64: move SCTLR_EL{1,2} assertions to <asm/sysreg.h> Mark Rutland
2018-07-11 13:56 ` [PATCHv5 03/21] arm64: kill config_sctlr_el1() Mark Rutland
2018-07-11 13:56 ` [PATCHv5 04/21] arm64: kill change_cpacr() Mark Rutland
2018-07-11 13:56 ` [PATCHv5 05/21] arm64: move sve_user_{enable,disable} to <asm/fpsimd.h> Mark Rutland
2018-07-11 13:56 ` [PATCHv5 06/21] arm64: remove sigreturn wrappers Mark Rutland
2018-07-11 13:56 ` [PATCHv5 07/21] arm64: introduce syscall_fn_t Mark Rutland
2018-07-11 13:56 ` [PATCHv5 08/21] arm64: convert raw syscall invocation to C Mark Rutland
2018-07-11 13:56 ` Mark Rutland [this message]
2018-07-11 13:56 ` [PATCHv5 10/21] arm64: convert native/compat syscall entry " Mark Rutland
2018-07-11 13:56 ` [PATCHv5 11/21] arm64: don't restore GPRs when context tracking Mark Rutland
2018-07-11 13:56 ` [PATCHv5 12/21] arm64: don't reload GPRs after apply_ssbd Mark Rutland
2018-07-11 13:56 ` [PATCHv5 13/21] arm64: zero GPRs upon entry from EL0 Mark Rutland
2018-07-11 13:56 ` [PATCHv5 14/21] arm64: drop alignment from syscall tables Mark Rutland
2018-07-11 13:56 ` [PATCHv5 15/21] kernel: add ksys_personality() Mark Rutland
2018-07-11 13:56 ` [PATCHv5 16/21] kernel: add kcompat_sys_{f,}statfs64() Mark Rutland
2018-07-11 13:56 ` [PATCHv5 17/21] arm64: remove in-kernel call to sys_personality() Mark Rutland
2018-07-11 13:56 ` [PATCHv5 18/21] arm64: use {COMPAT,}SYSCALL_DEFINE0 for sigreturn Mark Rutland
2018-07-11 13:56 ` [PATCHv5 19/21] arm64: use SYSCALL_DEFINE6() for mmap Mark Rutland
2018-07-11 13:56 ` [PATCHv5 20/21] arm64: convert compat wrappers to C Mark Rutland
2018-07-11 13:56 ` [PATCHv5 21/21] arm64: implement syscall wrappers Mark Rutland
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180711135656.20670-10-mark.rutland@arm.com \
--to=mark.rutland@arm.com \
--cc=catalin.marinas@arm.com \
--cc=dave.martin@arm.com \
--cc=hch@infradead.org \
--cc=james.morse@arm.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@dominikbrodowski.net \
--cc=marc.zyngier@arm.com \
--cc=viro@zeniv.linux.org.uk \
--cc=will.deacon@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).