Re: [PATCH v2 3/4] perf: arm_pmu: Add workaround for FUJITSU-MONAKA Erratum E#030002

From: Mark Rutland

Date: Fri Oct 16 2026 - 08:09:07 EST


On Fri, Oct 16, 2026 at 07:00:47PM +0900, Tomohiro Misono wrote:
> FUJITSU-MONAKA Erratum E#030002 affects FUJITSU-MONAKA CPU.
>
> On affected FUJITSU-MONAKA CPUs, after a PMU event counter is
> stopped at a value just before overflow, an overflow might still
> be incorrectly detected, resulting interrupt storm in some case.
>
> For example, if the following conditions are met:
> 1) Running perf to count an event in user space only
> 2) The event can also occur in kernel space
> 3) The counter value is set just before the overflow
> (when using the -F option, initial counter value is -1)
>
> when the kernel is about to return to user space after enabling
> the count, an overflow interrupt is incorrectly triggered by an
> event that occurred in kernel space. Since the counter value is
> not updated (correctly), the interrupt handler does nothing and
> returns with the same condition. This leads to another wrong interrupt
> and results in an interrupt storm and eventually a softlockup.

I don't fully understand this.

Surely the relevant PMOVS{CLR,SET}[n] bit set as if the counter n
overflowed?

If that bit is set, the handler will certainly do *something*.

If that bit is not set, the interrupt shouldn't be asserted at all. When
does it get de-asserted?

> Work around the erratum by avoiding programming PMU event counters
> with values within five counts of overflow.

Without more detail, I don't think that can be sufficient, because you
can end up in a scenario where:

1. The kernel confugures the counter to -5.

2. The kernel returns to userspace.

3. In userspace, 4 events occur, and are counted, leaving the counter at
-1.

4. Some unrelated interrupt is taken, entering the kernel.

5. Upon return to userspace, a kernel event occurs, triggering this
issue.

6. The PMU interupt handler runs, does nothing, leading right back to
the original issue.

What am I missing?

Mark.

> Signed-off-by: Tomohiro Misono <misono.tomohiro@xxxxxxxxxxx>
>
> ---
> Changes in v2:
> - Add user impact explanation in the commit message
> ---
> ---
> Documentation/arch/arm64/silicon-errata.rst | 2 ++
> arch/arm64/Kconfig | 17 +++++++++++++++++
> arch/arm64/include/asm/cpucaps.h | 2 ++
> arch/arm64/kernel/cpu_errata.c | 10 ++++++++++
> arch/arm64/tools/cpucaps | 1 +
> drivers/perf/arm_pmu.c | 13 +++++++++++++
> 6 files changed, 45 insertions(+)
>
> diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst
> index 527af20b26468..0efb24ec01b4c 100644
> --- a/Documentation/arch/arm64/silicon-errata.rst
> +++ b/Documentation/arch/arm64/silicon-errata.rst
> @@ -377,6 +377,8 @@ stable kernels.
> +----------------+-----------------+-----------------+-----------------------------+
> | Fujitsu | MONAKA | E#030001 | FUJITSU_ERRATUM_030001 |
> +----------------+-----------------+-----------------+-----------------------------+
> +| Fujitsu | MONAKA | E#030002 | FUJITSU_ERRATUM_030002 |
> ++----------------+-----------------+-----------------+-----------------------------+
> +----------------+-----------------+-----------------+-----------------------------+
> | ASR | ASR8601 | #8601001 | N/A |
> +----------------+-----------------+-----------------+-----------------------------+
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 5d1a17ab0f593..43fd265156e46 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -1361,6 +1361,23 @@ config FUJITSU_ERRATUM_030001
>
> If unsure, say Y.
>
> +config FUJITSU_ERRATUM_030002
> + bool "FUJITSU-MONAKA erratum E#030002: PMU overflow may be incorrectly detected"
> + depends on ARM_PMUV3
> + default y
> + help
> + This option adds a workaround for FUJITSU-MONAKA erratum E#030002.
> + On affected FUJITSU-MONAKA CPUs, after a PMU event counter is
> + stopped at a value just before overflow, an overflow might still
> + be incorrectly detected.
> +
> + Work around the erratum by avoiding programming PMU event counters
> + with values within five counts of overflow.
> +
> + The workaround only affects the FUJITSU-MONAKA.
> +
> + If unsure, say Y.
> +
> config HISILICON_ERRATUM_161600802
> bool "Hip07 161600802: Erroneous redistributor VLPI base"
> default y
> diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h
> index 9220b917ec207..c0a0452daf949 100644
> --- a/arch/arm64/include/asm/cpucaps.h
> +++ b/arch/arm64/include/asm/cpucaps.h
> @@ -68,6 +68,8 @@ cpucap_is_possible(const unsigned int cap)
> return IS_ENABLED(CONFIG_ARM64_ERRATUM_4193714);
> case ARM64_WORKAROUND_FUJITSU_030001:
> return IS_ENABLED(CONFIG_FUJITSU_ERRATUM_030001);
> + case ARM64_WORKAROUND_FUJITSU_030002:
> + return IS_ENABLED(CONFIG_FUJITSU_ERRATUM_030002);
> case ARM64_MPAM:
> /*
> * KVM MPAM support doesn't rely on the host kernel supporting MPAM.
> diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
> index a11135f83e858..6363b694b4478 100644
> --- a/arch/arm64/kernel/cpu_errata.c
> +++ b/arch/arm64/kernel/cpu_errata.c
> @@ -1048,6 +1048,16 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
> {}
> })),
> },
> +#endif
> +#ifdef CONFIG_FUJITSU_ERRATUM_030002
> + {
> + .desc = "FUJITSU-MONAKA Erratum E#030002",
> + .capability = ARM64_WORKAROUND_FUJITSU_030002,
> + ERRATA_MIDR_RANGE_LIST(((const struct midr_range[]) {
> + MIDR_ALL_VERSIONS(MIDR_FUJITSU_MONAKA),
> + {}
> + })),
> + },
> #endif
> {
> .desc = "Known broken GICv3 SEIS implementation",
> diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
> index 1e57a0105395b..ef8ce70ab7121 100644
> --- a/arch/arm64/tools/cpucaps
> +++ b/arch/arm64/tools/cpucaps
> @@ -133,3 +133,4 @@ WORKAROUND_SPECULATIVE_SSBS
> WORKAROUND_SPECULATIVE_UNPRIV_LOAD
> WORKAROUND_BROKEN_AMU_CONSTCNT
> WORKAROUND_FUJITSU_030001
> +WORKAROUND_FUJITSU_030002
> diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
> index 1150695653892..c0b8580d80bae 100644
> --- a/drivers/perf/arm_pmu.c
> +++ b/drivers/perf/arm_pmu.c
> @@ -234,6 +234,19 @@ int armpmu_event_set_period(struct perf_event *event)
> if (left > (max_period >> 1))
> left = (max_period >> 1);
>
> +#if IS_ENABLED(CONFIG_ARM64)
> + if (alternative_has_cap_unlikely(ARM64_WORKAROUND_FUJITSU_030002)) {
> + /*
> + * Due to the errata, overflow might be incorrectly detected in the handler
> + * when the counter is about to overflow in a single increment, resulting
> + * interrupt storm in some case. As the counter can increase by up to
> + * 5 at a time, set 6 here to prevent the condition.
> + */
> + if (left > 0 && left < 6)
> + left = 6;
> + }
> +#endif
> +
> local64_set(&hwc->prev_count, (u64)-left);
>
> armpmu->write_counter(event, (u64)(-left) & max_period);
>
> --
> 2.43.0
>