Loading arch/arm64/kernel/entry-common.c +32 −0 Original line number Diff line number Diff line Loading @@ -355,6 +355,35 @@ static bool cortex_a76_erratum_1463225_debug_handler(struct pt_regs *regs) } #endif /* CONFIG_ARM64_ERRATUM_1463225 */ /* * As per the ABI exit SME streaming mode and clear the SVE state not * shared with FPSIMD on syscall entry. */ static inline void fp_user_discard(void) { /* * If SME is active then exit streaming mode. If ZA is active * then flush the SVE registers but leave userspace access to * both SVE and SME enabled, otherwise disable SME for the * task and fall through to disabling SVE too. This means * that after a syscall we never have any streaming mode * register state to track, if this changes the KVM code will * need updating. */ if (system_supports_sme()) sme_smstop_sm(); if (!system_supports_sve()) return; if (test_thread_flag(TIF_SVE)) { unsigned int sve_vq_minus_one; sve_vq_minus_one = sve_vq_from_vl(task_get_sve_vl(current)) - 1; sve_flush_live(true, sve_vq_minus_one); } } UNHANDLED(el1t, 64, sync) UNHANDLED(el1t, 64, irq) UNHANDLED(el1t, 64, fiq) Loading Loading @@ -644,6 +673,8 @@ static void noinstr el0_svc(struct pt_regs *regs) { enter_from_user_mode(regs); cortex_a76_erratum_1463225_svc_handler(); fp_user_discard(); local_daif_restore(DAIF_PROCCTX); do_el0_svc(regs); exit_to_user_mode(regs); } Loading Loading @@ -783,6 +814,7 @@ static void noinstr el0_svc_compat(struct pt_regs *regs) { enter_from_user_mode(regs); cortex_a76_erratum_1463225_svc_handler(); local_daif_restore(DAIF_PROCCTX); do_el0_svc_compat(regs); exit_to_user_mode(regs); } Loading arch/arm64/kernel/syscall.c +0 −33 Original line number Diff line number Diff line Loading @@ -8,7 +8,6 @@ #include <linux/randomize_kstack.h> #include <linux/syscalls.h> #include <asm/daifflags.h> #include <asm/debug-monitors.h> #include <asm/exception.h> #include <asm/fpsimd.h> Loading Loading @@ -101,8 +100,6 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr, * (Similarly for HVC and SMC elsewhere.) */ local_daif_restore(DAIF_PROCCTX); if (flags & _TIF_MTE_ASYNC_FAULT) { /* * Process the asynchronous tag check fault before the actual Loading Loading @@ -153,38 +150,8 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr, syscall_trace_exit(regs); } /* * As per the ABI exit SME streaming mode and clear the SVE state not * shared with FPSIMD on syscall entry. */ static inline void fp_user_discard(void) { /* * If SME is active then exit streaming mode. If ZA is active * then flush the SVE registers but leave userspace access to * both SVE and SME enabled, otherwise disable SME for the * task and fall through to disabling SVE too. This means * that after a syscall we never have any streaming mode * register state to track, if this changes the KVM code will * need updating. */ if (system_supports_sme()) sme_smstop_sm(); if (!system_supports_sve()) return; if (test_thread_flag(TIF_SVE)) { unsigned int sve_vq_minus_one; sve_vq_minus_one = sve_vq_from_vl(task_get_sve_vl(current)) - 1; sve_flush_live(true, sve_vq_minus_one); } } void do_el0_svc(struct pt_regs *regs) { fp_user_discard(); el0_svc_common(regs, regs->regs[8], __NR_syscalls, sys_call_table); } Loading Loading
arch/arm64/kernel/entry-common.c +32 −0 Original line number Diff line number Diff line Loading @@ -355,6 +355,35 @@ static bool cortex_a76_erratum_1463225_debug_handler(struct pt_regs *regs) } #endif /* CONFIG_ARM64_ERRATUM_1463225 */ /* * As per the ABI exit SME streaming mode and clear the SVE state not * shared with FPSIMD on syscall entry. */ static inline void fp_user_discard(void) { /* * If SME is active then exit streaming mode. If ZA is active * then flush the SVE registers but leave userspace access to * both SVE and SME enabled, otherwise disable SME for the * task and fall through to disabling SVE too. This means * that after a syscall we never have any streaming mode * register state to track, if this changes the KVM code will * need updating. */ if (system_supports_sme()) sme_smstop_sm(); if (!system_supports_sve()) return; if (test_thread_flag(TIF_SVE)) { unsigned int sve_vq_minus_one; sve_vq_minus_one = sve_vq_from_vl(task_get_sve_vl(current)) - 1; sve_flush_live(true, sve_vq_minus_one); } } UNHANDLED(el1t, 64, sync) UNHANDLED(el1t, 64, irq) UNHANDLED(el1t, 64, fiq) Loading Loading @@ -644,6 +673,8 @@ static void noinstr el0_svc(struct pt_regs *regs) { enter_from_user_mode(regs); cortex_a76_erratum_1463225_svc_handler(); fp_user_discard(); local_daif_restore(DAIF_PROCCTX); do_el0_svc(regs); exit_to_user_mode(regs); } Loading Loading @@ -783,6 +814,7 @@ static void noinstr el0_svc_compat(struct pt_regs *regs) { enter_from_user_mode(regs); cortex_a76_erratum_1463225_svc_handler(); local_daif_restore(DAIF_PROCCTX); do_el0_svc_compat(regs); exit_to_user_mode(regs); } Loading
arch/arm64/kernel/syscall.c +0 −33 Original line number Diff line number Diff line Loading @@ -8,7 +8,6 @@ #include <linux/randomize_kstack.h> #include <linux/syscalls.h> #include <asm/daifflags.h> #include <asm/debug-monitors.h> #include <asm/exception.h> #include <asm/fpsimd.h> Loading Loading @@ -101,8 +100,6 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr, * (Similarly for HVC and SMC elsewhere.) */ local_daif_restore(DAIF_PROCCTX); if (flags & _TIF_MTE_ASYNC_FAULT) { /* * Process the asynchronous tag check fault before the actual Loading Loading @@ -153,38 +150,8 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr, syscall_trace_exit(regs); } /* * As per the ABI exit SME streaming mode and clear the SVE state not * shared with FPSIMD on syscall entry. */ static inline void fp_user_discard(void) { /* * If SME is active then exit streaming mode. If ZA is active * then flush the SVE registers but leave userspace access to * both SVE and SME enabled, otherwise disable SME for the * task and fall through to disabling SVE too. This means * that after a syscall we never have any streaming mode * register state to track, if this changes the KVM code will * need updating. */ if (system_supports_sme()) sme_smstop_sm(); if (!system_supports_sve()) return; if (test_thread_flag(TIF_SVE)) { unsigned int sve_vq_minus_one; sve_vq_minus_one = sve_vq_from_vl(task_get_sve_vl(current)) - 1; sve_flush_live(true, sve_vq_minus_one); } } void do_el0_svc(struct pt_regs *regs) { fp_user_discard(); el0_svc_common(regs, regs->regs[8], __NR_syscalls, sys_call_table); } Loading