Something went wrong. Try again.
(I'm so sorry!) Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122// SPDX-License-Identifier: GPL-2.0#define pr_fmt(fmt) "xen:" KBUILD_MODNAME ": " fmt
#include <linux/notifier.h>
#include <xen/xen.h>#include <xen/xenbus.h>
#include <asm/xen/hypervisor.h>#include <asm/cpu.h>
static void enable_hotplug_cpu(int cpu){ if (!cpu_present(cpu)) xen_arch_register_cpu(cpu);
set_cpu_present(cpu, true);}
static void disable_hotplug_cpu(int cpu){ if (!cpu_is_hotpluggable(cpu)) return; lock_device_hotplug(); if (cpu_online(cpu)) device_offline(get_cpu_device(cpu)); if (!cpu_online(cpu) && cpu_present(cpu)) { xen_arch_unregister_cpu(cpu); set_cpu_present(cpu, false); } unlock_device_hotplug();}
static int vcpu_online(unsigned int cpu){ int err; char dir[16], state[16];
sprintf(dir, "cpu/%u", cpu); err = xenbus_scanf(XBT_NIL, dir, "availability", "%15s", state); if (err != 1) { if (!xen_initial_domain()) pr_err("Unable to read cpu state\n"); return err; }
if (strcmp(state, "online") == 0) return 1; else if (strcmp(state, "offline") == 0) return 0;
pr_err("unknown state(%s) on CPU%d\n", state, cpu); return -EINVAL;}static void vcpu_hotplug(unsigned int cpu){ if (cpu >= nr_cpu_ids || !cpu_possible(cpu)) return;
switch (vcpu_online(cpu)) { case 1: enable_hotplug_cpu(cpu); break; case 0: disable_hotplug_cpu(cpu); break; default: break; }}
static void handle_vcpu_hotplug_event(struct xenbus_watch *watch, const char *path, const char *token){ unsigned int cpu; char *cpustr;
cpustr = strstr(path, "cpu/"); if (cpustr != NULL) { sscanf(cpustr, "cpu/%u", &cpu); vcpu_hotplug(cpu); }}
static int setup_cpu_watcher(struct notifier_block *notifier, unsigned long event, void *data){ int cpu; static struct xenbus_watch cpu_watch = { .node = "cpu", .callback = handle_vcpu_hotplug_event};
(void)register_xenbus_watch(&cpu_watch);
for_each_possible_cpu(cpu) { if (vcpu_online(cpu) == 0) disable_hotplug_cpu(cpu); }
return NOTIFY_DONE;}
static int __init setup_vcpu_hotplug_event(void){ static struct notifier_block xsn_cpu = { .notifier_call = setup_cpu_watcher };
#ifdef CONFIG_X86 if (!xen_pv_domain() && !xen_pvh_domain())#else if (!xen_domain())#endif return -ENODEV;
register_xenstore_notifier(&xsn_cpu);
return 0;}
late_initcall(setup_vcpu_hotplug_event);