debuggers.hg

view xen/arch/x86/x86_64/traps.c @ 3668:d55d523078f7

bitkeeper revision 1.1159.212.77 (4202221693AFbvFZWeMHHIjQfbzTIQ)

More x86_64 prgress. Many more gaps filled in. Next step is DOM0
construction.
Signed-off-by: keir.fraser@cl.cam.ac.uk
author kaf24@scramble.cl.cam.ac.uk
date Thu Feb 03 13:07:34 2005 +0000 (2005-02-03)
parents bf2c38625b39
children bbe8541361dd 8c6281ec8860
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/errno.h>
7 #include <xen/mm.h>
8 #include <xen/irq.h>
9 #include <xen/console.h>
11 static int kstack_depth_to_print = 8*20;
13 static inline int kernel_text_address(unsigned long addr)
14 {
15 if (addr >= (unsigned long) &_stext &&
16 addr <= (unsigned long) &_etext)
17 return 1;
18 return 0;
20 }
22 void show_guest_stack(void)
23 {
24 int i;
25 execution_context_t *ec = get_execution_context();
26 unsigned long *stack = (unsigned long *)ec->rsp;
27 printk("Guest RIP is %lx\n ", ec->rip);
29 for ( i = 0; i < kstack_depth_to_print; i++ )
30 {
31 if ( ((long)stack & (STACK_SIZE-1)) == 0 )
32 break;
33 if ( i && ((i % 8) == 0) )
34 printk("\n ");
35 printk("%p ", *stack++);
36 }
37 printk("\n");
39 }
41 void show_trace(unsigned long *rsp)
42 {
43 unsigned long *stack, addr;
44 int i;
46 printk("Call Trace from RSP=%p:\n ", rsp);
47 stack = rsp;
48 i = 0;
49 while (((long) stack & (STACK_SIZE-1)) != 0) {
50 addr = *stack++;
51 if (kernel_text_address(addr)) {
52 if (i && ((i % 6) == 0))
53 printk("\n ");
54 printk("[<%p>] ", addr);
55 i++;
56 }
57 }
58 printk("\n");
59 }
61 void show_stack(unsigned long *rsp)
62 {
63 unsigned long *stack;
64 int i;
66 printk("Stack trace from RSP=%p:\n ", rsp);
68 stack = rsp;
69 for ( i = 0; i < kstack_depth_to_print; i++ )
70 {
71 if ( ((long)stack & (STACK_SIZE-1)) == 0 )
72 break;
73 if ( i && ((i % 8) == 0) )
74 printk("\n ");
75 if ( kernel_text_address(*stack) )
76 printk("[%p] ", *stack++);
77 else
78 printk("%p ", *stack++);
79 }
80 printk("\n");
82 show_trace(rsp);
83 }
85 void show_registers(struct xen_regs *regs)
86 {
87 printk("CPU: %d\nEIP: %04lx:[<%p>] \nEFLAGS: %p\n",
88 smp_processor_id(), 0xffff & regs->cs, regs->rip, regs->eflags);
89 printk("rax: %p rbx: %p rcx: %p rdx: %p\n",
90 regs->rax, regs->rbx, regs->rcx, regs->rdx);
91 printk("rsi: %p rdi: %p rbp: %p rsp: %p\n",
92 regs->rsi, regs->rdi, regs->rbp, regs->rsp);
93 printk("r8: %p r9: %p r10: %p r11: %p\n",
94 regs->r8, regs->r9, regs->r10, regs->r11);
95 printk("r12: %p r13: %p r14: %p r15: %p\n",
96 regs->r12, regs->r13, regs->r14, regs->r15);
98 show_stack((unsigned long *)regs->rsp);
99 }
101 void show_page_walk(unsigned long addr)
102 {
103 unsigned long page = read_cr3();
105 printk("Pagetable walk from %p:\n", addr);
107 page &= PAGE_MASK;
108 page = ((unsigned long *) __va(page))[l4_table_offset(addr)];
109 printk(" L4 = %p\n", page);
110 if ( !(page & _PAGE_PRESENT) )
111 return;
113 page &= PAGE_MASK;
114 page = ((unsigned long *) __va(page))[l3_table_offset(addr)];
115 printk(" L3 = %p\n", page);
116 if ( !(page & _PAGE_PRESENT) )
117 return;
119 page &= PAGE_MASK;
120 page = ((unsigned long *) __va(page))[l2_table_offset(addr)];
121 printk(" L2 = %p %s\n", page, (page & _PAGE_PSE) ? "(2MB)" : "");
122 if ( !(page & _PAGE_PRESENT) || (page & _PAGE_PSE) )
123 return;
125 page &= PAGE_MASK;
126 page = ((unsigned long *) __va(page))[l1_table_offset(addr)];
127 printk(" L1 = %p\n", page);
128 }
130 #define DOUBLEFAULT_STACK_SIZE 1024
131 static unsigned char doublefault_stack[DOUBLEFAULT_STACK_SIZE];
132 asmlinkage void double_fault(void);
134 asmlinkage void do_double_fault(struct xen_regs *regs)
135 {
136 /* Disable the NMI watchdog. It's useless now. */
137 watchdog_on = 0;
139 /* Find information saved during fault and dump it to the console. */
140 printk("************************************\n");
141 printk("EIP: %04lx:[<%p>] \nEFLAGS: %p\n",
142 0xffff & regs->cs, regs->rip, regs->eflags);
143 printk("rax: %p rbx: %p rcx: %p rdx: %p\n",
144 regs->rax, regs->rbx, regs->rcx, regs->rdx);
145 printk("rsi: %p rdi: %p rbp: %p rsp: %p\n",
146 regs->rsi, regs->rdi, regs->rbp, regs->rsp);
147 printk("r8: %p r9: %p r10: %p r11: %p\n",
148 regs->r8, regs->r9, regs->r10, regs->r11);
149 printk("r12: %p r13: %p r14: %p r15: %p\n",
150 regs->r12, regs->r13, regs->r14, regs->r15);
151 printk("************************************\n");
152 printk("CPU%d DOUBLE FAULT -- system shutdown\n",
153 logical_smp_processor_id());
154 printk("System needs manual reset.\n");
155 printk("************************************\n");
157 /* Lock up the console to prevent spurious output from other CPUs. */
158 console_force_lock();
160 /* Wait for manual reset. */
161 for ( ; ; )
162 __asm__ __volatile__ ( "hlt" );
163 }
165 void __init doublefault_init(void)
166 {
167 int i;
169 /* Initialise IST1 for each CPU. Note the handler is non-reentrant. */
170 for ( i = 0; i < NR_CPUS; i++ )
171 init_tss[i].ist[0] = (unsigned long)
172 &doublefault_stack[DOUBLEFAULT_STACK_SIZE];
174 /* Set interrupt gate for double faults, specifying IST1. */
175 set_intr_gate(TRAP_double_fault, &double_fault);
176 idt_table[TRAP_double_fault].a |= 1UL << 32; /* IST1 */
177 }
179 void *decode_reg(struct xen_regs *regs, u8 b)
180 {
181 switch ( b )
182 {
183 case 0: return &regs->rax;
184 case 1: return &regs->rcx;
185 case 2: return &regs->rdx;
186 case 3: return &regs->rbx;
187 case 4: return &regs->rsp;
188 case 5: return &regs->rbp;
189 case 6: return &regs->rsi;
190 case 7: return &regs->rdi;
191 case 8: return &regs->r8;
192 case 9: return &regs->r9;
193 case 10: return &regs->r10;
194 case 11: return &regs->r11;
195 case 12: return &regs->r12;
196 case 13: return &regs->r13;
197 case 14: return &regs->r14;
198 case 15: return &regs->r15;
199 }
201 return NULL;
202 }