]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.14.53/ib-hfi1-fix-user-context-tail-allocation-for-dma_rtail.patch
5.1-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.14.53 / ib-hfi1-fix-user-context-tail-allocation-for-dma_rtail.patch
1 From 1bc0299d976e000ececc6acd76e33b4582646cb7 Mon Sep 17 00:00:00 2001
2 From: Mike Marciniszyn <mike.marciniszyn@intel.com>
3 Date: Thu, 31 May 2018 11:30:09 -0700
4 Subject: IB/hfi1: Fix user context tail allocation for DMA_RTAIL
5
6 From: Mike Marciniszyn <mike.marciniszyn@intel.com>
7
8 commit 1bc0299d976e000ececc6acd76e33b4582646cb7 upstream.
9
10 The following code fails to allocate a buffer for the
11 tail address that the hardware DMAs into when the user
12 context DMA_RTAIL is set.
13
14 if (HFI1_CAP_KGET_MASK(rcd->flags, DMA_RTAIL)) {
15 rcd->rcvhdrtail_kvaddr = dma_zalloc_coherent(
16 &dd->pcidev->dev, PAGE_SIZE, &dma_hdrqtail,
17 gfp_flags);
18 if (!rcd->rcvhdrtail_kvaddr)
19 goto bail_free;
20 rcd->rcvhdrqtailaddr_dma = dma_hdrqtail;
21 }
22
23 So the rcvhdrtail_kvaddr would then be NULL.
24
25 The mmap logic fails to check for a NULL rcvhdrtail_kvaddr.
26
27 The fix is to test for both user and kernel DMA_TAIL options
28 during the allocation as well as testing for a NULL
29 rcvhdrtail_kvaddr during the mmap processing.
30
31 Additionally, all downstream testing of the capmask for DMA_RTAIL
32 have been eliminated in favor of testing rcvhdrtail_kvaddr.
33
34 Cc: <stable@vger.kernel.org> # 4.9.x
35 Reviewed-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
36 Signed-off-by: Mike Marciniszyn <mike.marciniszyn@intel.com>
37 Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
38 Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
39 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
40
41 ---
42 drivers/infiniband/hw/hfi1/chip.c | 8 ++++----
43 drivers/infiniband/hw/hfi1/file_ops.c | 2 +-
44 drivers/infiniband/hw/hfi1/init.c | 9 ++++-----
45 3 files changed, 9 insertions(+), 10 deletions(-)
46
47 --- a/drivers/infiniband/hw/hfi1/chip.c
48 +++ b/drivers/infiniband/hw/hfi1/chip.c
49 @@ -6829,7 +6829,7 @@ static void rxe_kernel_unfreeze(struct h
50 }
51 rcvmask = HFI1_RCVCTRL_CTXT_ENB;
52 /* HFI1_RCVCTRL_TAILUPD_[ENB|DIS] needs to be set explicitly */
53 - rcvmask |= HFI1_CAP_KGET_MASK(rcd->flags, DMA_RTAIL) ?
54 + rcvmask |= rcd->rcvhdrtail_kvaddr ?
55 HFI1_RCVCTRL_TAILUPD_ENB : HFI1_RCVCTRL_TAILUPD_DIS;
56 hfi1_rcvctrl(dd, rcvmask, rcd);
57 hfi1_rcd_put(rcd);
58 @@ -8341,7 +8341,7 @@ static inline int check_packet_present(s
59 u32 tail;
60 int present;
61
62 - if (!HFI1_CAP_IS_KSET(DMA_RTAIL))
63 + if (!rcd->rcvhdrtail_kvaddr)
64 present = (rcd->seq_cnt ==
65 rhf_rcv_seq(rhf_to_cpu(get_rhf_addr(rcd))));
66 else /* is RDMA rtail */
67 @@ -11813,7 +11813,7 @@ void hfi1_rcvctrl(struct hfi1_devdata *d
68 /* reset the tail and hdr addresses, and sequence count */
69 write_kctxt_csr(dd, ctxt, RCV_HDR_ADDR,
70 rcd->rcvhdrq_dma);
71 - if (HFI1_CAP_KGET_MASK(rcd->flags, DMA_RTAIL))
72 + if (rcd->rcvhdrtail_kvaddr)
73 write_kctxt_csr(dd, ctxt, RCV_HDR_TAIL_ADDR,
74 rcd->rcvhdrqtailaddr_dma);
75 rcd->seq_cnt = 1;
76 @@ -11893,7 +11893,7 @@ void hfi1_rcvctrl(struct hfi1_devdata *d
77 rcvctrl |= RCV_CTXT_CTRL_INTR_AVAIL_SMASK;
78 if (op & HFI1_RCVCTRL_INTRAVAIL_DIS)
79 rcvctrl &= ~RCV_CTXT_CTRL_INTR_AVAIL_SMASK;
80 - if (op & HFI1_RCVCTRL_TAILUPD_ENB && rcd->rcvhdrqtailaddr_dma)
81 + if ((op & HFI1_RCVCTRL_TAILUPD_ENB) && rcd->rcvhdrtail_kvaddr)
82 rcvctrl |= RCV_CTXT_CTRL_TAIL_UPD_SMASK;
83 if (op & HFI1_RCVCTRL_TAILUPD_DIS) {
84 /* See comment on RcvCtxtCtrl.TailUpd above */
85 --- a/drivers/infiniband/hw/hfi1/file_ops.c
86 +++ b/drivers/infiniband/hw/hfi1/file_ops.c
87 @@ -622,7 +622,7 @@ static int hfi1_file_mmap(struct file *f
88 ret = -EINVAL;
89 goto done;
90 }
91 - if (flags & VM_WRITE) {
92 + if ((flags & VM_WRITE) || !uctxt->rcvhdrtail_kvaddr) {
93 ret = -EPERM;
94 goto done;
95 }
96 --- a/drivers/infiniband/hw/hfi1/init.c
97 +++ b/drivers/infiniband/hw/hfi1/init.c
98 @@ -1808,7 +1808,6 @@ int hfi1_create_rcvhdrq(struct hfi1_devd
99 u64 reg;
100
101 if (!rcd->rcvhdrq) {
102 - dma_addr_t dma_hdrqtail;
103 gfp_t gfp_flags;
104
105 /*
106 @@ -1834,13 +1833,13 @@ int hfi1_create_rcvhdrq(struct hfi1_devd
107 goto bail;
108 }
109
110 - if (HFI1_CAP_KGET_MASK(rcd->flags, DMA_RTAIL)) {
111 + if (HFI1_CAP_KGET_MASK(rcd->flags, DMA_RTAIL) ||
112 + HFI1_CAP_UGET_MASK(rcd->flags, DMA_RTAIL)) {
113 rcd->rcvhdrtail_kvaddr = dma_zalloc_coherent(
114 - &dd->pcidev->dev, PAGE_SIZE, &dma_hdrqtail,
115 - gfp_flags);
116 + &dd->pcidev->dev, PAGE_SIZE,
117 + &rcd->rcvhdrqtailaddr_dma, gfp_flags);
118 if (!rcd->rcvhdrtail_kvaddr)
119 goto bail_free;
120 - rcd->rcvhdrqtailaddr_dma = dma_hdrqtail;
121 }
122
123 rcd->rcvhdrq_size = amt;