arm64: Avoid #define'ing PTE_MAYBE_NG to 0x0 for asm use
authorArd Biesheuvel <ardb@kernel.org>
Wed, 14 Feb 2024 12:29:13 +0000 (13:29 +0100)
committerCatalin Marinas <catalin.marinas@arm.com>
Fri, 16 Feb 2024 12:42:37 +0000 (12:42 +0000)
The PROT_* macros resolve to expressions that are only valid in C and
not in assembler, and so they are only usable from C code. Currently, we
make an exception for the permission indirection init code in proc.S,
which doesn't care about the bits that are conditionally set, and so we
just #define PTE_MAYBE_NG to 0x0 for any assembler file that includes
these definitions.

This is dodgy because this means that PROT_NORMAL and friends is
generally available in asm code, but defined in a way that deviates from
the definition that C code will observe, which might lead to hard to
diagnose issues down the road.

So instead, #define PTE_MAYBE_NG only in the place where the PIE
constants are evaluated, and #undef it again right after. This allows us
to drop the #define from pgtable-prot.h, and avoid the risk of deviating
definitions between asm and C.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Link: https://lore.kernel.org/r/20240214122845.2033971-72-ardb+git@google.com
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
arch/arm64/include/asm/pgtable-prot.h
arch/arm64/mm/proc.S

index 483dbfa39c4c9cdec5c17df7ed01a62854cac075..63ced9ccec214936269795597433d04c6a2f0d84 100644 (file)
 #define _PAGE_READONLY_EXEC    (_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN)
 #define _PAGE_EXECONLY         (_PAGE_DEFAULT | PTE_RDONLY | PTE_NG | PTE_PXN)
 
-#ifdef __ASSEMBLY__
-#define PTE_MAYBE_NG   0
-#endif
-
 #ifndef __ASSEMBLY__
 
 #include <asm/cpufeature.h>
index d104ddab26a4124f414d4550b682f557da4678ca..6e1b2bc41a9fdf2e8c83e6b1d0c89ad9f3dc6cc6 100644 (file)
@@ -456,11 +456,24 @@ alternative_else_nop_endif
        ubfx    x1, x1, #ID_AA64MMFR3_EL1_S1PIE_SHIFT, #4
        cbz     x1, .Lskip_indirection
 
+       /*
+        * The PROT_* macros describing the various memory types may resolve to
+        * C expressions if they include the PTE_MAYBE_* macros, and so they
+        * can only be used from C code. The PIE_E* constants below are also
+        * defined in terms of those macros, but will mask out those
+        * PTE_MAYBE_* constants, whether they are set or not. So #define them
+        * as 0x0 here so we can evaluate the PIE_E* constants in asm context.
+        */
+
+#define PTE_MAYBE_NG           0
+
        mov_q   x0, PIE_E0
        msr     REG_PIRE0_EL1, x0
        mov_q   x0, PIE_E1
        msr     REG_PIR_EL1, x0
 
+#undef PTE_MAYBE_NG
+
        mov     x0, TCR2_EL1x_PIE
        msr     REG_TCR2_EL1, x0