0001
0002
0003
0004
0005
0006 #include <linux/magic.h>
0007 #include <asm/ppc_asm.h>
0008 #include <asm/asm-offsets.h>
0009 #include <asm/ftrace.h>
0010 #include <asm/ppc-opcode.h>
0011 #include <asm/export.h>
0012 #include <asm/thread_info.h>
0013 #include <asm/bug.h>
0014 #include <asm/ptrace.h>
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 .macro ftrace_regs_entry allregs
0036
0037 PPC_STLU r1,-SWITCH_FRAME_SIZE(r1)
0038
0039
0040 SAVE_GPR(0, r1)
0041 SAVE_GPRS(3, 10, r1)
0042
0043 #ifdef CONFIG_PPC64
0044
0045 std r0, LRSAVE+SWITCH_FRAME_SIZE(r1)
0046
0047 lbz r3, PACA_FTRACE_ENABLED(r13)
0048 cmpdi r3, 0
0049 beq ftrace_no_trace
0050 #endif
0051
0052 .if \allregs == 1
0053 SAVE_GPR(2, r1)
0054 SAVE_GPRS(11, 31, r1)
0055 .else
0056 #ifdef CONFIG_LIVEPATCH_64
0057 SAVE_GPR(14, r1)
0058 #endif
0059 .endif
0060
0061
0062 addi r8, r1, SWITCH_FRAME_SIZE
0063 PPC_STL r8, GPR1(r1)
0064
0065 .if \allregs == 1
0066
0067 mfmsr r8
0068 mfctr r9
0069 mfxer r10
0070 mfcr r11
0071 .else
0072
0073 li r8, 0
0074 .endif
0075
0076
0077 mflr r7
0078
0079 PPC_STL r7, _NIP(r1)
0080
0081 PPC_STL r0, _LINK(r1)
0082
0083 #ifdef CONFIG_PPC64
0084
0085 std r2, STK_GOT(r1)
0086 ld r2,PACATOC(r13)
0087
0088 addis r3,r2,function_trace_op@toc@ha
0089 addi r3,r3,function_trace_op@toc@l
0090 ld r5,0(r3)
0091 #else
0092 lis r3,function_trace_op@ha
0093 lwz r5,function_trace_op@l(r3)
0094 #endif
0095
0096 #ifdef CONFIG_LIVEPATCH_64
0097 mr r14, r7
0098 #endif
0099
0100
0101 subi r3, r7, MCOUNT_INSN_SIZE
0102
0103
0104 mr r4, r0
0105
0106
0107 PPC_STL r8, _MSR(r1)
0108 .if \allregs == 1
0109 PPC_STL r9, _CTR(r1)
0110 PPC_STL r10, _XER(r1)
0111 PPC_STL r11, _CCR(r1)
0112 .endif
0113
0114
0115 addi r6, r1, STACK_FRAME_OVERHEAD
0116 .endm
0117
0118 .macro ftrace_regs_exit allregs
0119
0120 PPC_LL r3, _NIP(r1)
0121 mtctr r3
0122
0123 #ifdef CONFIG_LIVEPATCH_64
0124 cmpd r14, r3
0125 #endif
0126
0127
0128 .if \allregs == 1
0129 REST_GPRS(2, 31, r1)
0130 .else
0131 REST_GPRS(3, 10, r1)
0132 #ifdef CONFIG_LIVEPATCH_64
0133 REST_GPR(14, r1)
0134 #endif
0135 .endif
0136
0137
0138 PPC_LL r0, _LINK(r1)
0139 mtlr r0
0140
0141 #ifdef CONFIG_PPC64
0142
0143 ld r2, STK_GOT(r1)
0144 #endif
0145
0146
0147 addi r1, r1, SWITCH_FRAME_SIZE
0148
0149 #ifdef CONFIG_LIVEPATCH_64
0150
0151 bne- livepatch_handler
0152 #endif
0153 bctr
0154 .endm
0155
0156 _GLOBAL(ftrace_regs_caller)
0157 ftrace_regs_entry 1
0158
0159 .globl ftrace_regs_call
0160 ftrace_regs_call:
0161 bl ftrace_stub
0162 nop
0163 ftrace_regs_exit 1
0164
0165 _GLOBAL(ftrace_caller)
0166 ftrace_regs_entry 0
0167
0168 .globl ftrace_call
0169 ftrace_call:
0170 bl ftrace_stub
0171 nop
0172 ftrace_regs_exit 0
0173
0174 _GLOBAL(ftrace_stub)
0175 blr
0176
0177 #ifdef CONFIG_PPC64
0178 ftrace_no_trace:
0179 mflr r3
0180 mtctr r3
0181 REST_GPR(3, r1)
0182 addi r1, r1, SWITCH_FRAME_SIZE
0183 mtlr r0
0184 bctr
0185 #endif
0186
0187 #ifdef CONFIG_LIVEPATCH_64
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202 livepatch_handler:
0203 ld r12, PACA_THREAD_INFO(r13)
0204
0205
0206 ld r11, TI_livepatch_sp(r12)
0207 addi r11, r11, 24
0208 std r11, TI_livepatch_sp(r12)
0209
0210
0211 std r2, -24(r11)
0212 mflr r12
0213 std r12, -16(r11)
0214
0215
0216 lis r12, STACK_END_MAGIC@h
0217 ori r12, r12, STACK_END_MAGIC@l
0218 std r12, -8(r11)
0219
0220
0221 mfctr r12
0222 bctrl
0223
0224
0225
0226
0227
0228
0229
0230 ld r12, PACA_THREAD_INFO(r13)
0231
0232 ld r11, TI_livepatch_sp(r12)
0233
0234
0235 lis r2, STACK_END_MAGIC@h
0236 ori r2, r2, STACK_END_MAGIC@l
0237 ld r12, -8(r11)
0238 1: tdne r12, r2
0239 EMIT_BUG_ENTRY 1b, __FILE__, __LINE__ - 1, 0
0240
0241
0242 ld r12, -16(r11)
0243 mtlr r12
0244 ld r2, -24(r11)
0245
0246
0247 ld r12, PACA_THREAD_INFO(r13)
0248 subi r11, r11, 24
0249 std r11, TI_livepatch_sp(r12)
0250
0251
0252 blr
0253 #endif