Устройства PCI серверов виртуализации можно перенаправлять на виртуальные машины. Ядро на сервере виртуализации должно поддерживать ввод/вывод MMU. Для процессоров Intel это реализация VT-d, для AMDAMD-Vi. Кроме того, должна обеспечиватьсяозможность внесения в черный список любого драйвера, который может получить доступ к PCI-устройству, которое необходимо подключить к виртуальным машинам.

Конфигурация ядра

Конфигурация ядра должна выполняться с учетом необходимости поддержки ввода/вывода MMU и блокировки любых драйверов, которые могут осуществлять доступ к устройствам PCI, предполагаемым для использования в виртуальных машинах. Параметр для подключения ввода/вывода MMU

intel_iommu=on 

Необходимо также разрешить ядру загружать драйвер vfio-pci и блокировать драйверы для выбранных карт. Например, для графической платы NVIDIA можно применять следующие параметры:

rd.driver.pre=vfio-pci rd.driver.blacklist=nouveau

Указанные выше параметры необходимо добавить в конфигурационный файл /etc/default/grub:

GRUB_CMDLINE_LINUX_DEFAULT="intel_iommu=on rd.driver.pre=vfio-pci rd.driver.blacklist=nouveau"
CODE

Загрузка драйвера vfio в initrd

Модули для vfio должны быть добавлены в initrd. Для этого необходимо:

  1. в конфигурационный файл /etc/modules добавить перечень модулей:
    pci_stub
    vfio
    vfio_iommu_type1
    vfio_pci
    vfio_virqfd
    CODE
  2. выполнить команду:
    update-initramfs -u -k all

Блокировка драйверов

Блокировка, которая определяется в параметрах ядра, должна вноситься и в настройки системы. Пример файла /etc/modprobe.d/blacklist.conf для графической платы NVIDIA:

blacklist nouveau
blacklist lbm-nouveau
options nouveau modeset=0
alias nouveau off
alias lbm-nouveau off
CODE

Наряду с этой конфигурацией драйвер vfio должен быть загружен с передачей идентификатора карт PCI, которые предполагается подключить к ВМ. Для того что бы узнать идентификатор PCI устройства, необходимо ввести команду:

lspci -nn

Например, для графической платы NVIDIA Grid K2 с идентификатором 10de:11bf в конфигурационный файл /etc/modprobe.d/blacklist.conf необходимо добавить следующую строку:

options vfio-pci ids=10de:11bf
CODE

Привязка устройства к vfio

Механизм ввода/вывода MMU разделяет устройства PCI на группы для изолирования работы памяти между устройствами и ВМ. Для добавления устройств PCI в vfio и назначения им группы можно использовать совместно используемые скрипты.

Пример

Скрипт привязывает карту к vfio, прописывается в файле /usr/local/bin/vfio-bind:

#!/bin/sh
modprobe vfio-pci
for dev in "$@"; do
vendor=$(cat /sys/bus/pci/devices/$dev/vendor)
device=$(cat /sys/bus/pci/devices/$dev/device)
if [ -e /sys/bus/pci/devices/\$dev/driver ]; then
echo $dev > /sys/bus/pci/devices/$dev/driver/unbind
fi
echo $vendor $device > /sys/bus/pci/drivers/vfio-pci/new_id
done
CODE

Необходимо сделать этот скрипт исполняемым.
Конфигурация прописывается в файле /etc/sysconfig/vfio-bind. Устройства указываются с PCI-адресами. Адреса можно получить командой lspci, добавив в начало домен, как правило, 0000.

DEVICES="0000:04:00.0 0000:05:00.0 0000:84:00.0 0000:85:00.0"
CODE

Приведенный в примере выше скрипт необходимо добавить в автостарт системы.
Для этого следует выполнить следующие действия:

  1. создать службу, например vfio-bind, сформировав unit-файл /etc/systemd/system/vfio-bind.service, такого содержания:
    [Unit]
    Description=Binds devices to vfio-pci
    After=syslog.target
    [Service]
    EnvironmentFile=-/etc/default/vfio-bind
    Type=oneshot
    RemainAfterExit=yes
    ExecStart=-/usr/local/bin/vfio-bind $DEVICES
    [Install]
    WantedBy=multi-user.target
    CODE
  2. перезагрузить список служб командой:
    sudo systemctl daemon-reload

  3. добавить службу vfio-bind в автозагрузку командой:
    sudo systemctl enable vfio-bind

Конфигурация qemu

После привязки PCI к vfio необходимо предоставить qemu-доступ к vfio-устройствам для групп, назначенных устройствам PCI. Список устройств PCI и их vfio-группу можно получить с помощью команды:

find /sys/kernel/iommu_groups/ -type l

Пример

Для карт с группами 45, 46 и 58 в файл /etc/libvirt/qemu.conf добавить конфигурацию:

cgroup_device_acl = [
"/dev/null", "/dev/full", "/dev/zero", "/dev/random", "/dev/urandom",
"/dev/ptmx", "/dev/kvm", "/dev/kqemu", "/dev/rtc","/dev/hpet",
"/dev/vfio/vfio", "/dev/vfio/45", "/dev/vfio/46", "/dev/vfio/58"

]
CODE

Настройка драйвера

Единственной необходимой настройкой является фильтр для теста системы мониторинга, который получает список устройств PCI. По умолчанию тест перечисляет все устройств PCI, имеющиеся на сервере виртуализации. Для изменения данного списка можно изменить настройки фильтра в файле /var/lib/one/remotes/im/kvm-probes.d/pci.rb и установить список с таким же форматом lspci:

# Данная функция содержит фильтры для мониторинга устройств PCI. Формат
# такой же, как lspci, и можно добавить несколько фильтров через запятые.
# Нулевой фильтр обеспечит извлечение всех устройств PCI.
#
# Из раздела помощи lspci:
# -d [<vendor>]:[<device>][:<class>]
#
# Например
#
# FILTER = ’::0300’ # все карты VGA
# FILTER = ’10de::0300’ # все карты NVIDIA VGA
# FILTER = ’10de:11bf:0300’ # только GK104GL [GRID K2]
# FILTER = ’8086::0300,::0106’ # все карты Intel VGA и любые контроллеры SATA
CODE

Настройка использования устройств PCI

Основным действием по настройке является просмотр информации о сервере виртуализации в интерфейсе командной строки или в веб-интерфейсе ПК СВ, обнаружение доступных устройств PCI и добавление желаемого устройства в шаблон. Устройства PCI можно добавлять, указывая значения параметров vendor (производитель), device (устройство) и class (класс). В ПК СВ виртуальная машина будет развернута только на сервере виртуализации с имеющимся устройством PCI. Если таких серверов виртуализации нет, в журнале планировщика появится сообщение об ошибке.

В интерфейсе командной строки перечень доступных устройств PCI на сервере виртуализации (секция PCI DEVICES) можно просмотреть командой:

onehost show <идентификатор_сервера_виртуализации>

Пример

Список устройств PCI сервера виртуализации с идентификатором 0: 

onehost show 0

пример вывода:

PCI DEVICES
VM ADDR TYPE NAME
00:00.0 8086:0a04:0600 Haswell-ULT DRAM Controller
00:02.0 8086:0a16:0300 Haswell-ULT Integrated Graphics Controller
123 00:03.0 8086:0a0c:0403 Haswell-ULT HD Audio Controller
00:14.0 8086:9c31:0c03 8 Series USB xHCI HC
00:16.0 8086:9c3a:0780 8 Series HECI #0
00:1b.0 8086:9c20:0403 8 Series HD Audio Controller
00:1c.0 8086:9c10:0604 8 Series PCI Express Root Port 1
00:1c.2 8086:9c14:0604 8 Series PCI Express Root Port 3
00:1d.0 8086:9c26:0c03 8 Series USB EHCI #1
00:1f.0 8086:9c43:0601 8 Series LPC Controller
00:1f.2 8086:9c03:0106 8 Series SATA Controller 1 [AHCI mode]
00:1f.3 8086:9c22:0c05 8 Series SMBus Controller
02:00.0 8086:08b1:0280 Wireless 7260
CODE

где:

  • VM — идентификационный номер ВМ, использующей данное устройство. Не указывается, если это устройство не используется ни одной ВМ;
  • ADDR — адрес на шине PCI;
  • TYPE (тип) — значения описания устройства, в формате vendor:device:class. Данные значения используются при выборе устройства PCI для перенаправления;
  • NAME (имя) — имя устройства PCI.


Для обеспечения перенаправления одного из устройств PCI, в шаблон ВМ необходимо добавить блок параметров PCI, с помощью которого производится выбор устройства для использования. Например, для устройства Haswell-ULT HD Audio Controller:

PCI = [
VENDOR = "8086",
DEVICE = "0a0c",
CLASS = "0403"
]
CODE

Устройство может быть также указано без всех типовых значений. Например, для получения любых портов PCI Express Root Ports в шаблон ВМ можно добавить:

PCI = [
CLASS = "0604"
]
CODE

Для подключения более одного устройства PCI в шаблоне ВМ необходимо добавить дополнительные блоки параметров PCI.
В веб-интерфейсе ПК СВ для отображения доступных устройств PCI сервера виртуализации, необходимо:

  1. В меню слева выбрать пункт меню ИнфраструктураУзлы.
  2. На открывшейся странице Узлы открыть вкладку PCI:

Для добавления устройства PCI в шаблон ВМ в веб-интерфейсе ПК СВ необходимо выполнить следующие действия:

  1. В меню слева выбрать пункт меню ШаблоныВМ и на открывшейся странице Шаблоны ВМ выбрать необходимый шаблон.
  2. На открывшейся странице Шаблон ВМ нажать кнопку Обновить.
  3. На открывшейся странице Изменить шаблон ВМ открыть вкладку Ввод/Вывод: