@@ -147,6 +147,9 @@ struct arm_boot_info {
* Confidential guest boot loads everything into RAM so it can be measured.
*/
bool confidential;
+ /* measurement log location in guest memory */
+ hwaddr log_start;
+ size_t log_size;
};
/**
@@ -180,6 +180,7 @@ struct VirtMachineState {
char *oem_id;
char *oem_table_id;
bool ns_el2_virt_timer_irq;
+ Object *event_log;
};
#define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM)
@@ -665,6 +665,24 @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
fdt_add_psci_node(fdt);
+ /* Add a reserved-memory node for the event log */
+ if (binfo->log_size) {
+ char *nodename;
+
+ qemu_fdt_add_subnode(fdt, "/reserved-memory");
+ qemu_fdt_setprop_cell(fdt, "/reserved-memory", "#address-cells", 0x2);
+ qemu_fdt_setprop_cell(fdt, "/reserved-memory", "#size-cells", 0x2);
+ qemu_fdt_setprop(fdt, "/reserved-memory", "ranges", NULL, 0);
+
+ nodename = g_strdup_printf("/reserved-memory/event-log@%" PRIx64,
+ binfo->log_start);
+ qemu_fdt_add_subnode(fdt, nodename);
+ qemu_fdt_setprop_string(fdt, nodename, "compatible", "cc-event-log");
+ qemu_fdt_setprop_sized_cells(fdt, nodename, "reg", 2, binfo->log_start,
+ 2, binfo->log_size);
+ g_free(nodename);
+ }
+
if (binfo->modify_dtb) {
binfo->modify_dtb(binfo, fdt);
}
@@ -943,6 +961,30 @@ static uint64_t load_aarch64_image(const char *filename, hwaddr mem_base,
return kernel_size;
}
+static void add_event_log(struct arm_boot_info *info)
+{
+ if (!info->log_size) {
+ return;
+ }
+
+ if (!info->dtb_limit) {
+ int dtb_size = 0;
+
+ if (!info->get_dtb(info, &dtb_size) || dtb_size == 0) {
+ error_report("Board does not have a DTB");
+ exit(1);
+ }
+ info->dtb_limit = info->dtb_start + dtb_size;
+ }
+
+ info->log_start = info->dtb_limit;
+ if (info->log_start + info->log_size >
+ info->loader_start + info->ram_size) {
+ error_report("Not enough space for measurement log and DTB");
+ exit(1);
+ }
+}
+
static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
struct arm_boot_info *info)
{
@@ -990,6 +1032,7 @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
}
info->dtb_start = info->loader_start;
info->dtb_limit = image_low_addr;
+ add_event_log(info);
}
}
entry = elf_entry;
@@ -1128,6 +1171,8 @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
error_report("Not enough space for DTB after kernel/initrd");
exit(1);
}
+ add_event_log(info);
+
fixupcontext[FIXUP_ARGPTR_LO] = info->dtb_start;
fixupcontext[FIXUP_ARGPTR_HI] = info->dtb_start >> 32;
} else {
@@ -1189,6 +1234,8 @@ static void arm_setup_confidential_firmware_boot(ARMCPU *cpu,
error_report("could not load firmware '%s'", firmware_filename);
exit(1);
}
+
+ add_event_log(info);
}
static void arm_setup_firmware_boot(ARMCPU *cpu, struct arm_boot_info *info,
@@ -1808,6 +1808,11 @@ void virt_machine_done(Notifier *notifier, void *data)
exit(1);
}
+ if (vms->event_log) {
+ object_property_set_uint(vms->event_log, "load-addr",
+ vms->bootinfo.log_start, &error_fatal);
+ }
+
fw_cfg_add_extra_pci_roots(vms->bus, vms->fw_cfg);
virt_acpi_setup(vms);
@@ -2149,6 +2154,21 @@ static void virt_cpu_post_init(VirtMachineState *vms, MemoryRegion *sysmem)
}
}
+static void create_measurement_log(VirtMachineState *vms)
+{
+ Error *err = NULL;
+
+ vms->event_log = kvm_arm_rme_get_measurement_log();
+ if (vms->event_log == NULL) {
+ return;
+ }
+ vms->bootinfo.log_size = object_property_get_uint(vms->event_log,
+ "max-size", &err);
+ if (err != NULL) {
+ error_report_err(err);
+ }
+}
+
static void machvirt_init(MachineState *machine)
{
VirtMachineState *vms = VIRT_MACHINE(machine);
@@ -2499,6 +2519,9 @@ static void machvirt_init(MachineState *machine)
vms->fw_cfg, OBJECT(vms));
}
+ kvm_arm_rme_set_ipa_size(64 - clz64(vms->highest_gpa));
+ create_measurement_log(vms);
+
vms->bootinfo.ram_size = machine->ram_size;
vms->bootinfo.board_id = -1;
vms->bootinfo.loader_start = vms->memmap[VIRT_MEM].base;
Create a measurement log describing operations performed by QEMU to initialize the guest, and load it into guest memory above the DTB. Cc: Stefan Berger <stefanb@linux.vnet.ibm.com> Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org> --- v2->v3: New --- include/hw/arm/boot.h | 3 +++ include/hw/arm/virt.h | 1 + hw/arm/boot.c | 47 +++++++++++++++++++++++++++++++++++++++++++ hw/arm/virt.c | 23 +++++++++++++++++++++ 4 files changed, 74 insertions(+)