Received: by 2002:a4a:311b:0:0:0:0:0 with SMTP id k27-v6csp4805819ooa; Tue, 14 Aug 2018 10:48:12 -0700 (PDT) X-Google-Smtp-Source: AA+uWPzikiKKVGImMqpGF+NUgZjoRZshefTwEFdTVzmIQRTzd534Sg0Trpz/uPfBPbEQIgvB/yVv X-Received: by 2002:a17:902:9b93:: with SMTP id y19-v6mr16994966plp.113.1534268892000; Tue, 14 Aug 2018 10:48:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1534268891; cv=none; d=google.com; s=arc-20160816; b=A6I0TpSPpFTTU3D8Wst+74HpoRrfc1E8VAo7J+P1+N4MtsSEILx/4TAFNkR4zo3tqG ZuaZSYZSJbJoLqeuBzZhok48akuir3ZUw4Z3oBsaoTDPUc+bY4RvFXY+gBR0yil9ezMq ti6YbDSW7DETyKd7icKPs61B/v1gT3PCSmhIVQDAviqYT1lpu0VjLKmMqoSXBL5NdKxN xM8M42j6DDzeggsgkAGeGskCb0WjrreH7lvT25lhkkUj4inejs8nKs0SL39ReRnZriBM iVg2DfwsKO0iiCQjRJ1/49VfSKghaxA1pUDp5BROg7kh6BZPwPJifmKWdHtt9ML+eW2v +lAA== 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=BQ7jGWV0i1SVASDU0+b7KyTYZKCLHFprzpbP5GEt0Cs=; b=h87DU2X0F1ESMklGWpZ4Btypia0V9kEc+SlswUtiCXXDowoh5jqtr7DI03sRxAgmF8 ZogbaQQqmgwDjuryNJsRPnpUW0n9uabhFA10L2iTfnmgliN4HTspm6abF7VY7AGzrlLB fdvVniPLRcpetga9BancEEuc8zAnk7frYllcGhzE1toIU498k6sKJNevLVTPwKQj7X7A ZRBc172LOi2n4D4dgCH4nbhMjMha9AEA7p9cCDUqLExWu6ZW53PKdSry9IyIq86lNVmC xRkn+WVdf012u4BUATR6TUBN5smKg4T+EGkzh+NQM6q2ZPoGwRS2IYt/RUo3J0SQF/yD a4fw== 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 i12-v6si22506963pfj.190.2018.08.14.10.47.57; Tue, 14 Aug 2018 10:48: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 S2391023AbeHNUeY (ORCPT + 99 others); Tue, 14 Aug 2018 16:34:24 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:60348 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390473AbeHNUeX (ORCPT ); Tue, 14 Aug 2018 16:34:23 -0400 Received: from localhost (unknown [194.244.16.108]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id 691C6CAE; Tue, 14 Aug 2018 17:46:10 +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 , Sudip Mukherjee Subject: [PATCH 4.4 14/43] IB/mlx4: Mark user MR as writable if actual virtual memory is writable Date: Tue, 14 Aug 2018 19:17:50 +0200 Message-Id: <20180814171518.046291292@linuxfoundation.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180814171517.014285600@linuxfoundation.org> References: <20180814171517.014285600@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.4-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: Sudip Mukherjee 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 @@ -130,6 +130,40 @@ out: return err; } +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) @@ -144,10 +178,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; @@ -214,6 +246,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)); @@ -227,10 +262,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 */