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>
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 }