Настройка PCI passthrough (на примере контроллера USB)

Настройка проброса устройств PCI для виртуальных машин при помощи функции passthrough в OpenStack. Для настройки системы необходима настроенная вычислительная нода с установленными и настроенными nova, neutron.

  1. Для выполнения манипуляций необходимо предварительно выяснить номер шины и устройства, vendor_id, product_id и имя драйвера, с которым устройство подключено в системе.

    Например:

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

    Определение ID устройства

    Далее:

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

    Определение номера шины и драйвера

  2. Следует включить в ядре поддержку iommu. Для включения опции при загрузке ОС можно применить добавление в опции ядра в GRUB:

    Для включения iommu необходимо добавить в файле /etc/default/grub параметру GRUB_CMDLINE_LINUX_DEFAULT значения intel_iommu=on и vfio_iommu_type1.allow_unsafe_interrupts=1. Опции дописываются в этот параметр через пробел. После редактирования файла следует выполнить команду grub-update (приведенный пример для систем на процессоре Intel).

  3. Добавление в файл /etc/modules загрузки необходимых для проброса модулей ядра:

    pci_stub
    vfio
    vfio_iommu_type1
    vfio-pci
    vfio_pci
    kvm
    kvm_intel
    

    Необходимо рестартовать систему для применения параметров.

  4. Проверка того, что модуль iommu включён в ядре:

    virt-host-validate
    
  5. Добавление в чёрный список драйверов для устройства, которое будет пробрасываться:

    echo 'blacklist xhci_hcd' >> /etc/modprobe.d/blacklist-xhci_hcd.conf
    
  6. Подтверждение, что поддерживается проброс устройства (подставьте свои номер шины и устройства):

    ls -ld /sys/kernel/iommu_groups/*/devices/*00:14.?/
    
  7. Добавление привязки устройства к модулю vfio-pci:

    • Добавление vendor_id:product_id контроллера в файл конфигурации модуля vfio. Если у вас несколько контроллеров, то надо указать каждый через запятую:

      /etc/modprobe.d/vfio.conf
      options vfio-pci ids=8086:8d31
      
    • Задание vfio-pci в качестве драйвера через параметры ядра:

      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
      
    • Проверка присвоения vfio-pci в качестве драйвера:

      lspci -s 00:14.0 -nnk
      
  8. Настройка в конфигурационном файле nova на вычислительной ноде:

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

    Рестарт службы nova-compute:

    systemctl restart nova-compute
    
  9. Настройка службы nova на контроллере:

    [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
    

    Рестарт служб nova:

    systemctl restart nova-*
    
  10. Создание типа виртуальной машины:

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

    где usbcontroller - это имя алиас на контроллере, 1 - сколько устройств будет передано виртуальной машине.