Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 15 Dec 2008 15:42:24 +0000 (UTC)
From:      Doug Rabson <dfr@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r186130 - in user/dfr/xenhvm/6/sys: dev/xen/blkfront i386/include/xen i386/xen xen xen/evtchn
Message-ID:  <200812151542.mBFFgOJF099155@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: dfr
Date: Mon Dec 15 15:42:24 2008
New Revision: 186130
URL: http://svn.freebsd.org/changeset/base/186130

Log:
  Fix PV mode suspend/resume.

Modified:
  user/dfr/xenhvm/6/sys/dev/xen/blkfront/blkfront.c
  user/dfr/xenhvm/6/sys/i386/include/xen/xenpmap.h
  user/dfr/xenhvm/6/sys/i386/xen/pmap.c
  user/dfr/xenhvm/6/sys/xen/evtchn/evtchn.c
  user/dfr/xenhvm/6/sys/xen/gnttab.c
  user/dfr/xenhvm/6/sys/xen/reboot.c

Modified: user/dfr/xenhvm/6/sys/dev/xen/blkfront/blkfront.c
==============================================================================
--- user/dfr/xenhvm/6/sys/dev/xen/blkfront/blkfront.c	Mon Dec 15 15:41:28 2008	(r186129)
+++ user/dfr/xenhvm/6/sys/dev/xen/blkfront/blkfront.c	Mon Dec 15 15:42:24 2008	(r186130)
@@ -370,6 +370,19 @@ blkfront_attach(device_t dev)
 }
 
 static int
+blkfront_suspend(device_t dev)
+{
+	struct blkfront_info *info = device_get_softc(dev);
+
+	/* Prevent new requests being issued until we fix things up. */
+	mtx_lock(&blkif_io_lock);
+	info->connected = BLKIF_STATE_SUSPENDED;
+	mtx_unlock(&blkif_io_lock);
+
+	return (0);
+}
+
+static int
 blkfront_resume(device_t dev)
 {
 	struct blkfront_info *info = device_get_softc(dev);
@@ -377,7 +390,7 @@ blkfront_resume(device_t dev)
 
 	DPRINTK("blkfront_resume: %s\n", xenbus_get_node(dev));
 
-	blkif_free(info, info->connected == BLKIF_STATE_CONNECTED);
+	blkif_free(info, 1);
 	err = talk_to_backend(dev, info);
 	if (info->connected == BLKIF_STATE_SUSPENDED && !err)
 		blkif_recover(info);
@@ -1082,7 +1095,7 @@ static device_method_t blkfront_methods[
 	DEVMETHOD(device_attach,        blkfront_attach), 
 	DEVMETHOD(device_detach,        blkfront_detach), 
 	DEVMETHOD(device_shutdown,      bus_generic_shutdown), 
-	DEVMETHOD(device_suspend,       bus_generic_suspend), 
+	DEVMETHOD(device_suspend,       blkfront_suspend), 
 	DEVMETHOD(device_resume,        blkfront_resume), 
  
 	/* Xenbus interface */

Modified: user/dfr/xenhvm/6/sys/i386/include/xen/xenpmap.h
==============================================================================
--- user/dfr/xenhvm/6/sys/i386/include/xen/xenpmap.h	Mon Dec 15 15:41:28 2008	(r186129)
+++ user/dfr/xenhvm/6/sys/i386/include/xen/xenpmap.h	Mon Dec 15 15:42:24 2008	(r186130)
@@ -49,6 +49,8 @@ void xen_check_queue(void);
 #if 0
 void pmap_ref(pt_entry_t *pte, vm_paddr_t ma);
 #endif
+void pmap_suspend(void);
+void pmap_resume(void);
 
 #ifdef INVARIANTS
 #define xen_queue_pt_update(a, b) _xen_queue_pt_update((a), (b), __FILE__, __LINE__)

Modified: user/dfr/xenhvm/6/sys/i386/xen/pmap.c
==============================================================================
--- user/dfr/xenhvm/6/sys/i386/xen/pmap.c	Mon Dec 15 15:41:28 2008	(r186129)
+++ user/dfr/xenhvm/6/sys/i386/xen/pmap.c	Mon Dec 15 15:42:24 2008	(r186130)
@@ -3701,6 +3701,71 @@ pmap_addr_hint(vm_object_t obj, vm_offse
 	return addr;
 }
 
+#ifdef XEN
+
+void
+pmap_suspend()
+{
+	pmap_t pmap;
+	int i, pdir, offset;
+	vm_paddr_t pdirma;
+	mmu_update_t mu[4];
+
+	/*
+	 * We need to remove the recursive mapping structure from all
+	 * our pmaps so that Xen doesn't get confused when it restores
+	 * the page tables. The recursive map lives at page directory
+	 * index PTDPTDI. We assume that the suspend code has stopped
+	 * the other vcpus (if any).
+	 */
+	LIST_FOREACH(pmap, &allpmaps, pm_list) {
+		for (i = 0; i < 4; i++) {
+			/*
+			 * Figure out which page directory (L2) page
+			 * contains this bit of the recursive map and
+			 * the offset within that page of the map
+			 * entry
+			 */
+			pdir = (PTDPTDI + i) / NPDEPG;
+			offset = (PTDPTDI + i) % NPDEPG;
+			pdirma = pmap->pm_pdpt[pdir] & PG_FRAME;
+			mu[i].ptr = pdirma + offset * sizeof(pd_entry_t);
+			mu[i].val = 0;
+		}
+		HYPERVISOR_mmu_update(mu, 4, NULL, DOMID_SELF);
+	}
+}
+
+void
+pmap_resume()
+{
+	pmap_t pmap;
+	int i, pdir, offset;
+	vm_paddr_t pdirma;
+	mmu_update_t mu[4];
+
+	/*
+	 * Restore the recursive map that we removed on suspend.
+	 */
+	LIST_FOREACH(pmap, &allpmaps, pm_list) {
+		for (i = 0; i < 4; i++) {
+			/*
+			 * Figure out which page directory (L2) page
+			 * contains this bit of the recursive map and
+			 * the offset within that page of the map
+			 * entry
+			 */
+			pdir = (PTDPTDI + i) / NPDEPG;
+			offset = (PTDPTDI + i) % NPDEPG;
+			pdirma = pmap->pm_pdpt[pdir] & PG_FRAME;
+			mu[i].ptr = pdirma + offset * sizeof(pd_entry_t);
+			mu[i].val = (pmap->pm_pdpt[i] & PG_FRAME) | PG_V;
+		}
+		HYPERVISOR_mmu_update(mu, 4, NULL, DOMID_SELF);
+	}
+}
+
+#endif
 
 #if defined(PMAP_DEBUG)
 pmap_pid_dump(int pid)

Modified: user/dfr/xenhvm/6/sys/xen/evtchn/evtchn.c
==============================================================================
--- user/dfr/xenhvm/6/sys/xen/evtchn/evtchn.c	Mon Dec 15 15:41:28 2008	(r186129)
+++ user/dfr/xenhvm/6/sys/xen/evtchn/evtchn.c	Mon Dec 15 15:42:24 2008	(r186130)
@@ -265,6 +265,7 @@ bind_caller_port_to_irq(unsigned int cal
         }
 
         irq_bindcount[irq]++;
+	unmask_evtchn(caller_port);
 
  out:
         mtx_unlock_spin(&irq_mapping_update_lock);
@@ -291,6 +292,7 @@ bind_local_port_to_irq(unsigned int loca
         evtchn_to_irq[local_port] = irq;
         irq_info[irq] = mk_irq_info(IRQT_LOCAL_PORT, 0, local_port);
         irq_bindcount[irq]++;
+	unmask_evtchn(local_port);
 
  out:
         mtx_unlock_spin(&irq_mapping_update_lock);
@@ -752,7 +754,7 @@ notify_remote_via_irq(int irq)
 	if (VALID_EVTCHN(evtchn))
 		notify_remote_via_evtchn(evtchn);
 	else
-		panic("invalid evtchn");
+		panic("invalid evtchn %d", irq);
 }
 
 /* required for support of physical devices */

Modified: user/dfr/xenhvm/6/sys/xen/gnttab.c
==============================================================================
--- user/dfr/xenhvm/6/sys/xen/gnttab.c	Mon Dec 15 15:41:28 2008	(r186129)
+++ user/dfr/xenhvm/6/sys/xen/gnttab.c	Mon Dec 15 15:42:24 2008	(r186130)
@@ -515,12 +515,10 @@ gnttab_resume(void)
 int
 gnttab_suspend(void)
 {	
-	int i, pages;
-
-	pages = (PAGE_SIZE*nr_grant_frames) >> PAGE_SHIFT;
+	int i;
 
-	for (i = 0; i < pages; i++)
-		PT_SET_MA(shared + (i*PAGE_SIZE), (vm_paddr_t)0);
+	for (i = 0; i < nr_grant_frames; i++)
+		pmap_kremove((vm_offset_t) shared + i * PAGE_SIZE);
 
 	return (0);
 }

Modified: user/dfr/xenhvm/6/sys/xen/reboot.c
==============================================================================
--- user/dfr/xenhvm/6/sys/xen/reboot.c	Mon Dec 15 15:41:28 2008	(r186129)
+++ user/dfr/xenhvm/6/sys/xen/reboot.c	Mon Dec 15 15:42:24 2008	(r186130)
@@ -169,7 +169,7 @@ static void 
 xen_suspend()
 {
 	int i, j, k, fpp;
-	unsigned long max_pfn;
+	unsigned long max_pfn, start_info_mfn;
 
 #ifdef SMP
 	cpumask_t map;
@@ -212,7 +212,10 @@ xen_suspend()
 	 * We'll stop somewhere inside this hypercall. When it returns,
 	 * we'll start resuming after the restore.
 	 */
-	HYPERVISOR_suspend(VTOMFN(xen_start_info));
+	start_info_mfn = VTOMFN(xen_start_info);
+	pmap_suspend();
+	HYPERVISOR_suspend(start_info_mfn);
+	pmap_resume();
 
 	pmap_kenter_ma((vm_offset_t) shared_info, xen_start_info->shared_info);
 	HYPERVISOR_shared_info = shared_info;
@@ -235,12 +238,9 @@ xen_suspend()
 
 	gnttab_resume();
 	irq_resume();
-	cpu_initclocks();
 	local_irq_enable();
 	xencons_resume();
 
-	printf("UP\n");
-
 #ifdef CONFIG_SMP
 	for_each_cpu(i)
 		vcpu_prepare(i);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200812151542.mBFFgOJF099155>