[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 1/4] HVM vcpu add/remove: qemu logic for vcpu add/revmoe
From: Ian Jackson <ian.jackson@xxxxxxxxxxxxx> -- at qemu side, get vcpu_avail which used for original cpu avail map; -- setup gpe ioread/iowrite at qmeu; -- setup vcpu add/remove user interface through monitor; -- setup SCI logic; Signed-off-by: Liu, Jinsong <jinsong.liu@xxxxxxxxx> [ PATCH 4/4 ] HVM vcpu add/remove: qemu logic for vcpu add/revmoe Port from qemu-xen-traditionnal to qemu-xen. Signed-off-by: Anthony PERARD <anthony.perard@xxxxxxxxxx> --- hmp-commands.hx | 9 +++++++ hw/acpi_piix4.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- monitor.c | 18 ++++++++++++++ qemu-options.hx | 3 +++ sysemu.h | 3 +++ vl.c | 6 +++++ 6 files changed, 113 insertions(+), 1 deletion(-) diff --git a/hmp-commands.hx b/hmp-commands.hx index 010b8c9..e92f173 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1581,3 +1581,12 @@ ETEXI STEXI @end table ETEXI + +HXCOMM TODO doc + { + .name = "cpu_set", + .args_type = "cpu_index:i,status:s", + .params = "cpu [online|offline]", + .help = "change cpu state", + .mhandler.cmd = do_cpu_set_nr, + }, diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c index 519269a..c73dc7c 100644 --- a/hw/acpi_piix4.c +++ b/hw/acpi_piix4.c @@ -45,8 +45,11 @@ #define PCI_DOWN_BASE 0xae04 #define PCI_EJ_BASE 0xae08 #define PCI_RMV_BASE 0xae0c +/* ioport to monitor cpu add/remove status */ +#define PROC_BASE 0xaf00 #define PIIX4_PCI_HOTPLUG_STATUS 2 +#define PIIX4_CPU_HOTPLUG_STATUS 4 struct pci_status { uint32_t up; /* deprecated, maintained for migration compatibility */ @@ -77,6 +80,9 @@ typedef struct PIIX4PMState { uint8_t disable_s3; uint8_t disable_s4; uint8_t s4_val; + + /* CPU bitmap */ + uint8_t cpus_sts[32]; } PIIX4PMState; static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s); @@ -95,7 +101,7 @@ static void pm_update_sci(PIIX4PMState *s) ACPI_BITMASK_GLOBAL_LOCK_ENABLE | ACPI_BITMASK_TIMER_ENABLE)) != 0) || (((s->ar.gpe.sts[0] & s->ar.gpe.en[0]) - & PIIX4_PCI_HOTPLUG_STATUS) != 0); + & (PIIX4_PCI_HOTPLUG_STATUS|PIIX4_CPU_HOTPLUG_STATUS)) != 0); qemu_set_irq(s->irq, sci_level); /* schedule a timer interruption if needed */ @@ -602,11 +608,48 @@ static uint32_t pcirmv_read(void *opaque, uint32_t addr) return s->pci0_hotplug_enable; } +static uint32_t gpe_cpus_readb(void *opaque, uint32_t addr) +{ + uint32_t val = 0; + PIIX4PMState *g = opaque; + + switch (addr) { + case PROC_BASE ... PROC_BASE+31: + val = g->cpus_sts[addr - PROC_BASE]; + default: + break; + } + + return val; +} + +static void gpe_cpus_writeb(void *opaque, uint32_t addr, uint32_t val) +{ + switch (addr) { + case PROC_BASE ... PROC_BASE + 31: + /* don't allow to change cpus_sts from inside a guest */ + break; + default: + break; + } +} + static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev, PCIHotplugState state); +extern uint64_t vcpu_avail; +static PIIX4PMState *acpi_state; static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s) { + int i = 0, cpus = max_cpus; + char *vcpumap = (char *)&vcpu_avail; + + while (cpus > 0) { + s->cpus_sts[i] = vcpumap[i]; + i++; + cpus -= 8; + } + acpi_state = s; register_ioport_write(GPE_BASE, GPE_LEN, 1, gpe_writeb, s); register_ioport_read(GPE_BASE, GPE_LEN, 1, gpe_readb, s); @@ -620,6 +663,9 @@ static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s) register_ioport_read(PCI_RMV_BASE, 4, 4, pcirmv_read, s); + register_ioport_read(PROC_BASE, 32, 1, gpe_cpus_readb, s); + register_ioport_write(PROC_BASE, 32, 1, gpe_cpus_writeb, s); + pci_bus_hotplug(bus, piix4_device_hotplug, &s->dev.qdev); } @@ -660,3 +706,30 @@ static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev, return 0; } + +static void enable_processor(PIIX4PMState *g, int cpu) +{ + g->ar.gpe.sts[0] |= 4; + g->cpus_sts[cpu/8] |= (1 << (cpu%8)); +} + +static void disable_processor(PIIX4PMState *g, int cpu) +{ + g->ar.gpe.sts[0] |= 4; + g->cpus_sts[cpu/8] &= ~(1 << (cpu%8)); +} + +void qemu_cpu_add_remove(int cpu, int state) +{ + if ((cpu <=0) || (cpu >= max_cpus)) { + fprintf(stderr, "vcpu out of range, should be [1~%d]\n", max_cpus - 1); + return; + } + + if (state) + enable_processor(acpi_state, cpu); + else + disable_processor(acpi_state, cpu); + + pm_update_sci(acpi_state); +} diff --git a/monitor.c b/monitor.c index c0e32d6..564373c 100644 --- a/monitor.c +++ b/monitor.c @@ -2421,6 +2421,24 @@ int monitor_handle_fd_param(Monitor *mon, const char *fdname) return fd; } +static void do_cpu_set_nr(Monitor *mon, const QDict *qdict) +{ + int cpu_index = qdict_get_int(qdict, "cpu_index"); + const char *status = qdict_get_str(qdict, "status"); + int state; + + if (!strcmp(status, "online")) { + state = 1; + } else if (!strcmp(status, "offline")) { + state = 0; + } else { + monitor_printf(mon, "invalid status: %s\n", status); + return; + } + + qemu_cpu_add_remove(cpu_index, state); +} + /* mon_cmds and info_cmds would be sorted at runtime */ static mon_cmd_t mon_cmds[] = { #include "hmp-commands.h" diff --git a/qemu-options.hx b/qemu-options.hx index de43b1b..0ba668f 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -94,6 +94,9 @@ given, the total number of CPUs @var{n} can be omitted. @var{maxcpus} specifies the maximum number of hotpluggable CPUs. ETEXI +DEF("vcpu_avail", HAS_ARG, QEMU_OPTION_vcpu_avail, + "-vcpu_avail bitmap\n", QEMU_ARCH_ALL) + DEF("numa", HAS_ARG, QEMU_OPTION_numa, "-numa node[,mem=size][,cpus=cpu[-cpu]][,nodeid=node]\n", QEMU_ARCH_ALL) STEXI diff --git a/sysemu.h b/sysemu.h index f5ac664..ed7b264 100644 --- a/sysemu.h +++ b/sysemu.h @@ -149,6 +149,9 @@ int pci_drive_hot_add(Monitor *mon, const QDict *qdict, DriveInfo *dinfo, int type); void do_pci_device_hot_remove(Monitor *mon, const QDict *qdict); +/* cpu hotplug */ +void qemu_cpu_add_remove(int cpu, int state); + /* generic hotplug */ void drive_hot_add(Monitor *mon, const QDict *qdict); diff --git a/vl.c b/vl.c index a3ab384..27ae6c1 100644 --- a/vl.c +++ b/vl.c @@ -207,6 +207,7 @@ int win2k_install_hack = 0; int singlestep = 0; int smp_cpus = 1; int max_cpus = 0; +uint64_t vcpu_avail = 1; int smp_cores = 1; int smp_threads = 1; #ifdef CONFIG_VNC @@ -3302,6 +3303,11 @@ int main(int argc, char **argv, char **envp) exit(1); } break; + case QEMU_OPTION_vcpu_avail: + vcpu_avail = atol(optarg); + fprintf(stderr, "qemu: the avail cpu bitmap is %lx\n", + vcpu_avail); + break; case QEMU_OPTION_vnc: #ifdef CONFIG_VNC display_remote++; -- Anthony PERARD _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |