.. | .. |
---|
29 | 29 | if (type == STACK_TYPE_ENTRY) |
---|
30 | 30 | return "ENTRY_TRAMPOLINE"; |
---|
31 | 31 | |
---|
| 32 | + if (type == STACK_TYPE_EXCEPTION) |
---|
| 33 | + return "#DF"; |
---|
| 34 | + |
---|
32 | 35 | return NULL; |
---|
33 | 36 | } |
---|
34 | 37 | |
---|
35 | 38 | static bool in_hardirq_stack(unsigned long *stack, struct stack_info *info) |
---|
36 | 39 | { |
---|
37 | | - unsigned long *begin = (unsigned long *)this_cpu_read(hardirq_stack); |
---|
| 40 | + unsigned long *begin = (unsigned long *)this_cpu_read(hardirq_stack_ptr); |
---|
38 | 41 | unsigned long *end = begin + (THREAD_SIZE / sizeof(long)); |
---|
39 | 42 | |
---|
40 | 43 | /* |
---|
41 | 44 | * This is a software stack, so 'end' can be a valid stack pointer. |
---|
42 | 45 | * It just means the stack is empty. |
---|
43 | 46 | */ |
---|
44 | | - if (stack <= begin || stack > end) |
---|
| 47 | + if (stack < begin || stack > end) |
---|
45 | 48 | return false; |
---|
46 | 49 | |
---|
47 | 50 | info->type = STACK_TYPE_IRQ; |
---|
.. | .. |
---|
59 | 62 | |
---|
60 | 63 | static bool in_softirq_stack(unsigned long *stack, struct stack_info *info) |
---|
61 | 64 | { |
---|
62 | | - unsigned long *begin = (unsigned long *)this_cpu_read(softirq_stack); |
---|
| 65 | + unsigned long *begin = (unsigned long *)this_cpu_read(softirq_stack_ptr); |
---|
63 | 66 | unsigned long *end = begin + (THREAD_SIZE / sizeof(long)); |
---|
64 | 67 | |
---|
65 | 68 | /* |
---|
66 | 69 | * This is a software stack, so 'end' can be a valid stack pointer. |
---|
67 | 70 | * It just means the stack is empty. |
---|
68 | 71 | */ |
---|
69 | | - if (stack <= begin || stack > end) |
---|
| 72 | + if (stack < begin || stack > end) |
---|
70 | 73 | return false; |
---|
71 | 74 | |
---|
72 | 75 | info->type = STACK_TYPE_SOFTIRQ; |
---|
.. | .. |
---|
81 | 84 | |
---|
82 | 85 | return true; |
---|
83 | 86 | } |
---|
| 87 | + |
---|
| 88 | +static bool in_doublefault_stack(unsigned long *stack, struct stack_info *info) |
---|
| 89 | +{ |
---|
| 90 | + struct cpu_entry_area *cea = get_cpu_entry_area(raw_smp_processor_id()); |
---|
| 91 | + struct doublefault_stack *ss = &cea->doublefault_stack; |
---|
| 92 | + |
---|
| 93 | + void *begin = ss->stack; |
---|
| 94 | + void *end = begin + sizeof(ss->stack); |
---|
| 95 | + |
---|
| 96 | + if ((void *)stack < begin || (void *)stack >= end) |
---|
| 97 | + return false; |
---|
| 98 | + |
---|
| 99 | + info->type = STACK_TYPE_EXCEPTION; |
---|
| 100 | + info->begin = begin; |
---|
| 101 | + info->end = end; |
---|
| 102 | + info->next_sp = (unsigned long *)this_cpu_read(cpu_tss_rw.x86_tss.sp); |
---|
| 103 | + |
---|
| 104 | + return true; |
---|
| 105 | +} |
---|
| 106 | + |
---|
84 | 107 | |
---|
85 | 108 | int get_stack_info(unsigned long *stack, struct task_struct *task, |
---|
86 | 109 | struct stack_info *info, unsigned long *visit_mask) |
---|
.. | .. |
---|
105 | 128 | if (in_softirq_stack(stack, info)) |
---|
106 | 129 | goto recursion_check; |
---|
107 | 130 | |
---|
| 131 | + if (in_doublefault_stack(stack, info)) |
---|
| 132 | + goto recursion_check; |
---|
| 133 | + |
---|
108 | 134 | goto unknown; |
---|
109 | 135 | |
---|
110 | 136 | recursion_check: |
---|