Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / arch / powerpc / kernel / optprobes_head.S
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
22 optinsn_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
31 optprobe_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
68 optprobe_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
82 optprobe_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
93 optprobe_template_insn:
94         /* 2, Pass instruction to be emulated in r4 */
95         nop
96         nop
97
98         .global optprobe_template_call_emulate
99 optprobe_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
125 optprobe_template_ret:
126         /* ... and jump back from trampoline */
127         nop
128
129         .global optprobe_template_end
130 optprobe_template_end: