qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[RFC PATCH] i386/sev: Support measured direct -kernel boot on SNP


From: Dov Murik
Subject: [RFC PATCH] i386/sev: Support measured direct -kernel boot on SNP
Date: Tue, 29 Mar 2022 06:40:38 +0000

This is an RFC patch based on AMD's RFC snp-v3 tree [1].

In SNP, the hashes page is not included in the ranges to pre-validate
that appear in the SNP metadata published by OVMF (See [2] for proposed
OVMF patches).

Therefore, if the user enabled kernel hashes (for measured direct boot),
we should fill hashes table and encrypt the page.  Note that in SNP
(unlike SEV and SEV-ES) the measurements is done in whole 4KB pages.
Therefore we zero the whole page that includes the hashes table, and
fill in the kernel hashes area in that page, and then encrypt the whole
page.  The rest of the page is reserved for SEV launch secrets which are
not usable anyway on SNP.

If the user disabled kernel hashes, QEMU pre-validates the page as a
zero page.

Note that the base branch [1] doesn't yet include the kernel-hashes
flag.

[1] https://github.com/AMDESE/qemu/tree/snp-v3
[2] https://edk2.groups.io/g/devel/message/88137

Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
---
 target/i386/sev.c | 40 ++++++++++++++++++++++++++++++++--------
 1 file changed, 32 insertions(+), 8 deletions(-)

diff --git a/target/i386/sev.c b/target/i386/sev.c
index 3c296a59ae..dbc9d570a9 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -1818,6 +1818,8 @@ bool sev_add_kernel_loader_hashes(SevKernelLoaderContext 
*ctx, Error **errp)
     uint8_t initrd_hash[HASH_SIZE];
     uint8_t kernel_hash[HASH_SIZE];
     uint8_t *hashp;
+    uint8_t *full_page = NULL;
+    int ret;
     size_t hash_len = HASH_SIZE;
     int aligned_len;
 
@@ -1826,12 +1828,25 @@ bool 
sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp)
         return false;
     }
 
-    if (sev_snp_enabled()) {
-        return false;
-    }
-
     area = (SevHashTableDescriptor *)data;
 
+    /*
+     * TODO: this is an RFC patch on top of an old tree that doesn't support
+     * the kernel-hashes=on flag.
+     *
+     * But, when kernel-hashes=off and SNP is active, we need to mark the
+     * pre-validate the hashes page as a zero page:
+     *
+     * if (kernel_hashes flag is off) {
+     *     uint32_t gpa = area->base & TARGET_PAGE_MASK
+     *     void *hva = gpa2hva(&mr, gpa, TARGET_PAGE_SIZE, NULL);
+     *     if (!hva) { ... }
+     *     ret = sev_snp_launch_update(sev_snp, gpa, hva, TARGET_PAGE_SIZE,
+     *                                 KVM_SEV_SNP_PAGE_TYPE_ZERO);
+     *     return ret == 0;
+     * }
+     */
+
     /*
      * Calculate hash of kernel command-line with the terminating null byte. If
      * the user doesn't supply a command-line via -append, the 1-byte "\0" will
@@ -1871,7 +1886,13 @@ bool sev_add_kernel_loader_hashes(SevKernelLoaderContext 
*ctx, Error **errp)
      * Populate the hashes table in the guest's memory at the OVMF-designated
      * area for the SEV hashes table
      */
-    ht = qemu_map_ram_ptr(NULL, area->base);
+    if (sev_snp_enabled()) {
+        full_page = qemu_map_ram_ptr(NULL, area->base & TARGET_PAGE_MASK);
+        memset(full_page, 0, TARGET_PAGE_SIZE);
+        ht = (SevHashTable *)(full_page + (area->base & ~TARGET_PAGE_MASK));
+    } else {
+        ht = (SevHashTable *)qemu_map_ram_ptr(NULL, area->base);
+    }
 
     ht->guid = sev_hash_table_header_guid;
     ht->len = sizeof(*ht);
@@ -1895,11 +1916,14 @@ bool 
sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp)
         memset(ht->padding, 0, aligned_len - ht->len);
     }
 
-    if (sev_encrypt_flash(area->base, (uint8_t *)ht, aligned_len, errp) < 0) {
-        return false;
+    if (sev_snp_enabled()) {
+        ret = sev_encrypt_flash(area->base & TARGET_PAGE_MASK, full_page,
+                                TARGET_PAGE_SIZE, errp);
+    } else {
+        ret = sev_encrypt_flash(area->base, (uint8_t *)ht, aligned_len, errp);
     }
 
-    return true;
+    return ret >= 0;
 }
 
 static void
-- 
2.20.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]