diff --git a/arch/arm64/include/asm/stacktrace/common.h b/arch/arm64/include/asm/stacktrace/common.h
index 638008f485972..508f734de46ee 100644
--- a/arch/arm64/include/asm/stacktrace/common.h
+++ b/arch/arm64/include/asm/stacktrace/common.h
@@ -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 @@ static inline int unwind_consume_stack(struct unwind_state *state,
  * 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;
 }
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index 9c8820f242625..634279b3b03d1 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -84,7 +84,7 @@ static int notrace unwind_next(struct unwind_state *state)
 	if (fp == (unsigned long)task_pt_regs(tsk)->stackframe)
 		return -ENOENT;
 
-	err = unwind_next_frame_record(state, NULL);
+	err = unwind_next_frame_record(state);
 	if (err)
 		return err;
 
diff --git a/arch/arm64/kvm/hyp/nvhe/stacktrace.c b/arch/arm64/kvm/hyp/nvhe/stacktrace.c
index 08e1325ead73f..ed6b58b19cfa5 100644
--- a/arch/arm64/kvm/hyp/nvhe/stacktrace.c
+++ b/arch/arm64/kvm/hyp/nvhe/stacktrace.c
@@ -64,7 +64,7 @@ static struct stack_info stackinfo_get_hyp(void)
 
 static int unwind_next(struct unwind_state *state)
 {
-	return unwind_next_frame_record(state, NULL);
+	return unwind_next_frame_record(state);
 }
 
 static void notrace unwind(struct unwind_state *state,
diff --git a/arch/arm64/kvm/stacktrace.c b/arch/arm64/kvm/stacktrace.c
index 0b4703945780f..3ace5b75813bd 100644
--- a/arch/arm64/kvm/stacktrace.c
+++ b/arch/arm64/kvm/stacktrace.c
@@ -34,6 +34,17 @@ static struct stack_info stackinfo_get_overflow(void)
 	};
 }
 
+static struct stack_info stackinfo_get_overflow_kern_va(void)
+{
+	unsigned long low = (unsigned long)this_cpu_ptr_nvhe_sym(overflow_stack);
+	unsigned long high = low + OVERFLOW_STACK_SIZE;
+
+	return (struct stack_info) {
+		.low = low,
+		.high = high,
+	};
+}
+
 static struct stack_info stackinfo_get_hyp(void)
 {
 	struct kvm_nvhe_stacktrace_info *stacktrace_info
@@ -47,6 +58,17 @@ static struct stack_info stackinfo_get_hyp(void)
 	};
 }
 
+static struct stack_info stackinfo_get_hyp_kern_va(void)
+{
+	unsigned long low = (unsigned long)*this_cpu_ptr(&kvm_arm_hyp_stack_page);
+	unsigned long high = low + PAGE_SIZE;
+
+	return (struct stack_info) {
+		.low = low,
+		.high = high,
+	};
+}
+
 /*
  * kvm_nvhe_stack_kern_va - Convert KVM nVHE HYP stack addresses to a kernel VAs
  *
@@ -62,33 +84,22 @@ static struct stack_info stackinfo_get_hyp(void)
  */
 static bool kvm_nvhe_stack_kern_va(unsigned long *addr, unsigned long size)
 {
-	struct kvm_nvhe_stacktrace_info *stacktrace_info;
-	unsigned long hyp_base, kern_base, hyp_offset;
-	struct stack_info stack;
+	struct stack_info stack_hyp, stack_kern;
 
-	stacktrace_info = this_cpu_ptr_nvhe_sym(kvm_stacktrace_info);
-
-	stack = stackinfo_get_hyp();
-	if (stackinfo_on_stack(&stack, *addr, size)) {
-		kern_base = (unsigned long)*this_cpu_ptr(&kvm_arm_hyp_stack_page);
-		hyp_base = (unsigned long)stacktrace_info->stack_base;
+	stack_hyp = stackinfo_get_hyp();
+	stack_kern = stackinfo_get_hyp_kern_va();
+	if (stackinfo_on_stack(&stack_hyp, *addr, size))
 		goto found;
-	}
 
-	stack = stackinfo_get_overflow();
-	if (stackinfo_on_stack(&stack, *addr, size)) {
-		kern_base = (unsigned long)this_cpu_ptr_nvhe_sym(overflow_stack);
-		hyp_base = (unsigned long)stacktrace_info->overflow_stack_base;
+	stack_hyp = stackinfo_get_overflow();
+	stack_kern = stackinfo_get_overflow_kern_va();
+	if (stackinfo_on_stack(&stack_hyp, *addr, size))
 		goto found;
-	}
 
 	return false;
 
 found:
-	hyp_offset = *addr - hyp_base;
-
-	*addr = kern_base + hyp_offset;
-
+	*addr = *addr - stack_hyp.low + stack_kern.low;
 	return true;
 }
 
@@ -102,7 +113,14 @@ static bool kvm_nvhe_stack_kern_record_va(unsigned long *addr)
 
 static int unwind_next(struct unwind_state *state)
 {
-	return unwind_next_frame_record(state, kvm_nvhe_stack_kern_record_va);
+	/*
+	 * The FP is in the hypervisor VA space. Convert it to the kernel VA
+	 * space so it can be unwound by the regular unwind functions.
+	 */
+	if (!kvm_nvhe_stack_kern_record_va(&state->fp))
+		return -EINVAL;
+
+	return unwind_next_frame_record(state);
 }
 
 static void unwind(struct unwind_state *state,
@@ -161,8 +179,8 @@ static void hyp_dump_backtrace(unsigned long hyp_offset)
 {
 	struct kvm_nvhe_stacktrace_info *stacktrace_info;
 	struct stack_info stacks[] = {
-		stackinfo_get_overflow(),
-		stackinfo_get_hyp(),
+		stackinfo_get_overflow_kern_va(),
+		stackinfo_get_hyp_kern_va(),
 	};
 	struct unwind_state state = {
 		.stacks = stacks,
