IOMMU DMA 重新對應

此頁面描述在 Windows 11 22H2 (WDDM 3.0) 中引進的 IOMMUv2 (IOMMUv2) IOMMU DMA 重新對應功能。 如需 WDDM 3.0 之前的 IOMMU GPU 隔離相關信息,請參閱 IOMMU 型 GPU 隔離

概觀

在WDDM 3.0之前, Dxgkrnl 僅支援IOMMU隔離到1:1實體重新對應,這表示 GPU 存取的邏輯頁面已轉譯為相同的實體頁碼。 IOMMU DMA 重新對應可讓 GPU 透過不再對應 1:1 的邏輯位址來存取記憶體。 相反 地,Dxgkrnl 能夠提供邏輯連續的位址範圍。

Dxgkrnl 會對 GPU 施加限制:GPU 必須能夠存取所有物理記憶體,裝置才能啟動。 如果 GPU 的最高可見位址未超過系統上安裝的最高實體位址, Dxgkrnl 會失敗適配卡的初始化。 即將推出的伺服器和高階工作站可以設定超過 1 TB 的記憶體,其跨越許多 GPU 的常見 40 位位址空間限制。 DMA 重新對應可用來做為允許 GPU 在此環境中運作的機制。

在啟動時, Dxgkrnl 會比較裝置的最高可存取實體位址與安裝在系統上的記憶體,來判斷是否需要邏輯重新對應。 如有必要,DMA 重新對應是用來將 GPU 可見界限內的邏輯位址範圍對應至系統上任何物理記憶體。 例如,如果 GPU 的限制為 1 TB, 則 Dxgkrnl 會從 [0, 1TB]) 配置邏輯位址,然後透過 IOMMU 對應至系統上的任何實體記憶體。

邏輯與實體配接器

Dxgkrnl 區分邏輯和實體配接器的概念。 實體適配卡代表可能或可能不會與 LDA 鏈結中的其他裝置連結的個別硬體裝置。 邏輯配接器代表一或多個鏈接器。

每個邏輯適配卡都會建立單一 IOMMU DMA 網域,並連結至所有鏈接的實體適配卡。 因此,所有實體適配卡都會共用相同的網域和相同的物理內存檢視。

整合式與離散 GPU 支援

由於 IOMMU DMA 重新對應對整合式 GPU 提供少量價值,因此根據定義,已設計為存取系統中的所有物理記憶體,但建議對整合元件實作支援。

離散 GPU 必須支援 IOMMU DMA 重新對應,這是 WDDM 3.0 認證的需求。

DDI 變更

下列 DDI 變更是為了支援 IOMMU DMA 重新對應。

驅動程式功能

需要兩組驅動程式上限,才能支援線性重新對應:

  • 驅動程式必須通知 Dxgkrnl 其物理記憶體限制;也就是說,透過DXGKQAITYPE_PHYSICAL_MEMORY_CAPS及其相關聯的DXGK_PHYSICAL_MEMORY_CAPS結構,關於其最高可見實體位址。
  • 驅動程式必須指出其支援IOMMU線性重新對應,透過 DXGKQAITYPE_IOMMU_CAPS 及其相關聯的 DXGK_IOMMU_CAPS 結構。 藉由指出支持,驅動程式表示支援及使用稍後所述的所有 DIS。

這兩個上限都必須在 Dxgkrnl 透過 DXGKDDI_START_DEVICE 啟動裝置之前提供,才能建立裝置並連結至 IOMMU 網域,才能存取任何記憶體。 只有在裝置未參考任何現有的物理記憶體時,才能完成線性重新對應。

獨佔存取

IOMMU 網域連結和中斷連結非常快速,但目前並非不可部分完成。 這表示在交換至具有不同對應的 IOMMU 網域時,不保證會正確轉譯透過 PCIe 發出的交易。

若要處理這種情況,從 Windows 10 1803 版 (WDDM 2.4) 開始,KMD 必須實作下列 DDI 配對,才能呼叫 Dxgkrnl

每當裝置切換至新的 IOMMU 網域時,驅動程式必須確定其硬體為無訊息。 也就是說,驅動程式必須確定它不會從這兩個呼叫之間的裝置讀取或寫入系統記憶體。

在這兩個呼叫之間, Dxgkrnl 會進行下列保證:

  • 排程器已暫停。 所有作用中的工作負載都會排清,而且不會在硬體上傳送或排程任何新的工作負載。
  • 不會進行其他 DDI 呼叫。

作為這些呼叫的一部分,驅動程式可以選擇停用和隱藏中斷, (包括獨佔存取期間) Vsync 中斷,即使操作系統沒有明確通知也一樣。

位址描述項清單

為了支援實體和邏輯存取模式,並在運行時間順暢地在兩種模式之間切換, Dxgkrnl 提供 DXGK_ADL 結構,描述 ADL) (位址描述項清單。 此數據結構類似於 MDL,但描述可以是實體或邏輯的頁面陣列。 由於這些頁面可以是邏輯頁面,因此ADL所描述的位址無法對應至虛擬位址以進行直接CPU存取。

DxgkddiBuildpagingbuffer 的DXGK_OPERATION_MAP_APERTURE_SEGMENT2作業

VidMm 提供 DXGK_OPERATION_MAP_APERTURE_SEGMENT2 分頁緩衝區模式,以便將記憶體對應至光圈區段,因為舊版使用與邏輯位址不相容的 MDL。 WDDM 3.0 驅動程式的 DxgkddiBuildpagingbuffer 回呼,可支援邏輯位址重新對應對 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.CpuVisibleAddressDXGK_OPERATION_MAP_APERTURE_SEGMENT2 作業的 NULL。

MapApertureCpuVisibleDxgkDdiBuildPagingBufferMapAperatureSegment2 功能的一部分,因此驅動程式必須設定 DXGK_VIDMMCAPS MapAperature2Supported 才能使用此字段。 如果未設定 MapAperature2Supported ,但驅動程式指定 MapApertureCpuVisible則對 DxgkDdiCreateAllocation 的呼叫會失敗。

此外,若要接收 DXGK_OPERATION_MAP_APERTURE_SEGMENT2 作業,驅動程式必須設定 DXGK_ALLOCATIONINFOFLAGS_WDDM2_0 AccessedPhysically 旗標 。 如果未設定 AccessedPhysically ,則任何在其支援區段集中指定光圈區段的配置都會升級至隱含系統記憶體區段,因為沒有可對應) 的光圈範圍,因此不會收到MAP_APERTURE呼叫 (。

總而言之,若要正確接收系統記憶體配置的 CPU 位址,驅動程式必須設定下列旗標/上限:

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

針對 MapApertureSegment2 呼叫,ADL 一律會初始化,並在啟用邏輯對應時以連續方式傳遞。 驅動程式必須檢查 ADL 旗標,以判斷配置是否連續,並據以運作。

記憶體管理服務

記憶體管理功能有三個基本需求:

  1. 管理物理記憶體的能力。 這可能包括透過非分頁記憶體函式配置記憶體,例如 MmAllocatePagesforMdlMmAllocateContiguousMemory,以及 ZwCreateSectionZwAllocateVirtualMemory 等分頁記憶體函式。 也需要表達IO空間範圍的能力。

  2. 從物理記憶體對應 GPU 可見邏輯位址的能力。 這會為呼叫者提供邏輯頁面清單, (與 MDL) 的 PFN 陣列非常類似,GPU 可進行程式設計以存取。 呼叫這些函式可確保基礎實體頁面已鎖定且無法分頁。

  3. 在使用者模式和核心模式中,從物理記憶體對應 CPU 虛擬位址的能力,其指定的快取類型 (Cached 與 WriteCombined) 。

下表列出說明邏輯/虛擬檢視之實體記憶體配置和對應的 DIS 和相關聯的輸入結構。 這些 DIS 是更新的集合,可取代提供給驅動程式的先前回呼,以管理 IOMMU 對應 (DxgkCbAllocatePagesforMdlDxgkCbAllocateContiguousMemoryDxgkCbMapMdlToIoMmu) 。 對於支持邏輯重新對應的 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 上,但從 1803 版 Windows 10 (WDDM 2.) 4 版開始,值 '3' 是唯一的,而且在不支援它的舊版組建上會忽略。 這可讓驅動程式在 INF 中設定此金鑰,而不必擔心相容性問題。