You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
124 lines
5.0 KiB
124 lines
5.0 KiB
2 months ago
|
From a20b2e3e52b9589ac1abc8b9b818d526c86368cf Mon Sep 17 00:00:00 2001
|
||
|
From: Michael Roth <michael.roth@amd.com>
|
||
|
Date: Thu, 30 May 2024 06:16:39 -0500
|
||
|
Subject: [PATCH 082/100] hw/i386/sev: Use guest_memfd for legacy ROMs
|
||
|
|
||
|
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
|
||
|
RH-MergeRequest: 245: SEV-SNP support
|
||
|
RH-Jira: RHEL-39544
|
||
|
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
||
|
RH-Acked-by: Bandan Das <bdas@redhat.com>
|
||
|
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||
|
RH-Commit: [82/91] a591e85e00c353009803b143c80852b8c9b1f15e (bonzini/rhel-qemu-kvm)
|
||
|
|
||
|
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>
|
||
|
(cherry picked from commit 413a67450750e0459efeffc3db3ba9759c3e381c)
|
||
|
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||
|
---
|
||
|
hw/i386/pc.c | 14 ++++++++++----
|
||
|
hw/i386/pc_sysfw.c | 19 +++++++++++++------
|
||
|
2 files changed, 23 insertions(+), 10 deletions(-)
|
||
|
|
||
|
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
|
||
|
index 0aca0cc79e..b25d075b59 100644
|
||
|
--- a/hw/i386/pc.c
|
||
|
+++ b/hw/i386/pc.c
|
||
|
@@ -62,6 +62,7 @@
|
||
|
#include "hw/mem/memory-device.h"
|
||
|
#include "e820_memory_layout.h"
|
||
|
#include "trace.h"
|
||
|
+#include "sev.h"
|
||
|
#include CONFIG_DEVICES
|
||
|
|
||
|
#ifdef CONFIG_XEN_EMU
|
||
|
@@ -1173,10 +1174,15 @@ void pc_memory_init(PCMachineState *pcms,
|
||
|
pc_system_firmware_init(pcms, rom_memory);
|
||
|
|
||
|
option_rom_mr = g_malloc(sizeof(*option_rom_mr));
|
||
|
- 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);
|
||
|
+ if (machine_require_guest_memfd(machine)) {
|
||
|
+ memory_region_init_ram_guest_memfd(option_rom_mr, NULL, "pc.rom",
|
||
|
+ PC_ROM_SIZE, &error_fatal);
|
||
|
+ } 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,
|
||
|
PC_ROM_MIN_VGA,
|
||
|
diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c
|
||
|
index 7cdbafc8d2..ef80281d28 100644
|
||
|
--- a/hw/i386/pc_sysfw.c
|
||
|
+++ b/hw/i386/pc_sysfw.c
|
||
|
@@ -40,8 +40,8 @@
|
||
|
|
||
|
#define FLASH_SECTOR_SIZE 4096
|
||
|
|
||
|
-static void pc_isa_bios_init(MemoryRegion *isa_bios, MemoryRegion *rom_memory,
|
||
|
- MemoryRegion *flash_mem)
|
||
|
+static void pc_isa_bios_init(PCMachineState *pcms, MemoryRegion *isa_bios,
|
||
|
+ MemoryRegion *rom_memory, MemoryRegion *flash_mem)
|
||
|
{
|
||
|
int isa_bios_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 */
|
||
|
isa_bios_size = MIN(flash_size, 128 * KiB);
|
||
|
- memory_region_init_ram(isa_bios, NULL, "isa-bios", isa_bios_size,
|
||
|
- &error_fatal);
|
||
|
+ if (machine_require_guest_memfd(MACHINE(pcms))) {
|
||
|
+ 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,
|
||
|
0x100000 - isa_bios_size,
|
||
|
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),
|
||
|
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,
|
||
|
@@ -191,7 +198,7 @@ static void pc_system_flash_map(PCMachineState *pcms,
|
||
|
x86_isa_bios_init(&x86ms->isa_bios, rom_memory, flash_mem,
|
||
|
true);
|
||
|
} 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 */
|
||
|
--
|
||
|
2.39.3
|
||
|
|