ia64/xen-unstable

view xen/arch/i386/traps.c @ 722:7a9d47fea66c

bitkeeper revision 1.428 (3f677454_j81KDQLm_L7AscjYn2nYg)

Merge labyrinth.cl.cam.ac.uk:/auto/groups/xeno/BK/xeno.bk
into labyrinth.cl.cam.ac.uk:/auto/anfs/scratch/labyrinth/iap10/xeno-clone/xeno.bk
author iap10@labyrinth.cl.cam.ac.uk
date Tue Sep 16 20:36:36 2003 +0000 (2003-09-16)
parents 76b59b68bc65 d0cdb9994a2b
children 8e974c88fa7a
line source
1 /*
2 * xen/arch/i386/traps.c
3 *
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 *
6 * Pentium III FXSR, SSE support
7 * Gareth Hughes <gareth@valinux.com>, May 2000
8 */
10 #include <xeno/config.h>
11 #include <xeno/init.h>
12 #include <xeno/interrupt.h>
13 #include <xeno/sched.h>
14 #include <xeno/lib.h>
15 #include <xeno/errno.h>
16 #include <xeno/mm.h>
17 #include <asm/ptrace.h>
18 #include <xeno/delay.h>
19 #include <xeno/spinlock.h>
20 #include <xeno/irq.h>
21 #include <xeno/perfc.h>
22 #include <asm/domain_page.h>
23 #include <asm/system.h>
24 #include <asm/io.h>
25 #include <asm/atomic.h>
26 #include <asm/desc.h>
27 #include <asm/debugreg.h>
28 #include <asm/smp.h>
29 #include <asm/pgalloc.h>
30 #include <asm/uaccess.h>
31 #include <asm/i387.h>
33 #define GTBF_TRAP 1
34 #define GTBF_TRAP_NOCODE 2
35 #define GTBF_TRAP_CR2 4
36 struct guest_trap_bounce {
37 unsigned long error_code; /* 0 */
38 unsigned long cr2; /* 4 */
39 unsigned short flags; /* 8 */
40 unsigned short cs; /* 10 */
41 unsigned long eip; /* 12 */
42 } guest_trap_bounce[NR_CPUS] = { { 0 } };
44 #define DOUBLEFAULT_STACK_SIZE 1024
45 static struct tss_struct doublefault_tss;
46 static unsigned char doublefault_stack[DOUBLEFAULT_STACK_SIZE];
48 asmlinkage int hypervisor_call(void);
49 asmlinkage void lcall7(void);
50 asmlinkage void lcall27(void);
52 /* Master table, and the one used by CPU0. */
53 struct desc_struct idt_table[256] = { {0, 0}, };
54 /* All other CPUs have their own copy. */
55 struct desc_struct *idt_tables[NR_CPUS] = { 0 };
57 asmlinkage void divide_error(void);
58 asmlinkage void debug(void);
59 asmlinkage void nmi(void);
60 asmlinkage void int3(void);
61 asmlinkage void overflow(void);
62 asmlinkage void bounds(void);
63 asmlinkage void invalid_op(void);
64 asmlinkage void device_not_available(void);
65 asmlinkage void coprocessor_segment_overrun(void);
66 asmlinkage void invalid_TSS(void);
67 asmlinkage void segment_not_present(void);
68 asmlinkage void stack_segment(void);
69 asmlinkage void general_protection(void);
70 asmlinkage void page_fault(void);
71 asmlinkage void coprocessor_error(void);
72 asmlinkage void simd_coprocessor_error(void);
73 asmlinkage void alignment_check(void);
74 asmlinkage void spurious_interrupt_bug(void);
75 asmlinkage void machine_check(void);
77 int kstack_depth_to_print = 8*20;
79 static inline int kernel_text_address(unsigned long addr)
80 {
81 if (addr >= (unsigned long) &_stext &&
82 addr <= (unsigned long) &_etext)
83 return 1;
84 return 0;
86 }
88 void show_trace(unsigned long * stack)
89 {
90 int i;
91 unsigned long addr;
93 if (!stack)
94 stack = (unsigned long*)&stack;
96 printk("Call Trace: ");
97 i = 1;
98 while (((long) stack & (THREAD_SIZE-1)) != 0) {
99 addr = *stack++;
100 if (kernel_text_address(addr)) {
101 if (i && ((i % 6) == 0))
102 printk("\n ");
103 printk("[<%08lx>] ", addr);
104 i++;
105 }
106 }
107 printk("\n");
108 }
110 void show_trace_task(struct task_struct *tsk)
111 {
112 unsigned long esp = tsk->thread.esp;
114 /* User space on another CPU? */
115 if ((esp ^ (unsigned long)tsk) & (PAGE_MASK<<1))
116 return;
117 show_trace((unsigned long *)esp);
118 }
120 void show_stack(unsigned long * esp)
121 {
122 unsigned long *stack;
123 int i;
125 if ( esp == NULL )
126 esp = (unsigned long *)&esp;
128 printk("Stack trace from ESP=%p:\n", esp);
130 stack = esp;
131 for ( i = 0; i < kstack_depth_to_print; i++ )
132 {
133 if ( ((long)stack & (THREAD_SIZE-1)) == 0 )
134 break;
135 if ( i && ((i % 8) == 0) )
136 printk("\n ");
137 if ( kernel_text_address(*stack) )
138 printk("[%08lx] ", *stack++);
139 else
140 printk("%08lx ", *stack++);
141 }
142 printk("\n");
143 }
145 void show_registers(struct pt_regs *regs)
146 {
147 unsigned long esp;
148 unsigned short ss;
150 esp = (unsigned long) (&regs->esp);
151 ss = __HYPERVISOR_DS;
152 if ( regs->xcs & 3 )
153 {
154 esp = regs->esp;
155 ss = regs->xss & 0xffff;
156 }
158 printk("CPU: %d\nEIP: %04x:[<%08lx>] \nEFLAGS: %08lx\n",
159 smp_processor_id(), 0xffff & regs->xcs, regs->eip, regs->eflags);
160 printk("eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n",
161 regs->eax, regs->ebx, regs->ecx, regs->edx);
162 printk("esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n",
163 regs->esi, regs->edi, regs->ebp, esp);
164 printk("ds: %04x es: %04x fs: %04x gs: %04x ss: %04x\n",
165 regs->xds & 0xffff, regs->xes & 0xffff,
166 regs->xfs & 0xffff, regs->xgs & 0xffff, ss);
168 show_stack(&regs->esp);
169 }
172 spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
174 void die(const char * str, struct pt_regs * regs, long err)
175 {
176 unsigned long flags;
177 spin_lock_irqsave(&die_lock, flags);
178 printk("%s: %04lx,%04lx\n", str, err >> 16, err & 0xffff);
179 show_registers(regs);
180 spin_unlock_irqrestore(&die_lock, flags);
181 panic("HYPERVISOR DEATH!!\n");
182 }
184 static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
185 {
186 if (!(3 & regs->xcs)) die(str, regs, err);
187 }
189 static void inline do_trap(int trapnr, char *str,
190 struct pt_regs * regs,
191 long error_code, int use_error_code)
192 {
193 struct task_struct *p = current;
194 struct guest_trap_bounce *gtb = guest_trap_bounce+smp_processor_id();
195 trap_info_t *ti;
196 unsigned long fixup;
198 if (!(regs->xcs & 3))
199 goto fault_in_hypervisor;
201 ti = current->thread.traps + trapnr;
202 gtb->flags = use_error_code ? GTBF_TRAP : GTBF_TRAP_NOCODE;
203 gtb->error_code = error_code;
204 gtb->cs = ti->cs;
205 gtb->eip = ti->address;
206 if ( TI_GET_IF(ti) )
207 clear_bit(EVENTS_MASTER_ENABLE_BIT, &p->shared_info->events_mask);
208 return;
210 fault_in_hypervisor:
212 if ( (fixup = search_exception_table(regs->eip)) != 0 )
213 {
214 regs->eip = fixup;
215 regs->xfs = regs->xgs = 0;
216 return;
217 }
219 show_registers(regs);
220 panic("CPU%d FATAL TRAP: vector = %d (%s)\n"
221 "[error_code=%08x]\n",
222 smp_processor_id(), trapnr, str, error_code);
223 }
225 #define DO_ERROR_NOCODE(trapnr, str, name) \
226 asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
227 { \
228 do_trap(trapnr, str, regs, error_code, 0); \
229 }
231 #define DO_ERROR(trapnr, str, name) \
232 asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
233 { \
234 do_trap(trapnr, str, regs, error_code, 1); \
235 }
237 DO_ERROR_NOCODE( 0, "divide error", divide_error)
238 DO_ERROR_NOCODE( 3, "int3", int3)
239 DO_ERROR_NOCODE( 4, "overflow", overflow)
240 DO_ERROR_NOCODE( 5, "bounds", bounds)
241 DO_ERROR_NOCODE( 6, "invalid operand", invalid_op)
242 DO_ERROR_NOCODE( 7, "device not available", device_not_available)
243 DO_ERROR_NOCODE( 9, "coprocessor segment overrun", coprocessor_segment_overrun)
244 DO_ERROR(10, "invalid TSS", invalid_TSS)
245 DO_ERROR(11, "segment not present", segment_not_present)
246 DO_ERROR(12, "stack segment", stack_segment)
247 /* Vector 15 reserved by Intel */
248 DO_ERROR_NOCODE(16, "fpu error", coprocessor_error)
249 DO_ERROR(17, "alignment check", alignment_check)
250 DO_ERROR_NOCODE(18, "machine check", machine_check)
251 DO_ERROR_NOCODE(19, "simd error", simd_coprocessor_error)
253 asmlinkage void do_double_fault(void)
254 {
255 extern spinlock_t console_lock;
256 struct tss_struct *tss = &doublefault_tss;
257 unsigned int cpu = ((tss->back_link>>3)-__FIRST_TSS_ENTRY)>>1;
259 /* Disable the NMI watchdog. It's useless now. */
260 watchdog_on = 0;
262 /* Find information saved during fault and dump it to the console. */
263 tss = &init_tss[cpu];
264 printk("CPU: %d\nEIP: %04x:[<%08lx>] \nEFLAGS: %08lx\n",
265 cpu, tss->cs, tss->eip, tss->eflags);
266 printk("CR3: %08lx\n", tss->__cr3);
267 printk("eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n",
268 tss->eax, tss->ebx, tss->ecx, tss->edx);
269 printk("esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n",
270 tss->esi, tss->edi, tss->ebp, tss->esp);
271 printk("ds: %04x es: %04x fs: %04x gs: %04x ss: %04x\n",
272 tss->ds, tss->es, tss->fs, tss->gs, tss->ss);
273 printk("************************************\n");
274 printk("CPU%d DOUBLE FAULT -- system shutdown\n", cpu);
275 printk("System needs manual reset.\n");
276 printk("************************************\n");
278 /* Lock up the console to prevent spurious output from other CPUs. */
279 spin_lock(&console_lock);
281 /* Wait for manual reset. */
282 for ( ; ; ) ;
283 }
285 asmlinkage void do_page_fault(struct pt_regs *regs, long error_code)
286 {
287 struct guest_trap_bounce *gtb = guest_trap_bounce+smp_processor_id();
288 trap_info_t *ti;
289 l2_pgentry_t *pl2e;
290 l1_pgentry_t *pl1e;
291 unsigned long addr, off, fixup, l2e, l1e, *ldt_page;
292 struct task_struct *p = current;
293 struct pfn_info *page;
294 int i;
296 __asm__ __volatile__ ("movl %%cr2,%0" : "=r" (addr) : );
298 if ( unlikely(addr > PAGE_OFFSET) )
299 goto fault_in_xen_space;
301 bounce_fault:
303 if ( unlikely(!(regs->xcs & 3)) )
304 goto fault_in_hypervisor;
306 ti = p->thread.traps + 14;
307 gtb->flags = GTBF_TRAP_CR2; /* page fault pushes %cr2 */
308 gtb->cr2 = addr;
309 gtb->error_code = error_code;
310 gtb->cs = ti->cs;
311 gtb->eip = ti->address;
312 if ( TI_GET_IF(ti) )
313 clear_bit(EVENTS_MASTER_ENABLE_BIT, &p->shared_info->events_mask);
314 return;
316 /*
317 * FAULT IN XEN ADDRESS SPACE:
318 * We only deal with one kind -- a fault in the shadow LDT mapping.
319 * If this occurs we pull a mapping from the guest's LDT, if it is
320 * valid. Otherwise we send the fault up to the guest OS to be handled.
321 */
322 fault_in_xen_space:
324 if ( (addr < LDT_VIRT_START) ||
325 (addr >= (LDT_VIRT_START + (p->mm.ldt_ents*LDT_ENTRY_SIZE))) )
326 goto bounce_fault;
328 off = addr - LDT_VIRT_START;
329 addr = p->mm.ldt_base + off;
331 spin_lock(&p->page_lock);
333 pl2e = map_domain_mem(pagetable_val(p->mm.pagetable));
334 l2e = l2_pgentry_val(pl2e[l2_table_offset(addr)]);
335 unmap_domain_mem(pl2e);
336 if ( !(l2e & _PAGE_PRESENT) )
337 goto unlock_and_bounce_fault;
339 pl1e = map_domain_mem(l2e & PAGE_MASK);
340 l1e = l1_pgentry_val(pl1e[l1_table_offset(addr)]);
341 unmap_domain_mem(pl1e);
342 if ( !(l1e & _PAGE_PRESENT) )
343 goto unlock_and_bounce_fault;
345 page = frame_table + (l1e >> PAGE_SHIFT);
346 if ( (page->flags & PG_type_mask) != PGT_ldt_page )
347 {
348 if ( page->type_count != 0 )
349 goto unlock_and_bounce_fault;
351 /* Check all potential LDT entries in the page. */
352 ldt_page = map_domain_mem(l1e & PAGE_MASK);
353 for ( i = 0; i < 512; i++ )
354 if ( !check_descriptor(ldt_page[i*2], ldt_page[i*2+1]) )
355 goto unlock_and_bounce_fault;
356 unmap_domain_mem(ldt_page);
358 if ( page->flags & PG_need_flush )
359 {
360 perfc_incrc(need_flush_tlb_flush);
361 local_flush_tlb();
362 page->flags &= ~PG_need_flush;
363 }
365 page->flags &= ~PG_type_mask;
366 page->flags |= PGT_ldt_page;
367 }
369 /* Success! */
370 get_page_type(page);
371 get_page_tot(page);
372 p->mm.perdomain_pt[l1_table_offset(off)+16] = mk_l1_pgentry(l1e|_PAGE_RW);
373 p->mm.shadow_ldt_mapcnt++;
375 spin_unlock(&p->page_lock);
376 return;
379 unlock_and_bounce_fault:
381 spin_unlock(&p->page_lock);
382 goto bounce_fault;
385 fault_in_hypervisor:
387 if ( (fixup = search_exception_table(regs->eip)) != 0 )
388 {
389 regs->eip = fixup;
390 regs->xfs = regs->xgs = 0;
391 return;
392 }
394 if ( addr >= PAGE_OFFSET )
395 {
396 unsigned long page;
397 unsigned long *pde;
398 pde = (unsigned long *)idle_pg_table[smp_processor_id()];
399 page = pde[addr >> L2_PAGETABLE_SHIFT];
400 printk("*pde = %08lx\n", page);
401 if ( page & _PAGE_PRESENT )
402 {
403 page &= PAGE_MASK;
404 page = ((unsigned long *) __va(page))[(addr&0x3ff000)>>PAGE_SHIFT];
405 printk(" *pte = %08lx\n", page);
406 }
407 }
409 show_registers(regs);
410 panic("CPU%d FATAL PAGE FAULT\n"
411 "[error_code=%08x]\n"
412 "Faulting linear address might be %08lx\n",
413 smp_processor_id(), error_code, addr);
414 }
416 asmlinkage void do_general_protection(struct pt_regs *regs, long error_code)
417 {
418 struct task_struct *p = current;
419 struct guest_trap_bounce *gtb = guest_trap_bounce+smp_processor_id();
420 trap_info_t *ti;
421 unsigned long fixup;
423 /* Bad shit if error in ring 0, or result of an interrupt. */
424 if (!(regs->xcs & 3) || (error_code & 1))
425 goto gp_in_kernel;
427 /*
428 * Cunning trick to allow arbitrary "INT n" handling.
429 *
430 * We set DPL == 0 on all vectors in the IDT. This prevents any INT <n>
431 * instruction from trapping to the appropriate vector, when that might not
432 * be expected by Xen or the guest OS. For example, that entry might be for
433 * a fault handler (unlike traps, faults don't increment EIP), or might
434 * expect an error code on the stack (which a software trap never
435 * provides), or might be a hardware interrupt handler that doesn't like
436 * being called spuriously.
437 *
438 * Instead, a GPF occurs with the faulting IDT vector in the error code.
439 * Bit 1 is set to indicate that an IDT entry caused the fault. Bit 0 is
440 * clear to indicate that it's a software fault, not hardware.
441 *
442 * NOTE: Vectors 3 and 4 are dealt with from their own handler. This is
443 * okay because they can only be triggered by an explicit DPL-checked
444 * instruction. The DPL specified by the guest OS for these vectors is NOT
445 * CHECKED!!
446 */
447 if ( (error_code & 3) == 2 )
448 {
449 /* This fault must be due to <INT n> instruction. */
450 ti = current->thread.traps + (error_code>>3);
451 if ( TI_GET_DPL(ti) >= (regs->xcs & 3) )
452 {
453 gtb->flags = GTBF_TRAP_NOCODE;
454 regs->eip += 2;
455 goto finish_propagation;
456 }
457 }
459 /* Pass on GPF as is. */
460 ti = current->thread.traps + 13;
461 gtb->flags = GTBF_TRAP;
462 gtb->error_code = error_code;
463 finish_propagation:
464 gtb->cs = ti->cs;
465 gtb->eip = ti->address;
466 if ( TI_GET_IF(ti) )
467 clear_bit(EVENTS_MASTER_ENABLE_BIT, &p->shared_info->events_mask);
468 return;
470 gp_in_kernel:
472 if ( (fixup = search_exception_table(regs->eip)) != 0 )
473 {
474 regs->eip = fixup;
475 regs->xfs = regs->xgs = 0;
476 return;
477 }
479 die("general protection fault", regs, error_code);
480 }
482 static void mem_parity_error(unsigned char reason, struct pt_regs * regs)
483 {
484 printk("Uhhuh. NMI received. Dazed and confused, but trying to continue\n");
485 printk("You probably have a hardware problem with your RAM chips\n");
487 /* Clear and disable the memory parity error line. */
488 reason = (reason & 0xf) | 4;
489 outb(reason, 0x61);
490 }
492 static void io_check_error(unsigned char reason, struct pt_regs * regs)
493 {
494 unsigned long i;
496 printk("NMI: IOCK error (debug interrupt?)\n");
497 show_registers(regs);
499 /* Re-enable the IOCK line, wait for a few seconds */
500 reason = (reason & 0xf) | 8;
501 outb(reason, 0x61);
502 i = 2000;
503 while (--i) udelay(1000);
504 reason &= ~8;
505 outb(reason, 0x61);
506 }
508 static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
509 {
510 printk("Uhhuh. NMI received for unknown reason %02x.\n", reason);
511 printk("Dazed and confused, but trying to continue\n");
512 printk("Do you have a strange power saving mode enabled?\n");
513 }
515 asmlinkage void do_nmi(struct pt_regs * regs, long error_code)
516 {
517 unsigned char reason = inb(0x61);
519 ++nmi_count(smp_processor_id());
521 if (!(reason & 0xc0)) {
522 #if CONFIG_X86_LOCAL_APIC
523 if (nmi_watchdog) {
524 nmi_watchdog_tick(regs);
525 return;
526 }
527 #endif
528 unknown_nmi_error(reason, regs);
529 return;
530 }
531 if (reason & 0x80)
532 mem_parity_error(reason, regs);
533 if (reason & 0x40)
534 io_check_error(reason, regs);
535 /*
536 * Reassert NMI in case it became active meanwhile
537 * as it's edge-triggered.
538 */
539 outb(0x8f, 0x70);
540 inb(0x71); /* dummy */
541 outb(0x0f, 0x70);
542 inb(0x71); /* dummy */
543 }
545 asmlinkage void math_state_restore(struct pt_regs *regs, long error_code)
546 {
547 /* Prevent recursion. */
548 clts();
550 if ( !(current->flags & PF_USEDFPU) )
551 {
552 if ( current->flags & PF_DONEFPUINIT )
553 restore_fpu(current);
554 else
555 init_fpu();
556 current->flags |= PF_USEDFPU; /* So we fnsave on switch_to() */
557 }
559 if ( current->flags & PF_GUEST_STTS )
560 {
561 struct guest_trap_bounce *gtb = guest_trap_bounce+smp_processor_id();
562 gtb->flags = GTBF_TRAP_NOCODE;
563 gtb->cs = current->thread.traps[7].cs;
564 gtb->eip = current->thread.traps[7].address;
565 current->flags &= ~PF_GUEST_STTS;
566 }
567 }
570 asmlinkage void do_debug(struct pt_regs * regs, long error_code)
571 {
572 unsigned int condition;
573 struct task_struct *tsk = current;
574 struct guest_trap_bounce *gtb = guest_trap_bounce+smp_processor_id();
576 __asm__ __volatile__("movl %%db6,%0" : "=r" (condition));
578 /* Mask out spurious debug traps due to lazy DR7 setting */
579 if ( (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) &&
580 (tsk->thread.debugreg[7] == 0) )
581 {
582 __asm__("movl %0,%%db7" : : "r" (0));
583 return;
584 }
586 if ( (regs->xcs & 3) == 0 )
587 {
588 /* Clear TF just for absolute sanity. */
589 regs->eflags &= ~EF_TF;
590 /*
591 * Basically, we ignore watchpoints when they trigger in
592 * the hypervisor. This may happen when a buffer is passed
593 * to us which previously had a watchpoint set on it.
594 * No need to bump EIP; the only faulting trap is an
595 * instruction breakpoint, which can't happen to us.
596 */
597 return;
598 }
600 /* Save debug status register where guest OS can peek at it */
601 tsk->thread.debugreg[6] = condition;
603 gtb->flags = GTBF_TRAP_NOCODE;
604 gtb->cs = tsk->thread.traps[1].cs;
605 gtb->eip = tsk->thread.traps[1].address;
606 }
609 asmlinkage void do_spurious_interrupt_bug(struct pt_regs * regs,
610 long error_code)
611 { /* nothing */ }
614 #define _set_gate(gate_addr,type,dpl,addr) \
615 do { \
616 int __d0, __d1; \
617 __asm__ __volatile__ ("movw %%dx,%%ax\n\t" \
618 "movw %4,%%dx\n\t" \
619 "movl %%eax,%0\n\t" \
620 "movl %%edx,%1" \
621 :"=m" (*((long *) (gate_addr))), \
622 "=m" (*(1+(long *) (gate_addr))), "=&a" (__d0), "=&d" (__d1) \
623 :"i" ((short) (0x8000+(dpl<<13)+(type<<8))), \
624 "3" ((char *) (addr)),"2" (__HYPERVISOR_CS << 16)); \
625 } while (0)
627 void set_intr_gate(unsigned int n, void *addr)
628 {
629 _set_gate(idt_table+n,14,0,addr);
630 }
632 static void __init set_system_gate(unsigned int n, void *addr)
633 {
634 _set_gate(idt_table+n,14,3,addr);
635 }
637 static void set_task_gate(unsigned int n, unsigned int sel)
638 {
639 idt_table[n].a = sel << 16;
640 idt_table[n].b = 0x8500;
641 }
643 #define _set_seg_desc(gate_addr,type,dpl,base,limit) {\
644 *((gate_addr)+1) = ((base) & 0xff000000) | \
645 (((base) & 0x00ff0000)>>16) | \
646 ((limit) & 0xf0000) | \
647 ((dpl)<<13) | \
648 (0x00408000) | \
649 ((type)<<8); \
650 *(gate_addr) = (((base) & 0x0000ffff)<<16) | \
651 ((limit) & 0x0ffff); }
653 #define _set_tssldt_desc(n,addr,limit,type) \
654 __asm__ __volatile__ ("movw %w3,0(%2)\n\t" \
655 "movw %%ax,2(%2)\n\t" \
656 "rorl $16,%%eax\n\t" \
657 "movb %%al,4(%2)\n\t" \
658 "movb %4,5(%2)\n\t" \
659 "movb $0,6(%2)\n\t" \
660 "movb %%ah,7(%2)\n\t" \
661 "rorl $16,%%eax" \
662 : "=m"(*(n)) : "a" (addr), "r"(n), "ir"(limit), "i"(type))
664 void set_tss_desc(unsigned int n, void *addr)
665 {
666 _set_tssldt_desc(gdt_table+__TSS(n), (int)addr, 235, 0x89);
667 }
669 void __init trap_init(void)
670 {
671 /*
672 * Make a separate task for double faults. This will get us debug output if
673 * we blow the kernel stack.
674 */
675 struct tss_struct *tss = &doublefault_tss;
676 memset(tss, 0, sizeof(*tss));
677 tss->ds = __HYPERVISOR_DS;
678 tss->es = __HYPERVISOR_DS;
679 tss->ss = __HYPERVISOR_DS;
680 tss->esp = (unsigned long)
681 &doublefault_stack[DOUBLEFAULT_STACK_SIZE];
682 tss->__cr3 = __pa(idle0_pg_table);
683 tss->cs = __HYPERVISOR_CS;
684 tss->eip = (unsigned long)do_double_fault;
685 tss->eflags = 2;
686 tss->bitmap = INVALID_IO_BITMAP_OFFSET;
687 _set_tssldt_desc(gdt_table+__DOUBLEFAULT_TSS_ENTRY,
688 (int)tss, 235, 0x89);
690 /*
691 * Note that interrupt gates are always used, rather than trap gates. We
692 * must have interrupts disabled until DS/ES/FS/GS are saved because the
693 * first activation must have the "bad" value(s) for these registers and
694 * we may lose them if another activation is installed before they are
695 * saved. The page-fault handler also needs interrupts disabled until %cr2
696 * has been read and saved on the stack.
697 */
698 set_intr_gate(0,&divide_error);
699 set_intr_gate(1,&debug);
700 set_intr_gate(2,&nmi);
701 set_system_gate(3,&int3); /* usable from all privilege levels */
702 set_system_gate(4,&overflow); /* usable from all privilege levels */
703 set_intr_gate(5,&bounds);
704 set_intr_gate(6,&invalid_op);
705 set_intr_gate(7,&device_not_available);
706 set_task_gate(8,__DOUBLEFAULT_TSS_ENTRY<<3);
707 set_intr_gate(9,&coprocessor_segment_overrun);
708 set_intr_gate(10,&invalid_TSS);
709 set_intr_gate(11,&segment_not_present);
710 set_intr_gate(12,&stack_segment);
711 set_intr_gate(13,&general_protection);
712 set_intr_gate(14,&page_fault);
713 set_intr_gate(15,&spurious_interrupt_bug);
714 set_intr_gate(16,&coprocessor_error);
715 set_intr_gate(17,&alignment_check);
716 set_intr_gate(18,&machine_check);
717 set_intr_gate(19,&simd_coprocessor_error);
719 /* Only ring 1 can access monitor services. */
720 _set_gate(idt_table+HYPERVISOR_CALL_VECTOR,14,1,&hypervisor_call);
722 /* CPU0 uses the master IDT. */
723 idt_tables[0] = idt_table;
725 /*
726 * Should be a barrier for any external CPU state.
727 */
728 {
729 extern void cpu_init(void);
730 cpu_init();
731 }
732 }
735 long do_set_trap_table(trap_info_t *traps)
736 {
737 trap_info_t cur;
738 trap_info_t *dst = current->thread.traps;
740 for ( ; ; )
741 {
742 if ( copy_from_user(&cur, traps, sizeof(cur)) ) return -EFAULT;
744 if ( cur.address == 0 ) break;
746 if ( !VALID_CODESEL(cur.cs) ) return -EPERM;
748 memcpy(dst+cur.vector, &cur, sizeof(cur));
749 traps++;
750 }
752 return 0;
753 }
756 long do_set_callbacks(unsigned long event_selector,
757 unsigned long event_address,
758 unsigned long failsafe_selector,
759 unsigned long failsafe_address)
760 {
761 struct task_struct *p = current;
763 if ( !VALID_CODESEL(event_selector) || !VALID_CODESEL(failsafe_selector) )
764 return -EPERM;
766 p->event_selector = event_selector;
767 p->event_address = event_address;
768 p->failsafe_selector = failsafe_selector;
769 p->failsafe_address = failsafe_address;
771 return 0;
772 }
775 long do_set_fast_trap(int idx)
776 {
777 trap_info_t *ti;
779 /* Index 0 is special: it disables fast traps. */
780 if ( idx == 0 )
781 {
782 CLEAR_FAST_TRAP(&current->thread);
783 SET_DEFAULT_FAST_TRAP(&current->thread);
784 return 0;
785 }
787 /*
788 * We only fast-trap vectors 0x20-0x2f, and vector 0x80.
789 * The former range is used by Windows and MS-DOS.
790 * Vector 0x80 is used by Linux and the BSD variants.
791 */
792 if ( (idx != 0x80) && ((idx < 0x20) || (idx > 0x2f)) )
793 return -1;
795 ti = current->thread.traps + idx;
797 /*
798 * We can't virtualise interrupt gates, as there's no way to get
799 * the CPU to automatically clear the events_mask variable.
800 */
801 if ( TI_GET_IF(ti) )
802 return -1;
804 CLEAR_FAST_TRAP(&current->thread);
806 current->thread.fast_trap_idx = idx;
807 current->thread.fast_trap_desc.a = (ti->cs << 16) | (ti->address & 0xffff);
808 current->thread.fast_trap_desc.b =
809 (ti->address & 0xffff0000) | 0x8f00 | (TI_GET_DPL(ti)&3)<<13;
811 SET_FAST_TRAP(&current->thread);
813 return 0;
814 }
817 long do_fpu_taskswitch(void)
818 {
819 current->flags |= PF_GUEST_STTS;
820 stts();
821 return 0;
822 }
825 long do_set_debugreg(int reg, unsigned long value)
826 {
827 int i;
829 switch ( reg )
830 {
831 case 0:
832 if ( value > (PAGE_OFFSET-4) ) return -EPERM;
833 __asm__ ( "movl %0, %%db0" : : "r" (value) );
834 break;
835 case 1:
836 if ( value > (PAGE_OFFSET-4) ) return -EPERM;
837 __asm__ ( "movl %0, %%db1" : : "r" (value) );
838 break;
839 case 2:
840 if ( value > (PAGE_OFFSET-4) ) return -EPERM;
841 __asm__ ( "movl %0, %%db2" : : "r" (value) );
842 break;
843 case 3:
844 if ( value > (PAGE_OFFSET-4) ) return -EPERM;
845 __asm__ ( "movl %0, %%db3" : : "r" (value) );
846 break;
847 case 6:
848 /*
849 * DR6: Bits 4-11,16-31 reserved (set to 1).
850 * Bit 12 reserved (set to 0).
851 */
852 value &= 0xffffefff; /* reserved bits => 0 */
853 value |= 0xffff0ff0; /* reserved bits => 1 */
854 __asm__ ( "movl %0, %%db6" : : "r" (value) );
855 break;
856 case 7:
857 /*
858 * DR7: Bit 10 reserved (set to 1).
859 * Bits 11-12,14-15 reserved (set to 0).
860 * Privileged bits:
861 * GD (bit 13): must be 0.
862 * R/Wn (bits 16-17,20-21,24-25,28-29): mustn't be 10.
863 * LENn (bits 18-19,22-23,26-27,30-31): mustn't be 10.
864 */
865 /* DR7 == 0 => debugging disabled for this domain. */
866 if ( value != 0 )
867 {
868 value &= 0xffff27ff; /* reserved bits => 0 */
869 value |= 0x00000400; /* reserved bits => 1 */
870 if ( (value & (1<<13)) != 0 ) return -EPERM;
871 for ( i = 0; i < 16; i += 2 )
872 if ( ((value >> (i+16)) & 3) == 2 ) return -EPERM;
873 }
874 __asm__ ( "movl %0, %%db7" : : "r" (value) );
875 break;
876 default:
877 return -EINVAL;
878 }
880 current->thread.debugreg[reg] = value;
881 return 0;
882 }
884 unsigned long do_get_debugreg(int reg)
885 {
886 if ( (reg < 0) || (reg > 7) ) return -EINVAL;
887 return current->thread.debugreg[reg];
888 }