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 aux 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.
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 requête 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 Plug-and-Play achèvement pair. 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. |