^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0-or-later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Code to prepare detour buffer for optprobes in Kernel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright 2017, Anju T, IBM Corp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <asm/ppc_asm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <asm/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <asm/asm-offsets.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #define OPT_SLOT_SIZE 65536
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) .balign 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * Reserve an area to allocate slots for detour buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * This is part of .text section (rather than vmalloc area)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * as this needs to be within 32MB of the probed address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) .global optinsn_slot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) optinsn_slot:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) .space OPT_SLOT_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * Optprobe template:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * This template gets copied into one of the slots in optinsn_slot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * and gets fixed up with real optprobe structures et al.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) .global optprobe_template_entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) optprobe_template_entry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) /* Create an in-memory pt_regs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) stdu r1,-INT_FRAME_SIZE(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) SAVE_GPR(0,r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /* Save the previous SP into stack */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) addi r0,r1,INT_FRAME_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) std r0,GPR1(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) SAVE_10GPRS(2,r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) SAVE_10GPRS(12,r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) SAVE_10GPRS(22,r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /* Save SPRS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) mfmsr r5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) std r5,_MSR(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) li r5,0x700
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) std r5,_TRAP(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) li r5,0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) std r5,ORIG_GPR3(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) std r5,RESULT(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) mfctr r5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) std r5,_CTR(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) mflr r5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) std r5,_LINK(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) mfspr r5,SPRN_XER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) std r5,_XER(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) mfcr r5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) std r5,_CCR(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) lbz r5,PACAIRQSOFTMASK(r13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) std r5,SOFTE(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * We may get here from a module, so load the kernel TOC in r2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * The original TOC gets restored when pt_regs is restored
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * further below.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) ld r2,PACATOC(r13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) .global optprobe_template_op_address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) optprobe_template_op_address:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * Parameters to optimized_callback():
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * 1. optimized_kprobe structure in r3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /* 2. pt_regs pointer in r4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) addi r4,r1,STACK_FRAME_OVERHEAD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) .global optprobe_template_call_handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) optprobe_template_call_handler:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /* Branch to optimized_callback() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * Parameters for instruction emulation:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * 1. Pass SP in register r3.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) addi r3,r1,STACK_FRAME_OVERHEAD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) .global optprobe_template_insn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) optprobe_template_insn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /* 2, Pass instruction to be emulated in r4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) .global optprobe_template_call_emulate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) optprobe_template_call_emulate:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) /* Branch to emulate_step() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * All done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * Now, restore the registers...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) ld r5,_MSR(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) mtmsr r5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) ld r5,_CTR(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) mtctr r5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) ld r5,_LINK(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) mtlr r5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) ld r5,_XER(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) mtxer r5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) ld r5,_CCR(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) mtcr r5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) REST_GPR(0,r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) REST_10GPRS(2,r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) REST_10GPRS(12,r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) REST_10GPRS(22,r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /* Restore the previous SP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) addi r1,r1,INT_FRAME_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) .global optprobe_template_ret
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) optprobe_template_ret:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) /* ... and jump back from trampoline */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) .global optprobe_template_end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) optprobe_template_end: