efi.c (966d47e1f27c45507c5df82b2a2157e5a4fd3909) efi.c (234fa51db95f3236a049557db735606908747f38)
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * efi.c - EFI subsystem
4 *
5 * Copyright (C) 2001,2003,2004 Dell <Matt_Domsch@dell.com>
6 * Copyright (C) 2004 Intel Corporation <matthew.e.tolentino@intel.com>
7 * Copyright (C) 2013 Tom Gundersen <teg@jklm.no>
8 *

--- 173 unchanged lines hidden (view full) ---

182static const struct attribute_group efi_subsys_attr_group = {
183 .attrs = efi_subsys_attrs,
184 .is_visible = efi_attr_is_visible,
185};
186
187static struct efivars generic_efivars;
188static struct efivar_operations generic_ops;
189
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * efi.c - EFI subsystem
4 *
5 * Copyright (C) 2001,2003,2004 Dell <Matt_Domsch@dell.com>
6 * Copyright (C) 2004 Intel Corporation <matthew.e.tolentino@intel.com>
7 * Copyright (C) 2013 Tom Gundersen <teg@jklm.no>
8 *

--- 173 unchanged lines hidden (view full) ---

182static const struct attribute_group efi_subsys_attr_group = {
183 .attrs = efi_subsys_attrs,
184 .is_visible = efi_attr_is_visible,
185};
186
187static struct efivars generic_efivars;
188static struct efivar_operations generic_ops;
189
190static bool generic_ops_supported(void)
191{
192 unsigned long name_size;
193 efi_status_t status;
194 efi_char16_t name;
195 efi_guid_t guid;
196
197 name_size = sizeof(name);
198
199 status = efi.get_next_variable(&name_size, &name, &guid);
200 if (status == EFI_UNSUPPORTED)
201 return false;
202
203 return true;
204}
205
190static int generic_ops_register(void)
191{
206static int generic_ops_register(void)
207{
208 if (!generic_ops_supported())
209 return 0;
210
192 generic_ops.get_variable = efi.get_variable;
193 generic_ops.get_next_variable = efi.get_next_variable;
194 generic_ops.query_variable_store = efi_query_variable_store;
195
196 if (efi_rt_services_supported(EFI_RT_SUPPORTED_SET_VARIABLE)) {
197 generic_ops.set_variable = efi.set_variable;
198 generic_ops.set_variable_nonblocking = efi.set_variable_nonblocking;
199 }
211 generic_ops.get_variable = efi.get_variable;
212 generic_ops.get_next_variable = efi.get_next_variable;
213 generic_ops.query_variable_store = efi_query_variable_store;
214
215 if (efi_rt_services_supported(EFI_RT_SUPPORTED_SET_VARIABLE)) {
216 generic_ops.set_variable = efi.set_variable;
217 generic_ops.set_variable_nonblocking = efi.set_variable_nonblocking;
218 }
200 return efivars_register(&generic_efivars, &generic_ops, efi_kobj);
219 return efivars_register(&generic_efivars, &generic_ops);
201}
202
203static void generic_ops_unregister(void)
204{
220}
221
222static void generic_ops_unregister(void)
223{
224 if (!generic_ops.get_variable)
225 return;
226
205 efivars_unregister(&generic_efivars);
206}
207
208#ifdef CONFIG_EFI_CUSTOM_SSDT_OVERLAYS
209#define EFIVAR_SSDT_NAME_MAX 16UL
210static char efivar_ssdt[EFIVAR_SSDT_NAME_MAX] __initdata;
211static int __init efivar_ssdt_setup(char *str)
212{

--- 176 unchanged lines hidden (view full) ---

389
390 if (efi_rt_services_supported(EFI_RT_SUPPORTED_TIME_SERVICES))
391 platform_device_register_simple("rtc-efi", 0, NULL, 0);
392
393 /* We register the efi directory at /sys/firmware/efi */
394 efi_kobj = kobject_create_and_add("efi", firmware_kobj);
395 if (!efi_kobj) {
396 pr_err("efi: Firmware registration failed.\n");
227 efivars_unregister(&generic_efivars);
228}
229
230#ifdef CONFIG_EFI_CUSTOM_SSDT_OVERLAYS
231#define EFIVAR_SSDT_NAME_MAX 16UL
232static char efivar_ssdt[EFIVAR_SSDT_NAME_MAX] __initdata;
233static int __init efivar_ssdt_setup(char *str)
234{

--- 176 unchanged lines hidden (view full) ---

411
412 if (efi_rt_services_supported(EFI_RT_SUPPORTED_TIME_SERVICES))
413 platform_device_register_simple("rtc-efi", 0, NULL, 0);
414
415 /* We register the efi directory at /sys/firmware/efi */
416 efi_kobj = kobject_create_and_add("efi", firmware_kobj);
417 if (!efi_kobj) {
418 pr_err("efi: Firmware registration failed.\n");
397 error = -ENOMEM;
398 goto err_destroy_wq;
419 destroy_workqueue(efi_rts_wq);
420 return -ENOMEM;
399 }
400
401 if (efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE |
402 EFI_RT_SUPPORTED_GET_NEXT_VARIABLE_NAME)) {
403 error = generic_ops_register();
404 if (error)
405 goto err_put;
406 efivar_ssdt_load();

--- 31 unchanged lines hidden (view full) ---

438 sysfs_remove_group(efi_kobj, &efi_subsys_attr_group);
439err_unregister:
440 if (efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE |
441 EFI_RT_SUPPORTED_GET_NEXT_VARIABLE_NAME))
442 generic_ops_unregister();
443err_put:
444 kobject_put(efi_kobj);
445 efi_kobj = NULL;
421 }
422
423 if (efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE |
424 EFI_RT_SUPPORTED_GET_NEXT_VARIABLE_NAME)) {
425 error = generic_ops_register();
426 if (error)
427 goto err_put;
428 efivar_ssdt_load();

--- 31 unchanged lines hidden (view full) ---

460 sysfs_remove_group(efi_kobj, &efi_subsys_attr_group);
461err_unregister:
462 if (efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE |
463 EFI_RT_SUPPORTED_GET_NEXT_VARIABLE_NAME))
464 generic_ops_unregister();
465err_put:
466 kobject_put(efi_kobj);
467 efi_kobj = NULL;
446err_destroy_wq:
447 if (efi_rts_wq)
448 destroy_workqueue(efi_rts_wq);
449
468 destroy_workqueue(efi_rts_wq);
450 return error;
451}
452
453subsys_initcall(efisubsys_init);
454
455void __init efi_find_mirror(void)
456{
457 efi_memory_desc_t *md;

--- 18 unchanged lines hidden (view full) ---

476}
477
478/*
479 * Find the efi memory descriptor for a given physical address. Given a
480 * physical address, determine if it exists within an EFI Memory Map entry,
481 * and if so, populate the supplied memory descriptor with the appropriate
482 * data.
483 */
469 return error;
470}
471
472subsys_initcall(efisubsys_init);
473
474void __init efi_find_mirror(void)
475{
476 efi_memory_desc_t *md;

--- 18 unchanged lines hidden (view full) ---

495}
496
497/*
498 * Find the efi memory descriptor for a given physical address. Given a
499 * physical address, determine if it exists within an EFI Memory Map entry,
500 * and if so, populate the supplied memory descriptor with the appropriate
501 * data.
502 */
484int efi_mem_desc_lookup(u64 phys_addr, efi_memory_desc_t *out_md)
503int __efi_mem_desc_lookup(u64 phys_addr, efi_memory_desc_t *out_md)
485{
486 efi_memory_desc_t *md;
487
488 if (!efi_enabled(EFI_MEMMAP)) {
489 pr_err_once("EFI_MEMMAP is not enabled.\n");
490 return -EINVAL;
491 }
492
493 if (!out_md) {
494 pr_err_once("out_md is null.\n");
495 return -EINVAL;
496 }
497
498 for_each_efi_memory_desc(md) {
499 u64 size;
500 u64 end;
501
504{
505 efi_memory_desc_t *md;
506
507 if (!efi_enabled(EFI_MEMMAP)) {
508 pr_err_once("EFI_MEMMAP is not enabled.\n");
509 return -EINVAL;
510 }
511
512 if (!out_md) {
513 pr_err_once("out_md is null.\n");
514 return -EINVAL;
515 }
516
517 for_each_efi_memory_desc(md) {
518 u64 size;
519 u64 end;
520
521 /* skip bogus entries (including empty ones) */
522 if ((md->phys_addr & (EFI_PAGE_SIZE - 1)) ||
523 (md->num_pages <= 0) ||
524 (md->num_pages > (U64_MAX - md->phys_addr) >> EFI_PAGE_SHIFT))
525 continue;
526
502 size = md->num_pages << EFI_PAGE_SHIFT;
503 end = md->phys_addr + size;
504 if (phys_addr >= md->phys_addr && phys_addr < end) {
505 memcpy(out_md, md, sizeof(*out_md));
506 return 0;
507 }
508 }
509 return -ENOENT;
510}
511
527 size = md->num_pages << EFI_PAGE_SHIFT;
528 end = md->phys_addr + size;
529 if (phys_addr >= md->phys_addr && phys_addr < end) {
530 memcpy(out_md, md, sizeof(*out_md));
531 return 0;
532 }
533 }
534 return -ENOENT;
535}
536
537extern int efi_mem_desc_lookup(u64 phys_addr, efi_memory_desc_t *out_md)
538 __weak __alias(__efi_mem_desc_lookup);
539
512/*
513 * Calculate the highest address of an efi memory descriptor.
514 */
515u64 __init efi_mem_desc_end(efi_memory_desc_t *md)
516{
517 u64 size = md->num_pages << EFI_PAGE_SHIFT;
518 u64 end = md->phys_addr + size;
519 return end;

--- 10 unchanged lines hidden (view full) ---

530 * prevent it being released by efi_free_boot_services().
531 *
532 * This function should be called drivers once they've parsed EFI
533 * configuration tables to figure out where their data lives, e.g.
534 * efi_esrt_init().
535 */
536void __init efi_mem_reserve(phys_addr_t addr, u64 size)
537{
540/*
541 * Calculate the highest address of an efi memory descriptor.
542 */
543u64 __init efi_mem_desc_end(efi_memory_desc_t *md)
544{
545 u64 size = md->num_pages << EFI_PAGE_SHIFT;
546 u64 end = md->phys_addr + size;
547 return end;

--- 10 unchanged lines hidden (view full) ---

558 * prevent it being released by efi_free_boot_services().
559 *
560 * This function should be called drivers once they've parsed EFI
561 * configuration tables to figure out where their data lives, e.g.
562 * efi_esrt_init().
563 */
564void __init efi_mem_reserve(phys_addr_t addr, u64 size)
565{
566 /* efi_mem_reserve() does not work under Xen */
567 if (WARN_ON_ONCE(efi_enabled(EFI_PARAVIRT)))
568 return;
569
538 if (!memblock_is_region_reserved(addr, size))
539 memblock_reserve(addr, size);
540
541 /*
542 * Some architectures (x86) reserve all boot services ranges
543 * until efi_free_boot_services() because of buggy firmware
544 * implementations. This means the above memblock_reserve() is
545 * superfluous on x86 and instead what it needs to do is

--- 32 unchanged lines hidden (view full) ---

578
579static __init int match_config_table(const efi_guid_t *guid,
580 unsigned long table,
581 const efi_config_table_type_t *table_types)
582{
583 int i;
584
585 for (i = 0; efi_guidcmp(table_types[i].guid, NULL_GUID); i++) {
570 if (!memblock_is_region_reserved(addr, size))
571 memblock_reserve(addr, size);
572
573 /*
574 * Some architectures (x86) reserve all boot services ranges
575 * until efi_free_boot_services() because of buggy firmware
576 * implementations. This means the above memblock_reserve() is
577 * superfluous on x86 and instead what it needs to do is

--- 32 unchanged lines hidden (view full) ---

610
611static __init int match_config_table(const efi_guid_t *guid,
612 unsigned long table,
613 const efi_config_table_type_t *table_types)
614{
615 int i;
616
617 for (i = 0; efi_guidcmp(table_types[i].guid, NULL_GUID); i++) {
586 if (!efi_guidcmp(*guid, table_types[i].guid)) {
587 *(table_types[i].ptr) = table;
618 if (efi_guidcmp(*guid, table_types[i].guid))
619 continue;
620
621 if (!efi_config_table_is_usable(guid, table)) {
588 if (table_types[i].name[0])
622 if (table_types[i].name[0])
589 pr_cont("%s=0x%lx ",
623 pr_cont("(%s=0x%lx unusable) ",
590 table_types[i].name, table);
591 return 1;
592 }
624 table_types[i].name, table);
625 return 1;
626 }
627
628 *(table_types[i].ptr) = table;
629 if (table_types[i].name[0])
630 pr_cont("%s=0x%lx ", table_types[i].name, table);
631 return 1;
593 }
594
595 return 0;
596}
597
598int __init efi_config_parse_tables(const efi_config_table_t *config_tables,
599 int count,
600 const efi_config_table_type_t *arch_tables)

--- 114 unchanged lines hidden (view full) ---

715 phys_initrd_size = tbl->size;
716 early_memunmap(tbl, sizeof(*tbl));
717 }
718 }
719
720 return 0;
721}
722
632 }
633
634 return 0;
635}
636
637int __init efi_config_parse_tables(const efi_config_table_t *config_tables,
638 int count,
639 const efi_config_table_type_t *arch_tables)

--- 114 unchanged lines hidden (view full) ---

754 phys_initrd_size = tbl->size;
755 early_memunmap(tbl, sizeof(*tbl));
756 }
757 }
758
759 return 0;
760}
761
723int __init efi_systab_check_header(const efi_table_hdr_t *systab_hdr,
724 int min_major_version)
762int __init efi_systab_check_header(const efi_table_hdr_t *systab_hdr)
725{
726 if (systab_hdr->signature != EFI_SYSTEM_TABLE_SIGNATURE) {
727 pr_err("System table signature incorrect!\n");
728 return -EINVAL;
729 }
730
763{
764 if (systab_hdr->signature != EFI_SYSTEM_TABLE_SIGNATURE) {
765 pr_err("System table signature incorrect!\n");
766 return -EINVAL;
767 }
768
731 if ((systab_hdr->revision >> 16) < min_major_version)
732 pr_err("Warning: System table version %d.%02d, expected %d.00 or greater!\n",
733 systab_hdr->revision >> 16,
734 systab_hdr->revision & 0xffff,
735 min_major_version);
736
737 return 0;
738}
739
740#ifndef CONFIG_IA64
741static const efi_char16_t *__init map_fw_vendor(unsigned long fw_vendor,
742 size_t size)
743{
744 const efi_char16_t *ret;

--- 257 unchanged lines hidden (view full) ---

1002 rc = efi_memreserve_map_root();
1003 if (rc)
1004 return rc;
1005 }
1006
1007 /* first try to find a slot in an existing linked list entry */
1008 for (prsv = efi_memreserve_root->next; prsv; ) {
1009 rsv = memremap(prsv, sizeof(*rsv), MEMREMAP_WB);
769 return 0;
770}
771
772#ifndef CONFIG_IA64
773static const efi_char16_t *__init map_fw_vendor(unsigned long fw_vendor,
774 size_t size)
775{
776 const efi_char16_t *ret;

--- 257 unchanged lines hidden (view full) ---

1034 rc = efi_memreserve_map_root();
1035 if (rc)
1036 return rc;
1037 }
1038
1039 /* first try to find a slot in an existing linked list entry */
1040 for (prsv = efi_memreserve_root->next; prsv; ) {
1041 rsv = memremap(prsv, sizeof(*rsv), MEMREMAP_WB);
1010 if (!rsv)
1011 return -ENOMEM;
1012 index = atomic_fetch_add_unless(&rsv->count, 1, rsv->size);
1013 if (index < rsv->size) {
1014 rsv->entry[index].base = addr;
1015 rsv->entry[index].size = size;
1016
1017 memunmap(rsv);
1018 return efi_mem_reserve_iomem(addr, size);
1019 }

--- 87 unchanged lines hidden ---
1042 index = atomic_fetch_add_unless(&rsv->count, 1, rsv->size);
1043 if (index < rsv->size) {
1044 rsv->entry[index].base = addr;
1045 rsv->entry[index].size = size;
1046
1047 memunmap(rsv);
1048 return efi_mem_reserve_iomem(addr, size);
1049 }

--- 87 unchanged lines hidden ---