Delen via


Een CPU-gebeurtenis signaleren vanuit een kernelmodusstuurprogramma

Er zijn gevallen waarin het stuurprogramma van de kernelmodus (KMD) een CPU-gebeurtenis moet signaleren om het stuurprogramma voor de gebruikersmodus (UMD) over iets te melden; bijvoorbeeld:

  • Wanneer KMD detecteert dat een van de objecten een slechte status heeft en UMD moet melden.
  • Tijdens GPU-foutopsporing waarbij KMD moet communiceren met UMD dat er een gebeurtenis is opgetreden. Voor IHV's met controlpanels voor GPU stelt het signaleren van CPU-gebeurtenissen door KMD de applicatie Control Panels in staat om op de hoogte te blijven van interne gebeurtenissen.

Normaal gesproken kan UMD een CPU-gebeurtenis maken en de NT-handle doorgeven aan KMD in privégegevens voor ontsnapping. Deze methode werkt niet in het scenario voor GPU-paravirtualisatie (GPU-PV), omdat NT-ingangen niet kunnen worden gebruikt binnen grenzen van virtuele machines.

Vanaf Windows 11 versie 21H2 (WDDM 3.0) is de WDDM-API uitgebreid zodat UMD een CPU-gebeurtenisobject kan maken dat kan worden gesignaleerd door KMD. Deze functie werkt zowel wanneer UMD wordt uitgevoerd op de host of op een virtuele machine met GPU-PV.

Functieproces

Het synchronisatieobject kan niet worden ingevoegd in een contextwachtrij. Het kan alleen worden gesignaleerd door KMD met behulp van DXGKCB_SIGNALEVENT.

API's in de gebruikersmodus voor het verwerken van CPU-gebeurtenissynchronisatieobjecten

Aanmaken van het KMD CPU-gebeurtenisobject

Het KMD CPU-gebeurtenisobject wordt gemaakt als een GPU-synchronisatieobject door D3D12DDICB_CREATESYNCHRONIZATIONOBJECT2 aan te roepen met:

  • Type is ingesteld op D3DDDI_CPU_NOTIFICATION.

  • vlaggen ingesteld op SignalByKmd om aan te geven dat het object wordt gesignaleerd door KMD. Deze vlag kan alleen worden ingesteld wanneer het type lid vanD3DDDI_SYNCHRONIZATIONOBJECTINFO2 is D3DDDI_CPU_NOTIFICATION.

Wanneer de vlag SignalByKmd is ingesteld, wordt DXGKDDI_CREATECPUEVENT aangeroepen om het KMD CPU-gebeurtenisobject te maken. Houd er rekening mee dat de apparaatgreep moet worden opgegeven bij het maken van het synchronisatieobject.

Het synchronisatieobject kan niet worden gebruikt in signaal- en wacht-API's (D3DKMTSignalSynchronizationObject, D3DKMTWaitForSynchronizatioObject). Het kan alleen worden gesignaleerd door KMD en UMD kan wachten op de bijbehorende CPU-gebeurtenis.

UMD escape om het gebruik van een KMD CPU-evenement-synchronisatieobject te definiëren

Er is een bekende ontsnappingsmogelijkheid toegevoegd aan D3DDDI_DRIVERESCAPETYPE. D3DDDI_DRIVERESCAPETYPE_CPUEVENTUSAGE wordt gebruikt om KMD op de hoogte te stellen van het beoogde gebruik van een KMD CPU-gebeurtenisobject. Een bekende escape wordt gedefinieerd door DXGKARG_ESCAPE::Flags.DriverKnownEscape = 1 in te stellen. Bekende escapes worden zelfs vanaf beveiligde virtuele machines naar de host verzonden.

Het volgende codefragment is een gebruiksvoorbeeld.

D3DDDI_DRIVERESCAPE_CPUEVENTUSAGE Command = {};
Command.EscapeType = D3DDDI_DRIVERESCAPETYPE_CPUEVENTUSAGE;
Command.hSyncObject = SyncObjectHandle;
Command.Usage[0] = 1;

D3DKMT_ESCAPE Args = {};
Args.hAdapter = AdapterHandle;
Args.Type = D3DKMT_ESCAPE_DRIVERPRIVATE;
Args.Flags.DriverKnownEscape = 1;
Args.Flags.NoAdapterSynchronization = 1; // Prevent waking up the device from D3
Args.pPrivateDriverData = &Command;
Args.PrivateDriverDataSize = sizeof(Command);

NTSTATUS Status = D3DKMTEscape(&Args);

Dxgkrnl roept DXGKDDI_ESCAPE aan met het volgende:

  • hDevice- ingesteld op de miniport-apparaatgreep die is gebruikt om het synchronisatieobject te maken
  • pPrivateDriverData die verwijst naar een D3DDDI_DRIVERESCAPE_CPUEVENTUSAGE-structuur
  • PrivateDriverDataSize ingesteld op sizeof(D3DDDI_DRIVERESCAPE_CPUEVENTUSAGE)

Een KMD CPU-gebeurtenisobject maken en vernietigen

De volgende DDIs worden gebruikt om KMD CPU-gebeurtenis-synchronisatie-objecten te maken en te vernietigen:

Een CPU-gebeurtenisobject signaleren door KMD

Als u een CPU-gebeurtenisobject wilt signaleren, roept KMD DXGKCB_SIGNALEVENT aan bij IRQL <= DISPATCH_LEVEL en met de DXGKARGCB_SIGNALEVENT structuurwaarden die als volgt zijn ingesteld:

  • hDxgkProcess is gelijk aan 0.

  • hEvent is gelijk aan de CPU-gebeurtenisobjecthandle Dxgkrnl die is doorgegeven aan DXGKDDI_CREATECPUEVENT.

  • CpuEventObject- moet 1 zijn.

  • gereserveerde moet 0 zijn.