Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 7 Jan 2011 14:03:28 +0000 (UTC)
From:      Colin Percival <cperciva@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r217095 - stable/8/sys/i386/xen
Message-ID:  <201101071403.p07E3SQZ054518@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: cperciva
Date: Fri Jan  7 14:03:28 2011
New Revision: 217095
URL: http://svn.freebsd.org/changeset/base/217095

Log:
  MFC r216944,r216963,r216960: Improve the stability of the i386/XEN pmap
  code by correctly protecting page mapping queue variables within a
  critical section and by adding ham-fisted locking to pmap.c.

Modified:
  stable/8/sys/i386/xen/pmap.c
  stable/8/sys/i386/xen/xen_machdep.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)

Modified: stable/8/sys/i386/xen/pmap.c
==============================================================================
--- stable/8/sys/i386/xen/pmap.c	Fri Jan  7 12:16:17 2011	(r217094)
+++ stable/8/sys/i386/xen/pmap.c	Fri Jan  7 14:03:28 2011	(r217095)
@@ -202,6 +202,11 @@ __FBSDID("$FreeBSD$");
 
 #define pmap_pte_set_prot(pte, v) ((*(int *)pte &= ~PG_PROT), (*(int *)pte |= (v)))
 
+#define HAMFISTED_LOCKING
+#ifdef HAMFISTED_LOCKING
+static struct mtx createdelete_lock;
+#endif
+
 struct pmap kernel_pmap_store;
 LIST_HEAD(pmaplist, pmap);
 static struct pmaplist allpmaps;
@@ -502,6 +507,10 @@ pmap_bootstrap(vm_paddr_t firstaddr)
 	/* Turn on PG_G on kernel page(s) */
 	pmap_set_pg();
 #endif
+
+#ifdef HAMFISTED_LOCKING
+	mtx_init(&createdelete_lock, "pmap create/delete", NULL, MTX_DEF);
+#endif
 }
 
 /*
@@ -1510,6 +1519,10 @@ pmap_pinit(pmap_t pmap)
 	static int color;
 	int i;
 
+#ifdef HAMFISTED_LOCKING
+	mtx_lock(&createdelete_lock);
+#endif
+
 	PMAP_LOCK_INIT(pmap);
 
 	/*
@@ -1521,6 +1534,9 @@ pmap_pinit(pmap_t pmap)
 		    NBPTD);
 		if (pmap->pm_pdir == NULL) {
 			PMAP_LOCK_DESTROY(pmap);
+#ifdef HAMFISTED_LOCKING
+			mtx_unlock(&createdelete_lock);
+#endif
 			return (0);
 		}
 #if defined(XEN) && defined(PAE)	
@@ -1606,6 +1622,9 @@ pmap_pinit(pmap_t pmap)
 	TAILQ_INIT(&pmap->pm_pvchunk);
 	bzero(&pmap->pm_stats, sizeof pmap->pm_stats);
 
+#ifdef HAMFISTED_LOCKING
+	mtx_unlock(&createdelete_lock);
+#endif
 	return (1);
 }
 
@@ -1841,6 +1860,10 @@ pmap_release(pmap_t pmap)
 	    pmap->pm_stats.resident_count));
 	PT_UPDATES_FLUSH();
 
+#ifdef HAMFISTED_LOCKING
+	mtx_lock(&createdelete_lock);
+#endif
+
 	pmap_lazyfix(pmap);
 	mtx_lock_spin(&allpmaps_lock);
 	LIST_REMOVE(pmap, pm_list);
@@ -1876,6 +1899,10 @@ pmap_release(pmap_t pmap)
 	pmap_qremove((vm_offset_t)pmap->pm_pdpt, 1);
 #endif
 	PMAP_LOCK_DESTROY(pmap);
+
+#ifdef HAMFISTED_LOCKING
+	mtx_unlock(&createdelete_lock);
+#endif
 }
 
 static int
@@ -3242,6 +3269,10 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pm
 	CTR5(KTR_PMAP, "pmap_copy:  dst_pmap=%p src_pmap=%p dst_addr=0x%x len=%d src_addr=0x%x",
 	    dst_pmap, src_pmap, dst_addr, len, src_addr);
 	
+#ifdef HAMFISTED_LOCKING
+	mtx_lock(&createdelete_lock);
+#endif
+
 	vm_page_lock_queues();
 	if (dst_pmap < src_pmap) {
 		PMAP_LOCK(dst_pmap);
@@ -3331,6 +3362,10 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pm
 	vm_page_unlock_queues();
 	PMAP_UNLOCK(src_pmap);
 	PMAP_UNLOCK(dst_pmap);
+
+#ifdef HAMFISTED_LOCKING
+	mtx_unlock(&createdelete_lock);
+#endif
 }	
 
 static __inline void

Modified: stable/8/sys/i386/xen/xen_machdep.c
==============================================================================
--- stable/8/sys/i386/xen/xen_machdep.c	Fri Jan  7 12:16:17 2011	(r217094)
+++ stable/8/sys/i386/xen/xen_machdep.c	Fri Jan  7 14:03:28 2011	(r217095)
@@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/malloc.h>
 #include <sys/mutex.h>
 #include <sys/kernel.h>
+#include <sys/proc.h>
 #include <sys/reboot.h>
 #include <sys/sysproto.h>
 
@@ -249,10 +250,12 @@ _xen_flush_queue(void)
 	SET_VCPU();
 	int _xpq_idx = XPQ_IDX;
 	int error, i;
-	/* window of vulnerability here? */
 
+#ifdef INVARIANTS
 	if (__predict_true(gdtset))
-		critical_enter();
+		CRITICAL_ASSERT(curthread);
+#endif
+
 	XPQ_IDX = 0;
 	/* Make sure index is cleared first to avoid double updates. */
 	error = HYPERVISOR_mmu_update((mmu_update_t *)&XPQ_QUEUE,
@@ -286,8 +289,6 @@ _xen_flush_queue(void)
 		}
 	}
 #endif	
-	if (__predict_true(gdtset))
-		critical_exit();
 	if (__predict_false(error < 0)) {
 		for (i = 0; i < _xpq_idx; i++)
 			printf("val: %llx ptr: %llx\n",
@@ -301,7 +302,12 @@ void
 xen_flush_queue(void)
 {
 	SET_VCPU();
+
+	if (__predict_true(gdtset))
+		critical_enter();
 	if (XPQ_IDX != 0) _xen_flush_queue();
+	if (__predict_true(gdtset))
+		critical_exit();
 }
 
 static __inline void



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201101071403.p07E3SQZ054518>