i386/sev: Extract build_kernel_loader_hashes

Extract the building of the kernel hashes table out from
sev_add_kernel_loader_hashes() to allow building it in
other memory areas (for SNP support).

No functional change intended.

Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Michael Roth <michael.roth@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-22-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Dov Murik 2024-05-30 06:16:33 -05:00 committed by Paolo Bonzini
parent e3cddff93c
commit 06cbd66cec
1 changed files with 58 additions and 44 deletions

View File

@ -1754,45 +1754,16 @@ static const QemuUUID sev_cmdline_entry_guid = {
0x4d, 0x36, 0xab, 0x2a)
};
/*
* Add the hashes of the linux kernel/initrd/cmdline to an encrypted guest page
* which is included in SEV's initial memory measurement.
*/
bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp)
static bool build_kernel_loader_hashes(PaddedSevHashTable *padded_ht,
SevKernelLoaderContext *ctx,
Error **errp)
{
uint8_t *data;
SevHashTableDescriptor *area;
SevHashTable *ht;
PaddedSevHashTable *padded_ht;
uint8_t cmdline_hash[HASH_SIZE];
uint8_t initrd_hash[HASH_SIZE];
uint8_t kernel_hash[HASH_SIZE];
uint8_t *hashp;
size_t hash_len = HASH_SIZE;
hwaddr mapped_len = sizeof(*padded_ht);
MemTxAttrs attrs = { 0 };
bool ret = true;
SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs);
/*
* Only add the kernel hashes if the sev-guest configuration explicitly
* stated kernel-hashes=on.
*/
if (!sev_common->kernel_hashes) {
return false;
}
if (!pc_system_ovmf_table_find(SEV_HASH_TABLE_RV_GUID, &data, NULL)) {
error_setg(errp, "SEV: kernel specified but guest firmware "
"has no hashes table GUID");
return false;
}
area = (SevHashTableDescriptor *)data;
if (!area->base || area->size < sizeof(PaddedSevHashTable)) {
error_setg(errp, "SEV: guest firmware hashes table area is invalid "
"(base=0x%x size=0x%x)", area->base, area->size);
return false;
}
/*
* Calculate hash of kernel command-line with the terminating null byte. If
@ -1829,16 +1800,6 @@ bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp)
}
assert(hash_len == HASH_SIZE);
/*
* Populate the hashes table in the guest's memory at the OVMF-designated
* area for the SEV hashes table
*/
padded_ht = address_space_map(&address_space_memory, area->base,
&mapped_len, true, attrs);
if (!padded_ht || mapped_len != sizeof(*padded_ht)) {
error_setg(errp, "SEV: cannot map hashes table guest memory area");
return false;
}
ht = &padded_ht->ht;
ht->guid = sev_hash_table_header_guid;
@ -1859,8 +1820,61 @@ bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp)
/* zero the excess data so the measurement can be reliably calculated */
memset(padded_ht->padding, 0, sizeof(padded_ht->padding));
if (sev_encrypt_flash(area->base, (uint8_t *)padded_ht,
sizeof(*padded_ht), errp) < 0) {
return true;
}
/*
* Add the hashes of the linux kernel/initrd/cmdline to an encrypted guest page
* which is included in SEV's initial memory measurement.
*/
bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp)
{
uint8_t *data;
SevHashTableDescriptor *area;
PaddedSevHashTable *padded_ht;
hwaddr mapped_len = sizeof(*padded_ht);
MemTxAttrs attrs = { 0 };
bool ret = true;
SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs);
/*
* Only add the kernel hashes if the sev-guest configuration explicitly
* stated kernel-hashes=on.
*/
if (!sev_common->kernel_hashes) {
return false;
}
if (!pc_system_ovmf_table_find(SEV_HASH_TABLE_RV_GUID, &data, NULL)) {
error_setg(errp, "SEV: kernel specified but guest firmware "
"has no hashes table GUID");
return false;
}
area = (SevHashTableDescriptor *)data;
if (!area->base || area->size < sizeof(PaddedSevHashTable)) {
error_setg(errp, "SEV: guest firmware hashes table area is invalid "
"(base=0x%x size=0x%x)", area->base, area->size);
return false;
}
/*
* Populate the hashes table in the guest's memory at the OVMF-designated
* area for the SEV hashes table
*/
padded_ht = address_space_map(&address_space_memory, area->base,
&mapped_len, true, attrs);
if (!padded_ht || mapped_len != sizeof(*padded_ht)) {
error_setg(errp, "SEV: cannot map hashes table guest memory area");
return false;
}
if (build_kernel_loader_hashes(padded_ht, ctx, errp)) {
if (sev_encrypt_flash(area->base, (uint8_t *)padded_ht,
sizeof(*padded_ht), errp) < 0) {
ret = false;
}
} else {
ret = false;
}