Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
dcac930e
Commit
dcac930e
authored
Oct 21, 2019
by
Marc Zyngier
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'arm64/for-next/smccc-conduit-cleanup' into kvm-arm64/stolen-time
parents
4f5cafb5
e6ea4651
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
57 additions
and
60 deletions
+57
-60
arch/arm/mm/proc-v7-bugs.c
arch/arm/mm/proc-v7-bugs.c
+3
-7
arch/arm64/kernel/cpu_errata.c
arch/arm64/kernel/cpu_errata.c
+12
-25
arch/arm64/kernel/sdei.c
arch/arm64/kernel/sdei.c
+2
-1
drivers/firmware/arm_sdei.c
drivers/firmware/arm_sdei.c
+6
-6
drivers/firmware/psci/psci.c
drivers/firmware/psci/psci.c
+16
-8
include/linux/arm-smccc.h
include/linux/arm-smccc.h
+16
-0
include/linux/arm_sdei.h
include/linux/arm_sdei.h
+0
-6
include/linux/psci.h
include/linux/psci.h
+2
-7
No files found.
arch/arm/mm/proc-v7-bugs.c
View file @
dcac930e
// 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
)
...
...
arch/arm64/kernel/cpu_errata.c
View file @
dcac930e
...
@@ -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
;
...
...
arch/arm64/kernel/sdei.c
View file @
dcac930e
...
@@ -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
())
{
...
...
drivers/firmware/arm_sdei.c
View file @
dcac930e
...
@@ -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
)
...
...
drivers/firmware/psci/psci.c
View file @
dcac930e
...
@@ -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
();
}
}
...
...
include/linux/arm-smccc.h
View file @
dcac930e
...
@@ -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
...
...
include/linux/arm_sdei.h
View file @
dcac930e
...
@@ -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
...
...
include/linux/psci.h
View file @
dcac930e
...
@@ -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
;
};
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment