@@ -187,6 +187,10 @@ void kvm_cpu__reset_vcpu(struct kvm_cpu *vcpu)
cpu_set_t *affinity;
int ret;
+ /* VCPU reset is done before activating the realm. */
+ if (kvm->arch.realm_is_active)
+ return;
+
affinity = kvm->arch.vcpu_affinity_cpuset;
if (affinity) {
ret = sched_setaffinity(0, sizeof(cpu_set_t), affinity);
@@ -1,4 +1,5 @@
#include "kvm/kvm.h"
+#include "kvm/kvm-cpu.h"
#include <linux/byteorder.h>
#include <asm/image.h>
@@ -192,3 +193,37 @@ void kvm_arm_realm_populate_dtb(struct kvm *kvm)
if (end > start)
realm_populate(kvm, start, end - start);
}
+
+static void kvm_arm_realm_activate_realm(struct kvm *kvm)
+{
+ struct kvm_enable_cap activate_realm = {
+ .cap = KVM_CAP_ARM_RME,
+ .args[0] = KVM_CAP_ARM_RME_ACTIVATE_REALM,
+ };
+
+ if (ioctl(kvm->vm_fd, KVM_ENABLE_CAP, &activate_realm) < 0)
+ die_perror("KVM_CAP_ARM_RME(KVM_CAP_ARM_RME_ACTIVATE_REALM)");
+
+ kvm->arch.realm_is_active = true;
+}
+
+static int kvm_arm_realm_finalize(struct kvm *kvm)
+{
+ int i;
+
+ if (!kvm->cfg.arch.is_realm)
+ return 0;
+
+ /*
+ * VCPU reset must happen before the realm is activated, because their
+ * state is part of the cryptographic measurement for the realm.
+ */
+ for (i = 0; i < kvm->nrcpus; i++)
+ kvm_cpu__reset_vcpu(kvm->cpus[i]);
+
+ /* Activate and seal the measurement for the realm. */
+ kvm_arm_realm_activate_realm(kvm);
+
+ return 0;
+}
+last_init(kvm_arm_realm_finalize)
@@ -116,6 +116,7 @@ struct kvm_arch {
cpu_set_t *vcpu_affinity_cpuset;
u64 measurement_algo;
u64 sve_vq;
+ bool realm_is_active;
};
#endif /* ARM_COMMON__KVM_ARCH_H */