1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef _ASM_X86_EFI_H |
3 | #define _ASM_X86_EFI_H |
4 | |
5 | #include <asm/fpu/api.h> |
6 | #include <asm/processor-flags.h> |
7 | #include <asm/tlb.h> |
8 | #include <asm/nospec-branch.h> |
9 | #include <asm/mmu_context.h> |
10 | #include <asm/ibt.h> |
11 | #include <linux/build_bug.h> |
12 | #include <linux/kernel.h> |
13 | #include <linux/pgtable.h> |
14 | |
15 | extern unsigned long efi_fw_vendor, efi_config_table; |
16 | extern unsigned long efi_mixed_mode_stack_pa; |
17 | |
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. |
27 | */ |
28 | |
29 | #define EFI32_LOADER_SIGNATURE "EL32" |
30 | #define EFI64_LOADER_SIGNATURE "EL64" |
31 | |
32 | #define ARCH_EFI_IRQ_FLAGS_MASK X86_EFLAGS_IF |
33 | |
34 | #define EFI_UNACCEPTED_UNIT_SIZE PMD_SIZE |
35 | |
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__, \ |
52 | __efi_arg_sentinel(9), __efi_arg_sentinel(8), \ |
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)) |
57 | #define __efi_nargs__(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, n, ...) \ |
58 | __take_second_arg(n, \ |
59 | ({ BUILD_BUG_ON_MSG(1, "__efi_nargs limit exceeded"); 10; })) |
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 | |
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 | |
92 | #ifdef CONFIG_X86_32 |
93 | #define EFI_X86_KERNEL_ALLOC_LIMIT (SZ_512M - 1) |
94 | #else /* !CONFIG_X86_32 */ |
95 | #define EFI_X86_KERNEL_ALLOC_LIMIT EFI_ALLOC_LIMIT |
96 | |
97 | extern asmlinkage u64 __efi_call(void *fp, ...); |
98 | |
99 | extern bool efi_disable_ibt_for_runtime; |
100 | |
101 | #define efi_call(...) ({ \ |
102 | __efi_nargs_check(efi_call, 7, __VA_ARGS__); \ |
103 | __efi_call(__VA_ARGS__); \ |
104 | }) |
105 | |
106 | #undef arch_efi_call_virt |
107 | #define arch_efi_call_virt(p, f, args...) ({ \ |
108 | u64 ret, ibt = ibt_save(efi_disable_ibt_for_runtime); \ |
109 | ret = efi_call((void *)p->f, args); \ |
110 | ibt_restore(ibt); \ |
111 | ret; \ |
112 | }) |
113 | |
114 | #ifdef CONFIG_KASAN |
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 |
124 | #endif |
125 | |
126 | #endif /* CONFIG_X86_32 */ |
127 | |
128 | extern int __init efi_memblock_x86_reserve_range(void); |
129 | extern void __init efi_print_memmap(void); |
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 int __init efi_alloc_page_tables(void); |
134 | extern int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages); |
135 | extern void __init efi_runtime_update_mappings(void); |
136 | extern void __init efi_dump_pagetable(void); |
137 | extern void __init efi_apply_memmap_quirks(void); |
138 | extern int __init efi_reuse_config(u64 tables, int nr_tables); |
139 | extern void efi_delete_dummy_variable(void); |
140 | extern void efi_crash_gracefully_on_page_fault(unsigned long phys_addr); |
141 | extern void efi_free_boot_services(void); |
142 | |
143 | void arch_efi_call_virt_setup(void); |
144 | void arch_efi_call_virt_teardown(void); |
145 | |
146 | extern u64 efi_setup; |
147 | |
148 | #ifdef CONFIG_EFI |
149 | extern u64 __efi64_thunk(u32, ...); |
150 | |
151 | #define efi64_thunk(...) ({ \ |
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); \ |
155 | }) |
156 | |
157 | static inline bool efi_is_mixed(void) |
158 | { |
159 | if (!IS_ENABLED(CONFIG_EFI_MIXED)) |
160 | return false; |
161 | return IS_ENABLED(CONFIG_X86_64) && !efi_enabled(EFI_64BIT); |
162 | } |
163 | |
164 | static inline bool efi_runtime_supported(void) |
165 | { |
166 | if (IS_ENABLED(CONFIG_X86_64) == efi_enabled(EFI_64BIT)) |
167 | return true; |
168 | |
169 | return IS_ENABLED(CONFIG_EFI_MIXED); |
170 | } |
171 | |
172 | extern void parse_efi_setup(u64 phys_addr, u32 data_len); |
173 | |
174 | extern void efi_thunk_runtime_setup(void); |
175 | efi_status_t efi_set_virtual_address_map(unsigned long memory_map_size, |
176 | unsigned long descriptor_size, |
177 | u32 descriptor_version, |
178 | efi_memory_desc_t *virtual_map, |
179 | unsigned long systab_phys); |
180 | |
181 | /* arch specific definitions used by the stub code */ |
182 | |
183 | #ifdef CONFIG_EFI_MIXED |
184 | |
185 | #define EFI_ALLOC_LIMIT (efi_is_64bit() ? ULONG_MAX : U32_MAX) |
186 | |
187 | #define ARCH_HAS_EFISTUB_WRAPPERS |
188 | |
189 | static inline bool efi_is_64bit(void) |
190 | { |
191 | extern const bool efi_is64; |
192 | |
193 | return efi_is64; |
194 | } |
195 | |
196 | static inline bool efi_is_native(void) |
197 | { |
198 | return efi_is_64bit(); |
199 | } |
200 | |
201 | #define efi_table_attr(inst, attr) \ |
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)) |
210 | |
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 | |
236 | static inline u32 efi64_convert_status(efi_status_t status) |
237 | { |
238 | return (u32)(status | (u64)status >> 32); |
239 | } |
240 | |
241 | #define __efi64_split(val) (val) & U32_MAX, (u64)(val) >> 32 |
242 | |
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 | |
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 | |
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 | |
267 | #define __efi64_argmap_locate_device_path(protocol, path, handle) \ |
268 | ((protocol), (path), efi64_zero_upper(handle)) |
269 | |
270 | #define __efi64_argmap_exit(handle, status, size, data) \ |
271 | ((handle), efi64_convert_status(status), (size), (data)) |
272 | |
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 | |
278 | /* LoadFile */ |
279 | #define __efi64_argmap_load_file(protocol, path, policy, bufsize, buf) \ |
280 | ((protocol), (path), (policy), efi64_zero_upper(bufsize), (buf)) |
281 | |
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 | |
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 | |
290 | /* DXE services */ |
291 | #define __efi64_argmap_get_memory_space_descriptor(phys, desc) \ |
292 | (__efi64_split(phys), (desc)) |
293 | |
294 | #define __efi64_argmap_set_memory_space_attributes(phys, size, flags) \ |
295 | (__efi64_split(phys), __efi64_split(size), __efi64_split(flags)) |
296 | |
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 | |
308 | /* Memory Attribute Protocol */ |
309 | #define __efi64_argmap_get_memory_attributes(protocol, phys, size, flags) \ |
310 | ((protocol), __efi64_split(phys), __efi64_split(size), (flags)) |
311 | |
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 | |
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 | |
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(word: rol32(word: status, shift: 1), shift: 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__)) |
358 | |
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 | |
368 | extern bool efi_reboot_required(void); |
369 | extern bool efi_is_table_address(unsigned long phys_addr); |
370 | |
371 | extern void efi_reserve_boot_services(void); |
372 | #else |
373 | static inline void parse_efi_setup(u64 phys_addr, u32 data_len) {} |
374 | static inline bool efi_reboot_required(void) |
375 | { |
376 | return false; |
377 | } |
378 | static inline bool efi_is_table_address(unsigned long phys_addr) |
379 | { |
380 | return false; |
381 | } |
382 | static inline void efi_reserve_boot_services(void) |
383 | { |
384 | } |
385 | #endif /* CONFIG_EFI */ |
386 | |
387 | #ifdef CONFIG_EFI_FAKE_MEMMAP |
388 | extern void __init efi_fake_memmap_early(void); |
389 | extern void __init efi_fake_memmap(void); |
390 | #else |
391 | static inline void efi_fake_memmap_early(void) |
392 | { |
393 | } |
394 | |
395 | static inline void efi_fake_memmap(void) |
396 | { |
397 | } |
398 | #endif |
399 | |
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 | |
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() |
415 | |
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 | |
438 | #endif /* _ASM_X86_EFI_H */ |
439 | |