From: Igor Mammedov <imammedo@redhat.com>
To: Miguel Luis <miguel.luis@oracle.com>
Cc: "salil.mehta@opnsrc.net" <salil.mehta@opnsrc.net>,
"qemu-devel@nongnu.org" <qemu-devel@nongnu.org>,
"qemu-arm@nongnu.org" <qemu-arm@nongnu.org>,
"mst@redhat.com" <mst@redhat.com>,
"salil.mehta@huawei.com" <salil.mehta@huawei.com>,
"maz@kernel.org" <maz@kernel.org>,
"jean-philippe@linaro.org" <jean-philippe@linaro.org>,
"jonathan.cameron@huawei.com" <jonathan.cameron@huawei.com>,
"lpieralisi@kernel.org" <lpieralisi@kernel.org>,
"peter.maydell@linaro.org" <peter.maydell@linaro.org>,
"richard.henderson@linaro.org" <richard.henderson@linaro.org>,
"armbru@redhat.com" <armbru@redhat.com>,
"andrew.jones@linux.dev" <andrew.jones@linux.dev>,
"david@redhat.com" <david@redhat.com>,
"philmd@linaro.org" <philmd@linaro.org>,
"eric.auger@redhat.com" <eric.auger@redhat.com>,
"will@kernel.org" <will@kernel.org>,
"ardb@kernel.org" <ardb@kernel.org>,
"oliver.upton@linux.dev" <oliver.upton@linux.dev>,
"pbonzini@redhat.com" <pbonzini@redhat.com>,
"gshan@redhat.com" <gshan@redhat.com>,
"rafael@kernel.org" <rafael@kernel.org>,
"borntraeger@linux.ibm.com" <borntraeger@linux.ibm.com>,
"alex.bennee@linaro.org" <alex.bennee@linaro.org>,
"gustavo.romero@linaro.org" <gustavo.romero@linaro.org>,
"npiggin@gmail.com" <npiggin@gmail.com>,
"harshpb@linux.ibm.com" <harshpb@linux.ibm.com>,
"linux@armlinux.org.uk" <linux@armlinux.org.uk>,
"darren@os.amperecomputing.com" <darren@os.amperecomputing.com>,
"ilkka@os.amperecomputing.com" <ilkka@os.amperecomputing.com>,
"vishnu@os.amperecomputing.com" <vishnu@os.amperecomputing.com>,
"gankulkarni@os.amperecomputing.com"
<gankulkarni@os.amperecomputing.com>,
Karl Heubaum <karl.heubaum@oracle.com>,
"zhukeqian1@huawei.com" <zhukeqian1@huawei.com>,
"wangxiongfeng2@huawei.com" <wangxiongfeng2@huawei.com>,
"wangyanan55@huawei.com" <wangyanan55@huawei.com>,
"wangzhou1@hisilicon.com" <wangzhou1@hisilicon.com>,
"linuxarm@huawei.com" <linuxarm@huawei.com>,
"jiakernel2@gmail.com" <jiakernel2@gmail.com>,
"maobibo@loongson.cn" <maobibo@loongson.cn>,
"lixianglai@loongson.cn" <lixianglai@loongson.cn>,
"shahuang@redhat.com" <shahuang@redhat.com>,
"zhao1.liu@intel.com" <zhao1.liu@intel.com>,
<devel@lists.libvirt.org>
Subject: Re: [PATCH RFC V6 03/24] hw/arm/virt: Clamp 'maxcpus' as-per machine's vCPU deferred online-capability
Date: Thu, 9 Oct 2025 15:11:23 +0200 [thread overview]
Message-ID: <20251009151123.6741ac61@fedora> (raw)
In-Reply-To: <4764573F-D108-40BB-AF23-B4B29E40BEF8@oracle.com>
On Thu, 9 Oct 2025 12:32:15 +0000
Miguel Luis <miguel.luis@oracle.com> wrote:
> Hi Salil,
>
> > On 1 Oct 2025, at 01:01, salil.mehta@opnsrc.net wrote:
> >
> > From: Salil Mehta <salil.mehta@huawei.com>
> >
> > To support a vCPU hot-add–like model on ARM, the virt machine may be setup with
> > more CPUs than are active at boot. These additional CPUs are fully realized in
> > KVM and listed in ACPI tables from the start, but begin in a disabled state.
> > They can later be brought online or taken offline under host or platform policy
> > control. The CPU topology is fixed at VM creation time and cannot change
> > dynamically on ARM. Therefore, we must determine precisely the 'maxcpus' value
> > that applies for the full lifetime of the VM.
> >
> > On ARM, this deferred online-capable model is only valid if:
> > - The GIC version is 3 or higher, and
> > - Each non-boot CPU’s GIC CPU Interface is marked “online-capable” in its
> > ACPI GICC structure (UEFI ACPI Specification 6.5, §5.2.12.14, Table 5.37
> > “GICC CPU Interface Flags”), and
> > - The chosen accelerator supports safe deferred CPU online:
> > * TCG with multi-threaded TCG (MTTCG) enabled
> > * KVM (on supported hosts)
> > * Not HVF or QTest
> >
> > This patch sizes the machine’s max-possible CPUs during VM init:
> > - If all conditions are satisfied, retain the full set of CPUs corresponding
> > to (`-smp cpus` + `-smp disabledcpus`), allowing the additional (initially
> > disabled) CPUs to participate in later policy-driven online.
> > - Otherwise, clamp the max-possible CPUs to the boot-enabled count
> > (`-smp disabledcpus=0` equivalent) to avoid advertising CPUs the guest can
> > never use.
> >
> > A new MachineClass flag, `has_online_capable_cpus`, records whether the machine
> > supports deferred vCPU online. This is usable by other machine types as well.
>
>
> By the definition of
>
> * @has_hotpluggable_cpus:
> * If true, board supports CPUs creation with -device/device_add.
>
> in include/hw/boards.h
It should be fine to rename it to has_pluggable_cpus.
But we should add support to arm/virt for -device/device_add cpu_foo,
to avoid awkward -device-set and mangling of -smp.
device_add in arm/virt case probably should be limited non hotplug usecase.
> seems one could take advantage of MachineClass's has_hotpluggable_cpus variable
> instead of creating a new has_online_capable_cpus one.
> (Again, IMHO ‘online capable’ is ACPI nomenclature and doesn’t need to be brought
> in MachineClass’s)
the issue with has_hotpluggable_cpus might be QMP ABI,
where libvirt migh use it to figure out if certain command are supported.
CCing libvirt to check if that would break something.
>
> Variable which would be initialized in machvirt_init on an assignment based on
> GIC version and/or wether there's inactive CPUs and proceed from there anyways,
> making the default assignment in machine_virt_class_init superfluous.
>
> We're at hw/arm/virt and we know these CPUs are administratively power state
> coordinated so admin_power_state_supported can still be set there in the
> presence of inactive CPUs.
>
> Thanks
> Miguel
>
> >
> > Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
> > ---
> > hw/arm/virt.c | 84 ++++++++++++++++++++++++++++++---------------
> > include/hw/boards.h | 1 +
> > 2 files changed, 57 insertions(+), 28 deletions(-)
> >
> > diff --git a/hw/arm/virt.c b/hw/arm/virt.c
> > index ef6be3660f..76f21bd56a 100644
> > --- a/hw/arm/virt.c
> > +++ b/hw/arm/virt.c
> > @@ -2168,8 +2168,7 @@ static void machvirt_init(MachineState *machine)
> > bool has_ged = !vmc->no_ged;
> > unsigned int smp_cpus = machine->smp.cpus;
> > unsigned int max_cpus = machine->smp.max_cpus;
> > -
> > - possible_cpus = mc->possible_cpu_arch_ids(machine);
> > + DeviceClass *dc;
> >
> > /*
> > * In accelerated mode, the memory map is computed earlier in kvm_type()
> > @@ -2186,7 +2185,7 @@ static void machvirt_init(MachineState *machine)
> > * we are about to deal with. Once this is done, get rid of
> > * the object.
> > */
> > - cpuobj = object_new(possible_cpus->cpus[0].type);
> > + cpuobj = object_new(machine->cpu_type);
> > armcpu = ARM_CPU(cpuobj);
> >
> > pa_bits = arm_pamax(armcpu);
> > @@ -2201,6 +2200,57 @@ static void machvirt_init(MachineState *machine)
> > */
> > finalize_gic_version(vms);
> >
> > + /*
> > + * The maximum number of CPUs depends on the GIC version, or on how
> > + * many redistributors we can fit into the memory map (which in turn
> > + * depends on whether this is a GICv3 or v4).
> > + */
> > + if (vms->gic_version == VIRT_GIC_VERSION_2) {
> > + virt_max_cpus = GIC_NCPU;
> > + } else {
> > + virt_max_cpus = virt_redist_capacity(vms, VIRT_GIC_REDIST);
> > + if (vms->highmem_redists) {
> > + virt_max_cpus += virt_redist_capacity(vms, VIRT_HIGH_GIC_REDIST2);
> > + }
> > + }
> > +
> > + if ((tcg_enabled() && !qemu_tcg_mttcg_enabled()) || hvf_enabled() ||
> > + qtest_enabled() || vms->gic_version == VIRT_GIC_VERSION_2) {
> > + max_cpus = machine->smp.max_cpus = smp_cpus;
> > + if (mc->has_online_capable_cpus) {
> > + if (vms->gic_version == VIRT_GIC_VERSION_2) {
> > + warn_report("GICv2 does not support online-capable CPUs");
> > + }
> > + mc->has_online_capable_cpus = false;
> > + }
> > + }
> > +
> > + if (mc->has_online_capable_cpus) {
> > + max_cpus = smp_cpus + machine->smp.disabledcpus;
> > + machine->smp.max_cpus = max_cpus;
> > + }
> > +
> > + if (max_cpus > virt_max_cpus) {
> > + error_report("Number of SMP CPUs requested (%d) exceeds max CPUs "
> > + "supported by machine 'mach-virt' (%d)",
> > + max_cpus, virt_max_cpus);
> > + if (vms->gic_version != VIRT_GIC_VERSION_2 && !vms->highmem_redists) {
> > + error_printf("Try 'highmem-redists=on' for more CPUs\n");
> > + }
> > +
> > + exit(1);
> > + }
> > +
> > + dc = DEVICE_CLASS(object_class_by_name(machine->cpu_type));
> > + if (!dc) {
> > + error_report("CPU type '%s' not registered", machine->cpu_type);
> > + exit(1);
> > + }
> > + dc->admin_power_state_supported = mc->has_online_capable_cpus;
> > +
> > + /* uses smp.max_cpus to initialize all possible vCPUs */
> > + possible_cpus = mc->possible_cpu_arch_ids(machine);
> > +
> > if (vms->secure) {
> > /*
> > * The Secure view of the world is the same as the NonSecure,
> > @@ -2235,31 +2285,6 @@ static void machvirt_init(MachineState *machine)
> > vms->psci_conduit = QEMU_PSCI_CONDUIT_HVC;
> > }
> >
> > - /*
> > - * The maximum number of CPUs depends on the GIC version, or on how
> > - * many redistributors we can fit into the memory map (which in turn
> > - * depends on whether this is a GICv3 or v4).
> > - */
> > - if (vms->gic_version == VIRT_GIC_VERSION_2) {
> > - virt_max_cpus = GIC_NCPU;
> > - } else {
> > - virt_max_cpus = virt_redist_capacity(vms, VIRT_GIC_REDIST);
> > - if (vms->highmem_redists) {
> > - virt_max_cpus += virt_redist_capacity(vms, VIRT_HIGH_GIC_REDIST2);
> > - }
> > - }
> > -
> > - if (max_cpus > virt_max_cpus) {
> > - error_report("Number of SMP CPUs requested (%d) exceeds max CPUs "
> > - "supported by machine 'mach-virt' (%d)",
> > - max_cpus, virt_max_cpus);
> > - if (vms->gic_version != VIRT_GIC_VERSION_2 && !vms->highmem_redists) {
> > - error_printf("Try 'highmem-redists=on' for more CPUs\n");
> > - }
> > -
> > - exit(1);
> > - }
> > -
> > if (vms->secure && !tcg_enabled() && !qtest_enabled()) {
> > error_report("mach-virt: %s does not support providing "
> > "Security extensions (TrustZone) to the guest CPU",
> > @@ -3245,6 +3270,9 @@ static void virt_machine_class_init(ObjectClass *oc, const void *data)
> > hc->plug = virt_machine_device_plug_cb;
> > hc->unplug_request = virt_machine_device_unplug_request_cb;
> > hc->unplug = virt_machine_device_unplug_cb;
> > +
> > + mc->has_online_capable_cpus = true;
> > +
> > mc->nvdimm_supported = true;
> > mc->smp_props.clusters_supported = true;
> > mc->auto_enable_numa_with_memhp = true;
> > diff --git a/include/hw/boards.h b/include/hw/boards.h
> > index 2b182d7817..b27c2326a2 100644
> > --- a/include/hw/boards.h
> > +++ b/include/hw/boards.h
> > @@ -302,6 +302,7 @@ struct MachineClass {
> > bool rom_file_has_mr;
> > int minimum_page_bits;
> > bool has_hotpluggable_cpus;
> > + bool has_online_capable_cpus;
> > bool ignore_memory_transaction_failures;
> > int numa_mem_align_shift;
> > const char * const *valid_cpu_types;
> > --
> > 2.34.1
> >
>
next prev parent reply other threads:[~2025-10-09 13:13 UTC|newest]
Thread overview: 51+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-10-01 1:01 [PATCH RFC V6 00/24] Support of Virtual CPU Hotplug-like Feature for ARMv8+ Arch salil.mehta
2025-10-01 1:01 ` [PATCH RFC V6 01/24] hw/core: Introduce administrative power-state property and its accessors salil.mehta
2025-10-09 10:48 ` Miguel Luis
2025-10-01 1:01 ` [PATCH RFC V6 02/24] hw/core, qemu-options.hx: Introduce 'disabledcpus' SMP parameter salil.mehta
2025-10-09 11:28 ` Miguel Luis
2025-10-09 13:17 ` Igor Mammedov
2025-10-09 11:51 ` Markus Armbruster
2025-10-01 1:01 ` [PATCH RFC V6 03/24] hw/arm/virt: Clamp 'maxcpus' as-per machine's vCPU deferred online-capability salil.mehta
2025-10-09 12:32 ` Miguel Luis
2025-10-09 13:11 ` Igor Mammedov [this message]
2025-10-01 1:01 ` [PATCH RFC V6 04/24] arm/virt, target/arm: Add new ARMCPU {socket, cluster, core, thread}-id property salil.mehta
2025-10-01 1:01 ` [PATCH RFC V6 05/24] arm/virt, kvm: Pre-create KVM vCPUs for 'disabled' QOM vCPUs at machine init salil.mehta
2025-10-01 1:01 ` [PATCH RFC V6 06/24] arm/virt, gicv3: Pre-size GIC with possible " salil.mehta
2025-10-01 1:01 ` [PATCH RFC V6 07/24] arm/gicv3: Refactor CPU interface init for shared TCG/KVM use salil.mehta
2025-10-01 1:01 ` [PATCH RFC V6 08/24] arm/virt, gicv3: Guard CPU interface access for admin disabled vCPUs salil.mehta
2025-10-01 1:01 ` [PATCH RFC V6 09/24] hw/intc/arm_gicv3_common: Migrate & check 'GICv3CPUState' accessibility mismatch salil.mehta
2025-10-01 1:01 ` [PATCH RFC V6 10/24] arm/virt: Init PMU at host for all present vCPUs salil.mehta
2025-10-03 15:02 ` Igor Mammedov
2025-10-01 1:01 ` [PATCH RFC V6 11/24] hw/arm/acpi: MADT change to size the guest with possible vCPUs salil.mehta
2025-10-03 15:09 ` Igor Mammedov
[not found] ` <0175e40f70424dd9a29389b8a4f16c42@huawei.com>
2025-10-07 12:20 ` Igor Mammedov
2025-10-10 3:15 ` Salil Mehta
2025-10-01 1:01 ` [PATCH RFC V6 12/24] hw/core: Introduce generic device power-state handler interface salil.mehta
2025-10-01 1:01 ` [PATCH RFC V6 13/24] qdev: make admin power state changes trigger platform transitions via ACPI salil.mehta
2025-10-01 1:01 ` [PATCH RFC V6 14/24] arm/acpi: Introduce dedicated CPU OSPM interface for ARM-like platforms salil.mehta
2025-10-03 14:58 ` Igor Mammedov
[not found] ` <7da6a9c470684754810414f0abd23a62@huawei.com>
2025-10-07 12:06 ` Igor Mammedov
2025-10-10 3:00 ` Salil Mehta
2025-10-01 1:01 ` [PATCH RFC V6 15/24] acpi/ged: Notify OSPM of CPU administrative state changes via GED salil.mehta
2025-10-01 1:01 ` [PATCH RFC V6 16/24] arm/virt/acpi: Update ACPI DSDT Tbl to include 'Online-Capable' CPUs AML salil.mehta
2025-10-01 1:01 ` [PATCH RFC V6 17/24] hw/arm/virt, acpi/ged: Add PowerStateHandler hooks for runtime CPU state changes salil.mehta
2025-10-01 1:01 ` [PATCH RFC V6 18/24] target/arm/kvm, tcg: Handle SMCCC hypercall exits in VMM during PSCI_CPU_{ON, OFF} salil.mehta
2025-10-01 1:01 ` [PATCH RFC V6 19/24] target/arm/cpu: Add the Accessor hook to fetch ARM CPU arch-id salil.mehta
2025-10-01 1:01 ` [PATCH RFC V6 20/24] target/arm/kvm: Write vCPU's state back to KVM on cold-reset salil.mehta
2025-10-01 1:01 ` [PATCH RFC V6 21/24] hw/intc/arm-gicv3-kvm: Pause all vCPUs & cache ICC_CTLR_EL1 for userspace PSCI CPU_ON salil.mehta
2025-10-01 1:01 ` [PATCH RFC V6 22/24] monitor, qdev: Introduce 'device_set' to change admin state of existing devices salil.mehta
2025-10-09 8:55 ` [PATCH RFC V6 22/24] monitor,qdev: " Markus Armbruster
2025-10-09 12:51 ` Igor Mammedov
2025-10-09 14:03 ` Daniel P. Berrangé
2025-10-09 14:55 ` Markus Armbruster
2025-10-09 15:19 ` Peter Maydell
2025-10-10 4:59 ` Markus Armbruster
2025-10-01 1:01 ` [PATCH RFC V6 23/24] monitor, qapi: add 'info cpus-powerstate' and QMP query (Admin + Oper states) salil.mehta
2025-10-09 11:53 ` [PATCH RFC V6 23/24] monitor,qapi: " Markus Armbruster
2025-10-01 1:01 ` [PATCH RFC V6 24/24] tcg: Defer TB flush for 'lazy realized' vCPUs on first region alloc salil.mehta
2025-10-01 21:34 ` Richard Henderson
2025-10-02 12:27 ` Salil Mehta via
2025-10-02 15:41 ` Richard Henderson
2025-10-07 10:14 ` Salil Mehta via
2025-10-06 14:00 ` [PATCH RFC V6 00/24] Support of Virtual CPU Hotplug-like Feature for ARMv8+ Arch Igor Mammedov
2025-10-13 0:34 ` Gavin Shan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251009151123.6741ac61@fedora \
--to=imammedo@redhat.com \
--cc=alex.bennee@linaro.org \
--cc=andrew.jones@linux.dev \
--cc=ardb@kernel.org \
--cc=armbru@redhat.com \
--cc=borntraeger@linux.ibm.com \
--cc=darren@os.amperecomputing.com \
--cc=david@redhat.com \
--cc=devel@lists.libvirt.org \
--cc=eric.auger@redhat.com \
--cc=gankulkarni@os.amperecomputing.com \
--cc=gshan@redhat.com \
--cc=gustavo.romero@linaro.org \
--cc=harshpb@linux.ibm.com \
--cc=ilkka@os.amperecomputing.com \
--cc=jean-philippe@linaro.org \
--cc=jiakernel2@gmail.com \
--cc=jonathan.cameron@huawei.com \
--cc=karl.heubaum@oracle.com \
--cc=linux@armlinux.org.uk \
--cc=linuxarm@huawei.com \
--cc=lixianglai@loongson.cn \
--cc=lpieralisi@kernel.org \
--cc=maobibo@loongson.cn \
--cc=maz@kernel.org \
--cc=miguel.luis@oracle.com \
--cc=mst@redhat.com \
--cc=npiggin@gmail.com \
--cc=oliver.upton@linux.dev \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=philmd@linaro.org \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=rafael@kernel.org \
--cc=richard.henderson@linaro.org \
--cc=salil.mehta@huawei.com \
--cc=salil.mehta@opnsrc.net \
--cc=shahuang@redhat.com \
--cc=vishnu@os.amperecomputing.com \
--cc=wangxiongfeng2@huawei.com \
--cc=wangyanan55@huawei.com \
--cc=wangzhou1@hisilicon.com \
--cc=will@kernel.org \
--cc=zhao1.liu@intel.com \
--cc=zhukeqian1@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).