Bagikan melalui


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. Remapping 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 mulai, Dxgkrnl menentukan apakah remapping logis diperlukan dengan membandingkan alamat fisik perangkat tertinggi yang dapat diakses dengan memori yang diinstal pada sistem. Jika perlu, remapping 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, 1 TB) 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 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 berbagi domain yang sama dan tampilan memori fisik yang sama.

Dukungan GPU yang 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 remapping 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 batas driver diperlukan untuk mendukung pemetaan linier:

  • Pengemudi harus memberi tahu Dxgkrnl tentang pembatasan memori fisiknya; yaitu, tentang alamat fisik tertinggi yang terlihat melalui DXGKQAITYPE_PHYSICAL_MEMORY_CAPS dan struktur DXGK_PHYSICAL_MEMORY_CAPS terkait.
  • Driver harus menunjukkan dukungannya untuk remapping linier IOMMU melalui DXGKQAITYPE_IOMMU_CAPS dan struktur DXGK_IOMMU_CAPS terkait. Dengan menunjukkan dukungan, driver menunjukkan bahwa semua DDI yang dijelaskan nanti didukung dan digunakan.

Kedua batas 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. Pemetakan ulang linier hanya dapat dilakukan jika perangkat tidak mereferensikan memori fisik yang ada.

Akses Eksklusif

Lampirkan dan lepas domain IOMMU sangat cepat, tetapi tetap saja saat ini tidak atomik. Kondisi 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 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 antara dua mode dengan mulus saat runtime, Dxgkrnl menyediakan struktur DXGK_ADL yang menjelaskan daftar deskriptor alamat (ADL). Struktur data ini mirip dengan MDL, tetapi menjelaskan array halaman yang dapat berupa fisik atau logis. Karena halaman ini dapat berupa halaman logis, alamat yang dijelaskan oleh ADL tidak dapat dipetakan ke alamat virtual untuk akses CPU langsung.

operasi DXGK_OPERATION_MAP_APERTURE_SEGMENT2 untuk DxgkddiBuildpagingbuffer

VidMm menyediakan mode buffer halaman 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 remapping 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 remapping 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 dibebaskan segera setelah panggilan DXGK_OPERATION_UNMAP_APERTURE_SEGMENT yang sesuai untuk alokasi yang sama.

Alamat ini mungkin tidak diperlukan untuk semua alokasi. Bendera MapApertureCpuVisible ditambahkan ke bendera alokasi untuk menunjukkan kapan alamat ini diperlukan.

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

MapApertureCpuVisible adalah bagian dari fungsionalitas MapAperatureSegment2 DxgkDdiBuildPagingBuffer, 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 bukaan 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/batas 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 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. Kemampuan ini mungkin mencakup alokasi memori melalui fungsi memori yang tidak disebarkan 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. Kemampuan 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 di-pageable.

  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 remapping logis, fungsi panggilan balik yang lebih lama ini tidak digunakan lagi dan tidak dapat digunakan. Driver harus menggunakan fungsi panggilan balik manajemen memori berikut.

Fungsi panggilan balik harus dipanggil di IRQL <= APC_LEVEL. Mulai 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 yang sesuai dari INF:

[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 berkoordinasi untuk menentukan jenis mode pemetaan apa yang harus digunakan (Remapping, Passthrough, dan sebagainya).

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