Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 31a85cb3 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'efi-core-for-linus' of git://git.kernel.org/pub/scm/linux/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
parents 4057adaf 83f0a7c7
Loading
Loading
Loading
Loading
+32 −82
Original line number Diff line number Diff line
@@ -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,
	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) {
@@ -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:
@@ -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;
@@ -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;

@@ -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;
@@ -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;

+57 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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);
+5 −0
Original line number Diff line number Diff line
@@ -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
+1 −0
Original line number Diff line number Diff line
@@ -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
+10 −4
Original line number Diff line number Diff line
@@ -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",

	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;
}

Loading