Skip to content

Commit abc1712

Browse files
committed
Merge branch 'for-next/feat_s1pie' into for-next/core
* for-next/feat_s1pie: : Support for the Armv8.9 Permission Indirection Extensions (stage 1 only) KVM: selftests: get-reg-list: add Permission Indirection registers KVM: selftests: get-reg-list: support ID register features arm64: Document boot requirements for PIE arm64: transfer permission indirection settings to EL2 arm64: enable Permission Indirection Extension (PIE) arm64: add encodings of PIRx_ELx registers arm64: disable EL2 traps for PIE arm64: reorganise PAGE_/PROT_ macros arm64: add PTE_WRITE to PROT_SECT_NORMAL arm64: add PTE_UXN/PTE_WRITE to SWAPPER_*_FLAGS KVM: arm64: expose ID_AA64MMFR3_EL1 to guests KVM: arm64: Save/restore PIE registers KVM: arm64: Save/restore TCR2_EL1 arm64: cpufeature: add Permission Indirection Extension cpucap arm64: cpufeature: add TCR2 cpucap arm64: cpufeature: add system register ID_AA64MMFR3 arm64/sysreg: add PIR*_ELx registers arm64/sysreg: update HCRX_EL2 register arm64/sysreg: add system registers TCR2_ELx arm64/sysreg: Add ID register ID_AA64MMFR3
2 parents f42039d + 5f0419a commit abc1712

File tree

19 files changed

+467
-44
lines changed

19 files changed

+467
-44
lines changed

Documentation/arm64/booting.rst

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,32 @@ Before jumping into the kernel, the following conditions must be met:
385385

386386
- HCRX_EL2.MSCEn (bit 11) must be initialised to 0b1.
387387

388+
For CPUs with the Extended Translation Control Register feature (FEAT_TCR2):
389+
390+
- If EL3 is present:
391+
392+
- SCR_EL3.TCR2En (bit 43) must be initialised to 0b1.
393+
394+
- If the kernel is entered at EL1 and EL2 is present:
395+
396+
- HCRX_EL2.TCR2En (bit 14) must be initialised to 0b1.
397+
398+
For CPUs with the Stage 1 Permission Indirection Extension feature (FEAT_S1PIE):
399+
400+
- If EL3 is present:
401+
402+
- SCR_EL3.PIEn (bit 45) must be initialised to 0b1.
403+
404+
- If the kernel is entered at EL1 and EL2 is present:
405+
406+
- HFGRTR_EL2.nPIR_EL1 (bit 58) must be initialised to 0b1.
407+
408+
- HFGWTR_EL2.nPIR_EL1 (bit 58) must be initialised to 0b1.
409+
410+
- HFGRTR_EL2.nPIRE0_EL1 (bit 57) must be initialised to 0b1.
411+
412+
- HFGRWR_EL2.nPIRE0_EL1 (bit 57) must be initialised to 0b1.
413+
388414
The requirements described above for CPU mode, caches, MMUs, architected
389415
timers, coherency and system registers apply to all CPUs. All CPUs must
390416
enter the kernel in the same exception level. Where the values documented

arch/arm64/include/asm/cpu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ struct cpuinfo_arm64 {
5656
u64 reg_id_aa64mmfr0;
5757
u64 reg_id_aa64mmfr1;
5858
u64 reg_id_aa64mmfr2;
59+
u64 reg_id_aa64mmfr3;
5960
u64 reg_id_aa64pfr0;
6061
u64 reg_id_aa64pfr1;
6162
u64 reg_id_aa64zfr0;

arch/arm64/include/asm/el2_setup.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,12 +159,21 @@
159159
mov x0, xzr
160160
mrs x1, id_aa64pfr1_el1
161161
ubfx x1, x1, #ID_AA64PFR1_EL1_SME_SHIFT, #4
162-
cbz x1, .Lset_fgt_\@
162+
cbz x1, .Lset_pie_fgt_\@
163163

164164
/* Disable nVHE traps of TPIDR2 and SMPRI */
165165
orr x0, x0, #HFGxTR_EL2_nSMPRI_EL1_MASK
166166
orr x0, x0, #HFGxTR_EL2_nTPIDR2_EL0_MASK
167167

168+
.Lset_pie_fgt_\@:
169+
mrs_s x1, SYS_ID_AA64MMFR3_EL1
170+
ubfx x1, x1, #ID_AA64MMFR3_EL1_S1PIE_SHIFT, #4
171+
cbz x1, .Lset_fgt_\@
172+
173+
/* Disable trapping of PIR_EL1 / PIRE0_EL1 */
174+
orr x0, x0, #HFGxTR_EL2_nPIR_EL1
175+
orr x0, x0, #HFGxTR_EL2_nPIRE0_EL1
176+
168177
.Lset_fgt_\@:
169178
msr_s SYS_HFGRTR_EL2, x0
170179
msr_s SYS_HFGWTR_EL2, x0

arch/arm64/include/asm/kernel-pgtable.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,14 +107,14 @@
107107
/*
108108
* Initial memory map attributes.
109109
*/
110-
#define SWAPPER_PTE_FLAGS (PTE_TYPE_PAGE | PTE_AF | PTE_SHARED)
111-
#define SWAPPER_PMD_FLAGS (PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S)
110+
#define SWAPPER_PTE_FLAGS (PTE_TYPE_PAGE | PTE_AF | PTE_SHARED | PTE_UXN)
111+
#define SWAPPER_PMD_FLAGS (PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S | PTE_UXN)
112112

113113
#ifdef CONFIG_ARM64_4K_PAGES
114-
#define SWAPPER_RW_MMUFLAGS (PMD_ATTRINDX(MT_NORMAL) | SWAPPER_PMD_FLAGS)
114+
#define SWAPPER_RW_MMUFLAGS (PMD_ATTRINDX(MT_NORMAL) | SWAPPER_PMD_FLAGS | PTE_WRITE)
115115
#define SWAPPER_RX_MMUFLAGS (SWAPPER_RW_MMUFLAGS | PMD_SECT_RDONLY)
116116
#else
117-
#define SWAPPER_RW_MMUFLAGS (PTE_ATTRINDX(MT_NORMAL) | SWAPPER_PTE_FLAGS)
117+
#define SWAPPER_RW_MMUFLAGS (PTE_ATTRINDX(MT_NORMAL) | SWAPPER_PTE_FLAGS | PTE_WRITE)
118118
#define SWAPPER_RX_MMUFLAGS (SWAPPER_RW_MMUFLAGS | PTE_RDONLY)
119119
#endif
120120

arch/arm64/include/asm/kvm_arm.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,8 @@
9393
#define HCR_HOST_NVHE_PROTECTED_FLAGS (HCR_HOST_NVHE_FLAGS | HCR_TSC)
9494
#define HCR_HOST_VHE_FLAGS (HCR_RW | HCR_TGE | HCR_E2H)
9595

96-
#define HCRX_GUEST_FLAGS (HCRX_EL2_SMPME)
97-
#define HCRX_HOST_FLAGS (HCRX_EL2_MSCEn)
96+
#define HCRX_GUEST_FLAGS (HCRX_EL2_SMPME | HCRX_EL2_TCR2En)
97+
#define HCRX_HOST_FLAGS (HCRX_EL2_MSCEn | HCRX_EL2_TCR2En)
9898

9999
/* TCR_EL2 Registers bits */
100100
#define TCR_EL2_RES1 ((1U << 31) | (1 << 23))

arch/arm64/include/asm/kvm_host.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,7 @@ enum vcpu_sysreg {
279279
TTBR0_EL1, /* Translation Table Base Register 0 */
280280
TTBR1_EL1, /* Translation Table Base Register 1 */
281281
TCR_EL1, /* Translation Control Register */
282+
TCR2_EL1, /* Extended Translation Control Register */
282283
ESR_EL1, /* Exception Syndrome Register */
283284
AFSR0_EL1, /* Auxiliary Fault Status Register 0 */
284285
AFSR1_EL1, /* Auxiliary Fault Status Register 1 */
@@ -339,6 +340,10 @@ enum vcpu_sysreg {
339340
TFSR_EL1, /* Tag Fault Status Register (EL1) */
340341
TFSRE0_EL1, /* Tag Fault Status Register (EL0) */
341342

343+
/* Permission Indirection Extension registers */
344+
PIR_EL1, /* Permission Indirection Register 1 (EL1) */
345+
PIRE0_EL1, /* Permission Indirection Register 0 (EL1) */
346+
342347
/* 32bit specific registers. */
343348
DACR32_EL2, /* Domain Access Control Register */
344349
IFSR32_EL2, /* Instruction Fault Status Register */

arch/arm64/include/asm/pgtable-hwdef.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,14 @@
170170
#define PTE_ATTRINDX(t) (_AT(pteval_t, (t)) << 2)
171171
#define PTE_ATTRINDX_MASK (_AT(pteval_t, 7) << 2)
172172

173+
/*
174+
* PIIndex[3:0] encoding (Permission Indirection Extension)
175+
*/
176+
#define PTE_PI_IDX_0 6 /* AP[1], USER */
177+
#define PTE_PI_IDX_1 51 /* DBM */
178+
#define PTE_PI_IDX_2 53 /* PXN */
179+
#define PTE_PI_IDX_3 54 /* UXN */
180+
173181
/*
174182
* Memory Attribute override for Stage-2 (MemAttr[3:0])
175183
*/

arch/arm64/include/asm/pgtable-prot.h

Lines changed: 94 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,47 @@
2727
*/
2828
#define PMD_PRESENT_INVALID (_AT(pteval_t, 1) << 59) /* only when !PMD_SECT_VALID */
2929

30+
#define _PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF | PTE_SHARED)
31+
#define _PROT_SECT_DEFAULT (PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S)
32+
33+
#define PROT_DEFAULT (_PROT_DEFAULT | PTE_MAYBE_NG)
34+
#define PROT_SECT_DEFAULT (_PROT_SECT_DEFAULT | PMD_MAYBE_NG)
35+
36+
#define PROT_DEVICE_nGnRnE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_DEVICE_nGnRnE))
37+
#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_DEVICE_nGnRE))
38+
#define PROT_NORMAL_NC (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_NC))
39+
#define PROT_NORMAL (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL))
40+
#define PROT_NORMAL_TAGGED (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_TAGGED))
41+
42+
#define PROT_SECT_DEVICE_nGnRE (PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_DEVICE_nGnRE))
43+
#define PROT_SECT_NORMAL (PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PTE_WRITE | PMD_ATTRINDX(MT_NORMAL))
44+
#define PROT_SECT_NORMAL_EXEC (PROT_SECT_DEFAULT | PMD_SECT_UXN | PMD_ATTRINDX(MT_NORMAL))
45+
46+
#define _PAGE_DEFAULT (_PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL))
47+
48+
#define _PAGE_KERNEL (PROT_NORMAL)
49+
#define _PAGE_KERNEL_RO ((PROT_NORMAL & ~PTE_WRITE) | PTE_RDONLY)
50+
#define _PAGE_KERNEL_ROX ((PROT_NORMAL & ~(PTE_WRITE | PTE_PXN)) | PTE_RDONLY)
51+
#define _PAGE_KERNEL_EXEC (PROT_NORMAL & ~PTE_PXN)
52+
#define _PAGE_KERNEL_EXEC_CONT ((PROT_NORMAL & ~PTE_PXN) | PTE_CONT)
53+
54+
#define _PAGE_SHARED (_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE)
55+
#define _PAGE_SHARED_EXEC (_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_WRITE)
56+
#define _PAGE_READONLY (_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN)
57+
#define _PAGE_READONLY_EXEC (_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN)
58+
#define _PAGE_EXECONLY (_PAGE_DEFAULT | PTE_RDONLY | PTE_NG | PTE_PXN)
59+
60+
#ifdef __ASSEMBLY__
61+
#define PTE_MAYBE_NG 0
62+
#endif
63+
3064
#ifndef __ASSEMBLY__
3165

3266
#include <asm/cpufeature.h>
3367
#include <asm/pgtable-types.h>
3468

3569
extern bool arm64_use_ng_mappings;
3670

37-
#define _PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF | PTE_SHARED)
38-
#define _PROT_SECT_DEFAULT (PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S)
39-
4071
#define PTE_MAYBE_NG (arm64_use_ng_mappings ? PTE_NG : 0)
4172
#define PMD_MAYBE_NG (arm64_use_ng_mappings ? PMD_SECT_NG : 0)
4273

@@ -50,26 +81,11 @@ extern bool arm64_use_ng_mappings;
5081
#define PTE_MAYBE_GP 0
5182
#endif
5283

53-
#define PROT_DEFAULT (_PROT_DEFAULT | PTE_MAYBE_NG)
54-
#define PROT_SECT_DEFAULT (_PROT_SECT_DEFAULT | PMD_MAYBE_NG)
55-
56-
#define PROT_DEVICE_nGnRnE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_DEVICE_nGnRnE))
57-
#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_DEVICE_nGnRE))
58-
#define PROT_NORMAL_NC (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_NC))
59-
#define PROT_NORMAL (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL))
60-
#define PROT_NORMAL_TAGGED (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_TAGGED))
61-
62-
#define PROT_SECT_DEVICE_nGnRE (PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_DEVICE_nGnRE))
63-
#define PROT_SECT_NORMAL (PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_NORMAL))
64-
#define PROT_SECT_NORMAL_EXEC (PROT_SECT_DEFAULT | PMD_SECT_UXN | PMD_ATTRINDX(MT_NORMAL))
65-
66-
#define _PAGE_DEFAULT (_PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL))
67-
68-
#define PAGE_KERNEL __pgprot(PROT_NORMAL)
69-
#define PAGE_KERNEL_RO __pgprot((PROT_NORMAL & ~PTE_WRITE) | PTE_RDONLY)
70-
#define PAGE_KERNEL_ROX __pgprot((PROT_NORMAL & ~(PTE_WRITE | PTE_PXN)) | PTE_RDONLY)
71-
#define PAGE_KERNEL_EXEC __pgprot(PROT_NORMAL & ~PTE_PXN)
72-
#define PAGE_KERNEL_EXEC_CONT __pgprot((PROT_NORMAL & ~PTE_PXN) | PTE_CONT)
84+
#define PAGE_KERNEL __pgprot(_PAGE_KERNEL)
85+
#define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL_RO)
86+
#define PAGE_KERNEL_ROX __pgprot(_PAGE_KERNEL_ROX)
87+
#define PAGE_KERNEL_EXEC __pgprot(_PAGE_KERNEL_EXEC)
88+
#define PAGE_KERNEL_EXEC_CONT __pgprot(_PAGE_KERNEL_EXEC_CONT)
7389

7490
#define PAGE_S2_MEMATTR(attr, has_fwb) \
7591
({ \
@@ -83,12 +99,62 @@ extern bool arm64_use_ng_mappings;
8399

84100
#define PAGE_NONE __pgprot(((_PAGE_DEFAULT) & ~PTE_VALID) | PTE_PROT_NONE | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN)
85101
/* shared+writable pages are clean by default, hence PTE_RDONLY|PTE_WRITE */
86-
#define PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE)
87-
#define PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_WRITE)
88-
#define PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN)
89-
#define PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN)
90-
#define PAGE_EXECONLY __pgprot(_PAGE_DEFAULT | PTE_RDONLY | PTE_NG | PTE_PXN)
102+
#define PAGE_SHARED __pgprot(_PAGE_SHARED)
103+
#define PAGE_SHARED_EXEC __pgprot(_PAGE_SHARED_EXEC)
104+
#define PAGE_READONLY __pgprot(_PAGE_READONLY)
105+
#define PAGE_READONLY_EXEC __pgprot(_PAGE_READONLY_EXEC)
106+
#define PAGE_EXECONLY __pgprot(_PAGE_EXECONLY)
91107

92108
#endif /* __ASSEMBLY__ */
93109

110+
#define pte_pi_index(pte) ( \
111+
((pte & BIT(PTE_PI_IDX_3)) >> (PTE_PI_IDX_3 - 3)) | \
112+
((pte & BIT(PTE_PI_IDX_2)) >> (PTE_PI_IDX_2 - 2)) | \
113+
((pte & BIT(PTE_PI_IDX_1)) >> (PTE_PI_IDX_1 - 1)) | \
114+
((pte & BIT(PTE_PI_IDX_0)) >> (PTE_PI_IDX_0 - 0)))
115+
116+
/*
117+
* Page types used via Permission Indirection Extension (PIE). PIE uses
118+
* the USER, DBM, PXN and UXN bits to to generate an index which is used
119+
* to look up the actual permission in PIR_ELx and PIRE0_EL1. We define
120+
* combinations we use on non-PIE systems with the same encoding, for
121+
* convenience these are listed here as comments as are the unallocated
122+
* encodings.
123+
*/
124+
125+
/* 0: PAGE_DEFAULT */
126+
/* 1: PTE_USER */
127+
/* 2: PTE_WRITE */
128+
/* 3: PTE_WRITE | PTE_USER */
129+
/* 4: PAGE_EXECONLY PTE_PXN */
130+
/* 5: PAGE_READONLY_EXEC PTE_PXN | PTE_USER */
131+
/* 6: PTE_PXN | PTE_WRITE */
132+
/* 7: PAGE_SHARED_EXEC PTE_PXN | PTE_WRITE | PTE_USER */
133+
/* 8: PAGE_KERNEL_ROX PTE_UXN */
134+
/* 9: PTE_UXN | PTE_USER */
135+
/* a: PAGE_KERNEL_EXEC PTE_UXN | PTE_WRITE */
136+
/* b: PTE_UXN | PTE_WRITE | PTE_USER */
137+
/* c: PAGE_KERNEL_RO PTE_UXN | PTE_PXN */
138+
/* d: PAGE_READONLY PTE_UXN | PTE_PXN | PTE_USER */
139+
/* e: PAGE_KERNEL PTE_UXN | PTE_PXN | PTE_WRITE */
140+
/* f: PAGE_SHARED PTE_UXN | PTE_PXN | PTE_WRITE | PTE_USER */
141+
142+
#define PIE_E0 ( \
143+
PIRx_ELx_PERM(pte_pi_index(_PAGE_EXECONLY), PIE_X_O) | \
144+
PIRx_ELx_PERM(pte_pi_index(_PAGE_READONLY_EXEC), PIE_RX) | \
145+
PIRx_ELx_PERM(pte_pi_index(_PAGE_SHARED_EXEC), PIE_RWX) | \
146+
PIRx_ELx_PERM(pte_pi_index(_PAGE_READONLY), PIE_R) | \
147+
PIRx_ELx_PERM(pte_pi_index(_PAGE_SHARED), PIE_RW))
148+
149+
#define PIE_E1 ( \
150+
PIRx_ELx_PERM(pte_pi_index(_PAGE_EXECONLY), PIE_NONE_O) | \
151+
PIRx_ELx_PERM(pte_pi_index(_PAGE_READONLY_EXEC), PIE_R) | \
152+
PIRx_ELx_PERM(pte_pi_index(_PAGE_SHARED_EXEC), PIE_RW) | \
153+
PIRx_ELx_PERM(pte_pi_index(_PAGE_READONLY), PIE_R) | \
154+
PIRx_ELx_PERM(pte_pi_index(_PAGE_SHARED), PIE_RW) | \
155+
PIRx_ELx_PERM(pte_pi_index(_PAGE_KERNEL_ROX), PIE_RX) | \
156+
PIRx_ELx_PERM(pte_pi_index(_PAGE_KERNEL_EXEC), PIE_RWX) | \
157+
PIRx_ELx_PERM(pte_pi_index(_PAGE_KERNEL_RO), PIE_R) | \
158+
PIRx_ELx_PERM(pte_pi_index(_PAGE_KERNEL), PIE_RW))
159+
94160
#endif /* __ASM_PGTABLE_PROT_H */

arch/arm64/include/asm/sysreg.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,25 @@
704704
#define ICH_VTR_TDS_SHIFT 19
705705
#define ICH_VTR_TDS_MASK (1 << ICH_VTR_TDS_SHIFT)
706706

707+
/*
708+
* Permission Indirection Extension (PIE) permission encodings.
709+
* Encodings with the _O suffix, have overlays applied (Permission Overlay Extension).
710+
*/
711+
#define PIE_NONE_O 0x0
712+
#define PIE_R_O 0x1
713+
#define PIE_X_O 0x2
714+
#define PIE_RX_O 0x3
715+
#define PIE_RW_O 0x5
716+
#define PIE_RWnX_O 0x6
717+
#define PIE_RWX_O 0x7
718+
#define PIE_R 0x8
719+
#define PIE_GCS 0x9
720+
#define PIE_RX 0xa
721+
#define PIE_RW 0xc
722+
#define PIE_RWX 0xe
723+
724+
#define PIRx_ELx_PERM(idx, perm) ((perm) << ((idx) * 4))
725+
707726
#define ARM64_FEATURE_FIELD_BITS 4
708727

709728
/* Defined for compatibility only, do not add new users. */

arch/arm64/kernel/cpufeature.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,12 @@ static const struct arm64_ftr_bits ftr_id_aa64mmfr2[] = {
398398
ARM64_FTR_END,
399399
};
400400

401+
static const struct arm64_ftr_bits ftr_id_aa64mmfr3[] = {
402+
ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR3_EL1_S1PIE_SHIFT, 4, 0),
403+
ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR3_EL1_TCRX_SHIFT, 4, 0),
404+
ARM64_FTR_END,
405+
};
406+
401407
static const struct arm64_ftr_bits ftr_ctr[] = {
402408
ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, 31, 1, 1), /* RES1 */
403409
ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, CTR_EL0_DIC_SHIFT, 1, 1),
@@ -724,6 +730,7 @@ static const struct __ftr_reg_entry {
724730
ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64MMFR1_EL1, ftr_id_aa64mmfr1,
725731
&id_aa64mmfr1_override),
726732
ARM64_FTR_REG(SYS_ID_AA64MMFR2_EL1, ftr_id_aa64mmfr2),
733+
ARM64_FTR_REG(SYS_ID_AA64MMFR3_EL1, ftr_id_aa64mmfr3),
727734

728735
/* Op1 = 0, CRn = 1, CRm = 2 */
729736
ARM64_FTR_REG(SYS_ZCR_EL1, ftr_zcr),
@@ -1019,6 +1026,7 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info)
10191026
init_cpu_ftr_reg(SYS_ID_AA64MMFR0_EL1, info->reg_id_aa64mmfr0);
10201027
init_cpu_ftr_reg(SYS_ID_AA64MMFR1_EL1, info->reg_id_aa64mmfr1);
10211028
init_cpu_ftr_reg(SYS_ID_AA64MMFR2_EL1, info->reg_id_aa64mmfr2);
1029+
init_cpu_ftr_reg(SYS_ID_AA64MMFR3_EL1, info->reg_id_aa64mmfr3);
10221030
init_cpu_ftr_reg(SYS_ID_AA64PFR0_EL1, info->reg_id_aa64pfr0);
10231031
init_cpu_ftr_reg(SYS_ID_AA64PFR1_EL1, info->reg_id_aa64pfr1);
10241032
init_cpu_ftr_reg(SYS_ID_AA64ZFR0_EL1, info->reg_id_aa64zfr0);
@@ -1264,6 +1272,8 @@ void update_cpu_features(int cpu,
12641272
info->reg_id_aa64mmfr1, boot->reg_id_aa64mmfr1);
12651273
taint |= check_update_ftr_reg(SYS_ID_AA64MMFR2_EL1, cpu,
12661274
info->reg_id_aa64mmfr2, boot->reg_id_aa64mmfr2);
1275+
taint |= check_update_ftr_reg(SYS_ID_AA64MMFR3_EL1, cpu,
1276+
info->reg_id_aa64mmfr3, boot->reg_id_aa64mmfr3);
12671277

12681278
taint |= check_update_ftr_reg(SYS_ID_AA64PFR0_EL1, cpu,
12691279
info->reg_id_aa64pfr0, boot->reg_id_aa64pfr0);
@@ -1393,6 +1403,7 @@ u64 __read_sysreg_by_encoding(u32 sys_id)
13931403
read_sysreg_case(SYS_ID_AA64MMFR0_EL1);
13941404
read_sysreg_case(SYS_ID_AA64MMFR1_EL1);
13951405
read_sysreg_case(SYS_ID_AA64MMFR2_EL1);
1406+
read_sysreg_case(SYS_ID_AA64MMFR3_EL1);
13961407
read_sysreg_case(SYS_ID_AA64ISAR0_EL1);
13971408
read_sysreg_case(SYS_ID_AA64ISAR1_EL1);
13981409
read_sysreg_case(SYS_ID_AA64ISAR2_EL1);
@@ -2659,6 +2670,19 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
26592670
.cpu_enable = cpu_enable_mops,
26602671
ARM64_CPUID_FIELDS(ID_AA64ISAR2_EL1, MOPS, IMP)
26612672
},
2673+
{
2674+
.capability = ARM64_HAS_TCR2,
2675+
.type = ARM64_CPUCAP_SYSTEM_FEATURE,
2676+
.matches = has_cpuid_feature,
2677+
ARM64_CPUID_FIELDS(ID_AA64MMFR3_EL1, TCRX, IMP)
2678+
},
2679+
{
2680+
.desc = "Stage-1 Permission Indirection Extension (S1PIE)",
2681+
.capability = ARM64_HAS_S1PIE,
2682+
.type = ARM64_CPUCAP_BOOT_CPU_FEATURE,
2683+
.matches = has_cpuid_feature,
2684+
ARM64_CPUID_FIELDS(ID_AA64MMFR3_EL1, S1PIE, IMP)
2685+
},
26622686
{},
26632687
};
26642688

0 commit comments

Comments
 (0)