From owner-p4-projects@FreeBSD.ORG Mon Jan 9 05:29:25 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 470C216A423; Mon, 9 Jan 2006 05:29:25 +0000 (GMT) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 1A06216A422 for ; Mon, 9 Jan 2006 05:29:25 +0000 (GMT) (envelope-from kmacy@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 935B143D48 for ; Mon, 9 Jan 2006 05:29:24 +0000 (GMT) (envelope-from kmacy@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id k095TOIb099617 for ; Mon, 9 Jan 2006 05:29:24 GMT (envelope-from kmacy@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id k095TOIt099614 for perforce@freebsd.org; Mon, 9 Jan 2006 05:29:24 GMT (envelope-from kmacy@freebsd.org) Date: Mon, 9 Jan 2006 05:29:24 GMT Message-Id: <200601090529.k095TOIt099614@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to kmacy@freebsd.org using -f From: Kip Macy To: Perforce Change Reviews Cc: Subject: PERFORCE change 89402 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 09 Jan 2006 05:29:26 -0000 http://perforce.freebsd.org/chv.cgi?CH=89402 Change 89402 by kmacy@kmacy:freebsd7_xen3 on 2006/01/09 05:29:16 import suspend support, but keep disabled until the xenbus + newbus integration happens Affected files ... .. //depot/projects/xen3/src/sys/i386-xen/i386-xen/xen_machdep.c#6 edit .. //depot/projects/xen3/src/sys/i386-xen/include/xenvar.h#3 edit Differences ... ==== //depot/projects/xen3/src/sys/i386-xen/i386-xen/xen_machdep.c#6 (text+ko) ==== @@ -55,20 +55,6 @@ #include #include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - #define IDTVEC(name) __CONCAT(X,name) extern inthand_t @@ -609,15 +595,23 @@ howto |= (RB_POWEROFF | RB_HALT); else if (strcmp(str, "halt") == 0) howto |= RB_HALT; -#ifdef notyet else if (strcmp(str, "suspend") == 0) - shutting_down = SHUTDOWN_SUSPEND; -#endif + 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: @@ -639,9 +633,143 @@ SYSINIT(shutdown, SI_SUB_PSEUDO, 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 + + 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_mfn = mfn_to_pfn(xen_start_info->console_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 /********** CODE WORTH KEEPING ABOVE HERE *****************/ void xen_failsafe_handler(void); ==== //depot/projects/xen3/src/sys/i386-xen/include/xenvar.h#3 (text+ko) ==== @@ -18,6 +18,7 @@ extern unsigned long *xen_machine_phys; #define PFNTOMFN(i) (((unsigned long *)xen_phys_machine)[i]) #define MFNTOPFN(i) (xen_machine_phys[i]) +#define VTOMFN(va) (vtomach(va) >> PAGE_SHIFT) #define phystomach(pa) ((((unsigned long *)xen_phys_machine)[(pa >> PAGE_SHIFT)]) << PAGE_SHIFT) void xpq_init(void);