1 介绍

        本文档对如何使用PCIE/PCI设备给出好的例子并解释了背后的原因。

        注意PCIE特性仅在X86架构上使用q35机器类型和AArch64架构使用virt机器类型时有效。其他机器类型目前不支持PCIE。

        下列文档可以与本文档一起阅读:

注意:使用的例子并不能代替完整的文档,请使用QEMU帮助来了解所有选项。

2 设备放置策略

        QEMU并没有一个清晰的socket-device匹配机制,它允许任何PCI/PCIe设备被插入到任何PCI/PCIe插槽里。

        插入一个PCI设备到PCIE插槽可能有时不能工作,因为对于裸机不能工作。

        将一个PCIE设备插入到PCI插槽将隐藏掉扩展配置空间,这也是不推荐的。

推荐的是区分PCIE和PCI层次。PCIE设备仅插入到PCIE root port和PCIE downstream port中。

2.1 Root Bus(pcie.0)

        仅下列类型的设备可以直接防止在RC上:

(1)PCIE设备(比如网卡,图像卡,IDE控制器),非控制器。仅将传统的PCI设备放置到RC上。这可以是集成Endpoint(注意集成Endpoint不是可插拔的)。

虽然PCIE手册不禁止PCIE设备是集成Endpoint,但目前存在的硬件几乎都集成了传统的PCI设备到RC。当PCIE设备被集成到RC时,Guest OS可能行为会很奇怪。

(2)PCIE root ports(比如ioh3420),用于开启专门的PCIE层次。

(3)PCE to PCI桥(pcie-pci-bridge),用于开启传统的PCI层次。

(4)额外RC(pxb-pcie),如果需要多个PCIE根总线。

qemu 直连物理网卡_ci

2.1.1 将一个设备插入到pcie.0上作为RC集成Endpoint如下:

-device <dev>[,bus=pcie.0]

2.1.2 暴露一个新下PCIE根总线如下:

-device pxb-pcie,id=pcie.1,bus_nr=x[,numa_node=y][,addr=z]

它链接到pcie.1总线上:

-device ioh3420,id=root_port1[,bus=pcie.1][,chassis=x][,slot=y][,addr=z]

-device pcie-pci-bridge,id=pcie_pci_bridge1,bus=pcie.1



2.2 PCIE层次

        通常使用PCIE root port来开始PCIE层次。

        一个PCIE根总线最大支持32个设备。因为每个PCIE root port为一个function且多function设备可以达到8个设备,每个PCIE根总线上最大PCIE root port为256。

        作者更喜欢将PCIE root port分组到多funcion设备中保持更简单的层级,这对于大多数场景足够。仅当没有空间给PCIE root port时在使用PCIE switch(x3130-upstream,xio3130-downstream)。

        仅插入PCIE设备到PCIE port中。

qemu 直连物理网卡_qemu_02

2.2.1 将一个PCIE设备插入到PCIE root port中

-device ioh3420,id=root_port1,chassis=x,slot=y,[,bus=pcie.1][,chassis=x][,slot=y][,addr=z] \

- device <dev>,bus=root_port1

2.2.2 使用多function的PCIE root port

-device ioh3420,id=root_port1,multifunction=on,chassis=x,addr=z.0[,slot=y][,bus=pcie.0] \

-device ioh3420,id=root_port2,chassis=x1,addr=z.1[,slot=y1][,bus=pcie.0] \

-device ioh3420,id=root_port3,chassis=x2,addr=z.2[,slot=y2][,bus=pcie.0] \

2.2.3 将PCIE设备插入到一个switch中

-device ioh3420,id=root_port1,chassis=x,slot=y[,bus=pcie.0][,addr=z] \

-device x3130-upstream,id=upstream_port1,bus=root_port1[,addr=x] \

-device xio3130-downstream,id=downstream_port1,bus=upstream_port1,chassis=x1,slot=y1[,addr=z1]

-device <dev>,bus=downstream_port1

NOTE: (slot, chassis)对是强制要求的必须对PCIE root port唯一。当没有明确指明时,slot默认为0。’addr’参数对上述所有例子都可以为0。

2.3 PCI层次

        传统的PCI设备可以作为集成Endpoint被插入到pcie.0上,但如第五部分提到的,这样的传统设备不具备热插拔能力。使用PCIE-PCI Bridge(pcie-pci-bridge)与PCI-PCI Bridge联合起来开启PCI层次。

        作者更喜欢平坦的层次。对于大多数场景一个PCIE-PCI Bridge和多个PCI-PCI Bridge将可以支持上百传统设备。建议在PCIE-PCI Bridge下遍历PCI-PCI Bridge知道满后再插入新的PCI-PCI Bridge。

qemu 直连物理网卡_ci_03

 2.3.1 插入一个PCI设备到pcie.0上作为集成Endpoint

-device <dev>[,bus=pcie.0]

2.3.2 将一个PCI设备插入到PCI-PCI桥

-device pcie-pci-bridge,id=pcie_pci_bridge1[,bus=pcie.0] \

-device pcie-bridge,id=pcie_bridge1,bus=pcie_pci_bridge1[.chassis_nr=x][,addr=y] \

-device <dev>,bus=pci_bridge1[,addr=x]

        注意如果shpc=off参数没有传递给PCI桥或PCIE-PCI桥,’addr’不能为0。

3 IO空间问题

        PCIE root port和PCIE downstream port可以作为PCI-PCI桥被Firmware/Guest OS看到。PCI spec要求每个port可以保存4K IO范围,即使仅有一个设备被插入到每个port。这会导致IO空间利用不充分。

        QEMU(SeaBIOS/OVMF)使用的firmware在下列情况下不对每个PCIE root/PCIE downstream port分配IO空间达到优化:

  1. port为空,或
  2. 在port后面的设备没有IO BAR。

        IO空间被限制在65536 byte宽的IO port,同时也可能会被平台设备的固定的IO port脆片化,这会导致当存在IO BAR的设备在PCIE层次使用时,最多每个系统有10个PCIE root port或PCIE downstream port。使用        建议的设备放置策略可以解决这个问题。

        PCIE spec要求PCIE设备不需要IO port时仍可以正常工作。PCI层次没有这个限制。

4 总线数目问题

        每个PCI域可以有最多256个总线,即使外部RC(pxb-pcie)被使用QEMU PCIE不支持多PCI域。

        PCIE层次的每个部件(RC, PCIE root port,PCIE downstream/upstream port)使用一个总线号。因为仅一个设备连接到PCIE root port或PCIE downstream port,建议提前计划预期的设备数量,以防总线数目短缺。

        阻止PCIE switch使层次不需要消耗总线号在upstream port。

        Pxb-pcie设备的属性bus_nr分区0..255总线号空间。在给定pxb-pcie设备的根总线分配给总线的所有总线号必须符合pxb-pcie设备的bus_nr属性,命令行为其他pxb-pcie设备设置bus_nr属性的最低位。

5 热插拔

        PCIE根总线(pcie.0和pxb-pcie设备导出的总线)不支持热插拔,因此任何嵌入到RC的设备也不能热插拔:

  1. PCIE集成Endpoint
  2. PCIE root port
  3. PCIE-PCI 桥
  4. Pxb-pcie

        注意PCIE downstream port不能热插入到一个已经存在的PCIE upsream port。

PCI设备可以热插入PCIE-PCI和PCI-PCI桥。PCI热插入到PCI-PCI桥是基于ACPI的。PCIE热插入到PCI桥是基于SHPC的。他们使用PCIE native hot-plug工作。

5.1 hot-plug

(1)PCI层次

让足够PCI-PCI桥空或增加一个或多个空PCI-PCI桥到PCIE。

对于每个PCI-PCI桥,Guest firmware可以保留4K IO空间和2M MMIO范围来用于所有设备。合适的PCI容量被设计。

因为硬件大约10个PCI桥的限制,不要使用超过9个PCI-PCI桥。留4K给集成Endpoint。

(2)PCIE层次

留足够PCIE root port。使用多function PCIE root port来使层次尽可以flat,这样更胜PCI总线号。如果你不是必须,不要使用PCIE switch,每个都使用额外的PCI总线。

5.3 hot-plug例子

        使用HMP

device_add <dev>,id=<id>,bus=<PCIE root port id/PCIE downstream port id/PCI-PCI Bridge id>