From: Mark Rutland <mark.rutland@arm.com> To: linux-arm-kernel@lists.infradead.org, catalin.marinas@arm.com, will.deacon@arm.com Cc: 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: [PATCHv3 09/19] arm64: convert syscall trace logic to C Date: Mon, 18 Jun 2018 13:03:00 +0100 [thread overview] Message-ID: <20180618120310.39527-10-mark.rutland@arm.com> (raw) In-Reply-To: <20180618120310.39527-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> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Will Deacon <will.deacon@arm.com> --- arch/arm64/kernel/entry.S | 53 ++--------------------------------------- arch/arm64/kernel/syscall.c | 58 ++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 57 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 b463b962d597..2adf1a073398 100644 --- a/arch/arm64/kernel/syscall.c +++ b/arch/arm64/kernel/syscall.c @@ -1,8 +1,13 @@ // SPDX-License-Identifier: GPL-2.0 +#include <linux/compiler.h> +#include <linux/context_tracking.h> #include <linux/nospec.h> #include <linux/ptrace.h> +#include <asm/daifflags.h> +#include <asm/thread_info.h> + long do_ni_syscall(struct pt_regs *regs); typedef long (*syscall_fn_t)(unsigned long, unsigned long, @@ -16,9 +21,9 @@ static void __invoke_syscall(struct pt_regs *regs, syscall_fn_t syscall_fn) regs->regs[4], regs->regs[5]); } -asmlinkage void invoke_syscall(struct pt_regs *regs, unsigned int scno, - unsigned int sc_nr, - syscall_fn_t syscall_table[]) +static void invoke_syscall(struct pt_regs *regs, unsigned int scno, + unsigned int sc_nr, + syscall_fn_t syscall_table[]) { if (scno < sc_nr) { syscall_fn_t syscall_fn; @@ -28,3 +33,50 @@ asmlinkage void invoke_syscall(struct pt_regs *regs, unsigned int scno, regs->regs[0] = do_ni_syscall(regs); } } + +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, + 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
WARNING: multiple messages have this Message-ID (diff)
From: mark.rutland@arm.com (Mark Rutland) To: linux-arm-kernel@lists.infradead.org Subject: [PATCHv3 09/19] arm64: convert syscall trace logic to C Date: Mon, 18 Jun 2018 13:03:00 +0100 [thread overview] Message-ID: <20180618120310.39527-10-mark.rutland@arm.com> (raw) In-Reply-To: <20180618120310.39527-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> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Will Deacon <will.deacon@arm.com> --- arch/arm64/kernel/entry.S | 53 ++--------------------------------------- arch/arm64/kernel/syscall.c | 58 ++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 57 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 b463b962d597..2adf1a073398 100644 --- a/arch/arm64/kernel/syscall.c +++ b/arch/arm64/kernel/syscall.c @@ -1,8 +1,13 @@ // SPDX-License-Identifier: GPL-2.0 +#include <linux/compiler.h> +#include <linux/context_tracking.h> #include <linux/nospec.h> #include <linux/ptrace.h> +#include <asm/daifflags.h> +#include <asm/thread_info.h> + long do_ni_syscall(struct pt_regs *regs); typedef long (*syscall_fn_t)(unsigned long, unsigned long, @@ -16,9 +21,9 @@ static void __invoke_syscall(struct pt_regs *regs, syscall_fn_t syscall_fn) regs->regs[4], regs->regs[5]); } -asmlinkage void invoke_syscall(struct pt_regs *regs, unsigned int scno, - unsigned int sc_nr, - syscall_fn_t syscall_table[]) +static void invoke_syscall(struct pt_regs *regs, unsigned int scno, + unsigned int sc_nr, + syscall_fn_t syscall_table[]) { if (scno < sc_nr) { syscall_fn_t syscall_fn; @@ -28,3 +33,50 @@ asmlinkage void invoke_syscall(struct pt_regs *regs, unsigned int scno, regs->regs[0] = do_ni_syscall(regs); } } + +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, + 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-06-18 12:03 UTC|newest] Thread overview: 106+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-06-18 12:02 [PATCHv3 00/19] arm64: invoke syscalls with pt_regs Mark Rutland 2018-06-18 12:02 ` Mark Rutland 2018-06-18 12:02 ` [PATCHv3 01/19] arm64: consistently use unsigned long for thread flags Mark Rutland 2018-06-18 12:02 ` Mark Rutland 2018-06-19 10:49 ` Catalin Marinas 2018-06-19 10:49 ` Catalin Marinas 2018-06-19 11:19 ` Mark Rutland 2018-06-19 11:19 ` Mark Rutland 2018-06-18 12:02 ` [PATCHv3 02/19] arm64: move SCTLR_EL{1,2} assertions to <asm/sysreg.h> Mark Rutland 2018-06-18 12:02 ` [PATCHv3 02/19] arm64: move SCTLR_EL{1, 2} " Mark Rutland 2018-06-19 11:02 ` Catalin Marinas 2018-06-19 11:02 ` Catalin Marinas 2018-06-19 11:48 ` [PATCHv3 02/19] arm64: move SCTLR_EL{1,2} " Mark Rutland 2018-06-19 11:48 ` Mark Rutland 2018-06-18 12:02 ` [PATCHv3 03/19] arm64: introduce sysreg_clear_set() Mark Rutland 2018-06-18 12:02 ` Mark Rutland 2018-06-19 11:44 ` Catalin Marinas 2018-06-19 11:44 ` Catalin Marinas 2018-06-19 11:47 ` Marc Zyngier 2018-06-19 11:47 ` Marc Zyngier 2018-06-18 12:02 ` [PATCHv3 04/19] arm64: kill config_sctlr_el1() Mark Rutland 2018-06-18 12:02 ` Mark Rutland 2018-06-19 11:44 ` Catalin Marinas 2018-06-19 11:44 ` Catalin Marinas 2018-06-18 12:02 ` [PATCHv3 05/19] arm64: kill change_cpacr() Mark Rutland 2018-06-18 12:02 ` Mark Rutland 2018-06-19 11:45 ` Catalin Marinas 2018-06-19 11:45 ` Catalin Marinas 2018-06-18 12:02 ` [PATCHv3 06/19] arm64: move sve_user_{enable,disable} to <asm/fpsimd.h> Mark Rutland 2018-06-18 12:02 ` [PATCHv3 06/19] arm64: move sve_user_{enable, disable} " Mark Rutland 2018-06-19 12:00 ` Catalin Marinas 2018-06-19 12:00 ` Catalin Marinas 2018-06-19 12:19 ` Dave Martin 2018-06-19 12:19 ` Dave Martin 2018-06-18 12:02 ` [PATCHv3 07/19] arm64: remove sigreturn wrappers Mark Rutland 2018-06-18 12:02 ` Mark Rutland 2018-06-19 12:47 ` Catalin Marinas 2018-06-19 12:47 ` Catalin Marinas 2018-06-18 12:02 ` [PATCHv3 08/19] arm64: convert raw syscall invocation to C Mark Rutland 2018-06-18 12:02 ` Mark Rutland 2018-06-19 13:33 ` Catalin Marinas 2018-06-19 13:33 ` Catalin Marinas 2018-06-19 14:21 ` Catalin Marinas 2018-06-19 14:21 ` Catalin Marinas 2018-06-19 14:48 ` Mark Rutland 2018-06-19 14:48 ` Mark Rutland 2018-06-19 14:55 ` Catalin Marinas 2018-06-19 14:55 ` Catalin Marinas 2018-06-19 14:58 ` Mark Rutland 2018-06-19 14:58 ` Mark Rutland 2018-06-18 12:03 ` Mark Rutland [this message] 2018-06-18 12:03 ` [PATCHv3 09/19] arm64: convert syscall trace logic " Mark Rutland 2018-06-19 14:32 ` Catalin Marinas 2018-06-19 14:32 ` Catalin Marinas 2018-06-19 15:14 ` Mark Rutland 2018-06-19 15:14 ` Mark Rutland 2018-06-18 12:03 ` [PATCHv3 10/19] arm64: convert native/compat syscall entry " Mark Rutland 2018-06-18 12:03 ` Mark Rutland 2018-06-19 12:18 ` Dave Martin 2018-06-19 12:18 ` Dave Martin 2018-06-19 13:15 ` Mark Rutland 2018-06-19 13:15 ` Mark Rutland 2018-06-20 9:21 ` Dave Martin 2018-06-20 9:21 ` Dave Martin 2018-06-19 15:20 ` Catalin Marinas 2018-06-19 15:20 ` Catalin Marinas 2018-06-18 12:03 ` [PATCHv3 11/19] arm64: don't reload GPRs after apply_ssbd Mark Rutland 2018-06-18 12:03 ` Mark Rutland 2018-06-19 15:23 ` Catalin Marinas 2018-06-19 15:23 ` Catalin Marinas 2018-06-18 12:03 ` [PATCHv3 12/19] arm64: zero GPRs upon entry from EL0 Mark Rutland 2018-06-18 12:03 ` Mark Rutland 2018-06-19 15:24 ` Catalin Marinas 2018-06-19 15:24 ` Catalin Marinas 2018-06-18 12:03 ` [PATCHv3 13/19] kernel: add ksys_personality() Mark Rutland 2018-06-18 12:03 ` Mark Rutland 2018-06-19 15:45 ` Catalin Marinas 2018-06-19 15:45 ` Catalin Marinas 2018-06-19 15:53 ` Mark Rutland 2018-06-19 15:53 ` Mark Rutland 2018-06-18 12:03 ` [PATCHv3 14/19] kernel: add kcompat_sys_{f,}statfs64() Mark Rutland 2018-06-18 12:03 ` Mark Rutland 2018-06-18 12:03 ` [PATCHv3 15/19] arm64: remove in-kernel call to sys_personality() Mark Rutland 2018-06-18 12:03 ` Mark Rutland 2018-06-19 15:46 ` Catalin Marinas 2018-06-19 15:46 ` Catalin Marinas 2018-06-18 12:03 ` [PATCHv3 16/19] arm64: use {COMPAT,}SYSCALL_DEFINE0 for sigreturn Mark Rutland 2018-06-18 12:03 ` Mark Rutland 2018-06-19 15:48 ` Catalin Marinas 2018-06-19 15:48 ` [PATCHv3 16/19] arm64: use {COMPAT, }SYSCALL_DEFINE0 " Catalin Marinas 2018-06-18 12:03 ` [PATCHv3 17/19] arm64: use SYSCALL_DEFINE6() for mmap Mark Rutland 2018-06-18 12:03 ` Mark Rutland 2018-06-19 15:50 ` Catalin Marinas 2018-06-19 15:50 ` Catalin Marinas 2018-06-18 12:03 ` [PATCHv3 18/19] arm64: convert compat wrappers to C Mark Rutland 2018-06-18 12:03 ` Mark Rutland 2018-06-19 15:51 ` Catalin Marinas 2018-06-19 15:51 ` Catalin Marinas 2018-06-18 12:03 ` [PATCHv3 19/19] arm64: implement syscall wrappers Mark Rutland 2018-06-18 12:03 ` Mark Rutland 2018-06-19 16:13 ` Catalin Marinas 2018-06-19 16:13 ` Catalin Marinas 2018-06-19 15:38 ` [PATCHv3 00/19] arm64: invoke syscalls with pt_regs Mark Rutland 2018-06-19 15:38 ` Mark Rutland 2018-06-19 16:14 ` Catalin Marinas 2018-06-19 16:14 ` Catalin Marinas
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=20180618120310.39527-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@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: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.