纯Qemu模拟
虽然说纯软件模拟的方式在大部分的情况下已经被替代了,但是对软件模拟方式的理解能够加深对虚拟化的理解,并且对软硬件进化的过程有个概念。
继承关系
TYPE_OBJECT
+-----------------------------+
|class_init | = object_class_init
| |
|instance_size | = sizeof(Object)
+-----------------------------+
TYPE_DEVICE
+-----------------------------+
|class_size | = sizeof(DeviceClass)
|class_init | = device_class_init
| |
|instance_size | = sizeof(Object)
|instance_init | = device_initfn
|instance_finalize | = device_finalize
| |
|realize | = apic_common_realize
+-----------------------------+
APICCommonClass TYPE_APIC_COMMON "apic-common"
+-----------------------------+
|class_size | = sizeof(APICCommonClass)
|class_init | = apic_common_class_init
| |
|instance_size | = sizeof(APICCommonState)
|instance_init | = apic_common_initfn
| |
+-----------------------------+
APICCommonClass TYPE_APIC "apic"
+-----------------------------+
|class_init | = apic_class_init
| |
|instance_size | = sizeof(APICCommonState)
| |
|realize | = apic_realize
+-----------------------------+这个继承层次也挺长的了,不过还好,没有cpu那个长。而且总的来说也还算蛮清晰的。
初始化
APIC的初始化和CPU还是有很大关联的,因为在硬件上他们两个人就是在一起的。所以qemu中APIC的创建也是随着CPU一起创建的。
为了说明问题,我们还是以x86 cpu为例。这个创建的过程就在x86_cpu_realizefn函数里。相关内容参见x86 cpu
接着我们就打开这个函数,看看究竟这个是怎么玩的。
实现
了解了初始化的流程,接下来我们看看APIC是怎么模拟的。
先来看看APICCommonState这个数据结构
首先是这个io_memory,这个就是在初始化时注册的内存空间。有意思的是不管有多少cpu,这个空间只有一个。而其中关键的就是对应的apic_io_ops了,具体的模拟手段都隐藏在这个操作中。
其次是apicbase,这就是系统默认的APIC访问的地址了。这没啥说的,就是按照手册来。
剩下的就是APIC的一些寄存器了,每次读写都会对这些寄存器访问。
发送中断
那现在我们就来看看对发送中断的模拟。
我们以IPI为例,在SDM中10.6小节描述了如何发送IPI。简单来说就是通过写ICR(Interrupt Command Register)来达到目的。
对应的在代码中,写APIC最后要走到apic_mem_write中0x30选项。
你看,是不是和手册上说的一样。写入时设置了ICR?
实际上msi的中断也是在apic_mem_write中执行的。貌似这两段内存空间是重合的?没搞懂,不过代码注释好像是这么写的。
从这里看,所有的路径基本都会走到cpu_interrupt函数。而这个函数的工作是设置s->interrupt_request并发送一个信号给vcpu thread。
处理中断
处理中断和vcpu thread有很大关系。这里我们只看没有kvm介入时tcg的情况 qemu_tcg_rr_cpu_thread_fn。
当vcpu thread起来后,每个周期中会去检测有没有异常和中断。当检测到有的时候,则模拟中断的处理。
这个代码可是老复杂了,感觉能写这个代码的人简直是神。
不过从上面的分析中可以看出,软件模拟的情况下中断处理会有两个问题:
中断处理是在vcpu thread处理的间歇执行的,而并没有强制打断vcpu thread的正常执行。所以这个中断将会有较大的延时。
如果持续有中断好像会一直处理中断,所以中断太过频繁,也会导致系统无法继续。
以上是对用户态软件模拟的LAPIC的理解,希望是正确的。
Last updated
Was this helpful?