During machvirt_init(), ARMCPU objects are pre-created along with the corresponding KVM vcpus in the host. Disabled possible KVM vcpus are then parked at the per-virt-machine list "kvm_parked_vcpus".
Prime purpose to pre-create ARMCPU objects for the disabled vcpus is to facilitate the GIC initialization (pre-sized with possible vcpus). GIC requires all vcpus corresponding to its GICC(GIC CPU Interface) to be initialized and present during its own initialization. After initialization of the machine is complete we release the ARMCPU objects for the disabled vcpus(which shall be re-created at the time when vcpu is hot plugged again. This newly created ARMCPU object is then attached with corresponding parked KVM VCPU). We have few options after the machine init where the disabled ARMCPU object could be released: 1. Release in context to the virt_machine_done() notifier.(This is also our current approach) 2. Defer the release till a new vcpu object is hot plugged. Then release the object in context to the pre_plug() phase. 3. Never release and keep on reusing them and release once at VM exit. This will require some modifications within the interface of qdevice_add() to get old ARMCPU object instead of creating a new one for the hotplug request. Each of the above approaches come with their own pros and cons. This prototype uses the 1st approach.(suggestions are welcome!) Co-developed-by: Keqian Zhu <zhukeqi...@huawei.com> Signed-off-by: Salil Mehta <salil.me...@huawei.com> --- hw/arm/virt.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index e9ead0e2dd..0faf54aa8f 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -1403,6 +1403,28 @@ static void create_secure_ram(VirtMachineState *vms, g_free(nodename); } +static void virt_remove_disabled_cpus(VirtMachineState *vms) +{ + MachineState *ms = MACHINE(vms); + int n; + + /* + * RFC: Question: Other approach could have been to keep them forever + * and release it only once when qemu exits as part o finalize or when + * new vcpu is hotplugged. In the later old could be released for the + * newly created object for the same vcpu? + */ + for (n = vms->smp_cpus; n < vms->max_cpus; n++) { + CPUState *cs = qemu_get_possible_cpu(n); + if (!qemu_present_cpu(cs)) { + CPUArchId *cpu_slot; + cpu_slot = virt_find_cpu_slot(ms, cs->cpu_index); + cpu_slot->cpu = NULL; + object_unref(OBJECT(cs)); + } + } +} + static bool virt_pmu_init(VirtMachineState *vms) { CPUArchIdList *possible_cpus = vms->parent.possible_cpus; @@ -1500,6 +1522,9 @@ void virt_machine_done(Notifier *notifier, void *data) virt_acpi_setup(vms); virt_build_smbios(vms); + + /* release the disabled ARMCPU objects used during init for pre-sizing */ + virt_remove_disabled_cpus(vms); } static uint64_t virt_cpu_mp_affinity(VirtMachineState *vms, int idx) -- 2.17.1