To implement the context tracker properly on arm64,
a function call needs to be made after debugging and
interrupts are turned on, but before the lr is changed
to point to ret_from_exception(). If the function call
is made after the lr is changed the function will not
return to the correct place.

For similar reasons, defer the setting of x0 so that
it doesn't need to be saved around the function call
(save far_el1 in x26 temporarily instead).

Signed-off-by: Larry Bassel <larry.bas...@linaro.org>
Reviewed-by: Kevin Hilman <khil...@linaro.org>
---
 arch/arm64/kernel/entry.S | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 39ac630..d920d7f 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -349,11 +349,11 @@ el0_sync:
        lsr     x24, x25, #ESR_EL1_EC_SHIFT     // exception class
        cmp     x24, #ESR_EL1_EC_SVC64          // SVC in 64-bit state
        b.eq    el0_svc
-       adr     lr, ret_from_exception
        cmp     x24, #ESR_EL1_EC_DABT_EL0       // data abort in EL0
        b.eq    el0_da
        cmp     x24, #ESR_EL1_EC_IABT_EL0       // instruction abort in EL0
        b.eq    el0_ia
+       adr     lr, ret_from_exception
        cmp     x24, #ESR_EL1_EC_FP_ASIMD       // FP/ASIMD access
        b.eq    el0_fpsimd_acc
        cmp     x24, #ESR_EL1_EC_FP_EXC64       // FP/ASIMD exception
@@ -378,11 +378,11 @@ el0_sync_compat:
        lsr     x24, x25, #ESR_EL1_EC_SHIFT     // exception class
        cmp     x24, #ESR_EL1_EC_SVC32          // SVC in 32-bit state
        b.eq    el0_svc_compat
-       adr     lr, ret_from_exception
        cmp     x24, #ESR_EL1_EC_DABT_EL0       // data abort in EL0
        b.eq    el0_da
        cmp     x24, #ESR_EL1_EC_IABT_EL0       // instruction abort in EL0
        b.eq    el0_ia
+       adr     lr, ret_from_exception
        cmp     x24, #ESR_EL1_EC_FP_ASIMD       // FP/ASIMD access
        b.eq    el0_fpsimd_acc
        cmp     x24, #ESR_EL1_EC_FP_EXC32       // FP/ASIMD exception
@@ -421,28 +421,32 @@ el0_da:
        /*
         * Data abort handling
         */
-       mrs     x0, far_el1
-       bic     x0, x0, #(0xff << 56)
+       mrs     x26, far_el1
        disable_step x1
        isb
        enable_dbg
        // enable interrupts before calling the main handler
        enable_irq
+       mov     x0, x26
+       bic     x0, x0, #(0xff << 56)
        mov     x1, x25
        mov     x2, sp
+       adr     lr, ret_from_exception
        b       do_mem_abort
 el0_ia:
        /*
         * Instruction abort handling
         */
-       mrs     x0, far_el1
+       mrs     x26, far_el1
        disable_step x1
        isb
        enable_dbg
        // enable interrupts before calling the main handler
        enable_irq
+       mov     x0, x26
        orr     x1, x25, #1 << 24               // use reserved ISS bit for 
instruction aborts
        mov     x2, sp
+       adr     lr, ret_from_exception
        b       do_mem_abort
 el0_fpsimd_acc:
        /*
-- 
1.8.3.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to