From 11f9628ceff019259ff12ce469deafbf50eb3075 Mon Sep 17 00:00:00 2001 From: Keqian Zhu Date: Fri, 10 Apr 2020 14:20:59 +0800 Subject: [PATCH] arm/virt: Start up CPU hot-plug All the CPU hotplug facilities are ready. Assemble them to start up CPU hot-plug capability for arm/virt. Signed-off-by: Keqian Zhu Signed-off-by: Salil Mehta --- hw/arm/virt.c | 61 ++++++++++++++++++++++++++++++++++++++++--- include/hw/arm/virt.h | 1 + qom/cpu.c | 5 ++++ target/arm/cpu.c | 2 ++ 4 files changed, 65 insertions(+), 4 deletions(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index c6a99e683a..112a6ae7cb 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -48,6 +48,8 @@ #include "sysemu/cpus.h" #include "sysemu/sysemu.h" #include "sysemu/kvm.h" +#include "sysemu/cpus.h" +#include "sysemu/hw_accel.h" #include "hw/loader.h" #include "exec/address-spaces.h" #include "qemu/bitops.h" @@ -649,9 +651,9 @@ static inline DeviceState *create_acpi_ged(VirtMachineState *vms) event |= ACPI_GED_MEM_HOTPLUG_EVT; } - /* event |= ACPI_GED_CPU_HOTPLUG_EVT; - * Currently CPU hotplug is not enabled. - */ + if (vms->cpu_hotplug_enabled) { + event |= ACPI_GED_CPU_HOTPLUG_EVT; + } dev = qdev_create(NULL, TYPE_ACPI_GED); qdev_prop_set_uint32(dev, "ged-event", event); @@ -2214,12 +2216,62 @@ static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev, object_property_set_link(cpuobj, OBJECT(secure_sysmem), "secure-memory", &error_abort); } + + /* If we use KVM accel, we should pause all vcpus to + * allow hot access of vcpu registers. + */ + if (dev->hotplugged && kvm_enabled()) { + pause_all_vcpus(); + } } static void virt_cpu_plug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { - /* Currently nothing to do */ + CPUArchId *cpu_slot; + CPUState *cs = CPU(dev); + int ncpu = cs->cpu_index; + MachineState *ms = MACHINE(hotplug_dev); + VirtMachineState *vms = VIRT_MACHINE(hotplug_dev); + GICv3State *gicv3; + ARMGICv3CommonClass *agcc; + Error *local_err = NULL; + + if (dev->hotplugged) { + /* Realize GIC related parts of CPU */ + assert(vms->gic_version == 3); + gicv3 = ARM_GICV3_COMMON(vms->gic); + agcc = ARM_GICV3_COMMON_GET_CLASS(gicv3); + agcc->cpu_hotplug_realize(gicv3, ncpu); + connect_gic_cpu_irqs(vms, ncpu); + + /* Register CPU reset and trigger it manually */ + cpu_synchronize_state(cs); + cpu_hotplug_register_reset(ncpu); + cpu_hotplug_reset_manually(ncpu); + cpu_synchronize_post_reset(cs); + + if (kvm_enabled()) { + resume_all_vcpus(); + } + } + + if (vms->acpi_dev) { + hotplug_handler_plug(HOTPLUG_HANDLER(vms->acpi_dev), dev, &local_err); + if (local_err) { + goto out; + } + } + + vms->boot_cpus++; + if (vms->fw_cfg) { + fw_cfg_modify_i16(vms->fw_cfg, FW_CFG_NB_CPUS, vms->boot_cpus); + } + + cpu_slot = &ms->possible_cpus->cpus[ncpu]; + cpu_slot->cpu = OBJECT(dev); +out: + error_propagate(errp, local_err); } static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev, @@ -2324,6 +2376,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data) mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15"); mc->get_default_cpu_node_id = virt_get_default_cpu_node_id; mc->kvm_type = virt_kvm_type; + mc->has_hotpluggable_cpus = true; assert(!mc->get_hotplug_handler); mc->get_hotplug_handler = virt_machine_get_hotplug_handler; hc->pre_plug = virt_machine_device_pre_plug_cb; diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h index b4c53d920e..a9429bed25 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -140,6 +140,7 @@ typedef struct { uint32_t msi_phandle; uint32_t iommu_phandle; int psci_conduit; + uint32_t boot_cpus; hwaddr highest_gpa; DeviceState *gic; DeviceState *acpi_dev; diff --git a/qom/cpu.c b/qom/cpu.c index f376f782d8..58cd9d5bbc 100644 --- a/qom/cpu.c +++ b/qom/cpu.c @@ -342,7 +342,12 @@ static void cpu_common_realizefn(DeviceState *dev, Error **errp) if (dev->hotplugged) { cpu_synchronize_post_init(cpu); + +#ifdef __aarch64__ + if (!kvm_enabled()) +#endif cpu_resume(cpu); + } /* NOTE: latest generic point where the cpu is fully realized */ diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 91f1e36cd8..811e5c6365 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -2598,6 +2598,8 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data) acc->parent_reset = cc->reset; cc->reset = arm_cpu_reset; + dc->user_creatable = true; + cc->class_by_name = arm_cpu_class_by_name; cc->has_work = arm_cpu_has_work; cc->cpu_exec_interrupt = arm_cpu_exec_interrupt; -- 2.19.1