Commit b03acc4c authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'efi-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull EFI updates from Thomas Gleixner:

 - 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!

* 'efi-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  MAINTAINERS: Remove Matt Fleming as EFI co-maintainer
  efi/capsule-loader: Reinstate virtual capsule mapping
  x86/efi: Fix kernel param add_efi_memmap regression
parents 3eac6903 81b60dbf
...@@ -5149,15 +5149,15 @@ F: sound/usb/misc/ua101.c ...@@ -5149,15 +5149,15 @@ F: sound/usb/misc/ua101.c
EFI TEST DRIVER EFI TEST DRIVER
L: linux-efi@vger.kernel.org L: linux-efi@vger.kernel.org
M: Ivan Hu <ivan.hu@canonical.com> M: Ivan Hu <ivan.hu@canonical.com>
M: Matt Fleming <matt@codeblueprint.co.uk> M: Ard Biesheuvel <ard.biesheuvel@linaro.org>
S: Maintained S: Maintained
F: drivers/firmware/efi/test/ F: drivers/firmware/efi/test/
EFI VARIABLE FILESYSTEM EFI VARIABLE FILESYSTEM
M: Matthew Garrett <matthew.garrett@nebula.com> M: Matthew Garrett <matthew.garrett@nebula.com>
M: Jeremy Kerr <jk@ozlabs.org> M: Jeremy Kerr <jk@ozlabs.org>
M: Matt Fleming <matt@codeblueprint.co.uk> M: Ard Biesheuvel <ard.biesheuvel@linaro.org>
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mfleming/efi.git T: git git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi.git
L: linux-efi@vger.kernel.org L: linux-efi@vger.kernel.org
S: Maintained S: Maintained
F: fs/efivarfs/ F: fs/efivarfs/
...@@ -5318,7 +5318,6 @@ S: Supported ...@@ -5318,7 +5318,6 @@ S: Supported
F: security/integrity/evm/ F: security/integrity/evm/
EXTENSIBLE FIRMWARE INTERFACE (EFI) EXTENSIBLE FIRMWARE INTERFACE (EFI)
M: Matt Fleming <matt@codeblueprint.co.uk>
M: Ard Biesheuvel <ard.biesheuvel@linaro.org> M: Ard Biesheuvel <ard.biesheuvel@linaro.org>
L: linux-efi@vger.kernel.org L: linux-efi@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi.git T: git git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi.git
......
...@@ -906,9 +906,6 @@ void __init setup_arch(char **cmdline_p) ...@@ -906,9 +906,6 @@ void __init setup_arch(char **cmdline_p)
set_bit(EFI_BOOT, &efi.flags); set_bit(EFI_BOOT, &efi.flags);
set_bit(EFI_64BIT, &efi.flags); set_bit(EFI_64BIT, &efi.flags);
} }
if (efi_enabled(EFI_BOOT))
efi_memblock_x86_reserve_range();
#endif #endif
x86_init.oem.arch_setup(); x86_init.oem.arch_setup();
...@@ -962,6 +959,8 @@ void __init setup_arch(char **cmdline_p) ...@@ -962,6 +959,8 @@ void __init setup_arch(char **cmdline_p)
parse_early_param(); parse_early_param();
if (efi_enabled(EFI_BOOT))
efi_memblock_x86_reserve_range();
#ifdef CONFIG_MEMORY_HOTPLUG #ifdef CONFIG_MEMORY_HOTPLUG
/* /*
* Memory used by the kernel cannot be hot-removed because Linux * Memory used by the kernel cannot be hot-removed because Linux
......
...@@ -592,7 +592,18 @@ static int qrk_capsule_setup_info(struct capsule_info *cap_info, void **pkbuff, ...@@ -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. * 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; return 1;
} }
......
...@@ -20,10 +20,6 @@ ...@@ -20,10 +20,6 @@
#define NO_FURTHER_WRITE_ACTION -1 #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 * efi_free_all_buff_pages - free all previous allocated buffer pages
* @cap_info: pointer to current instance of capsule_info structure * @cap_info: pointer to current instance of capsule_info structure
...@@ -35,7 +31,7 @@ ...@@ -35,7 +31,7 @@
static void efi_free_all_buff_pages(struct capsule_info *cap_info) static void efi_free_all_buff_pages(struct capsule_info *cap_info)
{ {
while (cap_info->index > 0) 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; cap_info->index = NO_FURTHER_WRITE_ACTION;
} }
...@@ -71,6 +67,14 @@ int __efi_capsule_setup_info(struct capsule_info *cap_info) ...@@ -71,6 +67,14 @@ int __efi_capsule_setup_info(struct capsule_info *cap_info)
cap_info->pages = temp_page; 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; return 0;
} }
...@@ -105,9 +109,24 @@ int __weak efi_capsule_setup_info(struct capsule_info *cap_info, void *kbuff, ...@@ -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) static ssize_t efi_capsule_submit_update(struct capsule_info *cap_info)
{ {
bool do_vunmap = false;
int ret; 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) { if (ret) {
pr_err("capsule update failed\n"); pr_err("capsule update failed\n");
return ret; return ret;
...@@ -165,10 +184,12 @@ static ssize_t efi_capsule_write(struct file *file, const char __user *buff, ...@@ -165,10 +184,12 @@ static ssize_t efi_capsule_write(struct file *file, const char __user *buff,
goto failed; 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->page_bytes_remain = PAGE_SIZE;
cap_info->index++;
} else { } else {
page = phys_to_page(cap_info->pages[cap_info->index - 1]); page = cap_info->pages[cap_info->index - 1];
} }
kbuff = kmap(page); kbuff = kmap(page);
...@@ -252,6 +273,7 @@ static int efi_capsule_release(struct inode *inode, struct file *file) ...@@ -252,6 +273,7 @@ static int efi_capsule_release(struct inode *inode, struct file *file)
struct capsule_info *cap_info = file->private_data; struct capsule_info *cap_info = file->private_data;
kfree(cap_info->pages); kfree(cap_info->pages);
kfree(cap_info->phys);
kfree(file->private_data); kfree(file->private_data);
file->private_data = NULL; file->private_data = NULL;
return 0; return 0;
...@@ -281,6 +303,13 @@ static int efi_capsule_open(struct inode *inode, struct file *file) ...@@ -281,6 +303,13 @@ static int efi_capsule_open(struct inode *inode, struct file *file)
return -ENOMEM; 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; file->private_data = cap_info;
return 0; return 0;
......
...@@ -140,11 +140,13 @@ struct efi_boot_memmap { ...@@ -140,11 +140,13 @@ struct efi_boot_memmap {
struct capsule_info { struct capsule_info {
efi_capsule_header_t header; efi_capsule_header_t header;
efi_capsule_header_t *capsule;
int reset_type; int reset_type;
long index; long index;
size_t count; size_t count;
size_t total_size; size_t total_size;
phys_addr_t *pages; struct page **pages;
phys_addr_t *phys;
size_t page_bytes_remain; size_t page_bytes_remain;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment