* [PATCH v11 00/10] virtio-iommu: VFIO integration
@ 2020-10-30 18:05 Jean-Philippe Brucker
2020-10-30 18:05 ` [PATCH v11 01/10] virtio-iommu: Fix virtio_iommu_mr() Jean-Philippe Brucker
` (9 more replies)
0 siblings, 10 replies; 14+ messages in thread
From: Jean-Philippe Brucker @ 2020-10-30 18:05 UTC (permalink / raw)
To: eric.auger, alex.williamson
Cc: Jean-Philippe Brucker, mst, qemu-devel, peterx, pbonzini,
bbhushan2
This series adds support for VFIO endpoints to virtio-iommu.
Since [v10] I addressed the review comments, and changed the logic of
patch 9 for setting the page mask, as discussed. Please see individual
changelogs for details.
[v10] https://lore.kernel.org/qemu-devel/20201008171558.410886-1-jean-philippe@linaro.org/
Bharat Bhushan (7):
virtio-iommu: Add memory notifiers for map/unmap
virtio-iommu: Call memory notifiers in attach/detach
virtio-iommu: Add replay() memory region callback
virtio-iommu: Add notify_flag_changed() memory region callback
memory: Add interface to set iommu page size mask
vfio: Set IOMMU page size as per host supported page size
virtio-iommu: Set supported page size mask
Jean-Philippe Brucker (3):
virtio-iommu: Fix virtio_iommu_mr()
virtio-iommu: Store memory region in endpoint struct
vfio: Don't issue full 2^64 unmap
include/exec/memory.h | 38 ++++++++
hw/vfio/common.c | 19 ++++
hw/virtio/virtio-iommu.c | 205 ++++++++++++++++++++++++++++++++++++++-
softmmu/memory.c | 13 +++
hw/virtio/trace-events | 6 ++
5 files changed, 279 insertions(+), 2 deletions(-)
--
2.29.1
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v11 01/10] virtio-iommu: Fix virtio_iommu_mr()
2020-10-30 18:05 [PATCH v11 00/10] virtio-iommu: VFIO integration Jean-Philippe Brucker
@ 2020-10-30 18:05 ` Jean-Philippe Brucker
2020-10-30 18:05 ` [PATCH v11 02/10] virtio-iommu: Store memory region in endpoint struct Jean-Philippe Brucker
` (8 subsequent siblings)
9 siblings, 0 replies; 14+ messages in thread
From: Jean-Philippe Brucker @ 2020-10-30 18:05 UTC (permalink / raw)
To: eric.auger, alex.williamson
Cc: Jean-Philippe Brucker, mst, qemu-devel, peterx, QEMU Stable,
pbonzini, bbhushan2
Due to an invalid mask, virtio_iommu_mr() may return the wrong memory
region. It hasn't been too problematic so far because the function was
only used to test existence of an endpoint, but that is about to change.
Fixes: cfb42188b24d ("virtio-iommu: Implement attach/detach command")
Cc: QEMU Stable <qemu-stable@nongnu.org>
Acked-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
---
hw/virtio/virtio-iommu.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c
index 21ec63b1082..4c8f3909b7d 100644
--- a/hw/virtio/virtio-iommu.c
+++ b/hw/virtio/virtio-iommu.c
@@ -101,7 +101,7 @@ static IOMMUMemoryRegion *virtio_iommu_mr(VirtIOIOMMU *s, uint32_t sid)
bus_n = PCI_BUS_NUM(sid);
iommu_pci_bus = iommu_find_iommu_pcibus(s, bus_n);
if (iommu_pci_bus) {
- devfn = sid & PCI_DEVFN_MAX;
+ devfn = sid & (PCI_DEVFN_MAX - 1);
dev = iommu_pci_bus->pbdev[devfn];
if (dev) {
return &dev->iommu_mr;
--
2.29.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v11 02/10] virtio-iommu: Store memory region in endpoint struct
2020-10-30 18:05 [PATCH v11 00/10] virtio-iommu: VFIO integration Jean-Philippe Brucker
2020-10-30 18:05 ` [PATCH v11 01/10] virtio-iommu: Fix virtio_iommu_mr() Jean-Philippe Brucker
@ 2020-10-30 18:05 ` Jean-Philippe Brucker
2020-10-30 18:05 ` [PATCH v11 03/10] virtio-iommu: Add memory notifiers for map/unmap Jean-Philippe Brucker
` (7 subsequent siblings)
9 siblings, 0 replies; 14+ messages in thread
From: Jean-Philippe Brucker @ 2020-10-30 18:05 UTC (permalink / raw)
To: eric.auger, alex.williamson
Cc: Jean-Philippe Brucker, mst, qemu-devel, peterx, pbonzini,
bbhushan2
Store the memory region associated to each endpoint into the endpoint
structure, to allow efficient memory notification on map/unmap.
Acked-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
---
hw/virtio/virtio-iommu.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c
index 4c8f3909b7d..a5c2d69aad6 100644
--- a/hw/virtio/virtio-iommu.c
+++ b/hw/virtio/virtio-iommu.c
@@ -49,6 +49,7 @@ typedef struct VirtIOIOMMUDomain {
typedef struct VirtIOIOMMUEndpoint {
uint32_t id;
VirtIOIOMMUDomain *domain;
+ IOMMUMemoryRegion *iommu_mr;
QLIST_ENTRY(VirtIOIOMMUEndpoint) next;
} VirtIOIOMMUEndpoint;
@@ -137,16 +138,19 @@ static VirtIOIOMMUEndpoint *virtio_iommu_get_endpoint(VirtIOIOMMU *s,
uint32_t ep_id)
{
VirtIOIOMMUEndpoint *ep;
+ IOMMUMemoryRegion *mr;
ep = g_tree_lookup(s->endpoints, GUINT_TO_POINTER(ep_id));
if (ep) {
return ep;
}
- if (!virtio_iommu_mr(s, ep_id)) {
+ mr = virtio_iommu_mr(s, ep_id);
+ if (!mr) {
return NULL;
}
ep = g_malloc0(sizeof(*ep));
ep->id = ep_id;
+ ep->iommu_mr = mr;
trace_virtio_iommu_get_endpoint(ep_id);
g_tree_insert(s->endpoints, GUINT_TO_POINTER(ep_id), ep);
return ep;
@@ -910,9 +914,14 @@ static gboolean reconstruct_endpoints(gpointer key, gpointer value,
VirtIOIOMMU *s = (VirtIOIOMMU *)data;
VirtIOIOMMUDomain *d = (VirtIOIOMMUDomain *)value;
VirtIOIOMMUEndpoint *iter;
+ IOMMUMemoryRegion *mr;
QLIST_FOREACH(iter, &d->endpoint_list, next) {
+ mr = virtio_iommu_mr(s, iter->id);
+ assert(mr);
+
iter->domain = d;
+ iter->iommu_mr = mr;
g_tree_insert(s->endpoints, GUINT_TO_POINTER(iter->id), iter);
}
return false; /* continue the domain traversal */
--
2.29.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v11 03/10] virtio-iommu: Add memory notifiers for map/unmap
2020-10-30 18:05 [PATCH v11 00/10] virtio-iommu: VFIO integration Jean-Philippe Brucker
2020-10-30 18:05 ` [PATCH v11 01/10] virtio-iommu: Fix virtio_iommu_mr() Jean-Philippe Brucker
2020-10-30 18:05 ` [PATCH v11 02/10] virtio-iommu: Store memory region in endpoint struct Jean-Philippe Brucker
@ 2020-10-30 18:05 ` Jean-Philippe Brucker
2020-10-30 18:05 ` [PATCH v11 04/10] virtio-iommu: Call memory notifiers in attach/detach Jean-Philippe Brucker
` (6 subsequent siblings)
9 siblings, 0 replies; 14+ messages in thread
From: Jean-Philippe Brucker @ 2020-10-30 18:05 UTC (permalink / raw)
To: eric.auger, alex.williamson
Cc: Jean-Philippe Brucker, mst, qemu-devel, peterx, pbonzini,
bbhushan2
From: Bharat Bhushan <bbhushan2@marvell.com>
Extend VIRTIO_IOMMU_T_MAP/UNMAP request to notify memory listeners. It
will call VFIO notifier to map/unmap regions in the physical IOMMU.
Signed-off-by: Bharat Bhushan <bbhushan2@marvell.com>
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
---
v11:
* Forward permissions from the MAP request
* Don't notify MMIO mappings
---
hw/virtio/virtio-iommu.c | 56 ++++++++++++++++++++++++++++++++++++++++
hw/virtio/trace-events | 2 ++
2 files changed, 58 insertions(+)
diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c
index a5c2d69aad6..7dd15c5eacd 100644
--- a/hw/virtio/virtio-iommu.c
+++ b/hw/virtio/virtio-iommu.c
@@ -125,6 +125,51 @@ static gint interval_cmp(gconstpointer a, gconstpointer b, gpointer user_data)
}
}
+static void virtio_iommu_notify_map(IOMMUMemoryRegion *mr, hwaddr virt_start,
+ hwaddr virt_end, hwaddr paddr,
+ uint32_t flags)
+{
+ IOMMUTLBEntry entry;
+ IOMMUAccessFlags perm = IOMMU_ACCESS_FLAG(flags & VIRTIO_IOMMU_MAP_F_READ,
+ flags & VIRTIO_IOMMU_MAP_F_WRITE);
+
+ if (!(mr->iommu_notify_flags & IOMMU_NOTIFIER_MAP) ||
+ (flags & VIRTIO_IOMMU_MAP_F_MMIO) || !perm) {
+ return;
+ }
+
+ trace_virtio_iommu_notify_map(mr->parent_obj.name, virt_start, virt_end,
+ paddr, perm);
+
+ entry.target_as = &address_space_memory;
+ entry.addr_mask = virt_end - virt_start;
+ entry.iova = virt_start;
+ entry.perm = perm;
+ entry.translated_addr = paddr;
+
+ memory_region_notify_iommu(mr, 0, entry);
+}
+
+static void virtio_iommu_notify_unmap(IOMMUMemoryRegion *mr, hwaddr virt_start,
+ hwaddr virt_end)
+{
+ IOMMUTLBEntry entry;
+
+ if (!(mr->iommu_notify_flags & IOMMU_NOTIFIER_UNMAP)) {
+ return;
+ }
+
+ trace_virtio_iommu_notify_unmap(mr->parent_obj.name, virt_start, virt_end);
+
+ entry.target_as = &address_space_memory;
+ entry.addr_mask = virt_end - virt_start;
+ entry.iova = virt_start;
+ entry.perm = IOMMU_NONE;
+ entry.translated_addr = 0;
+
+ memory_region_notify_iommu(mr, 0, entry);
+}
+
static void virtio_iommu_detach_endpoint_from_domain(VirtIOIOMMUEndpoint *ep)
{
if (!ep->domain) {
@@ -315,6 +360,7 @@ static int virtio_iommu_map(VirtIOIOMMU *s,
VirtIOIOMMUDomain *domain;
VirtIOIOMMUInterval *interval;
VirtIOIOMMUMapping *mapping;
+ VirtIOIOMMUEndpoint *ep;
if (flags & ~VIRTIO_IOMMU_MAP_F_MASK) {
return VIRTIO_IOMMU_S_INVAL;
@@ -344,6 +390,11 @@ static int virtio_iommu_map(VirtIOIOMMU *s,
g_tree_insert(domain->mappings, interval, mapping);
+ QLIST_FOREACH(ep, &domain->endpoint_list, next) {
+ virtio_iommu_notify_map(ep->iommu_mr, virt_start, virt_end, phys_start,
+ flags);
+ }
+
return VIRTIO_IOMMU_S_OK;
}
@@ -356,6 +407,7 @@ static int virtio_iommu_unmap(VirtIOIOMMU *s,
VirtIOIOMMUMapping *iter_val;
VirtIOIOMMUInterval interval, *iter_key;
VirtIOIOMMUDomain *domain;
+ VirtIOIOMMUEndpoint *ep;
int ret = VIRTIO_IOMMU_S_OK;
trace_virtio_iommu_unmap(domain_id, virt_start, virt_end);
@@ -373,6 +425,10 @@ static int virtio_iommu_unmap(VirtIOIOMMU *s,
uint64_t current_high = iter_key->high;
if (interval.low <= current_low && interval.high >= current_high) {
+ QLIST_FOREACH(ep, &domain->endpoint_list, next) {
+ virtio_iommu_notify_unmap(ep->iommu_mr, current_low,
+ current_high);
+ }
g_tree_remove(domain->mappings, iter_key);
trace_virtio_iommu_unmap_done(domain_id, current_low, current_high);
} else {
diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
index cf1e59de302..b87a3974069 100644
--- a/hw/virtio/trace-events
+++ b/hw/virtio/trace-events
@@ -106,6 +106,8 @@ virtio_iommu_put_domain(uint32_t domain_id) "Free domain=%d"
virtio_iommu_translate_out(uint64_t virt_addr, uint64_t phys_addr, uint32_t sid) "0x%"PRIx64" -> 0x%"PRIx64 " for sid=%d"
virtio_iommu_report_fault(uint8_t reason, uint32_t flags, uint32_t endpoint, uint64_t addr) "FAULT reason=%d flags=%d endpoint=%d address =0x%"PRIx64
virtio_iommu_fill_resv_property(uint32_t devid, uint8_t subtype, uint64_t start, uint64_t end) "dev= %d, type=%d start=0x%"PRIx64" end=0x%"PRIx64
+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-mem.c
virtio_mem_send_response(uint16_t type) "type=%" PRIu16
--
2.29.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v11 04/10] virtio-iommu: Call memory notifiers in attach/detach
2020-10-30 18:05 [PATCH v11 00/10] virtio-iommu: VFIO integration Jean-Philippe Brucker
` (2 preceding siblings ...)
2020-10-30 18:05 ` [PATCH v11 03/10] virtio-iommu: Add memory notifiers for map/unmap Jean-Philippe Brucker
@ 2020-10-30 18:05 ` Jean-Philippe Brucker
2020-10-30 18:05 ` [PATCH v11 05/10] virtio-iommu: Add replay() memory region callback Jean-Philippe Brucker
` (5 subsequent siblings)
9 siblings, 0 replies; 14+ messages in thread
From: Jean-Philippe Brucker @ 2020-10-30 18:05 UTC (permalink / raw)
To: eric.auger, alex.williamson
Cc: Jean-Philippe Brucker, mst, qemu-devel, peterx, pbonzini,
bbhushan2
From: Bharat Bhushan <bbhushan2@marvell.com>
Call the memory notifiers when attaching an endpoint to a domain, to
replay existing mappings, and when detaching the endpoint, to remove all
mappings.
Signed-off-by: Bharat Bhushan <bbhushan2@marvell.com>
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
---
v11: Pass mapping permissions to the notifiers
---
hw/virtio/virtio-iommu.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c
index 7dd15c5eacd..7b648923517 100644
--- a/hw/virtio/virtio-iommu.c
+++ b/hw/virtio/virtio-iommu.c
@@ -170,11 +170,39 @@ static void virtio_iommu_notify_unmap(IOMMUMemoryRegion *mr, hwaddr virt_start,
memory_region_notify_iommu(mr, 0, entry);
}
+static gboolean virtio_iommu_notify_unmap_cb(gpointer key, gpointer value,
+ gpointer data)
+{
+ VirtIOIOMMUInterval *interval = (VirtIOIOMMUInterval *) key;
+ IOMMUMemoryRegion *mr = (IOMMUMemoryRegion *) data;
+
+ virtio_iommu_notify_unmap(mr, interval->low, interval->high);
+
+ return false;
+}
+
+static gboolean virtio_iommu_notify_map_cb(gpointer key, gpointer value,
+ gpointer data)
+{
+ VirtIOIOMMUMapping *mapping = (VirtIOIOMMUMapping *) value;
+ VirtIOIOMMUInterval *interval = (VirtIOIOMMUInterval *) key;
+ IOMMUMemoryRegion *mr = (IOMMUMemoryRegion *) data;
+
+ virtio_iommu_notify_map(mr, interval->low, interval->high,
+ mapping->phys_addr, mapping->flags);
+
+ return false;
+}
+
static void virtio_iommu_detach_endpoint_from_domain(VirtIOIOMMUEndpoint *ep)
{
+ VirtIOIOMMUDomain *domain = ep->domain;
+
if (!ep->domain) {
return;
}
+ g_tree_foreach(domain->mappings, virtio_iommu_notify_unmap_cb,
+ ep->iommu_mr);
QLIST_REMOVE(ep, next);
ep->domain = NULL;
}
@@ -317,6 +345,10 @@ static int virtio_iommu_attach(VirtIOIOMMU *s,
ep->domain = domain;
+ /* Replay domain mappings on the associated memory region */
+ g_tree_foreach(domain->mappings, virtio_iommu_notify_map_cb,
+ ep->iommu_mr);
+
return VIRTIO_IOMMU_S_OK;
}
--
2.29.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v11 05/10] virtio-iommu: Add replay() memory region callback
2020-10-30 18:05 [PATCH v11 00/10] virtio-iommu: VFIO integration Jean-Philippe Brucker
` (3 preceding siblings ...)
2020-10-30 18:05 ` [PATCH v11 04/10] virtio-iommu: Call memory notifiers in attach/detach Jean-Philippe Brucker
@ 2020-10-30 18:05 ` Jean-Philippe Brucker
2020-10-30 18:05 ` [PATCH v11 06/10] virtio-iommu: Add notify_flag_changed() " Jean-Philippe Brucker
` (4 subsequent siblings)
9 siblings, 0 replies; 14+ messages in thread
From: Jean-Philippe Brucker @ 2020-10-30 18:05 UTC (permalink / raw)
To: eric.auger, alex.williamson
Cc: Jean-Philippe Brucker, mst, qemu-devel, peterx, pbonzini,
bbhushan2
From: Bharat Bhushan <bbhushan2@marvell.com>
Implement the replay callback to setup all mappings for a new memory
region.
Signed-off-by: Bharat Bhushan <bbhushan2@marvell.com>
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
---
v11: Don't notify unmap before map, add permission flags
---
hw/virtio/virtio-iommu.c | 40 ++++++++++++++++++++++++++++++++++++++++
hw/virtio/trace-events | 1 +
2 files changed, 41 insertions(+)
diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c
index 7b648923517..985257c88fd 100644
--- a/hw/virtio/virtio-iommu.c
+++ b/hw/virtio/virtio-iommu.c
@@ -847,6 +847,45 @@ static gint int_cmp(gconstpointer a, gconstpointer b, gpointer user_data)
return (ua > ub) - (ua < ub);
}
+static gboolean virtio_iommu_remap(gpointer key, gpointer value, gpointer data)
+{
+ VirtIOIOMMUMapping *mapping = (VirtIOIOMMUMapping *) value;
+ VirtIOIOMMUInterval *interval = (VirtIOIOMMUInterval *) key;
+ IOMMUMemoryRegion *mr = (IOMMUMemoryRegion *) data;
+
+ trace_virtio_iommu_remap(mr->parent_obj.name, interval->low, interval->high,
+ mapping->phys_addr);
+ virtio_iommu_notify_map(mr, interval->low, interval->high,
+ mapping->phys_addr, mapping->flags);
+ return false;
+}
+
+static void virtio_iommu_replay(IOMMUMemoryRegion *mr, IOMMUNotifier *n)
+{
+ IOMMUDevice *sdev = container_of(mr, IOMMUDevice, iommu_mr);
+ VirtIOIOMMU *s = sdev->viommu;
+ uint32_t sid;
+ VirtIOIOMMUEndpoint *ep;
+
+ sid = virtio_iommu_get_bdf(sdev);
+
+ qemu_mutex_lock(&s->mutex);
+
+ if (!s->endpoints) {
+ goto unlock;
+ }
+
+ ep = g_tree_lookup(s->endpoints, GUINT_TO_POINTER(sid));
+ if (!ep || !ep->domain) {
+ goto unlock;
+ }
+
+ g_tree_foreach(ep->domain->mappings, virtio_iommu_remap, mr);
+
+unlock:
+ qemu_mutex_unlock(&s->mutex);
+}
+
static void virtio_iommu_device_realize(DeviceState *dev, Error **errp)
{
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
@@ -1076,6 +1115,7 @@ static void virtio_iommu_memory_region_class_init(ObjectClass *klass,
IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass);
imrc->translate = virtio_iommu_translate;
+ imrc->replay = virtio_iommu_replay;
}
static const TypeInfo virtio_iommu_info = {
diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
index b87a3974069..ea3c3b25ad7 100644
--- a/hw/virtio/trace-events
+++ b/hw/virtio/trace-events
@@ -108,6 +108,7 @@ virtio_iommu_report_fault(uint8_t reason, uint32_t flags, uint32_t endpoint, uin
virtio_iommu_fill_resv_property(uint32_t devid, uint8_t subtype, uint64_t start, uint64_t end) "dev= %d, type=%d start=0x%"PRIx64" end=0x%"PRIx64
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-mem.c
virtio_mem_send_response(uint16_t type) "type=%" PRIu16
--
2.29.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v11 06/10] virtio-iommu: Add notify_flag_changed() memory region callback
2020-10-30 18:05 [PATCH v11 00/10] virtio-iommu: VFIO integration Jean-Philippe Brucker
` (4 preceding siblings ...)
2020-10-30 18:05 ` [PATCH v11 05/10] virtio-iommu: Add replay() memory region callback Jean-Philippe Brucker
@ 2020-10-30 18:05 ` Jean-Philippe Brucker
2020-10-30 18:05 ` [PATCH v11 07/10] memory: Add interface to set iommu page size mask Jean-Philippe Brucker
` (3 subsequent siblings)
9 siblings, 0 replies; 14+ messages in thread
From: Jean-Philippe Brucker @ 2020-10-30 18:05 UTC (permalink / raw)
To: eric.auger, alex.williamson
Cc: Jean-Philippe Brucker, mst, qemu-devel, peterx, pbonzini,
bbhushan2
From: Bharat Bhushan <bbhushan2@marvell.com>
Add notify_flag_changed() to notice when memory listeners are added and
removed.
Acked-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Bharat Bhushan <bbhushan2@marvell.com>
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
---
v11: improve tracepoint string
---
hw/virtio/virtio-iommu.c | 14 ++++++++++++++
hw/virtio/trace-events | 2 ++
2 files changed, 16 insertions(+)
diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c
index 985257c88fd..78e07aa40a5 100644
--- a/hw/virtio/virtio-iommu.c
+++ b/hw/virtio/virtio-iommu.c
@@ -886,6 +886,19 @@ unlock:
qemu_mutex_unlock(&s->mutex);
}
+static int virtio_iommu_notify_flag_changed(IOMMUMemoryRegion *iommu_mr,
+ IOMMUNotifierFlag old,
+ IOMMUNotifierFlag new,
+ Error **errp)
+{
+ if (old == IOMMU_NOTIFIER_NONE) {
+ trace_virtio_iommu_notify_flag_add(iommu_mr->parent_obj.name);
+ } else if (new == IOMMU_NOTIFIER_NONE) {
+ trace_virtio_iommu_notify_flag_del(iommu_mr->parent_obj.name);
+ }
+ return 0;
+}
+
static void virtio_iommu_device_realize(DeviceState *dev, Error **errp)
{
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
@@ -1116,6 +1129,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;
}
static const TypeInfo virtio_iommu_info = {
diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
index ea3c3b25ad7..982d0002a65 100644
--- a/hw/virtio/trace-events
+++ b/hw/virtio/trace-events
@@ -109,6 +109,8 @@ 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_notify_flag_add(const char *name) "add notifier to mr %s"
+virtio_iommu_notify_flag_del(const char *name) "del notifier from mr %s"
# virtio-mem.c
virtio_mem_send_response(uint16_t type) "type=%" PRIu16
--
2.29.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v11 07/10] memory: Add interface to set iommu page size mask
2020-10-30 18:05 [PATCH v11 00/10] virtio-iommu: VFIO integration Jean-Philippe Brucker
` (5 preceding siblings ...)
2020-10-30 18:05 ` [PATCH v11 06/10] virtio-iommu: Add notify_flag_changed() " Jean-Philippe Brucker
@ 2020-10-30 18:05 ` Jean-Philippe Brucker
2020-10-30 18:05 ` [PATCH v11 08/10] vfio: Set IOMMU page size as per host supported page size Jean-Philippe Brucker
` (2 subsequent siblings)
9 siblings, 0 replies; 14+ messages in thread
From: Jean-Philippe Brucker @ 2020-10-30 18:05 UTC (permalink / raw)
To: eric.auger, alex.williamson
Cc: Jean-Philippe Brucker, mst, qemu-devel, peterx, pbonzini,
bbhushan2
From: Bharat Bhushan <bbhushan2@marvell.com>
Allow to set the page size mask supported by an iommu memory region.
This enables a vIOMMU to communicate the page size granule supported by
an assigned device, on hosts that use page sizes greater than 4kB.
Acked-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Bharat Bhushan <bbhushan2@marvell.com>
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
---
v11: improve comment
---
include/exec/memory.h | 38 ++++++++++++++++++++++++++++++++++++++
softmmu/memory.c | 13 +++++++++++++
2 files changed, 51 insertions(+)
diff --git a/include/exec/memory.h b/include/exec/memory.h
index aff6ef76053..0f3e6bcd5e7 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -397,6 +397,32 @@ struct IOMMUMemoryRegionClass {
* @iommu: the IOMMUMemoryRegion
*/
int (*num_indexes)(IOMMUMemoryRegion *iommu);
+
+ /**
+ * @iommu_set_page_size_mask:
+ *
+ * Restrict the page size mask that can be supported with a given IOMMU
+ * memory region. Used for example to propagate host physical IOMMU page
+ * size mask limitations to the virtual IOMMU.
+ *
+ * Optional method: if this method is not provided, then the default global
+ * page mask is used.
+ *
+ * @iommu: the IOMMUMemoryRegion
+ *
+ * @page_size_mask: a bitmask of supported page sizes. At least one bit,
+ * representing the smallest page size, must be set. Additional set bits
+ * represent supported block sizes. For example a host physical IOMMU that
+ * uses page tables with a page size of 4kB, and supports 2MB and 4GB
+ * blocks, will set mask 0x40201000. A granule of 4kB with indiscriminate
+ * block sizes is specified with mask 0xfffffffffffff000.
+ *
+ * Returns 0 on success, or a negative error. In case of failure, the error
+ * object must be created.
+ */
+ int (*iommu_set_page_size_mask)(IOMMUMemoryRegion *iommu,
+ uint64_t page_size_mask,
+ Error **errp);
};
typedef struct CoalescedMemoryRange CoalescedMemoryRange;
@@ -1409,6 +1435,18 @@ int memory_region_iommu_attrs_to_index(IOMMUMemoryRegion *iommu_mr,
*/
int memory_region_iommu_num_indexes(IOMMUMemoryRegion *iommu_mr);
+/**
+ * memory_region_iommu_set_page_size_mask: set the supported page
+ * sizes for a given IOMMU memory region
+ *
+ * @iommu_mr: IOMMU memory region
+ * @page_size_mask: supported page size mask
+ * @errp: pointer to Error*, to store an error if it happens.
+ */
+int memory_region_iommu_set_page_size_mask(IOMMUMemoryRegion *iommu_mr,
+ uint64_t page_size_mask,
+ Error **errp);
+
/**
* memory_region_name: get a memory region's name
*
diff --git a/softmmu/memory.c b/softmmu/memory.c
index ee4a6bc1685..bb40d2a1d8b 100644
--- a/softmmu/memory.c
+++ b/softmmu/memory.c
@@ -1841,6 +1841,19 @@ static int memory_region_update_iommu_notify_flags(IOMMUMemoryRegion *iommu_mr,
return ret;
}
+int memory_region_iommu_set_page_size_mask(IOMMUMemoryRegion *iommu_mr,
+ uint64_t page_size_mask,
+ Error **errp)
+{
+ IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_GET_CLASS(iommu_mr);
+ int ret = 0;
+
+ if (imrc->iommu_set_page_size_mask) {
+ ret = imrc->iommu_set_page_size_mask(iommu_mr, page_size_mask, errp);
+ }
+ return ret;
+}
+
int memory_region_register_iommu_notifier(MemoryRegion *mr,
IOMMUNotifier *n, Error **errp)
{
--
2.29.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v11 08/10] vfio: Set IOMMU page size as per host supported page size
2020-10-30 18:05 [PATCH v11 00/10] virtio-iommu: VFIO integration Jean-Philippe Brucker
` (6 preceding siblings ...)
2020-10-30 18:05 ` [PATCH v11 07/10] memory: Add interface to set iommu page size mask Jean-Philippe Brucker
@ 2020-10-30 18:05 ` Jean-Philippe Brucker
2020-10-30 18:05 ` [PATCH v11 09/10] virtio-iommu: Set supported page size mask Jean-Philippe Brucker
2020-10-30 18:05 ` [PATCH v11 10/10] vfio: Don't issue full 2^64 unmap Jean-Philippe Brucker
9 siblings, 0 replies; 14+ messages in thread
From: Jean-Philippe Brucker @ 2020-10-30 18:05 UTC (permalink / raw)
To: eric.auger, alex.williamson
Cc: Jean-Philippe Brucker, mst, qemu-devel, peterx, pbonzini,
bbhushan2
From: Bharat Bhushan <bbhushan2@marvell.com>
Set IOMMU supported page size mask same as host Linux supported page
size mask.
Acked-by: Alex Williamson <alex.williamson@redhat.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Bharat Bhushan <bbhushan2@marvell.com>
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
---
---
hw/vfio/common.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 13471ae2943..e66054b02a7 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -636,6 +636,14 @@ static void vfio_listener_region_add(MemoryListener *listener,
int128_get64(llend),
iommu_idx);
+ ret = memory_region_iommu_set_page_size_mask(giommu->iommu,
+ container->pgsizes,
+ &err);
+ if (ret) {
+ g_free(giommu);
+ goto fail;
+ }
+
ret = memory_region_register_iommu_notifier(section->mr, &giommu->n,
&err);
if (ret) {
--
2.29.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v11 09/10] virtio-iommu: Set supported page size mask
2020-10-30 18:05 [PATCH v11 00/10] virtio-iommu: VFIO integration Jean-Philippe Brucker
` (7 preceding siblings ...)
2020-10-30 18:05 ` [PATCH v11 08/10] vfio: Set IOMMU page size as per host supported page size Jean-Philippe Brucker
@ 2020-10-30 18:05 ` Jean-Philippe Brucker
2020-11-02 22:47 ` Peter Xu
2020-10-30 18:05 ` [PATCH v11 10/10] vfio: Don't issue full 2^64 unmap Jean-Philippe Brucker
9 siblings, 1 reply; 14+ messages in thread
From: Jean-Philippe Brucker @ 2020-10-30 18:05 UTC (permalink / raw)
To: eric.auger, alex.williamson
Cc: Jean-Philippe Brucker, mst, qemu-devel, peterx, pbonzini,
bbhushan2
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>
---
v11: Simplify the update logic slightly
---
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 78e07aa40a5..fc5c75d6933 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 982d0002a65..2060a144a2f 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"
--
2.29.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v11 10/10] vfio: Don't issue full 2^64 unmap
2020-10-30 18:05 [PATCH v11 00/10] virtio-iommu: VFIO integration Jean-Philippe Brucker
` (8 preceding siblings ...)
2020-10-30 18:05 ` [PATCH v11 09/10] virtio-iommu: Set supported page size mask Jean-Philippe Brucker
@ 2020-10-30 18:05 ` Jean-Philippe Brucker
9 siblings, 0 replies; 14+ messages in thread
From: Jean-Philippe Brucker @ 2020-10-30 18:05 UTC (permalink / raw)
To: eric.auger, alex.williamson
Cc: Jean-Philippe Brucker, mst, qemu-devel, peterx, pbonzini,
bbhushan2
IOMMUs may declare memory regions spanning from 0 to UINT64_MAX. When
attempting to deal with such region, vfio_listener_region_del() passes a
size of 2^64 to int128_get64() which throws an assertion failure. Even
ignoring this, the VFIO_IOMMU_DMA_MAP ioctl cannot handle this size
since the size field is 64-bit. Split the request in two.
Acked-by: Alex Williamson <alex.williamson@redhat.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
---
For me this happens when memory_region_iommu_set_page_size_mask()
returns an error because a hotplugged endpoint uses an incompatible page
mask. vfio_connect_container() releases the memory listener which calls
region_del() with the 2^64 IOMMU region. There are probably other ways
to reach this.
---
hw/vfio/common.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index e66054b02a7..e90a89c389e 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -797,6 +797,17 @@ static void vfio_listener_region_del(MemoryListener *listener,
}
if (try_unmap) {
+ if (llsize == int128_2_64()) {
+ /* The unmap ioctl doesn't accept a full 64-bit span. */
+ llsize = int128_rshift(llsize, 1);
+ ret = vfio_dma_unmap(container, iova, int128_get64(llsize));
+ if (ret) {
+ error_report("vfio_dma_unmap(%p, 0x%"HWADDR_PRIx", "
+ "0x%"HWADDR_PRIx") = %d (%m)",
+ container, iova, int128_get64(llsize), ret);
+ }
+ iova += int128_get64(llsize);
+ }
ret = vfio_dma_unmap(container, iova, int128_get64(llsize));
if (ret) {
error_report("vfio_dma_unmap(%p, 0x%"HWADDR_PRIx", "
--
2.29.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH v11 09/10] virtio-iommu: Set supported page size mask
2020-10-30 18:05 ` [PATCH v11 09/10] virtio-iommu: Set supported page size mask Jean-Philippe Brucker
@ 2020-11-02 22:47 ` Peter Xu
2020-11-03 16:32 ` Jean-Philippe Brucker
0 siblings, 1 reply; 14+ messages in thread
From: Peter Xu @ 2020-11-02 22:47 UTC (permalink / raw)
To: Jean-Philippe Brucker
Cc: mst, qemu-devel, eric.auger, alex.williamson, pbonzini, bbhushan2
On Fri, Oct 30, 2020 at 07:05:09PM +0100, Jean-Philippe Brucker wrote:
> 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.
(Nit: Seems slightly mismatched with the code below)
[...]
> + /*
> + * 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);
IMHO, new_mask!=cur_mask is ok, as long as it's a superset of reported
cur_mask, then it'll still guarantee to work.
Meanwhile, checking against granule seems not safe enough if the guest driver
started to use huge pages in iommu pgtables...
In summary:
if (qdev_hotplug) {
if ((new_mask & cur_mask) == cur_mask) {
/* Superset of old mask; we're good. Keep the old mask since same */
return 0;
} else {
/* Guest driver can use any psize in cur_mask, not safe to continue */
error_setg(...);
return -1;
}
}
Maybe we can also work on top too (if this is the only reason to repost,
especially if Michael would like to pick this up sooner), so I just raise this
up.
Thanks,
--
Peter Xu
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v11 09/10] virtio-iommu: Set supported page size mask
2020-11-02 22:47 ` Peter Xu
@ 2020-11-03 16:32 ` Jean-Philippe Brucker
2020-11-03 16:44 ` Peter Xu
0 siblings, 1 reply; 14+ messages in thread
From: Jean-Philippe Brucker @ 2020-11-03 16:32 UTC (permalink / raw)
To: Peter Xu
Cc: mst, qemu-devel, eric.auger, alex.williamson, pbonzini, bbhushan2
On Mon, Nov 02, 2020 at 05:47:25PM -0500, Peter Xu wrote:
> On Fri, Oct 30, 2020 at 07:05:09PM +0100, Jean-Philippe Brucker wrote:
> > 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.
>
> (Nit: Seems slightly mismatched with the code below)
>
> [...]
>
> > + /*
> > + * 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);
>
> IMHO, new_mask!=cur_mask is ok, as long as it's a superset of reported
> cur_mask, then it'll still guarantee to work.
>
> Meanwhile, checking against granule seems not safe enough if the guest driver
> started to use huge pages in iommu pgtables...
As the guest doesn't directly touch the page tables I think it is safe,
albeit slow. If the host IOMMU driver cannot support one huge page for a
mapping, then it will use several small pages instead.
>
> In summary:
>
> if (qdev_hotplug) {
> if ((new_mask & cur_mask) == cur_mask) {
> /* Superset of old mask; we're good. Keep the old mask since same */
> return 0;
That looks correct, but a bit too restrictive. If we start with
cur_mask = 0xfffffffffffff000, and we hotplug a VFIO device with
new_mask = 0x40201000 (4k page, 2M 1G blocks), then this code rejects it
even though it would work.
Thanks,
Jean
> } else {
> /* Guest driver can use any psize in cur_mask, not safe to continue */
> error_setg(...);
> return -1;
> }
> }
>
> Maybe we can also work on top too (if this is the only reason to repost,
> especially if Michael would like to pick this up sooner), so I just raise this
> up.
>
> Thanks,
>
> --
> Peter Xu
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v11 09/10] virtio-iommu: Set supported page size mask
2020-11-03 16:32 ` Jean-Philippe Brucker
@ 2020-11-03 16:44 ` Peter Xu
0 siblings, 0 replies; 14+ messages in thread
From: Peter Xu @ 2020-11-03 16:44 UTC (permalink / raw)
To: Jean-Philippe Brucker
Cc: mst, qemu-devel, eric.auger, alex.williamson, pbonzini, bbhushan2
On Tue, Nov 03, 2020 at 05:32:34PM +0100, Jean-Philippe Brucker wrote:
> > In summary:
> >
> > if (qdev_hotplug) {
> > if ((new_mask & cur_mask) == cur_mask) {
> > /* Superset of old mask; we're good. Keep the old mask since same */
> > return 0;
>
> That looks correct, but a bit too restrictive. If we start with
> cur_mask = 0xfffffffffffff000, and we hotplug a VFIO device with
> new_mask = 0x40201000 (4k page, 2M 1G blocks), then this code rejects it
> even though it would work.
Yeah I think you're right - it should be the smallest granule that matters the
most. Thanks,
--
Peter Xu
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2020-11-03 16:45 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-10-30 18:05 [PATCH v11 00/10] virtio-iommu: VFIO integration Jean-Philippe Brucker
2020-10-30 18:05 ` [PATCH v11 01/10] virtio-iommu: Fix virtio_iommu_mr() Jean-Philippe Brucker
2020-10-30 18:05 ` [PATCH v11 02/10] virtio-iommu: Store memory region in endpoint struct Jean-Philippe Brucker
2020-10-30 18:05 ` [PATCH v11 03/10] virtio-iommu: Add memory notifiers for map/unmap Jean-Philippe Brucker
2020-10-30 18:05 ` [PATCH v11 04/10] virtio-iommu: Call memory notifiers in attach/detach Jean-Philippe Brucker
2020-10-30 18:05 ` [PATCH v11 05/10] virtio-iommu: Add replay() memory region callback Jean-Philippe Brucker
2020-10-30 18:05 ` [PATCH v11 06/10] virtio-iommu: Add notify_flag_changed() " Jean-Philippe Brucker
2020-10-30 18:05 ` [PATCH v11 07/10] memory: Add interface to set iommu page size mask Jean-Philippe Brucker
2020-10-30 18:05 ` [PATCH v11 08/10] vfio: Set IOMMU page size as per host supported page size Jean-Philippe Brucker
2020-10-30 18:05 ` [PATCH v11 09/10] virtio-iommu: Set supported page size mask Jean-Philippe Brucker
2020-11-02 22:47 ` Peter Xu
2020-11-03 16:32 ` Jean-Philippe Brucker
2020-11-03 16:44 ` Peter Xu
2020-10-30 18:05 ` [PATCH v11 10/10] vfio: Don't issue full 2^64 unmap Jean-Philippe Brucker
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).