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