Xen Guest中断简介2011-01-09 博客园 Superymk在Xen 3.4.2中,Xen Guest中断包括硬件中断和软中断(Soft IRQ)两种,在硬件虚拟化中,前者的分发在陷入Xen Hypervisor后由其负责,后者的话其实是在调用Xen Hypervisor中的一些函数,只能算模拟与前者功能相关的文件是archx86vmxVmx.c文件中的vmx_vmexit_handler函数,后者则是archx86irq.c 文件的do_IRQ函数,翻翻就可以看到,在xen中,Timer Interrupt和UART的一些中断都是软件中断。Xen Guest中断拦截试验在做context switch相关的实验中要注意,对于中断,既要处理外部中断又要处理异常,其效果也就是整个idt表都要hook住。附上一些代码关键point在vmx_vmexit_handler函数中switch ( exit_reason ) { case EXIT_REASON_EXCEPTION_NMI: { /* * We don"t set the software-interrupt exiting (INT n). * (1) We can get an exception (e.g. #PG) in the guest, or * (2) NMI */ unsigned int intr_info, vector; intr_info = __vmread(VM_EXIT_INTR_INFO); BUG_ON(!(intr_info & INTR_INFO_VALID_MASK)); vector = intr_info & INTR_INFO_VECTOR_MASK; //[Superymk] Add hook_idt //<---------------------------Key Point if(hook_idt) { joan_dprintk("Int:%d
", vector); } //[Superymk] Add finished /* * Re-set the NMI shadow if vmexit caused by a guest IRET fault (see 3B * 25.7.1.2, "Resuming Guest Software after Handling an Exception"). * (NB. If we emulate this IRET for any reason, we should re-clear!) */在do_IRQ函数中spin_lock(&desc->lock); desc->handler->ack(vector); if ( likely(desc->status & IRQ_GUEST) ) { //[Superymk] Add hook_idt //<---------------------------Key Point if(hook_idt) { joan_dprintk("Int:%d
", vector); } //[Superymk] Add finished irq_enter(); __do_IRQ_guest(vector); irq_exit(); spin_unlock(&desc->lock); return; } desc->status &= ~IRQ_REPLAY; desc->status |= IRQ_PENDING; /* * Since we set PENDING, if another processor is handling a different * instance of this same irq, the other processor will take care of it. */ if ( desc->status & (IRQ_DISABLED | IRQ_INPROGRESS) ) goto out; desc->status |= IRQ_INPROGRESS; action = desc->action; while ( desc->status & IRQ_PENDING ) { //[Superymk] Add hook_idt //<---------------------------Key Point if(hook_idt) { joan_dprintk("Int:%d
", vector); } //[Superymk] Add finished desc->status &= ~IRQ_PENDING; irq_enter(); spin_unlock_irq(&desc->lock); action->handler(vector_to_irq(vector), action->dev_id, regs); spin_lock_irq(&desc->lock); irq_exit(); }之所以都在irq_enter()外修改,是因为尽量缩短IRQ的处理时间。(它们需要在高特权级别下运行,未核实irq_enter()是否会提升IRQL)