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>