1fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick/* 2fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * IBM eServer eHCA Infiniband device driver for Linux on POWER 3fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * 4fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * userspace support verbs 5fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * 6fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * Authors: Christoph Raisch <raisch@de.ibm.com> 7fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * Hoang-Nam Nguyen <hnguyen@de.ibm.com> 8fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * Heiko J Schick <schickhj@de.ibm.com> 9fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * 10fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * Copyright (c) 2005 IBM Corporation 11fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * 12fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * All rights reserved. 13fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * 14fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * This source code is distributed under a dual license of GPL v2.0 and OpenIB 15fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * BSD. 16fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * 17fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * OpenIB BSD License 18fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * 19fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * Redistribution and use in source and binary forms, with or without 20fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * modification, are permitted provided that the following conditions are met: 21fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * 22fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * Redistributions of source code must retain the above copyright notice, this 23fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * list of conditions and the following disclaimer. 24fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * 25fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * Redistributions in binary form must reproduce the above copyright notice, 26fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * this list of conditions and the following disclaimer in the documentation 27fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * and/or other materials 28fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * provided with the distribution. 29fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * 30fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 31fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 32fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 33fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 34fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 35fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 36fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 37fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 38fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 39fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 40fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * POSSIBILITY OF SUCH DAMAGE. 41fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick */ 42fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 435a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 445a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo 45fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick#include "ehca_classes.h" 46fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick#include "ehca_iverbs.h" 47fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick#include "ehca_mrmw.h" 48fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick#include "ehca_tools.h" 49fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick#include "hcp_if.h" 50fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 51fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickstruct ib_ucontext *ehca_alloc_ucontext(struct ib_device *device, 52fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick struct ib_udata *udata) 53fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{ 54fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick struct ehca_ucontext *my_context; 55fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 56fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick my_context = kzalloc(sizeof *my_context, GFP_KERNEL); 57fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick if (!my_context) { 58fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick ehca_err(device, "Out of memory device=%p", device); 59fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick return ERR_PTR(-ENOMEM); 60fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick } 61fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 62fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick return &my_context->ib_ucontext; 63fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick} 64fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 65fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickint ehca_dealloc_ucontext(struct ib_ucontext *context) 66fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{ 67fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick kfree(container_of(context, struct ehca_ucontext, ib_ucontext)); 68fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick return 0; 69fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick} 70fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 714c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyenstatic void ehca_mm_open(struct vm_area_struct *vma) 72fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{ 732b94397adc68c2f0f851539884cc426e03444a26Hoang-Nam Nguyen u32 *count = (u32 *)vma->vm_private_data; 744c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen if (!count) { 754c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen ehca_gen_err("Invalid vma struct vm_start=%lx vm_end=%lx", 764c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen vma->vm_start, vma->vm_end); 774c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen return; 784c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen } 794c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen (*count)++; 804c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen if (!(*count)) 814c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen ehca_gen_err("Use count overflow vm_start=%lx vm_end=%lx", 824c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen vma->vm_start, vma->vm_end); 834c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen ehca_gen_dbg("vm_start=%lx vm_end=%lx count=%x", 844c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen vma->vm_start, vma->vm_end, *count); 854c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen} 86fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 874c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyenstatic void ehca_mm_close(struct vm_area_struct *vma) 884c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen{ 892b94397adc68c2f0f851539884cc426e03444a26Hoang-Nam Nguyen u32 *count = (u32 *)vma->vm_private_data; 904c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen if (!count) { 914c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen ehca_gen_err("Invalid vma struct vm_start=%lx vm_end=%lx", 924c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen vma->vm_start, vma->vm_end); 934c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen return; 944c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen } 954c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen (*count)--; 964c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen ehca_gen_dbg("vm_start=%lx vm_end=%lx count=%x", 974c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen vma->vm_start, vma->vm_end, *count); 984c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen} 99fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 100f0f37e2f77731b3473fa6bd5ee53255d9a9cdb40Alexey Dobriyanstatic const struct vm_operations_struct vm_ops = { 1014c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen .open = ehca_mm_open, 1024c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen .close = ehca_mm_close, 1034c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen}; 1044c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen 1054c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyenstatic int ehca_mmap_fw(struct vm_area_struct *vma, struct h_galpas *galpas, 1064c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen u32 *mm_count) 1074c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen{ 1084c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen int ret; 1094c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen u64 vsize, physical; 1104c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen 1114c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen vsize = vma->vm_end - vma->vm_start; 112e390d3b52f791fcea26312ba4982cda82052727bHoang-Nam Nguyen if (vsize < EHCA_PAGESIZE) { 1134c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen ehca_gen_err("invalid vsize=%lx", vma->vm_end - vma->vm_start); 1144c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen return -EINVAL; 1154c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen } 1164c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen 1174c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen physical = galpas->user.fw_handle; 1184c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 1193750f60557b68776eb749859ad68af70d1a01ad0Stephen Rothwell ehca_gen_dbg("vsize=%llx physical=%llx", vsize, physical); 120314e51b9851b4f4e8ab302243ff5a6fc6147f379Konstantin Khlebnikov /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */ 121e390d3b52f791fcea26312ba4982cda82052727bHoang-Nam Nguyen ret = remap_4k_pfn(vma, vma->vm_start, physical >> EHCA_PAGESHIFT, 122e390d3b52f791fcea26312ba4982cda82052727bHoang-Nam Nguyen vma->vm_page_prot); 1234c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen if (unlikely(ret)) { 124e37221928bf685d63ba5319746eafe463d61e330Joachim Fenkes ehca_gen_err("remap_pfn_range() failed ret=%i", ret); 1254c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen return -ENOMEM; 1264c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen } 1274c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen 1284c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen vma->vm_private_data = mm_count; 1294c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen (*mm_count)++; 1304c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen vma->vm_ops = &vm_ops; 1314c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen 1324c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen return 0; 1334c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen} 1344c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen 1354c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyenstatic int ehca_mmap_queue(struct vm_area_struct *vma, struct ipz_queue *queue, 1364c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen u32 *mm_count) 1374c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen{ 1384c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen int ret; 1394c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen u64 start, ofs; 1404c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen struct page *page; 1414c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen 142314e51b9851b4f4e8ab302243ff5a6fc6147f379Konstantin Khlebnikov vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP; 1434c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen start = vma->vm_start; 1444c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen for (ofs = 0; ofs < queue->queue_length; ofs += PAGE_SIZE) { 1454c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen u64 virt_addr = (u64)ipz_qeit_calc(queue, ofs); 1464c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen page = virt_to_page(virt_addr); 1474c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen ret = vm_insert_page(vma, start, page); 1484c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen if (unlikely(ret)) { 149e37221928bf685d63ba5319746eafe463d61e330Joachim Fenkes ehca_gen_err("vm_insert_page() failed rc=%i", ret); 1504c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen return ret; 151fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick } 152e2f81daf23efde23d8cac1fc253d41838f0347cfStefan Roscher <stefan.roscher at start += PAGE_SIZE; 1534c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen } 1544c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen vma->vm_private_data = mm_count; 1554c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen (*mm_count)++; 1564c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen vma->vm_ops = &vm_ops; 157fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 1584c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen return 0; 1594c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen} 1604c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen 1614c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyenstatic int ehca_mmap_cq(struct vm_area_struct *vma, struct ehca_cq *cq, 1624c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen u32 rsrc_type) 1634c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen{ 1644c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen int ret; 1654c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen 1664c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen switch (rsrc_type) { 1675281a4b8a0c6bac0c070913ec25868faa06a3115Stefan Roscher case 0: /* galpa fw handle */ 1684c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen ehca_dbg(cq->ib_cq.device, "cq_num=%x fw", cq->cq_number); 1694c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen ret = ehca_mmap_fw(vma, &cq->galpas, &cq->mm_count_galpa); 1704c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen if (unlikely(ret)) { 171fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick ehca_err(cq->ib_cq.device, 172e37221928bf685d63ba5319746eafe463d61e330Joachim Fenkes "ehca_mmap_fw() failed rc=%i cq_num=%x", 1734c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen ret, cq->cq_number); 1744c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen return ret; 175fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick } 1764c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen break; 177fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 1785281a4b8a0c6bac0c070913ec25868faa06a3115Stefan Roscher case 1: /* cq queue_addr */ 1794c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen ehca_dbg(cq->ib_cq.device, "cq_num=%x queue", cq->cq_number); 1804c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen ret = ehca_mmap_queue(vma, &cq->ipz_queue, &cq->mm_count_queue); 1814c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen if (unlikely(ret)) { 1824c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen ehca_err(cq->ib_cq.device, 183e37221928bf685d63ba5319746eafe463d61e330Joachim Fenkes "ehca_mmap_queue() failed rc=%i cq_num=%x", 1844c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen ret, cq->cq_number); 1854c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen return ret; 186fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick } 187fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick break; 188fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 1894c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen default: 1904c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen ehca_err(cq->ib_cq.device, "bad resource type=%x cq_num=%x", 1914c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen rsrc_type, cq->cq_number); 1924c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen return -EINVAL; 1934c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen } 194fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 1954c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen return 0; 1964c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen} 1974c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen 1984c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyenstatic int ehca_mmap_qp(struct vm_area_struct *vma, struct ehca_qp *qp, 1994c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen u32 rsrc_type) 2004c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen{ 2014c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen int ret; 2024c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen 2034c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen switch (rsrc_type) { 2045281a4b8a0c6bac0c070913ec25868faa06a3115Stefan Roscher case 0: /* galpa fw handle */ 2054c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen ehca_dbg(qp->ib_qp.device, "qp_num=%x fw", qp->ib_qp.qp_num); 2064c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen ret = ehca_mmap_fw(vma, &qp->galpas, &qp->mm_count_galpa); 2074c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen if (unlikely(ret)) { 2084c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen ehca_err(qp->ib_qp.device, 209e37221928bf685d63ba5319746eafe463d61e330Joachim Fenkes "remap_pfn_range() failed ret=%i qp_num=%x", 2104c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen ret, qp->ib_qp.qp_num); 2114c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen return -ENOMEM; 212fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick } 2134c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen break; 214fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 2155281a4b8a0c6bac0c070913ec25868faa06a3115Stefan Roscher case 1: /* qp rqueue_addr */ 2164da27d6d5b92c8fe4b3a3e5bcf42606d9e4a6fc8Joachim Fenkes ehca_dbg(qp->ib_qp.device, "qp_num=%x rq", qp->ib_qp.qp_num); 2172b94397adc68c2f0f851539884cc426e03444a26Hoang-Nam Nguyen ret = ehca_mmap_queue(vma, &qp->ipz_rqueue, 2182b94397adc68c2f0f851539884cc426e03444a26Hoang-Nam Nguyen &qp->mm_count_rqueue); 2194c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen if (unlikely(ret)) { 220fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick ehca_err(qp->ib_qp.device, 221e37221928bf685d63ba5319746eafe463d61e330Joachim Fenkes "ehca_mmap_queue(rq) failed rc=%i qp_num=%x", 2224c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen ret, qp->ib_qp.qp_num); 2234c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen return ret; 224fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick } 2254c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen break; 226fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 2275281a4b8a0c6bac0c070913ec25868faa06a3115Stefan Roscher case 2: /* qp squeue_addr */ 2284da27d6d5b92c8fe4b3a3e5bcf42606d9e4a6fc8Joachim Fenkes ehca_dbg(qp->ib_qp.device, "qp_num=%x sq", qp->ib_qp.qp_num); 2292b94397adc68c2f0f851539884cc426e03444a26Hoang-Nam Nguyen ret = ehca_mmap_queue(vma, &qp->ipz_squeue, 2302b94397adc68c2f0f851539884cc426e03444a26Hoang-Nam Nguyen &qp->mm_count_squeue); 2314c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen if (unlikely(ret)) { 2324c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen ehca_err(qp->ib_qp.device, 233e37221928bf685d63ba5319746eafe463d61e330Joachim Fenkes "ehca_mmap_queue(sq) failed rc=%i qp_num=%x", 2344c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen ret, qp->ib_qp.qp_num); 2354c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen return ret; 236fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick } 237fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick break; 238fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 239fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick default: 2404c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen ehca_err(qp->ib_qp.device, "bad resource type=%x qp=num=%x", 2414c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen rsrc_type, qp->ib_qp.qp_num); 2424c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen return -EINVAL; 243fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick } 244fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 2454c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen return 0; 246fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick} 247fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 248fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickint ehca_mmap(struct ib_ucontext *context, struct vm_area_struct *vma) 249fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{ 2505281a4b8a0c6bac0c070913ec25868faa06a3115Stefan Roscher u64 fileoffset = vma->vm_pgoff; 2515281a4b8a0c6bac0c070913ec25868faa06a3115Stefan Roscher u32 idr_handle = fileoffset & 0x1FFFFFF; 2525281a4b8a0c6bac0c070913ec25868faa06a3115Stefan Roscher u32 q_type = (fileoffset >> 27) & 0x1; /* CQ, QP,... */ 2535281a4b8a0c6bac0c070913ec25868faa06a3115Stefan Roscher u32 rsrc_type = (fileoffset >> 25) & 0x3; /* sq,rq,cmnd_window */ 254fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick u32 ret; 255fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick struct ehca_cq *cq; 256fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick struct ehca_qp *qp; 257a6a12947fbf4a1782535468d756b0d44babf9760Joachim Fenkes struct ib_uobject *uobject; 258fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 259fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick switch (q_type) { 2605281a4b8a0c6bac0c070913ec25868faa06a3115Stefan Roscher case 0: /* CQ */ 26126ed687fdd541c2542b79dcd75fb2c82eb36f189Joachim Fenkes read_lock(&ehca_cq_idr_lock); 262fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick cq = idr_find(&ehca_cq_idr, idr_handle); 26326ed687fdd541c2542b79dcd75fb2c82eb36f189Joachim Fenkes read_unlock(&ehca_cq_idr_lock); 264fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 265fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick /* make sure this mmap really belongs to the authorized user */ 266fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick if (!cq) 267fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick return -EINVAL; 268fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 269fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick if (!cq->ib_cq.uobject || cq->ib_cq.uobject->context != context) 270fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick return -EINVAL; 271fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 2724c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen ret = ehca_mmap_cq(vma, cq, rsrc_type); 2734c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen if (unlikely(ret)) { 2744c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen ehca_err(cq->ib_cq.device, 275e37221928bf685d63ba5319746eafe463d61e330Joachim Fenkes "ehca_mmap_cq() failed rc=%i cq_num=%x", 2764c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen ret, cq->cq_number); 2774c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen return ret; 278fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick } 279fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick break; 280fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 2815281a4b8a0c6bac0c070913ec25868faa06a3115Stefan Roscher case 1: /* QP */ 28226ed687fdd541c2542b79dcd75fb2c82eb36f189Joachim Fenkes read_lock(&ehca_qp_idr_lock); 283fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick qp = idr_find(&ehca_qp_idr, idr_handle); 28426ed687fdd541c2542b79dcd75fb2c82eb36f189Joachim Fenkes read_unlock(&ehca_qp_idr_lock); 285fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 286fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick /* make sure this mmap really belongs to the authorized user */ 287fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick if (!qp) 288fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick return -EINVAL; 289fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 290a6a12947fbf4a1782535468d756b0d44babf9760Joachim Fenkes uobject = IS_SRQ(qp) ? qp->ib_srq.uobject : qp->ib_qp.uobject; 291a6a12947fbf4a1782535468d756b0d44babf9760Joachim Fenkes if (!uobject || uobject->context != context) 292fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick return -EINVAL; 293fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 2944c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen ret = ehca_mmap_qp(vma, qp, rsrc_type); 2954c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen if (unlikely(ret)) { 2964c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen ehca_err(qp->ib_qp.device, 297e37221928bf685d63ba5319746eafe463d61e330Joachim Fenkes "ehca_mmap_qp() failed rc=%i qp_num=%x", 2984c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen ret, qp->ib_qp.qp_num); 2994c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen return ret; 300fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick } 301fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick break; 302fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 303fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick default: 304fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick ehca_gen_err("bad queue type %x", q_type); 305fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick return -EINVAL; 306fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick } 307fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 308fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick return 0; 309fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick} 310