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 --- |