diff mbox

[12/13] hw/rdma: Bugfix: Support non-aligned buffers

Message ID 20180716074038.3364-13-yuval.shaia@oracle.com (mailing list archive)
State New, archived
Headers show

Commit Message

Yuval Shaia July 16, 2018, 7:40 a.m. UTC
RDMA applications can provide non-aligned buffers to be registered. In
such case the DMA address passed by driver is pointing to the beginning
of the physical address of the mapped page so we can't distinguish
between two addresses from the same page.

Fix it by keeping the offset of the virtual address in mr->virt.

Signed-off-by: Yuval Shaia <yuval.shaia@oracle.com>
---
 hw/rdma/rdma_rm.c        | 2 ++
 hw/rdma/vmw/pvrdma_cmd.c | 1 +
 2 files changed, 3 insertions(+)

Comments

Marcel Apfelbaum July 24, 2018, 12:22 p.m. UTC | #1
On 07/16/2018 10:40 AM, Yuval Shaia wrote:
> RDMA applications can provide non-aligned buffers to be registered. In
> such case the DMA address passed by driver is pointing to the beginning
> of the physical address of the mapped page so we can't distinguish
> between two addresses from the same page.
>
> Fix it by keeping the offset of the virtual address in mr->virt.
>
> Signed-off-by: Yuval Shaia <yuval.shaia@oracle.com>
> ---
>   hw/rdma/rdma_rm.c        | 2 ++
>   hw/rdma/vmw/pvrdma_cmd.c | 1 +
>   2 files changed, 3 insertions(+)
>
> diff --git a/hw/rdma/rdma_rm.c b/hw/rdma/rdma_rm.c
> index 859c900003..8d59a42cd1 100644
> --- a/hw/rdma/rdma_rm.c
> +++ b/hw/rdma/rdma_rm.c
> @@ -166,6 +166,7 @@ int rdma_rm_alloc_mr(RdmaDeviceResources *dev_res, uint32_t pd_handle,
>           mr->virt = host_virt;
>           mr->start = guest_start;
>           mr->length = guest_length;
> +        mr->virt += (mr->start & (TARGET_PAGE_SIZE - 1));
>   
>           ret = rdma_backend_create_mr(&mr->backend_mr, &pd->backend_pd, mr->virt,
>                                        mr->length, access_flags);
> @@ -203,6 +204,7 @@ void rdma_rm_dealloc_mr(RdmaDeviceResources *dev_res, uint32_t mr_handle)
>           rdma_backend_destroy_mr(&mr->backend_mr);
>           pr_dbg("start=0x%" PRIx64 "\n", mr->start);
>           if (mr->start) {
> +            mr->virt -= (mr->start & (TARGET_PAGE_SIZE - 1));
>               munmap(mr->virt, mr->length);
>           }
>           res_tbl_dealloc(&dev_res->mr_tbl, mr_handle);
> diff --git a/hw/rdma/vmw/pvrdma_cmd.c b/hw/rdma/vmw/pvrdma_cmd.c
> index bb898265a3..4ff242e793 100644
> --- a/hw/rdma/vmw/pvrdma_cmd.c
> +++ b/hw/rdma/vmw/pvrdma_cmd.c
> @@ -59,6 +59,7 @@ static void *pvrdma_map_to_pdir(PCIDevice *pdev, uint64_t pdir_dma,
>       }
>   
>       host_virt = mremap(curr_page, 0, length, MREMAP_MAYMOVE);
> +    pr_dbg("mremap %p -> %p\n", curr_page, host_virt);
>       if (host_virt == MAP_FAILED) {
>           host_virt = NULL;
>           error_report("PVRDMA: Failed to remap memory for host_virt");

Nice catch!

Reviewed-by: Marcel Apfelbaum<marcel.apfelbaum@gmail.com>

Thanks,
Marcel
diff mbox

Patch

diff --git a/hw/rdma/rdma_rm.c b/hw/rdma/rdma_rm.c
index 859c900003..8d59a42cd1 100644
--- a/hw/rdma/rdma_rm.c
+++ b/hw/rdma/rdma_rm.c
@@ -166,6 +166,7 @@  int rdma_rm_alloc_mr(RdmaDeviceResources *dev_res, uint32_t pd_handle,
         mr->virt = host_virt;
         mr->start = guest_start;
         mr->length = guest_length;
+        mr->virt += (mr->start & (TARGET_PAGE_SIZE - 1));
 
         ret = rdma_backend_create_mr(&mr->backend_mr, &pd->backend_pd, mr->virt,
                                      mr->length, access_flags);
@@ -203,6 +204,7 @@  void rdma_rm_dealloc_mr(RdmaDeviceResources *dev_res, uint32_t mr_handle)
         rdma_backend_destroy_mr(&mr->backend_mr);
         pr_dbg("start=0x%" PRIx64 "\n", mr->start);
         if (mr->start) {
+            mr->virt -= (mr->start & (TARGET_PAGE_SIZE - 1));
             munmap(mr->virt, mr->length);
         }
         res_tbl_dealloc(&dev_res->mr_tbl, mr_handle);
diff --git a/hw/rdma/vmw/pvrdma_cmd.c b/hw/rdma/vmw/pvrdma_cmd.c
index bb898265a3..4ff242e793 100644
--- a/hw/rdma/vmw/pvrdma_cmd.c
+++ b/hw/rdma/vmw/pvrdma_cmd.c
@@ -59,6 +59,7 @@  static void *pvrdma_map_to_pdir(PCIDevice *pdev, uint64_t pdir_dma,
     }
 
     host_virt = mremap(curr_page, 0, length, MREMAP_MAYMOVE);
+    pr_dbg("mremap %p -> %p\n", curr_page, host_virt);
     if (host_virt == MAP_FAILED) {
         host_virt = NULL;
         error_report("PVRDMA: Failed to remap memory for host_virt");