Skip to content

Commit 06c0bd9

Browse files
committed
efi: Clean up config_parse_tables()
config_parse_tables() is a jumble of pointer arithmetic, due to the fact that on x86, we may be dealing with firmware whose native word size differs from the kernel's. This is not a concern on other architectures, and doesn't quite justify the state of the code, so let's clean it up by adding a non-x86 code path, constifying statically allocated tables and replacing preprocessor conditionals with IS_ENABLED() checks. Tested-by: Tony Luck <[email protected]> # arch/ia64 Signed-off-by: Ard Biesheuvel <[email protected]>
1 parent 3a0701d commit 06c0bd9

File tree

5 files changed

+32
-34
lines changed

5 files changed

+32
-34
lines changed

arch/ia64/kernel/efi.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ unsigned long __initdata esi_phys = EFI_INVALID_TABLE_ADDR;
5656
unsigned long hcdp_phys = EFI_INVALID_TABLE_ADDR;
5757
unsigned long sal_systab_phys = EFI_INVALID_TABLE_ADDR;
5858

59-
static __initdata efi_config_table_type_t arch_tables[] = {
59+
static const efi_config_table_type_t arch_tables[] __initconst = {
6060
{ESI_TABLE_GUID, "ESI", &esi_phys},
6161
{HCDP_TABLE_GUID, "HCDP", &hcdp_phys},
6262
{MPS_TABLE_GUID, "MPS", &mps_phys},
@@ -533,7 +533,6 @@ efi_init (void)
533533

534534
if (efi_config_parse_tables(__va(efi_systab->tables),
535535
efi_systab->nr_tables,
536-
sizeof(efi_config_table_t),
537536
arch_tables) != 0)
538537
return;
539538

arch/x86/platform/efi/efi.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ static u64 efi_systab_phys __initdata;
6060
static unsigned long prop_phys = EFI_INVALID_TABLE_ADDR;
6161
static unsigned long uga_phys = EFI_INVALID_TABLE_ADDR;
6262

63-
static efi_config_table_type_t arch_tables[] __initdata = {
63+
static const efi_config_table_type_t arch_tables[] __initconst = {
6464
{EFI_PROPERTIES_TABLE_GUID, "PROP", &prop_phys},
6565
{UGA_IO_PROTOCOL_GUID, "UGA", &uga_phys},
6666
#ifdef CONFIG_X86_UV
@@ -431,7 +431,7 @@ static int __init efi_systab_init(u64 phys)
431431
return 0;
432432
}
433433

434-
static int __init efi_config_init(efi_config_table_type_t *arch_tables)
434+
static int __init efi_config_init(const efi_config_table_type_t *arch_tables)
435435
{
436436
void *config_tables;
437437
int sz, ret;
@@ -454,7 +454,7 @@ static int __init efi_config_init(efi_config_table_type_t *arch_tables)
454454
return -ENOMEM;
455455
}
456456

457-
ret = efi_config_parse_tables(config_tables, efi.systab->nr_tables, sz,
457+
ret = efi_config_parse_tables(config_tables, efi.systab->nr_tables,
458458
arch_tables);
459459

460460
early_memunmap(config_tables, efi.systab->nr_tables * sz);

drivers/firmware/efi/arm-init.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ static phys_addr_t efi_to_phys(unsigned long addr)
5555

5656
static __initdata unsigned long screen_info_table = EFI_INVALID_TABLE_ADDR;
5757

58-
static __initdata efi_config_table_type_t arch_tables[] = {
58+
static const efi_config_table_type_t arch_tables[] __initconst = {
5959
{LINUX_EFI_ARM_SCREEN_INFO_TABLE_GUID, NULL, &screen_info_table},
6060
{NULL_GUID, NULL, NULL}
6161
};
@@ -85,7 +85,7 @@ static void __init init_screen_info(void)
8585

8686
static int __init uefi_init(void)
8787
{
88-
void *config_tables;
88+
efi_config_table_t *config_tables;
8989
size_t table_size;
9090
int retval;
9191

@@ -118,7 +118,6 @@ static int __init uefi_init(void)
118118
goto out;
119119
}
120120
retval = efi_config_parse_tables(config_tables, efi.systab->nr_tables,
121-
sizeof(efi_config_table_t),
122121
arch_tables);
123122

124123
if (!retval)

drivers/firmware/efi/efi.c

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ void __init efi_mem_reserve(phys_addr_t addr, u64 size)
460460
efi_arch_mem_reserve(addr, size);
461461
}
462462

463-
static __initdata efi_config_table_type_t common_tables[] = {
463+
static const efi_config_table_type_t common_tables[] __initconst = {
464464
{ACPI_20_TABLE_GUID, "ACPI 2.0", &efi.acpi20},
465465
{ACPI_TABLE_GUID, "ACPI", &efi.acpi},
466466
{SMBIOS_TABLE_GUID, "SMBIOS", &efi.smbios},
@@ -477,9 +477,9 @@ static __initdata efi_config_table_type_t common_tables[] = {
477477
{NULL_GUID, NULL, NULL},
478478
};
479479

480-
static __init int match_config_table(efi_guid_t *guid,
480+
static __init int match_config_table(const efi_guid_t *guid,
481481
unsigned long table,
482-
efi_config_table_type_t *table_types)
482+
const efi_config_table_type_t *table_types)
483483
{
484484
int i;
485485

@@ -498,39 +498,38 @@ static __init int match_config_table(efi_guid_t *guid,
498498
return 0;
499499
}
500500

501-
int __init efi_config_parse_tables(void *config_tables, int count, int sz,
502-
efi_config_table_type_t *arch_tables)
501+
int __init efi_config_parse_tables(const efi_config_table_t *config_tables,
502+
int count,
503+
const efi_config_table_type_t *arch_tables)
503504
{
504-
void *tablep;
505+
const efi_config_table_64_t *tbl64 = (void *)config_tables;
506+
const efi_config_table_32_t *tbl32 = (void *)config_tables;
507+
const efi_guid_t *guid;
508+
unsigned long table;
505509
int i;
506510

507-
tablep = config_tables;
508511
pr_info("");
509512
for (i = 0; i < count; i++) {
510-
efi_guid_t guid;
511-
unsigned long table;
512-
513-
if (efi_enabled(EFI_64BIT)) {
514-
u64 table64;
515-
guid = ((efi_config_table_64_t *)tablep)->guid;
516-
table64 = ((efi_config_table_64_t *)tablep)->table;
517-
table = table64;
518-
#ifndef CONFIG_64BIT
519-
if (table64 >> 32) {
513+
if (!IS_ENABLED(CONFIG_X86)) {
514+
guid = &config_tables[i].guid;
515+
table = (unsigned long)config_tables[i].table;
516+
} else if (efi_enabled(EFI_64BIT)) {
517+
guid = &tbl64[i].guid;
518+
table = tbl64[i].table;
519+
520+
if (IS_ENABLED(CONFIG_X86_32) &&
521+
tbl64[i].table > U32_MAX) {
520522
pr_cont("\n");
521523
pr_err("Table located above 4GB, disabling EFI.\n");
522524
return -EINVAL;
523525
}
524-
#endif
525526
} else {
526-
guid = ((efi_config_table_32_t *)tablep)->guid;
527-
table = ((efi_config_table_32_t *)tablep)->table;
527+
guid = &tbl32[i].guid;
528+
table = tbl32[i].table;
528529
}
529530

530-
if (!match_config_table(&guid, table, common_tables))
531-
match_config_table(&guid, table, arch_tables);
532-
533-
tablep += sz;
531+
if (!match_config_table(guid, table, common_tables))
532+
match_config_table(guid, table, arch_tables);
534533
}
535534
pr_cont("\n");
536535
set_bit(EFI_CONFIG_TABLES, &efi.flags);

include/linux/efi.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -613,8 +613,9 @@ extern void __init efi_esrt_init(void);
613613
#else
614614
static inline void efi_esrt_init(void) { }
615615
#endif
616-
extern int efi_config_parse_tables(void *config_tables, int count, int sz,
617-
efi_config_table_type_t *arch_tables);
616+
extern int efi_config_parse_tables(const efi_config_table_t *config_tables,
617+
int count,
618+
const efi_config_table_type_t *arch_tables);
618619
extern int efi_systab_check_header(const efi_table_hdr_t *systab_hdr,
619620
int min_major_version);
620621
extern void efi_systab_report_header(const efi_table_hdr_t *systab_hdr,

0 commit comments

Comments
 (0)