xen-vtx-unstable

annotate xen/arch/x86/x86_64/traps.c @ 6774:4d899a738d59

merge?
author cl349@firebug.cl.cam.ac.uk
date Tue Sep 13 15:05:49 2005 +0000 (2005-09-13)
parents bd951d23d713 291e816acbf4
children e7c7196fa329 8ca0f98ba8e2
rev   line source
kaf24@3602 1
kaf24@3602 2 #include <xen/config.h>
kaf24@3602 3 #include <xen/init.h>
kaf24@3602 4 #include <xen/sched.h>
kaf24@3602 5 #include <xen/lib.h>
kaf24@3602 6 #include <xen/errno.h>
kaf24@3602 7 #include <xen/mm.h>
kaf24@3602 8 #include <xen/irq.h>
kaf24@5824 9 #include <xen/symbols.h>
kaf24@3630 10 #include <xen/console.h>
kaf24@3650 11 #include <xen/sched.h>
cl349@5291 12 #include <asm/current.h>
kaf24@5159 13 #include <asm/flushtlb.h>
kaf24@3650 14 #include <asm/msr.h>
kaf24@6756 15 #include <asm/vmx.h>
kaf24@3602 16
kaf24@4683 17 void show_registers(struct cpu_user_regs *regs)
kaf24@3602 18 {
kaf24@6756 19 unsigned long rip, rsp, rflags, cs, cr0, cr3;
kaf24@6756 20 const char *context;
kaf24@6756 21
kaf24@6756 22 if ( VMX_DOMAIN(current) && (regs->eflags == 0) )
kaf24@6756 23 {
kaf24@6756 24 __vmread(GUEST_RIP, &rip);
kaf24@6756 25 __vmread(GUEST_RSP, &rsp);
kaf24@6756 26 __vmread(GUEST_RFLAGS, &rflags);
kaf24@6756 27 __vmread(GUEST_CS_SELECTOR, &cs);
kaf24@6756 28 __vmread(CR0_READ_SHADOW, &cr0);
kaf24@6756 29 __vmread(GUEST_CR3, &cr3);
kaf24@6756 30 context = "vmx guest";
kaf24@6756 31 }
kaf24@6756 32 else
kaf24@6756 33 {
kaf24@6756 34 rip = regs->rip;
kaf24@6756 35 rflags = regs->rflags;
kaf24@6756 36 cr0 = read_cr0();
kaf24@6756 37 cr3 = read_cr3();
kaf24@6756 38 rsp = regs->rsp;
kaf24@6756 39 cs = regs->cs & 0xffff;
kaf24@6756 40 context = GUEST_MODE(regs) ? "guest" : "hypervisor";
kaf24@6756 41 }
kaf24@6756 42
kaf24@6756 43 printk("CPU: %d\nRIP: %04lx:[<%016lx>]",
kaf24@6756 44 smp_processor_id(), cs, rip);
kaf24@6232 45 if ( !GUEST_MODE(regs) )
kaf24@6756 46 print_symbol(" %s", rip);
kaf24@6756 47 printk("\nRFLAGS: %016lx CONTEXT: %s\n", rflags, context);
kaf24@6477 48 printk("rax: %016lx rbx: %016lx rcx: %016lx\n",
kaf24@6477 49 regs->rax, regs->rbx, regs->rcx);
kaf24@6477 50 printk("rdx: %016lx rsi: %016lx rdi: %016lx\n",
kaf24@6477 51 regs->rdx, regs->rsi, regs->rdi);
kaf24@6477 52 printk("rbp: %016lx rsp: %016lx r8: %016lx\n",
kaf24@6756 53 regs->rbp, rsp, regs->r8);
kaf24@6477 54 printk("r9: %016lx r10: %016lx r11: %016lx\n",
kaf24@6477 55 regs->r9, regs->r10, regs->r11);
kaf24@6477 56 printk("r12: %016lx r13: %016lx r14: %016lx\n",
kaf24@6477 57 regs->r12, regs->r13, regs->r14);
kaf24@6756 58 printk("r15: %016lx cr0: %016lx cr3: %016lx\n",
kaf24@6756 59 regs->r15, cr0, cr3);
kaf24@3602 60
kaf24@6573 61 show_stack(regs);
kaf24@5073 62 }
kaf24@3602 63
kaf24@3630 64 void show_page_walk(unsigned long addr)
kaf24@3630 65 {
kaf24@3630 66 unsigned long page = read_cr3();
kaf24@3630 67
kaf24@4654 68 printk("Pagetable walk from %016lx:\n", addr);
kaf24@3630 69
kaf24@3630 70 page &= PAGE_MASK;
kaf24@3630 71 page = ((unsigned long *) __va(page))[l4_table_offset(addr)];
kaf24@4654 72 printk(" L4 = %016lx\n", page);
kaf24@3630 73 if ( !(page & _PAGE_PRESENT) )
kaf24@3630 74 return;
kaf24@3630 75
kaf24@3630 76 page &= PAGE_MASK;
kaf24@3630 77 page = ((unsigned long *) __va(page))[l3_table_offset(addr)];
kaf24@4654 78 printk(" L3 = %016lx\n", page);
kaf24@3630 79 if ( !(page & _PAGE_PRESENT) )
kaf24@3630 80 return;
kaf24@3630 81
kaf24@3630 82 page &= PAGE_MASK;
kaf24@3630 83 page = ((unsigned long *) __va(page))[l2_table_offset(addr)];
kaf24@4654 84 printk(" L2 = %016lx %s\n", page, (page & _PAGE_PSE) ? "(2MB)" : "");
kaf24@3630 85 if ( !(page & _PAGE_PRESENT) || (page & _PAGE_PSE) )
kaf24@3630 86 return;
kaf24@3630 87
kaf24@3630 88 page &= PAGE_MASK;
kaf24@3630 89 page = ((unsigned long *) __va(page))[l1_table_offset(addr)];
kaf24@4654 90 printk(" L1 = %016lx\n", page);
kaf24@3630 91 }
kaf24@3630 92
kaf24@3630 93 asmlinkage void double_fault(void);
kaf24@4683 94 asmlinkage void do_double_fault(struct cpu_user_regs *regs)
kaf24@3630 95 {
kaf24@4926 96 watchdog_disable();
kaf24@3630 97
kaf24@3686 98 console_force_unlock();
kaf24@3686 99
kaf24@3630 100 /* Find information saved during fault and dump it to the console. */
kaf24@3630 101 printk("************************************\n");
kaf24@3695 102 show_registers(regs);
kaf24@3630 103 printk("************************************\n");
kaf24@3695 104 printk("CPU%d DOUBLE FAULT -- system shutdown\n", smp_processor_id());
kaf24@3630 105 printk("System needs manual reset.\n");
kaf24@3630 106 printk("************************************\n");
kaf24@3630 107
kaf24@3630 108 /* Lock up the console to prevent spurious output from other CPUs. */
kaf24@3630 109 console_force_lock();
kaf24@3630 110
kaf24@3630 111 /* Wait for manual reset. */
kaf24@3630 112 for ( ; ; )
kaf24@3630 113 __asm__ __volatile__ ( "hlt" );
kaf24@3630 114 }
kaf24@3630 115
kaf24@3761 116 asmlinkage void syscall_enter(void);
kaf24@3650 117 void __init percpu_traps_init(void)
kaf24@3650 118 {
kaf24@3761 119 char *stack_bottom, *stack;
kaf24@3761 120 int cpu = smp_processor_id();
kaf24@3761 121
kaf24@3774 122 if ( cpu == 0 )
kaf24@3774 123 {
kaf24@3774 124 /* Specify dedicated interrupt stacks for NMIs and double faults. */
kaf24@3774 125 set_intr_gate(TRAP_double_fault, &double_fault);
kaf24@3774 126 idt_table[TRAP_double_fault].a |= 1UL << 32; /* IST1 */
kaf24@3774 127 idt_table[TRAP_nmi].a |= 2UL << 32; /* IST2 */
kaf24@3774 128 }
kaf24@3774 129
kaf24@3761 130 stack_bottom = (char *)get_stack_bottom();
kaf24@3761 131 stack = (char *)((unsigned long)stack_bottom & ~(STACK_SIZE - 1));
kaf24@3695 132
kaf24@3695 133 /* Double-fault handler has its own per-CPU 1kB stack. */
kaf24@3695 134 init_tss[cpu].ist[0] = (unsigned long)&stack[1024];
kaf24@3695 135
kaf24@3695 136 /* NMI handler has its own per-CPU 1kB stack. */
kaf24@3695 137 init_tss[cpu].ist[1] = (unsigned long)&stack[2048];
kaf24@3695 138
kaf24@3695 139 /*
kaf24@3695 140 * Trampoline for SYSCALL entry from long mode.
kaf24@3695 141 */
kaf24@3695 142
kaf24@3695 143 /* Skip the NMI and DF stacks. */
kaf24@3695 144 stack = &stack[2048];
kaf24@3695 145 wrmsr(MSR_LSTAR, (unsigned long)stack, ((unsigned long)stack>>32));
kaf24@3650 146
kaf24@3650 147 /* movq %rsp, saversp(%rip) */
kaf24@3650 148 stack[0] = 0x48;
kaf24@3650 149 stack[1] = 0x89;
kaf24@3650 150 stack[2] = 0x25;
kaf24@3761 151 *(u32 *)&stack[3] = (stack_bottom - &stack[7]) - 16;
kaf24@3650 152
kaf24@3650 153 /* leaq saversp(%rip), %rsp */
kaf24@3650 154 stack[7] = 0x48;
kaf24@3650 155 stack[8] = 0x8d;
kaf24@3650 156 stack[9] = 0x25;
kaf24@3761 157 *(u32 *)&stack[10] = (stack_bottom - &stack[14]) - 16;
kaf24@3650 158
kaf24@3783 159 /* pushq %r11 */
kaf24@3783 160 stack[14] = 0x41;
kaf24@3783 161 stack[15] = 0x53;
kaf24@3783 162
kaf24@3783 163 /* pushq $__GUEST_CS64 */
kaf24@3783 164 stack[16] = 0x68;
kaf24@3783 165 *(u32 *)&stack[17] = __GUEST_CS64;
kaf24@3783 166
kaf24@3761 167 /* jmp syscall_enter */
kaf24@3783 168 stack[21] = 0xe9;
kaf24@3783 169 *(u32 *)&stack[22] = (char *)syscall_enter - &stack[26];
kaf24@3650 170
kaf24@3695 171 /*
kaf24@3695 172 * Trampoline for SYSCALL entry from compatibility mode.
kaf24@3695 173 */
kaf24@3695 174
kaf24@3695 175 /* Skip the long-mode entry trampoline. */
kaf24@3783 176 stack = &stack[26];
kaf24@3695 177 wrmsr(MSR_CSTAR, (unsigned long)stack, ((unsigned long)stack>>32));
kaf24@3695 178
kaf24@3695 179 /* movq %rsp, saversp(%rip) */
kaf24@3695 180 stack[0] = 0x48;
kaf24@3695 181 stack[1] = 0x89;
kaf24@3695 182 stack[2] = 0x25;
kaf24@3761 183 *(u32 *)&stack[3] = (stack_bottom - &stack[7]) - 16;
kaf24@3695 184
kaf24@3695 185 /* leaq saversp(%rip), %rsp */
kaf24@3695 186 stack[7] = 0x48;
kaf24@3695 187 stack[8] = 0x8d;
kaf24@3695 188 stack[9] = 0x25;
kaf24@3761 189 *(u32 *)&stack[10] = (stack_bottom - &stack[14]) - 16;
kaf24@3695 190
kaf24@3783 191 /* pushq %r11 */
kaf24@3783 192 stack[14] = 0x41;
kaf24@3783 193 stack[15] = 0x53;
kaf24@3783 194
kaf24@3783 195 /* pushq $__GUEST_CS32 */
kaf24@3783 196 stack[16] = 0x68;
kaf24@3783 197 *(u32 *)&stack[17] = __GUEST_CS32;
kaf24@3783 198
kaf24@3761 199 /* jmp syscall_enter */
kaf24@3783 200 stack[21] = 0xe9;
kaf24@3783 201 *(u32 *)&stack[22] = (char *)syscall_enter - &stack[26];
kaf24@3695 202
kaf24@3695 203 /*
kaf24@3695 204 * Common SYSCALL parameters.
kaf24@3695 205 */
kaf24@3695 206
kaf24@3696 207 wrmsr(MSR_STAR, 0, (FLAT_RING3_CS32<<16) | __HYPERVISOR_CS);
kaf24@3822 208 wrmsr(MSR_SYSCALL_MASK, EF_VM|EF_RF|EF_NT|EF_DF|EF_IE|EF_TF, 0U);
kaf24@3650 209 }
kaf24@3650 210
kaf24@3780 211 long do_set_callbacks(unsigned long event_address,
kaf24@3780 212 unsigned long failsafe_address,
kaf24@3780 213 unsigned long syscall_address)
kaf24@3780 214 {
kaf24@5289 215 struct vcpu *d = current;
kaf24@3780 216
kaf24@4689 217 d->arch.guest_context.event_callback_eip = event_address;
kaf24@4689 218 d->arch.guest_context.failsafe_callback_eip = failsafe_address;
kaf24@4689 219 d->arch.guest_context.syscall_callback_eip = syscall_address;
kaf24@3780 220
kaf24@3780 221 return 0;
kaf24@3780 222 }
kaf24@6756 223
kaf24@6756 224 /*
kaf24@6756 225 * Local variables:
kaf24@6756 226 * mode: C
kaf24@6756 227 * c-set-style: "BSD"
kaf24@6756 228 * c-basic-offset: 4
kaf24@6756 229 * tab-width: 4
kaf24@6756 230 * indent-tabs-mode: nil
kaf24@6756 231 * End:
kaf24@6756 232 */