Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

riscv: mm: add userfaultfd write-protect support

The Svrsw60t59b extension allows to free the PTE reserved bits 60 and 59
for software, this patch uses bit 60 for uffd-wp tracking

Additionally for tracking the uffd-wp state as a PTE swap bit, we borrow
bit 4 which is not involved into swap entry computation.

Link: https://lkml.kernel.org/r/20251113072806.795029-6-zhangchunyan@iscas.ac.cn
Signed-off-by: Chunyan Zhang <zhangchunyan@iscas.ac.cn>
Cc: Albert Ou <aou@eecs.berkeley.edu>
Cc: Alexandre Ghiti <alex@ghiti.fr>
Cc: Alexandre Ghiti <alexghiti@rivosinc.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Andrew Jones <ajones@ventanamicro.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Axel Rasmussen <axelrasmussen@google.com>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Conor Dooley <conor.dooley@microchip.com>
Cc: Conor Dooley <conor@kernel.org>
Cc: David Hildenbrand <david@redhat.com>
Cc: Deepak Gupta <debug@rivosinc.com>
Cc: Jan Kara <jack@suse.cz>
Cc: Liam Howlett <liam.howlett@oracle.com>
Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Palmer Dabbelt <palmer@dabbelt.com>
Cc: Paul Walmsley <paul.walmsley@sifive.com>
Cc: Peter Xu <peterx@redhat.com>
Cc: Rob Herring <robh@kernel.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Yuanchu Xie <yuanchu@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Chunyan Zhang and committed by
Andrew Morton
c64da395 2a3ebad4

+87
+1
arch/riscv/Kconfig
··· 148 148 select HAVE_ARCH_TRANSPARENT_HUGEPAGE if 64BIT && MMU 149 149 select HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD if 64BIT && MMU 150 150 select HAVE_ARCH_USERFAULTFD_MINOR if 64BIT && USERFAULTFD 151 + select HAVE_ARCH_USERFAULTFD_WP if 64BIT && MMU && USERFAULTFD && RISCV_ISA_SVRSW60T59B 151 152 select HAVE_ARCH_VMAP_STACK if MMU && 64BIT 152 153 select HAVE_ASM_MODVERSIONS 153 154 select HAVE_CONTEXT_TRACKING_USER
+18
arch/riscv/include/asm/pgtable-bits.h
··· 38 38 #define _PAGE_SWP_SOFT_DIRTY 0 39 39 #endif /* CONFIG_MEM_SOFT_DIRTY */ 40 40 41 + #ifdef CONFIG_HAVE_ARCH_USERFAULTFD_WP 42 + 43 + /* ext_svrsw60t59b: Bit(60) for uffd-wp tracking */ 44 + #define _PAGE_UFFD_WP \ 45 + ((riscv_has_extension_unlikely(RISCV_ISA_EXT_SVRSW60T59B)) ? \ 46 + (1UL << 60) : 0) 47 + /* 48 + * Bit 4 is not involved into swap entry computation, so we 49 + * can borrow it for swap page uffd-wp tracking. 50 + */ 51 + #define _PAGE_SWP_UFFD_WP \ 52 + ((riscv_has_extension_unlikely(RISCV_ISA_EXT_SVRSW60T59B)) ? \ 53 + _PAGE_USER : 0) 54 + #else 55 + #define _PAGE_UFFD_WP 0 56 + #define _PAGE_SWP_UFFD_WP 0 57 + #endif 58 + 41 59 #define _PAGE_TABLE _PAGE_PRESENT 42 60 43 61 /*
+68
arch/riscv/include/asm/pgtable.h
··· 417 417 return __pte(pte_val(pte) & ~(_PAGE_WRITE)); 418 418 } 419 419 420 + #ifdef CONFIG_HAVE_ARCH_USERFAULTFD_WP 421 + #define pgtable_supports_uffd_wp() \ 422 + riscv_has_extension_unlikely(RISCV_ISA_EXT_SVRSW60T59B) 423 + 424 + static inline bool pte_uffd_wp(pte_t pte) 425 + { 426 + return !!(pte_val(pte) & _PAGE_UFFD_WP); 427 + } 428 + 429 + static inline pte_t pte_mkuffd_wp(pte_t pte) 430 + { 431 + return pte_wrprotect(__pte(pte_val(pte) | _PAGE_UFFD_WP)); 432 + } 433 + 434 + static inline pte_t pte_clear_uffd_wp(pte_t pte) 435 + { 436 + return __pte(pte_val(pte) & ~(_PAGE_UFFD_WP)); 437 + } 438 + 439 + static inline bool pte_swp_uffd_wp(pte_t pte) 440 + { 441 + return !!(pte_val(pte) & _PAGE_SWP_UFFD_WP); 442 + } 443 + 444 + static inline pte_t pte_swp_mkuffd_wp(pte_t pte) 445 + { 446 + return __pte(pte_val(pte) | _PAGE_SWP_UFFD_WP); 447 + } 448 + 449 + static inline pte_t pte_swp_clear_uffd_wp(pte_t pte) 450 + { 451 + return __pte(pte_val(pte) & ~(_PAGE_SWP_UFFD_WP)); 452 + } 453 + #endif /* CONFIG_HAVE_ARCH_USERFAULTFD_WP */ 454 + 420 455 /* static inline pte_t pte_mkread(pte_t pte) */ 421 456 422 457 static inline pte_t pte_mkwrite_novma(pte_t pte) ··· 876 841 } 877 842 #endif 878 843 844 + #ifdef CONFIG_HAVE_ARCH_USERFAULTFD_WP 845 + static inline bool pmd_uffd_wp(pmd_t pmd) 846 + { 847 + return pte_uffd_wp(pmd_pte(pmd)); 848 + } 849 + 850 + static inline pmd_t pmd_mkuffd_wp(pmd_t pmd) 851 + { 852 + return pte_pmd(pte_mkuffd_wp(pmd_pte(pmd))); 853 + } 854 + 855 + static inline pmd_t pmd_clear_uffd_wp(pmd_t pmd) 856 + { 857 + return pte_pmd(pte_clear_uffd_wp(pmd_pte(pmd))); 858 + } 859 + 860 + static inline bool pmd_swp_uffd_wp(pmd_t pmd) 861 + { 862 + return pte_swp_uffd_wp(pmd_pte(pmd)); 863 + } 864 + 865 + static inline pmd_t pmd_swp_mkuffd_wp(pmd_t pmd) 866 + { 867 + return pte_pmd(pte_swp_mkuffd_wp(pmd_pte(pmd))); 868 + } 869 + 870 + static inline pmd_t pmd_swp_clear_uffd_wp(pmd_t pmd) 871 + { 872 + return pte_pmd(pte_swp_clear_uffd_wp(pmd_pte(pmd))); 873 + } 874 + #endif /* CONFIG_HAVE_ARCH_USERFAULTFD_WP */ 875 + 879 876 #ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY 880 877 static inline bool pmd_soft_dirty(pmd_t pmd) 881 878 { ··· 1142 1075 * bit 0: _PAGE_PRESENT (zero) 1143 1076 * bit 1 to 2: (zero) 1144 1077 * bit 3: _PAGE_SWP_SOFT_DIRTY 1078 + * bit 4: _PAGE_SWP_UFFD_WP 1145 1079 * bit 5: _PAGE_PROT_NONE (zero) 1146 1080 * bit 6: exclusive marker 1147 1081 * bits 7 to 11: swap type