PERFORCE change 89402 for review
Kip Macy
kmacy at FreeBSD.org
Sun Jan 8 21:29:26 PST 2006
http://perforce.freebsd.org/chv.cgi?CH=89402
Change 89402 by kmacy at 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 <machine/asmacros.h>
#include <machine/xenbus.h>
-
-#include <sys/socket.h>
-#include <sys/sockio.h>
-#include <net/if.h>
-#include <net/if_dl.h>
-#include <net/if_types.h>
-#include <net/if_var.h>
-#include <net/ethernet.h>
-#include <netinet/in.h>
-#include <sys/mbuf.h>
-#include <nfs/rpcv2.h>
-#include <nfsclient/krpc.h>
-#include <nfs/nfsproto.h>
-
#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);
More information about the p4-projects
mailing list