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@.
This commit is contained in:
parent
58c984f9c2
commit
e795d0888c
|
@ -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
|
||||
|
|
|
@ -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 2019/04/21 06:37:21 maxv Exp $");
|
|||
#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) {
|
||||
|
|
|
@ -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, "sysctl machdep subtree setup")
|
|||
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, "sysctl machdep subtree setup")
|
|||
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
|
||||
|
||||
|
|
Loading…
Reference in New Issue