/* * Code to prepare detour buffer for optprobes in Kernel. * * Copyright 2017, Anju T, IBM Corp. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ #include #include #include #define OPT_SLOT_SIZE 65536 .balign 4 /* * Reserve an area to allocate slots for detour buffer. * This is part of .text section (rather than vmalloc area) * as this needs to be within 32MB of the probed address. */ .global optinsn_slot optinsn_slot: .space OPT_SLOT_SIZE /* * Optprobe template: * This template gets copied into one of the slots in optinsn_slot * and gets fixed up with real optprobe structures et al. */ .global optprobe_template_entry optprobe_template_entry: /* Create an in-memory pt_regs */ stdu r1,-INT_FRAME_SIZE(r1) SAVE_GPR(0,r1) /* Save the previous SP into stack */ addi r0,r1,INT_FRAME_SIZE std r0,GPR1(r1) SAVE_10GPRS(2,r1) SAVE_10GPRS(12,r1) SAVE_10GPRS(22,r1) /* Save SPRS */ mfmsr r5 std r5,_MSR(r1) li r5,0x700 std r5,_TRAP(r1) li r5,0 std r5,ORIG_GPR3(r1) std r5,RESULT(r1) mfctr r5 std r5,_CTR(r1) mflr r5 std r5,_LINK(r1) mfspr r5,SPRN_XER std r5,_XER(r1) mfcr r5 std r5,_CCR(r1) lbz r5,PACAIRQSOFTMASK(r13) std r5,SOFTE(r1) /* * We may get here from a module, so load the kernel TOC in r2. * The original TOC gets restored when pt_regs is restored * further below. */ ld r2,PACATOC(r13) .global optprobe_template_op_address optprobe_template_op_address: /* * Parameters to optimized_callback(): * 1. optimized_kprobe structure in r3 */ nop nop nop nop nop /* 2. pt_regs pointer in r4 */ addi r4,r1,STACK_FRAME_OVERHEAD .global optprobe_template_call_handler optprobe_template_call_handler: /* Branch to optimized_callback() */ nop /* * Parameters for instruction emulation: * 1. Pass SP in register r3. */ addi r3,r1,STACK_FRAME_OVERHEAD .global optprobe_template_insn optprobe_template_insn: /* 2, Pass instruction to be emulated in r4 */ nop nop .global optprobe_template_call_emulate optprobe_template_call_emulate: /* Branch to emulate_step() */ nop /* * All done. * Now, restore the registers... */ ld r5,_MSR(r1) mtmsr r5 ld r5,_CTR(r1) mtctr r5 ld r5,_LINK(r1) mtlr r5 ld r5,_XER(r1) mtxer r5 ld r5,_CCR(r1) mtcr r5 REST_GPR(0,r1) REST_10GPRS(2,r1) REST_10GPRS(12,r1) REST_10GPRS(22,r1) /* Restore the previous SP */ addi r1,r1,INT_FRAME_SIZE .global optprobe_template_ret optprobe_template_ret: /* ... and jump back from trampoline */ nop .global optprobe_template_end optprobe_template_end: