From: Eric Auger <eric.auger@redhat.com>
To: eric.auger.pro@gmail.com, eric.auger@redhat.com,
qemu-devel@nongnu.org, qemu-arm@nongnu.org,
peter.maydell@linaro.org, mst@redhat.com,
alex.williamson@redhat.com, jacob.jun.pan@linux.intel.com,
yi.l.liu@intel.com
Cc: jean-philippe@linaro.org, tnowicki@marvell.com, maz@kernel.org,
zhangfei.gao@foxmail.com, peterx@redhat.com,
shameerali.kolothum.thodi@huawei.com, zhangfei.gao@linaro.org,
bbhushan2@marvell.com, will@kernel.org
Subject: [RFC v6 11/24] vfio: Introduce helpers to DMA map/unmap a RAM section
Date: Fri, 20 Mar 2020 17:58:27 +0100 [thread overview]
Message-ID: <20200320165840.30057-12-eric.auger@redhat.com> (raw)
In-Reply-To: <20200320165840.30057-1-eric.auger@redhat.com>
Let's introduce two helpers that allow to DMA map/unmap a RAM
section. Those helpers will be called for nested stage setup in
another call site. Also the vfio_listener_region_add/del()
structure may be clearer.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
v5 -> v6:
- add Error **
---
hw/vfio/common.c | 177 ++++++++++++++++++++++++++-----------------
hw/vfio/trace-events | 4 +-
2 files changed, 108 insertions(+), 73 deletions(-)
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index f20b37fbee..e067009da8 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -512,13 +512,115 @@ hostwin_from_range(VFIOContainer *container, hwaddr iova, hwaddr end)
return NULL;
}
+static int vfio_dma_map_ram_section(VFIOContainer *container,
+ MemoryRegionSection *section, Error **err)
+{
+ VFIOHostDMAWindow *hostwin;
+ Int128 llend, llsize;
+ hwaddr iova, end;
+ void *vaddr;
+ int ret;
+
+ assert(memory_region_is_ram(section->mr));
+
+ iova = TARGET_PAGE_ALIGN(section->offset_within_address_space);
+ llend = int128_make64(section->offset_within_address_space);
+ llend = int128_add(llend, section->size);
+ llend = int128_and(llend, int128_exts64(TARGET_PAGE_MASK));
+ end = int128_get64(int128_sub(llend, int128_one()));
+
+ vaddr = memory_region_get_ram_ptr(section->mr) +
+ section->offset_within_region +
+ (iova - section->offset_within_address_space);
+
+ hostwin = hostwin_from_range(container, iova, end);
+ if (!hostwin) {
+ error_setg(err, "Container %p can't map guest IOVA region"
+ " 0x%"HWADDR_PRIx"..0x%"HWADDR_PRIx, container, iova, end);
+ return -EFAULT;
+ }
+
+ trace_vfio_dma_map_ram(iova, end, vaddr);
+
+ llsize = int128_sub(llend, int128_make64(iova));
+
+ if (memory_region_is_ram_device(section->mr)) {
+ hwaddr pgmask = (1ULL << ctz64(hostwin->iova_pgsizes)) - 1;
+
+ if ((iova & pgmask) || (int128_get64(llsize) & pgmask)) {
+ trace_vfio_listener_region_add_no_dma_map(
+ memory_region_name(section->mr),
+ section->offset_within_address_space,
+ int128_getlo(section->size),
+ pgmask + 1);
+ return 0;
+ }
+ }
+
+ ret = vfio_dma_map(container, iova, int128_get64(llsize),
+ vaddr, section->readonly);
+ if (ret) {
+ error_setg(err, "vfio_dma_map(%p, 0x%"HWADDR_PRIx", "
+ "0x%"HWADDR_PRIx", %p) = %d (%m)",
+ container, iova, int128_get64(llsize), vaddr, ret);
+ if (memory_region_is_ram_device(section->mr)) {
+ /* Allow unexpected mappings not to be fatal for RAM devices */
+ error_report_err(*err);
+ return 0;
+ }
+ return ret;
+ }
+ return 0;
+}
+
+static void vfio_dma_unmap_ram_section(VFIOContainer *container,
+ MemoryRegionSection *section)
+{
+ Int128 llend, llsize;
+ hwaddr iova, end;
+ bool try_unmap = true;
+ int ret;
+
+ iova = TARGET_PAGE_ALIGN(section->offset_within_address_space);
+ llend = int128_make64(section->offset_within_address_space);
+ llend = int128_add(llend, section->size);
+ llend = int128_and(llend, int128_exts64(TARGET_PAGE_MASK));
+
+ if (int128_ge(int128_make64(iova), llend)) {
+ return;
+ }
+ end = int128_get64(int128_sub(llend, int128_one()));
+
+ llsize = int128_sub(llend, int128_make64(iova));
+
+ trace_vfio_dma_unmap_ram(iova, end);
+
+ if (memory_region_is_ram_device(section->mr)) {
+ hwaddr pgmask;
+ VFIOHostDMAWindow *hostwin = hostwin_from_range(container, iova, end);
+
+ assert(hostwin); /* or region_add() would have failed */
+
+ pgmask = (1ULL << ctz64(hostwin->iova_pgsizes)) - 1;
+ try_unmap = !((iova & pgmask) || (int128_get64(llsize) & pgmask));
+ }
+
+ if (try_unmap) {
+ 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);
+ }
+ }
+}
+
static void vfio_listener_region_add(MemoryListener *listener,
MemoryRegionSection *section)
{
VFIOContainer *container = container_of(listener, VFIOContainer, listener);
hwaddr iova, end;
- Int128 llend, llsize;
- void *vaddr;
+ Int128 llend;
int ret;
VFIOHostDMAWindow *hostwin;
Error *err = NULL;
@@ -655,39 +757,7 @@ static void vfio_listener_region_add(MemoryListener *listener,
}
/* Here we assume that memory_region_is_ram(section->mr)==true */
-
- vaddr = memory_region_get_ram_ptr(section->mr) +
- section->offset_within_region +
- (iova - section->offset_within_address_space);
-
- trace_vfio_listener_region_add_ram(iova, end, vaddr);
-
- llsize = int128_sub(llend, int128_make64(iova));
-
- if (memory_region_is_ram_device(section->mr)) {
- hwaddr pgmask = (1ULL << ctz64(hostwin->iova_pgsizes)) - 1;
-
- if ((iova & pgmask) || (int128_get64(llsize) & pgmask)) {
- trace_vfio_listener_region_add_no_dma_map(
- memory_region_name(section->mr),
- section->offset_within_address_space,
- int128_getlo(section->size),
- pgmask + 1);
- return;
- }
- }
-
- ret = vfio_dma_map(container, iova, int128_get64(llsize),
- vaddr, section->readonly);
- if (ret) {
- error_setg(&err, "vfio_dma_map(%p, 0x%"HWADDR_PRIx", "
- "0x%"HWADDR_PRIx", %p) = %d (%m)",
- container, iova, int128_get64(llsize), vaddr, ret);
- if (memory_region_is_ram_device(section->mr)) {
- /* Allow unexpected mappings not to be fatal for RAM devices */
- error_report_err(err);
- return;
- }
+ if (vfio_dma_map_ram_section(container, section, &err)) {
goto fail;
}
@@ -721,10 +791,6 @@ static void vfio_listener_region_del(MemoryListener *listener,
MemoryRegionSection *section)
{
VFIOContainer *container = container_of(listener, VFIOContainer, listener);
- hwaddr iova, end;
- Int128 llend, llsize;
- int ret;
- bool try_unmap = true;
if (vfio_listener_skipped_section(section)) {
trace_vfio_listener_region_del_skip(
@@ -763,38 +829,7 @@ static void vfio_listener_region_del(MemoryListener *listener,
*/
}
- iova = TARGET_PAGE_ALIGN(section->offset_within_address_space);
- llend = int128_make64(section->offset_within_address_space);
- llend = int128_add(llend, section->size);
- llend = int128_and(llend, int128_exts64(TARGET_PAGE_MASK));
-
- if (int128_ge(int128_make64(iova), llend)) {
- return;
- }
- end = int128_get64(int128_sub(llend, int128_one()));
-
- llsize = int128_sub(llend, int128_make64(iova));
-
- trace_vfio_listener_region_del(iova, end);
-
- if (memory_region_is_ram_device(section->mr)) {
- hwaddr pgmask;
- VFIOHostDMAWindow *hostwin = hostwin_from_range(container, iova, end);
-
- assert(hostwin); /* or region_add() would have failed */
-
- pgmask = (1ULL << ctz64(hostwin->iova_pgsizes)) - 1;
- try_unmap = !((iova & pgmask) || (int128_get64(llsize) & pgmask));
- }
-
- if (try_unmap) {
- 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);
- }
- }
+ vfio_dma_unmap_ram_section(container, section);
memory_region_unref(section->mr);
diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events
index b1ef55a33f..410801de6e 100644
--- a/hw/vfio/trace-events
+++ b/hw/vfio/trace-events
@@ -97,10 +97,10 @@ vfio_iommu_map_notify(const char *op, uint64_t iova_start, uint64_t iova_end) "i
vfio_listener_region_add_skip(uint64_t start, uint64_t end) "SKIPPING region_add 0x%"PRIx64" - 0x%"PRIx64
vfio_spapr_group_attach(int groupfd, int tablefd) "Attached groupfd %d to liobn fd %d"
vfio_listener_region_add_iommu(uint64_t start, uint64_t end) "region_add [iommu] 0x%"PRIx64" - 0x%"PRIx64
-vfio_listener_region_add_ram(uint64_t iova_start, uint64_t iova_end, void *vaddr) "region_add [ram] 0x%"PRIx64" - 0x%"PRIx64" [%p]"
+vfio_dma_map_ram(uint64_t iova_start, uint64_t iova_end, void *vaddr) "region_add [ram] 0x%"PRIx64" - 0x%"PRIx64" [%p]"
vfio_listener_region_add_no_dma_map(const char *name, uint64_t iova, uint64_t size, uint64_t page_size) "Region \"%s\" 0x%"PRIx64" size=0x%"PRIx64" is not aligned to 0x%"PRIx64" and cannot be mapped for DMA"
vfio_listener_region_del_skip(uint64_t start, uint64_t end) "SKIPPING region_del 0x%"PRIx64" - 0x%"PRIx64
-vfio_listener_region_del(uint64_t start, uint64_t end) "region_del 0x%"PRIx64" - 0x%"PRIx64
+vfio_dma_unmap_ram(uint64_t start, uint64_t end) "region_del 0x%"PRIx64" - 0x%"PRIx64
vfio_disconnect_container(int fd) "close container->fd=%d"
vfio_put_group(int fd) "close group->fd=%d"
vfio_get_device(const char * name, unsigned int flags, unsigned int num_regions, unsigned int num_irqs) "Device %s flags: %u, regions: %u, irqs: %u"
--
2.20.1
next prev parent reply other threads:[~2020-03-20 17:09 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-03-20 16:58 [RFC v6 00/24] vSMMUv3/pSMMUv3 2 stage VFIO integration Eric Auger
2020-03-20 16:58 ` [RFC v6 01/24] update-linux-headers: Import iommu.h Eric Auger
2020-03-26 12:58 ` Liu, Yi L
2020-03-26 17:51 ` Auger Eric
2020-03-20 16:58 ` [RFC v6 02/24] header update against 5.6.0-rc3 and IOMMU/VFIO nested stage APIs Eric Auger
2020-03-20 16:58 ` [RFC v6 03/24] memory: Add IOMMU_ATTR_VFIO_NESTED IOMMU memory region attribute Eric Auger
2020-03-20 16:58 ` [RFC v6 04/24] memory: Add IOMMU_ATTR_MSI_TRANSLATE " Eric Auger
2020-03-20 16:58 ` [RFC v6 05/24] memory: Introduce IOMMU Memory Region inject_faults API Eric Auger
2020-03-26 13:13 ` Liu, Yi L
2020-03-20 16:58 ` [RFC v6 06/24] memory: Add arch_id and leaf fields in IOTLBEntry Eric Auger
2020-03-20 16:58 ` [RFC v6 07/24] iommu: Introduce generic header Eric Auger
2020-03-20 16:58 ` [RFC v6 08/24] pci: introduce PCIPASIDOps to PCIDevice Eric Auger
2020-03-26 13:01 ` Liu, Yi L
2020-03-20 16:58 ` [RFC v6 09/24] vfio: Force nested if iommu requires it Eric Auger
2020-03-31 6:34 ` Liu, Yi L
2020-03-31 8:04 ` Auger Eric
2020-03-31 8:34 ` Liu, Yi L
2020-03-20 16:58 ` [RFC v6 10/24] vfio: Introduce hostwin_from_range helper Eric Auger
2020-03-20 16:58 ` Eric Auger [this message]
2020-03-20 16:58 ` [RFC v6 12/24] vfio: Set up nested stage mappings Eric Auger
2020-03-20 16:58 ` [RFC v6 13/24] vfio: Pass stage 1 MSI bindings to the host Eric Auger
2020-03-20 16:58 ` [RFC v6 14/24] vfio: Helper to get IRQ info including capabilities Eric Auger
2020-03-20 16:58 ` [RFC v6 15/24] vfio/pci: Register handler for iommu fault Eric Auger
2020-03-20 16:58 ` [RFC v6 16/24] vfio/pci: Set up the DMA FAULT region Eric Auger
2020-03-20 16:58 ` [RFC v6 17/24] vfio/pci: Implement the DMA fault handler Eric Auger
2020-03-20 16:58 ` [RFC v6 18/24] hw/arm/smmuv3: Advertise MSI_TRANSLATE attribute Eric Auger
2020-03-20 16:58 ` [RFC v6 19/24] hw/arm/smmuv3: Store the PASID table GPA in the translation config Eric Auger
2020-03-20 16:58 ` [RFC v6 20/24] hw/arm/smmuv3: Fill the IOTLBEntry arch_id on NH_VA invalidation Eric Auger
2020-03-20 16:58 ` [RFC v6 21/24] hw/arm/smmuv3: Fill the IOTLBEntry leaf field " Eric Auger
2020-03-20 16:58 ` [RFC v6 22/24] hw/arm/smmuv3: Pass stage 1 configurations to the host Eric Auger
2020-03-20 16:58 ` [RFC v6 23/24] hw/arm/smmuv3: Implement fault injection Eric Auger
2020-03-20 16:58 ` [RFC v6 24/24] hw/arm/smmuv3: Allow MAP notifiers Eric Auger
2020-03-25 11:35 ` [RFC v6 00/24] vSMMUv3/pSMMUv3 2 stage VFIO integration Shameerali Kolothum Thodi
2020-03-25 12:42 ` Auger Eric
2020-04-03 10:45 ` Auger Eric
2020-04-03 12:10 ` Shameerali Kolothum Thodi
2020-03-31 6:42 ` Zhangfei Gao
2020-03-31 8:12 ` Auger Eric
2020-03-31 8:24 ` Zhangfei Gao
2020-04-02 16:46 ` Auger Eric
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200320165840.30057-12-eric.auger@redhat.com \
--to=eric.auger@redhat.com \
--cc=alex.williamson@redhat.com \
--cc=bbhushan2@marvell.com \
--cc=eric.auger.pro@gmail.com \
--cc=jacob.jun.pan@linux.intel.com \
--cc=jean-philippe@linaro.org \
--cc=maz@kernel.org \
--cc=mst@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=peterx@redhat.com \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=shameerali.kolothum.thodi@huawei.com \
--cc=tnowicki@marvell.com \
--cc=will@kernel.org \
--cc=yi.l.liu@intel.com \
--cc=zhangfei.gao@foxmail.com \
--cc=zhangfei.gao@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).