PERFORCE change 136140 for review

Kip Macy kmacy at FreeBSD.org
Mon Feb 25 04:12:53 UTC 2008


http://perforce.freebsd.org/chv.cgi?CH=136140

Change 136140 by kmacy at pandemonium:kmacy:xen31 on 2008/02/25 04:11:51

	ensure that access to xpq_queue is serialized
	add logging for queued updates

Affected files ...

.. //depot/projects/xen31/sys/i386/include/xen/xenfunc.h#2 edit
.. //depot/projects/xen31/sys/i386/include/xen/xenpmap.h#10 edit
.. //depot/projects/xen31/sys/i386/xen/xen_machdep.c#18 edit

Differences ...

==== //depot/projects/xen31/sys/i386/include/xen/xenfunc.h#2 (text+ko) ====

@@ -55,7 +55,13 @@
 
 int  xen_boothowto(char *envp);
 
-void xen_machphys_update(unsigned long, unsigned long);
+void _xen_machphys_update(unsigned long, unsigned long, char *file, int line);
+
+#ifdef INVARIANTS
+#define xen_machphys_update(a, b) _xen_machphys_update((a), (b), __FILE__, __LINE__)
+#else
+#define xen_machphys_update(a, b) _xen_machphys_update((a), (b), NULL, 0)
+#endif	
 
 void xen_update_descriptor(union descriptor *, union descriptor *);
 

==== //depot/projects/xen31/sys/i386/include/xen/xenpmap.h#10 (text+ko) ====

@@ -35,7 +35,7 @@
 #define _XEN_XENPMAP_H_
 void xen_invlpg(vm_offset_t);
 void xen_load_cr3(vm_paddr_t);
-void xen_queue_pt_update(vm_paddr_t, vm_paddr_t);
+void _xen_queue_pt_update(vm_paddr_t, vm_paddr_t, char *, int);
 void xen_pt_switch(vm_paddr_t);
 void xen_set_ldt(vm_paddr_t, unsigned long);
 void xen_tlb_flush(void);
@@ -47,6 +47,13 @@
 void xen_flush_queue(void);
 void pmap_ref(pt_entry_t *pte, vm_paddr_t ma);
 
+#ifdef INVARIANTS
+#define xen_queue_pt_update(a, b) _xen_queue_pt_update((a), (b), __FILE__, __LINE__)
+#else
+#define xen_queue_pt_update(a, b) _xen_queue_pt_update((a), (b), NULL, 0)
+#endif	
+
+
 #include <sys/param.h>
 #include <sys/pcpu.h>
 
@@ -62,9 +69,6 @@
 #define PMAP_DEC_REF_PAGE(a)
 #endif
 
-#if 0
-#define WRITABLE_PAGETABLES
-#endif
 #define ALWAYS_SYNC 0
 
 #ifdef PT_DEBUG

==== //depot/projects/xen31/sys/i386/xen/xen_machdep.c#18 (text+ko) ====

@@ -84,6 +84,7 @@
 xen_pfn_t *xen_phys_machine;
 int preemptable, init_first;
 extern unsigned int avail_space;
+extern int gdt_set;
 
 void ni_cli(void);
 void ni_sti(void);
@@ -190,7 +191,13 @@
 #define XPQ_IDX xpq_idx[vcpu]
 #define SET_VCPU() int vcpu = smp_processor_id()
 #else
+struct mmu_log {
+	char *file;
+	int line;
+};
+	
 static mmu_update_t xpq_queue[XPQUEUE_SIZE];
+static struct mmu_log xpq_queue_log[XPQUEUE_SIZE];
 static int xpq_idx = 0;
 
 #define XPQ_QUEUE xpq_queue
@@ -225,11 +232,36 @@
 	int error, i;
 	/* window of vulnerability here? */
 
+	if (__predict_true(gdt_set))
+		critical_enter();
 	XPQ_IDX = 0;
 	/* Make sure index is cleared first to avoid double updates. */
 	error = HYPERVISOR_mmu_update((mmu_update_t *)&XPQ_QUEUE,
 				      _xpq_idx, NULL, DOMID_SELF);
     
+#if 0
+	if (__predict_true(gdt_set))
+	for (i = _xpq_idx; i > 0;) {
+		if (i >= 3) {
+			CTR6(KTR_PMAP, "mmu:val: %lx ptr: %lx val: %lx ptr: %lx val: %lx ptr: %lx",
+			    (XPQ_QUEUE[i-1].val & 0xffffffff), (XPQ_QUEUE[i-1].ptr & 0xffffffff),
+			    (XPQ_QUEUE[i-2].val & 0xffffffff), (XPQ_QUEUE[i-2].ptr & 0xffffffff),
+			    (XPQ_QUEUE[i-3].val & 0xffffffff), (XPQ_QUEUE[i-3].ptr & 0xffffffff));
+			    i -= 3;
+		} else if (i == 2) {
+			CTR4(KTR_PMAP, "mmu: val: %lx ptr: %lx val: %lx ptr: %lx",
+			    (XPQ_QUEUE[i-1].val & 0xffffffff), (XPQ_QUEUE[i-1].ptr & 0xffffffff),
+			    (XPQ_QUEUE[i-2].val & 0xffffffff), (XPQ_QUEUE[i-2].ptr & 0xffffffff));
+			i = 0;
+		} else {
+			CTR2(KTR_PMAP, "mmu: val: %lx ptr: %lx", 
+			    (XPQ_QUEUE[i-1].val & 0xffffffff), (XPQ_QUEUE[i-1].ptr & 0xffffffff));
+			i = 0;
+		}
+	}
+#endif	
+	if (__predict_true(gdt_set))
+		critical_exit();
 	if (__predict_false(error < 0)) {
 		for (i = 0; i < _xpq_idx; i++)
 			printf("val: %llx ptr: %llx\n", XPQ_QUEUE[i].val, XPQ_QUEUE[i].ptr);
@@ -268,31 +300,50 @@
 xen_load_cr3(vm_paddr_t val)
 {
 	struct mmuext_op op;
+
+	KASSERT(XPQ_IDX == 0, ("pending operations XPQ_IDX=%d", XPQ_IDX));
 	op.cmd = MMUEXT_NEW_BASEPTR;
 	op.arg1.mfn = xpmap_ptom(val) >> PAGE_SHIFT;
-	xen_flush_queue();
 	PANIC_IF(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
 }
 
 void
-xen_machphys_update(unsigned long mfn, unsigned long pfn)
+_xen_machphys_update(unsigned long mfn, unsigned long pfn, char *file, int line)
 {
+
+	if (__predict_true(gdt_set))
+		critical_enter();
 	SET_VCPU();
-    
 	XPQ_QUEUE[XPQ_IDX].ptr = (mfn << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE;
 	XPQ_QUEUE[XPQ_IDX].val = pfn;
+#ifdef INVARIANTS
+	xpq_queue_log[XPQ_IDX].file = file;
+	xpq_queue_log[XPQ_IDX].line = line;	
+#endif		
 	xen_increment_idx();
-	_xen_flush_queue();
+	if (__predict_true(gdt_set))
+		critical_exit();
 }
 
 void
-xen_queue_pt_update(vm_paddr_t ptr, vm_paddr_t val)
+_xen_queue_pt_update(vm_paddr_t ptr, vm_paddr_t val, char *file, int line)
 {
+
+	if (__predict_true(gdt_set))	
+		mtx_assert(&vm_page_queue_mtx, MA_OWNED);
+
+	if (__predict_true(gdt_set))
+		critical_enter();
 	SET_VCPU();
-    
 	XPQ_QUEUE[XPQ_IDX].ptr = ((uint64_t)ptr) | MMU_NORMAL_PT_UPDATE;
 	XPQ_QUEUE[XPQ_IDX].val = (uint64_t)val;
+#ifdef INVARIANTS
+	xpq_queue_log[XPQ_IDX].file = file;
+	xpq_queue_log[XPQ_IDX].line = line;	
+#endif	
 	xen_increment_idx();
+	if (__predict_true(gdt_set))
+		critical_exit();
 }
 
 void 
@@ -800,7 +851,8 @@
 	for (i = 0; i < 4; i++) 
 		IdlePTDnewma[i] =  xpmap_ptom(
 			VTOP((uint8_t *)IdlePTDnew + i*PAGE_SIZE));
-	
+
+
 	/*
 	 * L3
 	 */
@@ -818,6 +870,7 @@
 	for (i = 0; i < 4; i++)
 		pdir_shadow[PTDPTDI + i] = IdlePTDnewma[i] | PG_V;
 
+	
 	PT_SET_MA(IdlePDPTnew, IdlePDPTnewma | PG_V);
 	xen_pt_unpin(IdlePDPTma);
 #endif  
@@ -843,10 +896,12 @@
 	offset = KPTDI;
 #endif	
 	/* allocate remainder of NKPT pages */
-	for (i = l1_pages; i < NKPT; i++, cur_space += PAGE_SIZE) 
+	for (i = l1_pages; i < NKPT; i++, cur_space += PAGE_SIZE) {
+		xen_pt_pin(xpmap_ptom(VTOP(cur_space)));
 		xen_queue_pt_update((vm_paddr_t)(IdlePTDma + (offset + i)*sizeof(vm_paddr_t)), 
-				    xpmap_ptom(VTOP(cur_space)) | PG_KERNEL);
-
+		    xpmap_ptom(VTOP(cur_space)) | PG_KERNEL);
+	}
+	
 	PT_UPDATES_FLUSH();
 	/*
 	 * L1 - can't copy Xen's mappings
@@ -861,9 +916,15 @@
 		PT_SET_MA((uint8_t *)pdir_shadow + i*PAGE_SIZE,
 		    pdir_shadow_ma[i] | PG_V);
 	}
+
+	xen_load_cr3(VTOP(IdlePDPTnew));
+	xen_pgdpt_pin(xpmap_ptom(VTOP(IdlePDPTnew)));
+	for (i = 0; i < 4; i++) {
+		xen_queue_pt_update((vm_paddr_t)(IdlePTDnewma[2] + (PTDPTDI - 1024 + i)*sizeof(vm_paddr_t)), 
+		    IdlePTDnewma[i] | PG_V);
+	}
+	PT_UPDATES_FLUSH();
 	
-	xen_load_cr3(VTOP(IdlePDPTnew));
-
 	IdlePTD = IdlePTDnew;
 	IdlePDPT = IdlePDPTnew;
 	IdlePDPTma = IdlePDPTnewma;


More information about the p4-projects mailing list