Commit | Line | Data |
---|---|---|
b2441318 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
1965aae3 PA |
2 | #ifndef _ASM_X86_EFI_H |
3 | #define _ASM_X86_EFI_H | |
5b83683f | 4 | |
df6b35f4 | 5 | #include <asm/fpu/api.h> |
9788375d | 6 | #include <asm/processor-flags.h> |
c9f2a9a6 | 7 | #include <asm/tlb.h> |
dd84441a | 8 | #include <asm/nospec-branch.h> |
7e904a91 | 9 | #include <asm/mmu_context.h> |
fe379fa4 | 10 | #include <asm/ibt.h> |
14b864f4 | 11 | #include <linux/build_bug.h> |
9b47c527 | 12 | #include <linux/kernel.h> |
65fddcfc | 13 | #include <linux/pgtable.h> |
744937b0 | 14 | |
9cd437ac | 15 | extern unsigned long efi_fw_vendor, efi_config_table; |
3e1e00c0 | 16 | extern unsigned long efi_mixed_mode_stack_pa; |
9cd437ac | 17 | |
d2f7cbe7 BP |
18 | /* |
19 | * We map the EFI regions needed for runtime services non-contiguously, | |
20 | * with preserved alignment on virtual addresses starting from -4G down | |
21 | * for a total max space of 64G. This way, we provide for stable runtime | |
22 | * services addresses across kernels so that a kexec'd kernel can still | |
23 | * use them. | |
24 | * | |
25 | * This is the main reason why we're doing stable VA mappings for RT | |
26 | * services. | |
d2f7cbe7 | 27 | */ |
d2f7cbe7 | 28 | |
b8ff87a6 MF |
29 | #define EFI32_LOADER_SIGNATURE "EL32" |
30 | #define EFI64_LOADER_SIGNATURE "EL64" | |
31 | ||
9788375d | 32 | #define ARCH_EFI_IRQ_FLAGS_MASK X86_EFLAGS_IF |
e429795c | 33 | |
745e3ed8 KS |
34 | #define EFI_UNACCEPTED_UNIT_SIZE PMD_SIZE |
35 | ||
14b864f4 AS |
36 | /* |
37 | * The EFI services are called through variadic functions in many cases. These | |
38 | * functions are implemented in assembler and support only a fixed number of | |
39 | * arguments. The macros below allows us to check at build time that we don't | |
40 | * try to call them with too many arguments. | |
41 | * | |
42 | * __efi_nargs() will return the number of arguments if it is 7 or less, and | |
43 | * cause a BUILD_BUG otherwise. The limitations of the C preprocessor make it | |
44 | * impossible to calculate the exact number of arguments beyond some | |
45 | * pre-defined limit. The maximum number of arguments currently supported by | |
46 | * any of the thunks is 7, so this is good enough for now and can be extended | |
47 | * in the obvious way if we ever need more. | |
48 | */ | |
49 | ||
50 | #define __efi_nargs(...) __efi_nargs_(__VA_ARGS__) | |
51 | #define __efi_nargs_(...) __efi_nargs__(0, ##__VA_ARGS__, \ | |
44f155b4 | 52 | __efi_arg_sentinel(9), __efi_arg_sentinel(8), \ |
14b864f4 AS |
53 | __efi_arg_sentinel(7), __efi_arg_sentinel(6), \ |
54 | __efi_arg_sentinel(5), __efi_arg_sentinel(4), \ | |
55 | __efi_arg_sentinel(3), __efi_arg_sentinel(2), \ | |
56 | __efi_arg_sentinel(1), __efi_arg_sentinel(0)) | |
44f155b4 | 57 | #define __efi_nargs__(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, n, ...) \ |
14b864f4 | 58 | __take_second_arg(n, \ |
44f155b4 | 59 | ({ BUILD_BUG_ON_MSG(1, "__efi_nargs limit exceeded"); 10; })) |
14b864f4 AS |
60 | #define __efi_arg_sentinel(n) , n |
61 | ||
62 | /* | |
63 | * __efi_nargs_check(f, n, ...) will cause a BUILD_BUG if the ellipsis | |
64 | * represents more than n arguments. | |
65 | */ | |
66 | ||
67 | #define __efi_nargs_check(f, n, ...) \ | |
68 | __efi_nargs_check_(f, __efi_nargs(__VA_ARGS__), n) | |
69 | #define __efi_nargs_check_(f, p, n) __efi_nargs_check__(f, p, n) | |
70 | #define __efi_nargs_check__(f, p, n) ({ \ | |
71 | BUILD_BUG_ON_MSG( \ | |
72 | (p) > (n), \ | |
73 | #f " called with too many arguments (" #p ">" #n ")"); \ | |
74 | }) | |
75 | ||
b0dc553c AL |
76 | static inline void efi_fpu_begin(void) |
77 | { | |
78 | /* | |
79 | * The UEFI calling convention (UEFI spec 2.3.2 and 2.3.4) requires | |
80 | * that FCW and MXCSR (64-bit) must be initialized prior to calling | |
81 | * UEFI code. (Oddly the spec does not require that the FPU stack | |
82 | * be empty.) | |
83 | */ | |
84 | kernel_fpu_begin_mask(KFPU_387 | KFPU_MXCSR); | |
85 | } | |
86 | ||
87 | static inline void efi_fpu_end(void) | |
88 | { | |
89 | kernel_fpu_end(); | |
90 | } | |
91 | ||
9788375d | 92 | #ifdef CONFIG_X86_32 |
a1b87d54 | 93 | #define EFI_X86_KERNEL_ALLOC_LIMIT (SZ_512M - 1) |
5b83683f | 94 | #else /* !CONFIG_X86_32 */ |
a1b87d54 | 95 | #define EFI_X86_KERNEL_ALLOC_LIMIT EFI_ALLOC_LIMIT |
62fa6e69 | 96 | |
14b864f4 AS |
97 | extern asmlinkage u64 __efi_call(void *fp, ...); |
98 | ||
93be2859 AB |
99 | extern bool efi_disable_ibt_for_runtime; |
100 | ||
14b864f4 AS |
101 | #define efi_call(...) ({ \ |
102 | __efi_nargs_check(efi_call, 7, __VA_ARGS__); \ | |
103 | __efi_call(__VA_ARGS__); \ | |
104 | }) | |
62fa6e69 | 105 | |
8add9a3a | 106 | #undef arch_efi_call_virt |
fe379fa4 | 107 | #define arch_efi_call_virt(p, f, args...) ({ \ |
93be2859 | 108 | u64 ret, ibt = ibt_save(efi_disable_ibt_for_runtime); \ |
fe379fa4 PZ |
109 | ret = efi_call((void *)p->f, args); \ |
110 | ibt_restore(ibt); \ | |
111 | ret; \ | |
112 | }) | |
bc25f9db | 113 | |
a523841e | 114 | #ifdef CONFIG_KASAN |
769a8089 AR |
115 | /* |
116 | * CONFIG_KASAN may redefine memset to __memset. __memset function is present | |
117 | * only in kernel binary. Since the EFI stub linked into a separate binary it | |
118 | * doesn't have __memset(). So we should use standard memset from | |
119 | * arch/x86/boot/compressed/string.c. The same applies to memcpy and memmove. | |
120 | */ | |
121 | #undef memcpy | |
122 | #undef memset | |
123 | #undef memmove | |
a523841e | 124 | #endif |
769a8089 | 125 | |
5b83683f HY |
126 | #endif /* CONFIG_X86_32 */ |
127 | ||
4e78eb05 | 128 | extern int __init efi_memblock_x86_reserve_range(void); |
0bbea1ce | 129 | extern void __init efi_print_memmap(void); |
d2f7cbe7 | 130 | extern void __init efi_map_region(efi_memory_desc_t *md); |
3b266496 | 131 | extern void __init efi_map_region_fixed(efi_memory_desc_t *md); |
d2f7cbe7 | 132 | extern void efi_sync_low_kernel_mappings(void); |
67a9108e | 133 | extern int __init efi_alloc_page_tables(void); |
4e78eb05 | 134 | extern int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages); |
6d0cc887 | 135 | extern void __init efi_runtime_update_mappings(void); |
11cc8512 | 136 | extern void __init efi_dump_pagetable(void); |
a5d90c92 | 137 | extern void __init efi_apply_memmap_quirks(void); |
eeb9db09 ST |
138 | extern int __init efi_reuse_config(u64 tables, int nr_tables); |
139 | extern void efi_delete_dummy_variable(void); | |
c46f5223 | 140 | extern void efi_crash_gracefully_on_page_fault(unsigned long phys_addr); |
47c33a09 | 141 | extern void efi_free_boot_services(void); |
5b83683f | 142 | |
762f169f AB |
143 | void arch_efi_call_virt_setup(void); |
144 | void arch_efi_call_virt_teardown(void); | |
514b1a84 | 145 | |
1fec0533 | 146 | extern u64 efi_setup; |
1fec0533 | 147 | |
6b59e366 | 148 | #ifdef CONFIG_EFI |
a61962d8 | 149 | extern u64 __efi64_thunk(u32, ...); |
14b864f4 AS |
150 | |
151 | #define efi64_thunk(...) ({ \ | |
44f155b4 AB |
152 | u64 __pad[3]; /* must have space for 3 args on the stack */ \ |
153 | __efi_nargs_check(efi64_thunk, 9, __VA_ARGS__); \ | |
154 | __efi64_thunk(__VA_ARGS__, __pad); \ | |
14b864f4 | 155 | }) |
6b59e366 | 156 | |
a8147dba | 157 | static inline bool efi_is_mixed(void) |
6b59e366 | 158 | { |
a8147dba AB |
159 | if (!IS_ENABLED(CONFIG_EFI_MIXED)) |
160 | return false; | |
161 | return IS_ENABLED(CONFIG_X86_64) && !efi_enabled(EFI_64BIT); | |
6b59e366 ST |
162 | } |
163 | ||
7d453eee MF |
164 | static inline bool efi_runtime_supported(void) |
165 | { | |
6cfcd6f0 | 166 | if (IS_ENABLED(CONFIG_X86_64) == efi_enabled(EFI_64BIT)) |
7d453eee MF |
167 | return true; |
168 | ||
1f299fad | 169 | return IS_ENABLED(CONFIG_EFI_MIXED); |
7d453eee MF |
170 | } |
171 | ||
5c12af0c | 172 | extern void parse_efi_setup(u64 phys_addr, u32 data_len); |
4f9dbcfc | 173 | |
4f9dbcfc | 174 | extern void efi_thunk_runtime_setup(void); |
69829470 AB |
175 | efi_status_t efi_set_virtual_address_map(unsigned long memory_map_size, |
176 | unsigned long descriptor_size, | |
177 | u32 descriptor_version, | |
59f2a619 AB |
178 | efi_memory_desc_t *virtual_map, |
179 | unsigned long systab_phys); | |
243b6754 AB |
180 | |
181 | /* arch specific definitions used by the stub code */ | |
182 | ||
de8c5520 AS |
183 | #ifdef CONFIG_EFI_MIXED |
184 | ||
a1b87d54 AB |
185 | #define EFI_ALLOC_LIMIT (efi_is_64bit() ? ULONG_MAX : U32_MAX) |
186 | ||
de8c5520 | 187 | #define ARCH_HAS_EFISTUB_WRAPPERS |
0a755614 AB |
188 | |
189 | static inline bool efi_is_64bit(void) | |
190 | { | |
de8c5520 AS |
191 | extern const bool efi_is64; |
192 | ||
193 | return efi_is64; | |
0a755614 | 194 | } |
27571616 | 195 | |
f958efe9 AB |
196 | static inline bool efi_is_native(void) |
197 | { | |
f958efe9 AB |
198 | return efi_is_64bit(); |
199 | } | |
200 | ||
99ea8b1d | 201 | #define efi_table_attr(inst, attr) \ |
a61962d8 AB |
202 | (efi_is_native() ? (inst)->attr \ |
203 | : efi_mixed_table_attr((inst), attr)) | |
204 | ||
205 | #define efi_mixed_table_attr(inst, attr) \ | |
206 | (__typeof__(inst->attr)) \ | |
207 | _Generic(inst->mixed_mode.attr, \ | |
208 | u32: (unsigned long)(inst->mixed_mode.attr), \ | |
209 | default: (inst->mixed_mode.attr)) | |
3552fdf2 | 210 | |
ea7d87f9 AS |
211 | /* |
212 | * The following macros allow translating arguments if necessary from native to | |
213 | * mixed mode. The use case for this is to initialize the upper 32 bits of | |
214 | * output parameters, and where the 32-bit method requires a 64-bit argument, | |
215 | * which must be split up into two arguments to be thunked properly. | |
216 | * | |
217 | * As examples, the AllocatePool boot service returns the address of the | |
218 | * allocation, but it will not set the high 32 bits of the address. To ensure | |
219 | * that the full 64-bit address is initialized, we zero-init the address before | |
220 | * calling the thunk. | |
221 | * | |
222 | * The FreePages boot service takes a 64-bit physical address even in 32-bit | |
223 | * mode. For the thunk to work correctly, a native 64-bit call of | |
224 | * free_pages(addr, size) | |
225 | * must be translated to | |
226 | * efi64_thunk(free_pages, addr & U32_MAX, addr >> 32, size) | |
227 | * so that the two 32-bit halves of addr get pushed onto the stack separately. | |
228 | */ | |
229 | ||
230 | static inline void *efi64_zero_upper(void *p) | |
231 | { | |
232 | ((u32 *)p)[1] = 0; | |
233 | return p; | |
234 | } | |
235 | ||
3b8f44fc AB |
236 | static inline u32 efi64_convert_status(efi_status_t status) |
237 | { | |
238 | return (u32)(status | (u64)status >> 32); | |
239 | } | |
240 | ||
31f1a0ed AB |
241 | #define __efi64_split(val) (val) & U32_MAX, (u64)(val) >> 32 |
242 | ||
ea7d87f9 AS |
243 | #define __efi64_argmap_free_pages(addr, size) \ |
244 | ((addr), 0, (size)) | |
245 | ||
246 | #define __efi64_argmap_get_memory_map(mm_size, mm, key, size, ver) \ | |
247 | ((mm_size), (mm), efi64_zero_upper(key), efi64_zero_upper(size), (ver)) | |
248 | ||
249 | #define __efi64_argmap_allocate_pool(type, size, buffer) \ | |
250 | ((type), (size), efi64_zero_upper(buffer)) | |
251 | ||
9b47c527 AS |
252 | #define __efi64_argmap_create_event(type, tpl, f, c, event) \ |
253 | ((type), (tpl), (f), (c), efi64_zero_upper(event)) | |
254 | ||
255 | #define __efi64_argmap_set_timer(event, type, time) \ | |
256 | ((event), (type), lower_32_bits(time), upper_32_bits(time)) | |
257 | ||
258 | #define __efi64_argmap_wait_for_event(num, event, index) \ | |
259 | ((num), (event), efi64_zero_upper(index)) | |
260 | ||
ea7d87f9 AS |
261 | #define __efi64_argmap_handle_protocol(handle, protocol, interface) \ |
262 | ((handle), (protocol), efi64_zero_upper(interface)) | |
263 | ||
264 | #define __efi64_argmap_locate_protocol(protocol, reg, interface) \ | |
265 | ((protocol), (reg), efi64_zero_upper(interface)) | |
266 | ||
abd26868 AB |
267 | #define __efi64_argmap_locate_device_path(protocol, path, handle) \ |
268 | ((protocol), (path), efi64_zero_upper(handle)) | |
269 | ||
3b8f44fc AB |
270 | #define __efi64_argmap_exit(handle, status, size, data) \ |
271 | ((handle), efi64_convert_status(status), (size), (data)) | |
272 | ||
4444f854 MG |
273 | /* PCI I/O */ |
274 | #define __efi64_argmap_get_location(protocol, seg, bus, dev, func) \ | |
275 | ((protocol), efi64_zero_upper(seg), efi64_zero_upper(bus), \ | |
276 | efi64_zero_upper(dev), efi64_zero_upper(func)) | |
277 | ||
2931d526 AB |
278 | /* LoadFile */ |
279 | #define __efi64_argmap_load_file(protocol, path, policy, bufsize, buf) \ | |
280 | ((protocol), (path), (policy), efi64_zero_upper(bufsize), (buf)) | |
281 | ||
b4b89a02 AS |
282 | /* Graphics Output Protocol */ |
283 | #define __efi64_argmap_query_mode(gop, mode, size, info) \ | |
284 | ((gop), (mode), efi64_zero_upper(size), efi64_zero_upper(info)) | |
285 | ||
4da87c51 AB |
286 | /* TCG2 protocol */ |
287 | #define __efi64_argmap_hash_log_extend_event(prot, fl, addr, size, ev) \ | |
288 | ((prot), (fl), 0ULL, (u64)(addr), 0ULL, (u64)(size), 0ULL, ev) | |
289 | ||
31f1a0ed AB |
290 | /* DXE services */ |
291 | #define __efi64_argmap_get_memory_space_descriptor(phys, desc) \ | |
292 | (__efi64_split(phys), (desc)) | |
293 | ||
aa6d1ed1 | 294 | #define __efi64_argmap_set_memory_space_attributes(phys, size, flags) \ |
31f1a0ed AB |
295 | (__efi64_split(phys), __efi64_split(size), __efi64_split(flags)) |
296 | ||
f8a31244 AB |
297 | /* file protocol */ |
298 | #define __efi64_argmap_open(prot, newh, fname, mode, attr) \ | |
299 | ((prot), efi64_zero_upper(newh), (fname), __efi64_split(mode), \ | |
300 | __efi64_split(attr)) | |
301 | ||
302 | #define __efi64_argmap_set_position(pos) (__efi64_split(pos)) | |
303 | ||
304 | /* file system protocol */ | |
305 | #define __efi64_argmap_open_volume(prot, file) \ | |
306 | ((prot), efi64_zero_upper(file)) | |
307 | ||
79729f26 | 308 | /* Memory Attribute Protocol */ |
45d51654 AB |
309 | #define __efi64_argmap_get_memory_attributes(protocol, phys, size, flags) \ |
310 | ((protocol), __efi64_split(phys), __efi64_split(size), (flags)) | |
311 | ||
79729f26 EB |
312 | #define __efi64_argmap_set_memory_attributes(protocol, phys, size, flags) \ |
313 | ((protocol), __efi64_split(phys), __efi64_split(size), __efi64_split(flags)) | |
314 | ||
315 | #define __efi64_argmap_clear_memory_attributes(protocol, phys, size, flags) \ | |
316 | ((protocol), __efi64_split(phys), __efi64_split(size), __efi64_split(flags)) | |
317 | ||
ea7d87f9 AS |
318 | /* |
319 | * The macros below handle the plumbing for the argument mapping. To add a | |
320 | * mapping for a specific EFI method, simply define a macro | |
321 | * __efi64_argmap_<method name>, following the examples above. | |
322 | */ | |
323 | ||
324 | #define __efi64_thunk_map(inst, func, ...) \ | |
325 | efi64_thunk(inst->mixed_mode.func, \ | |
326 | __efi64_argmap(__efi64_argmap_ ## func(__VA_ARGS__), \ | |
327 | (__VA_ARGS__))) | |
328 | ||
329 | #define __efi64_argmap(mapped, args) \ | |
330 | __PASTE(__efi64_argmap__, __efi_nargs(__efi_eat mapped))(mapped, args) | |
331 | #define __efi64_argmap__0(mapped, args) __efi_eval mapped | |
332 | #define __efi64_argmap__1(mapped, args) __efi_eval args | |
333 | ||
334 | #define __efi_eat(...) | |
335 | #define __efi_eval(...) __VA_ARGS__ | |
336 | ||
a61962d8 AB |
337 | static inline efi_status_t __efi64_widen_efi_status(u64 status) |
338 | { | |
339 | /* use rotate to move the value of bit #31 into position #63 */ | |
340 | return ror64(rol32(status, 1), 1); | |
341 | } | |
342 | ||
343 | /* The macro below handles dispatching via the thunk if needed */ | |
344 | ||
345 | #define efi_fn_call(inst, func, ...) \ | |
346 | (efi_is_native() ? (inst)->func(__VA_ARGS__) \ | |
347 | : efi_mixed_call((inst), func, ##__VA_ARGS__)) | |
348 | ||
349 | #define efi_mixed_call(inst, func, ...) \ | |
350 | _Generic(inst->func(__VA_ARGS__), \ | |
351 | efi_status_t: \ | |
352 | __efi64_widen_efi_status( \ | |
353 | __efi64_thunk_map(inst, func, ##__VA_ARGS__)), \ | |
354 | u64: ({ BUILD_BUG(); ULONG_MAX; }), \ | |
355 | default: \ | |
356 | (__typeof__(inst->func(__VA_ARGS__))) \ | |
357 | __efi64_thunk_map(inst, func, ##__VA_ARGS__)) | |
3ba75c13 | 358 | |
de8c5520 AS |
359 | #else /* CONFIG_EFI_MIXED */ |
360 | ||
361 | static inline bool efi_is_64bit(void) | |
362 | { | |
363 | return IS_ENABLED(CONFIG_X86_64); | |
364 | } | |
365 | ||
366 | #endif /* CONFIG_EFI_MIXED */ | |
367 | ||
44be28e9 | 368 | extern bool efi_reboot_required(void); |
e55f31a5 | 369 | extern bool efi_is_table_address(unsigned long phys_addr); |
44be28e9 | 370 | |
6950e31b | 371 | extern void efi_reserve_boot_services(void); |
6b59e366 | 372 | #else |
5c12af0c | 373 | static inline void parse_efi_setup(u64 phys_addr, u32 data_len) {} |
44be28e9 MF |
374 | static inline bool efi_reboot_required(void) |
375 | { | |
376 | return false; | |
377 | } | |
e55f31a5 AB |
378 | static inline bool efi_is_table_address(unsigned long phys_addr) |
379 | { | |
380 | return false; | |
381 | } | |
6950e31b DW |
382 | static inline void efi_reserve_boot_services(void) |
383 | { | |
384 | } | |
7f594232 RA |
385 | #endif /* CONFIG_EFI */ |
386 | ||
199c8471 DW |
387 | #ifdef CONFIG_EFI_FAKE_MEMMAP |
388 | extern void __init efi_fake_memmap_early(void); | |
4059ba65 | 389 | extern void __init efi_fake_memmap(void); |
199c8471 DW |
390 | #else |
391 | static inline void efi_fake_memmap_early(void) | |
392 | { | |
393 | } | |
4059ba65 AB |
394 | |
395 | static inline void efi_fake_memmap(void) | |
396 | { | |
397 | } | |
199c8471 DW |
398 | #endif |
399 | ||
fdc6d38d AB |
400 | extern int __init efi_memmap_alloc(unsigned int num_entries, |
401 | struct efi_memory_map_data *data); | |
402 | extern void __efi_memmap_free(u64 phys, unsigned long size, | |
403 | unsigned long flags); | |
404 | #define __efi_memmap_free __efi_memmap_free | |
405 | ||
406 | extern int __init efi_memmap_install(struct efi_memory_map_data *data); | |
407 | extern int __init efi_memmap_split_count(efi_memory_desc_t *md, | |
408 | struct range *range); | |
409 | extern void __init efi_memmap_insert(struct efi_memory_map *old_memmap, | |
410 | void *buf, struct efi_mem_range *mem); | |
411 | ||
785ddc8b TZ |
412 | extern enum efi_secureboot_mode __x86_ima_efi_boot_mode(void); |
413 | ||
414 | #define arch_ima_efi_boot_mode __x86_ima_efi_boot_mode() | |
25519d68 | 415 | |
1fff234d AB |
416 | #ifdef CONFIG_EFI_RUNTIME_MAP |
417 | int efi_get_runtime_map_size(void); | |
418 | int efi_get_runtime_map_desc_size(void); | |
419 | int efi_runtime_map_copy(void *buf, size_t bufsz); | |
420 | #else | |
421 | static inline int efi_get_runtime_map_size(void) | |
422 | { | |
423 | return 0; | |
424 | } | |
425 | ||
426 | static inline int efi_get_runtime_map_desc_size(void) | |
427 | { | |
428 | return 0; | |
429 | } | |
430 | ||
431 | static inline int efi_runtime_map_copy(void *buf, size_t bufsz) | |
432 | { | |
433 | return 0; | |
434 | } | |
435 | ||
436 | #endif | |
437 | ||
1965aae3 | 438 | #endif /* _ASM_X86_EFI_H */ |