Merge tag 'sched-urgent-2020-12-27' of git://git.kernel.org/pub/scm/linux/kernel...
[linux/fpc-iii.git] / arch / powerpc / kernel / optprobes_head.S
blobff8ba4d3824d52a2a23e556a076662f4208e52db
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  */
8 #include <asm/ppc_asm.h>
9 #include <asm/ptrace.h>
10 #include <asm/asm-offsets.h>
12 #define OPT_SLOT_SIZE   65536
14         .balign 4
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
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)
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)
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
81         .global optprobe_template_call_handler
82 optprobe_template_call_handler:
83         /* Branch to optimized_callback() */
84         nop
86         /*
87          * Parameters for instruction emulation:
88          * 1. Pass SP in register r3.
89          */
90         addi    r3,r1,STACK_FRAME_OVERHEAD
92         .global optprobe_template_insn
93 optprobe_template_insn:
94         /* 2, Pass instruction to be emulated in r4 */
95         nop
96         nop
97         nop
98         nop
99         nop
101         .global optprobe_template_call_emulate
102 optprobe_template_call_emulate:
103         /* Branch to emulate_step()  */
104         nop
106         /*
107          * All done.
108          * Now, restore the registers...
109          */
110         ld      r5,_MSR(r1)
111         mtmsr   r5
112         ld      r5,_CTR(r1)
113         mtctr   r5
114         ld      r5,_LINK(r1)
115         mtlr    r5
116         ld      r5,_XER(r1)
117         mtxer   r5
118         ld      r5,_CCR(r1)
119         mtcr    r5
120         REST_GPR(0,r1)
121         REST_10GPRS(2,r1)
122         REST_10GPRS(12,r1)
123         REST_10GPRS(22,r1)
124         /* Restore the previous SP */
125         addi    r1,r1,INT_FRAME_SIZE
127         .global optprobe_template_ret
128 optprobe_template_ret:
129         /* ... and jump back from trampoline */
130         nop
132         .global optprobe_template_end
133 optprobe_template_end: