1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef _ASM_X86_PTRACE_H |
3 | #define _ASM_X86_PTRACE_H |
4 | |
5 | #include <asm/segment.h> |
6 | #include <asm/page_types.h> |
7 | #include <uapi/asm/ptrace.h> |
8 | |
9 | #ifndef __ASSEMBLY__ |
10 | #ifdef __i386__ |
11 | |
12 | struct pt_regs { |
13 | /* |
14 | * NB: 32-bit x86 CPUs are inconsistent as what happens in the |
15 | * following cases (where %seg represents a segment register): |
16 | * |
17 | * - pushl %seg: some do a 16-bit write and leave the high |
18 | * bits alone |
19 | * - movl %seg, [mem]: some do a 16-bit write despite the movl |
20 | * - IDT entry: some (e.g. 486) will leave the high bits of CS |
21 | * and (if applicable) SS undefined. |
22 | * |
23 | * Fortunately, x86-32 doesn't read the high bits on POP or IRET, |
24 | * so we can just treat all of the segment registers as 16-bit |
25 | * values. |
26 | */ |
27 | unsigned long bx; |
28 | unsigned long cx; |
29 | unsigned long dx; |
30 | unsigned long si; |
31 | unsigned long di; |
32 | unsigned long bp; |
33 | unsigned long ax; |
34 | unsigned short ds; |
35 | unsigned short __dsh; |
36 | unsigned short es; |
37 | unsigned short __esh; |
38 | unsigned short fs; |
39 | unsigned short __fsh; |
40 | /* |
41 | * On interrupt, gs and __gsh store the vector number. They never |
42 | * store gs any more. |
43 | */ |
44 | unsigned short gs; |
45 | unsigned short __gsh; |
46 | /* On interrupt, this is the error code. */ |
47 | unsigned long orig_ax; |
48 | unsigned long ip; |
49 | unsigned short cs; |
50 | unsigned short __csh; |
51 | unsigned long flags; |
52 | unsigned long sp; |
53 | unsigned short ss; |
54 | unsigned short __ssh; |
55 | }; |
56 | |
57 | #else /* __i386__ */ |
58 | |
59 | struct fred_cs { |
60 | /* CS selector */ |
61 | u64 cs : 16, |
62 | /* Stack level at event time */ |
63 | sl : 2, |
64 | /* IBT in WAIT_FOR_ENDBRANCH state */ |
65 | wfe : 1, |
66 | : 45; |
67 | }; |
68 | |
69 | struct fred_ss { |
70 | /* SS selector */ |
71 | u64 ss : 16, |
72 | /* STI state */ |
73 | sti : 1, |
74 | /* Set if syscall, sysenter or INT n */ |
75 | swevent : 1, |
76 | /* Event is NMI type */ |
77 | nmi : 1, |
78 | : 13, |
79 | /* Event vector */ |
80 | vector : 8, |
81 | : 8, |
82 | /* Event type */ |
83 | type : 4, |
84 | : 4, |
85 | /* Event was incident to enclave execution */ |
86 | enclave : 1, |
87 | /* CPU was in long mode */ |
88 | lm : 1, |
89 | /* |
90 | * Nested exception during FRED delivery, not set |
91 | * for #DF. |
92 | */ |
93 | nested : 1, |
94 | : 1, |
95 | /* |
96 | * The length of the instruction causing the event. |
97 | * Only set for INTO, INT1, INT3, INT n, SYSCALL |
98 | * and SYSENTER. 0 otherwise. |
99 | */ |
100 | insnlen : 4; |
101 | }; |
102 | |
103 | struct pt_regs { |
104 | /* |
105 | * C ABI says these regs are callee-preserved. They aren't saved on |
106 | * kernel entry unless syscall needs a complete, fully filled |
107 | * "struct pt_regs". |
108 | */ |
109 | unsigned long r15; |
110 | unsigned long r14; |
111 | unsigned long r13; |
112 | unsigned long r12; |
113 | unsigned long bp; |
114 | unsigned long bx; |
115 | |
116 | /* These regs are callee-clobbered. Always saved on kernel entry. */ |
117 | unsigned long r11; |
118 | unsigned long r10; |
119 | unsigned long r9; |
120 | unsigned long r8; |
121 | unsigned long ax; |
122 | unsigned long cx; |
123 | unsigned long dx; |
124 | unsigned long si; |
125 | unsigned long di; |
126 | |
127 | /* |
128 | * orig_ax is used on entry for: |
129 | * - the syscall number (syscall, sysenter, int80) |
130 | * - error_code stored by the CPU on traps and exceptions |
131 | * - the interrupt number for device interrupts |
132 | * |
133 | * A FRED stack frame starts here: |
134 | * 1) It _always_ includes an error code; |
135 | * |
136 | * 2) The return frame for ERET[US] starts here, but |
137 | * the content of orig_ax is ignored. |
138 | */ |
139 | unsigned long orig_ax; |
140 | |
141 | /* The IRETQ return frame starts here */ |
142 | unsigned long ip; |
143 | |
144 | union { |
145 | /* CS selector */ |
146 | u16 cs; |
147 | /* The extended 64-bit data slot containing CS */ |
148 | u64 csx; |
149 | /* The FRED CS extension */ |
150 | struct fred_cs fred_cs; |
151 | }; |
152 | |
153 | unsigned long flags; |
154 | unsigned long sp; |
155 | |
156 | union { |
157 | /* SS selector */ |
158 | u16 ss; |
159 | /* The extended 64-bit data slot containing SS */ |
160 | u64 ssx; |
161 | /* The FRED SS extension */ |
162 | struct fred_ss fred_ss; |
163 | }; |
164 | |
165 | /* |
166 | * Top of stack on IDT systems, while FRED systems have extra fields |
167 | * defined above for storing exception related information, e.g. CR2 or |
168 | * DR6. |
169 | */ |
170 | }; |
171 | |
172 | #endif /* !__i386__ */ |
173 | |
174 | #ifdef CONFIG_PARAVIRT |
175 | #include <asm/paravirt_types.h> |
176 | #endif |
177 | |
178 | #include <asm/proto.h> |
179 | |
180 | struct cpuinfo_x86; |
181 | struct task_struct; |
182 | |
183 | extern unsigned long profile_pc(struct pt_regs *regs); |
184 | |
185 | extern unsigned long |
186 | convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs); |
187 | extern void send_sigtrap(struct pt_regs *regs, int error_code, int si_code); |
188 | |
189 | |
190 | static inline unsigned long regs_return_value(struct pt_regs *regs) |
191 | { |
192 | return regs->ax; |
193 | } |
194 | |
195 | static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc) |
196 | { |
197 | regs->ax = rc; |
198 | } |
199 | |
200 | /* |
201 | * user_mode(regs) determines whether a register set came from user |
202 | * mode. On x86_32, this is true if V8086 mode was enabled OR if the |
203 | * register set was from protected mode with RPL-3 CS value. This |
204 | * tricky test checks that with one comparison. |
205 | * |
206 | * On x86_64, vm86 mode is mercifully nonexistent, and we don't need |
207 | * the extra check. |
208 | */ |
209 | static __always_inline int user_mode(struct pt_regs *regs) |
210 | { |
211 | #ifdef CONFIG_X86_32 |
212 | return ((regs->cs & SEGMENT_RPL_MASK) | (regs->flags & X86_VM_MASK)) >= USER_RPL; |
213 | #else |
214 | return !!(regs->cs & 3); |
215 | #endif |
216 | } |
217 | |
218 | static __always_inline int v8086_mode(struct pt_regs *regs) |
219 | { |
220 | #ifdef CONFIG_X86_32 |
221 | return (regs->flags & X86_VM_MASK); |
222 | #else |
223 | return 0; /* No V86 mode support in long mode */ |
224 | #endif |
225 | } |
226 | |
227 | static inline bool user_64bit_mode(struct pt_regs *regs) |
228 | { |
229 | #ifdef CONFIG_X86_64 |
230 | #ifndef CONFIG_PARAVIRT_XXL |
231 | /* |
232 | * On non-paravirt systems, this is the only long mode CPL 3 |
233 | * selector. We do not allow long mode selectors in the LDT. |
234 | */ |
235 | return regs->cs == __USER_CS; |
236 | #else |
237 | /* Headers are too twisted for this to go in paravirt.h. */ |
238 | return regs->cs == __USER_CS || regs->cs == pv_info.extra_user_64bit_cs; |
239 | #endif |
240 | #else /* !CONFIG_X86_64 */ |
241 | return false; |
242 | #endif |
243 | } |
244 | |
245 | /* |
246 | * Determine whether the register set came from any context that is running in |
247 | * 64-bit mode. |
248 | */ |
249 | static inline bool any_64bit_mode(struct pt_regs *regs) |
250 | { |
251 | #ifdef CONFIG_X86_64 |
252 | return !user_mode(regs) || user_64bit_mode(regs); |
253 | #else |
254 | return false; |
255 | #endif |
256 | } |
257 | |
258 | #ifdef CONFIG_X86_64 |
259 | #define current_user_stack_pointer() current_pt_regs()->sp |
260 | #define compat_user_stack_pointer() current_pt_regs()->sp |
261 | |
262 | static __always_inline bool ip_within_syscall_gap(struct pt_regs *regs) |
263 | { |
264 | bool ret = (regs->ip >= (unsigned long)entry_SYSCALL_64 && |
265 | regs->ip < (unsigned long)entry_SYSCALL_64_safe_stack); |
266 | |
267 | ret = ret || (regs->ip >= (unsigned long)entry_SYSRETQ_unsafe_stack && |
268 | regs->ip < (unsigned long)entry_SYSRETQ_end); |
269 | #ifdef CONFIG_IA32_EMULATION |
270 | ret = ret || (regs->ip >= (unsigned long)entry_SYSCALL_compat && |
271 | regs->ip < (unsigned long)entry_SYSCALL_compat_safe_stack); |
272 | ret = ret || (regs->ip >= (unsigned long)entry_SYSRETL_compat_unsafe_stack && |
273 | regs->ip < (unsigned long)entry_SYSRETL_compat_end); |
274 | #endif |
275 | |
276 | return ret; |
277 | } |
278 | #endif |
279 | |
280 | static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) |
281 | { |
282 | return regs->sp; |
283 | } |
284 | |
285 | static inline unsigned long instruction_pointer(struct pt_regs *regs) |
286 | { |
287 | return regs->ip; |
288 | } |
289 | |
290 | static inline void instruction_pointer_set(struct pt_regs *regs, |
291 | unsigned long val) |
292 | { |
293 | regs->ip = val; |
294 | } |
295 | |
296 | static inline unsigned long frame_pointer(struct pt_regs *regs) |
297 | { |
298 | return regs->bp; |
299 | } |
300 | |
301 | static inline unsigned long user_stack_pointer(struct pt_regs *regs) |
302 | { |
303 | return regs->sp; |
304 | } |
305 | |
306 | static inline void user_stack_pointer_set(struct pt_regs *regs, |
307 | unsigned long val) |
308 | { |
309 | regs->sp = val; |
310 | } |
311 | |
312 | static __always_inline bool regs_irqs_disabled(struct pt_regs *regs) |
313 | { |
314 | return !(regs->flags & X86_EFLAGS_IF); |
315 | } |
316 | |
317 | /* Query offset/name of register from its name/offset */ |
318 | extern int regs_query_register_offset(const char *name); |
319 | extern const char *regs_query_register_name(unsigned int offset); |
320 | #define MAX_REG_OFFSET (offsetof(struct pt_regs, ss)) |
321 | |
322 | /** |
323 | * regs_get_register() - get register value from its offset |
324 | * @regs: pt_regs from which register value is gotten. |
325 | * @offset: offset number of the register. |
326 | * |
327 | * regs_get_register returns the value of a register. The @offset is the |
328 | * offset of the register in struct pt_regs address which specified by @regs. |
329 | * If @offset is bigger than MAX_REG_OFFSET, this returns 0. |
330 | */ |
331 | static inline unsigned long regs_get_register(struct pt_regs *regs, |
332 | unsigned int offset) |
333 | { |
334 | if (unlikely(offset > MAX_REG_OFFSET)) |
335 | return 0; |
336 | #ifdef CONFIG_X86_32 |
337 | /* The selector fields are 16-bit. */ |
338 | if (offset == offsetof(struct pt_regs, cs) || |
339 | offset == offsetof(struct pt_regs, ss) || |
340 | offset == offsetof(struct pt_regs, ds) || |
341 | offset == offsetof(struct pt_regs, es) || |
342 | offset == offsetof(struct pt_regs, fs) || |
343 | offset == offsetof(struct pt_regs, gs)) { |
344 | return *(u16 *)((unsigned long)regs + offset); |
345 | |
346 | } |
347 | #endif |
348 | return *(unsigned long *)((unsigned long)regs + offset); |
349 | } |
350 | |
351 | /** |
352 | * regs_within_kernel_stack() - check the address in the stack |
353 | * @regs: pt_regs which contains kernel stack pointer. |
354 | * @addr: address which is checked. |
355 | * |
356 | * regs_within_kernel_stack() checks @addr is within the kernel stack page(s). |
357 | * If @addr is within the kernel stack, it returns true. If not, returns false. |
358 | */ |
359 | static inline int regs_within_kernel_stack(struct pt_regs *regs, |
360 | unsigned long addr) |
361 | { |
362 | return ((addr & ~(THREAD_SIZE - 1)) == (regs->sp & ~(THREAD_SIZE - 1))); |
363 | } |
364 | |
365 | /** |
366 | * regs_get_kernel_stack_nth_addr() - get the address of the Nth entry on stack |
367 | * @regs: pt_regs which contains kernel stack pointer. |
368 | * @n: stack entry number. |
369 | * |
370 | * regs_get_kernel_stack_nth() returns the address of the @n th entry of the |
371 | * kernel stack which is specified by @regs. If the @n th entry is NOT in |
372 | * the kernel stack, this returns NULL. |
373 | */ |
374 | static inline unsigned long *regs_get_kernel_stack_nth_addr(struct pt_regs *regs, unsigned int n) |
375 | { |
376 | unsigned long *addr = (unsigned long *)regs->sp; |
377 | |
378 | addr += n; |
379 | if (regs_within_kernel_stack(regs, addr: (unsigned long)addr)) |
380 | return addr; |
381 | else |
382 | return NULL; |
383 | } |
384 | |
385 | /* To avoid include hell, we can't include uaccess.h */ |
386 | extern long copy_from_kernel_nofault(void *dst, const void *src, size_t size); |
387 | |
388 | /** |
389 | * regs_get_kernel_stack_nth() - get Nth entry of the stack |
390 | * @regs: pt_regs which contains kernel stack pointer. |
391 | * @n: stack entry number. |
392 | * |
393 | * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which |
394 | * is specified by @regs. If the @n th entry is NOT in the kernel stack |
395 | * this returns 0. |
396 | */ |
397 | static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, |
398 | unsigned int n) |
399 | { |
400 | unsigned long *addr; |
401 | unsigned long val; |
402 | long ret; |
403 | |
404 | addr = regs_get_kernel_stack_nth_addr(regs, n); |
405 | if (addr) { |
406 | ret = copy_from_kernel_nofault(dst: &val, src: addr, size: sizeof(val)); |
407 | if (!ret) |
408 | return val; |
409 | } |
410 | return 0; |
411 | } |
412 | |
413 | /** |
414 | * regs_get_kernel_argument() - get Nth function argument in kernel |
415 | * @regs: pt_regs of that context |
416 | * @n: function argument number (start from 0) |
417 | * |
418 | * regs_get_argument() returns @n th argument of the function call. |
419 | * Note that this chooses most probably assignment, in some case |
420 | * it can be incorrect. |
421 | * This is expected to be called from kprobes or ftrace with regs |
422 | * where the top of stack is the return address. |
423 | */ |
424 | static inline unsigned long regs_get_kernel_argument(struct pt_regs *regs, |
425 | unsigned int n) |
426 | { |
427 | static const unsigned int argument_offs[] = { |
428 | #ifdef __i386__ |
429 | offsetof(struct pt_regs, ax), |
430 | offsetof(struct pt_regs, dx), |
431 | offsetof(struct pt_regs, cx), |
432 | #define NR_REG_ARGUMENTS 3 |
433 | #else |
434 | offsetof(struct pt_regs, di), |
435 | offsetof(struct pt_regs, si), |
436 | offsetof(struct pt_regs, dx), |
437 | offsetof(struct pt_regs, cx), |
438 | offsetof(struct pt_regs, r8), |
439 | offsetof(struct pt_regs, r9), |
440 | #define NR_REG_ARGUMENTS 6 |
441 | #endif |
442 | }; |
443 | |
444 | if (n >= NR_REG_ARGUMENTS) { |
445 | n -= NR_REG_ARGUMENTS - 1; |
446 | return regs_get_kernel_stack_nth(regs, n); |
447 | } else |
448 | return regs_get_register(regs, offset: argument_offs[n]); |
449 | } |
450 | |
451 | #define arch_has_single_step() (1) |
452 | #ifdef CONFIG_X86_DEBUGCTLMSR |
453 | #define arch_has_block_step() (1) |
454 | #else |
455 | #define arch_has_block_step() (boot_cpu_data.x86 >= 6) |
456 | #endif |
457 | |
458 | #define ARCH_HAS_USER_SINGLE_STEP_REPORT |
459 | |
460 | struct user_desc; |
461 | extern int do_get_thread_area(struct task_struct *p, int idx, |
462 | struct user_desc __user *info); |
463 | extern int do_set_thread_area(struct task_struct *p, int idx, |
464 | struct user_desc __user *info, int can_allocate); |
465 | |
466 | #ifdef CONFIG_X86_64 |
467 | # define do_set_thread_area_64(p, s, t) do_arch_prctl_64(p, s, t) |
468 | #else |
469 | # define do_set_thread_area_64(p, s, t) (0) |
470 | #endif |
471 | |
472 | #endif /* !__ASSEMBLY__ */ |
473 | #endif /* _ASM_X86_PTRACE_H */ |
474 | |