From df0ed71781b42b3334d3cf4200cf60ae4eb0ec19 Mon Sep 17 00:00:00 2001 From: dfr Date: Wed, 1 Apr 2009 17:06:28 +0000 Subject: [PATCH] Fix the Xen build for i386 PV mode. --- sys/dev/xen/balloon/balloon.c | 8 +++++ sys/dev/xen/console/console.c | 3 +- sys/i386/include/xen/xenpmap.h | 2 ++ sys/i386/include/xen/xenvar.h | 2 ++ sys/i386/xen/pmap.c | 66 ++++++++++++++++++++++++++++++++++ sys/i386/xen/xen_machdep.c | 36 ++++++++++++++++++- sys/xen/evtchn/evtchn.c | 2 +- sys/xen/reboot.c | 8 +++-- 8 files changed, 121 insertions(+), 6 deletions(-) diff --git a/sys/dev/xen/balloon/balloon.c b/sys/dev/xen/balloon/balloon.c index c23433cbebcd..6948173765a9 100644 --- a/sys/dev/xen/balloon/balloon.c +++ b/sys/dev/xen/balloon/balloon.c @@ -167,6 +167,8 @@ minimum_target(void) { #ifdef XENHVM #define max_pfn physmem +#else +#define max_pfn HYPERVISOR_shared_info->arch.max_pfn #endif unsigned long min_pages, curr_pages = current_target(); @@ -256,6 +258,7 @@ increase_reservation(unsigned long nr_pages) set_phys_to_machine(pfn, frame_list[i]); +#if 0 #ifndef XENHVM /* Link back into the page tables if not highmem. */ if (pfn < max_low_pfn) { @@ -267,6 +270,7 @@ increase_reservation(unsigned long nr_pages) PASSING(ret == 0, ("HYPERVISOR_update_va_mapping failed")); } +#endif #endif /* Relinquish the page back to the allocator. */ @@ -447,6 +451,9 @@ balloon_init(void *arg) { #ifndef XENHVM vm_page_t page; + unsigned long pfn; + +#define max_pfn HYPERVISOR_shared_info->arch.max_pfn #endif if (!is_running_on_xen()) @@ -477,6 +484,7 @@ balloon_init(void *arg) page = PHYS_TO_VM_PAGE(pfn << PAGE_SHIFT); balloon_append(page); } +#undef max_pfn #endif target_watch.callback = watch_target; diff --git a/sys/dev/xen/console/console.c b/sys/dev/xen/console/console.c index 0634dadada30..ac8ebac9edb0 100644 --- a/sys/dev/xen/console/console.c +++ b/sys/dev/xen/console/console.c @@ -225,7 +225,6 @@ static int xc_attach(device_t dev) { int error; - struct xc_softc *sc = (struct xc_softc *)device_get_softc(dev); if (xen_start_info->flags & SIF_INITDOMAIN) { xc_consdev.cn_putc = xccnputc_dom0; @@ -247,7 +246,7 @@ xc_attach(device_t dev) 0, "console", NULL, - xencons_priv_interrupt, + xencons_priv_interrupt, NULL, INTR_TYPE_TTY, NULL); KASSERT(error >= 0, ("can't register console interrupt")); diff --git a/sys/i386/include/xen/xenpmap.h b/sys/i386/include/xen/xenpmap.h index 4bfd99e65e55..b8a545e55d3b 100644 --- a/sys/i386/include/xen/xenpmap.h +++ b/sys/i386/include/xen/xenpmap.h @@ -45,6 +45,8 @@ void xen_pt_pin(vm_paddr_t); void xen_pt_unpin(vm_paddr_t); void xen_flush_queue(void); void pmap_ref(pt_entry_t *pte, vm_paddr_t ma); +void pmap_suspend(void); +void pmap_resume(void); void xen_check_queue(void); #ifdef INVARIANTS diff --git a/sys/i386/include/xen/xenvar.h b/sys/i386/include/xen/xenvar.h index 402bc8af4a0b..cefbb058c1c5 100644 --- a/sys/i386/include/xen/xenvar.h +++ b/sys/i386/include/xen/xenvar.h @@ -40,6 +40,8 @@ extern int xendebug_flags; #include extern xen_pfn_t *xen_phys_machine; +extern xen_pfn_t *xen_pfn_to_mfn_frame_list[16]; +extern xen_pfn_t *xen_pfn_to_mfn_frame_list_list; #if 0 #define TRACE_ENTER XENPRINTF("(file=%s, line=%d) entered %s\n", __FILE__, __LINE__, __FUNCTION__) diff --git a/sys/i386/xen/pmap.c b/sys/i386/xen/pmap.c index 3725d0aa8f09..59947e8245f7 100644 --- a/sys/i386/xen/pmap.c +++ b/sys/i386/xen/pmap.c @@ -4100,6 +4100,72 @@ pmap_align_superpage(vm_object_t object, vm_ooffset_t offset, *addr = ((*addr + PDRMASK) & ~PDRMASK) + superpage_offset; } +#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) { diff --git a/sys/i386/xen/xen_machdep.c b/sys/i386/xen/xen_machdep.c index c99d754d0a7a..878f436fde7d 100644 --- a/sys/i386/xen/xen_machdep.c +++ b/sys/i386/xen/xen_machdep.c @@ -89,6 +89,8 @@ start_info_t *xen_start_info; shared_info_t *HYPERVISOR_shared_info; xen_pfn_t *xen_machine_phys = machine_to_phys_mapping; xen_pfn_t *xen_phys_machine; +xen_pfn_t *xen_pfn_to_mfn_frame_list[16]; +xen_pfn_t *xen_pfn_to_mfn_frame_list_list; int preemptable, init_first; extern unsigned int avail_space; @@ -810,6 +812,39 @@ shift_phys_machine(unsigned long *phys_machine, int nr_pages) } #endif /* ADD_ISA_HOLE */ +/* + * Build a directory of the pages that make up our Physical to Machine + * mapping table. The Xen suspend/restore code uses this to find our + * mapping table. + */ +static void +init_frame_list_list(void *arg) +{ + unsigned long nr_pages = xen_start_info->nr_pages; +#define FPP (PAGE_SIZE/sizeof(xen_pfn_t)) + int i, j, k; + + xen_pfn_to_mfn_frame_list_list = malloc(PAGE_SIZE, M_DEVBUF, M_WAITOK); + for (i = 0, j = 0, k = -1; i < nr_pages; + i += FPP, j++) { + if ((j & (FPP - 1)) == 0) { + k++; + xen_pfn_to_mfn_frame_list[k] = + malloc(PAGE_SIZE, M_DEVBUF, M_WAITOK); + xen_pfn_to_mfn_frame_list_list[k] = + VTOMFN(xen_pfn_to_mfn_frame_list[k]); + j = 0; + } + xen_pfn_to_mfn_frame_list[k][j] = + VTOMFN(&xen_phys_machine[i]); + } + + HYPERVISOR_shared_info->arch.max_pfn = nr_pages; + HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list + = VTOMFN(xen_pfn_to_mfn_frame_list_list); +} +SYSINIT(init_fll, SI_SUB_DEVFS, SI_ORDER_ANY, init_frame_list_list, NULL); + extern unsigned long physfree; int pdir, curoffset; @@ -1081,7 +1116,6 @@ initvalues(start_info_t *startinfo) PT_SET_MA(console_page, console_page_ma | PG_KERNEL); printk("#5\n"); - HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list = (unsigned long)xen_phys_machine; set_iopl.iopl = 1; PANIC_IF(HYPERVISOR_physdev_op(PHYSDEVOP_SET_IOPL, &set_iopl)); diff --git a/sys/xen/evtchn/evtchn.c b/sys/xen/evtchn/evtchn.c index 61b738b0d981..59d24b2df092 100644 --- a/sys/xen/evtchn/evtchn.c +++ b/sys/xen/evtchn/evtchn.c @@ -512,7 +512,7 @@ bind_interdomain_evtchn_to_irqhandler(unsigned int remote_domain, int bind_virq_to_irqhandler(unsigned int virq, unsigned int cpu, const char *devname, driver_filter_t filter, driver_intr_t handler, - unsigned long irqflags, unsigned int *irqp) + void *arg, unsigned long irqflags, unsigned int *irqp) { unsigned int irq; int error; diff --git a/sys/xen/reboot.c b/sys/xen/reboot.c index 892dfbf3c91a..04ba1326c8b7 100644 --- a/sys/xen/reboot.c +++ b/sys/xen/reboot.c @@ -176,9 +176,9 @@ xen_suspend() /* * Bind us to CPU 0 and stop any other VCPUs. */ - mtx_lock_spin(&sched_lock); + thread_lock(curthread); sched_bind(curthread, 0); - mtx_unlock_spin(&sched_lock); + thread_unlock(curthread); KASSERT(PCPU_GET(cpuid) == 0, ("xen_suspend: not running on cpu 0")); map = PCPU_GET(other_cpus) & ~stopped_cpus; @@ -188,8 +188,10 @@ xen_suspend() if (DEVICE_SUSPEND(root_bus) != 0) { printf("xen_suspend: device_suspend failed\n"); +#ifdef SMP if (map) restart_cpus(map); +#endif return; } @@ -253,7 +255,9 @@ xen_suspend() DEVICE_RESUME(root_bus); #ifdef SMP + thread_lock(curthread); sched_unbind(curthread); + thread_unlock(curthread); if (map) restart_cpus(map); #endif