diff --git a/target/arm/aarch64-qmp-cmds.c b/target/arm/aarch64-qmp-cmds.c index 10e35e163d..241a6662f1 100644 --- a/target/arm/aarch64-qmp-cmds.c +++ b/target/arm/aarch64-qmp-cmds.c @@ -36,7 +36,11 @@ CcaCapability *qmp_query_cca_capabilities(Error **errp) return NULL; } - if (!kvm_check_extension(kvm_state, KVM_CAP_ARM_RME)) { + /* + * Use the runtime-detected KVM_CAP_ARM_RME value to handle + * the ABI change between kernel versions (243 on 6.16, 244 on later). + */ + if (!kvm_check_extension(kvm_state, kvm_arm_rme_get_cap())) { error_setg(errp, "RME is not enabled in KVM"); return NULL; } diff --git a/target/arm/kvm-rme.c b/target/arm/kvm-rme.c index cf4f1ed1d7..5b6de24539 100644 --- a/target/arm/kvm-rme.c +++ b/target/arm/kvm-rme.c @@ -23,6 +23,37 @@ #include "system/runstate.h" #include +/* + * Returns the correct KVM_CAP_ARM_RME capability value for the running kernel. + * This handles the ABI change between kernel versions: + * - Linux 6.16: KVM_CAP_ARM_RME == 243 + * - Linux 6.17+: KVM_CAP_ARM_RME == 244 + */ +unsigned int kvm_arm_rme_get_cap(void) +{ + static unsigned int rme_cap = 0; + static bool detected = false; + + if (!detected) { + struct utsname buf; + int major, minor; + + rme_cap = KVM_CAP_ARM_RME; + + if (uname(&buf) == 0) { + if (sscanf(buf.release, "%d.%d", &major, &minor) == 2) { + /* For Linux kernel v6.16, KVM_CAP_ARM_RME == 243 */ + if ((major == 6) && (minor == 16)) { + rme_cap = 243; + } + } + } + detected = true; + } + + return rme_cap; +} + #define TYPE_RME_GUEST "rme-guest" OBJECT_DECLARE_SIMPLE_TYPE(RmeGuest, RME_GUEST) @@ -788,9 +819,6 @@ static void rme_guest_class_init(ObjectClass *oc, const void *data) static void rme_guest_init(Object *obj) { - struct utsname buf; - int major, minor; - if (rme_guest) { error_report("a single instance of RmeGuest is supported"); exit(1); @@ -800,16 +828,7 @@ static void rme_guest_init(Object *obj) rme_guest->measurement_algo = RME_GUEST_MEASUREMENT_ALGORITHM_SHA512; rme_guest->mec_specified = false; - rme_guest->rme_capable = KVM_CAP_ARM_RME; - - if (uname(&buf) == 0) { - if (sscanf(buf.release, "%d.%d", &major, &minor) == 2) { - /* For Linux kernel v6.16, KVM_CAP_ARM_RME == 243 */ - if ((major == 6) && (minor == 16)) { - rme_guest->rme_capable = 243; - } - } - } + rme_guest->rme_capable = kvm_arm_rme_get_cap(); } static void rme_guest_finalize(Object *obj) diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h index 7c737fd35a..1eab906d0a 100644 --- a/target/arm/kvm_arm.h +++ b/target/arm/kvm_arm.h @@ -274,6 +274,15 @@ void kvm_arm_enable_mte(Object *cpuobj, Error **errp); void arm_cpu_kvm_set_irq(void *arm_cpu, int irq, int level); +/** + * kvm_arm_rme_get_cap: + * + * Returns the correct KVM_CAP_ARM_RME capability value for the running + * kernel. This handles the ABI change between kernel versions where the + * capability number differs (e.g., 243 on kernel 6.16, 244 on later kernels). + */ +unsigned int kvm_arm_rme_get_cap(void); + /** * kvm_arm_rme_init * @ms: the machine state