Magellan Linux

Annotation of /trunk/kernel26-xen/patches-2.6.25-r1/1034-2.6.25-xen-stack-unwind.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 609 - (hide annotations) (download)
Fri May 23 17:35:37 2008 UTC (16 years ago) by niro
File size: 8838 byte(s)
-using opensuse xen patchset, updated kernel configs

1 niro 609 Subject: DWARF2 EH-frame based stack unwinding
2     From: jbeulich@novell.com
3     Patch-mainline: no
4    
5     Automatically created from "patches.suse/stack-unwind" by xen-port-patches.py
6    
7     Index: head-2008-03-06/arch/x86/kernel/entry_32-xen.S
8     ===================================================================
9     --- head-2008-03-06.orig/arch/x86/kernel/entry_32-xen.S 2008-03-06 10:51:44.000000000 +0100
10     +++ head-2008-03-06/arch/x86/kernel/entry_32-xen.S 2008-03-06 10:52:39.000000000 +0100
11     @@ -1252,6 +1252,38 @@ ENTRY(fixup_4gb_segment)
12     CFI_ENDPROC
13     END(spurious_interrupt_bug)
14    
15     +#ifdef CONFIG_STACK_UNWIND
16     +ENTRY(arch_unwind_init_running)
17     + CFI_STARTPROC
18     + movl 4(%esp), %edx
19     + movl (%esp), %ecx
20     + leal 4(%esp), %eax
21     + movl %ebx, PT_EBX(%edx)
22     + xorl %ebx, %ebx
23     + movl %ebx, PT_ECX(%edx)
24     + movl %ebx, PT_EDX(%edx)
25     + movl %esi, PT_ESI(%edx)
26     + movl %edi, PT_EDI(%edx)
27     + movl %ebp, PT_EBP(%edx)
28     + movl %ebx, PT_EAX(%edx)
29     + movl $__USER_DS, PT_DS(%edx)
30     + movl $__USER_DS, PT_ES(%edx)
31     + movl $__KERNEL_PERCPU, PT_FS(%edx)
32     + movl %ebx, PT_ORIG_EAX(%edx)
33     + movl %ecx, PT_EIP(%edx)
34     + movl 12(%esp), %ecx
35     + movl $__KERNEL_CS, PT_CS(%edx)
36     + movl %ebx, PT_EFLAGS(%edx)
37     + movl %eax, PT_OLDESP(%edx)
38     + movl 8(%esp), %eax
39     + movl %ecx, 8(%esp)
40     + movl PT_EBX(%edx), %ebx
41     + movl $__KERNEL_DS, PT_OLDSS(%edx)
42     + jmpl *%eax
43     + CFI_ENDPROC
44     +ENDPROC(arch_unwind_init_running)
45     +#endif
46     +
47     ENTRY(kernel_thread_helper)
48     pushl $0 # fake return address for unwinder
49     CFI_STARTPROC
50     Index: head-2008-03-06/arch/x86/kernel/entry_64-xen.S
51     ===================================================================
52     --- head-2008-03-06.orig/arch/x86/kernel/entry_64-xen.S 2008-03-06 10:52:04.000000000 +0100
53     +++ head-2008-03-06/arch/x86/kernel/entry_64-xen.S 2008-03-06 10:52:39.000000000 +0100
54     @@ -1258,3 +1258,36 @@ KPROBE_ENTRY(ignore_sysret)
55     HYPERVISOR_IRET 0
56     CFI_ENDPROC
57     ENDPROC(ignore_sysret)
58     +
59     +#ifdef CONFIG_STACK_UNWIND
60     +ENTRY(arch_unwind_init_running)
61     + CFI_STARTPROC
62     + movq %r15, R15(%rdi)
63     + movq %r14, R14(%rdi)
64     + xchgq %rsi, %rdx
65     + movq %r13, R13(%rdi)
66     + movq %r12, R12(%rdi)
67     + xorl %eax, %eax
68     + movq %rbp, RBP(%rdi)
69     + movq %rbx, RBX(%rdi)
70     + movq (%rsp), %rcx
71     + movq %rax, R11(%rdi)
72     + movq %rax, R10(%rdi)
73     + movq %rax, R9(%rdi)
74     + movq %rax, R8(%rdi)
75     + movq %rax, RAX(%rdi)
76     + movq %rax, RCX(%rdi)
77     + movq %rax, RDX(%rdi)
78     + movq %rax, RSI(%rdi)
79     + movq %rax, RDI(%rdi)
80     + movq %rax, ORIG_RAX(%rdi)
81     + movq %rcx, RIP(%rdi)
82     + leaq 8(%rsp), %rcx
83     + movq $__KERNEL_CS, CS(%rdi)
84     + movq %rax, EFLAGS(%rdi)
85     + movq %rcx, RSP(%rdi)
86     + movq $__KERNEL_DS, SS(%rdi)
87     + jmpq *%rdx
88     + CFI_ENDPROC
89     +ENDPROC(arch_unwind_init_running)
90     +#endif
91     Index: head-2008-03-06/arch/x86/kernel/traps_32-xen.c
92     ===================================================================
93     --- head-2008-03-06.orig/arch/x86/kernel/traps_32-xen.c 2008-03-06 10:52:38.000000000 +0100
94     +++ head-2008-03-06/arch/x86/kernel/traps_32-xen.c 2008-03-06 10:52:39.000000000 +0100
95     @@ -109,6 +109,11 @@ asmlinkage void machine_check(void);
96    
97     int kstack_depth_to_print = 24;
98     static unsigned int code_bytes = 64;
99     +#ifdef CONFIG_STACK_UNWIND
100     +static int call_trace = 1;
101     +#else
102     +#define call_trace (-1)
103     +#endif
104    
105     void printk_address(unsigned long address, int reliable)
106     {
107     @@ -174,7 +179,32 @@ static inline unsigned long print_contex
108     return bp;
109     }
110    
111     -#define MSG(msg) ops->warning(data, msg)
112     +struct ops_and_data {
113     + const struct stacktrace_ops *ops;
114     + void *data;
115     +};
116     +
117     +static asmlinkage int
118     +dump_trace_unwind(struct unwind_frame_info *info, void *data)
119     +{
120     + struct ops_and_data *oad = (struct ops_and_data *)data;
121     + int n = 0;
122     + unsigned long sp = UNW_SP(info);
123     +
124     + if (arch_unw_user_mode(info))
125     + return -1;
126     + while (unwind(info) == 0 && UNW_PC(info)) {
127     + n++;
128     + oad->ops->address(oad->data, UNW_PC(info), 1);
129     + if (arch_unw_user_mode(info))
130     + break;
131     + if ((sp & ~(PAGE_SIZE - 1)) == (UNW_SP(info) & ~(PAGE_SIZE - 1))
132     + && sp > UNW_SP(info))
133     + break;
134     + sp = UNW_SP(info);
135     + }
136     + return n;
137     +}
138    
139     void dump_trace(struct task_struct *task, struct pt_regs *regs,
140     unsigned long *stack, unsigned long bp,
141     @@ -183,6 +213,40 @@ void dump_trace(struct task_struct *task
142     if (!task)
143     task = current;
144    
145     + if (call_trace >= 0) {
146     + int unw_ret = 0;
147     + struct unwind_frame_info info;
148     + struct ops_and_data oad = { .ops = ops, .data = data };
149     +
150     + if (regs) {
151     + if (unwind_init_frame_info(&info, task, regs) == 0)
152     + unw_ret = dump_trace_unwind(&info, &oad);
153     + } else if (task == current)
154     + unw_ret = unwind_init_running(&info, dump_trace_unwind, &oad);
155     + else {
156     + if (unwind_init_blocked(&info, task) == 0)
157     + unw_ret = dump_trace_unwind(&info, &oad);
158     + }
159     + if (unw_ret > 0) {
160     + if (call_trace == 1 && !arch_unw_user_mode(&info)) {
161     + ops->warning_symbol(data, "DWARF2 unwinder stuck at %s\n",
162     + UNW_PC(&info));
163     + if (UNW_SP(&info) >= PAGE_OFFSET) {
164     + ops->warning(data, "Leftover inexact backtrace:\n");
165     + stack = (void *)UNW_SP(&info);
166     + if (!stack)
167     + return;
168     + bp = UNW_FP(&info);
169     + } else
170     + ops->warning(data, "Full inexact backtrace again:\n");
171     + } else if (call_trace >= 1)
172     + return;
173     + else
174     + ops->warning(data, "Full inexact backtrace again:\n");
175     + } else
176     + ops->warning(data, "Inexact backtrace:\n");
177     + }
178     +
179     if (!stack) {
180     unsigned long dummy;
181     stack = &dummy;
182     @@ -1197,3 +1261,19 @@ static int __init code_bytes_setup(char
183     return 1;
184     }
185     __setup("code_bytes=", code_bytes_setup);
186     +
187     +#ifdef CONFIG_STACK_UNWIND
188     +static int __init call_trace_setup(char *s)
189     +{
190     + if (strcmp(s, "old") == 0)
191     + call_trace = -1;
192     + else if (strcmp(s, "both") == 0)
193     + call_trace = 0;
194     + else if (strcmp(s, "newfallback") == 0)
195     + call_trace = 1;
196     + else if (strcmp(s, "new") == 2)
197     + call_trace = 2;
198     + return 1;
199     +}
200     +__setup("call_trace=", call_trace_setup);
201     +#endif
202     Index: head-2008-03-06/arch/x86/kernel/traps_64-xen.c
203     ===================================================================
204     --- head-2008-03-06.orig/arch/x86/kernel/traps_64-xen.c 2008-03-06 10:52:38.000000000 +0100
205     +++ head-2008-03-06/arch/x86/kernel/traps_64-xen.c 2008-03-06 10:52:39.000000000 +0100
206     @@ -99,6 +99,11 @@ static inline void preempt_conditional_c
207     }
208    
209     int kstack_depth_to_print = 12;
210     +#ifdef CONFIG_STACK_UNWIND
211     +static int call_trace = 1;
212     +#else
213     +#define call_trace (-1)
214     +#endif
215    
216     void printk_address(unsigned long address, int reliable)
217     {
218     @@ -204,7 +209,31 @@ static unsigned long *in_exception_stack
219     return NULL;
220     }
221    
222     -#define MSG(txt) ops->warning(data, txt)
223     +struct ops_and_data {
224     + const struct stacktrace_ops *ops;
225     + void *data;
226     +};
227     +
228     +static int dump_trace_unwind(struct unwind_frame_info *info, void *context)
229     +{
230     + struct ops_and_data *oad = (struct ops_and_data *)context;
231     + int n = 0;
232     + unsigned long sp = UNW_SP(info);
233     +
234     + if (arch_unw_user_mode(info))
235     + return -1;
236     + while (unwind(info) == 0 && UNW_PC(info)) {
237     + n++;
238     + oad->ops->address(oad->data, UNW_PC(info), 1);
239     + if (arch_unw_user_mode(info))
240     + break;
241     + if ((sp & ~(PAGE_SIZE - 1)) == (UNW_SP(info) & ~(PAGE_SIZE - 1))
242     + && sp > UNW_SP(info))
243     + break;
244     + sp = UNW_SP(info);
245     + }
246     + return n;
247     +}
248    
249     /*
250     * x86-64 can have up to three kernel stacks:
251     @@ -271,6 +300,39 @@ void dump_trace(struct task_struct *tsk,
252     tsk = current;
253     tinfo = task_thread_info(tsk);
254    
255     + if (call_trace >= 0) {
256     + int unw_ret = 0;
257     + struct unwind_frame_info info;
258     + struct ops_and_data oad = { .ops = ops, .data = data };
259     +
260     + if (regs) {
261     + if (unwind_init_frame_info(&info, tsk, regs) == 0)
262     + unw_ret = dump_trace_unwind(&info, &oad);
263     + } else if (tsk == current)
264     + unw_ret = unwind_init_running(&info, dump_trace_unwind, &oad);
265     + else {
266     + if (unwind_init_blocked(&info, tsk) == 0)
267     + unw_ret = dump_trace_unwind(&info, &oad);
268     + }
269     + if (unw_ret > 0) {
270     + if (call_trace == 1 && !arch_unw_user_mode(&info)) {
271     + ops->warning_symbol(data, "DWARF2 unwinder stuck at %s\n",
272     + UNW_PC(&info));
273     + if ((long)UNW_SP(&info) < 0) {
274     + ops->warning(data, "Leftover inexact backtrace:\n");
275     + stack = (unsigned long *)UNW_SP(&info);
276     + if (!stack)
277     + return;
278     + } else
279     + ops->warning(data, "Full inexact backtrace again:\n");
280     + } else if (call_trace >= 1)
281     + return;
282     + else
283     + ops->warning(data, "Full inexact backtrace again:\n");
284     + } else
285     + ops->warning(data, "Inexact backtrace:\n");
286     + }
287     +
288     if (!stack) {
289     unsigned long dummy;
290     stack = &dummy;
291     @@ -1215,3 +1277,21 @@ static int __init code_bytes_setup(char
292     return 1;
293     }
294     __setup("code_bytes=", code_bytes_setup);
295     +
296     +#ifdef CONFIG_STACK_UNWIND
297     +static int __init call_trace_setup(char *s)
298     +{
299     + if (!s)
300     + return -EINVAL;
301     + if (strcmp(s, "old") == 0)
302     + call_trace = -1;
303     + else if (strcmp(s, "both") == 0)
304     + call_trace = 0;
305     + else if (strcmp(s, "newfallback") == 0)
306     + call_trace = 1;
307     + else if (strcmp(s, "new") == 0)
308     + call_trace = 2;
309     + return 0;
310     +}
311     +early_param("call_trace", call_trace_setup);
312     +#endif