Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Guia de referência para usar interfaces usadas expondo VFs a uma máquina virtual.
Os dispositivos que estão em conformidade com a especificação PCI Express Single-Root I/O Virtualization (SR-IOV) podem fornecer várias interfaces para o dispositivo. Essas interfaces, conhecidas como Funções Virtuais (VFs), são independentes e são fornecidas por meio da interface inicial do dispositivo, conhecida como Função Física (PF). Por exemplo, uma placa de rede Ethernet que oferece suporte a SR-IOV pode ser projetada para ter um switch com uma porta Ethernet física (conectada ao fio físico) e muitas portas Ethernet virtuais.
O espaço de configuração do PF permite que o driver PF gerencie os recursos PCI do VF, incluindo espaço de E/S mapeado na memória e interrupções sinalizadas por mensagem. Como os VFs são um subconjunto de um dispositivo completo, eles podem ser mais baratos de expor no hardware do que uma função tradicional em um pacote multifuncional. Isso permite que o fabricante do dispositivo crie mais interfaces e gerencie todos os recursos compartilhados centralmente.
Quando o Windows está sendo executado diretamente no hardware do computador, os drivers de dispositivo participam de operações relacionadas a Plug and Play, gerenciamento de energia, gerenciamento de interrupções e outras tarefas. Um driver de barramento Windows confiável e a HAL (Camada de Abstração de Hardware) possuem a configuração de barramento e configuram todo o barramento. O driver é executado dentro do mesmo nível de privilégio e não há limites de confiança no modo kernel.
Quando o Windows está sendo executado em uma VM (máquina virtual), essas suposições não se aplicam. Os VFs podem ser colocados sob o controle de uma VM sem privilégios. No entanto, o hardware deve ser verificado para que a segurança ou o desempenho do sistema não sejam afetados.
Quando um driver em execução no VF solicita uma leitura ou gravação de espaço de configuração, a solicitação é recebida pela pilha de virtualização e enviada para o driver PF do dispositivo SR-IOV. É responsabilidade do motorista da PF responder a essas solicitações e fornecer detalhes para o VF. O driver PF pode ocasionalmente exigir que uma solicitação de leitura ou gravação de configuração seja passada para o hardware.
A pilha usa um MMU de E/S para diferenciar o tráfego proveniente das várias interfaces que o dispositivo expõe, impondo a política sobre quais regiões de memória um dispositivo pode acessar e quais interrupções ele pode gerar.
Requisitos de hardware
O sistema a ser usado para SR-IOV atribuição de dispositivo deve atender aos requisitos de rede SR-IOV e atribuição direta de dispositivo. O sistema deve ter um IOMMU, esse IOMMU deve ser configurado para dar controle de dispositivos ao sistema operacional e o PCIe ACS (Access Control Services) deve ser habilitado e configurado para uso pelo sistema operacional. Por fim, o dispositivo em questão não deve usar interrupções baseadas em linha e não deve exigir ATS (Serviços de Tradução de Endereços).
Mais informações aqui:
- Tudo o que você queria saber sobre SR-IOV no Hyper-V. Parte 1
- Atribuição de dispositivo discreto — Descrição e plano de fundo
Para determinar se um sistema dá suporte à atribuição de dispositivos e se um dispositivo PCI específico funcionará para atribuição de dispositivos:
Consultando dispositivos SR-IOV
GUID_DEVINTERFACE_VIRTUALIZABLE_DEVICE é uma interface de classe de dispositivo fornecida por drivers para dispositivos SR-IOV. Esse GUID fornece uma maneira de consultar todas as pilhas de dispositivos que expõem as várias tabelas de funções usadas para gerenciar os recursos relacionados à virtualização do dispositivo. Depois que o driver registra o GUID, os recursos individuais são descobertos enviando IRP_MN_QUERY_INTERFACE. O motorista deve responder a essa solicitação com GUID_SRIOV_DEVICE_INTERFACE_STANDARD. Os motoristas também devem lidar com IOCTL_SRIOV_NOTIFICATION e IOCTL_SRIOV_EVENT_COMPLETE.
Um driver para um dispositivo SR_IOV, que é executado em uma VM privilegiada, é o sistema operacional host. Ele possui Plug-and-Play e gerenciamento de energia para uma máquina inteira e expõe PCI Express SR-IOV Virtual Functions em VMs sem privilégios, deve fornecer o GUID_SRIOV_DEVICE_INTERFACE_STANDARD (definido no cabeçalho Pcivirt.h). Esse driver pode ser PCI Express SR-IOV driver PF (Função Física) que cria o FDO ou pode ser um filtro inferior nesse nó do dispositivo no caso em que o FDO está sendo gerenciado por um driver de porta.
A interface do dispositivo é necessária para que o driver possa acessar o espaço de configuração dos VFs.
Na implementação EVT_WDF_DRIVER_DEVICE_ADD do driver PF, execute estas tarefas:
- Depois de chamar WdfDeviceCreate para criar o FDO (objeto de dispositivo de função), chame WdfDeviceCreateDeviceInterface para registrar GUID_DEVINTERFACE_VIRTUALIZABLE_DEVICE. Isso permite que a pilha de virtualização recupere um identificador de dispositivo para o dispositivo SR-IOV.
- Exponha o GUID_SRIOV_DEVICE_INTERFACE_STANDARD.
- Inicialize uma estrutura SRIOV_DEVICE_INTERFACE_STANDARD e defina membros para ponteiros de função das funções de retorno de chamada implementadas pelo driver PF.
- Configure a estrutura chamando WDF_QUERY_INTERFACE_CONFIG_INIT.
- Registre a interface com o FDO chamando 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;
}
Manipulando eventos Plug and Play
A pilha de virtualização é responsável por enviar as mensagens apropriadas para a VM, aguardar a resposta (com um tempo limite) e no caso de VM não respondente e aplicar a ação apropriada, como vetar o evento PnP ou remover o dispositivo da VM sem privilégios. Os drivers PF que implementam GUID_DEVINTERFACE_VIRTUALIZABLE_DEVICE também devem lidar com essas solicitações de controle de E/S que permitem que a pilha de virtualização reaja a eventos PnP.
A pilha de virtualização primeiro envia IOCTL_SRIOV_ATTACH para o dispositivo. Isso notifica o dispositivo de que a pilha de virtualização precisa ser notificada sobre determinados eventos PnP.
Isso está em vigor até que a pilha de virtualização envie IOCTL_SRIOV_DETACH.
A pilha de virtualização consulta os dispositivos sobre eventos PnP enviando solicitações IOCTL_SRIOV_NOTIFICATION. O driver PF pode informar a pilha de virtualização de um evento PnP concluindo a solicitação IOCTL_SRIOV_NOTIFICATION.
A pilha de virtualização desbloqueia esses eventos enviando IOCTL_SRIOV_EVENT_COMPLETE.
pcivirt.h contém as seguintes interfaces de programação:
IOCTLs
|
IOCTL_SRIOV_ATTACH A solicitação indica que a pilha de virtualização deseja se registrar para eventos Plug and Play recebidos pelo dispositivo SR-IOV. |
|
IOCTL_SRIOV_DETACH A solicitação indica que a pilha de virtualização deseja cancelar o registro de eventos Plug and Play (registrados anteriormente por meio da solicitação IOCTL_SRIOV_ATTACH). |
|
IOCTL_SRIOV_EVENT_COMPLETE A solicitação indica que a pilha de virtualização ou o dispositivo SR-IOV recebeu um dos eventos listados em SRIOV_PF_EVENT. |
|
IOCTL_SRIOV_INVALIDATE_BLOCK A solicitação IOCTL_SRIOV_INVALIDATE_BLOCK indica que a pilha de virtualização deseja redefinir o conteúdo do bloco de configuração especificado. |
|
IOCTL_SRIOV_MITIGATED_RANGE_UPDATE A solicitação IOCTL_SRIOV_MITIGATED_RANGE_UPDATE indica que a pilha de virtualização deseja atualizar para os intervalos de mitigação. |
|
IOCTL_SRIOV_NOTIFICATION A solicitação indica que a pilha de virtualização deseja ser notificada quando um dos eventos listados no SRIOV_PF_EVENT ocorrer. |
|
IOCTL_SRIOV_PROXY_QUERY_LUID Essa solicitação fornece o identificador exclusivo local do dispositivo SR_IOV implementando a interface. |
|
IOCTL_SRIOV_QUERY_MITIGATED_RANGE_COUNT A solicitação determina os intervalos de espaço de E/S mapeado pela memória que devem ser mitigados. |
|
IOCTL_SRIOV_QUERY_MITIGATED_RANGES A solicitação determina os intervalos específicos nos quais as interceptações devem ser colocadas. |
Funções de retorno de chamada
|
READ_WRITE_MITIGATED_REGISTER Lê ou grava em espaços de endereço atenuados. |
|
SRIOV_GET_DEVICE_LOCATION Recupera informações sobre a localização atual do dispositivo PCI no barramento, como Segmento PCI, Barramento, Dispositivo e Número de Função. |
|
SRIOV_GET_MMIO_REQUIREMENTS Não há suporte para essa função de retorno de chamada. |
|
SRIOV_GET_RESOURCE_FOR_BAR Obtém o recurso traduzido para um BAR (Registro de Endereço Base) específico. |
|
SRIOV_GET_VENDOR_AND_DEVICE_IDS Fornece a ID do fornecedor e do dispositivo para uma VF (função virtual) do PCI Express SR-IOV a ser usada para gerar uma ID de Plug and Play mais genérica para o VF. Essas IDs não podem ser lidas diretamente do espaço de configuração do VF. |
|
SRIOV_QUERY_LUID Obtém o identificador exclusivo local do dispositivo SR-IOV. |
|
SRIOV_QUERY_LUID_VF Obtém o PCI Express SR-IOV VF (Função Virtual) dado um identificador exclusivo. |
|
SRIOV_QUERY_PROBED_BARS Consulta os dados lidos dos BARs (registros de endereço base) da função física (PF) se o valor -1 foram gravados neles primeiro. |
|
SRIOV_QUERY_PROBED_BARS_2 Consulta os dados lidos dos BARs (registros de endereço base) do PCI Express SR-IOV Virtual Function (VF) especificados se o valor -1 foram gravados primeiro. |
|
SRIOV_QUERY_VF_LUID Obtém o identificador exclusivo local do PCI Express SR-IOV Virtual Function (VF). |
|
SRIOV_READ_BLOCK Lê dados do bloco de configuração especificado de um PCI Express SR-IOV Virtual Function (VF). |
|
SRIOV_READ_CONFIG Lê dados do espaço de configuração do PCI Express SR-IOV Virtual Function (VF) especificado. |
|
SRIOV_RESET_FUNCTION Redefine o PCI Express SR-IOV Virtual Function (VF) especificado. |
|
SRIOV_SET_POWER_STATE Define o estado de energia do PCI Express SR-IOV Virtual Function (VF) especificado. |
|
SRIOV_WRITE_BLOCK Grava dados no bloco de configuração especificado de um PCI Express SR-IOV Virtual Function (VF). |
|
SRIOV_WRITE_CONFIG Grava dados de configuração em um VF (PCI Express SR-IOV Virtual Function). |
Estruturas
|
MITIGABLE_DEVICE_INTERFACE Armazena ponteiros de função para funções de retorno de chamada implementadas pelo driver PF (função física) para a interface de dispositivo atenuada. |
|
SRIOV_DEVICE_INTERFACE_STANDARD Armazena ponteiros de função para funções de retorno de chamada implementadas pelo driver de função física (PF) na pilha do dispositivo para o dispositivo SR-IOV. |
|
SRIOV_DEVICE_INTERFACE_STANDARD_2 Armazena ponteiros de função para funções de retorno de chamada implementadas pelo driver de função física (PF) na pilha do dispositivo para o dispositivo SR-IOV. Esta é uma versão estendida do SRIOV_DEVICE_INTERFACE_STANDARD. |
|
SRIOV_INVALIDATE_BLOCK Contém as informações do bloco de configuração. Essa estrutura é usada em uma solicitação IOCTL_SRIOV_INVALIDATE_BLOCK. |
|
SRIOV_MITIGATED_RANGE_COUNT_INPUT Essa estrutura é usada como um buffer de entrada para a solicitação IOCTL_SRIOV_QUERY_MITIGATED_RANGE_COUNT para determinar os intervalos de espaço de E/S mapeado pela memória que devem ser mitigados. |
|
SRIOV_MITIGATED_RANGE_COUNT_OUTPUT Essas estruturas são o buffer de saída recebido pela solicitação IOCTL_SRIOV_QUERY_MITIGATED_RANGE_COUNT que contém uma matriz de intervalos de espaço de E/S mapeado pela memória que devem ser mitigados. |
|
SRIOV_MITIGATED_RANGE_UPDATE_INPUT Essa estrutura é usada como um buffer de entrada para a solicitação IOCTL_SRIOV_MITIGATED_RANGE_UPDATE para indicar a VF (função virtual) cujo espaço de E/S mapeado pela memória deve ser mitigado. |
|
SRIOV_MITIGATED_RANGE_UPDATE_OUTPUT Essas estruturas são o buffer de saída recebido pela solicitação IOCTL_SRIOV_MITIGATED_RANGE_UPDATE que indica a VF (função virtual) cujo espaço de E/S mapeado pela memória foi mitigado. |
|
SRIOV_MITIGATED_RANGES_INPUT Essa estrutura é o buffer de entrada na solicitação IOCTL_SRIOV_QUERY_MITIGATED_RANGES para obter os intervalos específicos nos quais as interceptações devem ser colocadas. |
|
SRIOV_MITIGATED_RANGES_OUTPUT Essa estrutura é o buffer de saída recebido pela solicitação IOCTL_SRIOV_QUERY_MITIGATED_RANGES para obter os intervalos específicos nos quais as interceptações devem ser colocadas. |
|
SRIOV_PNP_EVENT_COMPLETE Armazena o status de um evento que o driver PF (SR-IOV Physical Function) deve definir para a conclusão par do Plug and Play. Essa estrutura é usada no buffer de entrada da solicitação IOCTL_SRIOV_EVENT_COMPLETE. |
|
SRIOV_PROXY_QUERY_LUID_OUTPUT Armazena o identificador exclusivo local do dispositivo SR_IOV implementando a interface. Essa estrutura é o buffer de saída da solicitação IOCTL_SRIOV_PROXY_QUERY_LUID. |
Enumerações
|
SRIOV_PF_EVENT Define valores de evento para o dispositivo SR-IOV. |