hc
2024-10-12 a5969cabbb4660eab42b6ef0412cbbd1200cf14d
kernel/arch/x86/include/asm/ptrace.h
....@@ -37,8 +37,10 @@
3737 unsigned short __esh;
3838 unsigned short fs;
3939 unsigned short __fsh;
40
+ /* On interrupt, gs and __gsh store the vector number. */
4041 unsigned short gs;
4142 unsigned short __gsh;
43
+ /* On interrupt, this is the error code. */
4244 unsigned long orig_ax;
4345 unsigned long ip;
4446 unsigned short cs;
....@@ -92,16 +94,16 @@
9294 #include <asm/paravirt_types.h>
9395 #endif
9496
97
+#include <asm/proto.h>
98
+
9599 struct cpuinfo_x86;
96100 struct task_struct;
97101
98102 extern unsigned long profile_pc(struct pt_regs *regs);
99
-#define profile_pc profile_pc
100103
101104 extern unsigned long
102105 convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs);
103
-extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
104
- int error_code, int si_code);
106
+extern void send_sigtrap(struct pt_regs *regs, int error_code, int si_code);
105107
106108
107109 static inline unsigned long regs_return_value(struct pt_regs *regs)
....@@ -123,7 +125,7 @@
123125 * On x86_64, vm86 mode is mercifully nonexistent, and we don't need
124126 * the extra check.
125127 */
126
-static inline int user_mode(struct pt_regs *regs)
128
+static __always_inline int user_mode(struct pt_regs *regs)
127129 {
128130 #ifdef CONFIG_X86_32
129131 return ((regs->cs & SEGMENT_RPL_MASK) | (regs->flags & X86_VM_MASK)) >= USER_RPL;
....@@ -144,7 +146,7 @@
144146 static inline bool user_64bit_mode(struct pt_regs *regs)
145147 {
146148 #ifdef CONFIG_X86_64
147
-#ifndef CONFIG_PARAVIRT
149
+#ifndef CONFIG_PARAVIRT_XXL
148150 /*
149151 * On non-paravirt systems, this is the only long mode CPL 3
150152 * selector. We do not allow long mode selectors in the LDT.
....@@ -159,25 +161,73 @@
159161 #endif
160162 }
161163
164
+/*
165
+ * Determine whether the register set came from any context that is running in
166
+ * 64-bit mode.
167
+ */
168
+static inline bool any_64bit_mode(struct pt_regs *regs)
169
+{
170
+#ifdef CONFIG_X86_64
171
+ return !user_mode(regs) || user_64bit_mode(regs);
172
+#else
173
+ return false;
174
+#endif
175
+}
176
+
162177 #ifdef CONFIG_X86_64
163178 #define current_user_stack_pointer() current_pt_regs()->sp
164179 #define compat_user_stack_pointer() current_pt_regs()->sp
180
+
181
+static inline bool ip_within_syscall_gap(struct pt_regs *regs)
182
+{
183
+ bool ret = (regs->ip >= (unsigned long)entry_SYSCALL_64 &&
184
+ regs->ip < (unsigned long)entry_SYSCALL_64_safe_stack);
185
+
186
+#ifdef CONFIG_IA32_EMULATION
187
+ ret = ret || (regs->ip >= (unsigned long)entry_SYSCALL_compat &&
188
+ regs->ip < (unsigned long)entry_SYSCALL_compat_safe_stack);
165189 #endif
166190
167
-#ifdef CONFIG_X86_32
168
-extern unsigned long kernel_stack_pointer(struct pt_regs *regs);
169
-#else
191
+ return ret;
192
+}
193
+#endif
194
+
170195 static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
171196 {
172197 return regs->sp;
173198 }
174
-#endif
175199
176
-#define GET_IP(regs) ((regs)->ip)
177
-#define GET_FP(regs) ((regs)->bp)
178
-#define GET_USP(regs) ((regs)->sp)
200
+static inline unsigned long instruction_pointer(struct pt_regs *regs)
201
+{
202
+ return regs->ip;
203
+}
179204
180
-#include <asm-generic/ptrace.h>
205
+static inline void instruction_pointer_set(struct pt_regs *regs,
206
+ unsigned long val)
207
+{
208
+ regs->ip = val;
209
+}
210
+
211
+static inline unsigned long frame_pointer(struct pt_regs *regs)
212
+{
213
+ return regs->bp;
214
+}
215
+
216
+static inline unsigned long user_stack_pointer(struct pt_regs *regs)
217
+{
218
+ return regs->sp;
219
+}
220
+
221
+static inline void user_stack_pointer_set(struct pt_regs *regs,
222
+ unsigned long val)
223
+{
224
+ regs->sp = val;
225
+}
226
+
227
+static __always_inline bool regs_irqs_disabled(struct pt_regs *regs)
228
+{
229
+ return !(regs->flags & X86_EFLAGS_IF);
230
+}
181231
182232 /* Query offset/name of register from its name/offset */
183233 extern int regs_query_register_offset(const char *name);
....@@ -199,14 +249,6 @@
199249 if (unlikely(offset > MAX_REG_OFFSET))
200250 return 0;
201251 #ifdef CONFIG_X86_32
202
- /*
203
- * Traps from the kernel do not save sp and ss.
204
- * Use the helper function to retrieve sp.
205
- */
206
- if (offset == offsetof(struct pt_regs, sp) &&
207
- regs->cs == __KERNEL_CS)
208
- return kernel_stack_pointer(regs);
209
-
210252 /* The selector fields are 16-bit. */
211253 if (offset == offsetof(struct pt_regs, cs) ||
212254 offset == offsetof(struct pt_regs, ss) ||
....@@ -232,8 +274,7 @@
232274 static inline int regs_within_kernel_stack(struct pt_regs *regs,
233275 unsigned long addr)
234276 {
235
- return ((addr & ~(THREAD_SIZE - 1)) ==
236
- (kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1)));
277
+ return ((addr & ~(THREAD_SIZE - 1)) == (regs->sp & ~(THREAD_SIZE - 1)));
237278 }
238279
239280 /**
....@@ -247,7 +288,7 @@
247288 */
248289 static inline unsigned long *regs_get_kernel_stack_nth_addr(struct pt_regs *regs, unsigned int n)
249290 {
250
- unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs);
291
+ unsigned long *addr = (unsigned long *)regs->sp;
251292
252293 addr += n;
253294 if (regs_within_kernel_stack(regs, (unsigned long)addr))
....@@ -257,7 +298,7 @@
257298 }
258299
259300 /* To avoid include hell, we can't include uaccess.h */
260
-extern long probe_kernel_read(void *dst, const void *src, size_t size);
301
+extern long copy_from_kernel_nofault(void *dst, const void *src, size_t size);
261302
262303 /**
263304 * regs_get_kernel_stack_nth() - get Nth entry of the stack
....@@ -277,11 +318,49 @@
277318
278319 addr = regs_get_kernel_stack_nth_addr(regs, n);
279320 if (addr) {
280
- ret = probe_kernel_read(&val, addr, sizeof(val));
321
+ ret = copy_from_kernel_nofault(&val, addr, sizeof(val));
281322 if (!ret)
282323 return val;
283324 }
284325 return 0;
326
+}
327
+
328
+/**
329
+ * regs_get_kernel_argument() - get Nth function argument in kernel
330
+ * @regs: pt_regs of that context
331
+ * @n: function argument number (start from 0)
332
+ *
333
+ * regs_get_argument() returns @n th argument of the function call.
334
+ * Note that this chooses most probably assignment, in some case
335
+ * it can be incorrect.
336
+ * This is expected to be called from kprobes or ftrace with regs
337
+ * where the top of stack is the return address.
338
+ */
339
+static inline unsigned long regs_get_kernel_argument(struct pt_regs *regs,
340
+ unsigned int n)
341
+{
342
+ static const unsigned int argument_offs[] = {
343
+#ifdef __i386__
344
+ offsetof(struct pt_regs, ax),
345
+ offsetof(struct pt_regs, dx),
346
+ offsetof(struct pt_regs, cx),
347
+#define NR_REG_ARGUMENTS 3
348
+#else
349
+ offsetof(struct pt_regs, di),
350
+ offsetof(struct pt_regs, si),
351
+ offsetof(struct pt_regs, dx),
352
+ offsetof(struct pt_regs, cx),
353
+ offsetof(struct pt_regs, r8),
354
+ offsetof(struct pt_regs, r9),
355
+#define NR_REG_ARGUMENTS 6
356
+#endif
357
+ };
358
+
359
+ if (n >= NR_REG_ARGUMENTS) {
360
+ n -= NR_REG_ARGUMENTS - 1;
361
+ return regs_get_kernel_stack_nth(regs, n);
362
+ } else
363
+ return regs_get_register(regs, argument_offs[n]);
285364 }
286365
287366 #define arch_has_single_step() (1)
....@@ -291,23 +370,7 @@
291370 #define arch_has_block_step() (boot_cpu_data.x86 >= 6)
292371 #endif
293372
294
-#define ARCH_HAS_USER_SINGLE_STEP_INFO
295
-
296
-/*
297
- * When hitting ptrace_stop(), we cannot return using SYSRET because
298
- * that does not restore the full CPU state, only a minimal set. The
299
- * ptracer can change arbitrary register values, which is usually okay
300
- * because the usual ptrace stops run off the signal delivery path which
301
- * forces IRET; however, ptrace_event() stops happen in arbitrary places
302
- * in the kernel and don't force IRET path.
303
- *
304
- * So force IRET path after a ptrace stop.
305
- */
306
-#define arch_ptrace_stop_needed(code, info) \
307
-({ \
308
- force_iret(); \
309
- false; \
310
-})
373
+#define ARCH_HAS_USER_SINGLE_STEP_REPORT
311374
312375 struct user_desc;
313376 extern int do_get_thread_area(struct task_struct *p, int idx,
....@@ -315,5 +378,11 @@
315378 extern int do_set_thread_area(struct task_struct *p, int idx,
316379 struct user_desc __user *info, int can_allocate);
317380
381
+#ifdef CONFIG_X86_64
382
+# define do_set_thread_area_64(p, s, t) do_arch_prctl_64(p, s, t)
383
+#else
384
+# define do_set_thread_area_64(p, s, t) (0)
385
+#endif
386
+
318387 #endif /* !__ASSEMBLY__ */
319388 #endif /* _ASM_X86_PTRACE_H */