Commit 2b7ced10 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux

Pull arm64 fixes from Will Deacon:
 "The major fix here is for a filesystem corruption issue reported on
  Apple M1 as a result of buggy management of the floating point
  register state introduced in 6.8. I initially reverted one of the
  offending patches, but in the end Ard cooked a proper fix so there's a
  revert+reapply in the series.

  Aside from that, we've got some CPU errata workarounds and misc other
  fixes.

   - Fix broken FP register state tracking which resulted in filesystem
     corruption when dm-crypt is used

   - Workarounds for Arm CPU errata affecting the SSBS Spectre
     mitigation

   - Fix lockdep assertion in DMC620 memory controller PMU driver

   - Fix alignment of BUG table when CONFIG_DEBUG_BUGVERBOSE is
     disabled"

* tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux:
  arm64/fpsimd: Avoid erroneous elide of user state reload
  Reapply "arm64: fpsimd: Implement lazy restore for kernel mode FPSIMD"
  arm64: asm-bug: Add .align 2 to the end of __BUG_ENTRY
  perf/arm-dmc620: Fix lockdep assert in ->event_init()
  Revert "arm64: fpsimd: Implement lazy restore for kernel mode FPSIMD"
  arm64: errata: Add workaround for Arm errata 3194386 and 3312417
  arm64: cputype: Add Neoverse-V3 definitions
  arm64: cputype: Add Cortex-X4 definitions
  arm64: barrier: Restore spec_bar() macro
parents 2ef32ad2 e92bee9f
...@@ -140,6 +140,8 @@ stable kernels. ...@@ -140,6 +140,8 @@ stable kernels.
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-X2 | #2224489 | ARM64_ERRATUM_2224489 | | ARM | Cortex-X2 | #2224489 | ARM64_ERRATUM_2224489 |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-X4 | #3194386 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-N1 | #1188873,1418040| ARM64_ERRATUM_1418040 | | ARM | Neoverse-N1 | #1188873,1418040| ARM64_ERRATUM_1418040 |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-N1 | #1349291 | N/A | | ARM | Neoverse-N1 | #1349291 | N/A |
...@@ -156,6 +158,8 @@ stable kernels. ...@@ -156,6 +158,8 @@ stable kernels.
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-V1 | #1619801 | N/A | | ARM | Neoverse-V1 | #1619801 | N/A |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-V3 | #3312417 | ARM64_ERRATUM_3312417 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | MMU-500 | #841119,826419 | N/A | | ARM | MMU-500 | #841119,826419 | N/A |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | MMU-600 | #1076982,1209401| N/A | | ARM | MMU-600 | #1076982,1209401| N/A |
......
...@@ -1067,6 +1067,48 @@ config ARM64_ERRATUM_3117295 ...@@ -1067,6 +1067,48 @@ config ARM64_ERRATUM_3117295
If unsure, say Y. If unsure, say Y.
config ARM64_WORKAROUND_SPECULATIVE_SSBS
bool
config ARM64_ERRATUM_3194386
bool "Cortex-X4: 3194386: workaround for MSR SSBS not self-synchronizing"
select ARM64_WORKAROUND_SPECULATIVE_SSBS
default y
help
This option adds the workaround for ARM Cortex-X4 erratum 3194386.
On affected cores "MSR SSBS, #0" instructions may not affect
subsequent speculative instructions, which may permit unexepected
speculative store bypassing.
Work around this problem by placing a speculation barrier after
kernel changes to SSBS. The presence of the SSBS special-purpose
register is hidden from hwcaps and EL0 reads of ID_AA64PFR1_EL1, such
that userspace will use the PR_SPEC_STORE_BYPASS prctl to change
SSBS.
If unsure, say Y.
config ARM64_ERRATUM_3312417
bool "Neoverse-V3: 3312417: workaround for MSR SSBS not self-synchronizing"
select ARM64_WORKAROUND_SPECULATIVE_SSBS
default y
help
This option adds the workaround for ARM Neoverse-V3 erratum 3312417.
On affected cores "MSR SSBS, #0" instructions may not affect
subsequent speculative instructions, which may permit unexepected
speculative store bypassing.
Work around this problem by placing a speculation barrier after
kernel changes to SSBS. The presence of the SSBS special-purpose
register is hidden from hwcaps and EL0 reads of ID_AA64PFR1_EL1, such
that userspace will use the PR_SPEC_STORE_BYPASS prctl to change
SSBS.
If unsure, say Y.
config CAVIUM_ERRATUM_22375 config CAVIUM_ERRATUM_22375
bool "Cavium erratum 22375, 24313" bool "Cavium erratum 22375, 24313"
default y default y
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
14470: .long 14471f - .; \ 14470: .long 14471f - .; \
_BUGVERBOSE_LOCATION(__FILE__, __LINE__) \ _BUGVERBOSE_LOCATION(__FILE__, __LINE__) \
.short flags; \ .short flags; \
.align 2; \
.popsection; \ .popsection; \
14471: 14471:
#else #else
......
...@@ -40,6 +40,10 @@ ...@@ -40,6 +40,10 @@
*/ */
#define dgh() asm volatile("hint #6" : : : "memory") #define dgh() asm volatile("hint #6" : : : "memory")
#define spec_bar() asm volatile(ALTERNATIVE("dsb nsh\nisb\n", \
SB_BARRIER_INSN"nop\n", \
ARM64_HAS_SB))
#ifdef CONFIG_ARM64_PSEUDO_NMI #ifdef CONFIG_ARM64_PSEUDO_NMI
#define pmr_sync() \ #define pmr_sync() \
do { \ do { \
......
...@@ -58,6 +58,8 @@ cpucap_is_possible(const unsigned int cap) ...@@ -58,6 +58,8 @@ cpucap_is_possible(const unsigned int cap)
return IS_ENABLED(CONFIG_NVIDIA_CARMEL_CNP_ERRATUM); return IS_ENABLED(CONFIG_NVIDIA_CARMEL_CNP_ERRATUM);
case ARM64_WORKAROUND_REPEAT_TLBI: case ARM64_WORKAROUND_REPEAT_TLBI:
return IS_ENABLED(CONFIG_ARM64_WORKAROUND_REPEAT_TLBI); return IS_ENABLED(CONFIG_ARM64_WORKAROUND_REPEAT_TLBI);
case ARM64_WORKAROUND_SPECULATIVE_SSBS:
return IS_ENABLED(CONFIG_ARM64_WORKAROUND_SPECULATIVE_SSBS);
} }
return true; return true;
......
...@@ -87,6 +87,8 @@ ...@@ -87,6 +87,8 @@
#define ARM_CPU_PART_NEOVERSE_N2 0xD49 #define ARM_CPU_PART_NEOVERSE_N2 0xD49
#define ARM_CPU_PART_CORTEX_A78C 0xD4B #define ARM_CPU_PART_CORTEX_A78C 0xD4B
#define ARM_CPU_PART_NEOVERSE_V2 0xD4F #define ARM_CPU_PART_NEOVERSE_V2 0xD4F
#define ARM_CPU_PART_CORTEX_X4 0xD82
#define ARM_CPU_PART_NEOVERSE_V3 0xD84
#define APM_CPU_PART_XGENE 0x000 #define APM_CPU_PART_XGENE 0x000
#define APM_CPU_VAR_POTENZA 0x00 #define APM_CPU_VAR_POTENZA 0x00
...@@ -161,6 +163,8 @@ ...@@ -161,6 +163,8 @@
#define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2) #define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2)
#define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C) #define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C)
#define MIDR_NEOVERSE_V2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V2) #define MIDR_NEOVERSE_V2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V2)
#define MIDR_CORTEX_X4 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X4)
#define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3)
#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX) #define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
#define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX) #define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)
#define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX) #define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX)
......
...@@ -432,6 +432,18 @@ static const struct midr_range erratum_spec_unpriv_load_list[] = { ...@@ -432,6 +432,18 @@ static const struct midr_range erratum_spec_unpriv_load_list[] = {
}; };
#endif #endif
#ifdef CONFIG_ARM64_WORKAROUND_SPECULATIVE_SSBS
static const struct midr_range erratum_spec_ssbs_list[] = {
#ifdef CONFIG_ARM64_ERRATUM_3194386
MIDR_ALL_VERSIONS(MIDR_CORTEX_X4),
#endif
#ifdef CONFIG_ARM64_ERRATUM_3312417
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V3),
#endif
{}
};
#endif
const struct arm64_cpu_capabilities arm64_errata[] = { const struct arm64_cpu_capabilities arm64_errata[] = {
#ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE #ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE
{ {
...@@ -729,6 +741,13 @@ const struct arm64_cpu_capabilities arm64_errata[] = { ...@@ -729,6 +741,13 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
MIDR_FIXED(MIDR_CPU_VAR_REV(1,1), BIT(25)), MIDR_FIXED(MIDR_CPU_VAR_REV(1,1), BIT(25)),
}, },
#endif #endif
#ifdef CONFIG_ARM64_WORKAROUND_SPECULATIVE_SSBS
{
.desc = "ARM errata 3194386, 3312417",
.capability = ARM64_WORKAROUND_SPECULATIVE_SSBS,
ERRATA_MIDR_RANGE_LIST(erratum_spec_ssbs_list),
},
#endif
#ifdef CONFIG_ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD #ifdef CONFIG_ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD
{ {
.desc = "ARM errata 2966298, 3117295", .desc = "ARM errata 2966298, 3117295",
......
...@@ -2307,6 +2307,14 @@ static void user_feature_fixup(void) ...@@ -2307,6 +2307,14 @@ static void user_feature_fixup(void)
if (regp) if (regp)
regp->user_mask &= ~ID_AA64ISAR1_EL1_BF16_MASK; regp->user_mask &= ~ID_AA64ISAR1_EL1_BF16_MASK;
} }
if (cpus_have_cap(ARM64_WORKAROUND_SPECULATIVE_SSBS)) {
struct arm64_ftr_reg *regp;
regp = get_arm64_ftr_reg(SYS_ID_AA64PFR1_EL1);
if (regp)
regp->user_mask &= ~ID_AA64PFR1_EL1_SSBS_MASK;
}
} }
static void elf_hwcap_fixup(void) static void elf_hwcap_fixup(void)
......
...@@ -1535,6 +1535,27 @@ static void fpsimd_save_kernel_state(struct task_struct *task) ...@@ -1535,6 +1535,27 @@ static void fpsimd_save_kernel_state(struct task_struct *task)
task->thread.kernel_fpsimd_cpu = smp_processor_id(); task->thread.kernel_fpsimd_cpu = smp_processor_id();
} }
/*
* Invalidate any task's FPSIMD state that is present on this cpu.
* The FPSIMD context should be acquired with get_cpu_fpsimd_context()
* before calling this function.
*/
static void fpsimd_flush_cpu_state(void)
{
WARN_ON(!system_supports_fpsimd());
__this_cpu_write(fpsimd_last_state.st, NULL);
/*
* Leaving streaming mode enabled will cause issues for any kernel
* NEON and leaving streaming mode or ZA enabled may increase power
* consumption.
*/
if (system_supports_sme())
sme_smstop();
set_thread_flag(TIF_FOREIGN_FPSTATE);
}
void fpsimd_thread_switch(struct task_struct *next) void fpsimd_thread_switch(struct task_struct *next)
{ {
bool wrong_task, wrong_cpu; bool wrong_task, wrong_cpu;
...@@ -1552,7 +1573,7 @@ void fpsimd_thread_switch(struct task_struct *next) ...@@ -1552,7 +1573,7 @@ void fpsimd_thread_switch(struct task_struct *next)
if (test_tsk_thread_flag(next, TIF_KERNEL_FPSTATE)) { if (test_tsk_thread_flag(next, TIF_KERNEL_FPSTATE)) {
fpsimd_load_kernel_state(next); fpsimd_load_kernel_state(next);
set_tsk_thread_flag(next, TIF_FOREIGN_FPSTATE); fpsimd_flush_cpu_state();
} else { } else {
/* /*
* Fix up TIF_FOREIGN_FPSTATE to correctly describe next's * Fix up TIF_FOREIGN_FPSTATE to correctly describe next's
...@@ -1842,27 +1863,6 @@ void fpsimd_flush_task_state(struct task_struct *t) ...@@ -1842,27 +1863,6 @@ void fpsimd_flush_task_state(struct task_struct *t)
barrier(); barrier();
} }
/*
* Invalidate any task's FPSIMD state that is present on this cpu.
* The FPSIMD context should be acquired with get_cpu_fpsimd_context()
* before calling this function.
*/
static void fpsimd_flush_cpu_state(void)
{
WARN_ON(!system_supports_fpsimd());
__this_cpu_write(fpsimd_last_state.st, NULL);
/*
* Leaving streaming mode enabled will cause issues for any kernel
* NEON and leaving streaming mode or ZA enabled may increase power
* consumption.
*/
if (system_supports_sme())
sme_smstop();
set_thread_flag(TIF_FOREIGN_FPSTATE);
}
/* /*
* Save the FPSIMD state to memory and invalidate cpu view. * Save the FPSIMD state to memory and invalidate cpu view.
* This function must be called with preemption disabled. * This function must be called with preemption disabled.
......
...@@ -558,6 +558,18 @@ static enum mitigation_state spectre_v4_enable_hw_mitigation(void) ...@@ -558,6 +558,18 @@ static enum mitigation_state spectre_v4_enable_hw_mitigation(void)
/* SCTLR_EL1.DSSBS was initialised to 0 during boot */ /* SCTLR_EL1.DSSBS was initialised to 0 during boot */
set_pstate_ssbs(0); set_pstate_ssbs(0);
/*
* SSBS is self-synchronizing and is intended to affect subsequent
* speculative instructions, but some CPUs can speculate with a stale
* value of SSBS.
*
* Mitigate this with an unconditional speculation barrier, as CPUs
* could mis-speculate branches and bypass a conditional barrier.
*/
if (IS_ENABLED(CONFIG_ARM64_WORKAROUND_SPECULATIVE_SSBS))
spec_bar();
return SPECTRE_MITIGATED; return SPECTRE_MITIGATED;
} }
......
...@@ -102,4 +102,5 @@ WORKAROUND_NVIDIA_CARMEL_CNP ...@@ -102,4 +102,5 @@ WORKAROUND_NVIDIA_CARMEL_CNP
WORKAROUND_QCOM_FALKOR_E1003 WORKAROUND_QCOM_FALKOR_E1003
WORKAROUND_REPEAT_TLBI WORKAROUND_REPEAT_TLBI
WORKAROUND_SPECULATIVE_AT WORKAROUND_SPECULATIVE_AT
WORKAROUND_SPECULATIVE_SSBS
WORKAROUND_SPECULATIVE_UNPRIV_LOAD WORKAROUND_SPECULATIVE_UNPRIV_LOAD
...@@ -542,12 +542,16 @@ static int dmc620_pmu_event_init(struct perf_event *event) ...@@ -542,12 +542,16 @@ static int dmc620_pmu_event_init(struct perf_event *event)
if (event->cpu < 0) if (event->cpu < 0)
return -EINVAL; return -EINVAL;
hwc->idx = -1;
if (event->group_leader == event)
return 0;
/* /*
* We can't atomically disable all HW counters so only one event allowed, * We can't atomically disable all HW counters so only one event allowed,
* although software events are acceptable. * although software events are acceptable.
*/ */
if (event->group_leader != event && if (!is_software_event(event->group_leader))
!is_software_event(event->group_leader))
return -EINVAL; return -EINVAL;
for_each_sibling_event(sibling, event->group_leader) { for_each_sibling_event(sibling, event->group_leader) {
...@@ -556,7 +560,6 @@ static int dmc620_pmu_event_init(struct perf_event *event) ...@@ -556,7 +560,6 @@ static int dmc620_pmu_event_init(struct perf_event *event)
return -EINVAL; return -EINVAL;
} }
hwc->idx = -1;
return 0; return 0;
} }
......
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