mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-01 06:04:48 -04:00
Merge remote-tracking branch 'arm64/for-next/smccc-conduit-cleanup' into kvm-arm64/stolen-time
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
// 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)
|
||||
|
||||
@@ -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,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()) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -80,6 +80,22 @@
|
||||
|
||||
#include <linux/linkage.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
|
||||
* @a0-a3 result values from registers 0 to 3
|
||||
|
||||
@@ -5,12 +5,6 @@
|
||||
|
||||
#include <uapi/linux/arm_sdei.h>
|
||||
|
||||
enum sdei_conduit_types {
|
||||
CONDUIT_INVALID = 0,
|
||||
CONDUIT_SMC,
|
||||
CONDUIT_HVC,
|
||||
};
|
||||
|
||||
#include <acpi/ghes.h>
|
||||
|
||||
#ifdef CONFIG_ARM_SDE_INTERFACE
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#ifndef __LINUX_PSCI_H
|
||||
#define __LINUX_PSCI_H
|
||||
|
||||
#include <linux/arm-smccc.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
@@ -18,12 +19,6 @@ bool psci_tos_resident_on(int cpu);
|
||||
int psci_cpu_suspend_enter(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 {
|
||||
SMCCC_VERSION_1_0,
|
||||
SMCCC_VERSION_1_1,
|
||||
@@ -38,7 +33,7 @@ struct psci_operations {
|
||||
int (*affinity_info)(unsigned long target_affinity,
|
||||
unsigned long lowest_affinity_level);
|
||||
int (*migrate_info_type)(void);
|
||||
enum psci_conduit conduit;
|
||||
enum arm_smccc_conduit conduit;
|
||||
enum smccc_version smccc_version;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user