All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrew Jones <andrew.jones@linux.dev>
To: kvm-riscv@lists.infradead.org
Subject: [kvm-unit-tests PATCH 10/24] riscv: Add backtrace support
Date: Wed, 24 Jan 2024 08:18:26 +0100	[thread overview]
Message-ID: <20240124071815.6898-36-andrew.jones@linux.dev> (raw)
In-Reply-To: <20240124071815.6898-26-andrew.jones@linux.dev>

Enable stack unwinding, even when going through an exception, by
implementing backtrace() and pushing a frame pointer on the stack
in exception_vectors.

Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
---
 lib/riscv/asm/stack.h |  3 +++
 lib/riscv/stack.c     | 32 ++++++++++++++++++++++++++++++++
 riscv/Makefile        |  1 +
 riscv/cstart.S        | 28 ++++++++++++++++++++++++++--
 4 files changed, 62 insertions(+), 2 deletions(-)
 create mode 100644 lib/riscv/stack.c

diff --git a/lib/riscv/asm/stack.h b/lib/riscv/asm/stack.h
index d081d0716d7b..f003ca37c913 100644
--- a/lib/riscv/asm/stack.h
+++ b/lib/riscv/asm/stack.h
@@ -6,4 +6,7 @@
 #error Do not directly include <asm/stack.h>. Just use <stack.h>.
 #endif
 
+#define HAVE_ARCH_BACKTRACE_FRAME
+#define HAVE_ARCH_BACKTRACE
+
 #endif
diff --git a/lib/riscv/stack.c b/lib/riscv/stack.c
new file mode 100644
index 000000000000..712a5478d547
--- /dev/null
+++ b/lib/riscv/stack.c
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <libcflat.h>
+#include <stack.h>
+
+int backtrace_frame(const void *frame, const void **return_addrs, int max_depth)
+{
+	static bool walking;
+	const unsigned long *fp = (unsigned long *)frame;
+	int depth;
+
+	if (walking) {
+		printf("RECURSIVE STACK WALK!!!\n");
+		return 0;
+	}
+	walking = true;
+
+	for (depth = 0; fp && depth < max_depth; ++depth) {
+		return_addrs[depth] = (void *)fp[-1];
+		if (return_addrs[depth] == 0)
+			break;
+		fp = (unsigned long *)fp[-2];
+	}
+
+	walking = false;
+	return depth;
+}
+
+int backtrace(const void **return_addrs, int max_depth)
+{
+	return backtrace_frame(__builtin_frame_address(0),
+			       return_addrs, max_depth);
+}
diff --git a/riscv/Makefile b/riscv/Makefile
index 1243be125c00..4a83f27f7df2 100644
--- a/riscv/Makefile
+++ b/riscv/Makefile
@@ -30,6 +30,7 @@ cflatobjs += lib/riscv/processor.o
 cflatobjs += lib/riscv/sbi.o
 cflatobjs += lib/riscv/setup.o
 cflatobjs += lib/riscv/smp.o
+cflatobjs += lib/riscv/stack.o
 ifeq ($(ARCH),riscv32)
 cflatobjs += lib/ldiv32.o
 endif
diff --git a/riscv/cstart.S b/riscv/cstart.S
index ac7858ef398f..9bdf2e3b17dd 100644
--- a/riscv/cstart.S
+++ b/riscv/cstart.S
@@ -17,6 +17,22 @@
 
 #define REG_L	__REG_SEL(ld, lw)
 #define REG_S	__REG_SEL(sd, sw)
+#define SZREG	__REG_SEL(8, 4)
+
+#define FP_SIZE 16
+
+.macro push_fp, ra=ra
+	addi	sp, sp, -FP_SIZE
+	REG_S	\ra, (FP_SIZE - SZREG)(sp)
+	REG_S	fp, (FP_SIZE - 2*SZREG)(sp)
+	addi	fp, sp, FP_SIZE
+.endm
+
+.macro pop_fp
+	REG_L	ra, (FP_SIZE - SZREG)(sp)
+	REG_L	fp, (FP_SIZE - 2*SZREG)(sp)
+	addi	sp, sp, FP_SIZE
+.endm
 
 .macro zero_range, tmp1, tmp2
 9998:	beq	\tmp1, \tmp2, 9997f
@@ -73,6 +89,7 @@ start:
 	li	a1, -8192
 	add	a1, sp, a1
 	zero_range a1, sp
+	mv	fp, zero			// Ensure fp starts out as zero
 
 	/* set up exception handling */
 	la	a1, exception_vectors
@@ -200,9 +217,16 @@ halt:
 .balign 4
 .global exception_vectors
 exception_vectors:
-	REG_S	a0, (-PT_SIZE + PT_ORIG_A0)(sp)
-	addi	a0, sp, -PT_SIZE
+	REG_S	a0, (-PT_SIZE - FP_SIZE + PT_ORIG_A0)(sp)
+	addi	a0, sp, -PT_SIZE - FP_SIZE
 	save_context
+	/*
+	 * Set a frame pointer "ra" which points to the last instruction.
+	 * Add 1 to it, because pretty_print_stacks.py subtracts 1.
+	 */
+	REG_L	a1, PT_EPC(a0)
+	addi	a1, a1, 1
+	push_fp	a1
 	mv	sp, a0
 	call	do_handle_exception
 	restore_context
-- 
2.43.0



WARNING: multiple messages have this Message-ID (diff)
From: Andrew Jones <andrew.jones@linux.dev>
To: kvm@vger.kernel.org, kvm-riscv@lists.infradead.org,
	kvmarm@lists.linux.dev
Cc: ajones@ventanamicro.com, anup@brainfault.org,
	atishp@atishpatra.org, pbonzini@redhat.com, thuth@redhat.com,
	alexandru.elisei@arm.com, eric.auger@redhat.com
Subject: [kvm-unit-tests PATCH 10/24] riscv: Add backtrace support
Date: Wed, 24 Jan 2024 08:18:26 +0100	[thread overview]
Message-ID: <20240124071815.6898-36-andrew.jones@linux.dev> (raw)
In-Reply-To: <20240124071815.6898-26-andrew.jones@linux.dev>

Enable stack unwinding, even when going through an exception, by
implementing backtrace() and pushing a frame pointer on the stack
in exception_vectors.

Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
---
 lib/riscv/asm/stack.h |  3 +++
 lib/riscv/stack.c     | 32 ++++++++++++++++++++++++++++++++
 riscv/Makefile        |  1 +
 riscv/cstart.S        | 28 ++++++++++++++++++++++++++--
 4 files changed, 62 insertions(+), 2 deletions(-)
 create mode 100644 lib/riscv/stack.c

diff --git a/lib/riscv/asm/stack.h b/lib/riscv/asm/stack.h
index d081d0716d7b..f003ca37c913 100644
--- a/lib/riscv/asm/stack.h
+++ b/lib/riscv/asm/stack.h
@@ -6,4 +6,7 @@
 #error Do not directly include <asm/stack.h>. Just use <stack.h>.
 #endif
 
+#define HAVE_ARCH_BACKTRACE_FRAME
+#define HAVE_ARCH_BACKTRACE
+
 #endif
diff --git a/lib/riscv/stack.c b/lib/riscv/stack.c
new file mode 100644
index 000000000000..712a5478d547
--- /dev/null
+++ b/lib/riscv/stack.c
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <libcflat.h>
+#include <stack.h>
+
+int backtrace_frame(const void *frame, const void **return_addrs, int max_depth)
+{
+	static bool walking;
+	const unsigned long *fp = (unsigned long *)frame;
+	int depth;
+
+	if (walking) {
+		printf("RECURSIVE STACK WALK!!!\n");
+		return 0;
+	}
+	walking = true;
+
+	for (depth = 0; fp && depth < max_depth; ++depth) {
+		return_addrs[depth] = (void *)fp[-1];
+		if (return_addrs[depth] == 0)
+			break;
+		fp = (unsigned long *)fp[-2];
+	}
+
+	walking = false;
+	return depth;
+}
+
+int backtrace(const void **return_addrs, int max_depth)
+{
+	return backtrace_frame(__builtin_frame_address(0),
+			       return_addrs, max_depth);
+}
diff --git a/riscv/Makefile b/riscv/Makefile
index 1243be125c00..4a83f27f7df2 100644
--- a/riscv/Makefile
+++ b/riscv/Makefile
@@ -30,6 +30,7 @@ cflatobjs += lib/riscv/processor.o
 cflatobjs += lib/riscv/sbi.o
 cflatobjs += lib/riscv/setup.o
 cflatobjs += lib/riscv/smp.o
+cflatobjs += lib/riscv/stack.o
 ifeq ($(ARCH),riscv32)
 cflatobjs += lib/ldiv32.o
 endif
diff --git a/riscv/cstart.S b/riscv/cstart.S
index ac7858ef398f..9bdf2e3b17dd 100644
--- a/riscv/cstart.S
+++ b/riscv/cstart.S
@@ -17,6 +17,22 @@
 
 #define REG_L	__REG_SEL(ld, lw)
 #define REG_S	__REG_SEL(sd, sw)
+#define SZREG	__REG_SEL(8, 4)
+
+#define FP_SIZE 16
+
+.macro push_fp, ra=ra
+	addi	sp, sp, -FP_SIZE
+	REG_S	\ra, (FP_SIZE - SZREG)(sp)
+	REG_S	fp, (FP_SIZE - 2*SZREG)(sp)
+	addi	fp, sp, FP_SIZE
+.endm
+
+.macro pop_fp
+	REG_L	ra, (FP_SIZE - SZREG)(sp)
+	REG_L	fp, (FP_SIZE - 2*SZREG)(sp)
+	addi	sp, sp, FP_SIZE
+.endm
 
 .macro zero_range, tmp1, tmp2
 9998:	beq	\tmp1, \tmp2, 9997f
@@ -73,6 +89,7 @@ start:
 	li	a1, -8192
 	add	a1, sp, a1
 	zero_range a1, sp
+	mv	fp, zero			// Ensure fp starts out as zero
 
 	/* set up exception handling */
 	la	a1, exception_vectors
@@ -200,9 +217,16 @@ halt:
 .balign 4
 .global exception_vectors
 exception_vectors:
-	REG_S	a0, (-PT_SIZE + PT_ORIG_A0)(sp)
-	addi	a0, sp, -PT_SIZE
+	REG_S	a0, (-PT_SIZE - FP_SIZE + PT_ORIG_A0)(sp)
+	addi	a0, sp, -PT_SIZE - FP_SIZE
 	save_context
+	/*
+	 * Set a frame pointer "ra" which points to the last instruction.
+	 * Add 1 to it, because pretty_print_stacks.py subtracts 1.
+	 */
+	REG_L	a1, PT_EPC(a0)
+	addi	a1, a1, 1
+	push_fp	a1
 	mv	sp, a0
 	call	do_handle_exception
 	restore_context
-- 
2.43.0


  parent reply	other threads:[~2024-01-24  7:18 UTC|newest]

Thread overview: 66+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-24  7:18 [kvm-unit-tests PATCH 00/24] Introduce RISC-V Andrew Jones
2024-01-24  7:18 ` Andrew Jones
2024-01-24  7:18 ` [kvm-unit-tests PATCH 01/24] configure: Add ARCH_LIBDIR Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  9:33   ` Thomas Huth
2024-01-24  9:33     ` Thomas Huth
2024-01-24  7:18 ` [kvm-unit-tests PATCH 02/24] riscv: Initial port, hello world Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  7:18 ` [kvm-unit-tests PATCH 03/24] arm/arm64: Move cpumask.h to common lib Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  9:52   ` Thomas Huth
2024-01-24  9:52     ` Thomas Huth
2024-01-24  7:18 ` [kvm-unit-tests PATCH 04/24] arm/arm64: Share cpu online, present and idle masks Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  9:53   ` Thomas Huth
2024-01-24  9:53     ` Thomas Huth
2024-01-24  7:18 ` [kvm-unit-tests PATCH 05/24] riscv: Add DT parsing Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  7:18 ` [kvm-unit-tests PATCH 06/24] riscv: Add initial SBI support Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  7:18 ` [kvm-unit-tests PATCH 07/24] riscv: Add run script and unittests.cfg Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  7:18 ` [kvm-unit-tests PATCH 08/24] riscv: Add riscv32 support Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  7:18 ` [kvm-unit-tests PATCH 09/24] riscv: Add exception handling Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  7:18 ` Andrew Jones [this message]
2024-01-24  7:18   ` [kvm-unit-tests PATCH 10/24] riscv: Add backtrace support Andrew Jones
2024-01-24  7:18 ` [kvm-unit-tests PATCH 11/24] arm/arm64: Generalize wfe/sev names in smp.c Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  7:18 ` [kvm-unit-tests PATCH 12/24] arm/arm64: Remove spinlocks from on_cpu_async Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  7:18 ` [kvm-unit-tests PATCH 13/24] arm/arm64: Share on_cpus Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  7:18 ` [kvm-unit-tests PATCH 14/24] riscv: Compile with march Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  7:18 ` [kvm-unit-tests PATCH 15/24] riscv: Add SMP support Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  7:18 ` [kvm-unit-tests PATCH 16/24] arm/arm64: Share memregions Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  7:18 ` [kvm-unit-tests PATCH 17/24] riscv: Populate memregions and switch to page allocator Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  7:18 ` [kvm-unit-tests PATCH 18/24] riscv: Add MMU support Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  7:18 ` [kvm-unit-tests PATCH 19/24] riscv: Enable the MMU in secondaries Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  7:18 ` [kvm-unit-tests PATCH 20/24] riscv: Enable vmalloc Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  7:18 ` [kvm-unit-tests PATCH 21/24] lib: Add strcasecmp and strncasecmp Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  9:41   ` Thomas Huth
2024-01-24  9:41     ` Thomas Huth
2024-01-24  7:18 ` [kvm-unit-tests PATCH 22/24] riscv: Add isa string parsing Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  7:18 ` [kvm-unit-tests PATCH 23/24] gitlab-ci: Add riscv64 tests Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  9:45   ` Thomas Huth
2024-01-24  9:45     ` Thomas Huth
2024-01-24 10:21     ` Andrew Jones
2024-01-24 10:21       ` Andrew Jones
2024-01-24  7:18 ` [kvm-unit-tests PATCH 24/24] MAINTAINERS: Add riscv Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  9:46   ` Thomas Huth
2024-01-24  9:46     ` Thomas Huth
2024-01-24  9:58 ` [kvm-unit-tests PATCH 00/24] Introduce RISC-V Thomas Huth
2024-01-24  9:58   ` Thomas Huth

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240124071815.6898-36-andrew.jones@linux.dev \
    --to=andrew.jones@linux.dev \
    --cc=kvm-riscv@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.