Received: by 2002:ac0:a581:0:0:0:0:0 with SMTP id m1-v6csp3009447imm; Sun, 1 Jul 2018 10:13:11 -0700 (PDT) X-Google-Smtp-Source: AAOMgpfnCLaqHLDO3LNn0+y6jzLc3qNv7TPmXjNM57M8lpv78hpbocFIuOWfwDyZ/2ZMTZnLlpn1 X-Received: by 2002:a17:902:6105:: with SMTP id t5-v6mr15673865plj.92.1530465191829; Sun, 01 Jul 2018 10:13:11 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1530465191; cv=none; d=google.com; s=arc-20160816; b=iPYXH1Iw4VOgCa/eqIH2FeEEwlW58/toStjD10KmP8kgXdr7wTsz7SGkq5+Dd6rH62 hSPt1fOf5fXlF0vA5qlagCecOPagIY+n77W3XLBZwCQh0k+UV184pJRyn2ikLJxkT51w Et/fhMRVTRuHJsTjkOuyiC+dH0cgyZ9V+49gJpahtOkVOBWHjj9J4AtNBVRz6YMwKT1m 2KJ/Z6Vf+gsKOS5zzcGgNV0T6uQCoYz/h/7d2xXlGBxc+k272sZr0I63J0LmYtUL+yG9 /6KnZaEm6mz5TxNNBid27ZdmhB3WA+d3KvE/8ZUuX/ZWjBSjZGVRRp+7AEswcKOKCbh7 oacw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:user-agent:references :in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=FLdz7fYpegLFDlAzB4RJitWMSANAWoX6HghHci/d/x0=; b=yHqqfBpduGlFZNZf77n+Z09PtJcYgcMU1Od48NnVf5OyglGUWF0zIvRXarDfovfIb0 I5J1yxCSdhtfJHQlUZvQTDMZbssw6BN/XWbfkyvY+VAlarsjRIZJmCnh2BZVrPmhl/L0 fsOkae2twwR7pnaMhMZNDq5BuSDFNmeQeVaL4pnkaasTsaG5+Par85ADST8i/iiCYBkm hk3ag5BZqUb+3EvQkqlk3gcEhawcr8kNyKkrzYzJaIUvJJzp8g9fybfMZ0Rup3gx5b72 BtoaPU3sVQeUBMSrJgkL2ttPlm2vxbH0SCsmUGo4sB241aztzIS7YNIwUjPVMnRAuScE RKtQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id h2-v6si9315048pfg.126.2018.07.01.10.12.57; Sun, 01 Jul 2018 10:13:11 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1031920AbeGAQkc (ORCPT + 99 others); Sun, 1 Jul 2018 12:40:32 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:37182 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1031899AbeGAQk1 (ORCPT ); Sun, 1 Jul 2018 12:40:27 -0400 Received: from localhost (LFbn-1-12247-202.w90-92.abo.wanadoo.fr [90.92.61.202]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id CF482AA6; Sun, 1 Jul 2018 16:40:26 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Jason Gunthorpe , Jack Morgenstein , Leon Romanovsky Subject: [PATCH 4.17 086/220] IB/mlx4: Mark user MR as writable if actual virtual memory is writable Date: Sun, 1 Jul 2018 18:21:50 +0200 Message-Id: <20180701160912.017917587@linuxfoundation.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180701160908.272447118@linuxfoundation.org> References: <20180701160908.272447118@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.17-stable review patch. If anyone has any objections, please let me know. ------------------ From: Jack Morgenstein commit d8f9cc328c8888369880e2527e9186d745f2bbf6 upstream. To allow rereg_user_mr to modify the MR from read-only to writable without using get_user_pages again, we needed to define the initial MR as writable. However, this was originally done unconditionally, without taking into account the writability of the underlying virtual memory. As a result, any attempt to register a read-only MR over read-only virtual memory failed. To fix this, do not add the writable flag bit when the user virtual memory is not writable (e.g. const memory). However, when the underlying memory is NOT writable (and we therefore do not define the initial MR as writable), the IB core adds a "force writable" flag to its user-pages request. If this succeeds, the reg_user_mr caller gets a writable copy of the original pages. If the user-space caller then does a rereg_user_mr operation to enable writability, this will succeed. This should not be allowed, since the original virtual memory was not writable. Cc: Fixes: 9376932d0c26 ("IB/mlx4_ib: Add support for user MR re-registration") Signed-off-by: Jason Gunthorpe Signed-off-by: Jack Morgenstein Signed-off-by: Leon Romanovsky Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/hw/mlx4/mr.c | 50 +++++++++++++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 8 deletions(-) --- a/drivers/infiniband/hw/mlx4/mr.c +++ b/drivers/infiniband/hw/mlx4/mr.c @@ -367,6 +367,40 @@ end: return block_shift; } +static struct ib_umem *mlx4_get_umem_mr(struct ib_ucontext *context, u64 start, + u64 length, u64 virt_addr, + int access_flags) +{ + /* + * Force registering the memory as writable if the underlying pages + * are writable. This is so rereg can change the access permissions + * from readable to writable without having to run through ib_umem_get + * again + */ + if (!ib_access_writable(access_flags)) { + struct vm_area_struct *vma; + + down_read(¤t->mm->mmap_sem); + /* + * FIXME: Ideally this would iterate over all the vmas that + * cover the memory, but for now it requires a single vma to + * entirely cover the MR to support RO mappings. + */ + vma = find_vma(current->mm, start); + if (vma && vma->vm_end >= start + length && + vma->vm_start <= start) { + if (vma->vm_flags & VM_WRITE) + access_flags |= IB_ACCESS_LOCAL_WRITE; + } else { + access_flags |= IB_ACCESS_LOCAL_WRITE; + } + + up_read(¤t->mm->mmap_sem); + } + + return ib_umem_get(context, start, length, access_flags, 0); +} + struct ib_mr *mlx4_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, u64 virt_addr, int access_flags, struct ib_udata *udata) @@ -381,10 +415,8 @@ struct ib_mr *mlx4_ib_reg_user_mr(struct if (!mr) return ERR_PTR(-ENOMEM); - /* Force registering the memory as writable. */ - /* Used for memory re-registeration. HCA protects the access */ - mr->umem = ib_umem_get(pd->uobject->context, start, length, - access_flags | IB_ACCESS_LOCAL_WRITE, 0); + mr->umem = mlx4_get_umem_mr(pd->uobject->context, start, length, + virt_addr, access_flags); if (IS_ERR(mr->umem)) { err = PTR_ERR(mr->umem); goto err_free; @@ -454,6 +486,9 @@ int mlx4_ib_rereg_user_mr(struct ib_mr * } if (flags & IB_MR_REREG_ACCESS) { + if (ib_access_writable(mr_access_flags) && !mmr->umem->writable) + return -EPERM; + err = mlx4_mr_hw_change_access(dev->dev, *pmpt_entry, convert_access(mr_access_flags)); @@ -467,10 +502,9 @@ int mlx4_ib_rereg_user_mr(struct ib_mr * mlx4_mr_rereg_mem_cleanup(dev->dev, &mmr->mmr); ib_umem_release(mmr->umem); - mmr->umem = ib_umem_get(mr->uobject->context, start, length, - mr_access_flags | - IB_ACCESS_LOCAL_WRITE, - 0); + mmr->umem = + mlx4_get_umem_mr(mr->uobject->context, start, length, + virt_addr, mr_access_flags); if (IS_ERR(mmr->umem)) { err = PTR_ERR(mmr->umem); /* Prevent mlx4_ib_dereg_mr from free'ing invalid pointer */