pcivirt.h 標頭

使用將 VF 公開至虛擬機器之介面的參考指南。

符合 PCI Express Single-Root I/O 虛擬化 (SR-IOV) 規格的裝置可以提供裝置的多個介面。 這些介面稱為虛擬函式 (VF) 是獨立的,而且是透過初始裝置介面提供,稱為實體函式 (PF) 。 例如,支援 SR-IOV 的乙太網路 NIC 可以設計成具有一個實體乙太網路埠的交換器, (連線到實體線路) 和許多虛擬乙太網路埠。

PF 的設定空間可讓 PF 驅動程式管理 VF 的 PCI 資源,包括記憶體對應的 I/O 空間和訊息訊號中斷。 由於 VF 是完整裝置的子集,因此在硬體中公開的成本可能比多函式套件中的傳統函式低。 這可讓裝置製作者建置更多介面,並集中管理任何共用資源。

當 Windows 直接在電腦硬體上執行時,設備磁碟機會參與與隨插即用、電源管理、中斷管理和其他工作相關的作業。 受信任的 Windows 匯流排驅動程式和硬體抽象層 (HAL) 自己的匯流排設定,並設定整個匯流排。 驅動程式會在相同的許可權等級內執行,而且核心模式中沒有信任界限。

當 Windows 在虛擬機器上執行 (VM) 時,這些假設不適用。 VF 可以置於非特殊許可權 VM 的控制之下。 不過,硬體必須經過安全性檢查,系統的安全性或效能不會受到影響。

當 VF 上執行的驅動程式要求設定空間讀取或寫入時,虛擬化堆疊會收到要求,並傳送至 SR-IOV 裝置的 PF 驅動程式。 PF 驅動程式負責回應這些要求,並提供 VF 的詳細資料。 PF 驅動程式偶爾可能會要求將設定讀取或寫入要求傳遞至硬體。

堆疊會使用 I/O MMU 來區分來自裝置所公開之各種介面的流量,並強制執行裝置可存取之記憶體區域的原則,以及可產生哪些中斷。

PCI 虛擬化。

硬體需求

要用於 SR-IOV 裝置指派的系統必須符合 SR-IOV 網路和直接裝置指派的需求。 系統必須有 IOMMU,該 IOMMU 必須設定為將裝置控制權授與作業系統,而且必須啟用並設定 PCIe ACS (存取控制 Services) 以供作業系統使用。 最後,有問題的裝置不得使用以行為基礎的中斷,而且不得要求 ATS (位址轉譯服務) 。

詳細資訊請參閱這裡:

您想要在 Hyper-V 中瞭解 SR-IOV 的一切。 第 1 部分

離散裝置指派 - 描述和背景

若要判斷系統是否支援裝置指派,以及特定 PCI 裝置是否適用于裝置指派:

離散裝置指派腳本

查詢 SR-IOV 裝置

GUID_DEVINTERFACE_VIRTUALIZABLE_DEVICE是由 SR-IOV 裝置的驅動程式所提供的裝置類別介面。 此 GUID 提供一種方式來查詢所有裝置堆疊,這些堆疊會公開用來管理裝置虛擬化相關功能的各種函式資料表。 在驅動程式註冊 GUID 之後,會藉由傳送IRP_MN_QUERY_INTERFACE來探索個別功能。 驅動程式必須使用GUID_SRIOV_DEVICE_INTERFACE_STANDARD來回應該要求。 驅動程式也必須處理IOCTL_SRIOV_NOTIFICATION和IOCTL_SRIOV_EVENT_COMPLETE。

SR_IOV裝置的驅動程式,在具特殊許可權的 VM 中執行是主機 OS。 它擁有整個電腦的隨插即用和電源管理,並在非特殊許可權的 VM 中公開 PCI Express SR-IOV 虛擬函式,必須提供 Pcivirt.h) 標頭中定義的GUID_SRIOV_DEVICE_INTERFACE_STANDARD (。 該驅動程式可能是 PCI Express SR-IOV 實體函式 (PF) 驅動程式,而該驅動程式會建立 FDO,或者當 FDO 是由埠驅動程式管理的情況下,該裝置節點上的較低篩選器。

需要裝置介面,驅動程式才能存取 VFs 的設定空間。

在 PF 驅動程式的EVT_WDF_DRIVER_DEVICE_ADD實作中,執行下列工作:

  • 呼叫 WdfDeviceCreate 以在 FDO) (建立函式裝置物件之後,請呼叫 WdfDeviceCreateDeviceInterface 來註冊GUID_DEVINTERFACE_VIRTUALIZABLE_DEVICE。 這可讓虛擬化堆疊擷取 SR-IOV 裝置的裝置控制碼。
  • 公開GUID_SRIOV_DEVICE_INTERFACE_STANDARD。
    • 初始化SRIOV_DEVICE_INTERFACE_STANDARD結構,並將成員設定為 PF 驅動程式所實作之回呼函式的函式指標。
    • 呼叫 WDF_QUERY_INTERFACE_CONFIG_INIT 來設定 結構。
    • 呼叫 WdfDeviceAddQueryInterface 向 FDO 註冊介面。
    // 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;
    }

處理隨插即用事件

虛擬化堆疊負責將適當的訊息傳送至 VM、等候回復 (逾時) ,以及在未回應 VM 的情況下套用適當的動作,例如 Vetoing PnP 事件,或從非特殊許可權 VM 意外移除裝置。 實作GUID_DEVINTERFACE_VIRTUALIZABLE_DEVICE的 PF 驅動程式也必須處理這些 I/O 控制要求,以允許虛擬化堆疊回應 PnP 事件。

  • 虛擬化堆疊會先將IOCTL_SRIOV_ATTACH傳送至裝置。 這會通知裝置虛擬化堆疊需要收到特定 PnP 事件的通知。

  • 這在虛擬化堆疊傳送IOCTL_SRIOV_DETACH之前生效。

  • 虛擬化堆疊會藉由傳送IOCTL_SRIOV_NOTIFICATION要求來查詢裝置有關 PnP 事件。 PF 驅動程式可以完成IOCTL_SRIOV_NOTIFICATION要求,以通知 PnP 事件的虛擬化堆疊。

  • 虛擬化堆疊會藉由傳送IOCTL_SRIOV_EVENT_COMPLETE來解除封鎖這些事件。

pcivirt.h 包含下列程式設計介面:

IOCTLs

 
IOCTL_SRIOV_ATTACH

要求指出虛擬化堆疊想要註冊 SR-IOV 裝置所接收的隨插即用事件。
IOCTL_SRIOV_DETACH

要求表示虛擬化堆疊想要取消註冊隨插即用事件, (先前透過IOCTL_SRIOV_ATTACH要求註冊) 。
IOCTL_SRIOV_EVENT_COMPLETE

要求指出虛擬化堆疊或 SR-IOV 裝置收到SRIOV_PF_EVENT中列出的其中一個事件。
IOCTL_SRIOV_INVALIDATE_BLOCK

IOCTL_SRIOV_INVALIDATE_BLOCK要求表示虛擬化堆疊想要重設指定組態區塊的內容。
IOCTL_SRIOV_MITIGATED_RANGE_UPDATE

IOCTL_SRIOV_MITIGATED_RANGE_UPDATE要求表示虛擬化堆疊想要更新為風險降低範圍。
IOCTL_SRIOV_NOTIFICATION

要求表示虛擬化堆疊想要在發生SRIOV_PF_EVENT所列其中一個事件時收到通知。
IOCTL_SRIOV_PROXY_QUERY_LUID

此要求會提供實作 介面之SR_IOV裝置的本機唯一識別碼。
IOCTL_SRIOV_QUERY_MITIGATED_RANGE_COUNT

要求會決定必須緩和的記憶體對應 I/O 空間範圍。
IOCTL_SRIOV_QUERY_MITIGATED_RANGES

要求會決定必須放置攔截的特定範圍。

回呼函式

 
READ_WRITE_MITIGATED_REGISTER

讀取或寫入以減少位址空間。
SRIOV_GET_DEVICE_LOCATION

擷取匯流排上 PCI 裝置目前位置的相關資訊,例如 PCI 區段、匯流排、裝置和函式號碼。
SRIOV_GET_MMIO_REQUIREMENTS

不支援此回呼函式。
SRIOV_GET_RESOURCE_FOR_BAR

取得特定基底位址暫存器 (BAR) 的翻譯資源。
SRIOV_GET_VENDOR_AND_DEVICE_IDS

提供 PCI Express SR-IOV 虛擬函式的廠商和裝置識別碼 (VF) ,以用於為 VF 產生更通用的隨插即用識別碼。 這些識別碼無法直接從 VF 的設定空間讀取。
SRIOV_QUERY_LUID

取得 SR-IOV 裝置的本機唯一識別碼。
SRIOV_QUERY_LUID_VF

取得指定唯一識別碼的 PCI Express SR-IOV 虛擬函式 (VF) 。
SRIOV_QUERY_PROBED_BARS

查詢從實體函式 (PF) 基底位址讀取的資料,如果值 -1 是先寫入其中, (BAR) 。
SRIOV_QUERY_PROBED_BARS_2

查詢從指定的 PCI Express SR-IOV 虛擬函式讀取的資料, (VF) 基底位址暫存器, (BAR) 如果第一次寫入 -1 值。
SRIOV_QUERY_VF_LUID

取得 PCI Express SR-IOV 虛擬函式的本機唯一識別碼, (VF) 。
SRIOV_READ_BLOCK

從 PCI Express SR-IOV 虛擬函式的指定設定區塊讀取資料, (VF) 。
SRIOV_READ_CONFIG

從指定 PCI Express SR-IOV 虛擬函式的設定空間讀取資料, (VF) 。
SRIOV_RESET_FUNCTION

重設指定的 PCI Express SR-IOV 虛擬函式 (VF) 。
SRIOV_SET_POWER_STATE

設定指定之 PCI Express SR-IOV 虛擬函式的電源狀態, (VF) 。
SRIOV_WRITE_BLOCK

將資料寫入 PCI Express SR-IOV 虛擬函式的指定組態區塊, (VF) 。
SRIOV_WRITE_CONFIG

將設定資料寫入 PCI Express SR-IOV 虛擬函式 (VF) 。

結構

 
MITIGABLE_DEVICE_INTERFACE

儲存實體函式所實作之回呼函式的函式指標, (PF) 驅動程式,以用於可模擬裝置介面。
SRIOV_DEVICE_INTERFACE_STANDARD

將實體函式所實作的函式指標儲存在 SR-IOV 裝置的裝置堆疊中, (PF) 驅動程式實作的回呼函式。
SRIOV_DEVICE_INTERFACE_STANDARD_2

將實體函式所實作的函式指標儲存在 SR-IOV 裝置的裝置堆疊中, (PF) 驅動程式實作的回呼函式。 這是擴充版本的 SRIOV_DEVICE_INTERFACE_STANDARD。
SRIOV_INVALIDATE_BLOCK

包含組態區塊資訊。 此結構用於IOCTL_SRIOV_INVALIDATE_BLOCK要求中。
SRIOV_MITIGATED_RANGE_COUNT_INPUT

此結構用來作為IOCTL_SRIOV_QUERY_MITIGATED_RANGE_COUNT要求的輸入緩衝區,以判斷必須緩和的記憶體對應 I/O 空間範圍。
SRIOV_MITIGATED_RANGE_COUNT_OUTPUT

此結構是由IOCTL_SRIOV_QUERY_MITIGATED_RANGE_COUNT要求收到的輸出緩衝區,其中包含必須緩和的記憶體對應 I/O 空間範圍陣列。
SRIOV_MITIGATED_RANGE_UPDATE_INPUT

此結構用來做為IOCTL_SRIOV_MITIGATED_RANGE_UPDATE要求的輸入緩衝區,以指出虛擬函式 (VF) 必須緩和的記憶體對應 I/O 空間。
SRIOV_MITIGATED_RANGE_UPDATE_OUTPUT

此結構是IOCTL_SRIOV_MITIGATED_RANGE_UPDATE要求所收到的輸出緩衝區,表示已緩和記憶體對應 I/O 空間的虛擬函式 (VF) 。
SRIOV_MITIGATED_RANGES_INPUT

此結構是IOCTL_SRIOV_QUERY_MITIGATED_RANGES要求中的輸入緩衝區,可取得必須放置攔截的特定範圍。
SRIOV_MITIGATED_RANGES_OUTPUT

此結構是IOCTL_SRIOV_QUERY_MITIGATED_RANGES要求所收到的輸出緩衝區,可取得必須放置攔截的特定範圍。
SRIOV_PNP_EVENT_COMPLETE

儲存 SR-IOV 實體函式 (PF) 驅動程式應該針對隨插即用完成設定的事件狀態。 此結構用於IOCTL_SRIOV_EVENT_COMPLETE要求的輸入緩衝區中。
SRIOV_PROXY_QUERY_LUID_OUTPUT

儲存實作 介面之SR_IOV裝置的本機唯一識別碼。 此結構是IOCTL_SRIOV_PROXY_QUERY_LUID要求的輸出緩衝區。

列舉

 
SRIOV_PF_EVENT

定義 SR-IOV 裝置的事件值。