On 9/4/26 5:35 AM, Mathieu Poirier wrote:
Initialise an @rme_guest object and install a handler to get notified
when the Realm is ready to start. That way we can finish reading the
Realm once we know everything is in place.
Signed-off-by: Jean-Philippe Brucker <[email protected]>
Signed-off-by: Lorenzo Pieralisi <[email protected]>
Signed-off-by: Mathieu Poirier <[email protected]>
---
target/arm/kvm-rme.c | 51 ++++++++++++++++++++++++++++++++++++++++++++
target/arm/kvm.c | 15 +++++++++++--
2 files changed, 64 insertions(+), 2 deletions(-)
diff --git a/target/arm/kvm-rme.c b/target/arm/kvm-rme.c
index 42e1d1e7b859..a4a5e195c196 100644
--- a/target/arm/kvm-rme.c
+++ b/target/arm/kvm-rme.c
@@ -13,6 +13,7 @@
#include "kvm_arm.h"
#include "migration/blocker.h"
#include "qapi/error.h"
+#include "qemu/error-report.h"
#include "qom/object_interfaces.h"
#include "system/confidential-guest-support.h"
#include "system/kvm.h"
@@ -29,12 +30,62 @@ OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES(RmeGuest,
rme_guest, RME_GUEST,
CONFIDENTIAL_GUEST_SUPPORT,
{ TYPE_USER_CREATABLE }, { })
+static RmeGuest *rme_guest;
+
+static void rme_vm_state_change(void *opaque, bool running, RunState state)
+{
+ if (!running) {
+ return;
+ }
+
+ kvm_mark_guest_state_protected();
+}
+
+static int kvm_arm_rme_init(ConfidentialGuestSupport *cgs, Error **errp)
+{
+ KVMState *s = KVM_STATE(current_accel());
+ static Error *rme_mig_blocker;
+
+ if (!rme_guest) {
+ return 0;
+ }
+
+ if (!kvm_vm_check_extension(s, KVM_CAP_ARM_RMI)) {
+ error_setg(errp, "VM doesn't support Realms");
+ return -ENODEV;
+ }
+
+ error_setg(&rme_mig_blocker, "RME: migration is not implemented");
+ migrate_add_blocker(&rme_mig_blocker, &error_fatal);
+
+ /*
+ * The realm activation is done last, when the VM starts, after all images
+ * have been loaded and all vcpus finalized.
+ */
+ qemu_add_vm_change_state_handler(rme_vm_state_change, NULL);
+
+ cgs->require_guest_memfd = true;
+ cgs->ready = true;
+ return 0;
+}
+
static void rme_guest_class_init(ObjectClass *oc, const void *data)
{
+ ConfidentialGuestSupportClass *klass =
CONFIDENTIAL_GUEST_SUPPORT_CLASS(oc);
+
+ klass->kvm_init = kvm_arm_rme_init;
}
static void rme_guest_init(Object *obj)
{
+ ConfidentialGuestSupport *cgs = CONFIDENTIAL_GUEST_SUPPORT(obj);
+
+ if (rme_guest) {
+ error_report("a single instance of RmeGuest is supported");
+ exit(1);
+ }
+ rme_guest = RME_GUEST(obj);
+ cgs->allow_convert_in_place = true;
}
static void rme_guest_finalize(Object *obj)
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index ed99be7fd80c..401a6f669cbb 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -33,6 +33,7 @@
#include "hw/pci/pci.h"
#include "exec/memattrs.h"
#include "system/address-spaces.h"
+#include "system/confidential-guest-support.h"
#include "gdbstub/enums.h"
#include "hw/core/boards.h"
#include "hw/core/irq.h"
@@ -596,7 +597,8 @@ int kvm_arch_get_default_type(MachineState *ms)
int kvm_arch_init(MachineState *ms, KVMState *s)
{
- int ret;
+ Error *local_err = NULL;
+ int ret = 0;
/* For ARM interrupt delivery is always asynchronous,
* whether we are using an in-kernel VGIC or not.
*/
@@ -610,6 +612,15 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
cap_has_mp_state = kvm_check_extension(s, KVM_CAP_MP_STATE);
+ /* Initialize confidential guest (Realm) if needed */
+ if (ms->cgs) {
+ ret = confidential_guest_kvm_init(ms->cgs, &local_err);
+ if (ret < 0) {
^^^^^
Code alignment issue here.
+ error_report_err(local_err);
+ return ret;
+ }
+ }
+
/* Check whether user space can specify guest syndrome value */
cap_has_inject_serror_esr =
kvm_check_extension(s, KVM_CAP_ARM_INJECT_SERROR_ESR);
@@ -660,7 +671,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
hw_breakpoints = g_array_sized_new(true, true,
sizeof(HWBreakpoint), max_hw_bps);
- return 0;
+ return ret;
}
unsigned long kvm_arch_vcpu_id(CPUState *cpu)
Thanks,
Gavin