ia64/xen-unstable

view xen/arch/x86/x86_64/traps.c @ 6552:a9873d384da4

Merge.
author adsharma@los-vmm.sc.intel.com
date Thu Aug 25 12:24:48 2005 -0700 (2005-08-25)
parents 112d44270733 fa0754a9f64f
children dfaf788ab18c
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\nEIP: %04x:[<%016lx>]",
19 smp_processor_id(), 0xffff & regs->cs, regs->rip);
20 if ( !GUEST_MODE(regs) )
21 print_symbol(" %s", regs->rip);
22 printk("\nEFLAGS: %016lx\n", regs->eflags);
23 printk("rax: %016lx rbx: %016lx rcx: %016lx rdx: %016lx\n",
24 regs->rax, regs->rbx, regs->rcx, regs->rdx);
25 printk("rsi: %016lx rdi: %016lx rbp: %016lx rsp: %016lx\n",
26 regs->rsi, regs->rdi, regs->rbp, regs->rsp);
27 printk("r8: %016lx r9: %016lx r10: %016lx r11: %016lx\n",
28 regs->r8, regs->r9, regs->r10, regs->r11);
29 printk("r12: %016lx r13: %016lx r14: %016lx r15: %016lx\n",
30 regs->r12, regs->r13, regs->r14, regs->r15);
32 if ( GUEST_MODE(regs) )
33 show_guest_stack();
34 else
35 show_stack((unsigned long *)regs->rsp);
36 }
38 void show_page_walk(unsigned long addr)
39 {
40 unsigned long page = read_cr3();
42 printk("Pagetable walk from %016lx:\n", addr);
44 page &= PAGE_MASK;
45 page = ((unsigned long *) __va(page))[l4_table_offset(addr)];
46 printk(" L4 = %016lx\n", page);
47 if ( !(page & _PAGE_PRESENT) )
48 return;
50 page &= PAGE_MASK;
51 page = ((unsigned long *) __va(page))[l3_table_offset(addr)];
52 printk(" L3 = %016lx\n", page);
53 if ( !(page & _PAGE_PRESENT) )
54 return;
56 page &= PAGE_MASK;
57 page = ((unsigned long *) __va(page))[l2_table_offset(addr)];
58 printk(" L2 = %016lx %s\n", page, (page & _PAGE_PSE) ? "(2MB)" : "");
59 if ( !(page & _PAGE_PRESENT) || (page & _PAGE_PSE) )
60 return;
62 page &= PAGE_MASK;
63 page = ((unsigned long *) __va(page))[l1_table_offset(addr)];
64 printk(" L1 = %016lx\n", page);
65 }
67 asmlinkage void double_fault(void);
68 asmlinkage void do_double_fault(struct cpu_user_regs *regs)
69 {
70 watchdog_disable();
72 console_force_unlock();
74 /* Find information saved during fault and dump it to the console. */
75 printk("************************************\n");
76 show_registers(regs);
77 printk("************************************\n");
78 printk("CPU%d DOUBLE FAULT -- system shutdown\n", smp_processor_id());
79 printk("System needs manual reset.\n");
80 printk("************************************\n");
82 /* Lock up the console to prevent spurious output from other CPUs. */
83 console_force_lock();
85 /* Wait for manual reset. */
86 for ( ; ; )
87 __asm__ __volatile__ ( "hlt" );
88 }
90 asmlinkage void syscall_enter(void);
91 void __init percpu_traps_init(void)
92 {
93 char *stack_bottom, *stack;
94 int cpu = smp_processor_id();
96 if ( cpu == 0 )
97 {
98 /* Specify dedicated interrupt stacks for NMIs and double faults. */
99 set_intr_gate(TRAP_double_fault, &double_fault);
100 idt_table[TRAP_double_fault].a |= 1UL << 32; /* IST1 */
101 idt_table[TRAP_nmi].a |= 2UL << 32; /* IST2 */
102 }
104 stack_bottom = (char *)get_stack_bottom();
105 stack = (char *)((unsigned long)stack_bottom & ~(STACK_SIZE - 1));
107 /* Double-fault handler has its own per-CPU 1kB stack. */
108 init_tss[cpu].ist[0] = (unsigned long)&stack[1024];
110 /* NMI handler has its own per-CPU 1kB stack. */
111 init_tss[cpu].ist[1] = (unsigned long)&stack[2048];
113 /*
114 * Trampoline for SYSCALL entry from long mode.
115 */
117 /* Skip the NMI and DF stacks. */
118 stack = &stack[2048];
119 wrmsr(MSR_LSTAR, (unsigned long)stack, ((unsigned long)stack>>32));
121 /* movq %rsp, saversp(%rip) */
122 stack[0] = 0x48;
123 stack[1] = 0x89;
124 stack[2] = 0x25;
125 *(u32 *)&stack[3] = (stack_bottom - &stack[7]) - 16;
127 /* leaq saversp(%rip), %rsp */
128 stack[7] = 0x48;
129 stack[8] = 0x8d;
130 stack[9] = 0x25;
131 *(u32 *)&stack[10] = (stack_bottom - &stack[14]) - 16;
133 /* pushq %r11 */
134 stack[14] = 0x41;
135 stack[15] = 0x53;
137 /* pushq $__GUEST_CS64 */
138 stack[16] = 0x68;
139 *(u32 *)&stack[17] = __GUEST_CS64;
141 /* jmp syscall_enter */
142 stack[21] = 0xe9;
143 *(u32 *)&stack[22] = (char *)syscall_enter - &stack[26];
145 /*
146 * Trampoline for SYSCALL entry from compatibility mode.
147 */
149 /* Skip the long-mode entry trampoline. */
150 stack = &stack[26];
151 wrmsr(MSR_CSTAR, (unsigned long)stack, ((unsigned long)stack>>32));
153 /* movq %rsp, saversp(%rip) */
154 stack[0] = 0x48;
155 stack[1] = 0x89;
156 stack[2] = 0x25;
157 *(u32 *)&stack[3] = (stack_bottom - &stack[7]) - 16;
159 /* leaq saversp(%rip), %rsp */
160 stack[7] = 0x48;
161 stack[8] = 0x8d;
162 stack[9] = 0x25;
163 *(u32 *)&stack[10] = (stack_bottom - &stack[14]) - 16;
165 /* pushq %r11 */
166 stack[14] = 0x41;
167 stack[15] = 0x53;
169 /* pushq $__GUEST_CS32 */
170 stack[16] = 0x68;
171 *(u32 *)&stack[17] = __GUEST_CS32;
173 /* jmp syscall_enter */
174 stack[21] = 0xe9;
175 *(u32 *)&stack[22] = (char *)syscall_enter - &stack[26];
177 /*
178 * Common SYSCALL parameters.
179 */
181 wrmsr(MSR_STAR, 0, (FLAT_RING3_CS32<<16) | __HYPERVISOR_CS);
182 wrmsr(MSR_SYSCALL_MASK, EF_VM|EF_RF|EF_NT|EF_DF|EF_IE|EF_TF, 0U);
183 }
185 long do_set_callbacks(unsigned long event_address,
186 unsigned long failsafe_address,
187 unsigned long syscall_address)
188 {
189 struct vcpu *d = current;
191 d->arch.guest_context.event_callback_eip = event_address;
192 d->arch.guest_context.failsafe_callback_eip = failsafe_address;
193 d->arch.guest_context.syscall_callback_eip = syscall_address;
195 return 0;
196 }