Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) #include <linux/arm-smccc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) #include <linux/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <asm/cp15.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <asm/cputype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <asm/proc-fns.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <asm/spectre.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <asm/system_misc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #ifdef CONFIG_ARM_PSCI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) static int __maybe_unused spectre_v2_get_cpu_fw_mitigation_state(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 	struct arm_smccc_res res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 	arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 			     ARM_SMCCC_ARCH_WORKAROUND_1, &res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 	switch ((int)res.a0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 	case SMCCC_RET_SUCCESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 		return SPECTRE_MITIGATED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 	case SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 		return SPECTRE_UNAFFECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 		return SPECTRE_VULNERABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) static int __maybe_unused spectre_v2_get_cpu_fw_mitigation_state(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	return SPECTRE_VULNERABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #ifdef CONFIG_HARDEN_BRANCH_PREDICTOR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) DEFINE_PER_CPU(harden_branch_predictor_fn_t, harden_branch_predictor_fn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) extern void cpu_v7_iciallu_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) extern void cpu_v7_bpiall_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) extern void cpu_v7_smc_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) extern void cpu_v7_hvc_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) static void harden_branch_predictor_bpiall(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	write_sysreg(0, BPIALL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) static void harden_branch_predictor_iciallu(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	write_sysreg(0, ICIALLU);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) static void __maybe_unused call_smc_arch_workaround_1(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	arm_smccc_1_1_smc(ARM_SMCCC_ARCH_WORKAROUND_1, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) static void __maybe_unused call_hvc_arch_workaround_1(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_WORKAROUND_1, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) static unsigned int spectre_v2_install_workaround(unsigned int method)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	const char *spectre_v2_method = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	int cpu = smp_processor_id();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	if (per_cpu(harden_branch_predictor_fn, cpu))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		return SPECTRE_MITIGATED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	switch (method) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	case SPECTRE_V2_METHOD_BPIALL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 		per_cpu(harden_branch_predictor_fn, cpu) =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 			harden_branch_predictor_bpiall;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		spectre_v2_method = "BPIALL";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	case SPECTRE_V2_METHOD_ICIALLU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		per_cpu(harden_branch_predictor_fn, cpu) =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 			harden_branch_predictor_iciallu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		spectre_v2_method = "ICIALLU";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	case SPECTRE_V2_METHOD_HVC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		per_cpu(harden_branch_predictor_fn, cpu) =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 			call_hvc_arch_workaround_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		cpu_do_switch_mm = cpu_v7_hvc_switch_mm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		spectre_v2_method = "hypervisor";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	case SPECTRE_V2_METHOD_SMC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		per_cpu(harden_branch_predictor_fn, cpu) =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 			call_smc_arch_workaround_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		cpu_do_switch_mm = cpu_v7_smc_switch_mm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		spectre_v2_method = "firmware";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	if (spectre_v2_method)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		pr_info("CPU%u: Spectre v2: using %s workaround\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 			smp_processor_id(), spectre_v2_method);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	return SPECTRE_MITIGATED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static unsigned int spectre_v2_install_workaround(unsigned int method)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	pr_info("CPU%u: Spectre V2: workarounds disabled by configuration\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		smp_processor_id());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	return SPECTRE_VULNERABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static void cpu_v7_spectre_v2_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	unsigned int state, method = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	switch (read_cpuid_part()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	case ARM_CPU_PART_CORTEX_A8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	case ARM_CPU_PART_CORTEX_A9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	case ARM_CPU_PART_CORTEX_A12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	case ARM_CPU_PART_CORTEX_A17:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	case ARM_CPU_PART_CORTEX_A73:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	case ARM_CPU_PART_CORTEX_A75:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 		state = SPECTRE_MITIGATED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		method = SPECTRE_V2_METHOD_BPIALL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	case ARM_CPU_PART_CORTEX_A15:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	case ARM_CPU_PART_BRAHMA_B15:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		state = SPECTRE_MITIGATED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 		method = SPECTRE_V2_METHOD_ICIALLU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	case ARM_CPU_PART_BRAHMA_B53:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 		/* Requires no workaround */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 		state = SPECTRE_UNAFFECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 		/* Other ARM CPUs require no workaround */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 		if (read_cpuid_implementor() == ARM_CPU_IMP_ARM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 			state = SPECTRE_UNAFFECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	/* Cortex A57/A72 require firmware workaround */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	case ARM_CPU_PART_CORTEX_A57:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	case ARM_CPU_PART_CORTEX_A72:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		state = spectre_v2_get_cpu_fw_mitigation_state();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		if (state != SPECTRE_MITIGATED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		switch (arm_smccc_1_1_get_conduit()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		case SMCCC_CONDUIT_HVC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 			method = SPECTRE_V2_METHOD_HVC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		case SMCCC_CONDUIT_SMC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 			method = SPECTRE_V2_METHOD_SMC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 			state = SPECTRE_VULNERABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	if (state == SPECTRE_MITIGATED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 		state = spectre_v2_install_workaround(method);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	spectre_v2_update_state(state, method);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) #ifdef CONFIG_HARDEN_BRANCH_HISTORY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) static int spectre_bhb_method;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) static const char *spectre_bhb_method_name(int method)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	switch (method) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	case SPECTRE_V2_METHOD_LOOP8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 		return "loop";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	case SPECTRE_V2_METHOD_BPIALL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		return "BPIALL";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 		return "unknown";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) static int spectre_bhb_install_workaround(int method)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	if (spectre_bhb_method != method) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 		if (spectre_bhb_method) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 			pr_err("CPU%u: Spectre BHB: method disagreement, system vulnerable\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 			       smp_processor_id());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 			return SPECTRE_VULNERABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		if (spectre_bhb_update_vectors(method) == SPECTRE_VULNERABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 			return SPECTRE_VULNERABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		spectre_bhb_method = method;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	pr_info("CPU%u: Spectre BHB: using %s workaround\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 		smp_processor_id(), spectre_bhb_method_name(method));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	return SPECTRE_MITIGATED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) static int spectre_bhb_install_workaround(int method)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	return SPECTRE_VULNERABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) static void cpu_v7_spectre_bhb_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	unsigned int state, method = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	switch (read_cpuid_part()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	case ARM_CPU_PART_CORTEX_A15:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	case ARM_CPU_PART_BRAHMA_B15:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	case ARM_CPU_PART_CORTEX_A57:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	case ARM_CPU_PART_CORTEX_A72:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		state = SPECTRE_MITIGATED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		method = SPECTRE_V2_METHOD_LOOP8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	case ARM_CPU_PART_CORTEX_A73:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	case ARM_CPU_PART_CORTEX_A75:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		state = SPECTRE_MITIGATED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		method = SPECTRE_V2_METHOD_BPIALL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		state = SPECTRE_UNAFFECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	if (state == SPECTRE_MITIGATED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 		state = spectre_bhb_install_workaround(method);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	spectre_v2_update_state(state, method);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) static __maybe_unused bool cpu_v7_check_auxcr_set(bool *warned,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 						  u32 mask, const char *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	u32 aux_cr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	asm("mrc p15, 0, %0, c1, c0, 1" : "=r" (aux_cr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	if ((aux_cr & mask) != mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 		if (!*warned)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 			pr_err("CPU%u: %s", smp_processor_id(), msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 		*warned = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) static DEFINE_PER_CPU(bool, spectre_warned);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) static bool check_spectre_auxcr(bool *warned, u32 bit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	return IS_ENABLED(CONFIG_HARDEN_BRANCH_PREDICTOR) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 		cpu_v7_check_auxcr_set(warned, bit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 				       "Spectre v2: firmware did not set auxiliary control register IBE bit, system vulnerable\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) void cpu_v7_ca8_ibe(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	if (check_spectre_auxcr(this_cpu_ptr(&spectre_warned), BIT(6)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 		cpu_v7_spectre_v2_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) void cpu_v7_ca15_ibe(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	if (check_spectre_auxcr(this_cpu_ptr(&spectre_warned), BIT(0)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		cpu_v7_spectre_v2_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) void cpu_v7_bugs_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	cpu_v7_spectre_v2_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	cpu_v7_spectre_bhb_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }