svn commit: r337773 - in head/sys/amd64: amd64 include

Konstantin Belousov kib at FreeBSD.org
Tue Aug 14 16:37:16 UTC 2018


Author: kib
Date: Tue Aug 14 16:37:14 2018
New Revision: 337773
URL: https://svnweb.freebsd.org/changeset/base/337773

Log:
  amd64: ensure that curproc->p_vmspace pmap always matches PCPU
  curpmap.
  
  When performing context switch on a machine without PCID, if current
  %cr3 equals to the new pmap %cr3, which is typical for kernel_pmap
  vs. kernel process, I overlooked to update PCPU curpmap value.  Remove
  check for %cr3 not equal to pm_cr3 for doing the update.  It is
  believed that this case cannot happen at all, due to other changes in
  this revision.
  
  Also, do not set the very first curpmap to kernel_pmap, it should be
  vmspace0 pmap instead to match curproc.
  
  Move the common code to activate the initial pmap both on BSP and APs
  into pmap_activate_boot() helper.
  
  Reported by: eadler, ambrisko
  Discussed with: kevans
  Reviewed by:	alc, markj (previous version)
  Tested by: ambrisko (previous version)
  Sponsored by:	The FreeBSD Foundation
  MFC after:	1 week
  Differential revision:	https://reviews.freebsd.org/D16618

Modified:
  head/sys/amd64/amd64/mp_machdep.c
  head/sys/amd64/amd64/pmap.c
  head/sys/amd64/include/pmap.h

Modified: head/sys/amd64/amd64/mp_machdep.c
==============================================================================
--- head/sys/amd64/amd64/mp_machdep.c	Tue Aug 14 16:33:30 2018	(r337772)
+++ head/sys/amd64/amd64/mp_machdep.c	Tue Aug 14 16:37:14 2018	(r337773)
@@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$");
 #include <vm/vm_param.h>
 #include <vm/pmap.h>
 #include <vm/vm_kern.h>
+#include <vm/vm_map.h>
 #include <vm/vm_extern.h>
 
 #include <x86/apicreg.h>
@@ -297,7 +298,6 @@ init_secondary(void)
 	pc->pc_gs32p = &gdt[NGDT * cpu + GUGS32_SEL];
 	pc->pc_ldt = (struct system_segment_descriptor *)&gdt[NGDT * cpu +
 	    GUSERLDT_SEL];
-	pc->pc_curpmap = kernel_pmap;
 	pc->pc_pcid_gen = 1;
 	pc->pc_pcid_next = PMAP_PCID_KERN + 1;
 	common_tss[cpu].tss_rsp0 = 0;
@@ -342,6 +342,7 @@ init_secondary(void)
 	while (atomic_load_acq_int(&aps_ready) == 0)
 		ia32_pause();
 
+	pmap_activate_boot(vmspace_pmap(proc0.p_vmspace));
 	init_secondary_tail();
 }
 

Modified: head/sys/amd64/amd64/pmap.c
==============================================================================
--- head/sys/amd64/amd64/pmap.c	Tue Aug 14 16:33:30 2018	(r337772)
+++ head/sys/amd64/amd64/pmap.c	Tue Aug 14 16:37:14 2018	(r337773)
@@ -2655,9 +2655,7 @@ pmap_pinit0(pmap_t pmap)
 			__pcpu[i].pc_ucr3 = PMAP_NO_CR3;
 		}
 	}
-	PCPU_SET(curpmap, kernel_pmap);
-	pmap_activate(curthread);
-	CPU_FILL(&kernel_pmap->pm_active);
+	pmap_activate_boot(pmap);
 }
 
 void
@@ -7529,7 +7527,7 @@ pmap_activate_sw(struct thread *td)
 			intr_restore(rflags);
 		if (cached)
 			PCPU_INC(pm_save_cnt);
-	} else if (cr3 != pmap->pm_cr3) {
+	} else {
 		load_cr3(pmap->pm_cr3);
 		PCPU_SET(curpmap, pmap);
 		if (pti) {
@@ -7557,6 +7555,26 @@ pmap_activate(struct thread *td)
 	critical_enter();
 	pmap_activate_sw(td);
 	critical_exit();
+}
+
+void
+pmap_activate_boot(pmap_t pmap)
+{
+	u_int cpuid;
+
+	/*
+	 * kernel_pmap must be never deactivated, and we ensure that
+	 * by never activating it at all.
+	 */
+	MPASS(pmap != kernel_pmap);
+
+	cpuid = PCPU_GET(cpuid);
+#ifdef SMP
+	CPU_SET_ATOMIC(cpuid, &pmap->pm_active);
+#else
+	CPU_SET(cpuid, &pmap->pm_active);
+#endif
+	PCPU_SET(curpmap, pmap);
 }
 
 void

Modified: head/sys/amd64/include/pmap.h
==============================================================================
--- head/sys/amd64/include/pmap.h	Tue Aug 14 16:33:30 2018	(r337772)
+++ head/sys/amd64/include/pmap.h	Tue Aug 14 16:37:14 2018	(r337773)
@@ -407,6 +407,7 @@ extern int invpcid_works;
 
 struct thread;
 
+void	pmap_activate_boot(pmap_t pmap);
 void	pmap_activate_sw(struct thread *);
 void	pmap_bootstrap(vm_paddr_t *);
 int	pmap_cache_bits(pmap_t pmap, int mode, boolean_t is_pde);


More information about the svn-src-all mailing list