Test en mode noyau des fonctionnalités WDDM
Cet article décrit la conception de l’infrastructure de test en mode noyau dans WDDM qui a été ajoutée dans Windows 11 version 24H2 (WDDM 3.2). Cette infrastructure permet de tester et de valider des pilotes qui ne prennent pas en charge les runtimes D3D, tels que les pilotes pour certains périphériques NPU. Il peut également être utilisé pour valider les pilotes qui prennent en charge les runtimes D3D sans impliquer le runtime D3D.
Vue d’ensemble
Il existe des scénarios où de nouveaux appareils de calcul basés sur WDDM ou MCDM sont introduits et les pilotes pour ces appareils ne prennent pas en charge les runtimes D3D. Pour vous aider à valider ces pilotes, les fonctionnalités sont ajoutées à Dxgkrnl pour effectuer la validation à l’aide de thunks en mode noyau uniquement ; autrement dit, sans impliquer le runtime D3D et le pilote en mode utilisateur (UMD).
Cette infrastructure permet également de tester la fonctionnalité WDDM à l’aide de paramètres précis sans avoir à passer par un runtime D3D ou un UMD, ce qui peut compliquer les choses.
Les DDIS sont introduites pour générer une mémoire tampon de commandes en mode noyau pour un ensemble donné de commandes. Les commandes sont simples, donc presque n’importe quel nœud d’exécution doit être en mesure de les exécuter à l’aide de nuanceurs précompilés ou d’autres moyens.
Pour prendre en charge cette fonctionnalité, le pilote en mode noyau (KMD) doit fournir la prise en charge suivante :
- Signalez que la fonctionnalité DXGK_FEATURE_KERNEL_MODE_TESTING est activée.
- Implémentez l’interface de fonctionnalité DXGKDDI_KERNELMODETESTINGINTERFACE .
- Fournissez des informations sur le nœud d’exécution qui prend en charge la génération et l’exécution des mémoires tampons de commande de test.
- Prise en charge de la création d’une file d’attente de contexte/matériel sans données de pilote privé. En règle générale, le format des commandes de pilote privé est nécessaire pour envoyer une charge de travail à un appareil. L’interface de test autorise la soumission de charge de travail sans données de pilote privé.
- Prise en charge de l’exécution des mémoires tampons de commande créées par pfnBuildTestCommandBuffer sur n’importe quel nœud de l’appareil qui prend en charge la fonctionnalité.
- Prise en charge d’un handle d’allocation NULL dans la pagination des DDIs (TRANSFER, FILL, etc.).
Cette fonctionnalité est utilisée uniquement lorsque la signature de test est activée sur l’ordinateur.
Les tests HLK qui utilisent cette fonctionnalité seront développés.
Modifications de l’DDI
Les structures et l’énumération suivantes ont été mises à jour pour prendre en charge les tests en mode noyau :
DXGK_FEATURE_KERNEL_MODE_TESTING est ajouté à l’énumération DXGK_FEATURE_ID.
SupportBuildTestCommandBuffer est ajouté à la structure DXGK_NODEMETADATA_FLAGS .
TestContext est ajouté à la structure DXGK_CREATECONTEXTFLAGS .
TestQueue est ajouté à la structure D3DDDI_CREATEHWQUEUEFLAGS .
Les DDIs, les structures et l’énumération suivants sont ajoutés pour prendre en charge les tests en mode noyau :
L’interface de fonctionnalité DXGKDDI_KERNELMODETESTINGINTERFACE est ajoutée, avec DXGKDDI_BUILDTESTCOMMANDBUFFER ::p fnBuildTestCommandBuffer comme seul membre de l’interface.
Prise en charge des rapports pour la fonctionnalité de test en mode noyau
Le système d’exploitation appelle la fonction DxgkDdiQueryFeatureSupport de KMD avec l’ID de fonctionnalité DXGK_FEATURE_KERNEL_MODE_TESTING ajouté pour vérifier si le pilote prend en charge les tests en mode noyau. Le kmD doit signaler que la fonctionnalité est prise en charge.
Le système appelle ensuite DxgkDdiQueryFeatureInterface avec le même ID de fonctionnalité pour obtenir le pointeur de fonction d’interface pour pfnBuildTestCommandBuffer. KMD doit implémenter cette fonction et fournir son pointeur pour l’interface DXGKDDI_KERNELMODETESTINGINTERFACE.
Création de rapports sur les nœuds d’exécution qui prennent en charge les tests en mode noyau
SupportBuildTestCommandBuffer est ajouté à la structure DXGK_NODEMETADATA_FLAGS . KMD doit définir cet indicateur pour indiquer que le nœud peut exécuter des mémoires tampons de commande générées par pfnBuildTestCommandBuffer. Il est recommandé de prendre en charge autant de nœuds que possible la fonctionnalité.
Création d’un contexte sans données privées
TestContext est ajouté à DXGK_CREATECONTEXTFLAGS pour indiquer qu’un contexte est un contexte de test. Cet indicateur a un effet uniquement lorsque la signature de test est activée.
DxgkDdiCreateContext de KMD doit prendre en charge la création d’un contexte sans données privées pour chaque nœud qui prend en charge l’exécution des mémoires tampons de commande produites par pfnBuildTestCommandBuffer. Pour indiquer cette prise en charge, définissez l’indicateur TestContext dans Les indicateurs lors de la création du contexte.
Création d’une file d’attente matérielle sans données privées de pilote
TestQueue est ajouté à D3DDDI_CREATEHWQUEUEFLAGS pour indiquer qu’une file d’attente matérielle est une file d’attente de test. Cet indicateur a un effet uniquement lorsque la signature de test est activée.
DxgkDdiCreateHwQueue de KMD doit prendre en charge la création d’une file d’attente matérielle sans données privées de pilote.
Génération d’une mémoire tampon de commande
Le pfnBuildTestCommandBuffer de KMD génère une mémoire tampon de commandes avec des instructions spécifiques à l’appareil pour un ensemble de commandes simples. KMD retourne un pointeur vers cette fonction à partir de DxgkDdiQueryFeatureInterface(DXGK_FEATURE_KERNEL_MODE_TESTING).
Une seule commande de test est envoyée à pfnBuildTestCommandBuffer. Les commandes suivantes sont actuellement prises en charge :
Commande | Description |
---|---|
D3DDDI_TESTCOMMAND_COPY | Copie les octets à l’aide d’adresses virtuelles GPU source et de destination. |
D3DDDI_TESTCOMMANDBUFFER_FILL | Remplit un emplacement de mémoire avec un modèle. |
Les commandes de test sont basées sur l’utilisation d’adresses virtuelles GPU. Le système d’exploitation garantit que les machines virtuelles GPU sont mappées aux allocations créées avec un type d’allocation standard de D3DKMT_STANDARDALLOCATIONTYPE_EXISTINGHEAP ou de D3DKMT_STANDARDALLOCATIONTYPE_INTERNALBACKINGSTORE.
La mémoire tampon de commande générée et les données privées sont retournées en mode utilisateur. Lorsque la mémoire tampon de commandes est envoyée pour l’exécution, l’appel provient du mode utilisateur. Une application malveillante peut modifier le contenu de la mémoire tampon et des données privées. Il incombe à KMD de valider à la fois la mémoire tampon de commande et les données du pilote privé pour éviter les vérifications de bogues.
La mémoire tampon de commande générée ne doit pas contenir d’instructions privilégiées.
Un pilote client en mode utilisateur (par exemple, Cuda) envoie la mémoire tampon de commande générée pour l’exécution à l’aide de D3DKMTSubmitCommand ou D3DKMTSubmitCommandToHwQueue. À l’avenir, le contenu de la mémoire tampon sera envoyé dans le cadre de la soumission en mode utilisateur.
Lorsqu’une mémoire tampon de commande générée est envoyée pour l’exécution, elle est garantie que la mémoire tampon de commande contient des instructions d’appareil pour une seule commande de test.
La mémoire tampon de commande générée est envoyée au nœud qui correspond au hContext passé à pfnBuildTestCommandBuffer.
La taille de la mémoire tampon DMA (pDmaBuffer) est limitée à 4 Ko et la taille des données de pilote privé DMA (pDmaBufferPrivateData) est limitée à 1 Ko.