root/arch/loongarch/kernel/rethook_trampoline.S
/* SPDX-License-Identifier: GPL-2.0+ */
#include <linux/linkage.h>
#include <asm/stackframe.h>

        .text

        .macro save_all_base_regs
        cfi_st  ra, PT_R1
        cfi_st  tp, PT_R2
        cfi_st  a0, PT_R4
        cfi_st  a1, PT_R5
        cfi_st  a2, PT_R6
        cfi_st  a3, PT_R7
        cfi_st  a4, PT_R8
        cfi_st  a5, PT_R9
        cfi_st  a6, PT_R10
        cfi_st  a7, PT_R11
        cfi_st  t0, PT_R12
        cfi_st  t1, PT_R13
        cfi_st  t2, PT_R14
        cfi_st  t3, PT_R15
        cfi_st  t4, PT_R16
        cfi_st  t5, PT_R17
        cfi_st  t6, PT_R18
        cfi_st  t7, PT_R19
        cfi_st  t8, PT_R20
        cfi_st  u0, PT_R21
        cfi_st  fp, PT_R22
        cfi_st  s0, PT_R23
        cfi_st  s1, PT_R24
        cfi_st  s2, PT_R25
        cfi_st  s3, PT_R26
        cfi_st  s4, PT_R27
        cfi_st  s5, PT_R28
        cfi_st  s6, PT_R29
        cfi_st  s7, PT_R30
        cfi_st  s8, PT_R31
        csrrd   t0, LOONGARCH_CSR_CRMD
        andi    t0, t0, 0x7 /* extract bit[1:0] PLV, bit[2] IE */
        LONG_S  t0, sp, PT_CRMD
        .endm

        .macro restore_all_base_regs
        cfi_ld  tp, PT_R2
        cfi_ld  a0, PT_R4
        cfi_ld  a1, PT_R5
        cfi_ld  a2, PT_R6
        cfi_ld  a3, PT_R7
        cfi_ld  a4, PT_R8
        cfi_ld  a5, PT_R9
        cfi_ld  a6, PT_R10
        cfi_ld  a7, PT_R11
        cfi_ld  t0, PT_R12
        cfi_ld  t1, PT_R13
        cfi_ld  t2, PT_R14
        cfi_ld  t3, PT_R15
        cfi_ld  t4, PT_R16
        cfi_ld  t5, PT_R17
        cfi_ld  t6, PT_R18
        cfi_ld  t7, PT_R19
        cfi_ld  t8, PT_R20
        cfi_ld  u0, PT_R21
        cfi_ld  fp, PT_R22
        cfi_ld  s0, PT_R23
        cfi_ld  s1, PT_R24
        cfi_ld  s2, PT_R25
        cfi_ld  s3, PT_R26
        cfi_ld  s4, PT_R27
        cfi_ld  s5, PT_R28
        cfi_ld  s6, PT_R29
        cfi_ld  s7, PT_R30
        cfi_ld  s8, PT_R31
        LONG_L  t0, sp, PT_CRMD
        li.d    t1, 0x7 /* mask bit[1:0] PLV, bit[2] IE */
        csrxchg t0, t1, LOONGARCH_CSR_CRMD
        .endm

SYM_CODE_START(arch_rethook_trampoline)
        UNWIND_HINT_UNDEFINED
        addi.d  sp, sp, -PT_SIZE
        save_all_base_regs

        addi.d  t0, sp, PT_SIZE
        LONG_S  t0, sp, PT_R3

        move a0, sp /* pt_regs */

        bl arch_rethook_trampoline_callback

        /* use the result as the return-address */
        move ra, a0

        restore_all_base_regs
        addi.d  sp, sp, PT_SIZE

        jr ra
SYM_CODE_END(arch_rethook_trampoline)