Udostępnij przez


Ponowne mapowanie IOMMU DMA

Na tej stronie opisano funkcję ponownego mapowania IOMMU DMA (IOMMUv2), która została wprowadzona w systemie Windows 11 22H2 (WDDM 3.0). Aby uzyskać informacje na temat izolacji GPU opartej na IOMMU przed WDDM 3.0, zobacz Izolacja GPU oparta na IOMMU.

Przegląd

Do czasu WDDM 3.0, Dxgkrnl obsługiwał tylko izolację IOMMU za pomocą fizycznego mapowania 1:1, co oznacza, że strony logiczne były tłumaczone na te same numery stron fizycznych przez GPU. Ponowne mapowanie dma IOMMU umożliwia procesorowi GPU dostęp do pamięci za pośrednictwem adresów logicznych, które nie są już mapowane 1:1. Zamiast tego Dxgkrnl jest w stanie zapewnić logicznie ciągłe zakresy adresów.

Dxgkrnl nakłada ograniczenie na procesory GPU: procesory GPU muszą mieć dostęp do całej pamięci fizycznej w celu uruchomienia urządzenia. Jeśli najwyższy widoczny adres procesora GPU nie przekracza najwyższego adresu fizycznego zainstalowanego w systemie, inicjowanie adaptera przez Dxgkrnl kończy się niepowodzeniem. Nadchodzące serwery i stacje robocze wysokiej klasy można skonfigurować z ponad 1 TB pamięci, która przekracza typowe 40-bitowe ograniczenie przestrzeni adresowej wielu procesorów GPU. Ponowne mapowanie DMA jest używane jako mechanizm umożliwiający działanie procesorów GPU w tym środowisku.

W czasie uruchamiania Dxgkrnl określa, czy konieczne jest ponowne mapowanie logiczne przez porównanie najwyższego dostępnego adresu fizycznego urządzenia z pamięcią zainstalowaną w systemie. Jeśli jest to konieczne, ponowne mapowanie DMA jest używane do mapowania logicznego zakresu adresów, który znajduje się w widocznych granicach procesora graficznego (GPU), na dowolną pamięć fizyczną w systemie. Na przykład, jeśli procesor GPU ma limit 1 TB, Dxgkrnl przydziela adresy logiczne z zakresu [0, 1 TB), które mogą być następnie mapowane na dowolną pamięć fizyczną w systemie za pośrednictwem IOMMU.

Adaptery logiczne kontra fizyczne

Dxgkrnl rozróżnia między koncepcją karty logicznej a fizycznej. Karta fizyczna reprezentuje pojedyncze urządzenie sprzętowe, które może być połączone z innymi urządzeniami w łańcuchu LDA. Adapter logiczny reprezentuje co najmniej jeden powiązany adapter fizyczny.

Jedna domena DMA IOMMU jest tworzona dla adaptera logicznego i przydzielana do wszystkich połączonych adapterów fizycznych. W związku z tym wszystkie adaptery fizyczne współdzielą tę samą domenę i ten sam widok pamięci fizycznej.

Zintegrowana i dyskretna obsługa procesora GPU

Ponieważ ponowne mapowanie IOMMU DMA oferuje niewielką wartość dla zintegrowanych procesorów GPU, które z definicji powinny być już zaprojektowane w celu uzyskania dostępu do całej pamięci fizycznej w systemie, implementacja obsługi zintegrowanych części jest opcjonalna, ale zalecana.

Dyskretne procesory GPU muszą obsługiwać ponowne mapowanie IOMMU DMA, co jest wymaganiem do certyfikacji WDDM 3.0.

Zmiany DDI

Następujące zmiany DDI zostały wprowadzone w celu obsługi ponownego mapowania IOMMU DMA.

Możliwości sterowników

Aby obsłużyć ponowne mapowanie liniowe, wymagane są dwa zestawy nakładek sterowników.

  • Sterownik musi poinformować Dxgkrnl o ograniczeniach pamięci fizycznej; oznacza to, że o jego najwyższym widocznym adresie fizycznym za pośrednictwem DXGKQAITYPE_PHYSICAL_MEMORY_CAPS i powiązanej struktury DXGK_PHYSICAL_MEMORY_CAPS .
  • Sterownik musi wskazać swoje wsparcie dla liniowego ponownego mapowania IOMMU przez DXGKQAITYPE_IOMMU_CAPS i skojarzoną strukturę DXGK_IOMMU_CAPS. Wskazując obsługę, sterownik wskazuje, że wszystkie opisane później DDIs są obsługiwane i używane.

Oba te limity należy podać przed uruchomieniem urządzenia za pośrednictwem DXGKDDI_START_DEVICE, aby można było utworzyć urządzenie i dołączyć je do domeny IOMMU, zanim będzie można uzyskać dostęp do jakiejkolwiek pamięci. Ponowne mapowanie liniowe można wykonać tylko wtedy, gdy urządzenie nie odwołuje się do żadnej istniejącej pamięci fizycznej.

Wyłączny dostęp

Dołączanie i odłączanie domeny IOMMU jest bardzo szybkie, ale jednak nie jest obecnie atomowe. Ten warunek oznacza, że transakcja wystawiona za pośrednictwem interfejsu PCIe nie ma gwarancji poprawnej translacji przy przełączaniu na domenę IOMMU o innych mapowaniach.

Aby obsłużyć tę sytuację, począwszy od systemu Windows 10 w wersji 1803 (WDDM 2.4), KMD musi zaimplementować następującą parę DDI, aby móc wywołać Dxgkrnl:

Sterownik musi upewnić się, że jego sprzęt jest cichy za każdym razem, gdy urządzenie zostanie przełączone do nowej domeny IOMMU. Oznacza to, że sterownik musi upewnić się, że nie odczytuje ani nie zapisuje w pamięci systemowej z urządzenia między tymi dwoma wywołaniami.

Między tymi dwoma wywołaniami Dxgkrnl zapewnia następujące gwarancje:

  • Harmonogram jest zawieszony. Wszystkie aktywne obciążenia są wyczyszczone, a żadne nowe obciążenia nie są wysyłane ani zaplanowane na sprzęcie.
  • Nie są wykonywane żadne inne wywołania DDI.

W ramach tych wywołań sterownik może wyłączyć i pominąć przerwania (w tym przerwania asynchroniczne) podczas wyłącznego dostępu, nawet bez wyraźnego powiadomienia z systemu operacyjnego.

Listy deskryptorów adresów

Aby bezproblemowo obsługiwać tryby dostępu fizycznego i logicznego oraz przełączać się między dwoma trybami w czasie wykonywania, Dxgkrnl zapewnia strukturę DXGK_ADL opisujący listę deskryptorów adresów (ADL). Ta struktura danych jest podobna do MDL, ale opisuje tablicę stron, które mogą być fizyczne lub logiczne. Ponieważ te strony mogą być stronami logicznymi, adresy opisane przez usługę ADL nie mogą być mapowane na adres wirtualny na potrzeby bezpośredniego dostępu do procesora CPU.

Operacja DXGK_OPERATION_MAP_APERTURE_SEGMENT2 dla DxgkddiBuildpagingbuffer

VidMm udostępnia tryb bufora stronicowania DXGK_OPERATION_MAP_APERTURE_SEGMENT2 do mapowania pamięci na segment przysłony, ponieważ poprzednia wersja używa MDL niezgodnego z adresami logicznymi. Wywołanie zwrotne DxgkddiBuildpagingbuffer sterowników WDDM 3.0 obsługujących ponowne mapowanie adresów logicznych odbiera wywołania do trybu DXGK_OPERATION_MAP_APERTURE_SEGMENT2 i nie otrzymują już wywołań do oryginalnego trybu DXGK_OPERATION_MAP_APERTURE_SEGMENT.

Ta operacja jest wymagana do obsługi ponownego mapowania logicznego DMA. Zachowuje się podobnie do oryginalnej operacji, ale zapewnia DXGK_ADL zamiast 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;

Aby wyrazić zgodę na operację DXGK_OPERATION_MAP_APERTURE_SEGMENT2 , sterownik musi wskazać obsługę wywołań MapApertureSegment2 w limitach zarządzania pamięcią:

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

Limity zarządzania pamięcią DXGK_VIDMMCAPS są częścią struktury danych DXGK_DRIVERCAPS . Sterownik nie może użyć funkcji ponownego mapowania dmA (czyli ponownego mapowania adresów logicznych) bez włączenia tej obsługi.

Niektóre sterowniki mogą wymagać dostępu procesora CPU do pamięci podczas wywołania MapApertureSegment2 . Ta funkcja jest opcjonalnie udostępniana za pośrednictwem innego parametru MapApertureSegment2.CpuVisibleAddress . Ten adres jest wirtualnym adresem trybu jądra, który jest prawidłowy, o ile alokacja jest mapowana do segmentu apertury. Oznacza to, że ten adres zostanie uwolniony natychmiast po odpowiednim wywołaniu DXGK_OPERATION_UNMAP_APERTURE_SEGMENT dla tej samej alokacji.

Ten adres może nie być wymagany dla wszystkich alokacji. Flaga MapApertureCpuVisible została dodana do flag alokacji, aby wskazać, kiedy ten adres jest wymagany.

Jeśli parametr MapApertureCpuVisible nie jest określony, parametr MapApertureSegment2.CpuVisibleAddress ma wartość NULL dla operacji DXGK_OPERATION_MAP_APERTURE_SEGMENT2 .

MapApertureCpuVisible jest częścią funkcji MapAperatureSegment2DxgkDdiBuildPagingBuffer, więc sterownik musi ustawić DXGK_VIDMMCAPS MapAperature2Supported, aby używać tego pola. Jeśli parametr MapAperature2Supported nie został ustawiony, ale sterownik określa element MapApertureCpuVisible, wywołanie metody DxgkDdiCreateAllocation kończy się niepowodzeniem.

Ponadto, aby otrzymać operację DXGK_OPERATION_MAP_APERTURE_SEGMENT2, sterownik musi ustawić flagę DXGK_ALLOCATIONINFOFLAGS_WDDM2_0 AccessedPhysically. Jeśli parametr AccessedPhysically nie jest ustawiony, każda alokacja, która określa segment apertury w obsługiwanym zestawie segmentów, zostanie przeniesiona na domyślny segment pamięci systemowej, który nie odbiera wywołań MAP_APERTURE, gdyż brak jest zakresów apertury do mapowania.

Podsumowując, aby prawidłowo otrzymać adres CPU alokacji pamięci systemowej, sterownik musi ustawić następujące flagi/właściwości:

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

W przypadku wywołań MapApertureSegment2 plik ADL jest zawsze inicjowany i przekazywany jako ciągły po włączeniu mapowania logicznego. Sterownik musi sprawdzić flagi ADL, aby określić, czy alokacja jest ciągła, i odpowiednio się zachować.

Usługi zarządzania pamięcią

Istnieją trzy podstawowe wymagania dotyczące funkcji zarządzania pamięcią:

  1. Możliwość zarządzania pamięcią fizyczną. Ta funkcja może obejmować alokację pamięci za pośrednictwem funkcji pamięci niestronicowanej, takich jak MmAllocatePagesforMdl lub MmAllocateContiguousMemory, oraz stronicowane funkcje pamięci, takie jak ZwCreateSection lub ZwAllocateVirtualMemory. Wymagana jest również zdolność do wyrażania zakresów przestrzeni I/O.

  2. Możliwość mapowania logicznego adresu widocznego dla GPU z pamięci fizycznej. Ta funkcja zapewniłaby wywołującemu listę stron logicznych (podobnie jak tablica PFN MDL), do których GPU można zaprogramować dostęp. Wywołanie tych funkcji gwarantuje, że bazowe strony fizyczne są zablokowane i niestronicowalne.

  3. Możliwość mapowania adresów wirtualnych CPU z pamięci fizycznej zarówno w trybie jądra, jak i w trybie użytkownika, z określonym typem pamięci podręcznej (Cached vs WriteCombined).

W poniższej tabeli wymieniono identyfikatory DDI i skojarzone struktury wejściowe wprowadzone w celu opisania alokacji pamięci fizycznej i mapowania widoków logicznych/wirtualnych. Te identyfikatory DDI to zaktualizowany zestaw umożliwiający zastąpienie poprzednich wywołań zwrotnych dostarczonych sterownikom do zarządzania mapowaniami IOMMU (DxgkCbAllocatePagesforMdl, DxgkCbAllocateContiguousMemory, DxgkCbMapMdlToMmu). W przypadku sterowników WDDM 3.0 obsługujących ponowne mapowanie logiczne te starsze funkcje wywołania zwrotnego są przestarzałe i nie można ich używać. Sterownik powinien zamiast tego używać następujących funkcji zwrotnych zarządzania pamięcią.

Funkcje wywołania zwrotnego muszą być wywoływane na poziomie IRQL <= APC_LEVEL. Począwszy od programu WDDM 3.2, sterowniki wywołujące dowolną z tych funkcji są weryfikowane pod kątem tego wymagania i sprawdzania błędów, jeśli środowisko IRQL jest DISPATCH_LEVEL lub nowsze.

Oddzwonienie Skojarzona struktura wywołania zwrotnego
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

Zmiany INF

Każdy obsługiwany typ urządzenia musi dodać następujący klucz rejestru i wartość do odpowiedniej sekcji INF:

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

Ta wartość informuje PnP, że urządzenie obsługuje ponowne mapowanie DMA. Dxgkrnl i HAL następnie koordynują, aby określić, jaki rodzaj trybu mapowania powinien być używany (ponowne mapowanie, przekazywanie itd.).

Mimo że ten klucz rejestru był obecny w starszych wersjach systemu Windows, wartość "3" jest unikatowa, począwszy od systemu Windows 10 w wersji 1803 (WDDM 2.4) i jest ignorowana w starszych kompilacjach, które nie obsługują go. Ta unikatowa wartość pozwala sterownikom ustawić ten klucz rejestru w INF i nie martwić się o problemy ze zgodnością w niższych wersjach.