hc
2024-10-12 a5969cabbb4660eab42b6ef0412cbbd1200cf14d
kernel/arch/arm64/include/asm/ptrace.h
....@@ -1,29 +1,59 @@
1
+/* SPDX-License-Identifier: GPL-2.0-only */
12 /*
23 * Based on arch/arm/include/asm/ptrace.h
34 *
45 * Copyright (C) 1996-2003 Russell King
56 * Copyright (C) 2012 ARM Ltd.
6
- *
7
- * This program is free software; you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License version 2 as
9
- * published by the Free Software Foundation.
10
- *
11
- * This program is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- * GNU General Public License for more details.
15
- *
16
- * You should have received a copy of the GNU General Public License
17
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
187 */
198 #ifndef __ASM_PTRACE_H
209 #define __ASM_PTRACE_H
10
+
11
+#include <asm/cpufeature.h>
2112
2213 #include <uapi/asm/ptrace.h>
2314
2415 /* Current Exception Level values, as contained in CurrentEL */
2516 #define CurrentEL_EL1 (1 << 2)
2617 #define CurrentEL_EL2 (2 << 2)
18
+
19
+#define INIT_PSTATE_EL1 \
20
+ (PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT | PSR_MODE_EL1h)
21
+#define INIT_PSTATE_EL2 \
22
+ (PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT | PSR_MODE_EL2h)
23
+
24
+/*
25
+ * PMR values used to mask/unmask interrupts.
26
+ *
27
+ * GIC priority masking works as follows: if an IRQ's priority is a higher value
28
+ * than the value held in PMR, that IRQ is masked. Lowering the value of PMR
29
+ * means masking more IRQs (or at least that the same IRQs remain masked).
30
+ *
31
+ * To mask interrupts, we clear the most significant bit of PMR.
32
+ *
33
+ * Some code sections either automatically switch back to PSR.I or explicitly
34
+ * require to not use priority masking. If bit GIC_PRIO_PSR_I_SET is included
35
+ * in the priority mask, it indicates that PSR.I should be set and
36
+ * interrupt disabling temporarily does not rely on IRQ priorities.
37
+ */
38
+#define GIC_PRIO_IRQON 0xe0
39
+#define __GIC_PRIO_IRQOFF (GIC_PRIO_IRQON & ~0x80)
40
+#define __GIC_PRIO_IRQOFF_NS 0xa0
41
+#define GIC_PRIO_PSR_I_SET (1 << 4)
42
+
43
+#define GIC_PRIO_IRQOFF \
44
+ ({ \
45
+ extern struct static_key_false gic_nonsecure_priorities;\
46
+ u8 __prio = __GIC_PRIO_IRQOFF; \
47
+ \
48
+ if (static_branch_unlikely(&gic_nonsecure_priorities)) \
49
+ __prio = __GIC_PRIO_IRQOFF_NS; \
50
+ \
51
+ __prio; \
52
+ })
53
+
54
+/* Additional SPSR bits not exposed in the UABI */
55
+#define PSR_MODE_THREAD_BIT (1 << 0)
56
+#define PSR_IL_BIT (1 << 20)
2757
2858 /* AArch32-specific ptrace requests */
2959 #define COMPAT_PTRACE_GETREGS 12
....@@ -165,8 +195,13 @@
165195 #endif
166196
167197 u64 orig_addr_limit;
168
- u64 unused; // maintain 16 byte alignment
198
+ /* Only valid when ARM64_HAS_IRQ_PRIO_MASKING is enabled. */
199
+ u64 pmr_save;
169200 u64 stackframe[2];
201
+
202
+ /* Only valid for some EL1 exceptions. */
203
+ u64 lockdep_hardirqs;
204
+ u64 exit_rcu;
170205 };
171206
172207 static inline bool in_syscall(struct pt_regs const *regs)
....@@ -200,17 +235,23 @@
200235 #define processor_mode(regs) \
201236 ((regs)->pstate & PSR_MODE_MASK)
202237
203
-#define interrupts_enabled(regs) \
204
- (!((regs)->pstate & PSR_I_BIT))
238
+#define irqs_priority_unmasked(regs) \
239
+ (system_uses_irq_prio_masking() ? \
240
+ (regs)->pmr_save == GIC_PRIO_IRQON : \
241
+ true)
242
+
243
+#define interrupts_enabled(regs) \
244
+ (!((regs)->pstate & PSR_I_BIT) && irqs_priority_unmasked(regs))
205245
206246 #define fast_interrupts_enabled(regs) \
207247 (!((regs)->pstate & PSR_F_BIT))
208248
209
-#define GET_USP(regs) \
210
- (!compat_user_mode(regs) ? (regs)->sp : (regs)->compat_sp)
211
-
212
-#define SET_USP(ptregs, value) \
213
- (!compat_user_mode(regs) ? ((regs)->sp = value) : ((regs)->compat_sp = value))
249
+static inline unsigned long user_stack_pointer(struct pt_regs *regs)
250
+{
251
+ if (compat_user_mode(regs))
252
+ return regs->compat_sp;
253
+ return regs->sp;
254
+}
214255
215256 extern int regs_query_register_offset(const char *name);
216257 extern unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
....@@ -280,20 +321,64 @@
280321
281322 static inline unsigned long regs_return_value(struct pt_regs *regs)
282323 {
283
- return regs->regs[0];
324
+ unsigned long val = regs->regs[0];
325
+
326
+ /*
327
+ * Audit currently uses regs_return_value() instead of
328
+ * syscall_get_return_value(). Apply the same sign-extension here until
329
+ * audit is updated to use syscall_get_return_value().
330
+ */
331
+ if (compat_user_mode(regs))
332
+ val = sign_extend64(val, 31);
333
+
334
+ return val;
335
+}
336
+
337
+static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc)
338
+{
339
+ regs->regs[0] = rc;
340
+}
341
+
342
+/**
343
+ * regs_get_kernel_argument() - get Nth function argument in kernel
344
+ * @regs: pt_regs of that context
345
+ * @n: function argument number (start from 0)
346
+ *
347
+ * regs_get_argument() returns @n th argument of the function call.
348
+ *
349
+ * Note that this chooses the most likely register mapping. In very rare
350
+ * cases this may not return correct data, for example, if one of the
351
+ * function parameters is 16 bytes or bigger. In such cases, we cannot
352
+ * get access the parameter correctly and the register assignment of
353
+ * subsequent parameters will be shifted.
354
+ */
355
+static inline unsigned long regs_get_kernel_argument(struct pt_regs *regs,
356
+ unsigned int n)
357
+{
358
+#define NR_REG_ARGUMENTS 8
359
+ if (n < NR_REG_ARGUMENTS)
360
+ return pt_regs_read_reg(regs, n);
361
+ return 0;
284362 }
285363
286364 /* We must avoid circular header include via sched.h */
287365 struct task_struct;
288366 int valid_user_regs(struct user_pt_regs *regs, struct task_struct *task);
289367
290
-#define GET_IP(regs) ((unsigned long)(regs)->pc)
291
-#define SET_IP(regs, value) ((regs)->pc = ((u64) (value)))
368
+static inline unsigned long instruction_pointer(struct pt_regs *regs)
369
+{
370
+ return regs->pc;
371
+}
372
+static inline void instruction_pointer_set(struct pt_regs *regs,
373
+ unsigned long val)
374
+{
375
+ regs->pc = val;
376
+}
292377
293
-#define GET_FP(ptregs) ((unsigned long)(ptregs)->regs[29])
294
-#define SET_FP(ptregs, value) ((ptregs)->regs[29] = ((u64) (value)))
295
-
296
-#include <asm-generic/ptrace.h>
378
+static inline unsigned long frame_pointer(struct pt_regs *regs)
379
+{
380
+ return regs->regs[29];
381
+}
297382
298383 #define procedure_link_pointer(regs) ((regs)->regs[30])
299384
....@@ -303,7 +388,6 @@
303388 procedure_link_pointer(regs) = val;
304389 }
305390
306
-#undef profile_pc
307391 extern unsigned long profile_pc(struct pt_regs *regs);
308392
309393 #endif /* __ASSEMBLY__ */