pmap_enter:

- when overwriting an existing mapping for the same page,
  inherit R/M bits so that they won't be lost.
- xen: don't leave ptp on error.
This commit is contained in:
yamt 2008-01-20 22:41:55 +00:00
parent f093a1dc3b
commit 569f933f28
1 changed files with 35 additions and 15 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: pmap.c,v 1.40 2008/01/20 21:56:11 yamt Exp $ */ /* $NetBSD: pmap.c,v 1.41 2008/01/20 22:41:55 yamt Exp $ */
/* /*
* Copyright (c) 2007 Manuel Bouyer. * Copyright (c) 2007 Manuel Bouyer.
@ -154,7 +154,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.40 2008/01/20 21:56:11 yamt Exp $"); __KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.41 2008/01/20 22:41:55 yamt Exp $");
#include "opt_user_ldt.h" #include "opt_user_ldt.h"
#include "opt_lockdebug.h" #include "opt_lockdebug.h"
@ -3842,21 +3842,41 @@ pmap_enter(struct pmap *pmap, vaddr_t va, paddr_t pa, vm_prot_t prot,
*/ */
ptep = &ptes[pl1_i(va)]; ptep = &ptes[pl1_i(va)];
do {
#ifdef XEN
if (domid != DOMID_SELF) {
int s = splvm();
opte = *ptep; opte = *ptep;
error = xpq_update_foreign((pt_entry_t *)vtomach((vaddr_t)ptep),
npte, domid); /*
splx(s); * if the same page, inherit PG_U and PG_M.
if (error) { */
pmap_unmap_ptes(pmap, pmap2); if (((opte ^ npte) & (PG_FRAME | PG_V)) == 0) {
goto out; npte |= opte & (PG_U | PG_M);
} }
} else #if defined(XEN)
#endif /* XEN */ if (domid != DOMID_SELF) {
opte = pmap_pte_testset(ptep, npte); /* zap! */ /* pmap_pte_cas with error handling */
int s = splvm();
if (opte != *ptep) {
splx(s);
continue;
}
error = xpq_update_foreign(
(pt_entry_t *)vtomach((vaddr_t)ptep), npte, domid);
splx(s);
if (error) {
struct vm_page *empty_ptps = NULL;
if (ptp != NULL && ptp->wire_count <= 1) {
pmap_free_ptp(pmap, ptp, va, ptes, pdes,
&empty_ptps);
}
pmap_unmap_ptes(pmap, pmap2);
pmap_free_empty_ptps(empty_ptps);
goto out;
}
break;
}
#endif /* defined(XEN) */
} while (pmap_pte_cas(ptep, opte, npte) != opte);
/* /*
* update statistics and PTP's reference count. * update statistics and PTP's reference count.