aboutsummaryrefslogtreecommitdiff
path: root/hw/s390x
diff options
context:
space:
mode:
authorMatthew Rosato <mjrosato@linux.ibm.com>2022-10-28 15:47:58 -0400
committerThomas Huth <thuth@redhat.com>2022-12-15 15:02:34 +0100
commitdf202e3ff3fccb49868e08f20d0bda86cb953fbe (patch)
treec6e920bdc5bd33071c4e0ecc7da2046b2f0269bf /hw/s390x
parentef536007c3301bbd6a787e4c2210ea289adaa6f0 (diff)
downloadqemu-df202e3ff3fccb49868e08f20d0bda86cb953fbe.zip
qemu-df202e3ff3fccb49868e08f20d0bda86cb953fbe.tar.gz
qemu-df202e3ff3fccb49868e08f20d0bda86cb953fbe.tar.bz2
s390x/pci: shrink DMA aperture to be bound by vfio DMA limit
Currently, s390x-pci performs accounting against the vfio DMA limit and triggers the guest to clean up mappings when the limit is reached. Let's go a step further and also limit the size of the supported DMA aperture reported to the guest based upon the initial vfio DMA limit reported for the container (if less than than the size reported by the firmware/host zPCI layer). This avoids processing sections of the guest DMA table during global refresh that, for common use cases, will never be used anway, and makes exhausting the vfio DMA limit due to mismatch between guest aperture size and host limit far less likely and more indicitive of an error. Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com> Message-Id: <20221028194758.204007-4-mjrosato@linux.ibm.com> Reviewed-by: Eric Farman <farman@linux.ibm.com> Signed-off-by: Thomas Huth <thuth@redhat.com>
Diffstat (limited to 'hw/s390x')
-rw-r--r--hw/s390x/s390-pci-vfio.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/hw/s390x/s390-pci-vfio.c b/hw/s390x/s390-pci-vfio.c
index 5f0adb0..f7bf36c 100644
--- a/hw/s390x/s390-pci-vfio.c
+++ b/hw/s390x/s390-pci-vfio.c
@@ -84,6 +84,7 @@ S390PCIDMACount *s390_pci_start_dma_count(S390pciState *s,
cnt->users = 1;
cnt->avail = avail;
QTAILQ_INSERT_TAIL(&s->zpci_dma_limit, cnt, link);
+ pbdev->iommu->max_dma_limit = avail;
return cnt;
}
@@ -103,6 +104,7 @@ static void s390_pci_read_base(S390PCIBusDevice *pbdev,
struct vfio_info_cap_header *hdr;
struct vfio_device_info_cap_zpci_base *cap;
VFIOPCIDevice *vpci = container_of(pbdev->pdev, VFIOPCIDevice, pdev);
+ uint64_t vfio_size;
hdr = vfio_get_device_info_cap(info, VFIO_DEVICE_INFO_CAP_ZPCI_BASE);
@@ -122,6 +124,15 @@ static void s390_pci_read_base(S390PCIBusDevice *pbdev,
/* The following values remain 0 until we support other FMB formats */
pbdev->zpci_fn.fmbl = 0;
pbdev->zpci_fn.pft = 0;
+
+ /*
+ * If appropriate, reduce the size of the supported DMA aperture reported
+ * to the guest based upon the vfio DMA limit.
+ */
+ vfio_size = pbdev->iommu->max_dma_limit << TARGET_PAGE_BITS;
+ if (vfio_size < (cap->end_dma - cap->start_dma + 1)) {
+ pbdev->zpci_fn.edma = cap->start_dma + vfio_size - 1;
+ }
}
static bool get_host_fh(S390PCIBusDevice *pbdev, struct vfio_device_info *info,