IB/ehca: Use remap_4k_pfn() to map firmware contexts to user space

Use Paul's new remap_4k_pfn() function to map our 4K firmware contexts
into user space on 64K-page machines without exposing neighboring
firmware contexts. Return the context's offset within a 64K page to
user space so it can determine the proper virtual address.

For details about remap_4k_pfn(), see commit 721151d0 or
http://patchwork.ozlabs.org/linuxppc/patch?id=10281

Signed-off-by: Joachim Fenkes <fenkes@de.ibm.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
This commit is contained in:
Hoang-Nam Nguyen 2007-09-11 15:31:06 +02:00 committed by Roland Dreier
parent 5281a4b8a0
commit e390d3b52f
4 changed files with 10 additions and 4 deletions

View File

@ -338,6 +338,8 @@ struct ehca_create_cq_resp {
u32 cq_number; u32 cq_number;
u32 token; u32 token;
struct ipzu_queue_resp ipz_queue; struct ipzu_queue_resp ipz_queue;
u32 fw_handle_ofs;
u32 dummy;
}; };
struct ehca_create_qp_resp { struct ehca_create_qp_resp {
@ -348,7 +350,7 @@ struct ehca_create_qp_resp {
u32 qkey; u32 qkey;
/* qp_num assigned by ehca: sqp0/1 may have got different numbers */ /* qp_num assigned by ehca: sqp0/1 may have got different numbers */
u32 real_qp_num; u32 real_qp_num;
u32 dummy; /* padding for 8 byte alignment */ u32 fw_handle_ofs;
struct ipzu_queue_resp ipz_squeue; struct ipzu_queue_resp ipz_squeue;
struct ipzu_queue_resp ipz_rqueue; struct ipzu_queue_resp ipz_rqueue;
}; };

View File

@ -281,6 +281,8 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector,
resp.ipz_queue.queue_length = ipz_queue->queue_length; resp.ipz_queue.queue_length = ipz_queue->queue_length;
resp.ipz_queue.pagesize = ipz_queue->pagesize; resp.ipz_queue.pagesize = ipz_queue->pagesize;
resp.ipz_queue.toggle_state = ipz_queue->toggle_state; resp.ipz_queue.toggle_state = ipz_queue->toggle_state;
resp.fw_handle_ofs = (u32)
(my_cq->galpas.user.fw_handle & (PAGE_SIZE - 1));
if (ib_copy_to_udata(udata, &resp, sizeof(resp))) { if (ib_copy_to_udata(udata, &resp, sizeof(resp))) {
ehca_err(device, "Copy to udata failed."); ehca_err(device, "Copy to udata failed.");
goto create_cq_exit4; goto create_cq_exit4;

View File

@ -749,6 +749,8 @@ static struct ehca_qp *internal_create_qp(
queue2resp(&resp.ipz_squeue, &my_qp->ipz_squeue); queue2resp(&resp.ipz_squeue, &my_qp->ipz_squeue);
if (HAS_RQ(my_qp)) if (HAS_RQ(my_qp))
queue2resp(&resp.ipz_rqueue, &my_qp->ipz_rqueue); queue2resp(&resp.ipz_rqueue, &my_qp->ipz_rqueue);
resp.fw_handle_ofs = (u32)
(my_qp->galpas.user.fw_handle & (PAGE_SIZE - 1));
if (ib_copy_to_udata(udata, &resp, sizeof resp)) { if (ib_copy_to_udata(udata, &resp, sizeof resp)) {
ehca_err(pd->device, "Copy to udata failed"); ehca_err(pd->device, "Copy to udata failed");

View File

@ -109,7 +109,7 @@ static int ehca_mmap_fw(struct vm_area_struct *vma, struct h_galpas *galpas,
u64 vsize, physical; u64 vsize, physical;
vsize = vma->vm_end - vma->vm_start; vsize = vma->vm_end - vma->vm_start;
if (vsize != EHCA_PAGESIZE) { if (vsize < EHCA_PAGESIZE) {
ehca_gen_err("invalid vsize=%lx", vma->vm_end - vma->vm_start); ehca_gen_err("invalid vsize=%lx", vma->vm_end - vma->vm_start);
return -EINVAL; return -EINVAL;
} }
@ -118,8 +118,8 @@ static int ehca_mmap_fw(struct vm_area_struct *vma, struct h_galpas *galpas,
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
ehca_gen_dbg("vsize=%lx physical=%lx", vsize, physical); ehca_gen_dbg("vsize=%lx physical=%lx", vsize, physical);
/* VM_IO | VM_RESERVED are set by remap_pfn_range() */ /* VM_IO | VM_RESERVED are set by remap_pfn_range() */
ret = remap_pfn_range(vma, vma->vm_start, physical >> PAGE_SHIFT, ret = remap_4k_pfn(vma, vma->vm_start, physical >> EHCA_PAGESHIFT,
vsize, vma->vm_page_prot); vma->vm_page_prot);
if (unlikely(ret)) { if (unlikely(ret)) {
ehca_gen_err("remap_pfn_range() failed ret=%x", ret); ehca_gen_err("remap_pfn_range() failed ret=%x", ret);
return -ENOMEM; return -ENOMEM;