arm/arm64: Make use of the SMCCC 1.1 wrapper

Rather than directly choosing which function to use based on
psci_ops.conduit, use the new arm_smccc_1_1 wrapper instead.

In some cases we still need to do some operations based on the
conduit, but the code duplication is removed.

No functional change.

Signed-off-by: Steven Price <steven.price@arm.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
This commit is contained in:
Steven Price 2019-10-21 16:28:22 +01:00 committed by Marc Zyngier
parent 541625ac47
commit ce4d5ca2b9
2 changed files with 34 additions and 60 deletions

View File

@ -74,12 +74,13 @@ static void cpu_v7_spectre_init(void)
case ARM_CPU_PART_CORTEX_A72: { case ARM_CPU_PART_CORTEX_A72: {
struct arm_smccc_res res; struct arm_smccc_res res;
arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
ARM_SMCCC_ARCH_WORKAROUND_1, &res);
if ((int)res.a0 != 0)
return;
switch (arm_smccc_1_1_get_conduit()) { switch (arm_smccc_1_1_get_conduit()) {
case SMCCC_CONDUIT_HVC: case SMCCC_CONDUIT_HVC:
arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
ARM_SMCCC_ARCH_WORKAROUND_1, &res);
if ((int)res.a0 != 0)
break;
per_cpu(harden_branch_predictor_fn, cpu) = per_cpu(harden_branch_predictor_fn, cpu) =
call_hvc_arch_workaround_1; call_hvc_arch_workaround_1;
cpu_do_switch_mm = cpu_v7_hvc_switch_mm; cpu_do_switch_mm = cpu_v7_hvc_switch_mm;
@ -87,10 +88,6 @@ static void cpu_v7_spectre_init(void)
break; break;
case SMCCC_CONDUIT_SMC: case SMCCC_CONDUIT_SMC:
arm_smccc_1_1_smc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
ARM_SMCCC_ARCH_WORKAROUND_1, &res);
if ((int)res.a0 != 0)
break;
per_cpu(harden_branch_predictor_fn, cpu) = per_cpu(harden_branch_predictor_fn, cpu) =
call_smc_arch_workaround_1; call_smc_arch_workaround_1;
cpu_do_switch_mm = cpu_v7_smc_switch_mm; cpu_do_switch_mm = cpu_v7_smc_switch_mm;

View File

@ -209,40 +209,31 @@ static int detect_harden_bp_fw(void)
struct arm_smccc_res res; struct arm_smccc_res res;
u32 midr = read_cpuid_id(); u32 midr = read_cpuid_id();
arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
ARM_SMCCC_ARCH_WORKAROUND_1, &res);
switch ((int)res.a0) {
case 1:
/* Firmware says we're just fine */
return 0;
case 0:
break;
default:
return -1;
}
switch (arm_smccc_1_1_get_conduit()) { switch (arm_smccc_1_1_get_conduit()) {
case SMCCC_CONDUIT_HVC: case SMCCC_CONDUIT_HVC:
arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID, cb = call_hvc_arch_workaround_1;
ARM_SMCCC_ARCH_WORKAROUND_1, &res); /* This is a guest, no need to patch KVM vectors */
switch ((int)res.a0) { smccc_start = NULL;
case 1: smccc_end = NULL;
/* Firmware says we're just fine */
return 0;
case 0:
cb = call_hvc_arch_workaround_1;
/* This is a guest, no need to patch KVM vectors */
smccc_start = NULL;
smccc_end = NULL;
break;
default:
return -1;
}
break; break;
case SMCCC_CONDUIT_SMC: case SMCCC_CONDUIT_SMC:
arm_smccc_1_1_smc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID, cb = call_smc_arch_workaround_1;
ARM_SMCCC_ARCH_WORKAROUND_1, &res); smccc_start = __smccc_workaround_1_smc_start;
switch ((int)res.a0) { smccc_end = __smccc_workaround_1_smc_end;
case 1:
/* Firmware says we're just fine */
return 0;
case 0:
cb = call_smc_arch_workaround_1;
smccc_start = __smccc_workaround_1_smc_start;
smccc_end = __smccc_workaround_1_smc_end;
break;
default:
return -1;
}
break; break;
default: default:
@ -332,6 +323,8 @@ void __init arm64_enable_wa2_handling(struct alt_instr *alt,
void arm64_set_ssbd_mitigation(bool state) void arm64_set_ssbd_mitigation(bool state)
{ {
int conduit;
if (!IS_ENABLED(CONFIG_ARM64_SSBD)) { if (!IS_ENABLED(CONFIG_ARM64_SSBD)) {
pr_info_once("SSBD disabled by kernel configuration\n"); pr_info_once("SSBD disabled by kernel configuration\n");
return; return;
@ -345,19 +338,10 @@ void arm64_set_ssbd_mitigation(bool state)
return; return;
} }
switch (arm_smccc_1_1_get_conduit()) { conduit = arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_WORKAROUND_2, state,
case SMCCC_CONDUIT_HVC: NULL);
arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_WORKAROUND_2, state, NULL);
break;
case SMCCC_CONDUIT_SMC: WARN_ON_ONCE(conduit == SMCCC_CONDUIT_NONE);
arm_smccc_1_1_smc(ARM_SMCCC_ARCH_WORKAROUND_2, state, NULL);
break;
default:
WARN_ON_ONCE(1);
break;
}
} }
static bool has_ssbd_mitigation(const struct arm64_cpu_capabilities *entry, static bool has_ssbd_mitigation(const struct arm64_cpu_capabilities *entry,
@ -367,6 +351,7 @@ static bool has_ssbd_mitigation(const struct arm64_cpu_capabilities *entry,
bool required = true; bool required = true;
s32 val; s32 val;
bool this_cpu_safe = false; bool this_cpu_safe = false;
int conduit;
WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible()); WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
@ -384,18 +369,10 @@ static bool has_ssbd_mitigation(const struct arm64_cpu_capabilities *entry,
goto out_printmsg; goto out_printmsg;
} }
switch (arm_smccc_1_1_get_conduit()) { conduit = arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
case SMCCC_CONDUIT_HVC: ARM_SMCCC_ARCH_WORKAROUND_2, &res);
arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
ARM_SMCCC_ARCH_WORKAROUND_2, &res);
break;
case SMCCC_CONDUIT_SMC: if (conduit == SMCCC_CONDUIT_NONE) {
arm_smccc_1_1_smc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
ARM_SMCCC_ARCH_WORKAROUND_2, &res);
break;
default:
ssbd_state = ARM64_SSBD_UNKNOWN; ssbd_state = ARM64_SSBD_UNKNOWN;
if (!this_cpu_safe) if (!this_cpu_safe)
__ssb_safe = false; __ssb_safe = false;