IB/hfi1: Fix user-space buffers mapping with IOMMU enabled
The dma_XXX API functions return bus addresses which are physical addresses when IOMMU is disabled. Buffer mapping to user-space is done via remap_pfn_range() with PFN based on bus address instead of physical. This results in wrong pages being mapped to user-space when IOMMU is enabled. Reviewed-by: Mitko Haralanov <mitko.haralanov@intel.com> Reviewed-by: Dennis Dalessandro <dennis.dalessandro@intel.com> Signed-off-by: Tymoteusz Kielan <tymoteusz.kielan@intel.com> Signed-off-by: Andrzej Kacprowski <andrzej.kacprowski@intel.com> Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
This commit is contained in:

committed by
Doug Ledford

parent
0b115ef100
commit
60368186fd
@@ -709,7 +709,7 @@ int hfi1_init(struct hfi1_devdata *dd, int reinit)
|
||||
/* allocate dummy tail memory for all receive contexts */
|
||||
dd->rcvhdrtail_dummy_kvaddr = dma_zalloc_coherent(
|
||||
&dd->pcidev->dev, sizeof(u64),
|
||||
&dd->rcvhdrtail_dummy_physaddr,
|
||||
&dd->rcvhdrtail_dummy_dma,
|
||||
GFP_KERNEL);
|
||||
|
||||
if (!dd->rcvhdrtail_dummy_kvaddr) {
|
||||
@@ -942,12 +942,12 @@ void hfi1_free_ctxtdata(struct hfi1_devdata *dd, struct hfi1_ctxtdata *rcd)
|
||||
|
||||
if (rcd->rcvhdrq) {
|
||||
dma_free_coherent(&dd->pcidev->dev, rcd->rcvhdrq_size,
|
||||
rcd->rcvhdrq, rcd->rcvhdrq_phys);
|
||||
rcd->rcvhdrq, rcd->rcvhdrq_dma);
|
||||
rcd->rcvhdrq = NULL;
|
||||
if (rcd->rcvhdrtail_kvaddr) {
|
||||
dma_free_coherent(&dd->pcidev->dev, PAGE_SIZE,
|
||||
(void *)rcd->rcvhdrtail_kvaddr,
|
||||
rcd->rcvhdrqtailaddr_phys);
|
||||
rcd->rcvhdrqtailaddr_dma);
|
||||
rcd->rcvhdrtail_kvaddr = NULL;
|
||||
}
|
||||
}
|
||||
@@ -956,11 +956,11 @@ void hfi1_free_ctxtdata(struct hfi1_devdata *dd, struct hfi1_ctxtdata *rcd)
|
||||
kfree(rcd->egrbufs.rcvtids);
|
||||
|
||||
for (e = 0; e < rcd->egrbufs.alloced; e++) {
|
||||
if (rcd->egrbufs.buffers[e].phys)
|
||||
if (rcd->egrbufs.buffers[e].dma)
|
||||
dma_free_coherent(&dd->pcidev->dev,
|
||||
rcd->egrbufs.buffers[e].len,
|
||||
rcd->egrbufs.buffers[e].addr,
|
||||
rcd->egrbufs.buffers[e].phys);
|
||||
rcd->egrbufs.buffers[e].dma);
|
||||
}
|
||||
kfree(rcd->egrbufs.buffers);
|
||||
|
||||
@@ -1354,7 +1354,7 @@ static void cleanup_device_data(struct hfi1_devdata *dd)
|
||||
if (dd->rcvhdrtail_dummy_kvaddr) {
|
||||
dma_free_coherent(&dd->pcidev->dev, sizeof(u64),
|
||||
(void *)dd->rcvhdrtail_dummy_kvaddr,
|
||||
dd->rcvhdrtail_dummy_physaddr);
|
||||
dd->rcvhdrtail_dummy_dma);
|
||||
dd->rcvhdrtail_dummy_kvaddr = NULL;
|
||||
}
|
||||
|
||||
@@ -1577,7 +1577,7 @@ int hfi1_create_rcvhdrq(struct hfi1_devdata *dd, struct hfi1_ctxtdata *rcd)
|
||||
u64 reg;
|
||||
|
||||
if (!rcd->rcvhdrq) {
|
||||
dma_addr_t phys_hdrqtail;
|
||||
dma_addr_t dma_hdrqtail;
|
||||
gfp_t gfp_flags;
|
||||
|
||||
/*
|
||||
@@ -1590,7 +1590,7 @@ int hfi1_create_rcvhdrq(struct hfi1_devdata *dd, struct hfi1_ctxtdata *rcd)
|
||||
gfp_flags = (rcd->ctxt >= dd->first_user_ctxt) ?
|
||||
GFP_USER : GFP_KERNEL;
|
||||
rcd->rcvhdrq = dma_zalloc_coherent(
|
||||
&dd->pcidev->dev, amt, &rcd->rcvhdrq_phys,
|
||||
&dd->pcidev->dev, amt, &rcd->rcvhdrq_dma,
|
||||
gfp_flags | __GFP_COMP);
|
||||
|
||||
if (!rcd->rcvhdrq) {
|
||||
@@ -1602,11 +1602,11 @@ int hfi1_create_rcvhdrq(struct hfi1_devdata *dd, struct hfi1_ctxtdata *rcd)
|
||||
|
||||
if (HFI1_CAP_KGET_MASK(rcd->flags, DMA_RTAIL)) {
|
||||
rcd->rcvhdrtail_kvaddr = dma_zalloc_coherent(
|
||||
&dd->pcidev->dev, PAGE_SIZE, &phys_hdrqtail,
|
||||
&dd->pcidev->dev, PAGE_SIZE, &dma_hdrqtail,
|
||||
gfp_flags);
|
||||
if (!rcd->rcvhdrtail_kvaddr)
|
||||
goto bail_free;
|
||||
rcd->rcvhdrqtailaddr_phys = phys_hdrqtail;
|
||||
rcd->rcvhdrqtailaddr_dma = dma_hdrqtail;
|
||||
}
|
||||
|
||||
rcd->rcvhdrq_size = amt;
|
||||
@@ -1634,7 +1634,7 @@ int hfi1_create_rcvhdrq(struct hfi1_devdata *dd, struct hfi1_ctxtdata *rcd)
|
||||
* before enabling any receive context
|
||||
*/
|
||||
write_kctxt_csr(dd, rcd->ctxt, RCV_HDR_TAIL_ADDR,
|
||||
dd->rcvhdrtail_dummy_physaddr);
|
||||
dd->rcvhdrtail_dummy_dma);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -1645,7 +1645,7 @@ bail_free:
|
||||
vfree(rcd->user_event_mask);
|
||||
rcd->user_event_mask = NULL;
|
||||
dma_free_coherent(&dd->pcidev->dev, amt, rcd->rcvhdrq,
|
||||
rcd->rcvhdrq_phys);
|
||||
rcd->rcvhdrq_dma);
|
||||
rcd->rcvhdrq = NULL;
|
||||
bail:
|
||||
return -ENOMEM;
|
||||
@@ -1706,15 +1706,15 @@ int hfi1_setup_eagerbufs(struct hfi1_ctxtdata *rcd)
|
||||
rcd->egrbufs.buffers[idx].addr =
|
||||
dma_zalloc_coherent(&dd->pcidev->dev,
|
||||
rcd->egrbufs.rcvtid_size,
|
||||
&rcd->egrbufs.buffers[idx].phys,
|
||||
&rcd->egrbufs.buffers[idx].dma,
|
||||
gfp_flags);
|
||||
if (rcd->egrbufs.buffers[idx].addr) {
|
||||
rcd->egrbufs.buffers[idx].len =
|
||||
rcd->egrbufs.rcvtid_size;
|
||||
rcd->egrbufs.rcvtids[rcd->egrbufs.alloced].addr =
|
||||
rcd->egrbufs.buffers[idx].addr;
|
||||
rcd->egrbufs.rcvtids[rcd->egrbufs.alloced].phys =
|
||||
rcd->egrbufs.buffers[idx].phys;
|
||||
rcd->egrbufs.rcvtids[rcd->egrbufs.alloced].dma =
|
||||
rcd->egrbufs.buffers[idx].dma;
|
||||
rcd->egrbufs.alloced++;
|
||||
alloced_bytes += rcd->egrbufs.rcvtid_size;
|
||||
idx++;
|
||||
@@ -1755,14 +1755,14 @@ int hfi1_setup_eagerbufs(struct hfi1_ctxtdata *rcd)
|
||||
for (i = 0, j = 0, offset = 0; j < idx; i++) {
|
||||
if (i >= rcd->egrbufs.count)
|
||||
break;
|
||||
rcd->egrbufs.rcvtids[i].phys =
|
||||
rcd->egrbufs.buffers[j].phys + offset;
|
||||
rcd->egrbufs.rcvtids[i].dma =
|
||||
rcd->egrbufs.buffers[j].dma + offset;
|
||||
rcd->egrbufs.rcvtids[i].addr =
|
||||
rcd->egrbufs.buffers[j].addr + offset;
|
||||
rcd->egrbufs.alloced++;
|
||||
if ((rcd->egrbufs.buffers[j].phys + offset +
|
||||
if ((rcd->egrbufs.buffers[j].dma + offset +
|
||||
new_size) ==
|
||||
(rcd->egrbufs.buffers[j].phys +
|
||||
(rcd->egrbufs.buffers[j].dma +
|
||||
rcd->egrbufs.buffers[j].len)) {
|
||||
j++;
|
||||
offset = 0;
|
||||
@@ -1814,7 +1814,7 @@ int hfi1_setup_eagerbufs(struct hfi1_ctxtdata *rcd)
|
||||
|
||||
for (idx = 0; idx < rcd->egrbufs.alloced; idx++) {
|
||||
hfi1_put_tid(dd, rcd->eager_base + idx, PT_EAGER,
|
||||
rcd->egrbufs.rcvtids[idx].phys, order);
|
||||
rcd->egrbufs.rcvtids[idx].dma, order);
|
||||
cond_resched();
|
||||
}
|
||||
goto bail;
|
||||
@@ -1826,9 +1826,9 @@ bail_rcvegrbuf_phys:
|
||||
dma_free_coherent(&dd->pcidev->dev,
|
||||
rcd->egrbufs.buffers[idx].len,
|
||||
rcd->egrbufs.buffers[idx].addr,
|
||||
rcd->egrbufs.buffers[idx].phys);
|
||||
rcd->egrbufs.buffers[idx].dma);
|
||||
rcd->egrbufs.buffers[idx].addr = NULL;
|
||||
rcd->egrbufs.buffers[idx].phys = 0;
|
||||
rcd->egrbufs.buffers[idx].dma = 0;
|
||||
rcd->egrbufs.buffers[idx].len = 0;
|
||||
}
|
||||
bail:
|
||||
|
Reference in New Issue
Block a user