Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion target/arm/aarch64-qmp-cmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
45 changes: 32 additions & 13 deletions target/arm/kvm-rme.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,37 @@
#include "system/runstate.h"
#include <sys/utsname.h>

/*
* 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)

Expand Down Expand Up @@ -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);
Expand All @@ -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)
Expand Down
9 changes: 9 additions & 0 deletions target/arm/kvm_arm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down