i386/tdx: register TDVF as private memory
Allocate the dedicated memory to hold bios image instead of re-using mmapped guest memory because the initial memory conversion to private memory wipes out the bios image by madvise(REMOVE). Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com> Co-developed-by: Xiaoyao Li <xiaoyao.li@intel.com> Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
This commit is contained in:
committed by
Nikolay Borisov
parent
2d3cb9cbe5
commit
b9ec2099cb
@@ -2841,7 +2841,7 @@ static void kvm_eat_signals(CPUState *cpu)
|
|||||||
} while (sigismember(&chkset, SIG_IPI));
|
} while (sigismember(&chkset, SIG_IPI));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int kvm_encrypt_reg_region(hwaddr start, hwaddr size, bool reg_region)
|
int kvm_encrypt_reg_region(hwaddr start, hwaddr size, bool reg_region)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
struct kvm_memory_attributes attr;
|
struct kvm_memory_attributes attr;
|
||||||
|
@@ -27,6 +27,7 @@
|
|||||||
#include "qemu/units.h"
|
#include "qemu/units.h"
|
||||||
#include "qemu/datadir.h"
|
#include "qemu/datadir.h"
|
||||||
#include "qemu/guest-random.h"
|
#include "qemu/guest-random.h"
|
||||||
|
#include "qom/object_interfaces.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qapi/qmp/qerror.h"
|
#include "qapi/qmp/qerror.h"
|
||||||
#include "qapi/qapi-visit-common.h"
|
#include "qapi/qapi-visit-common.h"
|
||||||
@@ -1188,8 +1189,15 @@ void x86_bios_rom_init(MachineState *ms, const char *default_firmware,
|
|||||||
(bios_size % 65536) != 0) {
|
(bios_size % 65536) != 0) {
|
||||||
goto bios_error;
|
goto bios_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
bios = g_malloc(sizeof(*bios));
|
bios = g_malloc(sizeof(*bios));
|
||||||
memory_region_init_ram(bios, NULL, "pc.bios", bios_size, &error_fatal);
|
if (is_tdx_vm()) {
|
||||||
|
memory_region_init_ram_restricted(bios, NULL, "pc.bios", bios_size, &error_fatal);
|
||||||
|
tdx_set_tdvf_region(bios);
|
||||||
|
} else {
|
||||||
|
memory_region_init_ram(bios, NULL, "pc.bios", bios_size, &error_fatal);
|
||||||
|
}
|
||||||
|
|
||||||
if (sev_enabled() || is_tdx_vm()) {
|
if (sev_enabled() || is_tdx_vm()) {
|
||||||
/*
|
/*
|
||||||
* The concept of a "reset" simply doesn't exist for
|
* The concept of a "reset" simply doesn't exist for
|
||||||
|
@@ -583,4 +583,6 @@ bool kvm_arch_cpu_check_are_resettable(void);
|
|||||||
bool kvm_dirty_ring_enabled(void);
|
bool kvm_dirty_ring_enabled(void);
|
||||||
|
|
||||||
uint32_t kvm_dirty_ring_size(void);
|
uint32_t kvm_dirty_ring_size(void);
|
||||||
|
|
||||||
|
int kvm_encrypt_reg_region(hwaddr start, hwaddr size, bool reg_region);
|
||||||
#endif
|
#endif
|
||||||
|
@@ -19,6 +19,9 @@
|
|||||||
#include "sysemu/kvm.h"
|
#include "sysemu/kvm.h"
|
||||||
#include "sysemu/sysemu.h"
|
#include "sysemu/sysemu.h"
|
||||||
|
|
||||||
|
#include "exec/address-spaces.h"
|
||||||
|
#include "exec/ramblock.h"
|
||||||
|
#include "hw/i386/apic_internal.h"
|
||||||
#include "hw/i386/e820_memory_layout.h"
|
#include "hw/i386/e820_memory_layout.h"
|
||||||
#include "hw/i386/x86.h"
|
#include "hw/i386/x86.h"
|
||||||
#include "hw/i386/tdvf.h"
|
#include "hw/i386/tdvf.h"
|
||||||
@@ -450,6 +453,12 @@ static void update_tdx_cpuid_lookup_by_tdx_caps(void)
|
|||||||
(tdx_caps->xfam_fixed1 & CPUID_XSTATE_XSS_MASK) >> 32;
|
(tdx_caps->xfam_fixed1 & CPUID_XSTATE_XSS_MASK) >> 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tdx_set_tdvf_region(MemoryRegion *tdvf_region)
|
||||||
|
{
|
||||||
|
assert(!tdx_guest->tdvf_region);
|
||||||
|
tdx_guest->tdvf_region = tdvf_region;
|
||||||
|
}
|
||||||
|
|
||||||
static TdxFirmwareEntry *tdx_get_hob_entry(TdxGuest *tdx)
|
static TdxFirmwareEntry *tdx_get_hob_entry(TdxGuest *tdx)
|
||||||
{
|
{
|
||||||
TdxFirmwareEntry *entry;
|
TdxFirmwareEntry *entry;
|
||||||
@@ -570,6 +579,7 @@ static void tdx_finalize_vm(Notifier *notifier, void *unused)
|
|||||||
{
|
{
|
||||||
TdxFirmware *tdvf = &tdx_guest->tdvf;
|
TdxFirmware *tdvf = &tdx_guest->tdvf;
|
||||||
TdxFirmwareEntry *entry;
|
TdxFirmwareEntry *entry;
|
||||||
|
RAMBlock *ram_block;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
tdx_init_ram_entries();
|
tdx_init_ram_entries();
|
||||||
@@ -604,6 +614,12 @@ static void tdx_finalize_vm(Notifier *notifier, void *unused)
|
|||||||
.nr_pages = entry->size / 4096,
|
.nr_pages = entry->size / 4096,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
r = kvm_encrypt_reg_region(entry->address, entry->size, true);
|
||||||
|
if (r < 0) {
|
||||||
|
error_report("Reserve initial private memory failed %s", strerror(-r));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
__u32 flags = entry->attributes & TDVF_SECTION_ATTRIBUTES_MR_EXTEND ?
|
__u32 flags = entry->attributes & TDVF_SECTION_ATTRIBUTES_MR_EXTEND ?
|
||||||
KVM_TDX_MEASURE_MEMORY_REGION : 0;
|
KVM_TDX_MEASURE_MEMORY_REGION : 0;
|
||||||
|
|
||||||
@@ -619,6 +635,10 @@ static void tdx_finalize_vm(Notifier *notifier, void *unused)
|
|||||||
entry->mem_ptr = NULL;
|
entry->mem_ptr = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Tdvf image was copied into private region above. It becomes unnecessary. */
|
||||||
|
ram_block = tdx_guest->tdvf_region->ram_block;
|
||||||
|
ram_block_discard_range(ram_block, 0, ram_block->max_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Notifier tdx_machine_done_notify = {
|
static Notifier tdx_machine_done_notify = {
|
||||||
|
@@ -35,6 +35,7 @@ typedef struct TdxGuest {
|
|||||||
uint64_t attributes; /* TD attributes */
|
uint64_t attributes; /* TD attributes */
|
||||||
|
|
||||||
TdxFirmware tdvf;
|
TdxFirmware tdvf;
|
||||||
|
MemoryRegion *tdvf_region;
|
||||||
|
|
||||||
uint32_t nr_ram_entries;
|
uint32_t nr_ram_entries;
|
||||||
TdxRamEntry *ram_entries;
|
TdxRamEntry *ram_entries;
|
||||||
@@ -50,6 +51,7 @@ int tdx_kvm_init(MachineState *ms, Error **errp);
|
|||||||
void tdx_get_supported_cpuid(uint32_t function, uint32_t index, int reg,
|
void tdx_get_supported_cpuid(uint32_t function, uint32_t index, int reg,
|
||||||
uint32_t *ret);
|
uint32_t *ret);
|
||||||
int tdx_pre_create_vcpu(CPUState *cpu);
|
int tdx_pre_create_vcpu(CPUState *cpu);
|
||||||
|
void tdx_set_tdvf_region(MemoryRegion *tdvf_region);
|
||||||
int tdx_parse_tdvf(void *flash_ptr, int size);
|
int tdx_parse_tdvf(void *flash_ptr, int size);
|
||||||
|
|
||||||
#endif /* QEMU_I386_TDX_H */
|
#endif /* QEMU_I386_TDX_H */
|
||||||
|
Reference in New Issue
Block a user