]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 16 Jun 2019 17:28:14 +0000 (07:28 -1000)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 16 Jun 2019 17:28:14 +0000 (07:28 -1000)
Pull x86 fixes from Thomas Gleixner:
 "The accumulated fixes from this and last week:

   - Fix vmalloc TLB flush and map range calculations which lead to
     stale TLBs, spurious faults and other hard to diagnose issues.

   - Use fault_in_pages_writable() for prefaulting the user stack in the
     FPU code as it's less fragile than the current solution

   - Use the PF_KTHREAD flag when checking for a kernel thread instead
     of current->mm as the latter can give the wrong answer due to
     use_mm()

   - Compute the vmemmap size correctly for KASLR and 5-Level paging.
     Otherwise this can end up with a way too small vmemmap area.

   - Make KASAN and 5-level paging work again by making sure that all
     invalid bits are masked out when computing the P4D offset. This
     worked before but got broken recently when the LDT remap area was
     moved.

   - Prevent a NULL pointer dereference in the resource control code
     which can be triggered with certain mount options when the
     requested resource is not available.

   - Enforce ordering of microcode loading vs. perf initialization on
     secondary CPUs. Otherwise perf tries to access a non-existing MSR
     as the boot CPU marked it as available.

   - Don't stop the resource control group walk early otherwise the
     control bitmaps are not updated correctly and become inconsistent.

   - Unbreak kgdb by returning 0 on success from
     kgdb_arch_set_breakpoint() instead of an error code.

   - Add more Icelake CPU model defines so depending changes can be
     queued in other trees"

* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/microcode, cpuhotplug: Add a microcode loader CPU hotplug callback
  x86/kasan: Fix boot with 5-level paging and KASAN
  x86/fpu: Don't use current->mm to check for a kthread
  x86/kgdb: Return 0 from kgdb_arch_set_breakpoint()
  x86/resctrl: Prevent NULL pointer dereference when local MBM is disabled
  x86/resctrl: Don't stop walking closids when a locksetup group is found
  x86/fpu: Update kernel's FPU state before using for the fsave header
  x86/mm/KASLR: Compute the size of the vmemmap section properly
  x86/fpu: Use fault_in_pages_writeable() for pre-faulting
  x86/CPU: Add more Icelake model numbers
  mm/vmalloc: Avoid rare case of flushing TLB with weird arguments
  mm/vmalloc: Fix calculation of direct map addr range

12 files changed:
arch/x86/include/asm/fpu/internal.h
arch/x86/include/asm/intel-family.h
arch/x86/kernel/cpu/microcode/core.c
arch/x86/kernel/cpu/resctrl/monitor.c
arch/x86/kernel/cpu/resctrl/rdtgroup.c
arch/x86/kernel/fpu/core.c
arch/x86/kernel/fpu/signal.c
arch/x86/kernel/kgdb.c
arch/x86/mm/kasan_init_64.c
arch/x86/mm/kaslr.c
include/linux/cpuhotplug.h
mm/vmalloc.c

index 9e27fa05a7ae6fca6503fd2eb15928db93355c8d..4c95c365058aa44a4242c5bc8ccd2cb30cc5aa7c 100644 (file)
@@ -536,7 +536,7 @@ static inline void __fpregs_load_activate(void)
        struct fpu *fpu = &current->thread.fpu;
        int cpu = smp_processor_id();
 
-       if (WARN_ON_ONCE(current->mm == NULL))
+       if (WARN_ON_ONCE(current->flags & PF_KTHREAD))
                return;
 
        if (!fpregs_state_valid(fpu, cpu)) {
@@ -567,11 +567,11 @@ static inline void __fpregs_load_activate(void)
  * otherwise.
  *
  * The FPU context is only stored/restored for a user task and
- * ->mm is used to distinguish between kernel and user threads.
+ * PF_KTHREAD is used to distinguish between kernel and user threads.
  */
 static inline void switch_fpu_prepare(struct fpu *old_fpu, int cpu)
 {
-       if (static_cpu_has(X86_FEATURE_FPU) && current->mm) {
+       if (static_cpu_has(X86_FEATURE_FPU) && !(current->flags & PF_KTHREAD)) {
                if (!copy_fpregs_to_fpstate(old_fpu))
                        old_fpu->last_cpu = -1;
                else
index 9f15384c504a407818168966610b36d3798a6683..310118805f576e1585e9114e8d0a84c1008ddd4d 100644 (file)
@@ -52,6 +52,9 @@
 
 #define INTEL_FAM6_CANNONLAKE_MOBILE   0x66
 
+#define INTEL_FAM6_ICELAKE_X           0x6A
+#define INTEL_FAM6_ICELAKE_XEON_D      0x6C
+#define INTEL_FAM6_ICELAKE_DESKTOP     0x7D
 #define INTEL_FAM6_ICELAKE_MOBILE      0x7E
 
 /* "Small Core" Processors (Atom) */
index 70a04436380e3e16affcc706366b9c6dd80f201a..a813987b5552ea84e018d72d28ec35ba93c84a1e 100644 (file)
@@ -872,7 +872,7 @@ int __init microcode_init(void)
                goto out_ucode_group;
 
        register_syscore_ops(&mc_syscore_ops);
-       cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, "x86/microcode:online",
+       cpuhp_setup_state_nocalls(CPUHP_AP_MICROCODE_LOADER, "x86/microcode:online",
                                  mc_cpu_online, mc_cpu_down_prep);
 
        pr_info("Microcode Update Driver: v%s.", DRIVER_VERSION);
index 7ee93125a2114b5f1cf818aa75103cf970193161..397206f23d14f9aeadf860747fa42662d42baadf 100644 (file)
@@ -360,6 +360,9 @@ static void update_mba_bw(struct rdtgroup *rgrp, struct rdt_domain *dom_mbm)
        struct list_head *head;
        struct rdtgroup *entry;
 
+       if (!is_mbm_local_enabled())
+               return;
+
        r_mba = &rdt_resources_all[RDT_RESOURCE_MBA];
        closid = rgrp->closid;
        rmid = rgrp->mon.rmid;
index 2f48f208f7e29eb7152e73f4351eaa449dbc39f5..2131b8bbaad7d5bc38975d792ff2b96abda6312e 100644 (file)
@@ -2534,7 +2534,12 @@ static int __init_one_rdt_domain(struct rdt_domain *d, struct rdt_resource *r,
                if (closid_allocated(i) && i != closid) {
                        mode = rdtgroup_mode_by_closid(i);
                        if (mode == RDT_MODE_PSEUDO_LOCKSETUP)
-                               break;
+                               /*
+                                * ctrl values for locksetup aren't relevant
+                                * until the schemata is written, and the mode
+                                * becomes RDT_MODE_PSEUDO_LOCKED.
+                                */
+                               continue;
                        /*
                         * If CDP is active include peer domain's
                         * usage to ensure there is no overlap
index 466fca686fb97cc9bb57f0dafba19c292037f948..649fbc3fcf9f52ee2f5bbe3f524d9d4f62b5ac95 100644 (file)
@@ -102,7 +102,7 @@ static void __kernel_fpu_begin(void)
 
        kernel_fpu_disable();
 
-       if (current->mm) {
+       if (!(current->flags & PF_KTHREAD)) {
                if (!test_thread_flag(TIF_NEED_FPU_LOAD)) {
                        set_thread_flag(TIF_NEED_FPU_LOAD);
                        /*
index 5a8d118bc423ec720f1439c6785f7f5abc0c33ed..0071b794ed19348447ddbe269fd4102d68ff536e 100644 (file)
@@ -5,6 +5,7 @@
 
 #include <linux/compat.h>
 #include <linux/cpu.h>
+#include <linux/pagemap.h>
 
 #include <asm/fpu/internal.h>
 #include <asm/fpu/signal.h>
@@ -61,6 +62,11 @@ static inline int save_fsave_header(struct task_struct *tsk, void __user *buf)
                struct user_i387_ia32_struct env;
                struct _fpstate_32 __user *fp = buf;
 
+               fpregs_lock();
+               if (!test_thread_flag(TIF_NEED_FPU_LOAD))
+                       copy_fxregs_to_kernel(&tsk->thread.fpu);
+               fpregs_unlock();
+
                convert_from_fxsr(&env, tsk);
 
                if (__copy_to_user(buf, &env, sizeof(env)) ||
@@ -189,15 +195,7 @@ retry:
        fpregs_unlock();
 
        if (ret) {
-               int aligned_size;
-               int nr_pages;
-
-               aligned_size = offset_in_page(buf_fx) + fpu_user_xstate_size;
-               nr_pages = DIV_ROUND_UP(aligned_size, PAGE_SIZE);
-
-               ret = get_user_pages_unlocked((unsigned long)buf_fx, nr_pages,
-                                             NULL, FOLL_WRITE);
-               if (ret == nr_pages)
+               if (!fault_in_pages_writeable(buf_fx, fpu_user_xstate_size))
                        goto retry;
                return -EFAULT;
        }
index 9a8c1648fc9a5167637add540d00865e697c2a07..6690c5652aebd290deebccd46a76390e8518f4cd 100644 (file)
@@ -758,7 +758,7 @@ int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
                       BREAK_INSTR_SIZE);
        bpt->type = BP_POKE_BREAKPOINT;
 
-       return err;
+       return 0;
 }
 
 int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt)
index 8dc0fc0b1382b6cde08e2774449b39b0607a1a64..296da58f30138f5f82a699b10c51e8d44c30839e 100644 (file)
@@ -199,7 +199,7 @@ static inline p4d_t *early_p4d_offset(pgd_t *pgd, unsigned long addr)
        if (!pgtable_l5_enabled())
                return (p4d_t *)pgd;
 
-       p4d = __pa_nodebug(pgd_val(*pgd)) & PTE_PFN_MASK;
+       p4d = pgd_val(*pgd) & PTE_PFN_MASK;
        p4d += __START_KERNEL_map - phys_base;
        return (p4d_t *)p4d + p4d_index(addr);
 }
index dc3f058bdf9be8bad920148a8a5737387b16b939..dc6182eecefad2b1fcf4f4f0aa2b11958d00cf24 100644 (file)
@@ -52,7 +52,7 @@ static __initdata struct kaslr_memory_region {
 } kaslr_regions[] = {
        { &page_offset_base, 0 },
        { &vmalloc_base, 0 },
-       { &vmemmap_base, 1 },
+       { &vmemmap_base, 0 },
 };
 
 /* Get size in bytes used by the memory region */
@@ -78,6 +78,7 @@ void __init kernel_randomize_memory(void)
        unsigned long rand, memory_tb;
        struct rnd_state rand_state;
        unsigned long remain_entropy;
+       unsigned long vmemmap_size;
 
        vaddr_start = pgtable_l5_enabled() ? __PAGE_OFFSET_BASE_L5 : __PAGE_OFFSET_BASE_L4;
        vaddr = vaddr_start;
@@ -109,6 +110,14 @@ void __init kernel_randomize_memory(void)
        if (memory_tb < kaslr_regions[0].size_tb)
                kaslr_regions[0].size_tb = memory_tb;
 
+       /*
+        * Calculate the vmemmap region size in TBs, aligned to a TB
+        * boundary.
+        */
+       vmemmap_size = (kaslr_regions[0].size_tb << (TB_SHIFT - PAGE_SHIFT)) *
+                       sizeof(struct page);
+       kaslr_regions[2].size_tb = DIV_ROUND_UP(vmemmap_size, 1UL << TB_SHIFT);
+
        /* Calculate entropy available between regions */
        remain_entropy = vaddr_end - vaddr_start;
        for (i = 0; i < ARRAY_SIZE(kaslr_regions); i++)
index 6a381594608cf2d4a63c4163b825d589703e3de1..5c6062206760a4b1470f616e0df52c0d205e4990 100644 (file)
@@ -101,6 +101,7 @@ enum cpuhp_state {
        CPUHP_AP_IRQ_BCM2836_STARTING,
        CPUHP_AP_IRQ_MIPS_GIC_STARTING,
        CPUHP_AP_ARM_MVEBU_COHERENCY,
+       CPUHP_AP_MICROCODE_LOADER,
        CPUHP_AP_PERF_X86_AMD_UNCORE_STARTING,
        CPUHP_AP_PERF_X86_STARTING,
        CPUHP_AP_PERF_X86_AMD_IBS_STARTING,
index 7350a124524bb4b203fff489c577586661cbf03d..4c9e150e5ad3d26356666457e2d9fb97f807c0a1 100644 (file)
@@ -2123,9 +2123,9 @@ static inline void set_area_direct_map(const struct vm_struct *area,
 /* Handle removing and resetting vm mappings related to the vm_struct. */
 static void vm_remove_mappings(struct vm_struct *area, int deallocate_pages)
 {
-       unsigned long addr = (unsigned long)area->addr;
        unsigned long start = ULONG_MAX, end = 0;
        int flush_reset = area->flags & VM_FLUSH_RESET_PERMS;
+       int flush_dmap = 0;
        int i;
 
        /*
@@ -2135,8 +2135,8 @@ static void vm_remove_mappings(struct vm_struct *area, int deallocate_pages)
         * execute permissions, without leaving a RW+X window.
         */
        if (flush_reset && !IS_ENABLED(CONFIG_ARCH_HAS_SET_DIRECT_MAP)) {
-               set_memory_nx(addr, area->nr_pages);
-               set_memory_rw(addr, area->nr_pages);
+               set_memory_nx((unsigned long)area->addr, area->nr_pages);
+               set_memory_rw((unsigned long)area->addr, area->nr_pages);
        }
 
        remove_vm_area(area->addr);
@@ -2160,9 +2160,11 @@ static void vm_remove_mappings(struct vm_struct *area, int deallocate_pages)
         * the vm_unmap_aliases() flush includes the direct map.
         */
        for (i = 0; i < area->nr_pages; i++) {
-               if (page_address(area->pages[i])) {
+               unsigned long addr = (unsigned long)page_address(area->pages[i]);
+               if (addr) {
                        start = min(addr, start);
-                       end = max(addr, end);
+                       end = max(addr + PAGE_SIZE, end);
+                       flush_dmap = 1;
                }
        }
 
@@ -2172,7 +2174,7 @@ static void vm_remove_mappings(struct vm_struct *area, int deallocate_pages)
         * reset the direct map permissions to the default.
         */
        set_area_direct_map(area, set_direct_map_invalid_noflush);
-       _vm_unmap_aliases(start, end, 1);
+       _vm_unmap_aliases(start, end, flush_dmap);
        set_area_direct_map(area, set_direct_map_default_noflush);
 }