xen-vtx-unstable
annotate xen/arch/x86/x86_64/traps.c @ 4689:cd690b71434a
bitkeeper revision 1.1389.1.4 (427125bdwah0mehgnafVLP-gRLDM_w)
Avoid field duplication between vcpu_guest_context and arch_exec_domain
structures. The latter now includes the former as a sub-field.
Signed-off-by: Keir Fraser <keir@xensource.com>
Avoid field duplication between vcpu_guest_context and arch_exec_domain
structures. The latter now includes the former as a sub-field.
Signed-off-by: Keir Fraser <keir@xensource.com>
author | kaf24@firebug.cl.cam.ac.uk |
---|---|
date | Thu Apr 28 18:04:45 2005 +0000 (2005-04-28) |
parents | 38a02ee9a9c8 |
children | 65b28c74cec2 |
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@3630 | 9 #include <xen/console.h> |
kaf24@3650 | 10 #include <xen/sched.h> |
kaf24@3650 | 11 #include <asm/msr.h> |
kaf24@3602 | 12 |
kaf24@3602 | 13 static int kstack_depth_to_print = 8*20; |
kaf24@3602 | 14 |
kaf24@3602 | 15 static inline int kernel_text_address(unsigned long addr) |
kaf24@3602 | 16 { |
kaf24@3602 | 17 if (addr >= (unsigned long) &_stext && |
kaf24@3602 | 18 addr <= (unsigned long) &_etext) |
kaf24@3602 | 19 return 1; |
kaf24@3602 | 20 return 0; |
kaf24@3602 | 21 |
kaf24@3602 | 22 } |
kaf24@3602 | 23 |
kaf24@3602 | 24 void show_guest_stack(void) |
kaf24@3602 | 25 { |
kaf24@3602 | 26 int i; |
kaf24@4683 | 27 struct cpu_user_regs *regs = get_cpu_user_regs(); |
kaf24@4683 | 28 unsigned long *stack = (unsigned long *)regs->rsp; |
kaf24@4683 | 29 |
kaf24@4683 | 30 printk("Guest RIP is %016lx\n ", regs->rip); |
kaf24@3602 | 31 |
kaf24@3602 | 32 for ( i = 0; i < kstack_depth_to_print; i++ ) |
kaf24@3602 | 33 { |
kaf24@3602 | 34 if ( ((long)stack & (STACK_SIZE-1)) == 0 ) |
kaf24@3602 | 35 break; |
kaf24@3602 | 36 if ( i && ((i % 8) == 0) ) |
kaf24@3621 | 37 printk("\n "); |
kaf24@4654 | 38 printk("%016lx ", *stack++); |
kaf24@3602 | 39 } |
kaf24@3602 | 40 printk("\n"); |
kaf24@3602 | 41 |
kaf24@3602 | 42 } |
kaf24@3602 | 43 |
kaf24@3602 | 44 void show_trace(unsigned long *rsp) |
kaf24@3602 | 45 { |
kaf24@3602 | 46 unsigned long *stack, addr; |
kaf24@3602 | 47 int i; |
kaf24@3602 | 48 |
kaf24@3621 | 49 printk("Call Trace from RSP=%p:\n ", rsp); |
kaf24@3602 | 50 stack = rsp; |
kaf24@3602 | 51 i = 0; |
kaf24@3602 | 52 while (((long) stack & (STACK_SIZE-1)) != 0) { |
kaf24@3602 | 53 addr = *stack++; |
kaf24@3602 | 54 if (kernel_text_address(addr)) { |
kaf24@3602 | 55 if (i && ((i % 6) == 0)) |
kaf24@3602 | 56 printk("\n "); |
kaf24@4654 | 57 printk("[<%016lx>] ", addr); |
kaf24@3602 | 58 i++; |
kaf24@3602 | 59 } |
kaf24@3602 | 60 } |
kaf24@3602 | 61 printk("\n"); |
kaf24@3602 | 62 } |
kaf24@3602 | 63 |
kaf24@3602 | 64 void show_stack(unsigned long *rsp) |
kaf24@3602 | 65 { |
kaf24@3602 | 66 unsigned long *stack; |
kaf24@3602 | 67 int i; |
kaf24@3602 | 68 |
kaf24@3621 | 69 printk("Stack trace from RSP=%p:\n ", rsp); |
kaf24@3602 | 70 |
kaf24@3602 | 71 stack = rsp; |
kaf24@3602 | 72 for ( i = 0; i < kstack_depth_to_print; i++ ) |
kaf24@3602 | 73 { |
kaf24@3602 | 74 if ( ((long)stack & (STACK_SIZE-1)) == 0 ) |
kaf24@3602 | 75 break; |
kaf24@3602 | 76 if ( i && ((i % 8) == 0) ) |
kaf24@3621 | 77 printk("\n "); |
kaf24@3602 | 78 if ( kernel_text_address(*stack) ) |
kaf24@4654 | 79 printk("[%016lx] ", *stack++); |
kaf24@3602 | 80 else |
kaf24@4654 | 81 printk("%016lx ", *stack++); |
kaf24@3602 | 82 } |
kaf24@3602 | 83 printk("\n"); |
kaf24@3602 | 84 |
kaf24@3602 | 85 show_trace(rsp); |
kaf24@3602 | 86 } |
kaf24@3602 | 87 |
kaf24@4683 | 88 void show_registers(struct cpu_user_regs *regs) |
kaf24@3602 | 89 { |
kaf24@4654 | 90 printk("CPU: %d\nEIP: %04lx:[<%016lx>] \nEFLAGS: %016lx\n", |
kaf24@3602 | 91 smp_processor_id(), 0xffff & regs->cs, regs->rip, regs->eflags); |
kaf24@4654 | 92 printk("rax: %016lx rbx: %016lx rcx: %016lx rdx: %016lx\n", |
kaf24@3602 | 93 regs->rax, regs->rbx, regs->rcx, regs->rdx); |
kaf24@4654 | 94 printk("rsi: %016lx rdi: %016lx rbp: %016lx rsp: %016lx\n", |
kaf24@3621 | 95 regs->rsi, regs->rdi, regs->rbp, regs->rsp); |
kaf24@4654 | 96 printk("r8: %016lx r9: %016lx r10: %016lx r11: %016lx\n", |
kaf24@3602 | 97 regs->r8, regs->r9, regs->r10, regs->r11); |
kaf24@4654 | 98 printk("r12: %016lx r13: %016lx r14: %016lx r15: %016lx\n", |
kaf24@3602 | 99 regs->r12, regs->r13, regs->r14, regs->r15); |
kaf24@3602 | 100 |
kaf24@3602 | 101 show_stack((unsigned long *)regs->rsp); |
kaf24@3602 | 102 } |
kaf24@3602 | 103 |
kaf24@3630 | 104 void show_page_walk(unsigned long addr) |
kaf24@3630 | 105 { |
kaf24@3630 | 106 unsigned long page = read_cr3(); |
kaf24@3630 | 107 |
kaf24@4654 | 108 printk("Pagetable walk from %016lx:\n", addr); |
kaf24@3630 | 109 |
kaf24@3630 | 110 page &= PAGE_MASK; |
kaf24@3630 | 111 page = ((unsigned long *) __va(page))[l4_table_offset(addr)]; |
kaf24@4654 | 112 printk(" L4 = %016lx\n", page); |
kaf24@3630 | 113 if ( !(page & _PAGE_PRESENT) ) |
kaf24@3630 | 114 return; |
kaf24@3630 | 115 |
kaf24@3630 | 116 page &= PAGE_MASK; |
kaf24@3630 | 117 page = ((unsigned long *) __va(page))[l3_table_offset(addr)]; |
kaf24@4654 | 118 printk(" L3 = %016lx\n", page); |
kaf24@3630 | 119 if ( !(page & _PAGE_PRESENT) ) |
kaf24@3630 | 120 return; |
kaf24@3630 | 121 |
kaf24@3630 | 122 page &= PAGE_MASK; |
kaf24@3630 | 123 page = ((unsigned long *) __va(page))[l2_table_offset(addr)]; |
kaf24@4654 | 124 printk(" L2 = %016lx %s\n", page, (page & _PAGE_PSE) ? "(2MB)" : ""); |
kaf24@3630 | 125 if ( !(page & _PAGE_PRESENT) || (page & _PAGE_PSE) ) |
kaf24@3630 | 126 return; |
kaf24@3630 | 127 |
kaf24@3630 | 128 page &= PAGE_MASK; |
kaf24@3630 | 129 page = ((unsigned long *) __va(page))[l1_table_offset(addr)]; |
kaf24@4654 | 130 printk(" L1 = %016lx\n", page); |
kaf24@3630 | 131 } |
kaf24@3630 | 132 |
kaf24@3630 | 133 asmlinkage void double_fault(void); |
kaf24@4683 | 134 asmlinkage void do_double_fault(struct cpu_user_regs *regs) |
kaf24@3630 | 135 { |
kaf24@3630 | 136 /* Disable the NMI watchdog. It's useless now. */ |
kaf24@3630 | 137 watchdog_on = 0; |
kaf24@3630 | 138 |
kaf24@3686 | 139 console_force_unlock(); |
kaf24@3686 | 140 |
kaf24@3630 | 141 /* Find information saved during fault and dump it to the console. */ |
kaf24@3630 | 142 printk("************************************\n"); |
kaf24@3695 | 143 show_registers(regs); |
kaf24@3630 | 144 printk("************************************\n"); |
kaf24@3695 | 145 printk("CPU%d DOUBLE FAULT -- system shutdown\n", smp_processor_id()); |
kaf24@3630 | 146 printk("System needs manual reset.\n"); |
kaf24@3630 | 147 printk("************************************\n"); |
kaf24@3630 | 148 |
kaf24@3630 | 149 /* Lock up the console to prevent spurious output from other CPUs. */ |
kaf24@3630 | 150 console_force_lock(); |
kaf24@3630 | 151 |
kaf24@3630 | 152 /* Wait for manual reset. */ |
kaf24@3630 | 153 for ( ; ; ) |
kaf24@3630 | 154 __asm__ __volatile__ ( "hlt" ); |
kaf24@3630 | 155 } |
kaf24@3630 | 156 |
kaf24@3761 | 157 asmlinkage void syscall_enter(void); |
kaf24@3650 | 158 void __init percpu_traps_init(void) |
kaf24@3650 | 159 { |
kaf24@3761 | 160 char *stack_bottom, *stack; |
kaf24@3761 | 161 int cpu = smp_processor_id(); |
kaf24@3761 | 162 |
kaf24@3774 | 163 if ( cpu == 0 ) |
kaf24@3774 | 164 { |
kaf24@3774 | 165 /* Specify dedicated interrupt stacks for NMIs and double faults. */ |
kaf24@3774 | 166 set_intr_gate(TRAP_double_fault, &double_fault); |
kaf24@3774 | 167 idt_table[TRAP_double_fault].a |= 1UL << 32; /* IST1 */ |
kaf24@3774 | 168 idt_table[TRAP_nmi].a |= 2UL << 32; /* IST2 */ |
kaf24@3774 | 169 } |
kaf24@3774 | 170 |
kaf24@3761 | 171 stack_bottom = (char *)get_stack_bottom(); |
kaf24@3761 | 172 stack = (char *)((unsigned long)stack_bottom & ~(STACK_SIZE - 1)); |
kaf24@3695 | 173 |
kaf24@3695 | 174 /* Double-fault handler has its own per-CPU 1kB stack. */ |
kaf24@3695 | 175 init_tss[cpu].ist[0] = (unsigned long)&stack[1024]; |
kaf24@3695 | 176 |
kaf24@3695 | 177 /* NMI handler has its own per-CPU 1kB stack. */ |
kaf24@3695 | 178 init_tss[cpu].ist[1] = (unsigned long)&stack[2048]; |
kaf24@3695 | 179 |
kaf24@3695 | 180 /* |
kaf24@3695 | 181 * Trampoline for SYSCALL entry from long mode. |
kaf24@3695 | 182 */ |
kaf24@3695 | 183 |
kaf24@3695 | 184 /* Skip the NMI and DF stacks. */ |
kaf24@3695 | 185 stack = &stack[2048]; |
kaf24@3695 | 186 wrmsr(MSR_LSTAR, (unsigned long)stack, ((unsigned long)stack>>32)); |
kaf24@3650 | 187 |
kaf24@3650 | 188 /* movq %rsp, saversp(%rip) */ |
kaf24@3650 | 189 stack[0] = 0x48; |
kaf24@3650 | 190 stack[1] = 0x89; |
kaf24@3650 | 191 stack[2] = 0x25; |
kaf24@3761 | 192 *(u32 *)&stack[3] = (stack_bottom - &stack[7]) - 16; |
kaf24@3650 | 193 |
kaf24@3650 | 194 /* leaq saversp(%rip), %rsp */ |
kaf24@3650 | 195 stack[7] = 0x48; |
kaf24@3650 | 196 stack[8] = 0x8d; |
kaf24@3650 | 197 stack[9] = 0x25; |
kaf24@3761 | 198 *(u32 *)&stack[10] = (stack_bottom - &stack[14]) - 16; |
kaf24@3650 | 199 |
kaf24@3783 | 200 /* pushq %r11 */ |
kaf24@3783 | 201 stack[14] = 0x41; |
kaf24@3783 | 202 stack[15] = 0x53; |
kaf24@3783 | 203 |
kaf24@3783 | 204 /* pushq $__GUEST_CS64 */ |
kaf24@3783 | 205 stack[16] = 0x68; |
kaf24@3783 | 206 *(u32 *)&stack[17] = __GUEST_CS64; |
kaf24@3783 | 207 |
kaf24@3761 | 208 /* jmp syscall_enter */ |
kaf24@3783 | 209 stack[21] = 0xe9; |
kaf24@3783 | 210 *(u32 *)&stack[22] = (char *)syscall_enter - &stack[26]; |
kaf24@3650 | 211 |
kaf24@3695 | 212 /* |
kaf24@3695 | 213 * Trampoline for SYSCALL entry from compatibility mode. |
kaf24@3695 | 214 */ |
kaf24@3695 | 215 |
kaf24@3695 | 216 /* Skip the long-mode entry trampoline. */ |
kaf24@3783 | 217 stack = &stack[26]; |
kaf24@3695 | 218 wrmsr(MSR_CSTAR, (unsigned long)stack, ((unsigned long)stack>>32)); |
kaf24@3695 | 219 |
kaf24@3695 | 220 /* movq %rsp, saversp(%rip) */ |
kaf24@3695 | 221 stack[0] = 0x48; |
kaf24@3695 | 222 stack[1] = 0x89; |
kaf24@3695 | 223 stack[2] = 0x25; |
kaf24@3761 | 224 *(u32 *)&stack[3] = (stack_bottom - &stack[7]) - 16; |
kaf24@3695 | 225 |
kaf24@3695 | 226 /* leaq saversp(%rip), %rsp */ |
kaf24@3695 | 227 stack[7] = 0x48; |
kaf24@3695 | 228 stack[8] = 0x8d; |
kaf24@3695 | 229 stack[9] = 0x25; |
kaf24@3761 | 230 *(u32 *)&stack[10] = (stack_bottom - &stack[14]) - 16; |
kaf24@3695 | 231 |
kaf24@3783 | 232 /* pushq %r11 */ |
kaf24@3783 | 233 stack[14] = 0x41; |
kaf24@3783 | 234 stack[15] = 0x53; |
kaf24@3783 | 235 |
kaf24@3783 | 236 /* pushq $__GUEST_CS32 */ |
kaf24@3783 | 237 stack[16] = 0x68; |
kaf24@3783 | 238 *(u32 *)&stack[17] = __GUEST_CS32; |
kaf24@3783 | 239 |
kaf24@3761 | 240 /* jmp syscall_enter */ |
kaf24@3783 | 241 stack[21] = 0xe9; |
kaf24@3783 | 242 *(u32 *)&stack[22] = (char *)syscall_enter - &stack[26]; |
kaf24@3695 | 243 |
kaf24@3695 | 244 /* |
kaf24@3695 | 245 * Common SYSCALL parameters. |
kaf24@3695 | 246 */ |
kaf24@3695 | 247 |
kaf24@3696 | 248 wrmsr(MSR_STAR, 0, (FLAT_RING3_CS32<<16) | __HYPERVISOR_CS); |
kaf24@3822 | 249 wrmsr(MSR_SYSCALL_MASK, EF_VM|EF_RF|EF_NT|EF_DF|EF_IE|EF_TF, 0U); |
kaf24@3650 | 250 } |
kaf24@3650 | 251 |
kaf24@3780 | 252 long do_set_callbacks(unsigned long event_address, |
kaf24@3780 | 253 unsigned long failsafe_address, |
kaf24@3780 | 254 unsigned long syscall_address) |
kaf24@3780 | 255 { |
kaf24@3780 | 256 struct exec_domain *d = current; |
kaf24@3780 | 257 |
kaf24@4689 | 258 d->arch.guest_context.event_callback_eip = event_address; |
kaf24@4689 | 259 d->arch.guest_context.failsafe_callback_eip = failsafe_address; |
kaf24@4689 | 260 d->arch.guest_context.syscall_callback_eip = syscall_address; |
kaf24@3780 | 261 |
kaf24@3780 | 262 return 0; |
kaf24@3780 | 263 } |