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:

 - decode x86 CPER data (Yazen Ghannam)

 - ignore unrealistically large option ROMs (Hans de Goede)

 - initialize UEFI secure boot state during Xen dom0 boot (Daniel Kiper)

 - additional minor tweaks and fixes.

* 'efi-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  efi/capsule-loader: Don't output reset log when reset flags are not set
  efi/x86: Ignore unrealistically large option ROMs
  efi/x86: Fold __setup_efi_pci32() and __setup_efi_pci64() into one function
  efi: Align efi_pci_io_protocol typedefs to type naming convention
  efi/libstub/tpm: Make function efi_retrieve_tpm2_eventlog_1_2() static
  efi: Decode IA32/X64 Context Info structure
  efi: Decode IA32/X64 MS Check structure
  efi: Decode additional IA32/X64 Bus Check fields
  efi: Decode IA32/X64 Cache, TLB, and Bus Check structures
  efi: Decode UEFI-defined IA32/X64 Error Structure GUIDs
  efi: Decode IA32/X64 Processor Error Info Structure
  efi: Decode IA32/X64 Processor Error Section
  efi: Fix IA32/X64 Processor Error Record definition
  efi/cper: Remove the INDENT_SP silliness
  x86/xen/efi: Initialize UEFI secure boot state during dom0 boot
  • Loading branch information
torvalds committed Jun 4, 2018
2 parents 4057ada + 83f0a7c commit 31a85cb
Show file tree
Hide file tree
Showing 12 changed files with 485 additions and 99 deletions.
114 changes: 32 additions & 82 deletions arch/x86/boot/compressed/eboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,23 +109,34 @@ void efi_char16_printk(efi_system_table_t *table, efi_char16_t *str)
}

static efi_status_t
__setup_efi_pci32(efi_pci_io_protocol_32 *pci, struct pci_setup_rom **__rom)
__setup_efi_pci(efi_pci_io_protocol_t *pci, struct pci_setup_rom **__rom)
{
struct pci_setup_rom *rom = NULL;
efi_status_t status;
unsigned long size;
uint64_t attributes;
uint64_t attributes, romsize;
void *romimage;

status = efi_early->call(pci->attributes, pci,
EfiPciIoAttributeOperationGet, 0, 0,
&attributes);
status = efi_call_proto(efi_pci_io_protocol, attributes, pci,
EfiPciIoAttributeOperationGet, 0, 0,
&attributes);
if (status != EFI_SUCCESS)
return status;

if (!pci->romimage || !pci->romsize)
/*
* Some firmware images contain EFI function pointers at the place where the
* romimage and romsize fields are supposed to be. Typically the EFI
* code is mapped at high addresses, translating to an unrealistically
* large romsize. The UEFI spec limits the size of option ROMs to 16
* MiB so we reject any ROMs over 16 MiB in size to catch this.
*/
romimage = (void *)(unsigned long)efi_table_attr(efi_pci_io_protocol,
romimage, pci);
romsize = efi_table_attr(efi_pci_io_protocol, romsize, pci);
if (!romimage || !romsize || romsize > SZ_16M)
return EFI_INVALID_PARAMETER;

size = pci->romsize + sizeof(*rom);
size = romsize + sizeof(*rom);

status = efi_call_early(allocate_pool, EFI_LOADER_DATA, size, &rom);
if (status != EFI_SUCCESS) {
Expand All @@ -141,30 +152,32 @@ __setup_efi_pci32(efi_pci_io_protocol_32 *pci, struct pci_setup_rom **__rom)
rom->pcilen = pci->romsize;
*__rom = rom;

status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16,
PCI_VENDOR_ID, 1, &(rom->vendor));
status = efi_call_proto(efi_pci_io_protocol, pci.read, pci,
EfiPciIoWidthUint16, PCI_VENDOR_ID, 1,
&rom->vendor);

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));
status = efi_call_proto(efi_pci_io_protocol, pci.read, pci,
EfiPciIoWidthUint16, PCI_DEVICE_ID, 1,
&rom->devid);

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));
status = efi_call_proto(efi_pci_io_protocol, get_location, pci,
&rom->segment, &rom->bus, &rom->device,
&rom->function);

if (status != EFI_SUCCESS)
goto free_struct;

memcpy(rom->romdata, (void *)(unsigned long)pci->romimage,
pci->romsize);
memcpy(rom->romdata, romimage, romsize);
return status;

free_struct:
Expand All @@ -176,7 +189,7 @@ static void
setup_efi_pci32(struct boot_params *params, void **pci_handle,
unsigned long size)
{
efi_pci_io_protocol_32 *pci = NULL;
efi_pci_io_protocol_t *pci = NULL;
efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID;
u32 *handles = (u32 *)(unsigned long)pci_handle;
efi_status_t status;
Expand All @@ -203,7 +216,7 @@ setup_efi_pci32(struct boot_params *params, void **pci_handle,
if (!pci)
continue;

status = __setup_efi_pci32(pci, &rom);
status = __setup_efi_pci(pci, &rom);
if (status != EFI_SUCCESS)
continue;

Expand All @@ -217,74 +230,11 @@ setup_efi_pci32(struct boot_params *params, void **pci_handle,
}
}

static efi_status_t
__setup_efi_pci64(efi_pci_io_protocol_64 *pci, struct pci_setup_rom **__rom)
{
struct pci_setup_rom *rom;
efi_status_t status;
unsigned long size;
uint64_t attributes;

status = efi_early->call(pci->attributes, pci,
EfiPciIoAttributeOperationGet, 0,
&attributes);
if (status != EFI_SUCCESS)
return status;

if (!pci->romimage || !pci->romsize)
return EFI_INVALID_PARAMETER;

size = pci->romsize + sizeof(*rom);

status = efi_call_early(allocate_pool, EFI_LOADER_DATA, size, &rom);
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);
rom->data.next = 0;
rom->pcilen = pci->romsize;
*__rom = rom;

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

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) {
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));

if (status != EFI_SUCCESS)
goto free_struct;

memcpy(rom->romdata, (void *)(unsigned long)pci->romimage,
pci->romsize);
return status;

free_struct:
efi_call_early(free_pool, rom);
return status;

}

static void
setup_efi_pci64(struct boot_params *params, void **pci_handle,
unsigned long size)
{
efi_pci_io_protocol_64 *pci = NULL;
efi_pci_io_protocol_t *pci = NULL;
efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID;
u64 *handles = (u64 *)(unsigned long)pci_handle;
efi_status_t status;
Expand All @@ -311,7 +261,7 @@ setup_efi_pci64(struct boot_params *params, void **pci_handle,
if (!pci)
continue;

status = __setup_efi_pci64(pci, &rom);
status = __setup_efi_pci(pci, &rom);
if (status != EFI_SUCCESS)
continue;

Expand Down
57 changes: 57 additions & 0 deletions arch/x86/xen/efi.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,61 @@ static efi_system_table_t __init *xen_efi_probe(void)
return &efi_systab_xen;
}

/*
* Determine whether we're in secure boot mode.
*
* Please keep the logic in sync with
* drivers/firmware/efi/libstub/secureboot.c:efi_get_secureboot().
*/
static enum efi_secureboot_mode xen_efi_get_secureboot(void)
{
static efi_guid_t efi_variable_guid = EFI_GLOBAL_VARIABLE_GUID;
static efi_guid_t shim_guid = EFI_SHIM_LOCK_GUID;
efi_status_t status;
u8 moksbstate, secboot, setupmode;
unsigned long size;

size = sizeof(secboot);
status = efi.get_variable(L"SecureBoot", &efi_variable_guid,
NULL, &size, &secboot);

if (status == EFI_NOT_FOUND)
return efi_secureboot_mode_disabled;

if (status != EFI_SUCCESS)
goto out_efi_err;

size = sizeof(setupmode);
status = efi.get_variable(L"SetupMode", &efi_variable_guid,
NULL, &size, &setupmode);

if (status != EFI_SUCCESS)
goto out_efi_err;

if (secboot == 0 || setupmode == 1)
return efi_secureboot_mode_disabled;

/* See if a user has put the shim into insecure mode. */
size = sizeof(moksbstate);
status = efi.get_variable(L"MokSBStateRT", &shim_guid,
NULL, &size, &moksbstate);

/* If it fails, we don't care why. Default to secure. */
if (status != EFI_SUCCESS)
goto secure_boot_enabled;

if (moksbstate == 1)
return efi_secureboot_mode_disabled;

secure_boot_enabled:
pr_info("UEFI Secure Boot is enabled.\n");
return efi_secureboot_mode_enabled;

out_efi_err:
pr_err("Could not determine UEFI Secure Boot status.\n");
return efi_secureboot_mode_unknown;
}

void __init xen_efi_init(void)
{
efi_system_table_t *efi_systab_xen;
Expand All @@ -129,6 +184,8 @@ void __init xen_efi_init(void)
boot_params.efi_info.efi_systab = (__u32)__pa(efi_systab_xen);
boot_params.efi_info.efi_systab_hi = (__u32)(__pa(efi_systab_xen) >> 32);

boot_params.secure_boot = xen_efi_get_secureboot();

set_bit(EFI_BOOT, &efi.flags);
set_bit(EFI_PARAVIRT, &efi.flags);
set_bit(EFI_64BIT, &efi.flags);
Expand Down
5 changes: 5 additions & 0 deletions drivers/firmware/efi/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,11 @@ config UEFI_CPER_ARM
depends on UEFI_CPER && ( ARM || ARM64 )
default y

config UEFI_CPER_X86
bool
depends on UEFI_CPER && X86
default y

config EFI_DEV_PATH_PARSER
bool
depends on ACPI
Expand Down
1 change: 1 addition & 0 deletions drivers/firmware/efi/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,4 @@ obj-$(CONFIG_ARM) += $(arm-obj-y)
obj-$(CONFIG_ARM64) += $(arm-obj-y)
obj-$(CONFIG_EFI_CAPSULE_LOADER) += capsule-loader.o
obj-$(CONFIG_UEFI_CPER_ARM) += cper-arm.o
obj-$(CONFIG_UEFI_CPER_X86) += cper-x86.o
14 changes: 10 additions & 4 deletions drivers/firmware/efi/capsule-loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,16 @@ static ssize_t efi_capsule_submit_update(struct capsule_info *cap_info)

/* Indicate capsule binary uploading is done */
cap_info->index = NO_FURTHER_WRITE_ACTION;
pr_info("Successfully upload capsule file with reboot type '%s'\n",
!cap_info->reset_type ? "RESET_COLD" :
cap_info->reset_type == 1 ? "RESET_WARM" :
"RESET_SHUTDOWN");

if (cap_info->header.flags & EFI_CAPSULE_PERSIST_ACROSS_RESET) {
pr_info("Successfully uploaded capsule file with reboot type '%s'\n",
!cap_info->reset_type ? "RESET_COLD" :
cap_info->reset_type == 1 ? "RESET_WARM" :
"RESET_SHUTDOWN");
} else {
pr_info("Successfully processed capsule file\n");
}

return 0;
}

Expand Down
6 changes: 2 additions & 4 deletions drivers/firmware/efi/cper-arm.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@
#include <acpi/ghes.h>
#include <ras/ras_event.h>

#define INDENT_SP " "

static const char * const arm_reg_ctx_strs[] = {
"AArch32 general purpose registers",
"AArch32 EL1 context registers",
Expand Down Expand Up @@ -283,7 +281,7 @@ void cper_print_proc_arm(const char *pfx,
pfx, proc->psci_state);
}

snprintf(newpfx, sizeof(newpfx), "%s%s", pfx, INDENT_SP);
snprintf(newpfx, sizeof(newpfx), "%s ", pfx);

err_info = (struct cper_arm_err_info *)(proc + 1);
for (i = 0; i < proc->err_info_num; i++) {
Expand All @@ -310,7 +308,7 @@ void cper_print_proc_arm(const char *pfx,
if (err_info->validation_bits & CPER_ARM_INFO_VALID_ERR_INFO) {
printk("%serror_info: 0x%016llx\n", newpfx,
err_info->error_info);
snprintf(infopfx, sizeof(infopfx), "%s%s", newpfx, INDENT_SP);
snprintf(infopfx, sizeof(infopfx), "%s ", newpfx);
cper_print_arm_err_info(infopfx, err_info->type,
err_info->error_info);
}
Expand Down
Loading

0 comments on commit 31a85cb

Please sign in to comment.