Rockchip平台PCIe设备虚拟化开发指南
:::info 文档信息
文档标识:RK-KF-YF-170 · 发布版本:V1.0.0 · 发布日期:2021-03-30 · 页数:7 · 语言:中文
原始文档:Rockchip_PCIe_Virtualization_Developer_Guide_CN.pdf
:::
章节大纲
- Rockchip平台PCIe设备虚拟化开发指南(P1)
- 环境搭建(P4)
- Guest OS内核配置(P4)
- Guest OS ramdisk准备(P4)
- HOST OS内核配置(P4)
- QEMU准备(P5)
- Host OS ramdisk准备(P5)
- DTS 配置(P5)
- SMMU配置(P5)
- PCIe补充配置(P6)
- 运行(P6)
- 遗留问题(P7)
- 环境搭建(P4)
在线预览
若预览无法显示,请直接下载 PDF 后用本地阅读器打开。
1. 环境搭建
1.1 Guest OS内核配置
使能如下配置。
CONFIG_ARM64_VA_BITS_39=y
CONFIG_ARM64_VA_BITS=39
关闭如下配置。
CONFIG_HUGETLBFS
CONFIG_HUGETLB_PAGE
使用以下命令生成guest os内核固件。
make ARCH=arm64
固件位置。
arch/arm64/boot/Image
1.2 Guest OS ramdisk准备
包含busybox工具,lspci,ifconfig工具。
1.3 HOST OS内核配置
在rockchip_defconfig基础上再使能如下配置。
CONFIG_KVM
CONFIG_VFIO
CONFIG_VFIO_PCI
CONFIG_IOMMU_SUPPORT
CONFIG_ARM_SMMU_V3
CONFIG_VFIO_IOMMU_TYPE1
CONFIG_BLK_DEV_NVME
CONFIG_R8169
CONFIG_PCIE_DW
CONFIG_PCIE_DW_HOST
CONFIG_PCIE_DW_ROCKCHIP
1.4 QEMU准备
使用Rockchip的buildroot工程编译qemu,可执行文件名称qemu-system-aarch64。
1.5 Host OS ramdisk准备
使用Rockchip的buildroot工程生成ramdisk,包含qemu-system-aarch64,guest os内核固件,guest os ramdisk固件。
Rockchip的buildroot工程配置以及编译方法参考buildroot使用文档,本指南提供预先编译好的ramdisk目录,包含需要的所有固件,
在ubuntu环境下,使用abootimg-pack-initrd,会在ramdisk同级目录生成initrd.img固件,使用abootimg- unpack-initrd解压initrd.img。
2. DTS 配置
2.1 SMMU配置
compatible = "arm,smmu-v3";
必须配置,用于匹配ARM SMMU-v3驱动。
以下寄存器以及中断配置以RK3588为例。
reg = <0x0 0xfc900000 0x0 0x100000>;
ARM SMMU-v3基地址以及大小。
interrupts = <GIC_SPI 369 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 371 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 374 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 367 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "eventq", "gerror", "priq", "cmdq-sync";
详见Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt。
#iommu-cells = <1>;
必须为1,用于描述设备的stream ID,详见Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt。
2.2 PCIe补充配置
iommu-map = <0x0 &smmu 0x0 0x10000>;
为PCIe外设创建SMMU页表。
3. 运行
- 卸载宿主机PCIe设备驱动
使用lspci得到设备地址,假设设备地址为0002:21:00.0,执行以下命令卸载。
echo 0002:21:00.0 > /sys/bus/pci/devices/0002\:21\:00.0/driver/unbind
- 将PCIe设备重新挂载到VFIO-PCI驱动
使用lspci得到设备vendor id和device id,以Realtek 8169PCIe网卡为例,vendor id和device id分别为10ec,0000,使用以下命令挂载。
echo 10ec 0000 > /sys/bus/pci/drivers/vfio-pci/new_id
- 运行qemu
qemu-system-aarch64 -nographic -monitor none -m 128 -machine virt,highmem=off
-serial stdio -cpu host -enable-kvm -device vfio-pci,host=0002:21:00.0 -
kernel /Image -initrd /ramdisk_ok.img
以下qemu参数说明。
qemu-system-aarch64
Rockchip buildroot编译出来的qemu二进制文件,放在host os根文件系统的bin/目录下。
-m 128
为虚拟机创建128M的内存空间。
highmem=off
使用低32位地址空间。
-device vfio-pci,host=0002:21:00.0
使用PCIe设备地址作为参数创建vfio设备,用于虚拟机访问。
-kernel /Image -initrd /ramdisk_ok.img
分别是guset os内核固件,guest os根文件系统固件,这里将这两个固件放在host os根文件系统的根目录。
- 待虚拟机启动完成,使用以下命令配置PCIe网卡
ifconfig eth0 up
ifconfig eth0 192.168.31.120 netmask 255.255.255.0
route add default gw 192.168.31.1
地址以及网关根据实际情况配置。
- 实用以下命令测试网络连接
ping 8.8.8.8
正常情况下,能看到ping信息。
4. 遗留问题
在虚拟机里面PCIe设备默认被设置为coherent属性,所以申请的dma buffer被设置成cacheable,从而导致数据一致性的问题,需要在虚拟机PCIe设备probe时候,手动设置为non-coherent,如下,才能规避数据一致性问题。
dev->archdata.dma_coherent = false;