aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/sparc/include/asm/hugetlb.h1
-rw-r--r--arch/sparc/include/asm/page_64.h4
-rw-r--r--arch/sparc/include/asm/tsb.h28
-rw-r--r--arch/sparc/kernel/kernel.h12
-rw-r--r--arch/sparc/kernel/leon_smp.c33
-rw-r--r--arch/sparc/kernel/smp_32.c86
-rw-r--r--arch/sparc/kernel/sun4d_smp.c29
-rw-r--r--arch/sparc/kernel/sun4m_smp.c33
-rw-r--r--arch/sparc/kernel/trampoline_32.S17
-rw-r--r--arch/sparc/kernel/tsb.S39
-rw-r--r--arch/sparc/mm/fault_64.c9
-rw-r--r--arch/sparc/mm/init_64.c62
-rw-r--r--arch/sparc/mm/tlb.c11
-rw-r--r--arch/sparc/mm/tsb.c2
14 files changed, 246 insertions, 120 deletions
diff --git a/arch/sparc/include/asm/hugetlb.h b/arch/sparc/include/asm/hugetlb.h
index 9661e9bc7bb6..7eb57d245044 100644
--- a/arch/sparc/include/asm/hugetlb.h
+++ b/arch/sparc/include/asm/hugetlb.h
@@ -12,7 +12,6 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
12 12
13static inline void hugetlb_prefault_arch_hook(struct mm_struct *mm) 13static inline void hugetlb_prefault_arch_hook(struct mm_struct *mm)
14{ 14{
15 hugetlb_setup(mm);
16} 15}
17 16
18static inline int is_hugepage_only_range(struct mm_struct *mm, 17static inline int is_hugepage_only_range(struct mm_struct *mm,
diff --git a/arch/sparc/include/asm/page_64.h b/arch/sparc/include/asm/page_64.h
index 4b39f74d6ca0..e15538899f3d 100644
--- a/arch/sparc/include/asm/page_64.h
+++ b/arch/sparc/include/asm/page_64.h
@@ -27,8 +27,8 @@
27#ifndef __ASSEMBLY__ 27#ifndef __ASSEMBLY__
28 28
29#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE) 29#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
30struct mm_struct; 30struct pt_regs;
31extern void hugetlb_setup(struct mm_struct *mm); 31extern void hugetlb_setup(struct pt_regs *regs);
32#endif 32#endif
33 33
34#define WANT_PAGE_VIRTUAL 34#define WANT_PAGE_VIRTUAL
diff --git a/arch/sparc/include/asm/tsb.h b/arch/sparc/include/asm/tsb.h
index b4c258de4443..e696432b950d 100644
--- a/arch/sparc/include/asm/tsb.h
+++ b/arch/sparc/include/asm/tsb.h
@@ -157,17 +157,26 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end;
157 andn REG2, 0x7, REG2; \ 157 andn REG2, 0x7, REG2; \
158 add REG1, REG2, REG1; 158 add REG1, REG2, REG1;
159 159
160 /* This macro exists only to make the PMD translator below easier 160 /* These macros exists only to make the PMD translator below
161 * to read. It hides the ELF section switch for the sun4v code 161 * easier to read. It hides the ELF section switch for the
162 * patching. 162 * sun4v code patching.
163 */ 163 */
164#define OR_PTE_BIT(REG, NAME) \ 164#define OR_PTE_BIT_1INSN(REG, NAME) \
165661: or REG, _PAGE_##NAME##_4U, REG; \ 165661: or REG, _PAGE_##NAME##_4U, REG; \
166 .section .sun4v_1insn_patch, "ax"; \ 166 .section .sun4v_1insn_patch, "ax"; \
167 .word 661b; \ 167 .word 661b; \
168 or REG, _PAGE_##NAME##_4V, REG; \ 168 or REG, _PAGE_##NAME##_4V, REG; \
169 .previous; 169 .previous;
170 170
171#define OR_PTE_BIT_2INSN(REG, TMP, NAME) \
172661: sethi %hi(_PAGE_##NAME##_4U), TMP; \
173 or REG, TMP, REG; \
174 .section .sun4v_2insn_patch, "ax"; \
175 .word 661b; \
176 mov -1, TMP; \
177 or REG, _PAGE_##NAME##_4V, REG; \
178 .previous;
179
171 /* Load into REG the PTE value for VALID, CACHE, and SZHUGE. */ 180 /* Load into REG the PTE value for VALID, CACHE, and SZHUGE. */
172#define BUILD_PTE_VALID_SZHUGE_CACHE(REG) \ 181#define BUILD_PTE_VALID_SZHUGE_CACHE(REG) \
173661: sethi %uhi(_PAGE_VALID|_PAGE_SZHUGE_4U), REG; \ 182661: sethi %uhi(_PAGE_VALID|_PAGE_SZHUGE_4U), REG; \
@@ -214,12 +223,13 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end;
214 andn REG1, PMD_HUGE_PROTBITS, REG2; \ 223 andn REG1, PMD_HUGE_PROTBITS, REG2; \
215 sllx REG2, PMD_PADDR_SHIFT, REG2; \ 224 sllx REG2, PMD_PADDR_SHIFT, REG2; \
216 /* REG2 now holds PFN << PAGE_SHIFT */ \ 225 /* REG2 now holds PFN << PAGE_SHIFT */ \
217 andcc REG1, PMD_HUGE_EXEC, %g0; \ 226 andcc REG1, PMD_HUGE_WRITE, %g0; \
218 bne,a,pt %xcc, 1f; \
219 OR_PTE_BIT(REG2, EXEC); \
2201: andcc REG1, PMD_HUGE_WRITE, %g0; \
221 bne,a,pt %xcc, 1f; \ 227 bne,a,pt %xcc, 1f; \
222 OR_PTE_BIT(REG2, W); \ 228 OR_PTE_BIT_1INSN(REG2, W); \
2291: andcc REG1, PMD_HUGE_EXEC, %g0; \
230 be,pt %xcc, 1f; \
231 nop; \
232 OR_PTE_BIT_2INSN(REG2, REG1, EXEC); \
223 /* REG1 can now be clobbered, build final PTE */ \ 233 /* REG1 can now be clobbered, build final PTE */ \
2241: BUILD_PTE_VALID_SZHUGE_CACHE(REG1); \ 2341: BUILD_PTE_VALID_SZHUGE_CACHE(REG1); \
225 ba,pt %xcc, PTE_LABEL; \ 235 ba,pt %xcc, PTE_LABEL; \
diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h
index 291bb5de9ce0..a702d9ab019c 100644
--- a/arch/sparc/kernel/kernel.h
+++ b/arch/sparc/kernel/kernel.h
@@ -48,6 +48,10 @@ extern void sun4m_init_IRQ(void);
48extern void sun4m_unmask_profile_irq(void); 48extern void sun4m_unmask_profile_irq(void);
49extern void sun4m_clear_profile_irq(int cpu); 49extern void sun4m_clear_profile_irq(int cpu);
50 50
51/* sun4m_smp.c */
52void sun4m_cpu_pre_starting(void *arg);
53void sun4m_cpu_pre_online(void *arg);
54
51/* sun4d_irq.c */ 55/* sun4d_irq.c */
52extern spinlock_t sun4d_imsk_lock; 56extern spinlock_t sun4d_imsk_lock;
53 57
@@ -60,6 +64,14 @@ extern int show_sun4d_interrupts(struct seq_file *, void *);
60extern void sun4d_distribute_irqs(void); 64extern void sun4d_distribute_irqs(void);
61extern void sun4d_free_irq(unsigned int irq, void *dev_id); 65extern void sun4d_free_irq(unsigned int irq, void *dev_id);
62 66
67/* sun4d_smp.c */
68void sun4d_cpu_pre_starting(void *arg);
69void sun4d_cpu_pre_online(void *arg);
70
71/* leon_smp.c */
72void leon_cpu_pre_starting(void *arg);
73void leon_cpu_pre_online(void *arg);
74
63/* head_32.S */ 75/* head_32.S */
64extern unsigned int t_nmi[]; 76extern unsigned int t_nmi[];
65extern unsigned int linux_trap_ipi15_sun4d[]; 77extern unsigned int linux_trap_ipi15_sun4d[];
diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c
index 0f3fb6d9c8ef..9b40c9c12a0c 100644
--- a/arch/sparc/kernel/leon_smp.c
+++ b/arch/sparc/kernel/leon_smp.c
@@ -69,31 +69,19 @@ static inline unsigned long do_swap(volatile unsigned long *ptr,
69 return val; 69 return val;
70} 70}
71 71
72void __cpuinit leon_callin(void) 72void __cpuinit leon_cpu_pre_starting(void *arg)
73{ 73{
74 int cpuid = hard_smp_processor_id();
75
76 local_ops->cache_all();
77 local_ops->tlb_all();
78 leon_configure_cache_smp(); 74 leon_configure_cache_smp();
75}
79 76
80 notify_cpu_starting(cpuid); 77void __cpuinit leon_cpu_pre_online(void *arg)
81 78{
82 /* Get our local ticker going. */ 79 int cpuid = hard_smp_processor_id();
83 register_percpu_ce(cpuid);
84
85 calibrate_delay();
86 smp_store_cpu_info(cpuid);
87
88 local_ops->cache_all();
89 local_ops->tlb_all();
90 80
91 /* 81 /* Allow master to continue. The master will then give us the
92 * Unblock the master CPU _only_ when the scheduler state 82 * go-ahead by setting the smp_commenced_mask and will wait without
93 * of all secondary CPUs will be up-to-date, so after 83 * timeouts until our setup is completed fully (signified by
94 * the SMP initialization the master will be just allowed 84 * our bit being set in the cpu_online_mask).
95 * to call the scheduler code.
96 * Allow master to continue.
97 */ 85 */
98 do_swap(&cpu_callin_map[cpuid], 1); 86 do_swap(&cpu_callin_map[cpuid], 1);
99 87
@@ -110,9 +98,6 @@ void __cpuinit leon_callin(void)
110 98
111 while (!cpumask_test_cpu(cpuid, &smp_commenced_mask)) 99 while (!cpumask_test_cpu(cpuid, &smp_commenced_mask))
112 mb(); 100 mb();
113
114 local_irq_enable();
115 set_cpu_online(cpuid, true);
116} 101}
117 102
118/* 103/*
diff --git a/arch/sparc/kernel/smp_32.c b/arch/sparc/kernel/smp_32.c
index 79db45e5134a..9e7e6d718367 100644
--- a/arch/sparc/kernel/smp_32.c
+++ b/arch/sparc/kernel/smp_32.c
@@ -20,6 +20,7 @@
20#include <linux/seq_file.h> 20#include <linux/seq_file.h>
21#include <linux/cache.h> 21#include <linux/cache.h>
22#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/cpu.h>
23 24
24#include <asm/ptrace.h> 25#include <asm/ptrace.h>
25#include <linux/atomic.h> 26#include <linux/atomic.h>
@@ -32,8 +33,10 @@
32#include <asm/cacheflush.h> 33#include <asm/cacheflush.h>
33#include <asm/tlbflush.h> 34#include <asm/tlbflush.h>
34#include <asm/cpudata.h> 35#include <asm/cpudata.h>
36#include <asm/timer.h>
35#include <asm/leon.h> 37#include <asm/leon.h>
36 38
39#include "kernel.h"
37#include "irq.h" 40#include "irq.h"
38 41
39volatile unsigned long cpu_callin_map[NR_CPUS] __cpuinitdata = {0,}; 42volatile unsigned long cpu_callin_map[NR_CPUS] __cpuinitdata = {0,};
@@ -294,6 +297,89 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
294 return ret; 297 return ret;
295} 298}
296 299
300void __cpuinit arch_cpu_pre_starting(void *arg)
301{
302 local_ops->cache_all();
303 local_ops->tlb_all();
304
305 switch(sparc_cpu_model) {
306 case sun4m:
307 sun4m_cpu_pre_starting(arg);
308 break;
309 case sun4d:
310 sun4d_cpu_pre_starting(arg);
311 break;
312 case sparc_leon:
313 leon_cpu_pre_starting(arg);
314 break;
315 default:
316 BUG();
317 }
318}
319
320void __cpuinit arch_cpu_pre_online(void *arg)
321{
322 unsigned int cpuid = hard_smp_processor_id();
323
324 register_percpu_ce(cpuid);
325
326 calibrate_delay();
327 smp_store_cpu_info(cpuid);
328
329 local_ops->cache_all();
330 local_ops->tlb_all();
331
332 switch(sparc_cpu_model) {
333 case sun4m:
334 sun4m_cpu_pre_online(arg);
335 break;
336 case sun4d:
337 sun4d_cpu_pre_online(arg);
338 break;
339 case sparc_leon:
340 leon_cpu_pre_online(arg);
341 break;
342 default:
343 BUG();
344 }
345}
346
347void __cpuinit sparc_start_secondary(void *arg)
348{
349 unsigned int cpu;
350
351 /*
352 * SMP booting is extremely fragile in some architectures. So run
353 * the cpu initialization code first before anything else.
354 */
355 arch_cpu_pre_starting(arg);
356
357 preempt_disable();
358 cpu = smp_processor_id();
359
360 /* Invoke the CPU_STARTING notifier callbacks */
361 notify_cpu_starting(cpu);
362
363 arch_cpu_pre_online(arg);
364
365 /* Set the CPU in the cpu_online_mask */
366 set_cpu_online(cpu, true);
367
368 /* Enable local interrupts now */
369 local_irq_enable();
370
371 wmb();
372 cpu_idle();
373
374 /* We should never reach here! */
375 BUG();
376}
377
378void __cpuinit smp_callin(void)
379{
380 sparc_start_secondary(NULL);
381}
382
297void smp_bogo(struct seq_file *m) 383void smp_bogo(struct seq_file *m)
298{ 384{
299 int i; 385 int i;
diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c
index ddaea31de586..c9eb82f23d92 100644
--- a/arch/sparc/kernel/sun4d_smp.c
+++ b/arch/sparc/kernel/sun4d_smp.c
@@ -50,10 +50,9 @@ static inline void show_leds(int cpuid)
50 "i" (ASI_M_CTL)); 50 "i" (ASI_M_CTL));
51} 51}
52 52
53void __cpuinit smp4d_callin(void) 53void __cpuinit sun4d_cpu_pre_starting(void *arg)
54{ 54{
55 int cpuid = hard_smp_processor_id(); 55 int cpuid = hard_smp_processor_id();
56 unsigned long flags;
57 56
58 /* Show we are alive */ 57 /* Show we are alive */
59 cpu_leds[cpuid] = 0x6; 58 cpu_leds[cpuid] = 0x6;
@@ -61,26 +60,20 @@ void __cpuinit smp4d_callin(void)
61 60
62 /* Enable level15 interrupt, disable level14 interrupt for now */ 61 /* Enable level15 interrupt, disable level14 interrupt for now */
63 cc_set_imsk((cc_get_imsk() & ~0x8000) | 0x4000); 62 cc_set_imsk((cc_get_imsk() & ~0x8000) | 0x4000);
63}
64 64
65 local_ops->cache_all(); 65void __cpuinit sun4d_cpu_pre_online(void *arg)
66 local_ops->tlb_all(); 66{
67 unsigned long flags;
68 int cpuid;
67 69
68 notify_cpu_starting(cpuid); 70 cpuid = hard_smp_processor_id();
69 /* 71
70 * Unblock the master CPU _only_ when the scheduler state 72 /* Unblock the master CPU _only_ when the scheduler state
71 * of all secondary CPUs will be up-to-date, so after 73 * of all secondary CPUs will be up-to-date, so after
72 * the SMP initialization the master will be just allowed 74 * the SMP initialization the master will be just allowed
73 * to call the scheduler code. 75 * to call the scheduler code.
74 */ 76 */
75 /* Get our local ticker going. */
76 register_percpu_ce(cpuid);
77
78 calibrate_delay();
79 smp_store_cpu_info(cpuid);
80 local_ops->cache_all();
81 local_ops->tlb_all();
82
83 /* Allow master to continue. */
84 sun4d_swap((unsigned long *)&cpu_callin_map[cpuid], 1); 77 sun4d_swap((unsigned long *)&cpu_callin_map[cpuid], 1);
85 local_ops->cache_all(); 78 local_ops->cache_all();
86 local_ops->tlb_all(); 79 local_ops->tlb_all();
@@ -106,16 +99,12 @@ void __cpuinit smp4d_callin(void)
106 local_ops->cache_all(); 99 local_ops->cache_all();
107 local_ops->tlb_all(); 100 local_ops->tlb_all();
108 101
109 local_irq_enable(); /* We don't allow PIL 14 yet */
110
111 while (!cpumask_test_cpu(cpuid, &smp_commenced_mask)) 102 while (!cpumask_test_cpu(cpuid, &smp_commenced_mask))
112 barrier(); 103 barrier();
113 104
114 spin_lock_irqsave(&sun4d_imsk_lock, flags); 105 spin_lock_irqsave(&sun4d_imsk_lock, flags);
115 cc_set_imsk(cc_get_imsk() & ~0x4000); /* Allow PIL 14 as well */ 106 cc_set_imsk(cc_get_imsk() & ~0x4000); /* Allow PIL 14 as well */
116 spin_unlock_irqrestore(&sun4d_imsk_lock, flags); 107 spin_unlock_irqrestore(&sun4d_imsk_lock, flags);
117 set_cpu_online(cpuid, true);
118
119} 108}
120 109
121/* 110/*
diff --git a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c
index 128af7304288..8a65f158153d 100644
--- a/arch/sparc/kernel/sun4m_smp.c
+++ b/arch/sparc/kernel/sun4m_smp.c
@@ -34,30 +34,19 @@ swap_ulong(volatile unsigned long *ptr, unsigned long val)
34 return val; 34 return val;
35} 35}
36 36
37void __cpuinit smp4m_callin(void) 37void __cpuinit sun4m_cpu_pre_starting(void *arg)
38{ 38{
39 int cpuid = hard_smp_processor_id(); 39}
40
41 local_ops->cache_all();
42 local_ops->tlb_all();
43
44 notify_cpu_starting(cpuid);
45
46 register_percpu_ce(cpuid);
47
48 calibrate_delay();
49 smp_store_cpu_info(cpuid);
50 40
51 local_ops->cache_all(); 41void __cpuinit sun4m_cpu_pre_online(void *arg)
52 local_ops->tlb_all(); 42{
43 int cpuid = hard_smp_processor_id();
53 44
54 /* 45 /* Allow master to continue. The master will then give us the
55 * Unblock the master CPU _only_ when the scheduler state 46 * go-ahead by setting the smp_commenced_mask and will wait without
56 * of all secondary CPUs will be up-to-date, so after 47 * timeouts until our setup is completed fully (signified by
57 * the SMP initialization the master will be just allowed 48 * our bit being set in the cpu_online_mask).
58 * to call the scheduler code.
59 */ 49 */
60 /* Allow master to continue. */
61 swap_ulong(&cpu_callin_map[cpuid], 1); 50 swap_ulong(&cpu_callin_map[cpuid], 1);
62 51
63 /* XXX: What's up with all the flushes? */ 52 /* XXX: What's up with all the flushes? */
@@ -75,10 +64,6 @@ void __cpuinit smp4m_callin(void)
75 64
76 while (!cpumask_test_cpu(cpuid, &smp_commenced_mask)) 65 while (!cpumask_test_cpu(cpuid, &smp_commenced_mask))
77 mb(); 66 mb();
78
79 local_irq_enable();
80
81 set_cpu_online(cpuid, true);
82} 67}
83 68
84/* 69/*
diff --git a/arch/sparc/kernel/trampoline_32.S b/arch/sparc/kernel/trampoline_32.S
index af27acab4486..6cdb08cdabf0 100644
--- a/arch/sparc/kernel/trampoline_32.S
+++ b/arch/sparc/kernel/trampoline_32.S
@@ -79,18 +79,15 @@ cpu3_startup:
79 nop 79 nop
80 80
81 /* Start this processor. */ 81 /* Start this processor. */
82 call smp4m_callin 82 call smp_callin
83 nop 83 nop
84 84
85 b,a smp_do_cpu_idle 85 b,a smp_panic
86 86
87 .text 87 .text
88 .align 4 88 .align 4
89 89
90smp_do_cpu_idle: 90smp_panic:
91 call cpu_idle
92 mov 0, %o0
93
94 call cpu_panic 91 call cpu_panic
95 nop 92 nop
96 93
@@ -144,10 +141,10 @@ sun4d_cpu_startup:
144 nop 141 nop
145 142
146 /* Start this processor. */ 143 /* Start this processor. */
147 call smp4d_callin 144 call smp_callin
148 nop 145 nop
149 146
150 b,a smp_do_cpu_idle 147 b,a smp_panic
151 148
152 __CPUINIT 149 __CPUINIT
153 .align 4 150 .align 4
@@ -201,7 +198,7 @@ leon_smp_cpu_startup:
201 nop 198 nop
202 199
203 /* Start this processor. */ 200 /* Start this processor. */
204 call leon_callin 201 call smp_callin
205 nop 202 nop
206 203
207 b,a smp_do_cpu_idle 204 b,a smp_panic
diff --git a/arch/sparc/kernel/tsb.S b/arch/sparc/kernel/tsb.S
index d4bdc7a62375..a313e4a9399b 100644
--- a/arch/sparc/kernel/tsb.S
+++ b/arch/sparc/kernel/tsb.S
@@ -136,12 +136,43 @@ tsb_miss_page_table_walk_sun4v_fastpath:
136 nop 136 nop
137 137
138 /* It is a huge page, use huge page TSB entry address we 138 /* It is a huge page, use huge page TSB entry address we
139 * calculated above. 139 * calculated above. If the huge page TSB has not been
140 * allocated, setup a trap stack and call hugetlb_setup()
141 * to do so, then return from the trap to replay the TLB
142 * miss.
143 *
144 * This is necessary to handle the case of transparent huge
145 * pages where we don't really have a non-atomic context
146 * in which to allocate the hugepage TSB hash table. When
147 * the 'mm' faults in the hugepage for the first time, we
148 * thus handle it here. This also makes sure that we can
149 * allocate the TSB hash table on the correct NUMA node.
140 */ 150 */
141 TRAP_LOAD_TRAP_BLOCK(%g7, %g2) 151 TRAP_LOAD_TRAP_BLOCK(%g7, %g2)
142 ldx [%g7 + TRAP_PER_CPU_TSB_HUGE_TEMP], %g2 152 ldx [%g7 + TRAP_PER_CPU_TSB_HUGE_TEMP], %g1
143 cmp %g2, -1 153 cmp %g1, -1
144 movne %xcc, %g2, %g1 154 bne,pt %xcc, 60f
155 nop
156
157661: rdpr %pstate, %g5
158 wrpr %g5, PSTATE_AG | PSTATE_MG, %pstate
159 .section .sun4v_2insn_patch, "ax"
160 .word 661b
161 SET_GL(1)
162 nop
163 .previous
164
165 rdpr %tl, %g3
166 cmp %g3, 1
167 bne,pn %xcc, winfix_trampoline
168 nop
169 ba,pt %xcc, etrap
170 rd %pc, %g7
171 call hugetlb_setup
172 add %sp, PTREGS_OFF, %o0
173 ba,pt %xcc, rtrap
174 nop
175
14560: 17660:
146#endif 177#endif
147 178
diff --git a/arch/sparc/mm/fault_64.c b/arch/sparc/mm/fault_64.c
index 097aee763af3..5062ff389e83 100644
--- a/arch/sparc/mm/fault_64.c
+++ b/arch/sparc/mm/fault_64.c
@@ -472,8 +472,13 @@ good_area:
472#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE) 472#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
473 mm_rss = mm->context.huge_pte_count; 473 mm_rss = mm->context.huge_pte_count;
474 if (unlikely(mm_rss > 474 if (unlikely(mm_rss >
475 mm->context.tsb_block[MM_TSB_HUGE].tsb_rss_limit)) 475 mm->context.tsb_block[MM_TSB_HUGE].tsb_rss_limit)) {
476 tsb_grow(mm, MM_TSB_HUGE, mm_rss); 476 if (mm->context.tsb_block[MM_TSB_HUGE].tsb)
477 tsb_grow(mm, MM_TSB_HUGE, mm_rss);
478 else
479 hugetlb_setup(regs);
480
481 }
477#endif 482#endif
478 return; 483 return;
479 484
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
index c3b72423c846..82bbf048a5b0 100644
--- a/arch/sparc/mm/init_64.c
+++ b/arch/sparc/mm/init_64.c
@@ -314,16 +314,31 @@ static void __update_mmu_tsb_insert(struct mm_struct *mm, unsigned long tsb_inde
314 struct tsb *tsb = mm->context.tsb_block[tsb_index].tsb; 314 struct tsb *tsb = mm->context.tsb_block[tsb_index].tsb;
315 unsigned long tag; 315 unsigned long tag;
316 316
317 if (unlikely(!tsb))
318 return;
319
317 tsb += ((address >> tsb_hash_shift) & 320 tsb += ((address >> tsb_hash_shift) &
318 (mm->context.tsb_block[tsb_index].tsb_nentries - 1UL)); 321 (mm->context.tsb_block[tsb_index].tsb_nentries - 1UL));
319 tag = (address >> 22UL); 322 tag = (address >> 22UL);
320 tsb_insert(tsb, tag, tte); 323 tsb_insert(tsb, tag, tte);
321} 324}
322 325
326#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
327static inline bool is_hugetlb_pte(pte_t pte)
328{
329 if ((tlb_type == hypervisor &&
330 (pte_val(pte) & _PAGE_SZALL_4V) == _PAGE_SZHUGE_4V) ||
331 (tlb_type != hypervisor &&
332 (pte_val(pte) & _PAGE_SZALL_4U) == _PAGE_SZHUGE_4U))
333 return true;
334 return false;
335}
336#endif
337
323void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep) 338void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
324{ 339{
325 unsigned long tsb_index, tsb_hash_shift, flags;
326 struct mm_struct *mm; 340 struct mm_struct *mm;
341 unsigned long flags;
327 pte_t pte = *ptep; 342 pte_t pte = *ptep;
328 343
329 if (tlb_type != hypervisor) { 344 if (tlb_type != hypervisor) {
@@ -335,25 +350,16 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *
335 350
336 mm = vma->vm_mm; 351 mm = vma->vm_mm;
337 352
338 tsb_index = MM_TSB_BASE;
339 tsb_hash_shift = PAGE_SHIFT;
340
341 spin_lock_irqsave(&mm->context.lock, flags); 353 spin_lock_irqsave(&mm->context.lock, flags);
342 354
343#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE) 355#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
344 if (mm->context.tsb_block[MM_TSB_HUGE].tsb != NULL) { 356 if (mm->context.huge_pte_count && is_hugetlb_pte(pte))
345 if ((tlb_type == hypervisor && 357 __update_mmu_tsb_insert(mm, MM_TSB_HUGE, HPAGE_SHIFT,
346 (pte_val(pte) & _PAGE_SZALL_4V) == _PAGE_SZHUGE_4V) || 358 address, pte_val(pte));
347 (tlb_type != hypervisor && 359 else
348 (pte_val(pte) & _PAGE_SZALL_4U) == _PAGE_SZHUGE_4U)) {
349 tsb_index = MM_TSB_HUGE;
350 tsb_hash_shift = HPAGE_SHIFT;
351 }
352 }
353#endif 360#endif
354 361 __update_mmu_tsb_insert(mm, MM_TSB_BASE, PAGE_SHIFT,
355 __update_mmu_tsb_insert(mm, tsb_index, tsb_hash_shift, 362 address, pte_val(pte));
356 address, pte_val(pte));
357 363
358 spin_unlock_irqrestore(&mm->context.lock, flags); 364 spin_unlock_irqrestore(&mm->context.lock, flags);
359} 365}
@@ -2712,14 +2718,28 @@ static void context_reload(void *__data)
2712 load_secondary_context(mm); 2718 load_secondary_context(mm);
2713} 2719}
2714 2720
2715void hugetlb_setup(struct mm_struct *mm) 2721void hugetlb_setup(struct pt_regs *regs)
2716{ 2722{
2717 struct tsb_config *tp = &mm->context.tsb_block[MM_TSB_HUGE]; 2723 struct mm_struct *mm = current->mm;
2724 struct tsb_config *tp;
2718 2725
2719 if (likely(tp->tsb != NULL)) 2726 if (in_atomic() || !mm) {
2720 return; 2727 const struct exception_table_entry *entry;
2728
2729 entry = search_exception_tables(regs->tpc);
2730 if (entry) {
2731 regs->tpc = entry->fixup;
2732 regs->tnpc = regs->tpc + 4;
2733 return;
2734 }
2735 pr_alert("Unexpected HugeTLB setup in atomic context.\n");
2736 die_if_kernel("HugeTSB in atomic", regs);
2737 }
2738
2739 tp = &mm->context.tsb_block[MM_TSB_HUGE];
2740 if (likely(tp->tsb == NULL))
2741 tsb_grow(mm, MM_TSB_HUGE, 0);
2721 2742
2722 tsb_grow(mm, MM_TSB_HUGE, 0);
2723 tsb_context_switch(mm); 2743 tsb_context_switch(mm);
2724 smp_tsb_sync(mm); 2744 smp_tsb_sync(mm);
2725 2745
diff --git a/arch/sparc/mm/tlb.c b/arch/sparc/mm/tlb.c
index 3e8fec391fe0..ba6ae7ffdc2c 100644
--- a/arch/sparc/mm/tlb.c
+++ b/arch/sparc/mm/tlb.c
@@ -135,8 +135,15 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr,
135 mm->context.huge_pte_count++; 135 mm->context.huge_pte_count++;
136 else 136 else
137 mm->context.huge_pte_count--; 137 mm->context.huge_pte_count--;
138 if (mm->context.huge_pte_count == 1) 138
139 hugetlb_setup(mm); 139 /* Do not try to allocate the TSB hash table if we
140 * don't have one already. We have various locks held
141 * and thus we'll end up doing a GFP_KERNEL allocation
142 * in an atomic context.
143 *
144 * Instead, we let the first TLB miss on a hugepage
145 * take care of this.
146 */
140 } 147 }
141 148
142 if (!pmd_none(orig)) { 149 if (!pmd_none(orig)) {
diff --git a/arch/sparc/mm/tsb.c b/arch/sparc/mm/tsb.c
index 7f6474347491..428982b9becf 100644
--- a/arch/sparc/mm/tsb.c
+++ b/arch/sparc/mm/tsb.c
@@ -314,7 +314,7 @@ void tsb_grow(struct mm_struct *mm, unsigned long tsb_index, unsigned long rss)
314retry_tsb_alloc: 314retry_tsb_alloc:
315 gfp_flags = GFP_KERNEL; 315 gfp_flags = GFP_KERNEL;
316 if (new_size > (PAGE_SIZE * 2)) 316 if (new_size > (PAGE_SIZE * 2))
317 gfp_flags = __GFP_NOWARN | __GFP_NORETRY; 317 gfp_flags |= __GFP_NOWARN | __GFP_NORETRY;
318 318
319 new_tsb = kmem_cache_alloc_node(tsb_caches[new_cache_index], 319 new_tsb = kmem_cache_alloc_node(tsb_caches[new_cache_index],
320 gfp_flags, numa_node_id()); 320 gfp_flags, numa_node_id());