hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/arch/powerpc/include/asm/ptrace.h
....@@ -1,3 +1,4 @@
1
+/* SPDX-License-Identifier: GPL-2.0-or-later */
12 /*
23 * Copyright (C) 2001 PPC64 Team, IBM Corp
34 *
....@@ -14,18 +15,56 @@
1415 *
1516 * Note that the offsets of the fields in this struct correspond with
1617 * the PT_* values below. This simplifies arch/powerpc/kernel/ptrace.c.
17
- *
18
- * This program is free software; you can redistribute it and/or
19
- * modify it under the terms of the GNU General Public License
20
- * as published by the Free Software Foundation; either version
21
- * 2 of the License, or (at your option) any later version.
2218 */
2319 #ifndef _ASM_POWERPC_PTRACE_H
2420 #define _ASM_POWERPC_PTRACE_H
2521
22
+#include <linux/err.h>
2623 #include <uapi/asm/ptrace.h>
2724 #include <asm/asm-const.h>
2825
26
+#ifndef __ASSEMBLY__
27
+struct pt_regs
28
+{
29
+ union {
30
+ struct user_pt_regs user_regs;
31
+ struct {
32
+ unsigned long gpr[32];
33
+ unsigned long nip;
34
+ unsigned long msr;
35
+ unsigned long orig_gpr3;
36
+ unsigned long ctr;
37
+ unsigned long link;
38
+ unsigned long xer;
39
+ unsigned long ccr;
40
+#ifdef CONFIG_PPC64
41
+ unsigned long softe;
42
+#else
43
+ unsigned long mq;
44
+#endif
45
+ unsigned long trap;
46
+ unsigned long dar;
47
+ unsigned long dsisr;
48
+ unsigned long result;
49
+ };
50
+ };
51
+
52
+ union {
53
+ struct {
54
+#ifdef CONFIG_PPC64
55
+ unsigned long ppr;
56
+#endif
57
+#ifdef CONFIG_PPC_KUAP
58
+ unsigned long kuap;
59
+#endif
60
+ };
61
+ unsigned long __pad[2]; /* Maintain 16 byte interrupt stack alignment */
62
+ };
63
+};
64
+#endif
65
+
66
+
67
+#define STACK_FRAME_WITH_PT_REGS (STACK_FRAME_OVERHEAD + sizeof(struct pt_regs))
2968
3069 #ifdef __powerpc64__
3170
....@@ -76,31 +115,35 @@
76115
77116 #ifndef __ASSEMBLY__
78117
79
-#define GET_IP(regs) ((regs)->nip)
80
-#define GET_USP(regs) ((regs)->gpr[1])
81
-#define GET_FP(regs) (0)
82
-#define SET_FP(regs, val)
118
+static inline unsigned long instruction_pointer(struct pt_regs *regs)
119
+{
120
+ return regs->nip;
121
+}
122
+
123
+static inline void instruction_pointer_set(struct pt_regs *regs,
124
+ unsigned long val)
125
+{
126
+ regs->nip = val;
127
+}
128
+
129
+static inline unsigned long user_stack_pointer(struct pt_regs *regs)
130
+{
131
+ return regs->gpr[1];
132
+}
133
+
134
+static inline unsigned long frame_pointer(struct pt_regs *regs)
135
+{
136
+ return 0;
137
+}
83138
84139 #ifdef CONFIG_SMP
85140 extern unsigned long profile_pc(struct pt_regs *regs);
86
-#define profile_pc profile_pc
141
+#else
142
+#define profile_pc(regs) instruction_pointer(regs)
87143 #endif
88144
89
-#include <asm-generic/ptrace.h>
90
-
91
-#define kernel_stack_pointer(regs) ((regs)->gpr[1])
92
-static inline int is_syscall_success(struct pt_regs *regs)
93
-{
94
- return !(regs->ccr & 0x10000000);
95
-}
96
-
97
-static inline long regs_return_value(struct pt_regs *regs)
98
-{
99
- if (is_syscall_success(regs))
100
- return regs->gpr[3];
101
- else
102
- return -regs->gpr[3];
103
-}
145
+long do_syscall_trace_enter(struct pt_regs *regs);
146
+void do_syscall_trace_leave(struct pt_regs *regs);
104147
105148 #ifdef __powerpc64__
106149 #define user_mode(regs) ((((regs)->msr) >> MSR_PR_LG) & 0x1)
....@@ -120,7 +163,23 @@
120163 unsigned long data);
121164
122165 #define current_pt_regs() \
123
- ((struct pt_regs *)((unsigned long)current_thread_info() + THREAD_SIZE) - 1)
166
+ ((struct pt_regs *)((unsigned long)task_stack_page(current) + THREAD_SIZE) - 1)
167
+
168
+#ifdef __powerpc64__
169
+#ifdef CONFIG_PPC_BOOK3S
170
+#define TRAP_FLAGS_MASK 0x10
171
+#define TRAP(regs) ((regs)->trap & ~TRAP_FLAGS_MASK)
172
+#define FULL_REGS(regs) true
173
+#define SET_FULL_REGS(regs) do { } while (0)
174
+#else
175
+#define TRAP_FLAGS_MASK 0x11
176
+#define TRAP(regs) ((regs)->trap & ~TRAP_FLAGS_MASK)
177
+#define FULL_REGS(regs) (((regs)->trap & 1) == 0)
178
+#define SET_FULL_REGS(regs) ((regs)->trap &= ~1)
179
+#endif
180
+#define CHECK_FULL_REGS(regs) BUG_ON(!FULL_REGS(regs))
181
+#define NV_REG_POISON 0xdeadbeefdeadbeefUL
182
+#else
124183 /*
125184 * We use the least-significant bit of the trap field to indicate
126185 * whether we have saved the full set of registers, or only a
....@@ -128,17 +187,13 @@
128187 * On 4xx we use the next bit to indicate whether the exception
129188 * is a critical exception (1 means it is).
130189 */
190
+#define TRAP_FLAGS_MASK 0x1F
191
+#define TRAP(regs) ((regs)->trap & ~TRAP_FLAGS_MASK)
131192 #define FULL_REGS(regs) (((regs)->trap & 1) == 0)
132
-#ifndef __powerpc64__
193
+#define SET_FULL_REGS(regs) ((regs)->trap &= ~1)
133194 #define IS_CRITICAL_EXC(regs) (((regs)->trap & 2) != 0)
134195 #define IS_MCHECK_EXC(regs) (((regs)->trap & 4) != 0)
135196 #define IS_DEBUG_EXC(regs) (((regs)->trap & 8) != 0)
136
-#endif /* ! __powerpc64__ */
137
-#define TRAP(regs) ((regs)->trap & ~0xF)
138
-#ifdef __powerpc64__
139
-#define NV_REG_POISON 0xdeadbeefdeadbeefUL
140
-#define CHECK_FULL_REGS(regs) BUG_ON(regs->trap & 1)
141
-#else
142197 #define NV_REG_POISON 0xdeadbeef
143198 #define CHECK_FULL_REGS(regs) \
144199 do { \
....@@ -147,9 +202,59 @@
147202 } while (0)
148203 #endif /* __powerpc64__ */
149204
205
+static inline void set_trap(struct pt_regs *regs, unsigned long val)
206
+{
207
+ regs->trap = (regs->trap & TRAP_FLAGS_MASK) | (val & ~TRAP_FLAGS_MASK);
208
+}
209
+
210
+static inline bool trap_is_scv(struct pt_regs *regs)
211
+{
212
+ return (IS_ENABLED(CONFIG_PPC_BOOK3S_64) && TRAP(regs) == 0x3000);
213
+}
214
+
215
+static inline bool trap_is_syscall(struct pt_regs *regs)
216
+{
217
+ return (trap_is_scv(regs) || TRAP(regs) == 0xc00);
218
+}
219
+
220
+static inline bool trap_norestart(struct pt_regs *regs)
221
+{
222
+ return regs->trap & 0x10;
223
+}
224
+
225
+static inline void set_trap_norestart(struct pt_regs *regs)
226
+{
227
+ regs->trap |= 0x10;
228
+}
229
+
230
+#define kernel_stack_pointer(regs) ((regs)->gpr[1])
231
+static inline int is_syscall_success(struct pt_regs *regs)
232
+{
233
+ if (trap_is_scv(regs))
234
+ return !IS_ERR_VALUE((unsigned long)regs->gpr[3]);
235
+ else
236
+ return !(regs->ccr & 0x10000000);
237
+}
238
+
239
+static inline long regs_return_value(struct pt_regs *regs)
240
+{
241
+ if (trap_is_scv(regs))
242
+ return regs->gpr[3];
243
+
244
+ if (is_syscall_success(regs))
245
+ return regs->gpr[3];
246
+ else
247
+ return -regs->gpr[3];
248
+}
249
+
250
+static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc)
251
+{
252
+ regs->gpr[3] = rc;
253
+}
254
+
150255 #define arch_has_single_step() (1)
151
-#define arch_has_block_step() (!cpu_has_feature(CPU_FTR_601))
152
-#define ARCH_HAS_USER_SINGLE_STEP_INFO
256
+#define arch_has_block_step() (true)
257
+#define ARCH_HAS_USER_SINGLE_STEP_REPORT
153258
154259 /*
155260 * kprobe-based event tracer support
....@@ -217,6 +322,8 @@
217322 #endif /* __ASSEMBLY__ */
218323
219324 #ifndef __powerpc64__
325
+/* We need PT_SOFTE defined at all time to avoid #ifdefs */
326
+#define PT_SOFTE PT_MQ
220327 #else /* __powerpc64__ */
221328 #define PT_FPSCR32 (PT_FPR0 + 2*32 + 1) /* each FP reg occupies 2 32-bit userspace slots */
222329 #define PT_VR0_32 164 /* each Vector reg occupies 4 slots in 32-bit */