Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 100
b: refs/heads/master
c: 0a65800
h: refs/heads/master
v: v3
  • Loading branch information
Andi Kleen authored and Linus Torvalds committed Apr 16, 2005
1 parent 04430f3 commit 310c9fe
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 69 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 635186447d0e6f3b35895fda993a266a1315d2a7
refs/heads/master: 0a65800243742480b4b594b619b759749a3cfef4
147 changes: 79 additions & 68 deletions trunk/arch/x86_64/kernel/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,95 +120,106 @@ int printk_address(unsigned long address)
}
#endif

unsigned long *in_exception_stack(int cpu, unsigned long stack)
{
int k;
static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
unsigned *usedp, const char **idp)
{
static const char ids[N_EXCEPTION_STACKS][8] = {
[DEBUG_STACK - 1] = "#DB",
[NMI_STACK - 1] = "NMI",
[DOUBLEFAULT_STACK - 1] = "#DF",
[STACKFAULT_STACK - 1] = "#SS",
[MCE_STACK - 1] = "#MC",
};
unsigned k;

for (k = 0; k < N_EXCEPTION_STACKS; k++) {
struct tss_struct *tss = &per_cpu(init_tss, cpu);
unsigned long start = tss->ist[k] - EXCEPTION_STKSZ;
unsigned long end;

if (stack >= start && stack < tss->ist[k])
return (unsigned long *)tss->ist[k];
end = per_cpu(init_tss, cpu).ist[k];
if (stack >= end)
continue;
if (stack >= end - EXCEPTION_STKSZ) {
if (*usedp & (1U << k))
break;
*usedp |= 1U << k;
*idp = ids[k];
return (unsigned long *)end;
}
}
return NULL;
}
}

/*
* x86-64 can have upto three kernel stacks:
* process stack
* interrupt stack
* severe exception (double fault, nmi, stack fault) hardware stack
* Check and process them in order.
* severe exception (double fault, nmi, stack fault, debug, mce) hardware stack
*/

void show_trace(unsigned long *stack)
{
unsigned long addr;
unsigned long *irqstack, *irqstack_end, *estack_end;
const int cpu = safe_smp_processor_id();
const unsigned cpu = safe_smp_processor_id();
unsigned long *irqstack_end = (unsigned long *)cpu_pda[cpu].irqstackptr;
int i;
unsigned used = 0;

printk("\nCall Trace:");
i = 0;

estack_end = in_exception_stack(cpu, (unsigned long)stack);
if (estack_end) {
while (stack < estack_end) {
addr = *stack++;
if (__kernel_text_address(addr)) {
i += printk_address(addr);
i += printk(" ");
if (i > 50) {
printk("\n");
i = 0;
}
}

#define HANDLE_STACK(cond) \
do while (cond) { \
addr = *stack++; \
if (kernel_text_address(addr)) { \
/* \
* If the address is either in the text segment of the \
* kernel, or in the region which contains vmalloc'ed \
* memory, it *may* be the address of a calling \
* routine; if so, print it so that someone tracing \
* down the cause of the crash will be able to figure \
* out the call path that was taken. \
*/ \
i += printk_address(addr); \
if (i > 50) { \
printk("\n "); \
i = 0; \
} \
else \
i += printk(" "); \
} \
} while (0)

for(i = 0; ; ) {
const char *id;
unsigned long *estack_end;
estack_end = in_exception_stack(cpu, (unsigned long)stack,
&used, &id);

if (estack_end) {
i += printk(" <%s> ", id);
HANDLE_STACK (stack < estack_end);
i += printk(" <EOE> ");
stack = (unsigned long *) estack_end[-2];
continue;
}
i += printk(" <EOE> ");
i += 7;
stack = (unsigned long *) estack_end[-2];
}

irqstack_end = (unsigned long *) (cpu_pda[cpu].irqstackptr);
irqstack = (unsigned long *) (cpu_pda[cpu].irqstackptr - IRQSTACKSIZE + 64);

if (stack >= irqstack && stack < irqstack_end) {
printk("<IRQ> ");
while (stack < irqstack_end) {
addr = *stack++;
/*
* If the address is either in the text segment of the
* kernel, or in the region which contains vmalloc'ed
* memory, it *may* be the address of a calling
* routine; if so, print it so that someone tracing
* down the cause of the crash will be able to figure
* out the call path that was taken.
*/
if (__kernel_text_address(addr)) {
i += printk_address(addr);
i += printk(" ");
if (i > 50) {
printk("\n ");
i = 0;
}
if (irqstack_end) {
unsigned long *irqstack;
irqstack = irqstack_end -
(IRQSTACKSIZE - 64) / sizeof(*irqstack);

if (stack >= irqstack && stack < irqstack_end) {
i += printk(" <IRQ> ");
HANDLE_STACK (stack < irqstack_end);
stack = (unsigned long *) (irqstack_end[-1]);
irqstack_end = NULL;
i += printk(" <EOI> ");
continue;
}
}
stack = (unsigned long *) (irqstack_end[-1]);
printk(" <EOI> ");
i += 7;
}

while (((long) stack & (THREAD_SIZE-1)) != 0) {
addr = *stack++;
if (__kernel_text_address(addr)) {
i += printk_address(addr);
i += printk(" ");
if (i > 50) {
printk("\n ");
i = 0;
}
}
break;
}

HANDLE_STACK (((long) stack & (THREAD_SIZE-1)) != 0);
#undef HANDLE_STACK
printk("\n");
}

Expand Down

0 comments on commit 310c9fe

Please sign in to comment.