Commit 886c2b0b authored by Mark Rutland's avatar Mark Rutland Committed by Catalin Marinas
Browse files

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: default avatarMark Rutland <mark.rutland@arm.com>
Reviewed-by: default avatarMark Brown <broonie@kernel.org>
Reviewed-by: default avatarMiroslav Benes <mbenes@suse.cz>
Reviewed-by: default avatarPuranjay 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: default avatarCatalin Marinas <catalin.marinas@arm.com>
parent 14543630
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -98,6 +98,8 @@
#include <linux/bug.h>
#include <linux/types.h>

#include <asm/stacktrace/frame.h>

/* sizeof(struct user) for AArch32 */
#define COMPAT_USER_SZ	296

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

	u64 stackframe[2];
	struct frame_record stackframe;

	/* Only valid for some EL1 exceptions. */
	u64 lockdep_hardirqs;
+5 −3
Original line number Diff line number Diff line
@@ -137,21 +137,23 @@ static inline int unwind_consume_stack(struct unwind_state *state,
static inline int
unwind_next_frame_record(struct unwind_state *state)
{
	struct frame_record *record;
	unsigned long fp = state->fp;
	int err;

	if (fp & 0x7)
		return -EINVAL;

	err = unwind_consume_stack(state, fp, 16);
	err = unwind_consume_stack(state, fp, sizeof(*record));
	if (err)
		return err;

	/*
	 * Record this frame record's values.
	 */
	state->fp = READ_ONCE(*(unsigned long *)(fp));
	state->pc = READ_ONCE(*(unsigned long *)(fp + 8));
	record = (struct frame_record *)fp;
	state->fp = READ_ONCE(record->fp);
	state->pc = READ_ONCE(record->lr);

	return 0;
}
+13 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef __ASM_STACKTRACE_FRAME_H
#define __ASM_STACKTRACE_FRAME_H

/*
 * A standard AAPCS64 frame record.
 */
struct frame_record {
	u64 fp;
	u64 lr;
};

#endif /* __ASM_STACKTRACE_FRAME_H */
+1 −1
Original line number Diff line number Diff line
@@ -419,7 +419,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
	 * For the benefit of the unwinder, set up childregs->stackframe
	 * as the final frame for the new task.
	 */
	p->thread.cpu_context.fp = (unsigned long)childregs->stackframe;
	p->thread.cpu_context.fp = (unsigned long)&childregs->stackframe;

	ptrace_hw_copy_thread(p);

+0 −5
Original line number Diff line number Diff line
@@ -42,11 +42,6 @@ struct rt_sigframe {
	struct ucontext uc;
};

struct frame_record {
	u64 fp;
	u64 lr;
};

struct rt_sigframe_user_layout {
	struct rt_sigframe __user *sigframe;
	struct frame_record __user *next_frame;
Loading