[PATCH v2 36/36] KVM: arm64: gic-v5: Communicate userspace-drivable PPIs via a UAPI
Sascha Bischoff
Sascha.Bischoff at arm.com
Fri Dec 19 07:52:48 PST 2025
GICv5 systems will likely not support the full set of PPIs. The
presence of any virtual PPI is tied to the presence of the physical
PPI. Therefore, the available PPIs will be limited by the physical
host. Userspace cannot drive any PPIs that are not implemented.
Moreover, it is not desirable to expose all PPIs to the guest in the
first place, even if they are supported in hardware. Some devices,
such as the arch timer, are implemented in KVM, and hence those PPIs
shouldn't be driven by userspace, either.
Provided a new UAPI:
KVM_DEV_ARM_VGIC_GRP_CTRL => KVM_DEV_ARM_VGIC_USERPSPACE_PPIs
This allows userspace to query which PPIs it is able to drive via
KVM_IRQ_LINE.
Signed-off-by: Sascha Bischoff <sascha.bischoff at arm.com>
---
.../virt/kvm/devices/arm-vgic-v5.rst | 13 ++++++++++
arch/arm64/include/uapi/asm/kvm.h | 1 +
arch/arm64/kvm/vgic/vgic-kvm-device.c | 25 +++++++++++++++++++
arch/arm64/kvm/vgic/vgic-v5.c | 8 ++++++
include/kvm/arm_vgic.h | 5 ++++
include/linux/irqchip/arm-gic-v5.h | 4 +++
tools/arch/arm64/include/uapi/asm/kvm.h | 1 +
7 files changed, 57 insertions(+)
diff --git a/Documentation/virt/kvm/devices/arm-vgic-v5.rst b/Documentation/virt/kvm/devices/arm-vgic-v5.rst
index 9904cb888277d..d9f2917b609c5 100644
--- a/Documentation/virt/kvm/devices/arm-vgic-v5.rst
+++ b/Documentation/virt/kvm/devices/arm-vgic-v5.rst
@@ -25,6 +25,19 @@ Groups:
request the initialization of the VGIC, no additional parameter in
kvm_device_attr.addr. Must be called after all VCPUs have been created.
+ KVM_DEV_ARM_VGIC_USERPSPACE_PPIs
+ request the mask of userspace-drivable PPIs. Only a subset of the PPIs can
+ be directly driven from userspace with GICv5, and the returned mask
+ informs userspace of which it is allowed to drive via KVM_IRQ_LINE.
+
+ Userspace must allocate and point to __u64[2] with of data in
+ kvm_device_attr.addr. When this call returns, the provided memory will be
+ populated with the userspace PPI mask. The lower __u64 contains the mask
+ for the lower 64 PPIS, with the remaining 64 being in the second __u64.
+
+ This is a read-only attribute, and cannot be set. Attempts to set it are
+ rejected.
+
Errors:
======= ========================================================
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index a792a599b9d68..1c13bfa2d38aa 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -428,6 +428,7 @@ enum {
#define KVM_DEV_ARM_ITS_RESTORE_TABLES 2
#define KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES 3
#define KVM_DEV_ARM_ITS_CTRL_RESET 4
+#define KVM_DEV_ARM_VGIC_USERSPACE_PPIS 5
/* Device Control API on vcpu fd */
#define KVM_ARM_VCPU_PMU_V3_CTRL 0
diff --git a/arch/arm64/kvm/vgic/vgic-kvm-device.c b/arch/arm64/kvm/vgic/vgic-kvm-device.c
index 78903182bba08..360c78ed4f104 100644
--- a/arch/arm64/kvm/vgic/vgic-kvm-device.c
+++ b/arch/arm64/kvm/vgic/vgic-kvm-device.c
@@ -719,6 +719,25 @@ struct kvm_device_ops kvm_arm_vgic_v3_ops = {
.has_attr = vgic_v3_has_attr,
};
+static int vgic_v5_get_userspace_ppis(struct kvm_device *dev,
+ struct kvm_device_attr *attr)
+{
+ u64 __user *uaddr = (u64 __user *)(long)attr->addr;
+ struct gicv5_vm *gicv5_vm = &dev->kvm->arch.vgic.gicv5_vm;
+ int i, ret;
+
+ guard(mutex)(&dev->kvm->arch.config_lock);
+
+ for (i = 0; i < 2; ++i) {
+ ret = put_user(gicv5_vm->userspace_ppis[i], uaddr);
+ if (ret)
+ return ret;
+ uaddr++;
+ }
+
+ return 0;
+}
+
static int vgic_v5_set_attr(struct kvm_device *dev,
struct kvm_device_attr *attr)
{
@@ -731,6 +750,8 @@ static int vgic_v5_set_attr(struct kvm_device *dev,
switch (attr->attr) {
case KVM_DEV_ARM_VGIC_CTRL_INIT:
return vgic_set_common_attr(dev, attr);
+ case KVM_DEV_ARM_VGIC_USERSPACE_PPIS:
+ break;
default:
break;
}
@@ -751,6 +772,8 @@ static int vgic_v5_get_attr(struct kvm_device *dev,
switch (attr->attr) {
case KVM_DEV_ARM_VGIC_CTRL_INIT:
return vgic_get_common_attr(dev, attr);
+ case KVM_DEV_ARM_VGIC_USERSPACE_PPIS:
+ return vgic_v5_get_userspace_ppis(dev, attr);
default:
break;
}
@@ -771,6 +794,8 @@ static int vgic_v5_has_attr(struct kvm_device *dev,
switch (attr->attr) {
case KVM_DEV_ARM_VGIC_CTRL_INIT:
return 0;
+ case KVM_DEV_ARM_VGIC_USERSPACE_PPIS:
+ return 0;
default:
break;
}
diff --git a/arch/arm64/kvm/vgic/vgic-v5.c b/arch/arm64/kvm/vgic/vgic-v5.c
index bf72982d6a2e8..04300926683b6 100644
--- a/arch/arm64/kvm/vgic/vgic-v5.c
+++ b/arch/arm64/kvm/vgic/vgic-v5.c
@@ -122,6 +122,14 @@ int vgic_v5_init(struct kvm *kvm)
}
}
+ /*
+ * We only allow userspace to drive the SW_PPI, if it is
+ * implemented.
+ */
+ kvm->arch.vgic.gicv5_vm.userspace_ppis[0] = GICV5_SW_PPI & GICV5_HWIRQ_ID;
+ kvm->arch.vgic.gicv5_vm.userspace_ppis[0] &= ppi_caps->impl_ppi_mask[0];
+ kvm->arch.vgic.gicv5_vm.userspace_ppis[1] = 0;
+
return 0;
}
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 22f979b561054..5a7de3b74a99d 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -404,6 +404,11 @@ struct vgic_dist {
* else.
*/
struct its_vm its_vm;
+
+ /*
+ * GICv5 per-VM data.
+ */
+ struct gicv5_vm gicv5_vm;
};
struct vgic_v2_cpu_if {
diff --git a/include/linux/irqchip/arm-gic-v5.h b/include/linux/irqchip/arm-gic-v5.h
index 06ebb2a1cfb1d..123c6cfc344c5 100644
--- a/include/linux/irqchip/arm-gic-v5.h
+++ b/include/linux/irqchip/arm-gic-v5.h
@@ -365,6 +365,10 @@ struct gicv5_vpe {
bool resident;
};
+struct gicv5_vm {
+ u64 userspace_ppis[2];
+};
+
struct gicv5_its_devtab_cfg {
union {
struct {
diff --git a/tools/arch/arm64/include/uapi/asm/kvm.h b/tools/arch/arm64/include/uapi/asm/kvm.h
index a792a599b9d68..1c13bfa2d38aa 100644
--- a/tools/arch/arm64/include/uapi/asm/kvm.h
+++ b/tools/arch/arm64/include/uapi/asm/kvm.h
@@ -428,6 +428,7 @@ enum {
#define KVM_DEV_ARM_ITS_RESTORE_TABLES 2
#define KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES 3
#define KVM_DEV_ARM_ITS_CTRL_RESET 4
+#define KVM_DEV_ARM_VGIC_USERSPACE_PPIS 5
/* Device Control API on vcpu fd */
#define KVM_ARM_VCPU_PMU_V3_CTRL 0
--
2.34.1
More information about the linux-arm-kernel
mailing list