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 branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 fixes from Thomas Gleixner:
"A couple of fixes addressing the following issues:

- The last polishing for the TLB code, removing the last BUG_ON() and
the debug file along with tidying up the lazy TLB code.

- Prevent triple fault on 1st Gen. 486 caused by stupidly calling the
early IDT setup after the first function which causes a fault which
should be caught by the exception table.

- Limit the mmap of /dev/mem to valid addresses

- Prevent late microcode loading on Broadwell X

- Remove a redundant assignment in the cache info code"

* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/mm: Limit mmap() of /dev/mem to valid physical addresses
x86/mm: Remove debug/x86/tlb_defer_switch_to_init_mm
x86/mm: Tidy up "x86/mm: Flush more aggressively in lazy TLB mode"
x86/mm/64: Remove the last VM_BUG_ON() from the TLB code
x86/microcode/intel: Disable late loading on model 79
x86/idt: Initialize early IDT before cr4_init_shadow()
x86/cpu/intel_cacheinfo: Remove redundant assignment to 'this_leaf'

+59 -67
+4
arch/x86/include/asm/io.h
··· 110 110 111 111 #endif 112 112 113 + #define ARCH_HAS_VALID_PHYS_ADDR_RANGE 114 + extern int valid_phys_addr_range(phys_addr_t addr, size_t size); 115 + extern int valid_mmap_phys_addr_range(unsigned long pfn, size_t size); 116 + 113 117 /** 114 118 * virt_to_phys - map virtual addresses to physical 115 119 * @address: address to remap
+15 -6
arch/x86/include/asm/tlbflush.h
··· 82 82 #define __flush_tlb_single(addr) __native_flush_tlb_single(addr) 83 83 #endif 84 84 85 - /* 86 - * If tlb_use_lazy_mode is true, then we try to avoid switching CR3 to point 87 - * to init_mm when we switch to a kernel thread (e.g. the idle thread). If 88 - * it's false, then we immediately switch CR3 when entering a kernel thread. 89 - */ 90 - DECLARE_STATIC_KEY_TRUE(tlb_use_lazy_mode); 85 + static inline bool tlb_defer_switch_to_init_mm(void) 86 + { 87 + /* 88 + * If we have PCID, then switching to init_mm is reasonably 89 + * fast. If we don't have PCID, then switching to init_mm is 90 + * quite slow, so we try to defer it in the hopes that we can 91 + * avoid it entirely. The latter approach runs the risk of 92 + * receiving otherwise unnecessary IPIs. 93 + * 94 + * This choice is just a heuristic. The tlb code can handle this 95 + * function returning true or false regardless of whether we have 96 + * PCID. 97 + */ 98 + return !static_cpu_has(X86_FEATURE_PCID); 99 + } 91 100 92 101 /* 93 102 * 6 because 6 should be plenty and struct tlb_state will fit in
-1
arch/x86/kernel/cpu/intel_cacheinfo.c
··· 831 831 } else if (boot_cpu_has(X86_FEATURE_TOPOEXT)) { 832 832 unsigned int apicid, nshared, first, last; 833 833 834 - this_leaf = this_cpu_ci->info_list + index; 835 834 nshared = base->eax.split.num_threads_sharing + 1; 836 835 apicid = cpu_data(cpu).apicid; 837 836 first = apicid - (apicid % nshared);
+19
arch/x86/kernel/cpu/microcode/intel.c
··· 34 34 #include <linux/mm.h> 35 35 36 36 #include <asm/microcode_intel.h> 37 + #include <asm/intel-family.h> 37 38 #include <asm/processor.h> 38 39 #include <asm/tlbflush.h> 39 40 #include <asm/setup.h> ··· 919 918 return 0; 920 919 } 921 920 921 + static bool is_blacklisted(unsigned int cpu) 922 + { 923 + struct cpuinfo_x86 *c = &cpu_data(cpu); 924 + 925 + if (c->x86 == 6 && c->x86_model == INTEL_FAM6_BROADWELL_X) { 926 + pr_err_once("late loading on model 79 is disabled.\n"); 927 + return true; 928 + } 929 + 930 + return false; 931 + } 932 + 922 933 static enum ucode_state request_microcode_fw(int cpu, struct device *device, 923 934 bool refresh_fw) 924 935 { ··· 938 925 struct cpuinfo_x86 *c = &cpu_data(cpu); 939 926 const struct firmware *firmware; 940 927 enum ucode_state ret; 928 + 929 + if (is_blacklisted(cpu)) 930 + return UCODE_NFOUND; 941 931 942 932 sprintf(name, "intel-ucode/%02x-%02x-%02x", 943 933 c->x86, c->x86_model, c->x86_mask); ··· 966 950 static enum ucode_state 967 951 request_microcode_user(int cpu, const void __user *buf, size_t size) 968 952 { 953 + if (is_blacklisted(cpu)) 954 + return UCODE_NFOUND; 955 + 969 956 return generic_load_microcode(cpu, (void *)buf, size, &get_ucode_user); 970 957 } 971 958
+3 -2
arch/x86/kernel/head32.c
··· 30 30 31 31 asmlinkage __visible void __init i386_start_kernel(void) 32 32 { 33 - cr4_init_shadow(); 34 - 33 + /* Make sure IDT is set up before any exception happens */ 35 34 idt_setup_early_handler(); 35 + 36 + cr4_init_shadow(); 36 37 37 38 sanitize_boot_params(&boot_params); 38 39
+12
arch/x86/mm/mmap.c
··· 174 174 return "[mpx]"; 175 175 return NULL; 176 176 } 177 + 178 + int valid_phys_addr_range(phys_addr_t addr, size_t count) 179 + { 180 + return addr + count <= __pa(high_memory); 181 + } 182 + 183 + int valid_mmap_phys_addr_range(unsigned long pfn, size_t count) 184 + { 185 + phys_addr_t addr = (phys_addr_t)pfn << PAGE_SHIFT; 186 + 187 + return valid_phys_addr_range(addr, count); 188 + }
+6 -58
arch/x86/mm/tlb.c
··· 30 30 31 31 atomic64_t last_mm_ctx_id = ATOMIC64_INIT(1); 32 32 33 - DEFINE_STATIC_KEY_TRUE(tlb_use_lazy_mode); 34 33 35 34 static void choose_new_asid(struct mm_struct *next, u64 next_tlb_gen, 36 35 u16 *new_asid, bool *need_flush) ··· 146 147 this_cpu_write(cpu_tlbstate.is_lazy, false); 147 148 148 149 if (real_prev == next) { 149 - VM_BUG_ON(this_cpu_read(cpu_tlbstate.ctxs[prev_asid].ctx_id) != 150 - next->context.ctx_id); 150 + VM_WARN_ON(this_cpu_read(cpu_tlbstate.ctxs[prev_asid].ctx_id) != 151 + next->context.ctx_id); 151 152 152 153 /* 153 154 * We don't currently support having a real mm loaded without ··· 212 213 } 213 214 214 215 /* 216 + * Please ignore the name of this function. It should be called 217 + * switch_to_kernel_thread(). 218 + * 215 219 * enter_lazy_tlb() is a hint from the scheduler that we are entering a 216 220 * kernel thread or other context without an mm. Acceptable implementations 217 221 * include doing nothing whatsoever, switching to init_mm, or various clever ··· 229 227 if (this_cpu_read(cpu_tlbstate.loaded_mm) == &init_mm) 230 228 return; 231 229 232 - if (static_branch_unlikely(&tlb_use_lazy_mode)) { 230 + if (tlb_defer_switch_to_init_mm()) { 233 231 /* 234 232 * There's a significant optimization that may be possible 235 233 * here. We have accurate enough TLB flush tracking that we ··· 628 626 return 0; 629 627 } 630 628 late_initcall(create_tlb_single_page_flush_ceiling); 631 - 632 - static ssize_t tlblazy_read_file(struct file *file, char __user *user_buf, 633 - size_t count, loff_t *ppos) 634 - { 635 - char buf[2]; 636 - 637 - buf[0] = static_branch_likely(&tlb_use_lazy_mode) ? '1' : '0'; 638 - buf[1] = '\n'; 639 - 640 - return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 641 - } 642 - 643 - static ssize_t tlblazy_write_file(struct file *file, 644 - const char __user *user_buf, size_t count, loff_t *ppos) 645 - { 646 - bool val; 647 - 648 - if (kstrtobool_from_user(user_buf, count, &val)) 649 - return -EINVAL; 650 - 651 - if (val) 652 - static_branch_enable(&tlb_use_lazy_mode); 653 - else 654 - static_branch_disable(&tlb_use_lazy_mode); 655 - 656 - return count; 657 - } 658 - 659 - static const struct file_operations fops_tlblazy = { 660 - .read = tlblazy_read_file, 661 - .write = tlblazy_write_file, 662 - .llseek = default_llseek, 663 - }; 664 - 665 - static int __init init_tlb_use_lazy_mode(void) 666 - { 667 - if (boot_cpu_has(X86_FEATURE_PCID)) { 668 - /* 669 - * Heuristic: with PCID on, switching to and from 670 - * init_mm is reasonably fast, but remote flush IPIs 671 - * as expensive as ever, so turn off lazy TLB mode. 672 - * 673 - * We can't do this in setup_pcid() because static keys 674 - * haven't been initialized yet, and it would blow up 675 - * badly. 676 - */ 677 - static_branch_disable(&tlb_use_lazy_mode); 678 - } 679 - 680 - debugfs_create_file("tlb_use_lazy_mode", S_IRUSR | S_IWUSR, 681 - arch_debugfs_dir, NULL, &fops_tlblazy); 682 - return 0; 683 - } 684 - late_initcall(init_tlb_use_lazy_mode);