|
16 | 16 |
|
17 | 17 | #include <asm/stacktrace.h>
|
18 | 18 |
|
| 19 | +static char *exception_stack_names[N_EXCEPTION_STACKS] = { |
| 20 | + [ DOUBLEFAULT_STACK-1 ] = "#DF", |
| 21 | + [ NMI_STACK-1 ] = "NMI", |
| 22 | + [ DEBUG_STACK-1 ] = "#DB", |
| 23 | + [ MCE_STACK-1 ] = "#MC", |
| 24 | +}; |
19 | 25 |
|
20 |
| -#define N_EXCEPTION_STACKS_END \ |
21 |
| - (N_EXCEPTION_STACKS + DEBUG_STKSZ/EXCEPTION_STKSZ - 2) |
22 |
| - |
23 |
| -static char x86_stack_ids[][8] = { |
24 |
| - [ DEBUG_STACK-1 ] = "#DB", |
25 |
| - [ NMI_STACK-1 ] = "NMI", |
26 |
| - [ DOUBLEFAULT_STACK-1 ] = "#DF", |
27 |
| - [ MCE_STACK-1 ] = "#MC", |
28 |
| -#if DEBUG_STKSZ > EXCEPTION_STKSZ |
29 |
| - [ N_EXCEPTION_STACKS ... |
30 |
| - N_EXCEPTION_STACKS_END ] = "#DB[?]" |
31 |
| -#endif |
| 26 | +static unsigned long exception_stack_sizes[N_EXCEPTION_STACKS] = { |
| 27 | + [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STKSZ, |
| 28 | + [DEBUG_STACK - 1] = DEBUG_STKSZ |
32 | 29 | };
|
33 | 30 |
|
34 | 31 | static unsigned long *in_exception_stack(unsigned long stack, unsigned *usedp,
|
35 | 32 | char **idp)
|
36 | 33 | {
|
| 34 | + unsigned long begin, end; |
37 | 35 | unsigned k;
|
38 | 36 |
|
39 |
| - /* |
40 |
| - * Iterate over all exception stacks, and figure out whether |
41 |
| - * 'stack' is in one of them: |
42 |
| - */ |
| 37 | + BUILD_BUG_ON(N_EXCEPTION_STACKS != 4); |
| 38 | + |
43 | 39 | for (k = 0; k < N_EXCEPTION_STACKS; k++) {
|
44 |
| - unsigned long end = raw_cpu_ptr(&orig_ist)->ist[k]; |
45 |
| - /* |
46 |
| - * Is 'stack' above this exception frame's end? |
47 |
| - * If yes then skip to the next frame. |
48 |
| - */ |
49 |
| - if (stack >= end) |
| 40 | + end = raw_cpu_ptr(&orig_ist)->ist[k]; |
| 41 | + begin = end - exception_stack_sizes[k]; |
| 42 | + |
| 43 | + if (stack < begin || stack >= end) |
50 | 44 | continue;
|
| 45 | + |
51 | 46 | /*
|
52 |
| - * Is 'stack' above this exception frame's start address? |
53 |
| - * If yes then we found the right frame. |
54 |
| - */ |
55 |
| - if (stack >= end - EXCEPTION_STKSZ) { |
56 |
| - /* |
57 |
| - * Make sure we only iterate through an exception |
58 |
| - * stack once. If it comes up for the second time |
59 |
| - * then there's something wrong going on - just |
60 |
| - * break out and return NULL: |
61 |
| - */ |
62 |
| - if (*usedp & (1U << k)) |
63 |
| - break; |
64 |
| - *usedp |= 1U << k; |
65 |
| - *idp = x86_stack_ids[k]; |
66 |
| - return (unsigned long *)end; |
67 |
| - } |
68 |
| - /* |
69 |
| - * If this is a debug stack, and if it has a larger size than |
70 |
| - * the usual exception stacks, then 'stack' might still |
71 |
| - * be within the lower portion of the debug stack: |
| 47 | + * Make sure we only iterate through an exception stack once. |
| 48 | + * If it comes up for the second time then there's something |
| 49 | + * wrong going on - just break and return NULL: |
72 | 50 | */
|
73 |
| -#if DEBUG_STKSZ > EXCEPTION_STKSZ |
74 |
| - if (k == DEBUG_STACK - 1 && stack >= end - DEBUG_STKSZ) { |
75 |
| - unsigned j = N_EXCEPTION_STACKS - 1; |
| 51 | + if (*usedp & (1U << k)) |
| 52 | + break; |
| 53 | + *usedp |= 1U << k; |
76 | 54 |
|
77 |
| - /* |
78 |
| - * Black magic. A large debug stack is composed of |
79 |
| - * multiple exception stack entries, which we |
80 |
| - * iterate through now. Dont look: |
81 |
| - */ |
82 |
| - do { |
83 |
| - ++j; |
84 |
| - end -= EXCEPTION_STKSZ; |
85 |
| - x86_stack_ids[j][4] = '1' + |
86 |
| - (j - N_EXCEPTION_STACKS); |
87 |
| - } while (stack < end - EXCEPTION_STKSZ); |
88 |
| - if (*usedp & (1U << j)) |
89 |
| - break; |
90 |
| - *usedp |= 1U << j; |
91 |
| - *idp = x86_stack_ids[j]; |
92 |
| - return (unsigned long *)end; |
93 |
| - } |
94 |
| -#endif |
| 55 | + *idp = exception_stack_names[k]; |
| 56 | + return (unsigned long *)end; |
95 | 57 | }
|
| 58 | + |
96 | 59 | return NULL;
|
97 | 60 | }
|
98 | 61 |
|
|
0 commit comments