socsvn commit: r269167 - soc2014/mihai/bhyve-icache-head/sys/amd64/vmm

mihai at FreeBSD.org mihai at FreeBSD.org
Fri Jun 6 09:24:00 UTC 2014


Author: mihai
Date: Fri Jun  6 09:23:59 2014
New Revision: 269167
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=269167

Log:
  sys: amd64: vmm: vmm_instruction_cache.c: change locking type to sx locks

Modified:
  soc2014/mihai/bhyve-icache-head/sys/amd64/vmm/vmm.c
  soc2014/mihai/bhyve-icache-head/sys/amd64/vmm/vmm_instruction_cache.c

Modified: soc2014/mihai/bhyve-icache-head/sys/amd64/vmm/vmm.c
==============================================================================
--- soc2014/mihai/bhyve-icache-head/sys/amd64/vmm/vmm.c	Fri Jun  6 08:42:03 2014	(r269166)
+++ soc2014/mihai/bhyve-icache-head/sys/amd64/vmm/vmm.c	Fri Jun  6 09:23:59 2014	(r269167)
@@ -1108,6 +1108,12 @@
 	    ftype == VM_PROT_WRITE || ftype == VM_PROT_EXECUTE,
 	    ("vm_handle_paging: invalid fault_type %d", ftype));
 
+	if (ftype == VM_PROT_WRITE) {
+		/* Remove all the instructions that resides in this page */
+		vm_inst_cache_delete(vm, vme->u.paging.gpa, vme->u.paging.cr3);
+	}
+
+
 	if (ftype == VM_PROT_READ || ftype == VM_PROT_WRITE) {
 		rv = pmap_emulate_accessed_dirty(vmspace_pmap(vm->vmspace),
 		    vme->u.paging.gpa, ftype);
@@ -1115,11 +1121,6 @@
 			goto done;
 	}
 
-	if (ftype == VM_PROT_WRITE) {
-		/* Remove all the instructions that resides in this page */
-		vm_inst_cache_delete(vm, vme->u.paging.gla, vme->u.paging.cr3);
-	}
-
 	map = &vm->vmspace->vm_map;
 	rv = vm_fault(map, vme->u.paging.gpa, ftype, VM_FAULT_NORMAL);
 

Modified: soc2014/mihai/bhyve-icache-head/sys/amd64/vmm/vmm_instruction_cache.c
==============================================================================
--- soc2014/mihai/bhyve-icache-head/sys/amd64/vmm/vmm_instruction_cache.c	Fri Jun  6 08:42:03 2014	(r269166)
+++ soc2014/mihai/bhyve-icache-head/sys/amd64/vmm/vmm_instruction_cache.c	Fri Jun  6 09:23:59 2014	(r269167)
@@ -34,14 +34,14 @@
 #include <sys/kernel.h>
 #include <sys/sysctl.h>
 #include <sys/lock.h>
-#include <sys/rmlock.h>
+#include <sys/sx.h>
 #include <sys/queue.h>
 #include <sys/hash.h>
 
 #include <vm/vm.h>
 #include <vm/pmap.h>
 #include <vm/vm_map.h>
-
+#include <vm/vm_param.h>
 #include <machine/vmparam.h>
 #include <machine/vmm.h>
 #include <machine/vmm_instruction_cache.h>
@@ -76,7 +76,7 @@
 
 struct vie_cached_hash {
 	struct vie_cached_head vie_cached_head;
-	struct rmlock vie_cached_lock;
+	struct sx vie_cached_lock;
 };
 
 static struct vie_cached_hash vie_cached_hash[VIE_CACHE_HASH_SIZE];
@@ -92,26 +92,40 @@
 
 	for (i = 0; i < VIE_CACHE_HASH_SIZE; i++) {
 		LIST_INIT(&vie_cached_hash[i].vie_cached_head);
-		rm_init(&vie_cached_hash[i].vie_cached_lock,
+		sx_init(&vie_cached_hash[i].vie_cached_lock,
 		    "VIE CACHED HASH LOCK");
 	}
 	return (0);
 }
+/* Clean-up a hash entry */
+static void
+vmm_inst_cache_cleanup_helper(int hash)
+{
+	struct vie_cached *vie_cached, *vie_cached_safe;
+	int i;
+
+	LIST_FOREACH_SAFE(vie_cached, &vie_cached_hash[hash].vie_cached_head,
+	    vie_link, vie_cached_safe)
+	{
+		for (i = 0; i < vie_cached->pages_count; i++)
+			vm_map_protect(&(vm_get_vmspace(vie_cached->vm)->vm_map),
+			    vie_cached->pages[i],
+			    vie_cached->pages[i] + vie_cached->pages_mask[i] + 1,
+			    VM_PROT_ALL, 0);
+
+		LIST_REMOVE(vie_cached, vie_link);
+		free(vie_cached, M_VIECACHED);
+	}
+}
 
 int
 vmm_inst_cache_cleanup(void)
 {
-	struct vie_cached *vie_cached, *vie_cached_safe;
 	int i;
 
 	for (i = 0; i < VIE_CACHE_HASH_SIZE; i++) {
-		LIST_FOREACH_SAFE(vie_cached, &vie_cached_hash[i].vie_cached_head,
-		    vie_link, vie_cached_safe)
-		{
-			LIST_REMOVE(vie_cached, vie_link);
-			free(vie_cached, M_VIECACHED);
-		}
-		rm_destroy(&vie_cached_hash[i].vie_cached_lock);
+		vmm_inst_cache_cleanup_helper(i);
+		sx_destroy(&vie_cached_hash[i].vie_cached_lock);
 	}
 	return (0);
 }
@@ -119,7 +133,6 @@
 static int
 sysctl_vmm_cached_instruction(SYSCTL_HANDLER_ARGS)
 {
-	struct vie_cached *vie_cached, *vie_cached_safe;
 	int error, temp, i;
 
 	temp = vmm_cached_instruction_enable;
@@ -134,14 +147,9 @@
 			vmm_cached_instruction_enable = temp;
 			if (temp == 0) {
 				for (i = 0; i < VIE_CACHE_HASH_SIZE; i++) {
-					rm_wlock(&vie_cached_hash[i].vie_cached_lock);
-					LIST_FOREACH_SAFE(vie_cached, &vie_cached_hash[i].vie_cached_head,
-					    vie_link, vie_cached_safe)
-					{
-						LIST_REMOVE(vie_cached, vie_link);
-						free(vie_cached, M_VIECACHED);
-					}
-					rm_wunlock(&vie_cached_hash[i].vie_cached_lock);
+					sx_xlock(&vie_cached_hash[i].vie_cached_lock);
+					vmm_inst_cache_cleanup_helper(i);
+					sx_xunlock(&vie_cached_hash[i].vie_cached_lock);
 				}
 			}
 		}
@@ -158,7 +166,7 @@
 {
 	int nlevels, ptpshift, ptpindex;
 	uint64_t *ptpbase, pte, pgsize;
-	uint32_t *ptpbase32, pte32, i;
+	uint32_t *ptpbase32, pte32;
 	void *cookie;
 	uint64_t gla;
 
@@ -209,7 +217,7 @@
 		vie_cached->pages_mask[vie_cached->pages_count] = (1 << ptpshift) - 1;
 		vie_cached->pages[vie_cached->pages_count++] = pte32;
 
-		goto protect;
+		return (0);
 	}
 
 	if (paging_mode == PAGING_MODE_PAE) {
@@ -279,16 +287,7 @@
 	vie_cached->pages_mask[vie_cached->pages_count] = (1 << ptpshift) - 1;
 	vie_cached->pages[vie_cached->pages_count++] = pte;
 
-protect:
-	i=0;
-	for (i = 0; i < vie_cached->pages_count; i++) {
-//		printf("vm_map_protect %d, %lx -> %lx\n",i, vie_cached->pages[i], vie_cached->pages_mask[i]);
-		vm_map_protect(&(vm_get_vmspace(vm)->vm_map), vie_cached->pages[i],
-		    vie_cached->pages[i] + vie_cached->pages_mask[i] + 1,
-		    VM_PROT_READ | VM_PROT_EXECUTE, 0);
-	}
 	return (0);
-
 error:
 	return (-1);
 }
@@ -298,7 +297,7 @@
 		    struct vie *vie)
 {
 	struct vie_cached *vie_cached;
-	int hash;
+	int hash, i;
 
 	/* Check to see if caching is enabled */
 	if (!vmm_cached_instruction_enable)
@@ -318,9 +317,16 @@
 
 	hash = jenkins_hash(&vm, sizeof(struct vm *), 0) & VIE_CACHE_HASH_MASK;
 
-	rm_wlock(&vie_cached_hash[hash].vie_cached_lock);
+	sx_xlock(&vie_cached_hash[hash].vie_cached_lock);
+
 	LIST_INSERT_HEAD(&vie_cached_hash[hash].vie_cached_head, vie_cached, vie_link);
-	rm_wunlock(&vie_cached_hash[hash].vie_cached_lock);
+
+	for (i = 0; i < vie_cached->pages_count; i++)
+		vm_map_protect(&(vm_get_vmspace(vm)->vm_map), vie_cached->pages[i],
+		    vie_cached->pages[i] + vie_cached->pages_mask[i] + 1,
+		    VM_PROT_READ | VM_PROT_EXECUTE, 0);
+
+	sx_xunlock(&vie_cached_hash[hash].vie_cached_lock);
 
 	return (0);
 }
@@ -330,7 +336,6 @@
 		    struct vie *vie)
 {
 	struct vie_cached *vie_cached;
-	struct rm_priotracker tracker;
 	int hash;
 
 	/* Check to see if caching is enabled */
@@ -339,7 +344,7 @@
 
 	hash = jenkins_hash(&vm, sizeof(struct vm *), 0) & VIE_CACHE_HASH_MASK;
 
-	rm_rlock(&vie_cached_hash[hash].vie_cached_lock, &tracker);
+	sx_slock(&vie_cached_hash[hash].vie_cached_lock);
 
 	LIST_FOREACH(vie_cached, &vie_cached_hash[hash].vie_cached_head, vie_link) {
 		if (vie_cached->vm == vm &&
@@ -347,20 +352,20 @@
 		    vie_cached->cr3 == cr3)
 		{
 			bcopy(&vie_cached->vie, vie, sizeof(struct vie));
-			rm_runlock(&vie_cached_hash[hash].vie_cached_lock, &tracker);
+			sx_sunlock(&vie_cached_hash[hash].vie_cached_lock);
 			return(0);
 		}
 	}
-	rm_runlock(&vie_cached_hash[hash].vie_cached_lock, &tracker);
+	sx_sunlock(&vie_cached_hash[hash].vie_cached_lock);
 	return (-1);
 }
 
 int
 vm_inst_cache_delete(struct vm *vm, uint64_t fault_address, uint64_t cr3)
 {
-	struct vie_cached *vie_cached;
+	struct vie_cached *vie_cached, *vie_cached_safe;
 	int hash, i;
-
+	uint64_t page_addr, page_size;
 	/* Check to see if caching is enabled */
 	if (!vmm_cached_instruction_enable)
 		return (0);
@@ -368,9 +373,14 @@
 
 	hash = jenkins_hash(&vm, sizeof(struct vm *), 0) & VIE_CACHE_HASH_MASK;
 
-	rm_wlock(&vie_cached_hash[hash].vie_cached_lock);
+	page_addr = fault_address & ~PAGE_MASK;
+	page_size = PAGE_SIZE;
 
-	LIST_FOREACH(vie_cached, &vie_cached_hash[hash].vie_cached_head, vie_link) {
+	sx_xlock(&vie_cached_hash[hash].vie_cached_lock);
+
+	LIST_FOREACH_SAFE(vie_cached, &vie_cached_hash[hash].vie_cached_head,
+		    vie_link, vie_cached_safe)
+	{
 		if (vie_cached->vm == vm &&
 		    vie_cached->cr3 == cr3)
 		{
@@ -381,6 +391,10 @@
 				{
 					/* Remove the RIP found and continue searching */
 					LIST_REMOVE(vie_cached, vie_link);
+
+					page_addr = vie_cached->pages[i];
+					page_size =  vie_cached->pages_mask[i] + 1;
+
 					/* Free the removed node */
 					free(vie_cached, M_VIECACHED);
 					break;
@@ -389,7 +403,10 @@
 		}
 	}
 
-	rm_wunlock(&vie_cached_hash[hash].vie_cached_lock);
+	vm_map_protect(&(vm_get_vmspace(vm)->vm_map), page_addr,
+	    page_addr + page_size, VM_PROT_ALL, 0);
+
+	sx_xunlock(&vie_cached_hash[hash].vie_cached_lock);
 
 	return (0);
 }


More information about the svn-soc-all mailing list