pcivirt.h-Header

Referenzhandbuch zur Verwendung von Schnittstellen, die verwendet werden, um VFs für einen virtuellen Computer verfügbar zu machen.

Geräte, die der SPEZIFIKATION PCI Express Single-Root I/O Virtualization (SR-IOV) entsprechen, können mehrere Schnittstellen für das Gerät bereitstellen. Diese Schnittstellen, die als virtuelle Funktionen (Virtual Functions, VFs) bezeichnet werden, sind unabhängig und werden über die anfängliche Geräteschnittstelle bereitgestellt, die als physische Funktion (Pf) bezeichnet wird. Beispielsweise kann eine Ethernet-Netzwerkkarte, die SR-IOV unterstützt, so konzipiert werden, dass sie über einen Switch mit einem physischen Ethernet-Port (verbunden mit dem physischen Kabel) und vielen virtuellen Ethernet-Ports verfügt.

Der Konfigurationsraum der PF ermöglicht es dem PF-Treiber, die PCI-Ressourcen des VF zu verwalten, einschließlich speicherabbildendem E/A-Speicherplatz und Nachrichtensignalunterbrechungen. Da es sich bei VFs um eine Teilmenge eines vollständigen Geräts handelt, kann die Bereitstellung in der Hardware kostengünstiger sein als eine herkömmliche Funktion in einem Multifunktionspaket. Dies ermöglicht es dem Gerätehersteller, mehr Schnittstellen zu erstellen und alle freigegebenen Ressourcen zentral zu verwalten.

Wenn Windows direkt auf der Computerhardware ausgeführt wird, nehmen die Gerätetreiber an Vorgängen im Zusammenhang mit Plug and Play, Energieverwaltung, Interruptverwaltung und anderen Aufgaben teil. Ein vertrauenswürdiger Windows-Bustreiber und eine EIGENE HAL-Buskonfiguration (Hardware Abstraction Layer) und konfigurieren den gesamten Bus. Der Treiber wird innerhalb derselben Berechtigungsstufe ausgeführt, und es gibt keine Vertrauensgrenzen im Kernelmodus.

Wenn Windows auf einem virtuellen Computer (VM) ausgeführt wird, gelten diese Annahmen nicht. VFs können der Kontrolle eines nicht privilegierten virtuellen Computers unterstellt werden. Die Hardware muss jedoch sicherheitsgeprüft werden, damit die Sicherheit oder Leistung des Systems nicht beeinträchtigt wird.

Wenn ein Treiber, der auf dem VF ausgeführt wird, einen Lese- oder Schreibzugriff auf einen Konfigurationsspeicher anfordert, wird die Anforderung vom Virtualisierungsstapel empfangen und an den PF-Treiber des SR-IOV-Geräts gesendet. Es liegt in der Verantwortung des PF-Treibers, auf diese Anforderungen zu reagieren und Details für den VF anzugeben. Der PF-Treiber erfordert gelegentlich eine Lese- oder Schreibanforderung für die Konfiguration, die an die Hardware übergeben wird.

Der Stapel verwendet eine E/A-MMU, um Datenverkehr von den verschiedenen Schnittstellen zu unterscheiden, die das Gerät verfügbar macht, und erzwingt eine Richtlinie darüber, auf welche Speicherbereiche ein Gerät zugreifen kann und welche Unterbrechungen es generieren kann.

PCI-Virtualisierung.

Hardwareanforderungen

Das für die SR-IOV-Gerätezuweisung zu verwendende System muss die Anforderungen für SR-IOV-Netzwerke und direkte Gerätezuweisung erfüllen. Das System muss über eine IOMMU verfügen, die IOMMU so konfiguriert sein muss, dass die Steuerung der Geräte an das Betriebssystem übertragen wird, und PCIe ACS (Access Control Services) muss aktiviert und für die Verwendung durch das Betriebssystem konfiguriert sein. Schließlich darf das betreffende Gerät keine leitungsbasierten Interrupts verwenden und darf keine ATS (Address Translation Services) erfordern.

Weitere Informationen finden Sie hier:

Alles, was Sie über SR-IOV in Hyper-V wissen wollten. Teil 1:

Diskrete Gerätezuweisung – Beschreibung und Hintergrund

So ermitteln Sie, ob ein System die Gerätezuweisung unterstützt und ob ein bestimmtes PCI-Gerät für die Gerätezuweisung funktioniert:

Skript für die diskrete Gerätezuweisung

Abfragen von SR-IOV-Geräten

GUID_DEVINTERFACE_VIRTUALIZABLE_DEVICE ist eine Geräteklassenschnittstelle, die von Treibern für SR-IOV-Geräte bereitgestellt wird. Diese GUID bietet eine Möglichkeit, alle Gerätestapel abzufragen, die die verschiedenen Funktionstabellen verfügbar machen, die zum Verwalten der virtualisierungsbezogenen Features des Geräts verwendet werden. Nachdem der Treiber die GUID registriert hat, werden einzelne Funktionen ermittelt, indem IRP_MN_QUERY_INTERFACE gesendet wird. Der Treiber muss auf diese Anforderung mit GUID_SRIOV_DEVICE_INTERFACE_STANDARD antworten. Treiber müssen auch IOCTL_SRIOV_NOTIFICATION und IOCTL_SRIOV_EVENT_COMPLETE verarbeiten.

Ein Treiber für ein SR_IOV Gerät, das auf einer privilegierten VM ausgeführt wird, ist das Hostbetriebssystem. Es besitzt Plug-and-Play- und Energieverwaltung für einen gesamten Computer und macht PCI Express SR-IOV Virtual Functions auf nicht privilegierten VMs verfügbar, muss die GUID_SRIOV_DEVICE_INTERFACE_STANDARD bereitstellen (definiert im Header Pcivirt.h). Bei diesem Treiber kann es sich um den PF-Treiber (PCI Express SR-IOV Physical Function) handelt, der die FDO erstellt, oder es kann ein niedrigerer Filter auf diesem Geräteknoten sein, wenn die FDO von einem Porttreiber verwaltet wird.

Die Geräteschnittstelle ist erforderlich, damit der Treiber auf den Konfigurationsraum der VFs zugreifen kann.

Führen Sie in der implementierung des EVT_WDF_DRIVER_DEVICE_ADD des PF-Treibers die folgenden Aufgaben aus:

  • Nachdem Sie WdfDeviceCreate aufgerufen haben, um das Funktionsgeräteobjekt (Function Device Object, FDO) zu erstellen, rufen Sie WdfDeviceCreateDeviceInterface auf, um GUID_DEVINTERFACE_VIRTUALIZABLE_DEVICE zu registrieren. Dadurch kann der Virtualisierungsstapel ein Gerätehandle auf das SR-IOV-Gerät abrufen.
  • Machen Sie die GUID_SRIOV_DEVICE_INTERFACE_STANDARD verfügbar.
    • Initialisieren Sie eine SRIOV_DEVICE_INTERFACE_STANDARD-Struktur, und legen Sie Member auf Funktionszeiger der vom PF-Treiber implementierten Rückruffunktionen fest.
    • Konfigurieren Sie die -Struktur, indem Sie WDF_QUERY_INTERFACE_CONFIG_INIT aufrufen.
    • Registrieren Sie die Schnittstelle bei der FDO, indem Sie WdfDeviceAddQueryInterface aufrufen.
    // Make the device visible as an assignable device.
    //
    status = WdfDeviceCreateDeviceInterface(
        fdo,
        &GUID_DEVINTERFACE_VIRTUALIZABLE_DEVICE,
        NULL);
    if (!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_INIT,
                    "Failed to create interface: %!STATUS!",
                    status);
        goto Cleanup;
    }

    //
    // Expose SRIOV_DEVICE_INTERFACE_STANDARD
    //
    RtlZeroMemory(&sriovInterface, sizeof(sriovInterface));
    sriovInterface.Size = sizeof(sriovInterface);
    sriovInterface.Version = 1;
    sriovInterface.Context = deviceContext;
    sriovInterface.InterfaceReference = Virtualization_ReferenceInterface;
    sriovInterface.InterfaceDereference = Virtualization_DereferenceInterface;
    sriovInterface.ReadVfConfig = Virtualization_ReadConfig;
    sriovInterface.WriteVfConfig = Virtualization_WriteConfig;
    sriovInterface.ReadVfConfigBlock = Virtualization_ReadBlock;
    sriovInterface.WriteVfConfigBlock = Virtualization_WriteBlock;
    sriovInterface.ResetVf = Virtualization_ResetFunction;
    sriovInterface.SetVfPowerState = Virtualization_SetPowerState;
    sriovInterface.GetDeviceLocation = Virtualization_GetDeviceLocation;
    sriovInterface.GetVendorAndDevice = Virtualization_GetVendorAndDevice;
    sriovInterface.QueryProbedBars = Virtualization_QueryProbedBars;
    sriovInterface.QueryLuid = Virtualization_QueryLuid;


    WDF_QUERY_INTERFACE_CONFIG_INIT(&qiConfig,
                                    (PINTERFACE)&sriovInterface,
                                    &GUID_SRIOV_DEVICE_INTERFACE_STANDARD,
                                    NULL);

    status = WdfDeviceAddQueryInterface(fdo, &qiConfig);

    if (!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_INIT,
                    "WdfDeviceAddQueryInterface failed: %!STATUS!\n",
                    status);
        goto Cleanup;
    }

Behandeln von Plug-and-Play-Ereignissen

Der Virtualisierungsstapel ist dafür verantwortlich, die entsprechenden Nachrichten an den virtuellen Computer zu senden, auf die Antwort (mit einem Timeout) zu warten und im Falle einer nicht reagierenden VM eine entsprechende Aktion anzuwenden, z. B. das Veto des PnP-Ereignisses oder das überraschende Entfernen des Geräts von der nicht privilegierten VM. PF-Treiber, die GUID_DEVINTERFACE_VIRTUALIZABLE_DEVICE implementieren, müssen auch diese E/A-Steuerungsanforderungen verarbeiten, die es dem Virtualisierungsstapel ermöglichen, auf PnP-Ereignisse zu reagieren.

  • Der Virtualisierungsstapel sendet zuerst IOCTL_SRIOV_ATTACH an das Gerät. Dadurch wird das Gerät benachrichtigt, dass der Virtualisierungsstapel über bestimmte PnP-Ereignisse benachrichtigt werden muss.

  • Dies ist in Kraft, bis der Virtualisierungsstapel IOCTL_SRIOV_DETACH sendet.

  • Der Virtualisierungsstapel fragt die Geräte nach PnP-Ereignissen ab, indem IOCTL_SRIOV_NOTIFICATION Anforderungen gesendet werden. Der PF-Treiber kann den Virtualisierungsstapel über ein PnP-Ereignis informieren, indem er die IOCTL_SRIOV_NOTIFICATION-Anforderung abschließt.

  • Der Virtualisierungsstapel hebt die Blockierung dieser Ereignisse auf, indem IOCTL_SRIOV_EVENT_COMPLETE gesendet wird.

pcivirt.h enthält die folgenden Programmierschnittstellen:

IOCTLs

 
IOCTL_SRIOV_ATTACH

Die Anforderung gibt an, dass der Virtualisierungsstapel sich für Plug-and-Play-Ereignisse registrieren möchte, die vom SR-IOV-Gerät empfangen werden.
IOCTL_SRIOV_DETACH

Die Anforderung gibt an, dass der Virtualisierungsstapel die Registrierung für Plug-and-Play-Ereignisse aufheben möchte (die zuvor über die IOCTL_SRIOV_ATTACH-Anforderung registriert wurden).
IOCTL_SRIOV_EVENT_COMPLETE

Die Anforderung gibt an, dass der Virtualisierungsstapel oder das SR-IOV-Gerät eines der in SRIOV_PF_EVENT aufgeführten Ereignisse empfangen hat.
IOCTL_SRIOV_INVALIDATE_BLOCK

Die IOCTL_SRIOV_INVALIDATE_BLOCK-Anforderung gibt an, dass der Virtualisierungsstapel den Inhalt des angegebenen Konfigurationsblocks zurücksetzen möchte.
IOCTL_SRIOV_MITIGATED_RANGE_UPDATE

Die IOCTL_SRIOV_MITIGATED_RANGE_UPDATE-Anforderung gibt an, dass der Virtualisierungsstapel auf die Entschärfungsbereiche aktualisiert werden soll.
IOCTL_SRIOV_NOTIFICATION

Die Anforderung gibt an, dass der Virtualisierungsstapel benachrichtigt werden möchte, wenn eines der in SRIOV_PF_EVENT aufgeführten Ereignisse auftritt.
IOCTL_SRIOV_PROXY_QUERY_LUID

Diese Anforderung stellt den lokalen eindeutigen Bezeichner des SR_IOV Geräts bereit, das die Schnittstelle implementiert.
IOCTL_SRIOV_QUERY_MITIGATED_RANGE_COUNT

Die Anforderung bestimmt die Bereiche des im Speicher zugeordneten E/A-Speicherplatzes, der entschärft werden muss.
IOCTL_SRIOV_QUERY_MITIGATED_RANGES

Die Anforderung bestimmt die spezifischen Bereiche, in denen Intercepts platziert werden müssen.

Rückruffunktionen

 
READ_WRITE_MITIGATED_REGISTER

Lese- oder Schreibvorgänge in entschärfte Adressräume.
SRIOV_GET_DEVICE_LOCATION

Ruft Informationen zum aktuellen Standort des PCI-Geräts auf dem Bus ab, z. B. PCI-Segment, Bus, Gerät und Funktionsnummer.
SRIOV_GET_MMIO_REQUIREMENTS

Diese Rückruffunktion wird nicht unterstützt.
SRIOV_GET_RESOURCE_FOR_BAR

Ruft die übersetzte Ressource für ein bestimmtes Basisadressregister (Base Address Register, BAR) ab.
SRIOV_GET_VENDOR_AND_DEVICE_IDS

Stellt die Anbieter- und Geräte-ID für eine PCI Express SR-IOV Virtual Function (VF) bereit, die zum Generieren einer generischeren Plug-and-Play-ID für den VF verwendet werden soll. Diese IDs können nicht direkt aus dem Konfigurationsbereich des Vf gelesen werden.
SRIOV_QUERY_LUID

Ruft den lokalen eindeutigen Bezeichner des SR-IOV-Geräts ab.
SRIOV_QUERY_LUID_VF

Ruft die PCI Express SR-IOV Virtual Function (VF) ab, wenn ein eindeutiger Bezeichner vorhanden ist.
SRIOV_QUERY_PROBED_BARS

Fragt die Daten ab, die aus den BASE-Adressregistern (BASE Address Registers, BARs) der physischen Funktion gelesen werden, wenn der Wert -1 zuerst in sie geschrieben wurde.
SRIOV_QUERY_PROBED_BARS_2

Fragt die Daten ab, die aus den angegebenen PCI Express SR-IOV Virtual Function (VF)-Basisadressregistern (BARs) gelesen werden, wenn der Wert -1 zuerst in sie geschrieben wurde.
SRIOV_QUERY_VF_LUID

Ruft den lokalen eindeutigen Bezeichner der pci Express SR-IOV Virtual Function (VF) ab.
SRIOV_READ_BLOCK

Liest Daten aus dem angegebenen Konfigurationsblock einer PCI Express SR-IOV Virtual Function (VF).
SRIOV_READ_CONFIG

Liest Daten aus dem Konfigurationsraum der angegebenen PCI Express SR-IOV Virtual Function (VF).
SRIOV_RESET_FUNCTION

Setzt die angegebene PCI Express SR-IOV Virtual Function (VF) zurück.
SRIOV_SET_POWER_STATE

Legt den Leistungszustand der angegebenen PCI Express SR-IOV Virtual Function (VF) fest.
SRIOV_WRITE_BLOCK

Schreibt Daten in den angegebenen Konfigurationsblock einer PCI Express SR-IOV Virtual Function (VF).
SRIOV_WRITE_CONFIG

Schreibt Konfigurationsdaten in eine PCI Express SR-IOV Virtual Function (VF).

Strukturen

 
MITIGABLE_DEVICE_INTERFACE

Speichert Funktionszeiger auf Rückruffunktionen, die vom PF-Treiber (Physical Function, physische Funktion) für die entschärfebare Geräteschnittstelle implementiert werden.
SRIOV_DEVICE_INTERFACE_STANDARD

Speichert Funktionszeiger auf Rückruffunktionen, die vom Treiber für die physische Funktion (PF) im Gerätestapel des SR-IOV-Geräts implementiert werden.
SRIOV_DEVICE_INTERFACE_STANDARD_2

Speichert Funktionszeiger auf Rückruffunktionen, die vom Treiber für die physische Funktion (PF) im Gerätestapel des SR-IOV-Geräts implementiert werden. Dies ist eine erweiterte Version von SRIOV_DEVICE_INTERFACE_STANDARD.
SRIOV_INVALIDATE_BLOCK

Enthält die Konfigurationsblockinformationen. Diese Struktur wird in einer IOCTL_SRIOV_INVALIDATE_BLOCK-Anforderung verwendet.
SRIOV_MITIGATED_RANGE_COUNT_INPUT

Diese Struktur wird als Eingabepuffer für die IOCTL_SRIOV_QUERY_MITIGATED_RANGE_COUNT-Anforderung verwendet, um die Bereiche des im Speicher zugeordneten E/A-Speicherplatzes zu bestimmen, der entschärft werden muss.
SRIOV_MITIGATED_RANGE_COUNT_OUTPUT

Diese Strukturen sind der Von der IOCTL_SRIOV_QUERY_MITIGATED_RANGE_COUNT-Anforderung empfangene Ausgabepuffer, der ein Array von Bereichen von E/A-Bereichen enthält, die im Speicher zugeordnet sind und entschärft werden müssen.
SRIOV_MITIGATED_RANGE_UPDATE_INPUT

Diese Struktur wird als Eingabepuffer für die IOCTL_SRIOV_MITIGATED_RANGE_UPDATE-Anforderung verwendet, um die virtuelle Funktion (VF) anzugeben, deren speicherseitig zugeordneter E/A-Speicherplatz entschärft werden muss.
SRIOV_MITIGATED_RANGE_UPDATE_OUTPUT

Diese Strukturen sind der Ausgabepuffer, der von der IOCTL_SRIOV_MITIGATED_RANGE_UPDATE-Anforderung empfangen wird und die virtuelle Funktion (VF) angibt, deren E/A-Speicherplatz im Speicher zugeordnet wurde.
SRIOV_MITIGATED_RANGES_INPUT

Diese Struktur ist der Eingabepuffer in der IOCTL_SRIOV_QUERY_MITIGATED_RANGES-Anforderung, um die spezifischen Bereiche abzurufen, in denen Intercepts platziert werden müssen.
SRIOV_MITIGATED_RANGES_OUTPUT

Diese Struktur ist der Ausgabepuffer, der von der IOCTL_SRIOV_QUERY_MITIGATED_RANGES-Anforderung empfangen wird, um die spezifischen Bereiche abzurufen, in denen Intercepts platziert werden müssen.
SRIOV_PNP_EVENT_COMPLETE

Speichert die status für ein Ereignis, das vom SR-IOV-Pf-Treiber (Physical Function) für plug and play even completion (Plug and Play) festgelegt werden soll. Diese Struktur wird im Eingabepuffer der IOCTL_SRIOV_EVENT_COMPLETE-Anforderung verwendet.
SRIOV_PROXY_QUERY_LUID_OUTPUT

Speichert den lokalen eindeutigen Bezeichner des SR_IOV Geräts, das die Schnittstelle implementiert. Diese Struktur ist der Ausgabepuffer für die IOCTL_SRIOV_PROXY_QUERY_LUID-Anforderung.

Enumerationen

 
SRIOV_PF_EVENT

Definiert Ereigniswerte für das SR-IOV-Gerät.