]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
Merge branches 'x86-fixes-for-linus' and 'x86-uv-for-linus' of git://git.kernel.org...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 30 Oct 2010 01:58:00 +0000 (18:58 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 30 Oct 2010 01:58:00 +0000 (18:58 -0700)
* 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  x86, alternative: Call stop_machine_text_poke() on all cpus
  x86-32: Restore irq stacks NUMA-aware allocations
  x86, memblock: Fix early_node_mem with big reserved region.

* 'x86-uv-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  x86, uv: More Westmere support on SGI UV
  x86, uv: Enable Westmere support on SGI UV

arch/x86/include/asm/uv/uv_hub.h
arch/x86/kernel/alternative.c
arch/x86/kernel/apic/x2apic_uv_x.c
arch/x86/kernel/irq_32.c
arch/x86/mm/numa_64.c

index bf6b88ef8eebb17d273c8f75c82c77b24213f003..e969f691cbfde23c6ffd53a540d0e3841084255d 100644 (file)
@@ -5,7 +5,7 @@
  *
  * SGI UV architectural definitions
  *
- * Copyright (C) 2007-2008 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2007-2010 Silicon Graphics, Inc. All rights reserved.
  */
 
 #ifndef _ASM_X86_UV_UV_HUB_H
@@ -77,7 +77,8 @@
  *
  *             1111110000000000
  *             5432109876543210
- *             pppppppppplc0cch
+ *             pppppppppplc0cch        Nehalem-EX
+ *             ppppppppplcc0cch        Westmere-EX
  *             sssssssssss
  *
  *                     p  = pnode bits
@@ -148,12 +149,25 @@ struct uv_hub_info_s {
        unsigned char           m_val;
        unsigned char           n_val;
        struct uv_scir_s        scir;
+       unsigned char           apic_pnode_shift;
 };
 
 DECLARE_PER_CPU(struct uv_hub_info_s, __uv_hub_info);
 #define uv_hub_info            (&__get_cpu_var(__uv_hub_info))
 #define uv_cpu_hub_info(cpu)   (&per_cpu(__uv_hub_info, cpu))
 
+union uvh_apicid {
+    unsigned long       v;
+    struct uvh_apicid_s {
+        unsigned long   local_apic_mask  : 24;
+        unsigned long   local_apic_shift :  5;
+        unsigned long   unused1          :  3;
+        unsigned long   pnode_mask       : 24;
+        unsigned long   pnode_shift      :  5;
+        unsigned long   unused2          :  3;
+    } s;
+};
+
 /*
  * Local & Global MMR space macros.
  *     Note: macros are intended to be used ONLY by inline functions
@@ -182,6 +196,7 @@ DECLARE_PER_CPU(struct uv_hub_info_s, __uv_hub_info);
 #define UV_GLOBAL_MMR64_PNODE_BITS(p)                                  \
        (((unsigned long)(p)) << UV_GLOBAL_MMR64_PNODE_SHIFT)
 
+#define UVH_APICID             0x002D0E00L
 #define UV_APIC_PNODE_SHIFT    6
 
 /* Local Bus from cpu's perspective */
@@ -280,7 +295,7 @@ static inline void *uv_pnode_offset_to_vaddr(int pnode, unsigned long offset)
  */
 static inline int uv_apicid_to_pnode(int apicid)
 {
-       return (apicid >> UV_APIC_PNODE_SHIFT);
+       return (apicid >> uv_hub_info->apic_pnode_shift);
 }
 
 /*
index a36bb90aef5383d68bcf4af0b0c33749d572163a..5ceeca382820c279c539a453b775fd1e16a2f386 100644 (file)
@@ -638,7 +638,7 @@ void *__kprobes text_poke_smp(void *addr, const void *opcode, size_t len)
        atomic_set(&stop_machine_first, 1);
        wrote_text = 0;
        /* Use __stop_machine() because the caller already got online_cpus. */
-       __stop_machine(stop_machine_text_poke, (void *)&tpp, NULL);
+       __stop_machine(stop_machine_text_poke, (void *)&tpp, cpu_online_mask);
        return addr;
 }
 
index f744f54cb248e7ac0cd6defaa84a8e673468b30a..ed4118de249ef0d3a72e08865ea5e949ee2d80fe 100644 (file)
@@ -5,7 +5,7 @@
  *
  * SGI UV APIC functions (note: not an Intel compatible APIC)
  *
- * Copyright (C) 2007-2009 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2007-2010 Silicon Graphics, Inc. All rights reserved.
  */
 #include <linux/cpumask.h>
 #include <linux/hardirq.h>
@@ -41,6 +41,7 @@ DEFINE_PER_CPU(int, x2apic_extra_bits);
 
 static enum uv_system_type uv_system_type;
 static u64 gru_start_paddr, gru_end_paddr;
+static union uvh_apicid uvh_apicid;
 int uv_min_hub_revision_id;
 EXPORT_SYMBOL_GPL(uv_min_hub_revision_id);
 static DEFINE_SPINLOCK(uv_nmi_lock);
@@ -70,12 +71,27 @@ static int early_get_nodeid(void)
        return node_id.s.node_id;
 }
 
+static void __init early_get_apic_pnode_shift(void)
+{
+       unsigned long *mmr;
+
+       mmr = early_ioremap(UV_LOCAL_MMR_BASE | UVH_APICID, sizeof(*mmr));
+       uvh_apicid.v = *mmr;
+       early_iounmap(mmr, sizeof(*mmr));
+       if (!uvh_apicid.v)
+               /*
+                * Old bios, use default value
+                */
+               uvh_apicid.s.pnode_shift = UV_APIC_PNODE_SHIFT;
+}
+
 static int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
 {
        int nodeid;
 
        if (!strcmp(oem_id, "SGI")) {
                nodeid = early_get_nodeid();
+               early_get_apic_pnode_shift();
                x86_platform.is_untracked_pat_range =  uv_is_untracked_pat_range;
                x86_platform.nmi_init = uv_nmi_init;
                if (!strcmp(oem_table_id, "UVL"))
@@ -84,7 +100,7 @@ static int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
                        uv_system_type = UV_X2APIC;
                else if (!strcmp(oem_table_id, "UVH")) {
                        __get_cpu_var(x2apic_extra_bits) =
-                               nodeid << (UV_APIC_PNODE_SHIFT - 1);
+                               nodeid << (uvh_apicid.s.pnode_shift - 1);
                        uv_system_type = UV_NON_UNIQUE_APIC;
                        return 1;
                }
@@ -716,6 +732,10 @@ void __init uv_system_init(void)
                int apicid = per_cpu(x86_cpu_to_apicid, cpu);
 
                nid = cpu_to_node(cpu);
+               /*
+                * apic_pnode_shift must be set before calling uv_apicid_to_pnode();
+                */
+               uv_cpu_hub_info(cpu)->apic_pnode_shift = uvh_apicid.s.pnode_shift;
                pnode = uv_apicid_to_pnode(apicid);
                blade = boot_pnode_to_blade(pnode);
                lcpu = uv_blade_info[blade].nr_possible_cpus;
index 64668dbf00a46185f7ef9d96a6a58996509e523d..96656f2077511bf280eec0010a087c96649fdaaa 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/delay.h>
 #include <linux/uaccess.h>
 #include <linux/percpu.h>
+#include <linux/mm.h>
 
 #include <asm/apic.h>
 
@@ -125,7 +126,9 @@ void __cpuinit irq_ctx_init(int cpu)
        if (per_cpu(hardirq_ctx, cpu))
                return;
 
-       irqctx = (union irq_ctx *)__get_free_pages(THREAD_FLAGS, THREAD_ORDER);
+       irqctx = page_address(alloc_pages_node(cpu_to_node(cpu),
+                                              THREAD_FLAGS,
+                                              THREAD_ORDER));
        irqctx->tinfo.task              = NULL;
        irqctx->tinfo.exec_domain       = NULL;
        irqctx->tinfo.cpu               = cpu;
@@ -134,7 +137,9 @@ void __cpuinit irq_ctx_init(int cpu)
 
        per_cpu(hardirq_ctx, cpu) = irqctx;
 
-       irqctx = (union irq_ctx *)__get_free_pages(THREAD_FLAGS, THREAD_ORDER);
+       irqctx = page_address(alloc_pages_node(cpu_to_node(cpu),
+                                              THREAD_FLAGS,
+                                              THREAD_ORDER));
        irqctx->tinfo.task              = NULL;
        irqctx->tinfo.exec_domain       = NULL;
        irqctx->tinfo.cpu               = cpu;
index 60f498511dd60b01a9eee62fdc0a69ba80d3082c..7ffc9b727efdc95ee6748acd1a1b646c8e164ffb 100644 (file)
@@ -178,11 +178,8 @@ static void * __init early_node_mem(int nodeid, unsigned long start,
 
        /* extend the search scope */
        end = max_pfn_mapped << PAGE_SHIFT;
-       if (end > (MAX_DMA32_PFN<<PAGE_SHIFT))
-               start = MAX_DMA32_PFN<<PAGE_SHIFT;
-       else
-               start = MAX_DMA_PFN<<PAGE_SHIFT;
-       mem = memblock_x86_find_in_range_node(nodeid, start, end, size, align);
+       start = MAX_DMA_PFN << PAGE_SHIFT;
+       mem = memblock_find_in_range(start, end, size, align);
        if (mem != MEMBLOCK_ERROR)
                return __va(mem);