Merge branch 'for-next/errata' into for-next/core

* for-next/errata:
  arch: arm64: add early_param idle=<wfi|yield|nop>
  arm64: proton-pack: Restore the nospectre_bhb command-line option
  arm64: errata: work around NVIDIA Olympus device store/load ordering
  arm64: Clarify ARM64_WORKAROUND_REPEAT_TLBI semantics
This commit is contained in:
Will Deacon
2026-08-14 10:16:08 +00:00
10 changed files with 141 additions and 20 deletions

View File

@@ -2236,6 +2236,29 @@ Kernel parameters
idle=nomwait: Disable mwait for CPU C-states
[ARM64,EARLY]
Format: idle=wfi, idle=yield, idle=nop
idle=wfi: Use the WFI (Wait For Interrupt) hint
instruction in the idle loop. This is the default and
allows the CPU to enter a low-power state until an
interrupt arrives.
idle=yield: Use the YIELD hint instruction instead of
WFI. CPUs supporting simultaneous multi-threading (SMT),
can continue executing another thread when the current
thread reaches the idle loop. This will make the CPUs
eat more power, but may be useful to get slightly better
performance in some applications, since the CPUs will
not enter a low-power state.
idle=nop: Do not execute any idle instruction in the
idle loop. This is useful on platforms where WFI
misbehaves, leading to system instability or loss of CPU
state. This will make the CPUs eat more power, but may
give slightly better performance in some applications,
since the CPUs will not enter a low-power state.
idxd.sva= [HW]
Format: <bool>
Allow force disabling of Shared Virtual Memory (SVA)

View File

@@ -308,6 +308,8 @@ stable kernels.
+----------------+-----------------+-----------------+-----------------------------+
| NVIDIA | Carmel Core | N/A | NVIDIA_CARMEL_CNP_ERRATUM |
+----------------+-----------------+-----------------+-----------------------------+
| NVIDIA | Olympus core | T410-OLY-1027 | NVIDIA_OLYMPUS_1027_ERRATUM |
+----------------+-----------------+-----------------+-----------------------------+
| NVIDIA | Olympus core | T410-OLY-1029 | ARM64_ERRATUM_4118414 |
+----------------+-----------------+-----------------+-----------------------------+
| NVIDIA | T241 GICv3/4.x | T241-FABRIC-4 | N/A |

View File

@@ -701,12 +701,34 @@ config ARM64_ERRATUM_1530923
If unsure, say Y.
config ARM64_WORKAROUND_REPEAT_TLBI
config ARM64_WORKAROUND_REPEAT_TLBI_SYNC
bool
# This workaround is (only) suitable for TLB invalidation errata where
# all of the following conditions are true:
#
# - The effects of the errata are only a loss of ordering/completion
# for explicit memory accesses when the TLBI is completed with a DSB.
# The removal of TLB entries is not affected.
#
# Note that architecturally, S2-only invalidation does not remove
# combined S1+S2 entries, and does not complete accesses translated
# via those S1+S2 entries. Consequently, where this condition holds,
# the errata do not affect S2-only invalidation.
#
# - The errata only affect broadcast TLB invalidation operations (e.g.
# TLBI VMALLE1IS), and do not affect local TLB invalidation
# operations (e.g. TLBI VMALLE1).
#
# - After any number of affected TLBI operations are completed with a
# DSB, the errata can be mitigated by executing a single arbitrary
# broadcast TLBI (which targets an arbitrary translation regime),
# followed by a DSB.
#
# For more rationale, see commit a8f78680ee6bf795.
config ARM64_ERRATUM_2441007
bool "Cortex-A55: Completion of affected memory accesses might not be guaranteed by completion of a TLBI (rare)"
select ARM64_WORKAROUND_REPEAT_TLBI
select ARM64_WORKAROUND_REPEAT_TLBI_SYNC
help
This option adds a workaround for ARM Cortex-A55 erratum #2441007.
@@ -722,7 +744,7 @@ config ARM64_ERRATUM_2441007
config ARM64_ERRATUM_1286807
bool "Cortex-A76: Modification of the translation table for a virtual address might lead to read-after-read ordering violation (rare)"
select ARM64_WORKAROUND_REPEAT_TLBI
select ARM64_WORKAROUND_REPEAT_TLBI_SYNC
help
This option adds a workaround for ARM Cortex-A76 erratum 1286807.
@@ -944,7 +966,7 @@ config ARM64_ERRATUM_2224489
config ARM64_ERRATUM_2441009
bool "Cortex-A510: Completion of affected memory accesses might not be guaranteed by completion of a TLBI (rare)"
select ARM64_WORKAROUND_REPEAT_TLBI
select ARM64_WORKAROUND_REPEAT_TLBI_SYNC
help
This option adds a workaround for ARM Cortex-A510 erratum #2441009.
@@ -1156,7 +1178,7 @@ config ARM64_ERRATUM_4193714
config ARM64_ERRATUM_4118414
bool "Various: Completion of affected memory accesses might not be guaranteed by completion of a TLBI"
default y
select ARM64_WORKAROUND_REPEAT_TLBI
select ARM64_WORKAROUND_REPEAT_TLBI_SYNC
help
This option adds a workaround for the following errata:
@@ -1340,7 +1362,7 @@ config QCOM_FALKOR_ERRATUM_1003
config QCOM_FALKOR_ERRATUM_1009
bool "Falkor E1009: Prematurely complete a DSB after a TLBI"
default y
select ARM64_WORKAROUND_REPEAT_TLBI
select ARM64_WORKAROUND_REPEAT_TLBI_SYNC
help
On Falkor v1, the CPU may prematurely complete a DSB following a
TLBI xxIS invalidate maintenance operation. Repeat the TLBI operation
@@ -1382,6 +1404,28 @@ config NVIDIA_CARMEL_CNP_ERRATUM
If unsure, say Y.
config NVIDIA_OLYMPUS_1027_ERRATUM
bool "NVIDIA Olympus: device store/load ordering erratum"
default y
help
This option adds an alternative code sequence to work around an
NVIDIA Olympus core erratum where a Device-nGnR* store can be
observed by a peripheral after a younger Device-nGnR* load to the
same peripheral. This breaks the program order that drivers rely
on for MMIO and can leave a device in an incorrect state.
The workaround inserts a DMB OSH immediately before raw MMIO loads.
The erratum cannot occur when a DMB that orders loads appears
between the store and load, preventing the younger load from being
observed before the older store.
The alternatives framework patches in DMB OSH only when an affected
CPU is detected. Other CPUs execute a NOP in its place. Disabling
this option leaves the original MMIO read instruction stream
unchanged.
If unsure, say Y.
config ROCKCHIP_ERRATUM_3568002
bool "Rockchip 3568002: GIC600 can not access physical addresses higher than 4GB"
default y

View File

@@ -60,8 +60,8 @@ cpucap_is_possible(const unsigned int cap)
return IS_ENABLED(CONFIG_CAVIUM_ERRATUM_23154);
case ARM64_WORKAROUND_DISABLE_CNP:
return IS_ENABLED(CONFIG_ARM64_WORKAROUND_DISABLE_CNP);
case ARM64_WORKAROUND_REPEAT_TLBI:
return IS_ENABLED(CONFIG_ARM64_WORKAROUND_REPEAT_TLBI);
case ARM64_WORKAROUND_REPEAT_TLBI_SYNC:
return IS_ENABLED(CONFIG_ARM64_WORKAROUND_REPEAT_TLBI_SYNC);
case ARM64_WORKAROUND_SPECULATIVE_SSBS:
return IS_ENABLED(CONFIG_ARM64_ERRATUM_3194386);
case ARM64_WORKAROUND_4193714:

View File

@@ -54,7 +54,9 @@ static __always_inline void __raw_writeq(u64 val, volatile void __iomem *addr)
static __always_inline u8 __raw_readb(const volatile void __iomem *addr)
{
u8 val;
asm volatile(ALTERNATIVE("ldrb %w0, [%1]",
asm volatile(ALTERNATIVE("nop", "dmb osh",
ARM64_WORKAROUND_NVIDIA_OLYMPUS_1027)
ALTERNATIVE("ldrb %w0, [%1]",
"ldarb %w0, [%1]",
ARM64_WORKAROUND_DEVICE_LOAD_ACQUIRE)
: "=r" (val) : "r" (addr));
@@ -66,7 +68,9 @@ static __always_inline u16 __raw_readw(const volatile void __iomem *addr)
{
u16 val;
asm volatile(ALTERNATIVE("ldrh %w0, [%1]",
asm volatile(ALTERNATIVE("nop", "dmb osh",
ARM64_WORKAROUND_NVIDIA_OLYMPUS_1027)
ALTERNATIVE("ldrh %w0, [%1]",
"ldarh %w0, [%1]",
ARM64_WORKAROUND_DEVICE_LOAD_ACQUIRE)
: "=r" (val) : "r" (addr));
@@ -77,7 +81,9 @@ static __always_inline u16 __raw_readw(const volatile void __iomem *addr)
static __always_inline u32 __raw_readl(const volatile void __iomem *addr)
{
u32 val;
asm volatile(ALTERNATIVE("ldr %w0, [%1]",
asm volatile(ALTERNATIVE("nop", "dmb osh",
ARM64_WORKAROUND_NVIDIA_OLYMPUS_1027)
ALTERNATIVE("ldr %w0, [%1]",
"ldar %w0, [%1]",
ARM64_WORKAROUND_DEVICE_LOAD_ACQUIRE)
: "=r" (val) : "r" (addr));
@@ -88,7 +94,9 @@ static __always_inline u32 __raw_readl(const volatile void __iomem *addr)
static __always_inline u64 __raw_readq(const volatile void __iomem *addr)
{
u64 val;
asm volatile(ALTERNATIVE("ldr %0, [%1]",
asm volatile(ALTERNATIVE("nop", "dmb osh",
ARM64_WORKAROUND_NVIDIA_OLYMPUS_1027)
ALTERNATIVE("ldr %0, [%1]",
"ldar %0, [%1]",
ARM64_WORKAROUND_DEVICE_LOAD_ACQUIRE)
: "=r" (val) : "r" (addr));

View File

@@ -236,7 +236,7 @@ static inline void __tlbi_level(tlbi_op op, u64 addr, u32 level)
#define __repeat_tlbi_sync(op, arg...) \
do { \
if (!alternative_has_cap_unlikely(ARM64_WORKAROUND_REPEAT_TLBI)) \
if (!alternative_has_cap_unlikely(ARM64_WORKAROUND_REPEAT_TLBI_SYNC)) \
break; \
__tlbi(op, ##arg); \
dsb(ish); \

View File

@@ -309,7 +309,7 @@ static void cpu_enable_impdef_pmuv3_traps(const struct arm64_cpu_capabilities *_
sysreg_clear_set_s(SYS_HACR_EL2, 0, BIT(56));
}
#ifdef CONFIG_ARM64_WORKAROUND_REPEAT_TLBI
#ifdef CONFIG_ARM64_WORKAROUND_REPEAT_TLBI_SYNC
static const struct arm64_cpu_capabilities arm64_repeat_tlbi_list[] = {
#ifdef CONFIG_QCOM_FALKOR_ERRATUM_1009
{
@@ -733,10 +733,10 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
.match_list = qcom_erratum_1003_list,
},
#endif
#ifdef CONFIG_ARM64_WORKAROUND_REPEAT_TLBI
#ifdef CONFIG_ARM64_WORKAROUND_REPEAT_TLBI_SYNC
{
.desc = "Broken broadcast TLBI completion",
.capability = ARM64_WORKAROUND_REPEAT_TLBI,
.capability = ARM64_WORKAROUND_REPEAT_TLBI_SYNC,
.type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
.matches = cpucap_multi_entry_cap_matches,
.match_list = arm64_repeat_tlbi_list,
@@ -850,6 +850,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
ERRATA_MIDR_RANGE_LIST(cnp_erratum_cpus),
},
#endif
#ifdef CONFIG_NVIDIA_OLYMPUS_1027_ERRATUM
{
/* NVIDIA Olympus core */
.desc = "NVIDIA Olympus device store/load ordering erratum",
.capability = ARM64_WORKAROUND_NVIDIA_OLYMPUS_1027,
ERRATA_MIDR_ALL_VERSIONS(MIDR_NVIDIA_OLYMPUS),
},
#endif
#ifdef CONFIG_ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE
{
/*

View File

@@ -11,6 +11,29 @@
#include <asm/cpufeature.h>
#include <asm/sysreg.h>
enum {
ARM64_IDLE_WFI,
ARM64_IDLE_YIELD,
ARM64_IDLE_NOP,
} idle = ARM64_IDLE_WFI;
static int __init setup_idle(char *arg)
{
if (!arg)
return -1;
else if (!strcmp(arg, "wfi"))
idle = ARM64_IDLE_WFI;
else if (!strcmp(arg, "yield"))
idle = ARM64_IDLE_YIELD;
else if (!strcmp(arg, "nop"))
idle = ARM64_IDLE_NOP;
else
return -1;
return 0;
}
early_param("idle", setup_idle);
/*
* cpu_do_idle()
*
@@ -26,8 +49,13 @@ void __cpuidle cpu_do_idle(void)
arm_cpuidle_save_irq_context(&context);
dsb(sy);
wfi();
if (likely(idle == ARM64_IDLE_WFI)) {
dsb(sy);
wfi();
} else if (idle == ARM64_IDLE_YIELD) {
dsb(sy);
asm volatile("yield" ::: "memory");
}
arm_cpuidle_restore_irq_context(&context);
}

View File

@@ -1023,6 +1023,11 @@ static int __init parse_spectre_bhb_param(char *str)
}
early_param("nospectre_bhb", parse_spectre_bhb_param);
static bool spectre_bhb_mitigations_off(void)
{
return __nospectre_bhb || cpu_mitigations_off();
}
void spectre_bhb_enable_mitigation(const struct arm64_cpu_capabilities *entry)
{
bp_hardening_cb_t cpu_cb;
@@ -1036,6 +1041,8 @@ void spectre_bhb_enable_mitigation(const struct arm64_cpu_capabilities *entry)
/* No point mitigating Spectre-BHB alone. */
} else if (!IS_ENABLED(CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY)) {
/* Do nothing */
} else if (spectre_bhb_mitigations_off()) {
/* Mitigation disabled on the command line */
} else if (supports_ecbhb(SCOPE_LOCAL_CPU)) {
state = SPECTRE_MITIGATED;
set_bit(BHB_HW, &system_bhb_mitigations);
@@ -1201,6 +1208,6 @@ void spectre_print_disabled_mitigations(void)
if (spectre_v4_mitigations_off())
pr_info("spectre-v4 %s", spectre_disabled_suffix);
if (__nospectre_bhb || cpu_mitigations_off())
if (spectre_bhb_mitigations_off())
pr_info("spectre-bhb %s", spectre_disabled_suffix);
}

View File

@@ -121,10 +121,11 @@ WORKAROUND_CAVIUM_TX2_219_TVM
WORKAROUND_CLEAN_CACHE
WORKAROUND_DEVICE_LOAD_ACQUIRE
WORKAROUND_DISABLE_CNP
WORKAROUND_NVIDIA_OLYMPUS_1027
WORKAROUND_PMUV3_IMPDEF_TRAPS
WORKAROUND_QCOM_FALKOR_E1003
WORKAROUND_QCOM_ORYON_CNTVOFF
WORKAROUND_REPEAT_TLBI
WORKAROUND_REPEAT_TLBI_SYNC
WORKAROUND_SPECULATIVE_AT
WORKAROUND_SPECULATIVE_SSBS
WORKAROUND_SPECULATIVE_UNPRIV_LOAD