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 Pointif(hook_idt)irq_enter();
{
joan_dprintk("Int:%d\n", vector);
}
//[Superymk] Add finished
__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 Pointdesc->status &= ~IRQ_PENDING;if(hook_idt)
{
joan_dprintk("Int:%d\n", vector);
}
//[Superymk] Add finished
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)