arm64: stacktrace: track hyp stacks in unwinder's address space

Currently unwind_next_frame_record() has an optional callback to convert
the address space of the FP. This is necessary for the NVHE unwinder,
which tracks the stacks in the hyp VA space, but accesses the frame
records in the kernel VA space.

This is a bit unfortunate since it clutters unwind_next_frame_record(),
which will get in the way of future rework.

Instead, this patch changes the NVHE unwinder to track the stacks in the
kernel's VA space and translate to FP prior to calling
unwind_next_frame_record(). This removes the need for the translate_fp()
callback, as all unwinders consistently track stacks in the native
address space of the unwinder.

At the same time, this patch consolidates the generation of the stack
addresses behind the stackinfo_get_*() helpers.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Kalesh Singh <kaleshsingh@google.com>
Reviewed-by: Madhavan T. Venkataraman <madvenka@linux.microsoft.com>
Reviewed-by: Mark Brown <broonie@kernel.org>
Cc: Fuad Tabba <tabba@google.com>
Cc: Marc Zyngier <maz@kernel.org>
Cc: Will Deacon <will@kernel.org>
Link: https://lore.kernel.org/r/20220901130646.1316937-10-mark.rutland@arm.com
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
This commit is contained in:
Mark Rutland
2022-09-01 14:06:46 +01:00
committed by Catalin Marinas
parent 8df137300d
commit 4b5e694e25
4 changed files with 46 additions and 49 deletions
+4 -25
View File
@@ -77,18 +77,6 @@ static inline void unwind_init_common(struct unwind_state *state,
state->stack = stackinfo_get_unknown();
}
/**
* typedef stack_trace_translate_fp_fn() - Translates a non-kernel frame
* pointer to a kernel address.
*
* @fp: the frame pointer to be updated to its kernel address.
*
* Return: true if the VA can be translated, false otherwise.
*
* Upon success @fp is updated to the corresponding kernel virtual address.
*/
typedef bool (*stack_trace_translate_fp_fn)(unsigned long *fp);
static struct stack_info *unwind_find_next_stack(const struct unwind_state *state,
unsigned long sp,
unsigned long size)
@@ -160,15 +148,13 @@ found:
* unwind_next_frame_record() - Unwind to the next frame record.
*
* @state: the current unwind state.
* @translate_fp: translates the fp prior to access (may be NULL)
*
* Return: 0 upon success, an error code otherwise.
*/
static inline int
unwind_next_frame_record(struct unwind_state *state,
stack_trace_translate_fp_fn translate_fp)
unwind_next_frame_record(struct unwind_state *state)
{
unsigned long fp = state->fp, kern_fp = fp;
unsigned long fp = state->fp;
int err;
if (fp & 0x7)
@@ -178,18 +164,11 @@ unwind_next_frame_record(struct unwind_state *state,
if (err)
return err;
/*
* If fp is not from the current address space perform the necessary
* translation before dereferencing it to get the next fp.
*/
if (translate_fp && !translate_fp(&kern_fp))
return -EINVAL;
/*
* Record this frame record's values.
*/
state->fp = READ_ONCE(*(unsigned long *)(kern_fp));
state->pc = READ_ONCE(*(unsigned long *)(kern_fp + 8));
state->fp = READ_ONCE(*(unsigned long *)(fp));
state->pc = READ_ONCE(*(unsigned long *)(fp + 8));
return 0;
}