Configuring PCI passthrough (on the example of a USB controller)

Configuring PCI device forwarding for instances using the passthrough function in OpenStack. To set up the system, you need a configured computing node with nova, neutron installed and configured.

  1. To perform manipulations, you must first find out the bus and device number, vendor_id, product_id and the name of the driver with which the device is connected in the system.

    For example:

    lspci -nn | grep -i usb
    
    ../../_images/device_id.png

    Determining the device ID

    Next step:

    lspci -nk|grep -A2 -i 8086:8d31
    
    ../../_images/device_id.png

    Determining the bus and driver number

  2. Enable iommu support in the kernel. To enable the option at OS boot, you can apply the addition to the kernel options in GRUB:

    To enable iommu, you need to set GRUB_CMDLINE_LINUX_DEFAULT parameter to intel_iommu=on and vfio_iommu_type1.allow_unsafe_interrupts=1``in the ``/etc/default/grub file set the GRUB_CMDLINE_LINUX_DEFAULT. Options are appended to this parameter separated by a space. After editing the file, run the grub-update command (this example is for Intel based systems).

  3. Adding to the file /etc/modules the loading of the necessary kernel modules for forwarding:

    pci_stub
    vfio
    vfio_iommu_type1
    vfio-pci
    vfio_pci
    kvm
    kvm_intel
    

    You need to restart the system to apply the settings.

  4. Checking if the iommu module is enabled in the kernel:

    virt-host-validate
    
  5. Adding to the black list of drivers for the device that will be forwarded:

    echo 'blacklist xhci_hcd' >> /etc/modprobe.d/blacklist-xhci_hcd.conf
    
  6. Confirmation that device forwarding is supported (substitute your bus and device number):

    ls -ld /sys/kernel/iommu_groups/*/devices/*00:14.?/
    
  7. Adding device binding to the vfio-pci module:

    • Adding a vendor_id:product_id controller to the vfio module configuration file. If you have several controllers, then you need to specify each one separated by a comma:

      /etc/modprobe.d/vfio.conf
      options vfio-pci ids=8086:8d31
      
    • Setting vfio-pci as driver via kernel options:

      mcedit /etc/default/grub
      GRUB_CMDLINE_LINUX_DEFAULT="intel_iommu=on vfio-pci.ids=8086:8d31
      vfio_iommu_type1.allow_unsafe_interrupts=1"
      update-grub
      
    • Verifying that vfio-pci is assigned as a driver:

      lspci -s 00:14.0 -nnk
      
  8. Setting in nova config file on compute node:

    [pci]
    passthrough_whitelist: { "vendor_id": "8086", "product_id": "8d31" }
    

    Restarting the nova-compute service:

    systemctl restart nova-compute
    
  9. Setting up the nova service on the controller:

    [pci]
    alias: { "vendor_id":"8086", "product_id":"8d31", "device_type":"type-PCI",
    "name":"usbcontroller" }
    [filter_scheduler]
    enabled_filters = PciPassthroughFilter
    available_filters = nova.scheduler.filters.all_filters
    

    Restarting nova services:

    systemctl restart nova-*
    
  10. Creating a flavor:

    openstack flavor create \
    --vcpus 8 \
    --ram 16384 \
    --disk 100 \
    --property "pci_passthrough:alias"="usbcontroller:1" \
    8_16384_100_usb
    

    where usbcontroller is the name of the alias on the controller, 1 - how many devices will be transferred to the instance.