博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Xen Guest中断简介

Posted on 2010-02-02 12:44  Superymk  阅读(2091)  评论(0编辑  收藏  举报

Xen Guest中断简介(转载注明出处,所有内容均为Superymk原创,版权归作者所有)

  • 在Xen 3.4.2中,Xen Guest中断包括硬件中断和软中断(Soft IRQ)两种,在硬件虚拟化中,前者的分发在陷入Xen Hypervisor后由其负责,后者的话其实是在调用Xen Hypervisor中的一些函数,只能算模拟
  • 与前者功能相关的文件是arch\x86\vmx\Vmx.c文件中的vmx_vmexit_handler函数,后者则是arch\x86\irq.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\n", 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\n", 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\n", 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)