# HG changeset patch
# User Alex Olson <alex.ol...@starlab.io>
# Date 1634669589 18000
#      Tue Oct 19 13:53:09 2021 -0500
# Node ID f3574795bf2ecbd0e717268f9cb9ccc8982f1861
# Parent  4eda9c0cf72d0fe0c217c251bdef2c5628e0c0a6
Replace EFI memory map in Multiboot2 info

tboot modifies both the e820 and EFI memory maps during its boot process,
but was only updating the Multiboot content's e820 map.  This meant
the unmodified EFI map was being passed even though it should have contained
reserved ranges specific to tboot.

This probably went unnoticied since the Linux kernel is not booted using
Multiboot (thus, was already receiving the updated EFI map on EFI systems).

This revision adds the update of the EFI Multiboot content, but has to make a
slight tradeoff as the combined expansion of the E820 and EFI memory maps
cannot be "paid" for with the memory savings from other Multiboot tag deletions.

Signed-off-by: Alex Olson <alex.ol...@starlab.io>

diff -r 4eda9c0cf72d -r f3574795bf2e tboot/common/efi_memmap.c
--- a/tboot/common/efi_memmap.c Fri Oct 15 13:35:59 2021 -0500
+++ b/tboot/common/efi_memmap.c Tue Oct 19 13:53:09 2021 -0500
@@ -372,4 +372,10 @@
     } else {
         return false;
     }
-}
\ No newline at end of file
+}
+
+
+bool efi_memmap_present(void)
+{
+    return efi_mmap_available;
+}
diff -r 4eda9c0cf72d -r f3574795bf2e tboot/common/loader.c
--- a/tboot/common/loader.c     Fri Oct 15 13:35:59 2021 -0500
+++ b/tboot/common/loader.c     Tue Oct 19 13:53:09 2021 -0500
@@ -331,6 +331,18 @@
     return true;
 }
 
+
+static bool remove_mb2_tag_by_type(loader_ctx *lctx, uint32_t tag_type)
+{
+    struct mb2_tag *start = next_mb2_tag(NULL);
+    struct mb2_tag *victim = find_mb2_tag_type(start, tag_type);
+
+    if (victim != NULL) {
+        return remove_mb2_tag(lctx,victim);
+    }
+    return false;
+}
+
 static bool
 grow_mb2_tag(loader_ctx *lctx, struct mb2_tag *which, uint32_t how_much)
 {
@@ -1401,11 +1413,22 @@
     }
 
     /* replace map in loader context with copy */
-    replace_e820_map(g_ldr_ctx);
+    if ( is_loader_launch_efi(g_ldr_ctx) && efi_memmap_present() ) {
+        /* for EFI, reclaim MB2 space by deleting the E820 map,
+           this ensures grow_mb2_tag() has enough slack available.
+           Due to the growth of each, there can only be one...
+         */
+        remove_mb2_tag_by_type(g_ldr_ctx, MB2_TAG_TYPE_MMAP);
+        replace_efi_map(g_ldr_ctx);
+    } else {
+        remove_mb2_tag_by_type(g_ldr_ctx, MB2_TAG_TYPE_EFI_MMAP);
+        replace_e820_map(g_ldr_ctx);
+    }
 
     if (get_tboot_dump_memmap()) {
         printk(TBOOT_DETA"adjusted e820 map:\n");
         print_e820_map();
+        efi_memmap_dump();
     }
 
     if ( !verify_loader_context(g_ldr_ctx) )
@@ -1907,6 +1930,47 @@
     return;
 }
 
+void
+replace_efi_map(loader_ctx *lctx)
+{
+    /* currently must be MBI type 2 */
+    if ( LOADER_CTX_BAD(lctx) || lctx->type == MB1_ONLY ){
+        return;
+    }
+
+    struct mb2_tag *start = (struct mb2_tag *)(lctx->addr + 8);
+    struct mb2_tag_efi_mmap *tag;
+    tag = (struct mb2_tag_efi_mmap *)find_mb2_tag_type(start, 
MB2_TAG_TYPE_EFI_MMAP);
+
+    if ( !tag ) {
+        printk(TBOOT_INFO"MB2 EFI map not found\n");
+        return;
+    }
+
+    const uint32_t old_mmap_size = tag->size - sizeof(struct mb2_tag_efi_mmap);
+    uint32_t new_descr_size=0;
+    uint32_t new_descr_vers=0;
+    uint32_t new_mmap_size=0;
+    void    *new_mmap;
+
+    new_mmap = (void *)efi_memmap_get_addr(&new_descr_size, &new_descr_vers, 
&new_mmap_size);
+
+    if ( old_mmap_size < new_mmap_size ) {
+        /* we have to grow */
+        if (false ==
+            grow_mb2_tag(lctx, (struct mb2_tag *)tag, 
(new_mmap_size-old_mmap_size))) {
+            printk(TBOOT_ERR"MB2 failed to grow EFI map tag\n");
+            return;
+        }
+    } else {
+        tag->size = sizeof(struct mb2_tag_efi_mmap) + new_mmap_size;
+    }
+    /* copy in new data */
+    tag->descr_size = new_descr_size;
+    tag->descr_vers = new_descr_vers;
+    tb_memcpy(tag->efi_mmap, new_mmap, new_mmap_size);
+}
+
 void print_loader_ctx(loader_ctx *lctx)
 {
     if (lctx->type != MB2_ONLY){
diff -r 4eda9c0cf72d -r f3574795bf2e tboot/include/efi_memmap.h
--- a/tboot/include/efi_memmap.h        Fri Oct 15 13:35:59 2021 -0500
+++ b/tboot/include/efi_memmap.h        Tue Oct 19 13:53:09 2021 -0500
@@ -98,4 +98,5 @@
                                       uint64_t *ram_base, uint64_t *ram_size);
 void efi_memmap_dump(void);
 
-#endif
\ No newline at end of file
+bool efi_memmap_present(void);
+#endif
diff -r 4eda9c0cf72d -r f3574795bf2e tboot/include/loader.h
--- a/tboot/include/loader.h    Fri Oct 15 13:35:59 2021 -0500
+++ b/tboot/include/loader.h    Tue Oct 19 13:53:09 2021 -0500
@@ -97,6 +97,7 @@
 extern void determine_loader_type(void *addr, uint32_t magic);
 extern unsigned long get_loader_ctx_end(loader_ctx *lctx);
 extern void replace_e820_map(loader_ctx *lctx);
+extern void replace_efi_map(loader_ctx *lctx);
 extern uint8_t *get_loader_rsdp(loader_ctx *lctx, uint32_t *length);
 extern bool is_loader_launch_efi(loader_ctx *lctx);
 extern bool get_loader_efi_ptr(loader_ctx *lctx, uint32_t *address, 


_______________________________________________
tboot-devel mailing list
tboot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tboot-devel

Reply via email to