qemu-kvm的pio和mmio的模拟

简介

I/O作为CPU和外设交流的一个渠道,主要分为两种,一种是PIO(Port I/O,PortIO),一种是MMIO(Memory mapping I/O)。PIO和MMIO的input和output方向是从CPU的角度来描述的,如:PIO的IN指令,指CPU从IO设备中读取数据。

对于qemu-kvm,虚拟机的设备驱动读写Port IO和MMIO时,会触发虚拟机退出到kvm,然后kvm处理Port IO和MMIO的读写操作,如果需要qemu模拟,则会退出到qemu进程中进行处理。

本文以x86架构的intel cpu分析pio和mmio的模拟。

PIO模拟

PIO是直接通过IO地址来访问的,IO地址位于IO地址空间,此时会直接触发CPU异常退出到kvm处理PIO,若需要qemu模拟时,则会退出到qemu进程中处理PIO。

Intel vmx的IO退出事件处理(x86):
handle_io (arch/x86/kvm/vmx.c)  -- EXIT_REASON_IO_INSTRUCTION , Port IO 类型
   emulate_instruction       处理IN,读Port IO
   kvm_fast_pio_out          处理OUT,写Port IO

MMIO模拟

MMIO是直接将设备I/O映射到内存地址空间内,而intel CPU架构的内存虚拟化通过EPT机制实现,因而虚拟机的设备的MMIO实现也需要利用EPT机制。

MMIO是通过设置spte的保留位来标志的。 虚拟机内部第一次访问MMIO的gpa时,会发生EPT_VIOLATION退出到kvm,然后在kvm中检查gpa发现对应的pfn不存在(qemu没有向EPT注册这段内存地址,qemu代码:kvm_set_phys_mem 中不会向kvm的EPT注册MMIO类型的内存地址,即:不会让kvm自动分配内存页),那么认为这是个MMIO,于是set_mmio_spte来标志它的spte是一个MMIO,并让vCPU再次尝试访问该gpa地址。当vCPU再次访问这个gpa时就会发生EPT_MISCONFIG,进而调用handle_ept_misconfig 来处理所有的MMIO操作了。(注:从数据总线读数据 或 向数据总线写入数据,因为外设或者内存都是通过总线与CPU连接的,地址总线设置需要访问的地址,而数据总线用于读写数据)

EPT缺页异常(EXIT_REASON_EPT_VIOLATION),用于给虚拟机分配内存页和MMIO的处理:
handle_ept_violation (arch/x86/kvm/vmx.c)
   kvm_mmu_page_fault (arch/x86/kvm/mmu.c)  MMU的页错误处理(会
      设置MMIO的页的spte保留位为1,让CPU再次尝试该地址,进而触发EPT_MISCONFIG)

EPT页表非法(EXIT_REASON_EPT_MISCONFIG),用于处理MMIO:
handle_ept_misconfig (arch/x86/kvm/vmx.c)
   handle_mmio_page_fault (arch/x86/kvm/mmu.c)  处理MMIO的页错误
      walk_shadow_page_get_mmio_spte  判断页的spte保留位是否已置位(
         是,则是MMIO的页;否则,则是普通页,需分配内存)
   x86_emulate_instruction    模拟MMIO的指令

perf分析io指令

可通过perf kvm指令分析虚拟机的io指令,用于分析io性能。

perf kvm stat record -p 37000 sleep 10 记录kvm事件(默认保存在perf.data.guest中)

perf kvm stat report 查看退出事件统计(默认参数 --event=vmexit)

perf kvm stat report --event=ioport 查看端口IO的事件统计(如:IO地址)

perf kvm stat report --event=mmio 查看内存映射IO(映射为内存的IO访问)的事件统计(如:IO地址),如:EPT MISCONFIG事件为mmio事件

可基于IO指令的地址在qemu进程的mtree信息(通过如下方式进入qemu进程的管理界面)中获取IO指定对应的类型或操作(过滤查找地址时,去掉0x):

qm monitor 

info mtree

quit

后记

特别说明:本文仅为本文的浅见,如有错误,烦请指正。

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BitSwimmer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值