return err;
}
-static int rxe_set_page(struct ib_mr *ibmr, u64 iova)
+static int rxe_set_page(struct ib_mr *ibmr, u64 dma_addr)
{
struct rxe_mr *mr = to_rmr(ibmr);
- struct page *page = virt_to_page(iova & mr->page_mask);
+ struct page *page = ib_virt_dma_to_page(dma_addr);
bool persistent = !!(mr->access & IB_ACCESS_FLUSH_PERSISTENT);
int err;
return 0;
}
-static void rxe_mr_copy_dma(struct rxe_mr *mr, u64 iova, void *addr,
+static void rxe_mr_copy_dma(struct rxe_mr *mr, u64 dma_addr, void *addr,
unsigned int length, enum rxe_mr_copy_dir dir)
{
- unsigned int page_offset = iova & (PAGE_SIZE - 1);
+ unsigned int page_offset = dma_addr & (PAGE_SIZE - 1);
unsigned int bytes;
struct page *page;
u8 *va;
while (length) {
- page = virt_to_page(iova & mr->page_mask);
+ page = ib_virt_dma_to_page(dma_addr);
bytes = min_t(unsigned int, length,
PAGE_SIZE - page_offset);
va = kmap_local_page(page);
kunmap_local(va);
page_offset = 0;
- iova += bytes;
+ dma_addr += bytes;
addr += bytes;
length -= bytes;
}
if (mr->ibmr.type == IB_MR_TYPE_DMA) {
page_offset = iova & (PAGE_SIZE - 1);
- page = virt_to_page(iova & PAGE_MASK);
+ page = ib_virt_dma_to_page(iova);
} else {
unsigned long index;
int err;
if (mr->ibmr.type == IB_MR_TYPE_DMA) {
page_offset = iova & (PAGE_SIZE - 1);
- page = virt_to_page(iova & PAGE_MASK);
+ page = ib_virt_dma_to_page(iova);
} else {
unsigned long index;
int err;
int i;
for (i = 0; i < ibwr->num_sge; i++, sge++) {
- memcpy(p, (void *)(uintptr_t)sge->addr, sge->length);
+ memcpy(p, ib_virt_dma_to_page(sge->addr), sge->length);
p += sge->length;
}
}
break;
bytes = min(bytes, len);
- if (siw_rx_kva(srx, (void *)(uintptr_t)buf_addr, bytes) ==
+ if (siw_rx_kva(srx, ib_virt_dma_to_ptr(buf_addr), bytes) ==
bytes) {
copied += bytes;
offset += bytes;
mem_p = *mem;
if (mem_p->mem_obj == NULL)
rv = siw_rx_kva(srx,
- (void *)(uintptr_t)(sge->laddr + frx->sge_off),
+ ib_virt_dma_to_ptr(sge->laddr + frx->sge_off),
sge_bytes);
else if (!mem_p->is_pbl)
rv = siw_rx_umem(srx, mem_p->umem,
if (mem_p->mem_obj == NULL)
rv = siw_rx_kva(srx,
- (void *)(uintptr_t)(sge->laddr + wqe->processed),
+ ib_virt_dma_to_ptr(sge->laddr + wqe->processed),
bytes);
else if (!mem_p->is_pbl)
rv = siw_rx_umem(srx, mem_p->umem, sge->laddr + wqe->processed,
dma_addr_t paddr = siw_pbl_get_buffer(pbl, offset, NULL, idx);
if (paddr)
- return virt_to_page((void *)(uintptr_t)paddr);
+ return ib_virt_dma_to_page(paddr);
return NULL;
}
if (!mem->mem_obj) {
/* Kernel client using kva */
- memcpy(paddr,
- (const void *)(uintptr_t)sge->laddr, bytes);
+ memcpy(paddr, ib_virt_dma_to_ptr(sge->laddr), bytes);
} else if (c_tx->in_syscall) {
if (copy_from_user(paddr, u64_to_user_ptr(sge->laddr),
bytes))
* or memory region with assigned kernel buffer
*/
iov[seg].iov_base =
- (void *)(uintptr_t)(sge->laddr + sge_off);
+ ib_virt_dma_to_ptr(sge->laddr + sge_off);
iov[seg].iov_len = sge_len;
if (do_crc)
* Cast to an uintptr_t to preserve all 64 bits
* in sge->laddr.
*/
- uintptr_t va = (uintptr_t)(sge->laddr + sge_off);
+ u64 va = sge->laddr + sge_off;
- /*
- * virt_to_page() takes a (void *) pointer
- * so cast to a (void *) meaning it will be 64
- * bits on a 64 bit platform and 32 bits on a
- * 32 bit platform.
- */
- page_array[seg] = virt_to_page((void *)(va & PAGE_MASK));
+ page_array[seg] = ib_virt_dma_to_page(va);
if (do_crc)
crypto_shash_update(
c_tx->mpa_crc_hd,
- (void *)va,
+ ib_virt_dma_to_ptr(va),
plen);
}
bytes = -EINVAL;
break;
}
- memcpy(kbuf, (void *)(uintptr_t)core_sge->addr,
+ memcpy(kbuf, ib_virt_dma_to_ptr(core_sge->addr),
core_sge->length);
kbuf += core_sge->length;
}
siw_dbg_mem(mem,
"sge[%d], size %u, addr 0x%p, total %lu\n",
- i, pble->size, (void *)(uintptr_t)pble->addr,
+ i, pble->size, ib_virt_dma_to_ptr(pble->addr),
pbl_size);
}
rv = ib_sg_to_pages(base_mr, sl, num_sle, sg_off, siw_set_pbl_page);
}
/**
+ * ib_virt_dma_to_ptr - Convert a dma_addr to a kernel pointer
+ * @dma_addr: The DMA address
+ *
+ * Used by ib_uses_virt_dma() devices to get back to the kernel pointer after
+ * going through the dma_addr marshalling.
+ */
+static inline void *ib_virt_dma_to_ptr(u64 dma_addr)
+{
+ /* virt_dma mode maps the kvs's directly into the dma addr */
+ return (void *)(uintptr_t)dma_addr;
+}
+
+/**
+ * ib_virt_dma_to_page - Convert a dma_addr to a struct page
+ * @dma_addr: The DMA address
+ *
+ * Used by ib_uses_virt_dma() device to get back to the struct page after going
+ * through the dma_addr marshalling.
+ */
+static inline struct page *ib_virt_dma_to_page(u64 dma_addr)
+{
+ return virt_to_page(ib_virt_dma_to_ptr(dma_addr));
+}
+
+/**
* ib_dma_mapping_error - check a DMA addr for error
* @dev: The device for which the dma_addr was created
* @dma_addr: The DMA address to check