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

Merge tag 'efi-urgent' into x86/urgent

* More tweaking to the EFI variable anti-bricking algorithm. Quite a
few users were reporting boot regressions in v3.9. This has now been
fixed with a more accurate "minimum storage requirement to avoid
bricking" value from Samsung (5K instead of 50%) and code to trigger
garbage collection when we near our limit - Matthew Garrett.

Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>

+65 -178
-47
arch/x86/boot/compressed/eboot.c
··· 251 251 *size = len; 252 252 } 253 253 254 - static efi_status_t setup_efi_vars(struct boot_params *params) 255 - { 256 - struct setup_data *data; 257 - struct efi_var_bootdata *efidata; 258 - u64 store_size, remaining_size, var_size; 259 - efi_status_t status; 260 - 261 - if (sys_table->runtime->hdr.revision < EFI_2_00_SYSTEM_TABLE_REVISION) 262 - return EFI_UNSUPPORTED; 263 - 264 - data = (struct setup_data *)(unsigned long)params->hdr.setup_data; 265 - 266 - while (data && data->next) 267 - data = (struct setup_data *)(unsigned long)data->next; 268 - 269 - status = efi_call_phys4((void *)sys_table->runtime->query_variable_info, 270 - EFI_VARIABLE_NON_VOLATILE | 271 - EFI_VARIABLE_BOOTSERVICE_ACCESS | 272 - EFI_VARIABLE_RUNTIME_ACCESS, &store_size, 273 - &remaining_size, &var_size); 274 - 275 - if (status != EFI_SUCCESS) 276 - return status; 277 - 278 - status = efi_call_phys3(sys_table->boottime->allocate_pool, 279 - EFI_LOADER_DATA, sizeof(*efidata), &efidata); 280 - 281 - if (status != EFI_SUCCESS) 282 - return status; 283 - 284 - efidata->data.type = SETUP_EFI_VARS; 285 - efidata->data.len = sizeof(struct efi_var_bootdata) - 286 - sizeof(struct setup_data); 287 - efidata->data.next = 0; 288 - efidata->store_size = store_size; 289 - efidata->remaining_size = remaining_size; 290 - efidata->max_var_size = var_size; 291 - 292 - if (data) 293 - data->next = (unsigned long)efidata; 294 - else 295 - params->hdr.setup_data = (unsigned long)efidata; 296 - 297 - } 298 - 299 254 static efi_status_t setup_efi_pci(struct boot_params *params) 300 255 { 301 256 efi_pci_io_protocol *pci; ··· 1156 1201 goto fail; 1157 1202 1158 1203 setup_graphics(boot_params); 1159 - 1160 - setup_efi_vars(boot_params); 1161 1204 1162 1205 setup_efi_pci(boot_params); 1163 1206
-7
arch/x86/include/asm/efi.h
··· 102 102 extern void efi_unmap_memmap(void); 103 103 extern void efi_memory_uc(u64 addr, unsigned long size); 104 104 105 - struct efi_var_bootdata { 106 - struct setup_data data; 107 - u64 store_size; 108 - u64 remaining_size; 109 - u64 max_var_size; 110 - }; 111 - 112 105 #ifdef CONFIG_EFI 113 106 114 107 static inline bool efi_is_native(void)
-1
arch/x86/include/uapi/asm/bootparam.h
··· 6 6 #define SETUP_E820_EXT 1 7 7 #define SETUP_DTB 2 8 8 #define SETUP_PCI 3 9 - #define SETUP_EFI_VARS 4 10 9 11 10 /* ram_size flags */ 12 11 #define RAMDISK_IMAGE_START_MASK 0x07FF
+65 -123
arch/x86/platform/efi/efi.c
··· 42 42 #include <linux/io.h> 43 43 #include <linux/reboot.h> 44 44 #include <linux/bcd.h> 45 - #include <linux/ucs2_string.h> 46 45 47 46 #include <asm/setup.h> 48 47 #include <asm/efi.h> ··· 53 54 54 55 #define EFI_DEBUG 1 55 56 56 - /* 57 - * There's some additional metadata associated with each 58 - * variable. Intel's reference implementation is 60 bytes - bump that 59 - * to account for potential alignment constraints 60 - */ 61 - #define VAR_METADATA_SIZE 64 57 + #define EFI_MIN_RESERVE 5120 58 + 59 + #define EFI_DUMMY_GUID \ 60 + EFI_GUID(0x4424ac57, 0xbe4b, 0x47dd, 0x9e, 0x97, 0xed, 0x50, 0xf0, 0x9f, 0x92, 0xa9) 61 + 62 + static efi_char16_t efi_dummy_name[6] = { 'D', 'U', 'M', 'M', 'Y', 0 }; 62 63 63 64 struct efi __read_mostly efi = { 64 65 .mps = EFI_INVALID_TABLE_ADDR, ··· 77 78 78 79 static struct efi efi_phys __initdata; 79 80 static efi_system_table_t efi_systab __initdata; 80 - 81 - static u64 efi_var_store_size; 82 - static u64 efi_var_remaining_size; 83 - static u64 efi_var_max_var_size; 84 - static u64 boot_used_size; 85 - static u64 boot_var_size; 86 - static u64 active_size; 87 81 88 82 unsigned long x86_efi_facility; 89 83 ··· 180 188 efi_char16_t *name, 181 189 efi_guid_t *vendor) 182 190 { 183 - efi_status_t status; 184 - static bool finished = false; 185 - static u64 var_size; 186 - 187 - status = efi_call_virt3(get_next_variable, 188 - name_size, name, vendor); 189 - 190 - if (status == EFI_NOT_FOUND) { 191 - finished = true; 192 - if (var_size < boot_used_size) { 193 - boot_var_size = boot_used_size - var_size; 194 - active_size += boot_var_size; 195 - } else { 196 - printk(KERN_WARNING FW_BUG "efi: Inconsistent initial sizes\n"); 197 - } 198 - } 199 - 200 - if (boot_used_size && !finished) { 201 - unsigned long size = 0; 202 - u32 attr; 203 - efi_status_t s; 204 - void *tmp; 205 - 206 - s = virt_efi_get_variable(name, vendor, &attr, &size, NULL); 207 - 208 - if (s != EFI_BUFFER_TOO_SMALL || !size) 209 - return status; 210 - 211 - tmp = kmalloc(size, GFP_ATOMIC); 212 - 213 - if (!tmp) 214 - return status; 215 - 216 - s = virt_efi_get_variable(name, vendor, &attr, &size, tmp); 217 - 218 - if (s == EFI_SUCCESS && (attr & EFI_VARIABLE_NON_VOLATILE)) { 219 - var_size += size; 220 - var_size += ucs2_strsize(name, 1024); 221 - active_size += size; 222 - active_size += VAR_METADATA_SIZE; 223 - active_size += ucs2_strsize(name, 1024); 224 - } 225 - 226 - kfree(tmp); 227 - } 228 - 229 - return status; 191 + return efi_call_virt3(get_next_variable, 192 + name_size, name, vendor); 230 193 } 231 194 232 195 static efi_status_t virt_efi_set_variable(efi_char16_t *name, ··· 190 243 unsigned long data_size, 191 244 void *data) 192 245 { 193 - efi_status_t status; 194 - u32 orig_attr = 0; 195 - unsigned long orig_size = 0; 196 - 197 - status = virt_efi_get_variable(name, vendor, &orig_attr, &orig_size, 198 - NULL); 199 - 200 - if (status != EFI_BUFFER_TOO_SMALL) 201 - orig_size = 0; 202 - 203 - status = efi_call_virt5(set_variable, 204 - name, vendor, attr, 205 - data_size, data); 206 - 207 - if (status == EFI_SUCCESS) { 208 - if (orig_size) { 209 - active_size -= orig_size; 210 - active_size -= ucs2_strsize(name, 1024); 211 - active_size -= VAR_METADATA_SIZE; 212 - } 213 - if (data_size) { 214 - active_size += data_size; 215 - active_size += ucs2_strsize(name, 1024); 216 - active_size += VAR_METADATA_SIZE; 217 - } 218 - } 219 - 220 - return status; 246 + return efi_call_virt5(set_variable, 247 + name, vendor, attr, 248 + data_size, data); 221 249 } 222 250 223 251 static efi_status_t virt_efi_query_variable_info(u32 attr, ··· 708 786 char vendor[100] = "unknown"; 709 787 int i = 0; 710 788 void *tmp; 711 - struct setup_data *data; 712 - struct efi_var_bootdata *efi_var_data; 713 - u64 pa_data; 714 789 715 790 #ifdef CONFIG_X86_32 716 791 if (boot_params.efi_info.efi_systab_hi || ··· 724 805 725 806 if (efi_systab_init(efi_phys.systab)) 726 807 return; 727 - 728 - pa_data = boot_params.hdr.setup_data; 729 - while (pa_data) { 730 - data = early_ioremap(pa_data, sizeof(*efi_var_data)); 731 - if (data->type == SETUP_EFI_VARS) { 732 - efi_var_data = (struct efi_var_bootdata *)data; 733 - 734 - efi_var_store_size = efi_var_data->store_size; 735 - efi_var_remaining_size = efi_var_data->remaining_size; 736 - efi_var_max_var_size = efi_var_data->max_var_size; 737 - } 738 - pa_data = data->next; 739 - early_iounmap(data, sizeof(*efi_var_data)); 740 - } 741 - 742 - boot_used_size = efi_var_store_size - efi_var_remaining_size; 743 808 744 809 set_bit(EFI_SYSTEM_TABLES, &x86_efi_facility); 745 810 ··· 988 1085 runtime_code_page_mkexec(); 989 1086 990 1087 kfree(new_memmap); 1088 + 1089 + /* clean DUMMY object */ 1090 + efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID, 1091 + EFI_VARIABLE_NON_VOLATILE | 1092 + EFI_VARIABLE_BOOTSERVICE_ACCESS | 1093 + EFI_VARIABLE_RUNTIME_ACCESS, 1094 + 0, NULL); 991 1095 } 992 1096 993 1097 /* ··· 1046 1136 efi_status_t status; 1047 1137 u64 storage_size, remaining_size, max_size; 1048 1138 1139 + if (!(attributes & EFI_VARIABLE_NON_VOLATILE)) 1140 + return 0; 1141 + 1049 1142 status = efi.query_variable_info(attributes, &storage_size, 1050 1143 &remaining_size, &max_size); 1051 1144 if (status != EFI_SUCCESS) 1052 1145 return status; 1053 1146 1054 - if (!max_size && remaining_size > size) 1055 - printk_once(KERN_ERR FW_BUG "Broken EFI implementation" 1056 - " is returning MaxVariableSize=0\n"); 1057 1147 /* 1058 1148 * Some firmware implementations refuse to boot if there's insufficient 1059 1149 * space in the variable store. We account for that by refusing the 1060 1150 * write if permitting it would reduce the available space to under 1061 - * 50%. However, some firmware won't reclaim variable space until 1062 - * after the used (not merely the actively used) space drops below 1063 - * a threshold. We can approximate that case with the value calculated 1064 - * above. If both the firmware and our calculations indicate that the 1065 - * available space would drop below 50%, refuse the write. 1151 + * 5KB. This figure was provided by Samsung, so should be safe. 1066 1152 */ 1153 + if ((remaining_size - size < EFI_MIN_RESERVE) && 1154 + !efi_no_storage_paranoia) { 1067 1155 1068 - if (!storage_size || size > remaining_size || 1069 - (max_size && size > max_size)) 1070 - return EFI_OUT_OF_RESOURCES; 1156 + /* 1157 + * Triggering garbage collection may require that the firmware 1158 + * generate a real EFI_OUT_OF_RESOURCES error. We can force 1159 + * that by attempting to use more space than is available. 1160 + */ 1161 + unsigned long dummy_size = remaining_size + 1024; 1162 + void *dummy = kmalloc(dummy_size, GFP_ATOMIC); 1071 1163 1072 - if (!efi_no_storage_paranoia && 1073 - ((active_size + size + VAR_METADATA_SIZE > storage_size / 2) && 1074 - (remaining_size - size < storage_size / 2))) 1075 - return EFI_OUT_OF_RESOURCES; 1164 + status = efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID, 1165 + EFI_VARIABLE_NON_VOLATILE | 1166 + EFI_VARIABLE_BOOTSERVICE_ACCESS | 1167 + EFI_VARIABLE_RUNTIME_ACCESS, 1168 + dummy_size, dummy); 1169 + 1170 + if (status == EFI_SUCCESS) { 1171 + /* 1172 + * This should have failed, so if it didn't make sure 1173 + * that we delete it... 1174 + */ 1175 + efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID, 1176 + EFI_VARIABLE_NON_VOLATILE | 1177 + EFI_VARIABLE_BOOTSERVICE_ACCESS | 1178 + EFI_VARIABLE_RUNTIME_ACCESS, 1179 + 0, dummy); 1180 + } 1181 + 1182 + /* 1183 + * The runtime code may now have triggered a garbage collection 1184 + * run, so check the variable info again 1185 + */ 1186 + status = efi.query_variable_info(attributes, &storage_size, 1187 + &remaining_size, &max_size); 1188 + 1189 + if (status != EFI_SUCCESS) 1190 + return status; 1191 + 1192 + /* 1193 + * There still isn't enough room, so return an error 1194 + */ 1195 + if (remaining_size - size < EFI_MIN_RESERVE) 1196 + return EFI_OUT_OF_RESOURCES; 1197 + } 1076 1198 1077 1199 return EFI_SUCCESS; 1078 1200 }