xen-vtx-unstable

view xen/arch/x86/x86_64/traps.c @ 6568:dd668f7527cb

merge?
author cl349@firebug.cl.cam.ac.uk
date Thu Sep 01 10:16:14 2005 +0000 (2005-09-01)
parents 38312fe7ec38 f0dc15fd3c1b
children 030a56a24fa6 291e816acbf4
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/symbols.h>
10 #include <xen/console.h>
11 #include <xen/sched.h>
12 #include <asm/current.h>
13 #include <asm/flushtlb.h>
14 #include <asm/msr.h>
16 void show_registers(struct cpu_user_regs *regs)
17 {
18 printk("CPU: %d\nRIP: %04x:[<%016lx>]",
19 smp_processor_id(), 0xffff & regs->cs, regs->rip);
20 if ( !GUEST_MODE(regs) )
21 print_symbol(" %s", regs->rip);
22 printk("\nRFLAGS: %016lx\n", regs->eflags);
23 printk("rax: %016lx rbx: %016lx rcx: %016lx\n",
24 regs->rax, regs->rbx, regs->rcx);
25 printk("rdx: %016lx rsi: %016lx rdi: %016lx\n",
26 regs->rdx, regs->rsi, regs->rdi);
27 printk("rbp: %016lx rsp: %016lx r8: %016lx\n",
28 regs->rbp, regs->rsp, regs->r8);
29 printk("r9: %016lx r10: %016lx r11: %016lx\n",
30 regs->r9, regs->r10, regs->r11);
31 printk("r12: %016lx r13: %016lx r14: %016lx\n",
32 regs->r12, regs->r13, regs->r14);
33 printk("r15: %016lx\n", regs->r15);
35 if ( GUEST_MODE(regs) )
36 show_guest_stack();
37 else
38 show_stack((unsigned long *)regs->rsp);
39 }
41 void show_page_walk(unsigned long addr)
42 {
43 unsigned long page = read_cr3();
45 printk("Pagetable walk from %016lx:\n", addr);
47 page &= PAGE_MASK;
48 page = ((unsigned long *) __va(page))[l4_table_offset(addr)];
49 printk(" L4 = %016lx\n", page);
50 if ( !(page & _PAGE_PRESENT) )
51 return;
53 page &= PAGE_MASK;
54 page = ((unsigned long *) __va(page))[l3_table_offset(addr)];
55 printk(" L3 = %016lx\n", page);
56 if ( !(page & _PAGE_PRESENT) )
57 return;
59 page &= PAGE_MASK;
60 page = ((unsigned long *) __va(page))[l2_table_offset(addr)];
61 printk(" L2 = %016lx %s\n", page, (page & _PAGE_PSE) ? "(2MB)" : "");
62 if ( !(page & _PAGE_PRESENT) || (page & _PAGE_PSE) )
63 return;
65 page &= PAGE_MASK;
66 page = ((unsigned long *) __va(page))[l1_table_offset(addr)];
67 printk(" L1 = %016lx\n", page);
68 }
70 asmlinkage void double_fault(void);
71 asmlinkage void do_double_fault(struct cpu_user_regs *regs)
72 {
73 watchdog_disable();
75 console_force_unlock();
77 /* Find information saved during fault and dump it to the console. */
78 printk("************************************\n");
79 show_registers(regs);
80 printk("************************************\n");
81 printk("CPU%d DOUBLE FAULT -- system shutdown\n", smp_processor_id());
82 printk("System needs manual reset.\n");
83 printk("************************************\n");
85 /* Lock up the console to prevent spurious output from other CPUs. */
86 console_force_lock();
88 /* Wait for manual reset. */
89 for ( ; ; )
90 __asm__ __volatile__ ( "hlt" );
91 }
93 asmlinkage void syscall_enter(void);
94 void __init percpu_traps_init(void)
95 {
96 char *stack_bottom, *stack;
97 int cpu = smp_processor_id();
99 if ( cpu == 0 )
100 {
101 /* Specify dedicated interrupt stacks for NMIs and double faults. */
102 set_intr_gate(TRAP_double_fault, &double_fault);
103 idt_table[TRAP_double_fault].a |= 1UL << 32; /* IST1 */
104 idt_table[TRAP_nmi].a |= 2UL << 32; /* IST2 */
105 }
107 stack_bottom = (char *)get_stack_bottom();
108 stack = (char *)((unsigned long)stack_bottom & ~(STACK_SIZE - 1));
110 /* Double-fault handler has its own per-CPU 1kB stack. */
111 init_tss[cpu].ist[0] = (unsigned long)&stack[1024];
113 /* NMI handler has its own per-CPU 1kB stack. */
114 init_tss[cpu].ist[1] = (unsigned long)&stack[2048];
116 /*
117 * Trampoline for SYSCALL entry from long mode.
118 */
120 /* Skip the NMI and DF stacks. */
121 stack = &stack[2048];
122 wrmsr(MSR_LSTAR, (unsigned long)stack, ((unsigned long)stack>>32));
124 /* movq %rsp, saversp(%rip) */
125 stack[0] = 0x48;
126 stack[1] = 0x89;
127 stack[2] = 0x25;
128 *(u32 *)&stack[3] = (stack_bottom - &stack[7]) - 16;
130 /* leaq saversp(%rip), %rsp */
131 stack[7] = 0x48;
132 stack[8] = 0x8d;
133 stack[9] = 0x25;
134 *(u32 *)&stack[10] = (stack_bottom - &stack[14]) - 16;
136 /* pushq %r11 */
137 stack[14] = 0x41;
138 stack[15] = 0x53;
140 /* pushq $__GUEST_CS64 */
141 stack[16] = 0x68;
142 *(u32 *)&stack[17] = __GUEST_CS64;
144 /* jmp syscall_enter */
145 stack[21] = 0xe9;
146 *(u32 *)&stack[22] = (char *)syscall_enter - &stack[26];
148 /*
149 * Trampoline for SYSCALL entry from compatibility mode.
150 */
152 /* Skip the long-mode entry trampoline. */
153 stack = &stack[26];
154 wrmsr(MSR_CSTAR, (unsigned long)stack, ((unsigned long)stack>>32));
156 /* movq %rsp, saversp(%rip) */
157 stack[0] = 0x48;
158 stack[1] = 0x89;
159 stack[2] = 0x25;
160 *(u32 *)&stack[3] = (stack_bottom - &stack[7]) - 16;
162 /* leaq saversp(%rip), %rsp */
163 stack[7] = 0x48;
164 stack[8] = 0x8d;
165 stack[9] = 0x25;
166 *(u32 *)&stack[10] = (stack_bottom - &stack[14]) - 16;
168 /* pushq %r11 */
169 stack[14] = 0x41;
170 stack[15] = 0x53;
172 /* pushq $__GUEST_CS32 */
173 stack[16] = 0x68;
174 *(u32 *)&stack[17] = __GUEST_CS32;
176 /* jmp syscall_enter */
177 stack[21] = 0xe9;
178 *(u32 *)&stack[22] = (char *)syscall_enter - &stack[26];
180 /*
181 * Common SYSCALL parameters.
182 */
184 wrmsr(MSR_STAR, 0, (FLAT_RING3_CS32<<16) | __HYPERVISOR_CS);
185 wrmsr(MSR_SYSCALL_MASK, EF_VM|EF_RF|EF_NT|EF_DF|EF_IE|EF_TF, 0U);
186 }
188 long do_set_callbacks(unsigned long event_address,
189 unsigned long failsafe_address,
190 unsigned long syscall_address)
191 {
192 struct vcpu *d = current;
194 d->arch.guest_context.event_callback_eip = event_address;
195 d->arch.guest_context.failsafe_callback_eip = failsafe_address;
196 d->arch.guest_context.syscall_callback_eip = syscall_address;
198 return 0;
199 }