1/* 2 * 3 * This file is provided under a dual BSD/GPLv2 license. When using or 4 * redistributing this file, you may do so under either license. 5 * 6 * GPL LICENSE SUMMARY 7 * 8 * Copyright(c) 2015 Intel Corporation. 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of version 2 of the GNU General Public License as 12 * published by the Free Software Foundation. 13 * 14 * This program is distributed in the hope that it will be useful, but 15 * WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * General Public License for more details. 18 * 19 * BSD LICENSE 20 * 21 * Copyright(c) 2015 Intel Corporation. 22 * 23 * Redistribution and use in source and binary forms, with or without 24 * modification, are permitted provided that the following conditions 25 * are met: 26 * 27 * - Redistributions of source code must retain the above copyright 28 * notice, this list of conditions and the following disclaimer. 29 * - Redistributions in binary form must reproduce the above copyright 30 * notice, this list of conditions and the following disclaimer in 31 * the documentation and/or other materials provided with the 32 * distribution. 33 * - Neither the name of Intel Corporation nor the names of its 34 * contributors may be used to endorse or promote products derived 35 * from this software without specific prior written permission. 36 * 37 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 38 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 39 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 40 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 41 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 43 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 44 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 45 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 46 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 47 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 48 * 49 */ 50 51#include <linux/mm.h> 52#include <linux/device.h> 53 54#include "hfi.h" 55 56static void __hfi1_release_user_pages(struct page **p, size_t num_pages, 57 int dirty) 58{ 59 size_t i; 60 61 for (i = 0; i < num_pages; i++) { 62 if (dirty) 63 set_page_dirty_lock(p[i]); 64 put_page(p[i]); 65 } 66} 67 68/* 69 * Call with current->mm->mmap_sem held. 70 */ 71static int __hfi1_get_user_pages(unsigned long start_page, size_t num_pages, 72 struct page **p) 73{ 74 unsigned long lock_limit; 75 size_t got; 76 int ret; 77 78 lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT; 79 80 if (num_pages > lock_limit && !capable(CAP_IPC_LOCK)) { 81 ret = -ENOMEM; 82 goto bail; 83 } 84 85 for (got = 0; got < num_pages; got += ret) { 86 ret = get_user_pages(current, current->mm, 87 start_page + got * PAGE_SIZE, 88 num_pages - got, 1, 1, 89 p + got, NULL); 90 if (ret < 0) 91 goto bail_release; 92 } 93 94 current->mm->pinned_vm += num_pages; 95 96 ret = 0; 97 goto bail; 98 99bail_release: 100 __hfi1_release_user_pages(p, got, 0); 101bail: 102 return ret; 103} 104 105/** 106 * hfi1_map_page - a safety wrapper around pci_map_page() 107 * 108 */ 109dma_addr_t hfi1_map_page(struct pci_dev *hwdev, struct page *page, 110 unsigned long offset, size_t size, int direction) 111{ 112 dma_addr_t phys; 113 114 phys = pci_map_page(hwdev, page, offset, size, direction); 115 116 return phys; 117} 118 119/** 120 * hfi1_get_user_pages - lock user pages into memory 121 * @start_page: the start page 122 * @num_pages: the number of pages 123 * @p: the output page structures 124 * 125 * This function takes a given start page (page aligned user virtual 126 * address) and pins it and the following specified number of pages. For 127 * now, num_pages is always 1, but that will probably change at some point 128 * (because caller is doing expected sends on a single virtually contiguous 129 * buffer, so we can do all pages at once). 130 */ 131int hfi1_get_user_pages(unsigned long start_page, size_t num_pages, 132 struct page **p) 133{ 134 int ret; 135 136 down_write(¤t->mm->mmap_sem); 137 138 ret = __hfi1_get_user_pages(start_page, num_pages, p); 139 140 up_write(¤t->mm->mmap_sem); 141 142 return ret; 143} 144 145void hfi1_release_user_pages(struct page **p, size_t num_pages) 146{ 147 if (current->mm) /* during close after signal, mm can be NULL */ 148 down_write(¤t->mm->mmap_sem); 149 150 __hfi1_release_user_pages(p, num_pages, 1); 151 152 if (current->mm) { 153 current->mm->pinned_vm -= num_pages; 154 up_write(¤t->mm->mmap_sem); 155 } 156} 157