ia64/xen-unstable

view xen/arch/x86/x86_64/traps.c @ 3822:1413266e3117

bitkeeper revision 1.1196 (420e70da1IwWQhyIdvfGOYQgoJQsJA)

Fix SYSCALL RFLAGS mask.
Signed-off-by: keir@xensource.com
author kaf24@viper.(none)
date Sat Feb 12 21:10:50 2005 +0000 (2005-02-12)
parents 0069a2f1f55d
children be135facb9ee cf2f74cc53af a13b9052d91d a01199a95070
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>
10 #include <xen/sched.h>
11 #include <asm/msr.h>
13 static int kstack_depth_to_print = 8*20;
15 static inline int kernel_text_address(unsigned long addr)
16 {
17 if (addr >= (unsigned long) &_stext &&
18 addr <= (unsigned long) &_etext)
19 return 1;
20 return 0;
22 }
24 void show_guest_stack(void)
25 {
26 int i;
27 execution_context_t *ec = get_execution_context();
28 unsigned long *stack = (unsigned long *)ec->rsp;
29 printk("Guest RIP is %lx\n ", ec->rip);
31 for ( i = 0; i < kstack_depth_to_print; i++ )
32 {
33 if ( ((long)stack & (STACK_SIZE-1)) == 0 )
34 break;
35 if ( i && ((i % 8) == 0) )
36 printk("\n ");
37 printk("%p ", *stack++);
38 }
39 printk("\n");
41 }
43 void show_trace(unsigned long *rsp)
44 {
45 unsigned long *stack, addr;
46 int i;
48 printk("Call Trace from RSP=%p:\n ", rsp);
49 stack = rsp;
50 i = 0;
51 while (((long) stack & (STACK_SIZE-1)) != 0) {
52 addr = *stack++;
53 if (kernel_text_address(addr)) {
54 if (i && ((i % 6) == 0))
55 printk("\n ");
56 printk("[<%p>] ", addr);
57 i++;
58 }
59 }
60 printk("\n");
61 }
63 void show_stack(unsigned long *rsp)
64 {
65 unsigned long *stack;
66 int i;
68 printk("Stack trace from RSP=%p:\n ", rsp);
70 stack = rsp;
71 for ( i = 0; i < kstack_depth_to_print; i++ )
72 {
73 if ( ((long)stack & (STACK_SIZE-1)) == 0 )
74 break;
75 if ( i && ((i % 8) == 0) )
76 printk("\n ");
77 if ( kernel_text_address(*stack) )
78 printk("[%p] ", *stack++);
79 else
80 printk("%p ", *stack++);
81 }
82 printk("\n");
84 show_trace(rsp);
85 }
87 void show_registers(struct xen_regs *regs)
88 {
89 printk("CPU: %d\nEIP: %04lx:[<%p>] \nEFLAGS: %p\n",
90 smp_processor_id(), 0xffff & regs->cs, regs->rip, regs->eflags);
91 printk("rax: %p rbx: %p rcx: %p rdx: %p\n",
92 regs->rax, regs->rbx, regs->rcx, regs->rdx);
93 printk("rsi: %p rdi: %p rbp: %p rsp: %p\n",
94 regs->rsi, regs->rdi, regs->rbp, regs->rsp);
95 printk("r8: %p r9: %p r10: %p r11: %p\n",
96 regs->r8, regs->r9, regs->r10, regs->r11);
97 printk("r12: %p r13: %p r14: %p r15: %p\n",
98 regs->r12, regs->r13, regs->r14, regs->r15);
100 show_stack((unsigned long *)regs->rsp);
101 }
103 void show_page_walk(unsigned long addr)
104 {
105 unsigned long page = read_cr3();
107 printk("Pagetable walk from %p:\n", addr);
109 page &= PAGE_MASK;
110 page = ((unsigned long *) __va(page))[l4_table_offset(addr)];
111 printk(" L4 = %p\n", page);
112 if ( !(page & _PAGE_PRESENT) )
113 return;
115 page &= PAGE_MASK;
116 page = ((unsigned long *) __va(page))[l3_table_offset(addr)];
117 printk(" L3 = %p\n", page);
118 if ( !(page & _PAGE_PRESENT) )
119 return;
121 page &= PAGE_MASK;
122 page = ((unsigned long *) __va(page))[l2_table_offset(addr)];
123 printk(" L2 = %p %s\n", page, (page & _PAGE_PSE) ? "(2MB)" : "");
124 if ( !(page & _PAGE_PRESENT) || (page & _PAGE_PSE) )
125 return;
127 page &= PAGE_MASK;
128 page = ((unsigned long *) __va(page))[l1_table_offset(addr)];
129 printk(" L1 = %p\n", page);
130 }
132 asmlinkage void double_fault(void);
133 asmlinkage void do_double_fault(struct xen_regs *regs)
134 {
135 /* Disable the NMI watchdog. It's useless now. */
136 watchdog_on = 0;
138 console_force_unlock();
140 /* Find information saved during fault and dump it to the console. */
141 printk("************************************\n");
142 show_registers(regs);
143 printk("************************************\n");
144 printk("CPU%d DOUBLE FAULT -- system shutdown\n", smp_processor_id());
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 asmlinkage void syscall_enter(void);
157 void __init percpu_traps_init(void)
158 {
159 char *stack_bottom, *stack;
160 int cpu = smp_processor_id();
162 if ( cpu == 0 )
163 {
164 /* Specify dedicated interrupt stacks for NMIs and double faults. */
165 set_intr_gate(TRAP_double_fault, &double_fault);
166 idt_table[TRAP_double_fault].a |= 1UL << 32; /* IST1 */
167 idt_table[TRAP_nmi].a |= 2UL << 32; /* IST2 */
168 }
170 stack_bottom = (char *)get_stack_bottom();
171 stack = (char *)((unsigned long)stack_bottom & ~(STACK_SIZE - 1));
173 /* Double-fault handler has its own per-CPU 1kB stack. */
174 init_tss[cpu].ist[0] = (unsigned long)&stack[1024];
176 /* NMI handler has its own per-CPU 1kB stack. */
177 init_tss[cpu].ist[1] = (unsigned long)&stack[2048];
179 /*
180 * Trampoline for SYSCALL entry from long mode.
181 */
183 /* Skip the NMI and DF stacks. */
184 stack = &stack[2048];
185 wrmsr(MSR_LSTAR, (unsigned long)stack, ((unsigned long)stack>>32));
187 /* movq %rsp, saversp(%rip) */
188 stack[0] = 0x48;
189 stack[1] = 0x89;
190 stack[2] = 0x25;
191 *(u32 *)&stack[3] = (stack_bottom - &stack[7]) - 16;
193 /* leaq saversp(%rip), %rsp */
194 stack[7] = 0x48;
195 stack[8] = 0x8d;
196 stack[9] = 0x25;
197 *(u32 *)&stack[10] = (stack_bottom - &stack[14]) - 16;
199 /* pushq %r11 */
200 stack[14] = 0x41;
201 stack[15] = 0x53;
203 /* pushq $__GUEST_CS64 */
204 stack[16] = 0x68;
205 *(u32 *)&stack[17] = __GUEST_CS64;
207 /* jmp syscall_enter */
208 stack[21] = 0xe9;
209 *(u32 *)&stack[22] = (char *)syscall_enter - &stack[26];
211 /*
212 * Trampoline for SYSCALL entry from compatibility mode.
213 */
215 /* Skip the long-mode entry trampoline. */
216 stack = &stack[26];
217 wrmsr(MSR_CSTAR, (unsigned long)stack, ((unsigned long)stack>>32));
219 /* movq %rsp, saversp(%rip) */
220 stack[0] = 0x48;
221 stack[1] = 0x89;
222 stack[2] = 0x25;
223 *(u32 *)&stack[3] = (stack_bottom - &stack[7]) - 16;
225 /* leaq saversp(%rip), %rsp */
226 stack[7] = 0x48;
227 stack[8] = 0x8d;
228 stack[9] = 0x25;
229 *(u32 *)&stack[10] = (stack_bottom - &stack[14]) - 16;
231 /* pushq %r11 */
232 stack[14] = 0x41;
233 stack[15] = 0x53;
235 /* pushq $__GUEST_CS32 */
236 stack[16] = 0x68;
237 *(u32 *)&stack[17] = __GUEST_CS32;
239 /* jmp syscall_enter */
240 stack[21] = 0xe9;
241 *(u32 *)&stack[22] = (char *)syscall_enter - &stack[26];
243 /*
244 * Common SYSCALL parameters.
245 */
247 wrmsr(MSR_STAR, 0, (FLAT_RING3_CS32<<16) | __HYPERVISOR_CS);
248 wrmsr(MSR_SYSCALL_MASK, EF_VM|EF_RF|EF_NT|EF_DF|EF_IE|EF_TF, 0U);
249 }
251 void *decode_reg(struct xen_regs *regs, u8 b)
252 {
253 switch ( b )
254 {
255 case 0: return &regs->rax;
256 case 1: return &regs->rcx;
257 case 2: return &regs->rdx;
258 case 3: return &regs->rbx;
259 case 4: return &regs->rsp;
260 case 5: return &regs->rbp;
261 case 6: return &regs->rsi;
262 case 7: return &regs->rdi;
263 case 8: return &regs->r8;
264 case 9: return &regs->r9;
265 case 10: return &regs->r10;
266 case 11: return &regs->r11;
267 case 12: return &regs->r12;
268 case 13: return &regs->r13;
269 case 14: return &regs->r14;
270 case 15: return &regs->r15;
271 }
273 return NULL;
274 }
276 long do_set_callbacks(unsigned long event_address,
277 unsigned long failsafe_address,
278 unsigned long syscall_address)
279 {
280 struct exec_domain *d = current;
282 d->arch.event_address = event_address;
283 d->arch.failsafe_address = failsafe_address;
284 d->arch.syscall_address = syscall_address;
286 return 0;
287 }