Commit 4d0a4388 authored by Ingo Molnar's avatar Ingo Molnar

Merge branch 'efi/urgent' into efi/core, to pick up fixes

These fixes missed the v5.9 merge window, pick them up for early v5.10 merge.
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parents cc383a9e d32de913
...@@ -1233,8 +1233,7 @@ ...@@ -1233,8 +1233,7 @@
efi= [EFI] efi= [EFI]
Format: { "debug", "disable_early_pci_dma", Format: { "debug", "disable_early_pci_dma",
"nochunk", "noruntime", "nosoftreserve", "nochunk", "noruntime", "nosoftreserve",
"novamap", "no_disable_early_pci_dma", "novamap", "no_disable_early_pci_dma" }
"old_map" }
debug: enable misc debug output. debug: enable misc debug output.
disable_early_pci_dma: disable the busmaster bit on all disable_early_pci_dma: disable the busmaster bit on all
PCI bridges while in the EFI boot stub. PCI bridges while in the EFI boot stub.
...@@ -1251,8 +1250,6 @@ ...@@ -1251,8 +1250,6 @@
novamap: do not call SetVirtualAddressMap(). novamap: do not call SetVirtualAddressMap().
no_disable_early_pci_dma: Leave the busmaster bit set no_disable_early_pci_dma: Leave the busmaster bit set
on all PCI bridges while in the EFI boot stub on all PCI bridges while in the EFI boot stub
old_map [X86-64]: switch to the old ioremap-based EFI
runtime services mapping. [Needs CONFIG_X86_UV=y]
efi_no_storage_paranoia [EFI; X86] efi_no_storage_paranoia [EFI; X86]
Using this parameter you can use more than 50% of Using this parameter you can use more than 50% of
......
...@@ -81,11 +81,8 @@ extern unsigned long efi_fw_vendor, efi_config_table; ...@@ -81,11 +81,8 @@ extern unsigned long efi_fw_vendor, efi_config_table;
kernel_fpu_end(); \ kernel_fpu_end(); \
}) })
#define arch_efi_call_virt(p, f, args...) p->f(args) #define arch_efi_call_virt(p, f, args...) p->f(args)
#define efi_ioremap(addr, size, type, attr) ioremap_cache(addr, size)
#else /* !CONFIG_X86_32 */ #else /* !CONFIG_X86_32 */
#define EFI_LOADER_SIGNATURE "EL64" #define EFI_LOADER_SIGNATURE "EL64"
...@@ -125,9 +122,6 @@ struct efi_scratch { ...@@ -125,9 +122,6 @@ struct efi_scratch {
kernel_fpu_end(); \ kernel_fpu_end(); \
}) })
extern void __iomem *__init efi_ioremap(unsigned long addr, unsigned long size,
u32 type, u64 attribute);
#ifdef CONFIG_KASAN #ifdef CONFIG_KASAN
/* /*
* CONFIG_KASAN may redefine memset to __memset. __memset function is present * CONFIG_KASAN may redefine memset to __memset. __memset function is present
...@@ -143,17 +137,13 @@ extern void __iomem *__init efi_ioremap(unsigned long addr, unsigned long size, ...@@ -143,17 +137,13 @@ extern void __iomem *__init efi_ioremap(unsigned long addr, unsigned long size,
#endif /* CONFIG_X86_32 */ #endif /* CONFIG_X86_32 */
extern struct efi_scratch efi_scratch; extern struct efi_scratch efi_scratch;
extern void __init efi_set_executable(efi_memory_desc_t *md, bool executable);
extern int __init efi_memblock_x86_reserve_range(void); extern int __init efi_memblock_x86_reserve_range(void);
extern void __init efi_print_memmap(void); extern void __init efi_print_memmap(void);
extern void __init efi_memory_uc(u64 addr, unsigned long size);
extern void __init efi_map_region(efi_memory_desc_t *md); extern void __init efi_map_region(efi_memory_desc_t *md);
extern void __init efi_map_region_fixed(efi_memory_desc_t *md); extern void __init efi_map_region_fixed(efi_memory_desc_t *md);
extern void efi_sync_low_kernel_mappings(void); extern void efi_sync_low_kernel_mappings(void);
extern int __init efi_alloc_page_tables(void); extern int __init efi_alloc_page_tables(void);
extern int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages); extern int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages);
extern void __init old_map_region(efi_memory_desc_t *md);
extern void __init runtime_code_page_mkexec(void);
extern void __init efi_runtime_update_mappings(void); extern void __init efi_runtime_update_mappings(void);
extern void __init efi_dump_pagetable(void); extern void __init efi_dump_pagetable(void);
extern void __init efi_apply_memmap_quirks(void); extern void __init efi_apply_memmap_quirks(void);
......
...@@ -49,7 +49,6 @@ ...@@ -49,7 +49,6 @@
#include <asm/efi.h> #include <asm/efi.h>
#include <asm/e820/api.h> #include <asm/e820/api.h>
#include <asm/time.h> #include <asm/time.h>
#include <asm/set_memory.h>
#include <asm/tlbflush.h> #include <asm/tlbflush.h>
#include <asm/x86_init.h> #include <asm/x86_init.h>
#include <asm/uv/uv.h> #include <asm/uv/uv.h>
...@@ -499,74 +498,6 @@ void __init efi_init(void) ...@@ -499,74 +498,6 @@ void __init efi_init(void)
efi_print_memmap(); efi_print_memmap();
} }
#if defined(CONFIG_X86_32)
void __init efi_set_executable(efi_memory_desc_t *md, bool executable)
{
u64 addr, npages;
addr = md->virt_addr;
npages = md->num_pages;
memrange_efi_to_native(&addr, &npages);
if (executable)
set_memory_x(addr, npages);
else
set_memory_nx(addr, npages);
}
void __init runtime_code_page_mkexec(void)
{
efi_memory_desc_t *md;
/* Make EFI runtime service code area executable */
for_each_efi_memory_desc(md) {
if (md->type != EFI_RUNTIME_SERVICES_CODE)
continue;
efi_set_executable(md, true);
}
}
void __init efi_memory_uc(u64 addr, unsigned long size)
{
unsigned long page_shift = 1UL << EFI_PAGE_SHIFT;
u64 npages;
npages = round_up(size, page_shift) / page_shift;
memrange_efi_to_native(&addr, &npages);
set_memory_uc(addr, npages);
}
void __init old_map_region(efi_memory_desc_t *md)
{
u64 start_pfn, end_pfn, end;
unsigned long size;
void *va;
start_pfn = PFN_DOWN(md->phys_addr);
size = md->num_pages << PAGE_SHIFT;
end = md->phys_addr + size;
end_pfn = PFN_UP(end);
if (pfn_range_is_mapped(start_pfn, end_pfn)) {
va = __va(md->phys_addr);
if (!(md->attribute & EFI_MEMORY_WB))
efi_memory_uc((u64)(unsigned long)va, size);
} else
va = efi_ioremap(md->phys_addr, size,
md->type, md->attribute);
md->virt_addr = (u64) (unsigned long) va;
if (!va)
pr_err("ioremap of 0x%llX failed!\n",
(unsigned long long)md->phys_addr);
}
#endif
/* Merge contiguous regions of the same type and attribute */ /* Merge contiguous regions of the same type and attribute */
static void __init efi_merge_regions(void) static void __init efi_merge_regions(void)
{ {
......
...@@ -29,9 +29,35 @@ ...@@ -29,9 +29,35 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/desc.h> #include <asm/desc.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/set_memory.h>
#include <asm/tlbflush.h> #include <asm/tlbflush.h>
#include <asm/efi.h> #include <asm/efi.h>
void __init efi_map_region(efi_memory_desc_t *md)
{
u64 start_pfn, end_pfn, end;
unsigned long size;
void *va;
start_pfn = PFN_DOWN(md->phys_addr);
size = md->num_pages << PAGE_SHIFT;
end = md->phys_addr + size;
end_pfn = PFN_UP(end);
if (pfn_range_is_mapped(start_pfn, end_pfn)) {
va = __va(md->phys_addr);
if (!(md->attribute & EFI_MEMORY_WB))
set_memory_uc((unsigned long)va, md->num_pages);
} else {
va = ioremap_cache(md->phys_addr, size);
}
md->virt_addr = (unsigned long)va;
if (!va)
pr_err("ioremap of 0x%llX failed!\n", md->phys_addr);
}
/* /*
* To make EFI call EFI runtime service in physical addressing mode we need * To make EFI call EFI runtime service in physical addressing mode we need
* prolog/epilog before/after the invocation to claim the EFI runtime service * prolog/epilog before/after the invocation to claim the EFI runtime service
...@@ -58,11 +84,6 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) ...@@ -58,11 +84,6 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages)
return 0; return 0;
} }
void __init efi_map_region(efi_memory_desc_t *md)
{
old_map_region(md);
}
void __init efi_map_region_fixed(efi_memory_desc_t *md) {} void __init efi_map_region_fixed(efi_memory_desc_t *md) {}
void __init parse_efi_setup(u64 phys_addr, u32 data_len) {} void __init parse_efi_setup(u64 phys_addr, u32 data_len) {}
...@@ -107,6 +128,15 @@ efi_status_t __init efi_set_virtual_address_map(unsigned long memory_map_size, ...@@ -107,6 +128,15 @@ efi_status_t __init efi_set_virtual_address_map(unsigned long memory_map_size,
void __init efi_runtime_update_mappings(void) void __init efi_runtime_update_mappings(void)
{ {
if (__supported_pte_mask & _PAGE_NX) if (__supported_pte_mask & _PAGE_NX) {
runtime_code_page_mkexec(); efi_memory_desc_t *md;
/* Make EFI runtime service code area executable */
for_each_efi_memory_desc(md) {
if (md->type != EFI_RUNTIME_SERVICES_CODE)
continue;
set_memory_x(md->virt_addr, md->num_pages);
}
}
} }
...@@ -259,6 +259,8 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) ...@@ -259,6 +259,8 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages)
npages = (__end_rodata - __start_rodata) >> PAGE_SHIFT; npages = (__end_rodata - __start_rodata) >> PAGE_SHIFT;
rodata = __pa(__start_rodata); rodata = __pa(__start_rodata);
pfn = rodata >> PAGE_SHIFT; pfn = rodata >> PAGE_SHIFT;
pf = _PAGE_NX | _PAGE_ENC;
if (kernel_map_pages_in_pgd(pgd, pfn, rodata, npages, pf)) { if (kernel_map_pages_in_pgd(pgd, pfn, rodata, npages, pf)) {
pr_err("Failed to map kernel rodata 1:1\n"); pr_err("Failed to map kernel rodata 1:1\n");
return 1; return 1;
......
...@@ -384,6 +384,7 @@ static int __init efisubsys_init(void) ...@@ -384,6 +384,7 @@ static int __init efisubsys_init(void)
efi_kobj = kobject_create_and_add("efi", firmware_kobj); efi_kobj = kobject_create_and_add("efi", firmware_kobj);
if (!efi_kobj) { if (!efi_kobj) {
pr_err("efi: Firmware registration failed.\n"); pr_err("efi: Firmware registration failed.\n");
destroy_workqueue(efi_rts_wq);
return -ENOMEM; return -ENOMEM;
} }
...@@ -427,6 +428,7 @@ static int __init efisubsys_init(void) ...@@ -427,6 +428,7 @@ static int __init efisubsys_init(void)
generic_ops_unregister(); generic_ops_unregister();
err_put: err_put:
kobject_put(efi_kobj); kobject_put(efi_kobj);
destroy_workqueue(efi_rts_wq);
return error; return error;
} }
...@@ -718,7 +720,7 @@ void __init efi_systab_report_header(const efi_table_hdr_t *systab_hdr, ...@@ -718,7 +720,7 @@ void __init efi_systab_report_header(const efi_table_hdr_t *systab_hdr,
vendor); vendor);
} }
static __initdata char memory_type_name[][20] = { static __initdata char memory_type_name[][13] = {
"Reserved", "Reserved",
"Loader Code", "Loader Code",
"Loader Data", "Loader Data",
...@@ -726,14 +728,14 @@ static __initdata char memory_type_name[][20] = { ...@@ -726,14 +728,14 @@ static __initdata char memory_type_name[][20] = {
"Boot Data", "Boot Data",
"Runtime Code", "Runtime Code",
"Runtime Data", "Runtime Data",
"Conventional Memory", "Conventional",
"Unusable Memory", "Unusable",
"ACPI Reclaim Memory", "ACPI Reclaim",
"ACPI Memory NVS", "ACPI Mem NVS",
"Memory Mapped I/O", "MMIO",
"MMIO Port Space", "MMIO Port",
"PAL Code", "PAL Code",
"Persistent Memory", "Persistent",
}; };
char * __init efi_md_typeattr_format(char *buf, size_t size, char * __init efi_md_typeattr_format(char *buf, size_t size,
...@@ -760,26 +762,27 @@ char * __init efi_md_typeattr_format(char *buf, size_t size, ...@@ -760,26 +762,27 @@ char * __init efi_md_typeattr_format(char *buf, size_t size,
if (attr & ~(EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT | if (attr & ~(EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT |
EFI_MEMORY_WB | EFI_MEMORY_UCE | EFI_MEMORY_RO | EFI_MEMORY_WB | EFI_MEMORY_UCE | EFI_MEMORY_RO |
EFI_MEMORY_WP | EFI_MEMORY_RP | EFI_MEMORY_XP | EFI_MEMORY_WP | EFI_MEMORY_RP | EFI_MEMORY_XP |
EFI_MEMORY_NV | EFI_MEMORY_SP | EFI_MEMORY_NV | EFI_MEMORY_SP | EFI_MEMORY_CPU_CRYPTO |
EFI_MEMORY_RUNTIME | EFI_MEMORY_MORE_RELIABLE)) EFI_MEMORY_RUNTIME | EFI_MEMORY_MORE_RELIABLE))
snprintf(pos, size, "|attr=0x%016llx]", snprintf(pos, size, "|attr=0x%016llx]",
(unsigned long long)attr); (unsigned long long)attr);
else else
snprintf(pos, size, snprintf(pos, size,
"|%3s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]", "|%3s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]",
attr & EFI_MEMORY_RUNTIME ? "RUN" : "", attr & EFI_MEMORY_RUNTIME ? "RUN" : "",
attr & EFI_MEMORY_MORE_RELIABLE ? "MR" : "", attr & EFI_MEMORY_MORE_RELIABLE ? "MR" : "",
attr & EFI_MEMORY_SP ? "SP" : "", attr & EFI_MEMORY_CPU_CRYPTO ? "CC" : "",
attr & EFI_MEMORY_NV ? "NV" : "", attr & EFI_MEMORY_SP ? "SP" : "",
attr & EFI_MEMORY_XP ? "XP" : "", attr & EFI_MEMORY_NV ? "NV" : "",
attr & EFI_MEMORY_RP ? "RP" : "", attr & EFI_MEMORY_XP ? "XP" : "",
attr & EFI_MEMORY_WP ? "WP" : "", attr & EFI_MEMORY_RP ? "RP" : "",
attr & EFI_MEMORY_RO ? "RO" : "", attr & EFI_MEMORY_WP ? "WP" : "",
attr & EFI_MEMORY_UCE ? "UCE" : "", attr & EFI_MEMORY_RO ? "RO" : "",
attr & EFI_MEMORY_WB ? "WB" : "", attr & EFI_MEMORY_UCE ? "UCE" : "",
attr & EFI_MEMORY_WT ? "WT" : "", attr & EFI_MEMORY_WB ? "WB" : "",
attr & EFI_MEMORY_WC ? "WC" : "", attr & EFI_MEMORY_WT ? "WT" : "",
attr & EFI_MEMORY_UC ? "UC" : ""); attr & EFI_MEMORY_WC ? "WC" : "",
attr & EFI_MEMORY_UC ? "UC" : "");
return buf; return buf;
} }
......
...@@ -84,7 +84,7 @@ static int __init efibc_init(void) ...@@ -84,7 +84,7 @@ static int __init efibc_init(void)
{ {
int ret; int ret;
if (!efi_enabled(EFI_RUNTIME_SERVICES)) if (!efivars_kobject() || !efivar_supports_writes())
return -ENODEV; return -ENODEV;
ret = register_reboot_notifier(&efibc_reboot_notifier); ret = register_reboot_notifier(&efibc_reboot_notifier);
......
...@@ -61,10 +61,12 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, ...@@ -61,10 +61,12 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
status = efi_get_random_bytes(sizeof(phys_seed), status = efi_get_random_bytes(sizeof(phys_seed),
(u8 *)&phys_seed); (u8 *)&phys_seed);
if (status == EFI_NOT_FOUND) { if (status == EFI_NOT_FOUND) {
efi_info("EFI_RNG_PROTOCOL unavailable, no randomness supplied\n"); efi_info("EFI_RNG_PROTOCOL unavailable, KASLR will be disabled\n");
efi_nokaslr = true;
} else if (status != EFI_SUCCESS) { } else if (status != EFI_SUCCESS) {
efi_err("efi_get_random_bytes() failed\n"); efi_err("efi_get_random_bytes() failed (0x%lx), KASLR will be disabled\n",
return status; status);
efi_nokaslr = true;
} }
} else { } else {
efi_info("KASLR disabled on kernel command line\n"); efi_info("KASLR disabled on kernel command line\n");
......
...@@ -187,20 +187,28 @@ int efi_printk(const char *fmt, ...) ...@@ -187,20 +187,28 @@ int efi_printk(const char *fmt, ...)
*/ */
efi_status_t efi_parse_options(char const *cmdline) efi_status_t efi_parse_options(char const *cmdline)
{ {
size_t len = strlen(cmdline) + 1; size_t len;
efi_status_t status; efi_status_t status;
char *str, *buf; char *str, *buf;
if (!cmdline)
return EFI_SUCCESS;
len = strnlen(cmdline, COMMAND_LINE_SIZE - 1) + 1;
status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, len, (void **)&buf); status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, len, (void **)&buf);
if (status != EFI_SUCCESS) if (status != EFI_SUCCESS)
return status; return status;
str = skip_spaces(memcpy(buf, cmdline, len)); memcpy(buf, cmdline, len - 1);
buf[len - 1] = '\0';
str = skip_spaces(buf);
while (*str) { while (*str) {
char *param, *val; char *param, *val;
str = next_arg(str, &param, &val); str = next_arg(str, &param, &val);
if (!val && !strcmp(param, "--"))
break;
if (!strcmp(param, "nokaslr")) { if (!strcmp(param, "nokaslr")) {
efi_nokaslr = true; efi_nokaslr = true;
......
...@@ -136,7 +136,7 @@ static efi_status_t update_fdt(void *orig_fdt, unsigned long orig_fdt_size, ...@@ -136,7 +136,7 @@ static efi_status_t update_fdt(void *orig_fdt, unsigned long orig_fdt_size,
if (status) if (status)
goto fdt_set_fail; goto fdt_set_fail;
if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) { if (IS_ENABLED(CONFIG_RANDOMIZE_BASE) && !efi_nokaslr) {
efi_status_t efi_status; efi_status_t efi_status;
efi_status = efi_get_random_bytes(sizeof(fdt_val64), efi_status = efi_get_random_bytes(sizeof(fdt_val64),
...@@ -145,8 +145,6 @@ static efi_status_t update_fdt(void *orig_fdt, unsigned long orig_fdt_size, ...@@ -145,8 +145,6 @@ static efi_status_t update_fdt(void *orig_fdt, unsigned long orig_fdt_size,
status = fdt_setprop_var(fdt, node, "kaslr-seed", fdt_val64); status = fdt_setprop_var(fdt, node, "kaslr-seed", fdt_val64);
if (status) if (status)
goto fdt_set_fail; goto fdt_set_fail;
} else if (efi_status != EFI_NOT_FOUND) {
return efi_status;
} }
} }
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
*/ */
#include <linux/ctype.h> #include <linux/ctype.h>
#include <linux/kernel.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/string.h> #include <linux/string.h>
......
...@@ -403,7 +403,6 @@ static void dup_variable_bug(efi_char16_t *str16, efi_guid_t *vendor_guid, ...@@ -403,7 +403,6 @@ static void dup_variable_bug(efi_char16_t *str16, efi_guid_t *vendor_guid,
* efivar_init - build the initial list of EFI variables * efivar_init - build the initial list of EFI variables
* @func: callback function to invoke for every variable * @func: callback function to invoke for every variable
* @data: function-specific data to pass to @func * @data: function-specific data to pass to @func
* @atomic: do we need to execute the @func-loop atomically?
* @duplicates: error if we encounter duplicates on @head? * @duplicates: error if we encounter duplicates on @head?
* @head: initialised head of variable list * @head: initialised head of variable list
* *
......
...@@ -141,6 +141,9 @@ static int efivarfs_callback(efi_char16_t *name16, efi_guid_t vendor, ...@@ -141,6 +141,9 @@ static int efivarfs_callback(efi_char16_t *name16, efi_guid_t vendor,
name[len + EFI_VARIABLE_GUID_LEN+1] = '\0'; name[len + EFI_VARIABLE_GUID_LEN+1] = '\0';
/* replace invalid slashes like kobject_set_name_vargs does for /sys/firmware/efi/vars. */
strreplace(name, '/', '!');
inode = efivarfs_get_inode(sb, d_inode(root), S_IFREG | 0644, 0, inode = efivarfs_get_inode(sb, d_inode(root), S_IFREG | 0644, 0,
is_removable); is_removable);
if (!inode) if (!inode)
......
...@@ -122,6 +122,7 @@ typedef struct { ...@@ -122,6 +122,7 @@ typedef struct {
((u64)0x0000000000010000ULL) /* higher reliability */ ((u64)0x0000000000010000ULL) /* higher reliability */
#define EFI_MEMORY_RO ((u64)0x0000000000020000ULL) /* read-only */ #define EFI_MEMORY_RO ((u64)0x0000000000020000ULL) /* read-only */
#define EFI_MEMORY_SP ((u64)0x0000000000040000ULL) /* soft reserved */ #define EFI_MEMORY_SP ((u64)0x0000000000040000ULL) /* soft reserved */
#define EFI_MEMORY_CPU_CRYPTO ((u64)0x0000000000080000ULL) /* supports encryption */
#define EFI_MEMORY_RUNTIME ((u64)0x8000000000000000ULL) /* range requires runtime mapping */ #define EFI_MEMORY_RUNTIME ((u64)0x8000000000000000ULL) /* range requires runtime mapping */
#define EFI_MEMORY_DESCRIPTOR_VERSION 1 #define EFI_MEMORY_DESCRIPTOR_VERSION 1
......
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