Compartir a través de


Reasignación de DMA de IOMMU

En esta página se describe la característica de reasignación de IOMMU DMA (IOMMUv2) que se introdujo en Windows 11 22H2 (WDDM 3.0). Consulte El aislamiento de GPU basado en IOMMU para obtener información sobre el aislamiento de GPU de IOMMU antes de WDDM 3.0.

Información general

Hasta WDDM 3.0, Dxgkrnl solo admitía el aislamiento de IOMMU a través de la reasignación física 1:1, lo que significa que las páginas lógicas a las que accedió la GPU se traduciron al mismo número de página físico. La reasignación de DMA de IOMMU permite que la GPU acceda a la memoria a través de direcciones lógicas que ya no están asignadas 1:1. En su lugar, Dxgkrnl es capaz de proporcionar intervalos de direcciones lógicamente contiguos.

Dxgkrnl impone una restricción en las GPU: las GPU deben poder acceder a toda la memoria física para que el dispositivo se inicie. Si la dirección visible más alta de la GPU no supera la dirección física más alta instalada en el sistema, Dxgkrnl produce un error en la inicialización del adaptador. Los próximos servidores y estaciones de trabajo de gama alta se pueden configurar con más de 1 TB de memoria que cruza la limitación común del espacio de direcciones de 40 bits de muchas GPU. La reasignación de DMA se usa como mecanismo para permitir que las GPU funcionen en este entorno.

En el momento de inicio, Dxgkrnl determina si la reasignación lógica es necesaria comparando la dirección física más alta accesible del dispositivo con la memoria instalada en el sistema. Si es necesario, la reasignación de DMA se usa para asignar un intervalo de direcciones lógico dentro de los límites visibles de la GPU a cualquier memoria física del sistema. Por ejemplo, si la GPU tiene un límite de 1 TB, Dxgkrnl asigna direcciones lógicas de [0, 1 TB) que luego se pueden asignar a cualquier memoria física del sistema a través de IOMMU.

Adaptadores lógicos frente a físicos

Dxgkrnl distingue entre el concepto de un adaptador lógico y físico. Un adaptador físico representa un dispositivo de hardware individual que puede o no estar vinculado a otros dispositivos de una cadena LDA. Un adaptador lógico representa uno o varios adaptadores físicos vinculados.

Se crea un único dominio de IOMMU DMA por adaptador lógico y se conecta a todos los adaptadores físicos que están vinculados. Por lo tanto, todos los adaptadores físicos comparten el mismo dominio y la misma vista de memoria física.

Compatibilidad con GPU integrada frente a discreta

Dado que la reasignación de DMA de IOMMU ofrece poco valor a las GPU integradas que deben, por definición, ya estar diseñadas para tener acceso a toda la memoria física del sistema, la implementación de la compatibilidad con las partes integradas es opcional, pero se recomienda.

Las GPU discretas deben admitir la reasignación de DMA de IOMMU, que es un requisito para la certificación WDDM 3.0.

Cambios de DDI

Se realizaron los siguientes cambios de DDI para admitir la reasignación de DMA de IOMMU.

Funcionalidades del controlador

Se requieren dos conjuntos de límites de controladores para admitir la reasignación lineal:

  • El controlador debe informar a Dxgkrnl sobre sus restricciones de memoria física; es decir, sobre su dirección física visible más alta a través de DXGKQAITYPE_PHYSICAL_MEMORY_CAPS y su estructura de DXGK_PHYSICAL_MEMORY_CAPS asociada.
  • El controlador debe indicar su compatibilidad con la reasignación lineal de IOMMU a través de DXGKQAITYPE_IOMMU_CAPS y su estructura de DXGK_IOMMU_CAPS asociada. Al indicar compatibilidad, el controlador indica que se admiten y se usan todas las DDIs descritas más adelante.

Ambos límites deben proporcionarse antes de que Dxgkrnl inicie el dispositivo a través de DXGKDDI_START_DEVICE para que el dispositivo se pueda crear y conectar a un dominio IOMMU antes de que se pueda acceder a cualquier memoria. La reasignación lineal solo se puede realizar si el dispositivo no hace referencia a ninguna memoria física existente.

Acceso exclusivo

La asociación y desasociación de dominios iomMU es extremadamente rápida, pero no es actualmente atómica. Esto significa que no se garantiza que una transacción emitida a través de PCIe se traduzca correctamente mientras se intercambia a un dominio IOMMU con diferentes asignaciones.

Para controlar esta situación, a partir de Windows 10 versión 1803 (WDDM 2.4), un KMD debe implementar el siguiente par DDI para que Dxgkrnl llame a:

El controlador debe asegurarse de que su hardware sea silencioso siempre que el dispositivo se cambie a un nuevo dominio IOMMU. Es decir, el controlador debe asegurarse de que no lee ni escribe en la memoria del sistema desde el dispositivo entre estas dos llamadas.

Entre estas dos llamadas, Dxgkrnl realiza las siguientes garantías:

  • El programador está suspendido. Todas las cargas de trabajo activas se vacían y no se envía ninguna carga de trabajo nueva a o se programa en el hardware.
  • No se realizan otras llamadas DDI.

Como parte de estas llamadas, el controlador puede optar por deshabilitar y suprimir interrupciones (incluidas las interrupciones de Vsync) durante el acceso exclusivo, incluso sin notificación explícita del sistema operativo.

Listas de descriptores de direcciones

Para admitir los modos de acceso físico y lógico y cambiar entre los dos modos sin problemas en tiempo de ejecución, Dxgkrnl proporciona una estructura de DXGK_ADL que describe una lista de descriptores de direcciones (ADL). Esta estructura de datos es similar a una MDL, pero describe una matriz de páginas que puede ser física o lógica. Dado que estas páginas pueden ser páginas lógicas, las direcciones descritas por un ADL no se pueden asignar a una dirección virtual para el acceso directo a la CPU.

DXGK_OPERATION_MAP_APERTURE_SEGMENT2 operación para DxgkddiBuildpagingbuffer

VidMm proporciona el DXGK_OPERATION_MAP_APERTURE_SEGMENT2 modo de búfer de paginación para asignar memoria al segmento de apertura, ya que la versión anterior usa una MDL que no es compatible con las direcciones lógicas. La devolución de llamada dxgkddiBuildpagingbuffer de los controladores WDDM 3.0 que admiten la reasignación de direcciones lógicas reciben llamadas al modo de DXGK_OPERATION_MAP_APERTURE_SEGMENT2 y ya no reciben llamadas al modo de DXGK_OPERATION_MAP_APERTURE_SEGMENT original.

Esta operación es necesaria para admitir la reasignación lógica de DMA. Se comporta de forma similar a la operación original, pero proporciona un DXGK_ADL en lugar de una 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;

Para participar en la operación de DXGK_OPERATION_MAP_APERTURE_SEGMENT2 , el controlador debe indicar la compatibilidad con las llamadas MapApertureSegment2 en los límites de administración de memoria:

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

Los límites de administración de memoria de DXGK_VIDMMCAPS forman parte de la estructura de datos DXGK_DRIVERCAPS . El controlador no puede usar la funcionalidad de reasignación de DMA (es decir, reasignación de direcciones lógicas) sin esta compatibilidad habilitada.

Algunos controladores pueden requerir acceso de CPU a la memoria durante una llamada a MapApertureSegment2 . Esta funcionalidad se proporciona opcionalmente a través de otro parámetro MapApertureSegment2.CpuVisibleAddress . Esta dirección es una dirección virtual en modo kernel que es válida siempre que la asignación se asigne al segmento de apertura. Es decir, esta dirección se liberará inmediatamente después de la DXGK_OPERATION_UNMAP_APERTURE_SEGMENT correspondiente llamada para la misma asignación.

Es posible que esta dirección no sea necesaria para todas las asignaciones, por lo que se agregó una marca MapApertureCpuVisible a las marcas de asignación para indicar cuándo es necesario.

Si no se especifica MapApertureCpuVisible , MapApertureSegment2.CpuVisibleAddress es NULL para las operaciones de DXGK_OPERATION_MAP_APERTURE_SEGMENT2 .

MapApertureCpuVisible forma parte de la funcionalidad MapAperatureSegment2 de DxgkDdiBuildPagingBuffer, por lo que el controlador debe establecer DXGK_VIDMMCAPS MapAperature2Supported para usar este campo. Si MapAperature2Supported no está establecido, pero el controlador especifica MapApertureCpuVisible, se produce un error en la llamada a DxgkDdiCreateAllocation .

Además, para recibir la operación de DXGK_OPERATION_MAP_APERTURE_SEGMENT2 , el controlador debe establecer la marca DXGK_ALLOCATIONINFOFLAGS_WDDM2_0 AccessedPhysically . Si No se establece AccessedPhysically , ninguna asignación que especifique un segmento de apertura en su conjunto de segmentos admitido se actualiza al segmento de memoria del sistema implícito, que no recibe llamadas MAP_APERTURE (ya que no hay intervalos de apertura para asignar).

En resumen, para recibir correctamente la dirección de CPU de una asignación de memoria del sistema, el controlador debe establecer las marcas o límites siguientes:

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

Para las llamadas MapApertureSegment2 , el ADL siempre se inicializa y se pasa como contiguo cuando se habilita la asignación lógica. El controlador debe comprobar las marcas de ADL para determinar si la asignación es contigua y comportarse en consecuencia.

Servicios de administración de memoria

Existen tres requisitos fundamentales para las funciones de administración de memoria:

  1. La capacidad de administrar la memoria física. Esto puede incluir la asignación de memoria a través de funciones de memoria no paginadas, como MmAllocatePagesforMdl o MmAllocateContiguousMemory, y funciones de memoria paginadas como ZwCreateSection o ZwAllocateVirtualMemory. También se requiere la capacidad de expresar intervalos de espacio de E/S.

  2. La capacidad de asignar una dirección lógica visible para GPU a partir de la memoria física. Esto proporcionaría al autor de la llamada una lista de páginas lógicas (al igual que la matriz PFN de una MDL) a la que se puede programar la GPU para acceder. Llamar a estas funciones garantizaría que las páginas físicas subyacentes están bloqueadas y no se pueden paginar.

  3. La capacidad de asignar direcciones virtuales de CPU desde la memoria física tanto en modo de usuario como en modo kernel, con un tipo de caché especificado (Cached vs WriteCombined).

En la tabla siguiente se enumeran las DDIs y las estructuras de entrada asociadas introducidas para describir la asignación y asignación de memoria física de vistas lógicas o virtuales. Estos DDIs son un conjunto actualizado para reemplazar las devoluciones de llamada anteriores proporcionadas a los controladores para administrar asignaciones de IOMMU (DxgkCbAllocatePagesforMdl, DxgkCbAllocateContiguousMemory, DxgkCbMapMdlToIoMmu). En el caso de los controladores WDDM 3.0 que admiten la reasignación lógica, estas funciones de devolución de llamada anteriores están en desuso y no se pueden usar. En su lugar, el controlador debe usar las siguientes funciones de devolución de llamada de administración de memoria.

Se debe llamar a las funciones de devolución de llamada en IRQL <= APC_LEVEL. A partir de WDDM 3.2, los controladores que llaman a cualquiera de estas funciones se validan con este requisito y comprueban errores si irQL está DISPATCH_LEVEL o superior.

Devolución de llamada Estructura de devolución de llamada asociada
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

Cambios de INF

Cada tipo de dispositivo admitido debe agregar la siguiente clave y valor del Registro a la sección adecuada de INF:

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

Este valor informa a PnP de que el dispositivo admite la reasignación de DMA. Dxgkrnl y HAL se coordinarán para determinar qué tipo de modo de asignación se debe usar (reasignación, paso a través, etc.).

Aunque esta clave del Registro estaba presente en versiones anteriores de Windows, el valor "3" es único a partir de Windows 10 versión 1803 (WDDM 2.4) y se omite en compilaciones anteriores que no lo admiten. Esto permitirá que los controladores establezcan esta clave en inf y no se preocupen por los problemas de compatibilidad por debajo del nivel.