Skip to content

Commit 8823485

Browse files
Fuad TabbaMarc Zyngier
authored andcommitted
KVM: arm64: Track KVM IOCTLs and their associated KVM caps
Track KVM IOCTLs (VM IOCTLs for now), and the associated KVM capability that enables that IOCTL. Add a function that performs the lookup. This will be used by CoCo VM Hypervisors (e.g., pKVM) to determine whether a particular KVM IOCTL is allowed for its VMs. Suggested-by: Oliver Upton <oupton@kernel.org> Signed-off-by: Fuad Tabba <tabba@google.com> [maz: don't expose KVM_CAP_BASIC to userspace, and rely on NR_VCPUS as a proxy for this] Link: https://patch.msgid.link/20251211104710.151771-8-tabba@google.com Signed-off-by: Marc Zyngier <maz@kernel.org>
1 parent f4eee30 commit 8823485

2 files changed

Lines changed: 47 additions & 0 deletions

File tree

arch/arm64/include/asm/kvm_host.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1655,4 +1655,6 @@ static __always_inline enum fgt_group_id __fgt_reg_to_group_id(enum vcpu_sysreg
16551655
p; \
16561656
})
16571657

1658+
long kvm_get_cap_for_kvm_ioctl(unsigned int ioctl, long *ext);
1659+
16581660
#endif /* __ARM64_KVM_HOST_H__ */

arch/arm64/kvm/arm.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,51 @@ enum kvm_wfx_trap_policy {
5858
static enum kvm_wfx_trap_policy kvm_wfi_trap_policy __read_mostly = KVM_WFX_NOTRAP_SINGLE_TASK;
5959
static enum kvm_wfx_trap_policy kvm_wfe_trap_policy __read_mostly = KVM_WFX_NOTRAP_SINGLE_TASK;
6060

61+
/*
62+
* Tracks KVM IOCTLs and their associated KVM capabilities.
63+
*/
64+
struct kvm_ioctl_cap_map {
65+
unsigned int ioctl;
66+
long ext;
67+
};
68+
69+
/* Make KVM_CAP_NR_VCPUS the reference for features we always supported */
70+
#define KVM_CAP_ARM_BASIC KVM_CAP_NR_VCPUS
71+
72+
/*
73+
* Sorted by ioctl to allow for potential binary search,
74+
* though linear scan is sufficient for this size.
75+
*/
76+
static const struct kvm_ioctl_cap_map vm_ioctl_caps[] = {
77+
{ KVM_CREATE_IRQCHIP, KVM_CAP_IRQCHIP },
78+
{ KVM_ARM_SET_DEVICE_ADDR, KVM_CAP_ARM_SET_DEVICE_ADDR },
79+
{ KVM_ARM_MTE_COPY_TAGS, KVM_CAP_ARM_MTE },
80+
{ KVM_SET_DEVICE_ATTR, KVM_CAP_DEVICE_CTRL },
81+
{ KVM_GET_DEVICE_ATTR, KVM_CAP_DEVICE_CTRL },
82+
{ KVM_HAS_DEVICE_ATTR, KVM_CAP_DEVICE_CTRL },
83+
{ KVM_ARM_SET_COUNTER_OFFSET, KVM_CAP_COUNTER_OFFSET },
84+
{ KVM_ARM_GET_REG_WRITABLE_MASKS, KVM_CAP_ARM_SUPPORTED_REG_MASK_RANGES },
85+
{ KVM_ARM_PREFERRED_TARGET, KVM_CAP_ARM_BASIC },
86+
};
87+
88+
/*
89+
* Set *ext to the capability.
90+
* Return 0 if found, or -EINVAL if no IOCTL matches.
91+
*/
92+
long kvm_get_cap_for_kvm_ioctl(unsigned int ioctl, long *ext)
93+
{
94+
int i;
95+
96+
for (i = 0; i < ARRAY_SIZE(vm_ioctl_caps); i++) {
97+
if (vm_ioctl_caps[i].ioctl == ioctl) {
98+
*ext = vm_ioctl_caps[i].ext;
99+
return 0;
100+
}
101+
}
102+
103+
return -EINVAL;
104+
}
105+
61106
DECLARE_KVM_HYP_PER_CPU(unsigned long, kvm_hyp_vector);
62107

63108
DEFINE_PER_CPU(unsigned long, kvm_arm_hyp_stack_base);

0 commit comments

Comments
 (0)