0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/stdarg.h>
0011
0012 #include <linux/ctype.h>
0013 #include <linux/efi.h>
0014 #include <linux/kernel.h>
0015 #include <linux/printk.h> /* For CONSOLE_LOGLEVEL_* */
0016 #include <asm/efi.h>
0017 #include <asm/setup.h>
0018
0019 #include "efistub.h"
0020
0021 bool efi_nochunk;
0022 bool efi_nokaslr = !IS_ENABLED(CONFIG_RANDOMIZE_BASE);
0023 int efi_loglevel = CONSOLE_LOGLEVEL_DEFAULT;
0024 bool efi_novamap;
0025
0026 static bool efi_noinitrd;
0027 static bool efi_nosoftreserve;
0028 static bool efi_disable_pci_dma = IS_ENABLED(CONFIG_EFI_DISABLE_PCI_DMA);
0029
0030 bool __pure __efi_soft_reserve_enabled(void)
0031 {
0032 return !efi_nosoftreserve;
0033 }
0034
0035
0036
0037
0038
0039 void efi_char16_puts(efi_char16_t *str)
0040 {
0041 efi_call_proto(efi_table_attr(efi_system_table, con_out),
0042 output_string, str);
0043 }
0044
0045 static
0046 u32 utf8_to_utf32(const u8 **s8)
0047 {
0048 u32 c32;
0049 u8 c0, cx;
0050 size_t clen, i;
0051
0052 c0 = cx = *(*s8)++;
0053
0054
0055
0056
0057 for (clen = 0; cx & 0x80; ++clen)
0058 cx <<= 1;
0059
0060
0061
0062
0063
0064
0065 if (clen < 2 || clen > 4)
0066 return c0;
0067
0068 c32 = cx >> clen--;
0069 for (i = 0; i < clen; ++i) {
0070
0071 cx = (*s8)[i] ^ 0x80;
0072 if (cx & 0xc0)
0073 return c0;
0074 c32 = (c32 << 6) | cx;
0075 }
0076
0077
0078
0079
0080
0081
0082 if (c32 > 0x10ffff ||
0083 (c32 & 0xf800) == 0xd800 ||
0084 clen != (c32 >= 0x80) + (c32 >= 0x800) + (c32 >= 0x10000))
0085 return c0;
0086 *s8 += clen;
0087 return c32;
0088 }
0089
0090
0091
0092
0093
0094 void efi_puts(const char *str)
0095 {
0096 efi_char16_t buf[128];
0097 size_t pos = 0, lim = ARRAY_SIZE(buf);
0098 const u8 *s8 = (const u8 *)str;
0099 u32 c32;
0100
0101 while (*s8) {
0102 if (*s8 == '\n')
0103 buf[pos++] = L'\r';
0104 c32 = utf8_to_utf32(&s8);
0105 if (c32 < 0x10000) {
0106
0107 buf[pos++] = c32;
0108 } else {
0109
0110
0111
0112
0113 buf[pos++] = (0xd800 - (0x10000 >> 10)) + (c32 >> 10);
0114 buf[pos++] = 0xdc00 + (c32 & 0x3ff);
0115 }
0116 if (*s8 == '\0' || pos >= lim - 2) {
0117 buf[pos] = L'\0';
0118 efi_char16_puts(buf);
0119 pos = 0;
0120 }
0121 }
0122 }
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134 int efi_printk(const char *fmt, ...)
0135 {
0136 char printf_buf[256];
0137 va_list args;
0138 int printed;
0139 int loglevel = printk_get_level(fmt);
0140
0141 switch (loglevel) {
0142 case '0' ... '9':
0143 loglevel -= '0';
0144 break;
0145 default:
0146
0147
0148
0149
0150 loglevel = -1;
0151 break;
0152 }
0153
0154 if (loglevel >= efi_loglevel)
0155 return 0;
0156
0157 if (loglevel >= 0)
0158 efi_puts("EFI stub: ");
0159
0160 fmt = printk_skip_level(fmt);
0161
0162 va_start(args, fmt);
0163 printed = vsnprintf(printf_buf, sizeof(printf_buf), fmt, args);
0164 va_end(args);
0165
0166 efi_puts(printf_buf);
0167 if (printed >= sizeof(printf_buf)) {
0168 efi_puts("[Message truncated]\n");
0169 return -1;
0170 }
0171
0172 return printed;
0173 }
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188 efi_status_t efi_parse_options(char const *cmdline)
0189 {
0190 size_t len;
0191 efi_status_t status;
0192 char *str, *buf;
0193
0194 if (!cmdline)
0195 return EFI_SUCCESS;
0196
0197 len = strnlen(cmdline, COMMAND_LINE_SIZE - 1) + 1;
0198 status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, len, (void **)&buf);
0199 if (status != EFI_SUCCESS)
0200 return status;
0201
0202 memcpy(buf, cmdline, len - 1);
0203 buf[len - 1] = '\0';
0204 str = skip_spaces(buf);
0205
0206 while (*str) {
0207 char *param, *val;
0208
0209 str = next_arg(str, ¶m, &val);
0210 if (!val && !strcmp(param, "--"))
0211 break;
0212
0213 if (!strcmp(param, "nokaslr")) {
0214 efi_nokaslr = true;
0215 } else if (!strcmp(param, "quiet")) {
0216 efi_loglevel = CONSOLE_LOGLEVEL_QUIET;
0217 } else if (!strcmp(param, "noinitrd")) {
0218 efi_noinitrd = true;
0219 } else if (!strcmp(param, "efi") && val) {
0220 efi_nochunk = parse_option_str(val, "nochunk");
0221 efi_novamap = parse_option_str(val, "novamap");
0222
0223 efi_nosoftreserve = IS_ENABLED(CONFIG_EFI_SOFT_RESERVE) &&
0224 parse_option_str(val, "nosoftreserve");
0225
0226 if (parse_option_str(val, "disable_early_pci_dma"))
0227 efi_disable_pci_dma = true;
0228 if (parse_option_str(val, "no_disable_early_pci_dma"))
0229 efi_disable_pci_dma = false;
0230 if (parse_option_str(val, "debug"))
0231 efi_loglevel = CONSOLE_LOGLEVEL_DEBUG;
0232 } else if (!strcmp(param, "video") &&
0233 val && strstarts(val, "efifb:")) {
0234 efi_parse_option_graphics(val + strlen("efifb:"));
0235 }
0236 }
0237 efi_bs_call(free_pool, buf);
0238 return EFI_SUCCESS;
0239 }
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251 static
0252 bool efi_load_option_unpack(efi_load_option_unpacked_t *dest,
0253 const efi_load_option_t *src, size_t size)
0254 {
0255 const void *pos;
0256 u16 c;
0257 efi_device_path_protocol_t header;
0258 const efi_char16_t *description;
0259 const efi_device_path_protocol_t *file_path_list;
0260
0261 if (size < offsetof(efi_load_option_t, variable_data))
0262 return false;
0263 pos = src->variable_data;
0264 size -= offsetof(efi_load_option_t, variable_data);
0265
0266 if ((src->attributes & ~EFI_LOAD_OPTION_MASK) != 0)
0267 return false;
0268
0269
0270 description = pos;
0271 do {
0272 if (size < sizeof(c))
0273 return false;
0274 c = *(const u16 *)pos;
0275 pos += sizeof(c);
0276 size -= sizeof(c);
0277 } while (c != L'\0');
0278
0279
0280 file_path_list = pos;
0281 do {
0282 if (size < sizeof(header))
0283 return false;
0284 header = *(const efi_device_path_protocol_t *)pos;
0285 if (header.length < sizeof(header))
0286 return false;
0287 if (size < header.length)
0288 return false;
0289 pos += header.length;
0290 size -= header.length;
0291 } while ((header.type != EFI_DEV_END_PATH && header.type != EFI_DEV_END_PATH2) ||
0292 (header.sub_type != EFI_DEV_END_ENTIRE));
0293 if (pos != (const void *)file_path_list + src->file_path_list_length)
0294 return false;
0295
0296 dest->attributes = src->attributes;
0297 dest->file_path_list_length = src->file_path_list_length;
0298 dest->description = description;
0299 dest->file_path_list = file_path_list;
0300 dest->optional_data_size = size;
0301 dest->optional_data = size ? pos : NULL;
0302
0303 return true;
0304 }
0305
0306
0307
0308
0309
0310
0311
0312
0313 void efi_apply_loadoptions_quirk(const void **load_options, int *load_options_size)
0314 {
0315 const efi_load_option_t *load_option = *load_options;
0316 efi_load_option_unpacked_t load_option_unpacked;
0317
0318 if (!IS_ENABLED(CONFIG_X86))
0319 return;
0320 if (!load_option)
0321 return;
0322 if (*load_options_size < sizeof(*load_option))
0323 return;
0324 if ((load_option->attributes & ~EFI_LOAD_OPTION_BOOT_MASK) != 0)
0325 return;
0326
0327 if (!efi_load_option_unpack(&load_option_unpacked, load_option, *load_options_size))
0328 return;
0329
0330 efi_warn_once(FW_BUG "LoadOptions is an EFI_LOAD_OPTION descriptor\n");
0331 efi_warn_once(FW_BUG "Using OptionalData as a workaround\n");
0332
0333 *load_options = load_option_unpacked.optional_data;
0334 *load_options_size = load_option_unpacked.optional_data_size;
0335 }
0336
0337
0338
0339
0340
0341
0342 char *efi_convert_cmdline(efi_loaded_image_t *image, int *cmd_line_len)
0343 {
0344 const u16 *s2;
0345 unsigned long cmdline_addr = 0;
0346 int options_chars = efi_table_attr(image, load_options_size);
0347 const u16 *options = efi_table_attr(image, load_options);
0348 int options_bytes = 0, safe_options_bytes = 0;
0349 bool in_quote = false;
0350 efi_status_t status;
0351
0352 efi_apply_loadoptions_quirk((const void **)&options, &options_chars);
0353 options_chars /= sizeof(*options);
0354
0355 if (options) {
0356 s2 = options;
0357 while (options_bytes < COMMAND_LINE_SIZE && options_chars--) {
0358 u16 c = *s2++;
0359
0360 if (c < 0x80) {
0361 if (c == L'\0' || c == L'\n')
0362 break;
0363 if (c == L'"')
0364 in_quote = !in_quote;
0365 else if (!in_quote && isspace((char)c))
0366 safe_options_bytes = options_bytes;
0367
0368 options_bytes++;
0369 continue;
0370 }
0371
0372
0373
0374
0375
0376
0377 options_bytes += 2 + (c >= 0x800);
0378
0379
0380
0381
0382
0383 if ((c & 0xfc00) == 0xd800) {
0384
0385
0386
0387
0388
0389 if (!options_chars) {
0390 options_bytes -= 3;
0391 } else if ((*s2 & 0xfc00) == 0xdc00) {
0392 options_bytes++;
0393 options_chars--;
0394 s2++;
0395 }
0396 }
0397 }
0398 if (options_bytes >= COMMAND_LINE_SIZE) {
0399 options_bytes = safe_options_bytes;
0400 efi_err("Command line is too long: truncated to %d bytes\n",
0401 options_bytes);
0402 }
0403 }
0404
0405 options_bytes++;
0406
0407 status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, options_bytes,
0408 (void **)&cmdline_addr);
0409 if (status != EFI_SUCCESS)
0410 return NULL;
0411
0412 snprintf((char *)cmdline_addr, options_bytes, "%.*ls",
0413 options_bytes - 1, options);
0414
0415 *cmd_line_len = options_bytes;
0416 return (char *)cmdline_addr;
0417 }
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432
0433
0434
0435 efi_status_t efi_exit_boot_services(void *handle,
0436 struct efi_boot_memmap *map,
0437 void *priv,
0438 efi_exit_boot_map_processing priv_func)
0439 {
0440 efi_status_t status;
0441
0442 status = efi_get_memory_map(map);
0443
0444 if (status != EFI_SUCCESS)
0445 goto fail;
0446
0447 status = priv_func(map, priv);
0448 if (status != EFI_SUCCESS)
0449 goto free_map;
0450
0451 if (efi_disable_pci_dma)
0452 efi_pci_disable_bridge_busmaster();
0453
0454 status = efi_bs_call(exit_boot_services, handle, *map->key_ptr);
0455
0456 if (status == EFI_INVALID_PARAMETER) {
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470 *map->map_size = *map->buff_size;
0471 status = efi_bs_call(get_memory_map,
0472 map->map_size,
0473 *map->map,
0474 map->key_ptr,
0475 map->desc_size,
0476 map->desc_ver);
0477
0478
0479 if (status != EFI_SUCCESS)
0480 goto fail;
0481
0482 status = priv_func(map, priv);
0483
0484 if (status != EFI_SUCCESS)
0485 goto fail;
0486
0487 status = efi_bs_call(exit_boot_services, handle, *map->key_ptr);
0488 }
0489
0490
0491 if (status != EFI_SUCCESS)
0492 goto fail;
0493
0494 return EFI_SUCCESS;
0495
0496 free_map:
0497 efi_bs_call(free_pool, *map->map);
0498 fail:
0499 return status;
0500 }
0501
0502
0503
0504
0505
0506
0507 void *get_efi_config_table(efi_guid_t guid)
0508 {
0509 unsigned long tables = efi_table_attr(efi_system_table, tables);
0510 int nr_tables = efi_table_attr(efi_system_table, nr_tables);
0511 int i;
0512
0513 for (i = 0; i < nr_tables; i++) {
0514 efi_config_table_t *t = (void *)tables;
0515
0516 if (efi_guidcmp(t->guid, guid) == 0)
0517 return efi_table_attr(t, table);
0518
0519 tables += efi_is_native() ? sizeof(efi_config_table_t)
0520 : sizeof(efi_config_table_32_t);
0521 }
0522 return NULL;
0523 }
0524
0525
0526
0527
0528
0529
0530
0531
0532
0533
0534
0535 static const struct {
0536 struct efi_vendor_dev_path vendor;
0537 struct efi_generic_dev_path end;
0538 } __packed initrd_dev_path = {
0539 {
0540 {
0541 EFI_DEV_MEDIA,
0542 EFI_DEV_MEDIA_VENDOR,
0543 sizeof(struct efi_vendor_dev_path),
0544 },
0545 LINUX_EFI_INITRD_MEDIA_GUID
0546 }, {
0547 EFI_DEV_END_PATH,
0548 EFI_DEV_END_ENTIRE,
0549 sizeof(struct efi_generic_dev_path)
0550 }
0551 };
0552
0553
0554
0555
0556
0557
0558
0559
0560
0561
0562
0563
0564
0565
0566
0567 static
0568 efi_status_t efi_load_initrd_dev_path(unsigned long *load_addr,
0569 unsigned long *load_size,
0570 unsigned long max)
0571 {
0572 efi_guid_t lf2_proto_guid = EFI_LOAD_FILE2_PROTOCOL_GUID;
0573 efi_device_path_protocol_t *dp;
0574 efi_load_file2_protocol_t *lf2;
0575 unsigned long initrd_addr;
0576 unsigned long initrd_size;
0577 efi_handle_t handle;
0578 efi_status_t status;
0579
0580 dp = (efi_device_path_protocol_t *)&initrd_dev_path;
0581 status = efi_bs_call(locate_device_path, &lf2_proto_guid, &dp, &handle);
0582 if (status != EFI_SUCCESS)
0583 return status;
0584
0585 status = efi_bs_call(handle_protocol, handle, &lf2_proto_guid,
0586 (void **)&lf2);
0587 if (status != EFI_SUCCESS)
0588 return status;
0589
0590 status = efi_call_proto(lf2, load_file, dp, false, &initrd_size, NULL);
0591 if (status != EFI_BUFFER_TOO_SMALL)
0592 return EFI_LOAD_ERROR;
0593
0594 status = efi_allocate_pages(initrd_size, &initrd_addr, max);
0595 if (status != EFI_SUCCESS)
0596 return status;
0597
0598 status = efi_call_proto(lf2, load_file, dp, false, &initrd_size,
0599 (void *)initrd_addr);
0600 if (status != EFI_SUCCESS) {
0601 efi_free(initrd_size, initrd_addr);
0602 return EFI_LOAD_ERROR;
0603 }
0604
0605 *load_addr = initrd_addr;
0606 *load_size = initrd_size;
0607 return EFI_SUCCESS;
0608 }
0609
0610 static
0611 efi_status_t efi_load_initrd_cmdline(efi_loaded_image_t *image,
0612 unsigned long *load_addr,
0613 unsigned long *load_size,
0614 unsigned long soft_limit,
0615 unsigned long hard_limit)
0616 {
0617 if (!IS_ENABLED(CONFIG_EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER) ||
0618 (IS_ENABLED(CONFIG_X86) && (!efi_is_native() || image == NULL))) {
0619 *load_addr = *load_size = 0;
0620 return EFI_SUCCESS;
0621 }
0622
0623 return handle_cmdline_files(image, L"initrd=", sizeof(L"initrd=") - 2,
0624 soft_limit, hard_limit,
0625 load_addr, load_size);
0626 }
0627
0628 static const struct {
0629 efi_tcg2_event_t event_data;
0630 efi_tcg2_tagged_event_t tagged_event;
0631 u8 tagged_event_data[];
0632 } initrd_tcg2_event = {
0633 {
0634 sizeof(initrd_tcg2_event) + sizeof("Linux initrd"),
0635 {
0636 sizeof(initrd_tcg2_event.event_data.event_header),
0637 EFI_TCG2_EVENT_HEADER_VERSION,
0638 9,
0639 EV_EVENT_TAG,
0640 },
0641 },
0642 {
0643 INITRD_EVENT_TAG_ID,
0644 sizeof("Linux initrd"),
0645 },
0646 { "Linux initrd" },
0647 };
0648
0649 static void efi_measure_initrd(unsigned long load_addr, unsigned long load_size)
0650 {
0651 efi_guid_t tcg2_guid = EFI_TCG2_PROTOCOL_GUID;
0652 efi_tcg2_protocol_t *tcg2 = NULL;
0653 efi_status_t status;
0654
0655 efi_bs_call(locate_protocol, &tcg2_guid, NULL, (void **)&tcg2);
0656 if (tcg2) {
0657 status = efi_call_proto(tcg2, hash_log_extend_event,
0658 0, load_addr, load_size,
0659 &initrd_tcg2_event.event_data);
0660 if (status != EFI_SUCCESS)
0661 efi_warn("Failed to measure initrd data: 0x%lx\n",
0662 status);
0663 else
0664 efi_info("Measured initrd data into PCR %d\n",
0665 initrd_tcg2_event.event_data.event_header.pcr_index);
0666 }
0667 }
0668
0669
0670
0671
0672
0673
0674
0675
0676
0677
0678
0679 efi_status_t efi_load_initrd(efi_loaded_image_t *image,
0680 unsigned long *load_addr,
0681 unsigned long *load_size,
0682 unsigned long soft_limit,
0683 unsigned long hard_limit)
0684 {
0685 efi_status_t status;
0686
0687 if (efi_noinitrd) {
0688 *load_addr = *load_size = 0;
0689 status = EFI_SUCCESS;
0690 } else {
0691 status = efi_load_initrd_dev_path(load_addr, load_size, hard_limit);
0692 if (status == EFI_SUCCESS) {
0693 efi_info("Loaded initrd from LINUX_EFI_INITRD_MEDIA_GUID device path\n");
0694 if (*load_size > 0)
0695 efi_measure_initrd(*load_addr, *load_size);
0696 } else if (status == EFI_NOT_FOUND) {
0697 status = efi_load_initrd_cmdline(image, load_addr, load_size,
0698 soft_limit, hard_limit);
0699 if (status == EFI_SUCCESS && *load_size > 0)
0700 efi_info("Loaded initrd from command line option\n");
0701 }
0702 if (status != EFI_SUCCESS) {
0703 efi_err("Failed to load initrd: 0x%lx\n", status);
0704 *load_addr = *load_size = 0;
0705 }
0706 }
0707
0708 return status;
0709 }
0710
0711
0712
0713
0714
0715
0716
0717
0718
0719
0720 efi_status_t efi_wait_for_key(unsigned long usec, efi_input_key_t *key)
0721 {
0722 efi_event_t events[2], timer;
0723 unsigned long index;
0724 efi_simple_text_input_protocol_t *con_in;
0725 efi_status_t status;
0726
0727 con_in = efi_table_attr(efi_system_table, con_in);
0728 if (!con_in)
0729 return EFI_UNSUPPORTED;
0730 efi_set_event_at(events, 0, efi_table_attr(con_in, wait_for_key));
0731
0732 status = efi_bs_call(create_event, EFI_EVT_TIMER, 0, NULL, NULL, &timer);
0733 if (status != EFI_SUCCESS)
0734 return status;
0735
0736 status = efi_bs_call(set_timer, timer, EfiTimerRelative,
0737 EFI_100NSEC_PER_USEC * usec);
0738 if (status != EFI_SUCCESS)
0739 return status;
0740 efi_set_event_at(events, 1, timer);
0741
0742 status = efi_bs_call(wait_for_event, 2, events, &index);
0743 if (status == EFI_SUCCESS) {
0744 if (index == 0)
0745 status = efi_call_proto(con_in, read_keystroke, key);
0746 else
0747 status = EFI_TIMEOUT;
0748 }
0749
0750 efi_bs_call(close_event, timer);
0751
0752 return status;
0753 }