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

Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 fixes from Peter Anvin:
"Several boot fixes (MacBook, legacy EFI bootloaders), another
please-don't-brick fix, and some minor stuff."

* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86: Do not try to sync identity map for non-mapped pages
x86, doc: Be explicit about what the x86 struct boot_params requires
x86: Don't clear efi_info even if the sentinel hits
x86, mm: Make sure to find a 2M free block for the first mapped area
x86: Fix 32-bit *_cpu_data initializers
efivarfs: return accurate error code in efivarfs_fill_super()
efivars: efivarfs_valid_name() should handle pstore syntax
efi: be more paranoid about available space when creating variables
iommu, x86: Add DMA remap fault reason
x86, smpboot: Remove unused variable

+192 -43
+18 -2
arch/x86/include/asm/bootparam_utils.h
··· 14 14 * analysis of kexec-tools; if other broken bootloaders initialize a 15 15 * different set of fields we will need to figure out how to disambiguate. 16 16 * 17 + * Note: efi_info is commonly left uninitialized, but that field has a 18 + * private magic, so it is better to leave it unchanged. 17 19 */ 18 20 static void sanitize_boot_params(struct boot_params *boot_params) 19 21 { 22 + /* 23 + * IMPORTANT NOTE TO BOOTLOADER AUTHORS: do not simply clear 24 + * this field. The purpose of this field is to guarantee 25 + * compliance with the x86 boot spec located in 26 + * Documentation/x86/boot.txt . That spec says that the 27 + * *whole* structure should be cleared, after which only the 28 + * portion defined by struct setup_header (boot_params->hdr) 29 + * should be copied in. 30 + * 31 + * If you're having an issue because the sentinel is set, you 32 + * need to change the whole structure to be cleared, not this 33 + * (or any other) individual field, or you will soon have 34 + * problems again. 35 + */ 20 36 if (boot_params->sentinel) { 21 - /*fields in boot_params are not valid, clear them */ 37 + /* fields in boot_params are left uninitialized, clear them */ 22 38 memset(&boot_params->olpc_ofw_header, 0, 23 - (char *)&boot_params->alt_mem_k - 39 + (char *)&boot_params->efi_info - 24 40 (char *)&boot_params->olpc_ofw_header); 25 41 memset(&boot_params->kbd_status, 0, 26 42 (char *)&boot_params->hdr -
+8 -2
arch/x86/kernel/setup.c
··· 171 171 172 172 #ifdef CONFIG_X86_32 173 173 /* cpu data as detected by the assembly code in head.S */ 174 - struct cpuinfo_x86 new_cpu_data __cpuinitdata = {0, 0, 0, 0, -1, 1, 0, 0, -1}; 174 + struct cpuinfo_x86 new_cpu_data __cpuinitdata = { 175 + .wp_works_ok = -1, 176 + .fdiv_bug = -1, 177 + }; 175 178 /* common cpu data for all cpus */ 176 - struct cpuinfo_x86 boot_cpu_data __read_mostly = {0, 0, 0, 0, -1, 1, 0, 0, -1}; 179 + struct cpuinfo_x86 boot_cpu_data __read_mostly = { 180 + .wp_works_ok = -1, 181 + .fdiv_bug = -1, 182 + }; 177 183 EXPORT_SYMBOL(boot_cpu_data); 178 184 179 185 unsigned int def_to_bigsmp;
+1 -2
arch/x86/kernel/smpboot.c
··· 1365 1365 unsigned int eax, ebx, ecx, edx; 1366 1366 unsigned int highest_cstate = 0; 1367 1367 unsigned int highest_subcstate = 0; 1368 - int i; 1369 1368 void *mwait_ptr; 1370 - struct cpuinfo_x86 *c = __this_cpu_ptr(&cpu_info); 1369 + int i; 1371 1370 1372 1371 if (!this_cpu_has(X86_FEATURE_MWAIT)) 1373 1372 return;
+2 -3
arch/x86/mm/init.c
··· 410 410 /* the ISA range is always mapped regardless of memory holes */ 411 411 init_memory_mapping(0, ISA_END_ADDRESS); 412 412 413 - /* xen has big range in reserved near end of ram, skip it at first */ 414 - addr = memblock_find_in_range(ISA_END_ADDRESS, end, PMD_SIZE, 415 - PAGE_SIZE); 413 + /* xen has big range in reserved near end of ram, skip it at first.*/ 414 + addr = memblock_find_in_range(ISA_END_ADDRESS, end, PMD_SIZE, PMD_SIZE); 416 415 real_end = addr + PMD_SIZE; 417 416 418 417 /* step_size need to be small so pgt_buf from BRK could cover it */
+7
arch/x86/mm/pat.c
··· 563 563 if (base > __pa(high_memory-1)) 564 564 return 0; 565 565 566 + /* 567 + * some areas in the middle of the kernel identity range 568 + * are not mapped, like the PCI space. 569 + */ 570 + if (!page_is_ram(base >> PAGE_SHIFT)) 571 + return 0; 572 + 566 573 id_sz = (__pa(high_memory-1) <= base + size) ? 567 574 __pa(high_memory) - base : 568 575 size;
+96 -34
drivers/firmware/efivars.c
··· 426 426 return status; 427 427 } 428 428 429 + static efi_status_t 430 + check_var_size_locked(struct efivars *efivars, u32 attributes, 431 + unsigned long size) 432 + { 433 + u64 storage_size, remaining_size, max_size; 434 + efi_status_t status; 435 + const struct efivar_operations *fops = efivars->ops; 436 + 437 + if (!efivars->ops->query_variable_info) 438 + return EFI_UNSUPPORTED; 439 + 440 + status = fops->query_variable_info(attributes, &storage_size, 441 + &remaining_size, &max_size); 442 + 443 + if (status != EFI_SUCCESS) 444 + return status; 445 + 446 + if (!storage_size || size > remaining_size || size > max_size || 447 + (remaining_size - size) < (storage_size / 2)) 448 + return EFI_OUT_OF_RESOURCES; 449 + 450 + return status; 451 + } 452 + 453 + 454 + static efi_status_t 455 + check_var_size(struct efivars *efivars, u32 attributes, unsigned long size) 456 + { 457 + efi_status_t status; 458 + unsigned long flags; 459 + 460 + spin_lock_irqsave(&efivars->lock, flags); 461 + status = check_var_size_locked(efivars, attributes, size); 462 + spin_unlock_irqrestore(&efivars->lock, flags); 463 + 464 + return status; 465 + } 466 + 429 467 static ssize_t 430 468 efivar_guid_read(struct efivar_entry *entry, char *buf) 431 469 { ··· 585 547 } 586 548 587 549 spin_lock_irq(&efivars->lock); 588 - status = efivars->ops->set_variable(new_var->VariableName, 589 - &new_var->VendorGuid, 590 - new_var->Attributes, 591 - new_var->DataSize, 592 - new_var->Data); 550 + 551 + status = check_var_size_locked(efivars, new_var->Attributes, 552 + new_var->DataSize + utf16_strsize(new_var->VariableName, 1024)); 553 + 554 + if (status == EFI_SUCCESS || status == EFI_UNSUPPORTED) 555 + status = efivars->ops->set_variable(new_var->VariableName, 556 + &new_var->VendorGuid, 557 + new_var->Attributes, 558 + new_var->DataSize, 559 + new_var->Data); 593 560 594 561 spin_unlock_irq(&efivars->lock); 595 562 ··· 745 702 u32 attributes; 746 703 struct inode *inode = file->f_mapping->host; 747 704 unsigned long datasize = count - sizeof(attributes); 748 - unsigned long newdatasize; 749 - u64 storage_size, remaining_size, max_size; 705 + unsigned long newdatasize, varsize; 750 706 ssize_t bytes = 0; 751 707 752 708 if (count < sizeof(attributes)) ··· 764 722 * amounts of memory. Pick a default size of 64K if 765 723 * QueryVariableInfo() isn't supported by the firmware. 766 724 */ 767 - spin_lock_irq(&efivars->lock); 768 725 769 - if (!efivars->ops->query_variable_info) 770 - status = EFI_UNSUPPORTED; 771 - else { 772 - const struct efivar_operations *fops = efivars->ops; 773 - status = fops->query_variable_info(attributes, &storage_size, 774 - &remaining_size, &max_size); 775 - } 776 - 777 - spin_unlock_irq(&efivars->lock); 726 + varsize = datasize + utf16_strsize(var->var.VariableName, 1024); 727 + status = check_var_size(efivars, attributes, varsize); 778 728 779 729 if (status != EFI_SUCCESS) { 780 730 if (status != EFI_UNSUPPORTED) 781 731 return efi_status_to_err(status); 782 732 783 - remaining_size = 65536; 733 + if (datasize > 65536) 734 + return -ENOSPC; 784 735 } 785 - 786 - if (datasize > remaining_size) 787 - return -ENOSPC; 788 736 789 737 data = kmalloc(datasize, GFP_KERNEL); 790 738 if (!data) ··· 796 764 * list (in the case of an authenticated delete). 797 765 */ 798 766 spin_lock_irq(&efivars->lock); 767 + 768 + /* 769 + * Ensure that the available space hasn't shrunk below the safe level 770 + */ 771 + 772 + status = check_var_size_locked(efivars, attributes, varsize); 773 + 774 + if (status != EFI_SUCCESS && status != EFI_UNSUPPORTED) { 775 + spin_unlock_irq(&efivars->lock); 776 + kfree(data); 777 + 778 + return efi_status_to_err(status); 779 + } 799 780 800 781 status = efivars->ops->set_variable(var->var.VariableName, 801 782 &var->var.VendorGuid, ··· 974 929 if (len < GUID_LEN + 2) 975 930 return false; 976 931 977 - /* GUID should be right after the first '-' */ 978 - if (s - 1 != strchr(str, '-')) 932 + /* GUID must be preceded by a '-' */ 933 + if (*(s - 1) != '-') 979 934 return false; 980 935 981 936 /* ··· 1163 1118 1164 1119 static struct dentry *efivarfs_alloc_dentry(struct dentry *parent, char *name) 1165 1120 { 1121 + struct dentry *d; 1166 1122 struct qstr q; 1123 + int err; 1167 1124 1168 1125 q.name = name; 1169 1126 q.len = strlen(name); 1170 1127 1171 - if (efivarfs_d_hash(NULL, NULL, &q)) 1172 - return NULL; 1128 + err = efivarfs_d_hash(NULL, NULL, &q); 1129 + if (err) 1130 + return ERR_PTR(err); 1173 1131 1174 - return d_alloc(parent, &q); 1132 + d = d_alloc(parent, &q); 1133 + if (d) 1134 + return d; 1135 + 1136 + return ERR_PTR(-ENOMEM); 1175 1137 } 1176 1138 1177 1139 static int efivarfs_fill_super(struct super_block *sb, void *data, int silent) ··· 1188 1136 struct efivar_entry *entry, *n; 1189 1137 struct efivars *efivars = &__efivars; 1190 1138 char *name; 1139 + int err = -ENOMEM; 1191 1140 1192 1141 efivarfs_sb = sb; 1193 1142 ··· 1239 1186 goto fail_name; 1240 1187 1241 1188 dentry = efivarfs_alloc_dentry(root, name); 1242 - if (!dentry) 1189 + if (IS_ERR(dentry)) { 1190 + err = PTR_ERR(dentry); 1243 1191 goto fail_inode; 1192 + } 1244 1193 1245 1194 /* copied by the above to local storage in the dentry. */ 1246 1195 kfree(name); ··· 1269 1214 fail_name: 1270 1215 kfree(name); 1271 1216 fail: 1272 - return -ENOMEM; 1217 + return err; 1273 1218 } 1274 1219 1275 1220 static struct dentry *efivarfs_mount(struct file_system_type *fs_type, ··· 1400 1345 efi_guid_t vendor = LINUX_EFI_CRASH_GUID; 1401 1346 struct efivars *efivars = psi->data; 1402 1347 int i, ret = 0; 1403 - u64 storage_space, remaining_space, max_variable_size; 1404 1348 efi_status_t status = EFI_NOT_FOUND; 1405 1349 unsigned long flags; 1406 1350 ··· 1419 1365 * size: a size of logging data 1420 1366 * DUMP_NAME_LEN * 2: a maximum size of variable name 1421 1367 */ 1422 - status = efivars->ops->query_variable_info(PSTORE_EFI_ATTRIBUTES, 1423 - &storage_space, 1424 - &remaining_space, 1425 - &max_variable_size); 1426 - if (status || remaining_space < size + DUMP_NAME_LEN * 2) { 1368 + 1369 + status = check_var_size_locked(efivars, PSTORE_EFI_ATTRIBUTES, 1370 + size + DUMP_NAME_LEN * 2); 1371 + 1372 + if (status) { 1427 1373 spin_unlock_irqrestore(&efivars->lock, flags); 1428 1374 *id = part; 1429 1375 return -ENOSPC; ··· 1596 1542 if (found) { 1597 1543 spin_unlock_irq(&efivars->lock); 1598 1544 return -EINVAL; 1545 + } 1546 + 1547 + status = check_var_size_locked(efivars, new_var->Attributes, 1548 + new_var->DataSize + utf16_strsize(new_var->VariableName, 1024)); 1549 + 1550 + if (status && status != EFI_UNSUPPORTED) { 1551 + spin_unlock_irq(&efivars->lock); 1552 + return efi_status_to_err(status); 1599 1553 } 1600 1554 1601 1555 /* now *really* create the variable via EFI */
+1
drivers/iommu/dmar.c
··· 1083 1083 "non-zero reserved fields in RTP", 1084 1084 "non-zero reserved fields in CTP", 1085 1085 "non-zero reserved fields in PTE", 1086 + "PCE for translation request specifies blocking", 1086 1087 }; 1087 1088 1088 1089 static const char *irq_remap_fault_reasons[] =
+59
tools/testing/selftests/efivarfs/efivarfs.sh
··· 125 125 ./open-unlink $file 126 126 } 127 127 128 + # test that we can create a range of filenames 129 + test_valid_filenames() 130 + { 131 + local attrs='\x07\x00\x00\x00' 132 + local ret=0 133 + 134 + local file_list="abc dump-type0-11-1-1362436005 1234 -" 135 + for f in $file_list; do 136 + local file=$efivarfs_mount/$f-$test_guid 137 + 138 + printf "$attrs\x00" > $file 139 + 140 + if [ ! -e $file ]; then 141 + echo "$file could not be created" >&2 142 + ret=1 143 + else 144 + rm $file 145 + fi 146 + done 147 + 148 + exit $ret 149 + } 150 + 151 + test_invalid_filenames() 152 + { 153 + local attrs='\x07\x00\x00\x00' 154 + local ret=0 155 + 156 + local file_list=" 157 + -1234-1234-1234-123456789abc 158 + foo 159 + foo-bar 160 + -foo- 161 + foo-barbazba-foob-foob-foob-foobarbazfoo 162 + foo------------------------------------- 163 + -12345678-1234-1234-1234-123456789abc 164 + a-12345678=1234-1234-1234-123456789abc 165 + a-12345678-1234=1234-1234-123456789abc 166 + a-12345678-1234-1234=1234-123456789abc 167 + a-12345678-1234-1234-1234=123456789abc 168 + 1112345678-1234-1234-1234-123456789abc" 169 + 170 + for f in $file_list; do 171 + local file=$efivarfs_mount/$f 172 + 173 + printf "$attrs\x00" 2>/dev/null > $file 174 + 175 + if [ -e $file ]; then 176 + echo "Creating $file should have failed" >&2 177 + rm $file 178 + ret=1 179 + fi 180 + done 181 + 182 + exit $ret 183 + } 184 + 128 185 check_prereqs 129 186 130 187 rc=0 ··· 192 135 run_test test_delete 193 136 run_test test_zero_size_delete 194 137 run_test test_open_unlink 138 + run_test test_valid_filenames 139 + run_test test_invalid_filenames 195 140 196 141 exit $rc