en-tête pcivirt.h

Guide de référence pour l’utilisation des interfaces utilisées pour exposer des machines virtuelles à une machine virtuelle.

Les appareils conformes à la spécification DE VIRTUALISATION d’E/S PCI Express Single-Root (SR-IOV) peuvent fournir plusieurs interfaces à l’appareil. Ces interfaces, appelées fonctions virtuelles (VF), sont indépendantes et sont fournies via l’interface initiale de l’appareil, appelée fonction physique (PF). Par exemple, une carte réseau Ethernet qui prend en charge SR-IOV peut être conçue pour avoir un commutateur avec un port Ethernet physique (connecté au câble physique) et de nombreux ports Ethernet virtuels.

L’espace de configuration du PF permet au pilote PF de gérer les ressources PCI de la VF, y compris l’espace d’E/S mappé en mémoire et les interruptions de message signalées. Étant donné que les machines virtuelles sont un sous-ensemble d’un appareil complet, elles peuvent être moins coûteuses à exposer dans le matériel qu’une fonction traditionnelle dans un package multi-fonction. Cela permet au fabricant d’appareils de créer davantage d’interfaces et de gérer les ressources partagées de manière centralisée.

Lorsque Windows s’exécute directement sur le matériel de l’ordinateur, les pilotes de périphérique participent aux opérations liées à Plug-and-Play, à la gestion de l’alimentation, à la gestion des interruptions et à d’autres tâches. Un pilote de bus Windows approuvé et une couche d’abstraction matérielle (HAL) possèdent la configuration du bus et configurent l’ensemble du bus. Le pilote s’exécute dans le même niveau de privilège et il n’existe aucune limite d’approbation en mode noyau.

Lorsque Windows s’exécute sur une machine virtuelle, ces hypothèses ne s’appliquent pas. Les machines virtuelles peuvent être placées sous le contrôle d’une machine virtuelle non privilégiée. Toutefois, le matériel doit être vérifié afin que la sécurité ou les performances du système ne soient pas affectées.

Lorsqu’un pilote s’exécutant sur la VF demande une lecture ou une écriture d’espace de configuration, la demande est reçue par la pile de virtualisation et envoyée au pilote PF de l’appareil SR-IOV. Il incombe au pilote PF de répondre à ces demandes et de fournir des détails pour la VF. Le pilote PF peut parfois exiger qu’une demande de lecture ou d’écriture de configuration soit transmise au matériel.

La pile utilise une MMU d’E/S pour différencier le trafic provenant des différentes interfaces exposées par l’appareil, en appliquant une stratégie concernant les régions de mémoire auxquelles un appareil peut accéder et les interruptions qu’il peut générer.

Virtualisation PCI.

Configuration matérielle requise

Le système à utiliser pour l’attribution d’appareil SR-IOV doit répondre aux exigences relatives à la mise en réseau SR-IOV et à l’attribution directe d’appareil. Le système doit disposer d’un IOMMU, que l’IOMMU doit être configuré pour donner le contrôle des appareils au système d’exploitation, et PCIe ACS (Access Control Services) doit être activé et configuré pour une utilisation par le système d’exploitation. Enfin, l’appareil en question ne doit pas utiliser d’interruptions basées sur des lignes et ne doit pas nécessiter ATS (Services de traduction d’adresses).

Plus d’informations ici :

Tout ce que vous vouliez savoir sur SR-IOV dans Hyper-V. Partie 1

Affectation discrète d’appareil — Description et arrière-plan

Pour déterminer si un système prend en charge l’attribution d’appareil et si un appareil PCI particulier fonctionnera pour l’attribution d’appareil :

Script d’affectation d’appareil discret

Interrogation des appareils SR-IOV

GUID_DEVINTERFACE_VIRTUALIZABLE_DEVICE est une interface de classe d’appareil fournie par les pilotes pour les appareils SR-IOV. Ce GUID permet d’interroger toutes les piles d’appareils qui exposent les différentes tables de fonctions utilisées pour gérer les fonctionnalités liées à la virtualisation de l’appareil. Une fois que le pilote a inscrit le GUID, des fonctionnalités individuelles sont découvertes en envoyant IRP_MN_QUERY_INTERFACE. Le pilote doit répondre à cette demande avec GUID_SRIOV_DEVICE_INTERFACE_STANDARD. Les pilotes doivent également gérer les IOCTL_SRIOV_NOTIFICATION et les IOCTL_SRIOV_EVENT_COMPLETE.

Un pilote pour un appareil SR_IOV, qui s’exécute dans une machine virtuelle privilégiée est le système d’exploitation hôte. Il possède plug-and-play et la gestion de l’alimentation pour une machine entière, et expose PCI Express SR-IOV Virtual Functions dans les machines virtuelles non privilégiées, doit fournir le GUID_SRIOV_DEVICE_INTERFACE_STANDARD (défini dans l’en-tête Pcivirt.h). Ce pilote peut être un pilote de fonction physique (PF) PCI Express Express SR-IOV qui crée le FDO, ou il peut s’agir d’un filtre inférieur sur ce nœud d’appareil dans le cas où le FDO est géré par un pilote de port.

L’interface de périphérique est requise pour que le pilote puisse accéder à l’espace de configuration des machines virtuelles.

Dans l’implémentation EVT_WDF_DRIVER_DEVICE_ADD du pilote PF, effectuez les tâches suivantes :

  • Après avoir appelé WdfDeviceCreate pour créer l’objet d’appareil de fonction (FDO), appelez WdfDeviceCreateDeviceInterface pour inscrire GUID_DEVINTERFACE_VIRTUALIZABLE_DEVICE. Cela permet à la pile de virtualisation de récupérer un handle d’appareil sur l’appareil SR-IOV.
  • Exposez le GUID_SRIOV_DEVICE_INTERFACE_STANDARD.
    • Initialisez une structure SRIOV_DEVICE_INTERFACE_STANDARD et définissez les membres sur les pointeurs de fonction des fonctions de rappel implémentées par le pilote PF.
    • Configurez la structure en appelant WDF_QUERY_INTERFACE_CONFIG_INIT.
    • Inscrivez l’interface auprès du FDO en appelant WdfDeviceAddQueryInterface.
    // 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;
    }

Gestion des événements Plug-and-Play

La pile de virtualisation est chargée d’envoyer les messages appropriés à la machine virtuelle, d’attendre la réponse (avec un délai d’expiration) et en cas de machine virtuelle qui ne répond pas, et d’appliquer les actions appropriées, telles que le veto à l’événement PnP ou la suppression surprise de l’appareil de la machine virtuelle non privilégiée. Les pilotes PF qui implémentent GUID_DEVINTERFACE_VIRTUALIZABLE_DEVICE doivent également gérer ces demandes de contrôle d’E/S qui permettent à la pile de virtualisation de réagir aux événements PnP.

  • La pile de virtualisation envoie d’abord IOCTL_SRIOV_ATTACH à l’appareil. Cela avertit l’appareil que la pile de virtualisation doit être informée de certains événements PnP.

  • Cela est en vigueur jusqu’à ce que la pile de virtualisation envoie IOCTL_SRIOV_DETACH.

  • La pile de virtualisation interroge les appareils sur les événements PnP en envoyant des requêtes IOCTL_SRIOV_NOTIFICATION. Le pilote PF peut informer la pile de virtualisation d’un événement PnP en effectuant la demande IOCTL_SRIOV_NOTIFICATION.

  • La pile de virtualisation débloque ces événements en envoyant IOCTL_SRIOV_EVENT_COMPLETE.

pcivirt.h contient les interfaces de programmation suivantes :

IOCTLs

 
IOCTL_SRIOV_ATTACH

La demande indique que la pile de virtualisation souhaite s’inscrire aux événements Plug-and-Play reçus par l’appareil SR-IOV.
IOCTL_SRIOV_DETACH

La demande indique que la pile de virtualisation souhaite annuler l’inscription pour les événements Plug-and-Play (précédemment inscrits via la demande de IOCTL_SRIOV_ATTACH).
IOCTL_SRIOV_EVENT_COMPLETE

La demande indique que la pile de virtualisation ou l’appareil SR-IOV a reçu l’un des événements répertoriés dans SRIOV_PF_EVENT.
IOCTL_SRIOV_INVALIDATE_BLOCK

La requête IOCTL_SRIOV_INVALIDATE_BLOCK indique que la pile de virtualisation souhaite réinitialiser le contenu du bloc de configuration spécifié.
IOCTL_SRIOV_MITIGATED_RANGE_UPDATE

La demande IOCTL_SRIOV_MITIGATED_RANGE_UPDATE indique que la pile de virtualisation souhaite être mise à jour vers les plages d’atténuation.
IOCTL_SRIOV_NOTIFICATION

La demande indique que la pile de virtualisation souhaite être avertie lorsqu’un des événements répertoriés dans SRIOV_PF_EVENT se produit.
IOCTL_SRIOV_PROXY_QUERY_LUID

Cette demande fournit l’identificateur unique local de l’appareil SR_IOV implémentant l’interface.
IOCTL_SRIOV_QUERY_MITIGATED_RANGE_COUNT

La requête détermine les plages d’espace d’E/S mappé en mémoire qui doivent être atténuées.
IOCTL_SRIOV_QUERY_MITIGATED_RANGES

La requête détermine les plages spécifiques sur lesquelles les intercepts doivent être placés.

Fonctions de rappel

 
READ_WRITE_MITIGATED_REGISTER

Lit ou écrit dans des espaces d’adressage atténués.
SRIOV_GET_DEVICE_LOCATION

Récupère des informations sur l’emplacement actuel de l’appareil PCI sur le bus, telles que le segment PCI, le bus, le numéro d’appareil et de fonction.
SRIOV_GET_MMIO_REQUIREMENTS

Cette fonction de rappel n’est pas prise en charge.
SRIOV_GET_RESOURCE_FOR_BAR

Obtient la ressource traduite pour un registre d’adresses de base (BAR) spécifique.
SRIOV_GET_VENDOR_AND_DEVICE_IDS

Fournit l’ID de fournisseur et d’appareil d’une fonction virtuelle PCI Express SR-IOV (VF) à utiliser pour générer un ID Plug-and-Play plus générique pour la VF. Ces ID ne peuvent pas être lus directement à partir de l’espace de configuration de la VF.
SRIOV_QUERY_LUID

Obtient l’identificateur unique local de l’appareil SR-IOV.
SRIOV_QUERY_LUID_VF

Obtient la fonction virtuelle (VF) PCI Express Express SR-IOV en fonction d’un identificateur unique.
SRIOV_QUERY_PROBED_BARS

Interroge les données lues à partir des registres d’adresses de base (BR) de la fonction physique (PF) si la valeur -1 leur a été écrite en premier.
SRIOV_QUERY_PROBED_BARS_2

Interroge les données lues à partir des registres d’adresses de base (BR) PCI Express SR-IOV (VF) spécifiés si la valeur -1 leur a été écrite en premier.
SRIOV_QUERY_VF_LUID

Obtient l’identificateur unique local de la fonction virtuelle (VF) PCI Express SR-IOV.
SRIOV_READ_BLOCK

Lit les données du bloc de configuration spécifié d’une fonction virtuelle (VF) PCI Express SR-IOV.
SRIOV_READ_CONFIG

Lit les données de l’espace de configuration de la fonction virtuelle (VF) PCI Express SR-IOV spécifiée.
SRIOV_RESET_FUNCTION

Réinitialise la fonction virtuelle (VF) PCI Express SR-IOV spécifiée.
SRIOV_SET_POWER_STATE

Définit l’état d’alimentation de la fonction virtuelle (VF) PCI Express SR-IOV spécifiée.
SRIOV_WRITE_BLOCK

Écrit des données dans le bloc de configuration spécifié d’une fonction virtuelle (VF) SR-IOV PCI Express.
SRIOV_WRITE_CONFIG

Écrit les données de configuration dans une fonction virtuelle (VF) SR-IOV PCI Express.

Structures

 
MITIGABLE_DEVICE_INTERFACE

Stocke les pointeurs de fonction vers les fonctions de rappel implémentées par le pilote de fonction physique (PF) pour l’interface de périphérique mitigable.
SRIOV_DEVICE_INTERFACE_STANDARD

Stocke les pointeurs de fonction vers les fonctions de rappel implémentées par le pilote de fonction physique (PF) dans la pile de périphériques pour le de l’appareil SR-IOV.
SRIOV_DEVICE_INTERFACE_STANDARD_2

Stocke les pointeurs de fonction vers les fonctions de rappel implémentées par le pilote de fonction physique (PF) dans la pile de périphériques pour le de l’appareil SR-IOV. Il s’agit d’une version étendue de SRIOV_DEVICE_INTERFACE_STANDARD.
SRIOV_INVALIDATE_BLOCK

Contient les informations de bloc de configuration. Cette structure est utilisée dans une demande de IOCTL_SRIOV_INVALIDATE_BLOCK.
SRIOV_MITIGATED_RANGE_COUNT_INPUT

Cette structure est utilisée comme mémoire tampon d’entrée pour la demande IOCTL_SRIOV_QUERY_MITIGATED_RANGE_COUNT pour déterminer les plages d’espace d’E/S mappé en mémoire qui doivent être atténuées.
SRIOV_MITIGATED_RANGE_COUNT_OUTPUT

Cette structure est la mémoire tampon de sortie reçue par la requête IOCTL_SRIOV_QUERY_MITIGATED_RANGE_COUNT qui contient un tableau de plages d’espace d’E/S mappé en mémoire qui doivent être atténuées.
SRIOV_MITIGATED_RANGE_UPDATE_INPUT

Cette structure est utilisée comme mémoire tampon d’entrée pour la demande IOCTL_SRIOV_MITIGATED_RANGE_UPDATE pour indiquer la fonction virtuelle (VF) dont l’espace d’E/S mappé en mémoire doit être atténué.
SRIOV_MITIGATED_RANGE_UPDATE_OUTPUT

Cette structure est la mémoire tampon de sortie reçue par la requête IOCTL_SRIOV_MITIGATED_RANGE_UPDATE qui indique la fonction virtuelle (VF) dont l’espace d’E/S mappé en mémoire a été atténué.
SRIOV_MITIGATED_RANGES_INPUT

Cette structure est la mémoire tampon d’entrée dans la demande de IOCTL_SRIOV_QUERY_MITIGATED_RANGES pour obtenir les plages spécifiques sur lesquelles les interceptions doivent être placées.
SRIOV_MITIGATED_RANGES_OUTPUT

Cette structure est la mémoire tampon de sortie reçue par la demande de IOCTL_SRIOV_QUERY_MITIGATED_RANGES pour obtenir les plages spécifiques sur lesquelles les interceptions doivent être placées.
SRIOV_PNP_EVENT_COMPLETE

Stocke les status pour un événement que le pilote de fonction physique (PF) SR-IOV doit définir pour l’achèvement pair Plug-and-Play. Cette structure est utilisée dans la mémoire tampon d’entrée de la demande IOCTL_SRIOV_EVENT_COMPLETE.
SRIOV_PROXY_QUERY_LUID_OUTPUT

Stocke l’identificateur unique local de l’appareil SR_IOV qui implémente l’interface. Cette structure est la mémoire tampon de sortie pour la requête IOCTL_SRIOV_PROXY_QUERY_LUID.

Énumérations

 
SRIOV_PF_EVENT

Définit les valeurs d’événement pour l’appareil SR-IOV.