diff options
-rw-r--r-- | arch/x86/include/asm/uv/uv_hub.h | 21 | ||||
-rw-r--r-- | arch/x86/kernel/alternative.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/apic/x2apic_uv_x.c | 24 | ||||
-rw-r--r-- | arch/x86/kernel/irq_32.c | 9 | ||||
-rw-r--r-- | arch/x86/mm/numa_64.c | 7 |
5 files changed, 50 insertions, 13 deletions
diff --git a/arch/x86/include/asm/uv/uv_hub.h b/arch/x86/include/asm/uv/uv_hub.h index bf6b88ef8eeb..e969f691cbfd 100644 --- a/arch/x86/include/asm/uv/uv_hub.h +++ b/arch/x86/include/asm/uv/uv_hub.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * SGI UV architectural definitions | 6 | * SGI UV architectural definitions |
7 | * | 7 | * |
8 | * Copyright (C) 2007-2008 Silicon Graphics, Inc. All rights reserved. | 8 | * Copyright (C) 2007-2010 Silicon Graphics, Inc. All rights reserved. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #ifndef _ASM_X86_UV_UV_HUB_H | 11 | #ifndef _ASM_X86_UV_UV_HUB_H |
@@ -77,7 +77,8 @@ | |||
77 | * | 77 | * |
78 | * 1111110000000000 | 78 | * 1111110000000000 |
79 | * 5432109876543210 | 79 | * 5432109876543210 |
80 | * pppppppppplc0cch | 80 | * pppppppppplc0cch Nehalem-EX |
81 | * ppppppppplcc0cch Westmere-EX | ||
81 | * sssssssssss | 82 | * sssssssssss |
82 | * | 83 | * |
83 | * p = pnode bits | 84 | * p = pnode bits |
@@ -148,12 +149,25 @@ struct uv_hub_info_s { | |||
148 | unsigned char m_val; | 149 | unsigned char m_val; |
149 | unsigned char n_val; | 150 | unsigned char n_val; |
150 | struct uv_scir_s scir; | 151 | struct uv_scir_s scir; |
152 | unsigned char apic_pnode_shift; | ||
151 | }; | 153 | }; |
152 | 154 | ||
153 | DECLARE_PER_CPU(struct uv_hub_info_s, __uv_hub_info); | 155 | DECLARE_PER_CPU(struct uv_hub_info_s, __uv_hub_info); |
154 | #define uv_hub_info (&__get_cpu_var(__uv_hub_info)) | 156 | #define uv_hub_info (&__get_cpu_var(__uv_hub_info)) |
155 | #define uv_cpu_hub_info(cpu) (&per_cpu(__uv_hub_info, cpu)) | 157 | #define uv_cpu_hub_info(cpu) (&per_cpu(__uv_hub_info, cpu)) |
156 | 158 | ||
159 | union uvh_apicid { | ||
160 | unsigned long v; | ||
161 | struct uvh_apicid_s { | ||
162 | unsigned long local_apic_mask : 24; | ||
163 | unsigned long local_apic_shift : 5; | ||
164 | unsigned long unused1 : 3; | ||
165 | unsigned long pnode_mask : 24; | ||
166 | unsigned long pnode_shift : 5; | ||
167 | unsigned long unused2 : 3; | ||
168 | } s; | ||
169 | }; | ||
170 | |||
157 | /* | 171 | /* |
158 | * Local & Global MMR space macros. | 172 | * Local & Global MMR space macros. |
159 | * Note: macros are intended to be used ONLY by inline functions | 173 | * 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); | |||
182 | #define UV_GLOBAL_MMR64_PNODE_BITS(p) \ | 196 | #define UV_GLOBAL_MMR64_PNODE_BITS(p) \ |
183 | (((unsigned long)(p)) << UV_GLOBAL_MMR64_PNODE_SHIFT) | 197 | (((unsigned long)(p)) << UV_GLOBAL_MMR64_PNODE_SHIFT) |
184 | 198 | ||
199 | #define UVH_APICID 0x002D0E00L | ||
185 | #define UV_APIC_PNODE_SHIFT 6 | 200 | #define UV_APIC_PNODE_SHIFT 6 |
186 | 201 | ||
187 | /* Local Bus from cpu's perspective */ | 202 | /* Local Bus from cpu's perspective */ |
@@ -280,7 +295,7 @@ static inline void *uv_pnode_offset_to_vaddr(int pnode, unsigned long offset) | |||
280 | */ | 295 | */ |
281 | static inline int uv_apicid_to_pnode(int apicid) | 296 | static inline int uv_apicid_to_pnode(int apicid) |
282 | { | 297 | { |
283 | return (apicid >> UV_APIC_PNODE_SHIFT); | 298 | return (apicid >> uv_hub_info->apic_pnode_shift); |
284 | } | 299 | } |
285 | 300 | ||
286 | /* | 301 | /* |
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index a36bb90aef53..5ceeca382820 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c | |||
@@ -638,7 +638,7 @@ void *__kprobes text_poke_smp(void *addr, const void *opcode, size_t len) | |||
638 | atomic_set(&stop_machine_first, 1); | 638 | atomic_set(&stop_machine_first, 1); |
639 | wrote_text = 0; | 639 | wrote_text = 0; |
640 | /* Use __stop_machine() because the caller already got online_cpus. */ | 640 | /* Use __stop_machine() because the caller already got online_cpus. */ |
641 | __stop_machine(stop_machine_text_poke, (void *)&tpp, NULL); | 641 | __stop_machine(stop_machine_text_poke, (void *)&tpp, cpu_online_mask); |
642 | return addr; | 642 | return addr; |
643 | } | 643 | } |
644 | 644 | ||
diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index f744f54cb248..ed4118de249e 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * SGI UV APIC functions (note: not an Intel compatible APIC) | 6 | * SGI UV APIC functions (note: not an Intel compatible APIC) |
7 | * | 7 | * |
8 | * Copyright (C) 2007-2009 Silicon Graphics, Inc. All rights reserved. | 8 | * Copyright (C) 2007-2010 Silicon Graphics, Inc. All rights reserved. |
9 | */ | 9 | */ |
10 | #include <linux/cpumask.h> | 10 | #include <linux/cpumask.h> |
11 | #include <linux/hardirq.h> | 11 | #include <linux/hardirq.h> |
@@ -41,6 +41,7 @@ DEFINE_PER_CPU(int, x2apic_extra_bits); | |||
41 | 41 | ||
42 | static enum uv_system_type uv_system_type; | 42 | static enum uv_system_type uv_system_type; |
43 | static u64 gru_start_paddr, gru_end_paddr; | 43 | static u64 gru_start_paddr, gru_end_paddr; |
44 | static union uvh_apicid uvh_apicid; | ||
44 | int uv_min_hub_revision_id; | 45 | int uv_min_hub_revision_id; |
45 | EXPORT_SYMBOL_GPL(uv_min_hub_revision_id); | 46 | EXPORT_SYMBOL_GPL(uv_min_hub_revision_id); |
46 | static DEFINE_SPINLOCK(uv_nmi_lock); | 47 | static DEFINE_SPINLOCK(uv_nmi_lock); |
@@ -70,12 +71,27 @@ static int early_get_nodeid(void) | |||
70 | return node_id.s.node_id; | 71 | return node_id.s.node_id; |
71 | } | 72 | } |
72 | 73 | ||
74 | static void __init early_get_apic_pnode_shift(void) | ||
75 | { | ||
76 | unsigned long *mmr; | ||
77 | |||
78 | mmr = early_ioremap(UV_LOCAL_MMR_BASE | UVH_APICID, sizeof(*mmr)); | ||
79 | uvh_apicid.v = *mmr; | ||
80 | early_iounmap(mmr, sizeof(*mmr)); | ||
81 | if (!uvh_apicid.v) | ||
82 | /* | ||
83 | * Old bios, use default value | ||
84 | */ | ||
85 | uvh_apicid.s.pnode_shift = UV_APIC_PNODE_SHIFT; | ||
86 | } | ||
87 | |||
73 | static int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id) | 88 | static int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id) |
74 | { | 89 | { |
75 | int nodeid; | 90 | int nodeid; |
76 | 91 | ||
77 | if (!strcmp(oem_id, "SGI")) { | 92 | if (!strcmp(oem_id, "SGI")) { |
78 | nodeid = early_get_nodeid(); | 93 | nodeid = early_get_nodeid(); |
94 | early_get_apic_pnode_shift(); | ||
79 | x86_platform.is_untracked_pat_range = uv_is_untracked_pat_range; | 95 | x86_platform.is_untracked_pat_range = uv_is_untracked_pat_range; |
80 | x86_platform.nmi_init = uv_nmi_init; | 96 | x86_platform.nmi_init = uv_nmi_init; |
81 | if (!strcmp(oem_table_id, "UVL")) | 97 | 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) | |||
84 | uv_system_type = UV_X2APIC; | 100 | uv_system_type = UV_X2APIC; |
85 | else if (!strcmp(oem_table_id, "UVH")) { | 101 | else if (!strcmp(oem_table_id, "UVH")) { |
86 | __get_cpu_var(x2apic_extra_bits) = | 102 | __get_cpu_var(x2apic_extra_bits) = |
87 | nodeid << (UV_APIC_PNODE_SHIFT - 1); | 103 | nodeid << (uvh_apicid.s.pnode_shift - 1); |
88 | uv_system_type = UV_NON_UNIQUE_APIC; | 104 | uv_system_type = UV_NON_UNIQUE_APIC; |
89 | return 1; | 105 | return 1; |
90 | } | 106 | } |
@@ -716,6 +732,10 @@ void __init uv_system_init(void) | |||
716 | int apicid = per_cpu(x86_cpu_to_apicid, cpu); | 732 | int apicid = per_cpu(x86_cpu_to_apicid, cpu); |
717 | 733 | ||
718 | nid = cpu_to_node(cpu); | 734 | nid = cpu_to_node(cpu); |
735 | /* | ||
736 | * apic_pnode_shift must be set before calling uv_apicid_to_pnode(); | ||
737 | */ | ||
738 | uv_cpu_hub_info(cpu)->apic_pnode_shift = uvh_apicid.s.pnode_shift; | ||
719 | pnode = uv_apicid_to_pnode(apicid); | 739 | pnode = uv_apicid_to_pnode(apicid); |
720 | blade = boot_pnode_to_blade(pnode); | 740 | blade = boot_pnode_to_blade(pnode); |
721 | lcpu = uv_blade_info[blade].nr_possible_cpus; | 741 | lcpu = uv_blade_info[blade].nr_possible_cpus; |
diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c index 64668dbf00a4..96656f207751 100644 --- a/arch/x86/kernel/irq_32.c +++ b/arch/x86/kernel/irq_32.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
18 | #include <linux/uaccess.h> | 18 | #include <linux/uaccess.h> |
19 | #include <linux/percpu.h> | 19 | #include <linux/percpu.h> |
20 | #include <linux/mm.h> | ||
20 | 21 | ||
21 | #include <asm/apic.h> | 22 | #include <asm/apic.h> |
22 | 23 | ||
@@ -125,7 +126,9 @@ void __cpuinit irq_ctx_init(int cpu) | |||
125 | if (per_cpu(hardirq_ctx, cpu)) | 126 | if (per_cpu(hardirq_ctx, cpu)) |
126 | return; | 127 | return; |
127 | 128 | ||
128 | irqctx = (union irq_ctx *)__get_free_pages(THREAD_FLAGS, THREAD_ORDER); | 129 | irqctx = page_address(alloc_pages_node(cpu_to_node(cpu), |
130 | THREAD_FLAGS, | ||
131 | THREAD_ORDER)); | ||
129 | irqctx->tinfo.task = NULL; | 132 | irqctx->tinfo.task = NULL; |
130 | irqctx->tinfo.exec_domain = NULL; | 133 | irqctx->tinfo.exec_domain = NULL; |
131 | irqctx->tinfo.cpu = cpu; | 134 | irqctx->tinfo.cpu = cpu; |
@@ -134,7 +137,9 @@ void __cpuinit irq_ctx_init(int cpu) | |||
134 | 137 | ||
135 | per_cpu(hardirq_ctx, cpu) = irqctx; | 138 | per_cpu(hardirq_ctx, cpu) = irqctx; |
136 | 139 | ||
137 | irqctx = (union irq_ctx *)__get_free_pages(THREAD_FLAGS, THREAD_ORDER); | 140 | irqctx = page_address(alloc_pages_node(cpu_to_node(cpu), |
141 | THREAD_FLAGS, | ||
142 | THREAD_ORDER)); | ||
138 | irqctx->tinfo.task = NULL; | 143 | irqctx->tinfo.task = NULL; |
139 | irqctx->tinfo.exec_domain = NULL; | 144 | irqctx->tinfo.exec_domain = NULL; |
140 | irqctx->tinfo.cpu = cpu; | 145 | irqctx->tinfo.cpu = cpu; |
diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c index 60f498511dd6..7ffc9b727efd 100644 --- a/arch/x86/mm/numa_64.c +++ b/arch/x86/mm/numa_64.c | |||
@@ -178,11 +178,8 @@ static void * __init early_node_mem(int nodeid, unsigned long start, | |||
178 | 178 | ||
179 | /* extend the search scope */ | 179 | /* extend the search scope */ |
180 | end = max_pfn_mapped << PAGE_SHIFT; | 180 | end = max_pfn_mapped << PAGE_SHIFT; |
181 | if (end > (MAX_DMA32_PFN<<PAGE_SHIFT)) | 181 | start = MAX_DMA_PFN << PAGE_SHIFT; |
182 | start = MAX_DMA32_PFN<<PAGE_SHIFT; | 182 | mem = memblock_find_in_range(start, end, size, align); |
183 | else | ||
184 | start = MAX_DMA_PFN<<PAGE_SHIFT; | ||
185 | mem = memblock_x86_find_in_range_node(nodeid, start, end, size, align); | ||
186 | if (mem != MEMBLOCK_ERROR) | 183 | if (mem != MEMBLOCK_ERROR) |
187 | return __va(mem); | 184 | return __va(mem); |
188 | 185 | ||