2 #include <linux/init.h>
3 #include <linux/kernel.h>
4 #include <linux/sched.h>
5 #include <linux/notifier.h>
7 #include <xen/cpu_hotplug.h>
8 #include <xen/xenbus.h>
11 * Set of CPUs that remote admin software will allow us to bring online.
12 * Notified to us via xenbus.
14 static cpumask_t xenbus_allowed_cpumask;
16 /* Set of CPUs that local admin will allow us to bring online. */
17 static cpumask_t local_allowed_cpumask = CPU_MASK_ALL;
19 static int local_cpu_hotplug_request(void)
22 * We assume a CPU hotplug request comes from local admin if it is made
23 * via a userspace process (i.e., one with a real mm_struct).
25 return (current->mm != NULL);
28 static void vcpu_hotplug(unsigned int cpu)
31 char dir[32], state[32];
33 if ((cpu >= NR_CPUS) || !cpu_possible(cpu))
36 sprintf(dir, "cpu/%d", cpu);
37 err = xenbus_scanf(XBT_NIL, dir, "availability", "%s", state);
39 printk(KERN_ERR "XENBUS: Unable to read cpu state\n");
43 if (strcmp(state, "online") == 0) {
44 cpu_set(cpu, xenbus_allowed_cpumask);
46 } else if (strcmp(state, "offline") == 0) {
47 cpu_clear(cpu, xenbus_allowed_cpumask);
50 printk(KERN_ERR "XENBUS: unknown state(%s) on CPU%d\n",
55 static void handle_vcpu_hotplug_event(
56 struct xenbus_watch *watch, const char **vec, unsigned int len)
60 const char *node = vec[XS_WATCH_PATH];
62 if ((cpustr = strstr(node, "cpu/")) != NULL) {
63 sscanf(cpustr, "cpu/%d", &cpu);
68 static int smpboot_cpu_notify(struct notifier_block *notifier,
69 unsigned long action, void *hcpu)
74 * We do this in a callback notifier rather than __cpu_disable()
75 * because local_cpu_hotplug_request() does not work in the latter
76 * as it's always executed from within a stopmachine kthread.
78 if ((action == CPU_DOWN_PREPARE) && local_cpu_hotplug_request())
79 cpu_clear(cpu, local_allowed_cpumask);
84 static int setup_cpu_watcher(struct notifier_block *notifier,
85 unsigned long event, void *data)
89 static struct xenbus_watch cpu_watch = {
91 .callback = handle_vcpu_hotplug_event,
92 .flags = XBWF_new_thread };
93 (void)register_xenbus_watch(&cpu_watch);
95 if (!is_initial_xendomain()) {
96 for_each_possible_cpu(i)
98 printk(KERN_INFO "Brought up %ld CPUs\n",
99 (long)num_online_cpus());
105 static int __init setup_vcpu_hotplug_event(void)
107 static struct notifier_block hotplug_cpu = {
108 .notifier_call = smpboot_cpu_notify };
109 static struct notifier_block xsn_cpu = {
110 .notifier_call = setup_cpu_watcher };
112 if (!is_running_on_xen())
115 register_cpu_notifier(&hotplug_cpu);
116 register_xenstore_notifier(&xsn_cpu);
121 arch_initcall(setup_vcpu_hotplug_event);
123 int smp_suspend(void)
130 * Take all other CPUs offline. We hold the hotplug mutex to
131 * avoid other processes bringing up CPUs under our feet.
133 while (num_online_cpus() > 1) {
134 unlock_cpu_hotplug();
135 for_each_online_cpu(i) {
140 printk(KERN_CRIT "Failed to take all CPUs "
142 for_each_possible_cpu(i)
153 void smp_resume(void)
157 for_each_possible_cpu(cpu)
158 cpu_initialize_context(cpu);
160 unlock_cpu_hotplug();
162 for_each_possible_cpu(cpu)
166 int cpu_up_check(unsigned int cpu)
170 if (local_cpu_hotplug_request()) {
171 cpu_set(cpu, local_allowed_cpumask);
172 if (!cpu_isset(cpu, xenbus_allowed_cpumask)) {
173 printk("%s: attempt to bring up CPU %u disallowed by "
174 "remote admin.\n", __FUNCTION__, cpu);
177 } else if (!cpu_isset(cpu, local_allowed_cpumask) ||
178 !cpu_isset(cpu, xenbus_allowed_cpumask)) {
185 void init_xenbus_allowed_cpumask(void)
187 xenbus_allowed_cpumask = cpu_present_map;