aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2015-04-01 09:10:25 -0400
committerIngo Molnar <mingo@kernel.org>2015-04-01 09:10:25 -0400
commit84a87c628a12f95d8b0c86cc7b8edb28ea5edf90 (patch)
tree320a9ecbea3e7899dd933e333d0fb64a7d5b3b11
parente42391cd048809d903291d07f86ed3934ce138e9 (diff)
parenta643375f4b175569bc3c03c7a3e758f845c1ccd9 (diff)
Merge tag 'efi-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mfleming/efi into core/efi
Pull EFI updates from Matt Fleming: - Fixes and cleanups for SMBIOS 3.0 DMI code. (Ivan Khoronzhuk) - A new efi=debug command line option that enables debug output in the EFI boot stub and results in less verbose EFI memory map output by default. (Borislav Petkov) - Disable interrupts around EFI calls and use a more standard page table saving and restoring idiom when making EFI calls. (Ingo Molnar) - Reduce the number of memory allocations performed when allocating the FDT in EFI boot stub by retrieving size from the FDT header in the EFI config table. (Ard Biesheuvel) Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--Documentation/kernel-parameters.txt3
-rw-r--r--arch/x86/include/asm/efi.h6
-rw-r--r--arch/x86/platform/efi/efi.c17
-rw-r--r--arch/x86/platform/efi/efi_32.c22
-rw-r--r--arch/x86/platform/efi/efi_64.c29
-rw-r--r--drivers/firmware/dmi_scan.c37
-rw-r--r--drivers/firmware/efi/libstub/arm-stub.c7
-rw-r--r--drivers/firmware/efi/libstub/efistub.h2
-rw-r--r--drivers/firmware/efi/libstub/fdt.c7
-rw-r--r--include/linux/efi.h1
10 files changed, 79 insertions, 52 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index bfcb1a62a7b4..01aa47d3b6ab 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1036,7 +1036,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
1036 Format: {"off" | "on" | "skip[mbr]"} 1036 Format: {"off" | "on" | "skip[mbr]"}
1037 1037
1038 efi= [EFI] 1038 efi= [EFI]
1039 Format: { "old_map", "nochunk", "noruntime" } 1039 Format: { "old_map", "nochunk", "noruntime", "debug" }
1040 old_map [X86-64]: switch to the old ioremap-based EFI 1040 old_map [X86-64]: switch to the old ioremap-based EFI
1041 runtime services mapping. 32-bit still uses this one by 1041 runtime services mapping. 32-bit still uses this one by
1042 default. 1042 default.
@@ -1044,6 +1044,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
1044 boot stub, as chunking can cause problems with some 1044 boot stub, as chunking can cause problems with some
1045 firmware implementations. 1045 firmware implementations.
1046 noruntime : disable EFI runtime services support 1046 noruntime : disable EFI runtime services support
1047 debug: enable misc debug output
1047 1048
1048 efi_no_storage_paranoia [EFI; X86] 1049 efi_no_storage_paranoia [EFI; X86]
1049 Using this parameter you can use more than 50% of 1050 Using this parameter you can use more than 50% of
diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
index 25bce45c6fc4..3738b138b843 100644
--- a/arch/x86/include/asm/efi.h
+++ b/arch/x86/include/asm/efi.h
@@ -2,6 +2,8 @@
2#define _ASM_X86_EFI_H 2#define _ASM_X86_EFI_H
3 3
4#include <asm/i387.h> 4#include <asm/i387.h>
5#include <asm/pgtable.h>
6
5/* 7/*
6 * We map the EFI regions needed for runtime services non-contiguously, 8 * We map the EFI regions needed for runtime services non-contiguously,
7 * with preserved alignment on virtual addresses starting from -4G down 9 * with preserved alignment on virtual addresses starting from -4G down
@@ -89,8 +91,8 @@ extern void __iomem *__init efi_ioremap(unsigned long addr, unsigned long size,
89extern struct efi_scratch efi_scratch; 91extern struct efi_scratch efi_scratch;
90extern void __init efi_set_executable(efi_memory_desc_t *md, bool executable); 92extern void __init efi_set_executable(efi_memory_desc_t *md, bool executable);
91extern int __init efi_memblock_x86_reserve_range(void); 93extern int __init efi_memblock_x86_reserve_range(void);
92extern void __init efi_call_phys_prolog(void); 94extern pgd_t * __init efi_call_phys_prolog(void);
93extern void __init efi_call_phys_epilog(void); 95extern void __init efi_call_phys_epilog(pgd_t *save_pgd);
94extern void __init efi_unmap_memmap(void); 96extern void __init efi_unmap_memmap(void);
95extern void __init efi_memory_uc(u64 addr, unsigned long size); 97extern void __init efi_memory_uc(u64 addr, unsigned long size);
96extern void __init efi_map_region(efi_memory_desc_t *md); 98extern void __init efi_map_region(efi_memory_desc_t *md);
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index dbc8627a5cdf..02744df576d5 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -85,12 +85,20 @@ static efi_status_t __init phys_efi_set_virtual_address_map(
85 efi_memory_desc_t *virtual_map) 85 efi_memory_desc_t *virtual_map)
86{ 86{
87 efi_status_t status; 87 efi_status_t status;
88 unsigned long flags;
89 pgd_t *save_pgd;
88 90
89 efi_call_phys_prolog(); 91 save_pgd = efi_call_phys_prolog();
92
93 /* Disable interrupts around EFI calls: */
94 local_irq_save(flags);
90 status = efi_call_phys(efi_phys.set_virtual_address_map, 95 status = efi_call_phys(efi_phys.set_virtual_address_map,
91 memory_map_size, descriptor_size, 96 memory_map_size, descriptor_size,
92 descriptor_version, virtual_map); 97 descriptor_version, virtual_map);
93 efi_call_phys_epilog(); 98 local_irq_restore(flags);
99
100 efi_call_phys_epilog(save_pgd);
101
94 return status; 102 return status;
95} 103}
96 104
@@ -491,7 +499,8 @@ void __init efi_init(void)
491 if (efi_memmap_init()) 499 if (efi_memmap_init())
492 return; 500 return;
493 501
494 print_efi_memmap(); 502 if (efi_enabled(EFI_DBG))
503 print_efi_memmap();
495} 504}
496 505
497void __init efi_late_init(void) 506void __init efi_late_init(void)
@@ -939,6 +948,8 @@ static int __init arch_parse_efi_cmdline(char *str)
939{ 948{
940 if (parse_option_str(str, "old_map")) 949 if (parse_option_str(str, "old_map"))
941 set_bit(EFI_OLD_MEMMAP, &efi.flags); 950 set_bit(EFI_OLD_MEMMAP, &efi.flags);
951 if (parse_option_str(str, "debug"))
952 set_bit(EFI_DBG, &efi.flags);
942 953
943 return 0; 954 return 0;
944} 955}
diff --git a/arch/x86/platform/efi/efi_32.c b/arch/x86/platform/efi/efi_32.c
index 40e7cda52936..ed5b67338294 100644
--- a/arch/x86/platform/efi/efi_32.c
+++ b/arch/x86/platform/efi/efi_32.c
@@ -33,11 +33,10 @@
33 33
34/* 34/*
35 * To make EFI call EFI runtime service in physical addressing mode we need 35 * To make EFI call EFI runtime service in physical addressing mode we need
36 * prolog/epilog before/after the invocation to disable interrupt, to 36 * prolog/epilog before/after the invocation to claim the EFI runtime service
37 * claim EFI runtime service handler exclusively and to duplicate a memory in 37 * handler exclusively and to duplicate a memory mapping in low memory space,
38 * low memory space say 0 - 3G. 38 * say 0 - 3G.
39 */ 39 */
40static unsigned long efi_rt_eflags;
41 40
42void efi_sync_low_kernel_mappings(void) {} 41void efi_sync_low_kernel_mappings(void) {}
43void __init efi_dump_pagetable(void) {} 42void __init efi_dump_pagetable(void) {}
@@ -57,21 +56,24 @@ void __init efi_map_region(efi_memory_desc_t *md)
57void __init efi_map_region_fixed(efi_memory_desc_t *md) {} 56void __init efi_map_region_fixed(efi_memory_desc_t *md) {}
58void __init parse_efi_setup(u64 phys_addr, u32 data_len) {} 57void __init parse_efi_setup(u64 phys_addr, u32 data_len) {}
59 58
60void __init efi_call_phys_prolog(void) 59pgd_t * __init efi_call_phys_prolog(void)
61{ 60{
62 struct desc_ptr gdt_descr; 61 struct desc_ptr gdt_descr;
62 pgd_t *save_pgd;
63 63
64 local_irq_save(efi_rt_eflags); 64 /* Current pgd is swapper_pg_dir, we'll restore it later: */
65 65 save_pgd = swapper_pg_dir;
66 load_cr3(initial_page_table); 66 load_cr3(initial_page_table);
67 __flush_tlb_all(); 67 __flush_tlb_all();
68 68
69 gdt_descr.address = __pa(get_cpu_gdt_table(0)); 69 gdt_descr.address = __pa(get_cpu_gdt_table(0));
70 gdt_descr.size = GDT_SIZE - 1; 70 gdt_descr.size = GDT_SIZE - 1;
71 load_gdt(&gdt_descr); 71 load_gdt(&gdt_descr);
72
73 return save_pgd;
72} 74}
73 75
74void __init efi_call_phys_epilog(void) 76void __init efi_call_phys_epilog(pgd_t *save_pgd)
75{ 77{
76 struct desc_ptr gdt_descr; 78 struct desc_ptr gdt_descr;
77 79
@@ -79,10 +81,8 @@ void __init efi_call_phys_epilog(void)
79 gdt_descr.size = GDT_SIZE - 1; 81 gdt_descr.size = GDT_SIZE - 1;
80 load_gdt(&gdt_descr); 82 load_gdt(&gdt_descr);
81 83
82 load_cr3(swapper_pg_dir); 84 load_cr3(save_pgd);
83 __flush_tlb_all(); 85 __flush_tlb_all();
84
85 local_irq_restore(efi_rt_eflags);
86} 86}
87 87
88void __init efi_runtime_mkexec(void) 88void __init efi_runtime_mkexec(void)
diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c
index 17e80d829df0..a0ac0f9c307f 100644
--- a/arch/x86/platform/efi/efi_64.c
+++ b/arch/x86/platform/efi/efi_64.c
@@ -41,9 +41,6 @@
41#include <asm/realmode.h> 41#include <asm/realmode.h>
42#include <asm/time.h> 42#include <asm/time.h>
43 43
44static pgd_t *save_pgd __initdata;
45static unsigned long efi_flags __initdata;
46
47/* 44/*
48 * We allocate runtime services regions bottom-up, starting from -4G, i.e. 45 * We allocate runtime services regions bottom-up, starting from -4G, i.e.
49 * 0xffff_ffff_0000_0000 and limit EFI VA mapping space to 64G. 46 * 0xffff_ffff_0000_0000 and limit EFI VA mapping space to 64G.
@@ -78,17 +75,18 @@ static void __init early_code_mapping_set_exec(int executable)
78 } 75 }
79} 76}
80 77
81void __init efi_call_phys_prolog(void) 78pgd_t * __init efi_call_phys_prolog(void)
82{ 79{
83 unsigned long vaddress; 80 unsigned long vaddress;
81 pgd_t *save_pgd;
82
84 int pgd; 83 int pgd;
85 int n_pgds; 84 int n_pgds;
86 85
87 if (!efi_enabled(EFI_OLD_MEMMAP)) 86 if (!efi_enabled(EFI_OLD_MEMMAP))
88 return; 87 return NULL;
89 88
90 early_code_mapping_set_exec(1); 89 early_code_mapping_set_exec(1);
91 local_irq_save(efi_flags);
92 90
93 n_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT), PGDIR_SIZE); 91 n_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT), PGDIR_SIZE);
94 save_pgd = kmalloc(n_pgds * sizeof(pgd_t), GFP_KERNEL); 92 save_pgd = kmalloc(n_pgds * sizeof(pgd_t), GFP_KERNEL);
@@ -99,24 +97,29 @@ void __init efi_call_phys_prolog(void)
99 set_pgd(pgd_offset_k(pgd * PGDIR_SIZE), *pgd_offset_k(vaddress)); 97 set_pgd(pgd_offset_k(pgd * PGDIR_SIZE), *pgd_offset_k(vaddress));
100 } 98 }
101 __flush_tlb_all(); 99 __flush_tlb_all();
100
101 return save_pgd;
102} 102}
103 103
104void __init efi_call_phys_epilog(void) 104void __init efi_call_phys_epilog(pgd_t *save_pgd)
105{ 105{
106 /* 106 /*
107 * After the lock is released, the original page table is restored. 107 * After the lock is released, the original page table is restored.
108 */ 108 */
109 int pgd; 109 int pgd_idx;
110 int n_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT) , PGDIR_SIZE); 110 int nr_pgds;
111 111
112 if (!efi_enabled(EFI_OLD_MEMMAP)) 112 if (!save_pgd)
113 return; 113 return;
114 114
115 for (pgd = 0; pgd < n_pgds; pgd++) 115 nr_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT) , PGDIR_SIZE);
116 set_pgd(pgd_offset_k(pgd * PGDIR_SIZE), save_pgd[pgd]); 116
117 for (pgd_idx = 0; pgd_idx < nr_pgds; pgd_idx++)
118 set_pgd(pgd_offset_k(pgd_idx * PGDIR_SIZE), save_pgd[pgd_idx]);
119
117 kfree(save_pgd); 120 kfree(save_pgd);
121
118 __flush_tlb_all(); 122 __flush_tlb_all();
119 local_irq_restore(efi_flags);
120 early_code_mapping_set_exec(0); 123 early_code_mapping_set_exec(0);
121} 124}
122 125
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
index 69fac068669f..c9cb725520c5 100644
--- a/drivers/firmware/dmi_scan.c
+++ b/drivers/firmware/dmi_scan.c
@@ -17,7 +17,9 @@
17 */ 17 */
18static const char dmi_empty_string[] = " "; 18static const char dmi_empty_string[] = " ";
19 19
20static u16 __initdata dmi_ver; 20static u32 dmi_ver __initdata;
21static u32 dmi_len;
22static u16 dmi_num;
21/* 23/*
22 * Catch too early calls to dmi_check_system(): 24 * Catch too early calls to dmi_check_system():
23 */ 25 */
@@ -78,7 +80,7 @@ static const char * __init dmi_string(const struct dmi_header *dm, u8 s)
78 * We have to be cautious here. We have seen BIOSes with DMI pointers 80 * We have to be cautious here. We have seen BIOSes with DMI pointers
79 * pointing to completely the wrong place for example 81 * pointing to completely the wrong place for example
80 */ 82 */
81static void dmi_table(u8 *buf, u32 len, int num, 83static void dmi_table(u8 *buf,
82 void (*decode)(const struct dmi_header *, void *), 84 void (*decode)(const struct dmi_header *, void *),
83 void *private_data) 85 void *private_data)
84{ 86{
@@ -89,7 +91,8 @@ static void dmi_table(u8 *buf, u32 len, int num,
89 * Stop when we see all the items the table claimed to have 91 * Stop when we see all the items the table claimed to have
90 * OR we run off the end of the table (also happens) 92 * OR we run off the end of the table (also happens)
91 */ 93 */
92 while ((i < num) && (data - buf + sizeof(struct dmi_header)) <= len) { 94 while ((i < dmi_num) && (data - buf + sizeof(struct dmi_header))
95 <= dmi_len) {
93 const struct dmi_header *dm = (const struct dmi_header *)data; 96 const struct dmi_header *dm = (const struct dmi_header *)data;
94 97
95 /* 98 /*
@@ -98,9 +101,9 @@ static void dmi_table(u8 *buf, u32 len, int num,
98 * table in dmi_decode or dmi_string 101 * table in dmi_decode or dmi_string
99 */ 102 */
100 data += dm->length; 103 data += dm->length;
101 while ((data - buf < len - 1) && (data[0] || data[1])) 104 while ((data - buf < dmi_len - 1) && (data[0] || data[1]))
102 data++; 105 data++;
103 if (data - buf < len - 1) 106 if (data - buf < dmi_len - 1)
104 decode(dm, private_data); 107 decode(dm, private_data);
105 108
106 /* 109 /*
@@ -115,8 +118,6 @@ static void dmi_table(u8 *buf, u32 len, int num,
115} 118}
116 119
117static phys_addr_t dmi_base; 120static phys_addr_t dmi_base;
118static u32 dmi_len;
119static u16 dmi_num;
120 121
121static int __init dmi_walk_early(void (*decode)(const struct dmi_header *, 122static int __init dmi_walk_early(void (*decode)(const struct dmi_header *,
122 void *)) 123 void *))
@@ -127,7 +128,7 @@ static int __init dmi_walk_early(void (*decode)(const struct dmi_header *,
127 if (buf == NULL) 128 if (buf == NULL)
128 return -1; 129 return -1;
129 130
130 dmi_table(buf, dmi_len, dmi_num, decode, NULL); 131 dmi_table(buf, decode, NULL);
131 132
132 add_device_randomness(buf, dmi_len); 133 add_device_randomness(buf, dmi_len);
133 134
@@ -198,7 +199,7 @@ static void __init dmi_save_uuid(const struct dmi_header *dm, int slot,
198 * the UUID are supposed to be little-endian encoded. The specification 199 * the UUID are supposed to be little-endian encoded. The specification
199 * says that this is the defacto standard. 200 * says that this is the defacto standard.
200 */ 201 */
201 if (dmi_ver >= 0x0206) 202 if (dmi_ver >= 0x020600)
202 sprintf(s, "%pUL", d); 203 sprintf(s, "%pUL", d);
203 else 204 else
204 sprintf(s, "%pUB", d); 205 sprintf(s, "%pUB", d);
@@ -470,7 +471,7 @@ static void __init dmi_format_ids(char *buf, size_t len)
470 */ 471 */
471static int __init dmi_present(const u8 *buf) 472static int __init dmi_present(const u8 *buf)
472{ 473{
473 int smbios_ver; 474 u32 smbios_ver;
474 475
475 if (memcmp(buf, "_SM_", 4) == 0 && 476 if (memcmp(buf, "_SM_", 4) == 0 &&
476 buf[5] < 32 && dmi_checksum(buf, buf[5])) { 477 buf[5] < 32 && dmi_checksum(buf, buf[5])) {
@@ -503,14 +504,16 @@ static int __init dmi_present(const u8 *buf)
503 if (dmi_walk_early(dmi_decode) == 0) { 504 if (dmi_walk_early(dmi_decode) == 0) {
504 if (smbios_ver) { 505 if (smbios_ver) {
505 dmi_ver = smbios_ver; 506 dmi_ver = smbios_ver;
506 pr_info("SMBIOS %d.%d present.\n", 507 pr_info("SMBIOS %d.%d%s present.\n",
507 dmi_ver >> 8, dmi_ver & 0xFF); 508 dmi_ver >> 8, dmi_ver & 0xFF,
509 (dmi_ver < 0x0300) ? "" : ".x");
508 } else { 510 } else {
509 dmi_ver = (buf[14] & 0xF0) << 4 | 511 dmi_ver = (buf[14] & 0xF0) << 4 |
510 (buf[14] & 0x0F); 512 (buf[14] & 0x0F);
511 pr_info("Legacy DMI %d.%d present.\n", 513 pr_info("Legacy DMI %d.%d present.\n",
512 dmi_ver >> 8, dmi_ver & 0xFF); 514 dmi_ver >> 8, dmi_ver & 0xFF);
513 } 515 }
516 dmi_ver <<= 8;
514 dmi_format_ids(dmi_ids_string, sizeof(dmi_ids_string)); 517 dmi_format_ids(dmi_ids_string, sizeof(dmi_ids_string));
515 printk(KERN_DEBUG "DMI: %s\n", dmi_ids_string); 518 printk(KERN_DEBUG "DMI: %s\n", dmi_ids_string);
516 return 0; 519 return 0;
@@ -528,7 +531,8 @@ static int __init dmi_smbios3_present(const u8 *buf)
528{ 531{
529 if (memcmp(buf, "_SM3_", 5) == 0 && 532 if (memcmp(buf, "_SM3_", 5) == 0 &&
530 buf[6] < 32 && dmi_checksum(buf, buf[6])) { 533 buf[6] < 32 && dmi_checksum(buf, buf[6])) {
531 dmi_ver = get_unaligned_be16(buf + 7); 534 dmi_ver = get_unaligned_be32(buf + 6);
535 dmi_ver &= 0xFFFFFF;
532 dmi_len = get_unaligned_le32(buf + 12); 536 dmi_len = get_unaligned_le32(buf + 12);
533 dmi_base = get_unaligned_le64(buf + 16); 537 dmi_base = get_unaligned_le64(buf + 16);
534 538
@@ -545,8 +549,9 @@ static int __init dmi_smbios3_present(const u8 *buf)
545 dmi_num = dmi_len / 4; 549 dmi_num = dmi_len / 4;
546 550
547 if (dmi_walk_early(dmi_decode) == 0) { 551 if (dmi_walk_early(dmi_decode) == 0) {
548 pr_info("SMBIOS %d.%d present.\n", 552 pr_info("SMBIOS %d.%d.%d present.\n",
549 dmi_ver >> 8, dmi_ver & 0xFF); 553 dmi_ver >> 16, (dmi_ver >> 8) & 0xFF,
554 dmi_ver & 0xFF);
550 dmi_format_ids(dmi_ids_string, sizeof(dmi_ids_string)); 555 dmi_format_ids(dmi_ids_string, sizeof(dmi_ids_string));
551 pr_debug("DMI: %s\n", dmi_ids_string); 556 pr_debug("DMI: %s\n", dmi_ids_string);
552 return 0; 557 return 0;
@@ -901,7 +906,7 @@ int dmi_walk(void (*decode)(const struct dmi_header *, void *),
901 if (buf == NULL) 906 if (buf == NULL)
902 return -1; 907 return -1;
903 908
904 dmi_table(buf, dmi_len, dmi_num, decode, private_data); 909 dmi_table(buf, decode, private_data);
905 910
906 dmi_unmap(buf); 911 dmi_unmap(buf);
907 return 0; 912 return 0;
diff --git a/drivers/firmware/efi/libstub/arm-stub.c b/drivers/firmware/efi/libstub/arm-stub.c
index dcae482a9a17..e29560e6b40b 100644
--- a/drivers/firmware/efi/libstub/arm-stub.c
+++ b/drivers/firmware/efi/libstub/arm-stub.c
@@ -175,7 +175,7 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table,
175 unsigned long initrd_addr; 175 unsigned long initrd_addr;
176 u64 initrd_size = 0; 176 u64 initrd_size = 0;
177 unsigned long fdt_addr = 0; /* Original DTB */ 177 unsigned long fdt_addr = 0; /* Original DTB */
178 u64 fdt_size = 0; /* We don't get size from configuration table */ 178 unsigned long fdt_size = 0;
179 char *cmdline_ptr = NULL; 179 char *cmdline_ptr = NULL;
180 int cmdline_size = 0; 180 int cmdline_size = 0;
181 unsigned long new_fdt_addr; 181 unsigned long new_fdt_addr;
@@ -239,8 +239,7 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table,
239 } else { 239 } else {
240 status = handle_cmdline_files(sys_table, image, cmdline_ptr, 240 status = handle_cmdline_files(sys_table, image, cmdline_ptr,
241 "dtb=", 241 "dtb=",
242 ~0UL, (unsigned long *)&fdt_addr, 242 ~0UL, &fdt_addr, &fdt_size);
243 (unsigned long *)&fdt_size);
244 243
245 if (status != EFI_SUCCESS) { 244 if (status != EFI_SUCCESS) {
246 pr_efi_err(sys_table, "Failed to load device tree!\n"); 245 pr_efi_err(sys_table, "Failed to load device tree!\n");
@@ -252,7 +251,7 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table,
252 pr_efi(sys_table, "Using DTB from command line\n"); 251 pr_efi(sys_table, "Using DTB from command line\n");
253 } else { 252 } else {
254 /* Look for a device tree configuration table entry. */ 253 /* Look for a device tree configuration table entry. */
255 fdt_addr = (uintptr_t)get_fdt(sys_table); 254 fdt_addr = (uintptr_t)get_fdt(sys_table, &fdt_size);
256 if (fdt_addr) 255 if (fdt_addr)
257 pr_efi(sys_table, "Using DTB from configuration table\n"); 256 pr_efi(sys_table, "Using DTB from configuration table\n");
258 } 257 }
diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h
index 47437b16b186..e334a01cf92f 100644
--- a/drivers/firmware/efi/libstub/efistub.h
+++ b/drivers/firmware/efi/libstub/efistub.h
@@ -41,7 +41,7 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
41 unsigned long fdt_addr, 41 unsigned long fdt_addr,
42 unsigned long fdt_size); 42 unsigned long fdt_size);
43 43
44void *get_fdt(efi_system_table_t *sys_table); 44void *get_fdt(efi_system_table_t *sys_table, unsigned long *fdt_size);
45 45
46void efi_get_virtmap(efi_memory_desc_t *memory_map, unsigned long map_size, 46void efi_get_virtmap(efi_memory_desc_t *memory_map, unsigned long map_size,
47 unsigned long desc_size, efi_memory_desc_t *runtime_map, 47 unsigned long desc_size, efi_memory_desc_t *runtime_map,
diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c
index 91da56c4fd54..ef5d764e2a27 100644
--- a/drivers/firmware/efi/libstub/fdt.c
+++ b/drivers/firmware/efi/libstub/fdt.c
@@ -323,7 +323,7 @@ fail:
323 return EFI_LOAD_ERROR; 323 return EFI_LOAD_ERROR;
324} 324}
325 325
326void *get_fdt(efi_system_table_t *sys_table) 326void *get_fdt(efi_system_table_t *sys_table, unsigned long *fdt_size)
327{ 327{
328 efi_guid_t fdt_guid = DEVICE_TREE_GUID; 328 efi_guid_t fdt_guid = DEVICE_TREE_GUID;
329 efi_config_table_t *tables; 329 efi_config_table_t *tables;
@@ -336,6 +336,11 @@ void *get_fdt(efi_system_table_t *sys_table)
336 for (i = 0; i < sys_table->nr_tables; i++) 336 for (i = 0; i < sys_table->nr_tables; i++)
337 if (efi_guidcmp(tables[i].guid, fdt_guid) == 0) { 337 if (efi_guidcmp(tables[i].guid, fdt_guid) == 0) {
338 fdt = (void *) tables[i].table; 338 fdt = (void *) tables[i].table;
339 if (fdt_check_header(fdt) != 0) {
340 pr_efi_err(sys_table, "Invalid header detected on UEFI supplied FDT, ignoring ...\n");
341 return NULL;
342 }
343 *fdt_size = fdt_totalsize(fdt);
339 break; 344 break;
340 } 345 }
341 346
diff --git a/include/linux/efi.h b/include/linux/efi.h
index cf7e431cbc73..af5be0368dec 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -942,6 +942,7 @@ extern int __init efi_setup_pcdp_console(char *);
942#define EFI_64BIT 5 /* Is the firmware 64-bit? */ 942#define EFI_64BIT 5 /* Is the firmware 64-bit? */
943#define EFI_PARAVIRT 6 /* Access is via a paravirt interface */ 943#define EFI_PARAVIRT 6 /* Access is via a paravirt interface */
944#define EFI_ARCH_1 7 /* First arch-specific bit */ 944#define EFI_ARCH_1 7 /* First arch-specific bit */
945#define EFI_DBG 8 /* Print additional debug info at runtime */
945 946
946#ifdef CONFIG_EFI 947#ifdef CONFIG_EFI
947/* 948/*