Skip to content

Commit 972d5e7

Browse files
committed
Merge branch 'x86-efi-kexec-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 EFI changes from Ingo Molnar: "This consists of two main parts: - New static EFI runtime services virtual mapping layout which is groundwork for kexec support on EFI (Borislav Petkov) - EFI kexec support itself (Dave Young)" * 'x86-efi-kexec-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (24 commits) x86/efi: parse_efi_setup() build fix x86: ksysfs.c build fix x86/efi: Delete superfluous global variables x86: Reserve setup_data ranges late after parsing memmap cmdline x86: Export x86 boot_params to sysfs x86: Add xloadflags bit for EFI runtime support on kexec x86/efi: Pass necessary EFI data for kexec via setup_data efi: Export EFI runtime memory mapping to sysfs efi: Export more EFI table variables to sysfs x86/efi: Cleanup efi_enter_virtual_mode() function x86/efi: Fix off-by-one bug in EFI Boot Services reservation x86/efi: Add a wrapper function efi_map_region_fixed() x86/efi: Remove unused variables in __map_region() x86/efi: Check krealloc return value x86/efi: Runtime services virtual mapping x86/mm/cpa: Map in an arbitrary pgd x86/mm/pageattr: Add last levels of error path x86/mm/pageattr: Add a PUD error unwinding path x86/mm/pageattr: Add a PTE pagetable populating function x86/mm/pageattr: Add a PMD pagetable populating function ...
2 parents 5d4863e + ef0b8b9 commit 972d5e7

File tree

23 files changed

+1689
-116
lines changed

23 files changed

+1689
-116
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
What: /sys/firmware/efi/fw_vendor
2+
Date: December 2013
3+
Contact: Dave Young <dyoung@redhat.com>
4+
Description: It shows the physical address of firmware vendor field in the
5+
EFI system table.
6+
Users: Kexec
7+
8+
What: /sys/firmware/efi/runtime
9+
Date: December 2013
10+
Contact: Dave Young <dyoung@redhat.com>
11+
Description: It shows the physical address of runtime service table entry in
12+
the EFI system table.
13+
Users: Kexec
14+
15+
What: /sys/firmware/efi/config_table
16+
Date: December 2013
17+
Contact: Dave Young <dyoung@redhat.com>
18+
Description: It shows the physical address of config table entry in the EFI
19+
system table.
20+
Users: Kexec
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
What: /sys/firmware/efi/runtime-map/
2+
Date: December 2013
3+
Contact: Dave Young <dyoung@redhat.com>
4+
Description: Switching efi runtime services to virtual mode requires
5+
that all efi memory ranges which have the runtime attribute
6+
bit set to be mapped to virtual addresses.
7+
8+
The efi runtime services can only be switched to virtual
9+
mode once without rebooting. The kexec kernel must maintain
10+
the same physical to virtual address mappings as the first
11+
kernel. The mappings are exported to sysfs so userspace tools
12+
can reassemble them and pass them into the kexec kernel.
13+
14+
/sys/firmware/efi/runtime-map/ is the directory the kernel
15+
exports that information in.
16+
17+
subdirectories are named with the number of the memory range:
18+
19+
/sys/firmware/efi/runtime-map/0
20+
/sys/firmware/efi/runtime-map/1
21+
/sys/firmware/efi/runtime-map/2
22+
/sys/firmware/efi/runtime-map/3
23+
...
24+
25+
Each subdirectory contains five files:
26+
27+
attribute : The attributes of the memory range.
28+
num_pages : The size of the memory range in pages.
29+
phys_addr : The physical address of the memory range.
30+
type : The type of the memory range.
31+
virt_addr : The virtual address of the memory range.
32+
33+
Above values are all hexadecimal numbers with the '0x' prefix.
34+
Users: Kexec
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
What: /sys/kernel/boot_params
2+
Date: December 2013
3+
Contact: Dave Young <dyoung@redhat.com>
4+
Description: The /sys/kernel/boot_params directory contains two
5+
files: "data" and "version" and one subdirectory "setup_data".
6+
It is used to export the kernel boot parameters of an x86
7+
platform to userspace for kexec and debugging purpose.
8+
9+
If there's no setup_data in boot_params the subdirectory will
10+
not be created.
11+
12+
"data" file is the binary representation of struct boot_params.
13+
14+
"version" file is the string representation of boot
15+
protocol version.
16+
17+
"setup_data" subdirectory contains the setup_data data
18+
structure in boot_params. setup_data is maintained in kernel
19+
as a link list. In "setup_data" subdirectory there's one
20+
subdirectory for each link list node named with the number
21+
of the list nodes. The list node subdirectory contains two
22+
files "type" and "data". "type" file is the string
23+
representation of setup_data type. "data" file is the binary
24+
representation of setup_data payload.
25+
26+
The whole boot_params directory structure is like below:
27+
/sys/kernel/boot_params
28+
|__ data
29+
|__ setup_data
30+
| |__ 0
31+
| | |__ data
32+
| | |__ type
33+
| |__ 1
34+
| |__ data
35+
| |__ type
36+
|__ version
37+
38+
Users: Kexec

Documentation/kernel-parameters.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -899,6 +899,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
899899
edd= [EDD]
900900
Format: {"off" | "on" | "skip[mbr]"}
901901

902+
efi= [EFI]
903+
Format: { "old_map" }
904+
old_map [X86-64]: switch to the old ioremap-based EFI
905+
runtime services mapping. 32-bit still uses this one by
906+
default.
907+
902908
efi_no_storage_paranoia [EFI; X86]
903909
Using this parameter you can use more than 50% of
904910
your efi variable storage. Use this parameter only if

Documentation/x86/boot.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,9 @@ Protocol: 2.12+
608608
- If 1, the kernel supports the 64-bit EFI handoff entry point
609609
given at handover_offset + 0x200.
610610

611+
Bit 4 (read): XLF_EFI_KEXEC
612+
- If 1, the kernel supports kexec EFI boot with EFI runtime support.
613+
611614
Field name: cmdline_size
612615
Type: read
613616
Offset/size: 0x238/4

Documentation/x86/x86_64/mm.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,11 @@ reference.
2828
Current X86-64 implementations only support 40 bits of address space,
2929
but we support up to 46 bits. This expands into MBZ space in the page tables.
3030

31+
->trampoline_pgd:
32+
33+
We map EFI runtime services in the aforementioned PGD in the virtual
34+
range of 64Gb (arbitrarily set, can be raised if needed)
35+
36+
0xffffffef00000000 - 0xffffffff00000000
37+
3138
-Andi Kleen, Jul 2004

arch/x86/boot/header.S

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,14 @@ xloadflags:
391391
#else
392392
# define XLF23 0
393393
#endif
394-
.word XLF0 | XLF1 | XLF23
394+
395+
#if defined(CONFIG_X86_64) && defined(CONFIG_EFI) && defined(CONFIG_KEXEC)
396+
# define XLF4 XLF_EFI_KEXEC
397+
#else
398+
# define XLF4 0
399+
#endif
400+
401+
.word XLF0 | XLF1 | XLF23 | XLF4
395402

396403
cmdline_size: .long COMMAND_LINE_SIZE-1 #length of the command line,
397404
#added with boot protocol

arch/x86/include/asm/efi.h

Lines changed: 60 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,24 @@
11
#ifndef _ASM_X86_EFI_H
22
#define _ASM_X86_EFI_H
33

4+
/*
5+
* We map the EFI regions needed for runtime services non-contiguously,
6+
* with preserved alignment on virtual addresses starting from -4G down
7+
* for a total max space of 64G. This way, we provide for stable runtime
8+
* services addresses across kernels so that a kexec'd kernel can still
9+
* use them.
10+
*
11+
* This is the main reason why we're doing stable VA mappings for RT
12+
* services.
13+
*
14+
* This flag is used in conjuction with a chicken bit called
15+
* "efi=old_map" which can be used as a fallback to the old runtime
16+
* services mapping method in case there's some b0rkage with a
17+
* particular EFI implementation (haha, it is hard to hold up the
18+
* sarcasm here...).
19+
*/
20+
#define EFI_OLD_MEMMAP EFI_ARCH_1
21+
422
#ifdef CONFIG_X86_32
523

624
#define EFI_LOADER_SIGNATURE "EL32"
@@ -69,24 +87,31 @@ extern u64 efi_call6(void *fp, u64 arg1, u64 arg2, u64 arg3,
6987
efi_call6((f), (u64)(a1), (u64)(a2), (u64)(a3), \
7088
(u64)(a4), (u64)(a5), (u64)(a6))
7189

90+
#define _efi_call_virtX(x, f, ...) \
91+
({ \
92+
efi_status_t __s; \
93+
\
94+
efi_sync_low_kernel_mappings(); \
95+
preempt_disable(); \
96+
__s = efi_call##x((void *)efi.systab->runtime->f, __VA_ARGS__); \
97+
preempt_enable(); \
98+
__s; \
99+
})
100+
72101
#define efi_call_virt0(f) \
73-
efi_call0((efi.systab->runtime->f))
74-
#define efi_call_virt1(f, a1) \
75-
efi_call1((efi.systab->runtime->f), (u64)(a1))
76-
#define efi_call_virt2(f, a1, a2) \
77-
efi_call2((efi.systab->runtime->f), (u64)(a1), (u64)(a2))
78-
#define efi_call_virt3(f, a1, a2, a3) \
79-
efi_call3((efi.systab->runtime->f), (u64)(a1), (u64)(a2), \
80-
(u64)(a3))
81-
#define efi_call_virt4(f, a1, a2, a3, a4) \
82-
efi_call4((efi.systab->runtime->f), (u64)(a1), (u64)(a2), \
83-
(u64)(a3), (u64)(a4))
84-
#define efi_call_virt5(f, a1, a2, a3, a4, a5) \
85-
efi_call5((efi.systab->runtime->f), (u64)(a1), (u64)(a2), \
86-
(u64)(a3), (u64)(a4), (u64)(a5))
87-
#define efi_call_virt6(f, a1, a2, a3, a4, a5, a6) \
88-
efi_call6((efi.systab->runtime->f), (u64)(a1), (u64)(a2), \
89-
(u64)(a3), (u64)(a4), (u64)(a5), (u64)(a6))
102+
_efi_call_virtX(0, f)
103+
#define efi_call_virt1(f, a1) \
104+
_efi_call_virtX(1, f, (u64)(a1))
105+
#define efi_call_virt2(f, a1, a2) \
106+
_efi_call_virtX(2, f, (u64)(a1), (u64)(a2))
107+
#define efi_call_virt3(f, a1, a2, a3) \
108+
_efi_call_virtX(3, f, (u64)(a1), (u64)(a2), (u64)(a3))
109+
#define efi_call_virt4(f, a1, a2, a3, a4) \
110+
_efi_call_virtX(4, f, (u64)(a1), (u64)(a2), (u64)(a3), (u64)(a4))
111+
#define efi_call_virt5(f, a1, a2, a3, a4, a5) \
112+
_efi_call_virtX(5, f, (u64)(a1), (u64)(a2), (u64)(a3), (u64)(a4), (u64)(a5))
113+
#define efi_call_virt6(f, a1, a2, a3, a4, a5, a6) \
114+
_efi_call_virtX(6, f, (u64)(a1), (u64)(a2), (u64)(a3), (u64)(a4), (u64)(a5), (u64)(a6))
90115

91116
extern void __iomem *efi_ioremap(unsigned long addr, unsigned long size,
92117
u32 type, u64 attribute);
@@ -95,12 +120,28 @@ extern void __iomem *efi_ioremap(unsigned long addr, unsigned long size,
95120

96121
extern int add_efi_memmap;
97122
extern unsigned long x86_efi_facility;
123+
extern struct efi_scratch efi_scratch;
98124
extern void efi_set_executable(efi_memory_desc_t *md, bool executable);
99125
extern int efi_memblock_x86_reserve_range(void);
100126
extern void efi_call_phys_prelog(void);
101127
extern void efi_call_phys_epilog(void);
102128
extern void efi_unmap_memmap(void);
103129
extern void efi_memory_uc(u64 addr, unsigned long size);
130+
extern void __init efi_map_region(efi_memory_desc_t *md);
131+
extern void __init efi_map_region_fixed(efi_memory_desc_t *md);
132+
extern void efi_sync_low_kernel_mappings(void);
133+
extern void efi_setup_page_tables(void);
134+
extern void __init old_map_region(efi_memory_desc_t *md);
135+
136+
struct efi_setup_data {
137+
u64 fw_vendor;
138+
u64 runtime;
139+
u64 tables;
140+
u64 smbios;
141+
u64 reserved[8];
142+
};
143+
144+
extern u64 efi_setup;
104145

105146
#ifdef CONFIG_EFI
106147

@@ -110,7 +151,7 @@ static inline bool efi_is_native(void)
110151
}
111152

112153
extern struct console early_efi_console;
113-
154+
extern void parse_efi_setup(u64 phys_addr, u32 data_len);
114155
#else
115156
/*
116157
* IF EFI is not configured, have the EFI calls return -ENOSYS.
@@ -122,6 +163,7 @@ extern struct console early_efi_console;
122163
#define efi_call4(_f, _a1, _a2, _a3, _a4) (-ENOSYS)
123164
#define efi_call5(_f, _a1, _a2, _a3, _a4, _a5) (-ENOSYS)
124165
#define efi_call6(_f, _a1, _a2, _a3, _a4, _a5, _a6) (-ENOSYS)
166+
static inline void parse_efi_setup(u64 phys_addr, u32 data_len) {}
125167
#endif /* CONFIG_EFI */
126168

127169
#endif /* _ASM_X86_EFI_H */

arch/x86/include/asm/pgtable_types.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,8 @@ static inline void update_page_count(int level, unsigned long pages) { }
382382
*/
383383
extern pte_t *lookup_address(unsigned long address, unsigned int *level);
384384
extern phys_addr_t slow_virt_to_phys(void *__address);
385-
385+
extern int kernel_map_pages_in_pgd(pgd_t *pgd, u64 pfn, unsigned long address,
386+
unsigned numpages, unsigned long page_flags);
386387
#endif /* !__ASSEMBLY__ */
387388

388389
#endif /* _ASM_X86_PGTABLE_DEFS_H */

arch/x86/include/uapi/asm/bootparam.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#define SETUP_E820_EXT 1
77
#define SETUP_DTB 2
88
#define SETUP_PCI 3
9+
#define SETUP_EFI 4
910

1011
/* ram_size flags */
1112
#define RAMDISK_IMAGE_START_MASK 0x07FF
@@ -23,6 +24,7 @@
2324
#define XLF_CAN_BE_LOADED_ABOVE_4G (1<<1)
2425
#define XLF_EFI_HANDOVER_32 (1<<2)
2526
#define XLF_EFI_HANDOVER_64 (1<<3)
27+
#define XLF_EFI_KEXEC (1<<4)
2628

2729
#ifndef __ASSEMBLY__
2830

arch/x86/kernel/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o
2929
obj-y += syscall_$(BITS).o
3030
obj-$(CONFIG_X86_64) += vsyscall_64.o
3131
obj-$(CONFIG_X86_64) += vsyscall_emu_64.o
32+
obj-$(CONFIG_SYSFS) += ksysfs.o
3233
obj-y += bootflag.o e820.o
3334
obj-y += pci-dma.o quirks.o topology.o kdebugfs.o
3435
obj-y += alternative.o i8253.o pci-nommu.o hw_breakpoint.o

0 commit comments

Comments
 (0)