Ретрансляция PCI#

Устройства 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"

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

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

  1. В конфигурационный файл /etc/modules добавить перечень модулей:

    pci_stub vfio
    vfio_iommu_type1
    vfio_pci
    vfio_virqfd
    
  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

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

lspci -nn

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

options vfio-pci ids=10de:11bf

Привязка устройств к 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

Необходимо сделать этот скрипт исполняемым.

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

Примечание

Пример

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

Приведенный в примере выше скрипт необходимо добавить в автостарт системы.

Примечание

Примеры

  1. Cоздать сервис, например 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
    
  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"

]

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

Единственной необходимой настройкой является фильтр для теста системы мониторинга, который получает список устройств 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

Настройка использования устройств 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
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

где:

  • VM — идентификационный номер ВМ, использующей данное устройство. Не указывается, если это устройство не используется ни одной ВМ;

  • ADDR — адрес на шине PCI;

  • TYPE (тип) — значения описания устройства, в формате vendor:device:class. Данные значения используются при выборе устройства PCI для проброса;

  • NAME (имя) — имя устройства PCI.

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

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

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

PCI = [
CLASS = "0604"
]

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

В веб-интерфейсе ПВ#

Для отображения доступных устройств PCI сервера виртуализации в веб-интерфейсе ПВ необходимо:

  1. В меню слева выбрать пункт меню Инфраструктура — Узлы;

  2. На открывшейся странице Узлы открыть вкладку PCI:

    ../../../../_images/pci_tab.png

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

  1. В меню слева выбрать пункт меню Шаблоны — ВМ и на открывшейся странице Шаблоны ВМ выбрать необходимый шаблон;

  2. На открывшейся странице Шаблон ВМ нажать на кнопку Обновить;

  3. На открывшейся странице Изменить шаблон ВМ открыть вкладку Ввод/Вывод:

    ../../../../_images/input_output_tab.png