[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[RFC PATCH v3 22/26] hw/arm/boot: Skip bootloader for confidential guest
From: |
Jean-Philippe Brucker |
Subject: |
[RFC PATCH v3 22/26] hw/arm/boot: Skip bootloader for confidential guests |
Date: |
Mon, 25 Nov 2024 19:56:21 +0000 |
An independent verifier needs to reconstruct the content of guest memory
in order to attest that it is running trusted code. To avoid having to
reconstruct the bootloader generated by QEMU, skip this step and jump
directly to the kernel, with the DTB address in x0 as specified by the
Linux boot protocol [1].
[1] https://docs.kernel.org/arch/arm64/booting.html
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
---
v2->v3: new
---
include/hw/arm/boot.h | 6 ++++++
hw/arm/boot.c | 23 +++++++++++++++++------
hw/arm/virt.c | 1 +
3 files changed, 24 insertions(+), 6 deletions(-)
diff --git a/include/hw/arm/boot.h b/include/hw/arm/boot.h
index d91cfc6942..5fcbaa2625 100644
--- a/include/hw/arm/boot.h
+++ b/include/hw/arm/boot.h
@@ -137,6 +137,12 @@ struct arm_boot_info {
arm_endianness endianness;
+ /*
+ * Instead of starting in a small bootloader that jumps to the kernel,
+ * immediately start in the kernel.
+ */
+ bool skip_bootloader;
+
/*
* Confidential guest boot loads everything into RAM so it can be measured.
*/
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 20b3071339..e461137595 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -762,7 +762,13 @@ static void do_cpu_reset(void *opaque)
if (cs == first_cpu) {
AddressSpace *as = arm_boot_address_space(cpu, info);
- cpu_set_pc(cs, info->loader_start);
+ if (info->skip_bootloader) {
+ assert(is_a64(env));
+ env->xregs[0] = info->dtb_start;
+ cpu_set_pc(cs, info->entry);
+ } else {
+ cpu_set_pc(cs, info->loader_start);
+ }
if (!have_dtb(info)) {
if (old_param) {
@@ -860,7 +866,8 @@ static ssize_t arm_load_elf(struct arm_boot_info *info,
uint64_t *pentry,
}
static uint64_t load_aarch64_image(const char *filename, hwaddr mem_base,
- hwaddr *entry, AddressSpace *as)
+ hwaddr *entry, AddressSpace *as,
+ bool skip_bootloader)
{
hwaddr kernel_load_offset = KERNEL64_LOAD_ADDR;
uint64_t kernel_size = 0;
@@ -912,7 +919,8 @@ static uint64_t load_aarch64_image(const char *filename,
hwaddr mem_base,
* bootloader, we can just load it starting at 2MB+offset rather
* than 0MB + offset.
*/
- if (kernel_load_offset < BOOTLOADER_MAX_SIZE) {
+ if (kernel_load_offset < BOOTLOADER_MAX_SIZE &&
+ !skip_bootloader) {
kernel_load_offset += 2 * MiB;
}
}
@@ -996,7 +1004,8 @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
}
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64) && kernel_size < 0) {
kernel_size = load_aarch64_image(info->kernel_filename,
- info->loader_start, &entry, as);
+ info->loader_start, &entry, as,
+ info->skip_bootloader);
is_linux = 1;
if (kernel_size >= 0) {
image_low_addr = entry;
@@ -1136,8 +1145,10 @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
fixupcontext[FIXUP_ENTRYPOINT_LO] = entry;
fixupcontext[FIXUP_ENTRYPOINT_HI] = entry >> 32;
- arm_write_bootloader("bootloader", as, info->loader_start,
- primary_loader, fixupcontext);
+ if (!info->skip_bootloader) {
+ arm_write_bootloader("bootloader", as, info->loader_start,
+ primary_loader, fixupcontext);
+ }
if (info->write_board_setup) {
info->write_board_setup(cpu, info);
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 0750c83fae..5247f53882 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -2509,6 +2509,7 @@ static void machvirt_init(MachineState *machine)
vms->bootinfo.firmware_max_size = vms->memmap[VIRT_FLASH].size;
vms->bootinfo.psci_conduit = vms->psci_conduit;
vms->bootinfo.confidential = virt_machine_is_confidential(vms);
+ vms->bootinfo.skip_bootloader = vms->bootinfo.confidential;
arm_load_kernel(ARM_CPU(first_cpu), machine, &vms->bootinfo);
vms->machine_done.notify = virt_machine_done;
--
2.47.0
- [PATCH v3 12/26] target/arm/cpu: Set number of breakpoints and watchpoints in KVM, (continued)
- [PATCH v3 12/26] target/arm/cpu: Set number of breakpoints and watchpoints in KVM, Jean-Philippe Brucker, 2024/11/25
- [PATCH v3 13/26] target/arm/cpu: Set number of PMU counters in KVM, Jean-Philippe Brucker, 2024/11/25
- [PATCH v3 14/26] target/arm/cpu: Inform about reading confidential CPU registers, Jean-Philippe Brucker, 2024/11/25
- [PATCH v3 16/26] hw/arm/virt: Disable DTB randomness for confidential VMs, Jean-Philippe Brucker, 2024/11/25
- [PATCH v3 08/26] hw/core/loader: Add ROM loader notifier, Jean-Philippe Brucker, 2024/11/25
- [PATCH v3 19/26] hw/arm/virt: Move virt_flash_create() to machvirt_init(), Jean-Philippe Brucker, 2024/11/25
- [PATCH v3 15/26] hw/arm/virt: Add support for Arm RME, Jean-Philippe Brucker, 2024/11/25
- [PATCH v3 17/26] hw/arm/virt: Reserve one bit of guest-physical address for RME, Jean-Philippe Brucker, 2024/11/25
- [PATCH v3 18/26] hw/arm/boot: Mark all guest memory as RIPAS_RAM., Jean-Philippe Brucker, 2024/11/25
- [RFC PATCH v3 21/26] hw/arm/boot: Load DTB as is for confidential VMs, Jean-Philippe Brucker, 2024/11/25
- [RFC PATCH v3 22/26] hw/arm/boot: Skip bootloader for confidential guests,
Jean-Philippe Brucker <=
- [RFC PATCH v3 24/26] hw/core/loader: Add fields to RomLoaderNotify, Jean-Philippe Brucker, 2024/11/25
- [RFC PATCH v3 26/26] hw/arm/virt: Add measurement log for confidential boot, Jean-Philippe Brucker, 2024/11/25
- [RFC PATCH v3 23/26] hw/tpm: Add TPM event log, Jean-Philippe Brucker, 2024/11/25
- [PATCH v3 20/26] hw/arm/virt: Use RAM instead of flash for confidential guest firmware, Jean-Philippe Brucker, 2024/11/25
- [RFC PATCH v3 25/26] target/arm/kvm-rme: Add measurement log, Jean-Philippe Brucker, 2024/11/25