mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 19:21:31 -04:00
Merge branch 'efi-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull EFI updates from Ingo Molnar:
"The main changes in this cycle were:
- Transparently fall back to other poweroff method(s) if EFI poweroff
fails (and returns)
- Use separate PE/COFF section headers for the RX and RW parts of the
ARM stub loader so that the firmware can use strict mapping
permissions
- Add support for requesting the firmware to wipe RAM at warm reboot
- Increase the size of the random seed obtained from UEFI so CRNG
fast init can complete earlier
- Update the EFI framebuffer address if it points to a BAR that gets
moved by the PCI resource allocation code
- Enable "reset attack mitigation" of TPM environments: this is
enabled if the kernel is configured with
CONFIG_RESET_ATTACK_MITIGATION=y.
- Clang related fixes
- Misc cleanups, constification, refactoring, etc"
* 'efi-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
efi/bgrt: Use efi_mem_type()
efi: Move efi_mem_type() to common code
efi/reboot: Make function pointer orig_pm_power_off static
efi/random: Increase size of firmware supplied randomness
efi/libstub: Enable reset attack mitigation
firmware/efi/esrt: Constify attribute_group structures
firmware/efi: Constify attribute_group structures
firmware/dcdbas: Constify attribute_group structures
arm/efi: Split zImage code and data into separate PE/COFF sections
arm/efi: Replace open coded constants with symbolic ones
arm/efi: Remove pointless dummy .reloc section
arm/efi: Remove forbidden values from the PE/COFF header
drivers/fbdev/efifb: Allow BAR to be moved instead of claiming it
efi/reboot: Fall back to original power-off method if EFI_RESET_SHUTDOWN returns
efi/arm/arm64: Add missing assignment of efi.config_table
efi/libstub/arm64: Set -fpie when building the EFI stub
efi/libstub/arm64: Force 'hidden' visibility for section markers
efi/libstub/arm64: Use hidden attribute for struct screen_info reference
efi/arm: Don't mark ACPI reclaim memory as MEMBLOCK_NOMAP
This commit is contained in:
commit
f92e3da18b
19 changed files with 280 additions and 157 deletions
|
|
@ -534,7 +534,7 @@ static struct attribute *dcdbas_dev_attrs[] = {
|
|||
NULL
|
||||
};
|
||||
|
||||
static struct attribute_group dcdbas_attr_group = {
|
||||
static const struct attribute_group dcdbas_attr_group = {
|
||||
.attrs = dcdbas_dev_attrs,
|
||||
.bin_attrs = dcdbas_bin_attrs,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -151,6 +151,16 @@ config APPLE_PROPERTIES
|
|||
|
||||
If unsure, say Y if you have a Mac. Otherwise N.
|
||||
|
||||
config RESET_ATTACK_MITIGATION
|
||||
bool "Reset memory attack mitigation"
|
||||
depends on EFI_STUB
|
||||
help
|
||||
Request that the firmware clear the contents of RAM after a reboot
|
||||
using the TCG Platform Reset Attack Mitigation specification. This
|
||||
protects against an attacker forcibly rebooting the system while it
|
||||
still contains secrets in RAM, booting another OS and extracting the
|
||||
secrets.
|
||||
|
||||
endmenu
|
||||
|
||||
config UEFI_CPER
|
||||
|
|
|
|||
|
|
@ -145,6 +145,9 @@ static int __init uefi_init(void)
|
|||
sizeof(efi_config_table_t),
|
||||
arch_tables);
|
||||
|
||||
if (!retval)
|
||||
efi.config_table = (unsigned long)efi.systab->tables;
|
||||
|
||||
early_memunmap(config_tables, table_size);
|
||||
out:
|
||||
early_memunmap(efi.systab, sizeof(efi_system_table_t));
|
||||
|
|
@ -159,6 +162,7 @@ static __init int is_usable_memory(efi_memory_desc_t *md)
|
|||
switch (md->type) {
|
||||
case EFI_LOADER_CODE:
|
||||
case EFI_LOADER_DATA:
|
||||
case EFI_ACPI_RECLAIM_MEMORY:
|
||||
case EFI_BOOT_SERVICES_CODE:
|
||||
case EFI_BOOT_SERVICES_DATA:
|
||||
case EFI_CONVENTIONAL_MEMORY:
|
||||
|
|
@ -211,6 +215,10 @@ static __init void reserve_regions(void)
|
|||
|
||||
if (!is_usable_memory(md))
|
||||
memblock_mark_nomap(paddr, size);
|
||||
|
||||
/* keep ACPI reclaim memory intact for kexec etc. */
|
||||
if (md->type == EFI_ACPI_RECLAIM_MEMORY)
|
||||
memblock_reserve(paddr, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,26 +27,6 @@ struct bmp_header {
|
|||
u32 size;
|
||||
} __packed;
|
||||
|
||||
static bool efi_bgrt_addr_valid(u64 addr)
|
||||
{
|
||||
efi_memory_desc_t *md;
|
||||
|
||||
for_each_efi_memory_desc(md) {
|
||||
u64 size;
|
||||
u64 end;
|
||||
|
||||
if (md->type != EFI_BOOT_SERVICES_DATA)
|
||||
continue;
|
||||
|
||||
size = md->num_pages << EFI_PAGE_SHIFT;
|
||||
end = md->phys_addr + size;
|
||||
if (addr >= md->phys_addr && addr < end)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void __init efi_bgrt_init(struct acpi_table_header *table)
|
||||
{
|
||||
void *image;
|
||||
|
|
@ -85,7 +65,7 @@ void __init efi_bgrt_init(struct acpi_table_header *table)
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (!efi_bgrt_addr_valid(bgrt->image_address)) {
|
||||
if (efi_mem_type(bgrt->image_address) != EFI_BOOT_SERVICES_DATA) {
|
||||
pr_notice("Ignoring BGRT: invalid image address\n");
|
||||
goto out;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -198,7 +198,7 @@ static umode_t efi_attr_is_visible(struct kobject *kobj,
|
|||
return attr->mode;
|
||||
}
|
||||
|
||||
static struct attribute_group efi_subsys_attr_group = {
|
||||
static const struct attribute_group efi_subsys_attr_group = {
|
||||
.attrs = efi_subsys_attrs,
|
||||
.is_visible = efi_attr_is_visible,
|
||||
};
|
||||
|
|
@ -541,6 +541,7 @@ int __init efi_config_parse_tables(void *config_tables, int count, int sz,
|
|||
if (seed != NULL) {
|
||||
add_device_randomness(seed->bits, seed->size);
|
||||
early_memunmap(seed, sizeof(*seed) + size);
|
||||
pr_notice("seeding entropy pool\n");
|
||||
} else {
|
||||
pr_err("Could not map UEFI random seed!\n");
|
||||
}
|
||||
|
|
@ -809,6 +810,11 @@ char * __init efi_md_typeattr_format(char *buf, size_t size,
|
|||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
* IA64 has a funky EFI memory map that doesn't work the same way as
|
||||
* other architectures.
|
||||
*/
|
||||
#ifndef CONFIG_IA64
|
||||
/*
|
||||
* efi_mem_attributes - lookup memmap attributes for physical address
|
||||
* @phys_addr: the physical address to lookup
|
||||
|
|
@ -816,13 +822,8 @@ char * __init efi_md_typeattr_format(char *buf, size_t size,
|
|||
* Search in the EFI memory map for the region covering
|
||||
* @phys_addr. Returns the EFI memory attributes if the region
|
||||
* was found in the memory map, 0 otherwise.
|
||||
*
|
||||
* Despite being marked __weak, most architectures should *not*
|
||||
* override this function. It is __weak solely for the benefit
|
||||
* of ia64 which has a funky EFI memory map that doesn't work
|
||||
* the same way as other architectures.
|
||||
*/
|
||||
u64 __weak efi_mem_attributes(unsigned long phys_addr)
|
||||
u64 efi_mem_attributes(unsigned long phys_addr)
|
||||
{
|
||||
efi_memory_desc_t *md;
|
||||
|
||||
|
|
@ -838,6 +839,31 @@ u64 __weak efi_mem_attributes(unsigned long phys_addr)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* efi_mem_type - lookup memmap type for physical address
|
||||
* @phys_addr: the physical address to lookup
|
||||
*
|
||||
* Search in the EFI memory map for the region covering @phys_addr.
|
||||
* Returns the EFI memory type if the region was found in the memory
|
||||
* map, EFI_RESERVED_TYPE (zero) otherwise.
|
||||
*/
|
||||
int efi_mem_type(unsigned long phys_addr)
|
||||
{
|
||||
const efi_memory_desc_t *md;
|
||||
|
||||
if (!efi_enabled(EFI_MEMMAP))
|
||||
return -ENOTSUPP;
|
||||
|
||||
for_each_efi_memory_desc(md) {
|
||||
if ((md->phys_addr <= phys_addr) &&
|
||||
(phys_addr < (md->phys_addr +
|
||||
(md->num_pages << EFI_PAGE_SHIFT))))
|
||||
return md->type;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
int efi_status_to_err(efi_status_t status)
|
||||
{
|
||||
int err;
|
||||
|
|
@ -900,7 +926,7 @@ static int update_efi_random_seed(struct notifier_block *nb,
|
|||
|
||||
seed = memremap(efi.rng_seed, sizeof(*seed), MEMREMAP_WB);
|
||||
if (seed != NULL) {
|
||||
size = min(seed->size, 32U);
|
||||
size = min(seed->size, EFI_RANDOM_SEED_SIZE);
|
||||
memunmap(seed);
|
||||
} else {
|
||||
pr_err("Could not map UEFI random seed!\n");
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@ static umode_t esrt_attr_is_visible(struct kobject *kobj,
|
|||
return attr->mode;
|
||||
}
|
||||
|
||||
static struct attribute_group esrt_attr_group = {
|
||||
static const struct attribute_group esrt_attr_group = {
|
||||
.attrs = esrt_attrs,
|
||||
.is_visible = esrt_attr_is_visible,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ cflags-$(CONFIG_X86) += -m$(BITS) -D__KERNEL__ -O2 \
|
|||
-fPIC -fno-strict-aliasing -mno-red-zone \
|
||||
-mno-mmx -mno-sse
|
||||
|
||||
cflags-$(CONFIG_ARM64) := $(subst -pg,,$(KBUILD_CFLAGS))
|
||||
cflags-$(CONFIG_ARM64) := $(subst -pg,,$(KBUILD_CFLAGS)) -fpie
|
||||
cflags-$(CONFIG_ARM) := $(subst -pg,,$(KBUILD_CFLAGS)) \
|
||||
-fno-builtin -fpic -mno-single-pic-base
|
||||
|
||||
|
|
@ -30,6 +30,7 @@ OBJECT_FILES_NON_STANDARD := y
|
|||
KCOV_INSTRUMENT := n
|
||||
|
||||
lib-y := efi-stub-helper.o gop.o secureboot.o
|
||||
lib-$(CONFIG_RESET_ATTACK_MITIGATION) += tpm.o
|
||||
|
||||
# include the stub's generic dependencies from lib/ when building for ARM/arm64
|
||||
arm-deps := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c fdt_empty_tree.c fdt_sw.c sort.c
|
||||
|
|
|
|||
|
|
@ -192,6 +192,9 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table,
|
|||
goto fail_free_cmdline;
|
||||
}
|
||||
|
||||
/* Ask the firmware to clear memory on unclean shutdown */
|
||||
efi_enable_reset_attack_mitigation(sys_table);
|
||||
|
||||
secure_boot = efi_get_secureboot(sys_table);
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -9,10 +9,18 @@
|
|||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* To prevent the compiler from emitting GOT-indirected (and thus absolute)
|
||||
* references to the section markers, override their visibility as 'hidden'
|
||||
*/
|
||||
#pragma GCC visibility push(hidden)
|
||||
#include <asm/sections.h>
|
||||
#pragma GCC visibility pop
|
||||
|
||||
#include <linux/efi.h>
|
||||
#include <asm/efi.h>
|
||||
#include <asm/memory.h>
|
||||
#include <asm/sections.h>
|
||||
#include <asm/sysreg.h>
|
||||
|
||||
#include "efistub.h"
|
||||
|
|
|
|||
|
|
@ -145,8 +145,6 @@ efi_status_t efi_random_alloc(efi_system_table_t *sys_table_arg,
|
|||
return status;
|
||||
}
|
||||
|
||||
#define RANDOM_SEED_SIZE 32
|
||||
|
||||
efi_status_t efi_random_get_seed(efi_system_table_t *sys_table_arg)
|
||||
{
|
||||
efi_guid_t rng_proto = EFI_RNG_PROTOCOL_GUID;
|
||||
|
|
@ -162,25 +160,25 @@ efi_status_t efi_random_get_seed(efi_system_table_t *sys_table_arg)
|
|||
return status;
|
||||
|
||||
status = efi_call_early(allocate_pool, EFI_RUNTIME_SERVICES_DATA,
|
||||
sizeof(*seed) + RANDOM_SEED_SIZE,
|
||||
sizeof(*seed) + EFI_RANDOM_SEED_SIZE,
|
||||
(void **)&seed);
|
||||
if (status != EFI_SUCCESS)
|
||||
return status;
|
||||
|
||||
status = rng->get_rng(rng, &rng_algo_raw, RANDOM_SEED_SIZE,
|
||||
status = rng->get_rng(rng, &rng_algo_raw, EFI_RANDOM_SEED_SIZE,
|
||||
seed->bits);
|
||||
if (status == EFI_UNSUPPORTED)
|
||||
/*
|
||||
* Use whatever algorithm we have available if the raw algorithm
|
||||
* is not implemented.
|
||||
*/
|
||||
status = rng->get_rng(rng, NULL, RANDOM_SEED_SIZE,
|
||||
status = rng->get_rng(rng, NULL, EFI_RANDOM_SEED_SIZE,
|
||||
seed->bits);
|
||||
|
||||
if (status != EFI_SUCCESS)
|
||||
goto err_freepool;
|
||||
|
||||
seed->size = RANDOM_SEED_SIZE;
|
||||
seed->size = EFI_RANDOM_SEED_SIZE;
|
||||
status = efi_call_early(install_configuration_table, &rng_table_guid,
|
||||
seed);
|
||||
if (status != EFI_SUCCESS)
|
||||
|
|
|
|||
58
drivers/firmware/efi/libstub/tpm.c
Normal file
58
drivers/firmware/efi/libstub/tpm.c
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* TPM handling.
|
||||
*
|
||||
* Copyright (C) 2016 CoreOS, Inc
|
||||
* Copyright (C) 2017 Google, Inc.
|
||||
* Matthew Garrett <mjg59@google.com>
|
||||
*
|
||||
* This file is part of the Linux kernel, and is made available under the
|
||||
* terms of the GNU General Public License version 2.
|
||||
*/
|
||||
#include <linux/efi.h>
|
||||
#include <asm/efi.h>
|
||||
|
||||
#include "efistub.h"
|
||||
|
||||
static const efi_char16_t efi_MemoryOverWriteRequest_name[] = {
|
||||
'M', 'e', 'm', 'o', 'r', 'y', 'O', 'v', 'e', 'r', 'w', 'r', 'i', 't',
|
||||
'e', 'R', 'e', 'q', 'u', 'e', 's', 't', 'C', 'o', 'n', 't', 'r', 'o',
|
||||
'l', 0
|
||||
};
|
||||
|
||||
#define MEMORY_ONLY_RESET_CONTROL_GUID \
|
||||
EFI_GUID(0xe20939be, 0x32d4, 0x41be, 0xa1, 0x50, 0x89, 0x7f, 0x85, 0xd4, 0x98, 0x29)
|
||||
|
||||
#define get_efi_var(name, vendor, ...) \
|
||||
efi_call_runtime(get_variable, \
|
||||
(efi_char16_t *)(name), (efi_guid_t *)(vendor), \
|
||||
__VA_ARGS__)
|
||||
|
||||
#define set_efi_var(name, vendor, ...) \
|
||||
efi_call_runtime(set_variable, \
|
||||
(efi_char16_t *)(name), (efi_guid_t *)(vendor), \
|
||||
__VA_ARGS__)
|
||||
|
||||
/*
|
||||
* Enable reboot attack mitigation. This requests that the firmware clear the
|
||||
* RAM on next reboot before proceeding with boot, ensuring that any secrets
|
||||
* are cleared. If userland has ensured that all secrets have been removed
|
||||
* from RAM before reboot it can simply reset this variable.
|
||||
*/
|
||||
void efi_enable_reset_attack_mitigation(efi_system_table_t *sys_table_arg)
|
||||
{
|
||||
u8 val = 1;
|
||||
efi_guid_t var_guid = MEMORY_ONLY_RESET_CONTROL_GUID;
|
||||
efi_status_t status;
|
||||
unsigned long datasize = 0;
|
||||
|
||||
status = get_efi_var(efi_MemoryOverWriteRequest_name, &var_guid,
|
||||
NULL, &datasize, NULL);
|
||||
|
||||
if (status == EFI_NOT_FOUND)
|
||||
return;
|
||||
|
||||
set_efi_var(efi_MemoryOverWriteRequest_name, &var_guid,
|
||||
EFI_VARIABLE_NON_VOLATILE |
|
||||
EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||
EFI_VARIABLE_RUNTIME_ACCESS, sizeof(val), &val);
|
||||
}
|
||||
|
|
@ -5,6 +5,8 @@
|
|||
#include <linux/efi.h>
|
||||
#include <linux/reboot.h>
|
||||
|
||||
static void (*orig_pm_power_off)(void);
|
||||
|
||||
int efi_reboot_quirk_mode = -1;
|
||||
|
||||
void efi_reboot(enum reboot_mode reboot_mode, const char *__unused)
|
||||
|
|
@ -51,6 +53,12 @@ bool __weak efi_poweroff_required(void)
|
|||
static void efi_power_off(void)
|
||||
{
|
||||
efi.reset_system(EFI_RESET_SHUTDOWN, EFI_SUCCESS, 0, NULL);
|
||||
/*
|
||||
* The above call should not return, if it does fall back to
|
||||
* the original power off method (typically ACPI poweroff).
|
||||
*/
|
||||
if (orig_pm_power_off)
|
||||
orig_pm_power_off();
|
||||
}
|
||||
|
||||
static int __init efi_shutdown_init(void)
|
||||
|
|
@ -58,8 +66,10 @@ static int __init efi_shutdown_init(void)
|
|||
if (!efi_enabled(EFI_RUNTIME_SERVICES))
|
||||
return -ENODEV;
|
||||
|
||||
if (efi_poweroff_required())
|
||||
if (efi_poweroff_required()) {
|
||||
orig_pm_power_off = pm_power_off;
|
||||
pm_power_off = efi_power_off;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue