Module Name: src Committed By: maxv Date: Wed May 15 17:31:41 UTC 2019
Modified Files: src/sys/arch/amd64/amd64: locore.S src/sys/arch/x86/x86: svs.c x86_machdep.c Log Message: Change the way SVS is disabled. Now you have to pass "boot -3" from the bootloader. The machdep.svs.enabled sysctl becomes read-only, and just indicates whether SVS is enabled. Sent on port-amd64@. To generate a diff of this commit: cvs rdiff -u -r1.181 -r1.182 src/sys/arch/amd64/amd64/locore.S cvs rdiff -u -r1.25 -r1.26 src/sys/arch/x86/x86/svs.c cvs rdiff -u -r1.124 -r1.125 src/sys/arch/x86/x86/x86_machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/amd64/amd64/locore.S diff -u src/sys/arch/amd64/amd64/locore.S:1.181 src/sys/arch/amd64/amd64/locore.S:1.182 --- src/sys/arch/amd64/amd64/locore.S:1.181 Tue May 14 16:59:25 2019 +++ src/sys/arch/amd64/amd64/locore.S Wed May 15 17:31:41 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.S,v 1.181 2019/05/14 16:59:25 maxv Exp $ */ +/* $NetBSD: locore.S,v 1.182 2019/05/15 17:31:41 maxv Exp $ */ /* * Copyright-o-rama! @@ -1621,10 +1621,6 @@ END(intrfastexit) .globl svs_enter_altstack, svs_enter_altstack_end .globl svs_leave, svs_leave_end .globl svs_leave_altstack, svs_leave_altstack_end - .globl nosvs_enter, nosvs_enter_end - .globl nosvs_enter_altstack, nosvs_enter_altstack_end - .globl nosvs_leave, nosvs_leave_end - .globl nosvs_leave_altstack, nosvs_leave_altstack_end LABEL(svs_enter) movabs SVS_UTLS+UTLS_KPDIRPA,%rax @@ -1668,30 +1664,6 @@ LABEL(svs_leave_nmi) movq (FRAMESIZE+1*8)(%rsp),%rax /* nmistore->scratch */ movq %rax,%cr3 LABEL(svs_leave_nmi_end) - -LABEL(nosvs_enter) - NOSVS_ENTER -LABEL(nosvs_enter_end) - -LABEL(nosvs_enter_altstack) - NOSVS_ENTER_ALTSTACK -LABEL(nosvs_enter_altstack_end) - -LABEL(nosvs_enter_nmi) - NOSVS_ENTER_NMI -LABEL(nosvs_enter_nmi_end) - -LABEL(nosvs_leave) - NOSVS_LEAVE -LABEL(nosvs_leave_end) - -LABEL(nosvs_leave_altstack) - NOSVS_LEAVE_ALTSTACK -LABEL(nosvs_leave_altstack_end) - -LABEL(nosvs_leave_nmi) - NOSVS_LEAVE_NMI -LABEL(nosvs_leave_nmi_end) #endif .globl ibrs_enter, ibrs_enter_end Index: src/sys/arch/x86/x86/svs.c diff -u src/sys/arch/x86/x86/svs.c:1.25 src/sys/arch/x86/x86/svs.c:1.26 --- src/sys/arch/x86/x86/svs.c:1.25 Sun Apr 21 06:37:21 2019 +++ src/sys/arch/x86/x86/svs.c Wed May 15 17:31:41 2019 @@ -1,7 +1,7 @@ -/* $NetBSD: svs.c,v 1.25 2019/04/21 06:37:21 maxv Exp $ */ +/* $NetBSD: svs.c,v 1.26 2019/05/15 17:31:41 maxv Exp $ */ /* - * Copyright (c) 2018 The NetBSD Foundation, Inc. + * Copyright (c) 2018-2019 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: svs.c,v 1.25 2019/04/21 06:37:21 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: svs.c,v 1.26 2019/05/15 17:31:41 maxv Exp $"); #include "opt_svs.h" @@ -41,6 +41,7 @@ __KERNEL_RCSID(0, "$NetBSD: svs.c,v 1.25 #include <sys/kauth.h> #include <sys/sysctl.h> #include <sys/xcall.h> +#include <sys/reboot.h> #include <x86/cputypes.h> #include <machine/cpuvar.h> @@ -611,147 +612,6 @@ svs_enable(void) x86_patch_window_close(psl, cr0); } -static void -svs_disable_hotpatch(void) -{ - extern uint8_t nosvs_enter, nosvs_enter_end; - extern uint8_t nosvs_enter_altstack, nosvs_enter_altstack_end; - extern uint8_t nosvs_enter_nmi, nosvs_enter_nmi_end; - extern uint8_t nosvs_leave, nosvs_leave_end; - extern uint8_t nosvs_leave_altstack, nosvs_leave_altstack_end; - extern uint8_t nosvs_leave_nmi, nosvs_leave_nmi_end; - u_long psl, cr0; - uint8_t *bytes; - size_t size; - - x86_patch_window_open(&psl, &cr0); - - bytes = &nosvs_enter; - size = (size_t)&nosvs_enter_end - (size_t)&nosvs_enter; - x86_hotpatch(HP_NAME_SVS_ENTER, bytes, size); - - bytes = &nosvs_enter_altstack; - size = (size_t)&nosvs_enter_altstack_end - - (size_t)&nosvs_enter_altstack; - x86_hotpatch(HP_NAME_SVS_ENTER_ALT, bytes, size); - - bytes = &nosvs_enter_nmi; - size = (size_t)&nosvs_enter_nmi_end - - (size_t)&nosvs_enter_nmi; - x86_hotpatch(HP_NAME_SVS_ENTER_NMI, bytes, size); - - bytes = &nosvs_leave; - size = (size_t)&nosvs_leave_end - (size_t)&nosvs_leave; - x86_hotpatch(HP_NAME_SVS_LEAVE, bytes, size); - - bytes = &nosvs_leave_altstack; - size = (size_t)&nosvs_leave_altstack_end - - (size_t)&nosvs_leave_altstack; - x86_hotpatch(HP_NAME_SVS_LEAVE_ALT, bytes, size); - - bytes = &nosvs_leave_nmi; - size = (size_t)&nosvs_leave_nmi_end - - (size_t)&nosvs_leave_nmi; - x86_hotpatch(HP_NAME_SVS_LEAVE_NMI, bytes, size); - - x86_patch_window_close(psl, cr0); -} - -static volatile unsigned long svs_cpu_barrier1 __cacheline_aligned; -static volatile unsigned long svs_cpu_barrier2 __cacheline_aligned; -typedef void (vector)(void); - -static void -svs_disable_cpu(void *arg1, void *arg2) -{ - struct cpu_info *ci = curcpu(); - extern vector Xsyscall; - u_long psl; - - psl = x86_read_psl(); - x86_disable_intr(); - - atomic_dec_ulong(&svs_cpu_barrier1); - while (atomic_cas_ulong(&svs_cpu_barrier1, 0, 0) != 0) { - x86_pause(); - } - - /* cpu0 is the one that does the hotpatch job */ - if (ci == &cpu_info_primary) { - svs_enabled = false; - svs_disable_hotpatch(); - } - - /* put back the non-SVS syscall entry point */ - wrmsr(MSR_LSTAR, (uint64_t)Xsyscall); - - /* enable global pages */ - if (cpu_feature[0] & CPUID_PGE) - lcr4(rcr4() | CR4_PGE); - - atomic_dec_ulong(&svs_cpu_barrier2); - while (atomic_cas_ulong(&svs_cpu_barrier2, 0, 0) != 0) { - x86_pause(); - } - - /* Write back and invalidate cache, flush pipelines. */ - wbinvd(); - x86_flush(); - - x86_write_psl(psl); -} - -static int -svs_disable(void) -{ - uint64_t xc; - - svs_cpu_barrier1 = ncpu; - svs_cpu_barrier2 = ncpu; - - printf("[+] Disabling SVS..."); - xc = xc_broadcast(0, svs_disable_cpu, NULL, NULL); - xc_wait(xc); - printf(" done!\n"); - - return 0; -} - -int sysctl_machdep_svs_enabled(SYSCTLFN_ARGS); - -int -sysctl_machdep_svs_enabled(SYSCTLFN_ARGS) -{ - struct sysctlnode node; - int error; - bool val; - - val = *(bool *)rnode->sysctl_data; - - node = *rnode; - node.sysctl_data = &val; - - error = sysctl_lookup(SYSCTLFN_CALL(&node)); - if (error != 0 || newp == NULL) - return error; - - if (val == 1) { - if (svs_enabled) - error = 0; - else - error = EOPNOTSUPP; - } else if (svs_enabled) { - error = kauth_authorize_machdep(kauth_cred_get(), - KAUTH_MACHDEP_SVS_DISABLE, NULL, NULL, NULL, NULL); - if (!error) - error = svs_disable(); - } else { - error = 0; - } - - return error; -} - void svs_init(void) { @@ -760,6 +620,9 @@ svs_init(void) if (cpu_vendor != CPUVENDOR_INTEL) { return; } + if (boothowto & RB_MD3) { + return; + } if (cpu_info_primary.ci_feat_val[7] & CPUID_SEF_ARCH_CAP) { msr = rdmsr(MSR_IA32_ARCH_CAPABILITIES); if (msr & IA32_ARCH_RDCL_NO) { Index: src/sys/arch/x86/x86/x86_machdep.c diff -u src/sys/arch/x86/x86/x86_machdep.c:1.124 src/sys/arch/x86/x86/x86_machdep.c:1.125 --- src/sys/arch/x86/x86/x86_machdep.c:1.124 Fri Feb 15 08:54:01 2019 +++ src/sys/arch/x86/x86/x86_machdep.c Wed May 15 17:31:41 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: x86_machdep.c,v 1.124 2019/02/15 08:54:01 nonaka Exp $ */ +/* $NetBSD: x86_machdep.c,v 1.125 2019/05/15 17:31:41 maxv Exp $ */ /*- * Copyright (c) 2002, 2006, 2007 YAMAMOTO Takashi, @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: x86_machdep.c,v 1.124 2019/02/15 08:54:01 nonaka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: x86_machdep.c,v 1.125 2019/05/15 17:31:41 maxv Exp $"); #include "opt_modular.h" #include "opt_physmem.h" @@ -1287,7 +1287,6 @@ SYSCTL_SETUP(sysctl_machdep_setup, "sysc sysctl_machdep_hypervisor, 0, NULL, 0, CTL_MACHDEP, CTL_CREATE, CTL_EOL); #ifdef SVS - int sysctl_machdep_svs_enabled(SYSCTLFN_ARGS); const struct sysctlnode *svs_rnode = NULL; sysctl_createv(clog, 0, NULL, &svs_rnode, CTLFLAG_PERMANENT, @@ -1295,10 +1294,10 @@ SYSCTL_SETUP(sysctl_machdep_setup, "sysc NULL, 0, NULL, 0, CTL_MACHDEP, CTL_CREATE); sysctl_createv(clog, 0, &svs_rnode, &svs_rnode, - CTLFLAG_READWRITE, + CTLFLAG_PERMANENT, CTLTYPE_BOOL, "enabled", SYSCTL_DESCR("Whether the kernel uses SVS"), - sysctl_machdep_svs_enabled, 0, &svs_enabled, 0, + NULL, 0, &svs_enabled, 0, CTL_CREATE, CTL_EOL); #endif