Add kvm_arm_vtlbid_supported() to check KVM_CAP_ARM_TLBIDOMAIN and kvm_arm_get_max_vdomains() to query the maximum number of TLBI domains supported by KVM via the KVM_ARM_GET_VDOMAIN_NUM ioctl. Add the corresponding KVM uapi definitions (KVM_CAP_ARM_TLBIDOMAIN and struct kvm_arm_get_vdomain) to linux-headers. These helpers are used by the subsequent -tlbidomain command-line parsing to validate the requested domain topology against KVM support. Signed-off-by: Tian Zheng <zhengtian10@huawei.com> --- linux-headers/linux/kvm.h | 8 ++++++++ target/arm/kvm64.c | 24 ++++++++++++++++++++++++ target/arm/kvm_arm.h | 25 +++++++++++++++++++++++++ 3 files changed, 57 insertions(+) diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h index 71ee851e6e..4d5792a95d 100644 --- a/linux-headers/linux/kvm.h +++ b/linux-headers/linux/kvm.h @@ -961,6 +961,7 @@ struct kvm_enable_cap { #define KVM_CAP_HYGON_COCO_EXT_CSV3_SP_MGR (1 << 4) #define KVM_CAP_ARM_HW_DIRTY_STATE_TRACK 502 +#define KVM_CAP_ARM_TLBIDOMAIN 503 #define KVM_CAP_ARM_HISI_IPIV 798 #define KVM_CAP_ARM_VIRT_MSI_BYPASS 799 @@ -1841,4 +1842,11 @@ struct kvm_create_guest_memfd { __u64 reserved[6]; }; +/* Available with KVM_CAP_ARM_TLBIDOMAIN */ +struct kvm_arm_get_vdomain { + __u8 max_vdomains; +}; + +#define KVM_ARM_GET_VDOMAIN_NUM _IOW(KVMIO, 0xd7, struct kvm_arm_get_vdomain) + #endif /* __LINUX_KVM_H */ diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c index ad202de259..a1255956f3 100644 --- a/target/arm/kvm64.c +++ b/target/arm/kvm64.c @@ -782,6 +782,30 @@ bool kvm_arm_vtimer_status_supported(void) return kvm_vm_check_extension(kvm_state, KVM_CAP_ARM_HISI_PVTIMER_STATUS); } +bool kvm_arm_vtlbid_supported(void) +{ + return kvm_check_extension(kvm_state, KVM_CAP_ARM_TLBIDOMAIN); +} + +uint8_t kvm_arm_get_max_vdomains(void) +{ + struct kvm_arm_get_vdomain arg; + int ret; + + if (!kvm_arm_vtlbid_supported()) { + return 0; + } + + ret = kvm_vm_ioctl(kvm_state, KVM_ARM_GET_VDOMAIN_NUM, &arg); + if (ret < 0) { + error_report("Failed to get max vdomains from KVM: %s", + strerror(errno)); + return 0; + } + + return arg.max_vdomains; +} + QEMU_BUILD_BUG_ON(KVM_ARM64_SVE_VQ_MIN != 1); uint32_t kvm_arm_sve_get_vls(CPUState *cs) diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h index 85b34533dd..645d1a8b45 100644 --- a/target/arm/kvm_arm.h +++ b/target/arm/kvm_arm.h @@ -329,6 +329,21 @@ void kvm_arm_steal_time_finalize(ARMCPU *cpu, Error **errp); */ bool kvm_arm_steal_time_supported(void); +/** + * kvm_arm_vtlbid_supported: + * + * Returns: true if KVM supports TLBI vdomain ioctl + * and false otherwise. + */ +bool kvm_arm_vtlbid_supported(void); + +/** + * kvm_arm_get_max_vdomains: + * + * Returns: max number of vdomains supported by KVM (0 if not supported). + */ +uint8_t kvm_arm_get_max_vdomains(void); + /** * kvm_arm_vtimer_status_finalize: * @cpu: ARMCPU for which to finalize kvm-vtimer-status @@ -570,6 +585,16 @@ static inline bool kvm_arm_vtimer_status_supported(void) return false; } +static inline bool kvm_arm_vtlbid_supported(void) +{ + return false; +} + +static inline uint8_t kvm_arm_get_max_vdomains(void) +{ + return 0; +} + static inline void kvm_arm_rme_init_guest_ram(hwaddr base, size_t size) { } -- 2.33.0