Переназначка DMA IOMMU
На этой странице описывается функция повторного сопоставления IOMMU DMA (IOMMUv2), представленная в Windows 11 22H2 (WDDM 3.0). Сведения об изоляции GPU на основе IOMMU см. в статье об изоляции GPU IOMMU до WDDM 3.0.
Обзор
До WDDM 3.0 dxgkrnl поддерживает только изоляцию IOMMU до 1:1 физического перемечения, то есть логические страницы, к которым обращается GPU, были переведены на тот же физический номер страницы. Повторное сопоставление DMA IOMMU позволяет GPU получать доступ к памяти через логические адреса, которые больше не сопоставлены 1:1. Вместо этого Dxgkrnl может предоставлять логически смежные диапазоны адресов.
Dxgkrnl накладывает ограничение на GPU: графические процессоры должны иметь возможность получить доступ ко всей физической памяти, чтобы устройство было запущено. Если самый высокий видимый адрес GPU не превышает самый высокий физический адрес, установленный в системе, Dxgkrnl завершается ошибкой инициализации адаптера. Предстоящие серверы и высокопроизводительные рабочие станции можно настроить с более чем 1 ТБ памяти, которая пересекает общее 40-разрядное ограничение адресного пространства для многих GPU. Переназначка DMA используется в качестве механизма, позволяющего графическим процессорам работать в этой среде.
Во время запуска Dxgkrnl определяет, требуется ли логическое переназначение, сравнивая самый доступный физический адрес устройства с памятью, установленной в системе. Если это необходимо, DMA переназначается для сопоставления диапазона логических адресов, который находится в видимых границах GPU с любой физической памятью в системе. Например, если GPU имеет ограничение в 1 ТБ, dxgkrnl выделяет логические адреса из [0, 1 ТБ), которые затем могут сопоставить любую физическую память в системе через IOMMU.
Логические и физические адаптеры
Dxgkrnl различает концепцию логического и физического адаптера. Физический адаптер представляет отдельное аппаратное устройство, которое может быть связано с другими устройствами в цепочке LDA. Логический адаптер представляет один или несколько связанных физических адаптеров.
Для каждого логического адаптера создается один домен DMA IOMMU и подключен ко всем физическим адаптерам, связанным. Таким образом, все физические адаптеры используют один и тот же домен и то же представление физической памяти.
Встроенная и дискретная поддержка GPU
Так как переназначка DMA IOMMU предлагает малое значение для интегрированных GPU, которые должны, по определению, уже предназначены для доступа ко всей физической памяти в системе, реализация поддержки интегрированных частей является необязательным, но рекомендуется.
Дискретные графические процессоры должны поддерживать повторное сопоставление DMA IOMMU, что является обязательным требованием для сертификации WDDM 3.0.
Изменения DDI
Следующие изменения DDI были внесены для поддержки повторного сопоставления IOMMU DMA.
Возможности драйвера
Для поддержки линейной перемычки требуется два набора заголовков драйверов:
- Драйвер должен сообщить 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 является частью функций MapAperatureSegment2 DxgkDdiBuildPagingBuffer, поэтому драйвер должен задать 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, чтобы определить, является ли выделение смежным, и вести себя соответствующим образом.
Службы управления памятью
Существует три основных требования для функций управления памятью:
Возможность управления физической памятью. Эта возможность может включать выделение памяти с помощью непагированных функций памяти, таких как MmAllocatePagesforMdl или MmAllocateContiguousMemory, и функции памяти страницы, такие как ZwCreateSection или ZwAllocateVirtualMemory. Также требуется возможность выражения диапазонов пространства ввода-вывода.
Возможность сопоставления видимого gpu логического адреса из физической памяти. Эта возможность обеспечит вызывающий объект со списком логических страниц (так же, как массив PFN MDL), который gpu можно запрограммировать для доступа. Вызов этих функций гарантирует, что базовые физические страницы заблокированы и недоступны для страниц.
Возможность сопоставлять виртуальные адреса ЦП из физической памяти как в пользовательском режиме, так и в режиме ядра с указанным типом кэша (cached vs WriteCombined).
В следующей таблице перечислены DDIs и связанные входные структуры, представленные для описания выделения физической памяти и сопоставления логических или виртуальных представлений. Эти DDIs — это обновленный набор для замены предыдущих обратных вызовов, предоставленных драйверам для управления сопоставлениями IOMMU (DxgkCbAllocatePagesforMdl, DxgkCbAllocateContiguousMemory, DxgkCbMapMdlToIoMmu). Для драйверов WDDM 3.0, поддерживающих логическую перемаценку, эти старые функции обратного вызова устарели и не могут использоваться. Вместо этого драйвер должен использовать следующие функции обратного вызова управления памятью.
Функции обратного вызова должны вызываться в IRQL <= APC_LEVEL. Начиная с версии WDDM 3.2 драйверы, вызывающие любую из этих функций, проверяются в отношении этого требования и проверки ошибок, если IRQL DISPATCH_LEVEL или более поздней версии.
Изменения 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 и не беспокоиться о проблемах совместимости вниз.