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