Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*
3 * Copyright (C) 2001 PPC64 Team, IBM Corp
4 *
5 * This struct defines the way the registers are stored on the
6 * kernel stack during a system call or other kernel entry.
7 *
8 * this should only contain volatile regs
9 * since we can keep non-volatile in the thread_struct
10 * should set this up when only volatiles are saved
11 * by intr code.
12 *
13 * Since this is going on the stack, *CARE MUST BE TAKEN* to insure
14 * that the overall structure is a multiple of 16 bytes in length.
15 *
16 * Note that the offsets of the fields in this struct correspond with
17 * the PT_* values below. This simplifies arch/powerpc/kernel/ptrace.c.
18 */
19#ifndef _ASM_POWERPC_PTRACE_H
20#define _ASM_POWERPC_PTRACE_H
21
22#include <uapi/asm/ptrace.h>
23#include <asm/asm-const.h>
24
25#ifndef __ASSEMBLY__
26struct pt_regs
27{
28 union {
29 struct user_pt_regs user_regs;
30 struct {
31 unsigned long gpr[32];
32 unsigned long nip;
33 unsigned long msr;
34 unsigned long orig_gpr3;
35 unsigned long ctr;
36 unsigned long link;
37 unsigned long xer;
38 unsigned long ccr;
39#ifdef CONFIG_PPC64
40 unsigned long softe;
41#else
42 unsigned long mq;
43#endif
44 unsigned long trap;
45 unsigned long dar;
46 unsigned long dsisr;
47 unsigned long result;
48 };
49 };
50
51 union {
52 struct {
53#ifdef CONFIG_PPC64
54 unsigned long ppr;
55#endif
56#ifdef CONFIG_PPC_KUAP
57 unsigned long kuap;
58#endif
59 };
60 unsigned long __pad[2]; /* Maintain 16 byte interrupt stack alignment */
61 };
62};
63#endif
64
65#ifdef __powerpc64__
66
67/*
68 * Size of redzone that userspace is allowed to use below the stack
69 * pointer. This is 288 in the 64-bit big-endian ELF ABI, and 512 in
70 * the new ELFv2 little-endian ABI, so we allow the larger amount.
71 *
72 * For kernel code we allow a 288-byte redzone, in order to conserve
73 * kernel stack space; gcc currently only uses 288 bytes, and will
74 * hopefully allow explicit control of the redzone size in future.
75 */
76#define USER_REDZONE_SIZE 512
77#define KERNEL_REDZONE_SIZE 288
78
79#define STACK_FRAME_OVERHEAD 112 /* size of minimum stack frame */
80#define STACK_FRAME_LR_SAVE 2 /* Location of LR in stack frame */
81#define STACK_FRAME_REGS_MARKER ASM_CONST(0x7265677368657265)
82#define STACK_INT_FRAME_SIZE (sizeof(struct pt_regs) + \
83 STACK_FRAME_OVERHEAD + KERNEL_REDZONE_SIZE)
84#define STACK_FRAME_MARKER 12
85
86#ifdef PPC64_ELF_ABI_v2
87#define STACK_FRAME_MIN_SIZE 32
88#else
89#define STACK_FRAME_MIN_SIZE STACK_FRAME_OVERHEAD
90#endif
91
92/* Size of dummy stack frame allocated when calling signal handler. */
93#define __SIGNAL_FRAMESIZE 128
94#define __SIGNAL_FRAMESIZE32 64
95
96#else /* __powerpc64__ */
97
98#define USER_REDZONE_SIZE 0
99#define KERNEL_REDZONE_SIZE 0
100#define STACK_FRAME_OVERHEAD 16 /* size of minimum stack frame */
101#define STACK_FRAME_LR_SAVE 1 /* Location of LR in stack frame */
102#define STACK_FRAME_REGS_MARKER ASM_CONST(0x72656773)
103#define STACK_INT_FRAME_SIZE (sizeof(struct pt_regs) + STACK_FRAME_OVERHEAD)
104#define STACK_FRAME_MARKER 2
105#define STACK_FRAME_MIN_SIZE STACK_FRAME_OVERHEAD
106
107/* Size of stack frame allocated when calling signal handler. */
108#define __SIGNAL_FRAMESIZE 64
109
110#endif /* __powerpc64__ */
111
112#ifndef __ASSEMBLY__
113
114static inline unsigned long instruction_pointer(struct pt_regs *regs)
115{
116 return regs->nip;
117}
118
119static inline void instruction_pointer_set(struct pt_regs *regs,
120 unsigned long val)
121{
122 regs->nip = val;
123}
124
125static inline unsigned long user_stack_pointer(struct pt_regs *regs)
126{
127 return regs->gpr[1];
128}
129
130static inline unsigned long frame_pointer(struct pt_regs *regs)
131{
132 return 0;
133}
134
135#ifdef CONFIG_SMP
136extern unsigned long profile_pc(struct pt_regs *regs);
137#else
138#define profile_pc(regs) instruction_pointer(regs)
139#endif
140
141long do_syscall_trace_enter(struct pt_regs *regs);
142void do_syscall_trace_leave(struct pt_regs *regs);
143
144#define kernel_stack_pointer(regs) ((regs)->gpr[1])
145static inline int is_syscall_success(struct pt_regs *regs)
146{
147 return !(regs->ccr & 0x10000000);
148}
149
150static inline long regs_return_value(struct pt_regs *regs)
151{
152 if (is_syscall_success(regs))
153 return regs->gpr[3];
154 else
155 return -regs->gpr[3];
156}
157
158static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc)
159{
160 regs->gpr[3] = rc;
161}
162
163#ifdef __powerpc64__
164#define user_mode(regs) ((((regs)->msr) >> MSR_PR_LG) & 0x1)
165#else
166#define user_mode(regs) (((regs)->msr & MSR_PR) != 0)
167#endif
168
169#define force_successful_syscall_return() \
170 do { \
171 set_thread_flag(TIF_NOERROR); \
172 } while(0)
173
174struct task_struct;
175extern int ptrace_get_reg(struct task_struct *task, int regno,
176 unsigned long *data);
177extern int ptrace_put_reg(struct task_struct *task, int regno,
178 unsigned long data);
179
180#define current_pt_regs() \
181 ((struct pt_regs *)((unsigned long)task_stack_page(current) + THREAD_SIZE) - 1)
182
183#ifdef __powerpc64__
184#ifdef CONFIG_PPC_BOOK3S
185#define TRAP_FLAGS_MASK 0x10
186#define TRAP(regs) ((regs)->trap & ~TRAP_FLAGS_MASK)
187#define FULL_REGS(regs) true
188#define SET_FULL_REGS(regs) do { } while (0)
189#else
190#define TRAP_FLAGS_MASK 0x11
191#define TRAP(regs) ((regs)->trap & ~TRAP_FLAGS_MASK)
192#define FULL_REGS(regs) (((regs)->trap & 1) == 0)
193#define SET_FULL_REGS(regs) ((regs)->trap |= 1)
194#endif
195#define CHECK_FULL_REGS(regs) BUG_ON(!FULL_REGS(regs))
196#define NV_REG_POISON 0xdeadbeefdeadbeefUL
197#else
198/*
199 * We use the least-significant bit of the trap field to indicate
200 * whether we have saved the full set of registers, or only a
201 * partial set. A 1 there means the partial set.
202 * On 4xx we use the next bit to indicate whether the exception
203 * is a critical exception (1 means it is).
204 */
205#define TRAP_FLAGS_MASK 0x1F
206#define TRAP(regs) ((regs)->trap & ~TRAP_FLAGS_MASK)
207#define FULL_REGS(regs) (((regs)->trap & 1) == 0)
208#define SET_FULL_REGS(regs) ((regs)->trap |= 1)
209#define IS_CRITICAL_EXC(regs) (((regs)->trap & 2) != 0)
210#define IS_MCHECK_EXC(regs) (((regs)->trap & 4) != 0)
211#define IS_DEBUG_EXC(regs) (((regs)->trap & 8) != 0)
212#define NV_REG_POISON 0xdeadbeef
213#define CHECK_FULL_REGS(regs) \
214do { \
215 if ((regs)->trap & 1) \
216 printk(KERN_CRIT "%s: partial register set\n", __func__); \
217} while (0)
218#endif /* __powerpc64__ */
219
220static inline void set_trap(struct pt_regs *regs, unsigned long val)
221{
222 regs->trap = (regs->trap & TRAP_FLAGS_MASK) | (val & ~TRAP_FLAGS_MASK);
223}
224
225static inline bool trap_is_syscall(struct pt_regs *regs)
226{
227 return TRAP(regs) == 0xc00;
228}
229
230static inline bool trap_norestart(struct pt_regs *regs)
231{
232 return regs->trap & 0x10;
233}
234
235static inline void set_trap_norestart(struct pt_regs *regs)
236{
237 regs->trap |= 0x10;
238}
239
240#define arch_has_single_step() (1)
241#ifndef CONFIG_BOOK3S_601
242#define arch_has_block_step() (true)
243#else
244#define arch_has_block_step() (false)
245#endif
246#define ARCH_HAS_USER_SINGLE_STEP_REPORT
247
248/*
249 * kprobe-based event tracer support
250 */
251
252#include <linux/stddef.h>
253#include <linux/thread_info.h>
254extern int regs_query_register_offset(const char *name);
255extern const char *regs_query_register_name(unsigned int offset);
256#define MAX_REG_OFFSET (offsetof(struct pt_regs, dsisr))
257
258/**
259 * regs_get_register() - get register value from its offset
260 * @regs: pt_regs from which register value is gotten
261 * @offset: offset number of the register.
262 *
263 * regs_get_register returns the value of a register whose offset from @regs.
264 * The @offset is the offset of the register in struct pt_regs.
265 * If @offset is bigger than MAX_REG_OFFSET, this returns 0.
266 */
267static inline unsigned long regs_get_register(struct pt_regs *regs,
268 unsigned int offset)
269{
270 if (unlikely(offset > MAX_REG_OFFSET))
271 return 0;
272 return *(unsigned long *)((unsigned long)regs + offset);
273}
274
275/**
276 * regs_within_kernel_stack() - check the address in the stack
277 * @regs: pt_regs which contains kernel stack pointer.
278 * @addr: address which is checked.
279 *
280 * regs_within_kernel_stack() checks @addr is within the kernel stack page(s).
281 * If @addr is within the kernel stack, it returns true. If not, returns false.
282 */
283
284static inline bool regs_within_kernel_stack(struct pt_regs *regs,
285 unsigned long addr)
286{
287 return ((addr & ~(THREAD_SIZE - 1)) ==
288 (kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1)));
289}
290
291/**
292 * regs_get_kernel_stack_nth() - get Nth entry of the stack
293 * @regs: pt_regs which contains kernel stack pointer.
294 * @n: stack entry number.
295 *
296 * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
297 * is specified by @regs. If the @n th entry is NOT in the kernel stack,
298 * this returns 0.
299 */
300static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
301 unsigned int n)
302{
303 unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs);
304 addr += n;
305 if (regs_within_kernel_stack(regs, (unsigned long)addr))
306 return *addr;
307 else
308 return 0;
309}
310
311#endif /* __ASSEMBLY__ */
312
313#ifndef __powerpc64__
314/* We need PT_SOFTE defined at all time to avoid #ifdefs */
315#define PT_SOFTE PT_MQ
316#else /* __powerpc64__ */
317#define PT_FPSCR32 (PT_FPR0 + 2*32 + 1) /* each FP reg occupies 2 32-bit userspace slots */
318#define PT_VR0_32 164 /* each Vector reg occupies 4 slots in 32-bit */
319#define PT_VSCR_32 (PT_VR0 + 32*4 + 3)
320#define PT_VRSAVE_32 (PT_VR0 + 33*4)
321#define PT_VSR0_32 300 /* each VSR reg occupies 4 slots in 32-bit */
322#endif /* __powerpc64__ */
323#endif /* _ASM_POWERPC_PTRACE_H */