Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma

Pull rdma fixes from Jason Gunthorpe:
"Two security issues and several small bug fixes. Things seem to have
stabilized for this release here.

Summary:

- Significant out of bounds access security issue in i40iw

- Fix misuse of mmu notifiers in hfi1

- Several errors in the register map/usage in hns

- Missing error returns in mthca"

* tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma:
RDMA/hns: Bugfix for memory window mtpt configuration
RDMA/hns: Fix retry_cnt and rnr_cnt when querying QP
RDMA/hns: Fix wrong field of SRQ number the device supports
IB/hfi1: Ensure correct mm is used at all times
RDMA/i40iw: Address an mmap handler exploit in i40iw
IB/mthca: fix return value of error branch in mthca_init_cq()

+97 -92
+1 -3
drivers/infiniband/hw/hfi1/file_ops.c
··· 1 1 /* 2 + * Copyright(c) 2020 Cornelis Networks, Inc. 2 3 * Copyright(c) 2015-2020 Intel Corporation. 3 4 * 4 5 * This file is provided under a dual BSD/GPLv2 license. When using or ··· 207 206 spin_lock_init(&fd->tid_lock); 208 207 spin_lock_init(&fd->invalid_lock); 209 208 fd->rec_cpu_num = -1; /* no cpu affinity by default */ 210 - fd->mm = current->mm; 211 - mmgrab(fd->mm); 212 209 fd->dd = dd; 213 210 fp->private_data = fd; 214 211 return 0; ··· 710 711 711 712 deallocate_ctxt(uctxt); 712 713 done: 713 - mmdrop(fdata->mm); 714 714 715 715 if (atomic_dec_and_test(&dd->user_refcount)) 716 716 complete(&dd->user_comp);
+1 -1
drivers/infiniband/hw/hfi1/hfi.h
··· 1 1 #ifndef _HFI1_KERNEL_H 2 2 #define _HFI1_KERNEL_H 3 3 /* 4 + * Copyright(c) 2020 Cornelis Networks, Inc. 4 5 * Copyright(c) 2015-2020 Intel Corporation. 5 6 * 6 7 * This file is provided under a dual BSD/GPLv2 license. When using or ··· 1452 1451 u32 invalid_tid_idx; 1453 1452 /* protect invalid_tids array and invalid_tid_idx */ 1454 1453 spinlock_t invalid_lock; 1455 - struct mm_struct *mm; 1456 1454 }; 1457 1455 1458 1456 extern struct xarray hfi1_dev_table;
+34 -32
drivers/infiniband/hw/hfi1/mmu_rb.c
··· 1 1 /* 2 + * Copyright(c) 2020 Cornelis Networks, Inc. 2 3 * Copyright(c) 2016 - 2017 Intel Corporation. 3 4 * 4 5 * This file is provided under a dual BSD/GPLv2 license. When using or ··· 49 48 #include <linux/rculist.h> 50 49 #include <linux/mmu_notifier.h> 51 50 #include <linux/interval_tree_generic.h> 51 + #include <linux/sched/mm.h> 52 52 53 53 #include "mmu_rb.h" 54 54 #include "trace.h" 55 - 56 - struct mmu_rb_handler { 57 - struct mmu_notifier mn; 58 - struct rb_root_cached root; 59 - void *ops_arg; 60 - spinlock_t lock; /* protect the RB tree */ 61 - struct mmu_rb_ops *ops; 62 - struct mm_struct *mm; 63 - struct list_head lru_list; 64 - struct work_struct del_work; 65 - struct list_head del_list; 66 - struct workqueue_struct *wq; 67 - }; 68 55 69 56 static unsigned long mmu_node_start(struct mmu_rb_node *); 70 57 static unsigned long mmu_node_last(struct mmu_rb_node *); ··· 81 92 return PAGE_ALIGN(node->addr + node->len) - 1; 82 93 } 83 94 84 - int hfi1_mmu_rb_register(void *ops_arg, struct mm_struct *mm, 95 + int hfi1_mmu_rb_register(void *ops_arg, 85 96 struct mmu_rb_ops *ops, 86 97 struct workqueue_struct *wq, 87 98 struct mmu_rb_handler **handler) 88 99 { 89 - struct mmu_rb_handler *handlr; 100 + struct mmu_rb_handler *h; 90 101 int ret; 91 102 92 - handlr = kmalloc(sizeof(*handlr), GFP_KERNEL); 93 - if (!handlr) 103 + h = kmalloc(sizeof(*h), GFP_KERNEL); 104 + if (!h) 94 105 return -ENOMEM; 95 106 96 - handlr->root = RB_ROOT_CACHED; 97 - handlr->ops = ops; 98 - handlr->ops_arg = ops_arg; 99 - INIT_HLIST_NODE(&handlr->mn.hlist); 100 - spin_lock_init(&handlr->lock); 101 - handlr->mn.ops = &mn_opts; 102 - handlr->mm = mm; 103 - INIT_WORK(&handlr->del_work, handle_remove); 104 - INIT_LIST_HEAD(&handlr->del_list); 105 - INIT_LIST_HEAD(&handlr->lru_list); 106 - handlr->wq = wq; 107 + h->root = RB_ROOT_CACHED; 108 + h->ops = ops; 109 + h->ops_arg = ops_arg; 110 + INIT_HLIST_NODE(&h->mn.hlist); 111 + spin_lock_init(&h->lock); 112 + h->mn.ops = &mn_opts; 113 + INIT_WORK(&h->del_work, handle_remove); 114 + INIT_LIST_HEAD(&h->del_list); 115 + INIT_LIST_HEAD(&h->lru_list); 116 + h->wq = wq; 107 117 108 - ret = mmu_notifier_register(&handlr->mn, handlr->mm); 118 + ret = mmu_notifier_register(&h->mn, current->mm); 109 119 if (ret) { 110 - kfree(handlr); 120 + kfree(h); 111 121 return ret; 112 122 } 113 123 114 - *handler = handlr; 124 + *handler = h; 115 125 return 0; 116 126 } 117 127 ··· 122 134 struct list_head del_list; 123 135 124 136 /* Unregister first so we don't get any more notifications. */ 125 - mmu_notifier_unregister(&handler->mn, handler->mm); 137 + mmu_notifier_unregister(&handler->mn, handler->mn.mm); 126 138 127 139 /* 128 140 * Make sure the wq delete handler is finished running. It will not ··· 154 166 int ret = 0; 155 167 156 168 trace_hfi1_mmu_rb_insert(mnode->addr, mnode->len); 169 + 170 + if (current->mm != handler->mn.mm) 171 + return -EPERM; 172 + 157 173 spin_lock_irqsave(&handler->lock, flags); 158 174 node = __mmu_rb_search(handler, mnode->addr, mnode->len); 159 175 if (node) { ··· 172 180 __mmu_int_rb_remove(mnode, &handler->root); 173 181 list_del(&mnode->list); /* remove from LRU list */ 174 182 } 183 + mnode->handler = handler; 175 184 unlock: 176 185 spin_unlock_irqrestore(&handler->lock, flags); 177 186 return ret; ··· 210 217 unsigned long flags; 211 218 bool ret = false; 212 219 220 + if (current->mm != handler->mn.mm) 221 + return ret; 222 + 213 223 spin_lock_irqsave(&handler->lock, flags); 214 224 node = __mmu_rb_search(handler, addr, len); 215 225 if (node) { ··· 234 238 struct list_head del_list; 235 239 unsigned long flags; 236 240 bool stop = false; 241 + 242 + if (current->mm != handler->mn.mm) 243 + return; 237 244 238 245 INIT_LIST_HEAD(&del_list); 239 246 ··· 270 271 struct mmu_rb_node *node) 271 272 { 272 273 unsigned long flags; 274 + 275 + if (current->mm != handler->mn.mm) 276 + return; 273 277 274 278 /* Validity of handler and node pointers has been checked by caller. */ 275 279 trace_hfi1_mmu_rb_remove(node->addr, node->len);
+15 -1
drivers/infiniband/hw/hfi1/mmu_rb.h
··· 1 1 /* 2 + * Copyright(c) 2020 Cornelis Networks, Inc. 2 3 * Copyright(c) 2016 Intel Corporation. 3 4 * 4 5 * This file is provided under a dual BSD/GPLv2 license. When using or ··· 55 54 unsigned long len; 56 55 unsigned long __last; 57 56 struct rb_node node; 57 + struct mmu_rb_handler *handler; 58 58 struct list_head list; 59 59 }; 60 60 ··· 73 71 void *evict_arg, bool *stop); 74 72 }; 75 73 76 - int hfi1_mmu_rb_register(void *ops_arg, struct mm_struct *mm, 74 + struct mmu_rb_handler { 75 + struct mmu_notifier mn; 76 + struct rb_root_cached root; 77 + void *ops_arg; 78 + spinlock_t lock; /* protect the RB tree */ 79 + struct mmu_rb_ops *ops; 80 + struct list_head lru_list; 81 + struct work_struct del_work; 82 + struct list_head del_list; 83 + struct workqueue_struct *wq; 84 + }; 85 + 86 + int hfi1_mmu_rb_register(void *ops_arg, 77 87 struct mmu_rb_ops *ops, 78 88 struct workqueue_struct *wq, 79 89 struct mmu_rb_handler **handler);
+8 -4
drivers/infiniband/hw/hfi1/user_exp_rcv.c
··· 1 1 /* 2 + * Copyright(c) 2020 Cornelis Networks, Inc. 2 3 * Copyright(c) 2015-2018 Intel Corporation. 3 4 * 4 5 * This file is provided under a dual BSD/GPLv2 license. When using or ··· 174 173 { 175 174 struct page **pages; 176 175 struct hfi1_devdata *dd = fd->uctxt->dd; 176 + struct mm_struct *mm; 177 177 178 178 if (mapped) { 179 179 pci_unmap_single(dd->pcidev, node->dma_addr, 180 180 node->npages * PAGE_SIZE, PCI_DMA_FROMDEVICE); 181 181 pages = &node->pages[idx]; 182 + mm = mm_from_tid_node(node); 182 183 } else { 183 184 pages = &tidbuf->pages[idx]; 185 + mm = current->mm; 184 186 } 185 - hfi1_release_user_pages(fd->mm, pages, npages, mapped); 187 + hfi1_release_user_pages(mm, pages, npages, mapped); 186 188 fd->tid_n_pinned -= npages; 187 189 } 188 190 ··· 220 216 * pages, accept the amount pinned so far and program only that. 221 217 * User space knows how to deal with partially programmed buffers. 222 218 */ 223 - if (!hfi1_can_pin_pages(dd, fd->mm, fd->tid_n_pinned, npages)) { 219 + if (!hfi1_can_pin_pages(dd, current->mm, fd->tid_n_pinned, npages)) { 224 220 kfree(pages); 225 221 return -ENOMEM; 226 222 } 227 223 228 - pinned = hfi1_acquire_user_pages(fd->mm, vaddr, npages, true, pages); 224 + pinned = hfi1_acquire_user_pages(current->mm, vaddr, npages, true, pages); 229 225 if (pinned <= 0) { 230 226 kfree(pages); 231 227 return pinned; ··· 760 756 761 757 if (fd->use_mn) { 762 758 ret = mmu_interval_notifier_insert( 763 - &node->notifier, fd->mm, 759 + &node->notifier, current->mm, 764 760 tbuf->vaddr + (pageidx * PAGE_SIZE), npages * PAGE_SIZE, 765 761 &tid_mn_ops); 766 762 if (ret)
+6
drivers/infiniband/hw/hfi1/user_exp_rcv.h
··· 1 1 #ifndef _HFI1_USER_EXP_RCV_H 2 2 #define _HFI1_USER_EXP_RCV_H 3 3 /* 4 + * Copyright(c) 2020 - Cornelis Networks, Inc. 4 5 * Copyright(c) 2015 - 2017 Intel Corporation. 5 6 * 6 7 * This file is provided under a dual BSD/GPLv2 license. When using or ··· 95 94 struct hfi1_tid_info *tinfo); 96 95 int hfi1_user_exp_rcv_invalid(struct hfi1_filedata *fd, 97 96 struct hfi1_tid_info *tinfo); 97 + 98 + static inline struct mm_struct *mm_from_tid_node(struct tid_rb_node *node) 99 + { 100 + return node->notifier.mm; 101 + } 98 102 99 103 #endif /* _HFI1_USER_EXP_RCV_H */
+7 -6
drivers/infiniband/hw/hfi1/user_sdma.c
··· 1 1 /* 2 + * Copyright(c) 2020 - Cornelis Networks, Inc. 2 3 * Copyright(c) 2015 - 2018 Intel Corporation. 3 4 * 4 5 * This file is provided under a dual BSD/GPLv2 license. When using or ··· 189 188 atomic_set(&pq->n_reqs, 0); 190 189 init_waitqueue_head(&pq->wait); 191 190 atomic_set(&pq->n_locked, 0); 192 - pq->mm = fd->mm; 193 191 194 192 iowait_init(&pq->busy, 0, NULL, NULL, defer_packet_queue, 195 193 activate_packet_queue, NULL, NULL); ··· 230 230 231 231 cq->nentries = hfi1_sdma_comp_ring_size; 232 232 233 - ret = hfi1_mmu_rb_register(pq, pq->mm, &sdma_rb_ops, dd->pport->hfi1_wq, 233 + ret = hfi1_mmu_rb_register(pq, &sdma_rb_ops, dd->pport->hfi1_wq, 234 234 &pq->handler); 235 235 if (ret) { 236 236 dd_dev_err(dd, "Failed to register with MMU %d", ret); ··· 980 980 981 981 npages -= node->npages; 982 982 retry: 983 - if (!hfi1_can_pin_pages(pq->dd, pq->mm, 983 + if (!hfi1_can_pin_pages(pq->dd, current->mm, 984 984 atomic_read(&pq->n_locked), npages)) { 985 985 cleared = sdma_cache_evict(pq, npages); 986 986 if (cleared >= npages) 987 987 goto retry; 988 988 } 989 - pinned = hfi1_acquire_user_pages(pq->mm, 989 + pinned = hfi1_acquire_user_pages(current->mm, 990 990 ((unsigned long)iovec->iov.iov_base + 991 991 (node->npages * PAGE_SIZE)), npages, 0, 992 992 pages + node->npages); ··· 995 995 return pinned; 996 996 } 997 997 if (pinned != npages) { 998 - unpin_vector_pages(pq->mm, pages, node->npages, pinned); 998 + unpin_vector_pages(current->mm, pages, node->npages, pinned); 999 999 return -EFAULT; 1000 1000 } 1001 1001 kfree(node->pages); ··· 1008 1008 static void unpin_sdma_pages(struct sdma_mmu_node *node) 1009 1009 { 1010 1010 if (node->npages) { 1011 - unpin_vector_pages(node->pq->mm, node->pages, 0, node->npages); 1011 + unpin_vector_pages(mm_from_sdma_node(node), node->pages, 0, 1012 + node->npages); 1012 1013 atomic_sub(node->npages, &node->pq->n_locked); 1013 1014 } 1014 1015 }
+6 -1
drivers/infiniband/hw/hfi1/user_sdma.h
··· 1 1 #ifndef _HFI1_USER_SDMA_H 2 2 #define _HFI1_USER_SDMA_H 3 3 /* 4 + * Copyright(c) 2020 - Cornelis Networks, Inc. 4 5 * Copyright(c) 2015 - 2018 Intel Corporation. 5 6 * 6 7 * This file is provided under a dual BSD/GPLv2 license. When using or ··· 134 133 unsigned long unpinned; 135 134 struct mmu_rb_handler *handler; 136 135 atomic_t n_locked; 137 - struct mm_struct *mm; 138 136 }; 139 137 140 138 struct hfi1_user_sdma_comp_q { ··· 249 249 int hfi1_user_sdma_process_request(struct hfi1_filedata *fd, 250 250 struct iovec *iovec, unsigned long dim, 251 251 unsigned long *count); 252 + 253 + static inline struct mm_struct *mm_from_sdma_node(struct sdma_mmu_node *node) 254 + { 255 + return node->rb.handler->mn.mm; 256 + } 252 257 253 258 #endif /* _HFI1_USER_SDMA_H */
+5 -4
drivers/infiniband/hw/hns/hns_roce_hw_v2.c
··· 2936 2936 2937 2937 roce_set_bit(mpt_entry->byte_8_mw_cnt_en, V2_MPT_BYTE_8_R_INV_EN_S, 1); 2938 2938 roce_set_bit(mpt_entry->byte_8_mw_cnt_en, V2_MPT_BYTE_8_L_INV_EN_S, 1); 2939 + roce_set_bit(mpt_entry->byte_8_mw_cnt_en, V2_MPT_BYTE_8_LW_EN_S, 1); 2939 2940 2940 2941 roce_set_bit(mpt_entry->byte_12_mw_pa, V2_MPT_BYTE_12_PA_S, 0); 2941 2942 roce_set_bit(mpt_entry->byte_12_mw_pa, V2_MPT_BYTE_12_MR_MW_S, 1); ··· 4990 4989 V2_QPC_BYTE_28_AT_M, 4991 4990 V2_QPC_BYTE_28_AT_S); 4992 4991 qp_attr->retry_cnt = roce_get_field(context.byte_212_lsn, 4993 - V2_QPC_BYTE_212_RETRY_CNT_M, 4994 - V2_QPC_BYTE_212_RETRY_CNT_S); 4992 + V2_QPC_BYTE_212_RETRY_NUM_INIT_M, 4993 + V2_QPC_BYTE_212_RETRY_NUM_INIT_S); 4995 4994 qp_attr->rnr_retry = roce_get_field(context.byte_244_rnr_rxack, 4996 - V2_QPC_BYTE_244_RNR_CNT_M, 4997 - V2_QPC_BYTE_244_RNR_CNT_S); 4995 + V2_QPC_BYTE_244_RNR_NUM_INIT_M, 4996 + V2_QPC_BYTE_244_RNR_NUM_INIT_S); 4998 4997 4999 4998 done: 5000 4999 qp_attr->cur_qp_state = qp_attr->qp_state;
+1 -1
drivers/infiniband/hw/hns/hns_roce_hw_v2.h
··· 1661 1661 __le32 rsv_uars_rsv_qps; 1662 1662 }; 1663 1663 #define V2_QUERY_PF_CAPS_D_NUM_SRQS_S 0 1664 - #define V2_QUERY_PF_CAPS_D_NUM_SRQS_M GENMASK(20, 0) 1664 + #define V2_QUERY_PF_CAPS_D_NUM_SRQS_M GENMASK(19, 0) 1665 1665 1666 1666 #define V2_QUERY_PF_CAPS_D_RQWQE_HOP_NUM_S 20 1667 1667 #define V2_QUERY_PF_CAPS_D_RQWQE_HOP_NUM_M GENMASK(21, 20)
-5
drivers/infiniband/hw/i40iw/i40iw_main.c
··· 54 54 #define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \ 55 55 __stringify(DRV_VERSION_MINOR) "." __stringify(DRV_VERSION_BUILD) 56 56 57 - static int push_mode; 58 - module_param(push_mode, int, 0644); 59 - MODULE_PARM_DESC(push_mode, "Low latency mode: 0=disabled (default), 1=enabled)"); 60 - 61 57 static int debug; 62 58 module_param(debug, int, 0644); 63 59 MODULE_PARM_DESC(debug, "debug flags: 0=disabled (default), 0x7fffffff=all"); ··· 1576 1580 if (status) 1577 1581 goto exit; 1578 1582 iwdev->obj_next = iwdev->obj_mem; 1579 - iwdev->push_mode = push_mode; 1580 1583 1581 1584 init_waitqueue_head(&iwdev->vchnl_waitq); 1582 1585 init_waitqueue_head(&dev->vf_reqs);
+7 -30
drivers/infiniband/hw/i40iw/i40iw_verbs.c
··· 167 167 */ 168 168 static int i40iw_mmap(struct ib_ucontext *context, struct vm_area_struct *vma) 169 169 { 170 - struct i40iw_ucontext *ucontext; 171 - u64 db_addr_offset, push_offset, pfn; 170 + struct i40iw_ucontext *ucontext = to_ucontext(context); 171 + u64 dbaddr; 172 172 173 - ucontext = to_ucontext(context); 174 - if (ucontext->iwdev->sc_dev.is_pf) { 175 - db_addr_offset = I40IW_DB_ADDR_OFFSET; 176 - push_offset = I40IW_PUSH_OFFSET; 177 - if (vma->vm_pgoff) 178 - vma->vm_pgoff += I40IW_PF_FIRST_PUSH_PAGE_INDEX - 1; 179 - } else { 180 - db_addr_offset = I40IW_VF_DB_ADDR_OFFSET; 181 - push_offset = I40IW_VF_PUSH_OFFSET; 182 - if (vma->vm_pgoff) 183 - vma->vm_pgoff += I40IW_VF_FIRST_PUSH_PAGE_INDEX - 1; 184 - } 173 + if (vma->vm_pgoff || vma->vm_end - vma->vm_start != PAGE_SIZE) 174 + return -EINVAL; 185 175 186 - vma->vm_pgoff += db_addr_offset >> PAGE_SHIFT; 176 + dbaddr = I40IW_DB_ADDR_OFFSET + pci_resource_start(ucontext->iwdev->ldev->pcidev, 0); 187 177 188 - if (vma->vm_pgoff == (db_addr_offset >> PAGE_SHIFT)) { 189 - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 190 - } else { 191 - if ((vma->vm_pgoff - (push_offset >> PAGE_SHIFT)) % 2) 192 - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 193 - else 194 - vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); 195 - } 196 - 197 - pfn = vma->vm_pgoff + 198 - (pci_resource_start(ucontext->iwdev->ldev->pcidev, 0) >> 199 - PAGE_SHIFT); 200 - 201 - return rdma_user_mmap_io(context, vma, pfn, PAGE_SIZE, 202 - vma->vm_page_prot, NULL); 178 + return rdma_user_mmap_io(context, vma, dbaddr >> PAGE_SHIFT, PAGE_SIZE, 179 + pgprot_noncached(vma->vm_page_prot), NULL); 203 180 } 204 181 205 182 /**
+6 -4
drivers/infiniband/hw/mthca/mthca_cq.c
··· 803 803 } 804 804 805 805 mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); 806 - if (IS_ERR(mailbox)) 806 + if (IS_ERR(mailbox)) { 807 + err = PTR_ERR(mailbox); 807 808 goto err_out_arm; 809 + } 808 810 809 811 cq_context = mailbox->buf; 810 812 ··· 848 846 } 849 847 850 848 spin_lock_irq(&dev->cq_table.lock); 851 - if (mthca_array_set(&dev->cq_table.cq, 852 - cq->cqn & (dev->limits.num_cqs - 1), 853 - cq)) { 849 + err = mthca_array_set(&dev->cq_table.cq, 850 + cq->cqn & (dev->limits.num_cqs - 1), cq); 851 + if (err) { 854 852 spin_unlock_irq(&dev->cq_table.lock); 855 853 goto err_out_free_mr; 856 854 }