aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Auger <eric.auger@redhat.com>2023-10-19 15:45:15 +0200
committerCédric Le Goater <clg@redhat.com>2023-11-03 09:20:31 +0100
commit09b4c3d6a2f098e64cc25aa63f388ea943990279 (patch)
treed9185268de206be3f218a60e59ab88d0cd772ae8
parentb439595a08d79120325de4684698bb7b6516aa8a (diff)
downloadqemu-09b4c3d6a2f098e64cc25aa63f388ea943990279.zip
qemu-09b4c3d6a2f098e64cc25aa63f388ea943990279.tar.gz
qemu-09b4c3d6a2f098e64cc25aa63f388ea943990279.tar.bz2
virtio-iommu: Record whether a probe request has been issued
Add an IOMMUDevice 'probe_done' flag to record that the driver already issued a probe request on that device. This will be useful to double check host reserved regions aren't notified after the probe and hence are not taken into account by the driver. Signed-off-by: Eric Auger <eric.auger@redhat.com> Suggested-by: Jean-Philippe Brucker <jean-philippe@linaro.org> Reviewed-by: "Michael S. Tsirkin" <mst@redhat.com> Tested-by: Yanghang Liu <yanghliu@redhat.com> Signed-off-by: Cédric Le Goater <clg@redhat.com>
-rw-r--r--hw/virtio/virtio-iommu.c20
-rw-r--r--include/hw/virtio/virtio-iommu.h1
2 files changed, 12 insertions, 9 deletions
diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c
index 0e23706..13c3c08 100644
--- a/hw/virtio/virtio-iommu.c
+++ b/hw/virtio/virtio-iommu.c
@@ -639,19 +639,13 @@ static int virtio_iommu_unmap(VirtIOIOMMU *s,
return ret;
}
-static ssize_t virtio_iommu_fill_resv_mem_prop(VirtIOIOMMU *s, uint32_t ep,
+static ssize_t virtio_iommu_fill_resv_mem_prop(IOMMUDevice *sdev, uint32_t ep,
uint8_t *buf, size_t free)
{
struct virtio_iommu_probe_resv_mem prop = {};
size_t size = sizeof(prop), length = size - sizeof(prop.head), total;
- IOMMUDevice *sdev;
GList *l;
- sdev = container_of(virtio_iommu_mr(s, ep), IOMMUDevice, iommu_mr);
- if (!sdev) {
- return -EINVAL;
- }
-
total = size * g_list_length(sdev->resv_regions);
if (total > free) {
return -ENOSPC;
@@ -688,19 +682,27 @@ static int virtio_iommu_probe(VirtIOIOMMU *s,
uint8_t *buf)
{
uint32_t ep_id = le32_to_cpu(req->endpoint);
+ IOMMUMemoryRegion *iommu_mr = virtio_iommu_mr(s, ep_id);
size_t free = VIOMMU_PROBE_SIZE;
+ IOMMUDevice *sdev;
ssize_t count;
- if (!virtio_iommu_mr(s, ep_id)) {
+ if (!iommu_mr) {
return VIRTIO_IOMMU_S_NOENT;
}
- count = virtio_iommu_fill_resv_mem_prop(s, ep_id, buf, free);
+ sdev = container_of(iommu_mr, IOMMUDevice, iommu_mr);
+ if (!sdev) {
+ return -EINVAL;
+ }
+
+ count = virtio_iommu_fill_resv_mem_prop(sdev, ep_id, buf, free);
if (count < 0) {
return VIRTIO_IOMMU_S_INVAL;
}
buf += count;
free -= count;
+ sdev->probe_done = true;
return VIRTIO_IOMMU_S_OK;
}
diff --git a/include/hw/virtio/virtio-iommu.h b/include/hw/virtio/virtio-iommu.h
index 70b8ace..1dd11ae 100644
--- a/include/hw/virtio/virtio-iommu.h
+++ b/include/hw/virtio/virtio-iommu.h
@@ -40,6 +40,7 @@ typedef struct IOMMUDevice {
MemoryRegion root; /* The root container of the device */
MemoryRegion bypass_mr; /* The alias of shared memory MR */
GList *resv_regions;
+ bool probe_done;
} IOMMUDevice;
typedef struct IOMMUPciBus {