Commit 2f0584f3 authored by Rick Edgecombe's avatar Rick Edgecombe
Browse files

mm: Rename arch pte_mkwrite()'s to pte_mkwrite_novma()



The x86 Shadow stack feature includes a new type of memory called shadow
stack. This shadow stack memory has some unusual properties, which requires
some core mm changes to function properly.

One of these unusual properties is that shadow stack memory is writable,
but only in limited ways. These limits are applied via a specific PTE
bit combination. Nevertheless, the memory is writable, and core mm code
will need to apply the writable permissions in the typical paths that
call pte_mkwrite(). The goal is to make pte_mkwrite() take a VMA, so
that the x86 implementation of it can know whether to create regular
writable or shadow stack mappings.

But there are a couple of challenges to this. Modifying the signatures of
each arch pte_mkwrite() implementation would be error prone because some
are generated with macros and would need to be re-implemented. Also, some
pte_mkwrite() callers operate on kernel memory without a VMA.

So this can be done in a three step process. First pte_mkwrite() can be
renamed to pte_mkwrite_novma() in each arch, with a generic pte_mkwrite()
added that just calls pte_mkwrite_novma(). Next callers without a VMA can
be moved to pte_mkwrite_novma(). And lastly, pte_mkwrite() and all callers
can be changed to take/pass a VMA.

Start the process by renaming pte_mkwrite() to pte_mkwrite_novma() and
adding the pte_mkwrite() wrapper in linux/pgtable.h. Apply the same
pattern for pmd_mkwrite(). Since not all archs have a pmd_mkwrite_novma(),
create a new arch config HAS_HUGE_PAGE that can be used to tell if
pmd_mkwrite() should be defined. Otherwise in the !HAS_HUGE_PAGE cases the
compiler would not be able to find pmd_mkwrite_novma().

No functional change.

Suggested-by: default avatarLinus Torvalds <torvalds@linuxfoundation.org>
Signed-off-by: default avatarRick Edgecombe <rick.p.edgecombe@intel.com>
Signed-off-by: default avatarDave Hansen <dave.hansen@linux.intel.com>
Reviewed-by: default avatarMike Rapoport (IBM) <rppt@kernel.org>
Acked-by: default avatarGeert Uytterhoeven <geert@linux-m68k.org>
Acked-by: default avatarDavid Hildenbrand <david@redhat.com>
Link: https://lore.kernel.org/lkml/CAHk-=wiZjSu7c9sFYZb3q04108stgHff2wfbokGCCgW7riz+8Q@mail.gmail.com/
Link: https://lore.kernel.org/all/20230613001108.3040476-2-rick.p.edgecombe%40intel.com
parent 06c2afb8
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -48,6 +48,9 @@ PTE Page Table Helpers
+---------------------------+--------------------------------------------------+
| pte_mkwrite               | Creates a writable PTE                           |
+---------------------------+--------------------------------------------------+
| pte_mkwrite_novma         | Creates a writable PTE, of the conventional type |
|                           | of writable.                                     |
+---------------------------+--------------------------------------------------+
| pte_wrprotect             | Creates a write protected PTE                    |
+---------------------------+--------------------------------------------------+
| pte_mkspecial             | Creates a special PTE                            |
@@ -120,6 +123,9 @@ PMD Page Table Helpers
+---------------------------+--------------------------------------------------+
| pmd_mkwrite               | Creates a writable PMD                           |
+---------------------------+--------------------------------------------------+
| pmd_mkwrite_novma         | Creates a writable PMD, of the conventional type |
|                           | of writable.                                     |
+---------------------------+--------------------------------------------------+
| pmd_wrprotect             | Creates a write protected PMD                    |
+---------------------------+--------------------------------------------------+
| pmd_mkspecial             | Creates a special PMD                            |
+8 −0
Original line number Diff line number Diff line
@@ -939,6 +939,14 @@ config HAVE_ARCH_HUGE_VMALLOC
config ARCH_WANT_HUGE_PMD_SHARE
	bool

# Archs that want to use pmd_mkwrite on kernel memory need it defined even
# if there are no userspace memory management features that use it
config ARCH_WANT_KERNEL_PMD_MKWRITE
	bool

config ARCH_WANT_PMD_MKWRITE
	def_bool TRANSPARENT_HUGEPAGE || ARCH_WANT_KERNEL_PMD_MKWRITE

config HAVE_ARCH_SOFT_DIRTY
	bool

+1 −1
Original line number Diff line number Diff line
@@ -256,7 +256,7 @@ extern inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED;
extern inline pte_t pte_wrprotect(pte_t pte)	{ pte_val(pte) |= _PAGE_FOW; return pte; }
extern inline pte_t pte_mkclean(pte_t pte)	{ pte_val(pte) &= ~(__DIRTY_BITS); return pte; }
extern inline pte_t pte_mkold(pte_t pte)	{ pte_val(pte) &= ~(__ACCESS_BITS); return pte; }
extern inline pte_t pte_mkwrite(pte_t pte)	{ pte_val(pte) &= ~_PAGE_FOW; return pte; }
extern inline pte_t pte_mkwrite_novma(pte_t pte){ pte_val(pte) &= ~_PAGE_FOW; return pte; }
extern inline pte_t pte_mkdirty(pte_t pte)	{ pte_val(pte) |= __DIRTY_BITS; return pte; }
extern inline pte_t pte_mkyoung(pte_t pte)	{ pte_val(pte) |= __ACCESS_BITS; return pte; }

+1 −1
Original line number Diff line number Diff line
@@ -21,7 +21,7 @@ static inline pmd_t pte_pmd(pte_t pte)
}

#define pmd_wrprotect(pmd)	pte_pmd(pte_wrprotect(pmd_pte(pmd)))
#define pmd_mkwrite(pmd)	pte_pmd(pte_mkwrite(pmd_pte(pmd)))
#define pmd_mkwrite_novma(pmd)	pte_pmd(pte_mkwrite_novma(pmd_pte(pmd)))
#define pmd_mkdirty(pmd)	pte_pmd(pte_mkdirty(pmd_pte(pmd)))
#define pmd_mkold(pmd)		pte_pmd(pte_mkold(pmd_pte(pmd)))
#define pmd_mkyoung(pmd)	pte_pmd(pte_mkyoung(pmd_pte(pmd)))
+1 −1
Original line number Diff line number Diff line
@@ -87,7 +87,7 @@

PTE_BIT_FUNC(mknotpresent,     &= ~(_PAGE_PRESENT));
PTE_BIT_FUNC(wrprotect,	&= ~(_PAGE_WRITE));
PTE_BIT_FUNC(mkwrite,	|= (_PAGE_WRITE));
PTE_BIT_FUNC(mkwrite_novma,	|= (_PAGE_WRITE));
PTE_BIT_FUNC(mkclean,	&= ~(_PAGE_DIRTY));
PTE_BIT_FUNC(mkdirty,	|= (_PAGE_DIRTY));
PTE_BIT_FUNC(mkold,	&= ~(_PAGE_ACCESSED));
Loading