From: Jagannathan Raman <jag.raman@oracle.com>
Pass through the MemoryRegion to DMA operation handlers of vfio
containers. The vfio-user container will need this later.
Originally-by: John Johnson <john.g.johnson@oracle.com>
Signed-off-by: Jagannathan Raman <jag.raman@oracle.com>
Signed-off-by: Elena Ufimtseva <elena.ufimtseva@oracle.com>
Signed-off-by: John Levon <john.levon@nutanix.com>
---
hw/vfio/common.c | 17 ++++++++++-------
hw/vfio/container-base.c | 4 ++--
hw/vfio/container.c | 3 ++-
hw/vfio/iommufd.c | 3 ++-
hw/virtio/vhost-vdpa.c | 2 +-
include/exec/memory.h | 4 +++-
include/hw/vfio/vfio-container-base.h | 4 ++--
system/memory.c | 7 ++++++-
8 files changed, 28 insertions(+), 16 deletions(-)
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index abbdc56b6d..8d3d425c63 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -248,12 +248,12 @@ static bool vfio_listener_skipped_section(MemoryRegionSection *section)
/* Called with rcu_read_lock held. */
static bool vfio_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr,
ram_addr_t *ram_addr, bool *read_only,
- Error **errp)
+ MemoryRegion **mrp, Error **errp)
{
bool ret, mr_has_discard_manager;
ret = memory_get_xlat_addr(iotlb, vaddr, ram_addr, read_only,
- &mr_has_discard_manager, errp);
+ &mr_has_discard_manager, mrp, errp);
if (ret && mr_has_discard_manager) {
/*
* Malicious VMs might trigger discarding of IOMMU-mapped memory. The
@@ -281,6 +281,7 @@ static void vfio_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb)
VFIOGuestIOMMU *giommu = container_of(n, VFIOGuestIOMMU, n);
VFIOContainerBase *bcontainer = giommu->bcontainer;
hwaddr iova = iotlb->iova + giommu->iommu_offset;
+ MemoryRegion *mrp;
void *vaddr;
int ret;
Error *local_err = NULL;
@@ -300,7 +301,8 @@ static void vfio_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb)
if ((iotlb->perm & IOMMU_RW) != IOMMU_NONE) {
bool read_only;
- if (!vfio_get_xlat_addr(iotlb, &vaddr, NULL, &read_only, &local_err)) {
+ if (!vfio_get_xlat_addr(iotlb, &vaddr, NULL, &read_only, &mrp,
+ &local_err)) {
error_report_err(local_err);
goto out;
}
@@ -313,7 +315,7 @@ static void vfio_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb)
*/
ret = vfio_container_dma_map(bcontainer, iova,
iotlb->addr_mask + 1, vaddr,
- read_only);
+ read_only, mrp);
if (ret) {
error_report("vfio_container_dma_map(%p, 0x%"HWADDR_PRIx", "
"0x%"HWADDR_PRIx", %p) = %d (%s)",
@@ -378,7 +380,7 @@ static int vfio_ram_discard_notify_populate(RamDiscardListener *rdl,
vaddr = memory_region_get_ram_ptr(section->mr) + start;
ret = vfio_container_dma_map(bcontainer, iova, next - start,
- vaddr, section->readonly);
+ vaddr, section->readonly, section->mr);
if (ret) {
/* Rollback */
vfio_ram_discard_notify_discard(rdl, section);
@@ -675,7 +677,7 @@ static void vfio_listener_region_add(MemoryListener *listener,
}
ret = vfio_container_dma_map(bcontainer, iova, int128_get64(llsize),
- vaddr, section->readonly);
+ vaddr, section->readonly, section->mr);
if (ret) {
error_setg(&err, "vfio_container_dma_map(%p, 0x%"HWADDR_PRIx", "
"0x%"HWADDR_PRIx", %p) = %d (%s)",
@@ -1232,7 +1234,8 @@ static void vfio_iommu_map_dirty_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb)
}
rcu_read_lock();
- if (!vfio_get_xlat_addr(iotlb, NULL, &translated_addr, NULL, &local_err)) {
+ if (!vfio_get_xlat_addr(iotlb, NULL, &translated_addr, NULL, NULL,
+ &local_err)) {
error_report_err(local_err);
goto out_unlock;
}
diff --git a/hw/vfio/container-base.c b/hw/vfio/container-base.c
index 749a3fd29d..5e0c9700d9 100644
--- a/hw/vfio/container-base.c
+++ b/hw/vfio/container-base.c
@@ -17,12 +17,12 @@
int vfio_container_dma_map(VFIOContainerBase *bcontainer,
hwaddr iova, ram_addr_t size,
- void *vaddr, bool readonly)
+ void *vaddr, bool readonly, MemoryRegion *mrp)
{
VFIOIOMMUClass *vioc = VFIO_IOMMU_GET_CLASS(bcontainer);
g_assert(vioc->dma_map);
- return vioc->dma_map(bcontainer, iova, size, vaddr, readonly);
+ return vioc->dma_map(bcontainer, iova, size, vaddr, readonly, mrp);
}
int vfio_container_dma_unmap(VFIOContainerBase *bcontainer,
diff --git a/hw/vfio/container.c b/hw/vfio/container.c
index 7c57bdd27b..0db0055f39 100644
--- a/hw/vfio/container.c
+++ b/hw/vfio/container.c
@@ -175,7 +175,8 @@ static int vfio_legacy_dma_unmap(const VFIOContainerBase *bcontainer,
}
static int vfio_legacy_dma_map(const VFIOContainerBase *bcontainer, hwaddr iova,
- ram_addr_t size, void *vaddr, bool readonly)
+ ram_addr_t size, void *vaddr, bool readonly,
+ MemoryRegion *mrp)
{
const VFIOContainer *container = container_of(bcontainer, VFIOContainer,
bcontainer);
diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
index df61edffc0..583b063707 100644
--- a/hw/vfio/iommufd.c
+++ b/hw/vfio/iommufd.c
@@ -28,7 +28,8 @@
#include "exec/ram_addr.h"
static int iommufd_cdev_map(const VFIOContainerBase *bcontainer, hwaddr iova,
- ram_addr_t size, void *vaddr, bool readonly)
+ ram_addr_t size, void *vaddr, bool readonly,
+ MemoryRegion *mrp)
{
const VFIOIOMMUFDContainer *container =
container_of(bcontainer, VFIOIOMMUFDContainer, bcontainer);
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index 3cdaa12ed5..a1866bb396 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -228,7 +228,7 @@ static void vhost_vdpa_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb)
if ((iotlb->perm & IOMMU_RW) != IOMMU_NONE) {
bool read_only;
- if (!memory_get_xlat_addr(iotlb, &vaddr, NULL, &read_only, NULL,
+ if (!memory_get_xlat_addr(iotlb, &vaddr, NULL, &read_only, NULL, NULL,
&local_err)) {
error_report_err(local_err);
return;
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 9f73b59867..adaf1d1ca4 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -747,13 +747,15 @@ void ram_discard_manager_unregister_listener(RamDiscardManager *rdm,
* @read_only: indicates if writes are allowed
* @mr_has_discard_manager: indicates memory is controlled by a
* RamDiscardManager
+ * @mrp: if non-NULL, fill in with MemoryRegion
* @errp: pointer to Error*, to store an error if it happens.
*
* Return: true on success, else false setting @errp with error.
*/
bool memory_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr,
ram_addr_t *ram_addr, bool *read_only,
- bool *mr_has_discard_manager, Error **errp);
+ bool *mr_has_discard_manager, MemoryRegion **mrp,
+ Error **errp);
typedef struct CoalescedMemoryRange CoalescedMemoryRange;
typedef struct MemoryRegionIoeventfd MemoryRegionIoeventfd;
diff --git a/include/hw/vfio/vfio-container-base.h b/include/hw/vfio/vfio-container-base.h
index 4cff9943ab..c9d339383e 100644
--- a/include/hw/vfio/vfio-container-base.h
+++ b/include/hw/vfio/vfio-container-base.h
@@ -73,7 +73,7 @@ typedef struct VFIORamDiscardListener {
int vfio_container_dma_map(VFIOContainerBase *bcontainer,
hwaddr iova, ram_addr_t size,
- void *vaddr, bool readonly);
+ void *vaddr, bool readonly, MemoryRegion *mrp);
int vfio_container_dma_unmap(VFIOContainerBase *bcontainer,
hwaddr iova, ram_addr_t size,
IOMMUTLBEntry *iotlb);
@@ -113,7 +113,7 @@ struct VFIOIOMMUClass {
bool (*setup)(VFIOContainerBase *bcontainer, Error **errp);
int (*dma_map)(const VFIOContainerBase *bcontainer,
hwaddr iova, ram_addr_t size,
- void *vaddr, bool readonly);
+ void *vaddr, bool readonly, MemoryRegion *mrp);
int (*dma_unmap)(const VFIOContainerBase *bcontainer,
hwaddr iova, ram_addr_t size,
IOMMUTLBEntry *iotlb);
diff --git a/system/memory.c b/system/memory.c
index 4c829793a0..de4f955a66 100644
--- a/system/memory.c
+++ b/system/memory.c
@@ -2185,7 +2185,8 @@ void ram_discard_manager_unregister_listener(RamDiscardManager *rdm,
/* Called with rcu_read_lock held. */
bool memory_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr,
ram_addr_t *ram_addr, bool *read_only,
- bool *mr_has_discard_manager, Error **errp)
+ bool *mr_has_discard_manager, MemoryRegion **mrp,
+ Error **errp)
{
MemoryRegion *mr;
hwaddr xlat;
@@ -2250,6 +2251,10 @@ bool memory_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr,
*read_only = !writable || mr->readonly;
}
+ if (mrp != NULL) {
+ *mrp = mr;
+ }
+
return true;
}
--
2.34.1
On 2/19/25 15:48, John Levon wrote: > From: Jagannathan Raman <jag.raman@oracle.com> > > Pass through the MemoryRegion to DMA operation handlers of vfio > containers. The vfio-user container will need this later. > > Originally-by: John Johnson <john.g.johnson@oracle.com> > Signed-off-by: Jagannathan Raman <jag.raman@oracle.com> > Signed-off-by: Elena Ufimtseva <elena.ufimtseva@oracle.com> > Signed-off-by: John Levon <john.levon@nutanix.com> FYI, in case you didn't see the discussion here : https://lore.kernel.org/qemu-devel/1739542467-226739-29-git-send-email-steven.sistare@oracle.com/ Thanks, C. > --- > hw/vfio/common.c | 17 ++++++++++------- > hw/vfio/container-base.c | 4 ++-- > hw/vfio/container.c | 3 ++- > hw/vfio/iommufd.c | 3 ++- > hw/virtio/vhost-vdpa.c | 2 +- > include/exec/memory.h | 4 +++- > include/hw/vfio/vfio-container-base.h | 4 ++-- > system/memory.c | 7 ++++++- > 8 files changed, 28 insertions(+), 16 deletions(-) > > diff --git a/hw/vfio/common.c b/hw/vfio/common.c > index abbdc56b6d..8d3d425c63 100644 > --- a/hw/vfio/common.c > +++ b/hw/vfio/common.c > @@ -248,12 +248,12 @@ static bool vfio_listener_skipped_section(MemoryRegionSection *section) > /* Called with rcu_read_lock held. */ > static bool vfio_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr, > ram_addr_t *ram_addr, bool *read_only, > - Error **errp) > + MemoryRegion **mrp, Error **errp) > { > bool ret, mr_has_discard_manager; > > ret = memory_get_xlat_addr(iotlb, vaddr, ram_addr, read_only, > - &mr_has_discard_manager, errp); > + &mr_has_discard_manager, mrp, errp); > if (ret && mr_has_discard_manager) { > /* > * Malicious VMs might trigger discarding of IOMMU-mapped memory. The > @@ -281,6 +281,7 @@ static void vfio_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb) > VFIOGuestIOMMU *giommu = container_of(n, VFIOGuestIOMMU, n); > VFIOContainerBase *bcontainer = giommu->bcontainer; > hwaddr iova = iotlb->iova + giommu->iommu_offset; > + MemoryRegion *mrp; > void *vaddr; > int ret; > Error *local_err = NULL; > @@ -300,7 +301,8 @@ static void vfio_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb) > if ((iotlb->perm & IOMMU_RW) != IOMMU_NONE) { > bool read_only; > > - if (!vfio_get_xlat_addr(iotlb, &vaddr, NULL, &read_only, &local_err)) { > + if (!vfio_get_xlat_addr(iotlb, &vaddr, NULL, &read_only, &mrp, > + &local_err)) { > error_report_err(local_err); > goto out; > } > @@ -313,7 +315,7 @@ static void vfio_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb) > */ > ret = vfio_container_dma_map(bcontainer, iova, > iotlb->addr_mask + 1, vaddr, > - read_only); > + read_only, mrp); > if (ret) { > error_report("vfio_container_dma_map(%p, 0x%"HWADDR_PRIx", " > "0x%"HWADDR_PRIx", %p) = %d (%s)", > @@ -378,7 +380,7 @@ static int vfio_ram_discard_notify_populate(RamDiscardListener *rdl, > vaddr = memory_region_get_ram_ptr(section->mr) + start; > > ret = vfio_container_dma_map(bcontainer, iova, next - start, > - vaddr, section->readonly); > + vaddr, section->readonly, section->mr); > if (ret) { > /* Rollback */ > vfio_ram_discard_notify_discard(rdl, section); > @@ -675,7 +677,7 @@ static void vfio_listener_region_add(MemoryListener *listener, > } > > ret = vfio_container_dma_map(bcontainer, iova, int128_get64(llsize), > - vaddr, section->readonly); > + vaddr, section->readonly, section->mr); > if (ret) { > error_setg(&err, "vfio_container_dma_map(%p, 0x%"HWADDR_PRIx", " > "0x%"HWADDR_PRIx", %p) = %d (%s)", > @@ -1232,7 +1234,8 @@ static void vfio_iommu_map_dirty_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb) > } > > rcu_read_lock(); > - if (!vfio_get_xlat_addr(iotlb, NULL, &translated_addr, NULL, &local_err)) { > + if (!vfio_get_xlat_addr(iotlb, NULL, &translated_addr, NULL, NULL, > + &local_err)) { > error_report_err(local_err); > goto out_unlock; > } > diff --git a/hw/vfio/container-base.c b/hw/vfio/container-base.c > index 749a3fd29d..5e0c9700d9 100644 > --- a/hw/vfio/container-base.c > +++ b/hw/vfio/container-base.c > @@ -17,12 +17,12 @@ > > int vfio_container_dma_map(VFIOContainerBase *bcontainer, > hwaddr iova, ram_addr_t size, > - void *vaddr, bool readonly) > + void *vaddr, bool readonly, MemoryRegion *mrp) > { > VFIOIOMMUClass *vioc = VFIO_IOMMU_GET_CLASS(bcontainer); > > g_assert(vioc->dma_map); > - return vioc->dma_map(bcontainer, iova, size, vaddr, readonly); > + return vioc->dma_map(bcontainer, iova, size, vaddr, readonly, mrp); > } > > int vfio_container_dma_unmap(VFIOContainerBase *bcontainer, > diff --git a/hw/vfio/container.c b/hw/vfio/container.c > index 7c57bdd27b..0db0055f39 100644 > --- a/hw/vfio/container.c > +++ b/hw/vfio/container.c > @@ -175,7 +175,8 @@ static int vfio_legacy_dma_unmap(const VFIOContainerBase *bcontainer, > } > > static int vfio_legacy_dma_map(const VFIOContainerBase *bcontainer, hwaddr iova, > - ram_addr_t size, void *vaddr, bool readonly) > + ram_addr_t size, void *vaddr, bool readonly, > + MemoryRegion *mrp) > { > const VFIOContainer *container = container_of(bcontainer, VFIOContainer, > bcontainer); > diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c > index df61edffc0..583b063707 100644 > --- a/hw/vfio/iommufd.c > +++ b/hw/vfio/iommufd.c > @@ -28,7 +28,8 @@ > #include "exec/ram_addr.h" > > static int iommufd_cdev_map(const VFIOContainerBase *bcontainer, hwaddr iova, > - ram_addr_t size, void *vaddr, bool readonly) > + ram_addr_t size, void *vaddr, bool readonly, > + MemoryRegion *mrp) > { > const VFIOIOMMUFDContainer *container = > container_of(bcontainer, VFIOIOMMUFDContainer, bcontainer); > diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c > index 3cdaa12ed5..a1866bb396 100644 > --- a/hw/virtio/vhost-vdpa.c > +++ b/hw/virtio/vhost-vdpa.c > @@ -228,7 +228,7 @@ static void vhost_vdpa_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb) > if ((iotlb->perm & IOMMU_RW) != IOMMU_NONE) { > bool read_only; > > - if (!memory_get_xlat_addr(iotlb, &vaddr, NULL, &read_only, NULL, > + if (!memory_get_xlat_addr(iotlb, &vaddr, NULL, &read_only, NULL, NULL, > &local_err)) { > error_report_err(local_err); > return; > diff --git a/include/exec/memory.h b/include/exec/memory.h > index 9f73b59867..adaf1d1ca4 100644 > --- a/include/exec/memory.h > +++ b/include/exec/memory.h > @@ -747,13 +747,15 @@ void ram_discard_manager_unregister_listener(RamDiscardManager *rdm, > * @read_only: indicates if writes are allowed > * @mr_has_discard_manager: indicates memory is controlled by a > * RamDiscardManager > + * @mrp: if non-NULL, fill in with MemoryRegion > * @errp: pointer to Error*, to store an error if it happens. > * > * Return: true on success, else false setting @errp with error. > */ > bool memory_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr, > ram_addr_t *ram_addr, bool *read_only, > - bool *mr_has_discard_manager, Error **errp); > + bool *mr_has_discard_manager, MemoryRegion **mrp, > + Error **errp); > > typedef struct CoalescedMemoryRange CoalescedMemoryRange; > typedef struct MemoryRegionIoeventfd MemoryRegionIoeventfd; > diff --git a/include/hw/vfio/vfio-container-base.h b/include/hw/vfio/vfio-container-base.h > index 4cff9943ab..c9d339383e 100644 > --- a/include/hw/vfio/vfio-container-base.h > +++ b/include/hw/vfio/vfio-container-base.h > @@ -73,7 +73,7 @@ typedef struct VFIORamDiscardListener { > > int vfio_container_dma_map(VFIOContainerBase *bcontainer, > hwaddr iova, ram_addr_t size, > - void *vaddr, bool readonly); > + void *vaddr, bool readonly, MemoryRegion *mrp); > int vfio_container_dma_unmap(VFIOContainerBase *bcontainer, > hwaddr iova, ram_addr_t size, > IOMMUTLBEntry *iotlb); > @@ -113,7 +113,7 @@ struct VFIOIOMMUClass { > bool (*setup)(VFIOContainerBase *bcontainer, Error **errp); > int (*dma_map)(const VFIOContainerBase *bcontainer, > hwaddr iova, ram_addr_t size, > - void *vaddr, bool readonly); > + void *vaddr, bool readonly, MemoryRegion *mrp); > int (*dma_unmap)(const VFIOContainerBase *bcontainer, > hwaddr iova, ram_addr_t size, > IOMMUTLBEntry *iotlb); > diff --git a/system/memory.c b/system/memory.c > index 4c829793a0..de4f955a66 100644 > --- a/system/memory.c > +++ b/system/memory.c > @@ -2185,7 +2185,8 @@ void ram_discard_manager_unregister_listener(RamDiscardManager *rdm, > /* Called with rcu_read_lock held. */ > bool memory_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr, > ram_addr_t *ram_addr, bool *read_only, > - bool *mr_has_discard_manager, Error **errp) > + bool *mr_has_discard_manager, MemoryRegion **mrp, > + Error **errp) > { > MemoryRegion *mr; > hwaddr xlat; > @@ -2250,6 +2251,10 @@ bool memory_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr, > *read_only = !writable || mr->readonly; > } > > + if (mrp != NULL) { > + *mrp = mr; > + } > + > return true; > } >
© 2016 - 2025 Red Hat, Inc.