summaryrefslogtreecommitdiffstats
path: root/sys/sparc64
diff options
context:
space:
mode:
authormarius <marius@FreeBSD.org>2006-02-19 11:54:46 +0000
committermarius <marius@FreeBSD.org>2006-02-19 11:54:46 +0000
commit8fac408a7262b12dce6d506344068ddc9964015c (patch)
treea990f489d0898146ccba742f0324af70fa95baf8 /sys/sparc64
parentd07e9ef4b2d775909a4e2e6c891922e109731b14 (diff)
downloadFreeBSD-src-8fac408a7262b12dce6d506344068ddc9964015c.zip
FreeBSD-src-8fac408a7262b12dce6d506344068ddc9964015c.tar.gz
- Don't bother traversing trap frames in stack_save(). This fixes panics
when option DEBUG_LOCKS is used. Trap frames are determined by checking whether the caller was one of the tl0_*() or tl1_*() asm functions via a newly added pair of dummy symbols in exception.S which mark the begin and end of these functions. The tl_trap_* pair marks those in the special .trap section and the tl_text_* in the regular .text section. Because of their performance penalty db_search_symbol()/db_symbol_values() and linker_ddb_search_symbol()/linker_ddb_symbol_values() aren't used here for determining the caller, with db_search_symbol()/db_symbol_values() additionally not being reentrant. - For consistency, change db_backtrace() to also use the new markers for determining the tl0_*() and tl1_*() asm functions instead of bcmp()'ing the symbol name. - Use FBSDID in db_trace.c. PR: 93226 Based on a patch by: Antoine Brodin <antoine.brodin@laposte.net> Ok'ed by: jhb
Diffstat (limited to 'sys/sparc64')
-rw-r--r--sys/sparc64/sparc64/db_trace.c22
-rw-r--r--sys/sparc64/sparc64/exception.S16
2 files changed, 34 insertions, 4 deletions
diff --git a/sys/sparc64/sparc64/db_trace.c b/sys/sparc64/sparc64/db_trace.c
index 66cc76b..bb5f60c 100644
--- a/sys/sparc64/sparc64/db_trace.c
+++ b/sys/sparc64/sparc64/db_trace.c
@@ -22,10 +22,11 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kdb.h>
@@ -49,6 +50,11 @@
#include <ddb/db_variables.h>
#include <ddb/db_watch.h>
+extern char tl_trap_begin[];
+extern char tl_trap_end[];
+extern char tl_text_begin[];
+extern char tl_text_end[];
+
#define INKERNEL(va) \
((va) >= VM_MIN_KERNEL_ADDRESS && (va) <= VM_MAX_KERNEL_ADDRESS)
@@ -259,8 +265,10 @@ db_backtrace(struct thread *td, struct frame *fp, int count)
name = "(null)";
fp = (struct frame *)(db_get_value((db_addr_t)&fp->fr_fp,
sizeof(fp->fr_fp), FALSE) + SPOFF);
- if (bcmp(name, "tl0_", 4) == 0 ||
- bcmp(name, "tl1_", 4) == 0) {
+ if ((value > (u_long)tl_trap_begin &&
+ value < (u_long)tl_trap_end) ||
+ (value > (u_long)tl_text_begin &&
+ value < (u_long)tl_text_end)) {
tf = (struct trapframe *)(fp + 1);
npc = db_get_value((db_addr_t)&tf->tf_tpc,
sizeof(tf->tf_tpc), FALSE);
@@ -307,6 +315,12 @@ stack_save(struct stack *st)
callpc = fp->fr_pc;
if (!INKERNEL(callpc))
break;
+ /* Don't bother traversing trap frames. */
+ if ((callpc > (u_long)tl_trap_begin &&
+ callpc < (u_long)tl_trap_end) ||
+ (callpc > (u_long)tl_text_begin &&
+ callpc < (u_long)tl_text_end))
+ break;
if (stack_put(st, callpc) == -1)
break;
fp = (struct frame *)(fp->fr_fp + SPOFF);
diff --git a/sys/sparc64/sparc64/exception.S b/sys/sparc64/sparc64/exception.S
index d3fcdb8..830a724 100644
--- a/sys/sparc64/sparc64/exception.S
+++ b/sys/sparc64/sparc64/exception.S
@@ -166,6 +166,10 @@ __FBSDID("$FreeBSD$");
ldx [ASP_REG + 0], %g1 ; \
inc 16, ASP_REG
+ .globl tl_text_begin
+tl_text_begin:
+ nop
+
ENTRY(tl1_kstack_fault)
rdpr %tl, %g1
1: cmp %g1, 2
@@ -1818,6 +1822,10 @@ END(tl1_spill_topcb)
.endm
.sect .trap
+ .globl tl_trap_begin
+tl_trap_begin:
+ nop
+
.align 0x8000
.globl tl0_base
@@ -2015,6 +2023,10 @@ tl1_breakpoint:
tl1_gen T_RSTRWP_VIRT ! 0x303
tl1_reserved 252 ! 0x304-0x3ff
+ .globl tl_trap_end
+tl_trap_end:
+ nop
+
/*
* User trap entry point.
*
@@ -2901,6 +2913,10 @@ ENTRY(tl1_intr)
retry
END(tl1_intr)
+ .globl tl_text_end
+tl_text_end:
+ nop
+
/*
* Freshly forked processes come here when switched to for the first time.
* The arguments to fork_exit() have been setup in the locals, we must move
OpenPOWER on IntegriCloud