aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2006-02-06 01:27:28 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-03-20 04:11:50 -0500
commit45fec05f805a113372c9a7ff4c653ac749f6921c (patch)
tree36fc99d10656775acb8e9442719447d64ac30a03
parent314981ac7177a933319e3c071a5cf0a579205e6e (diff)
[SPARC64]: Sanitize %pstate writes for sun4v.
If we're just switching between different alternate global sets, nop it out on sun4v. Also, get rid of all of the alternate global save/restore in the OBP CIF trampoline code. Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--arch/sparc64/kernel/ktlb.S18
-rw-r--r--arch/sparc64/kernel/setup.c26
-rw-r--r--arch/sparc64/kernel/tsb.S12
-rw-r--r--arch/sparc64/kernel/vmlinux.lds.S3
-rw-r--r--arch/sparc64/mm/ultra.S18
-rw-r--r--arch/sparc64/prom/cif.S211
-rw-r--r--include/asm-sparc64/cpudata.h6
7 files changed, 88 insertions, 206 deletions
diff --git a/arch/sparc64/kernel/ktlb.S b/arch/sparc64/kernel/ktlb.S
index 9b415ab6db6b..c1335432124e 100644
--- a/arch/sparc64/kernel/ktlb.S
+++ b/arch/sparc64/kernel/ktlb.S
@@ -60,8 +60,15 @@ kvmap_itlb_load:
60 retry 60 retry
61 61
62kvmap_itlb_longpath: 62kvmap_itlb_longpath:
63 rdpr %pstate, %g5 63
64661: rdpr %pstate, %g5
64 wrpr %g5, PSTATE_AG | PSTATE_MG, %pstate 65 wrpr %g5, PSTATE_AG | PSTATE_MG, %pstate
66 .section .gl_2insn_patch, "ax"
67 .word 661b
68 nop
69 nop
70 .previous
71
65 rdpr %tpc, %g5 72 rdpr %tpc, %g5
66 ba,pt %xcc, sparc64_realfault_common 73 ba,pt %xcc, sparc64_realfault_common
67 mov FAULT_CODE_ITLB, %g4 74 mov FAULT_CODE_ITLB, %g4
@@ -161,8 +168,15 @@ kvmap_check_obp:
161 nop 168 nop
162 169
163kvmap_dtlb_longpath: 170kvmap_dtlb_longpath:
164 rdpr %pstate, %g5 171
172661: rdpr %pstate, %g5
165 wrpr %g5, PSTATE_AG | PSTATE_MG, %pstate 173 wrpr %g5, PSTATE_AG | PSTATE_MG, %pstate
174 .section .gl_2insn_patch, "ax"
175 .word 661b
176 nop
177 nop
178 .previous
179
166 rdpr %tl, %g4 180 rdpr %tl, %g4
167 cmp %g4, 1 181 cmp %g4, 1
168 mov TLB_TAG_ACCESS, %g4 182 mov TLB_TAG_ACCESS, %g4
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
index aaab319ad885..e22bf5fc92ce 100644
--- a/arch/sparc64/kernel/setup.c
+++ b/arch/sparc64/kernel/setup.c
@@ -547,19 +547,33 @@ static void __init per_cpu_patch(void)
547 547
548static void __init gl_patch(void) 548static void __init gl_patch(void)
549{ 549{
550 struct gl_1insn_patch_entry *p; 550 struct gl_1insn_patch_entry *p1;
551 struct gl_2insn_patch_entry *p2;
551 552
552 if (tlb_type != hypervisor) 553 if (tlb_type != hypervisor)
553 return; 554 return;
554 555
555 p = &__gl_1insn_patch; 556 p1 = &__gl_1insn_patch;
556 while (p < &__gl_1insn_patch_end) { 557 while (p1 < &__gl_1insn_patch_end) {
557 unsigned long addr = p->addr; 558 unsigned long addr = p1->addr;
558 559
559 *(unsigned int *) (addr + 0) = p->insn; 560 *(unsigned int *) (addr + 0) = p1->insn;
560 __asm__ __volatile__("flush %0" : : "r" (addr + 0)); 561 __asm__ __volatile__("flush %0" : : "r" (addr + 0));
561 562
562 p++; 563 p1++;
564 }
565
566 p2 = &__gl_2insn_patch;
567 while (p2 < &__gl_2insn_patch_end) {
568 unsigned long addr = p2->addr;
569
570 *(unsigned int *) (addr + 0) = p2->insns[0];
571 __asm__ __volatile__("flush %0" : : "r" (addr + 0));
572
573 *(unsigned int *) (addr + 3) = p2->insns[1];
574 __asm__ __volatile__("flush %0" : : "r" (addr + 4));
575
576 p2++;
563 } 577 }
564} 578}
565 579
diff --git a/arch/sparc64/kernel/tsb.S b/arch/sparc64/kernel/tsb.S
index 3b45db98005a..96e63168d8b2 100644
--- a/arch/sparc64/kernel/tsb.S
+++ b/arch/sparc64/kernel/tsb.S
@@ -82,9 +82,17 @@ tsb_itlb_load:
82 .globl tsb_do_fault 82 .globl tsb_do_fault
83tsb_do_fault: 83tsb_do_fault:
84 cmp %g3, FAULT_CODE_DTLB 84 cmp %g3, FAULT_CODE_DTLB
85 rdpr %pstate, %g5 85
86661: rdpr %pstate, %g5
87 wrpr %g5, PSTATE_AG | PSTATE_MG, %pstate
88 .section .gl_2insn_patch, "ax"
89 .word 661b
90 nop
91 nop
92 .previous
93
86 bne,pn %xcc, tsb_do_itlb_fault 94 bne,pn %xcc, tsb_do_itlb_fault
87 wrpr %g5, PSTATE_AG | PSTATE_MG, %pstate 95 nop
88 96
89tsb_do_dtlb_fault: 97tsb_do_dtlb_fault:
90 rdpr %tl, %g4 98 rdpr %tl, %g4
diff --git a/arch/sparc64/kernel/vmlinux.lds.S b/arch/sparc64/kernel/vmlinux.lds.S
index 482d1ed87f4d..686bf6b3b03f 100644
--- a/arch/sparc64/kernel/vmlinux.lds.S
+++ b/arch/sparc64/kernel/vmlinux.lds.S
@@ -80,6 +80,9 @@ SECTIONS
80 __gl_1insn_patch = .; 80 __gl_1insn_patch = .;
81 .gl_1insn_patch : { *(.gl_1insn_patch) } 81 .gl_1insn_patch : { *(.gl_1insn_patch) }
82 __gl_1insn_patch_end = .; 82 __gl_1insn_patch_end = .;
83 __gl_2insn_patch = .;
84 .gl_2insn_patch : { *(.gl_2insn_patch) }
85 __gl_2insn_patch_end = .;
83 . = ALIGN(8192); 86 . = ALIGN(8192);
84 __initramfs_start = .; 87 __initramfs_start = .;
85 .init.ramfs : { *(.init.ramfs) } 88 .init.ramfs : { *(.init.ramfs) }
diff --git a/arch/sparc64/mm/ultra.S b/arch/sparc64/mm/ultra.S
index cac58d66fca9..5dd86ad0d29f 100644
--- a/arch/sparc64/mm/ultra.S
+++ b/arch/sparc64/mm/ultra.S
@@ -444,8 +444,15 @@ xcall_flush_tlb_kernel_range: /* 22 insns */
444 */ 444 */
445 .globl xcall_sync_tick 445 .globl xcall_sync_tick
446xcall_sync_tick: 446xcall_sync_tick:
447 rdpr %pstate, %g2 447
448661: rdpr %pstate, %g2
448 wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate 449 wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate
450 .section .gl_2insn_patch, "ax"
451 .word 661b
452 nop
453 nop
454 .previous
455
449 rdpr %pil, %g2 456 rdpr %pil, %g2
450 wrpr %g0, 15, %pil 457 wrpr %g0, 15, %pil
451 sethi %hi(109f), %g7 458 sethi %hi(109f), %g7
@@ -468,8 +475,15 @@ xcall_sync_tick:
468 */ 475 */
469 .globl xcall_report_regs 476 .globl xcall_report_regs
470xcall_report_regs: 477xcall_report_regs:
471 rdpr %pstate, %g2 478
479661: rdpr %pstate, %g2
472 wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate 480 wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate
481 .section .gl_2insn_patch, "ax"
482 .word 661b
483 nop
484 nop
485 .previous
486
473 rdpr %pil, %g2 487 rdpr %pil, %g2
474 wrpr %g0, 15, %pil 488 wrpr %g0, 15, %pil
475 sethi %hi(109f), %g7 489 sethi %hi(109f), %g7
diff --git a/arch/sparc64/prom/cif.S b/arch/sparc64/prom/cif.S
index 29d0ae74aed8..5f27ad779c0c 100644
--- a/arch/sparc64/prom/cif.S
+++ b/arch/sparc64/prom/cif.S
@@ -1,10 +1,12 @@
1/* cif.S: PROM entry/exit assembler trampolines. 1/* cif.S: PROM entry/exit assembler trampolines.
2 * 2 *
3 * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) 3 * Copyright (C) 1996, 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
4 * Copyright (C) 2005 David S. Miller <davem@davemloft.net> 4 * Copyright (C) 2005, 2006 David S. Miller <davem@davemloft.net>
5 */ 5 */
6 6
7#include <asm/pstate.h> 7#include <asm/pstate.h>
8#include <asm/cpudata.h>
9#include <asm/thread_info.h>
8 10
9 .text 11 .text
10 .globl prom_cif_interface 12 .globl prom_cif_interface
@@ -12,78 +14,16 @@ prom_cif_interface:
12 sethi %hi(p1275buf), %o0 14 sethi %hi(p1275buf), %o0
13 or %o0, %lo(p1275buf), %o0 15 or %o0, %lo(p1275buf), %o0
14 ldx [%o0 + 0x010], %o1 ! prom_cif_stack 16 ldx [%o0 + 0x010], %o1 ! prom_cif_stack
15 save %o1, -0x190, %sp 17 save %o1, -192, %sp
16 ldx [%i0 + 0x008], %l2 ! prom_cif_handler 18 ldx [%i0 + 0x008], %l2 ! prom_cif_handler
17 rdpr %pstate, %l4 19 mov %g4, %l0
18 wrpr %g0, 0x15, %pstate ! save alternate globals 20 mov %g5, %l1
19 stx %g1, [%sp + 2047 + 0x0b0] 21 mov %g6, %l3
20 stx %g2, [%sp + 2047 + 0x0b8]
21 stx %g3, [%sp + 2047 + 0x0c0]
22 stx %g4, [%sp + 2047 + 0x0c8]
23 stx %g5, [%sp + 2047 + 0x0d0]
24 stx %g6, [%sp + 2047 + 0x0d8]
25 stx %g7, [%sp + 2047 + 0x0e0]
26 wrpr %g0, 0x814, %pstate ! save interrupt globals
27 stx %g1, [%sp + 2047 + 0x0e8]
28 stx %g2, [%sp + 2047 + 0x0f0]
29 stx %g3, [%sp + 2047 + 0x0f8]
30 stx %g4, [%sp + 2047 + 0x100]
31 stx %g5, [%sp + 2047 + 0x108]
32 stx %g6, [%sp + 2047 + 0x110]
33 stx %g7, [%sp + 2047 + 0x118]
34 wrpr %g0, 0x14, %pstate ! save normal globals
35 stx %g1, [%sp + 2047 + 0x120]
36 stx %g2, [%sp + 2047 + 0x128]
37 stx %g3, [%sp + 2047 + 0x130]
38 stx %g4, [%sp + 2047 + 0x138]
39 stx %g5, [%sp + 2047 + 0x140]
40 stx %g6, [%sp + 2047 + 0x148]
41 stx %g7, [%sp + 2047 + 0x150]
42 wrpr %g0, 0x414, %pstate ! save mmu globals
43 stx %g1, [%sp + 2047 + 0x158]
44 stx %g2, [%sp + 2047 + 0x160]
45 stx %g3, [%sp + 2047 + 0x168]
46 stx %g4, [%sp + 2047 + 0x170]
47 stx %g5, [%sp + 2047 + 0x178]
48 stx %g6, [%sp + 2047 + 0x180]
49 stx %g7, [%sp + 2047 + 0x188]
50 mov %g1, %l0 ! also save to locals, so we can handle
51 mov %g2, %l1 ! tlb faults later on, when accessing
52 mov %g3, %l3 ! the stack.
53 mov %g7, %l5
54 wrpr %l4, PSTATE_IE, %pstate ! turn off interrupts
55 call %l2 22 call %l2
56 add %i0, 0x018, %o0 ! prom_args 23 add %i0, 0x018, %o0 ! prom_args
57 wrpr %g0, 0x414, %pstate ! restore mmu globals 24 mov %l0, %g4
58 mov %l0, %g1 25 mov %l1, %g5
59 mov %l1, %g2 26 mov %l3, %g6
60 mov %l3, %g3
61 mov %l5, %g7
62 wrpr %g0, 0x14, %pstate ! restore normal globals
63 ldx [%sp + 2047 + 0x120], %g1
64 ldx [%sp + 2047 + 0x128], %g2
65 ldx [%sp + 2047 + 0x130], %g3
66 ldx [%sp + 2047 + 0x138], %g4
67 ldx [%sp + 2047 + 0x140], %g5
68 ldx [%sp + 2047 + 0x148], %g6
69 ldx [%sp + 2047 + 0x150], %g7
70 wrpr %g0, 0x814, %pstate ! restore interrupt globals
71 ldx [%sp + 2047 + 0x0e8], %g1
72 ldx [%sp + 2047 + 0x0f0], %g2
73 ldx [%sp + 2047 + 0x0f8], %g3
74 ldx [%sp + 2047 + 0x100], %g4
75 ldx [%sp + 2047 + 0x108], %g5
76 ldx [%sp + 2047 + 0x110], %g6
77 ldx [%sp + 2047 + 0x118], %g7
78 wrpr %g0, 0x15, %pstate ! restore alternate globals
79 ldx [%sp + 2047 + 0x0b0], %g1
80 ldx [%sp + 2047 + 0x0b8], %g2
81 ldx [%sp + 2047 + 0x0c0], %g3
82 ldx [%sp + 2047 + 0x0c8], %g4
83 ldx [%sp + 2047 + 0x0d0], %g5
84 ldx [%sp + 2047 + 0x0d8], %g6
85 ldx [%sp + 2047 + 0x0e0], %g7
86 wrpr %l4, 0, %pstate ! restore original pstate
87 ret 27 ret
88 restore 28 restore
89 29
@@ -91,135 +31,18 @@ prom_cif_interface:
91prom_cif_callback: 31prom_cif_callback:
92 sethi %hi(p1275buf), %o1 32 sethi %hi(p1275buf), %o1
93 or %o1, %lo(p1275buf), %o1 33 or %o1, %lo(p1275buf), %o1
94 save %sp, -0x270, %sp 34 save %sp, -192, %sp
95 rdpr %pstate, %l4 35 TRAP_LOAD_THREAD_REG(%g6, %g1)
96 wrpr %g0, 0x15, %pstate ! save PROM alternate globals 36 LOAD_PER_CPU_BASE(%g5, %g6, %g4, %g3, %o0)
97 stx %g1, [%sp + 2047 + 0x0b0] 37 ldx [%g6 + TI_TASK], %g4
98 stx %g2, [%sp + 2047 + 0x0b8]
99 stx %g3, [%sp + 2047 + 0x0c0]
100 stx %g4, [%sp + 2047 + 0x0c8]
101 stx %g5, [%sp + 2047 + 0x0d0]
102 stx %g6, [%sp + 2047 + 0x0d8]
103 stx %g7, [%sp + 2047 + 0x0e0]
104 ! restore Linux alternate globals
105 ldx [%sp + 2047 + 0x190], %g1
106 ldx [%sp + 2047 + 0x198], %g2
107 ldx [%sp + 2047 + 0x1a0], %g3
108 ldx [%sp + 2047 + 0x1a8], %g4
109 ldx [%sp + 2047 + 0x1b0], %g5
110 ldx [%sp + 2047 + 0x1b8], %g6
111 ldx [%sp + 2047 + 0x1c0], %g7
112 wrpr %g0, 0x814, %pstate ! save PROM interrupt globals
113 stx %g1, [%sp + 2047 + 0x0e8]
114 stx %g2, [%sp + 2047 + 0x0f0]
115 stx %g3, [%sp + 2047 + 0x0f8]
116 stx %g4, [%sp + 2047 + 0x100]
117 stx %g5, [%sp + 2047 + 0x108]
118 stx %g6, [%sp + 2047 + 0x110]
119 stx %g7, [%sp + 2047 + 0x118]
120 ! restore Linux interrupt globals
121 ldx [%sp + 2047 + 0x1c8], %g1
122 ldx [%sp + 2047 + 0x1d0], %g2
123 ldx [%sp + 2047 + 0x1d8], %g3
124 ldx [%sp + 2047 + 0x1e0], %g4
125 ldx [%sp + 2047 + 0x1e8], %g5
126 ldx [%sp + 2047 + 0x1f0], %g6
127 ldx [%sp + 2047 + 0x1f8], %g7
128 wrpr %g0, 0x14, %pstate ! save PROM normal globals
129 stx %g1, [%sp + 2047 + 0x120]
130 stx %g2, [%sp + 2047 + 0x128]
131 stx %g3, [%sp + 2047 + 0x130]
132 stx %g4, [%sp + 2047 + 0x138]
133 stx %g5, [%sp + 2047 + 0x140]
134 stx %g6, [%sp + 2047 + 0x148]
135 stx %g7, [%sp + 2047 + 0x150]
136 ! restore Linux normal globals
137 ldx [%sp + 2047 + 0x200], %g1
138 ldx [%sp + 2047 + 0x208], %g2
139 ldx [%sp + 2047 + 0x210], %g3
140 ldx [%sp + 2047 + 0x218], %g4
141 ldx [%sp + 2047 + 0x220], %g5
142 ldx [%sp + 2047 + 0x228], %g6
143 ldx [%sp + 2047 + 0x230], %g7
144 wrpr %g0, 0x414, %pstate ! save PROM mmu globals
145 stx %g1, [%sp + 2047 + 0x158]
146 stx %g2, [%sp + 2047 + 0x160]
147 stx %g3, [%sp + 2047 + 0x168]
148 stx %g4, [%sp + 2047 + 0x170]
149 stx %g5, [%sp + 2047 + 0x178]
150 stx %g6, [%sp + 2047 + 0x180]
151 stx %g7, [%sp + 2047 + 0x188]
152 ! restore Linux mmu globals
153 ldx [%sp + 2047 + 0x238], %o0
154 ldx [%sp + 2047 + 0x240], %o1
155 ldx [%sp + 2047 + 0x248], %l2
156 ldx [%sp + 2047 + 0x250], %l3
157 ldx [%sp + 2047 + 0x258], %l5
158 ldx [%sp + 2047 + 0x260], %l6
159 ldx [%sp + 2047 + 0x268], %l7
160 ! switch to Linux tba
161 sethi %hi(sparc64_ttable_tl0), %l1
162 rdpr %tba, %l0 ! save PROM tba
163 mov %o0, %g1
164 mov %o1, %g2
165 mov %l2, %g3
166 mov %l3, %g4
167 mov %l5, %g5
168 mov %l6, %g6
169 mov %l7, %g7
170 wrpr %l1, %tba ! install Linux tba
171 wrpr %l4, 0, %pstate ! restore PSTATE
172 call prom_world 38 call prom_world
173 mov %g0, %o0 39 mov 0, %o0
174 ldx [%i1 + 0x000], %l2 40 ldx [%i1 + 0x000], %l2
175 call %l2 41 call %l2
176 mov %i0, %o0 42 mov %i0, %o0
177 mov %o0, %l1 43 mov %o0, %l1
178 call prom_world 44 call prom_world
179 or %g0, 1, %o0 45 mov 1, %o0
180 wrpr %g0, 0x14, %pstate ! interrupts off
181 ! restore PROM mmu globals
182 ldx [%sp + 2047 + 0x158], %o0
183 ldx [%sp + 2047 + 0x160], %o1
184 ldx [%sp + 2047 + 0x168], %l2
185 ldx [%sp + 2047 + 0x170], %l3
186 ldx [%sp + 2047 + 0x178], %l5
187 ldx [%sp + 2047 + 0x180], %l6
188 ldx [%sp + 2047 + 0x188], %l7
189 wrpr %g0, 0x414, %pstate ! restore PROM mmu globals
190 mov %o0, %g1
191 mov %o1, %g2
192 mov %l2, %g3
193 mov %l3, %g4
194 mov %l5, %g5
195 mov %l6, %g6
196 mov %l7, %g7
197 wrpr %l0, %tba ! restore PROM tba
198 wrpr %g0, 0x14, %pstate ! restore PROM normal globals
199 ldx [%sp + 2047 + 0x120], %g1
200 ldx [%sp + 2047 + 0x128], %g2
201 ldx [%sp + 2047 + 0x130], %g3
202 ldx [%sp + 2047 + 0x138], %g4
203 ldx [%sp + 2047 + 0x140], %g5
204 ldx [%sp + 2047 + 0x148], %g6
205 ldx [%sp + 2047 + 0x150], %g7
206 wrpr %g0, 0x814, %pstate ! restore PROM interrupt globals
207 ldx [%sp + 2047 + 0x0e8], %g1
208 ldx [%sp + 2047 + 0x0f0], %g2
209 ldx [%sp + 2047 + 0x0f8], %g3
210 ldx [%sp + 2047 + 0x100], %g4
211 ldx [%sp + 2047 + 0x108], %g5
212 ldx [%sp + 2047 + 0x110], %g6
213 ldx [%sp + 2047 + 0x118], %g7
214 wrpr %g0, 0x15, %pstate ! restore PROM alternate globals
215 ldx [%sp + 2047 + 0x0b0], %g1
216 ldx [%sp + 2047 + 0x0b8], %g2
217 ldx [%sp + 2047 + 0x0c0], %g3
218 ldx [%sp + 2047 + 0x0c8], %g4
219 ldx [%sp + 2047 + 0x0d0], %g5
220 ldx [%sp + 2047 + 0x0d8], %g6
221 ldx [%sp + 2047 + 0x0e0], %g7
222 wrpr %l4, 0, %pstate
223 ret 46 ret
224 restore %l1, 0, %o0 47 restore %l1, 0, %o0
225 48
diff --git a/include/asm-sparc64/cpudata.h b/include/asm-sparc64/cpudata.h
index 8666440c89af..998145b92653 100644
--- a/include/asm-sparc64/cpudata.h
+++ b/include/asm-sparc64/cpudata.h
@@ -78,6 +78,12 @@ struct gl_1insn_patch_entry {
78 unsigned int insn; 78 unsigned int insn;
79}; 79};
80extern struct gl_1insn_patch_entry __gl_1insn_patch, __gl_1insn_patch_end; 80extern struct gl_1insn_patch_entry __gl_1insn_patch, __gl_1insn_patch_end;
81
82struct gl_2insn_patch_entry {
83 unsigned int addr;
84 unsigned int insns[2];
85};
86extern struct gl_2insn_patch_entry __gl_2insn_patch, __gl_2insn_patch_end;
81#endif /* !(__ASSEMBLY__) */ 87#endif /* !(__ASSEMBLY__) */
82 88
83#define TRAP_PER_CPU_THREAD 0x00 89#define TRAP_PER_CPU_THREAD 0x00