arm64 fixes for -rc6

- Fix handling of CPU erratum #2645198 when batching pte updates
 
 - Fix truncation of CPU frequency calculation by using 64-bit arithmetic
   in arch_freq_get_on_cpu()
 
 - Work around AMU erratum #3821522 on Cortex-A725
 
 - Fix panic when trying to restore an SVE sigframe on a CPU that only
   supports SME
 -----BEGIN PGP SIGNATURE-----
 
 iQFEBAABCgAuFiEEPxTL6PPUbjXGY88ct6xw3ITBYzQFAmq/tpYQHHdpbGxAa2Vy
 bmVsLm9yZwAKCRC3rHDchMFjNJ6gB/9ZmDMU4ED2AbyP7T8Q6FttzvH01X85F2yz
 hlaaXv/2MDzjGSiz0spxDAZOuteJF+WSLj1WjZhlyr95xnQWfumc6D89D+kHeNre
 +twed6hbOQTWJzLB+u8Ef+4nKGcztIZ/FafFvPD6PKjFuhG048al8X/6oNXetBPy
 Ka13ywRYhnccflsWaXyWlvSwfKn2xJHOnpu4Mfbsb9DfaULDLLahz2ug+6apwX23
 tc/dy40Fi0G6wFzUQGF83R3nsyZgLiOv7LFBjjqDmoiu7W86KXn83UXEwHXrp8de
 Zbynk7F4Bxf0lsp6y+bxTmwzm8CwI355/NFU2ccxxu17e7Qv6PnJ
 =TRoC
 -----END PGP SIGNATURE-----

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

Pull arm64 fixes from Will Deacon:
 "Half of this is broken hardware (AMU counters and TLB invalidation)
  and the other half is broken software (frequency scaling and signals).
  So it seems as though we're all as bad as each other.

  The AMU workaround is a little noisy, as it refactors an existing
  workaround so that it can more easily be applied to additional CPUs.

  Summary:

   - Fix handling of CPU erratum #2645198 when batching pte updates

   - Fix truncation of CPU frequency calculation by using 64-bit
     arithmetic in arch_freq_get_on_cpu()

   - Work around AMU erratum #3821522 on Cortex-A725

   - Fix panic when trying to restore an SVE sigframe on a CPU that only
     supports SME"

* tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux:
  arm64/fpsimd: signal: Forbid non-streaming SVE payload on SME-only systems
  arm64: errata: Add Cortex-A725 erratum 3821522 workaround
  arm64: errata: Factor out broken AMU const counter cap
  arm64: topology: fix arch_freq_get_on_cpu() overflow above 4.19 GHz
  arm64: mm: Fix the break-before-make flush range for erratum 2645198
This commit is contained in:
Linus Torvalds 2026-10-03 07:54:58 -07:00
commit c5adb6c8a2
8 changed files with 84 additions and 34 deletions

View File

@ -174,6 +174,8 @@ stable kernels.
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A725 | #3456106 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A725 | #3821522 | ARM64_ERRATUM_3821522 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-X1 | #1502854 | N/A |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-X1 | #3324344 | ARM64_ERRATUM_3194386 |

View File

@ -1040,9 +1040,17 @@ config ARM64_ERRATUM_1902691
If unsure, say Y.
config ARM64_WORKAROUND_BROKEN_AMU_CONSTCNT
bool
# Targeting errata affecting AMEVCNTR01, the AMU constant counter.
# On affected CPUs the counter may not increment at the expected rate,
# making it unreliable. As a result, AMU users should treat it as
# unavailable rather than relying on misleading counter values.
config ARM64_ERRATUM_2457168
bool "Cortex-A510: 2457168: workaround for AMEVCNTR01 incrementing incorrectly"
depends on ARM64_AMU_EXTN
select ARM64_WORKAROUND_BROKEN_AMU_CONSTCNT
default y
help
This option adds the workaround for ARM Cortex-A510 erratum 2457168.
@ -1073,6 +1081,28 @@ config ARM64_ERRATUM_2645198
If unsure, say Y.
config ARM64_ERRATUM_3821522
bool "Cortex-A725: 3821522: workaround for possible CNT_CYCLES increment error due to WFE/WFI"
depends on ARM64_AMU_EXTN
select ARM64_WORKAROUND_BROKEN_AMU_CONSTCNT
default y
help
This option adds the workaround for ARM Cortex-A725 erratum 3821522.
On affected A725 cores, the CNT_CYCLES event may incur a significant
increment error when entering and subsequently exiting WFx.
As a result, the CNT_CYCLES may diverge from the system counter
frequency at which it is expected to increment.
This renders the AMU counter AMEVCNTR01, that implements CNT_CYCLES,
being unreliable and unsuitable for use.
Since there is no hardware workaround, reads of the affected CNT_CYCLES
counter return 0 in the relevant paths. This causes users of the counter
to treat it as unavailable and is functionally equivalent to firmware
disabling the affected counter.
If unsure, say Y.
config ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD
bool

View File

@ -384,6 +384,20 @@ static const struct arm64_cpu_capabilities arm64_repeat_tlbi_list[] = {
};
#endif
#ifdef CONFIG_ARM64_WORKAROUND_BROKEN_AMU_CONSTCNT
static const struct midr_range workaround_amu_constcnt_list[] = {
#ifdef CONFIG_ARM64_ERRATUM_2457168
/* Cortex-A510 r0p0-r1p1 */
MIDR_RANGE(MIDR_CORTEX_A510, 0, 0, 1, 1),
#endif
#ifdef CONFIG_ARM64_ERRATUM_3821522
/* Cortex-A725 r0p0 - r0p2 */
MIDR_RANGE(MIDR_CORTEX_A725, 0, 0, 0, 2),
#endif
{}
};
#endif /* CONFIG_ARM64_WORKAROUND_BROKEN_AMU_CONSTCNT */
#ifdef CONFIG_CAVIUM_ERRATUM_23154
static const struct midr_range cavium_erratum_23154_cpus[] = {
MIDR_ALL_VERSIONS(MIDR_THUNDERX),
@ -919,14 +933,12 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
},
#endif
#ifdef CONFIG_ARM64_ERRATUM_2457168
#ifdef CONFIG_ARM64_WORKAROUND_BROKEN_AMU_CONSTCNT
{
.desc = "ARM erratum 2457168",
.capability = ARM64_WORKAROUND_2457168,
.desc = "Broken AMU AMEVCNTR01 (const counter)",
.capability = ARM64_WORKAROUND_BROKEN_AMU_CONSTCNT,
.type = ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE,
/* Cortex-A510 r0p0-r1p1 */
CAP_MIDR_RANGE(MIDR_CORTEX_A510, 0, 0, 1, 1)
CAP_MIDR_RANGE_LIST(workaround_amu_constcnt_list)
},
#endif
#ifdef CONFIG_ARM64_ERRATUM_2038923

View File

@ -2089,7 +2089,7 @@ static void cpu_amu_enable(struct arm64_cpu_capabilities const *cap)
cpumask_set_cpu(smp_processor_id(), &amu_cpus);
/* 0 reference values signal broken/disabled counters */
if (!this_cpu_has_cap(ARM64_WORKAROUND_2457168))
if (!this_cpu_has_cap(ARM64_WORKAROUND_BROKEN_AMU_CONSTCNT))
update_freq_counters_refs();
}
}

View File

@ -433,6 +433,7 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
unsigned int vl, vq;
struct user_fpsimd_state fpsimd;
u16 user_vl, flags;
bool fpsimd_only;
bool sm;
if (user->sve_size < sizeof(*user->sve))
@ -443,19 +444,33 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
if (err)
return err;
fpsimd_only = (user->sve_size == sizeof(*user->sve));
sm = flags & SVE_SIG_FLAG_SM;
if (sm) {
if (!system_supports_sme())
return -EINVAL;
/*
* Streaming SVE state is always preserved with an SVE payload.
* Only accept streaming state which has an SVE payload.
*/
if (fpsimd_only)
return -EINVAL;
vl = task_get_sme_vl(current);
} else {
/*
* A SME only system use SVE for streaming mode so can
* have a SVE formatted context with a zero VL and no
* payload data.
* Non-streaming SVE state may be preserved without an SVE
* payload, in which case all state is saved in the FPSIMD
* context.
*
* On SME-only systems, non-streaming (FPSIMD-only) state is
* always preserved without an SVE payload, and with VL==0. On
* such systems, only accept non-streaming state without an SVE
* payload.
*/
if (!system_supports_sve() && !system_supports_sme())
if (!system_supports_sve() && !fpsimd_only)
return -EINVAL;
vl = task_get_sve_vl(current);
@ -464,16 +479,7 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
if (user_vl != vl)
return -EINVAL;
/*
* Non-streaming SVE state may be preserved without an SVE payload, in
* which case the SVE context only has a header with VL==0, and all
* state can be restored from the FPSIMD context.
*
* Streaming SVE state is always preserved with an SVE payload. For
* consistency and robustness, reject restoring streaming SVE state
* without an SVE payload.
*/
if (!sm && user->sve_size == sizeof(*user->sve))
if (fpsimd_only)
return restore_fpsimd_context(user);
vq = sve_vq_from_vl(vl);

View File

@ -186,7 +186,6 @@ int arch_freq_get_on_cpu(int cpu)
struct amu_cntr_sample *amu_sample;
unsigned int start_cpu = cpu;
unsigned long last_update;
unsigned int freq = 0;
u64 scale;
if (!amu_fie_cpu_supported(cpu) || !arch_scale_freq_ref(cpu))
@ -245,9 +244,8 @@ int arch_freq_get_on_cpu(int cpu)
* (see amu_scale_freq_tick for details)
*/
scale = arch_scale_freq_capacity(cpu);
freq = scale * arch_scale_freq_ref(cpu);
freq >>= SCHED_CAPACITY_SHIFT;
return freq;
return (scale * arch_scale_freq_ref(cpu)) >> SCHED_CAPACITY_SHIFT;
}
static void amu_fie_setup(const struct cpumask *cpus)
@ -397,12 +395,13 @@ static void cpu_read_corecnt(void *val)
static void cpu_read_constcnt(void *val)
{
/*
* Return 0 if the current CPU is affected by erratum 2457168. A value
* of 0 is also returned if the current CPU does not support AMUs or if
* the counter is disabled. A return value of 0 at counter read is
* properly handled as an error case by the users of the counter.
* Return 0 if the current CPU is affected by a HW erratum.
* A value of 0 is also returned if the current CPU does not
* support AMUs or if the counter is disabled. A return
* value of 0 at counter read is properly handled as an error
* case by the users of the counter.
*/
*(u64 *)val = this_cpu_has_cap(ARM64_WORKAROUND_2457168) ?
*(u64 *)val = this_cpu_has_cap(ARM64_WORKAROUND_BROKEN_AMU_CONSTCNT) ?
0UL : read_constcnt();
}
@ -463,8 +462,9 @@ static void amu_read_core_const_ctrs(void *val)
/*
* cpu_read_constcnt() incurs slight latency due to the
* ARM64_WORKAROUND_2457168 check. Read it first to minimize
* the sampling skew between the const and core counters.
* ARM64_WORKAROUND_BROKEN_AMU_CONSTCNT check.
* Read it first to minimize the sampling skew between the const
* and core counters.
*/
cpu_read_constcnt(&ctrs->constcnt);
cpu_read_corecnt(&ctrs->corecnt);

View File

@ -2295,7 +2295,7 @@ pte_t modify_prot_start_ptes(struct vm_area_struct *vma, unsigned long addr,
* in cases where cpu is affected with errata #2645198.
*/
if (pte_accessible(vma->vm_mm, pte) && pte_user_exec(pte))
__flush_tlb_range(vma, addr, nr * PAGE_SIZE,
__flush_tlb_range(vma, addr, addr + nr * PAGE_SIZE,
PAGE_SIZE, 3, TLBF_NOWALKCACHE);
}

View File

@ -105,7 +105,6 @@ WORKAROUND_1902691
WORKAROUND_2038923
WORKAROUND_2064142
WORKAROUND_2077057
WORKAROUND_2457168
WORKAROUND_2645198
WORKAROUND_2658417
WORKAROUND_4193714
@ -132,3 +131,4 @@ WORKAROUND_REPEAT_TLBI_SYNC
WORKAROUND_SPECULATIVE_AT
WORKAROUND_SPECULATIVE_SSBS
WORKAROUND_SPECULATIVE_UNPRIV_LOAD
WORKAROUND_BROKEN_AMU_CONSTCNT