aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2006-02-17 17:58:02 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-03-20 04:13:32 -0500
commit6c8927c9634e8a1bc95d5291c55205707f9fa40a (patch)
treee59db7dca9ab26808703ee3c20ad59c3425024fa /arch/sparc64/kernel
parent12e126ad229abc718d05600027fcd5794c1e31e5 (diff)
[SPARC64]: Fix some SUN4V TLB handling bugs.
1) Add error return checking for TLB load hypervisor calls. 2) Don't fallthru to dtlb tsb miss handler from itlb tsb miss handler, oops. 3) On window fixups, propagate fault information to fixup handler correctly. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel')
-rw-r--r--arch/sparc64/kernel/sun4v_tlb_miss.S57
-rw-r--r--arch/sparc64/kernel/traps.c34
-rw-r--r--arch/sparc64/kernel/tsb.S6
3 files changed, 92 insertions, 5 deletions
diff --git a/arch/sparc64/kernel/sun4v_tlb_miss.S b/arch/sparc64/kernel/sun4v_tlb_miss.S
index df65d712dcc6..244d50de8499 100644
--- a/arch/sparc64/kernel/sun4v_tlb_miss.S
+++ b/arch/sparc64/kernel/sun4v_tlb_miss.S
@@ -84,8 +84,9 @@ sun4v_itlb_load:
84 mov %g3, %o2 ! PTE 84 mov %g3, %o2 ! PTE
85 mov HV_MMU_IMMU, %o3 ! flags 85 mov HV_MMU_IMMU, %o3 ! flags
86 ta HV_MMU_MAP_ADDR_TRAP 86 ta HV_MMU_MAP_ADDR_TRAP
87 brnz,pn %o0, sun4v_itlb_error
88 mov %g2, %o1 ! restore %o1
87 mov %g1, %o0 ! restore %o0 89 mov %g1, %o0 ! restore %o0
88 mov %g2, %o1 ! restore %o1
89 mov %g5, %o2 ! restore %o2 90 mov %g5, %o2 ! restore %o2
90 mov %g7, %o3 ! restore %o3 91 mov %g7, %o3 ! restore %o3
91 92
@@ -126,8 +127,9 @@ sun4v_dtlb_load:
126 mov %g3, %o2 ! PTE 127 mov %g3, %o2 ! PTE
127 mov HV_MMU_DMMU, %o3 ! flags 128 mov HV_MMU_DMMU, %o3 ! flags
128 ta HV_MMU_MAP_ADDR_TRAP 129 ta HV_MMU_MAP_ADDR_TRAP
130 brnz,pn %o0, sun4v_dtlb_error
131 mov %g2, %o1 ! restore %o1
129 mov %g1, %o0 ! restore %o0 132 mov %g1, %o0 ! restore %o0
130 mov %g2, %o1 ! restore %o1
131 mov %g5, %o2 ! restore %o2 133 mov %g5, %o2 ! restore %o2
132 mov %g7, %o3 ! restore %o3 134 mov %g7, %o3 ! restore %o3
133 135
@@ -154,6 +156,7 @@ sun4v_itsb_miss:
154 ldxa [%g1] ASI_SCRATCHPAD, %g1 156 ldxa [%g1] ASI_SCRATCHPAD, %g1
155 brz,pn %g5, kvmap_itlb_4v 157 brz,pn %g5, kvmap_itlb_4v
156 mov FAULT_CODE_ITLB, %g3 158 mov FAULT_CODE_ITLB, %g3
159 ba,a,pt %xcc, sun4v_tsb_miss_common
157 160
158 /* Called from trap table with TAG TARGET placed into 161 /* Called from trap table with TAG TARGET placed into
159 * %g6 and SCRATCHPAD_UTSBREG1 contents in %g1. 162 * %g6 and SCRATCHPAD_UTSBREG1 contents in %g1.
@@ -182,6 +185,56 @@ sun4v_tsb_miss_common:
182 ba,pt %xcc, tsb_miss_page_table_walk_sun4v_fastpath 185 ba,pt %xcc, tsb_miss_page_table_walk_sun4v_fastpath
183 ldx [%g2 + TRAP_PER_CPU_PGD_PADDR], %g7 186 ldx [%g2 + TRAP_PER_CPU_PGD_PADDR], %g7
184 187
188sun4v_itlb_error:
189 sethi %hi(sun4v_err_itlb_vaddr), %g1
190 stx %g4, [%g1 + %lo(sun4v_err_itlb_vaddr)]
191 sethi %hi(sun4v_err_itlb_ctx), %g1
192 srlx %g6, 48, %o1 ! ctx
193 stx %o1, [%g1 + %lo(sun4v_err_itlb_ctx)]
194 sethi %hi(sun4v_err_itlb_pte), %g1
195 stx %g3, [%g1 + %lo(sun4v_err_itlb_pte)]
196 sethi %hi(sun4v_err_itlb_error), %g1
197 stx %o0, [%g1 + %lo(sun4v_err_itlb_error)]
198
199 rdpr %tl, %g4
200 cmp %g4, 1
201 ble,pt %icc, 1f
202 sethi %hi(2f), %g7
203 ba,pt %xcc, etraptl1
204 or %g7, %lo(2f), %g7
205
2061: ba,pt %xcc, etrap
2072: or %g7, %lo(2b), %g7
208 call sun4v_itlb_error_report
209 add %sp, PTREGS_OFF, %o0
210
211 /* NOTREACHED */
212
213sun4v_dtlb_error:
214 sethi %hi(sun4v_err_dtlb_vaddr), %g1
215 stx %g4, [%g1 + %lo(sun4v_err_dtlb_vaddr)]
216 sethi %hi(sun4v_err_dtlb_ctx), %g1
217 srlx %g6, 48, %o1 ! ctx
218 stx %o1, [%g1 + %lo(sun4v_err_dtlb_ctx)]
219 sethi %hi(sun4v_err_dtlb_pte), %g1
220 stx %g3, [%g1 + %lo(sun4v_err_dtlb_pte)]
221 sethi %hi(sun4v_err_dtlb_error), %g1
222 stx %o0, [%g1 + %lo(sun4v_err_dtlb_error)]
223
224 rdpr %tl, %g4
225 cmp %g4, 1
226 ble,pt %icc, 1f
227 sethi %hi(2f), %g7
228 ba,pt %xcc, etraptl1
229 or %g7, %lo(2f), %g7
230
2311: ba,pt %xcc, etrap
2322: or %g7, %lo(2b), %g7
233 call sun4v_dtlb_error_report
234 add %sp, PTREGS_OFF, %o0
235
236 /* NOTREACHED */
237
185 /* Instruction Access Exception, tl0. */ 238 /* Instruction Access Exception, tl0. */
186sun4v_iacc: 239sun4v_iacc:
187 ldxa [%g0] ASI_SCRATCHPAD, %g2 240 ldxa [%g0] ASI_SCRATCHPAD, %g2
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c
index c9484ae5bb8f..5a157e92bfc7 100644
--- a/arch/sparc64/kernel/traps.c
+++ b/arch/sparc64/kernel/traps.c
@@ -1928,6 +1928,40 @@ void sun4v_nonresum_overflow(struct pt_regs *regs)
1928 atomic_inc(&sun4v_nonresum_oflow_cnt); 1928 atomic_inc(&sun4v_nonresum_oflow_cnt);
1929} 1929}
1930 1930
1931unsigned long sun4v_err_itlb_vaddr;
1932unsigned long sun4v_err_itlb_ctx;
1933unsigned long sun4v_err_itlb_pte;
1934unsigned long sun4v_err_itlb_error;
1935
1936void sun4v_itlb_error_report(struct pt_regs *regs, int tl)
1937{
1938 if (tl > 1)
1939 dump_tl1_traplog((struct tl1_traplog *)(regs + 1));
1940
1941 printk("SUN4V-ITLB: Error at TPC[%lx], tl %d\n", regs->tpc, tl);
1942 printk("SUN4V-ITLB: vaddr[%lx] ctx[%lx] pte[%lx] error[%lx]\n",
1943 sun4v_err_itlb_vaddr, sun4v_err_itlb_ctx,
1944 sun4v_err_itlb_pte, sun4v_err_itlb_error);
1945 prom_halt();
1946}
1947
1948unsigned long sun4v_err_dtlb_vaddr;
1949unsigned long sun4v_err_dtlb_ctx;
1950unsigned long sun4v_err_dtlb_pte;
1951unsigned long sun4v_err_dtlb_error;
1952
1953void sun4v_dtlb_error_report(struct pt_regs *regs, int tl)
1954{
1955 if (tl > 1)
1956 dump_tl1_traplog((struct tl1_traplog *)(regs + 1));
1957
1958 printk("SUN4V-DTLB: Error at TPC[%lx], tl %d\n", regs->tpc, tl);
1959 printk("SUN4V-DTLB: vaddr[%lx] ctx[%lx] pte[%lx] error[%lx]\n",
1960 sun4v_err_dtlb_vaddr, sun4v_err_dtlb_ctx,
1961 sun4v_err_dtlb_pte, sun4v_err_dtlb_error);
1962 prom_halt();
1963}
1964
1931void do_fpe_common(struct pt_regs *regs) 1965void do_fpe_common(struct pt_regs *regs)
1932{ 1966{
1933 if (regs->tstate & TSTATE_PRIV) { 1967 if (regs->tstate & TSTATE_PRIV) {
diff --git a/arch/sparc64/kernel/tsb.S b/arch/sparc64/kernel/tsb.S
index 7996c9d66702..a17259cf34b8 100644
--- a/arch/sparc64/kernel/tsb.S
+++ b/arch/sparc64/kernel/tsb.S
@@ -135,8 +135,8 @@ tsb_do_fault:
135 wrpr %g5, PSTATE_AG | PSTATE_MG, %pstate 135 wrpr %g5, PSTATE_AG | PSTATE_MG, %pstate
136 .section .sun4v_2insn_patch, "ax" 136 .section .sun4v_2insn_patch, "ax"
137 .word 661b 137 .word 661b
138 nop 138 SET_GL(1)
139 nop 139 ldxa [%g0] ASI_SCRATCHPAD, %g2
140 .previous 140 .previous
141 141
142 bne,pn %xcc, tsb_do_itlb_fault 142 bne,pn %xcc, tsb_do_itlb_fault
@@ -150,7 +150,7 @@ tsb_do_dtlb_fault:
150 ldxa [%g4] ASI_DMMU, %g5 150 ldxa [%g4] ASI_DMMU, %g5
151 .section .sun4v_2insn_patch, "ax" 151 .section .sun4v_2insn_patch, "ax"
152 .word 661b 152 .word 661b
153 mov %g4, %g5 153 ldx [%g2 + HV_FAULT_D_ADDR_OFFSET], %g5
154 nop 154 nop
155 .previous 155 .previous
156 156