]> www.infradead.org Git - users/willy/pagecache.git/commitdiff
efi/mokvar-table: Avoid repeated map/unmap of the same page
authorArd Biesheuvel <ardb@kernel.org>
Thu, 27 Feb 2025 13:30:22 +0000 (14:30 +0100)
committerArd Biesheuvel <ardb@kernel.org>
Thu, 27 Feb 2025 17:25:44 +0000 (18:25 +0100)
Tweak the logic that traverses the MOKVAR UEFI configuration table to
only unmap the entry header and map the next one if they don't live in
the same physical page.

Link: https://lore.kernel.org/all/8f085931-3e9d-4386-9209-1d6c95616327@uncooperative.org/
Tested-By: Peter Jones <pjones@redhat.com>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
drivers/firmware/efi/mokvar-table.c

index d865cb1dbaad10f7cd45b853e44a691b2a5f4204..208db29613c63106c7df3d3ea36e89e17f8b000d 100644 (file)
@@ -99,13 +99,13 @@ static struct kobject *mokvar_kobj;
  */
 void __init efi_mokvar_table_init(void)
 {
+       struct efi_mokvar_table_entry __aligned(1) *mokvar_entry, *next_entry;
        efi_memory_desc_t md;
        void *va = NULL;
        unsigned long cur_offset = 0;
        unsigned long offset_limit;
        unsigned long map_size_needed = 0;
        unsigned long size;
-       struct efi_mokvar_table_entry *mokvar_entry;
        int err;
 
        if (!efi_enabled(EFI_MEMMAP))
@@ -142,7 +142,7 @@ void __init efi_mokvar_table_init(void)
                        return;
                }
                mokvar_entry = va;
-
+next:
                /* Check for last sentinel entry */
                if (mokvar_entry->name[0] == '\0') {
                        if (mokvar_entry->data_size != 0)
@@ -156,7 +156,19 @@ void __init efi_mokvar_table_init(void)
                mokvar_entry->name[sizeof(mokvar_entry->name) - 1] = '\0';
 
                /* Advance to the next entry */
-               cur_offset += sizeof(*mokvar_entry) + mokvar_entry->data_size;
+               size = sizeof(*mokvar_entry) + mokvar_entry->data_size;
+               cur_offset += size;
+
+               /*
+                * Don't bother remapping if the current entry header and the
+                * next one end on the same page.
+                */
+               next_entry = (void *)((unsigned long)mokvar_entry + size);
+               if (((((unsigned long)(mokvar_entry + 1) - 1) ^
+                     ((unsigned long)(next_entry + 1) - 1)) & PAGE_MASK) == 0) {
+                       mokvar_entry = next_entry;
+                       goto next;
+               }
        }
 
        if (va)