[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[RFC PATCH 08/16] target/arm/kvm-rme: Populate the realm with boot image
From: |
Jean-Philippe Brucker |
Subject: |
[RFC PATCH 08/16] target/arm/kvm-rme: Populate the realm with boot images |
Date: |
Fri, 27 Jan 2023 15:07:21 +0000 |
Initialize the GPA space and populate it with boot images (kernel,
initrd, firmware, etc). Populating has to be done at VM start time,
because the images are loaded during reset by rom_reset()
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
---
target/arm/kvm_arm.h | 6 ++++
target/arm/kvm-rme.c | 79 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 85 insertions(+)
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
index e4dc7fbb8d..cec6500603 100644
--- a/target/arm/kvm_arm.h
+++ b/target/arm/kvm_arm.h
@@ -371,6 +371,7 @@ int kvm_arm_set_irq(int cpu, int irqtype, int irq, int
level);
int kvm_arm_rme_init(ConfidentialGuestSupport *cgs, Error **errp);
int kvm_arm_rme_vm_type(MachineState *ms);
+void kvm_arm_rme_add_blob(hwaddr start, hwaddr src_size, hwaddr dst_size);
bool kvm_arm_rme_enabled(void);
int kvm_arm_rme_vcpu_init(CPUState *cs);
@@ -458,6 +459,11 @@ static inline int kvm_arm_rme_vm_type(MachineState *ms)
{
return 0;
}
+
+static inline void kvm_arm_rme_add_blob(hwaddr start, hwaddr src_size,
+ hwaddr dst_size)
+{
+}
#endif
static inline const char *gic_class_name(void)
diff --git a/target/arm/kvm-rme.c b/target/arm/kvm-rme.c
index 3833b187f9..c8c019f78a 100644
--- a/target/arm/kvm-rme.c
+++ b/target/arm/kvm-rme.c
@@ -9,6 +9,7 @@
#include "exec/confidential-guest-support.h"
#include "hw/boards.h"
#include "hw/core/cpu.h"
+#include "hw/loader.h"
#include "kvm_arm.h"
#include "migration/blocker.h"
#include "qapi/error.h"
@@ -19,12 +20,22 @@
#define TYPE_RME_GUEST "rme-guest"
OBJECT_DECLARE_SIMPLE_TYPE(RmeGuest, RME_GUEST)
+#define RME_PAGE_SIZE qemu_real_host_page_size()
+
typedef struct RmeGuest RmeGuest;
struct RmeGuest {
ConfidentialGuestSupport parent_obj;
};
+struct RmeImage {
+ hwaddr base;
+ hwaddr src_size;
+ hwaddr dst_size;
+};
+
+static GSList *rme_images;
+
static RmeGuest *cgs_to_rme(ConfidentialGuestSupport *cgs)
{
if (!cgs) {
@@ -51,6 +62,38 @@ static int rme_create_rd(RmeGuest *guest, Error **errp)
return ret;
}
+static void rme_populate_realm(gpointer data, gpointer user_data)
+{
+ int ret;
+ struct RmeImage *image = data;
+ struct kvm_cap_arm_rme_init_ipa_args init_args = {
+ .init_ipa_base = image->base,
+ .init_ipa_size = image->dst_size,
+ };
+ struct kvm_cap_arm_rme_populate_realm_args populate_args = {
+ .populate_ipa_base = image->base,
+ .populate_ipa_size = image->src_size,
+ };
+
+ ret = kvm_vm_enable_cap(kvm_state, KVM_CAP_ARM_RME, 0,
+ KVM_CAP_ARM_RME_INIT_IPA_REALM,
+ (intptr_t)&init_args);
+ if (ret) {
+ error_setg_errno(&error_fatal, -ret,
+ "RME: failed to initialize GPA range
(0x%"HWADDR_PRIx", 0x%"HWADDR_PRIx")",
+ image->base, image->dst_size);
+ }
+
+ ret = kvm_vm_enable_cap(kvm_state, KVM_CAP_ARM_RME, 0,
+ KVM_CAP_ARM_RME_POPULATE_REALM,
+ (intptr_t)&populate_args);
+ if (ret) {
+ error_setg_errno(&error_fatal, -ret,
+ "RME: failed to populate realm (0x%"HWADDR_PRIx",
0x%"HWADDR_PRIx")",
+ image->base, image->src_size);
+ }
+}
+
static void rme_vm_state_change(void *opaque, bool running, RunState state)
{
int ret;
@@ -72,6 +115,9 @@ static void rme_vm_state_change(void *opaque, bool running,
RunState state)
}
}
+ g_slist_foreach(rme_images, rme_populate_realm, NULL);
+ g_slist_free_full(g_steal_pointer(&rme_images), g_free);
+
ret = kvm_vm_enable_cap(kvm_state, KVM_CAP_ARM_RME, 0,
KVM_CAP_ARM_RME_ACTIVATE_REALM);
if (ret) {
@@ -118,6 +164,39 @@ int kvm_arm_rme_init(ConfidentialGuestSupport *cgs, Error
**errp)
return 0;
}
+/*
+ * kvm_arm_rme_add_blob - Initialize the Realm IPA range and set up the image.
+ *
+ * @src_size is the number of bytes of the source image, to be populated into
+ * Realm memory.
+ * @dst_size is the effective image size, which may be larger than @src_size.
+ * For a kernel @dst_size may include zero-initialized regions such as the
BSS
+ * and initial page directory.
+ */
+void kvm_arm_rme_add_blob(hwaddr base, hwaddr src_size, hwaddr dst_size)
+{
+ struct RmeImage *image;
+
+ if (!kvm_arm_rme_enabled()) {
+ return;
+ }
+
+ base = QEMU_ALIGN_DOWN(base, RME_PAGE_SIZE);
+ src_size = QEMU_ALIGN_UP(src_size, RME_PAGE_SIZE);
+ dst_size = QEMU_ALIGN_UP(dst_size, RME_PAGE_SIZE);
+
+ image = g_malloc0(sizeof(*image));
+ image->base = base;
+ image->src_size = src_size;
+ image->dst_size = dst_size;
+
+ /*
+ * The ROM loader will only load the images during reset, so postpone the
+ * populate call until VM start.
+ */
+ rme_images = g_slist_prepend(rme_images, image);
+}
+
int kvm_arm_rme_vcpu_init(CPUState *cs)
{
ARMCPU *cpu = ARM_CPU(cs);
--
2.39.0
- Re: [RFC PATCH 02/16] target/arm: Add confidential guest support, (continued)
- [RFC PATCH 04/16] hw/arm/virt: Add support for Arm RME, Jean-Philippe Brucker, 2023/01/27
- [RFC PATCH 05/16] target/arm/kvm: Split kvm_arch_get/put_registers, Jean-Philippe Brucker, 2023/01/27
- [RFC PATCH 06/16] target/arm/kvm-rme: Initialize vCPU, Jean-Philippe Brucker, 2023/01/27
- [RFC PATCH 08/16] target/arm/kvm-rme: Populate the realm with boot images,
Jean-Philippe Brucker <=
- [RFC PATCH 09/16] hw/arm/boot: Populate realm memory with boot images, Jean-Philippe Brucker, 2023/01/27
- [RFC PATCH 13/16] target/arm/kvm-rme: Add breakpoints and watchpoints parameters, Jean-Philippe Brucker, 2023/01/27
- [RFC PATCH 10/16] target/arm/kvm-rme: Add measurement algorithm property, Jean-Philippe Brucker, 2023/01/27
- [RFC PATCH 11/16] target/arm/kvm-rme: Add Realm Personalization Value parameter, Jean-Philippe Brucker, 2023/01/27
- [RFC PATCH 12/16] target/arm/kvm-rme: Add Realm SVE vector length, Jean-Philippe Brucker, 2023/01/27