diff options
author | Will Deacon <will.deacon@arm.com> | 2017-11-27 13:29:30 -0500 |
---|---|---|
committer | Catalin Marinas <catalin.marinas@arm.com> | 2018-01-08 13:43:34 -0500 |
commit | 179a56f6f9fbda28f6ca07db1fc3dfad6bc7343c (patch) | |
tree | 1732f38cd45c84444e8102b3c312258bc61041ea | |
parent | 0617052ddde355ee663b2f048e67dd381e5ebd6a (diff) |
arm64: Take into account ID_AA64PFR0_EL1.CSV3
For non-KASLR kernels where the KPTI behaviour has not been overridden
on the command line we can use ID_AA64PFR0_EL1.CSV3 to determine whether
or not we should unmap the kernel whilst running at EL0.
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
-rw-r--r-- | arch/arm64/include/asm/sysreg.h | 1 | ||||
-rw-r--r-- | arch/arm64/kernel/cpufeature.c | 8 |
2 files changed, 8 insertions, 1 deletions
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h index ab637886a6f9..262ae18f0e05 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h | |||
@@ -438,6 +438,7 @@ | |||
438 | #define ID_AA64ISAR1_DPB_SHIFT 0 | 438 | #define ID_AA64ISAR1_DPB_SHIFT 0 |
439 | 439 | ||
440 | /* id_aa64pfr0 */ | 440 | /* id_aa64pfr0 */ |
441 | #define ID_AA64PFR0_CSV3_SHIFT 60 | ||
441 | #define ID_AA64PFR0_SVE_SHIFT 32 | 442 | #define ID_AA64PFR0_SVE_SHIFT 32 |
442 | #define ID_AA64PFR0_GIC_SHIFT 24 | 443 | #define ID_AA64PFR0_GIC_SHIFT 24 |
443 | #define ID_AA64PFR0_ASIMD_SHIFT 20 | 444 | #define ID_AA64PFR0_ASIMD_SHIFT 20 |
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 1f024049eb30..0f3c96172f0f 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c | |||
@@ -146,6 +146,7 @@ static const struct arm64_ftr_bits ftr_id_aa64isar1[] = { | |||
146 | }; | 146 | }; |
147 | 147 | ||
148 | static const struct arm64_ftr_bits ftr_id_aa64pfr0[] = { | 148 | static const struct arm64_ftr_bits ftr_id_aa64pfr0[] = { |
149 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_CSV3_SHIFT, 4, 0), | ||
149 | ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_SVE_SHIFT, 4, 0), | 150 | ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_SVE_SHIFT, 4, 0), |
150 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_GIC_SHIFT, 4, 0), | 151 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_GIC_SHIFT, 4, 0), |
151 | S_ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_ASIMD_SHIFT, 4, ID_AA64PFR0_ASIMD_NI), | 152 | S_ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_ASIMD_SHIFT, 4, ID_AA64PFR0_ASIMD_NI), |
@@ -852,6 +853,8 @@ static int __kpti_forced; /* 0: not forced, >0: forced on, <0: forced off */ | |||
852 | static bool unmap_kernel_at_el0(const struct arm64_cpu_capabilities *entry, | 853 | static bool unmap_kernel_at_el0(const struct arm64_cpu_capabilities *entry, |
853 | int __unused) | 854 | int __unused) |
854 | { | 855 | { |
856 | u64 pfr0 = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1); | ||
857 | |||
855 | /* Forced on command line? */ | 858 | /* Forced on command line? */ |
856 | if (__kpti_forced) { | 859 | if (__kpti_forced) { |
857 | pr_info_once("kernel page table isolation forced %s by command line option\n", | 860 | pr_info_once("kernel page table isolation forced %s by command line option\n", |
@@ -863,7 +866,9 @@ static bool unmap_kernel_at_el0(const struct arm64_cpu_capabilities *entry, | |||
863 | if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) | 866 | if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) |
864 | return true; | 867 | return true; |
865 | 868 | ||
866 | return false; | 869 | /* Defer to CPU feature registers */ |
870 | return !cpuid_feature_extract_unsigned_field(pfr0, | ||
871 | ID_AA64PFR0_CSV3_SHIFT); | ||
867 | } | 872 | } |
868 | 873 | ||
869 | static int __init parse_kpti(char *str) | 874 | static int __init parse_kpti(char *str) |
@@ -968,6 +973,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = { | |||
968 | }, | 973 | }, |
969 | #ifdef CONFIG_UNMAP_KERNEL_AT_EL0 | 974 | #ifdef CONFIG_UNMAP_KERNEL_AT_EL0 |
970 | { | 975 | { |
976 | .desc = "Kernel page table isolation (KPTI)", | ||
971 | .capability = ARM64_UNMAP_KERNEL_AT_EL0, | 977 | .capability = ARM64_UNMAP_KERNEL_AT_EL0, |
972 | .def_scope = SCOPE_SYSTEM, | 978 | .def_scope = SCOPE_SYSTEM, |
973 | .matches = unmap_kernel_at_el0, | 979 | .matches = unmap_kernel_at_el0, |