hw/i386/sev: Use guest_memfd for legacy ROMs
Current SNP guest kernels will attempt to access these regions with with C-bit set, so guest_memfd is needed to handle that. Otherwise, kvm_convert_memory() will fail when the guest kernel tries to access it and QEMU attempts to call KVM_SET_MEMORY_ATTRIBUTES to set these ranges to private. Whether guests should actually try to access ROM regions in this way (or need to deal with legacy ROM regions at all), is a separate issue to be addressed on kernel side, but current SNP guest kernels will exhibit this behavior and so this handling is needed to allow QEMU to continue running existing SNP guest kernels. Signed-off-by: Michael Roth <michael.roth@amd.com> [pankaj: Added sev_snp_enabled() check] Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com> Message-ID: <20240530111643.1091816-28-pankaj.gupta@amd.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
a0aa6db7ce
commit
413a674507
14
hw/i386/pc.c
14
hw/i386/pc.c
@ -62,6 +62,7 @@
|
|||||||
#include "hw/mem/memory-device.h"
|
#include "hw/mem/memory-device.h"
|
||||||
#include "e820_memory_layout.h"
|
#include "e820_memory_layout.h"
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
|
#include "sev.h"
|
||||||
#include CONFIG_DEVICES
|
#include CONFIG_DEVICES
|
||||||
|
|
||||||
#ifdef CONFIG_XEN_EMU
|
#ifdef CONFIG_XEN_EMU
|
||||||
@ -1022,10 +1023,15 @@ void pc_memory_init(PCMachineState *pcms,
|
|||||||
pc_system_firmware_init(pcms, rom_memory);
|
pc_system_firmware_init(pcms, rom_memory);
|
||||||
|
|
||||||
option_rom_mr = g_malloc(sizeof(*option_rom_mr));
|
option_rom_mr = g_malloc(sizeof(*option_rom_mr));
|
||||||
memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE,
|
if (machine_require_guest_memfd(machine)) {
|
||||||
&error_fatal);
|
memory_region_init_ram_guest_memfd(option_rom_mr, NULL, "pc.rom",
|
||||||
if (pcmc->pci_enabled) {
|
PC_ROM_SIZE, &error_fatal);
|
||||||
memory_region_set_readonly(option_rom_mr, true);
|
} else {
|
||||||
|
memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE,
|
||||||
|
&error_fatal);
|
||||||
|
if (pcmc->pci_enabled) {
|
||||||
|
memory_region_set_readonly(option_rom_mr, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
memory_region_add_subregion_overlap(rom_memory,
|
memory_region_add_subregion_overlap(rom_memory,
|
||||||
PC_ROM_MIN_VGA,
|
PC_ROM_MIN_VGA,
|
||||||
|
@ -40,8 +40,8 @@
|
|||||||
|
|
||||||
#define FLASH_SECTOR_SIZE 4096
|
#define FLASH_SECTOR_SIZE 4096
|
||||||
|
|
||||||
static void pc_isa_bios_init(MemoryRegion *isa_bios, MemoryRegion *rom_memory,
|
static void pc_isa_bios_init(PCMachineState *pcms, MemoryRegion *isa_bios,
|
||||||
MemoryRegion *flash_mem)
|
MemoryRegion *rom_memory, MemoryRegion *flash_mem)
|
||||||
{
|
{
|
||||||
int isa_bios_size;
|
int isa_bios_size;
|
||||||
uint64_t flash_size;
|
uint64_t flash_size;
|
||||||
@ -51,8 +51,13 @@ static void pc_isa_bios_init(MemoryRegion *isa_bios, MemoryRegion *rom_memory,
|
|||||||
|
|
||||||
/* map the last 128KB of the BIOS in ISA space */
|
/* map the last 128KB of the BIOS in ISA space */
|
||||||
isa_bios_size = MIN(flash_size, 128 * KiB);
|
isa_bios_size = MIN(flash_size, 128 * KiB);
|
||||||
memory_region_init_ram(isa_bios, NULL, "isa-bios", isa_bios_size,
|
if (machine_require_guest_memfd(MACHINE(pcms))) {
|
||||||
&error_fatal);
|
memory_region_init_ram_guest_memfd(isa_bios, NULL, "isa-bios",
|
||||||
|
isa_bios_size, &error_fatal);
|
||||||
|
} else {
|
||||||
|
memory_region_init_ram(isa_bios, NULL, "isa-bios", isa_bios_size,
|
||||||
|
&error_fatal);
|
||||||
|
}
|
||||||
memory_region_add_subregion_overlap(rom_memory,
|
memory_region_add_subregion_overlap(rom_memory,
|
||||||
0x100000 - isa_bios_size,
|
0x100000 - isa_bios_size,
|
||||||
isa_bios,
|
isa_bios,
|
||||||
@ -65,7 +70,9 @@ static void pc_isa_bios_init(MemoryRegion *isa_bios, MemoryRegion *rom_memory,
|
|||||||
((uint8_t*)flash_ptr) + (flash_size - isa_bios_size),
|
((uint8_t*)flash_ptr) + (flash_size - isa_bios_size),
|
||||||
isa_bios_size);
|
isa_bios_size);
|
||||||
|
|
||||||
memory_region_set_readonly(isa_bios, true);
|
if (!machine_require_guest_memfd(current_machine)) {
|
||||||
|
memory_region_set_readonly(isa_bios, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static PFlashCFI01 *pc_pflash_create(PCMachineState *pcms,
|
static PFlashCFI01 *pc_pflash_create(PCMachineState *pcms,
|
||||||
@ -191,7 +198,7 @@ static void pc_system_flash_map(PCMachineState *pcms,
|
|||||||
x86_isa_bios_init(&x86ms->isa_bios, rom_memory, flash_mem,
|
x86_isa_bios_init(&x86ms->isa_bios, rom_memory, flash_mem,
|
||||||
true);
|
true);
|
||||||
} else {
|
} else {
|
||||||
pc_isa_bios_init(&x86ms->isa_bios, rom_memory, flash_mem);
|
pc_isa_bios_init(pcms, &x86ms->isa_bios, rom_memory, flash_mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Encrypt the pflash boot ROM */
|
/* Encrypt the pflash boot ROM */
|
||||||
|
Loading…
Reference in New Issue
Block a user