Module Name: src Committed By: maxv Date: Sat Feb 17 17:44:09 UTC 2018
Modified Files: src/sys/arch/x86/x86: pmap.c svs.c x86_machdep.c Log Message: Add svs_init. This is where we will detect the CPU and decide whether to turn SVS on or not. Add svs_pgg_update to dynamically add/remove PG_G from all the kernel pages. Use it now. To generate a diff of this commit: cvs rdiff -u -r1.279 -r1.280 src/sys/arch/x86/x86/pmap.c cvs rdiff -u -r1.1 -r1.2 src/sys/arch/x86/x86/svs.c cvs rdiff -u -r1.102 -r1.103 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/x86/x86/pmap.c diff -u src/sys/arch/x86/x86/pmap.c:1.279 src/sys/arch/x86/x86/pmap.c:1.280 --- src/sys/arch/x86/x86/pmap.c:1.279 Sat Jan 20 08:45:28 2018 +++ src/sys/arch/x86/x86/pmap.c Sat Feb 17 17:44:09 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.c,v 1.279 2018/01/20 08:45:28 maxv Exp $ */ +/* $NetBSD: pmap.c,v 1.280 2018/02/17 17:44:09 maxv Exp $ */ /* * Copyright (c) 2008, 2010, 2016, 2017 The NetBSD Foundation, Inc. @@ -170,7 +170,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.279 2018/01/20 08:45:28 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.280 2018/02/17 17:44:09 maxv Exp $"); #include "opt_user_ldt.h" #include "opt_lockdebug.h" @@ -559,7 +559,7 @@ static void pmap_init_pcpu(void); #ifdef __HAVE_DIRECT_MAP static void pmap_init_directmap(struct pmap *); #endif -#if !defined(XEN) && !defined(SVS) +#if !defined(XEN) static void pmap_remap_global(void); #endif #ifndef XEN @@ -1289,7 +1289,7 @@ pmap_bootstrap(vaddr_t kva_start) * operation of the system. */ -#if !defined(XEN) && !defined(SVS) +#if !defined(XEN) /* * Begin to enable global TLB entries if they are supported. * The G bit has no effect until the CR4_PGE bit is set in CR4, @@ -1655,7 +1655,7 @@ pmap_init_directmap(struct pmap *kpm) } #endif /* __HAVE_DIRECT_MAP */ -#if !defined(XEN) && !defined(SVS) +#if !defined(XEN) /* * Remap all of the virtual pages created so far with the PG_G bit. */ Index: src/sys/arch/x86/x86/svs.c diff -u src/sys/arch/x86/x86/svs.c:1.1 src/sys/arch/x86/x86/svs.c:1.2 --- src/sys/arch/x86/x86/svs.c:1.1 Sun Feb 11 09:39:37 2018 +++ src/sys/arch/x86/x86/svs.c Sat Feb 17 17:44:09 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: svs.c,v 1.1 2018/02/11 09:39:37 maxv Exp $ */ +/* $NetBSD: svs.c,v 1.2 2018/02/17 17:44:09 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.1 2018/02/11 09:39:37 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: svs.c,v 1.2 2018/02/17 17:44:09 maxv Exp $"); #include "opt_svs.h" @@ -39,6 +39,8 @@ __KERNEL_RCSID(0, "$NetBSD: svs.c,v 1.1 #include <sys/proc.h> #include <sys/cpu.h> +#include <machine/cpuvar.h> + #include <uvm/uvm.h> #include <uvm/uvm_page.h> @@ -424,3 +426,83 @@ svs_pdir_switch(struct pmap *pmap) mutex_exit(&ci->ci_svs_mtx); } + +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(); +} + +void svs_init(void); + +void +svs_init(void) +{ + svs_pgg_update(false); +} + Index: src/sys/arch/x86/x86/x86_machdep.c diff -u src/sys/arch/x86/x86/x86_machdep.c:1.102 src/sys/arch/x86/x86/x86_machdep.c:1.103 --- src/sys/arch/x86/x86/x86_machdep.c:1.102 Thu Nov 23 16:30:50 2017 +++ src/sys/arch/x86/x86/x86_machdep.c Sat Feb 17 17:44:09 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: x86_machdep.c,v 1.102 2017/11/23 16:30:50 kamil Exp $ */ +/* $NetBSD: x86_machdep.c,v 1.103 2018/02/17 17:44:09 maxv Exp $ */ /*- * Copyright (c) 2002, 2006, 2007 YAMAMOTO Takashi, @@ -31,12 +31,13 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: x86_machdep.c,v 1.102 2017/11/23 16:30:50 kamil Exp $"); +__KERNEL_RCSID(0, "$NetBSD: x86_machdep.c,v 1.103 2018/02/17 17:44:09 maxv Exp $"); #include "opt_modular.h" #include "opt_physmem.h" #include "opt_splash.h" #include "opt_kaslr.h" +#include "opt_svs.h" #include <sys/types.h> #include <sys/param.h> @@ -1090,6 +1091,10 @@ machdep_init(void) void x86_startup(void) { +#if SVS + void svs_init(void); + svs_init(); +#endif #if !defined(XEN) nmi_init(); pmc_init();