Thursday, February 6, 2020
kvm_all.c - kvm_cpu_exec, kvm_handle_io
简介
kvm_all.c位于/accel/kvm/kvm-all.c,用于QEMU - KVM的通信,与其相关的许多重要的函数,例如kvm_handle_io、kvm_cpu_exec都位于此。
kvm_cpu_exec,kvm状态下的大消息循环,对应tcg模式下的tcg_cpu_exec。这个函数处理大量的vcpu产生的事件。
该函数在调用cpu_exec_start启动vcpu后,(1)调用kvm_vcpu_ioctl发送ioctl KVM_RUN给kvm,此时启动vCPU。该ioctl会进入对vCPU运行的等待状态。如果kvm发生VMEXIT,即从KVM返回到qemu-kvm用户空间时,则该函数读取run->exit_reason,获取退出的原因,并调用对应的处理函数。
KVM是英特尔和AMD等供应商提供的硬件扩展的推动者,它们的虚拟化扩展包括SVM和VMX。KVM使用这些扩展在主机CPU上直接执行客户代码。但是,如果存在事件(例如,作为由QEMU模拟的客户内核代码访问硬件设备寄存器的操作的一部分),则KVM必须退出回QEMU并传递控制。然后QEMU可以模拟操作的结果。
有不同的退出原因,如以下代码所示:
对应如下:
KVM_EXIT_IO - kvm_handle_io
KVM_EXIT_MMIO - address_space_rw
KVM_EXIT_IRQ_WINDOW_OPEN - return EXCP_INTERRUPT
KVM_EXIT_SHUTDOWN - qemu_system_reset_request
KVM_EXIT_UNKNOWN - 异常退出
KVM_EXIT_INTERNAL_ERROR - kvm_handle_internal_error
KVM_EXIT_SYSTEM_EVENT - 根据事件类型,分别有
KVM_SYSTEM_EVENT_SHUTDOWN = qemu_system_shutdown_request
KVM_SYSTEM_EVENT_RESET = qemu_system_reset_request
KVM_SYSTEM_EVENT_CRASH = qemu_system_guest_panicked
其他 = kvm_arch_handle_exit
其他 - kvm_arch_handle_exit
处理完后,如果没有产生错误,则继续循环,回到(1)处等待kvm。
如果产生错误,则调用cpu_exec_end,停止cpu执行。
——————————–
kvm_handle_io则相对简单,它其实是对address_space_rw的封装。它会将传入的,要写入对应设备的数据依次写入。通常,这与直接写往ioport并没有什么区别。