From owner-svn-src-head@freebsd.org Wed Jan 4 21:13:23 2017 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 02B37C9F57F; Wed, 4 Jan 2017 21:13:23 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id CE67410AB; Wed, 4 Jan 2017 21:13:22 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v04LDM4Q096553; Wed, 4 Jan 2017 21:13:22 GMT (envelope-from jhb@FreeBSD.org) Received: (from jhb@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v04LDMQR096552; Wed, 4 Jan 2017 21:13:22 GMT (envelope-from jhb@FreeBSD.org) Message-Id: <201701042113.v04LDMQR096552@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jhb set sender to jhb@FreeBSD.org using -f From: John Baldwin Date: Wed, 4 Jan 2017 21:13:22 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r311309 - head/sys/mips/mips X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 04 Jan 2017 21:13:23 -0000 Author: jhb Date: Wed Jan 4 21:13:21 2017 New Revision: 311309 URL: https://svnweb.freebsd.org/changeset/base/311309 Log: Further refine MIPS stack traces across trapframes. Use the trapframe unwinder recently added for kernel stack overflow panics for frames crossing MipsKernGenException and MipsKernIntr. This provides more reliably unwinding across nested interrupts and exceptions in the kernel. While here, dump the value of the CAUSE and BADVADDR registers when crossing a trapframe. Submitted by: rwatson (original version) Obtained from: CheriBSD Sponsored by: DARPA / AFRL Modified: head/sys/mips/mips/db_trace.c Modified: head/sys/mips/mips/db_trace.c ============================================================================== --- head/sys/mips/mips/db_trace.c Wed Jan 4 20:56:03 2017 (r311308) +++ head/sys/mips/mips/db_trace.c Wed Jan 4 21:13:21 2017 (r311309) @@ -141,11 +141,12 @@ stacktrace_subr(register_t pc, register_ */ int valid_args[4]; register_t args[4]; - register_t va, subr; + register_t va, subr, cause, badvaddr; unsigned instr, mask; unsigned int frames = 0; int more, stksize, j; register_t next_ra; + bool trapframe; /* Jump here when done with a frame, to start a new one */ loop: @@ -160,6 +161,7 @@ loop: next_ra = 0; stksize = 0; subr = 0; + trapframe = false; if (frames++ > 100) { (*printfn) ("\nstackframe count exceeded\n"); /* return breaks stackframe-size heuristics with gcc -O2 */ @@ -183,17 +185,21 @@ loop: * preceding "j ra" at the tail of the preceding function. Depends * on relative ordering of functions in exception.S, swtch.S. */ - if (pcBetween(MipsKernGenException, MipsUserGenException)) + if (pcBetween(MipsKernGenException, MipsUserGenException)) { subr = (uintptr_t)MipsKernGenException; - else if (pcBetween(MipsUserGenException, MipsKernIntr)) + trapframe = true; + } else if (pcBetween(MipsUserGenException, MipsKernIntr)) subr = (uintptr_t)MipsUserGenException; - else if (pcBetween(MipsKernIntr, MipsUserIntr)) + else if (pcBetween(MipsKernIntr, MipsUserIntr)) { subr = (uintptr_t)MipsKernIntr; - else if (pcBetween(MipsUserIntr, MipsTLBInvalidException)) + trapframe = true; + } else if (pcBetween(MipsUserIntr, MipsTLBInvalidException)) subr = (uintptr_t)MipsUserIntr; - else if (pcBetween(MipsTLBInvalidException, MipsTLBMissException)) + else if (pcBetween(MipsTLBInvalidException, MipsTLBMissException)) { subr = (uintptr_t)MipsTLBInvalidException; - else if (pcBetween(fork_trampoline, savectx)) + if (pc == (uintptr_t)MipsKStackOverflow) + trapframe = true; + } else if (pcBetween(fork_trampoline, savectx)) subr = (uintptr_t)fork_trampoline; else if (pcBetween(savectx, cpu_throw)) subr = (uintptr_t)savectx; @@ -215,11 +221,11 @@ loop: } /* - * For a kernel stack overflow, skip to the output and - * afterwards pull the previous registers out of the trapframe - * instead of decoding the function prologue. + * For a trapframe, skip to the output and afterwards pull the + * previous registers out of the trapframe instead of decoding + * the function prologue. */ - if (pc == (uintptr_t)MipsKStackOverflow) + if (trapframe) goto done; /* @@ -398,19 +404,24 @@ done: (uintmax_t)(u_register_t) sp, stksize); - if (pc == (uintptr_t)MipsKStackOverflow) { + if (trapframe) { #define TF_REG(base, reg) ((base) + CALLFRAME_SIZ + ((reg) * SZREG)) #if defined(__mips_n64) || defined(__mips_n32) pc = kdbpeekd((int *)TF_REG(sp, PC)); ra = kdbpeekd((int *)TF_REG(sp, RA)); sp = kdbpeekd((int *)TF_REG(sp, SP)); + cause = kdbpeekd((int *)TF_REG(sp, CAUSE)); + badvaddr = kdbpeekd((int *)TF_REG(sp, BADVADDR)); #else pc = kdbpeek((int *)TF_REG(sp, PC)); ra = kdbpeek((int *)TF_REG(sp, RA)); sp = kdbpeek((int *)TF_REG(sp, SP)); + cause = kdbpeek((int *)TF_REG(sp, CAUSE)); + badvaddr = kdbpeek((int *)TF_REG(sp, BADVADDR)); #endif #undef TF_REG - (*printfn) ("--- Kernel Stack Overflow ---\n"); + (*printfn) ("--- exception, cause %jx badvaddr %jx ---\n", + (uintmax_t)cause, (uintmax_t)badvaddr); goto loop; } else if (ra) { if (pc == ra && stksize == 0)