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)))))

--=-=-=--