From patchwork Thu Oct 27 20:34:02 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Stoakes X-Patchwork-Id: 9400705 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 5E6F360231 for ; Fri, 28 Oct 2016 00:30:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4DB0A2A402 for ; Fri, 28 Oct 2016 00:30:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 41F232A404; Fri, 28 Oct 2016 00:30:24 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 98BDB2A403 for ; Fri, 28 Oct 2016 00:30:23 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id E7FA76EACE; Fri, 28 Oct 2016 00:30:10 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-wm0-x243.google.com (mail-wm0-x243.google.com [IPv6:2a00:1450:400c:c09::243]) by gabe.freedesktop.org (Postfix) with ESMTPS id 2FF1D6EAE1 for ; Thu, 27 Oct 2016 20:34:13 +0000 (UTC) Received: by mail-wm0-x243.google.com with SMTP id y138so4409531wme.1 for ; Thu, 27 Oct 2016 13:34:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=lJGQ9yLFo0Tvq75kzjJI5v0FxOAVDnVfQtI82j0K8t8=; b=eOOTrwVQg7cMFbTU4pFF1m8OM/DBPCLOGHzB7XXioPmN98u87wEdJzWJ5uV2150lNr 0dcvmKIbhRAKTnPSC/0V5WIysUa1B+zft6SVBGlbVAkBj4i8rsOutyWpNA8rY3bNxLdS uuq8VqyFAj0XkNR++mLNMVwCD7Xebu0ilqtUUUcIc+rsXwxNOwnq0C+QSLhUfad+rR6K uCtaOffTGaCUZxl8baxVEdflIkdjsow++NMgbV/6TwTOQA/kGMAZwKx8tsXIfpJAF0gL oZW2bENaH/lf2lbVEt32DSzL+YUuWVqnUvtoXJ4gdsyElquT7R9Sj1GZJFpEKrbS4Cbh YQxw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=lJGQ9yLFo0Tvq75kzjJI5v0FxOAVDnVfQtI82j0K8t8=; b=YdlGnhh87h/eCXpNzggwgD2uI/boxVTmSXD2RjqnxhxWUz5EIqCN/D82updJAoIQ/J uvTK7Pfilx9bTFZ/YiiqepdvOSVmGVxHrvnsc5a3Tjv9roMg4cUeoqJs0LhBs+5X6Azb cMHlYb0f/v2VUW4vRJI1rw7pxgGJVefUbsgOglq47OMbzClCxlJjTJMHDsyXzV6KPBXI YfT3bJjALPTVZOhgTcApiCAJOY+50KAHc4Z1Up/84a6OIeC3OpmTSyBC6+7B7dhFY87+ GujnFFlpKaV2+3uaB/X5hdlQMMBgWlLotH9nr0Oe3kWcsig7x3dKNBeB2WEUftKQsFGR v5pQ== X-Gm-Message-State: ABUngveqZ7JlYJATWvnl99MCHTNxqc7KOCi3KrsJzpHByx+i0ulsZBXNuIJ4HDLklNDWDQ== X-Received: by 10.194.178.200 with SMTP id da8mr8661575wjc.157.1477600451653; Thu, 27 Oct 2016 13:34:11 -0700 (PDT) Received: from localhost (cpc94060-newt37-2-0-cust185.19-3.cable.virginm.net. [92.234.204.186]) by smtp.gmail.com with ESMTPSA id x127sm5139678wmd.21.2016.10.27.13.34.09 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 27 Oct 2016 13:34:10 -0700 (PDT) From: Lorenzo Stoakes To: linux-mm@kvack.org Subject: [PATCH v2 1/2] mm: add locked parameter to get_user_pages_remote() Date: Thu, 27 Oct 2016 21:34:02 +0100 Message-Id: <20161027203403.31708-2-lstoakes@gmail.com> X-Mailer: git-send-email 2.10.1 In-Reply-To: <20161027203403.31708-1-lstoakes@gmail.com> References: <20161027203403.31708-1-lstoakes@gmail.com> X-Mailman-Approved-At: Fri, 28 Oct 2016 00:30:07 +0000 Cc: Rik van Riel , Jan Kara , Lorenzo Stoakes , kvm@vger.kernel.org, =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= , linux-rdma@vger.kernel.org, Mel Gorman , Dave Hansen , Hugh Dickins , linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, Michal Hocko , linux-security-module@vger.kernel.org, linux-fsdevel@vger.kernel.org, Paolo Bonzini , Andrew Morton , Linus Torvalds X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP This patch adds an int *locked parameter to get_user_pages_remote() to allow VM_FAULT_RETRY faulting behaviour similar to get_user_pages_[un]locked(). It additionally clears the way for __get_user_pages_unlocked() to be unexported as its sole remaining useful characteristic was to allow for VM_FAULT_RETRY behaviour when faulting in pages. It should not introduce any functional changes, however it does allow for subsequent changes to get_user_pages_remote() callers to take advantage of VM_FAULT_RETRY. Signed-off-by: Lorenzo Stoakes --- v2: updated description drivers/gpu/drm/etnaviv/etnaviv_gem.c | 2 +- drivers/gpu/drm/i915/i915_gem_userptr.c | 2 +- drivers/infiniband/core/umem_odp.c | 2 +- fs/exec.c | 2 +- include/linux/mm.h | 2 +- kernel/events/uprobes.c | 4 ++-- mm/gup.c | 12 ++++++++---- mm/memory.c | 2 +- security/tomoyo/domain.c | 2 +- 9 files changed, 17 insertions(+), 13 deletions(-) -- 2.10.1 diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c index 0370b84..0c69a97f 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c @@ -763,7 +763,7 @@ static struct page **etnaviv_gem_userptr_do_get_pages( down_read(&mm->mmap_sem); while (pinned < npages) { ret = get_user_pages_remote(task, mm, ptr, npages - pinned, - flags, pvec + pinned, NULL); + flags, pvec + pinned, NULL, NULL); if (ret < 0) break; diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index c6f780f..836b525 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c @@ -522,7 +522,7 @@ __i915_gem_userptr_get_pages_worker(struct work_struct *_work) obj->userptr.ptr + pinned * PAGE_SIZE, npages - pinned, flags, - pvec + pinned, NULL); + pvec + pinned, NULL, NULL); if (ret < 0) break; diff --git a/drivers/infiniband/core/umem_odp.c b/drivers/infiniband/core/umem_odp.c index 1f0fe32..6b079a3 100644 --- a/drivers/infiniband/core/umem_odp.c +++ b/drivers/infiniband/core/umem_odp.c @@ -578,7 +578,7 @@ int ib_umem_odp_map_dma_pages(struct ib_umem *umem, u64 user_virt, u64 bcnt, */ npages = get_user_pages_remote(owning_process, owning_mm, user_virt, gup_num_pages, - flags, local_page_list, NULL); + flags, local_page_list, NULL, NULL); up_read(&owning_mm->mmap_sem); if (npages < 0) diff --git a/fs/exec.c b/fs/exec.c index 4e497b9..2cf049d 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -209,7 +209,7 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, * doing the exec and bprm->mm is the new process's mm. */ ret = get_user_pages_remote(current, bprm->mm, pos, 1, gup_flags, - &page, NULL); + &page, NULL, NULL); if (ret <= 0) return NULL; diff --git a/include/linux/mm.h b/include/linux/mm.h index a92c8d7..cc15445 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1274,7 +1274,7 @@ extern int access_remote_vm(struct mm_struct *mm, unsigned long addr, long get_user_pages_remote(struct task_struct *tsk, struct mm_struct *mm, unsigned long start, unsigned long nr_pages, unsigned int gup_flags, struct page **pages, - struct vm_area_struct **vmas); + struct vm_area_struct **vmas, int *locked); long get_user_pages(unsigned long start, unsigned long nr_pages, unsigned int gup_flags, struct page **pages, struct vm_area_struct **vmas); diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index f9ec9ad..215871b 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -301,7 +301,7 @@ int uprobe_write_opcode(struct mm_struct *mm, unsigned long vaddr, retry: /* Read the page with vaddr into memory */ ret = get_user_pages_remote(NULL, mm, vaddr, 1, FOLL_FORCE, &old_page, - &vma); + &vma, NULL); if (ret <= 0) return ret; @@ -1712,7 +1712,7 @@ static int is_trap_at_addr(struct mm_struct *mm, unsigned long vaddr) * essentially a kernel access to the memory. */ result = get_user_pages_remote(NULL, mm, vaddr, 1, FOLL_FORCE, &page, - NULL); + NULL, NULL); if (result < 0) return result; diff --git a/mm/gup.c b/mm/gup.c index ec4f827..0567851 100644 --- a/mm/gup.c +++ b/mm/gup.c @@ -920,6 +920,9 @@ EXPORT_SYMBOL(get_user_pages_unlocked); * only intends to ensure the pages are faulted in. * @vmas: array of pointers to vmas corresponding to each page. * Or NULL if the caller does not require them. + * @locked: pointer to lock flag indicating whether lock is held and + * subsequently whether VM_FAULT_RETRY functionality can be + * utilised. Lock must initially be held. * * Returns number of pages pinned. This may be fewer than the number * requested. If nr_pages is 0 or negative, returns 0. If no pages @@ -963,10 +966,10 @@ EXPORT_SYMBOL(get_user_pages_unlocked); long get_user_pages_remote(struct task_struct *tsk, struct mm_struct *mm, unsigned long start, unsigned long nr_pages, unsigned int gup_flags, struct page **pages, - struct vm_area_struct **vmas) + struct vm_area_struct **vmas, int *locked) { return __get_user_pages_locked(tsk, mm, start, nr_pages, pages, vmas, - NULL, false, + locked, true, gup_flags | FOLL_TOUCH | FOLL_REMOTE); } EXPORT_SYMBOL(get_user_pages_remote); @@ -974,8 +977,9 @@ EXPORT_SYMBOL(get_user_pages_remote); /* * This is the same as get_user_pages_remote(), just with a * less-flexible calling convention where we assume that the task - * and mm being operated on are the current task's. We also - * obviously don't pass FOLL_REMOTE in here. + * and mm being operated on are the current task's and don't allow + * passing of a locked parameter. We also obviously don't pass + * FOLL_REMOTE in here. */ long get_user_pages(unsigned long start, unsigned long nr_pages, unsigned int gup_flags, struct page **pages, diff --git a/mm/memory.c b/mm/memory.c index e18c57b..2f3949b 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -3883,7 +3883,7 @@ static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm, struct page *page = NULL; ret = get_user_pages_remote(tsk, mm, addr, 1, - gup_flags, &page, &vma); + gup_flags, &page, &vma, NULL); if (ret <= 0) { #ifndef CONFIG_HAVE_IOREMAP_PROT break; diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c index 682b73a..838ffa7 100644 --- a/security/tomoyo/domain.c +++ b/security/tomoyo/domain.c @@ -881,7 +881,7 @@ bool tomoyo_dump_page(struct linux_binprm *bprm, unsigned long pos, * the execve(). */ if (get_user_pages_remote(current, bprm->mm, pos, 1, - FOLL_FORCE, &page, NULL) <= 0) + FOLL_FORCE, &page, NULL, NULL) <= 0) return false; #else page = bprm->page[pos / PAGE_SIZE];