[PATCH 1/2] KVM: arm64: vgic: Require matching VGIC model for GICv3 ITS

Sascha Bischoff sascha.bischoff at arm.com
Fri Oct 16 08:22:23 PDT 2026


On a GICv5 host with legacy support, KVM registers both VGICv3 and
VGICv5 devices. A VM can create a GICv3 ITS with another VGIC model,
setting has_its even though that model cannot use the GICv3 ITS.

Reject GICv3 ITS creation when the VM already has an incompatible VGIC.
KVM also permits creating an ITS before its VGIC, so record the model
required by the ITS and reject a later incompatible VGIC. Preserve
either creation order when the models match.

Signed-off-by: Sascha Bischoff <sascha.bischoff at arm.com>
---
 arch/arm64/kvm/vgic/vgic-init.c | 5 +++++
 arch/arm64/kvm/vgic/vgic-its.c  | 9 +++++++++
 include/kvm/arm_vgic.h          | 2 ++
 3 files changed, 16 insertions(+)

diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c
index b5ea1e39c6862..48a92555fa6ab 100644
--- a/arch/arm64/kvm/vgic/vgic-init.c
+++ b/arch/arm64/kvm/vgic/vgic-init.c
@@ -125,6 +125,11 @@ int kvm_vgic_create(struct kvm *kvm, u32 type)
 		goto out_unlock;
 	}
 
+	if (kvm->arch.vgic.its_model && kvm->arch.vgic.its_model != type) {
+		ret = -ENODEV;
+		goto out_unlock;
+	}
+
 	if (kvm_id_regs_final(kvm))
 		goto out_unlock;
 	ret = 0;
diff --git a/arch/arm64/kvm/vgic/vgic-its.c b/arch/arm64/kvm/vgic/vgic-its.c
index e5657cb603567..bf901626ea6df 100644
--- a/arch/arm64/kvm/vgic/vgic-its.c
+++ b/arch/arm64/kvm/vgic/vgic-its.c
@@ -1875,6 +1875,14 @@ static int vgic_its_create(struct kvm_device *dev, u32 type)
 
 	mutex_lock(&dev->kvm->arch.config_lock);
 
+	if ((irqchip_in_kernel(dev->kvm) && !vgic_is_v3(dev->kvm)) ||
+	    (dev->kvm->arch.vgic.its_model &&
+	     dev->kvm->arch.vgic.its_model != KVM_DEV_TYPE_ARM_VGIC_V3)) {
+		mutex_unlock(&dev->kvm->arch.config_lock);
+		kfree(its);
+		return -ENODEV;
+	}
+
 	if (vgic_initialized(dev->kvm)) {
 		ret = vgic_v4_init(dev->kvm);
 		if (ret < 0) {
@@ -1903,6 +1911,7 @@ static int vgic_its_create(struct kvm_device *dev, u32 type)
 
 	dev->kvm->arch.vgic.msis_require_devid = true;
 	dev->kvm->arch.vgic.has_its = true;
+	dev->kvm->arch.vgic.its_model = KVM_DEV_TYPE_ARM_VGIC_V3;
 	its->enabled = false;
 	its->dev = dev;
 
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 7be81b936bf10..a2b6b328808ba 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -548,6 +548,8 @@ struct vgic_dist {
 	struct vgic_io_device	cpuif_iodev;
 
 	bool			has_its;
+	/* VGIC model required by the VM's ITS devices. */
+	u32			its_model;
 	bool			table_write_in_progress;
 
 	/*
-- 
2.34.1




More information about the linux-arm-kernel mailing list