svn commit: r186130 - in user/dfr/xenhvm/6/sys: dev/xen/blkfront
i386/include/xen i386/xen xen xen/evtchn
Doug Rabson
dfr at FreeBSD.org
Mon Dec 15 07:42:24 PST 2008
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);
More information about the svn-src-user
mailing list