root/arch/riscv/kernel/tests/kprobes/test-kprobes-asm.S
/* SPDX-License-Identifier: GPL-2.0+ */

#include <linux/linkage.h>
#include <asm/asm.h>
#include "test-kprobes.h"

SYM_FUNC_START(test_kprobes_add)
        li a1, KPROBE_TEST_MAGIC_UPPER
        li a2, KPROBE_TEST_MAGIC_LOWER
test_kprobes_add_addr1:
        add a1, a1, a2
test_kprobes_add_addr2:
        add a0, a1, x0
        ret
SYM_FUNC_END(test_kprobes_add)

SYM_FUNC_START(test_kprobes_jal)
        li a0, 0
        mv a1, ra
        .option push
        .option norvc
test_kprobes_jal_addr1:
        jal x0, 2f
        ret
        .option pop
1:      li a0, KPROBE_TEST_MAGIC_UPPER
        ret
        .option push
        .option norvc
test_kprobes_jal_addr2:
2:      jal 1b
        .option pop
        li a2, KPROBE_TEST_MAGIC_LOWER
        add a0, a0, a2
        jr a1
SYM_FUNC_END(test_kprobes_jal)

SYM_FUNC_START(test_kprobes_jalr)
        la a0, 1f
        mv a1, ra
        .option push
        .option norvc
test_kprobes_jalr_addr:
        jalr a0
        .option pop
        li t0, KPROBE_TEST_MAGIC_UPPER
        add a0, a0, t0
        jr a1
1:      li a0, KPROBE_TEST_MAGIC_LOWER
        ret
SYM_FUNC_END(test_kprobes_jalr)

SYM_FUNC_START(test_kprobes_auipc)
test_kprobes_auipc_addr:
        auipc a0, KPROBE_TEST_MAGIC_LOWER
        la a1, test_kprobes_auipc_addr
        sub a0, a0, a1
        srli a0, a0, 12
        li a1, KPROBE_TEST_MAGIC_UPPER
        add a0, a0, a1
        ret
SYM_FUNC_END(test_kprobes_auipc)

SYM_FUNC_START(test_kprobes_branch)
        .option push
        .option norvc
        li a0, 0
        li a1, 1
        li a2, 2
test_kprobes_branch_addr1:
        beqz a0, 1f
        ret
1:
test_kprobes_branch_addr2:
        beqz a1, 3f
test_kprobes_branch_addr3:
        bnez a0, 3f
test_kprobes_branch_addr4:
        bnez a2, 1f
        ret
1:
test_kprobes_branch_addr5:
        bge a1, a2, 3f
test_kprobes_branch_addr6:
        bge a2, a1, 2f
        ret
1:
        li t0, KPROBE_TEST_MAGIC_UPPER
        add a0, a0, t0
        ret
2:
test_kprobes_branch_addr7:
        blt a2, a1, 3f
        li a0, KPROBE_TEST_MAGIC_LOWER
test_kprobes_branch_addr8:
        blt a1, a2, 1b
3:
        li a0, 0
        ret
        .option pop
SYM_FUNC_END(test_kprobes_branch)

#ifdef CONFIG_RISCV_ISA_C

SYM_FUNC_START(test_kprobes_c_j)
        li a0, 0
test_kprobes_branch_c_j_addr1:
        c.j 2f
1:
        li a1, KPROBE_TEST_MAGIC_UPPER
        add a0, a0, a1
        ret
2:      li a0, KPROBE_TEST_MAGIC_LOWER
test_kprobes_branch_c_j_addr2:
        c.j 1b
SYM_FUNC_END(test_kprobes_c_j)

SYM_FUNC_START(test_kprobes_c_jr)
        la a0, 2f
test_kprobes_c_jr_addr1:
        c.jr a0
        ret
1:      li a1, KPROBE_TEST_MAGIC_LOWER
        add a0, a0, a1
        ret
2:
        li a0, KPROBE_TEST_MAGIC_UPPER
        la a1, 1b
test_kprobes_c_jr_addr2:
        c.jr a1
SYM_FUNC_END(test_kprobes_c_jr)

SYM_FUNC_START(test_kprobes_c_jalr)
        mv a1, ra
        la a0, 1f
test_kprobes_c_jalr_addr:
        c.jalr a0
        li a2, KPROBE_TEST_MAGIC_UPPER
        add a0, a0, a2
        jr a1
1:      li a0, KPROBE_TEST_MAGIC_LOWER
        ret
SYM_FUNC_END(test_kprobes_c_jalr)

SYM_FUNC_START(test_kprobes_c_beqz)
        li a0, 0
        li a1, 1
test_kprobes_c_beqz_addr1:
        c.beqz a0, 2f
        ret
1:      li a1, KPROBE_TEST_MAGIC_UPPER
        add a0, a0, a1
        ret
test_kprobes_c_beqz_addr2:
2:      c.beqz a1, 3f
        li a0, KPROBE_TEST_MAGIC_LOWER
        mv a1, x0
test_kprobes_c_beqz_addr3:
        c.beqz a1, 1b
3:      li a0, 0
        ret
SYM_FUNC_END(test_kprobes_c_beqz)

SYM_FUNC_START(test_kprobes_c_bnez)
        li a0, 0
        li a1, 1
test_kprobes_c_bnez_addr1:
        c.bnez a1, 2f
        ret
1:      li a1, KPROBE_TEST_MAGIC_UPPER
        add a0, a0, a1
        ret
test_kprobes_c_bnez_addr2:
2:      c.bnez a0, 3f
        li a0, KPROBE_TEST_MAGIC_LOWER
test_kprobes_c_bnez_addr3:
        c.bnez a0, 1b
3:      li a0, 0
        ret
SYM_FUNC_END(test_kprobes_c_bnez)

#endif /* CONFIG_RISCV_ISA_C */

.section .rodata
SYM_DATA_START(test_kprobes_addresses)
        RISCV_PTR test_kprobes_add_addr1
        RISCV_PTR test_kprobes_add_addr2
        RISCV_PTR test_kprobes_jal_addr1
        RISCV_PTR test_kprobes_jal_addr2
        RISCV_PTR test_kprobes_jalr_addr
        RISCV_PTR test_kprobes_auipc_addr
        RISCV_PTR test_kprobes_branch_addr1
        RISCV_PTR test_kprobes_branch_addr2
        RISCV_PTR test_kprobes_branch_addr3
        RISCV_PTR test_kprobes_branch_addr4
        RISCV_PTR test_kprobes_branch_addr5
        RISCV_PTR test_kprobes_branch_addr6
        RISCV_PTR test_kprobes_branch_addr7
        RISCV_PTR test_kprobes_branch_addr8
#ifdef CONFIG_RISCV_ISA_C
        RISCV_PTR test_kprobes_branch_c_j_addr1
        RISCV_PTR test_kprobes_branch_c_j_addr2
        RISCV_PTR test_kprobes_c_jr_addr1
        RISCV_PTR test_kprobes_c_jr_addr2
        RISCV_PTR test_kprobes_c_jalr_addr
        RISCV_PTR test_kprobes_c_beqz_addr1
        RISCV_PTR test_kprobes_c_beqz_addr2
        RISCV_PTR test_kprobes_c_beqz_addr3
        RISCV_PTR test_kprobes_c_bnez_addr1
        RISCV_PTR test_kprobes_c_bnez_addr2
        RISCV_PTR test_kprobes_c_bnez_addr3
#endif /* CONFIG_RISCV_ISA_C */
        RISCV_PTR 0
SYM_DATA_END(test_kprobes_addresses)

.section .rodata
SYM_DATA_START(test_kprobes_functions)
        RISCV_PTR test_kprobes_add
        RISCV_PTR test_kprobes_jal
        RISCV_PTR test_kprobes_jalr
        RISCV_PTR test_kprobes_auipc
        RISCV_PTR test_kprobes_branch
#ifdef CONFIG_RISCV_ISA_C
        RISCV_PTR test_kprobes_c_j
        RISCV_PTR test_kprobes_c_jr
        RISCV_PTR test_kprobes_c_jalr
        RISCV_PTR test_kprobes_c_beqz
        RISCV_PTR test_kprobes_c_bnez
#endif /* CONFIG_RISCV_ISA_C */
        RISCV_PTR 0
SYM_DATA_END(test_kprobes_functions)