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