]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
arm64: trap implementation defined functionality in userspace
authorKristina Martsenko <kristina.martsenko@arm.com>
Wed, 22 Jun 2022 11:54:24 +0000 (12:54 +0100)
committerWill Deacon <will@kernel.org>
Thu, 23 Jun 2022 17:40:38 +0000 (18:40 +0100)
The Arm v8.8 extension adds a new control FEAT_TIDCP1 that allows the
kernel to disable all implementation-defined system registers and
instructions in userspace. This can improve robustness against covert
channels between processes, for example in cases where the firmware or
hardware didn't disable that functionality by default.

The kernel does not currently support any implementation-defined
features, as there are no hwcaps for any such features, so disable all
imp-def features unconditionally. Any use of imp-def instructions will
result in a SIGILL being delivered to the process (same as for undefined
instructions).

Signed-off-by: Kristina Martsenko <kristina.martsenko@arm.com>
Link: https://lore.kernel.org/r/20220622115424.683520-1-kristina.martsenko@arm.com
Signed-off-by: Will Deacon <will@kernel.org>
arch/arm64/include/asm/sysreg.h
arch/arm64/kernel/cpufeature.c
arch/arm64/tools/cpucaps

index 42ff95dba6da41a95785188df0b6e94b484c7e29..a8732507f298e12a2c63c56b545c38982850be54 100644 (file)
 
 /* id_aa64mmfr1 */
 #define ID_AA64MMFR1_ECBHB_SHIFT       60
+#define ID_AA64MMFR1_TIDCP1_SHIFT      52
 #define ID_AA64MMFR1_HCX_SHIFT         40
 #define ID_AA64MMFR1_AFP_SHIFT         44
 #define ID_AA64MMFR1_ETS_SHIFT         36
 #define ID_AA64MMFR1_VMIDBITS_8                0
 #define ID_AA64MMFR1_VMIDBITS_16       2
 
+#define ID_AA64MMFR1_TIDCP1_NI         0
+#define ID_AA64MMFR1_TIDCP1_IMP                1
+
 /* id_aa64mmfr2 */
 #define ID_AA64MMFR2_E0PD_SHIFT                60
 #define ID_AA64MMFR2_EVT_SHIFT         56
index 8d88433de81da0a0ecf890f8328433fa4a0c4d9a..9daa38b014b4049f8ee42eebec735f5a27b0418f 100644 (file)
@@ -361,6 +361,7 @@ static const struct arm64_ftr_bits ftr_id_aa64mmfr0[] = {
 };
 
 static const struct arm64_ftr_bits ftr_id_aa64mmfr1[] = {
+       ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_TIDCP1_SHIFT, 4, 0),
        ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_AFP_SHIFT, 4, 0),
        ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_ETS_SHIFT, 4, 0),
        ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_TWED_SHIFT, 4, 0),
@@ -1978,6 +1979,11 @@ static bool is_kvm_protected_mode(const struct arm64_cpu_capabilities *entry, in
 }
 #endif /* CONFIG_KVM */
 
+static void cpu_trap_el0_impdef(const struct arm64_cpu_capabilities *__unused)
+{
+       sysreg_clear_set(sctlr_el1, 0, SCTLR_EL1_TIDCP);
+}
+
 /* Internal helper functions to match cpu capability type */
 static bool
 cpucap_late_cpu_optional(const struct arm64_cpu_capabilities *cap)
@@ -2521,6 +2527,18 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
                .matches = has_cpuid_feature,
                .min_field_value = ID_AA64ISAR2_WFXT_SUPPORTED,
        },
+       {
+               .desc = "Trap EL0 IMPLEMENTATION DEFINED functionality",
+               .capability = ARM64_HAS_TIDCP1,
+               .type = ARM64_CPUCAP_SYSTEM_FEATURE,
+               .sys_reg = SYS_ID_AA64MMFR1_EL1,
+               .sign = FTR_UNSIGNED,
+               .field_pos = ID_AA64MMFR1_TIDCP1_SHIFT,
+               .field_width = 4,
+               .min_field_value = ID_AA64MMFR1_TIDCP1_IMP,
+               .matches = has_cpuid_feature,
+               .cpu_enable = cpu_trap_el0_impdef,
+       },
        {},
 };
 
index 507b20373953950c9dca2adb9e7d3033074803cb..e491d89913c20f3b452679c861ffe79dab8197c6 100644 (file)
@@ -36,6 +36,7 @@ HAS_RNG
 HAS_SB
 HAS_STAGE2_FWB
 HAS_SYSREG_GIC_CPUIF
+HAS_TIDCP1
 HAS_TLB_RANGE
 HAS_VIRT_HOST_EXTN
 HAS_WFXT