RE: [EXTERNAL] [PATCH RFC 2/2] PCI: hv: Add vPCI device reset support

From: Long Li

Date: Thu Aug 13 2026 - 17:41:06 EST




> -----Original Message-----
> From: wei.liu@xxxxxxxxxx <wei.liu@xxxxxxxxxx>
> Sent: Friday, July 24, 2026 4:09 PM
> To: Linux on Hyper-V List <linux-hyperv@xxxxxxxxxxxxxxx>; linux-
> pci@xxxxxxxxxxxxxxx
> Cc: Wei Liu <wei.liu@xxxxxxxxxx>; KY Srinivasan <kys@xxxxxxxxxxxxx>;
> Haiyang Zhang <haiyangz@xxxxxxxxxxxxx>; Dexuan Cui
> <DECUI@xxxxxxxxxxxxx>; Long Li <longli@xxxxxxxxxxxxx>; Jonathan Corbet
> <corbet@xxxxxxx>; Shuah Khan <skhan@xxxxxxxxxxxxxxxxxxx>; Lorenzo
> Pieralisi <lpieralisi@xxxxxxxxxx>; Krzysztof Wilczyński
> <kwilczynski@xxxxxxxxxx>; Manivannan Sadhasivam <mani@xxxxxxxxxx>; Rob
> Herring <robh@xxxxxxxxxx>; Bjorn Helgaas <bhelgaas@xxxxxxxxxx>; open
> list:DOCUMENTATION <linux-doc@xxxxxxxxxxxxxxx>; open list <linux-
> kernel@xxxxxxxxxxxxxxx>
> Subject: [EXTERNAL] [PATCH RFC 2/2] PCI: hv: Add vPCI device reset support
>
> From: Wei Liu <wei.liu@xxxxxxxxxx>
>
> Hyper-V vPCI protocol version 1.5 adds a RESET_DEVICE request for projected
> PCI functions. Negotiate the new protocol version and issue the request
> through the vPCI VMBus channel from the PCI controller reset callback.
>
> Use the existing VMBus response path. Return -ENOTTY when the host
> reports STATUS_NOT_SUPPORTED so PCI core may try another reset method.
>
> Signed-off-by: Wei Liu <wei.liu@xxxxxxxxxx>

Reviewed-by: Long Li <longli@xxxxxxxxxxxxx>





> ---
> Documentation/virt/hyperv/vpci.rst | 2 +- drivers/pci/controller/pci-
> hyperv.c | 61 +++++++++++++++++++++++++++++
> 2 files changed, 62 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/virt/hyperv/vpci.rst
> b/Documentation/virt/hyperv/vpci.rst
> index b65b2126ede3..6bfee7225c14 100644
> --- a/Documentation/virt/hyperv/vpci.rst
> +++ b/Documentation/virt/hyperv/vpci.rst
> @@ -65,7 +65,7 @@ exchange messages with the vPCI VSP for the purpose
> of setting up and configuring the vPCI device in Linux. Once the device is
> fully configured in Linux as a PCI device, the VMBus channel is used only if
> Linux changes the vCPU to be interrupted -in the guest, or if the vPCI device
> is removed from
> +in the guest, or if the vPCI device is reset or removed from
> the VM while the VM is running. The ongoing operation of the device
> happens directly between the Linux device driver for the device and the
> hardware, with VMBus and the VMBus channel diff --git
> a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
> index cfc8fa403dad..d3c0fd5e1d8e 100644
> --- a/drivers/pci/controller/pci-hyperv.c
> +++ b/drivers/pci/controller/pci-hyperv.c
> @@ -68,6 +68,7 @@ enum pci_protocol_version_t {
> PCI_PROTOCOL_VERSION_1_2 = PCI_MAKE_VERSION(1, 2), /*
> RS1 */
> PCI_PROTOCOL_VERSION_1_3 = PCI_MAKE_VERSION(1, 3), /*
> Vibranium */
> PCI_PROTOCOL_VERSION_1_4 = PCI_MAKE_VERSION(1, 4), /*
> WS2022 */
> + PCI_PROTOCOL_VERSION_1_5 = PCI_MAKE_VERSION(1, 5), /* GE,
> device reset */
> };
>
> #define CPU_AFFINITY_ALL -1ULL
> @@ -77,6 +78,7 @@ enum pci_protocol_version_t {
> * first.
> */
> static enum pci_protocol_version_t pci_protocol_versions[] = {
> + PCI_PROTOCOL_VERSION_1_5,
> PCI_PROTOCOL_VERSION_1_4,
> PCI_PROTOCOL_VERSION_1_3,
> PCI_PROTOCOL_VERSION_1_2,
> @@ -90,6 +92,7 @@ static enum pci_protocol_version_t
> pci_protocol_versions[] = { #define MAX_SUPPORTED_MSI_MESSAGES 0x400
>
> #define STATUS_REVISION_MISMATCH 0xC0000059
> +#define STATUS_NOT_SUPPORTED 0xC00000BB
>
> /* space for 32bit serial number as string */ #define SLOT_NAME_SIZE 11
> @@ -136,6 +139,7 @@ enum pci_message_type {
> PCI_BUS_RELATIONS2 = PCI_MESSAGE_BASE + 0x19,
> PCI_RESOURCES_ASSIGNED3 = PCI_MESSAGE_BASE + 0x1A,
> PCI_CREATE_INTERRUPT_MESSAGE3 = PCI_MESSAGE_BASE + 0x1B,
> + PCI_RESET_DEVICE = PCI_MESSAGE_BASE + 0x1C,
> PCI_MESSAGE_MAXIMUM
> };
>
> @@ -1397,10 +1401,66 @@ static int hv_pcifront_write_config(struct pci_bus
> *bus, unsigned int devfn,
> return PCIBIOS_SUCCESSFUL;
> }
>
> +static int hv_pcifront_reset(struct pci_dev *pdev, bool probe) {
> + struct hv_pcibus_device *hbus =
> + container_of(pdev->bus->sysdata, struct hv_pcibus_device,
> sysdata);
> + struct pci_child_message reset = {};
> + struct hv_pci_compl comp_pkt;
> + struct pci_packet pkt = {
> + .completion_func = hv_pci_generic_compl,
> + .compl_ctxt = &comp_pkt,
> + };
> + enum hv_pcibus_state state;
> + int ret;
> +
> + /* Device reset was added in vPCI protocol version 1.5. */
> + if (hbus->protocol_version < PCI_PROTOCOL_VERSION_1_5)
> + return -ENOTTY;
> +
> + /* Hyper-V exposes projected functions directly on the root bus. */
> + if (!pci_is_root_bus(pdev->bus))
> + return -ENOTTY;
> +
> + if (probe)
> + return 0;
> +
> + /* Do not take state_lock: eject holds it while removing/locking pdev.
> */
> + state = READ_ONCE(hbus->state);
> + if (state != hv_pcibus_probed && state != hv_pcibus_installed)
> + return -ENODEV;
> +
> + init_completion(&comp_pkt.host_event);
> + reset.message_type.type = PCI_RESET_DEVICE;
> + reset.wslot.slot = devfn_to_wslot(pdev->devfn);
> +
> + ret = vmbus_sendpacket(hbus->hdev->channel, &reset, sizeof(reset),
> + (unsigned long)&pkt, VM_PKT_DATA_INBAND,
> +
> VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
> + if (ret)
> + return ret;
> +
> + ret = wait_for_response(hbus->hdev, &comp_pkt.host_event);
> + if (ret)
> + return ret;
> +
> + if (comp_pkt.completion_status == STATUS_NOT_SUPPORTED)
> + return -ENOTTY;
> +
> + if (comp_pkt.completion_status) {
> + pci_err(pdev, "Hyper-V device reset failed: %#x\n",
> + comp_pkt.completion_status);
> + return -EIO;
> + }
> +
> + return 0;
> +}
> +
> /* PCIe operations */
> static struct pci_ops hv_pcifront_ops = {
> .read = hv_pcifront_read_config,
> .write = hv_pcifront_write_config,
> + .reset = hv_pcifront_reset,
> };
>
> /*
> @@ -1996,6 +2056,7 @@ static void hv_compose_msi_msg(struct irq_data
> *data, struct msi_msg *msg)
> break;
>
> case PCI_PROTOCOL_VERSION_1_4:
> + case PCI_PROTOCOL_VERSION_1_5:
> size = hv_compose_msi_req_v3(&ctxt.int_pkts.v3,
> cpu,
> hpdev->desc.win_slot.slot,
> --
> 2.53.0