• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <linux/notifier.h>
2 
3 #include <xen/xenbus.h>
4 
5 #include <asm/xen/hypervisor.h>
6 #include <asm/cpu.h>
7 
enable_hotplug_cpu(int cpu)8 static void enable_hotplug_cpu(int cpu)
9 {
10 	if (!cpu_present(cpu))
11 		arch_register_cpu(cpu);
12 
13 	cpu_set(cpu, cpu_present_map);
14 }
15 
disable_hotplug_cpu(int cpu)16 static void disable_hotplug_cpu(int cpu)
17 {
18 	if (cpu_present(cpu))
19 		arch_unregister_cpu(cpu);
20 
21 	cpu_clear(cpu, cpu_present_map);
22 }
23 
vcpu_hotplug(unsigned int cpu)24 static void vcpu_hotplug(unsigned int cpu)
25 {
26 	int err;
27 	char dir[32], state[32];
28 
29 	if (!cpu_possible(cpu))
30 		return;
31 
32 	sprintf(dir, "cpu/%u", cpu);
33 	err = xenbus_scanf(XBT_NIL, dir, "availability", "%s", state);
34 	if (err != 1) {
35 		printk(KERN_ERR "XENBUS: Unable to read cpu state\n");
36 		return;
37 	}
38 
39 	if (strcmp(state, "online") == 0) {
40 		enable_hotplug_cpu(cpu);
41 	} else if (strcmp(state, "offline") == 0) {
42 		(void)cpu_down(cpu);
43 		disable_hotplug_cpu(cpu);
44 	} else {
45 		printk(KERN_ERR "XENBUS: unknown state(%s) on CPU%d\n",
46 		       state, cpu);
47 	}
48 }
49 
handle_vcpu_hotplug_event(struct xenbus_watch * watch,const char ** vec,unsigned int len)50 static void handle_vcpu_hotplug_event(struct xenbus_watch *watch,
51 					const char **vec, unsigned int len)
52 {
53 	unsigned int cpu;
54 	char *cpustr;
55 	const char *node = vec[XS_WATCH_PATH];
56 
57 	cpustr = strstr(node, "cpu/");
58 	if (cpustr != NULL) {
59 		sscanf(cpustr, "cpu/%u", &cpu);
60 		vcpu_hotplug(cpu);
61 	}
62 }
63 
setup_cpu_watcher(struct notifier_block * notifier,unsigned long event,void * data)64 static int setup_cpu_watcher(struct notifier_block *notifier,
65 			      unsigned long event, void *data)
66 {
67 	static struct xenbus_watch cpu_watch = {
68 		.node = "cpu",
69 		.callback = handle_vcpu_hotplug_event};
70 
71 	(void)register_xenbus_watch(&cpu_watch);
72 
73 	return NOTIFY_DONE;
74 }
75 
setup_vcpu_hotplug_event(void)76 static int __init setup_vcpu_hotplug_event(void)
77 {
78 	static struct notifier_block xsn_cpu = {
79 		.notifier_call = setup_cpu_watcher };
80 
81 	if (!xen_pv_domain())
82 		return -ENODEV;
83 
84 	register_xenstore_notifier(&xsn_cpu);
85 
86 	return 0;
87 }
88 
89 arch_initcall(setup_vcpu_hotplug_event);
90 
91