1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Helper functions used by the EFI stub on multiple
4  * architectures. This should be #included by the EFI stub
5  * implementation files.
6  *
7  * Copyright 2011 Intel Corporation; author Matt Fleming
8  */
9 
10 #include <linux/stdarg.h>
11 
12 #include <linux/efi.h>
13 #include <linux/kernel.h>
14 #include <asm/efi.h>
15 #include <asm/setup.h>
16 
17 #include "efistub.h"
18 
19 bool efi_nochunk;
20 bool efi_nokaslr = !IS_ENABLED(CONFIG_RANDOMIZE_BASE);
21 bool efi_novamap;
22 
23 static bool efi_noinitrd;
24 static bool efi_nosoftreserve;
25 static bool efi_disable_pci_dma = IS_ENABLED(CONFIG_EFI_DISABLE_PCI_DMA);
26 
27 int efi_mem_encrypt;
28 
29 bool __pure __efi_soft_reserve_enabled(void)
30 {
31 	return !efi_nosoftreserve;
32 }
33 
34 /**
35  * efi_parse_options() - Parse EFI command line options
36  * @cmdline:	kernel command line
37  *
38  * Parse the ASCII string @cmdline for EFI options, denoted by the efi=
39  * option, e.g. efi=nochunk.
40  *
41  * It should be noted that efi= is parsed in two very different
42  * environments, first in the early boot environment of the EFI boot
43  * stub, and subsequently during the kernel boot.
44  *
45  * Return:	status code
46  */
47 efi_status_t efi_parse_options(char const *cmdline)
48 {
49 	size_t len;
50 	efi_status_t status;
51 	char *str, *buf;
52 
53 	if (!cmdline)
54 		return EFI_SUCCESS;
55 
56 	len = strnlen(cmdline, COMMAND_LINE_SIZE - 1) + 1;
57 	status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, len, (void **)&buf);
58 	if (status != EFI_SUCCESS)
59 		return status;
60 
61 	memcpy(buf, cmdline, len - 1);
62 	buf[len - 1] = '\0';
63 	str = skip_spaces(buf);
64 
65 	while (*str) {
66 		char *param, *val;
67 
68 		str = next_arg(str, &param, &val);
69 		if (!val && !strcmp(param, "--"))
70 			break;
71 
72 		if (!strcmp(param, "nokaslr")) {
73 			efi_nokaslr = true;
74 		} else if (!strcmp(param, "quiet")) {
75 			efi_loglevel = CONSOLE_LOGLEVEL_QUIET;
76 		} else if (!strcmp(param, "noinitrd")) {
77 			efi_noinitrd = true;
78 		} else if (IS_ENABLED(CONFIG_X86_64) && !strcmp(param, "no5lvl")) {
79 			efi_no5lvl = true;
80 		} else if (IS_ENABLED(CONFIG_ARCH_HAS_MEM_ENCRYPT) &&
81 			   !strcmp(param, "mem_encrypt") && val) {
82 			if (parse_option_str(val, "on"))
83 				efi_mem_encrypt = 1;
84 			else if (parse_option_str(val, "off"))
85 				efi_mem_encrypt = -1;
86 		} else if (!strcmp(param, "efi") && val) {
87 			efi_nochunk = parse_option_str(val, "nochunk");
88 			efi_novamap |= parse_option_str(val, "novamap");
89 
90 			efi_nosoftreserve = IS_ENABLED(CONFIG_EFI_SOFT_RESERVE) &&
91 					    parse_option_str(val, "nosoftreserve");
92 
93 			if (parse_option_str(val, "disable_early_pci_dma"))
94 				efi_disable_pci_dma = true;
95 			if (parse_option_str(val, "no_disable_early_pci_dma"))
96 				efi_disable_pci_dma = false;
97 			if (parse_option_str(val, "debug"))
98 				efi_loglevel = CONSOLE_LOGLEVEL_DEBUG;
99 		} else if (!strcmp(param, "video") &&
100 			   val && strstarts(val, "efifb:")) {
101 			efi_parse_option_graphics(val + strlen("efifb:"));
102 		}
103 	}
104 	efi_bs_call(free_pool, buf);
105 	return EFI_SUCCESS;
106 }
107 
108 /*
109  * The EFI_LOAD_OPTION descriptor has the following layout:
110  *	u32 Attributes;
111  *	u16 FilePathListLength;
112  *	u16 Description[];
113  *	efi_device_path_protocol_t FilePathList[];
114  *	u8 OptionalData[];
115  *
116  * This function validates and unpacks the variable-size data fields.
117  */
118 static
119 bool efi_load_option_unpack(efi_load_option_unpacked_t *dest,
120 			    const efi_load_option_t *src, size_t size)
121 {
122 	const void *pos;
123 	u16 c;
124 	efi_device_path_protocol_t header;
125 	const efi_char16_t *description;
126 	const efi_device_path_protocol_t *file_path_list;
127 
128 	if (size < offsetof(efi_load_option_t, variable_data))
129 		return false;
130 	pos = src->variable_data;
131 	size -= offsetof(efi_load_option_t, variable_data);
132 
133 	if ((src->attributes & ~EFI_LOAD_OPTION_MASK) != 0)
134 		return false;
135 
136 	/* Scan description. */
137 	description = pos;
138 	do {
139 		if (size < sizeof(c))
140 			return false;
141 		c = *(const u16 *)pos;
142 		pos += sizeof(c);
143 		size -= sizeof(c);
144 	} while (c != L'\0');
145 
146 	/* Scan file_path_list. */
147 	file_path_list = pos;
148 	do {
149 		if (size < sizeof(header))
150 			return false;
151 		header = *(const efi_device_path_protocol_t *)pos;
152 		if (header.length < sizeof(header))
153 			return false;
154 		if (size < header.length)
155 			return false;
156 		pos += header.length;
157 		size -= header.length;
158 	} while ((header.type != EFI_DEV_END_PATH && header.type != EFI_DEV_END_PATH2) ||
159 		 (header.sub_type != EFI_DEV_END_ENTIRE));
160 	if (pos != (const void *)file_path_list + src->file_path_list_length)
161 		return false;
162 
163 	dest->attributes = src->attributes;
164 	dest->file_path_list_length = src->file_path_list_length;
165 	dest->description = description;
166 	dest->file_path_list = file_path_list;
167 	dest->optional_data_size = size;
168 	dest->optional_data = size ? pos : NULL;
169 
170 	return true;
171 }
172 
173 /*
174  * At least some versions of Dell firmware pass the entire contents of the
175  * Boot#### variable, i.e. the EFI_LOAD_OPTION descriptor, rather than just the
176  * OptionalData field.
177  *
178  * Detect this case and extract OptionalData.
179  */
180 void efi_apply_loadoptions_quirk(const void **load_options, u32 *load_options_size)
181 {
182 	const efi_load_option_t *load_option = *load_options;
183 	efi_load_option_unpacked_t load_option_unpacked;
184 
185 	if (!IS_ENABLED(CONFIG_X86))
186 		return;
187 	if (!load_option)
188 		return;
189 	if (*load_options_size < sizeof(*load_option))
190 		return;
191 	if ((load_option->attributes & ~EFI_LOAD_OPTION_BOOT_MASK) != 0)
192 		return;
193 
194 	if (!efi_load_option_unpack(&load_option_unpacked, load_option, *load_options_size))
195 		return;
196 
197 	efi_warn_once(FW_BUG "LoadOptions is an EFI_LOAD_OPTION descriptor\n");
198 	efi_warn_once(FW_BUG "Using OptionalData as a workaround\n");
199 
200 	*load_options = load_option_unpacked.optional_data;
201 	*load_options_size = load_option_unpacked.optional_data_size;
202 }
203 
204 enum efistub_event {
205 	EFISTUB_EVT_INITRD,
206 	EFISTUB_EVT_LOAD_OPTIONS,
207 	EFISTUB_EVT_COUNT,
208 };
209 
210 #define STR_WITH_SIZE(s)	sizeof(s), s
211 
212 static const struct {
213 	u32		pcr_index;
214 	u32		event_id;
215 	u32		event_data_len;
216 	u8		event_data[52];
217 } events[] = {
218 	[EFISTUB_EVT_INITRD] = {
219 		9,
220 		INITRD_EVENT_TAG_ID,
221 		STR_WITH_SIZE("Linux initrd")
222 	},
223 	[EFISTUB_EVT_LOAD_OPTIONS] = {
224 		9,
225 		LOAD_OPTIONS_EVENT_TAG_ID,
226 		STR_WITH_SIZE("LOADED_IMAGE::LoadOptions")
227 	},
228 };
229 
230 static efi_status_t efi_measure_tagged_event(unsigned long load_addr,
231 					     unsigned long load_size,
232 					     enum efistub_event event)
233 {
234 	efi_guid_t tcg2_guid = EFI_TCG2_PROTOCOL_GUID;
235 	efi_tcg2_protocol_t *tcg2 = NULL;
236 	efi_status_t status;
237 
238 	efi_bs_call(locate_protocol, &tcg2_guid, NULL, (void **)&tcg2);
239 	if (tcg2) {
240 		struct efi_measured_event {
241 			efi_tcg2_event_t	event_data;
242 			efi_tcg2_tagged_event_t tagged_event;
243 			u8			tagged_event_data[];
244 		} *evt;
245 		int size = sizeof(*evt) + events[event].event_data_len;
246 
247 		status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, size,
248 				     (void **)&evt);
249 		if (status != EFI_SUCCESS)
250 			goto fail;
251 
252 		evt->event_data = (struct efi_tcg2_event){
253 			.event_size			= size,
254 			.event_header.header_size	= sizeof(evt->event_data.event_header),
255 			.event_header.header_version	= EFI_TCG2_EVENT_HEADER_VERSION,
256 			.event_header.pcr_index		= events[event].pcr_index,
257 			.event_header.event_type	= EV_EVENT_TAG,
258 		};
259 
260 		evt->tagged_event = (struct efi_tcg2_tagged_event){
261 			.tagged_event_id		= events[event].event_id,
262 			.tagged_event_data_size		= events[event].event_data_len,
263 		};
264 
265 		memcpy(evt->tagged_event_data, events[event].event_data,
266 		       events[event].event_data_len);
267 
268 		status = efi_call_proto(tcg2, hash_log_extend_event, 0,
269 					load_addr, load_size, &evt->event_data);
270 		efi_bs_call(free_pool, evt);
271 
272 		if (status != EFI_SUCCESS)
273 			goto fail;
274 		return EFI_SUCCESS;
275 	}
276 
277 	return EFI_UNSUPPORTED;
278 fail:
279 	efi_warn("Failed to measure data for event %d: 0x%lx\n", event, status);
280 	return status;
281 }
282 
283 /*
284  * Convert the unicode UEFI command line to ASCII to pass to kernel.
285  * Size of memory allocated return in *cmd_line_len.
286  * Returns NULL on error.
287  */
288 char *efi_convert_cmdline(efi_loaded_image_t *image, int *cmd_line_len)
289 {
290 	const efi_char16_t *options = efi_table_attr(image, load_options);
291 	u32 options_size = efi_table_attr(image, load_options_size);
292 	int options_bytes = 0, safe_options_bytes = 0;  /* UTF-8 bytes */
293 	unsigned long cmdline_addr = 0;
294 	const efi_char16_t *s2;
295 	bool in_quote = false;
296 	efi_status_t status;
297 	u32 options_chars;
298 
299 	if (options_size > 0)
300 		efi_measure_tagged_event((unsigned long)options, options_size,
301 					 EFISTUB_EVT_LOAD_OPTIONS);
302 
303 	efi_apply_loadoptions_quirk((const void **)&options, &options_size);
304 	options_chars = options_size / sizeof(efi_char16_t);
305 
306 	if (options) {
307 		s2 = options;
308 		while (options_bytes < COMMAND_LINE_SIZE && options_chars--) {
309 			efi_char16_t c = *s2++;
310 
311 			if (c < 0x80) {
312 				if (c == L'\0' || c == L'\n')
313 					break;
314 				if (c == L'"')
315 					in_quote = !in_quote;
316 				else if (!in_quote && isspace((char)c))
317 					safe_options_bytes = options_bytes;
318 
319 				options_bytes++;
320 				continue;
321 			}
322 
323 			/*
324 			 * Get the number of UTF-8 bytes corresponding to a
325 			 * UTF-16 character.
326 			 * The first part handles everything in the BMP.
327 			 */
328 			options_bytes += 2 + (c >= 0x800);
329 			/*
330 			 * Add one more byte for valid surrogate pairs. Invalid
331 			 * surrogates will be replaced with 0xfffd and take up
332 			 * only 3 bytes.
333 			 */
334 			if ((c & 0xfc00) == 0xd800) {
335 				/*
336 				 * If the very last word is a high surrogate,
337 				 * we must ignore it since we can't access the
338 				 * low surrogate.
339 				 */
340 				if (!options_chars) {
341 					options_bytes -= 3;
342 				} else if ((*s2 & 0xfc00) == 0xdc00) {
343 					options_bytes++;
344 					options_chars--;
345 					s2++;
346 				}
347 			}
348 		}
349 		if (options_bytes >= COMMAND_LINE_SIZE) {
350 			options_bytes = safe_options_bytes;
351 			efi_err("Command line is too long: truncated to %d bytes\n",
352 				options_bytes);
353 		}
354 	}
355 
356 	options_bytes++;	/* NUL termination */
357 
358 	status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, options_bytes,
359 			     (void **)&cmdline_addr);
360 	if (status != EFI_SUCCESS)
361 		return NULL;
362 
363 	snprintf((char *)cmdline_addr, options_bytes, "%.*ls",
364 		 options_bytes - 1, options);
365 
366 	*cmd_line_len = options_bytes;
367 	return (char *)cmdline_addr;
368 }
369 
370 /**
371  * efi_exit_boot_services() - Exit boot services
372  * @handle:	handle of the exiting image
373  * @priv:	argument to be passed to @priv_func
374  * @priv_func:	function to process the memory map before exiting boot services
375  *
376  * Handle calling ExitBootServices according to the requirements set out by the
377  * spec.  Obtains the current memory map, and returns that info after calling
378  * ExitBootServices.  The client must specify a function to perform any
379  * processing of the memory map data prior to ExitBootServices.  A client
380  * specific structure may be passed to the function via priv.  The client
381  * function may be called multiple times.
382  *
383  * Return:	status code
384  */
385 efi_status_t efi_exit_boot_services(void *handle, void *priv,
386 				    efi_exit_boot_map_processing priv_func)
387 {
388 	struct efi_boot_memmap *map;
389 	efi_status_t status;
390 
391 	if (efi_disable_pci_dma)
392 		efi_pci_disable_bridge_busmaster();
393 
394 	status = efi_get_memory_map(&map, true);
395 	if (status != EFI_SUCCESS)
396 		return status;
397 
398 	status = priv_func(map, priv);
399 	if (status != EFI_SUCCESS) {
400 		efi_bs_call(free_pool, map);
401 		return status;
402 	}
403 
404 	status = efi_bs_call(exit_boot_services, handle, map->map_key);
405 
406 	if (status == EFI_INVALID_PARAMETER) {
407 		/*
408 		 * The memory map changed between efi_get_memory_map() and
409 		 * exit_boot_services().  Per the UEFI Spec v2.6, Section 6.4:
410 		 * EFI_BOOT_SERVICES.ExitBootServices we need to get the
411 		 * updated map, and try again.  The spec implies one retry
412 		 * should be sufficent, which is confirmed against the EDK2
413 		 * implementation.  Per the spec, we can only invoke
414 		 * get_memory_map() and exit_boot_services() - we cannot alloc
415 		 * so efi_get_memory_map() cannot be used, and we must reuse
416 		 * the buffer.  For all practical purposes, the headroom in the
417 		 * buffer should account for any changes in the map so the call
418 		 * to get_memory_map() is expected to succeed here.
419 		 */
420 		map->map_size = map->buff_size;
421 		status = efi_bs_call(get_memory_map,
422 				     &map->map_size,
423 				     &map->map,
424 				     &map->map_key,
425 				     &map->desc_size,
426 				     &map->desc_ver);
427 
428 		/* exit_boot_services() was called, thus cannot free */
429 		if (status != EFI_SUCCESS)
430 			return status;
431 
432 		status = priv_func(map, priv);
433 		/* exit_boot_services() was called, thus cannot free */
434 		if (status != EFI_SUCCESS)
435 			return status;
436 
437 		status = efi_bs_call(exit_boot_services, handle, map->map_key);
438 	}
439 
440 	return status;
441 }
442 
443 /**
444  * get_efi_config_table() - retrieve UEFI configuration table
445  * @guid:	GUID of the configuration table to be retrieved
446  * Return:	pointer to the configuration table or NULL
447  */
448 void *get_efi_config_table(efi_guid_t guid)
449 {
450 	unsigned long tables = efi_table_attr(efi_system_table, tables);
451 	int nr_tables = efi_table_attr(efi_system_table, nr_tables);
452 	int i;
453 
454 	for (i = 0; i < nr_tables; i++) {
455 		efi_config_table_t *t = (void *)tables;
456 
457 		if (efi_guidcmp(t->guid, guid) == 0)
458 			return efi_table_attr(t, table);
459 
460 		tables += efi_is_native() ? sizeof(efi_config_table_t)
461 					  : sizeof(efi_config_table_32_t);
462 	}
463 	return NULL;
464 }
465 
466 /*
467  * The LINUX_EFI_INITRD_MEDIA_GUID vendor media device path below provides a way
468  * for the firmware or bootloader to expose the initrd data directly to the stub
469  * via the trivial LoadFile2 protocol, which is defined in the UEFI spec, and is
470  * very easy to implement. It is a simple Linux initrd specific conduit between
471  * kernel and firmware, allowing us to put the EFI stub (being part of the
472  * kernel) in charge of where and when to load the initrd, while leaving it up
473  * to the firmware to decide whether it needs to expose its filesystem hierarchy
474  * via EFI protocols.
475  */
476 static const struct {
477 	struct efi_vendor_dev_path	vendor;
478 	struct efi_generic_dev_path	end;
479 } __packed initrd_dev_path = {
480 	{
481 		{
482 			EFI_DEV_MEDIA,
483 			EFI_DEV_MEDIA_VENDOR,
484 			sizeof(struct efi_vendor_dev_path),
485 		},
486 		LINUX_EFI_INITRD_MEDIA_GUID
487 	}, {
488 		EFI_DEV_END_PATH,
489 		EFI_DEV_END_ENTIRE,
490 		sizeof(struct efi_generic_dev_path)
491 	}
492 };
493 
494 /**
495  * efi_load_initrd_dev_path() - load the initrd from the Linux initrd device path
496  * @initrd:	pointer of struct to store the address where the initrd was loaded
497  *		and the size of the loaded initrd
498  * @max:	upper limit for the initrd memory allocation
499  *
500  * Return:
501  * * %EFI_SUCCESS if the initrd was loaded successfully, in which
502  *   case @load_addr and @load_size are assigned accordingly
503  * * %EFI_NOT_FOUND if no LoadFile2 protocol exists on the initrd device path
504  * * %EFI_OUT_OF_RESOURCES if memory allocation failed
505  * * %EFI_LOAD_ERROR in all other cases
506  */
507 static
508 efi_status_t efi_load_initrd_dev_path(struct linux_efi_initrd *initrd,
509 				      unsigned long max)
510 {
511 	efi_guid_t lf2_proto_guid = EFI_LOAD_FILE2_PROTOCOL_GUID;
512 	efi_device_path_protocol_t *dp;
513 	efi_load_file2_protocol_t *lf2;
514 	efi_handle_t handle;
515 	efi_status_t status;
516 
517 	dp = (efi_device_path_protocol_t *)&initrd_dev_path;
518 	status = efi_bs_call(locate_device_path, &lf2_proto_guid, &dp, &handle);
519 	if (status != EFI_SUCCESS)
520 		return status;
521 
522 	status = efi_bs_call(handle_protocol, handle, &lf2_proto_guid,
523 			     (void **)&lf2);
524 	if (status != EFI_SUCCESS)
525 		return status;
526 
527 	initrd->size = 0;
528 	status = efi_call_proto(lf2, load_file, dp, false, &initrd->size, NULL);
529 	if (status != EFI_BUFFER_TOO_SMALL)
530 		return EFI_LOAD_ERROR;
531 
532 	status = efi_allocate_pages(initrd->size, &initrd->base, max);
533 	if (status != EFI_SUCCESS)
534 		return status;
535 
536 	status = efi_call_proto(lf2, load_file, dp, false, &initrd->size,
537 				(void *)initrd->base);
538 	if (status != EFI_SUCCESS) {
539 		efi_free(initrd->size, initrd->base);
540 		return EFI_LOAD_ERROR;
541 	}
542 	return EFI_SUCCESS;
543 }
544 
545 static
546 efi_status_t efi_load_initrd_cmdline(efi_loaded_image_t *image,
547 				     struct linux_efi_initrd *initrd,
548 				     unsigned long soft_limit,
549 				     unsigned long hard_limit)
550 {
551 	if (image == NULL)
552 		return EFI_UNSUPPORTED;
553 
554 	return handle_cmdline_files(image, L"initrd=", sizeof(L"initrd=") - 2,
555 				    soft_limit, hard_limit,
556 				    &initrd->base, &initrd->size);
557 }
558 
559 /**
560  * efi_load_initrd() - Load initial RAM disk
561  * @image:	EFI loaded image protocol
562  * @soft_limit:	preferred address for loading the initrd
563  * @hard_limit:	upper limit address for loading the initrd
564  *
565  * Return:	status code
566  */
567 efi_status_t efi_load_initrd(efi_loaded_image_t *image,
568 			     unsigned long soft_limit,
569 			     unsigned long hard_limit,
570 			     const struct linux_efi_initrd **out)
571 {
572 	efi_guid_t tbl_guid = LINUX_EFI_INITRD_MEDIA_GUID;
573 	efi_status_t status = EFI_SUCCESS;
574 	struct linux_efi_initrd initrd, *tbl;
575 
576 	if (!IS_ENABLED(CONFIG_BLK_DEV_INITRD) || efi_noinitrd)
577 		return EFI_SUCCESS;
578 
579 	status = efi_load_initrd_dev_path(&initrd, hard_limit);
580 	if (status == EFI_SUCCESS) {
581 		efi_info("Loaded initrd from LINUX_EFI_INITRD_MEDIA_GUID device path\n");
582 		if (initrd.size > 0 &&
583 		    efi_measure_tagged_event(initrd.base, initrd.size,
584 					     EFISTUB_EVT_INITRD) == EFI_SUCCESS)
585 			efi_info("Measured initrd data into PCR 9\n");
586 	} else if (status == EFI_NOT_FOUND) {
587 		status = efi_load_initrd_cmdline(image, &initrd, soft_limit,
588 						 hard_limit);
589 		/* command line loader disabled or no initrd= passed? */
590 		if (status == EFI_UNSUPPORTED || status == EFI_NOT_READY)
591 			return EFI_SUCCESS;
592 		if (status == EFI_SUCCESS)
593 			efi_info("Loaded initrd from command line option\n");
594 	}
595 	if (status != EFI_SUCCESS)
596 		goto failed;
597 
598 	status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, sizeof(initrd),
599 			     (void **)&tbl);
600 	if (status != EFI_SUCCESS)
601 		goto free_initrd;
602 
603 	*tbl = initrd;
604 	status = efi_bs_call(install_configuration_table, &tbl_guid, tbl);
605 	if (status != EFI_SUCCESS)
606 		goto free_tbl;
607 
608 	if (out)
609 		*out = tbl;
610 	return EFI_SUCCESS;
611 
612 free_tbl:
613 	efi_bs_call(free_pool, tbl);
614 free_initrd:
615 	efi_free(initrd.size, initrd.base);
616 failed:
617 	efi_err("Failed to load initrd: 0x%lx\n", status);
618 	return status;
619 }
620 
621 /**
622  * efi_wait_for_key() - Wait for key stroke
623  * @usec:	number of microseconds to wait for key stroke
624  * @key:	key entered
625  *
626  * Wait for up to @usec microseconds for a key stroke.
627  *
628  * Return:	status code, EFI_SUCCESS if key received
629  */
630 efi_status_t efi_wait_for_key(unsigned long usec, efi_input_key_t *key)
631 {
632 	efi_event_t events[2], timer;
633 	unsigned long index;
634 	efi_simple_text_input_protocol_t *con_in;
635 	efi_status_t status;
636 
637 	con_in = efi_table_attr(efi_system_table, con_in);
638 	if (!con_in)
639 		return EFI_UNSUPPORTED;
640 	efi_set_event_at(events, 0, efi_table_attr(con_in, wait_for_key));
641 
642 	status = efi_bs_call(create_event, EFI_EVT_TIMER, 0, NULL, NULL, &timer);
643 	if (status != EFI_SUCCESS)
644 		return status;
645 
646 	status = efi_bs_call(set_timer, timer, EfiTimerRelative,
647 			     EFI_100NSEC_PER_USEC * usec);
648 	if (status != EFI_SUCCESS)
649 		return status;
650 	efi_set_event_at(events, 1, timer);
651 
652 	status = efi_bs_call(wait_for_event, 2, events, &index);
653 	if (status == EFI_SUCCESS) {
654 		if (index == 0)
655 			status = efi_call_proto(con_in, read_keystroke, key);
656 		else
657 			status = EFI_TIMEOUT;
658 	}
659 
660 	efi_bs_call(close_event, timer);
661 
662 	return status;
663 }
664 
665 /**
666  * efi_remap_image - Remap a loaded image with the appropriate permissions
667  *                   for code and data
668  *
669  * @image_base:	the base of the image in memory
670  * @alloc_size:	the size of the area in memory occupied by the image
671  * @code_size:	the size of the leading part of the image containing code
672  * 		and read-only data
673  *
674  * efi_remap_image() uses the EFI memory attribute protocol to remap the code
675  * region of the loaded image read-only/executable, and the remainder
676  * read-write/non-executable. The code region is assumed to start at the base
677  * of the image, and will therefore cover the PE/COFF header as well.
678  */
679 void efi_remap_image(unsigned long image_base, unsigned alloc_size,
680 		     unsigned long code_size)
681 {
682 	efi_guid_t guid = EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID;
683 	efi_memory_attribute_protocol_t *memattr;
684 	efi_status_t status;
685 	u64 attr;
686 
687 	/*
688 	 * If the firmware implements the EFI_MEMORY_ATTRIBUTE_PROTOCOL, let's
689 	 * invoke it to remap the text/rodata region of the decompressed image
690 	 * as read-only and the data/bss region as non-executable.
691 	 */
692 	status = efi_bs_call(locate_protocol, &guid, NULL, (void **)&memattr);
693 	if (status != EFI_SUCCESS)
694 		return;
695 
696 	// Get the current attributes for the entire region
697 	status = memattr->get_memory_attributes(memattr, image_base,
698 						alloc_size, &attr);
699 	if (status != EFI_SUCCESS) {
700 		efi_warn("Failed to retrieve memory attributes for image region: 0x%lx\n",
701 			 status);
702 		return;
703 	}
704 
705 	// Mark the code region as read-only
706 	status = memattr->set_memory_attributes(memattr, image_base, code_size,
707 						EFI_MEMORY_RO);
708 	if (status != EFI_SUCCESS) {
709 		efi_warn("Failed to remap code region read-only\n");
710 		return;
711 	}
712 
713 	// If the entire region was already mapped as non-exec, clear the
714 	// attribute from the code region. Otherwise, set it on the data
715 	// region.
716 	if (attr & EFI_MEMORY_XP) {
717 		status = memattr->clear_memory_attributes(memattr, image_base,
718 							  code_size,
719 							  EFI_MEMORY_XP);
720 		if (status != EFI_SUCCESS)
721 			efi_warn("Failed to remap code region executable\n");
722 	} else {
723 		status = memattr->set_memory_attributes(memattr,
724 							image_base + code_size,
725 							alloc_size - code_size,
726 							EFI_MEMORY_XP);
727 		if (status != EFI_SUCCESS)
728 			efi_warn("Failed to remap data region non-executable\n");
729 	}
730 }
731