Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Fuad Tabba and committed by
Marc Zyngier
8823485a f4eee308

+47
+2
arch/arm64/include/asm/kvm_host.h
··· 1655 1655 p; \ 1656 1656 }) 1657 1657 1658 + long kvm_get_cap_for_kvm_ioctl(unsigned int ioctl, long *ext); 1659 + 1658 1660 #endif /* __ARM64_KVM_HOST_H__ */
+45
arch/arm64/kvm/arm.c
··· 58 58 static enum kvm_wfx_trap_policy kvm_wfi_trap_policy __read_mostly = KVM_WFX_NOTRAP_SINGLE_TASK; 59 59 static enum kvm_wfx_trap_policy kvm_wfe_trap_policy __read_mostly = KVM_WFX_NOTRAP_SINGLE_TASK; 60 60 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 + 61 106 DECLARE_KVM_HYP_PER_CPU(unsigned long, kvm_hyp_vector); 62 107 63 108 DEFINE_PER_CPU(unsigned long, kvm_arm_hyp_stack_base);