Commit dcac930e authored by Marc Zyngier's avatar Marc Zyngier

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

parents 4f5cafb5 e6ea4651
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
#include <linux/arm-smccc.h> #include <linux/arm-smccc.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/psci.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <asm/cp15.h> #include <asm/cp15.h>
...@@ -75,11 +74,8 @@ static void cpu_v7_spectre_init(void) ...@@ -75,11 +74,8 @@ 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;
if (psci_ops.smccc_version == SMCCC_VERSION_1_0) switch (arm_smccc_1_1_get_conduit()) {
break; case SMCCC_CONDUIT_HVC:
switch (psci_ops.conduit) {
case PSCI_CONDUIT_HVC:
arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID, arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
ARM_SMCCC_ARCH_WORKAROUND_1, &res); ARM_SMCCC_ARCH_WORKAROUND_1, &res);
if ((int)res.a0 != 0) if ((int)res.a0 != 0)
...@@ -90,7 +86,7 @@ static void cpu_v7_spectre_init(void) ...@@ -90,7 +86,7 @@ static void cpu_v7_spectre_init(void)
spectre_v2_method = "hypervisor"; spectre_v2_method = "hypervisor";
break; break;
case PSCI_CONDUIT_SMC: case SMCCC_CONDUIT_SMC:
arm_smccc_1_1_smc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID, arm_smccc_1_1_smc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
ARM_SMCCC_ARCH_WORKAROUND_1, &res); ARM_SMCCC_ARCH_WORKAROUND_1, &res);
if ((int)res.a0 != 0) if ((int)res.a0 != 0)
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
*/ */
#include <linux/arm-smccc.h> #include <linux/arm-smccc.h>
#include <linux/psci.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/cpu.h> #include <linux/cpu.h>
#include <asm/cpu.h> #include <asm/cpu.h>
...@@ -166,9 +165,7 @@ static void install_bp_hardening_cb(bp_hardening_cb_t fn, ...@@ -166,9 +165,7 @@ static void install_bp_hardening_cb(bp_hardening_cb_t fn,
} }
#endif /* CONFIG_KVM_INDIRECT_VECTORS */ #endif /* CONFIG_KVM_INDIRECT_VECTORS */
#include <uapi/linux/psci.h>
#include <linux/arm-smccc.h> #include <linux/arm-smccc.h>
#include <linux/psci.h>
static void call_smc_arch_workaround_1(void) static void call_smc_arch_workaround_1(void)
{ {
...@@ -212,11 +209,8 @@ static int detect_harden_bp_fw(void) ...@@ -212,11 +209,8 @@ 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();
if (psci_ops.smccc_version == SMCCC_VERSION_1_0) switch (arm_smccc_1_1_get_conduit()) {
return -1; case SMCCC_CONDUIT_HVC:
switch (psci_ops.conduit) {
case PSCI_CONDUIT_HVC:
arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID, arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
ARM_SMCCC_ARCH_WORKAROUND_1, &res); ARM_SMCCC_ARCH_WORKAROUND_1, &res);
switch ((int)res.a0) { switch ((int)res.a0) {
...@@ -234,7 +228,7 @@ static int detect_harden_bp_fw(void) ...@@ -234,7 +228,7 @@ static int detect_harden_bp_fw(void)
} }
break; break;
case PSCI_CONDUIT_SMC: case SMCCC_CONDUIT_SMC:
arm_smccc_1_1_smc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID, arm_smccc_1_1_smc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
ARM_SMCCC_ARCH_WORKAROUND_1, &res); ARM_SMCCC_ARCH_WORKAROUND_1, &res);
switch ((int)res.a0) { switch ((int)res.a0) {
...@@ -308,11 +302,11 @@ void __init arm64_update_smccc_conduit(struct alt_instr *alt, ...@@ -308,11 +302,11 @@ void __init arm64_update_smccc_conduit(struct alt_instr *alt,
BUG_ON(nr_inst != 1); BUG_ON(nr_inst != 1);
switch (psci_ops.conduit) { switch (arm_smccc_1_1_get_conduit()) {
case PSCI_CONDUIT_HVC: case SMCCC_CONDUIT_HVC:
insn = aarch64_insn_get_hvc_value(); insn = aarch64_insn_get_hvc_value();
break; break;
case PSCI_CONDUIT_SMC: case SMCCC_CONDUIT_SMC:
insn = aarch64_insn_get_smc_value(); insn = aarch64_insn_get_smc_value();
break; break;
default: default:
...@@ -351,12 +345,12 @@ void arm64_set_ssbd_mitigation(bool state) ...@@ -351,12 +345,12 @@ void arm64_set_ssbd_mitigation(bool state)
return; return;
} }
switch (psci_ops.conduit) { switch (arm_smccc_1_1_get_conduit()) {
case PSCI_CONDUIT_HVC: case SMCCC_CONDUIT_HVC:
arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_WORKAROUND_2, state, NULL); arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_WORKAROUND_2, state, NULL);
break; break;
case PSCI_CONDUIT_SMC: case SMCCC_CONDUIT_SMC:
arm_smccc_1_1_smc(ARM_SMCCC_ARCH_WORKAROUND_2, state, NULL); arm_smccc_1_1_smc(ARM_SMCCC_ARCH_WORKAROUND_2, state, NULL);
break; break;
...@@ -390,20 +384,13 @@ static bool has_ssbd_mitigation(const struct arm64_cpu_capabilities *entry, ...@@ -390,20 +384,13 @@ static bool has_ssbd_mitigation(const struct arm64_cpu_capabilities *entry,
goto out_printmsg; goto out_printmsg;
} }
if (psci_ops.smccc_version == SMCCC_VERSION_1_0) { switch (arm_smccc_1_1_get_conduit()) {
ssbd_state = ARM64_SSBD_UNKNOWN; case SMCCC_CONDUIT_HVC:
if (!this_cpu_safe)
__ssb_safe = false;
return false;
}
switch (psci_ops.conduit) {
case PSCI_CONDUIT_HVC:
arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID, arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
ARM_SMCCC_ARCH_WORKAROUND_2, &res); ARM_SMCCC_ARCH_WORKAROUND_2, &res);
break; break;
case PSCI_CONDUIT_SMC: case SMCCC_CONDUIT_SMC:
arm_smccc_1_1_smc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID, arm_smccc_1_1_smc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
ARM_SMCCC_ARCH_WORKAROUND_2, &res); ARM_SMCCC_ARCH_WORKAROUND_2, &res);
break; break;
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
// Copyright (C) 2017 Arm Ltd. // Copyright (C) 2017 Arm Ltd.
#define pr_fmt(fmt) "sdei: " fmt #define pr_fmt(fmt) "sdei: " fmt
#include <linux/arm-smccc.h>
#include <linux/arm_sdei.h> #include <linux/arm_sdei.h>
#include <linux/hardirq.h> #include <linux/hardirq.h>
#include <linux/irqflags.h> #include <linux/irqflags.h>
...@@ -161,7 +162,7 @@ unsigned long sdei_arch_get_entry_point(int conduit) ...@@ -161,7 +162,7 @@ unsigned long sdei_arch_get_entry_point(int conduit)
return 0; 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 #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
if (arm64_kernel_unmapped_at_el0()) { if (arm64_kernel_unmapped_at_el0()) {
......
...@@ -967,29 +967,29 @@ static int sdei_get_conduit(struct platform_device *pdev) ...@@ -967,29 +967,29 @@ static int sdei_get_conduit(struct platform_device *pdev)
if (np) { if (np) {
if (of_property_read_string(np, "method", &method)) { if (of_property_read_string(np, "method", &method)) {
pr_warn("missing \"method\" property\n"); pr_warn("missing \"method\" property\n");
return CONDUIT_INVALID; return SMCCC_CONDUIT_NONE;
} }
if (!strcmp("hvc", method)) { if (!strcmp("hvc", method)) {
sdei_firmware_call = &sdei_smccc_hvc; sdei_firmware_call = &sdei_smccc_hvc;
return CONDUIT_HVC; return SMCCC_CONDUIT_HVC;
} else if (!strcmp("smc", method)) { } else if (!strcmp("smc", method)) {
sdei_firmware_call = &sdei_smccc_smc; sdei_firmware_call = &sdei_smccc_smc;
return CONDUIT_SMC; return SMCCC_CONDUIT_SMC;
} }
pr_warn("invalid \"method\" property: %s\n", method); pr_warn("invalid \"method\" property: %s\n", method);
} else if (IS_ENABLED(CONFIG_ACPI) && !acpi_disabled) { } else if (IS_ENABLED(CONFIG_ACPI) && !acpi_disabled) {
if (acpi_psci_use_hvc()) { if (acpi_psci_use_hvc()) {
sdei_firmware_call = &sdei_smccc_hvc; sdei_firmware_call = &sdei_smccc_hvc;
return CONDUIT_HVC; return SMCCC_CONDUIT_HVC;
} else { } else {
sdei_firmware_call = &sdei_smccc_smc; 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) static int sdei_probe(struct platform_device *pdev)
......
...@@ -53,10 +53,18 @@ bool psci_tos_resident_on(int cpu) ...@@ -53,10 +53,18 @@ bool psci_tos_resident_on(int cpu)
} }
struct psci_operations psci_ops = { struct psci_operations psci_ops = {
.conduit = PSCI_CONDUIT_NONE, .conduit = SMCCC_CONDUIT_NONE,
.smccc_version = SMCCC_VERSION_1_0, .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, typedef unsigned long (psci_fn)(unsigned long, unsigned long,
unsigned long, unsigned long); unsigned long, unsigned long);
static psci_fn *invoke_psci_fn; static psci_fn *invoke_psci_fn;
...@@ -212,13 +220,13 @@ static unsigned long psci_migrate_info_up_cpu(void) ...@@ -212,13 +220,13 @@ static unsigned long psci_migrate_info_up_cpu(void)
0, 0, 0); 0, 0, 0);
} }
static void set_conduit(enum psci_conduit conduit) static void set_conduit(enum arm_smccc_conduit conduit)
{ {
switch (conduit) { switch (conduit) {
case PSCI_CONDUIT_HVC: case SMCCC_CONDUIT_HVC:
invoke_psci_fn = __invoke_psci_fn_hvc; invoke_psci_fn = __invoke_psci_fn_hvc;
break; break;
case PSCI_CONDUIT_SMC: case SMCCC_CONDUIT_SMC:
invoke_psci_fn = __invoke_psci_fn_smc; invoke_psci_fn = __invoke_psci_fn_smc;
break; break;
default: default:
...@@ -240,9 +248,9 @@ static int get_set_conduit_method(struct device_node *np) ...@@ -240,9 +248,9 @@ static int get_set_conduit_method(struct device_node *np)
} }
if (!strcmp("hvc", method)) { if (!strcmp("hvc", method)) {
set_conduit(PSCI_CONDUIT_HVC); set_conduit(SMCCC_CONDUIT_HVC);
} else if (!strcmp("smc", method)) { } else if (!strcmp("smc", method)) {
set_conduit(PSCI_CONDUIT_SMC); set_conduit(SMCCC_CONDUIT_SMC);
} else { } else {
pr_warn("invalid \"method\" property: %s\n", method); pr_warn("invalid \"method\" property: %s\n", method);
return -EINVAL; return -EINVAL;
...@@ -583,9 +591,9 @@ int __init psci_acpi_init(void) ...@@ -583,9 +591,9 @@ int __init psci_acpi_init(void)
pr_info("probing for conduit method from ACPI.\n"); pr_info("probing for conduit method from ACPI.\n");
if (acpi_psci_use_hvc()) if (acpi_psci_use_hvc())
set_conduit(PSCI_CONDUIT_HVC); set_conduit(SMCCC_CONDUIT_HVC);
else else
set_conduit(PSCI_CONDUIT_SMC); set_conduit(SMCCC_CONDUIT_SMC);
return psci_probe(); return psci_probe();
} }
......
...@@ -80,6 +80,22 @@ ...@@ -80,6 +80,22 @@
#include <linux/linkage.h> #include <linux/linkage.h>
#include <linux/types.h> #include <linux/types.h>
enum arm_smccc_conduit {
SMCCC_CONDUIT_NONE,
SMCCC_CONDUIT_SMC,
SMCCC_CONDUIT_HVC,
};
/**
* arm_smccc_1_1_get_conduit()
*
* Returns the conduit to be used for SMCCCv1.1 or later.
*
* When SMCCCv1.1 is not present, returns SMCCC_CONDUIT_NONE.
*/
enum arm_smccc_conduit arm_smccc_1_1_get_conduit(void);
/** /**
* struct arm_smccc_res - Result from SMC/HVC call * struct arm_smccc_res - Result from SMC/HVC call
* @a0-a3 result values from registers 0 to 3 * @a0-a3 result values from registers 0 to 3
......
...@@ -5,12 +5,6 @@ ...@@ -5,12 +5,6 @@
#include <uapi/linux/arm_sdei.h> #include <uapi/linux/arm_sdei.h>
enum sdei_conduit_types {
CONDUIT_INVALID = 0,
CONDUIT_SMC,
CONDUIT_HVC,
};
#include <acpi/ghes.h> #include <acpi/ghes.h>
#ifdef CONFIG_ARM_SDE_INTERFACE #ifdef CONFIG_ARM_SDE_INTERFACE
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#ifndef __LINUX_PSCI_H #ifndef __LINUX_PSCI_H
#define __LINUX_PSCI_H #define __LINUX_PSCI_H
#include <linux/arm-smccc.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/types.h> #include <linux/types.h>
...@@ -18,12 +19,6 @@ bool psci_tos_resident_on(int cpu); ...@@ -18,12 +19,6 @@ bool psci_tos_resident_on(int cpu);
int psci_cpu_suspend_enter(u32 state); int psci_cpu_suspend_enter(u32 state);
bool psci_power_state_is_valid(u32 state); bool psci_power_state_is_valid(u32 state);
enum psci_conduit {
PSCI_CONDUIT_NONE,
PSCI_CONDUIT_SMC,
PSCI_CONDUIT_HVC,
};
enum smccc_version { enum smccc_version {
SMCCC_VERSION_1_0, SMCCC_VERSION_1_0,
SMCCC_VERSION_1_1, SMCCC_VERSION_1_1,
...@@ -38,7 +33,7 @@ struct psci_operations { ...@@ -38,7 +33,7 @@ struct psci_operations {
int (*affinity_info)(unsigned long target_affinity, int (*affinity_info)(unsigned long target_affinity,
unsigned long lowest_affinity_level); unsigned long lowest_affinity_level);
int (*migrate_info_type)(void); int (*migrate_info_type)(void);
enum psci_conduit conduit; enum arm_smccc_conduit conduit;
enum smccc_version smccc_version; enum smccc_version smccc_version;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment