Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 18 Dec 2016 19:12:53 +0000 (11:12 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 18 Dec 2016 19:12:53 +0000 (11:12 -0800)
Pull x86 fixes and cleanups from Thomas Gleixner:
 "This set of updates contains:

   - Robustification for the logical package managment. Cures the AMD
     and virtualization issues.

   - Put the correct start_cpu() return address on the stack of the idle
     task.

   - Fixups for the fallout of the nodeid <-> cpuid persistent mapping
     modifciations

   - Move the x86/MPX specific mm_struct member to the arch specific
     mm_context where it belongs

   - Cleanups for C89 struct initializers and useless function
     arguments"

* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/floppy: Use designated initializers
  x86/mpx: Move bd_addr to mm_context_t
  x86/mm: Drop unused argument 'removed' from sync_global_pgds()
  ACPI/NUMA: Do not map pxm to node when NUMA is turned off
  x86/acpi: Use proper macro for invalid node
  x86/smpboot: Prevent false positive out of bounds cpumask access warning
  x86/boot/64: Push correct start_cpu() return address
  x86/boot/64: Use 'push' instead of 'call' in start_cpu()
  x86/smpboot: Make logical package management more robust

20 files changed:
arch/arm64/include/asm/numa.h
arch/arm64/mm/numa.c
arch/ia64/include/asm/numa.h
arch/x86/include/asm/floppy.h
arch/x86/include/asm/mmu.h
arch/x86/include/asm/mpx.h
arch/x86/include/asm/pgtable_64.h
arch/x86/kernel/acpi/boot.c
arch/x86/kernel/apic/apic.c
arch/x86/kernel/cpu/common.c
arch/x86/kernel/head_64.S
arch/x86/kernel/smpboot.c
arch/x86/mm/fault.c
arch/x86/mm/init_64.c
arch/x86/mm/mpx.c
arch/x86/mm/numa.c
arch/x86/xen/smp.c
drivers/acpi/numa.c
include/linux/cpumask.h
include/linux/mm_types.h

index 600887e..bf466d1 100644 (file)
@@ -15,6 +15,8 @@ int __node_distance(int from, int to);
 
 extern nodemask_t numa_nodes_parsed __initdata;
 
+extern bool numa_off;
+
 /* Mappings between node number and cpus on that node. */
 extern cpumask_var_t node_to_cpumask_map[MAX_NUMNODES];
 void numa_clear_node(unsigned int cpu);
index 4b32168..b388a99 100644 (file)
@@ -35,7 +35,7 @@ static int cpu_to_node_map[NR_CPUS] = { [0 ... NR_CPUS-1] = NUMA_NO_NODE };
 
 static int numa_distance_cnt;
 static u8 *numa_distance;
-static bool numa_off;
+bool numa_off;
 
 static __init int numa_parse_early_param(char *opt)
 {
index 2db0a6c..ebef7f4 100644 (file)
@@ -65,6 +65,8 @@ extern int paddr_to_nid(unsigned long paddr);
 
 #define local_nodeid (cpu_to_node_map[smp_processor_id()])
 
+#define numa_off     0
+
 extern void map_cpu_to_node(int cpu, int nid);
 extern void unmap_cpu_from_node(int cpu, int nid);
 extern void numa_clear_node(int cpu);
index 1c7eefe..7ec59ed 100644 (file)
@@ -229,18 +229,18 @@ static struct fd_routine_l {
        int (*_dma_setup)(char *addr, unsigned long size, int mode, int io);
 } fd_routine[] = {
        {
-               request_dma,
-               free_dma,
-               get_dma_residue,
-               dma_mem_alloc,
-               hard_dma_setup
+               ._request_dma           = request_dma,
+               ._free_dma              = free_dma,
+               ._get_dma_residue       = get_dma_residue,
+               ._dma_mem_alloc         = dma_mem_alloc,
+               ._dma_setup             = hard_dma_setup
        },
        {
-               vdma_request_dma,
-               vdma_nop,
-               vdma_get_dma_residue,
-               vdma_mem_alloc,
-               vdma_dma_setup
+               ._request_dma           = vdma_request_dma,
+               ._free_dma              = vdma_nop,
+               ._get_dma_residue       = vdma_get_dma_residue,
+               ._dma_mem_alloc         = vdma_mem_alloc,
+               ._dma_setup             = vdma_dma_setup
        }
 };
 
index 72198c6..f9813b6 100644 (file)
@@ -31,6 +31,10 @@ typedef struct {
        u16 pkey_allocation_map;
        s16 execute_only_pkey;
 #endif
+#ifdef CONFIG_X86_INTEL_MPX
+       /* address of the bounds directory */
+       void __user *bd_addr;
+#endif
 } mm_context_t;
 
 #ifdef CONFIG_SMP
index 7a35495..0b416d4 100644 (file)
@@ -59,7 +59,7 @@ siginfo_t *mpx_generate_siginfo(struct pt_regs *regs);
 int mpx_handle_bd_fault(void);
 static inline int kernel_managing_mpx_tables(struct mm_struct *mm)
 {
-       return (mm->bd_addr != MPX_INVALID_BOUNDS_DIR);
+       return (mm->context.bd_addr != MPX_INVALID_BOUNDS_DIR);
 }
 static inline void mpx_mm_init(struct mm_struct *mm)
 {
@@ -67,7 +67,7 @@ static inline void mpx_mm_init(struct mm_struct *mm)
         * NULL is theoretically a valid place to put the bounds
         * directory, so point this at an invalid address.
         */
-       mm->bd_addr = MPX_INVALID_BOUNDS_DIR;
+       mm->context.bd_addr = MPX_INVALID_BOUNDS_DIR;
 }
 void mpx_notify_unmap(struct mm_struct *mm, struct vm_area_struct *vma,
                      unsigned long start, unsigned long end);
index 1cc82ec..62b7759 100644 (file)
@@ -116,8 +116,7 @@ static inline void native_pgd_clear(pgd_t *pgd)
        native_set_pgd(pgd, native_make_pgd(0));
 }
 
-extern void sync_global_pgds(unsigned long start, unsigned long end,
-                            int removed);
+extern void sync_global_pgds(unsigned long start, unsigned long end);
 
 /*
  * Conversion functions: convert a page and protection to a page entry,
index 4764fa5..6f65b0e 100644 (file)
@@ -715,7 +715,7 @@ int acpi_map_cpu2node(acpi_handle handle, int cpu, int physid)
        int nid;
 
        nid = acpi_get_node(handle);
-       if (nid != -1) {
+       if (nid != NUMA_NO_NODE) {
                set_apicid_to_node(physid, nid);
                numa_set_node(cpu, nid);
        }
index bb47e5e..5b7e43e 100644 (file)
@@ -2160,21 +2160,6 @@ int __generic_processor_info(int apicid, int version, bool enabled)
        }
 
        /*
-        * This can happen on physical hotplug. The sanity check at boot time
-        * is done from native_smp_prepare_cpus() after num_possible_cpus() is
-        * established.
-        */
-       if (topology_update_package_map(apicid, cpu) < 0) {
-               int thiscpu = max + disabled_cpus;
-
-               pr_warning("APIC: Package limit reached. Processor %d/0x%x ignored.\n",
-                          thiscpu, apicid);
-
-               disabled_cpus++;
-               return -ENOSPC;
-       }
-
-       /*
         * Validate version
         */
        if (version == 0x0) {
index 729f92b..1f6b50a 100644 (file)
@@ -979,29 +979,21 @@ static void x86_init_cache_qos(struct cpuinfo_x86 *c)
 }
 
 /*
- * The physical to logical package id mapping is initialized from the
- * acpi/mptables information. Make sure that CPUID actually agrees with
- * that.
+ * Validate that ACPI/mptables have the same information about the
+ * effective APIC id and update the package map.
  */
-static void sanitize_package_id(struct cpuinfo_x86 *c)
+static void validate_apic_and_package_id(struct cpuinfo_x86 *c)
 {
 #ifdef CONFIG_SMP
-       unsigned int pkg, apicid, cpu = smp_processor_id();
+       unsigned int apicid, cpu = smp_processor_id();
 
        apicid = apic->cpu_present_to_apicid(cpu);
-       pkg = apicid >> boot_cpu_data.x86_coreid_bits;
 
-       if (apicid != c->initial_apicid) {
-               pr_err(FW_BUG "CPU%u: APIC id mismatch. Firmware: %x CPUID: %x\n",
+       if (apicid != c->apicid) {
+               pr_err(FW_BUG "CPU%u: APIC id mismatch. Firmware: %x APIC: %x\n",
                       cpu, apicid, c->initial_apicid);
-               c->initial_apicid = apicid;
        }
-       if (pkg != c->phys_proc_id) {
-               pr_err(FW_BUG "CPU%u: Using firmware package id %u instead of %u\n",
-                      cpu, pkg, c->phys_proc_id);
-               c->phys_proc_id = pkg;
-       }
-       c->logical_proc_id = topology_phys_to_logical_pkg(pkg);
+       BUG_ON(topology_update_package_map(c->phys_proc_id, cpu));
 #else
        c->logical_proc_id = 0;
 #endif
@@ -1132,7 +1124,6 @@ static void identify_cpu(struct cpuinfo_x86 *c)
 #ifdef CONFIG_NUMA
        numa_add_cpu(smp_processor_id());
 #endif
-       sanitize_package_id(c);
 }
 
 /*
@@ -1187,6 +1178,7 @@ void identify_secondary_cpu(struct cpuinfo_x86 *c)
        enable_sep_cpu();
 #endif
        mtrr_ap_init();
+       validate_apic_and_package_id(c);
 }
 
 static __init int setup_noclflush(char *arg)
index 90de288..b467b14 100644 (file)
@@ -298,12 +298,13 @@ ENTRY(start_cpu)
         *      REX.W + FF /5 JMP m16:64 Jump far, absolute indirect,
         *              address given in m16:64.
         */
-       call    1f              # put return address on stack for unwinder
-1:     xorq    %rbp, %rbp      # clear frame pointer
+       pushq   $.Lafter_lret   # put return address on stack for unwinder
+       xorq    %rbp, %rbp      # clear frame pointer
        movq    initial_code(%rip), %rax
        pushq   $__KERNEL_CS    # set correct cs
        pushq   %rax            # target address in negative space
        lretq
+.Lafter_lret:
 ENDPROC(start_cpu)
 
 #include "verify_cpu.S"
index 0c37d4f..46732dc 100644 (file)
@@ -103,7 +103,6 @@ static unsigned int max_physical_pkg_id __read_mostly;
 unsigned int __max_logical_packages __read_mostly;
 EXPORT_SYMBOL(__max_logical_packages);
 static unsigned int logical_packages __read_mostly;
-static bool logical_packages_frozen __read_mostly;
 
 /* Maximum number of SMT threads on any online core */
 int __max_smt_threads __read_mostly;
@@ -273,9 +272,14 @@ static void notrace start_secondary(void *unused)
        cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
 }
 
-int topology_update_package_map(unsigned int apicid, unsigned int cpu)
+/**
+ * topology_update_package_map - Update the physical to logical package map
+ * @pkg:       The physical package id as retrieved via CPUID
+ * @cpu:       The cpu for which this is updated
+ */
+int topology_update_package_map(unsigned int pkg, unsigned int cpu)
 {
-       unsigned int new, pkg = apicid >> boot_cpu_data.x86_coreid_bits;
+       unsigned int new;
 
        /* Called from early boot ? */
        if (!physical_package_map)
@@ -288,16 +292,17 @@ int topology_update_package_map(unsigned int apicid, unsigned int cpu)
        if (test_and_set_bit(pkg, physical_package_map))
                goto found;
 
-       if (logical_packages_frozen) {
-               physical_to_logical_pkg[pkg] = -1;
-               pr_warn("APIC(%x) Package %u exceeds logical package max\n",
-                       apicid, pkg);
+       if (logical_packages >= __max_logical_packages) {
+               pr_warn("Package %u of CPU %u exceeds BIOS package data %u.\n",
+                       logical_packages, cpu, __max_logical_packages);
                return -ENOSPC;
        }
 
        new = logical_packages++;
-       pr_info("APIC(%x) Converting physical %u to logical package %u\n",
-               apicid, pkg, new);
+       if (new != pkg) {
+               pr_info("CPU %u Converting physical %u to logical package %u\n",
+                       cpu, pkg, new);
+       }
        physical_to_logical_pkg[pkg] = new;
 
 found:
@@ -318,9 +323,9 @@ int topology_phys_to_logical_pkg(unsigned int phys_pkg)
 }
 EXPORT_SYMBOL(topology_phys_to_logical_pkg);
 
-static void __init smp_init_package_map(void)
+static void __init smp_init_package_map(struct cpuinfo_x86 *c, unsigned int cpu)
 {
-       unsigned int ncpus, cpu;
+       unsigned int ncpus;
        size_t size;
 
        /*
@@ -365,27 +370,9 @@ static void __init smp_init_package_map(void)
        size = BITS_TO_LONGS(max_physical_pkg_id) * sizeof(unsigned long);
        physical_package_map = kzalloc(size, GFP_KERNEL);
 
-       for_each_present_cpu(cpu) {
-               unsigned int apicid = apic->cpu_present_to_apicid(cpu);
-
-               if (apicid == BAD_APICID || !apic->apic_id_valid(apicid))
-                       continue;
-               if (!topology_update_package_map(apicid, cpu))
-                       continue;
-               pr_warn("CPU %u APICId %x disabled\n", cpu, apicid);
-               per_cpu(x86_bios_cpu_apicid, cpu) = BAD_APICID;
-               set_cpu_possible(cpu, false);
-               set_cpu_present(cpu, false);
-       }
-
-       if (logical_packages > __max_logical_packages) {
-               pr_warn("Detected more packages (%u), then computed by BIOS data (%u).\n",
-                       logical_packages, __max_logical_packages);
-               logical_packages_frozen = true;
-               __max_logical_packages  = logical_packages;
-       }
-
        pr_info("Max logical packages: %u\n", __max_logical_packages);
+
+       topology_update_package_map(c->phys_proc_id, cpu);
 }
 
 void __init smp_store_boot_cpu_info(void)
@@ -395,7 +382,7 @@ void __init smp_store_boot_cpu_info(void)
 
        *c = boot_cpu_data;
        c->cpu_index = id;
-       smp_init_package_map();
+       smp_init_package_map(c, id);
 }
 
 /*
@@ -1476,15 +1463,15 @@ __init void prefill_possible_map(void)
                possible = i;
        }
 
+       nr_cpu_ids = possible;
+
        pr_info("Allowing %d CPUs, %d hotplug CPUs\n",
                possible, max_t(int, possible - num_processors, 0));
 
+       reset_cpu_possible_mask();
+
        for (i = 0; i < possible; i++)
                set_cpu_possible(i, true);
-       for (; i < NR_CPUS; i++)
-               set_cpu_possible(i, false);
-
-       nr_cpu_ids = possible;
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
index 17c55a5..e3254ca 100644 (file)
@@ -413,7 +413,7 @@ out:
 
 void vmalloc_sync_all(void)
 {
-       sync_global_pgds(VMALLOC_START & PGDIR_MASK, VMALLOC_END, 0);
+       sync_global_pgds(VMALLOC_START & PGDIR_MASK, VMALLOC_END);
 }
 
 /*
index 14b9dd7..963895f 100644 (file)
@@ -89,10 +89,10 @@ static int __init nonx32_setup(char *str)
 __setup("noexec32=", nonx32_setup);
 
 /*
- * When memory was added/removed make sure all the processes MM have
+ * When memory was added make sure all the processes MM have
  * suitable PGD entries in the local PGD level page.
  */
-void sync_global_pgds(unsigned long start, unsigned long end, int removed)
+void sync_global_pgds(unsigned long start, unsigned long end)
 {
        unsigned long address;
 
@@ -100,12 +100,7 @@ void sync_global_pgds(unsigned long start, unsigned long end, int removed)
                const pgd_t *pgd_ref = pgd_offset_k(address);
                struct page *page;
 
-               /*
-                * When it is called after memory hot remove, pgd_none()
-                * returns true. In this case (removed == 1), we must clear
-                * the PGD entries in the local PGD level page.
-                */
-               if (pgd_none(*pgd_ref) && !removed)
+               if (pgd_none(*pgd_ref))
                        continue;
 
                spin_lock(&pgd_lock);
@@ -122,13 +117,8 @@ void sync_global_pgds(unsigned long start, unsigned long end, int removed)
                                BUG_ON(pgd_page_vaddr(*pgd)
                                       != pgd_page_vaddr(*pgd_ref));
 
-                       if (removed) {
-                               if (pgd_none(*pgd_ref) && !pgd_none(*pgd))
-                                       pgd_clear(pgd);
-                       } else {
-                               if (pgd_none(*pgd))
-                                       set_pgd(pgd, *pgd_ref);
-                       }
+                       if (pgd_none(*pgd))
+                               set_pgd(pgd, *pgd_ref);
 
                        spin_unlock(pgt_lock);
                }
@@ -596,7 +586,7 @@ kernel_physical_mapping_init(unsigned long paddr_start,
        }
 
        if (pgd_changed)
-               sync_global_pgds(vaddr_start, vaddr_end - 1, 0);
+               sync_global_pgds(vaddr_start, vaddr_end - 1);
 
        __flush_tlb_all();
 
@@ -1239,7 +1229,7 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node)
        } else
                err = vmemmap_populate_basepages(start, end, node);
        if (!err)
-               sync_global_pgds(start, end - 1, 0);
+               sync_global_pgds(start, end - 1);
        return err;
 }
 
index e4f8009..324e571 100644 (file)
@@ -350,12 +350,12 @@ int mpx_enable_management(void)
         * The copy_xregs_to_kernel() beneath get_xsave_field_ptr() is
         * expected to be relatively expensive. Storing the bounds
         * directory here means that we do not have to do xsave in the
-        * unmap path; we can just use mm->bd_addr instead.
+        * unmap path; we can just use mm->context.bd_addr instead.
         */
        bd_base = mpx_get_bounds_dir();
        down_write(&mm->mmap_sem);
-       mm->bd_addr = bd_base;
-       if (mm->bd_addr == MPX_INVALID_BOUNDS_DIR)
+       mm->context.bd_addr = bd_base;
+       if (mm->context.bd_addr == MPX_INVALID_BOUNDS_DIR)
                ret = -ENXIO;
 
        up_write(&mm->mmap_sem);
@@ -370,7 +370,7 @@ int mpx_disable_management(void)
                return -ENXIO;
 
        down_write(&mm->mmap_sem);
-       mm->bd_addr = MPX_INVALID_BOUNDS_DIR;
+       mm->context.bd_addr = MPX_INVALID_BOUNDS_DIR;
        up_write(&mm->mmap_sem);
        return 0;
 }
@@ -947,7 +947,7 @@ static int try_unmap_single_bt(struct mm_struct *mm,
                end = bta_end_vaddr;
        }
 
-       bde_vaddr = mm->bd_addr + mpx_get_bd_entry_offset(mm, start);
+       bde_vaddr = mm->context.bd_addr + mpx_get_bd_entry_offset(mm, start);
        ret = get_bt_addr(mm, bde_vaddr, &bt_addr);
        /*
         * No bounds table there, so nothing to unmap.
index 3f35b48..12dcad7 100644 (file)
@@ -19,7 +19,7 @@
 
 #include "numa_internal.h"
 
-int __initdata numa_off;
+int numa_off;
 nodemask_t numa_nodes_parsed __initdata;
 
 struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
index 9fa27ce..311acad 100644 (file)
@@ -87,12 +87,6 @@ static void cpu_bringup(void)
        cpu_data(cpu).x86_max_cores = 1;
        set_cpu_sibling_map(cpu);
 
-       /*
-        * identify_cpu() may have set logical_pkg_id to -1 due
-        * to incorrect phys_proc_id. Let's re-comupte it.
-        */
-       topology_update_package_map(apic->cpu_present_to_apicid(cpu), cpu);
-
        xen_setup_cpu_clockevents();
 
        notify_cpu_starting(cpu);
index ce3a7a1..edb0c79 100644 (file)
@@ -70,7 +70,7 @@ int acpi_map_pxm_to_node(int pxm)
 {
        int node;
 
-       if (pxm < 0 || pxm >= MAX_PXM_DOMAINS)
+       if (pxm < 0 || pxm >= MAX_PXM_DOMAINS || numa_off)
                return NUMA_NO_NODE;
 
        node = pxm_to_node_map[pxm];
index da7fbf1..c717f5e 100644 (file)
@@ -722,6 +722,11 @@ void init_cpu_present(const struct cpumask *src);
 void init_cpu_possible(const struct cpumask *src);
 void init_cpu_online(const struct cpumask *src);
 
+static inline void reset_cpu_possible_mask(void)
+{
+       bitmap_zero(cpumask_bits(&__cpu_possible_mask), NR_CPUS);
+}
+
 static inline void
 set_cpu_possible(unsigned int cpu, bool possible)
 {
index 08d947f..808751d 100644 (file)
@@ -509,10 +509,6 @@ struct mm_struct {
        bool tlb_flush_pending;
 #endif
        struct uprobes_state uprobes_state;
-#ifdef CONFIG_X86_INTEL_MPX
-       /* address of the bounds directory */
-       void __user *bd_addr;
-#endif
 #ifdef CONFIG_HUGETLB_PAGE
        atomic_long_t hugetlb_usage;
 #endif