add cpu hot-remove interface pc_hot_del_cpu() for unrealizing vcpu device. when using 'cpu-del' command, not need to specify vcpuid, the last one cpu will be removed.
Signed-off-by: Chen Fan <chen.fan.f...@cn.fujitsu.com> --- hw/i386/pc.c | 19 +++++++++++++++++++ hw/i386/pc_piix.c | 3 ++- include/hw/boards.h | 2 ++ include/hw/i386/pc.h | 1 + qapi-schema.json | 10 ++++++++++ qmp-commands.hx | 21 +++++++++++++++++++++ qmp.c | 9 +++++++++ 7 files changed, 64 insertions(+), 1 deletion(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index d000995..485e2ce 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -979,6 +979,25 @@ void pc_hot_add_cpu(const int64_t id, Error **errp) pc_new_cpu(current_cpu_model, apic_id, icc_bridge, errp); } +void pc_hot_del_cpu(Error **errp) +{ + CPUState *cpu = first_cpu; + X86CPUClass *xcc; + + while (CPU_NEXT(cpu)) { + cpu = CPU_NEXT(cpu); + } + + if (cpu == first_cpu) { + error_setg(errp, "Unable to delete the last " + "one cpu."); + return; + } + + xcc = X86_CPU_GET_CLASS(DEVICE(cpu)); + xcc->parent_unrealize(DEVICE(cpu), errp); +} + void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge) { int i; diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 4e0dae7..50c860b 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -362,7 +362,8 @@ static void pc_xen_hvm_init(QEMUMachineInitArgs *args) #define PC_I440FX_2_0_MACHINE_OPTIONS \ PC_I440FX_MACHINE_OPTIONS, \ - .default_machine_opts = "firmware=bios-256k.bin" + .default_machine_opts = "firmware=bios-256k.bin", \ + .hot_del_cpu = pc_hot_del_cpu static QEMUMachine pc_i440fx_machine_v2_0 = { PC_I440FX_2_0_MACHINE_OPTIONS, diff --git a/include/hw/boards.h b/include/hw/boards.h index 2151460..74334cb 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -23,6 +23,7 @@ typedef void QEMUMachineInitFunc(QEMUMachineInitArgs *args); typedef void QEMUMachineResetFunc(void); typedef void QEMUMachineHotAddCPUFunc(const int64_t id, Error **errp); +typedef void QEMUMachineHotDelCPUFunc(Error **errp); struct QEMUMachine { const char *name; @@ -31,6 +32,7 @@ struct QEMUMachine { QEMUMachineInitFunc *init; QEMUMachineResetFunc *reset; QEMUMachineHotAddCPUFunc *hot_add_cpu; + QEMUMachineHotDelCPUFunc *hot_del_cpu; BlockInterfaceType block_default_type; int max_cpus; unsigned int no_serial:1, diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 24eb3de..08bccfb 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -118,6 +118,7 @@ void pc_acpi_smi_interrupt(void *opaque, int irq, int level); void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge); void pc_hot_add_cpu(const int64_t id, Error **errp); +void pc_hot_del_cpu(Error **errp); void pc_acpi_init(const char *default_dsdt); PcGuestInfo *pc_guest_info_init(ram_addr_t below_4g_mem_size, diff --git a/qapi-schema.json b/qapi-schema.json index c3c939c..42600b7 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -1553,6 +1553,16 @@ ## { 'command': 'cpu-add', 'data': {'id': 'int'} } +# @cpu-del + +# Deletes CPU from the last ID +# +# Returns: Nothing on success +# +# Since 2.0 +## +{ 'command': 'cpu-del' } + ## # @memsave: # diff --git a/qmp-commands.hx b/qmp-commands.hx index fba15cd..865eb91 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -411,6 +411,27 @@ Example: EQMP { + .name = "cpu-del", + .args_type = "", + .mhandler.cmd_new = qmp_marshal_input_cpu_del, + }, + +SQMP +cpu-del +------- + +Deletes virtual cpu + +Arguments: None. + +Example: + +-> { "execute": "cpu-del" } +<- { "return": {} } + +EQMP + + { .name = "memsave", .args_type = "val:l,size:i,filename:s,cpu:i?", .mhandler.cmd_new = qmp_marshal_input_memsave, diff --git a/qmp.c b/qmp.c index 1d7a04d..935310a 100644 --- a/qmp.c +++ b/qmp.c @@ -118,6 +118,15 @@ void qmp_cpu_add(int64_t id, Error **errp) } } +void qmp_cpu_del(Error **errp) +{ + if (current_machine->hot_del_cpu) { + current_machine->hot_del_cpu(errp); + } else { + error_setg(errp, "Not supported"); + } +} + #ifndef CONFIG_VNC /* If VNC support is enabled, the "true" query-vnc command is defined in the VNC subsystem */ -- 1.8.1.4