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();

Reply via email to