PERFORCE change 133450 for review
Kip Macy
kmacy at FreeBSD.org
Wed Jan 16 20:15:11 PST 2008
http://perforce.freebsd.org/chv.cgi?CH=133450
Change 133450 by kmacy at pandemonium:kmacy:xen31 on 2008/01/17 04:14:24
This change works around an apparent flakiness in page table updating
hypercalls by switching to "writable" page tables.
This appears to introduce a new bug (albeit a much more deterministic one)
in which the wire count on a page table isn't appropriately set. This causes
the page table to be prematurely freed losing any information about the pages
still being mapped leaving the pv list on the md page corrupt.
Affected files ...
.. //depot/projects/xen31/sys/i386/i386/vm_machdep.c#6 edit
.. //depot/projects/xen31/sys/i386/include/pmap.h#10 edit
.. //depot/projects/xen31/sys/i386/xen/pmap.c#16 edit
.. //depot/projects/xen31/sys/i386/xen/xen_machdep.c#15 edit
Differences ...
==== //depot/projects/xen31/sys/i386/i386/vm_machdep.c#6 (text+ko) ====
@@ -779,7 +779,7 @@
ptep = vtopte(sf->kva);
opte = *ptep;
#ifdef XEN
- PT_SET_MA(sf->kva, xpmap_ptom(VM_PAGE_TO_PHYS(m)) | pgeflag | PG_RW | PG_V);
+ *ptep = xpmap_ptom(VM_PAGE_TO_PHYS(m)) | pgeflag | PG_RW | PG_V;
#else
*ptep = VM_PAGE_TO_PHYS(m) | pgeflag | PG_RW | PG_V;
#endif
==== //depot/projects/xen31/sys/i386/include/pmap.h#10 (text+ko) ====
@@ -232,32 +232,58 @@
void pmap_map_readonly(struct pmap *pmap, vm_offset_t va, int len);
void pmap_map_readwrite(struct pmap *pmap, vm_offset_t va, int len);
+
+static __inline pt_entry_t
+pte_load_store(pt_entry_t *ptep, pt_entry_t v)
+{
+ pt_entry_t r;
+
+ v = xpmap_ptom(v);
+ r = *ptep;
+ __asm __volatile(
+ "1:\n"
+ "\tlock; cmpxchg8b %1\n"
+ "\tjnz 1b"
+ : "+A" (r)
+ : "m" (*ptep), "b" ((uint32_t)v), "c" ((uint32_t)(v >> 32)));
+ return (r);
+}
+
static __inline pt_entry_t
-pte_load_clear(pt_entry_t *ptep)
+pte_load_store_ma(pt_entry_t *ptep, pt_entry_t v)
{
pt_entry_t r;
- r = PT_GET(ptep);
- PT_CLEAR_VA(ptep, TRUE);
+ r = *ptep;
+ __asm __volatile(
+ "1:\n"
+ "\tlock; cmpxchg8b %1\n"
+ "\tjnz 1b"
+ : "+A" (r)
+ : "m" (*ptep), "b" ((uint32_t)v), "c" ((uint32_t)(v >> 32)));
return (r);
}
+
+
+#else
+
+
static __inline pt_entry_t
pte_load_store(pt_entry_t *ptep, pt_entry_t v)
{
pt_entry_t r;
- r = PT_GET(ptep);
- PT_SET_VA(ptep, v, TRUE);
+
+ r = *ptep;
+ __asm __volatile(
+ "1:\n"
+ "\tlock; cmpxchg8b %1\n"
+ "\tjnz 1b"
+ : "+A" (r)
+ : "m" (*ptep), "b" ((uint32_t)v), "c" ((uint32_t)(v >> 32)));
return (r);
}
-#define pte_store(ptep, pte) pte_load_store((ptep), (pt_entry_t)pte)
-#define pte_clear(ptep) pte_load_store((ptep), (pt_entry_t)0ULL)
-
-#ifdef PAE
-extern pt_entry_t pg_nx;
-#endif
-#else
/*
* Routine: pmap_kextract
* Function:
@@ -278,6 +304,8 @@
return pa;
}
+#endif
+
#ifdef PAE
static __inline pt_entry_t
@@ -292,21 +320,6 @@
return (r);
}
-static __inline pt_entry_t
-pte_load_store(pt_entry_t *ptep, pt_entry_t v)
-{
- pt_entry_t r;
-
- r = *ptep;
- __asm __volatile(
- "1:\n"
- "\tlock; cmpxchg8b %1\n"
- "\tjnz 1b"
- : "+A" (r)
- : "m" (*ptep), "b" ((uint32_t)v), "c" ((uint32_t)(v >> 32)));
- return (r);
-}
-
/* XXXRU move to atomic.h? */
static __inline int
atomic_cmpset_64(volatile uint64_t *dst, uint64_t exp, uint64_t src)
@@ -332,6 +345,8 @@
#define pte_store(ptep, pte) pte_load_store((ptep), (pt_entry_t)pte)
+#define pte_store_ma(ptep, pte) pte_load_store_ma((ptep), (pt_entry_t)pte)
+
extern pt_entry_t pg_nx;
#else /* PAE */
@@ -373,8 +388,6 @@
#define pte_clear(ptep) pte_store((ptep), (pt_entry_t)0ULL)
#define pde_store(pdep, pde) pte_store((pdep), (pde))
-#endif /* !XEN */
-
#endif /* _KERNEL */
/*
==== //depot/projects/xen31/sys/i386/xen/pmap.c#16 (text+ko) ====
@@ -193,12 +193,8 @@
#define pmap_pte_u(pte) ((*(int *)pte & PG_A) != 0)
#define pmap_pte_v(pte) ((*(int *)pte & PG_V) != 0)
-#define pmap_pte_set_w(pte, v) { \
- if (v) \
- PT_SET_VA_MA(pte, *pte | PG_W, TRUE); \
- else \
- PT_SET_VA_MA(pte, *pte & ~PG_W, TRUE); \
-}
+#define pmap_pte_set_w(pte, v) ((v) ? atomic_set_int((u_int *)(pte), PG_W) : \
+ atomic_clear_int((u_int *)(pte), PG_W))
#define pmap_pte_set_prot(pte, v) ((*(int *)pte &= ~PG_PROT), (*(int *)pte |= (v)))
struct pmap kernel_pmap_store;
@@ -257,7 +253,6 @@
#endif
static pt_entry_t *PMAP1 = 0, *PMAP2;
static pt_entry_t *PADDR1 = 0, *PADDR2;
-static int PMAP1_inuse = 0, PMAP2_inuse = 0;
#ifdef SMP
static int PMAP1cpu;
static int PMAP1changedcpu;
@@ -419,8 +414,9 @@
}
SYSMAP(caddr_t, CMAP1, CADDR1, 1)
SYSMAP(caddr_t, CMAP3, CADDR3, 1)
- PT_CLEAR_VA(CMAP3, TRUE);
-
+ *CMAP3 = 0;
+
+
/*
* Crashdump maps.
*/
@@ -445,7 +441,7 @@
mtx_init(&PMAP2mutex, "PMAP2", NULL, MTX_DEF);
virtual_avail = va;
- PT_CLEAR_VA(CMAP1, TRUE);
+ *CMAP1 = 0;
/*
* Leave in place an identity mapping (virt == phys) for the low 1 MB
@@ -938,7 +934,7 @@
mtx_lock(&PMAP2mutex);
newpf = *pde & PG_FRAME;
if ((*PMAP2 & PG_FRAME) != newpf) {
- PT_SET_VA_MA(PMAP2, newpf | PG_V | PG_A | PG_M, TRUE);
+ *PMAP2 = newpf | PG_V | PG_A | PG_M;
pmap_invalidate_page(kernel_pmap, (vm_offset_t)PADDR2);
}
return (PADDR2 + (i386_btop(va) & (NPTEPG - 1)));
@@ -992,8 +988,8 @@
mtx_assert(&vm_page_queue_mtx, MA_OWNED);
KASSERT(curthread->td_pinned > 0, ("curthread not pinned"));
newpf = *pde & PG_FRAME;
- if ((PT_GET(PMAP1) & PG_FRAME) != newpf) {
- PT_SET_VA_MA(PMAP1, newpf | PG_V | PG_A, TRUE);
+ if ((*PMAP1 & PG_FRAME) != newpf) {
+ *PMAP1 = newpf | PG_V | PG_A;
#ifdef SMP
PMAP1cpu = PCPU_GET(cpuid);
#endif
@@ -1038,10 +1034,9 @@
pte = pmap_pte(pmap, va);
rtval = (PT_GET(pte) & PG_FRAME) | (va & PAGE_MASK);
pmap_pte_release(pte);
- if (PMAP2_inuse) {
- PT_CLEAR_VA(PMAP2, TRUE);
- PMAP2_inuse = 0;
- }
+
+ if (*PMAP2)
+ *PMAP2 = 0;
}
PMAP_UNLOCK(pmap);
return (rtval);
@@ -1072,10 +1067,8 @@
rtval = (*pte & PG_FRAME) | (va & PAGE_MASK);
pmap_pte_release(pte);
#ifdef XEN
- if (PMAP2_inuse) {
- PT_CLEAR_VA(PMAP2, TRUE);
- PMAP2_inuse = 0;
- }
+ if (*PMAP2)
+ *PMAP2 = 0;
#endif
}
PMAP_UNLOCK(pmap);
@@ -1110,10 +1103,8 @@
} else {
sched_pin();
pte = PT_GET(pmap_pte_quick(pmap, va));
- if (PMAP1_inuse) {
- PT_CLEAR_VA(PMAP1, TRUE);
- PMAP1_inuse = 0;
- }
+ if (*PMAP1)
+ *PMAP1 = 0;
if (pte != 0 &&
((pte & PG_RW) || (prot & VM_PROT_WRITE) == 0)) {
m = PHYS_TO_VM_PAGE(pte & PG_FRAME);
@@ -1150,7 +1141,7 @@
pt_entry_t *pte;
pte = vtopte(va);
- PT_SET_VA_MA(pte, ma | PG_RW | PG_V | pgeflag, TRUE);
+ pte_store_ma(pte, ma | PG_RW | PG_V | pgeflag);
}
@@ -1459,7 +1450,7 @@
for (i = KPTDI; i < KPTDI + nkpt; i++)
pmap->pm_pdir_shadow[i] = PTD[i] & ~(PG_RW|PG_M|PG_A);
for (i = 0; i < NPGPTD; i++) {
- vm_paddr_t *pd;
+ pt_entry_t *pd;
pd = pmap->pm_pdir + (i * NPDEPG);
PT_SET_MA(pd, *vtopte((vm_offset_t)pd) & ~(PG_M|PG_A|PG_U|PG_RW));
@@ -2102,11 +2093,12 @@
pmap_insert_entry(pmap_t pmap, vm_offset_t va, vm_page_t m)
{
pv_entry_t pv;
-
PMAP_LOCK_ASSERT(pmap, MA_OWNED);
mtx_assert(&vm_page_queue_mtx, MA_OWNED);
+
pv = get_pv_entry(pmap, FALSE);
pv->pv_va = va;
+
TAILQ_INSERT_TAIL(&m->md.pv_list, pv, pv_list);
}
@@ -2151,7 +2143,7 @@
pmap_invalidate_page(kernel_pmap, va);
pmap->pm_stats.resident_count -= 1;
if (oldpte & PG_MANAGED) {
- m = PHYS_TO_VM_PAGE(oldpte & PG_FRAME);
+ m = PHYS_TO_VM_PAGE(xpmap_mtop(oldpte) & PG_FRAME);
if (oldpte & PG_M) {
KASSERT((oldpte & PG_RW),
("pmap_remove_pte: modified page not writable: va: %#x, pte: %#jx",
@@ -2180,10 +2172,9 @@
return;
pmap_remove_pte(pmap, pte, va, free);
pmap_invalidate_page(pmap, va);
- if (PMAP1_inuse) {
- PT_CLEAR_VA(PMAP1, TRUE);
- PMAP1_inuse = 0;
- }
+ if (*PMAP1)
+ *PMAP1 = 0;
+
}
/*
@@ -2277,10 +2268,8 @@
break;
}
}
- if (PMAP1_inuse) {
- PT_CLEAR_VA(PMAP1, TRUE);
- PMAP1_inuse = 0;
- }
+ if (*PMAP1)
+ *PMAP1 = 0;
out:
sched_unpin();
if (anyvalid)
@@ -2351,10 +2340,8 @@
PMAP_UNLOCK(pmap);
}
vm_page_flag_clear(m, PG_WRITEABLE);
- if (PMAP1_inuse) {
- PT_CLEAR_VA(PMAP1, TRUE);
- PMAP1_inuse = 0;
- }
+ if (*PMAP1)
+ *PMAP1 = 0;
sched_unpin();
}
@@ -2426,27 +2413,25 @@
sva += PAGE_SIZE) {
vm_page_t m;
-#ifndef XEN
retry:
-#endif
/*
* Regardless of whether a pte is 32 or 64 bits in
* size, PG_RW, PG_A, and PG_M are among the least
* significant 32 bits.
*/
- obits = pbits = PT_GET(pte);
+ obits = pbits = *pte;
if ((pbits & PG_V) == 0)
continue;
if (pbits & PG_MANAGED) {
m = NULL;
if (pbits & PG_A) {
- m = PHYS_TO_VM_PAGE(pbits & PG_FRAME);
+ m = PHYS_TO_VM_PAGE(xpmap_mtop(pbits) & PG_FRAME);
vm_page_flag_set(m, PG_REFERENCED);
pbits &= ~PG_A;
}
if ((pbits & PG_M) != 0) {
if (m == NULL)
- m = PHYS_TO_VM_PAGE(pbits & PG_FRAME);
+ m = PHYS_TO_VM_PAGE(xpmap_mtop(pbits) & PG_FRAME);
vm_page_dirty(m);
}
}
@@ -2459,7 +2444,6 @@
#endif
if (pbits != obits) {
-#ifndef XEN
#ifdef PAE
if (!atomic_cmpset_64(pte, obits, pbits))
goto retry;
@@ -2468,9 +2452,6 @@
pbits))
goto retry;
#endif
-#else
- PT_SET_VA(pte, pbits, FALSE);
-#endif
if (obits & PG_G)
pmap_invalidate_page(pmap, sva);
else
@@ -2478,10 +2459,8 @@
}
}
}
- if (PMAP1_inuse) {
- PT_CLEAR_VA(PMAP1, TRUE);
- PMAP1_inuse = 0;
- }
+ if (*PMAP1)
+ *PMAP1 = 0;
sched_unpin();
if (anychanged)
pmap_invalidate_all(pmap);
@@ -2685,10 +2664,8 @@
} else
pte_store(pte, newpte | PG_A);
}
- if (PMAP1_inuse) {
- PT_CLEAR_VA(PMAP1, TRUE);
- PMAP1_inuse = 0;
- }
+ if (*PMAP1)
+ *PMAP1 = 0;
sched_unpin();
vm_page_unlock_queues();
PMAP_UNLOCK(pmap);
@@ -2964,10 +2941,8 @@
*/
pmap_pte_set_w(pte, wired);
pmap_pte_release(pte);
- if (PMAP2_inuse) {
- PT_CLEAR_VA(PMAP2, TRUE);
- PMAP2_inuse = 0;
- }
+ if (*PMAP2)
+ *PMAP2 = 0;
PMAP_UNLOCK(pmap);
}
@@ -3040,7 +3015,7 @@
src_pte = vtopte(addr);
while (addr < pdnxt) {
pt_entry_t ptetemp;
- ptetemp = PT_GET(src_pte);
+ ptetemp = *src_pte;
/*
* we only virtual copy managed pages
*/
@@ -3052,13 +3027,13 @@
dst_pte = pmap_pte_quick(dst_pmap, addr);
if (*dst_pte == 0 &&
pmap_try_insert_pv_entry(dst_pmap, addr,
- PHYS_TO_VM_PAGE(ptetemp & PG_FRAME))) {
+ PHYS_TO_VM_PAGE(xpmap_mtop(ptetemp) & PG_FRAME))) {
/*
* Clear the wired, modified, and
* accessed (referenced) bits
* during the copy.
*/
- PT_SET_VA(dst_pte, ptetemp & ~(PG_W | PG_M | PG_A), FALSE);
+ *dst_pte = ptetemp & ~(PG_W | PG_M | PG_A);
dst_pmap->pm_stats.resident_count++;
} else {
@@ -3077,10 +3052,8 @@
src_pte++;
}
}
- if (PMAP1_inuse) {
- PT_CLEAR_VA(PMAP1, FALSE);
- PMAP1_inuse = 0;
- }
+ if (*PMAP1)
+ *PMAP1 = 0;
sched_unpin();
vm_page_unlock_queues();
PT_UPDATES_FLUSH();
@@ -3118,17 +3091,13 @@
if (*sysmaps->CMAP2)
panic("pmap_zero_page: CMAP2 busy");
sched_pin();
-#ifdef XEN
- PT_SET_VA(sysmaps->CMAP2, PG_V | PG_RW | VM_PAGE_TO_PHYS(m) | PG_A | PG_M, TRUE);
-#else
- *sysmaps->CMAP2 = PG_V | PG_RW | VM_PAGE_TO_PHYS(m) | PG_A | PG_M;
-#endif
+ *sysmaps->CMAP2 = PG_V | PG_RW | xpmap_ptom(VM_PAGE_TO_PHYS(m)) | PG_A | PG_M;
KASSERT(*sysmaps->CMAP2 == (PG_V | PG_RW | xpmap_ptom(VM_PAGE_TO_PHYS(m)) | PG_A | PG_M),
("CMAP2 did not get set is %llx", *sysmaps->CMAP2));
invlcaddr(sysmaps->CADDR2);
pagezero(sysmaps->CADDR2);
- PT_CLEAR_VA(sysmaps->CMAP2, TRUE);
+ *sysmaps->CMAP2 = 0;
sched_unpin();
mtx_unlock(&sysmaps->lock);
}
@@ -3149,7 +3118,7 @@
if (*sysmaps->CMAP2)
panic("pmap_zero_page: CMAP2 busy");
sched_pin();
- PT_SET_VA(sysmaps->CMAP2, PG_V | PG_RW | VM_PAGE_TO_PHYS(m) | PG_A | PG_M, TRUE);
+ *sysmaps->CMAP2 = PG_V | PG_RW | xpmap_ptom(VM_PAGE_TO_PHYS(m)) | PG_A | PG_M;
invlcaddr(sysmaps->CADDR2);
if (off == 0 && size == PAGE_SIZE)
@@ -3157,7 +3126,7 @@
else
bzero((char *)sysmaps->CADDR2 + off, size);
- PT_CLEAR_VA(sysmaps->CMAP2, TRUE);
+ *sysmaps->CMAP2 = 0;
sched_unpin();
mtx_unlock(&sysmaps->lock);
}
@@ -3175,10 +3144,9 @@
if (*CMAP3)
panic("pmap_zero_page: CMAP3 busy");
sched_pin();
- PT_SET_VA(CMAP3, PG_V | PG_RW | VM_PAGE_TO_PHYS(m) | PG_A | PG_M, TRUE);
+ *CMAP3 = PG_V | PG_RW | xpmap_ptom(VM_PAGE_TO_PHYS(m)) | PG_A | PG_M;
invlcaddr(CADDR3);
pagezero(CADDR3);
- PT_CLEAR_VA(CMAP3, TRUE);
sched_unpin();
}
@@ -3202,15 +3170,16 @@
sched_pin();
invlpg((u_int)sysmaps->CADDR1);
invlpg((u_int)sysmaps->CADDR2);
- PT_SET_VA(sysmaps->CMAP1, PG_V | VM_PAGE_TO_PHYS(src) | PG_A, TRUE);
- PT_SET_VA(sysmaps->CMAP2, PG_V | PG_RW | VM_PAGE_TO_PHYS(dst) | PG_A | PG_M, TRUE);
+ *sysmaps->CMAP1 = PG_V | xpmap_ptom(VM_PAGE_TO_PHYS(src)) | PG_A;
+ *sysmaps->CMAP2 = PG_V | PG_RW | xpmap_ptom(VM_PAGE_TO_PHYS(dst)) | PG_A | PG_M;
+
KASSERT(*sysmaps->CMAP1 == (PG_V | xpmap_ptom(VM_PAGE_TO_PHYS(src)) | PG_A ),
("CMAP1 did not get set is %llx", *sysmaps->CMAP1));
KASSERT(*sysmaps->CMAP2 == (PG_V | PG_RW | xpmap_ptom(VM_PAGE_TO_PHYS(dst)) | PG_A | PG_M),
("CMAP2 did not get set is %llx", *sysmaps->CMAP2));
bcopy(sysmaps->CADDR1, sysmaps->CADDR2, PAGE_SIZE);
- PT_CLEAR_VA(sysmaps->CMAP1, FALSE);
- PT_CLEAR_VA(sysmaps->CMAP2, TRUE);
+ *sysmaps->CMAP1 = 0;
+ *sysmaps->CMAP2 = 0;
if (*sysmaps->CMAP1)
panic("pmap_copy_page: CMAP1 busy, CMAP1=%llx", *sysmaps->CMAP1);
if (*sysmaps->CMAP2)
@@ -3318,7 +3287,12 @@
if (pmap->pm_pdir_shadow[pv->pv_va >> PDRSHIFT] == 0) {
printf("PDIR IS ZERO @ VA %08x\n", pv->pv_va);
- panic("bad pte");
+ /* workaround insufficient wired count
+ * on page directory - this only buys
+ * us a little bit of time as the list
+ * on one of the pages is now corrupt
+ */
+ goto skip;
}
pte = vtopte(pv->pv_va);
@@ -3348,7 +3322,6 @@
("pmap_remove_pages: bad tpte %#jx",
(uintmax_t)tpte));
- pmap->pm_stats.resident_count--;
pte_clear(pte);
@@ -3358,16 +3331,19 @@
if (tpte & PG_M)
vm_page_dirty(m);
+ TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
+ if (TAILQ_EMPTY(&m->md.pv_list))
+ vm_page_flag_clear(m, PG_WRITEABLE);
+
+ pmap_unuse_pt(pmap, pv->pv_va, &free);
+ skip:
+
/* Mark free */
PV_STAT(pv_entry_frees++);
PV_STAT(pv_entry_spare++);
pv_entry_count--;
pc->pc_map[field] |= bitmask;
- TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
- if (TAILQ_EMPTY(&m->md.pv_list))
- vm_page_flag_clear(m, PG_WRITEABLE);
-
- pmap_unuse_pt(pmap, pv->pv_va, &free);
+ pmap->pm_stats.resident_count--;
}
}
if (allfree) {
@@ -3382,10 +3358,8 @@
pmap_ptelist_free(&pv_vafree, (vm_offset_t)pc);
}
}
- if (PMAP1_inuse) {
- PT_CLEAR_VA(PMAP1, TRUE);
- PMAP1_inuse = 0;
- }
+ if (*PMAP1)
+ *PMAP1 = 0;
sched_unpin();
pmap_invalidate_all(pmap);
vm_page_unlock_queues();
@@ -3422,10 +3396,8 @@
if (rv)
break;
}
- if (PMAP1_inuse) {
- PT_CLEAR_VA(PMAP1, TRUE);
- PMAP1_inuse = 0;
- }
+ if (*PMAP1)
+ *PMAP1 = 0;
sched_unpin();
return (rv);
}
@@ -3472,10 +3444,8 @@
pmap_pte_release(pte);
}
PT_UPDATES_FLUSH();
- if (PMAP2_inuse) {
- PT_CLEAR_VA(PMAP2, TRUE);
- PMAP2_inuse = 0;
- }
+ if (*PMAP2)
+ *PMAP2 = 0;
}
void
@@ -3490,10 +3460,8 @@
pmap_pte_release(pte);
}
PT_UPDATES_FLUSH();
- if (PMAP2_inuse) {
- PT_CLEAR_VA(PMAP2, TRUE);
- PMAP2_inuse = 0;
- }
+ if (*PMAP2)
+ *PMAP2 = 0;
}
/*
@@ -3515,23 +3483,17 @@
pmap = PV_PMAP(pv);
PMAP_LOCK(pmap);
pte = pmap_pte_quick(pmap, pv->pv_va);
-#ifndef XEN
retry:
-#endif
- oldpte = PT_GET(pte);
+ oldpte = *pte;
if ((oldpte & PG_RW) != 0) {
/*
* Regardless of whether a pte is 32 or 64 bits
* in size, PG_RW and PG_M are among the least
* significant 32 bits.
*/
-#ifndef XEN
if (!atomic_cmpset_int((u_int *)pte, oldpte,
oldpte & ~(PG_RW | PG_M)))
goto retry;
-#else
- PT_SET_VA(pte, oldpte & ~(PG_RW|PG_M), TRUE);
-#endif
if ((oldpte & PG_M) != 0)
vm_page_dirty(m);
pmap_invalidate_page(pmap, pv->pv_va);
@@ -3539,10 +3501,8 @@
PMAP_UNLOCK(pmap);
}
vm_page_flag_clear(m, PG_WRITEABLE);
- if (PMAP1_inuse) {
- PT_CLEAR_VA(PMAP1, TRUE);
- PMAP1_inuse = 0;
- }
+ if (*PMAP1)
+ *PMAP1 = 0;
sched_unpin();
}
@@ -3581,13 +3541,8 @@
pmap = PV_PMAP(pv);
PMAP_LOCK(pmap);
pte = pmap_pte_quick(pmap, pv->pv_va);
- if (pte && ((v = PT_GET(pte)) & PG_A) != 0) {
-#ifndef XEN
+ if (pte && ((v = *pte) & PG_A) != 0) {
atomic_clear_int((u_int *)pte, PG_A);
-#else
- PT_SET_VA(pte, v & ~PG_A, TRUE);
-#endif
-
pmap_invalidate_page(pmap, pv->pv_va);
rtval++;
if (rtval > 4)
@@ -3596,10 +3551,8 @@
PMAP_UNLOCK(pmap);
} while ((pv = pvn) != NULL && pv != pvf);
}
- if (PMAP1_inuse) {
- PT_CLEAR_VA(PMAP1, TRUE);
- PMAP1_inuse = 0;
- }
+ if (*PMAP1)
+ *PMAP1 = 0;
sched_unpin();
return (rtval);
}
@@ -3631,11 +3584,7 @@
* in size, PG_M is among the least significant
* 32 bits.
*/
-#ifndef XEN
atomic_clear_int((u_int *)pte, PG_M);
-#else
- PT_SET_MA(pv->pv_va, val & ~PG_M);
-#endif
pmap_invalidate_page(pmap, pv->pv_va);
}
PMAP_UNLOCK(pmap);
@@ -3671,11 +3620,7 @@
* in size, PG_A is among the least significant
* 32 bits.
*/
-#ifndef XEN
atomic_clear_int((u_int *)pte, PG_A);
-#else
- PT_SET_MA(pv->pv_va, val & ~PG_A);
-#endif
pmap_invalidate_page(pmap, pv->pv_va);
}
PMAP_UNLOCK(pmap);
@@ -3797,19 +3742,12 @@
* The cache mode bits are all in the low 32-bits of the
* PTE, so we can just spin on updating the low 32-bits.
*/
-#ifndef XEN
do {
opte = *(u_int *)pte;
npte = opte & ~(PG_PTE_PAT | PG_NC_PCD | PG_NC_PWT);
npte |= pmap_cache_bits(mode, 0);
} while (npte != opte &&
!atomic_cmpset_int((u_int *)pte, opte, npte));
-#else
- opte = *pte;
- npte = opte & ~(PG_PTE_PAT | PG_NC_PCD | PG_NC_PWT);
- npte |= pmap_cache_bits(mode, 0);
- PT_SET_MA(tmpva, npte);
-#endif
tmpva += PAGE_SIZE;
size -= PAGE_SIZE;
}
@@ -3841,10 +3779,8 @@
pte = (ptep != NULL) ? PT_GET(ptep) : 0;
pmap_pte_release(ptep);
PMAP_UNLOCK(pmap);
- if (PMAP2_inuse) {
- PT_CLEAR_VA(PMAP2, TRUE);
- PMAP2_inuse = 0;
- }
+ if (*PMAP2)
+ *PMAP2 = 0;
if (pte != 0) {
vm_paddr_t pa;
==== //depot/projects/xen31/sys/i386/xen/xen_machdep.c#15 (text+ko) ====
@@ -259,7 +259,7 @@
xen_invlpg(vm_offset_t va)
{
struct mmuext_op op;
- op.cmd = MMUEXT_INVLPG_LOCAL;
+ op.cmd = MMUEXT_INVLPG_ALL;
op.arg1.linear_addr = va & ~PAGE_MASK;
xen_flush_queue();
PANIC_IF(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
@@ -708,10 +708,9 @@
#endif
unsigned long i;
-#ifdef WRITABLE_PAGETABLES
- printk("using writable pagetables\n");
+
HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_writable_pagetables);
-#endif
+
xen_start_info = startinfo;
xen_phys_machine = (xen_pfn_t *)startinfo->mfn_list;
More information about the p4-projects
mailing list