From: Michael Roth <michael.roth@xxxxxxx> SEV-ES and SEV-SNP support OVMF images with non-volatile storage in cases where the storage area is generated as a separate image as part of the OVMF build process. Currently these are exposed with unit=0 corresponding to the actual BIOS image, and unit=1 corresponding to the storage image. However, pflash images are mapped guest memory using read-only memslots, which are not allowed in conjunction with guest_memfd-backed ranges. This makes that approach unusable for SEV-SNP, where the BIOS range will be encrypted and mapped as private guest_memfd-backed memory. For this reason, SEV-SNP will instead rely on -bios to handle loading the BIOS image. To allow for pflash to still be used for the storage image, rework the existing logic to remove assumptions that unit=0 contains the BIOS image when SEV-SNP, so that it can instead be used to handle only the storage image. Signed-off-by: Michael Roth <michael.roth@xxxxxxx> Signed-off-by: Pankaj Gupta <pankaj.gupta@xxxxxxx> --- hw/i386/pc_sysfw.c | 47 +++++++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c index def77a442d..7f97e62b16 100644 --- a/hw/i386/pc_sysfw.c +++ b/hw/i386/pc_sysfw.c @@ -125,21 +125,10 @@ void pc_system_flash_cleanup_unused(PCMachineState *pcms) } } -/* - * Map the pcms->flash[] from 4GiB downward, and realize. - * Map them in descending order, i.e. pcms->flash[0] at the top, - * without gaps. - * Stop at the first pcms->flash[0] lacking a block backend. - * Set each flash's size from its block backend. Fatal error if the - * size isn't a non-zero multiple of 4KiB, or the total size exceeds - * pcms->max_fw_size. - * - * If pcms->flash[0] has a block backend, its memory is passed to - * pc_isa_bios_init(). Merging several flash devices for isa-bios is - * not supported. - */ -static void pc_system_flash_map(PCMachineState *pcms, - MemoryRegion *rom_memory) +static void pc_system_flash_map_partial(PCMachineState *pcms, + MemoryRegion *rom_memory, + hwaddr offset, + bool storage_only) { X86MachineState *x86ms = X86_MACHINE(pcms); PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms); @@ -154,6 +143,8 @@ static void pc_system_flash_map(PCMachineState *pcms, assert(PC_MACHINE_GET_CLASS(pcms)->pci_enabled); + total_size = offset; + for (i = 0; i < ARRAY_SIZE(pcms->flash); i++) { hwaddr gpa; @@ -192,7 +183,7 @@ static void pc_system_flash_map(PCMachineState *pcms, sysbus_realize_and_unref(SYS_BUS_DEVICE(system_flash), &error_fatal); sysbus_mmio_map(SYS_BUS_DEVICE(system_flash), 0, gpa); - if (i == 0) { + if (i == 0 && !storage_only) { flash_mem = pflash_cfi01_get_memory(system_flash); if (pcmc->isa_bios_alias) { x86_isa_bios_init(&x86ms->isa_bios, rom_memory, flash_mem, @@ -211,6 +202,25 @@ static void pc_system_flash_map(PCMachineState *pcms, } } +/* + * Map the pcms->flash[] from 4GiB downward, and realize. + * Map them in descending order, i.e. pcms->flash[0] at the top, + * without gaps. + * Stop at the first pcms->flash[0] lacking a block backend. + * Set each flash's size from its block backend. Fatal error if the + * size isn't a non-zero multiple of 4KiB, or the total size exceeds + * pcms->max_fw_size. + * + * If pcms->flash[0] has a block backend, its memory is passed to + * pc_isa_bios_init(). Merging several flash devices for isa-bios is + * not supported. + */ +static void pc_system_flash_map(PCMachineState *pcms, + MemoryRegion *rom_memory) +{ + pc_system_flash_map_partial(pcms, rom_memory, 0, false); +} + void pc_system_firmware_init(PCMachineState *pcms, MemoryRegion *rom_memory) { @@ -238,9 +248,12 @@ void pc_system_firmware_init(PCMachineState *pcms, } } - if (!pflash_blk[0]) { + if (!pflash_blk[0] || sev_snp_enabled()) { /* Machine property pflash0 not set, use ROM mode */ x86_bios_rom_init(X86_MACHINE(pcms), "bios.bin", rom_memory, false); + if (sev_snp_enabled()) { + pc_system_flash_map_partial(pcms, rom_memory, 3653632, true); + } } else { if (kvm_enabled() && !kvm_readonly_mem_enabled()) { /* -- 2.34.1