[kvm][virt]MMIO技术分析

前言: 简单回顾一下前文,《内存映射技术分析》描述了虚拟内存的管理、内存映射;《物理内存管理》介绍了物理内存管理。《内存回收》介绍了一下PFRA内存回收。 上述三篇,简单建立Linux的内存管理模型,下面开始分析MMIO技术。 分析: 1,MMIO MMIO,即Memory mapping I/O;在x86上,CPU如果想要和外部交互数据,一种是使用in、out类型的端口访问的指令;一种是mov类型的读写内存的指令。对于前者来讲,就是PortIO(PIO);对于后者,就是MMIO。(这里说明一下,ARM上只有MMIO,简单了一些~) 所以,如果CPU和外部的设备交互,也逃不开这两种方式。对于PIO,如前文《PIO技术分析》中所说,CPU只要截获VM(Virtual Machine)的in、out指令,就可以知道CPU想要访问设备,那么用软件来模拟硬件的行为,就可以让VM觉得自己有设备。 对于MMIO,则相对复杂一点。首先来看一下VM中的iomem的layout,在VM中敲cat /proc/iomem:

2,System RAM 说明一下,作者给VM配置了6G的RAM。如上图中的System RAM: 00001000-0009fbff : System RAM 00100000-bffd7fff : System RAM -->这段大小约3G,地址范围在约低0G~3G的范围内。 100000000-1bfffffff : System RAM -->这段大小约3G,在4G~7G的范围内。 原因就是中间有1G的地址空间给了PCI、IOAPIC、LAPIC等使用。 在qemu-2.8.0-rc4/hw/i386/pc_piix.c中:

可见,在qemu中,就已经提前把内存分块,并留下了3G~4G的1G的物理地址空间。

那么问题来了,为什么不让内存连续在一起呢?内存连在一起的好处在于memory block之间没有hole,可以节省一些page struct(spare memory的情况下,节省一点计算量)。因为qemu并不知道将来要运行的VM的操作系统是否支持64bit,在32bit下,地址空间只有0~4G,那么可以减少一些内存,但是不能没有PCI,APIC等。

3,PCI Address 在VM中敲lspci:

以00:03.0 Ethernet controller: Intel Corporation 82540EM Gigabit Ethernet Controller (rev 03)为例,对应的是iomem中: febc0000-febdffff : 0000:00:03.0 febc0000-febdffff : e1000 00:03.0表示PCI地址:bus 0x00,device 0x03, function 0x00。 febc0000-febdffff表示网卡的MMIO的地址。 e1000是常用的虚拟网卡。 此时,CPU可以通过访问febc0000-febdffff之间的地址和e1000网卡交互。需要注意的是,这里是VM的物理地址,操作系统加载之后,跑在protected mode下,是访问虚拟地址的。所以还需要做一次mapping。 4,misconfig 继续上文3步,如果CPU访问了febc0000-febdffff,就说明在访问网卡设备了。所以,CPU需要截获虚拟机访问的具体地址,并发生了异常,从VM-mode下退出来,让qemu继续处理,模拟硬件的行为即可。这就是MMIO下的设备模拟过程,CPU截获MMIO的是misconfig异常。 在intel的官方文档中:EPT misconfiguration. An attempt to access memory with a guest-physical address encountered a misconfigured EPT paging-structure entry. 结合上面的地址信息,PCI的地址空间确实也不在内存的地址空间范围内。 5,KVM_EXIT_MMIO 如果发生了misconfig,KVM会返回KVM_EXIT_MMIO的exit reason。 6,handle mmio qemu-2.8.0-rc4/kvm-all.c中kvm_cpu_exec函数处理KVM_EXIT_MMIO:

根据地址,找到对应的设备。再继续模拟设备的行为。 后记: 设备的模拟,无论是PIO,还是MMIO,思路都差不多:CPU能够感知到访问了设备,并根据访问的具体的地址,找到对应的设备,最后模拟出来硬件的行为。 区别在于,两种方式下的处理不同,明显MMIO的路径要长一些,而且更加复杂一些。 Virtio设备本质上也是一个PCI设备(例如例子中的fe000000-fe003fff : virtio-pci-modern,就是作者挂载的Virtio-Blk),在Guest中需要kick Host,默认会使用PIO,而非MMIO。原因就是PIO的性能略好于MMIO。作者也实验过,在PIO VS MMIO的对比中,MMIO和PIO的性能都是ns级别的,二者相差不是很多,总体来说,PIO的数据略好于MMIO。

原文发布于微信公众号 - AlwaysGeek(gh_d0972b1eeb60)

原文发表时间:2017-03-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏源码之家

一键安装桌面及VNC

63460
来自专栏散尽浮华

Centos6.X 下安装并使用VNC的操作记录

VNC是一个的"远程桌面"工具。,通常用于“图形界面”的方式登录服务器,可视化操作。废话不多说了,操作记录如下: 1)安装桌面环境 [root@vm01 ~]#...

39670
来自专栏pythonlove

Linux防火墙iptables(二)

上一篇文章我们说了一些iptables/netfilter的基础知识,本文我们来介绍一下iptables的规则编写。Iptables的规则可以概括的分为两个方面...

45620
来自专栏从零开始学自动化测试

appium+python自动化36-android7.0连不上的问题

前言 由于最近很多android手机升级到7.0系统了,有些小伙伴的appium版本用的还是1.4版本,在运行android7.0的app自动化时候遇到无法启动...

48180
来自专栏腾讯Bugly的专栏

H5 缓存机制浅析 移动端 Web 加载性能优化

1 H5 缓存机制介绍 H5,即 HTML5,是新一代的 HTML 标准,加入很多新的特性。离线存储(也可称为缓存机制)是其中一个非常重要的特性。H5 引入的离...

40320
来自专栏Felix的技术分享

Stetho的通信原理

35530
来自专栏JAVA高级架构

详解 Tomcat 的连接数与线程池

前言 在使用tomcat时,经常会遇到连接数、线程数之类的配置问题,要真正理解这些概念,必须先了解Tomcat的连接器(Connector)。 在前面的文章 详...

1.2K90
来自专栏西安-晁州

小程序开发知识点总结

我承认,最近比较懒了,博客也很久没更新了,太对不住自己了,做了一段时间小程序开发,总结了一些知识点,直接上菜。

27110
来自专栏张戈的专栏

【腾讯云的1001种玩法】Nginx网站使用CDN之后禁止用户真实IP访问的方法

做过面向公网WEB运维的苦逼们肯定见识过各种恶意扫描、拉取、注入等图谋不轨行为吧?对于直接对外的WEB服务器,我们可以直接通过 iptables 、 Nginx...

1.3K00
来自专栏FreeBuf

经验分享 | Burpsuite抓取非HTTP流量

使用Burp对安卓应用进行渗透测试的过程中,有时候会遇到某些流量无法拦截的情况,这些流量可能不是HTTP协议的,或者是“比较特殊”的HTTP协议(以下统称非HT...

1.1K100

扫码关注云+社区

领取腾讯云代金券