xen-vtx-unstable
annotate xen/arch/x86/x86_64/traps.c @ 3686:253e8e10e986
bitkeeper revision 1.1159.212.105 (420666bemy1hHhMRPUknF0p3-jxn_w)
x86/64 debug builds use guard pages in unallocated heap space and for
stack-limit enforcement.
Signed-off-by: keir.fraser@cl.cam.ac.uk
x86/64 debug builds use guard pages in unallocated heap space and for
stack-limit enforcement.
Signed-off-by: keir.fraser@cl.cam.ac.uk
author | kaf24@viper.(none) |
---|---|
date | Sun Feb 06 18:49:34 2005 +0000 (2005-02-06) |
parents | 8c6281ec8860 |
children | 88957a238191 ff48344d34df |
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@3602 | 27 execution_context_t *ec = get_execution_context(); |
kaf24@3602 | 28 unsigned long *stack = (unsigned long *)ec->rsp; |
kaf24@3621 | 29 printk("Guest RIP is %lx\n ", ec->rip); |
kaf24@3602 | 30 |
kaf24@3602 | 31 for ( i = 0; i < kstack_depth_to_print; i++ ) |
kaf24@3602 | 32 { |
kaf24@3602 | 33 if ( ((long)stack & (STACK_SIZE-1)) == 0 ) |
kaf24@3602 | 34 break; |
kaf24@3602 | 35 if ( i && ((i % 8) == 0) ) |
kaf24@3621 | 36 printk("\n "); |
kaf24@3621 | 37 printk("%p ", *stack++); |
kaf24@3602 | 38 } |
kaf24@3602 | 39 printk("\n"); |
kaf24@3602 | 40 |
kaf24@3602 | 41 } |
kaf24@3602 | 42 |
kaf24@3602 | 43 void show_trace(unsigned long *rsp) |
kaf24@3602 | 44 { |
kaf24@3602 | 45 unsigned long *stack, addr; |
kaf24@3602 | 46 int i; |
kaf24@3602 | 47 |
kaf24@3621 | 48 printk("Call Trace from RSP=%p:\n ", rsp); |
kaf24@3602 | 49 stack = rsp; |
kaf24@3602 | 50 i = 0; |
kaf24@3602 | 51 while (((long) stack & (STACK_SIZE-1)) != 0) { |
kaf24@3602 | 52 addr = *stack++; |
kaf24@3602 | 53 if (kernel_text_address(addr)) { |
kaf24@3602 | 54 if (i && ((i % 6) == 0)) |
kaf24@3602 | 55 printk("\n "); |
kaf24@3621 | 56 printk("[<%p>] ", addr); |
kaf24@3602 | 57 i++; |
kaf24@3602 | 58 } |
kaf24@3602 | 59 } |
kaf24@3602 | 60 printk("\n"); |
kaf24@3602 | 61 } |
kaf24@3602 | 62 |
kaf24@3602 | 63 void show_stack(unsigned long *rsp) |
kaf24@3602 | 64 { |
kaf24@3602 | 65 unsigned long *stack; |
kaf24@3602 | 66 int i; |
kaf24@3602 | 67 |
kaf24@3621 | 68 printk("Stack trace from RSP=%p:\n ", rsp); |
kaf24@3602 | 69 |
kaf24@3602 | 70 stack = rsp; |
kaf24@3602 | 71 for ( i = 0; i < kstack_depth_to_print; i++ ) |
kaf24@3602 | 72 { |
kaf24@3602 | 73 if ( ((long)stack & (STACK_SIZE-1)) == 0 ) |
kaf24@3602 | 74 break; |
kaf24@3602 | 75 if ( i && ((i % 8) == 0) ) |
kaf24@3621 | 76 printk("\n "); |
kaf24@3602 | 77 if ( kernel_text_address(*stack) ) |
kaf24@3621 | 78 printk("[%p] ", *stack++); |
kaf24@3602 | 79 else |
kaf24@3621 | 80 printk("%p ", *stack++); |
kaf24@3602 | 81 } |
kaf24@3602 | 82 printk("\n"); |
kaf24@3602 | 83 |
kaf24@3602 | 84 show_trace(rsp); |
kaf24@3602 | 85 } |
kaf24@3602 | 86 |
kaf24@3602 | 87 void show_registers(struct xen_regs *regs) |
kaf24@3602 | 88 { |
kaf24@3621 | 89 printk("CPU: %d\nEIP: %04lx:[<%p>] \nEFLAGS: %p\n", |
kaf24@3602 | 90 smp_processor_id(), 0xffff & regs->cs, regs->rip, regs->eflags); |
kaf24@3621 | 91 printk("rax: %p rbx: %p rcx: %p rdx: %p\n", |
kaf24@3602 | 92 regs->rax, regs->rbx, regs->rcx, regs->rdx); |
kaf24@3621 | 93 printk("rsi: %p rdi: %p rbp: %p rsp: %p\n", |
kaf24@3621 | 94 regs->rsi, regs->rdi, regs->rbp, regs->rsp); |
kaf24@3621 | 95 printk("r8: %p r9: %p r10: %p r11: %p\n", |
kaf24@3602 | 96 regs->r8, regs->r9, regs->r10, regs->r11); |
kaf24@3621 | 97 printk("r12: %p r13: %p r14: %p r15: %p\n", |
kaf24@3602 | 98 regs->r12, regs->r13, regs->r14, regs->r15); |
kaf24@3602 | 99 |
kaf24@3602 | 100 show_stack((unsigned long *)regs->rsp); |
kaf24@3602 | 101 } |
kaf24@3602 | 102 |
kaf24@3630 | 103 void show_page_walk(unsigned long addr) |
kaf24@3630 | 104 { |
kaf24@3630 | 105 unsigned long page = read_cr3(); |
kaf24@3630 | 106 |
kaf24@3630 | 107 printk("Pagetable walk from %p:\n", addr); |
kaf24@3630 | 108 |
kaf24@3630 | 109 page &= PAGE_MASK; |
kaf24@3630 | 110 page = ((unsigned long *) __va(page))[l4_table_offset(addr)]; |
kaf24@3630 | 111 printk(" L4 = %p\n", page); |
kaf24@3630 | 112 if ( !(page & _PAGE_PRESENT) ) |
kaf24@3630 | 113 return; |
kaf24@3630 | 114 |
kaf24@3630 | 115 page &= PAGE_MASK; |
kaf24@3630 | 116 page = ((unsigned long *) __va(page))[l3_table_offset(addr)]; |
kaf24@3630 | 117 printk(" L3 = %p\n", page); |
kaf24@3630 | 118 if ( !(page & _PAGE_PRESENT) ) |
kaf24@3630 | 119 return; |
kaf24@3630 | 120 |
kaf24@3630 | 121 page &= PAGE_MASK; |
kaf24@3630 | 122 page = ((unsigned long *) __va(page))[l2_table_offset(addr)]; |
kaf24@3630 | 123 printk(" L2 = %p %s\n", page, (page & _PAGE_PSE) ? "(2MB)" : ""); |
kaf24@3630 | 124 if ( !(page & _PAGE_PRESENT) || (page & _PAGE_PSE) ) |
kaf24@3630 | 125 return; |
kaf24@3630 | 126 |
kaf24@3630 | 127 page &= PAGE_MASK; |
kaf24@3630 | 128 page = ((unsigned long *) __va(page))[l1_table_offset(addr)]; |
kaf24@3630 | 129 printk(" L1 = %p\n", page); |
kaf24@3630 | 130 } |
kaf24@3630 | 131 |
kaf24@3630 | 132 #define DOUBLEFAULT_STACK_SIZE 1024 |
kaf24@3630 | 133 static unsigned char doublefault_stack[DOUBLEFAULT_STACK_SIZE]; |
kaf24@3630 | 134 asmlinkage void double_fault(void); |
kaf24@3630 | 135 |
kaf24@3630 | 136 asmlinkage void do_double_fault(struct xen_regs *regs) |
kaf24@3630 | 137 { |
kaf24@3630 | 138 /* Disable the NMI watchdog. It's useless now. */ |
kaf24@3630 | 139 watchdog_on = 0; |
kaf24@3630 | 140 |
kaf24@3686 | 141 console_force_unlock(); |
kaf24@3686 | 142 |
kaf24@3630 | 143 /* Find information saved during fault and dump it to the console. */ |
kaf24@3630 | 144 printk("************************************\n"); |
kaf24@3630 | 145 printk("EIP: %04lx:[<%p>] \nEFLAGS: %p\n", |
kaf24@3630 | 146 0xffff & regs->cs, regs->rip, regs->eflags); |
kaf24@3630 | 147 printk("rax: %p rbx: %p rcx: %p rdx: %p\n", |
kaf24@3630 | 148 regs->rax, regs->rbx, regs->rcx, regs->rdx); |
kaf24@3630 | 149 printk("rsi: %p rdi: %p rbp: %p rsp: %p\n", |
kaf24@3630 | 150 regs->rsi, regs->rdi, regs->rbp, regs->rsp); |
kaf24@3630 | 151 printk("r8: %p r9: %p r10: %p r11: %p\n", |
kaf24@3630 | 152 regs->r8, regs->r9, regs->r10, regs->r11); |
kaf24@3630 | 153 printk("r12: %p r13: %p r14: %p r15: %p\n", |
kaf24@3630 | 154 regs->r12, regs->r13, regs->r14, regs->r15); |
kaf24@3630 | 155 printk("************************************\n"); |
kaf24@3630 | 156 printk("CPU%d DOUBLE FAULT -- system shutdown\n", |
kaf24@3630 | 157 logical_smp_processor_id()); |
kaf24@3630 | 158 printk("System needs manual reset.\n"); |
kaf24@3630 | 159 printk("************************************\n"); |
kaf24@3630 | 160 |
kaf24@3630 | 161 /* Lock up the console to prevent spurious output from other CPUs. */ |
kaf24@3630 | 162 console_force_lock(); |
kaf24@3630 | 163 |
kaf24@3630 | 164 /* Wait for manual reset. */ |
kaf24@3630 | 165 for ( ; ; ) |
kaf24@3630 | 166 __asm__ __volatile__ ( "hlt" ); |
kaf24@3630 | 167 } |
kaf24@3630 | 168 |
kaf24@3602 | 169 void __init doublefault_init(void) |
kaf24@3602 | 170 { |
kaf24@3630 | 171 int i; |
kaf24@3630 | 172 |
kaf24@3630 | 173 /* Initialise IST1 for each CPU. Note the handler is non-reentrant. */ |
kaf24@3630 | 174 for ( i = 0; i < NR_CPUS; i++ ) |
kaf24@3630 | 175 init_tss[i].ist[0] = (unsigned long) |
kaf24@3630 | 176 &doublefault_stack[DOUBLEFAULT_STACK_SIZE]; |
kaf24@3630 | 177 |
kaf24@3630 | 178 /* Set interrupt gate for double faults, specifying IST1. */ |
kaf24@3630 | 179 set_intr_gate(TRAP_double_fault, &double_fault); |
kaf24@3630 | 180 idt_table[TRAP_double_fault].a |= 1UL << 32; /* IST1 */ |
kaf24@3602 | 181 } |
kaf24@3602 | 182 |
kaf24@3650 | 183 asmlinkage void hypercall(void); |
kaf24@3650 | 184 void __init percpu_traps_init(void) |
kaf24@3650 | 185 { |
kaf24@3650 | 186 char *stack_top = (char *)get_stack_top(); |
kaf24@3650 | 187 char *stack = (char *)((unsigned long)stack_top & ~(STACK_SIZE - 1)); |
kaf24@3650 | 188 |
kaf24@3650 | 189 /* movq %rsp, saversp(%rip) */ |
kaf24@3650 | 190 stack[0] = 0x48; |
kaf24@3650 | 191 stack[1] = 0x89; |
kaf24@3650 | 192 stack[2] = 0x25; |
kaf24@3650 | 193 *(u32 *)&stack[3] = (stack_top - &stack[7]) - 16; |
kaf24@3650 | 194 |
kaf24@3650 | 195 /* leaq saversp(%rip), %rsp */ |
kaf24@3650 | 196 stack[7] = 0x48; |
kaf24@3650 | 197 stack[8] = 0x8d; |
kaf24@3650 | 198 stack[9] = 0x25; |
kaf24@3650 | 199 *(u32 *)&stack[10] = (stack_top - &stack[14]) - 16; |
kaf24@3650 | 200 |
kaf24@3650 | 201 /* jmp hypercall */ |
kaf24@3650 | 202 stack[14] = 0xe9; |
kaf24@3650 | 203 *(u32 *)&stack[15] = (char *)hypercall - &stack[19]; |
kaf24@3650 | 204 |
kaf24@3650 | 205 wrmsr(MSR_STAR, 0, (FLAT_RING3_CS64<<16) | __HYPERVISOR_CS); |
kaf24@3650 | 206 wrmsr(MSR_LSTAR, (unsigned long)stack, ((unsigned long)stack>>32)); |
kaf24@3650 | 207 wrmsr(MSR_SYSCALL_MASK, 0xFFFFFFFFU, 0U); |
kaf24@3650 | 208 } |
kaf24@3650 | 209 |
kaf24@3602 | 210 void *decode_reg(struct xen_regs *regs, u8 b) |
kaf24@3602 | 211 { |
kaf24@3602 | 212 switch ( b ) |
kaf24@3602 | 213 { |
kaf24@3602 | 214 case 0: return ®s->rax; |
kaf24@3602 | 215 case 1: return ®s->rcx; |
kaf24@3602 | 216 case 2: return ®s->rdx; |
kaf24@3602 | 217 case 3: return ®s->rbx; |
kaf24@3602 | 218 case 4: return ®s->rsp; |
kaf24@3602 | 219 case 5: return ®s->rbp; |
kaf24@3602 | 220 case 6: return ®s->rsi; |
kaf24@3602 | 221 case 7: return ®s->rdi; |
kaf24@3602 | 222 case 8: return ®s->r8; |
kaf24@3602 | 223 case 9: return ®s->r9; |
kaf24@3602 | 224 case 10: return ®s->r10; |
kaf24@3602 | 225 case 11: return ®s->r11; |
kaf24@3602 | 226 case 12: return ®s->r12; |
kaf24@3602 | 227 case 13: return ®s->r13; |
kaf24@3602 | 228 case 14: return ®s->r14; |
kaf24@3602 | 229 case 15: return ®s->r15; |
kaf24@3602 | 230 } |
kaf24@3602 | 231 |
kaf24@3602 | 232 return NULL; |
kaf24@3602 | 233 } |