debuggers.hg

view xen/arch/x86/x86_32/traps.c @ 3645:fd1dd0663b09

bitkeeper revision 1.1159.212.68 (42001e4d1AQiGV2pdPTNrs2AU2LjsQ)

Merge pb001.cl.cam.ac.uk:/auto/groups/xeno-xenod/BK/xen-unstable.bk
into pb001.cl.cam.ac.uk:/auto/groups/xeno/users/iap10/xeno-clone/xen-unstable.bk
author iap10@pb001.cl.cam.ac.uk
date Wed Feb 02 00:26:53 2005 +0000 (2005-02-02)
parents e6af5d8f8b39
children bf2c38625b39
line source
2 #include <xen/config.h>
3 #include <xen/init.h>
4 #include <xen/sched.h>
5 #include <xen/lib.h>
6 #include <xen/console.h>
7 #include <xen/mm.h>
8 #include <xen/irq.h>
10 static int kstack_depth_to_print = 8*20;
12 static inline int kernel_text_address(unsigned long addr)
13 {
14 if (addr >= (unsigned long) &_stext &&
15 addr <= (unsigned long) &_etext)
16 return 1;
17 return 0;
19 }
21 void show_guest_stack(void)
22 {
23 int i;
24 execution_context_t *ec = get_execution_context();
25 unsigned long *stack = (unsigned long *)ec->esp;
26 printk("Guest EIP is %lx\n",ec->eip);
28 for ( i = 0; i < kstack_depth_to_print; i++ )
29 {
30 if ( ((long)stack & (STACK_SIZE-1)) == 0 )
31 break;
32 if ( i && ((i % 8) == 0) )
33 printk("\n ");
34 printk("%08lx ", *stack++);
35 }
36 printk("\n");
38 }
40 void show_trace(unsigned long *esp)
41 {
42 unsigned long *stack, addr;
43 int i;
45 printk("Call Trace from ESP=%p: ", esp);
46 stack = esp;
47 i = 0;
48 while (((long) stack & (STACK_SIZE-1)) != 0) {
49 addr = *stack++;
50 if (kernel_text_address(addr)) {
51 if (i && ((i % 6) == 0))
52 printk("\n ");
53 printk("[<%08lx>] ", addr);
54 i++;
55 }
56 }
57 printk("\n");
58 }
60 void show_stack(unsigned long *esp)
61 {
62 unsigned long *stack;
63 int i;
65 printk("Stack trace from ESP=%p:\n", esp);
67 stack = esp;
68 for ( i = 0; i < kstack_depth_to_print; i++ )
69 {
70 if ( ((long)stack & (STACK_SIZE-1)) == 0 )
71 break;
72 if ( i && ((i % 8) == 0) )
73 printk("\n ");
74 if ( kernel_text_address(*stack) )
75 printk("[%08lx] ", *stack++);
76 else
77 printk("%08lx ", *stack++);
78 }
79 printk("\n");
81 show_trace( esp );
82 }
84 void show_registers(struct xen_regs *regs)
85 {
86 unsigned long esp;
87 unsigned short ss, ds, es, fs, gs;
89 if ( GUEST_FAULT(regs) )
90 {
91 esp = regs->esp;
92 ss = regs->ss & 0xffff;
93 ds = regs->ds & 0xffff;
94 es = regs->es & 0xffff;
95 fs = regs->fs & 0xffff;
96 gs = regs->gs & 0xffff;
97 }
98 else
99 {
100 esp = (unsigned long)(&regs->esp);
101 ss = __HYPERVISOR_DS;
102 ds = __HYPERVISOR_DS;
103 es = __HYPERVISOR_DS;
104 fs = __HYPERVISOR_DS;
105 gs = __HYPERVISOR_DS;
106 }
108 printk("CPU: %d\nEIP: %04lx:[<%08lx>] \nEFLAGS: %08lx\n",
109 smp_processor_id(), 0xffff & regs->cs, regs->eip, regs->eflags);
110 printk("eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n",
111 regs->eax, regs->ebx, regs->ecx, regs->edx);
112 printk("esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n",
113 regs->esi, regs->edi, regs->ebp, esp);
114 printk("ds: %04x es: %04x fs: %04x gs: %04x ss: %04x\n",
115 ds, es, fs, gs, ss);
117 show_stack((unsigned long *)&regs->esp);
118 }
120 #define DOUBLEFAULT_STACK_SIZE 1024
121 static struct tss_struct doublefault_tss;
122 static unsigned char doublefault_stack[DOUBLEFAULT_STACK_SIZE];
124 asmlinkage void do_double_fault(void)
125 {
126 struct tss_struct *tss = &doublefault_tss;
127 unsigned int cpu = ((tss->back_link>>3)-__FIRST_TSS_ENTRY)>>1;
129 /* Disable the NMI watchdog. It's useless now. */
130 watchdog_on = 0;
132 /* Find information saved during fault and dump it to the console. */
133 tss = &init_tss[cpu];
134 printk("CPU: %d\nEIP: %04x:[<%08x>] \nEFLAGS: %08x\n",
135 cpu, tss->cs, tss->eip, tss->eflags);
136 printk("CR3: %08x\n", tss->__cr3);
137 printk("eax: %08x ebx: %08x ecx: %08x edx: %08x\n",
138 tss->eax, tss->ebx, tss->ecx, tss->edx);
139 printk("esi: %08x edi: %08x ebp: %08x esp: %08x\n",
140 tss->esi, tss->edi, tss->ebp, tss->esp);
141 printk("ds: %04x es: %04x fs: %04x gs: %04x ss: %04x\n",
142 tss->ds, tss->es, tss->fs, tss->gs, tss->ss);
143 printk("************************************\n");
144 printk("CPU%d DOUBLE FAULT -- system shutdown\n", cpu);
145 printk("System needs manual reset.\n");
146 printk("************************************\n");
148 /* Lock up the console to prevent spurious output from other CPUs. */
149 console_force_lock();
151 /* Wait for manual reset. */
152 for ( ; ; )
153 __asm__ __volatile__ ( "hlt" );
154 }
156 void __init doublefault_init(void)
157 {
158 /*
159 * Make a separate task for double faults. This will get us debug output if
160 * we blow the kernel stack.
161 */
162 struct tss_struct *tss = &doublefault_tss;
163 memset(tss, 0, sizeof(*tss));
164 tss->ds = __HYPERVISOR_DS;
165 tss->es = __HYPERVISOR_DS;
166 tss->ss = __HYPERVISOR_DS;
167 tss->esp = (unsigned long)
168 &doublefault_stack[DOUBLEFAULT_STACK_SIZE];
169 tss->__cr3 = __pa(idle_pg_table);
170 tss->cs = __HYPERVISOR_CS;
171 tss->eip = (unsigned long)do_double_fault;
172 tss->eflags = 2;
173 tss->bitmap = IOBMP_INVALID_OFFSET;
174 _set_tssldt_desc(gdt_table+__DOUBLEFAULT_TSS_ENTRY,
175 (int)tss, 235, 0x89);
176 }
178 long set_fast_trap(struct exec_domain *p, int idx)
179 {
180 trap_info_t *ti;
182 /* Index 0 is special: it disables fast traps. */
183 if ( idx == 0 )
184 {
185 if ( p == current )
186 CLEAR_FAST_TRAP(&p->thread);
187 SET_DEFAULT_FAST_TRAP(&p->thread);
188 return 0;
189 }
191 /*
192 * We only fast-trap vectors 0x20-0x2f, and vector 0x80.
193 * The former range is used by Windows and MS-DOS.
194 * Vector 0x80 is used by Linux and the BSD variants.
195 */
196 if ( (idx != 0x80) && ((idx < 0x20) || (idx > 0x2f)) )
197 return -1;
199 ti = p->thread.traps + idx;
201 /*
202 * We can't virtualise interrupt gates, as there's no way to get
203 * the CPU to automatically clear the events_mask variable.
204 */
205 if ( TI_GET_IF(ti) )
206 return -1;
208 if ( p == current )
209 CLEAR_FAST_TRAP(&p->thread);
211 p->thread.fast_trap_idx = idx;
212 p->thread.fast_trap_desc.a = (ti->cs << 16) | (ti->address & 0xffff);
213 p->thread.fast_trap_desc.b =
214 (ti->address & 0xffff0000) | 0x8f00 | (TI_GET_DPL(ti)&3)<<13;
216 if ( p == current )
217 SET_FAST_TRAP(&p->thread);
219 return 0;
220 }
223 long do_set_fast_trap(int idx)
224 {
225 return set_fast_trap(current, idx);
226 }