Subject: Re: port-xen/30635
To: None <port-xen-maintainer@netbsd.org, gnats-admin@netbsd.org,>
From: Jed Davis <jdev@panix.com>
List: netbsd-bugs
Date: 08/30/2005 02:14:01
The following reply was made to PR port-xen/30635; it has been noted by GNATS.
From: Jed Davis <jdev@panix.com>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: port-xen/30635
Date: Mon, 29 Aug 2005 22:13:47 -0400
--=-=-=
I've found at least one other bug in xend that can trigger the panic,
though it's harder to reproduce. I also have a better fix for it:
making pmap_remap_pages roll back its increment of the PTP's
wire_count if the PTE change request is rejected by Xen; a patch is
attached (and also sent to port-xen@).
--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment; filename=ptp_wire_rollback.patch
Content-Description: Keep ptp->wire_count consistent in case of error.
Index: sys/arch/xen/i386/pmap.c
===================================================================
RCS file: /cvsroot/src/sys/arch/xen/i386/pmap.c,v
retrieving revision 1.8.2.3
diff -u -p -r1.8.2.3 pmap.c
--- sys/arch/xen/i386/pmap.c 6 Jun 2005 12:16:10 -0000 1.8.2.3
+++ sys/arch/xen/i386/pmap.c 30 Aug 2005 01:39:13 -0000
@@ -4135,7 +4135,9 @@ pmap_remap_pages(pmap, va, pa, npages, f
struct vm_page_md *mdpg;
struct pv_head *old_pvh;
struct pv_entry *pve = NULL; /* XXX gcc */
- int error;
+ int error, dptpwire;
+
+ dptpwire = 0;
XENPRINTK(("pmap_remap_pages(%p, %p, %p, %d, %08x, %d)\n",
pmap, (void *)va, (void *)pa, npages, flags, dom));
@@ -4301,14 +4305,23 @@ pmap_remap_pages(pmap, va, pa, npages, f
} else {
pmap->pm_stats.resident_count++;
pmap->pm_stats.wired_count++;
- if (ptp)
+ 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; %d\n",
+ 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)) {
--=-=-=--