Remapeamento de AMD da IOMMU
Esta página descreve o recurso de remapeamento de AMD da IOMMU (IOMMUv2) que foi introduzido no Windows 11 22H2 (WDDM 3.0). Consulte Isolamento de GPU baseado na IOMMU para obter informações sobre o isolamento de GPU da IOMMU antes do WDDM 3.0.
Visão geral
Até o WDDM 3.0, o Dxgkrnl só oferecia suporte ao isolamento da IOMMU por meio do remapeamento físico individual, o que significa que as páginas lógicas acessadas pela GPU eram convertidas para o mesmo número de página física. O remapeamento de AMD da IOMMU permite que a GPU acesse a memória por meio de endereços lógicos que não são mais mapeados individualmente. Em vez disso, o Dxgkrnl pode fornecer intervalos de endereços organizados logicamente.
Dxgkrnl impõe uma restrição nas GPUs: as GPUs precisam ter acesso a toda memória física do dispositivo para começar. Se o endereço mais alto e visível da GPU não excede o endereço físico na posição mais alta instalado no sistema, o Dxgkrnl não pode inicializar o adaptador. Os próximos servidores e estações de trabalho de ponta podem ser configurados com mais de 1 TB de memória, o que ultrapassa o limite de espaço do endereço de 40 bits de muitas GPUs. O remapeamento de AMD serve como um mecanismo para permitir que as GPUs funcionem nesse ambiente.
No momento da inicialização, o Dxgkrnl determina se o remapeamento lógico é obrigatório comparando o endereço físico acessível mais alto do dispositivo com a memória instalada no sistema. Se necessário, o remapeamento de AMD é feito para mapear um intervalo de endereços lógicos que está dentro dos limites visíveis da GPU para qualquer memória física no sistema. Por exemplo, se a GPU tiver um limite de 1 TB, o Dxgkrnl alocará endereços lógicos de [0, 1 TB) que podem ser mapeados para qualquer memória física no sistema por meio da IOMMU.
Comparação entre adaptadores lógicos e físicos
Dxgkrnl faz a distinção entre o conceito de um adaptador lógico e físico. Um adaptador físico representa um dispositivo de hardware individual que pode estar vinculado a outros dispositivos em uma cadeia LDA. Um adaptador lógico representa um ou mais adaptadores físicos vinculados.
Um único domínio de AMD da IOMMU é criado por adaptador lógico e anexado a todos os adaptadores físicos vinculados. Assim, todos os adaptadores físicos compartilham o mesmo domínio e a mesma visualização da memória física.
Comparação entre o suporte a GPU integrado e discreto
Como o remapeamento de AMD da IOMMU oferece pouco valor às GPUs integradas que, por definição, já devem ser projetadas para acessar toda a memória física do sistema, a implementação do suporte em partes integradas é opcional, mas recomendada.
GPUs discretas devem ter suporte ao remapeamento de AMD da IOMMU, que é um requisito para a certificação do WDDM 3.0.
Alterações de DDI
As seguintes alterações de DDI foram feitas para dar suporte ao remapeamento de AMD da IOMMU.
Funcionalidades do driver
É necessário usar dois conjuntos de limites de driver para dar suporte ao remapeamento linear:
- O driver deve informar o Dxgkrnl sobre as restrições de memória física, ou seja, sobre o endereço físico visível mais acima por meio do DXGKQAITYPE_PHYSICAL_MEMORY_CAPS e sua estrutura associada DXGK_PHYSICAL_MEMORY_CAPS.
- O driver deve indicar que tem suporte a remapeamento linear da IOMMU por meio do DXGKQAITYPE_IOMMU_CAPS e sua estrutura associada DXGK_IOMMU_CAPS. Ao indicar que há suporte, o driver está confirmando que todas as DDIs descritas posteriormente têm suporte e são usadas.
Os dois limites precisam ser fornecidos antes que o Dxgkrnl inicie o dispositivo pelo DXGKDDI_START_DEVICE para que o dispositivo seja criado e anexado a um domínio da IOMMU antes de acessar qualquer memória. O remapeamento linear só poderá ser realizado se o dispositivo não fizer referência a nenhuma memória física existente.
Acesso Exclusivo
Anexar e desanexar o domínio da IOMMU é uma tarefa bem rápida, mas ainda não é atômica. Essa condição prova que não há garantia de que uma transação emitida por PCIe será convertida corretamente durante a troca para um domínio da IOMMU com mapeamentos diferentes.
Para lidar com essa situação, a partir do Windows 10 versão 1803 (WDDM 2.4), o KMD precisa implementar o seguinte par de DDIs para que o Dxgkrnl chame:
- DxgkDdiBeginExclusiveAccess é chamado para notificar ao KMD que uma troca de domínio da IOMMU está prestes a ocorrer.
- DxgkDdiEndExclusiveAccess é chamado após a conclusão da troca de domínio da IOMMU.
O driver precisa ter um hardware silencioso quando o dispositivo mudar para um novo domínio da IOMMU. Ou seja, o driver deve conseguir ler e gravar na memória do sistema do dispositivo entre essas duas chamadas.
Entre essas duas chamadas, o Dxgkrnl garante o seguinte:
- O Agendador está suspenso. Todas as cargas de trabalho ativas são liberadas e nenhuma nova carga de trabalho é enviada ou agendada no hardware.
- Nenhuma outra chamada de DDI é feita.
Como parte dessas chamadas, o driver pode desativar e cancelar interrupções (incluindo interrupções Vsync) durante o acesso exclusivo, mesmo sem notificação explícita do sistema operacional.
Listas de descritores de endereços
Para oferecer suporte aos modos de acesso físico e lógico e alternar entre os dois modos perfeitamente em runtime, o Dxgkrnl fornece uma estrutura do DXGK_ADL que descreve uma lista de descritores de endereços (ADL). Essa estrutura de dados é semelhante a um MDL, mas descreve uma matriz de páginas que podem ser físicas ou lógicas. Como essas páginas podem ser lógicas, os endereços descritos por uma ADL não podem ser mapeados para um endereço virtual para acesso direto à CPU.
Operação do DXGK_OPERATION_MAP_APERTURE_SEGMENT2 para DxgkddiBuildpagingbuffer
O VidMm fornece a paginação do modo de buffer do DXGK_OPERATION_MAP_APERTURE_SEGMENT2 para mapear a memória para o segmento de abertura, pois a versão anterior usa um MDL incompatível com endereços lógicos. O retorno de chamada do DxgkddiBuildpagingbuffer dos drivers do WDDM 3.0 que dão suporte ao remapeamento de endereço lógico recebe chamadas para o modo DXGK_OPERATION_MAP_APERTURE_SEGMENT2 e não mais para o modo original DXGK_OPERATION_MAP_APERTURE_SEGMENT.
Essa operação é necessária para dar suporte ao remapeamento lógico do AMD. Ele se comporta de forma semelhante à operação original, mas fornece um DXGK_ADL em vez de um 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 aceitar a operação do DXGK_OPERATION_MAP_APERTURE_SEGMENT2, o driver precisa indicar suporte a chamadas do MapApertureSegment2 nos limites de gerenciamento de memória:
typedef struct _DXGK_VIDMMCAPS {
union {
struct {
...
UINT MapAperture2Supported : 1;
...
}
...
} DXGK_VIDMMCAPS;
Os limites de gerenciamento de memória do DXGK_VIDMMCAPS fazem parte da estrutura de dados do DXGK_DRIVERCAPS. O driver só pode usar o remapeamento do AMD (ou seja, o remapeamento de endereço lógico) com esse suporte habilitado.
Alguns drivers exigem acesso da CPU à memória durante uma chamada do MapApertureSegment2. Essa funcionalidade é fornecida opcionalmente por meio de outro parâmetro do MapApertureSegment2.CpuVisibleAddress. Esse é um endereço virtual no modo kernel válido desde que a alocação seja mapeada no segmento de abertura. Ou seja, esse endereço será liberado imediatamente depois de chamar o DXGK_OPERATION_UNMAP_APERTURE_SEGMENT correspondente para a mesma alocação.
Esse endereço pode não ser necessário para todas as alocações. O sinalizador do MapApertureCpuVisible foi adicionado aos sinalizadores de alocação para indicar quando é preciso usar esse endereço.
Se o MapApertureCpuVisible não for especificado, o MapApertureSegment2.CpuVisibleAddress é NULL para operações DXGK_OPERATION_MAP_APERTURE_SEGMENT2.
O MapApertureCpuVisible faz parte da funcionalidade do MapAperatureSegment2, chamadaDxgkDdiBuildPagingBuffer, então o driver precisa configurar o DXGK_VIDMMCAPS MapAperature2Supported para usar esse campo. Se o MapAperature2Supported não estiver definido, mas o driver especificar MapApertureCpuVisible, a chamada para DxgkDdiCreateAllocation falhará.
Além disso, para receber a operação DXGK_OPERATION_MAP_APERTURE_SEGMENT2, o driver precisa definir o sinalizador DXGK_ALLOCATIONINFOFLAGS_WDDM2_0 AccessedPhysically. Se o AccessedPhysically não estiver definido, qualquer alocação que especificar um segmento de abertura em seu conjunto de segmentos compatível será atualizada para o segmento de memória do sistema implícito, que não recebe chamadas MAP_APERTURE (já que não há intervalos de abertura a serem mapeados).
Em resumo, para receber corretamente o endereço da CPU de uma alocação de memória do sistema, o driver deve definir os seguintes sinalizadores/limites:
- DXGK_DRIVERCAPS::MemoryManagementCaps.MapAperture2Supported = 1
- DXGK_ALLOCATIONINFOFLAGS_WDDM2_0::MapApertureCpuVisible = 1
- DXGK_ALLOCATIONINFOFLAGS_WDDM2_0::AccessedPhysically = 1
Para chamadas do MapApertureSegment2, o ADL é sempre inicializado e passado como contíguo quando o mapeamento lógico está habilitado. O driver deve verificar os sinalizadores do ADL para determinar se a alocação é contígua, além de se comportar adequadamente.
Serviços de Gerenciamento de Memória
Há três requisitos fundamentais para as funções de gerenciamento de memória:
A capacidade de gerenciar a memória física. Essa funcionalidade pode incluir a alocação de memória por meio de funções de memória não paginadas, como MmAllocatePagesforMdl ou MmAllocateContiguousMemory, e as funções de memória paginadas, como ZwCreateSection ou ZwAllocateVirtualMemory. A capacidade de expressar intervalos de espaço de E/S também é necessária.
A capacidade de mapear um endereço lógico visível para GPU com base na memória física. Esse recurso forneceria ao chamador uma lista de páginas lógicas (muito parecidas com a matriz PFN de um MDL) que a GPU pode acessar quando programada. Chamar essas funções garantiria que as páginas físicas subjacentes fossem bloqueadas e não pagináveis.
A capacidade de mapear endereços virtuais da CPU pela memória física no modo de usuário e kernel, com um tipo de cache especificado (Cached x WriteCombined).
A tabela a seguir lista as DDIs e as estruturas de entrada associadas que foram introduzidas para descrever a alocação de memória física e o mapeamento de exibições lógicas/virtuais. Essas DDIs são um conjunto atualizado que substituirá os retornos de chamada anteriores fornecidos aos drivers para gerenciar mapeamentos da IOMMU (DxgkCbAllocatePagesforMdl, DxgkCbAllocateContiguousMemory e DxgkCbMapMdlToIoMmu). Para drivers do WDDM 3.0 com suporte ao remapeamento lógico, essas funções de retorno de chamada mais antigas foram preteridas e não podem ser usadas. Em vez disso, o driver deve usar as seguintes funções de retorno de chamada de gerenciamento de memória.
As funções de retorno de chamada devem ser chamadas em IRQL <= APC_LEVEL. A partir do WDDM 3.2, os drivers que chamam qualquer uma dessas funções são validados em relação a esse requisito e verificam se o IRQL é DISPATCH_LEVEL ou superior.
Alterações de INF
Cada tipo de dispositivo com suporte deve adicionar a seguinte chave e valor do registro à seção apropriada do INF:
[DMAr.reg]
; Add REG_DWORD 'DmaRemappingCompatible' with value of 3
HKR,Parameters,DmaRemappingCompatible,0x00010001,```3
Esse valor informa ao PnP que o dispositivo dá suporte ao remapeamento do AMD. O Dxgkrnl e o HAL trabalham juntos para definir qual tipo de modo de mapeamento deve ser usado (Remapeamento, Passagem e assim por diante).
Embora essa chave do registro estivesse presente em versões mais antigas do Windows, o valor "3" é exclusivo a partir do Windows 10 versão 1803 (WDDM 2.4) e é ignorado em versões mais antigas que sem suporte a ele. Esse valor exclusivo permite que os drivers definam essa chave no INF e não tenham que lidar com problemas de compatibilidade no nível inferior.