EFI updates for v6.11

- Drop support for the 'fake' EFI memory map on x86
 
 - Add an SMBIOS based tweak to the EFI stub instructing the firmware on
   x86 Macbook Pros to keep both GPUs enabled
 
 - Replace 0-sized array with flexible array in EFI memory attributes
   table handling
 
 - Drop redundant BSS clearing when booting via the native PE entrypoint
   on x86
 
 - Avoid returning EFI_SUCCESS when aborting on an out-of-memory
   condition
 
 - Cosmetic tweak for arm64 KASLR loading logic
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYIAB0WIQQQm/3uucuRGn1Dmh0wbglWLn0tXAUCZpTg5gAKCRAwbglWLn0t
 XOrOAQCpZjtjkPRPCBY+t3wUl84rOKiPr1SMHyL50Zl8udJKegD/bnwWSgX3FzLQ
 TN+xjnK7IAxEoKAEWt8lnt04cH5r3As=
 =7VWO
 -----END PGP SIGNATURE-----

Merge tag 'efi-next-for-v6.11' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi

Pull EFI updates from Ard Biesheuvel:
 "Note the removal of the EFI fake memory map support - this is believed
  to be unused and no longer worth supporting. However, we could easily
  bring it back if needed.

  With recent developments regarding confidential VMs and unaccepted
  memory, combined with kexec, creating a known inaccurate view of the
  firmware's memory map and handing it to the OS is a feature we can
  live without, hence the removal. Alternatively, I could imagine making
  this feature mutually exclusive with those confidential VM related
  features, but let's try simply removing it first.

  Summary:

   - Drop support for the 'fake' EFI memory map on x86

   - Add an SMBIOS based tweak to the EFI stub instructing the firmware
     on x86 Macbook Pros to keep both GPUs enabled

   - Replace 0-sized array with flexible array in EFI memory attributes
     table handling

   - Drop redundant BSS clearing when booting via the native PE
     entrypoint on x86

   - Avoid returning EFI_SUCCESS when aborting on an out-of-memory
     condition

   - Cosmetic tweak for arm64 KASLR loading logic"

* tag 'efi-next-for-v6.11' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi:
  efi: Replace efi_memory_attributes_table_t 0-sized array with flexible array
  efi: Rename efi_early_memdesc_ptr() to efi_memdesc_ptr()
  arm64/efistub: Clean up KASLR logic
  x86/efistub: Drop redundant clearing of BSS
  x86/efistub: Avoid returning EFI_SUCCESS on error
  x86/efistub: Call Apple set_os protocol on dual GPU Intel Macs
  x86/efistub: Enable SMBIOS protocol handling for x86
  efistub/smbios: Simplify SMBIOS enumeration API
  x86/efi: Drop support for fake EFI memory maps
This commit is contained in:
Linus Torvalds 2024-07-16 12:22:07 -07:00
commit e55037c879
20 changed files with 144 additions and 354 deletions

View File

@ -1435,27 +1435,6 @@
you are really sure that your UEFI does sane gc and
fulfills the spec otherwise your board may brick.
efi_fake_mem= nn[KMG]@ss[KMG]:aa[,nn[KMG]@ss[KMG]:aa,..] [EFI,X86,EARLY]
Add arbitrary attribute to specific memory range by
updating original EFI memory map.
Region of memory which aa attribute is added to is
from ss to ss+nn.
If efi_fake_mem=2G@4G:0x10000,2G@0x10a0000000:0x10000
is specified, EFI_MEMORY_MORE_RELIABLE(0x10000)
attribute is added to range 0x100000000-0x180000000 and
0x10a0000000-0x1120000000.
If efi_fake_mem=8G@9G:0x40000 is specified, the
EFI_MEMORY_SP(0x40000) attribute is added to
range 0x240000000-0x43fffffff.
Using this parameter you can do debugging of EFI memmap
related features. For example, you can do debugging of
Address Range Mirroring feature even if your box
doesn't support it, or mark specific memory as
"soft reserved".
efivar_ssdt= [EFI; X86] Name of an EFI variable that contains an SSDT
that is to be dynamically loaded by Linux. If there are
multiple variables with the same name but with different

View File

@ -2045,26 +2045,6 @@ config EFI_MIXED
If unsure, say N.
config EFI_FAKE_MEMMAP
bool "Enable EFI fake memory map"
depends on EFI
help
Saying Y here will enable "efi_fake_mem" boot option. By specifying
this parameter, you can add arbitrary attribute to specific memory
range by updating original (firmware provided) EFI memmap. This is
useful for debugging of EFI memmap related feature, e.g., Address
Range Mirroring feature.
config EFI_MAX_FAKE_MEM
int "maximum allowable number of ranges in efi_fake_mem boot option"
depends on EFI_FAKE_MEMMAP
range 1 128
default 8
help
Maximum allowable number of ranges in efi_fake_mem boot option.
Ranges can be set up to this value using comma-separated list.
The default value is 8.
config EFI_RUNTIME_MAP
bool "Export EFI runtime maps to sysfs" if EXPERT
depends on EFI

View File

@ -119,13 +119,8 @@ char *skip_spaces(const char *str)
#include "../../../../lib/ctype.c"
#include "../../../../lib/cmdline.c"
enum parse_mode {
PARSE_MEMMAP,
PARSE_EFI,
};
static int
parse_memmap(char *p, u64 *start, u64 *size, enum parse_mode mode)
parse_memmap(char *p, u64 *start, u64 *size)
{
char *oldp;
@ -148,29 +143,11 @@ parse_memmap(char *p, u64 *start, u64 *size, enum parse_mode mode)
*start = memparse(p + 1, &p);
return 0;
case '@':
if (mode == PARSE_MEMMAP) {
/*
* memmap=nn@ss specifies usable region, should
* be skipped
*/
*size = 0;
} else {
u64 flags;
/*
* efi_fake_mem=nn@ss:attr the attr specifies
* flags that might imply a soft-reservation.
*/
*start = memparse(p + 1, &p);
if (p && *p == ':') {
p++;
if (kstrtoull(p, 0, &flags) < 0)
*size = 0;
else if (flags & EFI_MEMORY_SP)
return 0;
}
*size = 0;
}
/*
* memmap=nn@ss specifies usable region, should
* be skipped
*/
*size = 0;
fallthrough;
default:
/*
@ -185,7 +162,7 @@ parse_memmap(char *p, u64 *start, u64 *size, enum parse_mode mode)
return -EINVAL;
}
static void mem_avoid_memmap(enum parse_mode mode, char *str)
static void mem_avoid_memmap(char *str)
{
static int i;
@ -200,7 +177,7 @@ static void mem_avoid_memmap(enum parse_mode mode, char *str)
if (k)
*k++ = 0;
rc = parse_memmap(str, &start, &size, mode);
rc = parse_memmap(str, &start, &size);
if (rc < 0)
break;
str = k;
@ -281,7 +258,7 @@ static void handle_mem_options(void)
break;
if (!strcmp(param, "memmap")) {
mem_avoid_memmap(PARSE_MEMMAP, val);
mem_avoid_memmap(val);
} else if (IS_ENABLED(CONFIG_X86_64) && strstr(param, "hugepages")) {
parse_gb_huge_pages(param, val);
} else if (!strcmp(param, "mem")) {
@ -295,8 +272,6 @@ static void handle_mem_options(void)
if (mem_size < mem_limit)
mem_limit = mem_size;
} else if (!strcmp(param, "efi_fake_mem")) {
mem_avoid_memmap(PARSE_EFI, val);
}
}

View File

@ -229,7 +229,8 @@ static inline bool efi_is_native(void)
static inline void *efi64_zero_upper(void *p)
{
((u32 *)p)[1] = 0;
if (p)
((u32 *)p)[1] = 0;
return p;
}
@ -315,6 +316,10 @@ static inline u32 efi64_convert_status(efi_status_t status)
#define __efi64_argmap_clear_memory_attributes(protocol, phys, size, flags) \
((protocol), __efi64_split(phys), __efi64_split(size), __efi64_split(flags))
/* EFI SMBIOS protocol */
#define __efi64_argmap_get_next(protocol, smbioshandle, type, record, phandle) \
((protocol), (smbioshandle), (type), efi64_zero_upper(record), \
efi64_zero_upper(phandle))
/*
* The macros below handle the plumbing for the argument mapping. To add a
* mapping for a specific EFI method, simply define a macro
@ -384,23 +389,8 @@ static inline void efi_reserve_boot_services(void)
}
#endif /* CONFIG_EFI */
#ifdef CONFIG_EFI_FAKE_MEMMAP
extern void __init efi_fake_memmap_early(void);
extern void __init efi_fake_memmap(void);
#else
static inline void efi_fake_memmap_early(void)
{
}
static inline void efi_fake_memmap(void)
{
}
#endif
extern int __init efi_memmap_alloc(unsigned int num_entries,
struct efi_memory_map_data *data);
extern void __efi_memmap_free(u64 phys, unsigned long size,
unsigned long flags);
extern int __init efi_memmap_install(struct efi_memory_map_data *data);
extern int __init efi_memmap_split_count(efi_memory_desc_t *md,

View File

@ -997,7 +997,6 @@ void __init setup_arch(char **cmdline_p)
mem_encrypt_setup_arch();
cc_random_init();
efi_fake_memmap();
efi_find_mirror();
efi_esrt_init();
efi_mokvar_table_init();

View File

@ -5,5 +5,4 @@ GCOV_PROFILE := n
obj-$(CONFIG_EFI) += memmap.o quirks.o efi.o efi_$(BITS).o \
efi_stub_$(BITS).o
obj-$(CONFIG_EFI_MIXED) += efi_thunk_$(BITS).o
obj-$(CONFIG_EFI_FAKE_MEMMAP) += fake_mem.o
obj-$(CONFIG_EFI_RUNTIME_MAP) += runtime-map.o

View File

@ -226,8 +226,6 @@ int __init efi_memblock_x86_reserve_range(void)
if (add_efi_memmap || do_efi_soft_reserve())
do_add_efi_memmap();
efi_fake_memmap_early();
WARN(efi.memmap.desc_version != 1,
"Unexpected EFI_MEMORY_DESCRIPTOR version %ld",
efi.memmap.desc_version);

View File

@ -1,197 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* fake_mem.c
*
* Copyright (C) 2015 FUJITSU LIMITED
* Author: Taku Izumi <izumi.taku@jp.fujitsu.com>
*
* This code introduces new boot option named "efi_fake_mem"
* By specifying this parameter, you can add arbitrary attribute to
* specific memory range by updating original (firmware provided) EFI
* memmap.
*/
#include <linux/kernel.h>
#include <linux/efi.h>
#include <linux/init.h>
#include <linux/memblock.h>
#include <linux/types.h>
#include <linux/sort.h>
#include <asm/e820/api.h>
#include <asm/efi.h>
#define EFI_MAX_FAKEMEM CONFIG_EFI_MAX_FAKE_MEM
static struct efi_mem_range efi_fake_mems[EFI_MAX_FAKEMEM];
static int nr_fake_mem;
static int __init cmp_fake_mem(const void *x1, const void *x2)
{
const struct efi_mem_range *m1 = x1;
const struct efi_mem_range *m2 = x2;
if (m1->range.start < m2->range.start)
return -1;
if (m1->range.start > m2->range.start)
return 1;
return 0;
}
static void __init efi_fake_range(struct efi_mem_range *efi_range)
{
struct efi_memory_map_data data = { 0 };
int new_nr_map = efi.memmap.nr_map;
efi_memory_desc_t *md;
void *new_memmap;
/* count up the number of EFI memory descriptor */
for_each_efi_memory_desc(md)
new_nr_map += efi_memmap_split_count(md, &efi_range->range);
/* allocate memory for new EFI memmap */
if (efi_memmap_alloc(new_nr_map, &data) != 0)
return;
/* create new EFI memmap */
new_memmap = early_memremap(data.phys_map, data.size);
if (!new_memmap) {
__efi_memmap_free(data.phys_map, data.size, data.flags);
return;
}
efi_memmap_insert(&efi.memmap, new_memmap, efi_range);
/* swap into new EFI memmap */
early_memunmap(new_memmap, data.size);
efi_memmap_install(&data);
}
void __init efi_fake_memmap(void)
{
int i;
if (!efi_enabled(EFI_MEMMAP) || !nr_fake_mem)
return;
for (i = 0; i < nr_fake_mem; i++)
efi_fake_range(&efi_fake_mems[i]);
/* print new EFI memmap */
efi_print_memmap();
}
static int __init setup_fake_mem(char *p)
{
u64 start = 0, mem_size = 0, attribute = 0;
int i;
if (!p)
return -EINVAL;
while (*p != '\0') {
mem_size = memparse(p, &p);
if (*p == '@')
start = memparse(p+1, &p);
else
break;
if (*p == ':')
attribute = simple_strtoull(p+1, &p, 0);
else
break;
if (nr_fake_mem >= EFI_MAX_FAKEMEM)
break;
efi_fake_mems[nr_fake_mem].range.start = start;
efi_fake_mems[nr_fake_mem].range.end = start + mem_size - 1;
efi_fake_mems[nr_fake_mem].attribute = attribute;
nr_fake_mem++;
if (*p == ',')
p++;
}
sort(efi_fake_mems, nr_fake_mem, sizeof(struct efi_mem_range),
cmp_fake_mem, NULL);
for (i = 0; i < nr_fake_mem; i++)
pr_info("efi_fake_mem: add attr=0x%016llx to [mem 0x%016llx-0x%016llx]",
efi_fake_mems[i].attribute, efi_fake_mems[i].range.start,
efi_fake_mems[i].range.end);
return *p == '\0' ? 0 : -EINVAL;
}
early_param("efi_fake_mem", setup_fake_mem);
void __init efi_fake_memmap_early(void)
{
int i;
/*
* The late efi_fake_mem() call can handle all requests if
* EFI_MEMORY_SP support is disabled.
*/
if (!efi_soft_reserve_enabled())
return;
if (!efi_enabled(EFI_MEMMAP) || !nr_fake_mem)
return;
/*
* Given that efi_fake_memmap() needs to perform memblock
* allocations it needs to run after e820__memblock_setup().
* However, if efi_fake_mem specifies EFI_MEMORY_SP for a given
* address range that potentially needs to mark the memory as
* reserved prior to e820__memblock_setup(). Update e820
* directly if EFI_MEMORY_SP is specified for an
* EFI_CONVENTIONAL_MEMORY descriptor.
*/
for (i = 0; i < nr_fake_mem; i++) {
struct efi_mem_range *mem = &efi_fake_mems[i];
efi_memory_desc_t *md;
u64 m_start, m_end;
if ((mem->attribute & EFI_MEMORY_SP) == 0)
continue;
m_start = mem->range.start;
m_end = mem->range.end;
for_each_efi_memory_desc(md) {
u64 start, end, size;
if (md->type != EFI_CONVENTIONAL_MEMORY)
continue;
start = md->phys_addr;
end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - 1;
if (m_start <= end && m_end >= start)
/* fake range overlaps descriptor */;
else
continue;
/*
* Trim the boundary of the e820 update to the
* descriptor in case the fake range overlaps
* !EFI_CONVENTIONAL_MEMORY
*/
start = max(start, m_start);
end = min(end, m_end);
size = end - start + 1;
if (end <= start)
continue;
/*
* Ensure each efi_fake_mem instance results in
* a unique e820 resource
*/
e820__range_remove(start, size, E820_TYPE_RAM, 1);
e820__range_add(start, size, E820_TYPE_SOFT_RESERVED);
e820__update_table(e820_table);
}
}
}

View File

@ -30,6 +30,7 @@ static phys_addr_t __init __efi_memmap_alloc_late(unsigned long size)
return PFN_PHYS(page_to_pfn(p));
}
static
void __init __efi_memmap_free(u64 phys, unsigned long size, unsigned long flags)
{
if (flags & EFI_MEMMAP_MEMBLOCK) {

View File

@ -76,7 +76,7 @@ lib-$(CONFIG_EFI_GENERIC_STUB) += efi-stub.o string.o intrinsics.o systable.o \
lib-$(CONFIG_ARM) += arm32-stub.o
lib-$(CONFIG_ARM64) += kaslr.o arm64.o arm64-stub.o smbios.o
lib-$(CONFIG_X86) += x86-stub.o
lib-$(CONFIG_X86) += x86-stub.o smbios.o
lib-$(CONFIG_X86_64) += x86-5lvl.o
lib-$(CONFIG_RISCV) += kaslr.o riscv.o riscv-stub.o
lib-$(CONFIG_LOONGARCH) += loongarch.o loongarch-stub.o

View File

@ -21,7 +21,6 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
efi_loaded_image_t *image,
efi_handle_t image_handle)
{
efi_status_t status;
unsigned long kernel_size, kernel_codesize, kernel_memsize;
if (image->image_base != _text) {
@ -39,15 +38,9 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
*reserve_size = kernel_memsize;
*image_addr = (unsigned long)_text;
status = efi_kaslr_relocate_kernel(image_addr,
reserve_addr, reserve_size,
kernel_size, kernel_codesize,
kernel_memsize,
efi_kaslr_get_phys_seed(image_handle));
if (status != EFI_SUCCESS)
return status;
return EFI_SUCCESS;
return efi_kaslr_relocate_kernel(image_addr, reserve_addr, reserve_size,
kernel_size, kernel_codesize, kernel_memsize,
efi_kaslr_get_phys_seed(image_handle));
}
asmlinkage void primary_entry(void);

View File

@ -39,8 +39,7 @@ static bool system_needs_vamap(void)
static char const emag[] = "eMAG";
default:
version = efi_get_smbios_string(&record->header, 4,
processor_version);
version = efi_get_smbios_string(record, processor_version);
if (!version || (strncmp(version, altra, sizeof(altra) - 1) &&
strncmp(version, emag, sizeof(emag) - 1)))
break;

View File

@ -1204,14 +1204,13 @@ struct efi_smbios_type4_record {
u16 thread_enabled;
};
#define efi_get_smbios_string(__record, __type, __name) ({ \
int off = offsetof(struct efi_smbios_type ## __type ## _record, \
__name); \
__efi_get_smbios_string((__record), __type, off); \
#define efi_get_smbios_string(__record, __field) ({ \
__typeof__(__record) __rec = __record; \
__efi_get_smbios_string(&__rec->header, &__rec->__field); \
})
const u8 *__efi_get_smbios_string(const struct efi_smbios_record *record,
u8 type, int offset);
const u8 *offset);
void efi_remap_image(unsigned long image_base, unsigned alloc_size,
unsigned long code_size);

View File

@ -18,8 +18,6 @@
*/
u32 efi_kaslr_get_phys_seed(efi_handle_t image_handle)
{
efi_status_t status;
u32 phys_seed;
efi_guid_t li_fixed_proto = LINUX_EFI_LOADED_IMAGE_FIXED_GUID;
void *p;
@ -32,18 +30,20 @@ u32 efi_kaslr_get_phys_seed(efi_handle_t image_handle)
&li_fixed_proto, &p) == EFI_SUCCESS) {
efi_info("Image placement fixed by loader\n");
} else {
efi_status_t status;
u32 phys_seed;
status = efi_get_random_bytes(sizeof(phys_seed),
(u8 *)&phys_seed);
if (status == EFI_SUCCESS) {
if (status == EFI_SUCCESS)
return phys_seed;
} else if (status == EFI_NOT_FOUND) {
if (status == EFI_NOT_FOUND)
efi_info("EFI_RNG_PROTOCOL unavailable\n");
efi_nokaslr = true;
} else if (status != EFI_SUCCESS) {
efi_err("efi_get_random_bytes() failed (0x%lx)\n",
status);
efi_nokaslr = true;
}
else
efi_err("efi_get_random_bytes() failed (0x%lx)\n", status);
efi_nokaslr = true;
}
return 0;

View File

@ -48,7 +48,7 @@ efi_status_t efi_low_alloc_above(unsigned long size, unsigned long align,
unsigned long m = (unsigned long)map->map;
u64 start, end;
desc = efi_early_memdesc_ptr(m, map->desc_size, i);
desc = efi_memdesc_ptr(m, map->desc_size, i);
if (desc->type != EFI_CONVENTIONAL_MEMORY)
continue;

View File

@ -6,20 +6,31 @@
#include "efistub.h"
typedef struct efi_smbios_protocol efi_smbios_protocol_t;
typedef union efi_smbios_protocol efi_smbios_protocol_t;
struct efi_smbios_protocol {
efi_status_t (__efiapi *add)(efi_smbios_protocol_t *, efi_handle_t,
u16 *, struct efi_smbios_record *);
efi_status_t (__efiapi *update_string)(efi_smbios_protocol_t *, u16 *,
unsigned long *, u8 *);
efi_status_t (__efiapi *remove)(efi_smbios_protocol_t *, u16);
efi_status_t (__efiapi *get_next)(efi_smbios_protocol_t *, u16 *, u8 *,
struct efi_smbios_record **,
efi_handle_t *);
union efi_smbios_protocol {
struct {
efi_status_t (__efiapi *add)(efi_smbios_protocol_t *, efi_handle_t,
u16 *, struct efi_smbios_record *);
efi_status_t (__efiapi *update_string)(efi_smbios_protocol_t *, u16 *,
unsigned long *, u8 *);
efi_status_t (__efiapi *remove)(efi_smbios_protocol_t *, u16);
efi_status_t (__efiapi *get_next)(efi_smbios_protocol_t *, u16 *, u8 *,
struct efi_smbios_record **,
efi_handle_t *);
u8 major_version;
u8 minor_version;
u8 major_version;
u8 minor_version;
};
struct {
u32 add;
u32 update_string;
u32 remove;
u32 get_next;
u8 major_version;
u8 minor_version;
} mixed_mode;
};
const struct efi_smbios_record *efi_get_smbios_record(u8 type)
@ -38,7 +49,7 @@ const struct efi_smbios_record *efi_get_smbios_record(u8 type)
}
const u8 *__efi_get_smbios_string(const struct efi_smbios_record *record,
u8 type, int offset)
const u8 *offset)
{
const u8 *strtable;
@ -46,7 +57,7 @@ const u8 *__efi_get_smbios_string(const struct efi_smbios_record *record,
return NULL;
strtable = (u8 *)record + record->length;
for (int i = 1; i < ((u8 *)record)[offset]; i++) {
for (int i = 1; i < *offset; i++) {
int len = strlen(strtable);
if (!len)

View File

@ -29,7 +29,7 @@ efi_status_t allocate_unaccepted_bitmap(__u32 nr_desc,
efi_memory_desc_t *d;
unsigned long m = (unsigned long)map->map;
d = efi_early_memdesc_ptr(m, map->desc_size, i);
d = efi_memdesc_ptr(m, map->desc_size, i);
if (d->type != EFI_UNACCEPTED_MEMORY)
continue;

View File

@ -225,6 +225,68 @@ static void retrieve_apple_device_properties(struct boot_params *boot_params)
}
}
static bool apple_match_product_name(void)
{
static const char type1_product_matches[][15] = {
"MacBookPro11,3",
"MacBookPro11,5",
"MacBookPro13,3",
"MacBookPro14,3",
"MacBookPro15,1",
"MacBookPro15,3",
"MacBookPro16,1",
"MacBookPro16,4",
};
const struct efi_smbios_type1_record *record;
const u8 *product;
record = (struct efi_smbios_type1_record *)efi_get_smbios_record(1);
if (!record)
return false;
product = efi_get_smbios_string(record, product_name);
if (!product)
return false;
for (int i = 0; i < ARRAY_SIZE(type1_product_matches); i++) {
if (!strcmp(product, type1_product_matches[i]))
return true;
}
return false;
}
static void apple_set_os(void)
{
struct {
unsigned long version;
efi_status_t (__efiapi *set_os_version)(const char *);
efi_status_t (__efiapi *set_os_vendor)(const char *);
} *set_os;
efi_status_t status;
if (!efi_is_64bit() || !apple_match_product_name())
return;
status = efi_bs_call(locate_protocol, &APPLE_SET_OS_PROTOCOL_GUID, NULL,
(void **)&set_os);
if (status != EFI_SUCCESS)
return;
if (set_os->version >= 2) {
status = set_os->set_os_vendor("Apple Inc.");
if (status != EFI_SUCCESS)
efi_err("Failed to set OS vendor via apple_set_os\n");
}
if (set_os->version > 0) {
/* The version being set doesn't seem to matter */
status = set_os->set_os_version("Mac OS X 10.9");
if (status != EFI_SUCCESS)
efi_err("Failed to set OS version via apple_set_os\n");
}
}
efi_status_t efi_adjust_memory_range_protection(unsigned long start,
unsigned long size)
{
@ -335,9 +397,12 @@ static const efi_char16_t apple[] = L"Apple";
static void setup_quirks(struct boot_params *boot_params)
{
if (IS_ENABLED(CONFIG_APPLE_PROPERTIES) &&
!memcmp(efistub_fw_vendor(), apple, sizeof(apple)))
retrieve_apple_device_properties(boot_params);
if (!memcmp(efistub_fw_vendor(), apple, sizeof(apple))) {
if (IS_ENABLED(CONFIG_APPLE_PROPERTIES))
retrieve_apple_device_properties(boot_params);
apple_set_os();
}
}
/*
@ -476,9 +541,6 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
efi_status_t status;
char *cmdline_ptr;
if (efi_is_native())
memset(_bss, 0, _ebss - _bss);
efi_system_table = sys_table_arg;
/* Check if we were booted by the EFI firmware */
@ -501,16 +563,13 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
/* Convert unicode cmdline to ascii */
cmdline_ptr = efi_convert_cmdline(image, &options_size);
if (!cmdline_ptr)
goto fail;
efi_exit(handle, EFI_OUT_OF_RESOURCES);
efi_set_u64_split((unsigned long)cmdline_ptr, &hdr->cmd_line_ptr,
&boot_params.ext_cmd_line_ptr);
efi_stub_entry(handle, sys_table_arg, &boot_params);
/* not reached */
fail:
efi_exit(handle, status);
}
static void add_e820ext(struct boot_params *params,
@ -555,7 +614,7 @@ setup_e820(struct boot_params *params, struct setup_data *e820ext, u32 e820ext_s
m |= (u64)efi->efi_memmap_hi << 32;
#endif
d = efi_early_memdesc_ptr(m, efi->efi_memdesc_size, i);
d = efi_memdesc_ptr(m, efi->efi_memdesc_size, i);
switch (d->type) {
case EFI_RESERVED_TYPE:
case EFI_RUNTIME_SERVICES_CODE:
@ -781,7 +840,7 @@ static const char *cmdline_memmap_override;
static efi_status_t parse_options(const char *cmdline)
{
static const char opts[][14] = {
"mem=", "memmap=", "efi_fake_mem=", "hugepages="
"mem=", "memmap=", "hugepages="
};
for (int i = 0; i < ARRAY_SIZE(opts); i++) {

View File

@ -164,7 +164,7 @@ int __init efi_memattr_apply_permissions(struct mm_struct *mm,
bool valid;
char buf[64];
valid = entry_is_valid((void *)tbl->entry + i * tbl->desc_size,
valid = entry_is_valid(efi_memdesc_ptr(tbl->entry, tbl->desc_size, i),
&md);
size = md.num_pages << EFI_PAGE_SHIFT;
if (efi_enabled(EFI_DBG) || !valid)

View File

@ -74,10 +74,10 @@ typedef void *efi_handle_t;
*/
typedef guid_t efi_guid_t __aligned(__alignof__(u32));
#define EFI_GUID(a, b, c, d...) (efi_guid_t){ { \
#define EFI_GUID(a, b, c, d...) ((efi_guid_t){ { \
(a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, \
(b) & 0xff, ((b) >> 8) & 0xff, \
(c) & 0xff, ((c) >> 8) & 0xff, d } }
(c) & 0xff, ((c) >> 8) & 0xff, d } })
/*
* Generic EFI table header
@ -385,6 +385,7 @@ void efi_native_runtime_setup(void);
#define EFI_MEMORY_ATTRIBUTES_TABLE_GUID EFI_GUID(0xdcfa911d, 0x26eb, 0x469f, 0xa2, 0x20, 0x38, 0xb7, 0xdc, 0x46, 0x12, 0x20)
#define EFI_CONSOLE_OUT_DEVICE_GUID EFI_GUID(0xd3b36f2c, 0xd551, 0x11d4, 0x9a, 0x46, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
#define APPLE_PROPERTIES_PROTOCOL_GUID EFI_GUID(0x91bd12fe, 0xf6c3, 0x44fb, 0xa5, 0xb7, 0x51, 0x22, 0xab, 0x30, 0x3a, 0xe0)
#define APPLE_SET_OS_PROTOCOL_GUID EFI_GUID(0xc5c5da95, 0x7d5c, 0x45e6, 0xb2, 0xf1, 0x3f, 0xd5, 0x2b, 0xb1, 0x00, 0x77)
#define EFI_TCG2_PROTOCOL_GUID EFI_GUID(0x607f766c, 0x7455, 0x42be, 0x93, 0x0b, 0xe4, 0xd7, 0x6d, 0xb2, 0x72, 0x0f)
#define EFI_TCG2_FINAL_EVENTS_TABLE_GUID EFI_GUID(0x1e2ed096, 0x30e2, 0x4254, 0xbd, 0x89, 0x86, 0x3b, 0xbe, 0xf8, 0x23, 0x25)
#define EFI_LOAD_FILE_PROTOCOL_GUID EFI_GUID(0x56ec3091, 0x954c, 0x11d2, 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
@ -607,7 +608,11 @@ typedef struct {
u32 num_entries;
u32 desc_size;
u32 flags;
efi_memory_desc_t entry[0];
/*
* There are @num_entries following, each of size @desc_size bytes,
* including an efi_memory_desc_t header. See efi_memdesc_ptr().
*/
efi_memory_desc_t entry[];
} efi_memory_attributes_table_t;
typedef struct {
@ -783,7 +788,7 @@ extern int efi_memattr_apply_permissions(struct mm_struct *mm,
efi_memattr_perm_setter fn);
/*
* efi_early_memdesc_ptr - get the n-th EFI memmap descriptor
* efi_memdesc_ptr - get the n-th EFI memmap descriptor
* @map: the start of efi memmap
* @desc_size: the size of space for each EFI memmap descriptor
* @n: the index of efi memmap descriptor
@ -801,7 +806,7 @@ extern int efi_memattr_apply_permissions(struct mm_struct *mm,
* during bootup since for_each_efi_memory_desc_xxx() is available after the
* kernel initializes the EFI subsystem to set up struct efi_memory_map.
*/
#define efi_early_memdesc_ptr(map, desc_size, n) \
#define efi_memdesc_ptr(map, desc_size, n) \
(efi_memory_desc_t *)((void *)(map) + ((n) * (desc_size)))
/* Iterate through an efi_memory_map */