diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index 22f8709f0e763edcb8719400ca31ea5012ee719a..83ab37e13159e87530b244546e9f717b610b9c2b 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -20,6 +20,14 @@
 #include <asm/stack_pointer.h>
 #include <asm/stacktrace.h>
 
+enum kunwind_source {
+	KUNWIND_SOURCE_UNKNOWN,
+	KUNWIND_SOURCE_FRAME,
+	KUNWIND_SOURCE_CALLER,
+	KUNWIND_SOURCE_TASK,
+	KUNWIND_SOURCE_REGS_PC,
+};
+
 /*
  * Kernel unwind state
  *
@@ -37,6 +45,7 @@ struct kunwind_state {
 #ifdef CONFIG_KRETPROBES
 	struct llist_node *kr_cur;
 #endif
+	enum kunwind_source source;
 };
 
 static __always_inline void
@@ -45,6 +54,7 @@ kunwind_init(struct kunwind_state *state,
 {
 	unwind_init_common(&state->common);
 	state->task = task;
+	state->source = KUNWIND_SOURCE_UNKNOWN;
 }
 
 /*
@@ -62,6 +72,7 @@ kunwind_init_from_regs(struct kunwind_state *state,
 
 	state->common.fp = regs->regs[29];
 	state->common.pc = regs->pc;
+	state->source = KUNWIND_SOURCE_REGS_PC;
 }
 
 /*
@@ -79,6 +90,7 @@ kunwind_init_from_caller(struct kunwind_state *state)
 
 	state->common.fp = (unsigned long)__builtin_frame_address(1);
 	state->common.pc = (unsigned long)__builtin_return_address(0);
+	state->source = KUNWIND_SOURCE_CALLER;
 }
 
 /*
@@ -99,6 +111,7 @@ kunwind_init_from_task(struct kunwind_state *state,
 
 	state->common.fp = thread_saved_fp(task);
 	state->common.pc = thread_saved_pc(task);
+	state->source = KUNWIND_SOURCE_TASK;
 }
 
 static __always_inline int
@@ -148,9 +161,19 @@ kunwind_next(struct kunwind_state *state)
 	if (fp == (unsigned long)&task_pt_regs(tsk)->stackframe)
 		return -ENOENT;
 
-	err = unwind_next_frame_record(&state->common);
-	if (err)
-		return err;
+	switch (state->source) {
+	case KUNWIND_SOURCE_FRAME:
+	case KUNWIND_SOURCE_CALLER:
+	case KUNWIND_SOURCE_TASK:
+	case KUNWIND_SOURCE_REGS_PC:
+		err = unwind_next_frame_record(&state->common);
+		if (err)
+			return err;
+		state->source = KUNWIND_SOURCE_FRAME;
+		break;
+	default:
+		return -EINVAL;
+	}
 
 	state->common.pc = ptrauth_strip_kernel_insn_pac(state->common.pc);
 
@@ -294,10 +317,26 @@ noinline noinstr void arch_bpf_stack_walk(bool (*consume_entry)(void *cookie, u6
 	kunwind_stack_walk(arch_bpf_unwind_consume_entry, &data, current, NULL);
 }
 
+static const char *state_source_string(const struct kunwind_state *state)
+{
+	switch (state->source) {
+	case KUNWIND_SOURCE_FRAME:	return NULL;
+	case KUNWIND_SOURCE_CALLER:	return "C";
+	case KUNWIND_SOURCE_TASK:	return "T";
+	case KUNWIND_SOURCE_REGS_PC:	return "P";
+	default:			return "U";
+	}
+}
+
 static bool dump_backtrace_entry(const struct kunwind_state *state, void *arg)
 {
+	const char *source = state_source_string(state);
 	char *loglvl = arg;
-	printk("%s %pSb\n", loglvl, (void *)state->common.pc);
+	printk("%s %pSb%s%s%s\n", loglvl,
+		(void *)state->common.pc,
+		source ? " (" : "",
+		source ? source : "",
+		source ? ")" : "");
 	return true;
 }