summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2007-11-15 22:00:57 +0000
committerjhb <jhb@FreeBSD.org>2007-11-15 22:00:57 +0000
commitbca11bf48fe38cb4822925e995f9b1be648fcc2a (patch)
treeede94b8163bb9be49c9615431eac45cfed8c0e91
parentb113160d81ef70bc2778ca6510430e65ba9232f3 (diff)
downloadFreeBSD-src-bca11bf48fe38cb4822925e995f9b1be648fcc2a.zip
FreeBSD-src-bca11bf48fe38cb4822925e995f9b1be648fcc2a.tar.gz
Add support for cross double fault frames in stack traces:
- Populate the register values for the trapframe put on the stack by the double fault handler. - Teach DDB's trace routine to treat a double fault like other trap frames. MFC after: 3 days
-rw-r--r--sys/amd64/amd64/db_trace.c3
-rw-r--r--sys/amd64/amd64/exception.S20
-rw-r--r--sys/amd64/amd64/machdep.c1
-rw-r--r--sys/amd64/amd64/trap.c7
4 files changed, 26 insertions, 5 deletions
diff --git a/sys/amd64/amd64/db_trace.c b/sys/amd64/amd64/db_trace.c
index 880be61..548c36c 100644
--- a/sys/amd64/amd64/db_trace.c
+++ b/sys/amd64/amd64/db_trace.c
@@ -317,7 +317,8 @@ db_nextframe(struct amd64_frame **fp, db_addr_t *ip, struct thread *td)
if (name != NULL) {
if (strcmp(name, "calltrap") == 0 ||
strcmp(name, "fork_trampoline") == 0 ||
- strcmp(name, "nmi_calltrap") == 0)
+ strcmp(name, "nmi_calltrap") == 0 ||
+ strcmp(name, "Xdblfault") == 0)
frame_type = TRAP;
else if (strncmp(name, "Xatpic_intr", 11) == 0 ||
strncmp(name, "Xapic_isr", 9) == 0 ||
diff --git a/sys/amd64/amd64/exception.S b/sys/amd64/amd64/exception.S
index 20e8c3d..da4918a 100644
--- a/sys/amd64/amd64/exception.S
+++ b/sys/amd64/amd64/exception.S
@@ -187,10 +187,28 @@ alltraps_noen:
IDTVEC(dblfault)
subq $TF_ERR,%rsp
movq $T_DOUBLEFLT,TF_TRAPNO(%rsp)
+ movq $0,TF_ADDR(%rsp)
+ movq $0,TF_ERR(%rsp)
+ movq %rdi,TF_RDI(%rsp)
+ movq %rsi,TF_RSI(%rsp)
+ movq %rdx,TF_RDX(%rsp)
+ movq %rcx,TF_RCX(%rsp)
+ movq %r8,TF_R8(%rsp)
+ movq %r9,TF_R9(%rsp)
+ movq %rax,TF_RAX(%rsp)
+ movq %rbx,TF_RBX(%rsp)
+ movq %rbp,TF_RBP(%rsp)
+ movq %r10,TF_R10(%rsp)
+ movq %r11,TF_R11(%rsp)
+ movq %r12,TF_R12(%rsp)
+ movq %r13,TF_R13(%rsp)
+ movq %r14,TF_R14(%rsp)
+ movq %r15,TF_R15(%rsp)
testb $SEL_RPL_MASK,TF_CS(%rsp) /* Did we come from kernel? */
jz 1f /* already running with kernel GS.base */
swapgs
-1: call dblfault_handler
+1: movq %rsp, %rdi
+ call dblfault_handler
2: hlt
jmp 2b
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index b1d9637..1928518 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -138,7 +138,6 @@ __FBSDID("$FreeBSD$");
CTASSERT(offsetof(struct pcpu, pc_curthread) == 0);
extern u_int64_t hammer_time(u_int64_t, u_int64_t);
-extern void dblfault_handler(void);
extern void printcpuinfo(void); /* XXX header file */
extern void identify_cpu(void);
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
index be6ffff..2ce8ed4 100644
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/trap.c
@@ -96,10 +96,10 @@ __FBSDID("$FreeBSD$");
extern void trap(struct trapframe *frame);
extern void syscall(struct trapframe *frame);
+void dblfault_handler(struct trapframe *frame);
static int trap_pfault(struct trapframe *, int);
static void trap_fatal(struct trapframe *, vm_offset_t);
-void dblfault_handler(void);
#define MAX_TRAP_MSG 30
static char *trap_msg[] = {
@@ -706,9 +706,12 @@ trap_fatal(frame, eva)
* for example).
*/
void
-dblfault_handler()
+dblfault_handler(struct trapframe *frame)
{
printf("\nFatal double fault\n");
+ printf("rip = 0x%lx\n", frame->tf_rip);
+ printf("rsp = 0x%lx\n", frame->tf_rsp);
+ printf("rbp = 0x%lx\n", frame->tf_rbp);
#ifdef SMP
/* two separate prints in case of a trap on an unmapped page */
printf("cpuid = %d; ", PCPU_GET(cpuid));
OpenPOWER on IntegriCloud