diff options
Diffstat (limited to 'arch/powerpc/mm')
-rw-r--r-- | arch/powerpc/mm/numa.c | 31 | ||||
-rw-r--r-- | arch/powerpc/mm/slb.c | 37 | ||||
-rw-r--r-- | arch/powerpc/mm/tlb_64.c | 1 |
3 files changed, 48 insertions, 21 deletions
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index fbe23933f731..6c0f1c7d83e5 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c | |||
@@ -159,12 +159,12 @@ static struct device_node * __cpuinit find_cpu_node(unsigned int cpu) | |||
159 | { | 159 | { |
160 | unsigned int hw_cpuid = get_hard_smp_processor_id(cpu); | 160 | unsigned int hw_cpuid = get_hard_smp_processor_id(cpu); |
161 | struct device_node *cpu_node = NULL; | 161 | struct device_node *cpu_node = NULL; |
162 | unsigned int *interrupt_server, *reg; | 162 | const unsigned int *interrupt_server, *reg; |
163 | int len; | 163 | int len; |
164 | 164 | ||
165 | while ((cpu_node = of_find_node_by_type(cpu_node, "cpu")) != NULL) { | 165 | while ((cpu_node = of_find_node_by_type(cpu_node, "cpu")) != NULL) { |
166 | /* Try interrupt server first */ | 166 | /* Try interrupt server first */ |
167 | interrupt_server = (unsigned int *)get_property(cpu_node, | 167 | interrupt_server = get_property(cpu_node, |
168 | "ibm,ppc-interrupt-server#s", &len); | 168 | "ibm,ppc-interrupt-server#s", &len); |
169 | 169 | ||
170 | len = len / sizeof(u32); | 170 | len = len / sizeof(u32); |
@@ -175,8 +175,7 @@ static struct device_node * __cpuinit find_cpu_node(unsigned int cpu) | |||
175 | return cpu_node; | 175 | return cpu_node; |
176 | } | 176 | } |
177 | } else { | 177 | } else { |
178 | reg = (unsigned int *)get_property(cpu_node, | 178 | reg = get_property(cpu_node, "reg", &len); |
179 | "reg", &len); | ||
180 | if (reg && (len > 0) && (reg[0] == hw_cpuid)) | 179 | if (reg && (len > 0) && (reg[0] == hw_cpuid)) |
181 | return cpu_node; | 180 | return cpu_node; |
182 | } | 181 | } |
@@ -186,9 +185,9 @@ static struct device_node * __cpuinit find_cpu_node(unsigned int cpu) | |||
186 | } | 185 | } |
187 | 186 | ||
188 | /* must hold reference to node during call */ | 187 | /* must hold reference to node during call */ |
189 | static int *of_get_associativity(struct device_node *dev) | 188 | static const int *of_get_associativity(struct device_node *dev) |
190 | { | 189 | { |
191 | return (unsigned int *)get_property(dev, "ibm,associativity", NULL); | 190 | return get_property(dev, "ibm,associativity", NULL); |
192 | } | 191 | } |
193 | 192 | ||
194 | /* Returns nid in the range [0..MAX_NUMNODES-1], or -1 if no useful numa | 193 | /* Returns nid in the range [0..MAX_NUMNODES-1], or -1 if no useful numa |
@@ -197,7 +196,7 @@ static int *of_get_associativity(struct device_node *dev) | |||
197 | static int of_node_to_nid_single(struct device_node *device) | 196 | static int of_node_to_nid_single(struct device_node *device) |
198 | { | 197 | { |
199 | int nid = -1; | 198 | int nid = -1; |
200 | unsigned int *tmp; | 199 | const unsigned int *tmp; |
201 | 200 | ||
202 | if (min_common_depth == -1) | 201 | if (min_common_depth == -1) |
203 | goto out; | 202 | goto out; |
@@ -255,7 +254,7 @@ EXPORT_SYMBOL_GPL(of_node_to_nid); | |||
255 | static int __init find_min_common_depth(void) | 254 | static int __init find_min_common_depth(void) |
256 | { | 255 | { |
257 | int depth; | 256 | int depth; |
258 | unsigned int *ref_points; | 257 | const unsigned int *ref_points; |
259 | struct device_node *rtas_root; | 258 | struct device_node *rtas_root; |
260 | unsigned int len; | 259 | unsigned int len; |
261 | 260 | ||
@@ -270,7 +269,7 @@ static int __init find_min_common_depth(void) | |||
270 | * configuration (should be all 0's) and the second is for a normal | 269 | * configuration (should be all 0's) and the second is for a normal |
271 | * NUMA configuration. | 270 | * NUMA configuration. |
272 | */ | 271 | */ |
273 | ref_points = (unsigned int *)get_property(rtas_root, | 272 | ref_points = get_property(rtas_root, |
274 | "ibm,associativity-reference-points", &len); | 273 | "ibm,associativity-reference-points", &len); |
275 | 274 | ||
276 | if ((len >= 1) && ref_points) { | 275 | if ((len >= 1) && ref_points) { |
@@ -297,7 +296,7 @@ static void __init get_n_mem_cells(int *n_addr_cells, int *n_size_cells) | |||
297 | of_node_put(memory); | 296 | of_node_put(memory); |
298 | } | 297 | } |
299 | 298 | ||
300 | static unsigned long __devinit read_n_cells(int n, unsigned int **buf) | 299 | static unsigned long __devinit read_n_cells(int n, const unsigned int **buf) |
301 | { | 300 | { |
302 | unsigned long result = 0; | 301 | unsigned long result = 0; |
303 | 302 | ||
@@ -435,15 +434,13 @@ static int __init parse_numa_properties(void) | |||
435 | unsigned long size; | 434 | unsigned long size; |
436 | int nid; | 435 | int nid; |
437 | int ranges; | 436 | int ranges; |
438 | unsigned int *memcell_buf; | 437 | const unsigned int *memcell_buf; |
439 | unsigned int len; | 438 | unsigned int len; |
440 | 439 | ||
441 | memcell_buf = (unsigned int *)get_property(memory, | 440 | memcell_buf = get_property(memory, |
442 | "linux,usable-memory", &len); | 441 | "linux,usable-memory", &len); |
443 | if (!memcell_buf || len <= 0) | 442 | if (!memcell_buf || len <= 0) |
444 | memcell_buf = | 443 | memcell_buf = get_property(memory, "reg", &len); |
445 | (unsigned int *)get_property(memory, "reg", | ||
446 | &len); | ||
447 | if (!memcell_buf || len <= 0) | 444 | if (!memcell_buf || len <= 0) |
448 | continue; | 445 | continue; |
449 | 446 | ||
@@ -787,10 +784,10 @@ int hot_add_scn_to_nid(unsigned long scn_addr) | |||
787 | while ((memory = of_find_node_by_type(memory, "memory")) != NULL) { | 784 | while ((memory = of_find_node_by_type(memory, "memory")) != NULL) { |
788 | unsigned long start, size; | 785 | unsigned long start, size; |
789 | int ranges; | 786 | int ranges; |
790 | unsigned int *memcell_buf; | 787 | const unsigned int *memcell_buf; |
791 | unsigned int len; | 788 | unsigned int len; |
792 | 789 | ||
793 | memcell_buf = (unsigned int *)get_property(memory, "reg", &len); | 790 | memcell_buf = get_property(memory, "reg", &len); |
794 | if (!memcell_buf || len <= 0) | 791 | if (!memcell_buf || len <= 0) |
795 | continue; | 792 | continue; |
796 | 793 | ||
diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c index de0c8842415c..d3733912adb4 100644 --- a/arch/powerpc/mm/slb.c +++ b/arch/powerpc/mm/slb.c | |||
@@ -22,6 +22,8 @@ | |||
22 | #include <asm/paca.h> | 22 | #include <asm/paca.h> |
23 | #include <asm/cputable.h> | 23 | #include <asm/cputable.h> |
24 | #include <asm/cacheflush.h> | 24 | #include <asm/cacheflush.h> |
25 | #include <asm/smp.h> | ||
26 | #include <linux/compiler.h> | ||
25 | 27 | ||
26 | #ifdef DEBUG | 28 | #ifdef DEBUG |
27 | #define DBG(fmt...) udbg_printf(fmt) | 29 | #define DBG(fmt...) udbg_printf(fmt) |
@@ -50,9 +52,32 @@ static inline unsigned long mk_vsid_data(unsigned long ea, unsigned long flags) | |||
50 | return (get_kernel_vsid(ea) << SLB_VSID_SHIFT) | flags; | 52 | return (get_kernel_vsid(ea) << SLB_VSID_SHIFT) | flags; |
51 | } | 53 | } |
52 | 54 | ||
53 | static inline void create_slbe(unsigned long ea, unsigned long flags, | 55 | static inline void slb_shadow_update(unsigned long esid, unsigned long vsid, |
54 | unsigned long entry) | 56 | unsigned long entry) |
55 | { | 57 | { |
58 | /* | ||
59 | * Clear the ESID first so the entry is not valid while we are | ||
60 | * updating it. | ||
61 | */ | ||
62 | get_slb_shadow()->save_area[entry].esid = 0; | ||
63 | barrier(); | ||
64 | get_slb_shadow()->save_area[entry].vsid = vsid; | ||
65 | barrier(); | ||
66 | get_slb_shadow()->save_area[entry].esid = esid; | ||
67 | |||
68 | } | ||
69 | |||
70 | static inline void create_shadowed_slbe(unsigned long ea, unsigned long flags, | ||
71 | unsigned long entry) | ||
72 | { | ||
73 | /* | ||
74 | * Updating the shadow buffer before writing the SLB ensures | ||
75 | * we don't get a stale entry here if we get preempted by PHYP | ||
76 | * between these two statements. | ||
77 | */ | ||
78 | slb_shadow_update(mk_esid_data(ea, entry), mk_vsid_data(ea, flags), | ||
79 | entry); | ||
80 | |||
56 | asm volatile("slbmte %0,%1" : | 81 | asm volatile("slbmte %0,%1" : |
57 | : "r" (mk_vsid_data(ea, flags)), | 82 | : "r" (mk_vsid_data(ea, flags)), |
58 | "r" (mk_esid_data(ea, entry)) | 83 | "r" (mk_esid_data(ea, entry)) |
@@ -77,6 +102,10 @@ void slb_flush_and_rebolt(void) | |||
77 | if ((ksp_esid_data & ESID_MASK) == PAGE_OFFSET) | 102 | if ((ksp_esid_data & ESID_MASK) == PAGE_OFFSET) |
78 | ksp_esid_data &= ~SLB_ESID_V; | 103 | ksp_esid_data &= ~SLB_ESID_V; |
79 | 104 | ||
105 | /* Only third entry (stack) may change here so only resave that */ | ||
106 | slb_shadow_update(ksp_esid_data, | ||
107 | mk_vsid_data(ksp_esid_data, lflags), 2); | ||
108 | |||
80 | /* We need to do this all in asm, so we're sure we don't touch | 109 | /* We need to do this all in asm, so we're sure we don't touch |
81 | * the stack between the slbia and rebolting it. */ | 110 | * the stack between the slbia and rebolting it. */ |
82 | asm volatile("isync\n" | 111 | asm volatile("isync\n" |
@@ -209,9 +238,9 @@ void slb_initialize(void) | |||
209 | asm volatile("isync":::"memory"); | 238 | asm volatile("isync":::"memory"); |
210 | asm volatile("slbmte %0,%0"::"r" (0) : "memory"); | 239 | asm volatile("slbmte %0,%0"::"r" (0) : "memory"); |
211 | asm volatile("isync; slbia; isync":::"memory"); | 240 | asm volatile("isync; slbia; isync":::"memory"); |
212 | create_slbe(PAGE_OFFSET, lflags, 0); | 241 | create_shadowed_slbe(PAGE_OFFSET, lflags, 0); |
213 | 242 | ||
214 | create_slbe(VMALLOC_START, vflags, 1); | 243 | create_shadowed_slbe(VMALLOC_START, vflags, 1); |
215 | 244 | ||
216 | /* We don't bolt the stack for the time being - we're in boot, | 245 | /* We don't bolt the stack for the time being - we're in boot, |
217 | * so the stack is in the bolted segment. By the time it goes | 246 | * so the stack is in the bolted segment. By the time it goes |
diff --git a/arch/powerpc/mm/tlb_64.c b/arch/powerpc/mm/tlb_64.c index f6eef78efd29..b58baa65c4a7 100644 --- a/arch/powerpc/mm/tlb_64.c +++ b/arch/powerpc/mm/tlb_64.c | |||
@@ -146,6 +146,7 @@ void hpte_update(struct mm_struct *mm, unsigned long addr, | |||
146 | psize = mmu_huge_psize; | 146 | psize = mmu_huge_psize; |
147 | #else | 147 | #else |
148 | BUG(); | 148 | BUG(); |
149 | psize = pte_pagesize_index(pte); /* shutup gcc */ | ||
149 | #endif | 150 | #endif |
150 | } else | 151 | } else |
151 | psize = pte_pagesize_index(pte); | 152 | psize = pte_pagesize_index(pte); |