Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 9 Jan 2006 05:29:24 GMT
From:      Kip Macy <kmacy@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 89402 for review
Message-ID:  <200601090529.k095TOIt099614@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 <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);
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200601090529.k095TOIt099614>