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
This commit is contained in:
commit
b03acc4cc2
|
@ -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
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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,
|
||||||
/*
|
/*
|
||||||
* 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 @@
|
||||||
|
|
||||||
#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 @@
|
||||||
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)
|
||||||
|
|
||||||
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,
|
||||||
**/
|
**/
|
||||||
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,
|
||||||
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)
|
||||||
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)
|
||||||
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 {
|
||||||
|
|
||||||
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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue