On 07/12/2021 22.04, Matthew Rosato wrote:
Use the associated vfio feature ioctl to enable adapter event notification
and forwarding for devices when requested. This feature will be set up
with or without firmware assist based upon the 'intassist' setting.
Signed-off-by: Matthew Rosato <mjrosato@xxxxxxxxxxxxx>
---
hw/s390x/s390-pci-bus.c | 24 +++++++--
hw/s390x/s390-pci-inst.c | 54 +++++++++++++++++++-
hw/s390x/s390-pci-vfio.c | 88 ++++++++++++++++++++++++++++++++
include/hw/s390x/s390-pci-bus.h | 1 +
include/hw/s390x/s390-pci-vfio.h | 20 ++++++++
5 files changed, 182 insertions(+), 5 deletions(-)
[...]
diff --git a/hw/s390x/s390-pci-vfio.c b/hw/s390x/s390-pci-vfio.c
index 78093aaac7..6f9271df87 100644
--- a/hw/s390x/s390-pci-vfio.c
+++ b/hw/s390x/s390-pci-vfio.c
@@ -152,6 +152,94 @@ int s390_pci_update_passthrough_fh(S390PCIBusDevice *pbdev)
return 0;
}
+int s390_pci_probe_aif(S390PCIBusDevice *pbdev)
+{
+ VFIOPCIDevice *vdev = container_of(pbdev->pdev, VFIOPCIDevice, pdev);
Should this use VFIO_PCI() instead of container_of ?
+ struct vfio_device_feature feat = {
+ .argsz = sizeof(struct vfio_device_feature),
+ .flags = VFIO_DEVICE_FEATURE_PROBE + VFIO_DEVICE_FEATURE_ZPCI_AIF
+ };
+
+ assert(vdev);
... then you could likely also drop the assert(), I think?
+ return ioctl(vdev->vbasedev.fd, VFIO_DEVICE_FEATURE, &feat);
+}
+
+int s390_pci_set_aif(S390PCIBusDevice *pbdev, ZpciFib *fib, bool enable,
+ bool assist)
+{
+ VFIOPCIDevice *vdev = container_of(pbdev->pdev, VFIOPCIDevice, pdev);
+ g_autofree struct vfio_device_feature *feat;
+ struct vfio_device_zpci_aif *data;
+ int size;
+
+ assert(vdev);
dito
+ size = sizeof(*feat) + sizeof(*data);
+ feat = g_malloc0(size);
+ feat->argsz = size;
+ feat->flags = VFIO_DEVICE_FEATURE_SET + VFIO_DEVICE_FEATURE_ZPCI_AIF;
+
+ data = (struct vfio_device_zpci_aif *)&feat->data;
+ if (enable) {
+ data->flags = VFIO_DEVICE_ZPCI_FLAG_AIF_FLOAT;
+ if (!pbdev->intassist) {
+ data->flags |= VFIO_DEVICE_ZPCI_FLAG_AIF_HOST;
+ }
+ /* Fill in the guest fib info */
+ data->ibv = fib->aibv;
+ data->sb = fib->aisb;
+ data->noi = FIB_DATA_NOI(fib->data);
+ data->isc = FIB_DATA_ISC(fib->data);
+ data->sbo = FIB_DATA_AISBO(fib->data);
+ } else {
+ data->flags = 0;
+ }
+
+ return ioctl(vdev->vbasedev.fd, VFIO_DEVICE_FEATURE, feat);
+}
+
+int s390_pci_get_aif(S390PCIBusDevice *pbdev, bool enable, bool assist)
+{
+ VFIOPCIDevice *vdev = container_of(pbdev->pdev, VFIOPCIDevice, pdev);
+ g_autofree struct vfio_device_feature *feat;
+ struct vfio_device_zpci_aif *data;
+ int size, rc;
+
+ assert(vdev);
dito
+ size = sizeof(*feat) + sizeof(*data);
+ feat = g_malloc0(size);
+ feat->argsz = size;
+ feat->flags = VFIO_DEVICE_FEATURE_GET + VFIO_DEVICE_FEATURE_ZPCI_AIF;
+
+ rc = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_FEATURE, feat);
+ if (rc) {
+ return rc;
+ }
+
+ /* Determine if current interrupt settings match the host */
+ data = (struct vfio_device_zpci_aif *)&feat->data;
+ if (enable && (!(data->flags & VFIO_DEVICE_ZPCI_FLAG_AIF_FLOAT))) {
+ rc = -EINVAL;
+ } else if (!enable && (data->flags & VFIO_DEVICE_ZPCI_FLAG_AIF_FLOAT)) {
+ rc = -EINVAL;
+ }
+
+ /*
+ * When enabled for interrupts, the assist and forced host-delivery are
+ * mututally exclusive
+ */
+ if (enable && assist && (data->flags & VFIO_DEVICE_ZPCI_FLAG_AIF_HOST)) {
+ rc = -EINVAL;
+ } else if (enable && (!assist) && (!(data->flags &
+ VFIO_DEVICE_ZPCI_FLAG_AIF_HOST))) {
+ rc = -EINVAL;
+ }
+
+ return rc;
+}
Thomas