Linus,

please pull the latest efi-urgent-for-linus git tree from:

   git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git 
efi-urgent-for-linus

This update contains:

 - A fix for a add_efi_memmap parameter regression which ensures that the
   parameter is parsed before it is used.

 - Reinstate the virtual capsule mapping as the cached copy turned out to
   break Quark and other things

 - Remove Matt Fleming as EFI co-maintainer. He stepped back a few days
   ago.  Thanks Matt for all your great work!


Thanks,

        tglx

------------------>
Ard Biesheuvel (1):
      efi/capsule-loader: Reinstate virtual capsule mapping

Dave Young (1):
      x86/efi: Fix kernel param add_efi_memmap regression

Matt Fleming (1):
      MAINTAINERS: Remove Matt Fleming as EFI co-maintainer


 MAINTAINERS                           |  7 +++---
 arch/x86/kernel/setup.c               |  5 ++--
 arch/x86/platform/efi/quirks.c        | 13 +++++++++-
 drivers/firmware/efi/capsule-loader.c | 45 ++++++++++++++++++++++++++++-------
 include/linux/efi.h                   |  4 +++-
 5 files changed, 57 insertions(+), 17 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index b46c9cea5ae5..95c3fa1f520f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5149,15 +5149,15 @@ F:      sound/usb/misc/ua101.c
 EFI TEST DRIVER
 L:     [email protected]
 M:     Ivan Hu <[email protected]>
-M:     Matt Fleming <[email protected]>
+M:     Ard Biesheuvel <[email protected]>
 S:     Maintained
 F:     drivers/firmware/efi/test/
 
 EFI VARIABLE FILESYSTEM
 M:     Matthew Garrett <[email protected]>
 M:     Jeremy Kerr <[email protected]>
-M:     Matt Fleming <[email protected]>
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mfleming/efi.git
+M:     Ard Biesheuvel <[email protected]>
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi.git
 L:     [email protected]
 S:     Maintained
 F:     fs/efivarfs/
@@ -5318,7 +5318,6 @@ S:        Supported
 F:     security/integrity/evm/
 
 EXTENSIBLE FIRMWARE INTERFACE (EFI)
-M:     Matt Fleming <[email protected]>
 M:     Ard Biesheuvel <[email protected]>
 L:     [email protected]
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi.git
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 8af2e8d0c0a1..145810b0edf6 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -906,9 +906,6 @@ void __init setup_arch(char **cmdline_p)
                set_bit(EFI_BOOT, &efi.flags);
                set_bit(EFI_64BIT, &efi.flags);
        }
-
-       if (efi_enabled(EFI_BOOT))
-               efi_memblock_x86_reserve_range();
 #endif
 
        x86_init.oem.arch_setup();
@@ -962,6 +959,8 @@ void __init setup_arch(char **cmdline_p)
 
        parse_early_param();
 
+       if (efi_enabled(EFI_BOOT))
+               efi_memblock_x86_reserve_range();
 #ifdef CONFIG_MEMORY_HOTPLUG
        /*
         * Memory used by the kernel cannot be hot-removed because Linux
diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c
index 8a99a2e96537..5b513ccffde4 100644
--- a/arch/x86/platform/efi/quirks.c
+++ b/arch/x86/platform/efi/quirks.c
@@ -592,7 +592,18 @@ static int qrk_capsule_setup_info(struct capsule_info 
*cap_info, void **pkbuff,
        /*
         * Update the first page pointer to skip over the CSH header.
         */
-       cap_info->pages[0] += csh->headersize;
+       cap_info->phys[0] += csh->headersize;
+
+       /*
+        * cap_info->capsule should point at a virtual mapping of the entire
+        * capsule, starting at the capsule header. Our image has the Quark
+        * security header prepended, so we cannot rely on the default vmap()
+        * mapping created by the generic capsule code.
+        * Given that the Quark firmware does not appear to care about the
+        * virtual mapping, let's just point cap_info->capsule at our copy
+        * of the capsule header.
+        */
+       cap_info->capsule = &cap_info->header;
 
        return 1;
 }
diff --git a/drivers/firmware/efi/capsule-loader.c 
b/drivers/firmware/efi/capsule-loader.c
index ec8ac5c4dd84..055e2e8f985a 100644
--- a/drivers/firmware/efi/capsule-loader.c
+++ b/drivers/firmware/efi/capsule-loader.c
@@ -20,10 +20,6 @@
 
 #define NO_FURTHER_WRITE_ACTION -1
 
-#ifndef phys_to_page
-#define phys_to_page(x)                pfn_to_page((x) >> PAGE_SHIFT)
-#endif
-
 /**
  * efi_free_all_buff_pages - free all previous allocated buffer pages
  * @cap_info: pointer to current instance of capsule_info structure
@@ -35,7 +31,7 @@
 static void efi_free_all_buff_pages(struct capsule_info *cap_info)
 {
        while (cap_info->index > 0)
-               __free_page(phys_to_page(cap_info->pages[--cap_info->index]));
+               __free_page(cap_info->pages[--cap_info->index]);
 
        cap_info->index = NO_FURTHER_WRITE_ACTION;
 }
@@ -71,6 +67,14 @@ int __efi_capsule_setup_info(struct capsule_info *cap_info)
 
        cap_info->pages = temp_page;
 
+       temp_page = krealloc(cap_info->phys,
+                            pages_needed * sizeof(phys_addr_t *),
+                            GFP_KERNEL | __GFP_ZERO);
+       if (!temp_page)
+               return -ENOMEM;
+
+       cap_info->phys = temp_page;
+
        return 0;
 }
 
@@ -105,9 +109,24 @@ int __weak efi_capsule_setup_info(struct capsule_info 
*cap_info, void *kbuff,
  **/
 static ssize_t efi_capsule_submit_update(struct capsule_info *cap_info)
 {
+       bool do_vunmap = false;
        int ret;
 
-       ret = efi_capsule_update(&cap_info->header, cap_info->pages);
+       /*
+        * cap_info->capsule may have been assigned already by a quirk
+        * handler, so only overwrite it if it is NULL
+        */
+       if (!cap_info->capsule) {
+               cap_info->capsule = vmap(cap_info->pages, cap_info->index,
+                                        VM_MAP, PAGE_KERNEL);
+               if (!cap_info->capsule)
+                       return -ENOMEM;
+               do_vunmap = true;
+       }
+
+       ret = efi_capsule_update(cap_info->capsule, cap_info->phys);
+       if (do_vunmap)
+               vunmap(cap_info->capsule);
        if (ret) {
                pr_err("capsule update failed\n");
                return ret;
@@ -165,10 +184,12 @@ static ssize_t efi_capsule_write(struct file *file, const 
char __user *buff,
                        goto failed;
                }
 
-               cap_info->pages[cap_info->index++] = page_to_phys(page);
+               cap_info->pages[cap_info->index] = page;
+               cap_info->phys[cap_info->index] = page_to_phys(page);
                cap_info->page_bytes_remain = PAGE_SIZE;
+               cap_info->index++;
        } else {
-               page = phys_to_page(cap_info->pages[cap_info->index - 1]);
+               page = cap_info->pages[cap_info->index - 1];
        }
 
        kbuff = kmap(page);
@@ -252,6 +273,7 @@ static int efi_capsule_release(struct inode *inode, struct 
file *file)
        struct capsule_info *cap_info = file->private_data;
 
        kfree(cap_info->pages);
+       kfree(cap_info->phys);
        kfree(file->private_data);
        file->private_data = NULL;
        return 0;
@@ -281,6 +303,13 @@ static int efi_capsule_open(struct inode *inode, struct 
file *file)
                return -ENOMEM;
        }
 
+       cap_info->phys = kzalloc(sizeof(void *), GFP_KERNEL);
+       if (!cap_info->phys) {
+               kfree(cap_info->pages);
+               kfree(cap_info);
+               return -ENOMEM;
+       }
+
        file->private_data = cap_info;
 
        return 0;
diff --git a/include/linux/efi.h b/include/linux/efi.h
index d813f7b04da7..29fdf8029cf6 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -140,11 +140,13 @@ struct efi_boot_memmap {
 
 struct capsule_info {
        efi_capsule_header_t    header;
+       efi_capsule_header_t    *capsule;
        int                     reset_type;
        long                    index;
        size_t                  count;
        size_t                  total_size;
-       phys_addr_t             *pages;
+       struct page             **pages;
+       phys_addr_t             *phys;
        size_t                  page_bytes_remain;
 };
 

Reply via email to