Переназначение DMA IOMMU

На этой странице описывается функция переназначивания DMA IOMMU (IOMMUv2), появилась в Windows 11 22H2 (WDDM 3.0). Сведения об изоляции GPU IOMMU до WDDM 3.0 см. в разделе Изоляция GPU на основе IOMMU .

Общие сведения

До WDDM 3.0 Dxgkrnl поддерживал только изоляцию IOMMU до физического сопоставления 1:1, то есть логические страницы, к которым обращается GPU, были переведены в один и тот же физический номер страницы. Переназначение DMA IOMMU позволяет GPU получать доступ к памяти через логические адреса, которые больше не сопоставляются 1:1. Вместо этого Dxgkrnl может предоставлять логически смежные диапазоны адресов.

Dxgkrnl накладывает ограничение на GPU: чтобы устройство запускалось, GPU должны иметь доступ ко всей физической памяти. Если максимальный видимый адрес GPU не превышает самый высокий физический адрес, установленный в системе, Dxgkrnl не сможет инициализация адаптера. Предстоящие серверы и рабочие станции высокого класса можно настроить с более чем 1 ТБ памяти, которая пересекает общее ограничение 40-разрядного адресного пространства для многих GPU. Переназначение DMA используется в качестве механизма, позволяющего графическим процессорам работать в этой среде.

Во время запуска Dxgkrnl определяет, требуется ли логическое переназначение, сравнивая самый доступный физический адрес устройства с памятью, установленной в системе. При необходимости переназначение DMA используется для сопоставления диапазона логических адресов, который находится в пределах видимых границ GPU, с любой физической памятью в системе. Например, если gpu имеет ограничение в 1 ТБ, dxgkrnl выделяет логические адреса из [0, 1 ТБ), которые затем могут сопоставляться с любой физической памятью в системе через IOMMU.

Логические и физические адаптеры

Dxgkrnl различает концепцию логического и физического адаптера. Физический адаптер представляет собой отдельное аппаратное устройство, которое может быть связано с другими устройствами в цепочке LDA. Логический адаптер представляет один или несколько связанных физических адаптеров.

Для каждого логического адаптера создается один домен DMA IOMMU, который присоединяется ко всем связанным физическим адаптерам. Таким образом, все физические адаптеры используют один домен и одинаковое представление физической памяти.

Встроенная и дискретная поддержка GPU

Так как переназначение DMA IOMMU имеет мало ценности для интегрированных GPU, которые по определению уже должны быть разработаны для доступа ко всей физической памяти в системе, реализация поддержки интегрированных частей является необязательной, но рекомендуется.

Дискретные GPU должны поддерживать переназначение DMA IOMMU, что является обязательным требованием для сертификации WDDM 3.0.

Изменения DDI

Для поддержки переназначивания DMA IOMMU были внесены следующие изменения.

Возможности драйвера

Для поддержки линейного переназначения требуется два набора пределов драйвера:

  • Драйвер должен сообщить Dxgkrnl об ограничениях физической памяти; т. е. о самом высоком видимом физическом адресе через DXGKQAITYPE_PHYSICAL_MEMORY_CAPS и связанной DXGK_PHYSICAL_MEMORY_CAPS структуре.
  • Драйвер должен указать поддержку линейного переназначения IOMMU через DXGKQAITYPE_IOMMU_CAPS и связанную DXGK_IOMMU_CAPS структуру. Указывая поддержку, драйвер указывает, что все DDIs, описанные далее, поддерживаются и используются.

Оба этих ограничения должны быть предоставлены до того, как Dxgkrnl запустит устройство через DXGKDDI_START_DEVICE чтобы устройство можно было создать и подключить к домену IOMMU до получения доступа к любой памяти. Линейное переназначение можно выполнить, только если устройство не ссылается на существующую физическую память.

Монопольный доступ

Подключение и отсоединение домена IOMMU выполняется очень быстро, но, тем не менее, в настоящее время не является атомарным. Это означает, что транзакция, выданная через PCIe, не гарантируется правильное преобразование при переключении на домен IOMMU с различными сопоставлениями.

Чтобы справиться с этой ситуацией, начиная с Windows 10 версии 1803 (WDDM 2.4), KMD должен реализовать следующую пару DDI для вызова Dxgkrnl:

  • DxgkDdiBeginExclusiveAccess вызывается, чтобы уведомить KMD о том, что ожидается переключение домена IOMMU.
  • DxgkDdiEndExclusiveAccess вызывается после завершения переключения домена IOMMU.

Драйвер должен гарантировать, что его оборудование не работает при каждом переключении устройства на новый домен IOMMU. То есть драйвер должен убедиться, что он не считывает и не записывает данные в системную память с устройства между этими двумя вызовами.

Между этими двумя вызовами Dxgkrnl дает следующие гарантии:

  • Планировщик приостанавливается. Все активные рабочие нагрузки сбрасываются, а новые рабочие нагрузки не отправляются или не планируются на оборудовании.
  • Другие вызовы DDI не выполняются.

В рамках этих вызовов драйвер может отключить и подавить прерывания (включая прерывания Vsync) во время монопольного доступа, даже без явного уведомления от ОС.

Списки дескрипторов адресов

Для поддержки физического и логического режимов доступа и простого переключения между двумя режимами во время выполнения Dxgkrnl предоставляет DXGK_ADL структуру, описывающую список дескрипторов адресов (ADL). Эта структура данных похожа на MDL, но описывает массив страниц, который может быть физическим или логическим. Так как эти страницы могут быть логическими, адреса, описанные в ADL, не могут быть сопоставлены с виртуальным адресом для прямого доступа к ЦП.

операция DXGK_OPERATION_MAP_APERTURE_SEGMENT2 для DxgkddiBuildpagingbuffer

VidMm предоставляет DXGK_OPERATION_MAP_APERTURE_SEGMENT2 режим буфера подкачки для сопоставления памяти с сегментом диафрагмы, так как в предыдущей версии используется MDL, несовместимый с логическими адресами. Обратный вызов DxgkddiBuildpagingbuffer драйверов WDDM 3.0, которые поддерживают логическое переназначение адресов, принимают вызовы в режиме DXGK_OPERATION_MAP_APERTURE_SEGMENT2 и больше не принимают вызовы в режиме исходного DXGK_OPERATION_MAP_APERTURE_SEGMENT .

Эта операция необходима для поддержки логического переназначивания DMA. Он ведет себя аналогично исходной операции, но предоставляет DXGK_ADL вместо MDL.

typedef enum _DXGK_BUILDPAGINGBUFFER_OPERATION
{
#if (DXGKDDI_INTERFACE_VERSION >= DXGKDDI_INTERFACE_VERSION_WDDM2_9)
    DXGK_OPERATION_MAP_APERTURE_SEGMENT2 = 17,
#endif //  DXGKDDI_INTERFACE_VERSION
};

// struct _DXGKARG_BUILDPAGINGBUFFER:
struct
{
    HANDLE  hDevice;
    HANDLE  hAllocation;
    UINT    SegmentId;
    SIZE_T  OffsetInPages;
    SIZE_T  NumberOfPages;
    DXGK_ADL Adl;
    DXGK_MAPAPERTUREFLAGS Flags;
    ULONG   AdlOffset;
    PVOID   CpuVisibleAddress;
} MapApertureSegment2;

Чтобы согласиться на операцию DXGK_OPERATION_MAP_APERTURE_SEGMENT2 , драйвер должен указать поддержку вызовов MapApertureSegment2 в ограничениях управления памятью:

typedef struct _DXGK_VIDMMCAPS {
  union {
    struct {
        ...
        UINT MapAperture2Supported : 1;
        ...
    }
    ...
} DXGK_VIDMMCAPS;

Ограничения DXGK_VIDMMCAPS управления памятью являются частью структуры данных DXGK_DRIVERCAPS . Драйвер не может использовать функцию переназначивания DMA (т. е. переназначение логического адреса) без этой поддержки.

Некоторым драйверам может потребоваться доступ ЦП к памяти во время вызова MapApertureSegment2 . Эта функция дополнительно предоставляется с помощью другого параметра MapApertureSegment2.CpuVisibleAddress . Этот адрес является виртуальным адресом в режиме ядра, который действителен при условии, что выделение сопоставляется с сегментом диафрагмы. То есть этот адрес будет освобожден сразу после вызова соответствующего DXGK_OPERATION_UNMAP_APERTURE_SEGMENT для того же выделения.

Этот адрес может потребоваться не для всех выделений, поэтому к флагам выделения был добавлен флаг MapApertureCpuVisible, чтобы указать, когда это необходимо.

Если mapApertureCpuVisible не указан, mapApertureSegment2.CpuVisibleAddress имеет значение NULL для операций DXGK_OPERATION_MAP_APERTURE_SEGMENT2 .

MapApertureCpuVisible является частью функциональных возможностей MapAperatureSegment2DxgkDdiBuildPufferBuffer, поэтому драйвер должен задать DXGK_VIDMMCAPS MapAperature2Supported для использования этого поля. Если параметр MapAperature2Supported не задан, но драйвер указывает MapApertureCpuVisible, вызов DxgkDdiCreateAllocation завершается ошибкой.

Кроме того, чтобы получить операцию DXGK_OPERATION_MAP_APERTURE_SEGMENT2 , драйвер должен установить флаг DXGK_ALLOCATIONINFOFLAGS_WDDM2_0 AccessedPhysically . Если параметр AccessedPhysically не задан, любое выделение, указывающее сегмент диафрагмы в поддерживаемом наборе сегментов, обновляется до неявного сегмента системной памяти, который не получает MAP_APERTURE вызовов (так как диапазоны диафрагмы для сопоставления отсутствуют).

Таким образом, чтобы правильно получить адрес ЦП для выделения системной памяти, драйвер должен установить следующие флаги и ограничения:

  • DXGK_DRIVERCAPS::MemoryManagementCaps.MapAperture2Supported = 1
  • DXGK_ALLOCATIONINFOFLAGS_WDDM2_0::MapApertureCpuVisible = 1
  • DXGK_ALLOCATIONINFOFLAGS_WDDM2_0::AccessedPhysically = 1

Для вызовов MapApertureSegment2 ADL всегда инициализируется и передается как непрерывный, если включено логическое сопоставление. Драйвер должен проверка флаги ADL, чтобы определить, является ли выделение непрерывным, и вести себя соответствующим образом.

Службы управления памятью

Существуют три основных требования к функциям управления памятью:

  1. Возможность управления физической памятью. Это может включать выделение памяти с помощью непагированных функций памяти, таких как MmAllocatePagesforMdl или MmAllocateContiguousMemory, и выгружаемых функций памяти, таких как ZwCreateSection или ZwAllocateVirtualMemory. Также требуется возможность выражения диапазонов пространства ввода-вывода.

  2. Возможность сопоставления видимого для GPU логического адреса из физической памяти. Это предоставит вызывающей объекту список логических страниц (так же, как массив PFN MDL), для доступа к которым может быть запрограммирован GPU. Вызов этих функций гарантирует, что базовые физические страницы будут заблокированы и не доступны для страниц.

  3. Возможность сопоставлять виртуальные адреса ЦП из физической памяти как в пользовательском режиме, так и в режиме ядра с указанным типом кэша (Cached и WriteCombined).

В следующей таблице перечислены DDIs и связанные с ними входные структуры, представленные для описания физического выделения памяти и сопоставления логических и виртуальных представлений. Эти DDIs представляют собой обновленный набор для замены предыдущих обратных вызовов, предоставленных драйверам для управления сопоставлениями IOMMU (DxgkCbAllocatePagesforMdl, DxgkCbAllocateContiguousMemory, DxgkCbMapMdlToIoMmu). Для драйверов WDDM 3.0, поддерживающих логическое переназначение, эти старые функции обратного вызова являются устаревшими и их нельзя использовать. Вместо этого драйвер должен использовать следующие функции обратного вызова управления памятью.

Функции обратного вызова должны вызываться по адресу IRQL <= APC_LEVEL. Начиная с версии WDDM 3.2 драйверы, вызывающие любую из этих функций, проверяются на соответствие этому требованию и проверяются ошибки, если irQL DISPATCH_LEVEL или выше.

Обратный вызов Связанная структура обратного вызова
DXGKCB_CREATEPHYSICALMEMORYOBJECT DXGKARGCB_CREATE_PHYSICAL_MEMORY_OBJECT
DXGKCB_DESTROYPHYSICALMEMORYOBJECT DXGKARGCB_DESTROY_PHYSICAL_MEMORY_OBJECT
DXGKCB_MAPPHYSICALMEMORY DXGKARGCB_MAP_PHYSICAL_MEMORY
DXGKCB_UNMAPPHYSICALMEMORY DXGKARGCB_UNMAP_PHYSICAL_MEMORY
DXGKCB_ALLOCATEADL DXGKARGCB_ALLOCATE_ADL
DXGKCB_FREEADL
DXGKCB_OPENPHYSICALMEMORYOBJECT DXGKARGCB_OPEN_PHYSICAL_MEMORY_OBJECT
DXGKCB_CLOSEPHYSICALMEMORYOBJECT DXGKARGCB_CLOSE_PHYSICAL_MEMORY_OBJECT

Изменения INF

Каждый поддерживаемый тип устройства должен добавить следующий раздел реестра и значение в соответствующий раздел INF:

[DMAr.reg]
; Add REG_DWORD 'DmaRemappingCompatible' with value of 3 
HKR,Parameters,DmaRemappingCompatible,0x00010001,```3

Это значение сообщает PnP, что устройство поддерживает переназначение DMA. Dxgkrnl и HAL затем будут координировать, чтобы определить, какой тип режима сопоставления следует использовать (переназначение, сквозная передача и т. д.).

Хотя этот раздел реестра присутствовал в более ранних версиях Windows, значение 3 уникально, начиная с Windows 10 версии 1803 (WDDM 2.4) и игнорируется в более старых сборках, которые его не поддерживают. Это позволит драйверам задать этот ключ в INF и не беспокоиться о проблемах совместимости на нижнем уровне.