Received: by 2002:a25:ab43:0:0:0:0:0 with SMTP id u61csp1368312ybi; Wed, 19 Jun 2019 19:26:21 -0700 (PDT) X-Google-Smtp-Source: APXvYqzTMJqyNI8M4SSypzS5AZV0qSL9IvoG7d4WUY6aePpa60VsvogH7HK1b7/IfUpjCbvESTjE X-Received: by 2002:aa7:8641:: with SMTP id a1mr9046402pfo.177.1560997581442; Wed, 19 Jun 2019 19:26:21 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1560997581; cv=none; d=google.com; s=arc-20160816; b=GgHVP9MqkSb3t/F1pJ4YCtz44GaAbkbMRiKNO5qiNjiRBv1ERovQAKUGuGwCJQ21P4 ryYPdKo9hL6EKh9lYirDA6LCxlHpH7EsolZWob9J6xk7SAz9vnkplAUG4ByEU1+/iqEx otLHV4pGLjEndpLyIpuePXwYqBdMpus/86IiBbwOjNSit8lupyqq7Nv6RevESgqJNeep WmCkVd4Z7Ty2lMt0NBMphIst9MBdWibqAFpj7Bfqr4XvzmlDP1/6eWfqFiVBeGeBp94E RxCagxSqOVixiwS/MBWCyb/hKGmsISt0oLP0jDKlqzXEeoGNyLdGHJlVWHN3w28G85Ic f1Gg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=n1hFkPZtnzXNVbq0M+P7hVnKByN4oXMlp+t0H+PU8qo=; b=OvjswLVpxNeBgKivWwY35olD4vJLEVCB41Y4+wCMvnstli5x/ShBvce2IQaAVUJDVg tiyObVXL8Re7wTscKM1ZcApH734cWa23cZFHTqzjEYxwTRr1L85Zm+WaUDkkHDPrNvfh 6z4DkmN3CfEZWVclpXvALomTJ/M+VFMLV3YeXsfLoihyttdEu+zcPOoWO600YZfnq0RA P+KUo1w2gdrMLsWQsQO0zwW7bjEY8u7paYcwSFx1Oi26mMJt7OL2QwHNeWaPeo/x1IS8 YYbYf/tG8QAZSBDa5/f9WAIWHNZyImWA6Ih53ZTsB+/khQ/aY0qL/tW6scYGEjgf5irN XDgQ== 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id x24si17855329pfm.83.2019.06.19.19.26.06; Wed, 19 Jun 2019 19:26:21 -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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731568AbfFTCYL (ORCPT + 99 others); Wed, 19 Jun 2019 22:24:11 -0400 Received: from mx1.redhat.com ([209.132.183.28]:55306 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726370AbfFTCYK (ORCPT ); Wed, 19 Jun 2019 22:24:10 -0400 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E30A3C05D275; Thu, 20 Jun 2019 02:24:09 +0000 (UTC) Received: from xz-x1.redhat.com (ovpn-12-78.pek2.redhat.com [10.72.12.78]) by smtp.corp.redhat.com (Postfix) with ESMTP id A7B5610190A8; Thu, 20 Jun 2019 02:23:53 +0000 (UTC) From: Peter Xu To: linux-mm@kvack.org, linux-kernel@vger.kernel.org Cc: David Hildenbrand , Hugh Dickins , Maya Gokhale , Jerome Glisse , Pavel Emelyanov , Johannes Weiner , peterx@redhat.com, Martin Cracauer , Denis Plotnikov , Shaohua Li , Andrea Arcangeli , Mike Kravetz , Marty McFadden , Mike Rapoport , Mel Gorman , "Kirill A . Shutemov" , "Dr . David Alan Gilbert" , Rik van Riel Subject: [PATCH v5 18/25] userfaultfd: wp: support write protection for userfault vma range Date: Thu, 20 Jun 2019 10:20:01 +0800 Message-Id: <20190620022008.19172-19-peterx@redhat.com> In-Reply-To: <20190620022008.19172-1-peterx@redhat.com> References: <20190620022008.19172-1-peterx@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Thu, 20 Jun 2019 02:24:10 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Shaohua Li Add API to enable/disable writeprotect a vma range. Unlike mprotect, this doesn't split/merge vmas. Cc: Andrea Arcangeli Cc: Rik van Riel Cc: Kirill A. Shutemov Cc: Mel Gorman Cc: Hugh Dickins Cc: Johannes Weiner Signed-off-by: Shaohua Li Signed-off-by: Andrea Arcangeli [peterx: - use the helper to find VMA; - return -ENOENT if not found to match mcopy case; - use the new MM_CP_UFFD_WP* flags for change_protection - check against mmap_changing for failures] Reviewed-by: Jerome Glisse Reviewed-by: Mike Rapoport Signed-off-by: Peter Xu --- include/linux/userfaultfd_k.h | 3 ++ mm/userfaultfd.c | 54 +++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/include/linux/userfaultfd_k.h b/include/linux/userfaultfd_k.h index dcd33172b728..a8e5f3ea9bb2 100644 --- a/include/linux/userfaultfd_k.h +++ b/include/linux/userfaultfd_k.h @@ -41,6 +41,9 @@ extern ssize_t mfill_zeropage(struct mm_struct *dst_mm, unsigned long dst_start, unsigned long len, bool *mmap_changing); +extern int mwriteprotect_range(struct mm_struct *dst_mm, + unsigned long start, unsigned long len, + bool enable_wp, bool *mmap_changing); /* mm helpers */ static inline bool is_mergeable_vm_userfaultfd_ctx(struct vm_area_struct *vma, diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c index 6b9dd5b66f64..4208592c7ca3 100644 --- a/mm/userfaultfd.c +++ b/mm/userfaultfd.c @@ -638,3 +638,57 @@ ssize_t mfill_zeropage(struct mm_struct *dst_mm, unsigned long start, { return __mcopy_atomic(dst_mm, start, 0, len, true, mmap_changing, 0); } + +int mwriteprotect_range(struct mm_struct *dst_mm, unsigned long start, + unsigned long len, bool enable_wp, bool *mmap_changing) +{ + struct vm_area_struct *dst_vma; + pgprot_t newprot; + int err; + + /* + * Sanitize the command parameters: + */ + BUG_ON(start & ~PAGE_MASK); + BUG_ON(len & ~PAGE_MASK); + + /* Does the address range wrap, or is the span zero-sized? */ + BUG_ON(start + len <= start); + + down_read(&dst_mm->mmap_sem); + + /* + * If memory mappings are changing because of non-cooperative + * operation (e.g. mremap) running in parallel, bail out and + * request the user to retry later + */ + err = -EAGAIN; + if (mmap_changing && READ_ONCE(*mmap_changing)) + goto out_unlock; + + err = -ENOENT; + dst_vma = vma_find_uffd(dst_mm, start, len); + /* + * Make sure the vma is not shared, that the dst range is + * both valid and fully within a single existing vma. + */ + if (!dst_vma || (dst_vma->vm_flags & VM_SHARED)) + goto out_unlock; + if (!userfaultfd_wp(dst_vma)) + goto out_unlock; + if (!vma_is_anonymous(dst_vma)) + goto out_unlock; + + if (enable_wp) + newprot = vm_get_page_prot(dst_vma->vm_flags & ~(VM_WRITE)); + else + newprot = vm_get_page_prot(dst_vma->vm_flags); + + change_protection(dst_vma, start, start + len, newprot, + enable_wp ? MM_CP_UFFD_WP : MM_CP_UFFD_WP_RESOLVE); + + err = 0; +out_unlock: + up_read(&dst_mm->mmap_sem); + return err; +} -- 2.21.0