|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 1/4] HVM vcpu add/remove: qemu logic for vcpu add/revmoe
On Fri, 31 May 2013, Anthony PERARD wrote:
> 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)) {
the original code has cpu < 0
> + 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);
> +}
This is also different, the code we have on qemu-xen-unstable is:
if (gpe_state.gpe0_en[0] & 4) {
qemu_set_irq(sci_irq, 1);
qemu_set_irq(sci_irq, 0);
}
what's the reason for the change?
If possible, it would be better to port a QMP command for vcpu hotplug
to avoid compatibility problems, so I would get rid of the code below
> 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++;
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |