Skip to content

Commit

Permalink
Merge branch 'x86-efi-for-linus' of git://git.kernel.org/pub/scm/linu…
Browse files Browse the repository at this point in the history
…x/kernel/git/tip/tip

Pull x86 EFI updates from Peter Anvin:
 "This patchset falls under the "maintainers that grovel" clause in the
  v3.18-rc1 announcement.  We had intended to push it late in the merge
  window since we got it into the -tip tree relatively late.

  Many of these are relatively simple things, but there are a couple of
  key bits, especially Ard's and Matt's patches"

* 'x86-efi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (24 commits)
  rtc: Disable EFI rtc for x86
  efi: rtc-efi: Export platform:rtc-efi as module alias
  efi: Delete the in_nmi() conditional runtime locking
  efi: Provide a non-blocking SetVariable() operation
  x86/efi: Adding efi_printks on memory allocationa and pci.reads
  x86/efi: Mark initialization code as such
  x86/efi: Update comment regarding required phys mapped EFI services
  x86/efi: Unexport add_efi_memmap variable
  x86/efi: Remove unused efi_call* macros
  efi: Resolve some shadow warnings
  arm64: efi: Format EFI memory type & attrs with efi_md_typeattr_format()
  ia64: efi: Format EFI memory type & attrs with efi_md_typeattr_format()
  x86: efi: Format EFI memory type & attrs with efi_md_typeattr_format()
  efi: Introduce efi_md_typeattr_format()
  efi: Add macro for EFI_MEMORY_UCE memory attribute
  x86/efi: Clear EFI_RUNTIME_SERVICES if failing to enter virtual mode
  arm64/efi: Do not enter virtual mode if booting with efi=noruntime or noefi
  arm64/efi: uefi_init error handling fix
  efi: Add kernel param efi=noruntime
  lib: Add a generic cmdline parse function parse_option_str
  ...
  • Loading branch information
Linus Torvalds committed Oct 23, 2014
2 parents 5de551e + 75b1285 commit 8c81f48
Show file tree
Hide file tree
Showing 20 changed files with 528 additions and 123 deletions.
8 changes: 6 additions & 2 deletions Documentation/kernel-parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1015,10 +1015,14 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
Format: {"off" | "on" | "skip[mbr]"}

efi= [EFI]
Format: { "old_map" }
Format: { "old_map", "nochunk", "noruntime" }
old_map [X86-64]: switch to the old ioremap-based EFI
runtime services mapping. 32-bit still uses this one by
default.
nochunk: disable reading files in "chunks" in the EFI
boot stub, as chunking can cause problems with some
firmware implementations.
noruntime : disable EFI runtime services support

efi_no_storage_paranoia [EFI; X86]
Using this parameter you can use more than 50% of
Expand Down Expand Up @@ -2232,7 +2236,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.

nodsp [SH] Disable hardware DSP at boot time.

noefi [X86] Disable EFI runtime services support.
noefi Disable EFI runtime services support.

noexec [IA-64]

Expand Down
44 changes: 18 additions & 26 deletions arch/arm64/kernel/efi.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ static int __init uefi_init(void)
*/
if (efi.systab->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) {
pr_err("System table signature incorrect\n");
return -EINVAL;
retval = -EINVAL;
goto out;
}
if ((efi.systab->hdr.revision >> 16) < 2)
pr_warn("Warning: EFI system table version %d.%02d, expected 2.00 or greater\n",
Expand All @@ -103,6 +104,7 @@ static int __init uefi_init(void)
for (i = 0; i < (int) sizeof(vendor) - 1 && *c16; ++i)
vendor[i] = c16[i];
vendor[i] = '\0';
early_memunmap(c16, sizeof(vendor));
}

pr_info("EFI v%u.%.02u by %s\n",
Expand All @@ -113,29 +115,11 @@ static int __init uefi_init(void)
if (retval == 0)
set_bit(EFI_CONFIG_TABLES, &efi.flags);

early_memunmap(c16, sizeof(vendor));
out:
early_memunmap(efi.systab, sizeof(efi_system_table_t));

return retval;
}

static __initdata char memory_type_name[][32] = {
{"Reserved"},
{"Loader Code"},
{"Loader Data"},
{"Boot Code"},
{"Boot Data"},
{"Runtime Code"},
{"Runtime Data"},
{"Conventional Memory"},
{"Unusable Memory"},
{"ACPI Reclaim Memory"},
{"ACPI Memory NVS"},
{"Memory Mapped I/O"},
{"MMIO Port Space"},
{"PAL Code"},
};

/*
* Return true for RAM regions we want to permanently reserve.
*/
Expand Down Expand Up @@ -166,10 +150,13 @@ static __init void reserve_regions(void)
paddr = md->phys_addr;
npages = md->num_pages;

if (uefi_debug)
pr_info(" 0x%012llx-0x%012llx [%s]",
if (uefi_debug) {
char buf[64];

pr_info(" 0x%012llx-0x%012llx %s",
paddr, paddr + (npages << EFI_PAGE_SHIFT) - 1,
memory_type_name[md->type]);
efi_md_typeattr_format(buf, sizeof(buf), md));
}

memrange_efi_to_native(&paddr, &npages);
size = npages << PAGE_SHIFT;
Expand Down Expand Up @@ -393,11 +380,16 @@ static int __init arm64_enter_virtual_mode(void)
return -1;
}

pr_info("Remapping and enabling EFI services.\n");

/* replace early memmap mapping with permanent mapping */
mapsize = memmap.map_end - memmap.map;
early_memunmap(memmap.map, mapsize);

if (efi_runtime_disabled()) {
pr_info("EFI runtime services will be disabled.\n");
return -1;
}

pr_info("Remapping and enabling EFI services.\n");
/* replace early memmap mapping with permanent mapping */
memmap.map = (__force void *)ioremap_cache((phys_addr_t)memmap.phys_map,
mapsize);
memmap.map_end = memmap.map + mapsize;
Expand Down
6 changes: 4 additions & 2 deletions arch/ia64/kernel/efi.c
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,7 @@ efi_init (void)
{
const char *unit;
unsigned long size;
char buf[64];

md = p;
size = md->num_pages << EFI_PAGE_SHIFT;
Expand All @@ -586,9 +587,10 @@ efi_init (void)
unit = "KB";
}

printk("mem%02d: type=%2u, attr=0x%016lx, "
printk("mem%02d: %s "
"range=[0x%016lx-0x%016lx) (%4lu%s)\n",
i, md->type, md->attribute, md->phys_addr,
i, efi_md_typeattr_format(buf, sizeof(buf), md),
md->phys_addr,
md->phys_addr + efi_md_size(md), size, unit);
}
}
Expand Down
32 changes: 25 additions & 7 deletions arch/x86/boot/compressed/eboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -330,8 +330,10 @@ __setup_efi_pci32(efi_pci_io_protocol_32 *pci, struct pci_setup_rom **__rom)
size = pci->romsize + sizeof(*rom);

status = efi_call_early(allocate_pool, EFI_LOADER_DATA, size, &rom);
if (status != EFI_SUCCESS)
if (status != EFI_SUCCESS) {
efi_printk(sys_table, "Failed to alloc mem for rom\n");
return status;
}

memset(rom, 0, sizeof(*rom));

Expand All @@ -344,14 +346,18 @@ __setup_efi_pci32(efi_pci_io_protocol_32 *pci, struct pci_setup_rom **__rom)
status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16,
PCI_VENDOR_ID, 1, &(rom->vendor));

if (status != EFI_SUCCESS)
if (status != EFI_SUCCESS) {
efi_printk(sys_table, "Failed to read rom->vendor\n");
goto free_struct;
}

status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16,
PCI_DEVICE_ID, 1, &(rom->devid));

if (status != EFI_SUCCESS)
if (status != EFI_SUCCESS) {
efi_printk(sys_table, "Failed to read rom->devid\n");
goto free_struct;
}

status = efi_early->call(pci->get_location, pci, &(rom->segment),
&(rom->bus), &(rom->device), &(rom->function));
Expand Down Expand Up @@ -432,8 +438,10 @@ __setup_efi_pci64(efi_pci_io_protocol_64 *pci, struct pci_setup_rom **__rom)
size = pci->romsize + sizeof(*rom);

status = efi_call_early(allocate_pool, EFI_LOADER_DATA, size, &rom);
if (status != EFI_SUCCESS)
if (status != EFI_SUCCESS) {
efi_printk(sys_table, "Failed to alloc mem for rom\n");
return status;
}

rom->data.type = SETUP_PCI;
rom->data.len = size - sizeof(struct setup_data);
Expand All @@ -444,14 +452,18 @@ __setup_efi_pci64(efi_pci_io_protocol_64 *pci, struct pci_setup_rom **__rom)
status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16,
PCI_VENDOR_ID, 1, &(rom->vendor));

if (status != EFI_SUCCESS)
if (status != EFI_SUCCESS) {
efi_printk(sys_table, "Failed to read rom->vendor\n");
goto free_struct;
}

status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16,
PCI_DEVICE_ID, 1, &(rom->devid));

if (status != EFI_SUCCESS)
if (status != EFI_SUCCESS) {
efi_printk(sys_table, "Failed to read rom->devid\n");
goto free_struct;
}

status = efi_early->call(pci->get_location, pci, &(rom->segment),
&(rom->bus), &(rom->device), &(rom->function));
Expand Down Expand Up @@ -538,8 +550,10 @@ static void setup_efi_pci(struct boot_params *params)
EFI_LOADER_DATA,
size, (void **)&pci_handle);

if (status != EFI_SUCCESS)
if (status != EFI_SUCCESS) {
efi_printk(sys_table, "Failed to alloc mem for pci_handle\n");
return;
}

status = efi_call_early(locate_handle,
EFI_LOCATE_BY_PROTOCOL, &pci_proto,
Expand Down Expand Up @@ -1105,6 +1119,10 @@ struct boot_params *make_boot_params(struct efi_config *c)

memset(sdt, 0, sizeof(*sdt));

status = efi_parse_options(cmdline_ptr);
if (status != EFI_SUCCESS)
goto fail2;

status = handle_cmdline_files(sys_table, image,
(char *)(unsigned long)hdr->cmd_line_ptr,
"initrd=", hdr->initrd_addr_max,
Expand Down
31 changes: 10 additions & 21 deletions arch/x86/include/asm/efi.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,24 +81,23 @@ extern u64 asmlinkage efi_call(void *fp, ...);
*/
#define __efi_call_virt(f, args...) efi_call_virt(f, args)

extern void __iomem *efi_ioremap(unsigned long addr, unsigned long size,
u32 type, u64 attribute);
extern void __iomem *__init efi_ioremap(unsigned long addr, unsigned long size,
u32 type, u64 attribute);

#endif /* CONFIG_X86_32 */

extern int add_efi_memmap;
extern struct efi_scratch efi_scratch;
extern void efi_set_executable(efi_memory_desc_t *md, bool executable);
extern int efi_memblock_x86_reserve_range(void);
extern void efi_call_phys_prelog(void);
extern void efi_call_phys_epilog(void);
extern void efi_unmap_memmap(void);
extern void efi_memory_uc(u64 addr, unsigned long size);
extern void __init efi_set_executable(efi_memory_desc_t *md, bool executable);
extern int __init efi_memblock_x86_reserve_range(void);
extern void __init efi_call_phys_prolog(void);
extern void __init efi_call_phys_epilog(void);
extern void __init efi_unmap_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_fixed(efi_memory_desc_t *md);
extern void efi_sync_low_kernel_mappings(void);
extern int efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages);
extern void efi_cleanup_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 efi_cleanup_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_mkexec(void);
Expand Down Expand Up @@ -162,16 +161,6 @@ static inline efi_status_t efi_thunk_set_virtual_address_map(
extern bool efi_reboot_required(void);

#else
/*
* IF EFI is not configured, have the EFI calls return -ENOSYS.
*/
#define efi_call0(_f) (-ENOSYS)
#define efi_call1(_f, _a1) (-ENOSYS)
#define efi_call2(_f, _a1, _a2) (-ENOSYS)
#define efi_call3(_f, _a1, _a2, _a3) (-ENOSYS)
#define efi_call4(_f, _a1, _a2, _a3, _a4) (-ENOSYS)
#define efi_call5(_f, _a1, _a2, _a3, _a4, _a5) (-ENOSYS)
#define efi_call6(_f, _a1, _a2, _a3, _a4, _a5, _a6) (-ENOSYS)
static inline void parse_efi_setup(u64 phys_addr, u32 data_len) {}
static inline bool efi_reboot_required(void)
{
Expand Down
36 changes: 30 additions & 6 deletions arch/x86/platform/efi/efi-bgrt.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,35 +40,59 @@ void __init efi_bgrt_init(void)
if (ACPI_FAILURE(status))
return;

if (bgrt_tab->header.length < sizeof(*bgrt_tab))
if (bgrt_tab->header.length < sizeof(*bgrt_tab)) {
pr_err("Ignoring BGRT: invalid length %u (expected %zu)\n",
bgrt_tab->header.length, sizeof(*bgrt_tab));
return;
if (bgrt_tab->version != 1 || bgrt_tab->status != 1)
}
if (bgrt_tab->version != 1) {
pr_err("Ignoring BGRT: invalid version %u (expected 1)\n",
bgrt_tab->version);
return;
}
if (bgrt_tab->status != 1) {
pr_err("Ignoring BGRT: invalid status %u (expected 1)\n",
bgrt_tab->status);
return;
}
if (bgrt_tab->image_type != 0) {
pr_err("Ignoring BGRT: invalid image type %u (expected 0)\n",
bgrt_tab->image_type);
return;
if (bgrt_tab->image_type != 0 || !bgrt_tab->image_address)
}
if (!bgrt_tab->image_address) {
pr_err("Ignoring BGRT: null image address\n");
return;
}

image = efi_lookup_mapped_addr(bgrt_tab->image_address);
if (!image) {
image = early_memremap(bgrt_tab->image_address,
sizeof(bmp_header));
ioremapped = true;
if (!image)
if (!image) {
pr_err("Ignoring BGRT: failed to map image header memory\n");
return;
}
}

memcpy_fromio(&bmp_header, image, sizeof(bmp_header));
if (ioremapped)
early_iounmap(image, sizeof(bmp_header));
bgrt_image_size = bmp_header.size;

bgrt_image = kmalloc(bgrt_image_size, GFP_KERNEL);
if (!bgrt_image)
bgrt_image = kmalloc(bgrt_image_size, GFP_KERNEL | __GFP_NOWARN);
if (!bgrt_image) {
pr_err("Ignoring BGRT: failed to allocate memory for image (wanted %zu bytes)\n",
bgrt_image_size);
return;
}

if (ioremapped) {
image = early_memremap(bgrt_tab->image_address,
bmp_header.size);
if (!image) {
pr_err("Ignoring BGRT: failed to map image memory\n");
kfree(bgrt_image);
bgrt_image = NULL;
return;
Expand Down
Loading

0 comments on commit 8c81f48

Please sign in to comment.