diff options
author | jhb <jhb@FreeBSD.org> | 2007-11-15 22:00:57 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2007-11-15 22:00:57 +0000 |
commit | bca11bf48fe38cb4822925e995f9b1be648fcc2a (patch) | |
tree | ede94b8163bb9be49c9615431eac45cfed8c0e91 | |
parent | b113160d81ef70bc2778ca6510430e65ba9232f3 (diff) | |
download | FreeBSD-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.c | 3 | ||||
-rw-r--r-- | sys/amd64/amd64/exception.S | 20 | ||||
-rw-r--r-- | sys/amd64/amd64/machdep.c | 1 | ||||
-rw-r--r-- | sys/amd64/amd64/trap.c | 7 |
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)); |