Skip to content

Commit

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

Pull EFI updates from Ingo Molnar:
 "The main changes in this cycle were:

   - Changes to the EFI init code to establish whether secure boot
     authentication was performed at boot time. (Josh Boyer, David
     Howells)

   - Wire up the UEFI memory attributes table for x86. This eliminates
     any runtime memory regions that are both writable and executable,
     on recent firmware versions. (Sai Praneeth)

   - Move the BGRT init code to an earlier stage so that we can still
     use efi_mem_reserve(). (Dave Young)

   - Preserve debug symbols in the ARM/arm64 UEFI stub (Ard Biesheuvel)

   - Code deduplication work and various other cleanups (Lukas Wunner)

   - ... plus various other fixes and cleanups"

* 'efi-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  efi/libstub: Make file I/O chunking x86-specific
  efi: Print the secure boot status in x86 setup_arch()
  efi: Disable secure boot if shim is in insecure mode
  efi: Get and store the secure boot status
  efi: Add SHIM and image security database GUID definitions
  arm/efi: Allow invocation of arbitrary runtime services
  x86/efi: Allow invocation of arbitrary runtime services
  efi/libstub: Preserve .debug sections after absolute relocation check
  efi/x86: Add debug code to print cooked memmap
  efi/x86: Move the EFI BGRT init code to early init code
  efi: Use typed function pointers for the runtime services table
  efi/esrt: Fix typo in pr_err() message
  x86/efi: Add support for EFI_MEMORY_ATTRIBUTES_TABLE
  efi: Introduce the EFI_MEM_ATTR bit and set it from the memory attributes table
  efi: Make EFI_MEMORY_ATTRIBUTES_TABLE initialization common across all architectures
  x86/efi: Deduplicate efi_char16_printk()
  efi: Deduplicate efi_file_size() / _read() / _close()
  • Loading branch information
torvalds committed Feb 20, 2017
2 parents f7458a5 + b3879a4 commit 32e2d7c
Show file tree
Hide file tree
Showing 27 changed files with 383 additions and 413 deletions.
2 changes: 2 additions & 0 deletions Documentation/x86/zero-page.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ Offset Proto Name Meaning
1E9/001 ALL eddbuf_entries Number of entries in eddbuf (below)
1EA/001 ALL edd_mbr_sig_buf_entries Number of entries in edd_mbr_sig_buffer
(below)
1EB/001 ALL kbd_status Numlock is enabled
1EC/001 ALL secure_boot Secure boot is enabled in the firmware
1EF/001 ALL sentinel Used to detect broken bootloaders
290/040 ALL edd_mbr_sig_buffer EDD MBR signatures
2D0/A00 ALL e820_map E820 memory map table
Expand Down
1 change: 1 addition & 0 deletions arch/arm/include/asm/efi.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ void efi_virtmap_unload(void);

#define efi_call_early(f, ...) sys_table_arg->boottime->f(__VA_ARGS__)
#define __efi_call_early(f, ...) f(__VA_ARGS__)
#define efi_call_runtime(f, ...) sys_table_arg->runtime->f(__VA_ARGS__)
#define efi_is_64bit() (false)

#define efi_call_proto(protocol, f, instance, ...) \
Expand Down
1 change: 1 addition & 0 deletions arch/arm64/include/asm/efi.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md);

#define efi_call_early(f, ...) sys_table_arg->boottime->f(__VA_ARGS__)
#define __efi_call_early(f, ...) f(__VA_ARGS__)
#define efi_call_runtime(f, ...) sys_table_arg->runtime->f(__VA_ARGS__)
#define efi_is_64bit() (true)

#define efi_call_proto(protocol, f, instance, ...) \
Expand Down
182 changes: 10 additions & 172 deletions arch/x86/boot/compressed/eboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,160 +32,13 @@ static void setup_boot_services##bits(struct efi_config *c) \
\
table = (typeof(table))sys_table; \
\
c->runtime_services = table->runtime; \
c->boot_services = table->boottime; \
c->text_output = table->con_out; \
}
BOOT_SERVICES(32);
BOOT_SERVICES(64);

void efi_char16_printk(efi_system_table_t *, efi_char16_t *);

static efi_status_t
__file_size32(void *__fh, efi_char16_t *filename_16,
void **handle, u64 *file_sz)
{
efi_file_handle_32_t *h, *fh = __fh;
efi_file_info_t *info;
efi_status_t status;
efi_guid_t info_guid = EFI_FILE_INFO_ID;
u32 info_sz;

status = efi_early->call((unsigned long)fh->open, fh, &h, filename_16,
EFI_FILE_MODE_READ, (u64)0);
if (status != EFI_SUCCESS) {
efi_printk(sys_table, "Failed to open file: ");
efi_char16_printk(sys_table, filename_16);
efi_printk(sys_table, "\n");
return status;
}

*handle = h;

info_sz = 0;
status = efi_early->call((unsigned long)h->get_info, h, &info_guid,
&info_sz, NULL);
if (status != EFI_BUFFER_TOO_SMALL) {
efi_printk(sys_table, "Failed to get file info size\n");
return status;
}

grow:
status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
info_sz, (void **)&info);
if (status != EFI_SUCCESS) {
efi_printk(sys_table, "Failed to alloc mem for file info\n");
return status;
}

status = efi_early->call((unsigned long)h->get_info, h, &info_guid,
&info_sz, info);
if (status == EFI_BUFFER_TOO_SMALL) {
efi_call_early(free_pool, info);
goto grow;
}

*file_sz = info->file_size;
efi_call_early(free_pool, info);

if (status != EFI_SUCCESS)
efi_printk(sys_table, "Failed to get initrd info\n");

return status;
}

static efi_status_t
__file_size64(void *__fh, efi_char16_t *filename_16,
void **handle, u64 *file_sz)
{
efi_file_handle_64_t *h, *fh = __fh;
efi_file_info_t *info;
efi_status_t status;
efi_guid_t info_guid = EFI_FILE_INFO_ID;
u64 info_sz;

status = efi_early->call((unsigned long)fh->open, fh, &h, filename_16,
EFI_FILE_MODE_READ, (u64)0);
if (status != EFI_SUCCESS) {
efi_printk(sys_table, "Failed to open file: ");
efi_char16_printk(sys_table, filename_16);
efi_printk(sys_table, "\n");
return status;
}

*handle = h;

info_sz = 0;
status = efi_early->call((unsigned long)h->get_info, h, &info_guid,
&info_sz, NULL);
if (status != EFI_BUFFER_TOO_SMALL) {
efi_printk(sys_table, "Failed to get file info size\n");
return status;
}

grow:
status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
info_sz, (void **)&info);
if (status != EFI_SUCCESS) {
efi_printk(sys_table, "Failed to alloc mem for file info\n");
return status;
}

status = efi_early->call((unsigned long)h->get_info, h, &info_guid,
&info_sz, info);
if (status == EFI_BUFFER_TOO_SMALL) {
efi_call_early(free_pool, info);
goto grow;
}

*file_sz = info->file_size;
efi_call_early(free_pool, info);

if (status != EFI_SUCCESS)
efi_printk(sys_table, "Failed to get initrd info\n");

return status;
}
efi_status_t
efi_file_size(efi_system_table_t *sys_table, void *__fh,
efi_char16_t *filename_16, void **handle, u64 *file_sz)
{
if (efi_early->is64)
return __file_size64(__fh, filename_16, handle, file_sz);

return __file_size32(__fh, filename_16, handle, file_sz);
}

efi_status_t
efi_file_read(void *handle, unsigned long *size, void *addr)
{
unsigned long func;

if (efi_early->is64) {
efi_file_handle_64_t *fh = handle;

func = (unsigned long)fh->read;
return efi_early->call(func, handle, size, addr);
} else {
efi_file_handle_32_t *fh = handle;

func = (unsigned long)fh->read;
return efi_early->call(func, handle, size, addr);
}
}

efi_status_t efi_file_close(void *handle)
{
if (efi_early->is64) {
efi_file_handle_64_t *fh = handle;

return efi_early->call((unsigned long)fh->close, handle);
} else {
efi_file_handle_32_t *fh = handle;

return efi_early->call((unsigned long)fh->close, handle);
}
}

static inline efi_status_t __open_volume32(void *__image, void **__fh)
{
efi_file_io_interface_t *io;
Expand Down Expand Up @@ -249,30 +102,8 @@ efi_open_volume(efi_system_table_t *sys_table, void *__image, void **__fh)

void efi_char16_printk(efi_system_table_t *table, efi_char16_t *str)
{
unsigned long output_string;
size_t offset;

if (efi_early->is64) {
struct efi_simple_text_output_protocol_64 *out;
u64 *func;

offset = offsetof(typeof(*out), output_string);
output_string = efi_early->text_output + offset;
out = (typeof(out))(unsigned long)efi_early->text_output;
func = (u64 *)output_string;

efi_early->call(*func, out, str);
} else {
struct efi_simple_text_output_protocol_32 *out;
u32 *func;

offset = offsetof(typeof(*out), output_string);
output_string = efi_early->text_output + offset;
out = (typeof(out))(unsigned long)efi_early->text_output;
func = (u32 *)output_string;

efi_early->call(*func, out, str);
}
efi_call_proto(efi_simple_text_output_protocol, output_string,
efi_early->text_output, str);
}

static efi_status_t
Expand Down Expand Up @@ -1157,6 +988,13 @@ struct boot_params *efi_main(struct efi_config *c,
else
setup_boot_services32(efi_early);

/*
* If the boot loader gave us a value for secure_boot then we use that,
* otherwise we ask the BIOS.
*/
if (boot_params->secure_boot == efi_secureboot_mode_unset)
boot_params->secure_boot = efi_get_secureboot(sys_table);

setup_graphics(boot_params);

setup_efi_pci(boot_params);
Expand Down
6 changes: 3 additions & 3 deletions arch/x86/boot/compressed/head_32.S
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ ENTRY(efi_pe_entry)

/* Relocate efi_config->call() */
leal efi32_config(%esi), %eax
add %esi, 32(%eax)
add %esi, 40(%eax)
pushl %eax

call make_boot_params
Expand All @@ -108,7 +108,7 @@ ENTRY(efi32_stub_entry)

/* Relocate efi_config->call() */
leal efi32_config(%esi), %eax
add %esi, 32(%eax)
add %esi, 40(%eax)
pushl %eax
2:
call efi_main
Expand Down Expand Up @@ -264,7 +264,7 @@ relocated:
#ifdef CONFIG_EFI_STUB
.data
efi32_config:
.fill 4,8,0
.fill 5,8,0
.long efi_call_phys
.long 0
.byte 0
Expand Down
8 changes: 4 additions & 4 deletions arch/x86/boot/compressed/head_64.S
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ ENTRY(efi_pe_entry)
/*
* Relocate efi_config->call().
*/
addq %rbp, efi64_config+32(%rip)
addq %rbp, efi64_config+40(%rip)

movq %rax, %rdi
call make_boot_params
Expand All @@ -284,7 +284,7 @@ handover_entry:
* Relocate efi_config->call().
*/
movq efi_config(%rip), %rax
addq %rbp, 32(%rax)
addq %rbp, 40(%rax)
2:
movq efi_config(%rip), %rdi
call efi_main
Expand Down Expand Up @@ -456,14 +456,14 @@ efi_config:
#ifdef CONFIG_EFI_MIXED
.global efi32_config
efi32_config:
.fill 4,8,0
.fill 5,8,0
.quad efi64_thunk
.byte 0
#endif

.global efi64_config
efi64_config:
.fill 4,8,0
.fill 5,8,0
.quad efi_call
.byte 1
#endif /* CONFIG_EFI_STUB */
Expand Down
5 changes: 5 additions & 0 deletions arch/x86/include/asm/efi.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ static inline efi_status_t efi_thunk_set_virtual_address_map(
struct efi_config {
u64 image_handle;
u64 table;
u64 runtime_services;
u64 boot_services;
u64 text_output;
efi_status_t (*call)(unsigned long, ...);
Expand Down Expand Up @@ -226,6 +227,10 @@ static inline bool efi_is_64bit(void)
#define __efi_call_early(f, ...) \
__efi_early()->call((unsigned long)f, __VA_ARGS__);

#define efi_call_runtime(f, ...) \
__efi_early()->call(efi_table_attr(efi_runtime_services, f, \
__efi_early()->runtime_services), __VA_ARGS__)

extern bool efi_reboot_required(void);

#else
Expand Down
3 changes: 2 additions & 1 deletion arch/x86/include/uapi/asm/bootparam.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,8 @@ struct boot_params {
__u8 eddbuf_entries; /* 0x1e9 */
__u8 edd_mbr_sig_buf_entries; /* 0x1ea */
__u8 kbd_status; /* 0x1eb */
__u8 _pad5[3]; /* 0x1ec */
__u8 secure_boot; /* 0x1ec */
__u8 _pad5[2]; /* 0x1ed */
/*
* The sentinel is set to a nonzero value (0xff) in header.S.
*
Expand Down
9 changes: 9 additions & 0 deletions arch/x86/kernel/acpi/boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include <linux/bootmem.h>
#include <linux/ioport.h>
#include <linux/pci.h>
#include <linux/efi-bgrt.h>

#include <asm/irqdomain.h>
#include <asm/pci_x86.h>
Expand Down Expand Up @@ -1557,6 +1558,12 @@ int __init early_acpi_boot_init(void)
return 0;
}

static int __init acpi_parse_bgrt(struct acpi_table_header *table)
{
efi_bgrt_init(table);
return 0;
}

int __init acpi_boot_init(void)
{
/* those are executed after early-quirks are executed */
Expand All @@ -1581,6 +1588,8 @@ int __init acpi_boot_init(void)
acpi_process_madt();

acpi_table_parse(ACPI_SIG_HPET, acpi_parse_hpet);
if (IS_ENABLED(CONFIG_ACPI_BGRT))
acpi_table_parse(ACPI_SIG_BGRT, acpi_parse_bgrt);

if (!acpi_noirq)
x86_init.pci.init = pci_acpi_init;
Expand Down
1 change: 1 addition & 0 deletions arch/x86/kernel/asm-offsets.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ void common(void) {

BLANK();
OFFSET(BP_scratch, boot_params, scratch);
OFFSET(BP_secure_boot, boot_params, secure_boot);
OFFSET(BP_loadflags, boot_params, hdr.loadflags);
OFFSET(BP_hardware_subarch, boot_params, hdr.hardware_subarch);
OFFSET(BP_version, boot_params, hdr.version);
Expand Down
14 changes: 14 additions & 0 deletions arch/x86/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -1176,6 +1176,20 @@ void __init setup_arch(char **cmdline_p)
/* Allocate bigger log buffer */
setup_log_buf(1);

if (efi_enabled(EFI_BOOT)) {
switch (boot_params.secure_boot) {
case efi_secureboot_mode_disabled:
pr_info("Secure boot disabled\n");
break;
case efi_secureboot_mode_enabled:
pr_info("Secure boot enabled\n");
break;
default:
pr_info("Secure boot could not be determined\n");
break;
}
}

reserve_initrd();

acpi_table_upgrade();
Expand Down
Loading

0 comments on commit 32e2d7c

Please sign in to comment.