From: Ryan Roberts <ryan.roberts@arm.com> To: Catalin Marinas <catalin.marinas@arm.com>, Will Deacon <will@kernel.org>, Joey Gouly <joey.gouly@arm.com>, Ard Biesheuvel <ardb@kernel.org>, Mark Rutland <mark.rutland@arm.com>, Anshuman Khandual <anshuman.khandual@arm.com>, David Hildenbrand <david@redhat.com>, Peter Xu <peterx@redhat.com>, Mike Rapoport <rppt@linux.ibm.com>, Shivansh Vij <shivanshvij@outlook.com> Cc: Ryan Roberts <ryan.roberts@arm.com>, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH v1 1/2] arm64/mm: Move PTE_PROT_NONE and PMD_PRESENT_INVALID Date: Wed, 24 Apr 2024 12:10:16 +0100 [thread overview] Message-ID: <20240424111017.3160195-2-ryan.roberts@arm.com> (raw) In-Reply-To: <20240424111017.3160195-1-ryan.roberts@arm.com> Previously PTE_PROT_NONE was occupying bit 58, one of the bits reserved for SW use when the PTE is valid. This is a waste of those precious SW bits since PTE_PROT_NONE can only ever be set when valid is clear. Instead let's overlay it on what would be a HW bit if valid was set. We need to be careful about which HW bit to choose since some of them must be preserved; when pte_present() is true (as it is for a PTE_PROT_NONE pte), it is legitimate for the core to call various accessors, e.g. pte_dirty(), pte_write() etc. There are also some accessors that are private to the arch which must continue to be honoured, e.g. pte_user(), pte_user_exec() etc. So we choose to overlay PTE_UXN; This effectively means that whenever a pte has PTE_PROT_NONE set, it will always report pte_user_exec() == false, which is obviously always correct. As a result of this change, we must shuffle the layout of the arch-specific swap pte so that PTE_PROT_NONE is always zero and not overlapping with any other field. As a result of this, there is no way to keep the `type` field contiguous without conflicting with PMD_PRESENT_INVALID (bit 59), which must also be 0 for a swap pte. So let's move PMD_PRESENT_INVALID to bit 60. In the end, this frees up bit 58 for future use as a proper SW bit (e.g. soft-dirty or uffd-wp). Signed-off-by: Ryan Roberts <ryan.roberts@arm.com> --- arch/arm64/include/asm/pgtable-prot.h | 4 ++-- arch/arm64/include/asm/pgtable.h | 16 +++++++++------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h index dd9ee67d1d87..ef952d69fd04 100644 --- a/arch/arm64/include/asm/pgtable-prot.h +++ b/arch/arm64/include/asm/pgtable-prot.h @@ -18,14 +18,14 @@ #define PTE_DIRTY (_AT(pteval_t, 1) << 55) #define PTE_SPECIAL (_AT(pteval_t, 1) << 56) #define PTE_DEVMAP (_AT(pteval_t, 1) << 57) -#define PTE_PROT_NONE (_AT(pteval_t, 1) << 58) /* only when !PTE_VALID */ +#define PTE_PROT_NONE (PTE_UXN) /* Reuse PTE_UXN; only when !PTE_VALID */ /* * This bit indicates that the entry is present i.e. pmd_page() * still points to a valid huge page in memory even if the pmd * has been invalidated. */ -#define PMD_PRESENT_INVALID (_AT(pteval_t, 1) << 59) /* only when !PMD_SECT_VALID */ +#define PMD_PRESENT_INVALID (_AT(pteval_t, 1) << 60) /* only when !PMD_SECT_VALID */ #define _PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF | PTE_SHARED) #define _PROT_SECT_DEFAULT (PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S) diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index afdd56d26ad7..23aabff4fa6f 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -1248,20 +1248,22 @@ static inline pmd_t pmdp_establish(struct vm_area_struct *vma, * Encode and decode a swap entry: * bits 0-1: present (must be zero) * bits 2: remember PG_anon_exclusive - * bits 3-7: swap type - * bits 8-57: swap offset - * bit 58: PTE_PROT_NONE (must be zero) + * bits 4-53: swap offset + * bit 54: PTE_PROT_NONE (overlays PTE_UXN) (must be zero) + * bits 55-59: swap type + * bit 60: PMD_PRESENT_INVALID (must be zero) */ -#define __SWP_TYPE_SHIFT 3 +#define __SWP_TYPE_SHIFT 55 #define __SWP_TYPE_BITS 5 -#define __SWP_OFFSET_BITS 50 #define __SWP_TYPE_MASK ((1 << __SWP_TYPE_BITS) - 1) -#define __SWP_OFFSET_SHIFT (__SWP_TYPE_BITS + __SWP_TYPE_SHIFT) +#define __SWP_OFFSET_SHIFT 4 +#define __SWP_OFFSET_BITS 50 #define __SWP_OFFSET_MASK ((1UL << __SWP_OFFSET_BITS) - 1) #define __swp_type(x) (((x).val >> __SWP_TYPE_SHIFT) & __SWP_TYPE_MASK) #define __swp_offset(x) (((x).val >> __SWP_OFFSET_SHIFT) & __SWP_OFFSET_MASK) -#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << __SWP_TYPE_SHIFT) | ((offset) << __SWP_OFFSET_SHIFT) }) +#define __swp_entry(type, offset) ((swp_entry_t) { ((unsigned long)(type) << __SWP_TYPE_SHIFT) | \ + ((unsigned long)(offset) << __SWP_OFFSET_SHIFT) }) #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) #define __swp_entry_to_pte(swp) ((pte_t) { (swp).val }) -- 2.25.1
WARNING: multiple messages have this Message-ID (diff)
From: Ryan Roberts <ryan.roberts@arm.com> To: Catalin Marinas <catalin.marinas@arm.com>, Will Deacon <will@kernel.org>, Joey Gouly <joey.gouly@arm.com>, Ard Biesheuvel <ardb@kernel.org>, Mark Rutland <mark.rutland@arm.com>, Anshuman Khandual <anshuman.khandual@arm.com>, David Hildenbrand <david@redhat.com>, Peter Xu <peterx@redhat.com>, Mike Rapoport <rppt@linux.ibm.com>, Shivansh Vij <shivanshvij@outlook.com> Cc: Ryan Roberts <ryan.roberts@arm.com>, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH v1 1/2] arm64/mm: Move PTE_PROT_NONE and PMD_PRESENT_INVALID Date: Wed, 24 Apr 2024 12:10:16 +0100 [thread overview] Message-ID: <20240424111017.3160195-2-ryan.roberts@arm.com> (raw) In-Reply-To: <20240424111017.3160195-1-ryan.roberts@arm.com> Previously PTE_PROT_NONE was occupying bit 58, one of the bits reserved for SW use when the PTE is valid. This is a waste of those precious SW bits since PTE_PROT_NONE can only ever be set when valid is clear. Instead let's overlay it on what would be a HW bit if valid was set. We need to be careful about which HW bit to choose since some of them must be preserved; when pte_present() is true (as it is for a PTE_PROT_NONE pte), it is legitimate for the core to call various accessors, e.g. pte_dirty(), pte_write() etc. There are also some accessors that are private to the arch which must continue to be honoured, e.g. pte_user(), pte_user_exec() etc. So we choose to overlay PTE_UXN; This effectively means that whenever a pte has PTE_PROT_NONE set, it will always report pte_user_exec() == false, which is obviously always correct. As a result of this change, we must shuffle the layout of the arch-specific swap pte so that PTE_PROT_NONE is always zero and not overlapping with any other field. As a result of this, there is no way to keep the `type` field contiguous without conflicting with PMD_PRESENT_INVALID (bit 59), which must also be 0 for a swap pte. So let's move PMD_PRESENT_INVALID to bit 60. In the end, this frees up bit 58 for future use as a proper SW bit (e.g. soft-dirty or uffd-wp). Signed-off-by: Ryan Roberts <ryan.roberts@arm.com> --- arch/arm64/include/asm/pgtable-prot.h | 4 ++-- arch/arm64/include/asm/pgtable.h | 16 +++++++++------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h index dd9ee67d1d87..ef952d69fd04 100644 --- a/arch/arm64/include/asm/pgtable-prot.h +++ b/arch/arm64/include/asm/pgtable-prot.h @@ -18,14 +18,14 @@ #define PTE_DIRTY (_AT(pteval_t, 1) << 55) #define PTE_SPECIAL (_AT(pteval_t, 1) << 56) #define PTE_DEVMAP (_AT(pteval_t, 1) << 57) -#define PTE_PROT_NONE (_AT(pteval_t, 1) << 58) /* only when !PTE_VALID */ +#define PTE_PROT_NONE (PTE_UXN) /* Reuse PTE_UXN; only when !PTE_VALID */ /* * This bit indicates that the entry is present i.e. pmd_page() * still points to a valid huge page in memory even if the pmd * has been invalidated. */ -#define PMD_PRESENT_INVALID (_AT(pteval_t, 1) << 59) /* only when !PMD_SECT_VALID */ +#define PMD_PRESENT_INVALID (_AT(pteval_t, 1) << 60) /* only when !PMD_SECT_VALID */ #define _PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF | PTE_SHARED) #define _PROT_SECT_DEFAULT (PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S) diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index afdd56d26ad7..23aabff4fa6f 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -1248,20 +1248,22 @@ static inline pmd_t pmdp_establish(struct vm_area_struct *vma, * Encode and decode a swap entry: * bits 0-1: present (must be zero) * bits 2: remember PG_anon_exclusive - * bits 3-7: swap type - * bits 8-57: swap offset - * bit 58: PTE_PROT_NONE (must be zero) + * bits 4-53: swap offset + * bit 54: PTE_PROT_NONE (overlays PTE_UXN) (must be zero) + * bits 55-59: swap type + * bit 60: PMD_PRESENT_INVALID (must be zero) */ -#define __SWP_TYPE_SHIFT 3 +#define __SWP_TYPE_SHIFT 55 #define __SWP_TYPE_BITS 5 -#define __SWP_OFFSET_BITS 50 #define __SWP_TYPE_MASK ((1 << __SWP_TYPE_BITS) - 1) -#define __SWP_OFFSET_SHIFT (__SWP_TYPE_BITS + __SWP_TYPE_SHIFT) +#define __SWP_OFFSET_SHIFT 4 +#define __SWP_OFFSET_BITS 50 #define __SWP_OFFSET_MASK ((1UL << __SWP_OFFSET_BITS) - 1) #define __swp_type(x) (((x).val >> __SWP_TYPE_SHIFT) & __SWP_TYPE_MASK) #define __swp_offset(x) (((x).val >> __SWP_OFFSET_SHIFT) & __SWP_OFFSET_MASK) -#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << __SWP_TYPE_SHIFT) | ((offset) << __SWP_OFFSET_SHIFT) }) +#define __swp_entry(type, offset) ((swp_entry_t) { ((unsigned long)(type) << __SWP_TYPE_SHIFT) | \ + ((unsigned long)(offset) << __SWP_OFFSET_SHIFT) }) #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) #define __swp_entry_to_pte(swp) ((pte_t) { (swp).val }) -- 2.25.1 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2024-04-24 11:10 UTC|newest] Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top 2024-04-24 11:10 [PATCH v1 0/2] arm64/mm: Enable userfaultfd write-protect Ryan Roberts 2024-04-24 11:10 ` Ryan Roberts 2024-04-24 11:10 ` Ryan Roberts [this message] 2024-04-24 11:10 ` [PATCH v1 1/2] arm64/mm: Move PTE_PROT_NONE and PMD_PRESENT_INVALID Ryan Roberts 2024-04-24 16:43 ` Catalin Marinas 2024-04-24 16:43 ` Catalin Marinas 2024-04-25 8:40 ` Ryan Roberts 2024-04-25 8:40 ` Ryan Roberts 2024-04-25 9:16 ` David Hildenbrand 2024-04-25 9:16 ` David Hildenbrand 2024-04-25 10:29 ` Ryan Roberts 2024-04-25 10:29 ` Ryan Roberts 2024-04-25 10:37 ` Ryan Roberts 2024-04-25 10:37 ` Ryan Roberts 2024-04-26 14:48 ` Catalin Marinas 2024-04-26 14:48 ` Catalin Marinas 2024-04-29 10:04 ` Ryan Roberts 2024-04-29 10:04 ` Ryan Roberts 2024-04-29 12:38 ` Catalin Marinas 2024-04-29 12:38 ` Catalin Marinas 2024-04-29 13:01 ` Ryan Roberts 2024-04-29 13:01 ` Ryan Roberts 2024-04-29 13:23 ` Ryan Roberts 2024-04-29 13:23 ` Ryan Roberts 2024-04-29 14:18 ` Catalin Marinas 2024-04-29 14:18 ` Catalin Marinas 2024-04-29 15:04 ` Ryan Roberts 2024-04-29 15:04 ` Ryan Roberts 2024-04-24 11:10 ` [PATCH v1 2/2] arm64/mm: Add uffd write-protect support Ryan Roberts 2024-04-24 11:10 ` Ryan Roberts 2024-04-24 11:57 ` Peter Xu 2024-04-24 11:57 ` Peter Xu 2024-04-24 12:51 ` Ryan Roberts 2024-04-24 12:51 ` Ryan Roberts 2024-04-26 13:17 ` Ryan Roberts 2024-04-26 13:17 ` Ryan Roberts 2024-04-26 13:54 ` Peter Xu 2024-04-26 13:54 ` Peter Xu 2024-04-29 9:39 ` Ryan Roberts 2024-04-29 9:39 ` Ryan Roberts 2024-04-24 16:46 ` Catalin Marinas 2024-04-24 16:46 ` Catalin Marinas
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20240424111017.3160195-2-ryan.roberts@arm.com \ --to=ryan.roberts@arm.com \ --cc=anshuman.khandual@arm.com \ --cc=ardb@kernel.org \ --cc=catalin.marinas@arm.com \ --cc=david@redhat.com \ --cc=joey.gouly@arm.com \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-kernel@vger.kernel.org \ --cc=mark.rutland@arm.com \ --cc=peterx@redhat.com \ --cc=rppt@linux.ibm.com \ --cc=shivanshvij@outlook.com \ --cc=will@kernel.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.