From: Oliver Upton <oliver.upton@linux.dev>
To: kvmarm@lists.linux.dev
Cc: Marc Zyngier <maz@kernel.org>, Joey Gouly <joey.gouly@arm.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
Zenghui Yu <yuzenghui@huawei.com>,
Raghavendra Rao Ananta <rananta@google.com>,
Ben Horgan <ben.horgan@arm.com>,
Oliver Upton <oliver.upton@linux.dev>
Subject: [PATCH v2 3/4] KVM: arm64: Introduce attribute to control GICD_TYPER2.nASSGIcap
Date: Fri, 30 May 2025 18:25:44 -0700 [thread overview]
Message-ID: <20250531012545.709887-4-oliver.upton@linux.dev> (raw)
In-Reply-To: <20250531012545.709887-1-oliver.upton@linux.dev>
From: Raghavendra Rao Ananta <rananta@google.com>
KVM unconditionally advertises GICD_TYPER2.nASSGIcap (which internally
implies vSGIs) on GICv4.1 systems. Allow userspace to change whether a
VM supports the feature. Only allow changes prior to VGIC initialization
as at that point vPEs need to be allocated for the VM.
For convenience, bundle support for vLPIs and vSGIs behind this feature,
allowing userspace to control vPE allocation for VMs in environments
that may be constrained on vPE IDs.
Signed-off-by: Raghavendra Rao Ananta <rananta@google.com>
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
---
.../virt/kvm/devices/arm-vgic-v3.rst | 29 +++++++++++++++
arch/arm64/include/uapi/asm/kvm.h | 3 ++
arch/arm64/kvm/vgic/vgic-init.c | 3 ++
arch/arm64/kvm/vgic/vgic-kvm-device.c | 37 +++++++++++++++++++
arch/arm64/kvm/vgic/vgic-mmio-v3.c | 10 ++++-
include/kvm/arm_vgic.h | 3 ++
6 files changed, 84 insertions(+), 1 deletion(-)
diff --git a/Documentation/virt/kvm/devices/arm-vgic-v3.rst b/Documentation/virt/kvm/devices/arm-vgic-v3.rst
index e860498b1e35..049d77eae591 100644
--- a/Documentation/virt/kvm/devices/arm-vgic-v3.rst
+++ b/Documentation/virt/kvm/devices/arm-vgic-v3.rst
@@ -306,3 +306,32 @@ Groups:
The vINTID specifies which interrupt is generated when the vGIC
must generate a maintenance interrupt. This must be a PPI.
+
+ KVM_DEV_ARM_VGIC_GRP_FEATURES
+ Attributes:
+
+ KVM_DEV_ARM_VGIC_FEATURE_nASSGIcap
+ Control whether support for SGIs without an active state is exposed
+ to the VM. attr->addr points to a __u8 value which indicates whether
+ he feature is enabled / disabled.
+
+ A value of 0 indicates that the feature is disabled. A nonzero value
+ indicates that the feature is enabled.
+
+ This attribute can only be set prior to initializing the VGIC (i.e.
+ KVM_DEV_ARM_VGIC_CTRL_INIT).
+
+ Support for SGIs without an active state depends on hardware support.
+ Userspace can discover support for the feature by reading the
+ attribute after creating a VGICv3. It is possible that
+ KVM_DEV_ARM_VGIC_CTRL_INIT can later fail if this feature is enabled
+ and KVM is unable to allocate GIC vPEs for the VM.
+
+ Errors:
+
+ ======= ========================================================
+ -ENXIO Invalid attribute in attr->attr
+ -EFAULT Invalid user address in attr->addr
+ -EBUSY The VGIC has already been initialized
+ -EINVAL KVM doesn't support the requested feature setting
+ ======= ========================================================
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index ed5f3892674c..41e9ce412afd 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -417,6 +417,7 @@ enum {
#define KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO 7
#define KVM_DEV_ARM_VGIC_GRP_ITS_REGS 8
#define KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ 9
+#define KVM_DEV_ARM_VGIC_GRP_FEATURES 10
#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT 10
#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_MASK \
(0x3fffffULL << KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT)
@@ -429,6 +430,8 @@ enum {
#define KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES 3
#define KVM_DEV_ARM_ITS_CTRL_RESET 4
+#define KVM_DEV_ARM_VGIC_FEATURE_nASSGIcap 0
+
/* Device Control API on vcpu fd */
#define KVM_ARM_VCPU_PMU_V3_CTRL 0
#define KVM_ARM_VCPU_PMU_V3_IRQ 0
diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c
index fd9e639cd665..93a616131ed6 100644
--- a/arch/arm64/kvm/vgic/vgic-init.c
+++ b/arch/arm64/kvm/vgic/vgic-init.c
@@ -132,6 +132,9 @@ int kvm_vgic_create(struct kvm *kvm, u32 type)
kvm->arch.vgic.in_kernel = true;
kvm->arch.vgic.vgic_model = type;
+ if (type == KVM_DEV_TYPE_ARM_VGIC_V3)
+ kvm->arch.vgic.nassgicap = kvm_vgic_global_state.has_gicv4_1 &&
+ gic_cpuif_has_vsgi();
kvm->arch.vgic.vgic_dist_base = VGIC_ADDR_UNDEF;
diff --git a/arch/arm64/kvm/vgic/vgic-kvm-device.c b/arch/arm64/kvm/vgic/vgic-kvm-device.c
index b0baad68777c..c9d41ae9fe4f 100644
--- a/arch/arm64/kvm/vgic/vgic-kvm-device.c
+++ b/arch/arm64/kvm/vgic/vgic-kvm-device.c
@@ -626,6 +626,26 @@ static int vgic_v3_set_attr(struct kvm_device *dev,
dev->kvm->arch.vgic.mi_intid = val;
return 0;
}
+ case KVM_DEV_ARM_VGIC_GRP_FEATURES: {
+ u8 __user *uaddr = (u8 __user *)attr->addr;
+ u8 val;
+
+ if (attr->attr != KVM_DEV_ARM_VGIC_FEATURE_nASSGIcap)
+ return -ENXIO;
+
+ if (get_user(val, uaddr))
+ return -EFAULT;
+
+ guard(mutex)(&dev->kvm->arch.config_lock);
+ if (vgic_initialized(dev->kvm))
+ return -EBUSY;
+
+ if (!(kvm_vgic_global_state.has_gicv4_1 && gic_cpuif_has_vsgi()) && val)
+ return -EINVAL;
+
+ dev->kvm->arch.vgic.nassgicap = val;
+ return 0;
+ }
default:
return vgic_set_common_attr(dev, attr);
}
@@ -646,6 +666,17 @@ static int vgic_v3_get_attr(struct kvm_device *dev,
guard(mutex)(&dev->kvm->arch.config_lock);
return put_user(dev->kvm->arch.vgic.mi_intid, uaddr);
}
+ case KVM_DEV_ARM_VGIC_GRP_FEATURES: {
+ u8 __user *uaddr = (u8 __user *)attr->addr;
+ u8 val;
+
+ if (attr->attr != KVM_DEV_ARM_VGIC_FEATURE_nASSGIcap)
+ return -ENXIO;
+
+ guard(mutex)(&dev->kvm->arch.config_lock);
+ val = dev->kvm->arch.vgic.nassgicap;
+ return put_user(val, uaddr);
+ }
default:
return vgic_get_common_attr(dev, attr);
}
@@ -683,8 +714,14 @@ static int vgic_v3_has_attr(struct kvm_device *dev,
return 0;
case KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES:
return 0;
+ default:
+ return -ENXIO;
}
+ case KVM_DEV_ARM_VGIC_GRP_FEATURES:
+ return attr->attr != KVM_DEV_ARM_VGIC_FEATURE_nASSGIcap ?
+ -ENXIO : 0;
}
+
return -ENXIO;
}
diff --git a/arch/arm64/kvm/vgic/vgic-mmio-v3.c b/arch/arm64/kvm/vgic/vgic-mmio-v3.c
index 1a9c5b4418b2..43f59e70e1a2 100644
--- a/arch/arm64/kvm/vgic/vgic-mmio-v3.c
+++ b/arch/arm64/kvm/vgic/vgic-mmio-v3.c
@@ -50,12 +50,20 @@ bool vgic_has_its(struct kvm *kvm)
bool vgic_supports_direct_msis(struct kvm *kvm)
{
+ /*
+ * Deliberately conflate vLPI and vSGI support on GICv4.1 hardware,
+ * indirectly allowing userspace to control whether or not vPEs are
+ * allocated for the VM.
+ */
+ if (kvm_vgic_global_state.has_gicv4_1 && !vgic_supports_direct_sgis(kvm))
+ return false;
+
return kvm_vgic_global_state.has_gicv4 && vgic_has_its(kvm);
}
bool vgic_supports_direct_sgis(struct kvm *kvm)
{
- return kvm_vgic_global_state.has_gicv4_1 && gic_cpuif_has_vsgi();
+ return kvm->arch.vgic.nassgicap;
}
/*
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 714cef854c1c..0e8cface0878 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -264,6 +264,9 @@ struct vgic_dist {
/* distributor enabled */
bool enabled;
+ /* Supports SGIs without active state */
+ bool nassgicap;
+
/* Wants SGIs without active state */
bool nassgireq;
--
2.39.5
next prev parent reply other threads:[~2025-05-31 1:26 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-05-31 1:25 [PATCH v2 0/4] KVM: arm64: Add attribute to control GICD_TYPER2.nASSGIcap Oliver Upton
2025-05-31 1:25 ` [PATCH v2 1/4] KVM: arm64: Disambiguate support for vSGIs v. vLPIs Oliver Upton
2025-05-31 1:25 ` [PATCH v2 2/4] KVM: arm64: vgic-v3: Consolidate MAINT_IRQ handling Oliver Upton
2025-05-31 1:25 ` Oliver Upton [this message]
2025-06-03 18:33 ` [PATCH v2 3/4] KVM: arm64: Introduce attribute to control GICD_TYPER2.nASSGIcap Raghavendra Rao Ananta
2025-06-03 19:03 ` Oliver Upton
2025-05-31 1:25 ` [PATCH v2 4/4] KVM: arm64: selftests: Add test for nASSGIcap attribute Oliver Upton
2025-06-03 18:42 ` Raghavendra Rao Ananta
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=20250531012545.709887-4-oliver.upton@linux.dev \
--to=oliver.upton@linux.dev \
--cc=ben.horgan@arm.com \
--cc=joey.gouly@arm.com \
--cc=kvmarm@lists.linux.dev \
--cc=maz@kernel.org \
--cc=rananta@google.com \
--cc=suzuki.poulose@arm.com \
--cc=yuzenghui@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.