OSDN Git Service

FROMLIST: arm64: entry: Hook up entry trampoline to exception vectors
authorWill Deacon <will.deacon@arm.com>
Tue, 14 Nov 2017 14:24:29 +0000 (14:24 +0000)
committerGreg Kroah-Hartman <gregkh@google.com>
Sat, 6 Jan 2018 10:14:01 +0000 (11:14 +0100)
Hook up the entry trampoline to our exception vectors so that all
exceptions from and returns to EL0 go via the trampoline, which swizzles
the vector base register accordingly. Transitioning to and from the
kernel clobbers x30, so we use tpidrro_el0 and far_el1 as scratch
registers for native tasks.

Reviewed-by: Mark Rutland <mark.rutland@arm.com>
Tested-by: Laura Abbott <labbott@redhat.com>
Tested-by: Shanker Donthineni <shankerd@codeaurora.org>
Signed-off-by: Will Deacon <will.deacon@arm.com>
(cherry picked from git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git
 commit 4bf3286d29f3a88425d8d8cd53428cbb8f865f04)

Change-Id: Id1e175bdaa0ec2bf8e59f941502183907902a710
[ghackmann@google.com: adjust context, replacing
 alternative_if_not ARM64_WORKAROUND_845719 block with upstream version]
Signed-off-by: Greg Hackmann <ghackmann@google.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
arch/arm64/kernel/entry.S

index 7d178ff..bf52151 100644 (file)
 
        .macro kernel_ventry, el, label, regsize = 64
        .align 7
+#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
+       .if     \el == 0
+       .if     \regsize == 64
+       mrs     x30, tpidrro_el0
+       msr     tpidrro_el0, xzr
+       .else
+       mov     x30, xzr
+       .endif
+       .endif
+#endif
+
        sub     sp, sp, #S_FRAME_SIZE
        b       el\()\el\()_\label
        .endm
 
+       .macro tramp_alias, dst, sym
+       mov_q   \dst, TRAMP_VALIAS
+       add     \dst, \dst, #(\sym - .entry.tramp.text)
+       .endm
+
        .macro  kernel_entry, el, regsize = 64
        .if     \regsize == 32
        mov     w0, w0                          // zero upper 32 bits of x0
@@ -235,24 +251,20 @@ alternative_else_nop_endif
        .if     \el == 0
        ldr     x23, [sp, #S_SP]                // load return stack pointer
        msr     sp_el0, x23
+       tst     x22, #PSR_MODE32_BIT            // native task?
+       b.eq    3f
+
 #ifdef CONFIG_ARM64_ERRATUM_845719
-alternative_if_not ARM64_WORKAROUND_845719
-       nop
-       nop
-#ifdef CONFIG_PID_IN_CONTEXTIDR
-       nop
-#endif
-alternative_else
-       tbz     x22, #4, 1f
+alternative_if ARM64_WORKAROUND_845719
 #ifdef CONFIG_PID_IN_CONTEXTIDR
        mrs     x29, contextidr_el1
        msr     contextidr_el1, x29
 #else
        msr contextidr_el1, xzr
 #endif
-1:
-alternative_endif
+alternative_else_nop_endif
 #endif
+3:
        .endif
 
        msr     elr_el1, x21                    // set up the return data
@@ -274,7 +286,22 @@ alternative_endif
        ldp     x28, x29, [sp, #16 * 14]
        ldr     lr, [sp, #S_LR]
        add     sp, sp, #S_FRAME_SIZE           // restore sp
-       eret                                    // return to kernel
+
+#ifndef CONFIG_UNMAP_KERNEL_AT_EL0
+       eret
+#else
+       .if     \el == 0
+       bne     4f
+       msr     far_el1, x30
+       tramp_alias     x30, tramp_exit_native
+       br      x30
+4:
+       tramp_alias     x30, tramp_exit_compat
+       br      x30
+       .else
+       eret
+       .endif
+#endif
        .endm
 
        .macro  irq_stack_entry