Skip to content

Commit 886c2b0

Browse files
mrutland-armctmarinas
authored andcommitted
arm64: use a common struct frame_record
Currently the signal handling code has its own struct frame_record, the definition of struct pt_regs open-codes a frame record as an array, and the kernel unwinder hard-codes frame record offsets. Move to a common struct frame_record that can be used throughout the kernel. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Reviewed-by: Mark Brown <broonie@kernel.org> Reviewed-by: Miroslav Benes <mbenes@suse.cz> Reviewed-by: Puranjay Mohan <puranjay12@gmail.com> Cc: Ard Biesheuvel <ardb@kernel.org> Cc: Josh Poimboeuf <jpoimboe@kernel.org> Cc: Kalesh Singh <kaleshsingh@google.com> Cc: Madhavan T. Venkataraman <madvenka@linux.microsoft.com> Cc: Marc Zyngier <maz@kernel.org> Cc: Will Deacon <will@kernel.org> Link: https://lore.kernel.org/r/20241017092538.1859841-6-mark.rutland@arm.com Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
1 parent 1454363 commit 886c2b0

File tree

6 files changed

+23
-11
lines changed

6 files changed

+23
-11
lines changed

arch/arm64/include/asm/ptrace.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@
9898
#include <linux/bug.h>
9999
#include <linux/types.h>
100100

101+
#include <asm/stacktrace/frame.h>
102+
101103
/* sizeof(struct user) for AArch32 */
102104
#define COMPAT_USER_SZ 296
103105

@@ -168,7 +170,7 @@ struct pt_regs {
168170
u64 sdei_ttbr1;
169171
u64 unused;
170172

171-
u64 stackframe[2];
173+
struct frame_record stackframe;
172174

173175
/* Only valid for some EL1 exceptions. */
174176
u64 lockdep_hardirqs;

arch/arm64/include/asm/stacktrace/common.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,21 +137,23 @@ static inline int unwind_consume_stack(struct unwind_state *state,
137137
static inline int
138138
unwind_next_frame_record(struct unwind_state *state)
139139
{
140+
struct frame_record *record;
140141
unsigned long fp = state->fp;
141142
int err;
142143

143144
if (fp & 0x7)
144145
return -EINVAL;
145146

146-
err = unwind_consume_stack(state, fp, 16);
147+
err = unwind_consume_stack(state, fp, sizeof(*record));
147148
if (err)
148149
return err;
149150

150151
/*
151152
* Record this frame record's values.
152153
*/
153-
state->fp = READ_ONCE(*(unsigned long *)(fp));
154-
state->pc = READ_ONCE(*(unsigned long *)(fp + 8));
154+
record = (struct frame_record *)fp;
155+
state->fp = READ_ONCE(record->fp);
156+
state->pc = READ_ONCE(record->lr);
155157

156158
return 0;
157159
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
#ifndef __ASM_STACKTRACE_FRAME_H
3+
#define __ASM_STACKTRACE_FRAME_H
4+
5+
/*
6+
* A standard AAPCS64 frame record.
7+
*/
8+
struct frame_record {
9+
u64 fp;
10+
u64 lr;
11+
};
12+
13+
#endif /* __ASM_STACKTRACE_FRAME_H */

arch/arm64/kernel/process.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
419419
* For the benefit of the unwinder, set up childregs->stackframe
420420
* as the final frame for the new task.
421421
*/
422-
p->thread.cpu_context.fp = (unsigned long)childregs->stackframe;
422+
p->thread.cpu_context.fp = (unsigned long)&childregs->stackframe;
423423

424424
ptrace_hw_copy_thread(p);
425425

arch/arm64/kernel/signal.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,6 @@ struct rt_sigframe {
4242
struct ucontext uc;
4343
};
4444

45-
struct frame_record {
46-
u64 fp;
47-
u64 lr;
48-
};
49-
5045
struct rt_sigframe_user_layout {
5146
struct rt_sigframe __user *sigframe;
5247
struct frame_record __user *next_frame;

arch/arm64/kernel/stacktrace.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ kunwind_next(struct kunwind_state *state)
145145
int err;
146146

147147
/* Final frame; nothing to unwind */
148-
if (fp == (unsigned long)task_pt_regs(tsk)->stackframe)
148+
if (fp == (unsigned long)&task_pt_regs(tsk)->stackframe)
149149
return -ENOENT;
150150

151151
err = unwind_next_frame_record(&state->common);

0 commit comments

Comments
 (0)