main.c (37aa5c36aa70c9fc5f633b89cce990f04aaa3cd4) | main.c (cff5a0f3a3cda0d852425093f92acca169eb5aea) |
---|---|
1/* 2 * Copyright (c) 2013-2015, Mellanox Technologies. All rights reserved. 3 * 4 * This software is available to you under a choice of one of two 5 * licenses. You may choose to be licensed under the terms of the GNU 6 * General Public License (GPL) Version 2, available from the file 7 * COPYING in the main directory of this source tree, or the 8 * OpenIB.org BSD license below: --- 24 unchanged lines hidden (view full) --- 33#include <linux/highmem.h> 34#include <linux/module.h> 35#include <linux/init.h> 36#include <linux/errno.h> 37#include <linux/pci.h> 38#include <linux/dma-mapping.h> 39#include <linux/slab.h> 40#include <linux/io-mapping.h> | 1/* 2 * Copyright (c) 2013-2015, Mellanox Technologies. All rights reserved. 3 * 4 * This software is available to you under a choice of one of two 5 * licenses. You may choose to be licensed under the terms of the GNU 6 * General Public License (GPL) Version 2, available from the file 7 * COPYING in the main directory of this source tree, or the 8 * OpenIB.org BSD license below: --- 24 unchanged lines hidden (view full) --- 33#include <linux/highmem.h> 34#include <linux/module.h> 35#include <linux/init.h> 36#include <linux/errno.h> 37#include <linux/pci.h> 38#include <linux/dma-mapping.h> 39#include <linux/slab.h> 40#include <linux/io-mapping.h> |
41#if defined(CONFIG_X86) 42#include <asm/pat.h> 43#endif | |
44#include <linux/sched.h> 45#include <rdma/ib_user_verbs.h> 46#include <rdma/ib_addr.h> 47#include <rdma/ib_cache.h> 48#include <linux/mlx5/port.h> 49#include <linux/mlx5/vport.h> 50#include <rdma/ib_smi.h> 51#include <rdma/ib_umem.h> --- 463 unchanged lines hidden (view full) --- 515 (MLX5_CAP_ETH(dev->mdev, csum_cap))) 516 props->device_cap_flags |= IB_DEVICE_RAW_IP_CSUM; 517 518 if (MLX5_CAP_GEN(mdev, ipoib_basic_offloads)) { 519 props->device_cap_flags |= IB_DEVICE_UD_IP_CSUM; 520 props->device_cap_flags |= IB_DEVICE_UD_TSO; 521 } 522 | 41#include <linux/sched.h> 42#include <rdma/ib_user_verbs.h> 43#include <rdma/ib_addr.h> 44#include <rdma/ib_cache.h> 45#include <linux/mlx5/port.h> 46#include <linux/mlx5/vport.h> 47#include <rdma/ib_smi.h> 48#include <rdma/ib_umem.h> --- 463 unchanged lines hidden (view full) --- 512 (MLX5_CAP_ETH(dev->mdev, csum_cap))) 513 props->device_cap_flags |= IB_DEVICE_RAW_IP_CSUM; 514 515 if (MLX5_CAP_GEN(mdev, ipoib_basic_offloads)) { 516 props->device_cap_flags |= IB_DEVICE_UD_IP_CSUM; 517 props->device_cap_flags |= IB_DEVICE_UD_TSO; 518 } 519 |
520 if (MLX5_CAP_GEN(dev->mdev, eth_net_offloads) && 521 MLX5_CAP_ETH(dev->mdev, scatter_fcs)) 522 props->device_cap_flags |= IB_DEVICE_RAW_SCATTER_FCS; 523 |
|
523 props->vendor_part_id = mdev->pdev->device; 524 props->hw_ver = mdev->pdev->revision; 525 526 props->max_mr_size = ~0ull; 527 props->page_size_cap = ~(min_page_size - 1); 528 props->max_qp = 1 << MLX5_CAP_GEN(mdev, log_max_qp); 529 props->max_qp_wr = 1 << MLX5_CAP_GEN(mdev, log_max_qp_sz); 530 max_rq_sg = MLX5_CAP_GEN(mdev, max_wqe_sz_rq) / --- 535 unchanged lines hidden (view full) --- 1066 return offset & ((1 << MLX5_IB_MMAP_CMD_SHIFT) - 1); 1067} 1068 1069static int get_index(unsigned long offset) 1070{ 1071 return get_arg(offset); 1072} 1073 | 524 props->vendor_part_id = mdev->pdev->device; 525 props->hw_ver = mdev->pdev->revision; 526 527 props->max_mr_size = ~0ull; 528 props->page_size_cap = ~(min_page_size - 1); 529 props->max_qp = 1 << MLX5_CAP_GEN(mdev, log_max_qp); 530 props->max_qp_wr = 1 << MLX5_CAP_GEN(mdev, log_max_qp_sz); 531 max_rq_sg = MLX5_CAP_GEN(mdev, max_wqe_sz_rq) / --- 535 unchanged lines hidden (view full) --- 1067 return offset & ((1 << MLX5_IB_MMAP_CMD_SHIFT) - 1); 1068} 1069 1070static int get_index(unsigned long offset) 1071{ 1072 return get_arg(offset); 1073} 1074 |
1074static inline char *mmap_cmd2str(enum mlx5_ib_mmap_cmd cmd) 1075{ 1076 switch (cmd) { 1077 case MLX5_IB_MMAP_WC_PAGE: 1078 return "WC"; 1079 case MLX5_IB_MMAP_REGULAR_PAGE: 1080 return "best effort WC"; 1081 case MLX5_IB_MMAP_NC_PAGE: 1082 return "NC"; 1083 default: 1084 return NULL; 1085 } 1086} 1087 1088static int uar_mmap(struct mlx5_ib_dev *dev, enum mlx5_ib_mmap_cmd cmd, 1089 struct vm_area_struct *vma, struct mlx5_uuar_info *uuari) 1090{ 1091 int err; 1092 unsigned long idx; 1093 phys_addr_t pfn, pa; 1094 pgprot_t prot; 1095 1096 switch (cmd) { 1097 case MLX5_IB_MMAP_WC_PAGE: 1098/* Some architectures don't support WC memory */ 1099#if defined(CONFIG_X86) 1100 if (!pat_enabled()) 1101 return -EPERM; 1102#elif !(defined(CONFIG_PPC) || (defined(CONFIG_ARM) && defined(CONFIG_MMU))) 1103 return -EPERM; 1104#endif 1105 /* fall through */ 1106 case MLX5_IB_MMAP_REGULAR_PAGE: 1107 /* For MLX5_IB_MMAP_REGULAR_PAGE do the best effort to get WC */ 1108 prot = pgprot_writecombine(vma->vm_page_prot); 1109 break; 1110 case MLX5_IB_MMAP_NC_PAGE: 1111 prot = pgprot_noncached(vma->vm_page_prot); 1112 break; 1113 default: 1114 return -EINVAL; 1115 } 1116 1117 if (vma->vm_end - vma->vm_start != PAGE_SIZE) 1118 return -EINVAL; 1119 1120 idx = get_index(vma->vm_pgoff); 1121 if (idx >= uuari->num_uars) 1122 return -EINVAL; 1123 1124 pfn = uar_index2pfn(dev, uuari->uars[idx].index); 1125 mlx5_ib_dbg(dev, "uar idx 0x%lx, pfn %pa\n", idx, &pfn); 1126 1127 vma->vm_page_prot = prot; 1128 err = io_remap_pfn_range(vma, vma->vm_start, pfn, 1129 PAGE_SIZE, vma->vm_page_prot); 1130 if (err) { 1131 mlx5_ib_err(dev, "io_remap_pfn_range failed with error=%d, vm_start=0x%lx, pfn=%pa, mmap_cmd=%s\n", 1132 err, vma->vm_start, &pfn, mmap_cmd2str(cmd)); 1133 return -EAGAIN; 1134 } 1135 1136 pa = pfn << PAGE_SHIFT; 1137 mlx5_ib_dbg(dev, "mapped %s at 0x%lx, PA %pa\n", mmap_cmd2str(cmd), 1138 vma->vm_start, &pa); 1139 1140 return 0; 1141} 1142 | |
1143static int mlx5_ib_mmap(struct ib_ucontext *ibcontext, struct vm_area_struct *vma) 1144{ 1145 struct mlx5_ib_ucontext *context = to_mucontext(ibcontext); 1146 struct mlx5_ib_dev *dev = to_mdev(ibcontext->device); 1147 struct mlx5_uuar_info *uuari = &context->uuari; 1148 unsigned long command; | 1075static int mlx5_ib_mmap(struct ib_ucontext *ibcontext, struct vm_area_struct *vma) 1076{ 1077 struct mlx5_ib_ucontext *context = to_mucontext(ibcontext); 1078 struct mlx5_ib_dev *dev = to_mdev(ibcontext->device); 1079 struct mlx5_uuar_info *uuari = &context->uuari; 1080 unsigned long command; |
1081 unsigned long idx; |
|
1149 phys_addr_t pfn; 1150 1151 command = get_command(vma->vm_pgoff); 1152 switch (command) { | 1082 phys_addr_t pfn; 1083 1084 command = get_command(vma->vm_pgoff); 1085 switch (command) { |
1153 case MLX5_IB_MMAP_WC_PAGE: 1154 case MLX5_IB_MMAP_NC_PAGE: | |
1155 case MLX5_IB_MMAP_REGULAR_PAGE: | 1086 case MLX5_IB_MMAP_REGULAR_PAGE: |
1156 return uar_mmap(dev, command, vma, uuari); | 1087 if (vma->vm_end - vma->vm_start != PAGE_SIZE) 1088 return -EINVAL; |
1157 | 1089 |
1090 idx = get_index(vma->vm_pgoff); 1091 if (idx >= uuari->num_uars) 1092 return -EINVAL; 1093 1094 pfn = uar_index2pfn(dev, uuari->uars[idx].index); 1095 mlx5_ib_dbg(dev, "uar idx 0x%lx, pfn 0x%llx\n", idx, 1096 (unsigned long long)pfn); 1097 1098 vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); 1099 if (io_remap_pfn_range(vma, vma->vm_start, pfn, 1100 PAGE_SIZE, vma->vm_page_prot)) 1101 return -EAGAIN; 1102 1103 mlx5_ib_dbg(dev, "mapped WC at 0x%lx, PA 0x%llx\n", 1104 vma->vm_start, 1105 (unsigned long long)pfn << PAGE_SHIFT); 1106 break; 1107 |
|
1158 case MLX5_IB_MMAP_GET_CONTIGUOUS_PAGES: 1159 return -ENOSYS; 1160 1161 case MLX5_IB_MMAP_CORE_CLOCK: 1162 if (vma->vm_end - vma->vm_start != PAGE_SIZE) 1163 return -EINVAL; 1164 | 1108 case MLX5_IB_MMAP_GET_CONTIGUOUS_PAGES: 1109 return -ENOSYS; 1110 1111 case MLX5_IB_MMAP_CORE_CLOCK: 1112 if (vma->vm_end - vma->vm_start != PAGE_SIZE) 1113 return -EINVAL; 1114 |
1165 if (vma->vm_flags & VM_WRITE) | 1115 if (vma->vm_flags & (VM_WRITE | VM_EXEC)) |
1166 return -EPERM; 1167 1168 /* Don't expose to user-space information it shouldn't have */ 1169 if (PAGE_SIZE > 4096) 1170 return -EOPNOTSUPP; 1171 1172 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 1173 pfn = (dev->mdev->iseg_base + --- 1383 unchanged lines hidden --- | 1116 return -EPERM; 1117 1118 /* Don't expose to user-space information it shouldn't have */ 1119 if (PAGE_SIZE > 4096) 1120 return -EOPNOTSUPP; 1121 1122 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 1123 pfn = (dev->mdev->iseg_base + --- 1383 unchanged lines hidden --- |