From patchwork Wed Jul 11 13:56:45 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Rutland X-Patchwork-Id: 141749 Delivered-To: patch@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp321629ljj; Wed, 11 Jul 2018 06:57:46 -0700 (PDT) X-Google-Smtp-Source: AAOMgpdrVG//PTs4YKSMHlRoATd9d7mzZqCpr8trt7BHLmhB3f4bdd4c+sxbqDnPorNd1X1kuc8c X-Received: by 2002:a65:4888:: with SMTP id n8-v6mr27210101pgs.149.1531317466705; Wed, 11 Jul 2018 06:57:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1531317466; cv=none; d=google.com; s=arc-20160816; b=u4RO4ss9sNDCWLdiUStfqGW5d/JAZuhpfLp8jxRnTRItReqyFo6ZwexCfUv0x5LNb7 3Cctq1+dXFad6z5MdMlRU/TVMSLCoWUrlBqCJlystvFzbmLbTMvvLNTStMxxBy/3h2lV rDNBo3JQpG0bfktuh6o3IOW0u2wt6a9ISfKStbTQMicCvqzR3t1oDi2+re6IgIXv5GtG 4Wh8+ML37n7iloFpCkhbDq9xpPH8P+Z+ld2a4msu6Dxb8evvhLClkAVZvZ3JukvcRlzz tmkz4n1aDxouzkOd3acoklmT4LjT3Qrc3tP64UMSpqB1FBP907eHlLH9GlSMGpEGGLwh xjlw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=iqDBGQvIfM25QE/x+62w3uJ8nhHrhMpkYUDuqJglmbk=; b=cOQuNjPLxKYf6MWE/OoktssUH9QDi9UWxBP5rJYqZLAOX2t19D/fTag2LbI7sIF4TE Ph9oVDSKYedcVkUqczrWLEsoiYYAtqa2ibeWeV4wvu753DmwyP9olJYLz3mxI1j7zQZy uolqVx/qNhYS9GqNKNA3lnwYg3t+0TfjF3kam/cYU99uAm3x0OCvxa7ydH/+t6uqxEtQ ZaG1/bnyB1KMn39yIHiV87P2Awm9gR/G5Q71XEKel+kFTOeH8NJCQ2D4HP4CfdeVVDdU ZPvCcj7p+4cCIWfOtzai4y0414SY6F+rrUEFHDEggIaEdF4k3W8EcJKZbwkbct46TpHd /gew== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id t62-v6si11897404pgd.485.2018.07.11.06.57.46; Wed, 11 Jul 2018 06:57:46 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388509AbeGKOCM (ORCPT + 23 others); Wed, 11 Jul 2018 10:02:12 -0400 Received: from foss.arm.com ([217.140.101.70]:36396 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2388274AbeGKOCJ (ORCPT ); Wed, 11 Jul 2018 10:02:09 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 30AFF1BB0; Wed, 11 Jul 2018 06:57:41 -0700 (PDT) Received: from lakrids.cambridge.arm.com (usa-sjc-imap-foss1.foss.arm.com [10.72.51.249]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 20A1D3F5B1; Wed, 11 Jul 2018 06:57:38 -0700 (PDT) From: Mark Rutland 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 10/21] arm64: convert native/compat syscall entry to C Date: Wed, 11 Jul 2018 14:56:45 +0100 Message-Id: <20180711135656.20670-11-mark.rutland@arm.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180711135656.20670-1-mark.rutland@arm.com> References: <20180711135656.20670-1-mark.rutland@arm.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Now that the syscall invocation logic is in C, we can migrate the rest of the syscall entry logic over, so that the entry assembly needn't look at the register values at all. The SVE reset across syscall logic now unconditionally clears TIF_SVE, but sve_user_disable() will only write back to CPACR_EL1 when SVE is actually enabled. Signed-off-by: Mark Rutland Reviewed-by: Catalin Marinas Reviewed-by: Dave Martin Cc: Will Deacon --- arch/arm64/include/asm/syscall.h | 4 ++++ arch/arm64/kernel/entry.S | 42 ++++------------------------------------ arch/arm64/kernel/syscall.c | 37 +++++++++++++++++++++++++++++++++-- 3 files changed, 43 insertions(+), 40 deletions(-) -- 2.11.0 diff --git a/arch/arm64/include/asm/syscall.h b/arch/arm64/include/asm/syscall.h index 50841cb1bfa9..b83d0e6980a3 100644 --- a/arch/arm64/include/asm/syscall.h +++ b/arch/arm64/include/asm/syscall.h @@ -26,6 +26,10 @@ typedef long (*syscall_fn_t)(unsigned long, unsigned long, extern const syscall_fn_t sys_call_table[]; +#ifdef CONFIG_COMPAT +extern const syscall_fn_t compat_sys_call_table[]; +#endif + static inline int syscall_get_nr(struct task_struct *task, struct pt_regs *regs) { diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index 05b9f03f3e00..156c4e3fd1a4 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -720,14 +720,9 @@ el0_sync_compat: b.ge el0_dbg b el0_inv el0_svc_compat: - /* - * AArch32 syscall handling - */ - ldr x16, [tsk, #TSK_TI_FLAGS] // load thread flags - adrp stbl, compat_sys_call_table // load compat syscall table pointer - mov wscno, w7 // syscall number in w7 (r7) - mov wsc_nr, #__NR_compat_syscalls - b el0_svc_naked + mov x0, sp + bl el0_svc_compat_handler + b ret_to_user .align 6 el0_irq_compat: @@ -925,37 +920,8 @@ ENDPROC(ret_to_user) */ .align 6 el0_svc: - ldr x16, [tsk, #TSK_TI_FLAGS] // load thread flags - adrp stbl, sys_call_table // load syscall table pointer - mov wscno, w8 // syscall number in w8 - mov wsc_nr, #__NR_syscalls - -#ifdef CONFIG_ARM64_SVE -alternative_if_not ARM64_SVE - b el0_svc_naked -alternative_else_nop_endif - tbz x16, #TIF_SVE, el0_svc_naked // Skip unless TIF_SVE set: - bic x16, x16, #_TIF_SVE // discard SVE state - str x16, [tsk, #TSK_TI_FLAGS] - - /* - * task_fpsimd_load() won't be called to update CPACR_EL1 in - * ret_to_user unless TIF_FOREIGN_FPSTATE is still set, which only - * happens if a context switch or kernel_neon_begin() or context - * modification (sigreturn, ptrace) intervenes. - * So, ensure that CPACR_EL1 is already correct for the fast-path case: - */ - mrs x9, cpacr_el1 - bic x9, x9, #CPACR_EL1_ZEN_EL0EN // disable SVE for el0 - msr cpacr_el1, x9 // synchronised by eret to el0 -#endif - -el0_svc_naked: // compat entry point mov x0, sp - mov w1, wscno - mov w2, wsc_nr - mov x3, stbl - bl el0_svc_common + bl el0_svc_handler b ret_to_user ENDPROC(el0_svc) diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c index 3e1df8ca1e79..d1c66e6bd359 100644 --- a/arch/arm64/kernel/syscall.c +++ b/arch/arm64/kernel/syscall.c @@ -8,8 +8,10 @@ #include #include +#include #include #include +#include long compat_arm_syscall(struct pt_regs *regs); @@ -58,8 +60,8 @@ static inline bool has_syscall_work(unsigned long flags) 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[]) +static 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; @@ -96,3 +98,34 @@ asmlinkage void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr, trace_exit: syscall_trace_exit(regs); } + +static inline void sve_user_discard(void) +{ + if (!system_supports_sve()) + return; + + clear_thread_flag(TIF_SVE); + + /* + * task_fpsimd_load() won't be called to update CPACR_EL1 in + * ret_to_user unless TIF_FOREIGN_FPSTATE is still set, which only + * happens if a context switch or kernel_neon_begin() or context + * modification (sigreturn, ptrace) intervenes. + * So, ensure that CPACR_EL1 is already correct for the fast-path case. + */ + sve_user_disable(); +} + +asmlinkage void el0_svc_handler(struct pt_regs *regs) +{ + sve_user_discard(); + el0_svc_common(regs, regs->regs[8], __NR_syscalls, sys_call_table); +} + +#ifdef CONFIG_COMPAT +asmlinkage void el0_svc_compat_handler(struct pt_regs *regs) +{ + el0_svc_common(regs, regs->regs[7], __NR_compat_syscalls, + compat_sys_call_table); +} +#endif