svn commit: r306351 - head/sys/amd64/amd64

Konstantin Belousov kib at FreeBSD.org
Mon Sep 26 17:25:27 UTC 2016


Author: kib
Date: Mon Sep 26 17:25:25 2016
New Revision: 306351
URL: https://svnweb.freebsd.org/changeset/base/306351

Log:
  Handle TLB shootdown IPI during the EFI runtime calls, on SandyBridge
  and IvyBridge machines, which support PCID but do not have INVPCID
  instruction.
  
  MFC after:	1 week

Modified:
  head/sys/amd64/amd64/efirt.c

Modified: head/sys/amd64/amd64/efirt.c
==============================================================================
--- head/sys/amd64/amd64/efirt.c	Mon Sep 26 17:22:44 2016	(r306350)
+++ head/sys/amd64/amd64/efirt.c	Mon Sep 26 17:25:25 2016	(r306351)
@@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$");
 #include <machine/vmparam.h>
 #include <vm/vm.h>
 #include <vm/pmap.h>
+#include <vm/vm_map.h>
 #include <vm/vm_object.h>
 #include <vm/vm_page.h>
 #include <vm/vm_pager.h>
@@ -301,6 +302,17 @@ efi_enter(void)
 		PMAP_UNLOCK(curpmap);
 		return (error);
 	}
+
+	/*
+	 * IPI TLB shootdown handler invltlb_pcid_handler() reloads
+	 * %cr3 from the curpmap->pm_cr3, which would disable runtime
+	 * segments mappings.  Block the handler's action by setting
+	 * curpmap to impossible value.  See also comment in
+	 * pmap.c:pmap_activate_sw().
+	 */
+	if (pmap_pcid_enabled && !invpcid_works)
+		PCPU_SET(curpmap, NULL);
+
 	load_cr3(VM_PAGE_TO_PHYS(efi_pml4_page) | (pmap_pcid_enabled ?
 	    curpmap->pm_pcids[PCPU_GET(cpuid)].pm_pcid : 0));
 	/*
@@ -317,7 +329,9 @@ efi_leave(void)
 {
 	pmap_t curpmap;
 
-	curpmap = PCPU_GET(curpmap);
+	curpmap = &curproc->p_vmspace->vm_pmap;
+	if (pmap_pcid_enabled && !invpcid_works)
+		PCPU_SET(curpmap, curpmap);
 	load_cr3(curpmap->pm_cr3 | (pmap_pcid_enabled ?
 	    curpmap->pm_pcids[PCPU_GET(cpuid)].pm_pcid : 0));
 	if (!pmap_pcid_enabled)


More information about the svn-src-head mailing list