首页 > 代码库 > 虚拟机设备直通的两种方式(Working in Progress)

虚拟机设备直通的两种方式(Working in Progress)

声明:

本博客欢迎转发,但请保留原作者信息!

博客地址:http://blog.csdn.net/halcyonbaby

内容系本人学习、研究和总结,如有雷同,实属荣幸!

pci passthrough

  • 概念
    • 允许guest排他使用host上的某个PCI设备,就像将该设备物理连接到guest上一样。
  • 使用场景
    • 提升性能(如直通网卡和显卡)
    • 降低延迟(避免数据丢失或丢祯)
    • 直接利用bare-metal上设备的驱动
  • 用法1
    需要CPU支持VT-d。主板也支持该技术。
    • 预先配置:
      • 打开bios中的VT-d设置。
      • 激活kernel中参数配置kernel /vmlinuz-2.6.18-190.el5 ro root=/dev/VolGroup00/LogVol00 rhgb quiet intel_iommu=on
    • 直通配置方法
      • libvirt
      1. 识别设备  
      # virsh nodedev-list --tree |grep pci
      2. 获取设备xml   
      ```# virsh nodedev-dumpxml pci_8086_3a6c```
      3. detach设备  
      ```# virsh nodedev-dettach pci_8086_3a6c```
      4. 修改虚拟机xml文件(将dumpxml查询到的bus,slot,function填入) 
      <devices>
      ......
      <hostdev mode=‘subsystem‘ type=‘pci‘ managed=‘yes‘>
       <source>
         <address domain=‘0x0000‘ bus=‘0x03‘ slot=‘0x00‘ function=‘0x0‘/>
       </source>
      </hostdev>
      ......
      </devices>
      5. 启动虚拟机  
      
      • qemu
      1. unbind pci设备  
        modprobe pci_stub
        lspci -D -nn查询pci设备(domain,slot,bus,function)和(vendor id, device id )
        以设备(01:00.0, vendor & device ID 8086:10b9)为例:
        echo "8086 10b9" > /sys/bus/pci/drivers/pci-stub/new_id
        echo 0000:01:00.0 > /sys/bus/pci/devices/0000:01:00.0/driver/unbind
        echo 0000:01:00.0 > /sys/bus/pci/drivers/pci-stub/bind
      2. 启动虚拟机
        -device pci-assign,host=01:00.0
      
  • 如何将直通设备对应
    host上直通设备与虚拟机中设备对应关系确定方法。
    可以通过hostdev中增加address(不是source中的address)确定设备在虚拟机中的挂载路径。
    虚拟机种通过lspci查看即可对应起来。

http://www.linux-kvm.org/page/How_to_assign_devices_with_VT-d_in_KVM

pci passthrough(VFIO)2

VFIO在kernel3.6/qemu1.4以后支持,目前只支持PCI设备。
VFIO是一套用户态驱动框架,提供两种基本服务:

  • 向用户态提供设备访问接口
  • 向用户态提供配置IOMMU接口

VFIO可以用于实现高效的用户态驱动。在虚拟化场景可以用于device passthrough。
通过用户态配置IOMMU接口,可以将DMA地址空间映射限制在进程虚拟空间中。
这对高性能驱动和虚拟化场景device passthrough尤其重要。

相对于传统方式,VFIO对UEFI支持更好。
VFIO技术实现了用户空间直接访问设备。无须root特权,更安全,功能更多。
http://lwn.net/Articles/509153/http://lwn.net/Articles/474088/https://www.ibm.com/developerworks/community/blogs/5144904d-5d75-45ed-9d2b-cf1754ee936a/entry/vfio?lang=en

  • 操作方法
    • 安装kernel module
      sudo modprobe vfio
      sudo modprobe vfio-pci
    • 设备unbind
      1. 查看iommu_group及其下所有设备
      cd /sys/bus/pci/devices/0000:0d:00.0/
      readlink iommu_group    #查看iommu_group名字
      ll iommu_group/devices  #查看iommu_group下设备
      2. 需要将iommu_group下所有设备unbind并添加到iommu_group中  
      echo 0000:0d:00.0 > /sys/bus/pci/devices/0000:0d:00.0/driver/unbind   
      echo 1180 e823 > /sys/bus/pci/drivers/vfio-pci/new_id   
    
    • 启动虚拟机
      -device vfio-pci,host=0000:03:00.0
    

    参考http://blog.csdn.net/richardysteven/article/details/9008971

IOMMU

IOMMU
IOMMU:input/output memory management unit。
连接DMA io bus和主存,完成从设备虚拟地址到物理地址的映射。以及提供对故障设备的内存保护的功能。

  • 优点
    • 由于IOMMU的映射,可以将多个不连续的物理地址映射为大块连续的地址供设备使用,便于简化驱动设计
    • 使旧设备(32bit设备)可以使用高位地址。(可以改善内存使用,提高性能)
    • 内存保护,避免设备使用不属于它的地址
    • 提供硬件中断remapping功能
  • 缺点
    • 地址转换和管理开销带来的性能降级
    • 消耗物理内存
  • 虚拟化中的应用
    一般来说,由于内存地址不同,虚拟机中的操作系统无法直接访问host上的设备。
    通过IOMMU,可以将设备地址在虚拟机中和host中映射为相同的支持,供虚拟机使用。这种做法也可以缓解IO delay。