Remapping IOMMU DMA

Halaman ini menjelaskan fitur remapping IOMMU DMA (IOMMUv2) yang diperkenalkan di Windows 11 22H2 (WDDM 3.0). Lihat isolasi GPU berbasis IOMMU untuk informasi tentang isolasi GPU IOMMU sebelum WDDM 3.0.

Gambaran Umum

Hingga WDDM 3.0, Dxgkrnl hanya mendukung isolasi IOMMU melalui remapping fisik 1:1, yang berarti halaman logis yang diakses oleh GPU diterjemahkan ke nomor halaman fisik yang sama. Pemetaan ulang IOMMU DMA memungkinkan GPU mengakses memori melalui alamat logis yang tidak lagi dipetakan 1:1. Sebaliknya, Dxgkrnl dapat menyediakan rentang alamat yang berdampingan secara logis.

Dxgkrnl memberlakukan pembatasan GPU: GPU harus dapat mengakses semua memori fisik agar perangkat dapat dimulai. Jika alamat GPU tertinggi yang terlihat tidak melebihi alamat fisik tertinggi yang diinstal pada sistem, Dxgkrnl gagal menginisialisasi adaptor. Server yang akan datang dan stasiun kerja kelas atas dapat dikonfigurasi dengan lebih dari 1 TB memori yang melewati batasan ruang alamat 40-bit umum dari banyak GPU. Remapping DMA digunakan sebagai mekanisme untuk memungkinkan GPU bekerja di lingkungan ini.

Pada waktu startup, Dxgkrnl menentukan apakah pemeriksaan ulang logis diperlukan dengan membandingkan alamat fisik perangkat tertinggi yang dapat diakses dengan memori yang diinstal pada sistem. Jika perlu, pemetaan ulang DMA digunakan untuk memetakan rentang alamat logis yang berada dalam batas GPU yang terlihat ke memori fisik apa pun pada sistem. Misalnya, jika GPU memiliki batas 1 TB, maka Dxgkrnl mengalokasikan alamat logis dari [0, 1TB) yang kemudian dapat memetakan ke memori fisik apa pun pada sistem melalui IOMMU.

Adaptor logis versus fisik

Dxgkrnl membedakan antara konsep adaptor logis dan fisik. Adaptor fisik mewakili perangkat keras individual yang mungkin atau mungkin tidak ditautkan dengan perangkat lain dalam rantai LDA. Adaptor logis mewakili satu atau beberapa adaptor fisik yang ditautkan.

Satu domain IOMMU DMA dibuat per adaptor logis dan dilampirkan ke semua adaptor fisik yang ditautkan. Dengan demikian, semua adaptor fisik memiliki domain yang sama dan tampilan memori fisik yang sama.

Dukungan GPU terintegrasi versus diskrit

Karena remapping IOMMU DMA menawarkan sedikit nilai untuk GPU terintegrasi yang seharusnya, menurut definisi, sudah dirancang untuk mengakses semua memori fisik dalam sistem, menerapkan dukungan pada bagian terintegrasi bersifat opsional tetapi direkomendasikan.

GPU diskrit harus mendukung pengubahan IOMMU DMA, yang merupakan persyaratan untuk sertifikasi WDDM 3.0.

Perubahan DDI

Perubahan DDI berikut dilakukan untuk mendukung remapping IOMMU DMA.

Kemampuan driver

Dua set tutup driver diperlukan untuk mendukung pemilahan linier:

Kedua topi ini harus disediakan sebelum Dxgkrnl memulai perangkat melalui DXGKDDI_START_DEVICE sehingga perangkat dapat dibuat dan dilampirkan ke domain IOMMU sebelum memori apa pun dapat diakses. Pemilahan linier hanya dapat dilakukan jika perangkat tidak mereferensikan memori fisik yang ada.

Akses Eksklusif

Melampirkan dan melepaskan domain IOMMU sangat cepat, tetapi tetap tidak saat ini atomik. Ini berarti bahwa transaksi yang dikeluarkan melalui PCIe tidak dijamin akan diterjemahkan dengan benar saat bertukar ke domain IOMMU dengan pemetaan yang berbeda.

Untuk menangani situasi ini, mulai dari Windows 10 versi 1803 (WDDM 2.4), KMD harus menerapkan pasangan DDI berikut agar Dxgkrnl dapat memanggil:

Driver harus memastikan bahwa perangkat kerasnya diam setiap kali perangkat dialihkan ke domain IOMMU baru. Artinya, driver harus memastikan bahwa driver tidak membaca atau menulis ke memori sistem dari perangkat di antara kedua panggilan ini.

Di antara kedua panggilan ini, Dxgkrnl membuat jaminan berikut:

  • Penjadwal ditangguhkan. Semua beban kerja aktif dibersihkan, dan tidak ada beban kerja baru yang dikirim atau dijadwalkan pada perangkat keras.
  • Tidak ada panggilan DDI lain yang dilakukan.

Sebagai bagian dari panggilan ini, driver dapat memilih untuk menonaktifkan dan menekan gangguan (termasuk interupsi Vsync) selama akses eksklusif, bahkan tanpa pemberitahuan eksplisit dari OS.

Daftar deskriptor alamat

Untuk mendukung mode akses fisik dan logis dan beralih di antara dua mode dengan mulus saat runtime, Dxgkrnl menyediakan struktur DXGK_ADL yang menjelaskan daftar pendeskripsi alamat (ADL). Struktur data ini mirip dengan MDL, tetapi menjelaskan array halaman yang dapat berupa fisik atau logis. Karena halaman ini dapat menjadi halaman logis, alamat yang dijelaskan oleh ADL tidak dapat dipetakan ke alamat virtual untuk akses CPU langsung.

DXGK_OPERATION_MAP_APERTURE_SEGMENT2 operasi untuk DxgkddiBuildpagingbuffer

VidMm menyediakan mode buffer paging DXGK_OPERATION_MAP_APERTURE_SEGMENT2 untuk memetakan memori ke segmen aperture karena versi sebelumnya menggunakan MDL yang tidak kompatibel dengan alamat logis. Panggilan balik DxgkddiBuildpagingbuffer driver WDDM 3.0 yang mendukung pemecahan ulang alamat logis menerima panggilan ke mode DXGK_OPERATION_MAP_APERTURE_SEGMENT2 , dan tidak lagi menerima panggilan ke mode DXGK_OPERATION_MAP_APERTURE_SEGMENT asli.

Operasi ini diperlukan untuk mendukung pememajaan DMA logis. Ini berperilaku mirip dengan operasi asli, tetapi menyediakan DXGK_ADL alih-alih 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;

Untuk ikut serta dalam operasi DXGK_OPERATION_MAP_APERTURE_SEGMENT2 , driver harus menunjukkan dukungan untuk panggilan MapApertureSegment2 dalam batas manajemen memori:

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

Batas manajemen memori DXGK_VIDMMCAPS adalah bagian dari struktur data DXGK_DRIVERCAPS . Driver tidak dapat menggunakan fungsionalitas remapping DMA (yaitu, remapping alamat logis) tanpa dukungan ini diaktifkan.

Beberapa driver mungkin memerlukan akses CPU ke memori selama panggilan MapApertureSegment2 . Fungsionalitas ini secara opsional disediakan melalui parameter MapApertureSegment2.CpuVisibleAddress lain. Alamat ini adalah alamat virtual mode kernel yang valid selama alokasi dipetakan ke segmen aperture. Artinya, alamat ini akan segera dibebaskan setelah panggilan DXGK_OPERATION_UNMAP_APERTURE_SEGMENT yang sesuai untuk alokasi yang sama.

Alamat ini mungkin tidak diperlukan untuk semua alokasi, sehingga bendera MapApertureCpuVisible ditambahkan ke bendera alokasi untuk menunjukkan kapan diperlukan.

Jika MapApertureCpuVisible tidak ditentukan, MapApertureSegment2.CpuVisibleAddress adalah NULL untuk operasi DXGK_OPERATION_MAP_APERTURE_SEGMENT2 .

MapApertureCpuVisible adalah bagian dari fungsionalitas MapAperatureSegment2DxgkDdiBuildPagingBuffer, sehingga driver harus mengatur DXGK_VIDMMCAPS MapAperature2Supported untuk menggunakan bidang ini. Jika MapAperature2Supported tidak diatur tetapi driver menentukan MapApertureCpuVisible, panggilan ke DxgkDdiCreateAllocation gagal.

Selain itu, untuk menerima operasi DXGK_OPERATION_MAP_APERTURE_SEGMENT2 , driver harus mengatur bendera DXGK_ALLOCATIONINFOFLAGS_WDDM2_0 AccessedPhysically . Jika AccessedPhysically tidak diatur, alokasi apa pun yang menentukan segmen aperture dalam set segmen yang didukung akan ditingkatkan ke segmen memori sistem implisit, yang tidak menerima panggilan MAP_APERTURE (karena tidak ada rentang bukaan untuk dipetakan).

Singkatnya, untuk menerima alamat CPU alokasi memori sistem dengan benar, driver harus mengatur bendera/tutup berikut:

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

Untuk panggilan MapApertureSegment2 , ADL selalu diinisialisasi dan diteruskan sebagai berdekatan saat pemetaan logis diaktifkan. Driver harus memeriksa bendera ADL untuk menentukan apakah alokasi berdampingan, dan berperilaku sesuai.

Layanan Manajemen Memori

Ada tiga persyaratan mendasar untuk fungsi manajemen memori:

  1. Kemampuan untuk mengelola memori fisik. Ini mungkin termasuk alokasi memori melalui fungsi memori yang tidak di-patah seperti MmAllocatePagesforMdl atau MmAllocateContiguousMemory, dan fungsi memori halaman seperti ZwCreateSection atau ZwAllocateVirtualMemory. Kemampuan untuk mengekspresikan rentang ruang IO juga diperlukan.

  2. Kemampuan untuk memetakan alamat logis yang terlihat GPU dari memori fisik. Ini akan memberi pemanggil daftar halaman logis (seperti array PFN MDL) yang dapat diakses oleh GPU. Memanggil fungsi-fungsi ini akan menjamin bahwa halaman fisik yang mendasar dikunci dan tidak dapat dipaginasi.

  3. Kemampuan untuk memetakan alamat virtual CPU dari memori fisik dalam mode pengguna dan mode kernel, dengan jenis cache tertentu (Cache vs WriteCombined).

Tabel berikut mencantumkan DDI dan struktur input terkait yang diperkenalkan untuk menjelaskan alokasi memori fisik dan pemetaan tampilan logis/virtual. DDI ini adalah set yang diperbarui untuk menggantikan panggilan balik sebelumnya yang disediakan kepada driver untuk mengelola pemetaan IOMMU (DxgkCbAllocatePagesforMdl, DxgkCbAllocateContiguousMemory, DxgkCbMapMdlToIoMmu). Untuk driver WDDM 3.0 yang mendukung pemecahan ulang logis, fungsi panggilan balik yang lebih lama ini tidak digunakan lagi dan tidak dapat digunakan. Sebagai gantinya, driver harus menggunakan fungsi panggilan balik manajemen memori berikut.

Fungsi panggilan balik harus dipanggil di IRQL <= APC_LEVEL. Mulai dari WDDM 3.2, driver yang memanggil salah satu fungsi ini divalidasi terhadap persyaratan dan pemeriksaan bug ini jika IRQL DISPATCH_LEVEL atau lebih tinggi.

Panggilan Balik Struktur panggilan balik terkait
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

Perubahan INF

Setiap jenis perangkat yang didukung harus menambahkan kunci dan nilai registri berikut ke bagian INF yang sesuai:

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

Nilai ini menginformasikan PnP bahwa perangkat mendukung remapping DMA. Dxgkrnl dan HAL kemudian akan berkoordinasi untuk menentukan jenis mode pemetaan apa yang harus digunakan (Remapping, Passthrough, dll).

Meskipun kunci registri ini ada pada versi Windows yang lebih lama, nilai '3' unik mulai dari Windows 10 versi 1803 (WDDM 2.4) dan diabaikan pada build yang lebih lama yang tidak mendukungnya. Ini akan memungkinkan driver untuk mengatur kunci ini di INF dan tidak khawatir tentang masalah kompatibilitas ke tingkat bawah.