Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 /*
0003  * Code to prepare detour buffer for optprobes in Kernel.
0004  *
0005  * Copyright 2017, Anju T, IBM Corp.
0006  */
0007 
0008 #include <asm/ppc_asm.h>
0009 #include <asm/ptrace.h>
0010 #include <asm/asm-offsets.h>
0011 
0012 #ifdef CONFIG_PPC64
0013 #define SAVE_30GPRS(base) SAVE_GPRS(2, 31, base)
0014 #define REST_30GPRS(base) REST_GPRS(2, 31, base)
0015 #define TEMPLATE_FOR_IMM_LOAD_INSNS nop; nop; nop; nop; nop
0016 #else
0017 #define SAVE_30GPRS(base) stmw  r2, GPR2(base)
0018 #define REST_30GPRS(base) lmw   r2, GPR2(base)
0019 #define TEMPLATE_FOR_IMM_LOAD_INSNS nop; nop; nop
0020 #endif
0021 
0022 #define OPT_SLOT_SIZE   65536
0023 
0024     .balign 4
0025 
0026     /*
0027      * Reserve an area to allocate slots for detour buffer.
0028      * This is part of .text section (rather than vmalloc area)
0029      * as this needs to be within 32MB of the probed address.
0030      */
0031     .global optinsn_slot
0032 optinsn_slot:
0033     .space  OPT_SLOT_SIZE
0034 
0035     /*
0036      * Optprobe template:
0037      * This template gets copied into one of the slots in optinsn_slot
0038      * and gets fixed up with real optprobe structures et al.
0039      */
0040     .global optprobe_template_entry
0041 optprobe_template_entry:
0042     /* Create an in-memory pt_regs */
0043     PPC_STLU    r1,-INT_FRAME_SIZE(r1)
0044     SAVE_GPR(0,r1)
0045     /* Save the previous SP into stack */
0046     addi    r0,r1,INT_FRAME_SIZE
0047     PPC_STL r0,GPR1(r1)
0048     SAVE_30GPRS(r1)
0049     /* Save SPRS */
0050     mfmsr   r5
0051     PPC_STL r5,_MSR(r1)
0052     li  r5,0x700
0053     PPC_STL r5,_TRAP(r1)
0054     li  r5,0
0055     PPC_STL r5,ORIG_GPR3(r1)
0056     PPC_STL r5,RESULT(r1)
0057     mfctr   r5
0058     PPC_STL r5,_CTR(r1)
0059     mflr    r5
0060     PPC_STL r5,_LINK(r1)
0061     mfspr   r5,SPRN_XER
0062     PPC_STL r5,_XER(r1)
0063     mfcr    r5
0064     PPC_STL r5,_CCR(r1)
0065 #ifdef CONFIG_PPC64
0066     lbz     r5,PACAIRQSOFTMASK(r13)
0067     std     r5,SOFTE(r1)
0068 #endif
0069 
0070     /*
0071      * We may get here from a module, so load the kernel TOC in r2.
0072      * The original TOC gets restored when pt_regs is restored
0073      * further below.
0074      */
0075 #ifdef CONFIG_PPC64
0076     ld  r2,PACATOC(r13)
0077 #endif
0078 
0079     .global optprobe_template_op_address
0080 optprobe_template_op_address:
0081     /*
0082      * Parameters to optimized_callback():
0083      * 1. optimized_kprobe structure in r3
0084      */
0085     TEMPLATE_FOR_IMM_LOAD_INSNS
0086 
0087     /* 2. pt_regs pointer in r4 */
0088     addi    r4,r1,STACK_FRAME_OVERHEAD
0089 
0090     .global optprobe_template_call_handler
0091 optprobe_template_call_handler:
0092     /* Branch to optimized_callback() */
0093     nop
0094 
0095     /*
0096      * Parameters for instruction emulation:
0097      * 1. Pass SP in register r3.
0098      */
0099     addi    r3,r1,STACK_FRAME_OVERHEAD
0100 
0101     .global optprobe_template_insn
0102 optprobe_template_insn:
0103     /* 2, Pass instruction to be emulated in r4 */
0104     TEMPLATE_FOR_IMM_LOAD_INSNS
0105 
0106     .global optprobe_template_call_emulate
0107 optprobe_template_call_emulate:
0108     /* Branch to emulate_step()  */
0109     nop
0110 
0111     /*
0112      * All done.
0113      * Now, restore the registers...
0114      */
0115     PPC_LL  r5,_MSR(r1)
0116     mtmsr   r5
0117     PPC_LL  r5,_CTR(r1)
0118     mtctr   r5
0119     PPC_LL  r5,_LINK(r1)
0120     mtlr    r5
0121     PPC_LL  r5,_XER(r1)
0122     mtxer   r5
0123     PPC_LL  r5,_CCR(r1)
0124     mtcr    r5
0125     REST_GPR(0,r1)
0126     REST_30GPRS(r1)
0127     /* Restore the previous SP */
0128     addi    r1,r1,INT_FRAME_SIZE
0129 
0130     .global optprobe_template_ret
0131 optprobe_template_ret:
0132     /* ... and jump back from trampoline */
0133     nop
0134 
0135     .global optprobe_template_end
0136 optprobe_template_end: