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 <stdarg.h>
11 
12 #include <linux/efi.h>
13 #include <linux/kernel.h>
14 #include <asm/efi.h>
15 
16 #include "efistub.h"
17 
18 bool efi_nochunk;
19 bool efi_nokaslr;
20 bool efi_noinitrd;
21 bool efi_quiet;
22 bool efi_novamap;
23 
24 static bool efi_nosoftreserve;
25 static bool efi_disable_pci_dma = IS_ENABLED(CONFIG_EFI_DISABLE_PCI_DMA);
26 
27 bool __pure __efi_soft_reserve_enabled(void)
28 {
29 	return !efi_nosoftreserve;
30 }
31 
32 void efi_char16_puts(efi_char16_t *str)
33 {
34 	efi_call_proto(efi_table_attr(efi_system_table, con_out),
35 		       output_string, str);
36 }
37 
38 void efi_puts(const char *str)
39 {
40 	efi_char16_t buf[128];
41 	size_t pos = 0, lim = ARRAY_SIZE(buf);
42 
43 	while (*str) {
44 		if (*str == '\n')
45 			buf[pos++] = L'\r';
46 		/* Cast to unsigned char to avoid sign-extension */
47 		buf[pos++] = (unsigned char)(*str++);
48 		if (*str == '\0' || pos >= lim - 2) {
49 			buf[pos] = L'\0';
50 			efi_char16_puts(buf);
51 			pos = 0;
52 		}
53 	}
54 }
55 
56 int efi_printk(const char *fmt, ...)
57 {
58 	char printf_buf[256];
59 	va_list args;
60 	int printed;
61 
62 	va_start(args, fmt);
63 	printed = vsnprintf(printf_buf, sizeof(printf_buf), fmt, args);
64 	va_end(args);
65 
66 	efi_puts(printf_buf);
67 	if (printed >= sizeof(printf_buf)) {
68 		efi_puts("[Message truncated]\n");
69 		return -1;
70 	}
71 
72 	return printed;
73 }
74 
75 /*
76  * Parse the ASCII string 'cmdline' for EFI options, denoted by the efi=
77  * option, e.g. efi=nochunk.
78  *
79  * It should be noted that efi= is parsed in two very different
80  * environments, first in the early boot environment of the EFI boot
81  * stub, and subsequently during the kernel boot.
82  */
83 efi_status_t efi_parse_options(char const *cmdline)
84 {
85 	size_t len = strlen(cmdline) + 1;
86 	efi_status_t status;
87 	char *str, *buf;
88 
89 	status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, len, (void **)&buf);
90 	if (status != EFI_SUCCESS)
91 		return status;
92 
93 	str = skip_spaces(memcpy(buf, cmdline, len));
94 
95 	while (*str) {
96 		char *param, *val;
97 
98 		str = next_arg(str, &param, &val);
99 
100 		if (!strcmp(param, "nokaslr")) {
101 			efi_nokaslr = true;
102 		} else if (!strcmp(param, "quiet")) {
103 			efi_quiet = true;
104 		} else if (!strcmp(param, "noinitrd")) {
105 			efi_noinitrd = true;
106 		} else if (!strcmp(param, "efi") && val) {
107 			efi_nochunk = parse_option_str(val, "nochunk");
108 			efi_novamap = parse_option_str(val, "novamap");
109 
110 			efi_nosoftreserve = IS_ENABLED(CONFIG_EFI_SOFT_RESERVE) &&
111 					    parse_option_str(val, "nosoftreserve");
112 
113 			if (parse_option_str(val, "disable_early_pci_dma"))
114 				efi_disable_pci_dma = true;
115 			if (parse_option_str(val, "no_disable_early_pci_dma"))
116 				efi_disable_pci_dma = false;
117 		} else if (!strcmp(param, "video") &&
118 			   val && strstarts(val, "efifb:")) {
119 			efi_parse_option_graphics(val + strlen("efifb:"));
120 		}
121 	}
122 	efi_bs_call(free_pool, buf);
123 	return EFI_SUCCESS;
124 }
125 
126 /*
127  * Get the number of UTF-8 bytes corresponding to an UTF-16 character.
128  * This overestimates for surrogates, but that is okay.
129  */
130 static int efi_utf8_bytes(u16 c)
131 {
132 	return 1 + (c >= 0x80) + (c >= 0x800);
133 }
134 
135 /*
136  * Convert an UTF-16 string, not necessarily null terminated, to UTF-8.
137  */
138 static u8 *efi_utf16_to_utf8(u8 *dst, const u16 *src, int n)
139 {
140 	unsigned int c;
141 
142 	while (n--) {
143 		c = *src++;
144 		if (n && c >= 0xd800 && c <= 0xdbff &&
145 		    *src >= 0xdc00 && *src <= 0xdfff) {
146 			c = 0x10000 + ((c & 0x3ff) << 10) + (*src & 0x3ff);
147 			src++;
148 			n--;
149 		}
150 		if (c >= 0xd800 && c <= 0xdfff)
151 			c = 0xfffd; /* Unmatched surrogate */
152 		if (c < 0x80) {
153 			*dst++ = c;
154 			continue;
155 		}
156 		if (c < 0x800) {
157 			*dst++ = 0xc0 + (c >> 6);
158 			goto t1;
159 		}
160 		if (c < 0x10000) {
161 			*dst++ = 0xe0 + (c >> 12);
162 			goto t2;
163 		}
164 		*dst++ = 0xf0 + (c >> 18);
165 		*dst++ = 0x80 + ((c >> 12) & 0x3f);
166 	t2:
167 		*dst++ = 0x80 + ((c >> 6) & 0x3f);
168 	t1:
169 		*dst++ = 0x80 + (c & 0x3f);
170 	}
171 
172 	return dst;
173 }
174 
175 /*
176  * Convert the unicode UEFI command line to ASCII to pass to kernel.
177  * Size of memory allocated return in *cmd_line_len.
178  * Returns NULL on error.
179  */
180 char *efi_convert_cmdline(efi_loaded_image_t *image,
181 			  int *cmd_line_len, unsigned long max_addr)
182 {
183 	const u16 *s2;
184 	u8 *s1 = NULL;
185 	unsigned long cmdline_addr = 0;
186 	int load_options_chars = efi_table_attr(image, load_options_size) / 2;
187 	const u16 *options = efi_table_attr(image, load_options);
188 	int options_bytes = 0;  /* UTF-8 bytes */
189 	int options_chars = 0;  /* UTF-16 chars */
190 	efi_status_t status;
191 	u16 zero = 0;
192 
193 	if (options) {
194 		s2 = options;
195 		while (*s2 && *s2 != '\n'
196 		       && options_chars < load_options_chars) {
197 			options_bytes += efi_utf8_bytes(*s2++);
198 			options_chars++;
199 		}
200 	}
201 
202 	if (!options_chars) {
203 		/* No command line options, so return empty string*/
204 		options = &zero;
205 	}
206 
207 	options_bytes++;	/* NUL termination */
208 
209 	status = efi_allocate_pages(options_bytes, &cmdline_addr, max_addr);
210 	if (status != EFI_SUCCESS)
211 		return NULL;
212 
213 	s1 = (u8 *)cmdline_addr;
214 	s2 = (const u16 *)options;
215 
216 	s1 = efi_utf16_to_utf8(s1, s2, options_chars);
217 	*s1 = '\0';
218 
219 	*cmd_line_len = options_bytes;
220 	return (char *)cmdline_addr;
221 }
222 
223 /*
224  * Handle calling ExitBootServices according to the requirements set out by the
225  * spec.  Obtains the current memory map, and returns that info after calling
226  * ExitBootServices.  The client must specify a function to perform any
227  * processing of the memory map data prior to ExitBootServices.  A client
228  * specific structure may be passed to the function via priv.  The client
229  * function may be called multiple times.
230  */
231 efi_status_t efi_exit_boot_services(void *handle,
232 				    struct efi_boot_memmap *map,
233 				    void *priv,
234 				    efi_exit_boot_map_processing priv_func)
235 {
236 	efi_status_t status;
237 
238 	status = efi_get_memory_map(map);
239 
240 	if (status != EFI_SUCCESS)
241 		goto fail;
242 
243 	status = priv_func(map, priv);
244 	if (status != EFI_SUCCESS)
245 		goto free_map;
246 
247 	if (efi_disable_pci_dma)
248 		efi_pci_disable_bridge_busmaster();
249 
250 	status = efi_bs_call(exit_boot_services, handle, *map->key_ptr);
251 
252 	if (status == EFI_INVALID_PARAMETER) {
253 		/*
254 		 * The memory map changed between efi_get_memory_map() and
255 		 * exit_boot_services().  Per the UEFI Spec v2.6, Section 6.4:
256 		 * EFI_BOOT_SERVICES.ExitBootServices we need to get the
257 		 * updated map, and try again.  The spec implies one retry
258 		 * should be sufficent, which is confirmed against the EDK2
259 		 * implementation.  Per the spec, we can only invoke
260 		 * get_memory_map() and exit_boot_services() - we cannot alloc
261 		 * so efi_get_memory_map() cannot be used, and we must reuse
262 		 * the buffer.  For all practical purposes, the headroom in the
263 		 * buffer should account for any changes in the map so the call
264 		 * to get_memory_map() is expected to succeed here.
265 		 */
266 		*map->map_size = *map->buff_size;
267 		status = efi_bs_call(get_memory_map,
268 				     map->map_size,
269 				     *map->map,
270 				     map->key_ptr,
271 				     map->desc_size,
272 				     map->desc_ver);
273 
274 		/* exit_boot_services() was called, thus cannot free */
275 		if (status != EFI_SUCCESS)
276 			goto fail;
277 
278 		status = priv_func(map, priv);
279 		/* exit_boot_services() was called, thus cannot free */
280 		if (status != EFI_SUCCESS)
281 			goto fail;
282 
283 		status = efi_bs_call(exit_boot_services, handle, *map->key_ptr);
284 	}
285 
286 	/* exit_boot_services() was called, thus cannot free */
287 	if (status != EFI_SUCCESS)
288 		goto fail;
289 
290 	return EFI_SUCCESS;
291 
292 free_map:
293 	efi_bs_call(free_pool, *map->map);
294 fail:
295 	return status;
296 }
297 
298 void *get_efi_config_table(efi_guid_t guid)
299 {
300 	unsigned long tables = efi_table_attr(efi_system_table, tables);
301 	int nr_tables = efi_table_attr(efi_system_table, nr_tables);
302 	int i;
303 
304 	for (i = 0; i < nr_tables; i++) {
305 		efi_config_table_t *t = (void *)tables;
306 
307 		if (efi_guidcmp(t->guid, guid) == 0)
308 			return efi_table_attr(t, table);
309 
310 		tables += efi_is_native() ? sizeof(efi_config_table_t)
311 					  : sizeof(efi_config_table_32_t);
312 	}
313 	return NULL;
314 }
315 
316 /*
317  * The LINUX_EFI_INITRD_MEDIA_GUID vendor media device path below provides a way
318  * for the firmware or bootloader to expose the initrd data directly to the stub
319  * via the trivial LoadFile2 protocol, which is defined in the UEFI spec, and is
320  * very easy to implement. It is a simple Linux initrd specific conduit between
321  * kernel and firmware, allowing us to put the EFI stub (being part of the
322  * kernel) in charge of where and when to load the initrd, while leaving it up
323  * to the firmware to decide whether it needs to expose its filesystem hierarchy
324  * via EFI protocols.
325  */
326 static const struct {
327 	struct efi_vendor_dev_path	vendor;
328 	struct efi_generic_dev_path	end;
329 } __packed initrd_dev_path = {
330 	{
331 		{
332 			EFI_DEV_MEDIA,
333 			EFI_DEV_MEDIA_VENDOR,
334 			sizeof(struct efi_vendor_dev_path),
335 		},
336 		LINUX_EFI_INITRD_MEDIA_GUID
337 	}, {
338 		EFI_DEV_END_PATH,
339 		EFI_DEV_END_ENTIRE,
340 		sizeof(struct efi_generic_dev_path)
341 	}
342 };
343 
344 /**
345  * efi_load_initrd_dev_path - load the initrd from the Linux initrd device path
346  * @load_addr:	pointer to store the address where the initrd was loaded
347  * @load_size:	pointer to store the size of the loaded initrd
348  * @max:	upper limit for the initrd memory allocation
349  * @return:	%EFI_SUCCESS if the initrd was loaded successfully, in which
350  *		case @load_addr and @load_size are assigned accordingly
351  *		%EFI_NOT_FOUND if no LoadFile2 protocol exists on the initrd
352  *		device path
353  *		%EFI_INVALID_PARAMETER if load_addr == NULL or load_size == NULL
354  *		%EFI_OUT_OF_RESOURCES if memory allocation failed
355  *		%EFI_LOAD_ERROR in all other cases
356  */
357 static
358 efi_status_t efi_load_initrd_dev_path(unsigned long *load_addr,
359 				      unsigned long *load_size,
360 				      unsigned long max)
361 {
362 	efi_guid_t lf2_proto_guid = EFI_LOAD_FILE2_PROTOCOL_GUID;
363 	efi_device_path_protocol_t *dp;
364 	efi_load_file2_protocol_t *lf2;
365 	unsigned long initrd_addr;
366 	unsigned long initrd_size;
367 	efi_handle_t handle;
368 	efi_status_t status;
369 
370 	dp = (efi_device_path_protocol_t *)&initrd_dev_path;
371 	status = efi_bs_call(locate_device_path, &lf2_proto_guid, &dp, &handle);
372 	if (status != EFI_SUCCESS)
373 		return status;
374 
375 	status = efi_bs_call(handle_protocol, handle, &lf2_proto_guid,
376 			     (void **)&lf2);
377 	if (status != EFI_SUCCESS)
378 		return status;
379 
380 	status = efi_call_proto(lf2, load_file, dp, false, &initrd_size, NULL);
381 	if (status != EFI_BUFFER_TOO_SMALL)
382 		return EFI_LOAD_ERROR;
383 
384 	status = efi_allocate_pages(initrd_size, &initrd_addr, max);
385 	if (status != EFI_SUCCESS)
386 		return status;
387 
388 	status = efi_call_proto(lf2, load_file, dp, false, &initrd_size,
389 				(void *)initrd_addr);
390 	if (status != EFI_SUCCESS) {
391 		efi_free(initrd_size, initrd_addr);
392 		return EFI_LOAD_ERROR;
393 	}
394 
395 	*load_addr = initrd_addr;
396 	*load_size = initrd_size;
397 	return EFI_SUCCESS;
398 }
399 
400 static
401 efi_status_t efi_load_initrd_cmdline(efi_loaded_image_t *image,
402 				     unsigned long *load_addr,
403 				     unsigned long *load_size,
404 				     unsigned long soft_limit,
405 				     unsigned long hard_limit)
406 {
407 	if (!IS_ENABLED(CONFIG_EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER) ||
408 	    (IS_ENABLED(CONFIG_X86) && (!efi_is_native() || image == NULL))) {
409 		*load_addr = *load_size = 0;
410 		return EFI_SUCCESS;
411 	}
412 
413 	return handle_cmdline_files(image, L"initrd=", sizeof(L"initrd=") - 2,
414 				    soft_limit, hard_limit,
415 				    load_addr, load_size);
416 }
417 
418 efi_status_t efi_load_initrd(efi_loaded_image_t *image,
419 			     unsigned long *load_addr,
420 			     unsigned long *load_size,
421 			     unsigned long soft_limit,
422 			     unsigned long hard_limit)
423 {
424 	efi_status_t status;
425 
426 	if (!load_addr || !load_size)
427 		return EFI_INVALID_PARAMETER;
428 
429 	status = efi_load_initrd_dev_path(load_addr, load_size, hard_limit);
430 	if (status == EFI_SUCCESS) {
431 		efi_info("Loaded initrd from LINUX_EFI_INITRD_MEDIA_GUID device path\n");
432 	} else if (status == EFI_NOT_FOUND) {
433 		status = efi_load_initrd_cmdline(image, load_addr, load_size,
434 						 soft_limit, hard_limit);
435 		if (status == EFI_SUCCESS && *load_size > 0)
436 			efi_info("Loaded initrd from command line option\n");
437 	}
438 
439 	return status;
440 }
441