|
|
1.1 ! root 1: /* ! 2: * Copyright (C) 2006-2009 Free Software Foundation ! 3: * ! 4: * This program is free software ; you can redistribute it and/or modify ! 5: * it under the terms of the GNU General Public License as published by ! 6: * the Free Software Foundation ; either version 2 of the License, or ! 7: * (at your option) any later version. ! 8: * ! 9: * This program is distributed in the hope that it will be useful, ! 10: * but WITHOUT ANY WARRANTY ; without even the implied warranty of ! 11: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 12: * GNU General Public License for more details. ! 13: * ! 14: * You should have received a copy of the GNU General Public License ! 15: * along with the program ; if not, write to the Free Software ! 16: * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ! 17: */ ! 18: ! 19: #include <mach/machine/asm.h> ! 20: ! 21: #include <i386/i386asm.h> ! 22: #include <i386/cpu_number.h> ! 23: #include <i386/xen.h> ! 24: ! 25: .data 2 ! 26: int_active: ! 27: .long 0 ! 28: ! 29: ! 30: .text ! 31: .globl hyp_callback, hyp_failsafe_callback ! 32: P2ALIGN(TEXT_ALIGN) ! 33: hyp_callback: ! 34: pushl %eax ! 35: jmp EXT(all_intrs) ! 36: ! 37: ENTRY(interrupt) ! 38: incl int_active /* currently handling interrupts */ ! 39: call EXT(hyp_c_callback) /* call generic interrupt routine */ ! 40: decl int_active /* stopped handling interrupts */ ! 41: sti ! 42: ret ! 43: ! 44: /* FIXME: if we're _very_ unlucky, we may be re-interrupted, filling stack ! 45: * ! 46: * Far from trivial, see mini-os. That said, maybe we could just, before poping ! 47: * everything (which is _not_ destructive), save sp into a known place and use ! 48: * it+jmp back? ! 49: * ! 50: * Mmm, there seems to be an iret hypcall that does exactly what we want: ! 51: * perform iret, and if IF is set, clear the interrupt mask. ! 52: */ ! 53: ! 54: /* Pfff, we have to check pending interrupts ourselves. Some other DomUs just make an hypercall for retriggering the irq. Not sure it's really easier/faster */ ! 55: ENTRY(hyp_sti) ! 56: pushl %ebp ! 57: movl %esp, %ebp ! 58: _hyp_sti: ! 59: movb $0,hyp_shared_info+CPU_CLI /* Enable interrupts */ ! 60: cmpl $0,int_active /* Check whether we were already checking pending interrupts */ ! 61: jz 0f ! 62: popl %ebp ! 63: ret /* Already active, just return */ ! 64: 0: ! 65: /* Not active, check pending interrupts by hand */ ! 66: /* no memory barrier needed on x86 */ ! 67: cmpb $0,hyp_shared_info+CPU_PENDING ! 68: jne 0f ! 69: popl %ebp ! 70: ret ! 71: 0: ! 72: movb $0xff,hyp_shared_info+CPU_CLI ! 73: 1: ! 74: pushl %eax ! 75: pushl %ecx ! 76: pushl %edx ! 77: incl int_active /* currently handling interrupts */ ! 78: ! 79: pushl $0 ! 80: pushl $0 ! 81: call EXT(hyp_c_callback) ! 82: popl %edx ! 83: popl %edx ! 84: ! 85: popl %edx ! 86: popl %ecx ! 87: popl %eax ! 88: decl int_active /* stopped handling interrupts */ ! 89: cmpb $0,hyp_shared_info+CPU_PENDING ! 90: jne 1b ! 91: jmp _hyp_sti ! 92: ! 93: /* Hypervisor failed to reload segments. Dump them. */ ! 94: hyp_failsafe_callback: ! 95: #if 1 ! 96: /* load sane segments */ ! 97: mov %ss, %ax ! 98: mov %ax, %ds ! 99: mov %ax, %es ! 100: mov %ax, %fs ! 101: mov %ax, %gs ! 102: push %esp ! 103: call EXT(hyp_failsafe_c_callback) ! 104: #else ! 105: popl %ds ! 106: popl %es ! 107: popl %fs ! 108: popl %gs ! 109: iret ! 110: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.