Введение в VFIO. Анализ исходного кода ядра Linux. Загрузка модуля. Интерфейс IOCTL. DPDK использует VFIO.
Введение в VFIO. Анализ исходного кода ядра Linux. Загрузка модуля. Интерфейс IOCTL. DPDK использует VFIO.

термин

VFIO (универсальная платформа для ввода-вывода в пользовательском пространстве): многофункциональная платформа для ввода-вывода в пользовательском пространстве.

LPC: Linux Plumbers Конференция (Конференция Linux «Сантехник») — это техническая конференция сообщества открытого исходного кода, посвященная решению проблем разработки Linux и продвижению кода вперед. Конференция собрала посвященных Ведущий разработчик «конвейера» Linux (подсистемы ядра, основные библиотеки, оконная система) и т. д. - и дал им три дня для совместной работы над ключевыми проблемами проектирования внутри и между подсистемами. также включает соответствующие Linux Презентации новых инновационных проектов, интересных сообществу. В число участников входят приглашенные посетители, докладчики, выбранные в ходе открытого конкурсного процесса судейства, а также студенты. турнирссылка: https://lpc.events/blog/current/index.php/2023/08/21/vfio-iommu-pci-mc-cfp/

Введение в ВФИО

Многие современные системы теперь предлагают DMA и инструменты переназначения прерываний, которые помогут гарантировать I/O Устройство работает в заданных границах. Это включает в себя использование AMD-Vi и Intel VT-d из x86 Аппаратное обеспечение с использованием разделяемых конечных точек (PE) из POWER системы и встроенные PowerPC система (напр. Freescale PAMU)。 VFIO Водитель - это IOMMU/оборудование, независимое от рамок существования IOMMU Защищатьиз открыто для пользовательского в безопасной среде пространствоизпрямойоборудованиедоступ。 Другими словами, это позволяет безопасно , непривилегированный драйвер пользовательского пространства, зачем нам это нужно? При настройке получить как можно больше из I/O В целях повышения производительности виртуальные машины обычно используют прямой доступ к устройствам («распределение устройств»). С точки зрения оборудования и хозяйствования это превращает виртуальную машину в пользовательское. Драйвер пространства со значительно уменьшенной задержкой, более высокой пропускной способностью и прямым использованием драйвера аппаратного оборудования. Некоторые приложения, особенно в области высокопроизводительных вычислений, Также воспользуйтесь пользовательским Пространство несет низкие накладные расходы, простой доступ к оборудованию. Примеры включают сетевые адаптеры (обычно не основанные на TCP/IP) и ускоритель вычислений. существовать VFIO Раньше эти драйверы должны были пройти полный цикл разработки, прежде чем стать полноценными драйверами восходящего потока, поддерживаемыми вне дерева или поддерживаемыми вне дерева. UIO каркас, который не имеет IOMMU Защитите свою концепцию, поддерживайте неограниченное количество перерывов и удовлетворяйте свои потребности root доступ PCI Настройте пространство, другое содержимое и разрешения. VFIO Структура драйверов призвана унифицировать их и заменить KVM PCI Конкретному оборудованию присваивается код и указывается соотношение UIO Более безопасное и функциональное потребительское среда космического драйвера

Гостевой виртуальный IOMMU (гостевой vIOMMU в QEMU)

Intel VT-d Поддержка моделирования, guest vIOMMU да QEMU серединаиз Универсальныйоборудование。 В настоящее время только Q35 Поддержка платформы guest vIOMMU。 Дечать даиспользовать Intel e1000 Карта игость vIOMMU запускать Q35 Самый простой пример машины из

Язык кода:javascript
копировать
qemu-system-x86_64 -machine q35,accel=kvm,kernel-irqchip=split -m 2G \
                   -device intel-iommu,intremap=on \
                   -netdev user,id=net0 \
                   -device e1000,netdev=net0 \
                   $IMAGE_PATH

здесь intremap=[on|off] показывать guest vIOMMU да Нет поддержки прерывать переназначение. чтобы полностью включить vIOMMU Функции, которые мы нуждаемсясуществовать, доступны здесь. intremap=on。 в настоящий момент,Переназначение прерываний не поддерживает полный irqchip ядра,толькоподдерживать“split”и“off”。

Больше всегомоделированиеоборудование(Как упоминалось вышеприезжатьиз e1000) сейчас существующие должны соответствовать Intel vIOMMU Работайте вместе без проблем. Однако есть некоторые специальные устройства,требующие особого ухода. Этиоборудованиеда:

  • распространятьизоборудование(Assigned, Например vfio-pci
  • Устройство Virtio(Например virtio-net-pci

При использовании включения устройств vIOMMU распределение устройств имеет особые зависимости. Давайте сделаем несколько представлений.

мы можемкиспользоватьк Отдать приказзапускатьиметь VT-d единицаираспространятьоборудованиеизвиртуальная машина:

Язык кода:javascript
копировать
qemu-system-x86_64 -M q35,accel=kvm,kernel-irqchip=split -m 2G \
                   -device intel-iommu,intremap=on,caching-mode=on \
                   -device vfio-pci,host=02:00.0 \
                   $IMAGE_PATH

когда мы используем intel-iommu оборудованиераспространятьоборудованиечас,здесьнуждаться caching-mode=on 。 В приведенном выше примере будет Хозяин PCI оборудование 02:00.0 Назначается гостям.

В то же время оно должно быть intel-iommu оборудованиеобозначениедляпараметрсписоксерединаиз Первыйиндивидуальныйоборудование(существоватьвсе остальноеоборудование До)

Схема традиционной архитектуры распределения устройств в Qemu

Давайте рассмотрим вышеизложенное PCI оборудование, оно подключается к системе Хозяин из реального оборудования. Хозяин может использовать универсальный драйвер ядра для управления оборудованием. существуют В этом случае,Долженоборудованиеиз Все прочитано/написать все ВолякприезжатьХозяин МОМУ из Защищать,Да Безопасностьиз。 к Защищатьиз DMA Возьмите зеленую стрелку. PCI оборудование Также возможнок Назначается гостям. Используя ядро ​​Хозяина из VFIO Драйвер, оборудование может изготовить любое пользовательское космическая программа (например, QEMU) для специализированного управления. существованию присвоено оборудованиеизгость, и мы должны увидеть то же самое, что и в Хозяинизоборудование (как показано пунктирной линией). В настоящее время программа управления виртуальной машиной может изменять информацию об оборудовании, например функциональные биты и т. д. посетителям от Воляоборудованиераспространять,мы можемксуществоватьГости получают ту же производительность, что и в Хозяине.。 С другой стороны, когда оборудование назначается гостю, адресное пространство гостевой памяти полностью доступно аппаратному обеспечению. PCI оборудование。 Поэтому, когда оборудование выполняется в клиентской системе При DMA (особенно да написании) никакой Защищать не будет. Вредоносная запись может мгновенно повредить клиент. Те, кто не в безопасности DMA Когда отображается красная стрелка. Вот и вседадлячто мынуждатьсясуществоватьгостьсерединаиспользовать VIOMMU для усиления защиты

Вариант использования 1. Распределение гостевых устройств с помощью vIOMMU.

для Понятно Защищатьгость Памятьотказалсякзлонамеренныйраспространятьоборудованиеиз Влияние,мы можемксуществоватьгостьсерединаиметь vIOMMU,нравиться Хозяин МОМУ Сделайте это с Хозяином. На картинке выше единственное отличие да мы ввели guest vIOMMU Приди и сделай это DMA Защищать。 Таким образом, гости DMA Сейчас существование безопасно. существоватьздесь,Мы извариант Использование нацелено на издаиспользовать изгость драйвера ядра. Стоит упомянуть изда, в настоящее время этот вариант Использование может оказать существенное влияние на результаты распределения изоборудования. гость IOVA Картированиединамичныйраспространять Воляпривести квиртуальная машина Программа управления выполняет большую работуделать,кудобный Воля Таблицы теневых страниц синхронизируются с реальным оборудованием.。 Да,карта памяти существует статически из случая,Не должно оказывать существенного влияния на производительность.(подизDPDK также одномерный использования)。 длядинамичный Память Картирование Общая ситуация,нуждаться Делать больше работы для дальнейшего снижения негативного воздействия «Защищать»

Вариант использования 2. Распределение гостевых устройств с помощью vIOMMU – сценарий DPDK

DPDK (так называемый изDataPlane Development Kit) широко используется в высокопроизводительной сцене, которая перемещает драйверы пространства ядра в пользовательское пространство. пространство для лучшей производительности. Обычно программы DPDK можно запускать непосредственно на «голом железе» для достижения оптимальной производительности на конкретном оборудовании. В то же время он также может действовать внутри существования, чтобы стимулировать распространение и оснащение предприятий или виртуальное оборудование (пример: virtio оборудование). За упоминания изгость DPDK вариант использования, хост все равно может продолжать использовать DPDK Чтобы максимизировать доставку пакетов в виртуальных коммутаторах 。 OVS-DPDK Просто хороший пример. Однако ДПДК Возникает проблема, потому что мы не можем доверять ни одному приложению пользовательского пространства, поэтому мы не можем доверять ни одному из них. DPDK приложение, особенно если оно может полностью получить доступ к системной памяти через аппаратное обеспечение и загрязнить адресное пространство ядра. здесь,vIOMMU Не только можно защитить аппаратные ошибки и другое вредоносное оборудование, но и гостей можно защитить от DPDK и т.п. бракованное изпользовательское драйвер пространства из аффектов (через клиент из VFIO водитель). Фактически, ДПДК Приложениями можно управлять как минимум тремя способами пространствосерединаизоборудование (Эти методы в основном носят общий характер и не ограничиваются DPDK Вариант использования):

  • VFIO
  • Режим VFIO без iommu
  • UIO, UIO устареет, потому что для него не хватает из Функция и Небезопасность.

Рассмотрим систему с двумя PCI оборудованиеизклиент DPDK Извариант приложения использования。 Для того, чтобы прояснить различия между вышеуказанными методами, я использую разные методы, назначенные для оборудования. DPDK Применение: Как показано выше, PCI оборудование 1 и PCI оборудование 2 да назначен гостю DPDK издваиндивидуальныйоборудование приложение. существовать Хозяинсередина,этотдваиндивидуальныйоборудование Всеиспользовать Ядро VFIO Драйвер назначен гостю (здесь мы не можем использовать "VFIO no-iommu модель» или «UIO», но причина этого выходит за рамки этой страницы :). И, кстати, когда мы назначаем оборудование приложению DPDK, мы можем использовать один из трех вышеуказанных методов. Но да, только когда мы используем Универсальный VFIO Водитель (требуется в ИОММУ) Распределение оборудования, мы можем получить только безопасное размещение изоборудования. Через «UIO» или «VFIO». no-iommu модель”распространятьоборудование Вседа Небезопасно из-за。 существоватьнасизпримерребеноксередина,PCI оборудование 1 дабезопасностьиз, в то время как PCI оборудование 2 да Небезопасно из-за

Вариант использования 3. Назначение вложенных гостевых устройств

использовать vIOMMU Сделать назначение оборудования по другому варианту использования, вложенное назначение оборудования будет работать как по волшебству. Как упоминалось в нашей первой части, распределение оборудования зависит IOMMU Работать. существоватьздесь,хотеть Воля L1 гостьоборудованиераспространять Давать L2 гость,насвозвращатьсянуждаться L1 гостьвнутреннийиз vIOMMU Построить сопоставление страниц, необходимое для работы по назначению оборудования. Вложенныйоборудованиераспространять Как показано ниже:

Устройство Virtio

Устройство Virtio особенный, потому что по умолчанию они обходят DMA Remapping Remap (не существует в драйвере ядра, используйте его). Нам нужны некоторые специальные параметры, чтобы явно включить DMA Переназначить. А переназначение прерываний не зависит от типа оборудования, поэтому оно включается/выключается так же, как и другие не virtio оборудование Такой же

для virtio-net-pci оборудованиедавать возможность DMAR (переназначение DMA) из самой простой командной строки:

Язык кода:javascript
копировать
qemu-system-x86_64 -M q35,accel=kvm,kernel-irqchip=split -m 2G \
                   -device intel-iommu,intremap=on,device-iotlb=on \
                   -device ioh3420,id=pcie.1,chassis=1 \
                   -device virtio-net-pci,bus=pcie.1,netdev=net0,disable-legacy=on,disable-modern=off,iommu_platform=on,ats=on \
                   -netdev tap,id=net0,vhostforce \
                   $IMAGE_PATH

здесь Мы дополнительно нуждаемся в следующих вещах:

моделирование vIOMMU Требуется «device-iotlb=on». Это делает оборудование IOTLB поддерживать vIOMMU, и он работает со следующими изats=on попарноиспользовать。 Нужен еще один ioh3420 оборудование。 Он используется для обеспечения virtio-net-pci оборудованиероды PCIe Под корневым портом нуждаться virtio оборудованиеда: существоватьсоздаватьизPCIeПод корневым портом,убеждатьсяиспользоватьсовременный virtio, убеждаться iommu_platform=on , Установите «ats=on», который аналогичен разделу «device-iotlb=on» выше. Кроме virtio-net-pci Кроме того, другие виды из virtio PCI оборудованиетакженуждатьсяпохожийизвещь。

Контейнер/группа/устройство выключено

Отношения VFIO и PCI

Связь структуры данных между Qemu/контейнером/группой/устройством

Взаимосвязь структур данных между группой/IOMMU/контейнером/доменом IOMMU/устройствами VFIO_PCI

Анализ исходного кода ядра VFIO

Загрузите модуль vfio-pci

Язык кода:javascript
копировать
vfio, Documentation/driver-api/vfio.rst
echo 1 | sudo tee /sys/module/vfio_pci/parameters/enable_sriov
modprobe vfio-pci enable_sriov=1 -> module_init(vfio_pci_init) -> vfio/pci: будет pci_driver код из vfio_pci_core.c разделить его и отделить vfio_pci Драйвер разбивается на две логические части, т.е. реализует "любой PCI оборудованиеиз Универсальный VFIO поддерживать”из“struct pci_driver" (vfio_pci.c) и кодовая база ( vfio_pci_core.c),помощьсуществовать PCI Внедряется поверх оборудования struct vfio_device。 vfio_pci.ko продолжатьсуществовать sysfs Ниже представлен тот же интерфейс, это изменение не повлияет на функциональность. Следующий патч поместит vfio_pci и vfio_pci_core Стать отдельным модулем. Этот дадля позволяет другому модулю предоставлять pci_driver и разрешить модулю настраивать VFIO настраивать методы, внедрять собственные операции и легко расширять функциональность, специфичную для конкретного поставщика. В это время vfio_pci_core все еще содержит много примешанного к нему из vfio_pci Функция. Последующие патчи удалят больше крупных объектов, но для их очистки потребуется еще одна серия очистки.
    vfio_pci_core_set_params
    pci_register_driver(&vfio_pci_driver)
    vfio_pci_fill_ids()
    pci_add_dynid(&vfio_pci_driver, vendor, device, subvendor, subdevice, class, class_mask, 0) -> будет новым PCI оборудование ID Добавьте к этому драйверу и перепроверьте оборудование
​
​
static struct pci_driver vfio_pci_driver = {
    .name           = "vfio-pci",
    .id_table       = vfio_pci_table,
    .probe          = vfio_pci_probe,
    .remove         = vfio_pci_remove,
    .sriov_configure    = vfio_pci_sriov_configure,
    .err_handler        = &vfio_pci_core_err_handlers,
    .driver_managed_dma = true,
};
​
vfio_pci_probe
    vfio_pci_is_denylisted
    vdev = vfio_alloc_device(vfio_pci_core_device, vdev, &pdev->dev, &vfio_pci_ops) -> container_of(_vfio_alloc_device
        vfio_init_device(device, dev, ops) -> vfio: добавить единство vfio_device Жизненный цикл помощника, идея дать возможность vfio основное управление vfio_device Жизненный цикл без дублирования логики между драйверами. Это также будет структурировать устройство добавляется на шаг подготовки vfio_deviceiz. Новинка из пары помощников и vfio_device серединаиз kref: - vfio_alloc_device() - vfio_put_device() Водители могут быть зарегистрированы @init/@release Обратные вызовы для управления упаковкой vfio_device из Любое частное государство. Однако vfio-ccw Не подходит для этой модели, поскольку она представляет собой частную структуру, смешанную с родительской и mdev Информация, поэтому жизненный цикл хаотичен и поэтому должен существовать. vfio оборудованиеиз выделено/высвобождено вне срока эксплуатации. Согласно предыдущим обсуждениям, IBM Персонал не будет существовать в ближайшее время, решая эту проблему. Вместо того, чтобы ждать этих изменений, да вводится еще один помощник vfio_init_device(), чтобы ccw Его можно вызвать для инициализации предварительного выделения из vfio_device。 ccw Навык в дальнейшем значении да vfio_device Не могущийсуществовать vfio Унифицированный выпуск в ядре. Вместо этого нуждаться *каждый* драйвер реализует @release и освобождает внутреннее изvfio_device. Тогда ccw может бесплатно отложить его. Еще один совет kvzalloc() используется для удовлетворения gvt изнуждаться,gvt использовать vzalloc(), а все остальные используются kzalloc()。 Поэтому водителю следует вызвать помощника vfio_free_device() освободить vfio_device без даассеме kfree() или vfree() применять позже, однажды ccw Как только беспорядок будет устранен, мы сможем убрать уловки и полностью разобраться с ситуацией. vfio из структуры выделения/освобождения в основном. Все существующие варианты использования после конвертации в новую модель, существующие vfio_{un}init_group_dev() будет устаревшим
            ida_alloc_max
            init_completion(&device->comp)
            ret = ops->init(device) -> vfio_pci_core_init_dev
                INIT_LIST_HEAD(&vdev->dummy_resources_list)
                INIT_LIST_HEAD(&vdev->ioeventfds_list)
                INIT_LIST_HEAD(&vdev->vma_list)
                INIT_LIST_HEAD(&vdev->sriov_pfs_item)
                xa_init(&vdev->ctx) -> vfio/pci:usexarray для хранения контекста прерывания, выделение контекста прерывания выделяется статически при возникновении прерывания. После выделения контекст управляется путем прямой индексации массива доступа из элементов через вектор использования. Когда прерывания отключены, память освобождается. давать возможность MSI-X После этого вы можете динамически выделить один MSI-X Прерывать. нуждаться в контексте прерывания из динамического хранилища, чтобы поддержать это. Замените массив контекстов прерываний на для xarray (аналогично ядру, используемому в качестве MSI Хранилище дескрипторов из массива), которое можно динамически расширять, сохраняя при этом вектор использования для индексации и настройки. использовать динамическое хранилище, больше не выделяет предварительно контекст прерывания, когда нуждаться в выделении прерываний. MSI и MSI-X серединаперерывначальствонижетолькосуществоватьсерединаперерывдавать возможностьчасиспользовать。 Поэтому их выделение может быть отложено до тех пор, пока не будет разрешено прерывание. толькодавать возможностьизсерединаперерыв才встречаиметь关联изсерединаперерывначальствониже。 да Нет назначенного прерывания (Linux irq количество сохранений существует) в случае, разрешить ли прерывание из стандарта
            device_initialize(&device->device)
    dev_set_drvdata(&pdev->dev, vdev) -> vfio/pci: сделать все VFIO PCI Водитель будет vfio_pci_core_device хранилищесуществовать drvdata середина,существовать drvdata Наличие согласованных указателей позволит следующему патчу использовать некоторые помощники основного кода в из. drvdata。 существовать vfio_pci_core_register_device() Внутрииспользовать WARN_ON Чтобы обнаружить отсутствие этого драйвера
    vfio_pci_core_register_device(vdev)
        if (pdev->hdr_type != PCI_HEADER_TYPE_NORMAL)
        if (pci_num_vf(pdev)) -> Предотвратить привязку приезжатьдавать возможность Понятно VF из PF,VF МожетЁсимасасуществоватьодеяло Хозяинилидругие пользователииспользовать。 если VF существования уже сохранены, мы не можем их захватить или отследить VF пользователь. Здесь отключено SR-IOV начну удалять VF,этот Воля Удалить драйверизобязательность,если Должен VF Также покрыто vfio-pci использовать, драйвер склонен к блокировке. Просто отклоните эти PF и позвольте пользователям разобраться в них.
        vfio_assign_device_set -> vfio/pci: переходим к инфраструктуре набора оборудования, PCI надеюсь, что будет как обычно open/close_device() логика, но немного другая, т.е. open/close_device() Должны существовать все vfio_device Обмен осуществляется под единым замком PCI «Группа сброса». Сброс настроек и настроек оборудования pci_reset_bus() Контактное изоборудование решает, можно весь автобус, а можно только слоты. Положитесь на основной код для завершения reflck Сделайте все и удалите его полностью reflck -> vfio:для Открыть/выпускатьvfio_device_opsпоставлятьлучшеиз Универсальныйподдерживать,Текущий водительopsесть одининдивидуальный Открыть/выпускатьверно,Каждый Второсортный ОткрытьилизакрытиеоборудованиеFDчас Всепозвонюодин Второсортный。 Добавьте набор доп. open/close_device() действовать,Этидействоватьсуществоватьоборудование FD Вызывается при первом открытии и последнем закрытии. Анализ показывает, что все драйверы имеют такую ​​семантику. Некоторые люди называют его открытый код «для». reflck Реализация частично, некоторые люди просто имеют ошибки и полностью ее пропускают. длязарезервировано PCI и FSL Зависит от текущей семантики из, введением понятия «комплект оборудования», который для группы существования использует один и тот же замок при открытии. vfio_device。 Набор оборудования да устанавливается путем предоставления указателя «set_id». Все они предоставляют один и тот же указатель vfio_device Подключится к той же одноэлементной памяти и заблокирует всю коллекцию. Это эффективно заменяет имя Strange из reflck。 После преобразования set_id Будет происходить из: - fsl_mc_device (fsl) из struct device - struct pci_slot (pci) - struct pci_bus (pci) - struct vfio_device (все) Конструкция убеждается, что указанный выше указатель действителен. если бы только vfio_device зарегистрированные, они образуют надежный и уникальный ключ к vfio_device Группа. Эта реализацияиспользовать xarray Вместо поиска в структуре ядра драйвера это упрощает довольно сложную область блокировки. Следующий патч преобразует все драйверы
            INIT_LIST_HEAD(&new_dev_set->device_list)
            dev_set = __xa_cmpxchg -> сравнивать и хранить, При вызове этой функции вы уже должны удерживать xa_lock。 еслинуждатьсяраспространятьпамять,это Волявыпускать Замок,а затем загрузить его повторно
        vfio_pci_vf_init -> vfio_pci_probe() Довольно сложно, есть варианты VF и VGA подкомпонент. Переместите их, чтобы очистить init/uninit функция и имеет линейный поток обнаружения/удаления. Это исправляет некоторые мелкие ошибки: - vfio_pci_remove() из Неправильный порядок, vga_client_register() Удалить Notifier и найти по адресу kfree(vdev) После этого, но уведомитель ссылается vdev, чтобы оно могло существовать и конкурировать в free Изназадиспользовать。 - vga_client_register() Может потерпеть неудачу, но игнорироваться Организуйте вещи так, чтобы порядок разрушения был противоположен порядку создания.
            if (pdev->is_virtfn) 
                pci_physfn
                list_for_each_entry(cur, &vfio_pci_sriov_pfs,
            vdev->nb.notifier_call = vfio_pci_bus_notifier
                if (action == BUS_NOTIFY_ADD_DEVICE
            ret = bus_register_notifier(&pci_bus_type, &vdev->nb)
        vfio_pci_vga_init -> Video Graphics Array (VGA) connector
            vfio_pci_is_vga
            aperture_remove_conflicting_pci_devices
            vga_client_register(pdev, vfio_pci_set_decode)
            vga_set_legacy_decoding(pdev, vfio_pci_set_decode(pdev, false))
        vfio_pci_probe_power_state
            pci_read_config_word(pdev, pdev->pm_cap + PCI_PM_CTRL, &pmcsr)
        vfio_pci_set_power_state
        pm_runtime_allow
        vfio_register_group_dev -> vfio: Упрощенное посредническое оборудованиеиз iommu Групповое назначение, повторное использование vfio_noiommu_group_alloc Среда из логики, назначение ложных заказов оборудованию путем декомпозиции универсальной функции для посреднического оборудования iommu группу и замените ее перечислением struct vfio_group серединаиз noiommu Логическое поле, позволяющее различать эти три Различные типы групп
            dev_set_name(&device->device, "vfio%d", device->index)
            vfio_device_set_group(device, type)
                vfio_group_find_or_alloc
                    vfio_noiommu_group_alloc
                    group = vfio_group_find_from_iommu(iommu_group) -> list_for_each_entry(group, &vfio.group_list
                        vfio_group_has_device
                    group = vfio_create_group(iommu_group, VFIO_IOMMU)
                        group = vfio_group_alloc(iommu_group, type)
                            cdev_init(&group->cdev, &vfio_group_fops)
                            INIT_LIST_HEAD(&group->device_list)
                        dev_set_name(&group->dev, "%s%d"
                        cdev_device_add(&group->cdev, &group->dev)
                        list_add(&group->vfio_next, &vfio.group_list)
                or vfio_noiommu_group_alloc
            vfio_device_add(device) -> vfio:для vfio_device добавить в cdev,этотвстречадобавить в Справа vfio_device из cdev поддерживать。 Это позволяет пользователям напрямую открывать vfio оборудование вместо использования старого интерфейса контейнера/группы, это дапод поддержка вложенного перевода и т. д. Новое iommu Функция из предпосылок. Открыть таким образом изоборудование fd Не могущийдоступ оборудование,потому чтодля fops open() оборудование не будет открыто до успешного завершения VFIO_DEVICE_BIND_IOMMUFD ioctl(Волясуществоватькназадизпластырьсерединадобавить в)。 С этим патчем зарегистрируйтесь, чтобы vfio Ядро изоборудования одновременно создаст старую группу и новый интерфейс оборудования. - Групповой интерфейс: /dev/vfio/$groupID - оборудованиеинтерфейс:/dev/vfio/devices/vfioX - обычнооборудование(“X”дачерез vfio оборудованиеиз уникальный номер) Для данного оборудования пользователь может определить соответствие из vfioX Поиск по оборудованиюиз sysfs Путь вниз из vfio-dev папка. к PCI оборудование (0000:6a:01.0) дляпример,/sys/bus/pci/devices/0000\:6a\:01.0/vfio-dev/vfioX выражать /dev/vfio/devices/ Следующий матч из vfioX и vfio-dev/vfioX/dev содержит совпадения из /dev/vfio/devices/vfioX из Большие и второстепенные числа. Пользователи могуткпроходить Открыть/dev/vfio/devices/vfioX получитьоборудованиеfd。 Этот патч находится в разработке vfio_device cdev логика: *) __vfio_register_dev() Путь в конечном итоге будет для каждого vfio_device осуществлять cdev_device_add()(если Конфигурация Понятно VFIO_DEVICE_CDEV)。 *) vfio_unregister_group_dev() путьосуществлять cdev_device_del(); cdev интерфейс Нетподдерживать noiommu оборудование,потому чтоэтот VFIO Только для нет IOMMU из Физического оборудования Создать старый групповой интерфейс. noiommu Пользователи должны использовать старый интерфейс группы.
                device_add
            vfio_device_group_register -> list_add(&device->group_next, &device->group->device_list)
            vfio_device_debugfs_init -> vfio/migration: для драйвера живой миграции добавить вdebugfs,Процесс термической миграции включает в себя множествоиндивидуальныйоборудование、программное обеспечениеидействоватьшаг。 Ошибка на любом узле может привести к сбою операции динамической миграции. Из-за этого сложного процесса очень сложно найти и проанализировать причину сбоя функции. для Понятносуществоватьтермическая миграциянеудачачас Быстрый заказ Кусочек Исходная проблемапотому что,ясуществоватьvfioтермическая миграцияводить машинусерединадобавить в Понятноодин Группаdebugf, commit, https://github.com/ssbandjl/linux/commit/2202844e4468c7539dba0c0b06577c93735af952
                vdev->debug_root = debugfs_create_dir(dev_name(vdev->dev),
                vfio_dev_migration = debugfs_create_dir("migration",
                debugfs_create_devm_seqfile(dev, "state", vfio_dev_migration,
​
static const struct vfio_device_ops vfio_pci_ops = {
    .name       = "vfio-pci",
    .init       = vfio_pci_core_init_dev,
    .release    = vfio_pci_core_release_dev,
    .open_device    = vfio_pci_open_device,
    .close_device   = vfio_pci_core_close_device,
    .ioctl      = vfio_pci_core_ioctl,
    .device_feature = vfio_pci_core_ioctl_feature,
    .read       = vfio_pci_core_read,
    .write      = vfio_pci_core_write,
    .mmap       = vfio_pci_core_mmap,
    .request    = vfio_pci_core_request,
    .match      = vfio_pci_core_match,
    .bind_iommufd   = vfio_iommufd_physical_bind,
    .unbind_iommufd = vfio_iommufd_physical_unbind,
    .attach_ioas    = vfio_iommufd_physical_attach_ioas,
    .detach_ioas    = vfio_iommufd_physical_detach_ioas,
};

Отладка архитектуры файловой системы (debugfs) при горячей миграции в Qemu

Язык кода:javascript
копировать
всеиндивидуальныйdebugfsОглавление Воляна макрос на основеCONFIG_DEBUG_FS из определения. если Нетдавать возможность Должен Макрос,vfio.hсерединаизинтерфейс Волядляпустое определение,ии НетвстречаосуществлятьdebugfsОглавлениеизсоздаватьиинициализация, debugfs создаст общий корневой файл «vfio», а затем для каждого оборудования живой миграции создаст файл dev_name(). Сначала создайте файл «миграции» из единого файла получения статуса в этом каталоге оборудования. Затем создайте общедоступный файл поиска состояния живой миграции «state».
    +-------------------------------------------+
    |                                           |
    |                                           |
    |                  QEMU                     |
    |                                           |
    |                                           |
    +---+----------------------------+----------+
        |      ^                     |      ^
        |      |                     |      |
        |      |                     |      |
        v      |                     v      |
     +---------+--+               +---------+--+
     |src vfio_dev|               |dst vfio_dev|
     +--+---------+               +--+---------+
        |      ^                     |      ^
        |      |                     |      |
        v      |                     |      |
   +-----------+----+           +-----------+----+
   |src dev debugfs |           |dst dev debugfs |
   +----------------+           +----------------+

Загрузите модуль VFIO

Язык кода:javascript
копировать
modprobe vfio, vfio.ko
static struct vfio {
    struct class            *device_class;
    struct ida          device_ida;
} vfio; -> VFIO да Используется безопасный драйвер пользовательского уровня, который работает с виртуальными машинами, и драйверы пользовательского уровня. VFIO использовать IOMMU Группа создается изолированно, что обеспечивает доступ непривилегированным пользователям. VFIO цельсуществоватьзаменять KVM оборудованиераспространятьи UIO Драйвер (существовать целевую платформу содержит достаточную функциональность из IOMMU из случая). эта версия VFIO из новых функций даподдержка Pass IOMMU основное управлениеиз IOMMU группа, и API Были внесены изменения по удалению комбинации «Кроме» и объединению интерфейсов. Теперь мы существуем обратно в более похожее на оригинал VFIO иподдерживать UIOMMU из модели, откуда /dev/vfio/vfio Получить из файлового дескриптора разрешен доступ IOMMU,нотолькосуществоватьдобавить в Группа Изназад,избегать Понятнокпредыдущий типиз Проблема с разрешениями Модель. IOMMU поддерживатьсейчассуществоватьтакжеда Полностью модульныйиз,потому чтодля IOMMU существуют Разные платформы имеют совершенно разные требования к интерфейсу. VFIO Пользователи могут запрашивать и инициализировать свой выбор. IOMMU Модель. пожалуйста Видетьназад Продолжениедокументпредставлять на рассмотрениек Двигайтесь дальшеизописыватьииспользовать Показыватьпример
commit, https://github.com/ssbandjl/linux/commit/cba3345cc494ad286ca8823f44b2c16cae496679
module_init(vfio_init)
    ida_init(&vfio.device_ida)
    vfio_group_init()
        INIT_LIST_HEAD(&vfio.group_list)
        vfio_container_init
            INIT_LIST_HEAD(&vfio.iommu_drivers_list)
            misc_register(&vfio_dev)
            if (IS_ENABLED(CONFIG_VFIO_NOIOMMU))
                vfio_register_iommu_driver(&vfio_noiommu_ops)
                    list_add(&driver->vfio_next, &vfio.iommu_drivers_list)
        vfio.class = class_create("vfio") -> /dev/vfio/$GROUP
        alloc_chrdev_region(&vfio.group_devt, 0, MINORMASK + 1, "vfio") -> register_chrdev_region нуждатьсяразвивать ВОЗобозначениеоборудованиеизхозяиноборудование Число,и alloc_chrdev_region Тогда ядром автоматически присваивается основной номер оборудования.
    vfio_virqfd_init() -> create_singlethread_workqueue("vfio-irqfd-cleanup")
    vfio.device_class = class_create("vfio-dev")
    vfio_cdev_init(vfio.device_class)
    alloc_chrdev_region(&device_devt, 0, MINORMASK + 1, "vfio-dev")
    vfio_debugfs_create_root -> vfio_debugfs_root = debugfs_create_dir("vfio", NULL)
​
​
​
static struct miscdevice vfio_dev = {
    .minor = VFIO_MINOR,
    .name = "vfio",
    .fops = &vfio_fops,
    .nodename = "vfio/vfio",
    .mode = S_IRUGO | S_IWUGO,
};
​
static const struct file_operations vfio_fops = {
    .owner      = THIS_MODULE,
    .open       = vfio_fops_open,
    .release    = vfio_fops_release,
    .unlocked_ioctl = vfio_fops_unl_ioctl,
    .compat_ioctl   = compat_ptr_ioctl,
};
​
​
static const struct vfio_iommu_driver_ops vfio_noiommu_ops = {
    .name = "vfio-noiommu",
    .owner = THIS_MODULE,
    .open = vfio_noiommu_open,
    .release = vfio_noiommu_release,
    .ioctl = vfio_noiommu_ioctl,
    .attach_group = vfio_noiommu_attach_group,
    .detach_group = vfio_noiommu_detach_group,
};
​
vfio_fops_open
    INIT_LIST_HEAD(&container->group_list)
​
include/uapi/linux/vfio.h
​
vfio_pci_sriov_configure -> vfio_pci_core_sriov_configure
    if (nr_virtfn)
        list_add_tail(&vdev->sriov_pfs_item, &vfio_pci_sriov_pfs)
        pm_runtime_resume_and_get
        vfio_pci_set_power_state
        pci_enable_sriov
    pci_disable_sriov
​
​
vfio_df_ioctl_bind_iommufd
​
​
static const struct file_operations vfio_group_fops = {
    .owner      = THIS_MODULE,
    .unlocked_ioctl = vfio_group_fops_unl_ioctl,
    .compat_ioctl   = compat_ptr_ioctl,
    .open       = vfio_group_fops_open,
    .release    = vfio_group_fops_release,
};
​
​
vfio_group_fops_open
    struct vfio_group *group
    group->opened_file = filep
    filep->private_data = group

Типичный процесс IOCTL (интерфейс ioctl)

Язык кода:javascript
копировать
vfio_group_fops_unl_ioctl
    switch (cmd)
    case VFIO_GROUP_GET_DEVICE_FD
        vfio_group_ioctl_get_device_fd
            vfio_device_open_file
                vfio_df_group_open
                    vfio_df_open
                        vfio_df_device_first_open
                            device->ops->open_device(device) -> vfio_pci_open_device
                                vfio_pci_core_enable
                                    pci_enable_device
                                    pci_try_reset_function
                                    pci_read_config_word(pdev, PCI_COMMAND, &cmd)
                                    vfio_pci_zdev_open_device -> vfio-pci/zdev:добавить в Открыть/закрытиеоборудованиемонтировать,существоватьvfio-pci период open_device,пройти дальше иvfioгрупповая ассоциацияизKVM(еслижитьсуществовать)。 Этот дадля будет специальным индикатором (GISA) перешел на прошивку,к Разрешить zPCI Инструменты интерпретации используются только с vfio-pci оборудованиесвязанное неспецифическое KVM。 существовать vfio-pci close_device В течение этого периода процесс уведомления об отмене
                                        return zpci_kvm_hook.kvm_register(zdev, vdev->vdev.kvm) -> давать возможность zPCI инструкцияизобъяснятьосуществлять + Прерывание адаптера, s390x KVM vfio-pci из Форвард. Дапроходитьсуществовать VFIO группа с KVM Запустить процедуру, когда гость связан, передать специальный токен в прошивку (GISA имя)кделать Долженидентификациягостьможетсуществовать Должен zPCI оборудованиеначальствообъяснятьосуществлятьзавершитьиз。 Ранназад,нагрузка/хранилищеобъяснятьдавать возможность Зависит отпользовательское контроль пространства (на основе SHM Бит дано помещается в дескриптор существующей виртуальной функции). Уведомление о событии адаптера объяснено новым из KVM ioctl отпользовательское пространствоконтрольиз。 позволяя интерпретировать zPCI Инструкции и указания guest виртуальная машинапередаватьсерединаперерывизпрошивка,мы можемкуменьшать zPCI из guest SIE Выходная частота. от guest Конфигурацияизперспектива,Ты можешьк В соответствии ск То же, что и раньшеизспособ пройти zPCI оборудование,и по умолчаниюиспользоватьобъяснятьподдерживать(еслисуществовать kernel+qemu доступно в). Будем следить за обновлениями QEMU Серия по ссылке. Журнал изменений v7->v8: - ремонт ioctl документ (Thomas) - от ioctl Удалить в copy_to_user, из старой версии (Thomas) - KVM_S390_ZPCIOP_REG_AEN: не установлен неопределенный флаг. (Thomas) - kvm_s390_pci_zpci_reg_aen: Очистить настройки флага Хозяина. (Thomas) И ремонт неожиданный из-за ошибки битовая инверсия - CONFIG_VFIO_PCI_ZDEV_KVM:добавить вслучайное упущениесуществоватьпомощьтекстсерединаиз“say Y”(Jason) - Рефакторинг "vfio:remove VFIO_GROUP_NOTIFY_SET_KVM» vfio-pci-zdev Фрагмент (Джейсон) - open_device/ close_device Теперь существование будет называться напрямую kvm Процедура регистрации. Воля open_device звонок перенесен на vfio_pci_core_enable,кудобный Можетк Распространение ошибок。 Для проверки четности,Воля close_device звонок перенесен на vfio_pci_core_disable -> commit, https://lwn.net/Articles/897230/
                                    vfio_config_init -> Для каждого оборудования мы назначаем pci_config_map указать род деятельности каждогоиндивидуальныйдвойное словоизспособность,оти指Показыватьнасдля чтения и письмаиз struct perm_bits。 Мы также выделяем пространство конфигурации виртуализации для отслеживания наших моделей избитизчтения для пользователей. отоборудование восполняет первоначальную стоимость. существоватьвсе vfio-pci оборудованиемеждуиспользоватьобщий struct perm_bits Можеткделатьнасотказался于для Каждыйиндивидуальныйоборудованиеиз virt и write распространять cfg_size буфер. мы можемкудалить vconfig идлянуждатьсямоделирование Кусочекиз Каждыйиндивидуальныйобластьраспространятьодинизбуфер,Но массив указателейизразмер Волядовольно(По крайней мере для стандартного конфигурационного пространства)-> ключевые структуры данных, struct vfio_pci_core_device, Воляpciаппаратное обеспечениеспособностьи Конфигурацияпроходитьvfioизpciоборудование暴露Даватьначальствослой
                                        map = kmalloc(pdev->cfg_size, GFP_KERNEL_ACCOUNT) -> Конфигурационное пространство, заглавные буквы и ecaps Вседадвойное слововерно齐из,потому чтоэтотмы можемкиспользовать Каждыйиндивидуальныйдвойное словоодининдивидуальный Байты для типа записи。 носпособностьиз Нет длиныхотетьпросить,Местокспособностьмеждуиззазорнуждаться Байтовая детализация
                                        vfio_fill_vconfig_bytes -> vfio:добавить вPCIоборудованиеводить машину,добавить вPCIоборудование против VFIOизподдержки. PCI оборудование общедоступное для доступаоборудованиеиз конфигурационного пространства, ввода/вывода портовое пространство и MMIO Площадь из площади. PCI Настройка доступсуществовать в ядре виртуализации позволяет нам предотвратить различные виды доступа, одновременно уменьшая перекрестное разнообразие поль зовательского доступа. Космический драйвер из дубликатов требует убедить систему в целостности. I/O Порт поддерживает доступ для чтения/записи, в то время как MMIO Также поддерживается достаточная площадь территории из mmap。 использовать eventfds Кпользовательское пространство обеспечивает INTx、MSI и MSI-X перестань поддерживать -> commit, https://github.com/ssbandjl/linux/commit/89e1f7d4c66d85f42c3d52ea3866eb10cadf6153
                                        vdev->rbar[0] = le32_to_cpu(*(__le32 *)&vconfig[PCI_BASE_ADDRESS_0]);
                                        ...
                                        vfio_cap_init
                                        vfio_ecap_init
                                    vdev->has_dyn_msix = pci_msix_can_alloc_dyn(pdev)
                                vfio_pci_core_finish_enable
                                    vfio_pci_probe_mmaps
                                        for (i = 0; i < PCI_STD_NUM_BARS; i++) -> 6
                                            dummy_res->resource.name = "vfio sub-page reserved"
                                    eeh_dev_open -> eeh_dev_open - Увеличивать PE изпрямойоборудованиесчитать,@pdev:PCI оборудование Увеличиватьобозначение PE изпрямойоборудованиесчитать。 результат,существовать PE обнаружен на EEH ошибка Воля Нетвстречаодеяло Отчет。 PE все ВОЗВоля Ответственный за тестированиеивосстанавливаться -> Extended Error Handling -> на основе IBM POWER из pSeries и iSeries Компьютер включает в себя PCI Чипы контроллера шины. Эти чипы способны обнаруживать и сообщать о различных PCI автобусошибка Состояниеиз Расширять Функция. Эти функции имеют название «EEH», то есть «Расширенная обработка ошибок». EEH Аппаратная функция позволяет очистить PCI Ошибка шины и «перезапуск» PCI карту без переустановки операционной системы. Это отличается от традиционного PCI Вместо этого существует обработка ошибок, традиционная PCI Обработка ошибок, PCI Чип подключен напрямую к CPU, ошибка приведет к CPU Проверка машины/Проверьте условия остановки,отиполная остановка CPU。 Другой вид“Традиция”технологияда忽略этот类ошибка,этот Может能привести кпользовательданныеили Ядроданныеиз Повреждение данных、Адаптер зависает/Нет ответаили Сбой системы/запирание。 Поэтому ЭЭХ Идея создания операционной системы «Защита» от PCI Ошибка влияет и дает операционной системе возможность «перезапустить запуск»/восстановить каждый PCI оборудованиеизспособность,действоватьсистема Можеткстать более надежнымикрепкий。 Другие поставщики основе PCI-E Спецификация будущих систем может включать аналогичную функциональность, ref, https://android.googlesource.com/kernel/common/+/bcmdhd-3.10/Documentation/powerpc/eeh-pci-error-recovery.txt
    vfio_group_ioctl_get_status
        iommu_group_dma_owner_claimed ->  Query group dma ownership status -> многоиндивидуальныйоборудование Можеткместосуществоватьтакой жеиндивидуальный IOMMU группы, поскольку для них невозможно изолировать друг от друга. Этиоборудованиедолжно быть полностьюк Ядроконтрольилипользовательское контроль пространства, нельзя смешивать. этотсуществовать iommu основнойсерединадобавить в Понятно dma Управление собственностью и раскрытие драйверов оборудования пространствораспространятьрамка(Прямо сейчас VFIO)измногоиндивидуальныйинтерфейс,кудобный Можетксуществовать Обнаружение с самого началаприезжатьпользовательи Ядроконтрольиз dma Любой конфликт между из. Для оборудования Драйвер из Интерфейса да int iommu_device_use_default_domain(struct device *dev); void iommu_device_unuse_default_domain(struct device *dev); Позвонив iommu_device_use_default_domain(), сообщает драйвер оборудования iommu слойоборудование dma дапасс ядра DMA API Обработка из. iommu слой Воляуправлять IOVA И используйте домен по умолчанию, чтобы продолжить DMA Перевод адреса. 面Коборудованиепользовательское пространствораспространятьрамкаизинтерфейсда int iommu_group_claim_dma_owner(struct iommu_group *group, void *owner); неверный iommu_group_release_dma_owner(struct iommu_group *group); bool iommu_group_dma_owner_claimed(struct iommu_group *group); если DMA Если владелец заявляет, что интерфейс возвращает ошибку, его необходимо отключить. пространствораспространять
    vfio_group_ioctl_set_container
        f = fdget(fd)
        container = vfio_container_from_file(f.file)
        vfio_container_attach_group
            driver->ops->attach_group(container->iommu_data, group->iommu_group, group->type) -> vfio_noiommu_attach_group
            list_add(&group->container_next, &container->group_list)
            vfio_container_get(container)
        iommufd = iommufd_ctx_from_file(f.file)
        iommufd_vfio_compat_set_no_iommu
        or iommufd_vfio_compat_ioas_create -> убеждатьсясоздавать Понятно compat IOAS, @ictx: работать в контексте совместимость IOAS да vfio совместимость ioctls Операция IOAS, потому что они ABI Никто IOAS ID входить. Простое добавление группы должно привести к внутреннему ioas изпо умолчаниюсоздавать,еслиужеккаким-то образомраспространять Понятносейчасиметь ioas,ноэтот Нетвстречаосуществлятьлюбойдействовать
            ioas = iommufd_ioas_alloc(ictx) -> iommufd: контейнер vfio FD ioctlсовместимость,iommufdМожеткпроходить Воля/dev/vfio/vfioконтейнерIOCTLкартографированиеприезжатьio_pagetableдействовать Приходитьпрямой Реальностьсейчасэтоих。 пользовательское пространствоприложение Можетк针верно iommufd тестиподтверждатьсовместимость,Ранназад Просто сделайодиннебольшие изменения Прямо сейчас Может Открыть /dev/iommu Вместо того, чтобы да /dev/vfio/vfio。 В целях тестирования /dev/vfio/vfio Можетксимвол Число Связьприезжать /dev/iommu,Ранназадвсеприложение Воляиспользоватьсовместимостьпуть,Никаких изменений кода не требуется。 Последующие серии позволяют iommufd Предоставить напрямую /dev/vfio/vfio, это также позволяет rlimit модель работает аналогично. В этой серии представлены только iommufd Аспект совместимости. На самом деле воляитс ссылка приезжать VFIO_SET_CONTAINER да Продолжение серии, в сопроводительном письме есть ссылка. существоватьвнутренний,совместимость API использоватьобычноиз IOAS объект, связанный с vfio Такой же,существоватьсоединять Первыйиндивидуальныйоборудованиечасавтоматическийраспространять。 пользовательское пространствовозвращаться Можеткиспользовать IOMMU_VFIO_IOAS ioctl прямой Запросилинастраиватьэтот IOAS объект. Это позволяет смешивать и сопоставлять только новые iommufd Функционален, пока еще пользуюсь VFIO Сопоставление/отмена сопоставления стилей ioctl。 虽Ранэтотногикдействовать qemu, но у него есть некоторые отличия: - Ограничения ресурсов зависят от памяти cgroup Приходить限制пользовательское пространство Можеткосуществлятьиздействовать,Вместо того, чтобы да параметры модуля dma_entry_limit。 - VFIO P2P Не реализовано. vfio из DMABUF патч да iommufd импортный специальный DMABUF из РЕШЕНИЕ из СТАРТ. Это дадля позволяет избежать дальнейшего распространения follow_pfn() Контрольный вопрос. - Еще не законченопопарнопедантичныйсовместимостьдеталь(Например errnos и т.д.) из Комплексный обзор - powerpc SPAPR опущено, поскольку для оно не связано с iommu_domain рамка. кажется правильным SPAPR из Интерес мало, потому что в настоящее время он существует v6.1-rc1 не работает в . их необходимо преобразовать в iommu Структура подсистемы может быть использована iommfd。 к下Внутри容Нетвстречаодеяло Реальностьсейчас,наснадеяться Воляэтоихот VFIO type1 Удалить в: - Программный доступ «Грязное отслеживание». 正如просить职信середина Местообсуждатьиз,этот Волясуществовать VFIO завершено в
                ioas = iommufd_object_alloc(ictx, ioas, IOMMUFD_OBJ_IOAS)
                iopt_init_table(&ioas->iopt) -> iommufd: Предоставить IOVA приезжать PFN Сопоставление структуры данных Да IOAS Остальная структура данных. Укажите имя для io_pagetable из объекта, на который указывает iopt_pages из iopt_areas к И зеркало IOVA приезжать PFN Картирование iommu_domains Состав списка. Топда iopt_areas из Простое дерево интервалов, показывающее IOVA приезжать iopt_pages из картографии. xarray Список доменов отслеживания. на на основе Дополнительно из домена,житьсуществоватьобластьизминимальное выравнивание(Можетможет быть меньше, чем PAGE_SIZE)、Не могущий Картированиебронировать IOVA издерево интерваловкивсегда Может Картированиепозволять IOVA из IOVA。 Концепция «доступ» относится к изда, аналогичному VFIO mdev все, этодоступно IOVA ииспользовать“struct page *"Неси основе CPU издоступ。 Внешний API, API соответствовать IOCTL Интерфейс имеет дополнительные требования к полям сопоставления/отмены сопоставления. API Обеспечивает примитив «копировать» путем повторного использования. iopt_pages, существование отличается от существующего отображения из IOAS Создайте новый в IOVA картографирование. Дапо обеспечивает одиночное крепление базового механизма. Целью его разработки является издапод сопровождение процесса предварительной регистрации, в ходе которого пользовательское пространство Воля Установка одногоиндивидуальный没иметьдоменизвиртуальный IOAS,картографированиеприезжать Памятьсередина,Ранназад Учреждать Волявсе PFN зафиксированныйприезжать xarray Среднее разрешение доступа. Ранназад,Можеткиспользоватькопироватьсуществовать Неттакой жеиз IOAS Создать новый в IOVA отобразить и добавить iommu_domains。 копироватьназад,Воляот xarray Читать в PFN и Воля Чтокартографированиеприезжать iommu_domains середина,отиизбегатьлюбой pin_user_pages() накладные расходы
                    iopt->area_itree = RB_ROOT_CACHED
                    iopt->allowed_itree = RB_ROOT_CACHED
                    iopt->reserved_itree = RB_ROOT_CACHED
                    xa_init_flags(&iopt->domains, XA_FLAGS_ACCOUNT)
                    xa_init_flags(&iopt->access_list, XA_FLAGS_ALLOC)
                INIT_LIST_HEAD(&ioas->hwpt_list) -> iommufd:добавить водининдивидуальный Объект таблицы страниц оборудования,hw_pagetable объект Волявнутреннийструктура iommu_domain 暴露Даватьпользовательское пространство。 когда-нибудь DMA оборудованиесоединятьприезжать IOAS кпроходить iommu управление водителем io таблица страницчас,нуждаться iommu_domain。 для с VFIO Совместимо, когда DMA оборудованиесоединятьприезжать IOAS будет автоматически создан, когда hw_pagetable。 еслисовместимыйиз iommu_domain Если существование уже сохранено, оно будет связано с ним hw_pagetable Воля для аксессуаров. существоватьпервыйизрядсередина,hw_pagetable Объект не существует iommufd uAPI。 Следующий патч предусмотрен для драйверов из IO Добавление таблицы страниц API, который позволяет водителям принимать IOAS или hw_pagetable ID,ипозволятьводить машинупрограммавозвращатьсяот IOAS Автоматически выбирать из hw_pagetable ID。 ожидать Водитель будетпроходить Что Собственныйиз FD поставлять uAPI,к Воля Чтооборудованиедополнительныйприезжать iommufd。 этотпозволятьпользовательское пространство Понятноразвязатьоборудованиеприезжать iommu_domains изMap и переопределить автоматические соединения. будущееизаппаратное обеспечениеидентификацияинтерфейс Воляпозволятьпользовательское пространствоиспользовать带иметь IOMMU Специфические параметры драйвера iommu_domains создавать hw_pagetable объект. Долженинфраструктура Воляпозволять Воля Этидомен Связьприезжать IOAS иоборудование
            iommufd_object_finalize -> позволятьиволосыдоступ Долженобъект,один В противном случаеодининдивидуальныйнить Можетксмотретьприезжать Долженобъектуказатель,Сразу Можетк Предотвратить разрушение объекта。 Кромеособенныйизтолько Ядрообъект Из外,没иметь Ядрометод Можетк Может Приказ об уничтожении землииндивидуальныйобъект. потому чтоэтот,всесоздаватьобъектиз API Вседолжениспользовать iommufd_object_abort() Приходить处理ошибка,иитолькосуществоватьобъектсоздавать Нетвстречанеудачачас Просто позвони iommufd_object_finalize()
                old = xa_store(&ictx->objects, obj->id, obj, GFP_KERNEL)
    vfio_group_ioctl_unset_container
        vfio_group_detach_container
            driver->ops->detach_group(container->iommu_data,

Пример кода VFIO

Язык кода:javascript
копировать
# vfio code demo:
int container, group, device, i;
struct vfio_group_status group_status =
                                { .argsz = sizeof(group_status) };
struct vfio_iommu_type1_info iommu_info = { .argsz = sizeof(iommu_info) };
struct vfio_iommu_type1_dma_map dma_map = { .argsz = sizeof(dma_map) };
struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
​
/* Create a new container */
container = open("/dev/vfio/vfio", O_RDWR);
​
if (ioctl(container, VFIO_GET_API_VERSION) != VFIO_API_VERSION)
        /* Unknown API version */
​
if (!ioctl(container, VFIO_CHECK_EXTENSION, VFIO_TYPE1_IOMMU))
        /* Doesn't support the IOMMU driver we want. */
​
/* Open the group */
group = open("/dev/vfio/26", O_RDWR);
​
/* Test the group is viable and available */
ioctl(group, VFIO_GROUP_GET_STATUS, &group_status);
​
if (!(group_status.flags & VFIO_GROUP_FLAGS_VIABLE))
        /* Group is not viable (ie, not all devices bound for vfio) */
​
/* Add the group to the container */
ioctl(group, VFIO_GROUP_SET_CONTAINER, &container);
​
/* Enable the IOMMU model we want */
ioctl(container, VFIO_SET_IOMMU, VFIO_TYPE1_IOMMU);
​
/* Get addition IOMMU info */
ioctl(container, VFIO_IOMMU_GET_INFO, &iommu_info);
​
/* Allocate some space and setup a DMA mapping */
dma_map.vaddr = mmap(0, 1024 * 1024, PROT_READ | PROT_WRITE,
                     MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
dma_map.size = 1024 * 1024;
dma_map.iova = 0; /* 1MB starting at 0x0 from device view */
dma_map.flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE;
​
ioctl(container, VFIO_IOMMU_MAP_DMA, &dma_map);
​
/* Get a file descriptor for the device */
device = ioctl(group, VFIO_GROUP_GET_DEVICE_FD, "0000:06:0d.0");
​
/* Test and setup the device */
ioctl(device, VFIO_DEVICE_GET_INFO, &device_info);
​
for (i = 0; i < device_info.num_regions; i++) {
        struct vfio_region_info reg = { .argsz = sizeof(reg) };
​
        reg.index = i;
​
        ioctl(device, VFIO_DEVICE_GET_REGION_INFO, &reg);
​
        /* Setup mappings... read/write offsets, mmaps
         * For PCI devices, config space is a region */
}
​
for (i = 0; i < device_info.num_irqs; i++) {
        struct vfio_irq_info irq = { .argsz = sizeof(irq) };
​
        irq.index = i;
​
        ioctl(device, VFIO_DEVICE_GET_IRQ_INFO, &irq);
​
        /* Setup IRQs... eventfds, VFIO_DEVICE_SET_IRQS */
}
​
/* Gratuitous device reset and go... */
ioctl(device, VFIO_DEVICE_RESET);
​
​
struct vfio_device_bind_iommufd bind = {
        .argsz = sizeof(bind),
        .flags = 0,
};
struct iommu_ioas_alloc alloc_data  = {
        .size = sizeof(alloc_data),
        .flags = 0,
};
struct vfio_device_attach_iommufd_pt attach_data = {
        .argsz = sizeof(attach_data),
        .flags = 0,
};
struct iommu_ioas_map map = {
        .size = sizeof(map),
        .flags = IOMMU_IOAS_MAP_READABLE |
                 IOMMU_IOAS_MAP_WRITEABLE |
                 IOMMU_IOAS_MAP_FIXED_IOVA,
        .__reserved = 0,
};
​
iommufd = open("/dev/iommu", O_RDWR);
​
bind.iommufd = iommufd;
ioctl(cdev_fd, VFIO_DEVICE_BIND_IOMMUFD, &bind);
​
ioctl(iommufd, IOMMU_IOAS_ALLOC, &alloc_data);
attach_data.pt_id = alloc_data.out_ioas_id;
ioctl(cdev_fd, VFIO_DEVICE_ATTACH_IOMMUFD_PT, &attach_data);
​
/* Allocate some space and setup a DMA mapping */
map.user_va = (int64_t)mmap(0, 1024 * 1024, PROT_READ | PROT_WRITE,
                            MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
map.iova = 0; /* 1MB starting at 0x0 from device view */
map.length = 1024 * 1024;
map.ioas_id = alloc_data.out_ioas_id;;
​
ioctl(iommufd, IOMMU_IOAS_MAP, &map);
​
/* Other device operations as stated in "VFIO Usage Example" */

DPDK использует VFIO

Язык кода:javascript
копировать
helloworld -> examples/helloworld/main.c
main(int argc, char **argv)
rte_eal_init(int argc, char **argv)
    rte_eal_get_configuration
    eal_get_internal_configuration
    rte_cpu_is_supported
        RTE_COMPILE_TIME_CPUFLAGS -> #define RTE_COMPILE_TIME_CPUFLAGS RTE_CPUFLAG_SSE,RTE_CPUFLAG_SSE2,RTE_CPUFLAG_SSE3,RTE_CPUFLAG_SSSE3,RTE_CPUFLAG_SSE4_1,RTE_CPUFLAG_SSE4_2,RTE_CPUFLAG_AES,RTE_CPUFLAG_AVX,RTE_CPUFLAG_AVX2,RTE_CPUFLAG_AVX512BW,RTE_CPUFLAG_AVX512CD,RTE_CPUFLAG_AVX512DQ,RTE_CPUFLAG_AVX512F,RTE_CPUFLAG_AVX512VL,RTE_CPUFLAG_PCLMULQDQ,RTE_CPUFLAG_RDRAND,RTE_CPUFLAG_RDSEED
        rte_cpu_get_flag_enabled
            rte_cpu_feature_table
            __get_cpuid_max(feat->leaf & 0x80000000, NULL)
            const struct feature_entry rte_cpu_feature_table[]
    __atomic_compare_exchange_n
    eal_reset_internal_config
        internal_cfg->iova_mode = RTE_IOVA_DC -> default memory mode
    eal_log_level_parse -> set_log demo: ./app/test-pmd --log-level='pmd\.i40e.*,8' -> Теперь существование настроено правильно --log-level=7 не будет печатать из rte_eal_cpu_init() Рутины и сообщения
    eal_save_args -> Connecting to /var/run/dpdk/rte/dpdk_telemetry.v2
        handle_eal_info_request
            rte_tel_data_start_array
            rte_tel_data_add_array_string
    rte_eal_cpu_init -> eal:НетхотетьверноCPUчувство обнаруженияприезжатьпаника,Возможно, не существует способа изящно восстановиться,Но да должен уведомить приложение о том, что произошел сбой,Вместо того, чтобы даполностьюсерединаконец。 Это позволяет пользователям продолжить использование решений типа «медленный путь». После внесения этого изменения EAL CPU NUMA Шаги анализа узла больше не выдаются. rte_panic。 Это связано с rte_eal_init Код в коде согласован. Код ожидает возврата кода ошибки в случае сбоя. -> использовать физический и логический процессор из конфигурации количества населения Эта функцияда EAL Специальный из. анализировать /proc/cpuinfo к Получить количество физических и логических процессоров на компьютере, /sys/devices/system/cpu
        eal_cpu_socket_id -> NUMA_NODE_PATH "/sys/devices/system/node"
        eal_cpu_detected -> еал: без кэширования lcore Статус обнаружения, мы обслуживаем только ядро ​​и -c/-l Опция из контролирует это состояние в пути использования. использовать--lcores , значение не обновляется. существоватьнуждатьсяизместоиспользоватьвнутреннийпомощник    eal_parse_args
        while ((opt = getopt_long
        eal_parse_common_option
            -l и -c Опция Да Выбрать DPDK использовать ядро ​​двумя способами. Они имеют разные форматы, но одинаковы для выбранного ядра. использоватьсередина间数Группа Воляидентификацияизанализировать Чек и общийизодин Отдельные проверки согласованности。 анализироватьфункциясейчассуществовать Сосредоточьтесь на доставке валидацииизнить,и Нетосуществлять Чтоондействовать。 мы можемк Отчетвсеневерныйизосновной индекс,и Неттолькотолькода Первыйиндивидуальныйошибка。 существоватьошибкасообщение журналасередина,Когда основной список не является смежным,Воля [0, cfg->lcore_count - 1] Отчет для допустимого диапазона до ошибки из
            eal_service_cores_parsed
            rte_eal_parse_coremask
            update_lcore_config
            -n -> conf->force_nchannel = atoi(optarg)
        eal_create_runtime_dir -> eal:Прямо сейчасделать Нетиспользовать Поделиться данными,такжесоздаватьбегатьчас Оглавление,При работе без необходимости многопроцессности и DPDKиспользовать флаг «no-shconf».,Библиотека телеметрии все ещенуждатьсяодининдивидуальныйбегатьчас Оглавление Приходитьместодля телеметриисоединятьизunixрозетка。 потому чтоэтот,мы можемк Изменить кодкпытатьсясоздавать Оглавление,Вместо того, чтобы дасуществоватьнастраиватьэтотлоготипчас Нетсоздавать Оглавление,ноеслинеудачано Нетвстреча出错。 еслиуспех,затем телеметрия Воля Можетиспользовать,ноеслинеудача,DPDK из Чтоостаток Волясуществоватьнет телеметрииизбежать под。 этотубеждаться Понятно“Памятьсередина”логотип Воляпозволять DPDK Запускать, даже если вся файловая система доступна только для чтения
            /var/run/dpdk
            eal_get_hugefile_prefix
            eal_set_runtime_dir
                strlcpy(runtime_dir, run_dir, PATH_MAX) 
        eal_adjust_config
            eal_auto_detect_cores -> eal: ограничить автоматическое обнаружение ядра,когда еще нетобозначениек Следующий вариантчас,этот патчиспользовать pthread_getaffinity_np() Чтобы сузить основную сферу использования: * coremask (-c) * corelist (-l) * и coremap (--lcores) Сделай это patchизглазиздасуществоватьконтейнер Развертывание в средеDPDKприложениечасупущение Этиосновной相关选项,кудобныйпользовательсуществоватьразвиватьприложениечас Нетнуждаться Определить основные параметры, связанные с。 Вместо этого, когда приложение развертывается в контейнере, пожалуйста, cpu-set Приходить限制Можетксуществовать Долженконтейнер Реальностьпример Внутрииспользовать Какое ядро。 Приложения DPDK в контейнере полагаются на этот механизм автоматического обнаружения только для опроса потоков. Уведомление:Доиметь部分пользовательиспользоватьизоляцияCPU,по умолчанию Можеткисключать。 пожалуйстадобавить в Набор задач ожидает прихода команды.использовать Этиосновной。 Тестовый пример: $taskset 0xc0000 ./examples/helloworld/build/helloworld -m 1024
                rte_thread_get_affinity_by_id
            eal_proc_type_detect
            main_lcore_parsed -> eal: переименовать lcore masterиslave,Воляmaster lcore заменяет дляmain lcore,и Воляslave lcore заменяет forworker lcore。 бронировать旧функцияи Макрос,но Воляэтоих标记длясуществоватьэта версиясередина已弃использовать。 Параметр командной строки «--master-lcore» также устарел, любой из них выведет предупреждение, а использование «--main-lcore» будет заменено на для использовать.
            compute_ctrl_threads_cpuset -> eal: Ограничить запуск потока управления CPU Родство, существование не принадлежит eal coremask генерируется на любом контенте ctrl Поток в системуиз Чтоостаток Приходить说Нет Слишком вежливо,особенно Чтодакогда ты очень осторожениспользоватьинструмент Воляпроцесс исправленсуществовать cpu Доступность ресурсов Например, набор задач (linux)/cpuset (freebsd). мы не представляем еще один eal Варианты контроля, которые существуют cpu начальствосоздавать Эти ctrl нить,идакзапускать cpu родственникишедеврдляссылкаиот Удалить в eal coremask。 если ничего не осталось cpu, то по умолчанию мы используем основное ядро. cpuset существовать init рассчитывается один раз, а затем исходное cpu Актуальность потеряется. Введен макрос RTE_CPU_AND для абстрагирования различий между соответствующими макросами Linux и FreeBSD. -> taskset -c 7  ./master/app/testpmd --master-lcore 0 --lcores '(0,7)@(7,4,5)'  --no-huge --no-pci -m 512 -- -i --total-num-mbufs=2048
                RTE_CPU_AND
        eal_check_common_options -> sanity checks -> eal: разложить проверки работоспособности опций, устраняя необходимость в повторных проверках общих опций. для Опции -c и -m Установка одногонекоторыйлоготипк Упрощение проверки
            Main lcore
            mbuf_pool ...
        eal_usage
            eal_common_usage -> help
    eal_plugins_init -> eal: существоватьоборудованиеанализировать Звонил раньшеплагин инициализация, по умолчанию eal_init кодовый вызов 0. eal_plugins_init 1. eal_option_device_parse 2. rte_bus_scan IOVA Отправить: cf408c224 скучать Понятносуществовать eal_option_device_parse、rte_bus_scan Звонил раньше eal_plugins_init киподпредставлятьизобщиймодельвозвращаться:использовать CONFIG_RTE_BUILD_SHARED_LIB=y: 'net_vhost 0 ,iface=/tmp/vhost-user2' -d ./install/lib/librte_pmd_vhost.so -- --portmask=1 --disable-hw-vlan -i --rxq=1 --txq=1 --nb -cores=1 --eth-peer=0,52:54:00:11:22:12 EAL: обнаружить местонахождение 4 индивидуальный lcore ошибка:Не могущийанализироватьоборудование“net_vhost0”EAL:Не могущийанализироватьоборудование“net_vhost0,iface” =/tmp/vhost-user2' main() Паника произошла: Невозможно инициализировать EAL
        еслинас Нетдастатическая ссылка,пожалуйстадобавить впо умолчаниюводить машинупрограмманагрузкапуть(еслиэтоделатьдля Оглавлениежитьсуществовать)。 (существовать EAL начальствоиспользовать带иметь NOLOAD логотип из dlopen,если EAL общий Библиотеки еще нетнагрузка,то есть это дастатическая ссылкаиз,Потом Воля возвращается NULL
        is_shared_build
            #define EAL_SO "librte_eal.so
            handle = dlopen(soname, RTLD_LAZY | RTLD_NOLOAD)
        eal_plugin_add -> eal:поддерживатьот Оглавлениенагрузкаводить машинупрограмма,добавить в Справа Оглавлениеизподдерживатьделатьдля -d изпараметр,кот Давать定Оглавлениенагрузкавсеводить машинупрограмма。 также,Можетксуществовать Строитьчас Конфигурациясерединанастраиватьпо умолчаниюводить машинупрограмма Оглавление,существуют В этом случае,существоватьинициализация EAL час Волявсегдаиспользовать Должен Оглавление。 ииспользовать -d Руководствонагрузкаодининдивидуальныйводить машинупрограмма相比,Это значительно упрощает настройку разделяемой библиотеки.,ипозволятьволосы ХОРОШО版Учреждатьодининдивидуальный Встроенныйводить машинупрограмма Оглавление,кудобныйи Нет. 3 Полная интеграция с драйверами вечеринок и многим другим.
            -> #define RTE_EAL_PMD_PATH "/usr/local/lib/x86_64-linux-gnu/dpdk/pmds-23.1"
        TAILQ_FOREACH
            eal_plugindir_init
            eal_dlopen
    rte_config_init
        rte_eal_config_create
            mem_cfg_fd = open(pathname, O_RDWR | O_CREAT, 0600)
            retval = ftruncate(mem_cfg_fd, cfg_len)
            retval = fcntl(mem_cfg_fd, F_SETLK, &wr_lock)
            eal_get_virtual_area -> eal:ремонтмногопроцессиз Память Конфигурацияраспространять,в настоящий момент,Память Конфигурация Волясуществовать Нетиспользоватьвиртуальныйобластьсдержанныйинфраструктураиз Состояние下进ХОРОШОкартографирование,этотиметь в видуэто Воляодеялокартографированиеприезжатьпроизвольный Кусочекнабор。 Это может привести к сбою конфигурации сопоставленного общего ресурса в существующем рабочем процессе из-за PCI 白名одинпараметрсуществоватьхозяинпроцесс已распространятьобщий Память Конфигурацияизкосмоссерединараспространять Память。 проходитьиспользоватьвиртуальныйобластьсдержанный Приходитьдля Память Конфигурациясдержанныйкосмос Приходитьремонтэтот вопрос,отиизбегать Долженвопросибронироватьобщий Конфигурация(надеюсь на это)далеко не что-то нормальноеиз Памятьраспространять
                rte_mem_page_size -> eal: введение оболочки управления памятью, представление независимой от операционной системы оболочки для операций управления памятью между DPDK, особенно в публичном коде дасуществоватьEALиз: * rte_mem_map() * rte_mem_unmap() * rte_mem_page_size() * rte_mem_lock() Windows использует другой API для сопоставления памяти и сохраняю, пока Unices Память резервируется посредством сопоставления. представлять EAL частная функциякподдерживатьобщественный кодсерединаиз Памятьсдержанный: * eal_mem_reserve() * eal_mem_free() * eal_mem_set_dump() Соответствие обертке ограничивается DPDK Задача из POSIX семантики, но их подписи намеренно связаны с POSIX знак Неттакой же,кболее Безопасностьи Более выразительныйсейчассила。 Новый символ да внутренний из. Поскольку упаковка очень тонкая, специального ухода не требуется.
                eal_get_baseaddr -> Linux Ядроиспользоватьодининдивидуальныйочень высокийизадресделатьдля Служить mmap Звонок с начального адреса. еслижитьсуществовать Устранение ограниченийии IOVA модельдля ВА, то стартовый адрес может быть слишком велик для этого оборудования. Да,Можетксуществоватьпроцессвиртуальныйадрескосмоссерединаиспользоватьнижеизадрес,потому чтодля 64 Есть много свободного места. Текущие известные ограничения да 39 или 40 Кусочек. Воляначинатьадреснастраиватьдля 4GB значит есть 508GB или 1020GB Используется для отображения доступных больших страниц. Этого, вероятно, достаточно для большинства систем, хотя с учетом ограничений изоборудование следует называть rte_mem_check_dma_mask кубеждатьсявсе Память Всесуществоватьподдерживатьизв пределах досягаемости
                    return 0x7000000000ULL -> 28GB = int("0x700000000", 16)/(1<<30)
                    or
                    return 0x100000000ULL -> 4GB
                eal_mem_reserve
                    int sys_flags = MAP_PRIVATE | MAP_ANONYMOUS;
                    sys_flags |= MAP_HUGETLB
                     mem_map(requested_addr, size, PROT_NONE, sys_flags, -1, 0)
                RTE_PTR_ALIGN
            mapped_mem_cfg_addr = mmap(rte_mem_cfg_addr,
            cfg_len_aligned, PROT_READ | PROT_WRITE,
            MAP_SHARED | MAP_FIXED, mem_cfg_fd, 0);
        eal_mcfg_update_from_internal
            mcfg->single_file_segments = internal_conf->single_file_segments
        rte_eal_config_attach
        eal_mcfg_wait_complete
        __rte_mp_enable
    rte_eal_using_phys_addrs -> eal:в соответствии сPAМожетиспользовать性计算IOVAмодель,в настоящий момент,если Выбор автобусаIOVAделатьдляPA,Тогда существования не хватает физического адреса издоступа,Инициализация памяти может завершиться неудачно. Для обычных пользователей,Может быть трудно понять, что происходит не так,потому чтодля Дапо умолчанию ХОРОШОдля。 Проверяя доступность физического адреса, существует eal init середина尽早волосысейчасэтот种Состояние,или ВОЗсуществоватьне выражен ясноиз Предпочтениечасвыбирать IOVA。 Код автобуса изменен,кудобныйэтосуществовать Нетзабота IOVA модель отчета и пусть eal init Решать. существоватьLinuxРеальностьсейчассередина,Перепроектирование rte_eal_using_phys_addrs(),кудобный Можетк更早地调использоватьэто,но仍Ранизбегатьиrte_mem_virt2phys()изциклическая зависимость。 существовать FreeBSD В реализации rte_eal_using_phys_addrs() всегда возвращайся false, поэтому часть обнаружения остается без изменений. есликомпилировать Понятноlibrte_kniинагрузка ПонятноKNI kmod, - еслиавтобуспожалуйстапроситьVA,еслифизикаадрес Можетиспользовать,затем обязательно использоватьPA,Точно так же, как то, что мы делали раньше,- В противном случае,ВоляiovaбронироватьдляVA,KNI initнемногоназад Волянеудача
        rte_eal_has_hugepages -> no_hugetlbfs -> default use hugepage
        rte_mem_virt2phy
            return RTE_BAD_IOVA
    rte_bus_get_iommu_class
    if (internal_conf->no_hugetlbfs == 0)
        hugepage_info_init
        create_shared_memory
            map_sharee_memory
    ...
    RTE_LOG(DEBUG, EAL, "IOMMU is not available, selecting IOVA as PA mode.\n")
    rte_eal_get_configuration
    eal_hugepage_info_init
    eal_log_init
    rte_eal_vfio_setup // DPDK установил VFIO
    rte_eal_memzone_init
    eal_hugedirs_unlock
    rte_eal_malloc_heap_init
    rte_eal_tailqs_init
    rte_eal_timer_init
    eal_check_mem_on_local_socket
    rte_thread_set_affinity_by_id
    eal_thread_dump_current_affinity
    RTE_LCORE_FOREACH_WORKER(i)
        eal_worker_thread_create(i)
    rte_eal_mp_remote_launch sync_func
    rte_eal_mp_wait_lcore
    rte_service_init
    if (rte_bus_probe())
    rte_vfio_is_enabled
    rte_service_start_with_defaults
    eal_clean_runtime_dir
    rte_log_register_type_and_pick_level
    rte_telemetry_init
    eal_mcfg_complete
rte_eal_remote_launch(lcore_hello, NULL, lcore_id)
lcore_hello
​
...
rte_eal_vfio_setup
    rte_vfio_enable("vfio")
        for (i = 0; i < VFIO_MAX_CONTAINERS; i++) -> 64
            for (j = 0; j < VFIO_MAX_GROUPS; j++) -> 64
        vfio_available = rte_eal_check_module(modname) -> vfio:избегатьсуществовать Модуль ненагрузкачасдавать возможность,когда Ядроподдерживать vfio Функция не загружена vfio модульчас,пример Ченг все ещепытаться Открытьконтейнерк Получить файлописывать。 этотдействовать Нет Безопасность,Конечно, я буду взимать платуприезжатьошибкаинформация: EAL: Detected 40 lcore(s) EAL: unsupported IOMMU type! EAL: VFIO Поддержка не может быть инициализирована EAL: настраивать Память...этот Может能встречапозволятьпользователь Чувствоприезжатьозадаченный,этотиндивидуальныйпластырьиспользоватьдомашнее хозяйство более разумно、более гладкий
        /sys/module/vfio
        default_vfio_cfg->vfio_container_fd = rte_vfio_get_container_fd()
            open(VFIO_CONTAINER_PATH, O_RDWR) -> open /dev/vfio/vfio
        or vfio_get_default_container_fd
        static const struct vfio_iommu_type iommu_types[]

ссылка

Linux kernel vfio, https://docs.kernel.org/driver-api/vfio.html

IOMMUFD, https://docs.kernel.org/userspace-api/iommufd.html

VFIOвиртуализациясерединамеждуоборудование, https://docs.kernel.org/driver-api/vfio-mediated-device.html

vfio-pci Критерии приемлемости драйверов для оборудования (модуль vfio-pci-core), https://docs.kernel.org/driver-api/vfio-pci-device-specific-driver-acceptance.html

Анализ драйвера VFIO: https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2019/08/21/vfio-driver-analysis

Введение в ВФИО: https://insujang.github.io/2017-04-27/introduction-to-vfio/

Подробное объяснение VFIO: https://zhuanlan.zhihu.com/p/651145174

RedHatКрасная шляпа Введение в ВФИО: https://awilliam.github.io/presentations/KVM-Forum-2016/#/1

Анализ кода VFIO (7) Создание экземпляра VFIO в QEMU 2: https://blog.csdn.net/flyingnosky/article/details/123748011

Intel Технология виртуализации VT-d и VFIO: https://wiki.qemu.org/Features/VT-d

Конференция сантехников Linux: https://lpc.events/blog/current/index.php/2023/08/21/vfio-iommu-pci-mc-cfp/

Сяобин (ssbandjl)

блог: https://cloud.tencent.com/developer/user/5060293/articles | https://logread.cn | https://blog.csdn.net/ssbandjl | https://www.zhihu.com/people/ssbandjl/posts | https://chattoyou.cn

столбец ДПУ

https://cloud.tencent.com/developer/column/101987

Технические друзья: Добро пожаловать в DPU/SmartNIC/Uninstall/Network.,хранилищеускоряться/Безопасностьизоляцияждатьтехнология Чувство兴趣из Друзья присоединяйтесьТехнология ДПУКоммуникационная группа

boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose