Subject: Re: IOCTL_PRIVCMD_MMAP
To: None <port-xen@NetBSD.org>
From: Jed Davis <jdev@panix.com>
List: port-xen
Date: 08/29/2005 22:02:23
--=-=-=
Jed Davis <jdev@panix.com> writes:
> patch to xend; in both cases, with my change to IOCTL_PRIVCMD_MMAP,
> the panic is replaced by xend dying with:
>
> xen.lowlevel.xu.PortError: Failed to map domain control interface
>
> At one point I noticed that one of the xpq_update_foreign calls in
> pmap_remap_pages was failing when this happens; I'll look into that
> some more.
It's failing because the foreign domain no longer exists, but xend
isn't aware of that and tries to map its control interface anyway. I
have here a patch that rolls back the increment to the PTP's
wire_count if the update fails, and that avoids the panic without
needing to lock the remapped memory:
--=-=-=
Content-Type: text/x-patch
Content-Disposition: inline; 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)) {
--=-=-=
--
(let ((C call-with-current-continuation)) (apply (lambda (x y) (x y)) (map
((lambda (r) ((C C) (lambda (s) (r (lambda l (apply (s s) l)))))) (lambda
(f) (lambda (l) (if (null? l) C (lambda (k) (display (car l)) ((f (cdr l))
(C k))))))) '((#\J #\d #\D #\v #\s) (#\e #\space #\a #\i #\newline)))))
--=-=-=--