Module Name: src Committed By: maxv Date: Thu Feb 22 13:27:18 UTC 2018
Modified Files: src/sys/arch/amd64/amd64: machdep.c src/sys/arch/amd64/include: pmap.h src/sys/arch/x86/x86: cpu.c svs.c x86_machdep.c Log Message: Remove svs_pgg_update(). Instead of manually changing PG_G on each page, we can disable the global-paging mechanism in %cr4 with CR4_PGE. Do that. In addition, install CR4_PGE when SVS is disabled manually (via the sysctl). Now, doing "sysctl -w machdep.svs_enabled=0" restores the performance completely, exactly as if SVS hadn't been enabled in the first place. To generate a diff of this commit: cvs rdiff -u -r1.300 -r1.301 src/sys/arch/amd64/amd64/machdep.c cvs rdiff -u -r1.44 -r1.45 src/sys/arch/amd64/include/pmap.h cvs rdiff -u -r1.148 -r1.149 src/sys/arch/x86/x86/cpu.c cvs rdiff -u -r1.7 -r1.8 src/sys/arch/x86/x86/svs.c cvs rdiff -u -r1.106 -r1.107 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/machdep.c diff -u src/sys/arch/amd64/amd64/machdep.c:1.300 src/sys/arch/amd64/amd64/machdep.c:1.301 --- src/sys/arch/amd64/amd64/machdep.c:1.300 Thu Feb 22 10:26:32 2018 +++ src/sys/arch/amd64/amd64/machdep.c Thu Feb 22 13:27:17 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.300 2018/02/22 10:26:32 maxv Exp $ */ +/* $NetBSD: machdep.c,v 1.301 2018/02/22 13:27:17 maxv Exp $ */ /* * Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011 @@ -110,7 +110,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.300 2018/02/22 10:26:32 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.301 2018/02/22 13:27:17 maxv Exp $"); /* #define XENDEBUG_LOW */ @@ -1599,7 +1599,7 @@ init_x86_64(paddr_t first_avail) cpu_probe(&cpu_info_primary); #ifdef SVS - svs_init(true); + svs_init(); #endif cpu_init_msrs(&cpu_info_primary, true); Index: src/sys/arch/amd64/include/pmap.h diff -u src/sys/arch/amd64/include/pmap.h:1.44 src/sys/arch/amd64/include/pmap.h:1.45 --- src/sys/arch/amd64/include/pmap.h:1.44 Thu Feb 22 09:41:06 2018 +++ src/sys/arch/amd64/include/pmap.h Thu Feb 22 13:27:18 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.h,v 1.44 2018/02/22 09:41:06 maxv Exp $ */ +/* $NetBSD: pmap.h,v 1.45 2018/02/22 13:27:18 maxv Exp $ */ /* * Copyright (c) 1997 Charles D. Cranor and Washington University. @@ -221,7 +221,7 @@ void svs_pmap_sync(struct pmap *, int); void svs_lwp_switch(struct lwp *, struct lwp *); void svs_pdir_switch(struct pmap *); -void svs_init(bool); +void svs_init(void); extern bool svs_enabled; #include <x86/pmap.h> Index: src/sys/arch/x86/x86/cpu.c diff -u src/sys/arch/x86/x86/cpu.c:1.148 src/sys/arch/x86/x86/cpu.c:1.149 --- src/sys/arch/x86/x86/cpu.c:1.148 Thu Feb 22 08:56:52 2018 +++ src/sys/arch/x86/x86/cpu.c Thu Feb 22 13:27:18 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: cpu.c,v 1.148 2018/02/22 08:56:52 maxv Exp $ */ +/* $NetBSD: cpu.c,v 1.149 2018/02/22 13:27:18 maxv Exp $ */ /* * Copyright (c) 2000-2012 NetBSD Foundation, Inc. @@ -62,7 +62,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.148 2018/02/22 08:56:52 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.149 2018/02/22 13:27:18 maxv Exp $"); #include "opt_ddb.h" #include "opt_mpbios.h" /* for MPDEBUG */ @@ -589,6 +589,9 @@ cpu_init(struct cpu_info *ci) * hardware supports it. */ if (cpu_feature[0] & CPUID_PGE) +#ifdef SVS + if (!svs_enabled) +#endif cr4 |= CR4_PGE; /* enable global TLB caching */ /* Index: src/sys/arch/x86/x86/svs.c diff -u src/sys/arch/x86/x86/svs.c:1.7 src/sys/arch/x86/x86/svs.c:1.8 --- src/sys/arch/x86/x86/svs.c:1.7 Thu Feb 22 11:57:39 2018 +++ src/sys/arch/x86/x86/svs.c Thu Feb 22 13:27:18 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: svs.c,v 1.7 2018/02/22 11:57:39 maxv Exp $ */ +/* $NetBSD: svs.c,v 1.8 2018/02/22 13:27:18 maxv Exp $ */ /* * Copyright (c) 2018 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: svs.c,v 1.7 2018/02/22 11:57:39 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: svs.c,v 1.8 2018/02/22 13:27:18 maxv Exp $"); #include "opt_svs.h" @@ -437,77 +437,6 @@ svs_pdir_switch(struct pmap *pmap) } static void -svs_pgg_scanlvl(bool enable, int lvl, vaddr_t *levels) -{ - pd_entry_t *pde = (pd_entry_t *)(levels[lvl-1]); - pt_entry_t set, rem; - size_t i, start; - paddr_t pa; - int nlvl; - - set = enable ? PG_G : 0; - rem = enable ? 0 : PG_G; - - start = (lvl == 4) ? 256 : 0; - - for (i = start; i < 512; i++) { - if (!pmap_valid_entry(pde[i])) { - continue; - } - if (lvl == 1) { - pde[i] = (pde[i] & ~rem) | set; - } else if (pde[i] & PG_PS) { - pde[i] = (pde[i] & ~rem) | set; - } else { - pa = (paddr_t)(pde[i] & PG_FRAME); - nlvl = lvl - 1; - - /* remove the previous mapping */ - pmap_kremove_local(levels[nlvl-1], PAGE_SIZE); - - /* kenter the lower level */ - pmap_kenter_pa(levels[nlvl-1], pa, - VM_PROT_READ|VM_PROT_WRITE, 0); - pmap_update(pmap_kernel()); - - /* go to the lower level */ - svs_pgg_scanlvl(enable, nlvl, levels); - } - } -} - -static void -svs_pgg_update(bool enable) -{ - const paddr_t pa = pmap_pdirpa(pmap_kernel(), 0); - vaddr_t levels[4]; - size_t i; - - if (!(cpu_feature[0] & CPUID_PGE)) { - return; - } - - pmap_pg_g = enable ? PG_G : 0; - - for (i = 0; i < 4; i++) { - levels[i] = uvm_km_alloc(kernel_map, PAGE_SIZE, 0, - UVM_KMF_VAONLY); - } - - pmap_kenter_pa(levels[3], pa, VM_PROT_READ|VM_PROT_WRITE, 0); - pmap_update(pmap_kernel()); - - svs_pgg_scanlvl(enable, 4, levels); - - for (i = 0; i < 4; i++) { - pmap_kremove_local(levels[i], PAGE_SIZE); - uvm_km_free(kernel_map, levels[i], PAGE_SIZE, UVM_KMF_VAONLY); - } - - tlbflushg(); -} - -static void svs_enable(void) { extern uint8_t svs_enter, svs_enter_end; @@ -604,6 +533,10 @@ svs_disable_cpu(void *arg1, void *arg2) /* 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(); @@ -641,16 +574,10 @@ svs_disable(void) svs_cpu_barrier1 = ncpu; svs_cpu_barrier2 = ncpu; - printf("[+] Disabling SVS\n"); + printf("[+] Disabling SVS..."); xc = xc_broadcast(0, svs_disable_cpu, NULL, NULL); xc_wait(xc); - - /* - * XXX printf("[+] Installing PG_G\n"); - * XXX svs_pgg_update(true); - */ - - printf("[+] Done\n"); + printf(" done!\n"); mutex_exit(&cpu_lock); @@ -687,19 +614,10 @@ sysctl_machdep_svs_enabled(SYSCTLFN_ARGS } void -svs_init(bool early) +svs_init(void) { - /* - * When early, declare that we want to use SVS, and hotpatch the - * entry points. When late, remove PG_G from the page tables. - */ - if (early) { - if (cpu_vendor != CPUVENDOR_INTEL) { - return; - } - svs_enable(); - } else if (svs_enabled) { - svs_pgg_update(false); + if (cpu_vendor != CPUVENDOR_INTEL) { + return; } + svs_enable(); } - Index: src/sys/arch/x86/x86/x86_machdep.c diff -u src/sys/arch/x86/x86/x86_machdep.c:1.106 src/sys/arch/x86/x86/x86_machdep.c:1.107 --- src/sys/arch/x86/x86/x86_machdep.c:1.106 Thu Feb 22 10:42:11 2018 +++ src/sys/arch/x86/x86/x86_machdep.c Thu Feb 22 13:27:18 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: x86_machdep.c,v 1.106 2018/02/22 10:42:11 maxv Exp $ */ +/* $NetBSD: x86_machdep.c,v 1.107 2018/02/22 13:27:18 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.106 2018/02/22 10:42:11 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: x86_machdep.c,v 1.107 2018/02/22 13:27:18 maxv Exp $"); #include "opt_modular.h" #include "opt_physmem.h" @@ -1091,9 +1091,6 @@ machdep_init(void) void x86_startup(void) { -#if SVS - svs_init(false); -#endif #if !defined(XEN) nmi_init(); pmc_init();