Merge 3rd batch of EFI fixes into efi/urgent

Changed files
+71 -10
drivers
+6 -2
drivers/firmware/efi/efi.c
··· 273 273 if (status == EFI_NOT_FOUND) { 274 274 break; 275 275 } else if (status == EFI_BUFFER_TOO_SMALL) { 276 - name = krealloc(name, name_size, GFP_KERNEL); 277 - if (!name) 276 + efi_char16_t *name_tmp = 277 + krealloc(name, name_size, GFP_KERNEL); 278 + if (!name_tmp) { 279 + kfree(name); 278 280 return -ENOMEM; 281 + } 282 + name = name_tmp; 279 283 continue; 280 284 } 281 285
+3 -4
drivers/firmware/efi/libstub/x86-stub.c
··· 605 605 break; 606 606 607 607 case EFI_UNACCEPTED_MEMORY: 608 - if (!IS_ENABLED(CONFIG_UNACCEPTED_MEMORY)) { 609 - efi_warn_once( 610 - "The system has unaccepted memory, but kernel does not support it\nConsider enabling CONFIG_UNACCEPTED_MEMORY\n"); 608 + if (!IS_ENABLED(CONFIG_UNACCEPTED_MEMORY)) 611 609 continue; 612 - } 613 610 e820_type = E820_TYPE_RAM; 614 611 process_unaccepted_memory(d->phys_addr, 615 612 d->phys_addr + PAGE_SIZE * d->num_pages); ··· 848 851 const struct linux_efi_initrd *initrd = NULL; 849 852 unsigned long kernel_entry; 850 853 efi_status_t status; 854 + 855 + boot_params_pointer = boot_params; 851 856 852 857 efi_system_table = sys_table_arg; 853 858 /* Check if we were booted by the EFI firmware */
+2
drivers/firmware/efi/libstub/x86-stub.h
··· 2 2 3 3 #include <linux/efi.h> 4 4 5 + extern struct boot_params *boot_params_pointer asm("boot_params"); 6 + 5 7 extern void trampoline_32bit_src(void *, bool); 6 8 extern const u16 trampoline_ljmp_imm_offset; 7 9
+60 -4
drivers/firmware/efi/unaccepted_memory.c
··· 5 5 #include <linux/spinlock.h> 6 6 #include <asm/unaccepted_memory.h> 7 7 8 - /* Protects unaccepted memory bitmap */ 8 + /* Protects unaccepted memory bitmap and accepting_list */ 9 9 static DEFINE_SPINLOCK(unaccepted_memory_lock); 10 + 11 + struct accept_range { 12 + struct list_head list; 13 + unsigned long start; 14 + unsigned long end; 15 + }; 16 + 17 + static LIST_HEAD(accepting_list); 10 18 11 19 /* 12 20 * accept_memory() -- Consult bitmap and accept the memory if needed. ··· 32 24 { 33 25 struct efi_unaccepted_memory *unaccepted; 34 26 unsigned long range_start, range_end; 27 + struct accept_range range, *entry; 35 28 unsigned long flags; 36 29 u64 unit_size; 37 30 ··· 87 78 if (end > unaccepted->size * unit_size * BITS_PER_BYTE) 88 79 end = unaccepted->size * unit_size * BITS_PER_BYTE; 89 80 90 - range_start = start / unit_size; 91 - 81 + range.start = start / unit_size; 82 + range.end = DIV_ROUND_UP(end, unit_size); 83 + retry: 92 84 spin_lock_irqsave(&unaccepted_memory_lock, flags); 85 + 86 + /* 87 + * Check if anybody works on accepting the same range of the memory. 88 + * 89 + * The check is done with unit_size granularity. It is crucial to catch 90 + * all accept requests to the same unit_size block, even if they don't 91 + * overlap on physical address level. 92 + */ 93 + list_for_each_entry(entry, &accepting_list, list) { 94 + if (entry->end < range.start) 95 + continue; 96 + if (entry->start >= range.end) 97 + continue; 98 + 99 + /* 100 + * Somebody else accepting the range. Or at least part of it. 101 + * 102 + * Drop the lock and retry until it is complete. 103 + */ 104 + spin_unlock_irqrestore(&unaccepted_memory_lock, flags); 105 + goto retry; 106 + } 107 + 108 + /* 109 + * Register that the range is about to be accepted. 110 + * Make sure nobody else will accept it. 111 + */ 112 + list_add(&range.list, &accepting_list); 113 + 114 + range_start = range.start; 93 115 for_each_set_bitrange_from(range_start, range_end, unaccepted->bitmap, 94 - DIV_ROUND_UP(end, unit_size)) { 116 + range.end) { 95 117 unsigned long phys_start, phys_end; 96 118 unsigned long len = range_end - range_start; 97 119 98 120 phys_start = range_start * unit_size + unaccepted->phys_base; 99 121 phys_end = range_end * unit_size + unaccepted->phys_base; 100 122 123 + /* 124 + * Keep interrupts disabled until the accept operation is 125 + * complete in order to prevent deadlocks. 126 + * 127 + * Enabling interrupts before calling arch_accept_memory() 128 + * creates an opportunity for an interrupt handler to request 129 + * acceptance for the same memory. The handler will continuously 130 + * spin with interrupts disabled, preventing other task from 131 + * making progress with the acceptance process. 132 + */ 133 + spin_unlock(&unaccepted_memory_lock); 134 + 101 135 arch_accept_memory(phys_start, phys_end); 136 + 137 + spin_lock(&unaccepted_memory_lock); 102 138 bitmap_clear(unaccepted->bitmap, range_start, len); 103 139 } 140 + 141 + list_del(&range.list); 104 142 spin_unlock_irqrestore(&unaccepted_memory_lock, flags); 105 143 } 106 144