Subject: merging pmap_enter and friends
To: None <bouyer@netbsd.org>
From: YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp>
List: port-xen
Date: 01/23/2006 05:32:27
--NextPart-20060123053029-0429100
Content-Type: Text/Plain; charset=us-ascii
hi,
the attached patch merges pmap_enter, pmap_enter_ma, and pmap_remap_pages.
unless anyone has an objection or conflicting changes (bouyer?),
i'll commit it soon.
YAMAMOTO Takashi
--NextPart-20060123053029-0429100
Content-Type: Text/Plain; charset=us-ascii
Content-Disposition: attachment; filename="a.diff"
Index: include/pmap.h
===================================================================
--- include/pmap.h (revision 1481)
+++ include/pmap.h (working copy)
@@ -355,11 +355,9 @@ void pmap_write_protect(struct pmap *,
int pmap_exec_fixup(struct vm_map *, struct trapframe *,
struct pcb *);
void pmap_load(void);
-int pmap_enter_ma(struct pmap *, vaddr_t, paddr_t, vm_prot_t,
- int);
-boolean_t pmap_extract_ma(pmap_t, vaddr_t, paddr_t *);
-int pmap_remap_pages(struct pmap *, vaddr_t, paddr_t, int,
+int pmap_enter_ma(struct pmap *, vaddr_t, paddr_t, paddr_t,
vm_prot_t, int, int);
+boolean_t pmap_extract_ma(pmap_t, vaddr_t, paddr_t *);
vaddr_t reserve_dumppages(vaddr_t); /* XXX: not a pmap fn */
Index: i386/pmap.c
===================================================================
--- i386/pmap.c (revision 1481)
+++ i386/pmap.c (working copy)
@@ -883,6 +883,25 @@ pte_atomic_update_ma(pt_entry_t *pte, pt
return opte;
}
+static inline int
+pte_atomic_update_ma_domid(pt_entry_t *pte, pt_entry_t npte, pt_entry_t *opte,
+ int domid)
+{
+ pt_entry_t *maptp = (pt_entry_t *)vtomach((vaddr_t)pte);
+ int error;
+
+ if (domid == DOMID_SELF) {
+ *opte = pte_atomic_update_ma(pte, maptp, npte);
+ error = 0;
+ } else {
+ /* XXX */
+ *opte = PTE_GET_MA(pte);
+ error = xpq_update_foreign(maptp, npte, domid);
+ }
+
+ return error;
+}
+
inline static pt_entry_t
pte_atomic_update(pt_entry_t *pte, pt_entry_t *mapte, pt_entry_t npte)
{
@@ -3535,20 +3554,9 @@ pmap_collect(pmap)
* defined as macro in pmap.h
*/
-/*
- * pmap_enter: enter a mapping into a pmap
- *
- * => must be done "now" ... no lazy-evaluation
- * => we set pmap => pv_head locking
- */
-
int
-pmap_enter(pmap, va, pa, prot, flags)
- struct pmap *pmap;
- vaddr_t va;
- paddr_t pa;
- vm_prot_t prot;
- int flags;
+pmap_enter_ma(struct pmap *pmap, vaddr_t va, paddr_t ma, paddr_t pa,
+ vm_prot_t prot, int flags, int domid)
{
pt_entry_t *ptes, opte, npte;
struct vm_page *ptp, *pg;
@@ -3557,42 +3565,32 @@ pmap_enter(pmap, va, pa, prot, flags)
struct pv_entry *pve = NULL; /* XXX gcc */
int error;
boolean_t wired = (flags & PMAP_WIRED) != 0;
- pt_entry_t *maptp;
+ int resid_delta = 0;
+ int wired_delta = 0;
- XENPRINTK(("pmap_enter(%p, %p, %p, %08x, %08x)\n",
- pmap, (void *)va, (void *)pa, prot, flags));
+ XENPRINTK(("%s(%p, %p, %p, %08x, %08x)\n",
+ __func__, pmap, (void *)va, (void *)pa, prot, flags));
+ KASSERT(domid == DOMID_SELF || pa == 0);
KASSERT(pmap_initialized);
#ifdef DIAGNOSTIC
/* sanity check: totally out of range? */
if (va >= VM_MAX_KERNEL_ADDRESS)
- panic("pmap_enter: too big");
+ panic("%s: too big", __func__);
if (va == (vaddr_t) PDP_BASE || va == (vaddr_t) APDP_BASE)
- panic("pmap_enter: trying to map over PDP/APDP!");
+ panic("%s: trying to map over PDP/APDP!", __func__);
/* sanity check: kernel PTPs should already have been pre-allocated */
if (va >= VM_MIN_KERNEL_ADDRESS &&
!pmap_valid_entry(pmap->pm_pdir[pdei(va)]))
- panic("pmap_enter: missing kernel PTP!");
+ panic("%s: missing kernel PTP!", __func__);
#endif
- npte = protection_codes[prot] | PG_V;
-
- if (pa >= pmap_pa_start && pa < pmap_pa_end)
- npte |= xpmap_ptom(pa);
- else {
- XENPRINTF(("pmap_enter: va %08lx outside pa range %08lx\n",
- va, pa));
- npte |= pa;
- }
-
- /* XENPRINTK(("npte %p\n", npte)); */
-
+ npte = protection_codes[prot] | PG_V | ma;
if (wired)
npte |= PG_W;
-
if (va < VM_MAXUSER_ADDRESS)
npte |= PG_u;
else if (va < VM_MAX_ADDRESS)
@@ -3618,7 +3616,7 @@ pmap_enter(pmap, va, pa, prot, flags)
error = ENOMEM;
goto out;
}
- panic("pmap_enter: get ptp failed");
+ panic("%s: get ptp failed", __func__);
}
}
@@ -3627,37 +3625,40 @@ pmap_enter(pmap, va, pa, prot, flags)
* on SMP the PTE might gain PG_U and PG_M flags
* before we zap it later
*/
- opte = pte_get(&ptes[x86_btop(va)]); /* old PTE */
+ opte = pte_get_ma(&ptes[x86_btop(va)]); /* old PTE */
XENPRINTK(("npte %p opte %p ptes %p idx %03x\n",
(void *)npte, (void *)opte, ptes, x86_btop(va)));
/*
* is there currently a valid mapping at our VA and does it
- * map to the same PA as the one we want to map ?
+ * map to the same MA as the one we want to map ?
*/
- if (pmap_valid_entry(opte) && ((opte & PG_FRAME) == pa)) {
+ if (pmap_valid_entry(opte) && ((opte & PG_FRAME) == ma)) {
/*
* first, calculate pm_stats updates. resident count will not
* change since we are replacing/changing a valid mapping.
* wired count might change...
*/
- pmap->pm_stats.wired_count +=
- ((npte & PG_W) ? 1 : 0) - ((opte & PG_W) ? 1 : 0);
+ wired_delta = ((npte & PG_W) ? 1 : 0) - ((opte & PG_W) ? 1 : 0);
npte |= (opte & PG_PVLIST);
XENPRINTK(("pmap update opte == pa"));
/* zap! */
- maptp = (pt_entry_t *)vtomach((vaddr_t)&ptes[x86_btop(va)]);
- opte = pte_atomic_update_ma(&ptes[x86_btop(va)], maptp, npte);
+ error = pte_atomic_update_ma_domid(&ptes[x86_btop(va)], npte,
+ &opte, domid);
+ if (error) {
+ goto out;
+ }
/*
* Might be cached in the TLB as being writable
* if this is on the PVLIST, sync R/M bit
*/
if (opte & PG_PVLIST) {
+ KASSERT(domid == DOMID_SELF);
pg = PHYS_TO_VM_PAGE(pa);
#ifdef DIAGNOSTIC
if (pg == NULL)
@@ -3675,7 +3676,11 @@ pmap_enter(pmap, va, pa, prot, flags)
goto shootdown_now;
}
- pg = PHYS_TO_VM_PAGE(pa);
+ if (domid == DOMID_SELF) {
+ pg = PHYS_TO_VM_PAGE(pa);
+ } else {
+ pg = NULL;
+ }
XENPRINTK(("pg %p from %p, init %d\n", pg, (void *)pa,
pmap_initialized));
if (pg != NULL) {
@@ -3705,7 +3710,7 @@ pmap_enter(pmap, va, pa, prot, flags)
if (pmap_valid_entry(opte)) {
/*
- * changing PAs: we must remove the old one first
+ * changing MAs: we must remove the old one first
*/
/*
@@ -3713,16 +3718,16 @@ pmap_enter(pmap, va, pa, prot, flags)
* change since we are replacing/changing a valid mapping.
* wired count might change...
*/
- pmap->pm_stats.wired_count +=
- ((npte & PG_W) ? 1 : 0) - ((opte & PG_W) ? 1 : 0);
+ wired_delta = ((npte & PG_W) ? 1 : 0) - ((opte & PG_W) ? 1 : 0);
if (opte & PG_PVLIST) {
- pg = PHYS_TO_VM_PAGE(opte & PG_FRAME);
+ paddr_t opa = xpmap_mtop(opte & PG_FRAME);
+ pg = PHYS_TO_VM_PAGE(opa);
#ifdef DIAGNOSTIC
if (pg == NULL)
- panic("pmap_enter: PG_PVLIST mapping with "
- "unmanaged page "
- "pa = 0x%lx (0x%lx)", pa, atop(pa));
+ panic("%s: PG_PVLIST mapping with "
+ "unmanaged page pa = 0x%lx (0x%lx)",
+ __func__, pa, atop(pa));
#endif
mdpg = &pg->mdpage;
old_pvh = &mdpg->mp_pvhead;
@@ -3732,10 +3737,11 @@ pmap_enter(pmap, va, pa, prot, flags)
XENPRINTK(("pmap change pa"));
/* zap! */
- maptp = (pt_entry_t *)vtomach(
- (vaddr_t)&ptes[x86_btop(va)]);
- opte = pte_atomic_update_ma(&ptes[x86_btop(va)], maptp,
- npte);
+ error = pte_atomic_update_ma_domid(&ptes[x86_btop(va)],
+ npte, &opte, domid);
+ if (error) {
+ goto out;
+ }
pve = pmap_remove_pv(old_pvh, pmap, va);
KASSERT(pve != 0);
@@ -3751,11 +3757,9 @@ pmap_enter(pmap, va, pa, prot, flags)
goto shootdown_test;
}
} else { /* opte not valid */
- pmap->pm_stats.resident_count++;
+ resid_delta = 1;
if (wired)
- pmap->pm_stats.wired_count++;
- if (ptp)
- ptp->wire_count++;
+ wired_delta = 1;
}
if (new_pvh) {
@@ -3765,9 +3769,12 @@ pmap_enter(pmap, va, pa, prot, flags)
}
XENPRINTK(("pmap initial setup\n"));
- maptp = (pt_entry_t *)vtomach((vaddr_t)&ptes[x86_btop(va)]);
- opte = pte_atomic_update_ma(&ptes[x86_btop(va)],
- maptp, npte); /* zap! */
+ /* zap! */
+ error = pte_atomic_update_ma_domid(&ptes[x86_btop(va)], npte,
+ &opte, domid);
+ if (error) {
+ goto out;
+ }
shootdown_test:
/* Update page attributes if needed */
@@ -3789,455 +3796,45 @@ shootdown_now:
error = 0;
out:
- pmap_unmap_ptes(pmap);
- PMAP_MAP_TO_HEAD_UNLOCK();
-
- XENPRINTK(("pmap_enter: %d\n", error));
- return error;
-}
-
-/*
- * pmap_enter_ma: enter a mapping into a pmap
- *
- * => must be done "now" ... no lazy-evaluation
- * => we set pmap => pv_head locking
- */
-
-int
-pmap_enter_ma(pmap, va, pa, prot, flags)
- struct pmap *pmap;
- vaddr_t va;
- paddr_t pa;
- vm_prot_t prot;
- int flags;
-{
- pt_entry_t *ptes, opte, npte;
- pt_entry_t *maptp;
- struct vm_page *ptp, *pg;
- struct vm_page_md *mdpg;
- struct pv_head *old_pvh;
- struct pv_entry *pve = NULL; /* XXX gcc */
- int error;
- boolean_t wired = (flags & PMAP_WIRED) != 0;
-
- XENPRINTK(("pmap_enter_ma(%p, %p, %p, %08x, %08x)\n",
- pmap, (void *)va, (void *)pa, prot, flags));
-
-#ifdef DIAGNOSTIC
- /* sanity check: totally out of range? */
- if (va >= VM_MAX_KERNEL_ADDRESS)
- panic("pmap_enter: too big");
-
- if (va == (vaddr_t) PDP_BASE || va == (vaddr_t) APDP_BASE)
- panic("pmap_enter: trying to map over PDP/APDP!");
-
- /* sanity check: kernel PTPs should already have been pre-allocated */
- if (va >= VM_MIN_KERNEL_ADDRESS &&
- !pmap_valid_entry(pmap->pm_pdir[pdei(va)]))
- panic("pmap_enter: missing kernel PTP!");
-#endif
-
- npte = pa | protection_codes[prot] | PG_V;
- /* XENPRINTK(("npte %p\n", npte)); */
-
- if (wired)
- npte |= PG_W;
-
- if (va < VM_MAXUSER_ADDRESS)
- npte |= PG_u;
- else if (va < VM_MAX_ADDRESS)
- npte |= (PG_u | PG_RW); /* XXXCDC: no longer needed? */
- if (pmap == pmap_kernel())
- npte |= pmap_pg_g;
- if (flags & VM_PROT_ALL) {
- npte |= PG_U;
- if (flags & VM_PROT_WRITE)
- npte |= PG_M;
- }
-
- /* get lock */
- PMAP_MAP_TO_HEAD_LOCK();
-
- ptes = pmap_map_ptes(pmap); /* locks pmap */
- if (pmap == pmap_kernel()) {
- ptp = NULL;
- } else {
- ptp = pmap_get_ptp(pmap, pdei(va));
- if (ptp == NULL) {
- if (flags & PMAP_CANFAIL) {
- error = ENOMEM;
- goto out;
+ if (error == 0) {
+ if (wired_delta) {
+ KASSERT(wired_delta == 1 || wired_delta == -1);
+ pmap->pm_stats.wired_count += wired_delta;
+ }
+ if (resid_delta) {
+ KASSERT(resid_delta == 1);
+ pmap->pm_stats.resident_count += resid_delta;
+ if (ptp) {
+ ptp->wire_count += resid_delta;
}
- panic("pmap_enter: get ptp failed");
}
}
-
- /*
- * Get first view on old PTE
- * on SMP the PTE might gain PG_U and PG_M flags
- * before we zap it later
- */
- opte = pte_get_ma(&ptes[x86_btop(va)]); /* old PTE */
- XENPRINTK(("npte %p opte %p ptes %p idx %03x\n",
- (void *)npte, (void *)opte, ptes, x86_btop(va)));
- XENPRINTF(("pmap_enter_ma pa %08lx va %08lx opte %08x npte %08x "
- "wired %d count %ld\n", pa, va, opte, npte, wired,
- pmap->pm_stats.wired_count));
-
- /*
- * is there currently a valid mapping at our VA and does it
- * map to the same MA as the one we want to map ?
- */
-
- if (pmap_valid_entry(opte) && ((opte & PG_FRAME) == pa)) {
-
- /*
- * first, calculate pm_stats updates. resident count will not
- * change since we are replacing/changing a valid mapping.
- * wired count might change...
- */
- pmap->pm_stats.wired_count +=
- ((npte & PG_W) ? 1 : 0) - ((opte & PG_W) ? 1 : 0);
-
- XENPRINTK(("pmap update opte == pa"));
- /* zap! */
- maptp = (pt_entry_t *)vtomach((vaddr_t)&ptes[x86_btop(va)]);
- opte = pte_atomic_update_ma(&ptes[x86_btop(va)], maptp, npte);
-
- /*
- * Might be cached in the TLB as being writable
- * if this is on the PVLIST, sync R/M bit
- */
- KDASSERT((opte & PG_PVLIST) == 0);
- goto shootdown_now;
- }
-
- /*
- * no managed mapping for pages mapped through pmap_enter_ma.
- */
-
- /*
- * is there currently a valid mapping at our VA?
- */
-
- if (pmap_valid_entry(opte)) {
-
- /*
- * changing PAs: we must remove the old one first
- */
-
- /*
- * first, calculate pm_stats updates. resident count will not
- * change since we are replacing/changing a valid mapping.
- * wired count might change...
- */
- pmap->pm_stats.wired_count +=
- ((npte & PG_W) ? 1 : 0) - ((opte & PG_W) ? 1 : 0);
-
- if (opte & PG_PVLIST) {
- opte = xpmap_mtop(opte);
- KDASSERT((opte & PG_FRAME) != (KERNTEXTOFF - KERNBASE));
-
- pg = PHYS_TO_VM_PAGE(opte & PG_FRAME);
-#ifdef DIAGNOSTIC
- if (pg == NULL)
- panic("pmap_enter: PG_PVLIST mapping with "
- "unmanaged page "
- "pa = 0x%lx (0x%lx)", pa, atop(pa));
-#endif
- mdpg = &pg->mdpage;
- old_pvh = &mdpg->mp_pvhead;
-
- /* NULL new_pvh since page will not be managed */
- pmap_lock_pvhs(old_pvh, NULL);
-
- XENPRINTK(("pmap change pa"));
- /* zap! */
- maptp = (pt_entry_t *)vtomach(
- (vaddr_t)&ptes[x86_btop(va)]);
- opte = pte_atomic_update_ma(&ptes[x86_btop(va)], maptp,
- npte);
-
- pve = pmap_remove_pv(old_pvh, pmap, va);
- KASSERT(pve != 0);
- mdpg->mp_attrs |= opte;
-
- pmap_free_pv(pmap, pve);
- simple_unlock(&old_pvh->pvh_lock);
-
- goto shootdown_test;
- }
- } else { /* opte not valid */
- pmap->pm_stats.resident_count++;
- if (wired)
- pmap->pm_stats.wired_count++;
- if (ptp)
- ptp->wire_count++;
- }
-
- XENPRINTK(("pmap initial setup"));
- maptp = (pt_entry_t *)vtomach((vaddr_t)&ptes[x86_btop(va)]);
- opte = pte_atomic_update_ma(&ptes[x86_btop(va)],
- maptp, npte); /* zap! */
-
-shootdown_test:
- /* Update page attributes if needed */
- if ((opte & (PG_V | PG_U)) == (PG_V | PG_U)) {
-#if defined(MULTIPROCESSOR)
- int32_t cpumask = 0;
-#endif
-shootdown_now:
-#if defined(MULTIPROCESSOR)
- pmap_tlb_shootdown(pmap, va, opte, &cpumask);
- pmap_tlb_shootnow(cpumask);
-#else
- /* Don't bother deferring in the single CPU case. */
- if (pmap_is_curpmap(pmap))
- pmap_update_pg(va);
-#endif
- }
-
- error = 0;
-
-out:
pmap_unmap_ptes(pmap);
PMAP_MAP_TO_HEAD_UNLOCK();
- XENPRINTK(("pmap_enter: %d\n", error));
+ XENPRINTK(("%s: %d\n", __func__, error));
return error;
}
/*
- * pmap_remap_pages: change an existing mapping to new machine pages
+ * pmap_enter: enter a mapping into a pmap
*
* => must be done "now" ... no lazy-evaluation
* => we set pmap => pv_head locking
*/
int
-pmap_remap_pages(pmap, va, pa, npages, prot, flags, dom)
- struct pmap *pmap;
- vaddr_t va;
- paddr_t pa;
- int npages;
- vm_prot_t prot;
- int flags;
- int dom;
+pmap_enter(struct pmap *pmap, vaddr_t va, paddr_t pa, vm_prot_t prot, int flags)
{
- pt_entry_t *ptes, opte, npte;
- pt_entry_t *maptp;
- struct vm_page *ptp, *pg;
- struct vm_page_md *mdpg;
- struct pv_head *old_pvh;
- struct pv_entry *pve = NULL; /* XXX gcc */
- int error, dptpwire;
+ paddr_t ma;
- dptpwire = 0;
-
- XENPRINTK(("pmap_remap_pages(%p, %p, %p, %d, %08x, %d)\n",
- pmap, (void *)va, (void *)pa, npages, flags, dom));
- //printf("pmap_remap_pages(%p, %p, %p, %d, %08x, %d)\n", pmap, (void *)va, (void *)pa, npages, flags, dom);
-
- if (npages != 1)
- panic("pmap_remap_pages: not yet");
-
-#ifdef DIAGNOSTIC
- /* sanity check: totally out of range? */
- if (va >= VM_MAX_KERNEL_ADDRESS)
- panic("pmap_remap_pages: too big");
-
- if (va == (vaddr_t) PDP_BASE || va == (vaddr_t) APDP_BASE)
- panic("pmap_remap_pages: trying to map over PDP/APDP!");
-
- /* sanity check: kernel PTPs should already have been pre-allocated */
- if (va >= VM_MIN_KERNEL_ADDRESS &&
- !pmap_valid_entry(pmap->pm_pdir[pdei(va)]))
- panic("pmap_remap_pages: missing kernel PTP!");
-#endif
-
- npte = pa | PG_V;
- /* XENPRINTK(("npte %p\n", npte)); */
- //printf("npte 0x%x\n", npte);
-
- /* it is always a wired mapping */
- npte |= PG_W;
-
- if (va < VM_MAXUSER_ADDRESS)
- npte |= PG_u;
- else if (va < VM_MAX_ADDRESS)
- npte |= (PG_u | PG_RW); /* XXXCDC: no longer needed? */
- if (pmap == pmap_kernel())
- npte |= pmap_pg_g;
- if (flags & VM_PROT_ALL) {
- npte |= PG_U;
- if (flags & VM_PROT_WRITE)
- npte |= PG_M;
- }
-
- /* get lock */
- PMAP_MAP_TO_HEAD_LOCK();
-
- ptes = pmap_map_ptes(pmap); /* locks pmap */
- if (pmap == pmap_kernel()) {
- ptp = NULL;
+ if (__predict_false(pa < pmap_pa_start || pmap_pa_end <= pa)) {
+ ma = pa; /* XXX hack */
} else {
- ptp = pmap_get_ptp(pmap, pdei(va));
- if (ptp == NULL) {
- if (flags & PMAP_CANFAIL) {
- error = ENOMEM;
- goto out;
- }
- panic("pmap_remap_pages: get ptp failed");
- }
+ ma = xpmap_ptom(pa);
}
- /*
- * Get first view on old PTE
- * on SMP the PTE might gain PG_U and PG_M flags
- * before we zap it later
- */
- opte = pte_get_ma(&ptes[x86_btop(va)]); /* old PTE */
- XENPRINTK(("npte %p opte %p ptes %p idx %03x\n",
- (void *)npte, (void *)opte, ptes, x86_btop(va)));
- XENPRINTF(("pmap_remap_pages pa %08lx va %08lx opte %08x npte %08x "
- "count %ld\n", pa, va, opte, npte,
- pmap->pm_stats.wired_count));
- //printf("npte %p opte %p ptes %p idx %03x\n", (void *)npte, (void *)opte, ptes, x86_btop(va));
- //printf("pmap_remap_pages pa %08lx va %08lx opte %08x npte %08x count %ld\n", pa, va, opte, npte, pmap->pm_stats.wired_count);
-
- if (prot & VM_PROT_WRITE)
- npte |= (PG_M | PG_RW);
- else
- npte |= PG_RO;
-
- /*
- * is there currently a valid mapping at our VA and does it
- * map to the same MA as the one we want to map ?
- */
- if (pmap_valid_entry(opte) && ((opte & PG_FRAME) == pa)) {
- /*
- * first, calculate pm_stats updates. resident count will not
- * change since we are replacing/changing a valid mapping.
- * wired count might change...
- */
- pmap->pm_stats.wired_count += 1 - ((opte & PG_W) ? 1 : 0);
-
- //printf("pmap_remap_pages opte == pa");
- /* zap! */
- maptp = (pt_entry_t *)vtomach((vaddr_t)&ptes[x86_btop(va)]);
- error = xpq_update_foreign(maptp, npte, dom);
-
- /*
- * The protection bits should not have changed
- */
- if ((npte & PG_RW)
- || ((opte & (PG_M | PG_RW)) != (PG_M | PG_RW)))
- panic("pmap_remap_pages protection changed\n");
- /*
- * Might be cached in the TLB as being writable
- * if this is on the PVLIST, sync R/M bit
- */
- KDASSERT((opte & PG_PVLIST) == 0);
- goto shootdown_now;
- }
-
- /*
- * no managed mapping for pages mapped through pmap_remap_pages.
- */
-
- /*
- * is there currently a valid mapping at our VA?
- */
-
- if (pmap_valid_entry(opte)) {
- /*
- * changing PAs: we must remove the old one first
- */
-
- /*
- * first, calculate pm_stats updates. resident count will not
- * change since we are replacing/changing a valid mapping.
- * wired count might change...
- */
- pmap->pm_stats.wired_count += 1 - ((opte & PG_W) ? 1 : 0);
-
- if (opte & PG_PVLIST) {
- opte = xpmap_mtop(opte);
- KDASSERT((opte & PG_FRAME) != (KERNTEXTOFF - KERNBASE));
-
- pg = PHYS_TO_VM_PAGE(opte & PG_FRAME);
-#ifdef DIAGNOSTIC
- if (pg == NULL)
- panic("pmap_remap_pages: PG_PVLIST mapping with "
- "unmanaged page "
- "pa = 0x%lx (0x%lx)", pa, atop(pa));
-#endif
- mdpg = &pg->mdpage;
- old_pvh = &mdpg->mp_pvhead;
-
- /* NULL new_pvh since page will not be managed */
- pmap_lock_pvhs(old_pvh, NULL);
-
- //printf("pmap change pa");
- /* zap! */
- opte = pte_get_ma(&ptes[x86_btop(va)]);
- maptp = (pt_entry_t *)vtomach(
- (vaddr_t)&ptes[x86_btop(va)]);
- error = xpq_update_foreign(maptp, npte, dom);
-
- pve = pmap_remove_pv(old_pvh, pmap, va);
- KASSERT(pve != 0);
- mdpg->mp_attrs |= opte;
-
- pmap_free_pv(pmap, pve);
- simple_unlock(&old_pvh->pvh_lock);
-
- goto shootdown_test;
- }
- } else {
- pmap->pm_stats.resident_count++;
- pmap->pm_stats.wired_count++;
- if (ptp) {
- dptpwire = 1;
- ptp->wire_count++;
- }
- }
-
- //printf("pmap initial setup");
- maptp = (pt_entry_t *)vtomach((vaddr_t)&ptes[x86_btop(va)]);
- error = xpq_update_foreign(maptp, npte, dom);
- if (error) {
- printf("pmap_remap_pages: xpq_update_foreign failed va=%lx"
- " npte=%lx error=%d dptpwire=%d\n",
- va, (unsigned long)npte, error, dptpwire);
- ptp->wire_count -= dptpwire;
- /* XXX fix other stats? */
- goto out;
- }
-
-shootdown_test:
- /* Update page attributes if needed */
- if ((opte & (PG_V | PG_U)) == (PG_V | PG_U)) {
-#if defined(MULTIPROCESSOR)
- int32_t cpumask = 0;
-#endif
-shootdown_now:
-#if defined(MULTIPROCESSOR)
- pmap_tlb_shootdown(pmap, va, opte, &cpumask);
- pmap_tlb_shootnow(cpumask);
-#else
- /* Don't bother deferring in the single CPU case. */
- if (pmap_is_curpmap(pmap))
- pmap_update_pg(va);
-#endif
- }
-
-out:
- pmap_unmap_ptes(pmap);
- PMAP_MAP_TO_HEAD_UNLOCK();
-
- //printf("pmap_remap_pages: %d\n", error);
- return error;
+ return pmap_enter_ma(pmap, va, ma, pa, prot, flags, DOMID_SELF);
}
/*
Index: xen/xbdback.c
===================================================================
--- xen/xbdback.c (revision 1481)
+++ xen/xbdback.c (working copy)
@@ -391,8 +391,8 @@ xbdback_ctrlif_rx(ctrl_msg_t *msg, unsig
}
xbdi->ma_ring = req->shmem_frame << PAGE_SHIFT;
- error = pmap_remap_pages(pmap_kernel(), ring_addr,
- xbdi->ma_ring, 1, VM_PROT_READ | VM_PROT_WRITE,
+ error = pmap_enter_ma(pmap_kernel(), ring_addr,
+ xbdi->ma_ring, 0, VM_PROT_READ | VM_PROT_WRITE,
PMAP_WIRED | PMAP_CANFAIL, req->domid);
if (error) {
uvm_km_free(kernel_map, ring_addr, PAGE_SIZE,
Index: xen/privcmd.c
===================================================================
--- xen/privcmd.c (revision 1540)
+++ xen/privcmd.c (working copy)
@@ -146,10 +146,12 @@ privcmd_ioctl(void *v)
for (j = 0; j < mentry.npages; j++) {
//printf("remap va 0x%lx to 0x%lx\n", va, ma);
- if ((error = pmap_remap_pages(pmap, va, ma, 1,
+ error = pmap_enter_ma(pmap, va, ma, 0,
prot, PMAP_WIRED | PMAP_CANFAIL,
- mcmd->dom)))
+ mcmd->dom);
+ if (error != 0) {
return error;
+ }
va += PAGE_SIZE;
ma += PAGE_SIZE;
}
@@ -206,7 +208,7 @@ privcmd_ioctl(void *v)
* these into fewer hypercalls.
*/
//printf("mmapbatch: va=%lx ma=%lx dom=%d\n", va, ma, pmb->dom);
- error = pmap_remap_pages(pmap, va, ma, 1, prot,
+ error = pmap_enter_ma(pmap, va, ma, 0, prot,
PMAP_WIRED | PMAP_CANFAIL, pmb->dom);
if (error != 0) {
printf("mmapbatch: remap error %d!\n", error);
Index: xen/xennetback.c
===================================================================
--- xen/xennetback.c (revision 1540)
+++ xen/xennetback.c (working copy)
@@ -381,14 +381,14 @@ xnetback_ctrlif_rx(ctrl_msg_t *msg, unsi
}
xneti->xni_ma_rxring = req->rx_shmem_frame << PAGE_SHIFT;
xneti->xni_ma_txring = req->tx_shmem_frame << PAGE_SHIFT;
- error = pmap_remap_pages(pmap_kernel(), ring_rxaddr,
- xneti->xni_ma_rxring, 1, VM_PROT_READ | VM_PROT_WRITE,
+ error = pmap_enter_ma(pmap_kernel(), ring_rxaddr,
+ xneti->xni_ma_rxring, 0, VM_PROT_READ | VM_PROT_WRITE,
PMAP_WIRED | PMAP_CANFAIL, req->domid);
if (error) {
goto fail_1;
}
- error = pmap_remap_pages(pmap_kernel(), ring_txaddr,
- xneti->xni_ma_txring, 1, VM_PROT_READ | VM_PROT_WRITE,
+ error = pmap_enter_ma(pmap_kernel(), ring_txaddr,
+ xneti->xni_ma_txring, 0, VM_PROT_READ | VM_PROT_WRITE,
PMAP_WIRED | PMAP_CANFAIL, req->domid);
if (error) {
pmap_remove(pmap_kernel(), ring_rxaddr,
--NextPart-20060123053029-0429100--