Commit dcac930e authored by Marc Zyngier's avatar Marc Zyngier
Browse files

Merge remote-tracking branch 'arm64/for-next/smccc-conduit-cleanup' into kvm-arm64/stolen-time

parents 4f5cafb5 e6ea4651
Loading
Loading
Loading
Loading
+3 −7
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
#include <linux/arm-smccc.h>
#include <linux/kernel.h>
#include <linux/psci.h>
#include <linux/smp.h>

#include <asm/cp15.h>
@@ -75,11 +74,8 @@ static void cpu_v7_spectre_init(void)
	case ARM_CPU_PART_CORTEX_A72: {
		struct arm_smccc_res res;

		if (psci_ops.smccc_version == SMCCC_VERSION_1_0)
			break;

		switch (psci_ops.conduit) {
		case PSCI_CONDUIT_HVC:
		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_1, &res);
			if ((int)res.a0 != 0)
@@ -90,7 +86,7 @@ static void cpu_v7_spectre_init(void)
			spectre_v2_method = "hypervisor";
			break;

		case PSCI_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)
+12 −25
Original line number Diff line number Diff line
@@ -6,7 +6,6 @@
 */

#include <linux/arm-smccc.h>
#include <linux/psci.h>
#include <linux/types.h>
#include <linux/cpu.h>
#include <asm/cpu.h>
@@ -166,9 +165,7 @@ static void install_bp_hardening_cb(bp_hardening_cb_t fn,
}
#endif	/* CONFIG_KVM_INDIRECT_VECTORS */

#include <uapi/linux/psci.h>
#include <linux/arm-smccc.h>
#include <linux/psci.h>

static void call_smc_arch_workaround_1(void)
{
@@ -212,11 +209,8 @@ static int detect_harden_bp_fw(void)
	struct arm_smccc_res res;
	u32 midr = read_cpuid_id();

	if (psci_ops.smccc_version == SMCCC_VERSION_1_0)
		return -1;

	switch (psci_ops.conduit) {
	case PSCI_CONDUIT_HVC:
	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_1, &res);
		switch ((int)res.a0) {
@@ -234,7 +228,7 @@ static int detect_harden_bp_fw(void)
		}
		break;

	case PSCI_CONDUIT_SMC:
	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) {
@@ -308,11 +302,11 @@ void __init arm64_update_smccc_conduit(struct alt_instr *alt,

	BUG_ON(nr_inst != 1);

	switch (psci_ops.conduit) {
	case PSCI_CONDUIT_HVC:
	switch (arm_smccc_1_1_get_conduit()) {
	case SMCCC_CONDUIT_HVC:
		insn = aarch64_insn_get_hvc_value();
		break;
	case PSCI_CONDUIT_SMC:
	case SMCCC_CONDUIT_SMC:
		insn = aarch64_insn_get_smc_value();
		break;
	default:
@@ -351,12 +345,12 @@ void arm64_set_ssbd_mitigation(bool state)
		return;
	}

	switch (psci_ops.conduit) {
	case PSCI_CONDUIT_HVC:
	switch (arm_smccc_1_1_get_conduit()) {
	case SMCCC_CONDUIT_HVC:
		arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_WORKAROUND_2, state, NULL);
		break;

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

@@ -390,20 +384,13 @@ static bool has_ssbd_mitigation(const struct arm64_cpu_capabilities *entry,
		goto out_printmsg;
	}

	if (psci_ops.smccc_version == SMCCC_VERSION_1_0) {
		ssbd_state = ARM64_SSBD_UNKNOWN;
		if (!this_cpu_safe)
			__ssb_safe = false;
		return false;
	}

	switch (psci_ops.conduit) {
	case PSCI_CONDUIT_HVC:
	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 PSCI_CONDUIT_SMC:
	case SMCCC_CONDUIT_SMC:
		arm_smccc_1_1_smc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
				  ARM_SMCCC_ARCH_WORKAROUND_2, &res);
		break;
+2 −1
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@
// Copyright (C) 2017 Arm Ltd.
#define pr_fmt(fmt) "sdei: " fmt

#include <linux/arm-smccc.h>
#include <linux/arm_sdei.h>
#include <linux/hardirq.h>
#include <linux/irqflags.h>
@@ -161,7 +162,7 @@ unsigned long sdei_arch_get_entry_point(int conduit)
			return 0;
	}

	sdei_exit_mode = (conduit == CONDUIT_HVC) ? SDEI_EXIT_HVC : SDEI_EXIT_SMC;
	sdei_exit_mode = (conduit == SMCCC_CONDUIT_HVC) ? SDEI_EXIT_HVC : SDEI_EXIT_SMC;

#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
	if (arm64_kernel_unmapped_at_el0()) {
+6 −6
Original line number Diff line number Diff line
@@ -967,29 +967,29 @@ static int sdei_get_conduit(struct platform_device *pdev)
	if (np) {
		if (of_property_read_string(np, "method", &method)) {
			pr_warn("missing \"method\" property\n");
			return CONDUIT_INVALID;
			return SMCCC_CONDUIT_NONE;
		}

		if (!strcmp("hvc", method)) {
			sdei_firmware_call = &sdei_smccc_hvc;
			return CONDUIT_HVC;
			return SMCCC_CONDUIT_HVC;
		} else if (!strcmp("smc", method)) {
			sdei_firmware_call = &sdei_smccc_smc;
			return CONDUIT_SMC;
			return SMCCC_CONDUIT_SMC;
		}

		pr_warn("invalid \"method\" property: %s\n", method);
	} else if (IS_ENABLED(CONFIG_ACPI) && !acpi_disabled) {
		if (acpi_psci_use_hvc()) {
			sdei_firmware_call = &sdei_smccc_hvc;
			return CONDUIT_HVC;
			return SMCCC_CONDUIT_HVC;
		} else {
			sdei_firmware_call = &sdei_smccc_smc;
			return CONDUIT_SMC;
			return SMCCC_CONDUIT_SMC;
		}
	}

	return CONDUIT_INVALID;
	return SMCCC_CONDUIT_NONE;
}

static int sdei_probe(struct platform_device *pdev)
+16 −8
Original line number Diff line number Diff line
@@ -53,10 +53,18 @@ bool psci_tos_resident_on(int cpu)
}

struct psci_operations psci_ops = {
	.conduit = PSCI_CONDUIT_NONE,
	.conduit = SMCCC_CONDUIT_NONE,
	.smccc_version = SMCCC_VERSION_1_0,
};

enum arm_smccc_conduit arm_smccc_1_1_get_conduit(void)
{
	if (psci_ops.smccc_version < SMCCC_VERSION_1_1)
		return SMCCC_CONDUIT_NONE;

	return psci_ops.conduit;
}

typedef unsigned long (psci_fn)(unsigned long, unsigned long,
				unsigned long, unsigned long);
static psci_fn *invoke_psci_fn;
@@ -212,13 +220,13 @@ static unsigned long psci_migrate_info_up_cpu(void)
			      0, 0, 0);
}

static void set_conduit(enum psci_conduit conduit)
static void set_conduit(enum arm_smccc_conduit conduit)
{
	switch (conduit) {
	case PSCI_CONDUIT_HVC:
	case SMCCC_CONDUIT_HVC:
		invoke_psci_fn = __invoke_psci_fn_hvc;
		break;
	case PSCI_CONDUIT_SMC:
	case SMCCC_CONDUIT_SMC:
		invoke_psci_fn = __invoke_psci_fn_smc;
		break;
	default:
@@ -240,9 +248,9 @@ static int get_set_conduit_method(struct device_node *np)
	}

	if (!strcmp("hvc", method)) {
		set_conduit(PSCI_CONDUIT_HVC);
		set_conduit(SMCCC_CONDUIT_HVC);
	} else if (!strcmp("smc", method)) {
		set_conduit(PSCI_CONDUIT_SMC);
		set_conduit(SMCCC_CONDUIT_SMC);
	} else {
		pr_warn("invalid \"method\" property: %s\n", method);
		return -EINVAL;
@@ -583,9 +591,9 @@ int __init psci_acpi_init(void)
	pr_info("probing for conduit method from ACPI.\n");

	if (acpi_psci_use_hvc())
		set_conduit(PSCI_CONDUIT_HVC);
		set_conduit(SMCCC_CONDUIT_HVC);
	else
		set_conduit(PSCI_CONDUIT_SMC);
		set_conduit(SMCCC_CONDUIT_SMC);

	return psci_probe();
}
Loading