diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/i386/xen/xen_machdep.c | 248 |
1 files changed, 33 insertions, 215 deletions
diff --git a/sys/i386/xen/xen_machdep.c b/sys/i386/xen/xen_machdep.c index 7784c71..725a552 100644 --- a/sys/i386/xen/xen_machdep.c +++ b/sys/i386/xen/xen_machdep.c @@ -36,8 +36,10 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/systm.h> #include <sys/bus.h> +#include <sys/lock.h> #include <sys/mount.h> #include <sys/malloc.h> +#include <sys/mutex.h> #include <sys/kernel.h> #include <sys/reboot.h> #include <sys/sysproto.h> @@ -61,7 +63,6 @@ __FBSDID("$FreeBSD$"); #include <machine/xen/xenvar.h> #include <machine/xen/xenfunc.h> #include <machine/xen/xenpmap.h> -#include <machine/xen/xenbus.h> #include <machine/xen/xenfunc.h> #include <xen/interface/memory.h> #include <machine/xen/features.h> @@ -851,6 +852,37 @@ initvalues(start_info_t *startinfo) xen_start_info = startinfo; xen_phys_machine = (xen_pfn_t *)startinfo->mfn_list; + IdlePTD = (pd_entry_t *)((uint8_t *)startinfo->pt_base + PAGE_SIZE); + l1_pages = 0; + +#ifdef PAE + l3_pages = 1; + l2_pages = 0; + IdlePDPT = (pd_entry_t *)startinfo->pt_base; + IdlePDPTma = xpmap_ptom(VTOP(startinfo->pt_base)); + for (i = (KERNBASE >> 30); + (i < 4) && (IdlePDPT[i] != 0); i++) + l2_pages++; + /* + * Note that only one page directory has been allocated at this point. + * Thus, if KERNBASE + */ + for (i = 0; i < l2_pages; i++) + IdlePTDma[i] = xpmap_ptom(VTOP(IdlePTD + i*PAGE_SIZE)); + + l2_pages = (l2_pages == 0) ? 1 : l2_pages; +#else + l3_pages = 0; + l2_pages = 1; +#endif + for (i = (((KERNBASE>>18) & PAGE_MASK)>>PAGE_SHIFT); + (i<l2_pages*NPDEPG) && (i<(VM_MAX_KERNEL_ADDRESS>>PDRSHIFT)); i++) { + + if (IdlePTD[i] == 0) + break; + l1_pages++; + } + /* number of pages allocated after the pts + 1*/; cur_space = xen_start_info->pt_base + ((xen_start_info->nr_pt_frames) + 3 )*PAGE_SIZE; @@ -1123,220 +1155,6 @@ trap_info_t trap_table[] = { }; -static void -shutdown_handler(struct xenbus_watch *watch, - const char **vec, unsigned int len) -{ - char *str; - struct xenbus_transaction xbt; - int err, howto; - struct reboot_args uap; - - howto = 0; - - again: - err = xenbus_transaction_start(&xbt); - if (err) - return; - str = (char *)xenbus_read(xbt, "control", "shutdown", NULL); - /* Ignore read errors and empty reads. */ - if (XENBUS_IS_ERR_READ(str)) { - xenbus_transaction_end(xbt, 1); - return; - } - - xenbus_write(xbt, "control", "shutdown", ""); - - err = xenbus_transaction_end(xbt, 0); - if (err == EAGAIN) { - free(str, M_DEVBUF); - goto again; - } - - if (strcmp(str, "reboot") == 0) - howto = 0; - else if (strcmp(str, "poweroff") == 0) - howto |= (RB_POWEROFF | RB_HALT); - else if (strcmp(str, "halt") == 0) - howto |= RB_HALT; - else if (strcmp(str, "suspend") == 0) - howto = -1; - else { - printf("Ignoring shutdown request: %s\n", str); - goto done; - } -#ifdef notyet - if (howto == -1) { - do_suspend(NULL); - goto done; - } -#else - if (howto == -1) { - printf("suspend not currently supported\n"); - goto done; - } -#endif - uap.opt = howto; - reboot(curthread, &uap); - done: - free(str, M_DEVBUF); -} - -static struct xenbus_watch shutdown_watch = { - .node = "control/shutdown", - .callback = shutdown_handler -}; - - -void setup_shutdown_watcher(void *unused); - - -void -setup_shutdown_watcher(void *unused) -{ - if (register_xenbus_watch(&shutdown_watch)) - printf("Failed to set shutdown watcher\n"); -} - - -SYSINIT(shutdown, SI_SUB_RUN_SCHEDULER, SI_ORDER_ANY, setup_shutdown_watcher, NULL); - -#ifdef notyet - -static void -xen_suspend(void *ignore) -{ - int i, j, k, fpp; - - extern void time_resume(void); - extern unsigned long max_pfn; - extern unsigned long *pfn_to_mfn_frame_list_list; - extern unsigned long *pfn_to_mfn_frame_list[]; - -#ifdef CONFIG_SMP -#error "do_suspend must be run cpu 0 - need to create separate thread" - cpumask_t prev_online_cpus; - int vcpu_prepare(int vcpu); -#endif - - int err = 0; - - PANIC_IF(smp_processor_id() != 0); - -#if defined(CONFIG_SMP) && !defined(CONFIG_HOTPLUG_CPU) - if (num_online_cpus() > 1) { - printk(KERN_WARNING "Can't suspend SMP guests " - "without CONFIG_HOTPLUG_CPU\n"); - return -EOPNOTSUPP; - } -#endif - - xenbus_suspend(); - -#ifdef CONFIG_SMP - lock_cpu_hotplug(); - /* - * Take all other CPUs offline. We hold the hotplug semaphore to - * avoid other processes bringing up CPUs under our feet. - */ - cpus_clear(prev_online_cpus); - while (num_online_cpus() > 1) { - for_each_online_cpu(i) { - if (i == 0) - continue; - unlock_cpu_hotplug(); - err = cpu_down(i); - lock_cpu_hotplug(); - if (err != 0) { - printk(KERN_CRIT "Failed to take all CPUs " - "down: %d.\n", err); - goto out_reenable_cpus; - } - cpu_set(i, prev_online_cpus); - } - } -#endif /* CONFIG_SMP */ - - preempt_disable(); - - - __cli(); - preempt_enable(); -#ifdef SMP - unlock_cpu_hotplug(); -#endif - gnttab_suspend(); - - pmap_kremove(HYPERVISOR_shared_info); - - xen_start_info->store_mfn = mfn_to_pfn(xen_start_info->store_mfn); - xen_start_info->console.domU.mfn = mfn_to_pfn(xen_start_info->console.domU.mfn); - - /* - * We'll stop somewhere inside this hypercall. When it returns, - * we'll start resuming after the restore. - */ - HYPERVISOR_suspend(VTOMFN(xen_start_info)); - - pmap_kenter_ma(HYPERVISOR_shared_info, xen_start_info->shared_info); - set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info); - -#if 0 - memset(empty_zero_page, 0, PAGE_SIZE); -#endif - HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list = - VTOMFN(pfn_to_mfn_frame_list_list); - - fpp = PAGE_SIZE/sizeof(unsigned long); - for (i = 0, j = 0, k = -1; i < max_pfn; i += fpp, j++) { - if ((j % fpp) == 0) { - k++; - pfn_to_mfn_frame_list_list[k] = - VTOMFN(pfn_to_mfn_frame_list[k]); - j = 0; - } - pfn_to_mfn_frame_list[k][j] = - VTOMFN(&phys_to_machine_mapping[i]); - } - HYPERVISOR_shared_info->arch.max_pfn = max_pfn; - - gnttab_resume(); - - irq_resume(); - - time_resume(); - - __sti(); - - xencons_resume(); - -#ifdef CONFIG_SMP - for_each_cpu(i) - vcpu_prepare(i); - -#endif - /* - * Only resume xenbus /after/ we've prepared our VCPUs; otherwise - * the VCPU hotplug callback can race with our vcpu_prepare - */ - xenbus_resume(); - -#ifdef CONFIG_SMP - out_reenable_cpus: - for_each_cpu_mask(i, prev_online_cpus) { - j = cpu_up(i); - if ((j != 0) && !cpu_online(i)) { - printk(KERN_CRIT "Failed to bring cpu " - "%d back up (%d).\n", - i, j); - err = j; - } - } -#endif - return err; -} - -#endif /* notyet */ /********** CODE WORTH KEEPING ABOVE HERE *****************/ void xen_failsafe_handler(void); |