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