Configuring pass-through PCI devices

Specify the PCI device as a VFIO device in the configuration-XML.

Before you begin

On the host, the PCI function must be controlled by the vfio-pci device driver before it can be used by a KVM guest. You can configure the device such that libvirt automatically effects this host setup while the device is claimed by a guest. Alternatively, you can perform the host setup as described in Preparing PCI pass-through devices.

Procedure

  1. Configure the PCI device with the hostdev element (see <hostdev>).
    hostdev mode attribute: subsystem
    hostdev type attribute: pci
    hostdev managed attribute: yes|no
    The managed attribute is optional. If it is set to yes, libvirt handles the host setup for the device for you.
    You can configure PCI networking devices with an interface element of type hostdev instead of using a hostdev element. Use this alternative if you must adhere to a particular network topology with specific values for MAC addresses or virtual ports. Apart from the mac and virtualport elements, the interface and hostdev elements have the same child elements (see <interface>).
  2. Configure the PCI device as a VFIO device with the driver element.
    driver name attribute: vfio
  3. Identify the device on the host with the address element as child of the source element.
    address domain attribute: 0x<domain>
    address bus attribute: 0x<bus>
    address slot attribute: 0x<slot>
    address function attribute: 0x<function>
    Set the values of the domain, bus, slot, and function attributes such as to match the PCI function addresses of the form <domain>.<bus>.<slot>.<function> on the host.
    Tip: Issue lspci to list your PCIe devices with their function addresses.
    Example: To identify a PCI device with function address 0002:00:00.0, specify:
    <address domain="0x0002" bus="0x00" slot="0x00" function="0x0"/>
  4. Optional: Identify the device on the guest with the address element as child of the source element. If you omit this specification, libvirt generates a valid, unique device address for you.
    address type attribute: pci
    QEMU needs valid settings for the PCI domain, bus, slot, and function, although these settings are not visible on the guest. Omit these specifications to make libvirt generate valid values for you. You can see the generated values in the expanded libvirt-internal configuration of the virtual server.

  5. Optional: Complement the device identification on the guest with identifiers that are specific to z/Architecture®. These specifications are visible in the guest and help you to identify the device.
    zpci uid attribute: <uid>
    zpci fid attribute: <fid>
    The uid attribute has a similar role to a domain on the host. Valid specifications for <uid> are 4-digit hexadecimal values in the range 0x0001 - 0xffff. Valid specifications for <fid> are 8-digit hexadecimal values in the range 0x00000000 - 0xffffffff.

Example


 <hostdev mode="subsystem" type="pci" managed="yes">
   <driver name="vfio"/>
   <source>
     <address domain="0x0002" bus="0x00" slot="0x00" function="0x0"/>
   </source>
   <address type="pci"> 
     <zpci uid="0x0001" fid="0x00000000"/>
   </address>
 </hostdev>
Tip: Passing multiple PCI devices to a guest

When assigning multiple PCI devices to a single guest, VFIO does not share pinned-page accounting across devices. Each device counts its page references toward the guest’s locked memory limit. To avoid memory limit issues, configure the guest to allow for guest_memory × N pinned pages, where N is the number of PCI devices. Set the QEMU process’s locked memory limit using the memtune element.

In the following example, the guest has a memory of 10 gigabytes (guest_memory = 10 with unit = 'G') and you plan to pass through 3 PCI devices (x = 3). Therefore, you need to adjust the hard_limit to 30 gigabytes (= 10 × 3).
<memory unit='G'>10</memory>
<memtune>
 <hard_limit unit='G'>30</hard_limit>
</memtune>