[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 10/22] virtio-iommu: Implement set_iova_ranges() callback
|
From: |
Cédric Le Goater |
|
Subject: |
[PULL 10/22] virtio-iommu: Implement set_iova_ranges() callback |
|
Date: |
Mon, 6 Nov 2023 15:36:41 +0100 |
From: Eric Auger <eric.auger@redhat.com>
The implementation populates the array of per IOMMUDevice
host reserved ranges.
It is forbidden to have conflicting sets of host IOVA ranges
to be applied onto the same IOMMU MR (implied by different
host devices).
In case the callback is called after the probe request has
been issues by the driver, a warning is issued.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
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>
---
include/hw/virtio/virtio-iommu.h | 1 +
hw/virtio/virtio-iommu.c | 67 ++++++++++++++++++++++++++++++++
2 files changed, 68 insertions(+)
diff --git a/include/hw/virtio/virtio-iommu.h b/include/hw/virtio/virtio-iommu.h
index
1dd11ae81aeac25410f6f0a9bff89414b8edd48c..781ebaea8fca196ea4b74a8f790484ca61b5d37d
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;
+ GList *host_resv_ranges;
bool probe_done;
} IOMMUDevice;
diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c
index
13c3c087fe2ed7a4163ade5b40e11e6c8ea90b6e..15aadd6fdd623a59eaaf56980857e0b7d0bf4ee0
100644
--- a/hw/virtio/virtio-iommu.c
+++ b/hw/virtio/virtio-iommu.c
@@ -20,6 +20,7 @@
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "qemu/iov.h"
+#include "qemu/range.h"
#include "exec/target_page.h"
#include "hw/qdev-properties.h"
#include "hw/virtio/virtio.h"
@@ -1155,6 +1156,71 @@ static int
virtio_iommu_set_page_size_mask(IOMMUMemoryRegion *mr,
return 0;
}
+/**
+ * virtio_iommu_set_iova_ranges: Conveys the usable IOVA ranges
+ *
+ * The function turns those into reserved ranges. Once some
+ * reserved ranges have been set, new reserved regions cannot be
+ * added outside of the original ones.
+ *
+ * @mr: IOMMU MR
+ * @iova_ranges: list of usable IOVA ranges
+ * @errp: error handle
+ */
+static int virtio_iommu_set_iova_ranges(IOMMUMemoryRegion *mr,
+ GList *iova_ranges,
+ Error **errp)
+{
+ IOMMUDevice *sdev = container_of(mr, IOMMUDevice, iommu_mr);
+ GList *current_ranges = sdev->host_resv_ranges;
+ GList *l, *tmp, *new_ranges = NULL;
+ int ret = -EINVAL;
+
+ /* check that each new resv region is included in an existing one */
+ if (sdev->host_resv_ranges) {
+ range_inverse_array(iova_ranges,
+ &new_ranges,
+ 0, UINT64_MAX);
+
+ for (tmp = new_ranges; tmp; tmp = tmp->next) {
+ Range *newr = (Range *)tmp->data;
+ bool included = false;
+
+ for (l = current_ranges; l; l = l->next) {
+ Range * r = (Range *)l->data;
+
+ if (range_contains_range(r, newr)) {
+ included = true;
+ break;
+ }
+ }
+ if (!included) {
+ goto error;
+ }
+ }
+ /* all new reserved ranges are included in existing ones */
+ ret = 0;
+ goto out;
+ }
+
+ if (sdev->probe_done) {
+ warn_report("%s: Notified about new host reserved regions after probe",
+ mr->parent_obj.name);
+ }
+
+ range_inverse_array(iova_ranges,
+ &sdev->host_resv_ranges,
+ 0, UINT64_MAX);
+
+ return 0;
+error:
+ error_setg(errp, "IOMMU mr=%s Conflicting host reserved ranges set!",
+ mr->parent_obj.name);
+out:
+ g_list_free_full(new_ranges, g_free);
+ return ret;
+}
+
static void virtio_iommu_system_reset(void *opaque)
{
VirtIOIOMMU *s = opaque;
@@ -1450,6 +1516,7 @@ static void
virtio_iommu_memory_region_class_init(ObjectClass *klass,
imrc->replay = virtio_iommu_replay;
imrc->notify_flag_changed = virtio_iommu_notify_flag_changed;
imrc->iommu_set_page_size_mask = virtio_iommu_set_page_size_mask;
+ imrc->iommu_set_iova_ranges = virtio_iommu_set_iova_ranges;
}
static const TypeInfo virtio_iommu_info = {
--
2.41.0
- [PULL 01/22] memory: Let ReservedRegion use Range, (continued)
- [PULL 01/22] memory: Let ReservedRegion use Range, Cédric Le Goater, 2023/11/06
- [PULL 04/22] virtio-iommu: Rename reserved_regions into prop_resv_regions, Cédric Le Goater, 2023/11/06
- [PULL 05/22] range: Make range_compare() public, Cédric Le Goater, 2023/11/06
- [PULL 06/22] util/reserved-region: Add new ReservedRegion helpers, Cédric Le Goater, 2023/11/06
- [PULL 07/22] virtio-iommu: Introduce per IOMMUDevice reserved regions, Cédric Le Goater, 2023/11/06
- [PULL 03/22] vfio: Collect container iova range info, Cédric Le Goater, 2023/11/06
- [PULL 08/22] range: Introduce range_inverse_array(), Cédric Le Goater, 2023/11/06
- [PULL 09/22] virtio-iommu: Record whether a probe request has been issued, Cédric Le Goater, 2023/11/06
- [PULL 10/22] virtio-iommu: Implement set_iova_ranges() callback,
Cédric Le Goater <=
- [PULL 12/22] test: Add some tests for range and resv-mem helpers, Cédric Le Goater, 2023/11/06
- [PULL 11/22] virtio-iommu: Consolidate host reserved regions and property set ones, Cédric Le Goater, 2023/11/06
- [PULL 13/22] hw/pci: modify pci_setup_iommu() to set PCIIOMMUOps, Cédric Le Goater, 2023/11/06
- [PULL 14/22] util/uuid: Add UUID_STR_LEN definition, Cédric Le Goater, 2023/11/06
- [PULL 15/22] vfio/pci: Fix buffer overrun when writing the VF token, Cédric Le Goater, 2023/11/06
- [PULL 16/22] util/uuid: Remove UUID_FMT_LEN, Cédric Le Goater, 2023/11/06
- [PULL 17/22] util/uuid: Define UUID_STR_LEN from UUID_NONE string, Cédric Le Goater, 2023/11/06
- [PULL 18/22] vfio/container: Move IBM EEH related functions into spapr_pci_vfio.c, Cédric Le Goater, 2023/11/06
- [PULL 19/22] vfio/container: Move vfio_container_add/del_section_window into spapr.c, Cédric Le Goater, 2023/11/06
- [PULL 20/22] vfio/container: Move spapr specific init/deinit into spapr.c, Cédric Le Goater, 2023/11/06