Commit ce4d5ca2 authored by Steven Price's avatar Steven Price Committed by Marc Zyngier
Browse files

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: default avatarSteven Price <steven.price@arm.com>
Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
parent 541625ac
Loading
Loading
Loading
Loading
+5 −8
Original line number Diff line number Diff line
@@ -74,12 +74,13 @@ static void cpu_v7_spectre_init(void)
	case ARM_CPU_PART_CORTEX_A72: {
		struct arm_smccc_res res;

		switch (arm_smccc_1_1_get_conduit()) {
		case SMCCC_CONDUIT_HVC:
			arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
		arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
				     ARM_SMCCC_ARCH_WORKAROUND_1, &res);
		if ((int)res.a0 != 0)
				break;
			return;

		switch (arm_smccc_1_1_get_conduit()) {
		case SMCCC_CONDUIT_HVC:
			per_cpu(harden_branch_predictor_fn, cpu) =
				call_hvc_arch_workaround_1;
			cpu_do_switch_mm = cpu_v7_hvc_switch_mm;
@@ -87,10 +88,6 @@ static void cpu_v7_spectre_init(void)
			break;

		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) =
				call_smc_arch_workaround_1;
			cpu_do_switch_mm = cpu_v7_smc_switch_mm;
+29 −52
Original line number Diff line number Diff line
@@ -209,41 +209,32 @@ static int detect_harden_bp_fw(void)
	struct arm_smccc_res res;
	u32 midr = read_cpuid_id();

	switch (arm_smccc_1_1_get_conduit()) {
	case SMCCC_CONDUIT_HVC:
		arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_FEATURES_FUNC_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:
			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;
	}

	switch (arm_smccc_1_1_get_conduit()) {
	case SMCCC_CONDUIT_HVC:
		cb = call_hvc_arch_workaround_1;
		/* This is a guest, no need to patch KVM vectors */
		smccc_start = NULL;
		smccc_end = NULL;
		break;

	case SMCCC_CONDUIT_SMC:
		arm_smccc_1_1_smc(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:
		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;

	default:
		return -1;
@@ -332,6 +323,8 @@ void __init arm64_enable_wa2_handling(struct alt_instr *alt,

void arm64_set_ssbd_mitigation(bool state)
{
	int conduit;

	if (!IS_ENABLED(CONFIG_ARM64_SSBD)) {
		pr_info_once("SSBD disabled by kernel configuration\n");
		return;
@@ -345,19 +338,10 @@ void arm64_set_ssbd_mitigation(bool state)
		return;
	}

	switch (arm_smccc_1_1_get_conduit()) {
	case SMCCC_CONDUIT_HVC:
		arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_WORKAROUND_2, state, NULL);
		break;
	conduit = arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_WORKAROUND_2, state,
				       NULL);

	case SMCCC_CONDUIT_SMC:
		arm_smccc_1_1_smc(ARM_SMCCC_ARCH_WORKAROUND_2, state, NULL);
		break;

	default:
		WARN_ON_ONCE(1);
		break;
	}
	WARN_ON_ONCE(conduit == SMCCC_CONDUIT_NONE);
}

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;
	s32 val;
	bool this_cpu_safe = false;
	int conduit;

	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;
	}

	switch (arm_smccc_1_1_get_conduit()) {
	case SMCCC_CONDUIT_HVC:
		arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
				  ARM_SMCCC_ARCH_WORKAROUND_2, &res);
		break;

	case SMCCC_CONDUIT_SMC:
		arm_smccc_1_1_smc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
	conduit = arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
				       ARM_SMCCC_ARCH_WORKAROUND_2, &res);
		break;

	default:
	if (conduit == SMCCC_CONDUIT_NONE) {
		ssbd_state = ARM64_SSBD_UNKNOWN;
		if (!this_cpu_safe)
			__ssb_safe = false;