hw/i386/sev: Add function to get SEV metadata from OVMF header

A recent version of OVMF expanded the reset vector GUID list to add
SEV-specific metadata GUID. The SEV metadata describes the reserved
memory regions such as the secrets and CPUID page used during the SEV-SNP
guest launch.

The pc_system_get_ovmf_sev_metadata_ptr() is used to retieve the SEV
metadata pointer from the OVMF GUID list.

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Signed-off-by: Michael Roth <michael.roth@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-19-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Brijesh Singh 2024-05-30 06:16:30 -05:00 committed by Paolo Bonzini
parent 3d44fdff60
commit f3c30c575d
5 changed files with 68 additions and 0 deletions

View File

@ -260,6 +260,10 @@ void x86_firmware_configure(void *ptr, int size)
pc_system_parse_ovmf_flash(ptr, size);
if (sev_enabled()) {
/* Copy the SEV metadata table (if it exists) */
pc_system_parse_sev_metadata(ptr, size);
ret = sev_es_save_reset_vector(ptr, size);
if (ret) {
error_report("failed to locate and/or save reset vector");

View File

@ -164,6 +164,32 @@ void pc_acpi_smi_interrupt(void *opaque, int irq, int level);
#define PCI_HOST_ABOVE_4G_MEM_SIZE "above-4g-mem-size"
#define PCI_HOST_PROP_SMM_RANGES "smm-ranges"
typedef enum {
SEV_DESC_TYPE_UNDEF,
/* The section contains the region that must be validated by the VMM. */
SEV_DESC_TYPE_SNP_SEC_MEM,
/* The section contains the SNP secrets page */
SEV_DESC_TYPE_SNP_SECRETS,
/* The section contains address that can be used as a CPUID page */
SEV_DESC_TYPE_CPUID,
} ovmf_sev_metadata_desc_type;
typedef struct __attribute__((__packed__)) OvmfSevMetadataDesc {
uint32_t base;
uint32_t len;
ovmf_sev_metadata_desc_type type;
} OvmfSevMetadataDesc;
typedef struct __attribute__((__packed__)) OvmfSevMetadata {
uint8_t signature[4];
uint32_t len;
uint32_t version;
uint32_t num_desc;
OvmfSevMetadataDesc descs[];
} OvmfSevMetadata;
OvmfSevMetadata *pc_system_get_ovmf_sev_metadata_ptr(void);
void pc_pci_as_mapping_init(MemoryRegion *system_memory,
MemoryRegion *pci_address_space);

View File

@ -67,3 +67,7 @@ void hmp_info_sev(Monitor *mon, const QDict *qdict)
{
monitor_printf(mon, "SEV is not available in this QEMU\n");
}
void pc_system_parse_sev_metadata(uint8_t *flash_ptr, size_t flash_size)
{
}

View File

@ -597,6 +597,38 @@ SevCapability *qmp_query_sev_capabilities(Error **errp)
return sev_get_capabilities(errp);
}
static OvmfSevMetadata *ovmf_sev_metadata_table;
#define OVMF_SEV_META_DATA_GUID "dc886566-984a-4798-A75e-5585a7bf67cc"
typedef struct __attribute__((__packed__)) OvmfSevMetadataOffset {
uint32_t offset;
} OvmfSevMetadataOffset;
OvmfSevMetadata *pc_system_get_ovmf_sev_metadata_ptr(void)
{
return ovmf_sev_metadata_table;
}
void pc_system_parse_sev_metadata(uint8_t *flash_ptr, size_t flash_size)
{
OvmfSevMetadata *metadata;
OvmfSevMetadataOffset *data;
if (!pc_system_ovmf_table_find(OVMF_SEV_META_DATA_GUID, (uint8_t **)&data,
NULL)) {
return;
}
metadata = (OvmfSevMetadata *)(flash_ptr + flash_size - data->offset);
if (memcmp(metadata->signature, "ASEV", 4) != 0 ||
metadata->len < sizeof(OvmfSevMetadata) ||
metadata->len > flash_size - data->offset) {
return;
}
ovmf_sev_metadata_table = g_memdup2(metadata, metadata->len);
}
static SevAttestationReport *sev_get_attestation_report(const char *mnonce,
Error **errp)
{

View File

@ -66,4 +66,6 @@ int sev_inject_launch_secret(const char *hdr, const char *secret,
int sev_es_save_reset_vector(void *flash_ptr, uint64_t flash_size);
void sev_es_set_reset_vector(CPUState *cpu);
void pc_system_parse_sev_metadata(uint8_t *flash_ptr, size_t flash_size);
#endif