Xen处理中断、异常

来源:互联网 发布:淘宝最畅销产品排行榜 编辑:程序博客网 时间:2024/06/06 13:36

物理中断处理

    Xen在获得外部中断后如何将其送到正确的Guest OS中,并找到正确的中断处理程序。    由于Xen系统中绝大部分物理中断最终都要交由Guest OS进行处理,Xen仅处理极少部分的物理中断,因此处理函数do_IRQ()的主要工作是处理这极少部分的物理中断,而将绝大部分需要Guest OS处理的中断通过函数_do_IRQ_guest()传递给Guest OS。凡是需要传递给Guest OS的中断,在其对应的irq_desc_t结构体中都需要设置IRQ_GUEST标志位,这也是判断是否传递给Guest OS的判断标志。    在Xen系统中,物理中断(PIRQ)的处理是基于事件通道机制实现的。因此,Xen在函数_do_IRQ_guest()中通过send_guest_pirq()向Guest OS发送的是绑定到该物理中断的事件通道产生的事件通知。与该中断号绑定的事件通道端口号保存在pirq_to_evtchn()数组中。    在Xen通过send_guest_pirq()向Guest OS发送绑定到该物理中断的事件通道产生的事件通知后,Guest OS中与该事件通道绑定的VCPU将会获得事件通知,并调用函数evtchn_do_upcall()进行处理。在该函数中,与物理中断绑定的事件通知由函数do_IRQ()进行处理。

物理中断申请

    驱动程序调用函数request_irq()来注册中断处理程序,函数的作用是,填充中断号对应的irq_desc结构体,并将处理例程加入到该中断的处理队列中。完成这些工作后,调用startup_pirq()函数,启动该中断。由于在Guest OS 中物理中断被事件通道取代,所以startup_pirq()函数的主要工作是为该物理中断号申请绑定事件通道。通过超级调用HYPERVISOR_event_channel_op提供的物理中断绑定操作进行事件通道的绑定。

虚拟中断处理

    为了方便Xen和Domain之间通信,Xen设置了一系列的虚拟中断,即通过Xen向Guest OS发送虚拟中断并由Guest OS处理该中断来完成Xen和Domain之间的通信。同物理中断相比,虚拟中断的实现和处理过程是在Xen系统内部实现的。在处理过程中,Xen用事件通知来代替虚拟中断信号进行传递。

虚拟中断申请

    系统函数bind_virq_to_irqhandler()用于申请虚拟中断。该函数先通过调用函数bind_virq_to_irq()为虚拟中断分配中断号,再调用函数request_irq()注册相应的中断处理例程。

虚拟中断相应

    若Xen向Guest OS发送虚拟中断,仅仅需要通过与该虚拟中断绑定的事件通道发送事件通知即可,即调用函数send_guest_vcpu_virq()。该函数内部调用evtchn_set_pending()设置与事件通道相关的标志位。在设置好相应的事件通道标志位后,虚拟中断后面的处理过程和物理中断一样,都是借助于Linux系统原有的中断处理方式。

Guest OS处理异常

    相比于利用事件通道机制处理中断,Guest OS处理异常要简单的多。Xen为每个正在运行的Guest OS建立了一个虚拟IDT(VIDT),使得Guest OS能够直接通过VIDT设置异常处理程序并处理异常。VIDT只能用于Guest OS处理Domain内部发生的异常,不能用来接收物理中断。    当异常发生时,Xen捕获到该异常,然后在Guest OS中创建异常栈框,再交由Guest OS自己处理。在Xen为Guest OS创建的异常栈框中,保存着与处理该异常相关的错误码、段基地址、段内偏移量及标志位等信息。具体来讲,当异常发生时,首先由Xen处理该异常,即首先要陷入Xen,调用Xen自己的异常处理函数,在处理函数中,Xen首先要通过函数guest_mode()判断该异常是否来自Guest OS,若是,则调用do_guest_trap()进行处理。然后Xen创建相应的异常栈框,给Guest OS模拟了一次异常,Guest OS直接利用Linux系统处理异常的方式进行处理。    所以,当应用程序申请系统调用时(异常),直接由3环转入0环,在0环经过Xen处理后再返回一环(Guest OS内核),并在Guest OS内核中处理该系统调用。    为了减小系统开销,Xen为每个Guest OS注册一个快速异常处理程序,应用程序在使用系统调用时,可以通过该程序直接从3环进入1环,而不需要再经过0环的Xen,提高了性能。
原创粉丝点击