Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Esta página descreve o recurso de remapeamento IOMMU DMA (IOMMUv2) que foi introduzido no Windows 11 22H2 (WDDM 3.0). Consulte Isolamento de GPU baseado em IOMMU para obter informações sobre o isolamento de GPU IOMMU antes do WDDM 3.0.
Visão geral
Até o WDDM 3.0, o Dxgkrnl suportava apenas o isolamento IOMMU por meio de remapeamento físico 1:1, o que significa que as páginas lógicas acessadas pela GPU eram traduzidas para o mesmo número de página física. O remapeamento IOMMU DMA permite que a GPU acesse a memória através de endereços lógicos que não são mais mapeados 1:1. Em vez disso, o Dxgkrnl é capaz de fornecer intervalos de endereços logicamente contíguos.
O Dxgkrnl impõe uma restrição às GPUs: as GPUs devem ser capazes de acessar toda a memória física para que o dispositivo seja iniciado. Se o endereço visível mais alto da GPU não exceder o endereço físico mais alto instalado no sistema, o Dxgkrnl falhará na inicialização do adaptador. Os próximos servidores e estações de trabalho high-end podem ser configurados com mais de 1 TB de memória que ultrapassa a limitação comum de espaço de endereçamento de 40 bits de muitas GPUs. O remapeamento de DMA é usado como um mecanismo para permitir que as GPUs trabalhem nesse ambiente.
No momento da inicialização, o Dxgkrnl determina se o remapeamento lógico é necessário, comparando o endereço físico mais acessível do dispositivo com a memória instalada no sistema. Se for necessário, o remapeamento DMA é usado para mapear um intervalo de endereços lógicos que esteja 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 aloca endereços lógicos de [0, 1 TB) que podem ser mapeados para qualquer memória física no sistema através do IOMMU.
Adaptadores lógicos versus físicos
Dxgkrnl distingue 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 IOMMU DMA é 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 visão da memória física.
Suporte a GPU integrada versus discreta
Como o remapeamento IOMMU DMA oferece pouco valor para GPUs integradas que, por definição, já devem ser projetadas para acessar toda a memória física do sistema, a implementação de suporte em partes integradas é opcional, mas recomendada.
GPUs discretas devem suportar o remapeamento IOMMU DMA, que é um requisito para a certificação WDDM 3.0.
Alterações no DDI
As seguintes alterações de DDI foram feitas para dar suporte ao remapeamento de DMA da IOMMU.
Capacidades do controlador
Dois conjuntos de limites de driver são necessários para suportar o remapeamento linear:
- O condutor deve informar a Dxgkrnl sobre as suas restrições de memória física; ou seja, sobre o seu endereço físico visível mais elevado através DXGKQAITYPE_PHYSICAL_MEMORY_CAPS e a sua estrutura DXGK_PHYSICAL_MEMORY_CAPS associada.
- O controlador deve indicar o seu suporte para o remapeamento linear IOMMU através de DXGKQAITYPE_IOMMU_CAPS e a sua estrutura associada DXGK_IOMMU_CAPS. Ao indicar o suporte, o driver está indicando que todas as DDIs descritas posteriormente são suportadas e usadas.
Ambos os limites devem ser fornecidos antes que o Dxgkrnl inicie o dispositivo via DXGKDDI_START_DEVICE para que o dispositivo possa ser criado e conectado a um domínio IOMMU antes que qualquer memória possa ser acessada. O remapeamento linear só pode ser feito se o dispositivo não fizer referência a nenhuma memória física existente.
Acesso Exclusivo
A anexação e desanexação de domínio IOMMU é extremamente rápida, mas não é atualmente atómica. Essa condição significa que não é garantido que uma transação emitida por PCIe seja traduzida corretamente durante a troca para um domínio IOMMU com mapeamentos diferentes.
Para lidar com esta situação, a partir do Windows 10 versão 1803 (WDDM 2.4), um KMD deve implementar o seguinte par DDI para que Dxgkrnl possa chamar:
- DxgkDdiBeginExclusiveAccess é chamado para notificar o KMD de que uma alternância de domínio IOMMU está prestes a acontecer.
- DxgkDdiEndExclusiveAccess é chamado depois de a comutação de domínio IOMMU estar completa.
O driver deve garantir que seu hardware seja silencioso sempre que o dispositivo for alternado para um novo domínio IOMMU. Ou seja, o driver deve garantir que ele não lê ou grava na memória do sistema do dispositivo entre essas duas chamadas.
Entre estas duas chamadas, Dxgkrnl faz as seguintes garantias:
- 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 DDI é feita.
Como parte dessas chamadas, o motorista pode optar por desativar e suprimir 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 suportar os modos de acesso físico e lógico e alternar entre os dois modos perfeitamente em tempo de execução, o Dxgkrnl fornece uma estrutura DXGK_ADL que descreve uma lista de descritores de endereços (ADL). Essa estrutura de dados é semelhante a uma MDL, mas descreve uma matriz de páginas que podem ser físicas ou lógicas. Como essas páginas podem ser páginas lógicas, os endereços descritos por uma ADL não podem ser mapeados para um endereço virtual para acesso direto à CPU.
DXGK_OPERATION_MAP_APERTURE_SEGMENT2 operação do DxgkddiBuildpagingbuffer
O VidMm fornece o modo de buffer de paginação DXGK_OPERATION_MAP_APERTURE_SEGMENT2 para mapear a memória para o segmento de "aperture", uma vez que a versão anterior usa um MDL que é incompatível com endereços lógicos. A função de retorno de chamada DxgkddiBuildpagingbuffer dos drivers WDDM 3.0 que suportam o remapeamento de endereços lógicos recebe chamadas para o modo DXGK_OPERATION_MAP_APERTURE_SEGMENT2 e não recebe mais chamadas para o modo DXGK_OPERATION_MAP_APERTURE_SEGMENT original.
Esta operação é necessária para suportar o remapeamento lógico do DMA. 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 aderir à operação DXGK_OPERATION_MAP_APERTURE_SEGMENT2, o driver deve indicar o suporte para chamadas MapApertureSegment2 nas capacidades de gestão de memória:
typedef struct _DXGK_VIDMMCAPS {
union {
struct {
...
UINT MapAperture2Supported : 1;
...
}
...
} DXGK_VIDMMCAPS;
Os limites de gerenciamento de memória DXGK_VIDMMCAPS fazem parte da estrutura de dados DXGK_DRIVERCAPS . O driver não pode usar a funcionalidade de remapeamento DMA (ou seja, remapeamento de endereço lógico) sem esse suporte habilitado.
Alguns drivers podem exigir acesso da CPU à memória durante uma chamada MapApertureSegment2 . Esta funcionalidade é opcionalmente fornecida através de outro parâmetro MapApertureSegment2.CpuVisibleAddress . Este endereço é um endereço virtual em modo kernel que é válido desde que a alocação esteja mapeada no segmento de abertura. Ou seja, esse endereço será liberado imediatamente após a chamada de DXGK_OPERATION_UNMAP_APERTURE_SEGMENT correspondente para a mesma alocação.
Este endereço pode não ser necessário para todas as alocações. O sinalizador MapApertureCpuVisible foi adicionado aos sinalizadores de alocação para indicar quando esse endereço é necessário.
Se MapApertureCpuVisible não for especificado, MapApertureSegment2.CpuVisibleAddress fica NULL para operações DXGK_OPERATION_MAP_APERTURE_SEGMENT2.
MapApertureCpuVisible é uma parte da funcionalidade MapAperatureSegment2 do DxgkDdiBuildPagingBuffer, portanto, o driver deve definir DXGK_VIDMMCAPS MapAperature2Supported para usar este campo. Se 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 deve definir o sinalizador DXGK_ALLOCATIONINFOFLAGS_WDDM2_0 AccessedPhysically. Se AccessedFisicamente não estiver definido, qualquer alocação que especifique um segmento de abertura no seu conjunto de segmentos suportados será atualizada para o segmento implícito de memória do sistema, que não recebe chamadas para MAP_APERTURE (já que não há intervalos de abertura para mapear).
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/tampas:
- DXGK_DRIVERCAPS::MemoryManagementCaps.MapAperture2Supported = 1
- DXGK_ALLOCATIONINFOFLAGS_WDDM2_0::MapApertureCpuVisible = 1
- DXGK_ALLOCATIONINFOFLAGS_WDDM2_0::AccessedFisicamente = 1
Para chamadas MapApertureSegment2 , a ADL é sempre inicializada e passada como contígua quando o mapeamento lógico está habilitado. O condutor deve verificar as bandeiras ADL para determinar se a atribuição é contígua e comportar-se em conformidade.
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. Esse recurso pode incluir a alocação de memória por meio de funções de memória não paginadas, como MmAllocatePagesforMdl ou MmAllocateContiguousMemory, e funções de memória paginada, como ZwCreateSection ou ZwAllocateVirtualMemory. A capacidade de expressar intervalos de espaços de E/S também é necessária.
A capacidade de mapear um endereço lógico visível por GPU a partir da 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 ser programada para acessar. Chamar essas funções garantiria que as subjacentes páginas físicas fossem bloqueadas e não possam ser paginadas.
A capacidade de mapear endereços virtuais da CPU a partir da memória física no modo de usuário e no modo kernel, com um tipo de cache especificado (Cached vs WriteCombined).
A tabela a seguir lista os DDIs e as estruturas de entrada associadas 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 destinado a substituir as callbacks anteriores fornecidas aos drivers para a gestão de mapeamentos do IOMMU (DxgkCbAllocatePagesforMdl, DxgkCbAllocateContiguousMemory, DxgkCbMapMdlToIoMmu). Para os controladores WDDM 3.0 que suportam remapeamento lógico, as 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 callback para gestão de memória.
As funções de retorno de chamada devem ser chamadas no 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 do INF
Cada tipo de dispositivo suportado deve adicionar a seguinte chave de registo e valor na secçã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 suporta o remapeamento DMA. Dxgkrnl e o HAL então coordenam para determinar que tipo de modo de mapeamento deve ser usado (Remapping, Passthrough 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 compilações mais antigas que não oferecem suporte a ele. Esse valor exclusivo permite que os drivers definam essa chave no INF e não se preocupem com problemas de compatibilidade no nível inferior.