David S. Miller | 314ef68 | 2006-02-04 00:10:01 -0800 | [diff] [blame] | 1 | /* winfixup.S: Handle cases where user stack pointer is found to be bogus. |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2 | * |
David S. Miller | 314ef68 | 2006-02-04 00:10:01 -0800 | [diff] [blame] | 3 | * Copyright (C) 1997, 2006 David S. Miller (davem@davemloft.net) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 4 | */ |
| 5 | |
| 6 | #include <asm/asi.h> |
| 7 | #include <asm/head.h> |
| 8 | #include <asm/page.h> |
| 9 | #include <asm/ptrace.h> |
| 10 | #include <asm/processor.h> |
| 11 | #include <asm/spitfire.h> |
| 12 | #include <asm/thread_info.h> |
| 13 | |
| 14 | .text |
| 15 | |
David S. Miller | 314ef68 | 2006-02-04 00:10:01 -0800 | [diff] [blame] | 16 | /* It used to be the case that these register window fault |
| 17 | * handlers could run via the save and restore instructions |
| 18 | * done by the trap entry and exit code. They now do the |
| 19 | * window spill/fill by hand, so that case no longer can occur. |
| 20 | */ |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 21 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 22 | .align 32 |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 23 | fill_fixup: |
David S. Miller | ffe483d | 2006-02-02 21:55:10 -0800 | [diff] [blame] | 24 | TRAP_LOAD_THREAD_REG(%g6, %g1) |
David S. Miller | 314ef68 | 2006-02-04 00:10:01 -0800 | [diff] [blame] | 25 | rdpr %tstate, %g1 |
| 26 | and %g1, TSTATE_CWP, %g1 |
| 27 | or %g4, FAULT_CODE_WINFIXUP, %g4 |
| 28 | stb %g4, [%g6 + TI_FAULT_CODE] |
| 29 | stx %g5, [%g6 + TI_FAULT_ADDR] |
| 30 | wrpr %g1, %cwp |
| 31 | ba,pt %xcc, etrap |
| 32 | rd %pc, %g7 |
| 33 | call do_sparc64_fault |
| 34 | add %sp, PTREGS_OFF, %o0 |
David S. Miller | 7697daa | 2008-04-24 03:15:22 -0700 | [diff] [blame] | 35 | ba,pt %xcc, rtrap |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 36 | nop |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 37 | |
David S. Miller | 314ef68 | 2006-02-04 00:10:01 -0800 | [diff] [blame] | 38 | /* Be very careful about usage of the trap globals here. |
| 39 | * You cannot touch %g5 as that has the fault information. |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 40 | */ |
| 41 | spill_fixup: |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 42 | spill_fixup_mna: |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 43 | spill_fixup_dax: |
David S. Miller | ffe483d | 2006-02-02 21:55:10 -0800 | [diff] [blame] | 44 | TRAP_LOAD_THREAD_REG(%g6, %g1) |
David S. Miller | 314ef68 | 2006-02-04 00:10:01 -0800 | [diff] [blame] | 45 | ldx [%g6 + TI_FLAGS], %g1 |
David S. Miller | 517ffce | 2012-10-26 15:18:37 -0700 | [diff] [blame] | 46 | andcc %sp, 0x1, %g0 |
| 47 | movne %icc, 0, %g1 |
David S. Miller | 314ef68 | 2006-02-04 00:10:01 -0800 | [diff] [blame] | 48 | andcc %g1, _TIF_32BIT, %g0 |
| 49 | ldub [%g6 + TI_WSAVED], %g1 |
| 50 | sll %g1, 3, %g3 |
| 51 | add %g6, %g3, %g3 |
| 52 | stx %sp, [%g3 + TI_RWIN_SPTRS] |
| 53 | sll %g1, 7, %g3 |
| 54 | bne,pt %xcc, 1f |
| 55 | add %g6, %g3, %g3 |
| 56 | stx %l0, [%g3 + TI_REG_WINDOW + 0x00] |
| 57 | stx %l1, [%g3 + TI_REG_WINDOW + 0x08] |
| 58 | stx %l2, [%g3 + TI_REG_WINDOW + 0x10] |
| 59 | stx %l3, [%g3 + TI_REG_WINDOW + 0x18] |
| 60 | stx %l4, [%g3 + TI_REG_WINDOW + 0x20] |
| 61 | stx %l5, [%g3 + TI_REG_WINDOW + 0x28] |
| 62 | stx %l6, [%g3 + TI_REG_WINDOW + 0x30] |
| 63 | stx %l7, [%g3 + TI_REG_WINDOW + 0x38] |
| 64 | stx %i0, [%g3 + TI_REG_WINDOW + 0x40] |
| 65 | stx %i1, [%g3 + TI_REG_WINDOW + 0x48] |
| 66 | stx %i2, [%g3 + TI_REG_WINDOW + 0x50] |
| 67 | stx %i3, [%g3 + TI_REG_WINDOW + 0x58] |
| 68 | stx %i4, [%g3 + TI_REG_WINDOW + 0x60] |
| 69 | stx %i5, [%g3 + TI_REG_WINDOW + 0x68] |
| 70 | stx %i6, [%g3 + TI_REG_WINDOW + 0x70] |
| 71 | ba,pt %xcc, 2f |
| 72 | stx %i7, [%g3 + TI_REG_WINDOW + 0x78] |
| 73 | 1: stw %l0, [%g3 + TI_REG_WINDOW + 0x00] |
| 74 | stw %l1, [%g3 + TI_REG_WINDOW + 0x04] |
| 75 | stw %l2, [%g3 + TI_REG_WINDOW + 0x08] |
| 76 | stw %l3, [%g3 + TI_REG_WINDOW + 0x0c] |
| 77 | stw %l4, [%g3 + TI_REG_WINDOW + 0x10] |
| 78 | stw %l5, [%g3 + TI_REG_WINDOW + 0x14] |
| 79 | stw %l6, [%g3 + TI_REG_WINDOW + 0x18] |
| 80 | stw %l7, [%g3 + TI_REG_WINDOW + 0x1c] |
| 81 | stw %i0, [%g3 + TI_REG_WINDOW + 0x20] |
| 82 | stw %i1, [%g3 + TI_REG_WINDOW + 0x24] |
| 83 | stw %i2, [%g3 + TI_REG_WINDOW + 0x28] |
| 84 | stw %i3, [%g3 + TI_REG_WINDOW + 0x2c] |
| 85 | stw %i4, [%g3 + TI_REG_WINDOW + 0x30] |
| 86 | stw %i5, [%g3 + TI_REG_WINDOW + 0x34] |
| 87 | stw %i6, [%g3 + TI_REG_WINDOW + 0x38] |
| 88 | stw %i7, [%g3 + TI_REG_WINDOW + 0x3c] |
| 89 | 2: add %g1, 1, %g1 |
| 90 | stb %g1, [%g6 + TI_WSAVED] |
| 91 | rdpr %tstate, %g1 |
| 92 | andcc %g1, TSTATE_PRIV, %g0 |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 93 | saved |
David S. Miller | 314ef68 | 2006-02-04 00:10:01 -0800 | [diff] [blame] | 94 | be,pn %xcc, 1f |
| 95 | and %g1, TSTATE_CWP, %g1 |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 96 | retry |
David S. Miller | 314ef68 | 2006-02-04 00:10:01 -0800 | [diff] [blame] | 97 | 1: mov FAULT_CODE_WRITE | FAULT_CODE_DTLB | FAULT_CODE_WINFIXUP, %g4 |
| 98 | stb %g4, [%g6 + TI_FAULT_CODE] |
| 99 | stx %g5, [%g6 + TI_FAULT_ADDR] |
| 100 | wrpr %g1, %cwp |
| 101 | ba,pt %xcc, etrap |
| 102 | rd %pc, %g7 |
| 103 | call do_sparc64_fault |
| 104 | add %sp, PTREGS_OFF, %o0 |
David S. Miller | 7697daa | 2008-04-24 03:15:22 -0700 | [diff] [blame] | 105 | ba,a,pt %xcc, rtrap |
David S. Miller | 314ef68 | 2006-02-04 00:10:01 -0800 | [diff] [blame] | 106 | |
| 107 | winfix_mna: |
| 108 | andn %g3, 0x7f, %g3 |
| 109 | add %g3, 0x78, %g3 |
| 110 | wrpr %g3, %tnpc |
| 111 | done |
| 112 | |
| 113 | fill_fixup_mna: |
David S. Miller | 314ef68 | 2006-02-04 00:10:01 -0800 | [diff] [blame] | 114 | rdpr %tstate, %g1 |
| 115 | and %g1, TSTATE_CWP, %g1 |
| 116 | wrpr %g1, %cwp |
| 117 | ba,pt %xcc, etrap |
| 118 | rd %pc, %g7 |
David S. Miller | ed6b0b4 | 2006-02-09 20:20:34 -0800 | [diff] [blame] | 119 | sethi %hi(tlb_type), %g1 |
David S. Miller | ed6b0b4 | 2006-02-09 20:20:34 -0800 | [diff] [blame] | 120 | lduw [%g1 + %lo(tlb_type)], %g1 |
David S. Miller | ed6b0b4 | 2006-02-09 20:20:34 -0800 | [diff] [blame] | 121 | cmp %g1, 3 |
| 122 | bne,pt %icc, 1f |
David S. Miller | 314ef68 | 2006-02-04 00:10:01 -0800 | [diff] [blame] | 123 | add %sp, PTREGS_OFF, %o0 |
David S. Miller | 24c523e | 2006-02-18 16:39:39 -0800 | [diff] [blame] | 124 | mov %l4, %o2 |
David S. Miller | 9b6b464 | 2006-02-16 01:45:49 -0800 | [diff] [blame] | 125 | call sun4v_do_mna |
David S. Miller | 24c523e | 2006-02-18 16:39:39 -0800 | [diff] [blame] | 126 | mov %l5, %o1 |
David S. Miller | 7697daa | 2008-04-24 03:15:22 -0700 | [diff] [blame] | 127 | ba,a,pt %xcc, rtrap |
David S. Miller | 24c523e | 2006-02-18 16:39:39 -0800 | [diff] [blame] | 128 | 1: mov %l4, %o1 |
| 129 | mov %l5, %o2 |
| 130 | call mem_address_unaligned |
David S. Miller | ed6b0b4 | 2006-02-09 20:20:34 -0800 | [diff] [blame] | 131 | nop |
David S. Miller | 7697daa | 2008-04-24 03:15:22 -0700 | [diff] [blame] | 132 | ba,a,pt %xcc, rtrap |
David S. Miller | 314ef68 | 2006-02-04 00:10:01 -0800 | [diff] [blame] | 133 | |
| 134 | winfix_dax: |
| 135 | andn %g3, 0x7f, %g3 |
| 136 | add %g3, 0x74, %g3 |
| 137 | wrpr %g3, %tnpc |
| 138 | done |
| 139 | |
| 140 | fill_fixup_dax: |
David S. Miller | 314ef68 | 2006-02-04 00:10:01 -0800 | [diff] [blame] | 141 | rdpr %tstate, %g1 |
| 142 | and %g1, TSTATE_CWP, %g1 |
| 143 | wrpr %g1, %cwp |
| 144 | ba,pt %xcc, etrap |
| 145 | rd %pc, %g7 |
David S. Miller | ed6b0b4 | 2006-02-09 20:20:34 -0800 | [diff] [blame] | 146 | sethi %hi(tlb_type), %g1 |
David S. Miller | 314ef68 | 2006-02-04 00:10:01 -0800 | [diff] [blame] | 147 | mov %l4, %o1 |
David S. Miller | ed6b0b4 | 2006-02-09 20:20:34 -0800 | [diff] [blame] | 148 | lduw [%g1 + %lo(tlb_type)], %g1 |
David S. Miller | 314ef68 | 2006-02-04 00:10:01 -0800 | [diff] [blame] | 149 | mov %l5, %o2 |
David S. Miller | ed6b0b4 | 2006-02-09 20:20:34 -0800 | [diff] [blame] | 150 | cmp %g1, 3 |
| 151 | bne,pt %icc, 1f |
David S. Miller | 314ef68 | 2006-02-04 00:10:01 -0800 | [diff] [blame] | 152 | add %sp, PTREGS_OFF, %o0 |
David S. Miller | ed6b0b4 | 2006-02-09 20:20:34 -0800 | [diff] [blame] | 153 | call sun4v_data_access_exception |
| 154 | nop |
David S. Miller | 7697daa | 2008-04-24 03:15:22 -0700 | [diff] [blame] | 155 | ba,a,pt %xcc, rtrap |
David S. Miller | ed6b0b4 | 2006-02-09 20:20:34 -0800 | [diff] [blame] | 156 | 1: call spitfire_data_access_exception |
| 157 | nop |
David S. Miller | 7697daa | 2008-04-24 03:15:22 -0700 | [diff] [blame] | 158 | ba,a,pt %xcc, rtrap |