From: Sascha Bischoff <Sascha.Bischoff@arm•com>
To: "linux-arm-kernel@lists•infradead.org"
<linux-arm-kernel@lists•infradead.org>,
"kvmarm@lists•linux.dev" <kvmarm@lists•linux.dev>,
"kvm@vger•kernel.org" <kvm@vger•kernel.org>
Cc: nd <nd@arm•com>, "maz@kernel•org" <maz@kernel•org>,
"oliver.upton@linux•dev" <oliver.upton@linux•dev>,
Joey Gouly <Joey.Gouly@arm•com>,
Suzuki Poulose <Suzuki.Poulose@arm•com>,
"yuzenghui@huawei•com" <yuzenghui@huawei•com>,
"peter.maydell@linaro•org" <peter.maydell@linaro•org>,
"lpieralisi@kernel•org" <lpieralisi@kernel•org>,
Timothy Hayes <Timothy.Hayes@arm•com>
Subject: [PATCH v2 12/39] KVM: arm64: gic-v5: Keep GICv5 vCPU limit model-specific
Date: Thu, 21 May 2026 14:53:14 +0000 [thread overview]
Message-ID: <20260521144846.1899475-13-sascha.bischoff@arm.com> (raw)
In-Reply-To: <20260521144846.1899475-1-sascha.bischoff@arm.com>
A GICv5 host with FEAT_GCIE_LEGACY can expose both a native vGICv5 or
a vGICv3 device. These models do not necessarily have the same vCPU
limit: the native GICv5 limit is probed from the IRS VPE capacity,
while the GICv3 limit remains the fixed KVM vGICv3 limit.
Keep the IRS-derived limit separately for vGICv5 creation. The
pre-VGIC KVM_CAP_MAX_VCPUS value continues to expose the largest limit
among the still-selectable models, and kvm_vgic_create() clamps the VM
to the limit of the VGIC model userspace actually selected.
Signed-off-by: Sascha Bischoff <sascha.bischoff@arm•com>
---
arch/arm64/kvm/vgic/vgic-init.c | 14 +++++++++-----
arch/arm64/kvm/vgic/vgic-v5.c | 19 +++++++++----------
include/kvm/arm_vgic.h | 16 ++++++++++++----
3 files changed, 30 insertions(+), 19 deletions(-)
diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c
index 079a57c2b18f6..94632fd90b728 100644
--- a/arch/arm64/kvm/vgic/vgic-init.c
+++ b/arch/arm64/kvm/vgic/vgic-init.c
@@ -129,13 +129,17 @@ int kvm_vgic_create(struct kvm *kvm, u32 type)
}
ret = 0;
- if (type == KVM_DEV_TYPE_ARM_VGIC_V2)
+ switch (type) {
+ case KVM_DEV_TYPE_ARM_VGIC_V2:
kvm->max_vcpus = VGIC_V2_MAX_CPUS;
- else if (type == KVM_DEV_TYPE_ARM_VGIC_V3)
+ break;
+ case KVM_DEV_TYPE_ARM_VGIC_V3:
kvm->max_vcpus = VGIC_V3_MAX_CPUS;
- else if (type == KVM_DEV_TYPE_ARM_VGIC_V5)
- kvm->max_vcpus = min(VGIC_V5_MAX_CPUS,
- kvm_vgic_global_state.max_gic_vcpus);
+ break;
+ case KVM_DEV_TYPE_ARM_VGIC_V5:
+ kvm->max_vcpus = kvm_vgic_global_state.max_gicv5_vcpus;
+ break;
+ }
if (atomic_read(&kvm->online_vcpus) > kvm->max_vcpus) {
ret = -E2BIG;
diff --git a/arch/arm64/kvm/vgic/vgic-v5.c b/arch/arm64/kvm/vgic/vgic-v5.c
index f9578c2a634a4..909cef5f31afa 100644
--- a/arch/arm64/kvm/vgic/vgic-v5.c
+++ b/arch/arm64/kvm/vgic/vgic-v5.c
@@ -110,7 +110,8 @@ int vgic_v5_probe(const struct gic_kvm_info *info)
int ret;
kvm_vgic_global_state.type = VGIC_V5;
- kvm_vgic_global_state.max_gic_vcpus = VGIC_V5_MAX_CPUS;
+ kvm_vgic_global_state.max_gic_vcpus = 0;
+ kvm_vgic_global_state.max_gicv5_vcpus = 0;
kvm_vgic_global_state.vcpu_base = 0;
kvm_vgic_global_state.vctrl_base = NULL;
@@ -135,8 +136,8 @@ int vgic_v5_probe(const struct gic_kvm_info *info)
* Even if the HW supports more per-VM vCPUs, artificially cap as we
* can't use them all.
*/
- kvm_vgic_global_state.max_gic_vcpus = min(irs_caps.max_vpes,
- VGIC_V5_MAX_CPUS);
+ kvm_vgic_global_state.max_gicv5_vcpus = min(irs_caps.max_vpes,
+ VGIC_V5_MAX_CPUS);
/*
* GICv5 requires a set of tables to be allocated in order to manage
@@ -145,7 +146,7 @@ int vgic_v5_probe(const struct gic_kvm_info *info)
* we want to run. For now, we match the maximum number offered by the
* hardware, but this might not be a wise choice in the long term.
*/
- ret = vgic_v5_vmt_allocate(kvm_vgic_global_state.max_gic_vcpus);
+ ret = vgic_v5_vmt_allocate(kvm_vgic_global_state.max_gicv5_vcpus);
if (ret) {
kvm_err("Failed to allocate the GICv5 VM tables; no GICv5 support\n");
return -ENODEV;
@@ -166,9 +167,6 @@ int vgic_v5_probe(const struct gic_kvm_info *info)
return -ENODEV;
}
- kvm_vgic_global_state.max_gic_vcpus = min(irs_caps.max_vpes,
- VGIC_V5_MAX_CPUS);
-
ret = kvm_register_vgic_device(KVM_DEV_TYPE_ARM_VGIC_V5);
if (ret) {
kvm_err("Cannot register GICv5 KVM device.\n");
@@ -178,6 +176,8 @@ int vgic_v5_probe(const struct gic_kvm_info *info)
}
v5_registered = true;
+ kvm_vgic_global_state.max_gic_vcpus =
+ kvm_vgic_global_state.max_gicv5_vcpus;
kvm_info("GCIE system register CPU interface\n");
skip_v5:
@@ -205,9 +205,8 @@ int vgic_v5_probe(const struct gic_kvm_info *info)
return v5_registered ? 0 : ret;
}
- /* We potentially limit the max VCPUs further than we need to here */
- kvm_vgic_global_state.max_gic_vcpus = min(VGIC_V3_MAX_CPUS,
- kvm_vgic_global_state.max_gic_vcpus);
+ kvm_vgic_global_state.max_gic_vcpus = max(kvm_vgic_global_state.max_gic_vcpus,
+ VGIC_V3_MAX_CPUS);
static_branch_enable(&kvm_vgic_global_state.gicv3_cpuif);
kvm_info("GCIE legacy system register CPU interface\n");
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index ba32cd71fe0a7..6f736094a0e7e 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -157,9 +157,16 @@ struct vgic_global {
/* Maintenance IRQ number */
unsigned int maint_irq;
- /* maximum number of VCPUs allowed (GICv2 limits us to 8) */
+ /*
+ * Maximum number of VCPUs exposed before userspace has selected a
+ * VGIC model. Individual VGIC models can impose a lower limit
+ * (GICv2 limits us to 8).
+ */
int max_gic_vcpus;
+ /* Maximum number of VCPUs allowed for a GICv5 VM. */
+ int max_gicv5_vcpus;
+
/* Only needed for the legacy KVM_CREATE_IRQCHIP */
bool can_emulate_gicv2;
@@ -635,10 +642,11 @@ void kvm_vgic_process_async_update(struct kvm_vcpu *vcpu);
void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg, bool allow_group1);
/**
- * kvm_vgic_get_max_vcpus - Get the maximum number of VCPUs allowed by HW
+ * kvm_vgic_get_max_vcpus - Get the pre-VGIC-selection VCPU limit
*
- * The host's GIC naturally limits the maximum amount of VCPUs a guest
- * can use.
+ * Userspace can query KVM_CAP_MAX_VCPUS before selecting a VGIC model, so
+ * expose the highest model-specific limit and let kvm_vgic_create() enforce
+ * the selected model's actual limit.
*/
static inline int kvm_vgic_get_max_vcpus(void)
{
--
2.34.1
next prev parent reply other threads:[~2026-05-21 14:54 UTC|newest]
Thread overview: 47+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-21 14:49 [PATCH v2 00/39] KVM: arm64: Add GICv5 IRS support Sascha Bischoff
2026-05-21 14:49 ` [PATCH v2 01/39] irqchip/gic-v5: Allow KVM setup without a maintenance IRQ Sascha Bischoff
2026-05-21 14:49 ` [PATCH v2 02/39] irqchip/gic-v5: Provide OF IRS config frame attrs to KVM Sascha Bischoff
2026-05-21 14:50 ` [PATCH v2 03/39] irqchip/gic-v5: Setup gic_kvm_info on ACPI hosts Sascha Bischoff
2026-05-27 10:51 ` Marc Zyngier
2026-05-29 14:33 ` Sascha Bischoff
2026-05-28 7:14 ` Lorenzo Pieralisi
2026-05-29 14:41 ` Sascha Bischoff
2026-05-21 14:50 ` [PATCH v2 04/39] KVM: arm64: gic-v5: Define remaining IRS MMIO registers Sascha Bischoff
2026-05-21 14:50 ` [PATCH v2 05/39] arm64/sysreg: Add GICv5 GIC VDPEND and VDRCFG encodings Sascha Bischoff
2026-05-21 14:51 ` [PATCH v2 06/39] arm64/sysreg: Update ICC_CR0_EL1 with LINK and LINK_IDLE fields Sascha Bischoff
2026-05-21 14:51 ` [PATCH v2 07/39] KVM: arm64: gic-v5: Extract host IRS caps from IRS config frame Sascha Bischoff
2026-05-21 14:51 ` [PATCH v2 08/39] KVM: arm64: gic-v5: Add VPE doorbell domain Sascha Bischoff
2026-05-21 14:52 ` [PATCH v2 09/39] KVM: arm64: gic-v5: Create & manage VM and VPE tables Sascha Bischoff
2026-05-21 14:52 ` [PATCH v2 10/39] KVM: arm64: gic-v5: Introduce guest IST alloc and management Sascha Bischoff
2026-05-21 14:52 ` [PATCH v2 11/39] KVM: arm64: gic-v5: Implement VMT/vIST IRS MMIO Ops Sascha Bischoff
2026-05-21 14:53 ` Sascha Bischoff [this message]
2026-05-21 14:53 ` [PATCH v2 13/39] KVM: arm64: gic-v5: Implement VPE " Sascha Bischoff
2026-05-21 14:53 ` [PATCH v2 14/39] KVM: arm64: gic-v5: Set up VMTEs and VPE doorbells Sascha Bischoff
2026-05-21 14:54 ` [PATCH v2 15/39] KVM: arm64: gic-v5: Add resident/non-resident hyp calls Sascha Bischoff
2026-05-21 14:54 ` [PATCH v2 16/39] KVM: arm64: gic-v5: Request doorbells when VPEs enter WFI Sascha Bischoff
2026-05-21 14:54 ` [PATCH v2 17/39] KVM: arm64: gic-v5: Introduce struct vgic_v5_irs and IRS base address Sascha Bischoff
2026-05-21 14:55 ` [PATCH v2 18/39] KVM: arm64: gic-v5: Add IRS IODEV support to MMIO handlers Sascha Bischoff
2026-05-21 14:55 ` [PATCH v2 19/39] KVM: arm64: gic-v5: Add KVM_VGIC_V5_ADDR_TYPE_IRS to UAPI Sascha Bischoff
2026-05-21 14:55 ` [PATCH v2 20/39] KVM: arm64: gic-v5: Add GICv5 IRS IODEV and MMIO emulation Sascha Bischoff
2026-05-21 14:56 ` [PATCH v2 21/39] KVM: arm64: gic-v5: Initialise per-VM IRS state Sascha Bischoff
2026-05-21 14:56 ` [PATCH v2 22/39] KVM: arm64: gic-v5: Register the IRS IODEV Sascha Bischoff
2026-05-21 14:57 ` [PATCH v2 23/39] KVM: arm64: gic-v5: Set IRICHPPIDIS based on IRS enable state Sascha Bischoff
2026-05-21 14:57 ` [PATCH v2 24/39] KVM: arm64: selftests: Update vGICv5 selftest to set IRS address Sascha Bischoff
2026-05-21 14:57 ` [PATCH v2 25/39] KVM: arm64: gic-v5: Introduce SPI AP list Sascha Bischoff
2026-05-21 14:58 ` [PATCH v2 26/39] KVM: arm64: gic-v5: Add GIC VDPEND and GIC VDRCFG hyp calls Sascha Bischoff
2026-05-21 14:58 ` [PATCH v2 27/39] KVM: arm64: gic-v5: Track SPI state for in-flight SPIs Sascha Bischoff
2026-05-21 14:58 ` [PATCH v2 28/39] KVM: arm64: gic: Introduce set_pending_state() to irq_op Sascha Bischoff
2026-05-21 14:59 ` [PATCH v2 29/39] KVM: arm64: gic-v5: Support SPI injection Sascha Bischoff
2026-05-26 13:41 ` Vladimir Murzin
2026-05-28 14:59 ` Sascha Bischoff
2026-05-21 14:59 ` [PATCH v2 30/39] Documentation: KVM: Extend VGICv5 docs for KVM_VGIC_V5_ADDR_TYPE_IRS Sascha Bischoff
2026-05-21 14:59 ` [PATCH v2 31/39] KVM: arm64: gic-v5: Add GICv5 SPI injection to irqfd Sascha Bischoff
2026-06-04 10:51 ` Vladimir Murzin
2026-05-21 15:00 ` [PATCH v2 32/39] KVM: arm64: gic-v5: Mask per-vcpu PPI state in vgic_v5_finalize_ppi_state() Sascha Bischoff
2026-05-21 15:00 ` [PATCH v2 33/39] KVM: arm64: gic-v5: Add GICv5 EL1 sysreg userspace accessors Sascha Bischoff
2026-05-21 15:00 ` [PATCH v2 34/39] KVM: arm64: gic-v5: Handle userspace accesses to IRS MMIO region Sascha Bischoff
2026-05-21 15:01 ` [PATCH v2 35/39] KVM: arm64: gic-v5: Implement save/restore mechanisms for ISTs Sascha Bischoff
2026-05-21 15:01 ` [PATCH v2 36/39] Documentation: KVM: Document KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS for VGICv5 Sascha Bischoff
2026-05-21 15:01 ` [PATCH v2 37/39] Documentation: KVM: Add KVM_DEV_ARM_VGIC_GRP_IRS_REGS to VGICv5 docs Sascha Bischoff
2026-05-21 15:02 ` [PATCH v2 38/39] Documentation: KVM: Add docs for KVM_DEV_ARM_VGIC_GRP_IST Sascha Bischoff
2026-05-21 15:02 ` [PATCH v2 39/39] Documentation: KVM: Add the VGICv5 IRS save/restore sequences Sascha Bischoff
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=20260521144846.1899475-13-sascha.bischoff@arm.com \
--to=sascha.bischoff@arm$(echo .)com \
--cc=Joey.Gouly@arm$(echo .)com \
--cc=Suzuki.Poulose@arm$(echo .)com \
--cc=Timothy.Hayes@arm$(echo .)com \
--cc=kvm@vger$(echo .)kernel.org \
--cc=kvmarm@lists$(echo .)linux.dev \
--cc=linux-arm-kernel@lists$(echo .)infradead.org \
--cc=lpieralisi@kernel$(echo .)org \
--cc=maz@kernel$(echo .)org \
--cc=nd@arm$(echo .)com \
--cc=oliver.upton@linux$(echo .)dev \
--cc=peter.maydell@linaro$(echo .)org \
--cc=yuzenghui@huawei$(echo .)com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
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