On 8/25/25 23:24, Farhan Ali wrote:
For passthrough devices in error state, for a guest driven reset of the
device we can attempt a reset to recover the device. A reset of the device
will trigger a CLP disable/enable cycle on the host to bring the device
into a recovered state.
Signed-off-by: Farhan Ali <al...@linux.ibm.com>
---
hw/s390x/s390-pci-bus.c | 7 +++++++
hw/s390x/s390-pci-vfio.c | 6 ++++++
include/hw/s390x/s390-pci-vfio.h | 2 ++
3 files changed, 15 insertions(+)
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index af42eb9938..c9c2d775f0 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -1493,6 +1493,8 @@ static void s390_pci_device_reset(DeviceState *dev)
return;
case ZPCI_FS_STANDBY:
break;
+ case ZPCI_FS_ERROR:
+ break;
default:
pbdev->fh &= ~FH_MASK_ENABLE;
pbdev->state = ZPCI_FS_DISABLED;
@@ -1505,6 +1507,11 @@ static void s390_pci_device_reset(DeviceState *dev)
} else if (pbdev->summary_ind) {
pci_dereg_irqs(pbdev);
}
+
+ if (pbdev->state == ZPCI_FS_ERROR) {
+ s390_pci_reset(pbdev);
+ }
+
if (pbdev->iommu->enabled) {
pci_dereg_ioat(pbdev->iommu);
}
diff --git a/hw/s390x/s390-pci-vfio.c b/hw/s390x/s390-pci-vfio.c
index 87ecd06a81..a11ec770a7 100644
--- a/hw/s390x/s390-pci-vfio.c
+++ b/hw/s390x/s390-pci-vfio.c
@@ -158,6 +158,12 @@ static void s390_pci_err_handler(VFIOPCIDevice *vfio_pci)
return;
}
+void s390_pci_reset(S390PCIBusDevice *pbdev)
+{
+ VFIOPCIDevice *vfio_pci = container_of(pbdev->pdev, VFIOPCIDevice, pdev);
+ ioctl(vfio_pci->vbasedev.fd, VFIO_DEVICE_RESET);
+}
+
static void s390_pci_read_base(S390PCIBusDevice *pbdev,
struct vfio_device_info *info)
{
diff --git a/include/hw/s390x/s390-pci-vfio.h b/include/hw/s390x/s390-pci-vfio.h
index 66b274293c..c28dafeed8 100644
--- a/include/hw/s390x/s390-pci-vfio.h
+++ b/include/hw/s390x/s390-pci-vfio.h
@@ -23,6 +23,7 @@ void s390_pci_end_dma_count(S390pciState *s, S390PCIDMACount
*cnt);
bool s390_pci_get_host_fh(S390PCIBusDevice *pbdev, uint32_t *fh);
void s390_pci_get_clp_info(S390PCIBusDevice *pbdev);
void s390_pci_setup_err_handler(S390PCIBusDevice *pbdev);
+void s390_pci_reset(S390PCIBusDevice *pbdev);
#else
static inline bool s390_pci_update_dma_avail(int fd, unsigned int *avail)
{
@@ -41,6 +42,7 @@ static inline bool s390_pci_get_host_fh(S390PCIBusDevice
*pbdev, uint32_t *fh)
}
static inline void s390_pci_get_clp_info(S390PCIBusDevice *pbdev) { }
static inline void s390_pci_setup_err_handler(S390PCIBusDevice *pbdev) { }
+void s390_pci_reset(S390PCIBusDevice *pbdev) { }
static inline void ... ^
Thanks,
C.
#endif
#endif