Skip to content

Commit

Permalink
arm64: add encodings of PIRx_ELx registers
Browse files Browse the repository at this point in the history
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@arm.com>
Cc: Will Deacon <will@kernel.org>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Link: https://lore.kernel.org/r/20230606145859.697944-16-joey.gouly@arm.com
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
  • Loading branch information
Joey Gouly authored and Catalin Marinas committed Jun 6, 2023
1 parent 7df7170 commit eeda243
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 0 deletions.
8 changes: 8 additions & 0 deletions arch/arm64/include/asm/pgtable-hwdef.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 /* AP[1], USER */
#define PTE_PI_IDX_1 51 /* DBM */
#define PTE_PI_IDX_2 53 /* PXN */
#define PTE_PI_IDX_3 54 /* UXN */

/*
* Memory Attribute override for Stage-2 (MemAttr[3:0])
*/
Expand Down
50 changes: 50 additions & 0 deletions arch/arm64/include/asm/pgtable-prot.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,54 @@ extern bool arm64_use_ng_mappings;

#endif /* __ASSEMBLY__ */

#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)))

/*
* Page types used via Permission Indirection Extension (PIE). PIE uses
* the USER, DBM, PXN and UXN bits to to generate an index which is used
* to look up the actual permission in PIR_ELx and PIRE0_EL1. We define
* combinations we use on non-PIE systems with the same encoding, for
* convenience these are listed here as comments as are the unallocated
* encodings.
*/

/* 0: PAGE_DEFAULT */
/* 1: PTE_USER */
/* 2: PTE_WRITE */
/* 3: PTE_WRITE | PTE_USER */
/* 4: PAGE_EXECONLY PTE_PXN */
/* 5: PAGE_READONLY_EXEC PTE_PXN | PTE_USER */
/* 6: PTE_PXN | PTE_WRITE */
/* 7: PAGE_SHARED_EXEC PTE_PXN | PTE_WRITE | PTE_USER */
/* 8: PAGE_KERNEL_ROX PTE_UXN */
/* 9: PTE_UXN | PTE_USER */
/* a: PAGE_KERNEL_EXEC PTE_UXN | PTE_WRITE */
/* b: PTE_UXN | PTE_WRITE | PTE_USER */
/* c: PAGE_KERNEL_RO PTE_UXN | PTE_PXN */
/* d: PAGE_READONLY PTE_UXN | PTE_PXN | PTE_USER */
/* e: PAGE_KERNEL PTE_UXN | PTE_PXN | PTE_WRITE */
/* f: PAGE_SHARED PTE_UXN | PTE_PXN | PTE_WRITE | PTE_USER */

#define PIE_E0 ( \
PIRx_ELx_PERM(pte_pi_index(_PAGE_EXECONLY), PIE_X_O) | \
PIRx_ELx_PERM(pte_pi_index(_PAGE_READONLY_EXEC), PIE_RX) | \
PIRx_ELx_PERM(pte_pi_index(_PAGE_SHARED_EXEC), PIE_RWX) | \
PIRx_ELx_PERM(pte_pi_index(_PAGE_READONLY), PIE_R) | \
PIRx_ELx_PERM(pte_pi_index(_PAGE_SHARED), PIE_RW))

#define PIE_E1 ( \
PIRx_ELx_PERM(pte_pi_index(_PAGE_EXECONLY), PIE_NONE_O) | \
PIRx_ELx_PERM(pte_pi_index(_PAGE_READONLY_EXEC), PIE_R) | \
PIRx_ELx_PERM(pte_pi_index(_PAGE_SHARED_EXEC), PIE_RW) | \
PIRx_ELx_PERM(pte_pi_index(_PAGE_READONLY), PIE_R) | \
PIRx_ELx_PERM(pte_pi_index(_PAGE_SHARED), PIE_RW) | \
PIRx_ELx_PERM(pte_pi_index(_PAGE_KERNEL_ROX), PIE_RX) | \
PIRx_ELx_PERM(pte_pi_index(_PAGE_KERNEL_EXEC), PIE_RWX) | \
PIRx_ELx_PERM(pte_pi_index(_PAGE_KERNEL_RO), PIE_R) | \
PIRx_ELx_PERM(pte_pi_index(_PAGE_KERNEL), PIE_RW))

#endif /* __ASM_PGTABLE_PROT_H */

0 comments on commit eeda243

Please sign in to comment.