[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 21/38] virtio-iommu: Set supported page size mask
From: |
Michael S. Tsirkin |
Subject: |
[PULL 21/38] virtio-iommu: Set supported page size mask |
Date: |
Tue, 3 Nov 2020 09:34:55 -0500 |
From: Bharat Bhushan <bbhushan2@marvell.com>
The virtio-iommu device can deal with arbitrary page sizes for virtual
endpoints, but for endpoints assigned with VFIO it must follow the page
granule used by the host IOMMU driver.
Implement the interface to set the vIOMMU page size mask, called by VFIO
for each endpoint. We assume that all host IOMMU drivers use the same
page granule (the host page granule). Override the page_size_mask field
in the virtio config space.
Signed-off-by: Bharat Bhushan <bbhushan2@marvell.com>
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
Message-Id: <20201030180510.747225-10-jean-philippe@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
hw/virtio/virtio-iommu.c | 50 ++++++++++++++++++++++++++++++++++++++++
hw/virtio/trace-events | 1 +
2 files changed, 51 insertions(+)
diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c
index 78e07aa40a..fc5c75d693 100644
--- a/hw/virtio/virtio-iommu.c
+++ b/hw/virtio/virtio-iommu.c
@@ -899,6 +899,55 @@ static int
virtio_iommu_notify_flag_changed(IOMMUMemoryRegion *iommu_mr,
return 0;
}
+/*
+ * The default mask (TARGET_PAGE_MASK) is the smallest supported guest granule,
+ * for example 0xfffffffffffff000. When an assigned device has page size
+ * restrictions due to the hardware IOMMU configuration, apply this restriction
+ * to the mask.
+ */
+static int virtio_iommu_set_page_size_mask(IOMMUMemoryRegion *mr,
+ uint64_t new_mask,
+ Error **errp)
+{
+ IOMMUDevice *sdev = container_of(mr, IOMMUDevice, iommu_mr);
+ VirtIOIOMMU *s = sdev->viommu;
+ uint64_t cur_mask = s->config.page_size_mask;
+
+ trace_virtio_iommu_set_page_size_mask(mr->parent_obj.name, cur_mask,
+ new_mask);
+
+ if ((cur_mask & new_mask) == 0) {
+ error_setg(errp, "virtio-iommu page mask 0x%"PRIx64
+ " is incompatible with mask 0x%"PRIx64, cur_mask, new_mask);
+ return -1;
+ }
+
+ /*
+ * After the machine is finalized, we can't change the mask anymore. If by
+ * chance the hotplugged device supports the same granule, we can still
+ * accept it. Having a different masks is possible but the guest will use
+ * sub-optimal block sizes, so warn about it.
+ */
+ if (qdev_hotplug) {
+ int new_granule = ctz64(new_mask);
+ int cur_granule = ctz64(cur_mask);
+
+ if (new_granule != cur_granule) {
+ error_setg(errp, "virtio-iommu page mask 0x%"PRIx64
+ " is incompatible with mask 0x%"PRIx64, cur_mask,
+ new_mask);
+ return -1;
+ } else if (new_mask != cur_mask) {
+ warn_report("virtio-iommu page mask 0x%"PRIx64
+ " does not match 0x%"PRIx64, cur_mask, new_mask);
+ }
+ return 0;
+ }
+
+ s->config.page_size_mask &= new_mask;
+ return 0;
+}
+
static void virtio_iommu_device_realize(DeviceState *dev, Error **errp)
{
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
@@ -1130,6 +1179,7 @@ static void
virtio_iommu_memory_region_class_init(ObjectClass *klass,
imrc->translate = virtio_iommu_translate;
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;
}
static const TypeInfo virtio_iommu_info = {
diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
index 982d0002a6..2060a144a2 100644
--- a/hw/virtio/trace-events
+++ b/hw/virtio/trace-events
@@ -109,6 +109,7 @@ virtio_iommu_fill_resv_property(uint32_t devid, uint8_t
subtype, uint64_t start,
virtio_iommu_notify_map(const char *name, uint64_t virt_start, uint64_t
virt_end, uint64_t phys_start, uint32_t flags) "mr=%s virt_start=0x%"PRIx64"
virt_end=0x%"PRIx64" phys_start=0x%"PRIx64" flags=%d"
virtio_iommu_notify_unmap(const char *name, uint64_t virt_start, uint64_t
virt_end) "mr=%s virt_start=0x%"PRIx64" virt_end=0x%"PRIx64
virtio_iommu_remap(const char *name, uint64_t virt_start, uint64_t virt_end,
uint64_t phys_start) "mr=%s virt_start=0x%"PRIx64" virt_end=0x%"PRIx64"
phys_start=0x%"PRIx64
+virtio_iommu_set_page_size_mask(const char *name, uint64_t old, uint64_t new)
"mr=%s old_mask=0x%"PRIx64" new_mask=0x%"PRIx64
virtio_iommu_notify_flag_add(const char *name) "add notifier to mr %s"
virtio_iommu_notify_flag_del(const char *name) "del notifier from mr %s"
--
MST
- [PULL 09/38] hw/acpi : add space before the open parenthesis '(', (continued)
- [PULL 09/38] hw/acpi : add space before the open parenthesis '(', Michael S. Tsirkin, 2020/11/03
- [PULL 13/38] virtio-iommu: Fix virtio_iommu_mr(), Michael S. Tsirkin, 2020/11/03
- [PULL 11/38] hw/virtio/vhost-backend: Fix Coverity CID 1432871, Michael S. Tsirkin, 2020/11/03
- [PULL 14/38] virtio-iommu: Store memory region in endpoint struct, Michael S. Tsirkin, 2020/11/03
- [PULL 15/38] virtio-iommu: Add memory notifiers for map/unmap, Michael S. Tsirkin, 2020/11/03
- [PULL 12/38] hw/smbios: Fix leaked fd in save_opt_one() error path, Michael S. Tsirkin, 2020/11/03
- [PULL 17/38] virtio-iommu: Add replay() memory region callback, Michael S. Tsirkin, 2020/11/03
- [PULL 18/38] virtio-iommu: Add notify_flag_changed() memory region callback, Michael S. Tsirkin, 2020/11/03
- [PULL 19/38] memory: Add interface to set iommu page size mask, Michael S. Tsirkin, 2020/11/03
- [PULL 20/38] vfio: Set IOMMU page size as per host supported page size, Michael S. Tsirkin, 2020/11/03
- [PULL 21/38] virtio-iommu: Set supported page size mask,
Michael S. Tsirkin <=
- [PULL 22/38] vfio: Don't issue full 2^64 unmap, Michael S. Tsirkin, 2020/11/03
- [PULL 23/38] vhost-vdpa: Add qemu_close in vhost_vdpa_cleanup, Michael S. Tsirkin, 2020/11/03
- [PULL 24/38] net: Add vhost-vdpa in show_netdevs(), Michael S. Tsirkin, 2020/11/03
- [PULL 26/38] vhost-blk: set features before setting inflight feature, Michael S. Tsirkin, 2020/11/03
- [PULL 27/38] libvhost-user: follow QEMU comment style, Michael S. Tsirkin, 2020/11/03
- [PULL 28/38] configure: introduce --enable-vhost-user-blk-server, Michael S. Tsirkin, 2020/11/03
- [PULL 29/38] block/export: make vhost-user-blk config space little-endian, Michael S. Tsirkin, 2020/11/03
- [PULL 30/38] block/export: fix vhost-user-blk get_config() information leak, Michael S. Tsirkin, 2020/11/03
- [PULL 31/38] contrib/vhost-user-blk: fix get_config() information leak, Michael S. Tsirkin, 2020/11/03
- [PULL 33/38] tests/qtest: add multi-queue test case to vhost-user-blk-test, Michael S. Tsirkin, 2020/11/03