Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'efi-next-for-v7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi

Pull EFI updates from Ard Biesheuvel:
"Again not a busy cycle for EFI, just some minor tweaks and bug fixes:

- Enable boot graphics resource table (BGRT) on Xen/x86

- Correct a misguided assumption in the memory attributes table
sanity check

- Start tagging efi_mem_reserve()'d regions as MEMBLOCK_RSRV_KERN

- Some other minor fixes and cleanups"

* tag 'efi-next-for-v7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi:
efi/capsule-loader: fix incorrect sizeof in phys array reallocation
efi: Tag memblock reservations of boot services regions as RSRV_KERN
memblock: Permit existing reserved regions to be marked RSRV_KERN
efi/memattr: Fix thinko in table size sanity check
efi: libstub: fix type of fdt 32 and 64bit variables
efi: Drop unused efi_range_is_wc() function
efi: Enable BGRT loading under Xen
efi: make efi_mem_type() and efi_mem_attributes() work on Xen PV

+68 -58
+1 -1
drivers/firmware/efi/capsule-loader.c
··· 67 67 cap_info->pages = temp_page; 68 68 69 69 temp_page = krealloc(cap_info->phys, 70 - pages_needed * sizeof(phys_addr_t *), 70 + pages_needed * sizeof(phys_addr_t), 71 71 GFP_KERNEL | __GFP_ZERO); 72 72 if (!temp_page) 73 73 return -ENOMEM;
+5 -2
drivers/firmware/efi/efi-bgrt.c
··· 29 29 void *image; 30 30 struct bmp_header bmp_header; 31 31 struct acpi_table_bgrt *bgrt = &bgrt_tab; 32 + int mem_type; 32 33 33 34 if (acpi_disabled) 34 35 return; 35 36 36 - if (!efi_enabled(EFI_MEMMAP)) 37 + if (!efi_enabled(EFI_MEMMAP) && !efi_enabled(EFI_PARAVIRT)) 37 38 return; 38 39 39 40 if (table->length < sizeof(bgrt_tab)) { ··· 63 62 goto out; 64 63 } 65 64 66 - if (efi_mem_type(bgrt->image_address) != EFI_BOOT_SERVICES_DATA) { 65 + mem_type = efi_mem_type(bgrt->image_address); 66 + if (mem_type != EFI_BOOT_SERVICES_DATA && 67 + mem_type != EFI_ACPI_RECLAIM_MEMORY) { 67 68 pr_notice("Ignoring BGRT: invalid image address\n"); 68 69 goto out; 69 70 }
+12 -19
drivers/firmware/efi/efi.c
··· 600 600 return; 601 601 602 602 if (!memblock_is_region_reserved(addr, size)) 603 - memblock_reserve(addr, size); 603 + memblock_reserve_kern(addr, size); 604 + else 605 + memblock_reserved_mark_kern(addr, size); 604 606 605 607 /* 606 608 * Some architectures (x86) reserve all boot services ranges ··· 985 983 */ 986 984 u64 efi_mem_attributes(unsigned long phys_addr) 987 985 { 988 - efi_memory_desc_t *md; 986 + efi_memory_desc_t md; 989 987 990 - if (!efi_enabled(EFI_MEMMAP)) 988 + if (efi_mem_desc_lookup(phys_addr, &md)) 991 989 return 0; 992 990 993 - for_each_efi_memory_desc(md) { 994 - if ((md->phys_addr <= phys_addr) && 995 - (phys_addr < (md->phys_addr + 996 - (md->num_pages << EFI_PAGE_SHIFT)))) 997 - return md->attribute; 998 - } 999 - return 0; 991 + return md.attribute; 1000 992 } 1001 993 1002 994 /* ··· 1003 1007 */ 1004 1008 int efi_mem_type(unsigned long phys_addr) 1005 1009 { 1006 - const efi_memory_desc_t *md; 1010 + efi_memory_desc_t md; 1007 1011 1008 - if (!efi_enabled(EFI_MEMMAP)) 1012 + if (!efi_enabled(EFI_MEMMAP) && !efi_enabled(EFI_PARAVIRT)) 1009 1013 return -ENOTSUPP; 1010 1014 1011 - for_each_efi_memory_desc(md) { 1012 - if ((md->phys_addr <= phys_addr) && 1013 - (phys_addr < (md->phys_addr + 1014 - (md->num_pages << EFI_PAGE_SHIFT)))) 1015 - return md->type; 1016 - } 1017 - return -EINVAL; 1015 + if (efi_mem_desc_lookup(phys_addr, &md)) 1016 + return -EINVAL; 1017 + 1018 + return md.type; 1018 1019 } 1019 1020 1020 1021 int efi_status_to_err(efi_status_t status)
+6 -6
drivers/firmware/efi/libstub/fdt.c
··· 32 32 { 33 33 int node, num_rsv; 34 34 int status; 35 - u32 fdt_val32; 36 - u64 fdt_val64; 35 + fdt32_t fdt_val32; 36 + fdt64_t fdt_val64; 37 37 38 38 /* Do some checks on provided FDT, if it exists: */ 39 39 if (orig_fdt) { ··· 100 100 if (status) 101 101 goto fdt_set_fail; 102 102 103 - fdt_val64 = U64_MAX; /* placeholder */ 103 + fdt_val64 = cpu_to_fdt64(U64_MAX); /* placeholder */ 104 104 105 105 status = fdt_setprop_var(fdt, node, "linux,uefi-mmap-start", fdt_val64); 106 106 if (status) 107 107 goto fdt_set_fail; 108 108 109 - fdt_val32 = U32_MAX; /* placeholder */ 109 + fdt_val32 = cpu_to_fdt32(U32_MAX); /* placeholder */ 110 110 111 111 status = fdt_setprop_var(fdt, node, "linux,uefi-mmap-size", fdt_val32); 112 112 if (status) ··· 147 147 static efi_status_t update_fdt_memmap(void *fdt, struct efi_boot_memmap *map) 148 148 { 149 149 int node = fdt_path_offset(fdt, "/chosen"); 150 - u64 fdt_val64; 151 - u32 fdt_val32; 150 + fdt64_t fdt_val64; 151 + fdt32_t fdt_val32; 152 152 int err; 153 153 154 154 if (node < 0)
+28 -9
drivers/firmware/efi/memattr.c
··· 22 22 void __init efi_memattr_init(void) 23 23 { 24 24 efi_memory_attributes_table_t *tbl; 25 - unsigned long size; 26 25 27 26 if (efi_mem_attr_table == EFI_INVALID_TABLE_ADDR) 28 27 return; ··· 39 40 goto unmap; 40 41 } 41 42 43 + /* 44 + * The EFI memory attributes table descriptors might potentially be 45 + * smaller than those used by the EFI memory map, as long as they can 46 + * fit a efi_memory_desc_t. However, a larger descriptor size makes no 47 + * sense, and might be an indication that the table is corrupted. 48 + * 49 + * The only exception is kexec_load(), where the EFI memory map is 50 + * reconstructed by user space, and may use a smaller descriptor size 51 + * than the original. Given that, ignoring this companion table is 52 + * still the right thing to do here, but don't complain too loudly when 53 + * this happens. 54 + */ 55 + if (tbl->desc_size < sizeof(efi_memory_desc_t) || 56 + tbl->desc_size > efi.memmap.desc_size) { 57 + pr_warn("Unexpected EFI Memory Attributes descriptor size %u (expected: %lu)\n", 58 + tbl->desc_size, efi.memmap.desc_size); 59 + goto unmap; 60 + } 42 61 43 62 /* 44 - * Sanity check: the Memory Attributes Table contains up to 3 entries 45 - * for each entry of type EfiRuntimeServicesCode in the EFI memory map. 46 - * So if the size of the table exceeds 3x the size of the entire EFI 47 - * memory map, there is clearly something wrong, and the table should 48 - * just be ignored altogether. 63 + * Sanity check: the Memory Attributes Table contains multiple entries 64 + * for each EFI runtime services code or data region in the EFI memory 65 + * map, each with the permission attributes that may be applied when 66 + * mapping the region. There is no upper bound for the number of 67 + * entries, as it could conceivably contain more entries than the EFI 68 + * memory map itself. So pick an arbitrary limit of 64k, which is 69 + * ludicrously high. This prevents a corrupted table from eating all 70 + * system RAM. 49 71 */ 50 - size = tbl->num_entries * tbl->desc_size; 51 - if (size > 3 * efi.memmap.nr_map * efi.memmap.desc_size) { 72 + if (tbl->num_entries > SZ_64K) { 52 73 pr_warn(FW_BUG "Corrupted EFI Memory Attributes Table detected! (version == %u, desc_size == %u, num_entries == %u)\n", 53 74 tbl->version, tbl->desc_size, tbl->num_entries); 54 75 goto unmap; 55 76 } 56 77 57 - tbl_size = sizeof(*tbl) + size; 78 + tbl_size = sizeof(*tbl) + tbl->num_entries * tbl->desc_size; 58 79 memblock_reserve(efi_mem_attr_table, tbl_size); 59 80 set_bit(EFI_MEM_ATTR, &efi.flags); 60 81
-21
include/linux/efi.h
··· 832 832 const void *data, size_t size, 833 833 efi_element_handler_t (*get_handler_for_guid)(const efi_guid_t *)); 834 834 835 - /** 836 - * efi_range_is_wc - check the WC bit on an address range 837 - * @start: starting kvirt address 838 - * @len: length of range 839 - * 840 - * Consult the EFI memory map and make sure it's ok to set this range WC. 841 - * Returns true or false. 842 - */ 843 - static inline int efi_range_is_wc(unsigned long start, unsigned long len) 844 - { 845 - unsigned long i; 846 - 847 - for (i = 0; i < len; i += (1UL << EFI_PAGE_SHIFT)) { 848 - unsigned long paddr = __pa(start + i); 849 - if (!(efi_mem_attributes(paddr) & EFI_MEMORY_WC)) 850 - return 0; 851 - } 852 - /* The range checked out */ 853 - return 1; 854 - } 855 - 856 835 /* 857 836 * We play games with efi_enabled so that the compiler will, if 858 837 * possible, remove EFI-related code altogether.
+1
include/linux/memblock.h
··· 155 155 int memblock_mark_nomap(phys_addr_t base, phys_addr_t size); 156 156 int memblock_clear_nomap(phys_addr_t base, phys_addr_t size); 157 157 int memblock_reserved_mark_noinit(phys_addr_t base, phys_addr_t size); 158 + int memblock_reserved_mark_kern(phys_addr_t base, phys_addr_t size); 158 159 int memblock_mark_kho_scratch(phys_addr_t base, phys_addr_t size); 159 160 int memblock_clear_kho_scratch(phys_addr_t base, phys_addr_t size); 160 161
+15
mm/memblock.c
··· 1116 1116 } 1117 1117 1118 1118 /** 1119 + * memblock_reserved_mark_kern - Mark a reserved memory region with flag 1120 + * MEMBLOCK_RSRV_KERN 1121 + * 1122 + * @base: the base phys addr of the region 1123 + * @size: the size of the region 1124 + * 1125 + * Return: 0 on success, -errno on failure. 1126 + */ 1127 + int __init_memblock memblock_reserved_mark_kern(phys_addr_t base, phys_addr_t size) 1128 + { 1129 + return memblock_setclr_flag(&memblock.reserved, base, size, 1, 1130 + MEMBLOCK_RSRV_KERN); 1131 + } 1132 + 1133 + /** 1119 1134 * memblock_mark_kho_scratch - Mark a memory region as MEMBLOCK_KHO_SCRATCH. 1120 1135 * @base: the base phys addr of the region 1121 1136 * @size: the size of the region