Linux PCI subsystem development
 help / color / mirror / Atom feed
* [PATCH RFC 0/2] Support Hyper-V vPCI controller reset method
@ 2026-07-24 23:08 wei.liu
  2026-07-24 23:08 ` [PATCH RFC 1/2] PCI: Add " wei.liu
  2026-07-24 23:08 ` [PATCH RFC 2/2] PCI: hv: Add vPCI device reset support wei.liu
  0 siblings, 2 replies; 13+ messages in thread
From: wei.liu @ 2026-07-24 23:08 UTC (permalink / raw)
  To: Linux on Hyper-V List, linux-pci; +Cc: Wei Liu

From: Wei Liu <wei.liu@kernel.org>

Hi,

On Azure, there are devices that don't support function level or PM
reset. They can only be reset by sending a VMBus message to the host.

This series is RFC because I modelled the reset method at the controller
level. If there is a better way to do it, I'm happy to change the code.

Thanks,
Wei

Wei Liu (2):
  PCI: Add controller reset method
  PCI: hv: Add vPCI device reset support

 Documentation/virt/hyperv/vpci.rst  |  2 +-
 drivers/pci/controller/pci-hyperv.c | 61 +++++++++++++++++++++++++++++
 drivers/pci/pci.c                   | 22 +++++++++++
 include/linux/pci.h                 |  3 +-
 4 files changed, 86 insertions(+), 2 deletions(-)

-- 
2.53.0


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH RFC 1/2] PCI: Add controller reset method
  2026-07-24 23:08 [PATCH RFC 0/2] Support Hyper-V vPCI controller reset method wei.liu
@ 2026-07-24 23:08 ` wei.liu
  2026-07-24 23:16   ` sashiko-bot
  2026-08-10 18:55   ` Wei Liu
  2026-07-24 23:08 ` [PATCH RFC 2/2] PCI: hv: Add vPCI device reset support wei.liu
  1 sibling, 2 replies; 13+ messages in thread
From: wei.liu @ 2026-07-24 23:08 UTC (permalink / raw)
  To: Linux on Hyper-V List, linux-pci; +Cc: Wei Liu, Bjorn Helgaas, open list

From: Wei Liu <wei.liu@kernel.org>

Some PCI controllers provide a function reset mechanism that is not
advertised in PCI configuration space. Allow them to expose it through an
optional pci_ops callback.

Add the controller reset method to the standard reset_method interface.
Prefer FLR and AF FLR by default, and use the controller operation before
PM and bus reset fallbacks.

Signed-off-by: Wei Liu <wei.liu@kernel.org>
---
 drivers/pci/pci.c   | 22 ++++++++++++++++++++++
 include/linux/pci.h |  3 ++-
 2 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 77b17b13ee61..4e55da202cad 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -4962,6 +4962,27 @@ static int pci_reset_bus_function(struct pci_dev *dev, bool probe)
 	return rc;
 }
 
+static int pci_controller_reset(struct pci_dev *dev, bool probe)
+{
+	int rc;
+
+	if (!dev->bus->ops->reset)
+		return -ENOTTY;
+
+	if (probe)
+		return dev->bus->ops->reset(dev, probe);
+
+	rc = pci_dev_reset_iommu_prepare(dev);
+	if (rc) {
+		pci_err(dev, "failed to stop IOMMU for a PCI reset: %d\n", rc);
+		return rc;
+	}
+
+	rc = dev->bus->ops->reset(dev, probe);
+	pci_dev_reset_iommu_done(dev);
+	return rc;
+}
+
 static int cxl_reset_bus_function(struct pci_dev *dev, bool probe)
 {
 	struct pci_dev *bridge;
@@ -5094,6 +5115,7 @@ const struct pci_reset_fn_method pci_reset_fn_methods[] = {
 	{ pci_dev_acpi_reset, .name = "acpi" },
 	{ pcie_reset_flr, .name = "flr" },
 	{ pci_af_flr, .name = "af_flr" },
+	{ pci_controller_reset, .name = "controller" },
 	{ pci_pm_reset, .name = "pm" },
 	{ pci_reset_bus_function, .name = "bus" },
 	{ cxl_reset_bus_function, .name = "cxl_bus" },
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 64b308b6e61c..d7759ee70670 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -52,7 +52,7 @@
 			       PCI_STATUS_PARITY)
 
 /* Number of reset methods used in pci_reset_fn_methods array in pci.c */
-#define PCI_NUM_RESET_METHODS 8
+#define PCI_NUM_RESET_METHODS 9
 
 #define PCI_RESET_PROBE		true
 #define PCI_RESET_DO_RESET	false
@@ -875,6 +875,7 @@ struct pci_ops {
 	void __iomem *(*map_bus)(struct pci_bus *bus, unsigned int devfn, int where);
 	int (*read)(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val);
 	int (*write)(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val);
+	int (*reset)(struct pci_dev *dev, bool probe);
 };
 
 /*
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH RFC 2/2] PCI: hv: Add vPCI device reset support
  2026-07-24 23:08 [PATCH RFC 0/2] Support Hyper-V vPCI controller reset method wei.liu
  2026-07-24 23:08 ` [PATCH RFC 1/2] PCI: Add " wei.liu
@ 2026-07-24 23:08 ` wei.liu
  2026-07-24 23:25   ` sashiko-bot
                     ` (2 more replies)
  1 sibling, 3 replies; 13+ messages in thread
From: wei.liu @ 2026-07-24 23:08 UTC (permalink / raw)
  To: Linux on Hyper-V List, linux-pci
  Cc: Wei Liu, K. Y. Srinivasan, Haiyang Zhang, Dexuan Cui, Long Li,
	Jonathan Corbet, Shuah Khan, Lorenzo Pieralisi,
	Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
	Bjorn Helgaas, open list:DOCUMENTATION, open list

From: Wei Liu <wei.liu@kernel.org>

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@kernel.org>
---
 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


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH RFC 1/2] PCI: Add controller reset method
  2026-07-24 23:08 ` [PATCH RFC 1/2] PCI: Add " wei.liu
@ 2026-07-24 23:16   ` sashiko-bot
  2026-08-10 18:55   ` Wei Liu
  1 sibling, 0 replies; 13+ messages in thread
From: sashiko-bot @ 2026-07-24 23:16 UTC (permalink / raw)
  To: wei.liu; +Cc: linux-hyperv, linux-pci

> From: Wei Liu <wei.liu@kernel.org>
> 
> Some PCI controllers provide a function reset mechanism that is not
> advertised in PCI configuration space. Allow them to expose it through an
> optional pci_ops callback.
> 
> Add the controller reset method to the standard reset_method interface.
> Prefer FLR and AF FLR by default, and use the controller operation before
> PM and bus reset fallbacks.
> 
> Signed-off-by: Wei Liu <wei.liu@kernel.org>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260724230844.3259741-1-wei.liu@kernel.org?part=1


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH RFC 2/2] PCI: hv: Add vPCI device reset support
  2026-07-24 23:08 ` [PATCH RFC 2/2] PCI: hv: Add vPCI device reset support wei.liu
@ 2026-07-24 23:25   ` sashiko-bot
  2026-08-11 16:10   ` Michael Kelley
  2026-08-13 21:40   ` [EXTERNAL] " Long Li
  2 siblings, 0 replies; 13+ messages in thread
From: sashiko-bot @ 2026-07-24 23:25 UTC (permalink / raw)
  To: wei.liu; +Cc: linux-hyperv, linux-pci

> From: Wei Liu <wei.liu@kernel.org>
> 
> 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@kernel.org>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260724230844.3259741-1-wei.liu@kernel.org?part=2


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH RFC 1/2] PCI: Add controller reset method
  2026-07-24 23:08 ` [PATCH RFC 1/2] PCI: Add " wei.liu
  2026-07-24 23:16   ` sashiko-bot
@ 2026-08-10 18:55   ` Wei Liu
  2026-08-11 16:28     ` Manivannan Sadhasivam
  1 sibling, 1 reply; 13+ messages in thread
From: Wei Liu @ 2026-08-10 18:55 UTC (permalink / raw)
  To: Linux on Hyper-V List, linux-pci; +Cc: Wei Liu, Bjorn Helgaas, open list

Hi Bjorn,

Since this is adding to the PCI reset framework, this patch needs your
approval.

Please see below for my questions. I'm happy to change the code however
you see fit.

On Fri, Jul 24, 2026 at 04:08:42PM -0700, wei.liu@kernel.org wrote:
> From: Wei Liu <wei.liu@kernel.org>
> 
> Some PCI controllers provide a function reset mechanism that is not
> advertised in PCI configuration space. Allow them to expose it through an
> optional pci_ops callback.
> 
> Add the controller reset method to the standard reset_method interface.
> Prefer FLR and AF FLR by default, and use the controller operation before
> PM and bus reset fallbacks.
> 
> Signed-off-by: Wei Liu <wei.liu@kernel.org>
> ---
>  drivers/pci/pci.c   | 22 ++++++++++++++++++++++
>  include/linux/pci.h |  3 ++-
>  2 files changed, 24 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> index 77b17b13ee61..4e55da202cad 100644
> --- a/drivers/pci/pci.c
> +++ b/drivers/pci/pci.c
> @@ -4962,6 +4962,27 @@ static int pci_reset_bus_function(struct pci_dev *dev, bool probe)
>  	return rc;
>  }
>  
> +static int pci_controller_reset(struct pci_dev *dev, bool probe)
> +{
> +	int rc;
> +
> +	if (!dev->bus->ops->reset)
> +		return -ENOTTY;
> +
> +	if (probe)
> +		return dev->bus->ops->reset(dev, probe);
> +
> +	rc = pci_dev_reset_iommu_prepare(dev);
> +	if (rc) {
> +		pci_err(dev, "failed to stop IOMMU for a PCI reset: %d\n", rc);
> +		return rc;
> +	}
> +
> +	rc = dev->bus->ops->reset(dev, probe);
> +	pci_dev_reset_iommu_done(dev);
> +	return rc;
> +}
> +

The first question is whether modelling this on the controller level
is the correct approach.

Please refer to the second patch for the intended usage in the Hyper-V
vPCI code.

Whatever is added here, a new reset_method value will be added to the
table. I chose "controller" to reflect the decision above.


>  static int cxl_reset_bus_function(struct pci_dev *dev, bool probe)
>  {
>  	struct pci_dev *bridge;
> @@ -5094,6 +5115,7 @@ const struct pci_reset_fn_method pci_reset_fn_methods[] = {
>  	{ pci_dev_acpi_reset, .name = "acpi" },
>  	{ pcie_reset_flr, .name = "flr" },
>  	{ pci_af_flr, .name = "af_flr" },
> +	{ pci_controller_reset, .name = "controller" },

The second question is whether this ordering is okay.

Thanks,
Wei

>  	{ pci_pm_reset, .name = "pm" },
>  	{ pci_reset_bus_function, .name = "bus" },
>  	{ cxl_reset_bus_function, .name = "cxl_bus" },
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index 64b308b6e61c..d7759ee70670 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -52,7 +52,7 @@
>  			       PCI_STATUS_PARITY)
>  
>  /* Number of reset methods used in pci_reset_fn_methods array in pci.c */
> -#define PCI_NUM_RESET_METHODS 8
> +#define PCI_NUM_RESET_METHODS 9
>  
>  #define PCI_RESET_PROBE		true
>  #define PCI_RESET_DO_RESET	false
> @@ -875,6 +875,7 @@ struct pci_ops {
>  	void __iomem *(*map_bus)(struct pci_bus *bus, unsigned int devfn, int where);
>  	int (*read)(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val);
>  	int (*write)(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val);
> +	int (*reset)(struct pci_dev *dev, bool probe);
>  };
>  
>  /*
> -- 
> 2.53.0
> 

^ permalink raw reply	[flat|nested] 13+ messages in thread

* RE: [PATCH RFC 2/2] PCI: hv: Add vPCI device reset support
  2026-07-24 23:08 ` [PATCH RFC 2/2] PCI: hv: Add vPCI device reset support wei.liu
  2026-07-24 23:25   ` sashiko-bot
@ 2026-08-11 16:10   ` Michael Kelley
  2026-08-11 17:36     ` Wei Liu
  2026-08-13 21:40   ` [EXTERNAL] " Long Li
  2 siblings, 1 reply; 13+ messages in thread
From: Michael Kelley @ 2026-08-11 16:10 UTC (permalink / raw)
  To: wei.liu@kernel.org, Linux on Hyper-V List,
	linux-pci@vger.kernel.org
  Cc: K. Y. Srinivasan, Haiyang Zhang, Dexuan Cui, Long Li,
	Jonathan Corbet, Shuah Khan, Lorenzo Pieralisi,
	Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
	Bjorn Helgaas, open list:DOCUMENTATION, open list

From: wei.liu@kernel.org <wei.liu@kernel.org> Sent: Friday, July 24, 2026 4:09 PM
> 
> 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@kernel.org>
> ---
>  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 */

I wish there were a better way to identify the Hyper-V version than internal
code names that mean nothing to the Linux community. "GE" refers to
Germanium, which would be the Build 26100 series, right?

>  };
> 
>  #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;

I tried this patch series in a linux-next20260726 build, and running on a D16lds v6
VM in Azure. The host hypervisor version is 10.0.26100.1652-1-0, and the VM
has a paravisor with HvLite.

This VM has an NVMe OS disk, two NVMe temp disks, and a MANA network controller.
Absent this patch set, the temp disks and MANA report the "reset_method" as "flr",
while the NVMe OS disk reports no reset methods. With this patch set, "controller"
is added as a reset method for all. The NVMe disks and MANA network controller
are probed with PCI protocol 1.5. That's all good and as expected (though I'm not
sure why the NVMe OS disk doesn't support flr).

I then did "echo 1 >reset" for the NVMe OS disk. This returns a -ENOTTY error
from the above line of code. So the host hypervisor (or paravisor?) is saying that
the new PCI_RESET_DEVICE message isn't supported. Presumably this is new
functionality that hasn’t been rolled out to where I'm running this Azure VM.
That's fine too.

But interestingly, the NVMe OS disk did a Linux-side reset anyway. That's
because of this stack trace from the "echo 1 >reset" command:

[   99.642483]  nvme_try_sched_reset+0x25/0x60 [nvme_core]
[   99.642495]  nvme_reset_done+0x1c/0x40 [nvme]
[   99.642499]  pci_dev_restore+0x35/0x70
[   99.642503]  pci_reset_function+0x100/0x140
[   99.642506]  reset_store+0x5a/0xa0
[   99.642508]  dev_attr_store+0x16/0x30
[   99.642512]  sysfs_kf_write+0x71/0x80
[   99.642516]  kernfs_fop_write_iter+0x140/0x1d0
[   99.642518]  vfs_write+0x313/0x420
[   99.642522]  ksys_write+0x68/0xe0
[   99.642525]  __x64_sys_write+0x18/0x20
[   99.642527]  x64_sys_call+0x1700/0x21c0
[   99.642530]  do_syscall_64+0x8d/0x440
[   99.642532]  entry_SYSCALL_64_after_hwframe+0x76/0x7e

Even though __pci_reset_function_locked() failed, the subsequent
code in pci_reset_function() calls nvme_try_sched_reset(), which puts
nvme_reset_work() on a workqueue.  nvme_reset_work() tears
things down on the Linux side and rebuilds, and the message

    nvme nvme0: 16/0/0 default/read/poll queues

is output.

It's not immediately clear to me how to resolve this issue, so
I'm just pointing it out. :-(

Michael

> +
> +	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
> 


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH RFC 1/2] PCI: Add controller reset method
  2026-08-10 18:55   ` Wei Liu
@ 2026-08-11 16:28     ` Manivannan Sadhasivam
  2026-08-11 17:56       ` Wei Liu
  0 siblings, 1 reply; 13+ messages in thread
From: Manivannan Sadhasivam @ 2026-08-11 16:28 UTC (permalink / raw)
  To: Wei Liu; +Cc: Linux on Hyper-V List, linux-pci, Bjorn Helgaas, open list

On Mon, Aug 10, 2026 at 11:55:45AM -0700, Wei Liu wrote:
> Hi Bjorn,
> 
> Since this is adding to the PCI reset framework, this patch needs your
> approval.
> 
> Please see below for my questions. I'm happy to change the code however
> you see fit.
> 
> On Fri, Jul 24, 2026 at 04:08:42PM -0700, wei.liu@kernel.org wrote:
> > From: Wei Liu <wei.liu@kernel.org>
> > 
> > Some PCI controllers provide a function reset mechanism that is not
> > advertised in PCI configuration space. Allow them to expose it through an
> > optional pci_ops callback.
> > 
> > Add the controller reset method to the standard reset_method interface.
> > Prefer FLR and AF FLR by default, and use the controller operation before
> > PM and bus reset fallbacks.
> > 
> > Signed-off-by: Wei Liu <wei.liu@kernel.org>
> > ---
> >  drivers/pci/pci.c   | 22 ++++++++++++++++++++++
> >  include/linux/pci.h |  3 ++-
> >  2 files changed, 24 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> > index 77b17b13ee61..4e55da202cad 100644
> > --- a/drivers/pci/pci.c
> > +++ b/drivers/pci/pci.c
> > @@ -4962,6 +4962,27 @@ static int pci_reset_bus_function(struct pci_dev *dev, bool probe)
> >  	return rc;
> >  }
> >  
> > +static int pci_controller_reset(struct pci_dev *dev, bool probe)
> > +{
> > +	int rc;
> > +
> > +	if (!dev->bus->ops->reset)
> > +		return -ENOTTY;
> > +
> > +	if (probe)
> > +		return dev->bus->ops->reset(dev, probe);
> > +
> > +	rc = pci_dev_reset_iommu_prepare(dev);
> > +	if (rc) {
> > +		pci_err(dev, "failed to stop IOMMU for a PCI reset: %d\n", rc);
> > +		return rc;
> > +	}
> > +
> > +	rc = dev->bus->ops->reset(dev, probe);
> > +	pci_dev_reset_iommu_done(dev);
> > +	return rc;
> > +}
> > +
> 
> The first question is whether modelling this on the controller level
> is the correct approach.
> 
> Please refer to the second patch for the intended usage in the Hyper-V
> vPCI code.
> 
> Whatever is added here, a new reset_method value will be added to the
> table. I chose "controller" to reflect the decision above.
> 

I recently added a hook for resetting the Root Ports in a platform specific way
[1]. This new hook is called in the SBR reset path. Will it work for you?

- Mani

[1] https://lore.kernel.org/all/20260729-pci-port-reset-v9-2-53570b92064d@oss.qualcomm.com/

-- 
மணிவண்ணன் சதாசிவம்

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH RFC 2/2] PCI: hv: Add vPCI device reset support
  2026-08-11 16:10   ` Michael Kelley
@ 2026-08-11 17:36     ` Wei Liu
  2026-08-11 17:58       ` Michael Kelley
  0 siblings, 1 reply; 13+ messages in thread
From: Wei Liu @ 2026-08-11 17:36 UTC (permalink / raw)
  To: Michael Kelley
  Cc: wei.liu@kernel.org, Linux on Hyper-V List,
	linux-pci@vger.kernel.org, K. Y. Srinivasan, Haiyang Zhang,
	Dexuan Cui, Long Li, Jonathan Corbet, Shuah Khan,
	Lorenzo Pieralisi, Krzysztof Wilczyński,
	Manivannan Sadhasivam, Rob Herring, Bjorn Helgaas,
	open list:DOCUMENTATION, open list

On Tue, Aug 11, 2026 at 04:10:33PM +0000, Michael Kelley wrote:
> From: wei.liu@kernel.org <wei.liu@kernel.org> Sent: Friday, July 24, 2026 4:09 PM
> > 
> > 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@kernel.org>
> > ---
> >  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 */
> 
> I wish there were a better way to identify the Hyper-V version than internal
> code names that mean nothing to the Linux community. "GE" refers to
> Germanium, which would be the Build 26100 series, right?
> 

Yes, you're right about Germanium. I see the numbers also match, though
I don't have a clear idea that the numbering will stay the same.

> >  };
> > 
> >  #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;
> 
> I tried this patch series in a linux-next20260726 build, and running on a D16lds v6
> VM in Azure. The host hypervisor version is 10.0.26100.1652-1-0, and the VM
> has a paravisor with HvLite.
> 
> This VM has an NVMe OS disk, two NVMe temp disks, and a MANA network controller.
> Absent this patch set, the temp disks and MANA report the "reset_method" as "flr",
> while the NVMe OS disk reports no reset methods. With this patch set, "controller"
> is added as a reset method for all. The NVMe disks and MANA network controller
> are probed with PCI protocol 1.5. That's all good and as expected (though I'm not
> sure why the NVMe OS disk doesn't support flr).
> 
> I then did "echo 1 >reset" for the NVMe OS disk. This returns a -ENOTTY error
> from the above line of code. So the host hypervisor (or paravisor?) is saying that
> the new PCI_RESET_DEVICE message isn't supported. Presumably this is new
> functionality that hasn’t been rolled out to where I'm running this Azure VM.
> That's fine too.
> 

That's right. It is not yet rolled out.

> But interestingly, the NVMe OS disk did a Linux-side reset anyway. That's
> because of this stack trace from the "echo 1 >reset" command:
> 
> [   99.642483]  nvme_try_sched_reset+0x25/0x60 [nvme_core]
> [   99.642495]  nvme_reset_done+0x1c/0x40 [nvme]
> [   99.642499]  pci_dev_restore+0x35/0x70
> [   99.642503]  pci_reset_function+0x100/0x140
> [   99.642506]  reset_store+0x5a/0xa0
> [   99.642508]  dev_attr_store+0x16/0x30
> [   99.642512]  sysfs_kf_write+0x71/0x80
> [   99.642516]  kernfs_fop_write_iter+0x140/0x1d0
> [   99.642518]  vfs_write+0x313/0x420
> [   99.642522]  ksys_write+0x68/0xe0
> [   99.642525]  __x64_sys_write+0x18/0x20
> [   99.642527]  x64_sys_call+0x1700/0x21c0
> [   99.642530]  do_syscall_64+0x8d/0x440
> [   99.642532]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
> 
> Even though __pci_reset_function_locked() failed, the subsequent
> code in pci_reset_function() calls nvme_try_sched_reset(), which puts
> nvme_reset_work() on a workqueue.  nvme_reset_work() tears
> things down on the Linux side and rebuilds, and the message
> 
>     nvme nvme0: 16/0/0 default/read/poll queues
> 
> is output.
> 
> It's not immediately clear to me how to resolve this issue, so
> I'm just pointing it out. :-(
> 

Is resetting the OS disk a real use case?

I'm not sure what magic is happening behind this.

Wei

> Michael
> 
> > +
> > +	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
> > 
> 

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH RFC 1/2] PCI: Add controller reset method
  2026-08-11 16:28     ` Manivannan Sadhasivam
@ 2026-08-11 17:56       ` Wei Liu
  0 siblings, 0 replies; 13+ messages in thread
From: Wei Liu @ 2026-08-11 17:56 UTC (permalink / raw)
  To: Manivannan Sadhasivam
  Cc: Wei Liu, Linux on Hyper-V List, linux-pci, Bjorn Helgaas,
	open list

On Tue, Aug 11, 2026 at 06:28:19PM +0200, Manivannan Sadhasivam wrote:
> 
> I recently added a hook for resetting the Root Ports in a platform specific way
> [1]. This new hook is called in the SBR reset path. Will it work for you?
> 
> - Mani
> 
> [1] https://lore.kernel.org/all/20260729-pci-port-reset-v9-2-53570b92064d@oss.qualcomm.com/
> 

Thank you. I will check that out.

Wei

^ permalink raw reply	[flat|nested] 13+ messages in thread

* RE: [PATCH RFC 2/2] PCI: hv: Add vPCI device reset support
  2026-08-11 17:36     ` Wei Liu
@ 2026-08-11 17:58       ` Michael Kelley
  0 siblings, 0 replies; 13+ messages in thread
From: Michael Kelley @ 2026-08-11 17:58 UTC (permalink / raw)
  To: Wei Liu, Michael Kelley
  Cc: Linux on Hyper-V List, linux-pci@vger.kernel.org,
	K. Y. Srinivasan, Haiyang Zhang, Dexuan Cui, Long Li,
	Jonathan Corbet, Shuah Khan, Lorenzo Pieralisi,
	Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
	Bjorn Helgaas, open list:DOCUMENTATION, open list

From: Wei Liu <wei.liu@kernel.org> Sent: Tuesday, August 11, 2026 10:37 AM
> 
> On Tue, Aug 11, 2026 at 04:10:33PM +0000, Michael Kelley wrote:
> > From: wei.liu@kernel.org <wei.liu@kernel.org> Sent: Friday, July 24, 2026 4:09 PM
> > >
> > > 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@kernel.org>
> > > ---
> > >  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 */
> >
> > I wish there were a better way to identify the Hyper-V version than internal
> > code names that mean nothing to the Linux community. "GE" refers to
> > Germanium, which would be the Build 26100 series, right?
> >
> 
> Yes, you're right about Germanium. I see the numbers also match, though
> I don't have a clear idea that the numbering will stay the same.
> 
> > >  };
> > >
> > >  #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;
> >
> > I tried this patch series in a linux-next20260726 build, and running on a D16lds v6
> > VM in Azure. The host hypervisor version is 10.0.26100.1652-1-0, and the VM
> > has a paravisor with HvLite.
> >
> > This VM has an NVMe OS disk, two NVMe temp disks, and a MANA network controller.
> > Absent this patch set, the temp disks and MANA report the "reset_method" as "flr",
> > while the NVMe OS disk reports no reset methods. With this patch set, "controller"
> > is added as a reset method for all. The NVMe disks and MANA network controller
> > are probed with PCI protocol 1.5. That's all good and as expected (though I'm not
> > sure why the NVMe OS disk doesn't support flr).
> >
> > I then did "echo 1 >reset" for the NVMe OS disk. This returns a -ENOTTY error
> > from the above line of code. So the host hypervisor (or paravisor?) is saying that
> > the new PCI_RESET_DEVICE message isn't supported. Presumably this is new
> > functionality that hasn’t been rolled out to where I'm running this Azure VM.
> > That's fine too.
> >
> 
> That's right. It is not yet rolled out.
> 
> > But interestingly, the NVMe OS disk did a Linux-side reset anyway. That's
> > because of this stack trace from the "echo 1 >reset" command:
> >
> > [   99.642483]  nvme_try_sched_reset+0x25/0x60 [nvme_core]
> > [   99.642495]  nvme_reset_done+0x1c/0x40 [nvme]
> > [   99.642499]  pci_dev_restore+0x35/0x70
> > [   99.642503]  pci_reset_function+0x100/0x140
> > [   99.642506]  reset_store+0x5a/0xa0
> > [   99.642508]  dev_attr_store+0x16/0x30
> > [   99.642512]  sysfs_kf_write+0x71/0x80
> > [   99.642516]  kernfs_fop_write_iter+0x140/0x1d0
> > [   99.642518]  vfs_write+0x313/0x420
> > [   99.642522]  ksys_write+0x68/0xe0
> > [   99.642525]  __x64_sys_write+0x18/0x20
> > [   99.642527]  x64_sys_call+0x1700/0x21c0
> > [   99.642530]  do_syscall_64+0x8d/0x440
> > [   99.642532]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
> >
> > Even though __pci_reset_function_locked() failed, the subsequent
> > code in pci_reset_function() calls nvme_try_sched_reset(), which puts
> > nvme_reset_work() on a workqueue.  nvme_reset_work() tears
> > things down on the Linux side and rebuilds, and the message
> >
> >     nvme nvme0: 16/0/0 default/read/poll queues
> >
> > is output.
> >
> > It's not immediately clear to me how to resolve this issue, so
> > I'm just pointing it out. :-(
> >
> 
> Is resetting the OS disk a real use case?

Perhaps not. However, the same behavior occurs with the NVMe
temp disks if "flr" is removed from "reset_modes" so that the
"controller" method is used. I was just trying to see how this new
controller method behaves, and the result seemed anomalous.
Using the "controller" method against the MANA device (again
presumably with a "not supported" reply from Hyper-V) produced
a hung MANA that I couldn't recover without rebooting the VM.
I did not try to sort out what when wrong there.

> 
> I'm not sure what magic is happening behind this.
> 

FWIW, I don't think anything is happening on the Hyper-V host side.
Hyper-V says PCI_RESET_DEVICE isn't supported and then just goes
on normally. But the Linux path through pci_reset_function() and
the NVMe driver does its reset handling even if none of the available
reset methods succeed. Arguably that's independent of your patch
set, though the existence of Hyper-V versions that support vPCI
protocol 1.5 but not PCI_RESET_DEVICE could make the problem
more likely.

Michael

^ permalink raw reply	[flat|nested] 13+ messages in thread

* RE: [EXTERNAL] [PATCH RFC 2/2] PCI: hv: Add vPCI device reset support
  2026-07-24 23:08 ` [PATCH RFC 2/2] PCI: hv: Add vPCI device reset support wei.liu
  2026-07-24 23:25   ` sashiko-bot
  2026-08-11 16:10   ` Michael Kelley
@ 2026-08-13 21:40   ` Long Li
  2026-08-23 23:57     ` Wei Liu
  2 siblings, 1 reply; 13+ messages in thread
From: Long Li @ 2026-08-13 21:40 UTC (permalink / raw)
  To: wei.liu@kernel.org, Linux on Hyper-V List,
	linux-pci@vger.kernel.org
  Cc: KY Srinivasan, Haiyang Zhang, Dexuan Cui, Jonathan Corbet,
	Shuah Khan, Lorenzo Pieralisi, Krzysztof Wilczyński,
	Manivannan Sadhasivam, Rob Herring, Bjorn Helgaas,
	open list:DOCUMENTATION, open list



> -----Original Message-----
> From: wei.liu@kernel.org <wei.liu@kernel.org>
> Sent: Friday, July 24, 2026 4:09 PM
> To: Linux on Hyper-V List <linux-hyperv@vger.kernel.org>; linux-
> pci@vger.kernel.org
> Cc: Wei Liu <wei.liu@kernel.org>; KY Srinivasan <kys@microsoft.com>;
> Haiyang Zhang <haiyangz@microsoft.com>; Dexuan Cui
> <DECUI@microsoft.com>; Long Li <longli@microsoft.com>; Jonathan Corbet
> <corbet@lwn.net>; Shuah Khan <skhan@linuxfoundation.org>; Lorenzo
> Pieralisi <lpieralisi@kernel.org>; Krzysztof Wilczyński
> <kwilczynski@kernel.org>; Manivannan Sadhasivam <mani@kernel.org>; Rob
> Herring <robh@kernel.org>; Bjorn Helgaas <bhelgaas@google.com>; open
> list:DOCUMENTATION <linux-doc@vger.kernel.org>; open list <linux-
> kernel@vger.kernel.org>
> Subject: [EXTERNAL] [PATCH RFC 2/2] PCI: hv: Add vPCI device reset support
> 
> From: Wei Liu <wei.liu@kernel.org>
> 
> 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@kernel.org>

Reviewed-by: Long Li <longli@microsoft.com>





> ---
>  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


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [EXTERNAL] [PATCH RFC 2/2] PCI: hv: Add vPCI device reset support
  2026-08-13 21:40   ` [EXTERNAL] " Long Li
@ 2026-08-23 23:57     ` Wei Liu
  0 siblings, 0 replies; 13+ messages in thread
From: Wei Liu @ 2026-08-23 23:57 UTC (permalink / raw)
  To: Long Li
  Cc: wei.liu@kernel.org, Linux on Hyper-V List,
	linux-pci@vger.kernel.org, KY Srinivasan, Haiyang Zhang,
	Dexuan Cui, Jonathan Corbet, Shuah Khan, Lorenzo Pieralisi,
	Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
	Bjorn Helgaas, open list:DOCUMENTATION, open list

On Thu, Aug 13, 2026 at 09:40:48PM +0000, Long Li wrote:
> 
> 
> > -----Original Message-----
> > From: wei.liu@kernel.org <wei.liu@kernel.org>
> > Sent: Friday, July 24, 2026 4:09 PM
> > To: Linux on Hyper-V List <linux-hyperv@vger.kernel.org>; linux-
> > pci@vger.kernel.org
> > Cc: Wei Liu <wei.liu@kernel.org>; KY Srinivasan <kys@microsoft.com>;
> > Haiyang Zhang <haiyangz@microsoft.com>; Dexuan Cui
> > <DECUI@microsoft.com>; Long Li <longli@microsoft.com>; Jonathan Corbet
> > <corbet@lwn.net>; Shuah Khan <skhan@linuxfoundation.org>; Lorenzo
> > Pieralisi <lpieralisi@kernel.org>; Krzysztof Wilczyński
> > <kwilczynski@kernel.org>; Manivannan Sadhasivam <mani@kernel.org>; Rob
> > Herring <robh@kernel.org>; Bjorn Helgaas <bhelgaas@google.com>; open
> > list:DOCUMENTATION <linux-doc@vger.kernel.org>; open list <linux-
> > kernel@vger.kernel.org>
> > Subject: [EXTERNAL] [PATCH RFC 2/2] PCI: hv: Add vPCI device reset support
> > 
> > From: Wei Liu <wei.liu@kernel.org>
> > 
> > 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@kernel.org>
> 
> Reviewed-by: Long Li <longli@microsoft.com>

Thanks for the review!

I still need to find some copious free time to test the new hook
suggested in patch one.

I don't think changes in patch 1 will result in major changes in this
patch, so I intend to retain this tag when I post next time.

Thanks,
Wei

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2026-08-23 23:57 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-24 23:08 [PATCH RFC 0/2] Support Hyper-V vPCI controller reset method wei.liu
2026-07-24 23:08 ` [PATCH RFC 1/2] PCI: Add " wei.liu
2026-07-24 23:16   ` sashiko-bot
2026-08-10 18:55   ` Wei Liu
2026-08-11 16:28     ` Manivannan Sadhasivam
2026-08-11 17:56       ` Wei Liu
2026-07-24 23:08 ` [PATCH RFC 2/2] PCI: hv: Add vPCI device reset support wei.liu
2026-07-24 23:25   ` sashiko-bot
2026-08-11 16:10   ` Michael Kelley
2026-08-11 17:36     ` Wei Liu
2026-08-11 17:58       ` Michael Kelley
2026-08-13 21:40   ` [EXTERNAL] " Long Li
2026-08-23 23:57     ` Wei Liu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox