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


Reply via email to