Skip to content

Commit

Permalink
hw/i386/sev: Add support to encrypt BIOS when SEV-SNP is enabled
Browse files Browse the repository at this point in the history
TODO: - As with other instances noted by Paolo, move
        sev/snp_launch_update_data() into an sev_common class method
        that gets overloaded based on guest type rather than checking
        for sev_snp_enabled().

As with SEV, an SNP guest requires that the BIOS be part of the initial
encrypted/measured guest payload. Extend sev_encrypt_flash() to handle
the SNP case and plumb through the GPA of the BIOS location since this
is needed for SNP.

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Signed-off-by: Michael Roth <michael.roth@amd.com>
  • Loading branch information
codomania authored and mdroth committed Mar 21, 2024
1 parent ae177e6 commit c54618a
Show file tree
Hide file tree
Showing 6 changed files with 22 additions and 13 deletions.
12 changes: 7 additions & 5 deletions hw/i386/pc_sysfw.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@ static void pc_system_flash_map(PCMachineState *pcms,
assert(PC_MACHINE_GET_CLASS(pcms)->pci_enabled);

for (i = 0; i < ARRAY_SIZE(pcms->flash); i++) {
hwaddr gpa;

system_flash = pcms->flash[i];
blk = pflash_cfi01_get_blk(system_flash);
if (!blk) {
Expand Down Expand Up @@ -178,11 +180,11 @@ static void pc_system_flash_map(PCMachineState *pcms,
}

total_size += size;
gpa = 0x100000000ULL - total_size; /* where the flash is mapped */
qdev_prop_set_uint32(DEVICE(system_flash), "num-blocks",
size / FLASH_SECTOR_SIZE);
sysbus_realize_and_unref(SYS_BUS_DEVICE(system_flash), &error_fatal);
sysbus_mmio_map(SYS_BUS_DEVICE(system_flash), 0,
0x100000000ULL - total_size);
sysbus_mmio_map(SYS_BUS_DEVICE(system_flash), 0, gpa);

if (i == 0) {
flash_mem = pflash_cfi01_get_memory(system_flash);
Expand All @@ -192,7 +194,7 @@ static void pc_system_flash_map(PCMachineState *pcms,
if (sev_enabled()) {
flash_ptr = memory_region_get_ram_ptr(flash_mem);
flash_size = memory_region_size(flash_mem);
x86_firmware_configure(flash_ptr, flash_size);
x86_firmware_configure(gpa, flash_ptr, flash_size);
}
}
}
Expand Down Expand Up @@ -245,7 +247,7 @@ void pc_system_firmware_init(PCMachineState *pcms,
pc_system_flash_cleanup_unused(pcms);
}

void x86_firmware_configure(void *ptr, int size)
void x86_firmware_configure(hwaddr gpa, void *ptr, int size)
{
int ret;

Expand All @@ -262,6 +264,6 @@ void x86_firmware_configure(void *ptr, int size)
exit(1);
}

sev_encrypt_flash(ptr, size, &error_fatal);
sev_encrypt_flash(gpa, ptr, size, &error_fatal);
}
}
2 changes: 1 addition & 1 deletion hw/i386/x86.c
Original file line number Diff line number Diff line change
Expand Up @@ -1161,7 +1161,7 @@ void x86_bios_rom_init(MachineState *ms, const char *default_firmware,
*/
void *ptr = memory_region_get_ram_ptr(bios);
load_image_size(filename, ptr, bios_size);
x86_firmware_configure(ptr, bios_size);
x86_firmware_configure(0x100000000ULL - bios_size, ptr, bios_size);
} else {
if (!isapc_ram_fw) {
memory_region_set_readonly(bios, true);
Expand Down
2 changes: 1 addition & 1 deletion include/hw/i386/x86.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,6 @@ void ioapic_init_gsi(GSIState *gsi_state, Object *parent);
DeviceState *ioapic_init_secondary(GSIState *gsi_state);

/* pc_sysfw.c */
void x86_firmware_configure(void *ptr, int size);
void x86_firmware_configure(hwaddr gpa, void *ptr, int size);

#endif
2 changes: 1 addition & 1 deletion target/i386/sev-sysemu-stub.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ void qmp_sev_inject_launch_secret(const char *packet_header, const char *secret,
error_setg(errp, "SEV is not available in this QEMU");
}

int sev_encrypt_flash(uint8_t *ptr, uint64_t len, Error **errp)
int sev_encrypt_flash(hwaddr gpa, uint8_t *ptr, uint64_t len, Error **errp)
{
g_assert_not_reached();
}
Expand Down
15 changes: 11 additions & 4 deletions target/i386/sev.c
Original file line number Diff line number Diff line change
Expand Up @@ -1449,7 +1449,7 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
}

int
sev_encrypt_flash(uint8_t *ptr, uint64_t len, Error **errp)
sev_encrypt_flash(hwaddr gpa, uint8_t *ptr, uint64_t len, Error **errp)
{
SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs);

Expand All @@ -1459,7 +1459,14 @@ sev_encrypt_flash(uint8_t *ptr, uint64_t len, Error **errp)

/* if SEV is in update state then encrypt the data else do nothing */
if (sev_check_state(sev_common, SEV_STATE_LAUNCH_UPDATE)) {
int ret = sev_launch_update_data(SEV_GUEST(sev_common), ptr, len);
int ret;

if (sev_snp_enabled()) {
ret = snp_launch_update_data(gpa, ptr, len,
KVM_SEV_SNP_PAGE_TYPE_NORMAL);
} else {
ret = sev_launch_update_data(SEV_GUEST(sev_common), ptr, len);
}
if (ret < 0) {
error_setg(errp, "SEV: Failed to encrypt pflash rom");
return ret;
Expand Down Expand Up @@ -1829,8 +1836,8 @@ bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp)
}

if (build_kernel_loader_hashes(padded_ht, ctx, errp)) {
if (sev_encrypt_flash((uint8_t *)padded_ht, sizeof(*padded_ht),
errp) < 0) {
if (sev_encrypt_flash(area->base, (uint8_t *)padded_ht,
sizeof(*padded_ht), errp) < 0) {
ret = false;
}
} else {
Expand Down
2 changes: 1 addition & 1 deletion target/i386/sev.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ uint32_t sev_get_cbit_position(void);
uint32_t sev_get_reduced_phys_bits(void);
bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp);

int sev_encrypt_flash(uint8_t *ptr, uint64_t len, Error **errp);
int sev_encrypt_flash(hwaddr gpa, uint8_t *ptr, uint64_t len, Error **errp);
int sev_inject_launch_secret(const char *hdr, const char *secret,
uint64_t gpa, Error **errp);

Expand Down

0 comments on commit c54618a

Please sign in to comment.