mirror of
https://github.com/torvalds/linux.git
synced 2024-10-27 15:21:45 +00:00
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:
parent
541625ac47
commit
ce4d5ca2b9
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user