Loading...
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#ifdef CONFIG_PPC64
13#define SAVE_30GPRS(base) SAVE_GPRS(2, 31, base)
14#define REST_30GPRS(base) REST_GPRS(2, 31, base)
15#define TEMPLATE_FOR_IMM_LOAD_INSNS nop; nop; nop; nop; nop
16#else
17#define SAVE_30GPRS(base) stmw r2, GPR2(base)
18#define REST_30GPRS(base) lmw r2, GPR2(base)
19#define TEMPLATE_FOR_IMM_LOAD_INSNS nop; nop; nop
20#endif
21
22#define OPT_SLOT_SIZE 65536
23
24 .balign 4
25
26 /*
27 * Reserve an area to allocate slots for detour buffer.
28 * This is part of .text section (rather than vmalloc area)
29 * as this needs to be within 32MB of the probed address.
30 */
31 .global optinsn_slot
32optinsn_slot:
33 .space OPT_SLOT_SIZE
34
35 /*
36 * Optprobe template:
37 * This template gets copied into one of the slots in optinsn_slot
38 * and gets fixed up with real optprobe structures et al.
39 */
40 .global optprobe_template_entry
41optprobe_template_entry:
42 /* Create an in-memory pt_regs */
43 PPC_STLU r1,-INT_FRAME_SIZE(r1)
44 SAVE_GPR(0,r1)
45 /* Save the previous SP into stack */
46 addi r0,r1,INT_FRAME_SIZE
47 PPC_STL r0,GPR1(r1)
48 SAVE_30GPRS(r1)
49 /* Save SPRS */
50 mfmsr r5
51 PPC_STL r5,_MSR(r1)
52 li r5,0x700
53 PPC_STL r5,_TRAP(r1)
54 li r5,0
55 PPC_STL r5,ORIG_GPR3(r1)
56 PPC_STL r5,RESULT(r1)
57 mfctr r5
58 PPC_STL r5,_CTR(r1)
59 mflr r5
60 PPC_STL r5,_LINK(r1)
61 mfspr r5,SPRN_XER
62 PPC_STL r5,_XER(r1)
63 mfcr r5
64 PPC_STL r5,_CCR(r1)
65#ifdef CONFIG_PPC64
66 lbz r5,PACAIRQSOFTMASK(r13)
67 std r5,SOFTE(r1)
68#endif
69
70 /*
71 * We may get here from a module, so load the kernel TOC in r2.
72 * The original TOC gets restored when pt_regs is restored
73 * further below.
74 */
75#ifdef CONFIG_PPC64
76 LOAD_PACA_TOC()
77#endif
78
79 .global optprobe_template_op_address
80optprobe_template_op_address:
81 /*
82 * Parameters to optimized_callback():
83 * 1. optimized_kprobe structure in r3
84 */
85 TEMPLATE_FOR_IMM_LOAD_INSNS
86
87 /* 2. pt_regs pointer in r4 */
88 addi r4,r1,STACK_INT_FRAME_REGS
89
90 .global optprobe_template_call_handler
91optprobe_template_call_handler:
92 /* Branch to optimized_callback() */
93 nop
94
95 /*
96 * Parameters for instruction emulation:
97 * 1. Pass SP in register r3.
98 */
99 addi r3,r1,STACK_INT_FRAME_REGS
100
101 .global optprobe_template_insn
102optprobe_template_insn:
103 /* 2, Pass instruction to be emulated in r4 */
104 TEMPLATE_FOR_IMM_LOAD_INSNS
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 PPC_LL r5,_MSR(r1)
116 mtmsr r5
117 PPC_LL r5,_CTR(r1)
118 mtctr r5
119 PPC_LL r5,_LINK(r1)
120 mtlr r5
121 PPC_LL r5,_XER(r1)
122 mtxer r5
123 PPC_LL r5,_CCR(r1)
124 mtcr r5
125 REST_GPR(0,r1)
126 REST_30GPRS(r1)
127 /* Restore the previous SP */
128 addi r1,r1,INT_FRAME_SIZE
129
130 .global optprobe_template_ret
131optprobe_template_ret:
132 /* ... and jump back from trampoline */
133 nop
134
135 .global optprobe_template_end
136optprobe_template_end:
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: