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