Loading arch/xtensa/kernel/vectors.S +136 −22 Original line number Diff line number Diff line Loading @@ -376,38 +376,42 @@ _DoubleExceptionVector_WindowOverflow: beqz a2, 1f # if at start of vector, don't restore addi a0, a0, -128 bbsi a0, 8, 1f # don't restore except for overflow 8 and 12 bbsi a0, 7, 2f bbsi.l a0, 8, 1f # don't restore except for overflow 8 and 12 /* * This fixup handler is for the extremely unlikely case where the * overflow handler's reference thru a0 gets a hardware TLB refill * that bumps out the (distinct, aliasing) TLB entry that mapped its * prior references thru a9/a13, and where our reference now thru * a9/a13 gets a 2nd-level miss exception (not hardware TLB refill). */ movi a2, window_overflow_restore_a0_fixup s32i a2, a3, EXC_TABLE_FIXUP l32i a2, a3, EXC_TABLE_DOUBLE_SAVE xsr a3, excsave1 bbsi.l a0, 7, 2f /* * Restore a0 as saved by _WindowOverflow8(). * * FIXME: we really need a fixup handler for this L32E, * for the extremely unlikely case where the overflow handler's * reference thru a0 gets a hardware TLB refill that bumps out * the (distinct, aliasing) TLB entry that mapped its prior * references thru a9, and where our reference now thru a9 * gets a 2nd-level miss exception (not hardware TLB refill). */ l32e a2, a9, -16 wsr a2, depc # replace the saved a0 j 1f l32e a0, a9, -16 wsr a0, depc # replace the saved a0 j 3f 2: /* * Restore a0 as saved by _WindowOverflow12(). * * FIXME: we really need a fixup handler for this L32E, * for the extremely unlikely case where the overflow handler's * reference thru a0 gets a hardware TLB refill that bumps out * the (distinct, aliasing) TLB entry that mapped its prior * references thru a13, and where our reference now thru a13 * gets a 2nd-level miss exception (not hardware TLB refill). */ l32e a2, a13, -16 wsr a2, depc # replace the saved a0 l32e a0, a13, -16 wsr a0, depc # replace the saved a0 3: xsr a3, excsave1 movi a0, 0 s32i a0, a3, EXC_TABLE_FIXUP s32i a2, a3, EXC_TABLE_DOUBLE_SAVE 1: /* * Restore WindowBase while leaving all address registers restored. Loading Loading @@ -449,6 +453,7 @@ _DoubleExceptionVector_WindowOverflow: s32i a0, a2, PT_DEPC _DoubleExceptionVector_handle_exception: addx4 a0, a0, a3 l32i a0, a0, EXC_TABLE_FAST_USER xsr a3, excsave1 Loading @@ -464,10 +469,119 @@ _DoubleExceptionVector_WindowOverflow: rotw -3 j 1b .end literal_prefix ENDPROC(_DoubleExceptionVector) /* * Fixup handler for TLB miss in double exception handler for window owerflow. * We get here with windowbase set to the window that was being spilled and * a0 trashed. a0 bit 7 determines if this is a call8 (bit clear) or call12 * (bit set) window. * * We do the following here: * - go to the original window retaining a0 value; * - set up exception stack to return back to appropriate a0 restore code * (we'll need to rotate window back and there's no place to save this * information, use different return address for that); * - handle the exception; * - go to the window that was being spilled; * - set up window_overflow_restore_a0_fixup as a fixup routine; * - reload a0; * - restore the original window; * - reset the default fixup routine; * - return to user. By the time we get to this fixup handler all information * about the conditions of the original double exception that happened in * the window overflow handler is lost, so we just return to userspace to * retry overflow from start. * * a0: value of depc, original value in depc * a2: trashed, original value in EXC_TABLE_DOUBLE_SAVE * a3: exctable, original value in excsave1 */ ENTRY(window_overflow_restore_a0_fixup) rsr a0, ps extui a0, a0, PS_OWB_SHIFT, PS_OWB_WIDTH rsr a2, windowbase sub a0, a2, a0 extui a0, a0, 0, 3 l32i a2, a3, EXC_TABLE_DOUBLE_SAVE xsr a3, excsave1 _beqi a0, 1, .Lhandle_1 _beqi a0, 3, .Lhandle_3 .macro overflow_fixup_handle_exception_pane n rsr a0, depc rotw -\n xsr a3, excsave1 wsr a2, depc l32i a2, a3, EXC_TABLE_KSTK s32i a0, a2, PT_AREG0 movi a0, .Lrestore_\n s32i a0, a2, PT_DEPC rsr a0, exccause j _DoubleExceptionVector_handle_exception .endm overflow_fixup_handle_exception_pane 2 .Lhandle_1: overflow_fixup_handle_exception_pane 1 .Lhandle_3: overflow_fixup_handle_exception_pane 3 .macro overflow_fixup_restore_a0_pane n rotw \n /* Need to preserve a0 value here to be able to handle exception * that may occur on a0 reload from stack. It may occur because * TLB miss handler may not be atomic and pointer to page table * may be lost before we get here. There are no free registers, * so we need to use EXC_TABLE_DOUBLE_SAVE area. */ xsr a3, excsave1 s32i a2, a3, EXC_TABLE_DOUBLE_SAVE movi a2, window_overflow_restore_a0_fixup s32i a2, a3, EXC_TABLE_FIXUP l32i a2, a3, EXC_TABLE_DOUBLE_SAVE xsr a3, excsave1 bbsi.l a0, 7, 1f l32e a0, a9, -16 j 2f 1: l32e a0, a13, -16 2: rotw -\n .endm .Lrestore_2: overflow_fixup_restore_a0_pane 2 .Lset_default_fixup: xsr a3, excsave1 s32i a2, a3, EXC_TABLE_DOUBLE_SAVE movi a2, 0 s32i a2, a3, EXC_TABLE_FIXUP l32i a2, a3, EXC_TABLE_DOUBLE_SAVE xsr a3, excsave1 rfe .Lrestore_1: overflow_fixup_restore_a0_pane 1 j .Lset_default_fixup .Lrestore_3: overflow_fixup_restore_a0_pane 3 j .Lset_default_fixup ENDPROC(window_overflow_restore_a0_fixup) .end literal_prefix /* * Debug interrupt vector * Loading arch/xtensa/kernel/vmlinux.lds.S +2 −2 Original line number Diff line number Diff line Loading @@ -269,13 +269,13 @@ SECTIONS .UserExceptionVector.literal) SECTION_VECTOR (_DoubleExceptionVector_literal, .DoubleExceptionVector.literal, DOUBLEEXC_VECTOR_VADDR - 16, DOUBLEEXC_VECTOR_VADDR - 40, SIZEOF(.UserExceptionVector.text), .UserExceptionVector.text) SECTION_VECTOR (_DoubleExceptionVector_text, .DoubleExceptionVector.text, DOUBLEEXC_VECTOR_VADDR, 32, 40, .DoubleExceptionVector.literal) . = (LOADADDR( .DoubleExceptionVector.text ) + SIZEOF( .DoubleExceptionVector.text ) + 3) & ~ 3; Loading arch/xtensa/mm/init.c +1 −1 Original line number Diff line number Diff line Loading @@ -191,7 +191,7 @@ int __init mem_reserve(unsigned long start, unsigned long end, int must_exist) return -EINVAL; } if (it && start - it->start < bank_sz) { if (it && start - it->start <= bank_sz) { if (start == it->start) { if (end - it->start < bank_sz) { it->start = end; Loading Loading
arch/xtensa/kernel/vectors.S +136 −22 Original line number Diff line number Diff line Loading @@ -376,38 +376,42 @@ _DoubleExceptionVector_WindowOverflow: beqz a2, 1f # if at start of vector, don't restore addi a0, a0, -128 bbsi a0, 8, 1f # don't restore except for overflow 8 and 12 bbsi a0, 7, 2f bbsi.l a0, 8, 1f # don't restore except for overflow 8 and 12 /* * This fixup handler is for the extremely unlikely case where the * overflow handler's reference thru a0 gets a hardware TLB refill * that bumps out the (distinct, aliasing) TLB entry that mapped its * prior references thru a9/a13, and where our reference now thru * a9/a13 gets a 2nd-level miss exception (not hardware TLB refill). */ movi a2, window_overflow_restore_a0_fixup s32i a2, a3, EXC_TABLE_FIXUP l32i a2, a3, EXC_TABLE_DOUBLE_SAVE xsr a3, excsave1 bbsi.l a0, 7, 2f /* * Restore a0 as saved by _WindowOverflow8(). * * FIXME: we really need a fixup handler for this L32E, * for the extremely unlikely case where the overflow handler's * reference thru a0 gets a hardware TLB refill that bumps out * the (distinct, aliasing) TLB entry that mapped its prior * references thru a9, and where our reference now thru a9 * gets a 2nd-level miss exception (not hardware TLB refill). */ l32e a2, a9, -16 wsr a2, depc # replace the saved a0 j 1f l32e a0, a9, -16 wsr a0, depc # replace the saved a0 j 3f 2: /* * Restore a0 as saved by _WindowOverflow12(). * * FIXME: we really need a fixup handler for this L32E, * for the extremely unlikely case where the overflow handler's * reference thru a0 gets a hardware TLB refill that bumps out * the (distinct, aliasing) TLB entry that mapped its prior * references thru a13, and where our reference now thru a13 * gets a 2nd-level miss exception (not hardware TLB refill). */ l32e a2, a13, -16 wsr a2, depc # replace the saved a0 l32e a0, a13, -16 wsr a0, depc # replace the saved a0 3: xsr a3, excsave1 movi a0, 0 s32i a0, a3, EXC_TABLE_FIXUP s32i a2, a3, EXC_TABLE_DOUBLE_SAVE 1: /* * Restore WindowBase while leaving all address registers restored. Loading Loading @@ -449,6 +453,7 @@ _DoubleExceptionVector_WindowOverflow: s32i a0, a2, PT_DEPC _DoubleExceptionVector_handle_exception: addx4 a0, a0, a3 l32i a0, a0, EXC_TABLE_FAST_USER xsr a3, excsave1 Loading @@ -464,10 +469,119 @@ _DoubleExceptionVector_WindowOverflow: rotw -3 j 1b .end literal_prefix ENDPROC(_DoubleExceptionVector) /* * Fixup handler for TLB miss in double exception handler for window owerflow. * We get here with windowbase set to the window that was being spilled and * a0 trashed. a0 bit 7 determines if this is a call8 (bit clear) or call12 * (bit set) window. * * We do the following here: * - go to the original window retaining a0 value; * - set up exception stack to return back to appropriate a0 restore code * (we'll need to rotate window back and there's no place to save this * information, use different return address for that); * - handle the exception; * - go to the window that was being spilled; * - set up window_overflow_restore_a0_fixup as a fixup routine; * - reload a0; * - restore the original window; * - reset the default fixup routine; * - return to user. By the time we get to this fixup handler all information * about the conditions of the original double exception that happened in * the window overflow handler is lost, so we just return to userspace to * retry overflow from start. * * a0: value of depc, original value in depc * a2: trashed, original value in EXC_TABLE_DOUBLE_SAVE * a3: exctable, original value in excsave1 */ ENTRY(window_overflow_restore_a0_fixup) rsr a0, ps extui a0, a0, PS_OWB_SHIFT, PS_OWB_WIDTH rsr a2, windowbase sub a0, a2, a0 extui a0, a0, 0, 3 l32i a2, a3, EXC_TABLE_DOUBLE_SAVE xsr a3, excsave1 _beqi a0, 1, .Lhandle_1 _beqi a0, 3, .Lhandle_3 .macro overflow_fixup_handle_exception_pane n rsr a0, depc rotw -\n xsr a3, excsave1 wsr a2, depc l32i a2, a3, EXC_TABLE_KSTK s32i a0, a2, PT_AREG0 movi a0, .Lrestore_\n s32i a0, a2, PT_DEPC rsr a0, exccause j _DoubleExceptionVector_handle_exception .endm overflow_fixup_handle_exception_pane 2 .Lhandle_1: overflow_fixup_handle_exception_pane 1 .Lhandle_3: overflow_fixup_handle_exception_pane 3 .macro overflow_fixup_restore_a0_pane n rotw \n /* Need to preserve a0 value here to be able to handle exception * that may occur on a0 reload from stack. It may occur because * TLB miss handler may not be atomic and pointer to page table * may be lost before we get here. There are no free registers, * so we need to use EXC_TABLE_DOUBLE_SAVE area. */ xsr a3, excsave1 s32i a2, a3, EXC_TABLE_DOUBLE_SAVE movi a2, window_overflow_restore_a0_fixup s32i a2, a3, EXC_TABLE_FIXUP l32i a2, a3, EXC_TABLE_DOUBLE_SAVE xsr a3, excsave1 bbsi.l a0, 7, 1f l32e a0, a9, -16 j 2f 1: l32e a0, a13, -16 2: rotw -\n .endm .Lrestore_2: overflow_fixup_restore_a0_pane 2 .Lset_default_fixup: xsr a3, excsave1 s32i a2, a3, EXC_TABLE_DOUBLE_SAVE movi a2, 0 s32i a2, a3, EXC_TABLE_FIXUP l32i a2, a3, EXC_TABLE_DOUBLE_SAVE xsr a3, excsave1 rfe .Lrestore_1: overflow_fixup_restore_a0_pane 1 j .Lset_default_fixup .Lrestore_3: overflow_fixup_restore_a0_pane 3 j .Lset_default_fixup ENDPROC(window_overflow_restore_a0_fixup) .end literal_prefix /* * Debug interrupt vector * Loading
arch/xtensa/kernel/vmlinux.lds.S +2 −2 Original line number Diff line number Diff line Loading @@ -269,13 +269,13 @@ SECTIONS .UserExceptionVector.literal) SECTION_VECTOR (_DoubleExceptionVector_literal, .DoubleExceptionVector.literal, DOUBLEEXC_VECTOR_VADDR - 16, DOUBLEEXC_VECTOR_VADDR - 40, SIZEOF(.UserExceptionVector.text), .UserExceptionVector.text) SECTION_VECTOR (_DoubleExceptionVector_text, .DoubleExceptionVector.text, DOUBLEEXC_VECTOR_VADDR, 32, 40, .DoubleExceptionVector.literal) . = (LOADADDR( .DoubleExceptionVector.text ) + SIZEOF( .DoubleExceptionVector.text ) + 3) & ~ 3; Loading
arch/xtensa/mm/init.c +1 −1 Original line number Diff line number Diff line Loading @@ -191,7 +191,7 @@ int __init mem_reserve(unsigned long start, unsigned long end, int must_exist) return -EINVAL; } if (it && start - it->start < bank_sz) { if (it && start - it->start <= bank_sz) { if (start == it->start) { if (end - it->start < bank_sz) { it->start = end; Loading