[PATCH v1 16/18] arm64: add encodings of PIRx_ELx registers

Joey Gouly joey.gouly at arm.com
Thu Mar 9 06:52:44 PST 2023


The encodings used in the permission indirection registers means that the
values that Linux puts in the PTEs do not need to be changed.

The E0 values are replicated in E1, with the execute permissions removed.
This is needed as the futex operations access user mappings with privileged
loads/stores.

Signed-off-by: Joey Gouly <joey.gouly at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
---
 arch/arm64/include/asm/pgtable-hwdef.h |  8 ++++++++
 arch/arm64/include/asm/pgtable-prot.h  | 18 ++++++++++++++++++
 arch/arm64/include/asm/pgtable.h       |  6 ++++++
 3 files changed, 32 insertions(+)

diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
index f658aafc47df..11c81e700335 100644
--- a/arch/arm64/include/asm/pgtable-hwdef.h
+++ b/arch/arm64/include/asm/pgtable-hwdef.h
@@ -170,6 +170,14 @@
 #define PTE_ATTRINDX(t)		(_AT(pteval_t, (t)) << 2)
 #define PTE_ATTRINDX_MASK	(_AT(pteval_t, 7) << 2)
 
+/*
+ * PIIndex[3:0] encoding (Permission Indirection Extension)
+ */
+#define PTE_PI_IDX_0	6
+#define PTE_PI_IDX_1	51
+#define PTE_PI_IDX_2	53
+#define PTE_PI_IDX_3	54
+
 /*
  * Memory Attribute override for Stage-2 (MemAttr[3:0])
  */
diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h
index a45af0a22b25..2b192da1ef9d 100644
--- a/arch/arm64/include/asm/pgtable-prot.h
+++ b/arch/arm64/include/asm/pgtable-prot.h
@@ -107,4 +107,22 @@ extern bool arm64_use_ng_mappings;
 
 #endif /* __ASSEMBLY__ */
 
+#define PIE_E0	( \
+	PIRx_ELx_PERMIDX(PIE_X_O, pte_pi_index(_PAGE_EXECONLY))      | \
+	PIRx_ELx_PERMIDX(PIE_RX,  pte_pi_index(_PAGE_READONLY_EXEC)) | \
+	PIRx_ELx_PERMIDX(PIE_RWX, pte_pi_index(_PAGE_SHARED_EXEC))   | \
+	PIRx_ELx_PERMIDX(PIE_R,   pte_pi_index(_PAGE_READONLY))      | \
+	PIRx_ELx_PERMIDX(PIE_RW,  pte_pi_index(_PAGE_SHARED)))
+
+#define PIE_E1	( \
+	PIRx_ELx_PERMIDX(PIE_NONE_O, pte_pi_index(_PAGE_EXECONLY))      | \
+	PIRx_ELx_PERMIDX(PIE_R,      pte_pi_index(_PAGE_READONLY_EXEC)) | \
+	PIRx_ELx_PERMIDX(PIE_RW,     pte_pi_index(_PAGE_SHARED_EXEC))   | \
+	PIRx_ELx_PERMIDX(PIE_R,      pte_pi_index(_PAGE_READONLY))      | \
+	PIRx_ELx_PERMIDX(PIE_RW,     pte_pi_index(_PAGE_SHARED))        | \
+	PIRx_ELx_PERMIDX(PIE_RX,     pte_pi_index(_PAGE_KERNEL_ROX))    | \
+	PIRx_ELx_PERMIDX(PIE_RWX,    pte_pi_index(_PAGE_KERNEL_EXEC))   | \
+	PIRx_ELx_PERMIDX(PIE_R,      pte_pi_index(_PAGE_KERNEL_RO))     | \
+	PIRx_ELx_PERMIDX(PIE_RW,     pte_pi_index(_PAGE_KERNEL)))
+
 #endif /* __ASM_PGTABLE_PROT_H */
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index b6ba466e2e8a..b31d39f22803 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -26,6 +26,12 @@
 
 #define vmemmap			((struct page *)VMEMMAP_START - (memstart_addr >> PAGE_SHIFT))
 
+#define pte_pi_index(pte) ( \
+	((pte & BIT(PTE_PI_IDX_3)) >> (PTE_PI_IDX_3 - 3)) | \
+	((pte & BIT(PTE_PI_IDX_2)) >> (PTE_PI_IDX_2 - 2)) | \
+	((pte & BIT(PTE_PI_IDX_1)) >> (PTE_PI_IDX_1 - 1)) | \
+	((pte & BIT(PTE_PI_IDX_0)) >> (PTE_PI_IDX_0 - 0)))
+
 #ifndef __ASSEMBLY__
 
 #include <asm/cmpxchg.h>
-- 
2.17.1




More information about the linux-arm-kernel mailing list