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