Skip to content

Commit

Permalink
[SPARC64]: Fix some SUN4V TLB handling bugs.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
David S. Miller committed Mar 20, 2006
1 parent 12e126a commit 6c8927c
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 5 deletions.
57 changes: 55 additions & 2 deletions arch/sparc64/kernel/sun4v_tlb_miss.S
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,9 @@ sun4v_itlb_load:
mov %g3, %o2 ! PTE
mov HV_MMU_IMMU, %o3 ! flags
ta HV_MMU_MAP_ADDR_TRAP
brnz,pn %o0, sun4v_itlb_error
mov %g2, %o1 ! restore %o1
mov %g1, %o0 ! restore %o0
mov %g2, %o1 ! restore %o1
mov %g5, %o2 ! restore %o2
mov %g7, %o3 ! restore %o3

Expand Down Expand Up @@ -126,8 +127,9 @@ sun4v_dtlb_load:
mov %g3, %o2 ! PTE
mov HV_MMU_DMMU, %o3 ! flags
ta HV_MMU_MAP_ADDR_TRAP
brnz,pn %o0, sun4v_dtlb_error
mov %g2, %o1 ! restore %o1
mov %g1, %o0 ! restore %o0
mov %g2, %o1 ! restore %o1
mov %g5, %o2 ! restore %o2
mov %g7, %o3 ! restore %o3

Expand All @@ -154,6 +156,7 @@ sun4v_itsb_miss:
ldxa [%g1] ASI_SCRATCHPAD, %g1
brz,pn %g5, kvmap_itlb_4v
mov FAULT_CODE_ITLB, %g3
ba,a,pt %xcc, sun4v_tsb_miss_common

/* Called from trap table with TAG TARGET placed into
* %g6 and SCRATCHPAD_UTSBREG1 contents in %g1.
Expand Down Expand Up @@ -182,6 +185,56 @@ sun4v_tsb_miss_common:
ba,pt %xcc, tsb_miss_page_table_walk_sun4v_fastpath
ldx [%g2 + TRAP_PER_CPU_PGD_PADDR], %g7

sun4v_itlb_error:
sethi %hi(sun4v_err_itlb_vaddr), %g1
stx %g4, [%g1 + %lo(sun4v_err_itlb_vaddr)]
sethi %hi(sun4v_err_itlb_ctx), %g1
srlx %g6, 48, %o1 ! ctx
stx %o1, [%g1 + %lo(sun4v_err_itlb_ctx)]
sethi %hi(sun4v_err_itlb_pte), %g1
stx %g3, [%g1 + %lo(sun4v_err_itlb_pte)]
sethi %hi(sun4v_err_itlb_error), %g1
stx %o0, [%g1 + %lo(sun4v_err_itlb_error)]

rdpr %tl, %g4
cmp %g4, 1
ble,pt %icc, 1f
sethi %hi(2f), %g7
ba,pt %xcc, etraptl1
or %g7, %lo(2f), %g7

1: ba,pt %xcc, etrap
2: or %g7, %lo(2b), %g7
call sun4v_itlb_error_report
add %sp, PTREGS_OFF, %o0

/* NOTREACHED */

sun4v_dtlb_error:
sethi %hi(sun4v_err_dtlb_vaddr), %g1
stx %g4, [%g1 + %lo(sun4v_err_dtlb_vaddr)]
sethi %hi(sun4v_err_dtlb_ctx), %g1
srlx %g6, 48, %o1 ! ctx
stx %o1, [%g1 + %lo(sun4v_err_dtlb_ctx)]
sethi %hi(sun4v_err_dtlb_pte), %g1
stx %g3, [%g1 + %lo(sun4v_err_dtlb_pte)]
sethi %hi(sun4v_err_dtlb_error), %g1
stx %o0, [%g1 + %lo(sun4v_err_dtlb_error)]

rdpr %tl, %g4
cmp %g4, 1
ble,pt %icc, 1f
sethi %hi(2f), %g7
ba,pt %xcc, etraptl1
or %g7, %lo(2f), %g7

1: ba,pt %xcc, etrap
2: or %g7, %lo(2b), %g7
call sun4v_dtlb_error_report
add %sp, PTREGS_OFF, %o0

/* NOTREACHED */

/* Instruction Access Exception, tl0. */
sun4v_iacc:
ldxa [%g0] ASI_SCRATCHPAD, %g2
Expand Down
34 changes: 34 additions & 0 deletions arch/sparc64/kernel/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -1928,6 +1928,40 @@ void sun4v_nonresum_overflow(struct pt_regs *regs)
atomic_inc(&sun4v_nonresum_oflow_cnt);
}

unsigned long sun4v_err_itlb_vaddr;
unsigned long sun4v_err_itlb_ctx;
unsigned long sun4v_err_itlb_pte;
unsigned long sun4v_err_itlb_error;

void sun4v_itlb_error_report(struct pt_regs *regs, int tl)
{
if (tl > 1)
dump_tl1_traplog((struct tl1_traplog *)(regs + 1));

printk("SUN4V-ITLB: Error at TPC[%lx], tl %d\n", regs->tpc, tl);
printk("SUN4V-ITLB: vaddr[%lx] ctx[%lx] pte[%lx] error[%lx]\n",
sun4v_err_itlb_vaddr, sun4v_err_itlb_ctx,
sun4v_err_itlb_pte, sun4v_err_itlb_error);
prom_halt();
}

unsigned long sun4v_err_dtlb_vaddr;
unsigned long sun4v_err_dtlb_ctx;
unsigned long sun4v_err_dtlb_pte;
unsigned long sun4v_err_dtlb_error;

void sun4v_dtlb_error_report(struct pt_regs *regs, int tl)
{
if (tl > 1)
dump_tl1_traplog((struct tl1_traplog *)(regs + 1));

printk("SUN4V-DTLB: Error at TPC[%lx], tl %d\n", regs->tpc, tl);
printk("SUN4V-DTLB: vaddr[%lx] ctx[%lx] pte[%lx] error[%lx]\n",
sun4v_err_dtlb_vaddr, sun4v_err_dtlb_ctx,
sun4v_err_dtlb_pte, sun4v_err_dtlb_error);
prom_halt();
}

void do_fpe_common(struct pt_regs *regs)
{
if (regs->tstate & TSTATE_PRIV) {
Expand Down
6 changes: 3 additions & 3 deletions arch/sparc64/kernel/tsb.S
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,8 @@ tsb_do_fault:
wrpr %g5, PSTATE_AG | PSTATE_MG, %pstate
.section .sun4v_2insn_patch, "ax"
.word 661b
nop
nop
SET_GL(1)
ldxa [%g0] ASI_SCRATCHPAD, %g2
.previous

bne,pn %xcc, tsb_do_itlb_fault
Expand All @@ -150,7 +150,7 @@ tsb_do_dtlb_fault:
ldxa [%g4] ASI_DMMU, %g5
.section .sun4v_2insn_patch, "ax"
.word 661b
mov %g4, %g5
ldx [%g2 + HV_FAULT_D_ADDR_OFFSET], %g5
nop
.previous

Expand Down

0 comments on commit 6c8927c

Please sign in to comment.