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
This commit is contained in:
commit
abc17128c8
@ -385,6 +385,32 @@ Before jumping into the kernel, the following conditions must be met:
|
||||
|
||||
- HCRX_EL2.MSCEn (bit 11) must be initialised to 0b1.
|
||||
|
||||
For CPUs with the Extended Translation Control Register feature (FEAT_TCR2):
|
||||
|
||||
- If EL3 is present:
|
||||
|
||||
- SCR_EL3.TCR2En (bit 43) must be initialised to 0b1.
|
||||
|
||||
- If the kernel is entered at EL1 and EL2 is present:
|
||||
|
||||
- HCRX_EL2.TCR2En (bit 14) must be initialised to 0b1.
|
||||
|
||||
For CPUs with the Stage 1 Permission Indirection Extension feature (FEAT_S1PIE):
|
||||
|
||||
- If EL3 is present:
|
||||
|
||||
- SCR_EL3.PIEn (bit 45) must be initialised to 0b1.
|
||||
|
||||
- If the kernel is entered at EL1 and EL2 is present:
|
||||
|
||||
- HFGRTR_EL2.nPIR_EL1 (bit 58) must be initialised to 0b1.
|
||||
|
||||
- HFGWTR_EL2.nPIR_EL1 (bit 58) must be initialised to 0b1.
|
||||
|
||||
- HFGRTR_EL2.nPIRE0_EL1 (bit 57) must be initialised to 0b1.
|
||||
|
||||
- HFGRWR_EL2.nPIRE0_EL1 (bit 57) must be initialised to 0b1.
|
||||
|
||||
The requirements described above for CPU mode, caches, MMUs, architected
|
||||
timers, coherency and system registers apply to all CPUs. All CPUs must
|
||||
enter the kernel in the same exception level. Where the values documented
|
||||
|
@ -56,6 +56,7 @@ struct cpuinfo_arm64 {
|
||||
u64 reg_id_aa64mmfr0;
|
||||
u64 reg_id_aa64mmfr1;
|
||||
u64 reg_id_aa64mmfr2;
|
||||
u64 reg_id_aa64mmfr3;
|
||||
u64 reg_id_aa64pfr0;
|
||||
u64 reg_id_aa64pfr1;
|
||||
u64 reg_id_aa64zfr0;
|
||||
|
@ -159,12 +159,21 @@
|
||||
mov x0, xzr
|
||||
mrs x1, id_aa64pfr1_el1
|
||||
ubfx x1, x1, #ID_AA64PFR1_EL1_SME_SHIFT, #4
|
||||
cbz x1, .Lset_fgt_\@
|
||||
cbz x1, .Lset_pie_fgt_\@
|
||||
|
||||
/* Disable nVHE traps of TPIDR2 and SMPRI */
|
||||
orr x0, x0, #HFGxTR_EL2_nSMPRI_EL1_MASK
|
||||
orr x0, x0, #HFGxTR_EL2_nTPIDR2_EL0_MASK
|
||||
|
||||
.Lset_pie_fgt_\@:
|
||||
mrs_s x1, SYS_ID_AA64MMFR3_EL1
|
||||
ubfx x1, x1, #ID_AA64MMFR3_EL1_S1PIE_SHIFT, #4
|
||||
cbz x1, .Lset_fgt_\@
|
||||
|
||||
/* Disable trapping of PIR_EL1 / PIRE0_EL1 */
|
||||
orr x0, x0, #HFGxTR_EL2_nPIR_EL1
|
||||
orr x0, x0, #HFGxTR_EL2_nPIRE0_EL1
|
||||
|
||||
.Lset_fgt_\@:
|
||||
msr_s SYS_HFGRTR_EL2, x0
|
||||
msr_s SYS_HFGWTR_EL2, x0
|
||||
|
@ -107,14 +107,14 @@
|
||||
/*
|
||||
* Initial memory map attributes.
|
||||
*/
|
||||
#define SWAPPER_PTE_FLAGS (PTE_TYPE_PAGE | PTE_AF | PTE_SHARED)
|
||||
#define SWAPPER_PMD_FLAGS (PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S)
|
||||
#define SWAPPER_PTE_FLAGS (PTE_TYPE_PAGE | PTE_AF | PTE_SHARED | PTE_UXN)
|
||||
#define SWAPPER_PMD_FLAGS (PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S | PTE_UXN)
|
||||
|
||||
#ifdef CONFIG_ARM64_4K_PAGES
|
||||
#define SWAPPER_RW_MMUFLAGS (PMD_ATTRINDX(MT_NORMAL) | SWAPPER_PMD_FLAGS)
|
||||
#define SWAPPER_RW_MMUFLAGS (PMD_ATTRINDX(MT_NORMAL) | SWAPPER_PMD_FLAGS | PTE_WRITE)
|
||||
#define SWAPPER_RX_MMUFLAGS (SWAPPER_RW_MMUFLAGS | PMD_SECT_RDONLY)
|
||||
#else
|
||||
#define SWAPPER_RW_MMUFLAGS (PTE_ATTRINDX(MT_NORMAL) | SWAPPER_PTE_FLAGS)
|
||||
#define SWAPPER_RW_MMUFLAGS (PTE_ATTRINDX(MT_NORMAL) | SWAPPER_PTE_FLAGS | PTE_WRITE)
|
||||
#define SWAPPER_RX_MMUFLAGS (SWAPPER_RW_MMUFLAGS | PTE_RDONLY)
|
||||
#endif
|
||||
|
||||
|
@ -93,8 +93,8 @@
|
||||
#define HCR_HOST_NVHE_PROTECTED_FLAGS (HCR_HOST_NVHE_FLAGS | HCR_TSC)
|
||||
#define HCR_HOST_VHE_FLAGS (HCR_RW | HCR_TGE | HCR_E2H)
|
||||
|
||||
#define HCRX_GUEST_FLAGS (HCRX_EL2_SMPME)
|
||||
#define HCRX_HOST_FLAGS (HCRX_EL2_MSCEn)
|
||||
#define HCRX_GUEST_FLAGS (HCRX_EL2_SMPME | HCRX_EL2_TCR2En)
|
||||
#define HCRX_HOST_FLAGS (HCRX_EL2_MSCEn | HCRX_EL2_TCR2En)
|
||||
|
||||
/* TCR_EL2 Registers bits */
|
||||
#define TCR_EL2_RES1 ((1U << 31) | (1 << 23))
|
||||
|
@ -279,6 +279,7 @@ enum vcpu_sysreg {
|
||||
TTBR0_EL1, /* Translation Table Base Register 0 */
|
||||
TTBR1_EL1, /* Translation Table Base Register 1 */
|
||||
TCR_EL1, /* Translation Control Register */
|
||||
TCR2_EL1, /* Extended Translation Control Register */
|
||||
ESR_EL1, /* Exception Syndrome Register */
|
||||
AFSR0_EL1, /* Auxiliary Fault Status Register 0 */
|
||||
AFSR1_EL1, /* Auxiliary Fault Status Register 1 */
|
||||
@ -339,6 +340,10 @@ enum vcpu_sysreg {
|
||||
TFSR_EL1, /* Tag Fault Status Register (EL1) */
|
||||
TFSRE0_EL1, /* Tag Fault Status Register (EL0) */
|
||||
|
||||
/* Permission Indirection Extension registers */
|
||||
PIR_EL1, /* Permission Indirection Register 1 (EL1) */
|
||||
PIRE0_EL1, /* Permission Indirection Register 0 (EL1) */
|
||||
|
||||
/* 32bit specific registers. */
|
||||
DACR32_EL2, /* Domain Access Control Register */
|
||||
IFSR32_EL2, /* Instruction Fault Status Register */
|
||||
|
@ -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])
|
||||
*/
|
||||
|
@ -27,6 +27,40 @@
|
||||
*/
|
||||
#define PMD_PRESENT_INVALID (_AT(pteval_t, 1) << 59) /* only when !PMD_SECT_VALID */
|
||||
|
||||
#define _PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF | PTE_SHARED)
|
||||
#define _PROT_SECT_DEFAULT (PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S)
|
||||
|
||||
#define PROT_DEFAULT (_PROT_DEFAULT | PTE_MAYBE_NG)
|
||||
#define PROT_SECT_DEFAULT (_PROT_SECT_DEFAULT | PMD_MAYBE_NG)
|
||||
|
||||
#define PROT_DEVICE_nGnRnE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_DEVICE_nGnRnE))
|
||||
#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_DEVICE_nGnRE))
|
||||
#define PROT_NORMAL_NC (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_NC))
|
||||
#define PROT_NORMAL (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL))
|
||||
#define PROT_NORMAL_TAGGED (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_TAGGED))
|
||||
|
||||
#define PROT_SECT_DEVICE_nGnRE (PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_DEVICE_nGnRE))
|
||||
#define PROT_SECT_NORMAL (PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PTE_WRITE | PMD_ATTRINDX(MT_NORMAL))
|
||||
#define PROT_SECT_NORMAL_EXEC (PROT_SECT_DEFAULT | PMD_SECT_UXN | PMD_ATTRINDX(MT_NORMAL))
|
||||
|
||||
#define _PAGE_DEFAULT (_PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL))
|
||||
|
||||
#define _PAGE_KERNEL (PROT_NORMAL)
|
||||
#define _PAGE_KERNEL_RO ((PROT_NORMAL & ~PTE_WRITE) | PTE_RDONLY)
|
||||
#define _PAGE_KERNEL_ROX ((PROT_NORMAL & ~(PTE_WRITE | PTE_PXN)) | PTE_RDONLY)
|
||||
#define _PAGE_KERNEL_EXEC (PROT_NORMAL & ~PTE_PXN)
|
||||
#define _PAGE_KERNEL_EXEC_CONT ((PROT_NORMAL & ~PTE_PXN) | PTE_CONT)
|
||||
|
||||
#define _PAGE_SHARED (_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE)
|
||||
#define _PAGE_SHARED_EXEC (_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_WRITE)
|
||||
#define _PAGE_READONLY (_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN)
|
||||
#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>
|
||||
@ -34,9 +68,6 @@
|
||||
|
||||
extern bool arm64_use_ng_mappings;
|
||||
|
||||
#define _PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF | PTE_SHARED)
|
||||
#define _PROT_SECT_DEFAULT (PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S)
|
||||
|
||||
#define PTE_MAYBE_NG (arm64_use_ng_mappings ? PTE_NG : 0)
|
||||
#define PMD_MAYBE_NG (arm64_use_ng_mappings ? PMD_SECT_NG : 0)
|
||||
|
||||
@ -50,26 +81,11 @@ extern bool arm64_use_ng_mappings;
|
||||
#define PTE_MAYBE_GP 0
|
||||
#endif
|
||||
|
||||
#define PROT_DEFAULT (_PROT_DEFAULT | PTE_MAYBE_NG)
|
||||
#define PROT_SECT_DEFAULT (_PROT_SECT_DEFAULT | PMD_MAYBE_NG)
|
||||
|
||||
#define PROT_DEVICE_nGnRnE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_DEVICE_nGnRnE))
|
||||
#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_DEVICE_nGnRE))
|
||||
#define PROT_NORMAL_NC (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_NC))
|
||||
#define PROT_NORMAL (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL))
|
||||
#define PROT_NORMAL_TAGGED (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_TAGGED))
|
||||
|
||||
#define PROT_SECT_DEVICE_nGnRE (PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_DEVICE_nGnRE))
|
||||
#define PROT_SECT_NORMAL (PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_NORMAL))
|
||||
#define PROT_SECT_NORMAL_EXEC (PROT_SECT_DEFAULT | PMD_SECT_UXN | PMD_ATTRINDX(MT_NORMAL))
|
||||
|
||||
#define _PAGE_DEFAULT (_PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL))
|
||||
|
||||
#define PAGE_KERNEL __pgprot(PROT_NORMAL)
|
||||
#define PAGE_KERNEL_RO __pgprot((PROT_NORMAL & ~PTE_WRITE) | PTE_RDONLY)
|
||||
#define PAGE_KERNEL_ROX __pgprot((PROT_NORMAL & ~(PTE_WRITE | PTE_PXN)) | PTE_RDONLY)
|
||||
#define PAGE_KERNEL_EXEC __pgprot(PROT_NORMAL & ~PTE_PXN)
|
||||
#define PAGE_KERNEL_EXEC_CONT __pgprot((PROT_NORMAL & ~PTE_PXN) | PTE_CONT)
|
||||
#define PAGE_KERNEL __pgprot(_PAGE_KERNEL)
|
||||
#define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL_RO)
|
||||
#define PAGE_KERNEL_ROX __pgprot(_PAGE_KERNEL_ROX)
|
||||
#define PAGE_KERNEL_EXEC __pgprot(_PAGE_KERNEL_EXEC)
|
||||
#define PAGE_KERNEL_EXEC_CONT __pgprot(_PAGE_KERNEL_EXEC_CONT)
|
||||
|
||||
#define PAGE_S2_MEMATTR(attr, has_fwb) \
|
||||
({ \
|
||||
@ -83,12 +99,62 @@ extern bool arm64_use_ng_mappings;
|
||||
|
||||
#define PAGE_NONE __pgprot(((_PAGE_DEFAULT) & ~PTE_VALID) | PTE_PROT_NONE | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN)
|
||||
/* shared+writable pages are clean by default, hence PTE_RDONLY|PTE_WRITE */
|
||||
#define PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE)
|
||||
#define PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_WRITE)
|
||||
#define PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN)
|
||||
#define PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN)
|
||||
#define PAGE_EXECONLY __pgprot(_PAGE_DEFAULT | PTE_RDONLY | PTE_NG | PTE_PXN)
|
||||
#define PAGE_SHARED __pgprot(_PAGE_SHARED)
|
||||
#define PAGE_SHARED_EXEC __pgprot(_PAGE_SHARED_EXEC)
|
||||
#define PAGE_READONLY __pgprot(_PAGE_READONLY)
|
||||
#define PAGE_READONLY_EXEC __pgprot(_PAGE_READONLY_EXEC)
|
||||
#define PAGE_EXECONLY __pgprot(_PAGE_EXECONLY)
|
||||
|
||||
#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 */
|
||||
|
@ -704,6 +704,25 @@
|
||||
#define ICH_VTR_TDS_SHIFT 19
|
||||
#define ICH_VTR_TDS_MASK (1 << ICH_VTR_TDS_SHIFT)
|
||||
|
||||
/*
|
||||
* Permission Indirection Extension (PIE) permission encodings.
|
||||
* Encodings with the _O suffix, have overlays applied (Permission Overlay Extension).
|
||||
*/
|
||||
#define PIE_NONE_O 0x0
|
||||
#define PIE_R_O 0x1
|
||||
#define PIE_X_O 0x2
|
||||
#define PIE_RX_O 0x3
|
||||
#define PIE_RW_O 0x5
|
||||
#define PIE_RWnX_O 0x6
|
||||
#define PIE_RWX_O 0x7
|
||||
#define PIE_R 0x8
|
||||
#define PIE_GCS 0x9
|
||||
#define PIE_RX 0xa
|
||||
#define PIE_RW 0xc
|
||||
#define PIE_RWX 0xe
|
||||
|
||||
#define PIRx_ELx_PERM(idx, perm) ((perm) << ((idx) * 4))
|
||||
|
||||
#define ARM64_FEATURE_FIELD_BITS 4
|
||||
|
||||
/* Defined for compatibility only, do not add new users. */
|
||||
|
@ -398,6 +398,12 @@ static const struct arm64_ftr_bits ftr_id_aa64mmfr2[] = {
|
||||
ARM64_FTR_END,
|
||||
};
|
||||
|
||||
static const struct arm64_ftr_bits ftr_id_aa64mmfr3[] = {
|
||||
ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR3_EL1_S1PIE_SHIFT, 4, 0),
|
||||
ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR3_EL1_TCRX_SHIFT, 4, 0),
|
||||
ARM64_FTR_END,
|
||||
};
|
||||
|
||||
static const struct arm64_ftr_bits ftr_ctr[] = {
|
||||
ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, 31, 1, 1), /* RES1 */
|
||||
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 {
|
||||
ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64MMFR1_EL1, ftr_id_aa64mmfr1,
|
||||
&id_aa64mmfr1_override),
|
||||
ARM64_FTR_REG(SYS_ID_AA64MMFR2_EL1, ftr_id_aa64mmfr2),
|
||||
ARM64_FTR_REG(SYS_ID_AA64MMFR3_EL1, ftr_id_aa64mmfr3),
|
||||
|
||||
/* Op1 = 0, CRn = 1, CRm = 2 */
|
||||
ARM64_FTR_REG(SYS_ZCR_EL1, ftr_zcr),
|
||||
@ -1019,6 +1026,7 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info)
|
||||
init_cpu_ftr_reg(SYS_ID_AA64MMFR0_EL1, info->reg_id_aa64mmfr0);
|
||||
init_cpu_ftr_reg(SYS_ID_AA64MMFR1_EL1, info->reg_id_aa64mmfr1);
|
||||
init_cpu_ftr_reg(SYS_ID_AA64MMFR2_EL1, info->reg_id_aa64mmfr2);
|
||||
init_cpu_ftr_reg(SYS_ID_AA64MMFR3_EL1, info->reg_id_aa64mmfr3);
|
||||
init_cpu_ftr_reg(SYS_ID_AA64PFR0_EL1, info->reg_id_aa64pfr0);
|
||||
init_cpu_ftr_reg(SYS_ID_AA64PFR1_EL1, info->reg_id_aa64pfr1);
|
||||
init_cpu_ftr_reg(SYS_ID_AA64ZFR0_EL1, info->reg_id_aa64zfr0);
|
||||
@ -1264,6 +1272,8 @@ void update_cpu_features(int cpu,
|
||||
info->reg_id_aa64mmfr1, boot->reg_id_aa64mmfr1);
|
||||
taint |= check_update_ftr_reg(SYS_ID_AA64MMFR2_EL1, cpu,
|
||||
info->reg_id_aa64mmfr2, boot->reg_id_aa64mmfr2);
|
||||
taint |= check_update_ftr_reg(SYS_ID_AA64MMFR3_EL1, cpu,
|
||||
info->reg_id_aa64mmfr3, boot->reg_id_aa64mmfr3);
|
||||
|
||||
taint |= check_update_ftr_reg(SYS_ID_AA64PFR0_EL1, cpu,
|
||||
info->reg_id_aa64pfr0, boot->reg_id_aa64pfr0);
|
||||
@ -1393,6 +1403,7 @@ u64 __read_sysreg_by_encoding(u32 sys_id)
|
||||
read_sysreg_case(SYS_ID_AA64MMFR0_EL1);
|
||||
read_sysreg_case(SYS_ID_AA64MMFR1_EL1);
|
||||
read_sysreg_case(SYS_ID_AA64MMFR2_EL1);
|
||||
read_sysreg_case(SYS_ID_AA64MMFR3_EL1);
|
||||
read_sysreg_case(SYS_ID_AA64ISAR0_EL1);
|
||||
read_sysreg_case(SYS_ID_AA64ISAR1_EL1);
|
||||
read_sysreg_case(SYS_ID_AA64ISAR2_EL1);
|
||||
@ -2659,6 +2670,19 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
|
||||
.cpu_enable = cpu_enable_mops,
|
||||
ARM64_CPUID_FIELDS(ID_AA64ISAR2_EL1, MOPS, IMP)
|
||||
},
|
||||
{
|
||||
.capability = ARM64_HAS_TCR2,
|
||||
.type = ARM64_CPUCAP_SYSTEM_FEATURE,
|
||||
.matches = has_cpuid_feature,
|
||||
ARM64_CPUID_FIELDS(ID_AA64MMFR3_EL1, TCRX, IMP)
|
||||
},
|
||||
{
|
||||
.desc = "Stage-1 Permission Indirection Extension (S1PIE)",
|
||||
.capability = ARM64_HAS_S1PIE,
|
||||
.type = ARM64_CPUCAP_BOOT_CPU_FEATURE,
|
||||
.matches = has_cpuid_feature,
|
||||
ARM64_CPUID_FIELDS(ID_AA64MMFR3_EL1, S1PIE, IMP)
|
||||
},
|
||||
{},
|
||||
};
|
||||
|
||||
|
@ -447,6 +447,7 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
|
||||
info->reg_id_aa64mmfr0 = read_cpuid(ID_AA64MMFR0_EL1);
|
||||
info->reg_id_aa64mmfr1 = read_cpuid(ID_AA64MMFR1_EL1);
|
||||
info->reg_id_aa64mmfr2 = read_cpuid(ID_AA64MMFR2_EL1);
|
||||
info->reg_id_aa64mmfr3 = read_cpuid(ID_AA64MMFR3_EL1);
|
||||
info->reg_id_aa64pfr0 = read_cpuid(ID_AA64PFR0_EL1);
|
||||
info->reg_id_aa64pfr1 = read_cpuid(ID_AA64PFR1_EL1);
|
||||
info->reg_id_aa64zfr0 = read_cpuid(ID_AA64ZFR0_EL1);
|
||||
|
@ -382,7 +382,7 @@ SYM_FUNC_START_LOCAL(create_idmap)
|
||||
adrp x0, init_idmap_pg_dir
|
||||
adrp x3, _text
|
||||
adrp x6, _end + MAX_FDT_SIZE + SWAPPER_BLOCK_SIZE
|
||||
mov x7, SWAPPER_RX_MMUFLAGS
|
||||
mov_q x7, SWAPPER_RX_MMUFLAGS
|
||||
|
||||
map_memory x0, x1, x3, x6, x7, x3, IDMAP_PGD_ORDER, x10, x11, x12, x13, x14, EXTRA_SHIFT
|
||||
|
||||
@ -391,7 +391,7 @@ SYM_FUNC_START_LOCAL(create_idmap)
|
||||
adrp x2, init_pg_dir
|
||||
adrp x3, init_pg_end
|
||||
bic x4, x2, #SWAPPER_BLOCK_SIZE - 1
|
||||
mov x5, SWAPPER_RW_MMUFLAGS
|
||||
mov_q x5, SWAPPER_RW_MMUFLAGS
|
||||
mov x6, #SWAPPER_BLOCK_SHIFT
|
||||
bl remap_region
|
||||
|
||||
@ -402,7 +402,7 @@ SYM_FUNC_START_LOCAL(create_idmap)
|
||||
bfi x22, x21, #0, #SWAPPER_BLOCK_SHIFT // remapped FDT address
|
||||
add x3, x2, #MAX_FDT_SIZE + SWAPPER_BLOCK_SIZE
|
||||
bic x4, x21, #SWAPPER_BLOCK_SIZE - 1
|
||||
mov x5, SWAPPER_RW_MMUFLAGS
|
||||
mov_q x5, SWAPPER_RW_MMUFLAGS
|
||||
mov x6, #SWAPPER_BLOCK_SHIFT
|
||||
bl remap_region
|
||||
|
||||
@ -430,7 +430,7 @@ SYM_FUNC_START_LOCAL(create_kernel_mapping)
|
||||
adrp x3, _text // runtime __pa(_text)
|
||||
sub x6, x6, x3 // _end - _text
|
||||
add x6, x6, x5 // runtime __va(_end)
|
||||
mov x7, SWAPPER_RW_MMUFLAGS
|
||||
mov_q x7, SWAPPER_RW_MMUFLAGS
|
||||
|
||||
map_memory x0, x1, x5, x6, x7, x3, (VA_BITS - PGDIR_SHIFT), x10, x11, x12, x13, x14
|
||||
|
||||
|
@ -119,6 +119,24 @@ SYM_CODE_START_LOCAL(__finalise_el2)
|
||||
msr ttbr1_el1, x0
|
||||
mrs_s x0, SYS_MAIR_EL12
|
||||
msr mair_el1, x0
|
||||
mrs x1, REG_ID_AA64MMFR3_EL1
|
||||
ubfx x1, x1, #ID_AA64MMFR3_EL1_TCRX_SHIFT, #4
|
||||
cbz x1, .Lskip_tcr2
|
||||
mrs x0, REG_TCR2_EL12
|
||||
msr REG_TCR2_EL1, x0
|
||||
|
||||
// Transfer permission indirection state
|
||||
mrs x1, REG_ID_AA64MMFR3_EL1
|
||||
ubfx x1, x1, #ID_AA64MMFR3_EL1_S1PIE_SHIFT, #4
|
||||
cbz x1, .Lskip_indirection
|
||||
mrs x0, REG_PIRE0_EL12
|
||||
msr REG_PIRE0_EL1, x0
|
||||
mrs x0, REG_PIR_EL12
|
||||
msr REG_PIR_EL1, x0
|
||||
|
||||
.Lskip_indirection:
|
||||
.Lskip_tcr2:
|
||||
|
||||
isb
|
||||
|
||||
// Hack the exception return to stay at EL2
|
||||
|
@ -44,6 +44,8 @@ static inline void __sysreg_save_el1_state(struct kvm_cpu_context *ctxt)
|
||||
ctxt_sys_reg(ctxt, TTBR0_EL1) = read_sysreg_el1(SYS_TTBR0);
|
||||
ctxt_sys_reg(ctxt, TTBR1_EL1) = read_sysreg_el1(SYS_TTBR1);
|
||||
ctxt_sys_reg(ctxt, TCR_EL1) = read_sysreg_el1(SYS_TCR);
|
||||
if (cpus_have_final_cap(ARM64_HAS_TCR2))
|
||||
ctxt_sys_reg(ctxt, TCR2_EL1) = read_sysreg_el1(SYS_TCR2);
|
||||
ctxt_sys_reg(ctxt, ESR_EL1) = read_sysreg_el1(SYS_ESR);
|
||||
ctxt_sys_reg(ctxt, AFSR0_EL1) = read_sysreg_el1(SYS_AFSR0);
|
||||
ctxt_sys_reg(ctxt, AFSR1_EL1) = read_sysreg_el1(SYS_AFSR1);
|
||||
@ -53,6 +55,10 @@ static inline void __sysreg_save_el1_state(struct kvm_cpu_context *ctxt)
|
||||
ctxt_sys_reg(ctxt, CONTEXTIDR_EL1) = read_sysreg_el1(SYS_CONTEXTIDR);
|
||||
ctxt_sys_reg(ctxt, AMAIR_EL1) = read_sysreg_el1(SYS_AMAIR);
|
||||
ctxt_sys_reg(ctxt, CNTKCTL_EL1) = read_sysreg_el1(SYS_CNTKCTL);
|
||||
if (cpus_have_final_cap(ARM64_HAS_S1PIE)) {
|
||||
ctxt_sys_reg(ctxt, PIR_EL1) = read_sysreg_el1(SYS_PIR);
|
||||
ctxt_sys_reg(ctxt, PIRE0_EL1) = read_sysreg_el1(SYS_PIRE0);
|
||||
}
|
||||
ctxt_sys_reg(ctxt, PAR_EL1) = read_sysreg_par();
|
||||
ctxt_sys_reg(ctxt, TPIDR_EL1) = read_sysreg(tpidr_el1);
|
||||
|
||||
@ -114,6 +120,8 @@ static inline void __sysreg_restore_el1_state(struct kvm_cpu_context *ctxt)
|
||||
write_sysreg_el1(ctxt_sys_reg(ctxt, CPACR_EL1), SYS_CPACR);
|
||||
write_sysreg_el1(ctxt_sys_reg(ctxt, TTBR0_EL1), SYS_TTBR0);
|
||||
write_sysreg_el1(ctxt_sys_reg(ctxt, TTBR1_EL1), SYS_TTBR1);
|
||||
if (cpus_have_final_cap(ARM64_HAS_TCR2))
|
||||
write_sysreg_el1(ctxt_sys_reg(ctxt, TCR2_EL1), SYS_TCR2);
|
||||
write_sysreg_el1(ctxt_sys_reg(ctxt, ESR_EL1), SYS_ESR);
|
||||
write_sysreg_el1(ctxt_sys_reg(ctxt, AFSR0_EL1), SYS_AFSR0);
|
||||
write_sysreg_el1(ctxt_sys_reg(ctxt, AFSR1_EL1), SYS_AFSR1);
|
||||
@ -123,6 +131,10 @@ static inline void __sysreg_restore_el1_state(struct kvm_cpu_context *ctxt)
|
||||
write_sysreg_el1(ctxt_sys_reg(ctxt, CONTEXTIDR_EL1), SYS_CONTEXTIDR);
|
||||
write_sysreg_el1(ctxt_sys_reg(ctxt, AMAIR_EL1), SYS_AMAIR);
|
||||
write_sysreg_el1(ctxt_sys_reg(ctxt, CNTKCTL_EL1), SYS_CNTKCTL);
|
||||
if (cpus_have_final_cap(ARM64_HAS_S1PIE)) {
|
||||
write_sysreg_el1(ctxt_sys_reg(ctxt, PIR_EL1), SYS_PIR);
|
||||
write_sysreg_el1(ctxt_sys_reg(ctxt, PIRE0_EL1), SYS_PIRE0);
|
||||
}
|
||||
write_sysreg(ctxt_sys_reg(ctxt, PAR_EL1), par_el1);
|
||||
write_sysreg(ctxt_sys_reg(ctxt, TPIDR_EL1), tpidr_el1);
|
||||
|
||||
|
@ -1873,7 +1873,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
|
||||
ID_SANITISED(ID_AA64MMFR0_EL1),
|
||||
ID_SANITISED(ID_AA64MMFR1_EL1),
|
||||
ID_SANITISED(ID_AA64MMFR2_EL1),
|
||||
ID_UNALLOCATED(7,3),
|
||||
ID_SANITISED(ID_AA64MMFR3_EL1),
|
||||
ID_UNALLOCATED(7,4),
|
||||
ID_UNALLOCATED(7,5),
|
||||
ID_UNALLOCATED(7,6),
|
||||
@ -1893,6 +1893,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
|
||||
{ SYS_DESC(SYS_TTBR0_EL1), access_vm_reg, reset_unknown, TTBR0_EL1 },
|
||||
{ SYS_DESC(SYS_TTBR1_EL1), access_vm_reg, reset_unknown, TTBR1_EL1 },
|
||||
{ SYS_DESC(SYS_TCR_EL1), access_vm_reg, reset_val, TCR_EL1, 0 },
|
||||
{ SYS_DESC(SYS_TCR2_EL1), access_vm_reg, reset_val, TCR2_EL1, 0 },
|
||||
|
||||
PTRAUTH_KEY(APIA),
|
||||
PTRAUTH_KEY(APIB),
|
||||
@ -1942,6 +1943,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
|
||||
{ SYS_DESC(SYS_PMMIR_EL1), trap_raz_wi },
|
||||
|
||||
{ SYS_DESC(SYS_MAIR_EL1), access_vm_reg, reset_unknown, MAIR_EL1 },
|
||||
{ SYS_DESC(SYS_PIRE0_EL1), access_vm_reg, reset_unknown, PIRE0_EL1 },
|
||||
{ SYS_DESC(SYS_PIR_EL1), access_vm_reg, reset_unknown, PIR_EL1 },
|
||||
{ SYS_DESC(SYS_AMAIR_EL1), access_vm_reg, reset_amair_el1, AMAIR_EL1 },
|
||||
|
||||
{ SYS_DESC(SYS_LORSA_EL1), trap_loregion },
|
||||
|
@ -199,7 +199,7 @@ SYM_FUNC_END(idmap_cpu_replace_ttbr1)
|
||||
|
||||
#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
|
||||
|
||||
#define KPTI_NG_PTE_FLAGS (PTE_ATTRINDX(MT_NORMAL) | SWAPPER_PTE_FLAGS)
|
||||
#define KPTI_NG_PTE_FLAGS (PTE_ATTRINDX(MT_NORMAL) | SWAPPER_PTE_FLAGS | PTE_WRITE)
|
||||
|
||||
.pushsection ".idmap.text", "a"
|
||||
|
||||
@ -290,7 +290,7 @@ SYM_TYPED_FUNC_START(idmap_kpti_install_ng_mappings)
|
||||
isb
|
||||
|
||||
mov temp_pte, x5
|
||||
mov pte_flags, #KPTI_NG_PTE_FLAGS
|
||||
mov_q pte_flags, KPTI_NG_PTE_FLAGS
|
||||
|
||||
/* Everybody is enjoying the idmap, so we can rewrite swapper. */
|
||||
/* PGD */
|
||||
@ -454,6 +454,21 @@ SYM_FUNC_START(__cpu_setup)
|
||||
#endif /* CONFIG_ARM64_HW_AFDBM */
|
||||
msr mair_el1, mair
|
||||
msr tcr_el1, tcr
|
||||
|
||||
mrs_s x1, SYS_ID_AA64MMFR3_EL1
|
||||
ubfx x1, x1, #ID_AA64MMFR3_EL1_S1PIE_SHIFT, #4
|
||||
cbz x1, .Lskip_indirection
|
||||
|
||||
mov_q x0, PIE_E0
|
||||
msr REG_PIRE0_EL1, x0
|
||||
mov_q x0, PIE_E1
|
||||
msr REG_PIR_EL1, x0
|
||||
|
||||
mov x0, TCR2_EL1x_PIE
|
||||
msr REG_TCR2_EL1, x0
|
||||
|
||||
.Lskip_indirection:
|
||||
|
||||
/*
|
||||
* Prepare SCTLR
|
||||
*/
|
||||
|
@ -40,10 +40,12 @@ HAS_NESTED_VIRT
|
||||
HAS_NO_FPSIMD
|
||||
HAS_NO_HW_PREFETCH
|
||||
HAS_PAN
|
||||
HAS_S1PIE
|
||||
HAS_RAS_EXTN
|
||||
HAS_RNG
|
||||
HAS_SB
|
||||
HAS_STAGE2_FWB
|
||||
HAS_TCR2
|
||||
HAS_TIDCP1
|
||||
HAS_TLB_RANGE
|
||||
HAS_VIRT_HOST_EXTN
|
||||
|
@ -1593,6 +1593,78 @@ UnsignedEnum 3:0 CnP
|
||||
EndEnum
|
||||
EndSysreg
|
||||
|
||||
Sysreg ID_AA64MMFR3_EL1 3 0 0 7 3
|
||||
UnsignedEnum 63:60 Spec_FPACC
|
||||
0b0000 NI
|
||||
0b0001 IMP
|
||||
EndEnum
|
||||
UnsignedEnum 59:56 ADERR
|
||||
0b0000 NI
|
||||
0b0001 DEV_ASYNC
|
||||
0b0010 FEAT_ADERR
|
||||
0b0011 FEAT_ADERR_IND
|
||||
EndEnum
|
||||
UnsignedEnum 55:52 SDERR
|
||||
0b0000 NI
|
||||
0b0001 DEV_SYNC
|
||||
0b0010 FEAT_ADERR
|
||||
0b0011 FEAT_ADERR_IND
|
||||
EndEnum
|
||||
Res0 51:48
|
||||
UnsignedEnum 47:44 ANERR
|
||||
0b0000 NI
|
||||
0b0001 ASYNC
|
||||
0b0010 FEAT_ANERR
|
||||
0b0011 FEAT_ANERR_IND
|
||||
EndEnum
|
||||
UnsignedEnum 43:40 SNERR
|
||||
0b0000 NI
|
||||
0b0001 SYNC
|
||||
0b0010 FEAT_ANERR
|
||||
0b0011 FEAT_ANERR_IND
|
||||
EndEnum
|
||||
UnsignedEnum 39:36 D128_2
|
||||
0b0000 NI
|
||||
0b0001 IMP
|
||||
EndEnum
|
||||
UnsignedEnum 35:32 D128
|
||||
0b0000 NI
|
||||
0b0001 IMP
|
||||
EndEnum
|
||||
UnsignedEnum 31:28 MEC
|
||||
0b0000 NI
|
||||
0b0001 IMP
|
||||
EndEnum
|
||||
UnsignedEnum 27:24 AIE
|
||||
0b0000 NI
|
||||
0b0001 IMP
|
||||
EndEnum
|
||||
UnsignedEnum 23:20 S2POE
|
||||
0b0000 NI
|
||||
0b0001 IMP
|
||||
EndEnum
|
||||
UnsignedEnum 19:16 S1POE
|
||||
0b0000 NI
|
||||
0b0001 IMP
|
||||
EndEnum
|
||||
UnsignedEnum 15:12 S2PIE
|
||||
0b0000 NI
|
||||
0b0001 IMP
|
||||
EndEnum
|
||||
UnsignedEnum 11:8 S1PIE
|
||||
0b0000 NI
|
||||
0b0001 IMP
|
||||
EndEnum
|
||||
UnsignedEnum 7:4 SCTLRX
|
||||
0b0000 NI
|
||||
0b0001 IMP
|
||||
EndEnum
|
||||
UnsignedEnum 3:0 TCRX
|
||||
0b0000 NI
|
||||
0b0001 IMP
|
||||
EndEnum
|
||||
EndSysreg
|
||||
|
||||
Sysreg SCTLR_EL1 3 0 1 0 0
|
||||
Field 63 TIDCP
|
||||
Field 62 SPINTMASK
|
||||
@ -2089,7 +2161,17 @@ Fields ZCR_ELx
|
||||
EndSysreg
|
||||
|
||||
Sysreg HCRX_EL2 3 4 1 2 2
|
||||
Res0 63:12
|
||||
Res0 63:23
|
||||
Field 22 GCSEn
|
||||
Field 21 EnIDCP128
|
||||
Field 20 EnSDERR
|
||||
Field 19 TMEA
|
||||
Field 18 EnSNERR
|
||||
Field 17 D128En
|
||||
Field 16 PTTWI
|
||||
Field 15 SCTLR2En
|
||||
Field 14 TCR2En
|
||||
Res0 13:12
|
||||
Field 11 MSCEn
|
||||
Field 10 MCE2
|
||||
Field 9 CMOW
|
||||
@ -2208,6 +2290,87 @@ Sysreg TTBR1_EL1 3 0 2 0 1
|
||||
Fields TTBRx_EL1
|
||||
EndSysreg
|
||||
|
||||
SysregFields TCR2_EL1x
|
||||
Res0 63:16
|
||||
Field 15 DisCH1
|
||||
Field 14 DisCH0
|
||||
Res0 13:12
|
||||
Field 11 HAFT
|
||||
Field 10 PTTWI
|
||||
Res0 9:6
|
||||
Field 5 D128
|
||||
Field 4 AIE
|
||||
Field 3 POE
|
||||
Field 2 E0POE
|
||||
Field 1 PIE
|
||||
Field 0 PnCH
|
||||
EndSysregFields
|
||||
|
||||
Sysreg TCR2_EL1 3 0 2 0 3
|
||||
Fields TCR2_EL1x
|
||||
EndSysreg
|
||||
|
||||
Sysreg TCR2_EL12 3 5 2 0 3
|
||||
Fields TCR2_EL1x
|
||||
EndSysreg
|
||||
|
||||
Sysreg TCR2_EL2 3 4 2 0 3
|
||||
Res0 63:16
|
||||
Field 15 DisCH1
|
||||
Field 14 DisCH0
|
||||
Field 13 AMEC1
|
||||
Field 12 AMEC0
|
||||
Field 11 HAFT
|
||||
Field 10 PTTWI
|
||||
Field 9:8 SKL1
|
||||
Field 7:6 SKL0
|
||||
Field 5 D128
|
||||
Field 4 AIE
|
||||
Field 3 POE
|
||||
Field 2 E0POE
|
||||
Field 1 PIE
|
||||
Field 0 PnCH
|
||||
EndSysreg
|
||||
|
||||
SysregFields PIRx_ELx
|
||||
Field 63:60 Perm15
|
||||
Field 59:56 Perm14
|
||||
Field 55:52 Perm13
|
||||
Field 51:48 Perm12
|
||||
Field 47:44 Perm11
|
||||
Field 43:40 Perm10
|
||||
Field 39:36 Perm9
|
||||
Field 35:32 Perm8
|
||||
Field 31:28 Perm7
|
||||
Field 27:24 Perm6
|
||||
Field 23:20 Perm5
|
||||
Field 19:16 Perm4
|
||||
Field 15:12 Perm3
|
||||
Field 11:8 Perm2
|
||||
Field 7:4 Perm1
|
||||
Field 3:0 Perm0
|
||||
EndSysregFields
|
||||
|
||||
Sysreg PIRE0_EL1 3 0 10 2 2
|
||||
Fields PIRx_ELx
|
||||
EndSysreg
|
||||
|
||||
Sysreg PIRE0_EL12 3 5 10 2 2
|
||||
Fields PIRx_ELx
|
||||
EndSysreg
|
||||
|
||||
Sysreg PIR_EL1 3 0 10 2 3
|
||||
Fields PIRx_ELx
|
||||
EndSysreg
|
||||
|
||||
Sysreg PIR_EL12 3 5 10 2 3
|
||||
Fields PIRx_ELx
|
||||
EndSysreg
|
||||
|
||||
Sysreg PIR_EL2 3 4 10 2 3
|
||||
Fields PIRx_ELx
|
||||
EndSysreg
|
||||
|
||||
Sysreg LORSA_EL1 3 0 10 4 0
|
||||
Res0 63:52
|
||||
Field 51:16 SA
|
||||
|
@ -48,6 +48,34 @@ struct reg_sublist {
|
||||
__u64 rejects_set_n;
|
||||
};
|
||||
|
||||
struct feature_id_reg {
|
||||
__u64 reg;
|
||||
__u64 id_reg;
|
||||
__u64 feat_shift;
|
||||
__u64 feat_min;
|
||||
};
|
||||
|
||||
static struct feature_id_reg feat_id_regs[] = {
|
||||
{
|
||||
ARM64_SYS_REG(3, 0, 2, 0, 3), /* TCR2_EL1 */
|
||||
ARM64_SYS_REG(3, 0, 0, 7, 3), /* ID_AA64MMFR3_EL1 */
|
||||
0,
|
||||
1
|
||||
},
|
||||
{
|
||||
ARM64_SYS_REG(3, 0, 10, 2, 2), /* PIRE0_EL1 */
|
||||
ARM64_SYS_REG(3, 0, 0, 7, 3), /* ID_AA64MMFR3_EL1 */
|
||||
4,
|
||||
1
|
||||
},
|
||||
{
|
||||
ARM64_SYS_REG(3, 0, 10, 2, 3), /* PIR_EL1 */
|
||||
ARM64_SYS_REG(3, 0, 0, 7, 3), /* ID_AA64MMFR3_EL1 */
|
||||
4,
|
||||
1
|
||||
}
|
||||
};
|
||||
|
||||
struct vcpu_config {
|
||||
char *name;
|
||||
struct reg_sublist sublists[];
|
||||
@ -68,7 +96,8 @@ static int vcpu_configs_n;
|
||||
|
||||
#define for_each_missing_reg(i) \
|
||||
for ((i) = 0; (i) < blessed_n; ++(i)) \
|
||||
if (!find_reg(reg_list->reg, reg_list->n, blessed_reg[i]))
|
||||
if (!find_reg(reg_list->reg, reg_list->n, blessed_reg[i])) \
|
||||
if (check_supported_feat_reg(vcpu, blessed_reg[i]))
|
||||
|
||||
#define for_each_new_reg(i) \
|
||||
for_each_reg_filtered(i) \
|
||||
@ -132,6 +161,25 @@ static bool find_reg(__u64 regs[], __u64 nr_regs, __u64 reg)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool check_supported_feat_reg(struct kvm_vcpu *vcpu, __u64 reg)
|
||||
{
|
||||
int i, ret;
|
||||
__u64 data, feat_val;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(feat_id_regs); i++) {
|
||||
if (feat_id_regs[i].reg == reg) {
|
||||
ret = __vcpu_get_reg(vcpu, feat_id_regs[i].id_reg, &data);
|
||||
if (ret < 0)
|
||||
return false;
|
||||
|
||||
feat_val = ((data >> feat_id_regs[i].feat_shift) & 0xf);
|
||||
return feat_val >= feat_id_regs[i].feat_min;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static const char *str_with_index(const char *template, __u64 index)
|
||||
{
|
||||
char *str, *p;
|
||||
@ -843,12 +891,15 @@ static __u64 base_regs[] = {
|
||||
ARM64_SYS_REG(3, 0, 2, 0, 0), /* TTBR0_EL1 */
|
||||
ARM64_SYS_REG(3, 0, 2, 0, 1), /* TTBR1_EL1 */
|
||||
ARM64_SYS_REG(3, 0, 2, 0, 2), /* TCR_EL1 */
|
||||
ARM64_SYS_REG(3, 0, 2, 0, 3), /* TCR2_EL1 */
|
||||
ARM64_SYS_REG(3, 0, 5, 1, 0), /* AFSR0_EL1 */
|
||||
ARM64_SYS_REG(3, 0, 5, 1, 1), /* AFSR1_EL1 */
|
||||
ARM64_SYS_REG(3, 0, 5, 2, 0), /* ESR_EL1 */
|
||||
ARM64_SYS_REG(3, 0, 6, 0, 0), /* FAR_EL1 */
|
||||
ARM64_SYS_REG(3, 0, 7, 4, 0), /* PAR_EL1 */
|
||||
ARM64_SYS_REG(3, 0, 10, 2, 0), /* MAIR_EL1 */
|
||||
ARM64_SYS_REG(3, 0, 10, 2, 2), /* PIRE0_EL1 */
|
||||
ARM64_SYS_REG(3, 0, 10, 2, 3), /* PIR_EL1 */
|
||||
ARM64_SYS_REG(3, 0, 10, 3, 0), /* AMAIR_EL1 */
|
||||
ARM64_SYS_REG(3, 0, 12, 0, 0), /* VBAR_EL1 */
|
||||
ARM64_SYS_REG(3, 0, 12, 1, 1), /* DISR_EL1 */
|
||||
|
Loading…
Reference in New Issue
Block a user