aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-04-28 13:00:45 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-04-28 13:00:45 -0400
commit14f974d7f0f1f93d8c35f496ae774ba0f1b3389a (patch)
treef91018a260c8090311ef4cfde609a9487967daab
parent72a6e35db32b63883e2e3d19cd6a515eac1f5d67 (diff)
parent2557fabd6e29f349bfa0ac13f38ac98aa5eafc74 (diff)
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma
Pull rdma fixes from Jason Gunthorpe: "One core bug fix and a few driver ones - FRWR memory registration for hfi1/qib didn't work with with some iovas causing a NFSoRDMA failure regression due to a fix in the NFS side - A command flow error in mlx5 allowed user space to send a corrupt command (and also smash the kernel stack we've since learned) - Fix a regression and some bugs with device hot unplug that was discovered while reviewing Andrea's patches - hns has a failure if the user asks for certain QP configurations" * tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma: RDMA/hns: Bugfix for mapping user db RDMA/ucontext: Fix regression with disassociate RDMA/mlx5: Use rdma_user_map_io for mapping BAR pages RDMA/mlx5: Do not allow the user to write to the clock page IB/mlx5: Fix scatter to CQE in DCT QP creation IB/rdmavt: Fix frwr memory registration
-rw-r--r--drivers/infiniband/core/uverbs.h1
-rw-r--r--drivers/infiniband/core/uverbs_main.c52
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_qp.c2
-rw-r--r--drivers/infiniband/hw/mlx5/main.c12
-rw-r--r--drivers/infiniband/hw/mlx5/qp.c11
-rw-r--r--drivers/infiniband/sw/rdmavt/mr.c17
-rw-r--r--include/uapi/rdma/mlx5-abi.h1
7 files changed, 76 insertions, 20 deletions
diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h
index ea0bc6885517..32cc8fe7902f 100644
--- a/drivers/infiniband/core/uverbs.h
+++ b/drivers/infiniband/core/uverbs.h
@@ -160,6 +160,7 @@ struct ib_uverbs_file {
160 160
161 struct mutex umap_lock; 161 struct mutex umap_lock;
162 struct list_head umaps; 162 struct list_head umaps;
163 struct page *disassociate_page;
163 164
164 struct idr idr; 165 struct idr idr;
165 /* spinlock protects write access to idr */ 166 /* spinlock protects write access to idr */
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index f2e7ffe6fc54..7843e89235c3 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -208,6 +208,9 @@ void ib_uverbs_release_file(struct kref *ref)
208 kref_put(&file->async_file->ref, 208 kref_put(&file->async_file->ref,
209 ib_uverbs_release_async_event_file); 209 ib_uverbs_release_async_event_file);
210 put_device(&file->device->dev); 210 put_device(&file->device->dev);
211
212 if (file->disassociate_page)
213 __free_pages(file->disassociate_page, 0);
211 kfree(file); 214 kfree(file);
212} 215}
213 216
@@ -877,9 +880,50 @@ static void rdma_umap_close(struct vm_area_struct *vma)
877 kfree(priv); 880 kfree(priv);
878} 881}
879 882
883/*
884 * Once the zap_vma_ptes has been called touches to the VMA will come here and
885 * we return a dummy writable zero page for all the pfns.
886 */
887static vm_fault_t rdma_umap_fault(struct vm_fault *vmf)
888{
889 struct ib_uverbs_file *ufile = vmf->vma->vm_file->private_data;
890 struct rdma_umap_priv *priv = vmf->vma->vm_private_data;
891 vm_fault_t ret = 0;
892
893 if (!priv)
894 return VM_FAULT_SIGBUS;
895
896 /* Read only pages can just use the system zero page. */
897 if (!(vmf->vma->vm_flags & (VM_WRITE | VM_MAYWRITE))) {
898 vmf->page = ZERO_PAGE(vmf->vm_start);
899 get_page(vmf->page);
900 return 0;
901 }
902
903 mutex_lock(&ufile->umap_lock);
904 if (!ufile->disassociate_page)
905 ufile->disassociate_page =
906 alloc_pages(vmf->gfp_mask | __GFP_ZERO, 0);
907
908 if (ufile->disassociate_page) {
909 /*
910 * This VMA is forced to always be shared so this doesn't have
911 * to worry about COW.
912 */
913 vmf->page = ufile->disassociate_page;
914 get_page(vmf->page);
915 } else {
916 ret = VM_FAULT_SIGBUS;
917 }
918 mutex_unlock(&ufile->umap_lock);
919
920 return ret;
921}
922
880static const struct vm_operations_struct rdma_umap_ops = { 923static const struct vm_operations_struct rdma_umap_ops = {
881 .open = rdma_umap_open, 924 .open = rdma_umap_open,
882 .close = rdma_umap_close, 925 .close = rdma_umap_close,
926 .fault = rdma_umap_fault,
883}; 927};
884 928
885static struct rdma_umap_priv *rdma_user_mmap_pre(struct ib_ucontext *ucontext, 929static struct rdma_umap_priv *rdma_user_mmap_pre(struct ib_ucontext *ucontext,
@@ -889,6 +933,9 @@ static struct rdma_umap_priv *rdma_user_mmap_pre(struct ib_ucontext *ucontext,
889 struct ib_uverbs_file *ufile = ucontext->ufile; 933 struct ib_uverbs_file *ufile = ucontext->ufile;
890 struct rdma_umap_priv *priv; 934 struct rdma_umap_priv *priv;
891 935
936 if (!(vma->vm_flags & VM_SHARED))
937 return ERR_PTR(-EINVAL);
938
892 if (vma->vm_end - vma->vm_start != size) 939 if (vma->vm_end - vma->vm_start != size)
893 return ERR_PTR(-EINVAL); 940 return ERR_PTR(-EINVAL);
894 941
@@ -992,7 +1039,7 @@ void uverbs_user_mmap_disassociate(struct ib_uverbs_file *ufile)
992 * at a time to get the lock ordering right. Typically there 1039 * at a time to get the lock ordering right. Typically there
993 * will only be one mm, so no big deal. 1040 * will only be one mm, so no big deal.
994 */ 1041 */
995 down_write(&mm->mmap_sem); 1042 down_read(&mm->mmap_sem);
996 if (!mmget_still_valid(mm)) 1043 if (!mmget_still_valid(mm))
997 goto skip_mm; 1044 goto skip_mm;
998 mutex_lock(&ufile->umap_lock); 1045 mutex_lock(&ufile->umap_lock);
@@ -1006,11 +1053,10 @@ void uverbs_user_mmap_disassociate(struct ib_uverbs_file *ufile)
1006 1053
1007 zap_vma_ptes(vma, vma->vm_start, 1054 zap_vma_ptes(vma, vma->vm_start,
1008 vma->vm_end - vma->vm_start); 1055 vma->vm_end - vma->vm_start);
1009 vma->vm_flags &= ~(VM_SHARED | VM_MAYSHARE);
1010 } 1056 }
1011 mutex_unlock(&ufile->umap_lock); 1057 mutex_unlock(&ufile->umap_lock);
1012 skip_mm: 1058 skip_mm:
1013 up_write(&mm->mmap_sem); 1059 up_read(&mm->mmap_sem);
1014 mmput(mm); 1060 mmput(mm);
1015 } 1061 }
1016} 1062}
diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c
index 66cdf625534f..60cf9f03e941 100644
--- a/drivers/infiniband/hw/hns/hns_roce_qp.c
+++ b/drivers/infiniband/hw/hns/hns_roce_qp.c
@@ -533,7 +533,7 @@ static int hns_roce_set_kernel_sq_size(struct hns_roce_dev *hr_dev,
533 533
534static int hns_roce_qp_has_sq(struct ib_qp_init_attr *attr) 534static int hns_roce_qp_has_sq(struct ib_qp_init_attr *attr)
535{ 535{
536 if (attr->qp_type == IB_QPT_XRC_TGT) 536 if (attr->qp_type == IB_QPT_XRC_TGT || !attr->cap.max_send_wr)
537 return 0; 537 return 0;
538 538
539 return 1; 539 return 1;
diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
index 531ff20b32ad..d3dd290ae1b1 100644
--- a/drivers/infiniband/hw/mlx5/main.c
+++ b/drivers/infiniband/hw/mlx5/main.c
@@ -1119,6 +1119,8 @@ static int mlx5_ib_query_device(struct ib_device *ibdev,
1119 if (MLX5_CAP_GEN(mdev, qp_packet_based)) 1119 if (MLX5_CAP_GEN(mdev, qp_packet_based))
1120 resp.flags |= 1120 resp.flags |=
1121 MLX5_IB_QUERY_DEV_RESP_PACKET_BASED_CREDIT_MODE; 1121 MLX5_IB_QUERY_DEV_RESP_PACKET_BASED_CREDIT_MODE;
1122
1123 resp.flags |= MLX5_IB_QUERY_DEV_RESP_FLAGS_SCAT2CQE_DCT;
1122 } 1124 }
1123 1125
1124 if (field_avail(typeof(resp), sw_parsing_caps, 1126 if (field_avail(typeof(resp), sw_parsing_caps,
@@ -2066,6 +2068,7 @@ static int mlx5_ib_mmap_clock_info_page(struct mlx5_ib_dev *dev,
2066 2068
2067 if (vma->vm_flags & VM_WRITE) 2069 if (vma->vm_flags & VM_WRITE)
2068 return -EPERM; 2070 return -EPERM;
2071 vma->vm_flags &= ~VM_MAYWRITE;
2069 2072
2070 if (!dev->mdev->clock_info_page) 2073 if (!dev->mdev->clock_info_page)
2071 return -EOPNOTSUPP; 2074 return -EOPNOTSUPP;
@@ -2231,19 +2234,18 @@ static int mlx5_ib_mmap(struct ib_ucontext *ibcontext, struct vm_area_struct *vm
2231 2234
2232 if (vma->vm_flags & VM_WRITE) 2235 if (vma->vm_flags & VM_WRITE)
2233 return -EPERM; 2236 return -EPERM;
2237 vma->vm_flags &= ~VM_MAYWRITE;
2234 2238
2235 /* Don't expose to user-space information it shouldn't have */ 2239 /* Don't expose to user-space information it shouldn't have */
2236 if (PAGE_SIZE > 4096) 2240 if (PAGE_SIZE > 4096)
2237 return -EOPNOTSUPP; 2241 return -EOPNOTSUPP;
2238 2242
2239 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
2240 pfn = (dev->mdev->iseg_base + 2243 pfn = (dev->mdev->iseg_base +
2241 offsetof(struct mlx5_init_seg, internal_timer_h)) >> 2244 offsetof(struct mlx5_init_seg, internal_timer_h)) >>
2242 PAGE_SHIFT; 2245 PAGE_SHIFT;
2243 if (io_remap_pfn_range(vma, vma->vm_start, pfn, 2246 return rdma_user_mmap_io(&context->ibucontext, vma, pfn,
2244 PAGE_SIZE, vma->vm_page_prot)) 2247 PAGE_SIZE,
2245 return -EAGAIN; 2248 pgprot_noncached(vma->vm_page_prot));
2246 break;
2247 case MLX5_IB_MMAP_CLOCK_INFO: 2249 case MLX5_IB_MMAP_CLOCK_INFO:
2248 return mlx5_ib_mmap_clock_info_page(dev, vma, context); 2250 return mlx5_ib_mmap_clock_info_page(dev, vma, context);
2249 2251
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
index 7cd006da1dae..8870c350fda0 100644
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@ -1818,13 +1818,16 @@ static void configure_responder_scat_cqe(struct ib_qp_init_attr *init_attr,
1818 1818
1819 rcqe_sz = mlx5_ib_get_cqe_size(init_attr->recv_cq); 1819 rcqe_sz = mlx5_ib_get_cqe_size(init_attr->recv_cq);
1820 1820
1821 if (rcqe_sz == 128) { 1821 if (init_attr->qp_type == MLX5_IB_QPT_DCT) {
1822 MLX5_SET(qpc, qpc, cs_res, MLX5_RES_SCAT_DATA64_CQE); 1822 if (rcqe_sz == 128)
1823 MLX5_SET(dctc, qpc, cs_res, MLX5_RES_SCAT_DATA64_CQE);
1824
1823 return; 1825 return;
1824 } 1826 }
1825 1827
1826 if (init_attr->qp_type != MLX5_IB_QPT_DCT) 1828 MLX5_SET(qpc, qpc, cs_res,
1827 MLX5_SET(qpc, qpc, cs_res, MLX5_RES_SCAT_DATA32_CQE); 1829 rcqe_sz == 128 ? MLX5_RES_SCAT_DATA64_CQE :
1830 MLX5_RES_SCAT_DATA32_CQE);
1828} 1831}
1829 1832
1830static void configure_requester_scat_cqe(struct mlx5_ib_dev *dev, 1833static void configure_requester_scat_cqe(struct mlx5_ib_dev *dev,
diff --git a/drivers/infiniband/sw/rdmavt/mr.c b/drivers/infiniband/sw/rdmavt/mr.c
index 728795043496..0bb6e39dd03a 100644
--- a/drivers/infiniband/sw/rdmavt/mr.c
+++ b/drivers/infiniband/sw/rdmavt/mr.c
@@ -608,11 +608,6 @@ static int rvt_set_page(struct ib_mr *ibmr, u64 addr)
608 if (unlikely(mapped_segs == mr->mr.max_segs)) 608 if (unlikely(mapped_segs == mr->mr.max_segs))
609 return -ENOMEM; 609 return -ENOMEM;
610 610
611 if (mr->mr.length == 0) {
612 mr->mr.user_base = addr;
613 mr->mr.iova = addr;
614 }
615
616 m = mapped_segs / RVT_SEGSZ; 611 m = mapped_segs / RVT_SEGSZ;
617 n = mapped_segs % RVT_SEGSZ; 612 n = mapped_segs % RVT_SEGSZ;
618 mr->mr.map[m]->segs[n].vaddr = (void *)addr; 613 mr->mr.map[m]->segs[n].vaddr = (void *)addr;
@@ -630,17 +625,24 @@ static int rvt_set_page(struct ib_mr *ibmr, u64 addr)
630 * @sg_nents: number of entries in sg 625 * @sg_nents: number of entries in sg
631 * @sg_offset: offset in bytes into sg 626 * @sg_offset: offset in bytes into sg
632 * 627 *
628 * Overwrite rvt_mr length with mr length calculated by ib_sg_to_pages.
629 *
633 * Return: number of sg elements mapped to the memory region 630 * Return: number of sg elements mapped to the memory region
634 */ 631 */
635int rvt_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg, 632int rvt_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg,
636 int sg_nents, unsigned int *sg_offset) 633 int sg_nents, unsigned int *sg_offset)
637{ 634{
638 struct rvt_mr *mr = to_imr(ibmr); 635 struct rvt_mr *mr = to_imr(ibmr);
636 int ret;
639 637
640 mr->mr.length = 0; 638 mr->mr.length = 0;
641 mr->mr.page_shift = PAGE_SHIFT; 639 mr->mr.page_shift = PAGE_SHIFT;
642 return ib_sg_to_pages(ibmr, sg, sg_nents, sg_offset, 640 ret = ib_sg_to_pages(ibmr, sg, sg_nents, sg_offset, rvt_set_page);
643 rvt_set_page); 641 mr->mr.user_base = ibmr->iova;
642 mr->mr.iova = ibmr->iova;
643 mr->mr.offset = ibmr->iova - (u64)mr->mr.map[0]->segs[0].vaddr;
644 mr->mr.length = (size_t)ibmr->length;
645 return ret;
644} 646}
645 647
646/** 648/**
@@ -671,6 +673,7 @@ int rvt_fast_reg_mr(struct rvt_qp *qp, struct ib_mr *ibmr, u32 key,
671 ibmr->rkey = key; 673 ibmr->rkey = key;
672 mr->mr.lkey = key; 674 mr->mr.lkey = key;
673 mr->mr.access_flags = access; 675 mr->mr.access_flags = access;
676 mr->mr.iova = ibmr->iova;
674 atomic_set(&mr->mr.lkey_invalid, 0); 677 atomic_set(&mr->mr.lkey_invalid, 0);
675 678
676 return 0; 679 return 0;
diff --git a/include/uapi/rdma/mlx5-abi.h b/include/uapi/rdma/mlx5-abi.h
index 87b3198f4b5d..f4d4010b7e3e 100644
--- a/include/uapi/rdma/mlx5-abi.h
+++ b/include/uapi/rdma/mlx5-abi.h
@@ -238,6 +238,7 @@ enum mlx5_ib_query_dev_resp_flags {
238 MLX5_IB_QUERY_DEV_RESP_FLAGS_CQE_128B_COMP = 1 << 0, 238 MLX5_IB_QUERY_DEV_RESP_FLAGS_CQE_128B_COMP = 1 << 0,
239 MLX5_IB_QUERY_DEV_RESP_FLAGS_CQE_128B_PAD = 1 << 1, 239 MLX5_IB_QUERY_DEV_RESP_FLAGS_CQE_128B_PAD = 1 << 1,
240 MLX5_IB_QUERY_DEV_RESP_PACKET_BASED_CREDIT_MODE = 1 << 2, 240 MLX5_IB_QUERY_DEV_RESP_PACKET_BASED_CREDIT_MODE = 1 << 2,
241 MLX5_IB_QUERY_DEV_RESP_FLAGS_SCAT2CQE_DCT = 1 << 3,
241}; 242};
242 243
243enum mlx5_ib_tunnel_offloads { 244enum mlx5_ib_tunnel_offloads {