From patchwork Mon Aug 21 12:30:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kefeng Wang X-Patchwork-Id: 13359370 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 408BBEE49B0 for ; Mon, 21 Aug 2023 12:31:24 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 61D248D000C; Mon, 21 Aug 2023 08:31:23 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 5A2538D0002; Mon, 21 Aug 2023 08:31:23 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 41D438D000C; Mon, 21 Aug 2023 08:31:23 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0013.hostedemail.com [216.40.44.13]) by kanga.kvack.org (Postfix) with ESMTP id 319648D0002 for ; Mon, 21 Aug 2023 08:31:23 -0400 (EDT) Received: from smtpin26.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay03.hostedemail.com (Postfix) with ESMTP id E7331A0BCD for ; Mon, 21 Aug 2023 12:31:22 +0000 (UTC) X-FDA: 81148047204.26.753E87C Received: from szxga02-in.huawei.com (szxga02-in.huawei.com [45.249.212.188]) by imf25.hostedemail.com (Postfix) with ESMTP id 1B356A0009 for ; Mon, 21 Aug 2023 12:31:18 +0000 (UTC) Authentication-Results: imf25.hostedemail.com; dkim=none; spf=pass (imf25.hostedemail.com: domain of wangkefeng.wang@huawei.com designates 45.249.212.188 as permitted sender) smtp.mailfrom=wangkefeng.wang@huawei.com; dmarc=pass (policy=quarantine) header.from=huawei.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1692621080; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=nHw7Ttr+6gOLYyndAOJOMAYlLCBrQmERbINb9LSfgAI=; b=RIkSHgkItruDptKA4Q7olfjzQKEl2CkD/2gftexvqg4jmr/Bd7lVNLxeCOzBwRv7R1LDYp TyM1r4YtH7WUahPnSCkCOB8eekZ2N2BIAbnHyjbhjIdjGz58/Knh5W80TAMA7U9xUsS22i Ax/0DyFSFAHP5DHBc3XXFVvi+dyQLbI= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1692621080; a=rsa-sha256; cv=none; b=zQL0iB/ZugUbpeCw+4YR/Qo9oJi3B3XEil1GrTu70fhzeN6b0MjthbxNdVRL6FCnecxrlc I+zo6sJ3ES0AYS3j5hE2LVPX7E5mKptYsTnloHIOlSL4RpN7YGnCcnZfkitAfaXy2s7VxQ jKfi4IfVBf5BOnMxy6h449P99Ks5v/Y= ARC-Authentication-Results: i=1; imf25.hostedemail.com; dkim=none; spf=pass (imf25.hostedemail.com: domain of wangkefeng.wang@huawei.com designates 45.249.212.188 as permitted sender) smtp.mailfrom=wangkefeng.wang@huawei.com; dmarc=pass (policy=quarantine) header.from=huawei.com Received: from dggpemm100001.china.huawei.com (unknown [172.30.72.55]) by szxga02-in.huawei.com (SkyGuard) with ESMTP id 4RTsF81thwzNnKj; Mon, 21 Aug 2023 20:27:40 +0800 (CST) Received: from localhost.localdomain (10.175.112.125) by dggpemm100001.china.huawei.com (7.185.36.93) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.31; Mon, 21 Aug 2023 20:31:12 +0800 From: Kefeng Wang To: Andrew Morton , CC: , , Russell King , Catalin Marinas , Will Deacon , Huacai Chen , WANG Xuerui , Michael Ellerman , Nicholas Piggin , Christophe Leroy , Paul Walmsley , Palmer Dabbelt , Albert Ou , Alexander Gordeev , Gerald Schaefer , Heiko Carstens , Vasily Gorbik , Christian Borntraeger , Sven Schnelle , Dave Hansen , Andy Lutomirski , Peter Zijlstra , Thomas Gleixner , Ingo Molnar , Borislav Petkov , , "H . Peter Anvin" , , , , , , , Kefeng Wang Subject: [PATCH rfc v2 01/10] mm: add a generic VMA lock-based page fault handler Date: Mon, 21 Aug 2023 20:30:47 +0800 Message-ID: <20230821123056.2109942-2-wangkefeng.wang@huawei.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20230821123056.2109942-1-wangkefeng.wang@huawei.com> References: <20230821123056.2109942-1-wangkefeng.wang@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.112.125] X-ClientProxiedBy: dggems705-chm.china.huawei.com (10.3.19.182) To dggpemm100001.china.huawei.com (7.185.36.93) X-CFilter-Loop: Reflected X-Rspamd-Queue-Id: 1B356A0009 X-Rspam-User: X-Stat-Signature: 3nytg88fhcmizn8z8se39495ya7xows4 X-Rspamd-Server: rspam03 X-HE-Tag: 1692621078-504 X-HE-Meta: U2FsdGVkX1/3o5KjKrNfCj8ZsvYt94oJ8m6QxztLmAL992dAa1oMp404eYhR8nrk4GY2We40Q4bbEFXmMpgxDAAAFUbuaPpUnPlUbTO0Ms1lUpeSDCrbt0iRK9J+3T7KOCeS8rz/CTlbuYmdPF+Vsb1NJY28QzCwANBMcddWQxhaGBsCuIbAyvq4TwyRyEIWOM90kAcoZa21rPbimpv4vmo94oqVyRgvUJFK2LkLXAflJOheo2ZYBP0xeq0b68caZWel1uVl0X6rnPyDxFQ9TeY79fxgV8nXRtymNS7/yv5n5q08qCXfVNSujGGifnUahnOD0r/dFT0R/8eV3Nw5RTDP/WWL+NgUe8j1iWlJi/65/xKQElW7DrIeXYtyx386JRvpqh5OyTQCnGXdoiVnyK8EtBCvOA59XOy5Qyn2xcvekrP14XDwd81HKaQ4Z9YynukvabtnA4jBrYr0UN2St60mwGuP/OHjP/i/QyFEituIVCI8JpETLK669lqRrU+wAwgS+yprueya6V4bBveRvEPVO9hwJfGhUKtqh+CHQCNWbxMKH4q5BM6x+TXvKBSvgTd8E+UpOZuB638FmwORtm07JiBrlTzucOQFs4guOGK/AKsmUd/MlZazZwyCJuNYu7aolJ48BHiQZ1SkIEQolvMx2ZTd3Au+LLdHreTxmrV1H9EhX9ypFW1nLtUVBSbXfTUw3GaJB5XKF08bmOEK+7TFRYo25uWgPyMaO97vugX7WOPNRnMNNyOVDw+C2utOU9birkWMiywg8NNzfI9W75j9zbQZk2fLvzg5CjVBlAtgHX4lopnyVOsHU3cHQSrqkOHRPks/k8Kj2chLGMDlbfvYLBYwhYI2ptRGKXwZ39Ptz57lslfpSHbDV3ghDw6PxHxbp3h9IVO/VFQfb0su0CV5fidVMZXy3VP9klfXeFeOsDqW5zFgPy/3CjHcz/vbw/IjiPUNeA8DnM7WlDy 4xm2d5LI Q7FiXN7F3EJzX0mfyw6+FKWwPYl/mrB4MePe/a0NoD3VZJXmhlASn5BefEs+og5gORNdKyIRavjMJIb6duo7xS0sDaBdDR9BAKYjv/RWnqPTcfQfCYfdgOUxtoTYEfmXw2OT3AMzrO53QxqV8usuArI81nw== X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: The ARCH_SUPPORTS_PER_VMA_LOCK are enabled by more and more architectures, eg, x86, arm64, powerpc and s390, and riscv, those implementation are very similar which results in some duplicated codes, let's add a generic VMA lock-based page fault handler try_to_vma_locked_page_fault() to eliminate them, and which also make us easy to support this on new architectures. Since different architectures use different way to check vma whether is accessable or not, the struct pt_regs, page fault error code and vma flags are added into struct vm_fault, then, the architecture's page fault code could re-use struct vm_fault to record and check vma accessable by each own implementation. Signed-off-by: Kefeng Wang --- include/linux/mm.h | 17 +++++++++++++++++ include/linux/mm_types.h | 2 ++ mm/memory.c | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+) diff --git a/include/linux/mm.h b/include/linux/mm.h index 3f764e84e567..22a6f4c56ff3 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -512,9 +512,12 @@ struct vm_fault { pgoff_t pgoff; /* Logical page offset based on vma */ unsigned long address; /* Faulting virtual address - masked */ unsigned long real_address; /* Faulting virtual address - unmasked */ + unsigned long fault_code; /* Faulting error code during page fault */ + struct pt_regs *regs; /* The registers stored during page fault */ }; enum fault_flag flags; /* FAULT_FLAG_xxx flags * XXX: should really be 'const' */ + vm_flags_t vm_flags; /* VMA flags to be used for access checking */ pmd_t *pmd; /* Pointer to pmd entry matching * the 'address' */ pud_t *pud; /* Pointer to pud entry matching @@ -774,6 +777,9 @@ static inline void assert_fault_locked(struct vm_fault *vmf) struct vm_area_struct *lock_vma_under_rcu(struct mm_struct *mm, unsigned long address); +bool arch_vma_access_error(struct vm_area_struct *vma, struct vm_fault *vmf); +vm_fault_t try_vma_locked_page_fault(struct vm_fault *vmf); + #else /* CONFIG_PER_VMA_LOCK */ static inline bool vma_start_read(struct vm_area_struct *vma) @@ -801,6 +807,17 @@ static inline void assert_fault_locked(struct vm_fault *vmf) mmap_assert_locked(vmf->vma->vm_mm); } +static inline struct vm_area_struct *lock_vma_under_rcu(struct mm_struct *mm, + unsigned long address) +{ + return NULL; +} + +static inline vm_fault_t try_vma_locked_page_fault(struct vm_fault *vmf) +{ + return VM_FAULT_NONE; +} + #endif /* CONFIG_PER_VMA_LOCK */ extern const struct vm_operations_struct vma_dummy_vm_ops; diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index f5ba5b0bc836..702820cea3f9 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -1119,6 +1119,7 @@ typedef __bitwise unsigned int vm_fault_t; * fault. Used to decide whether a process gets delivered SIGBUS or * just gets major/minor fault counters bumped up. * + * @VM_FAULT_NONE: Special case, not starting to handle fault * @VM_FAULT_OOM: Out Of Memory * @VM_FAULT_SIGBUS: Bad access * @VM_FAULT_MAJOR: Page read from storage @@ -1139,6 +1140,7 @@ typedef __bitwise unsigned int vm_fault_t; * */ enum vm_fault_reason { + VM_FAULT_NONE = (__force vm_fault_t)0x000000, VM_FAULT_OOM = (__force vm_fault_t)0x000001, VM_FAULT_SIGBUS = (__force vm_fault_t)0x000002, VM_FAULT_MAJOR = (__force vm_fault_t)0x000004, diff --git a/mm/memory.c b/mm/memory.c index 3b4aaa0d2fff..60fe35db5134 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -5510,6 +5510,45 @@ struct vm_area_struct *lock_vma_under_rcu(struct mm_struct *mm, count_vm_vma_lock_event(VMA_LOCK_ABORT); return NULL; } + +#ifdef CONFIG_PER_VMA_LOCK +bool __weak arch_vma_access_error(struct vm_area_struct *vma, struct vm_fault *vmf) +{ + return (vma->vm_flags & vmf->vm_flags) == 0; +} +#endif + +vm_fault_t try_vma_locked_page_fault(struct vm_fault *vmf) +{ + vm_fault_t fault = VM_FAULT_NONE; + struct vm_area_struct *vma; + + if (!(vmf->flags & FAULT_FLAG_USER)) + return fault; + + vma = lock_vma_under_rcu(current->mm, vmf->real_address); + if (!vma) + return fault; + + if (arch_vma_access_error(vma, vmf)) { + vma_end_read(vma); + return fault; + } + + fault = handle_mm_fault(vma, vmf->real_address, + vmf->flags | FAULT_FLAG_VMA_LOCK, vmf->regs); + + if (!(fault & (VM_FAULT_RETRY | VM_FAULT_COMPLETED))) + vma_end_read(vma); + + if (fault & VM_FAULT_RETRY) + count_vm_vma_lock_event(VMA_LOCK_RETRY); + else + count_vm_vma_lock_event(VMA_LOCK_SUCCESS); + + return fault; +} + #endif /* CONFIG_PER_VMA_LOCK */ #ifndef __PAGETABLE_P4D_FOLDED