Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec
[sfrench/cifs-2.6.git] / arch / powerpc / kernel / optprobes_head.S
1 /*
2  * Code to prepare detour buffer for optprobes in Kernel.
3  *
4  * Copyright 2017, Anju T, IBM Corp.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version
9  * 2 of the License, or (at your option) any later version.
10  */
11
12 #include <asm/ppc_asm.h>
13 #include <asm/ptrace.h>
14 #include <asm/asm-offsets.h>
15
16 #define OPT_SLOT_SIZE   65536
17
18         .balign 4
19
20         /*
21          * Reserve an area to allocate slots for detour buffer.
22          * This is part of .text section (rather than vmalloc area)
23          * as this needs to be within 32MB of the probed address.
24          */
25         .global optinsn_slot
26 optinsn_slot:
27         .space  OPT_SLOT_SIZE
28
29         /*
30          * Optprobe template:
31          * This template gets copied into one of the slots in optinsn_slot
32          * and gets fixed up with real optprobe structures et al.
33          */
34         .global optprobe_template_entry
35 optprobe_template_entry:
36         /* Create an in-memory pt_regs */
37         stdu    r1,-INT_FRAME_SIZE(r1)
38         SAVE_GPR(0,r1)
39         /* Save the previous SP into stack */
40         addi    r0,r1,INT_FRAME_SIZE
41         std     r0,GPR1(r1)
42         SAVE_10GPRS(2,r1)
43         SAVE_10GPRS(12,r1)
44         SAVE_10GPRS(22,r1)
45         /* Save SPRS */
46         mfmsr   r5
47         std     r5,_MSR(r1)
48         li      r5,0x700
49         std     r5,_TRAP(r1)
50         li      r5,0
51         std     r5,ORIG_GPR3(r1)
52         std     r5,RESULT(r1)
53         mfctr   r5
54         std     r5,_CTR(r1)
55         mflr    r5
56         std     r5,_LINK(r1)
57         mfspr   r5,SPRN_XER
58         std     r5,_XER(r1)
59         mfcr    r5
60         std     r5,_CCR(r1)
61         lbz     r5,PACAIRQSOFTMASK(r13)
62         std     r5,SOFTE(r1)
63
64         /*
65          * We may get here from a module, so load the kernel TOC in r2.
66          * The original TOC gets restored when pt_regs is restored
67          * further below.
68          */
69         ld      r2,PACATOC(r13)
70
71         .global optprobe_template_op_address
72 optprobe_template_op_address:
73         /*
74          * Parameters to optimized_callback():
75          * 1. optimized_kprobe structure in r3
76          */
77         nop
78         nop
79         nop
80         nop
81         nop
82         /* 2. pt_regs pointer in r4 */
83         addi    r4,r1,STACK_FRAME_OVERHEAD
84
85         .global optprobe_template_call_handler
86 optprobe_template_call_handler:
87         /* Branch to optimized_callback() */
88         nop
89
90         /*
91          * Parameters for instruction emulation:
92          * 1. Pass SP in register r3.
93          */
94         addi    r3,r1,STACK_FRAME_OVERHEAD
95
96         .global optprobe_template_insn
97 optprobe_template_insn:
98         /* 2, Pass instruction to be emulated in r4 */
99         nop
100         nop
101
102         .global optprobe_template_call_emulate
103 optprobe_template_call_emulate:
104         /* Branch to emulate_step()  */
105         nop
106
107         /*
108          * All done.
109          * Now, restore the registers...
110          */
111         ld      r5,_MSR(r1)
112         mtmsr   r5
113         ld      r5,_CTR(r1)
114         mtctr   r5
115         ld      r5,_LINK(r1)
116         mtlr    r5
117         ld      r5,_XER(r1)
118         mtxer   r5
119         ld      r5,_CCR(r1)
120         mtcr    r5
121         REST_GPR(0,r1)
122         REST_10GPRS(2,r1)
123         REST_10GPRS(12,r1)
124         REST_10GPRS(22,r1)
125         /* Restore the previous SP */
126         addi    r1,r1,INT_FRAME_SIZE
127
128         .global optprobe_template_ret
129 optprobe_template_ret:
130         /* ... and jump back from trampoline */
131         nop
132
133         .global optprobe_template_end
134 optprobe_template_end: