* [PATCH] perf/x86/amd: Reject AMD Merge event as a countable event
@ 2026-09-16 12:33 Luka Absandze
2026-09-16 12:51 ` sashiko-bot
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Luka Absandze @ 2026-09-16 12:33 UTC (permalink / raw)
To: peterz, mingo, acme, namhyung, tglx, bp, dave.hansen, x86, yaoz,
dwmw2
Cc: kim.phillips, kvm, linux-perf-users, linux-kernel, Luka Absandze
AMD event select 0xFFF (Merge) is the hardware control encoding used by
Large Increment per Cycle (LIPC) pairs. When written into an odd
counter's PerfCtl it turns that counter into the upper 16 bits of a
64-bit merged accumulator; any subsequent arming write (-(2^47-1)) is
silently truncated to its low 16 bits, while hwc->prev_count retains the
full value.
This is particularly problematic with a KVM guest, which will program
the Merge encoding into its own odd vPMC as a normal part of scheduling
a LIPC event. KVM intercepts that write and faithfully forwards it to
the host as a raw event carrying the Merge encoding, where it is
accepted as an ordinary countable event. Once a counter's PerfCtl holds
the Merge encoding, every later user of that counter gets a first delta
inflated by 2^47
Reject Merge (AMD_MERGE_EVENT) in amd_core_hw_config() so it cannot be
submitted as a user-visible event. The pair mechanism programs it
itself via x86_pmu.perf_ctr_pair_en; nothing else should do so.
Fixes: 5738891229a2 ("perf/x86/amd: Add support for Large Increment per Cycle Events")
Reported-by: Yao Zhou <yaoz@meta.com>
Signed-off-by: Luka Absandze <absandze@amazon.de>
---
arch/x86/events/amd/core.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c
index 49b6b8fce566..cb655c751e5b 100644
--- a/arch/x86/events/amd/core.c
+++ b/arch/x86/events/amd/core.c
@@ -380,8 +380,12 @@ static int amd_core_hw_config(struct perf_event *event)
else if (event->attr.exclude_guest)
event->hw.config |= AMD64_EVENTSEL_HOSTONLY;
- if ((x86_pmu.flags & PMU_FL_PAIR) && amd_is_pair_event_code(&event->hw))
- event->hw.flags |= PERF_X86_EVENT_PAIR;
+ if (x86_pmu.flags & PMU_FL_PAIR) {
+ if ((event->hw.config & AMD64_EVENTSEL_EVENT) == AMD_MERGE_EVENT)
+ return -EINVAL;
+ if (amd_is_pair_event_code(&event->hw))
+ event->hw.flags |= PERF_X86_EVENT_PAIR;
+ }
if (has_branch_stack(event))
return static_call(amd_pmu_branch_hw_config)(event);
--
2.47.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH] perf/x86/amd: Reject AMD Merge event as a countable event
2026-09-16 12:33 [PATCH] perf/x86/amd: Reject AMD Merge event as a countable event Luka Absandze
@ 2026-09-16 12:51 ` sashiko-bot
2026-09-16 14:02 ` Absandze, Luka
2026-09-16 15:04 ` Borislav Petkov
2026-09-21 5:09 ` Sandipan Das
2 siblings, 1 reply; 6+ messages in thread
From: sashiko-bot @ 2026-09-16 12:51 UTC (permalink / raw)
To: Luka Absandze; +Cc: kvm, linux-perf-users
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] perf/x86/amd: -EINVAL on AMD_MERGE_EVENT causes KVM retry storm
--
commit 74f1b4944fbb968a39b8b39a32bd5ffa921c5814
Author: Luka Absandze <absandze@amazon.de>
perf/x86/amd: Reject AMD Merge event as a countable event
This commit modifies amd_core_hw_config() to reject the AMD Merge event
(AMD_MERGE_EVENT) as a user-visible event by returning -EINVAL. It prevents a
counter's PerfCtl from holding the Merge encoding inappropriately, which could
otherwise artificially inflate deltas.
> diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c
> index 49b6b8fce5664..cb655c751e5b1 100644
> --- a/arch/x86/events/amd/core.c
> +++ b/arch/x86/events/amd/core.c
> @@ -380,8 +380,12 @@ static int amd_core_hw_config(struct perf_event *event)
[ ... ]
> - if ((x86_pmu.flags & PMU_FL_PAIR) && amd_is_pair_event_code(&event->hw))
> - event->hw.flags |= PERF_X86_EVENT_PAIR;
> + if (x86_pmu.flags & PMU_FL_PAIR) {
> + if ((event->hw.config & AMD64_EVENTSEL_EVENT) == AMD_MERGE_EVENT)
> + return -EINVAL;
[Severity: High]
Does returning a permanent -EINVAL error here cause an opportunistic retry storm
in KVM?
If a KVM guest programs a Large Increment per Cycle (LIPC) event by writing
AMD_MERGE_EVENT to an odd vPMC, KVM intercepts this and attempts to create a
raw host perf event. When this fails with -EINVAL, KVM's reprogram_counter()
propagates the error to kvm_pmu_handle_event():
arch/x86/kvm/pmu.c:kvm_pmu_handle_event() {
...
if (reprogram_counter(pmc))
set_bit(pmc->idx, pmu->reprogram_pmi);
...
}
Because KVM treats all failures as transient and unconditionally re-adds the
failing counter to pmu->reprogram_pmi, on every subsequent PMU refresh KVM
will repeatedly retry the failed counter.
Could this create a permanent retry storm that degrades VM performance and
wastes host CPU cycles?
> + if (amd_is_pair_event_code(&event->hw))
> + event->hw.flags |= PERF_X86_EVENT_PAIR;
> + }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260916123315.89042-1-absandze@amazon.de?part=1
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] perf/x86/amd: Reject AMD Merge event as a countable event
2026-09-16 12:51 ` sashiko-bot
@ 2026-09-16 14:02 ` Absandze, Luka
2026-09-17 6:44 ` Sandipan Das
0 siblings, 1 reply; 6+ messages in thread
From: Absandze, Luka @ 2026-09-16 14:02 UTC (permalink / raw)
To: sashiko-reviews@lists.linux.dev
Cc: kvm@vger.kernel.org, linux-perf-users@vger.kernel.org
On 2026-09-16 12:51, sashiko-bot@kernel.org wrote:
> [Severity: High]
> Does returning a permanent -EINVAL error here cause an opportunistic retry storm
> in KVM?
>
> If a KVM guest programs a Large Increment per Cycle (LIPC) event by writing
> AMD_MERGE_EVENT to an odd vPMC, KVM intercepts this and attempts to create a
> raw host perf event. When this fails with -EINVAL, KVM's reprogram_counter()
> propagates the error to kvm_pmu_handle_event():
>
> arch/x86/kvm/pmu.c:kvm_pmu_handle_event() {
> ...
> if (reprogram_counter(pmc))
> set_bit(pmc->idx, pmu->reprogram_pmi);
> ...
> }
>
> Because KVM treats all failures as transient and unconditionally re-adds the
> failing counter to pmu->reprogram_pmi, on every subsequent PMU refresh KVM
> will repeatedly retry the failed counter.
>
> Could this create a permanent retry storm that degrades VM performance and
> wastes host CPU cycles?
>
There ins't any substantial load generated, we short circuit here before
the expesnive parts. However, a followup in KVM could be beneficial to
reject this case outright.
I'll wait for opinions
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] perf/x86/amd: Reject AMD Merge event as a countable event
2026-09-16 12:33 [PATCH] perf/x86/amd: Reject AMD Merge event as a countable event Luka Absandze
2026-09-16 12:51 ` sashiko-bot
@ 2026-09-16 15:04 ` Borislav Petkov
2026-09-21 5:09 ` Sandipan Das
2 siblings, 0 replies; 6+ messages in thread
From: Borislav Petkov @ 2026-09-16 15:04 UTC (permalink / raw)
To: Luka Absandze, Sandipan Das
Cc: peterz, mingo, acme, namhyung, tglx, dave.hansen, x86, yaoz,
dwmw2, kim.phillips, kvm, linux-perf-users, linux-kernel
+ Sandipan
On Wed, Sep 16, 2026 at 12:33:15PM +0000, Luka Absandze wrote:
> AMD event select 0xFFF (Merge) is the hardware control encoding used by
> Large Increment per Cycle (LIPC) pairs. When written into an odd
> counter's PerfCtl it turns that counter into the upper 16 bits of a
> 64-bit merged accumulator; any subsequent arming write (-(2^47-1)) is
> silently truncated to its low 16 bits, while hwc->prev_count retains the
> full value.
>
> This is particularly problematic with a KVM guest, which will program
> the Merge encoding into its own odd vPMC as a normal part of scheduling
> a LIPC event. KVM intercepts that write and faithfully forwards it to
> the host as a raw event carrying the Merge encoding, where it is
> accepted as an ordinary countable event. Once a counter's PerfCtl holds
> the Merge encoding, every later user of that counter gets a first delta
> inflated by 2^47
>
> Reject Merge (AMD_MERGE_EVENT) in amd_core_hw_config() so it cannot be
> submitted as a user-visible event. The pair mechanism programs it
> itself via x86_pmu.perf_ctr_pair_en; nothing else should do so.
>
> Fixes: 5738891229a2 ("perf/x86/amd: Add support for Large Increment per Cycle Events")
> Reported-by: Yao Zhou <yaoz@meta.com>
> Signed-off-by: Luka Absandze <absandze@amazon.de>
> ---
> arch/x86/events/amd/core.c | 8 ++++++--
> 1 file changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c
> index 49b6b8fce566..cb655c751e5b 100644
> --- a/arch/x86/events/amd/core.c
> +++ b/arch/x86/events/amd/core.c
> @@ -380,8 +380,12 @@ static int amd_core_hw_config(struct perf_event *event)
> else if (event->attr.exclude_guest)
> event->hw.config |= AMD64_EVENTSEL_HOSTONLY;
>
> - if ((x86_pmu.flags & PMU_FL_PAIR) && amd_is_pair_event_code(&event->hw))
> - event->hw.flags |= PERF_X86_EVENT_PAIR;
> + if (x86_pmu.flags & PMU_FL_PAIR) {
> + if ((event->hw.config & AMD64_EVENTSEL_EVENT) == AMD_MERGE_EVENT)
> + return -EINVAL;
> + if (amd_is_pair_event_code(&event->hw))
> + event->hw.flags |= PERF_X86_EVENT_PAIR;
> + }
>
> if (has_branch_stack(event))
> return static_call(amd_pmu_branch_hw_config)(event);
> --
> 2.47.3
>
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] perf/x86/amd: Reject AMD Merge event as a countable event
2026-09-16 14:02 ` Absandze, Luka
@ 2026-09-17 6:44 ` Sandipan Das
0 siblings, 0 replies; 6+ messages in thread
From: Sandipan Das @ 2026-09-17 6:44 UTC (permalink / raw)
To: Absandze, Luka, sashiko-reviews@lists.linux.dev
Cc: kvm@vger.kernel.org, linux-perf-users@vger.kernel.org
On 16-09-2026 19:32, Absandze, Luka wrote:
> On 2026-09-16 12:51, sashiko-bot@kernel.org wrote:
>> [Severity: High]
>> Does returning a permanent -EINVAL error here cause an opportunistic retry storm
>> in KVM?
>>
>> If a KVM guest programs a Large Increment per Cycle (LIPC) event by writing
>> AMD_MERGE_EVENT to an odd vPMC, KVM intercepts this and attempts to create a
>> raw host perf event. When this fails with -EINVAL, KVM's reprogram_counter()
>> propagates the error to kvm_pmu_handle_event():
>>
>> arch/x86/kvm/pmu.c:kvm_pmu_handle_event() {
>> ...
>> if (reprogram_counter(pmc))
>> set_bit(pmc->idx, pmu->reprogram_pmi);
>> ...
>> }
>>
>> Because KVM treats all failures as transient and unconditionally re-adds the
>> failing counter to pmu->reprogram_pmi, on every subsequent PMU refresh KVM
>> will repeatedly retry the failed counter.
>>
>> Could this create a permanent retry storm that degrades VM performance and
>> wastes host CPU cycles?
>>
>
> There ins't any substantial load generated, we short circuit here before
> the expesnive parts. However, a followup in KVM could be beneficial to
> reject this case outright.
>
> I'll wait for opinions
I think it makes sense for the host layer to reject PMCxFFF altogether. Today,
at least for emulated vPMU, when a KVM guest programs a LIPC event, 3 PMCs are
consumed. This will ensure that the 3rd one, initiated by the guest programming
PMCxFFF, is dropped.
I also agree that a followup in KVM is required.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] perf/x86/amd: Reject AMD Merge event as a countable event
2026-09-16 12:33 [PATCH] perf/x86/amd: Reject AMD Merge event as a countable event Luka Absandze
2026-09-16 12:51 ` sashiko-bot
2026-09-16 15:04 ` Borislav Petkov
@ 2026-09-21 5:09 ` Sandipan Das
2 siblings, 0 replies; 6+ messages in thread
From: Sandipan Das @ 2026-09-21 5:09 UTC (permalink / raw)
To: Luka Absandze, peterz, mingo, acme, namhyung, tglx, bp,
dave.hansen, x86, yaoz, dwmw2
Cc: kim.phillips, kvm, linux-perf-users, linux-kernel
On 16-09-2026 18:03, Luka Absandze wrote:
> AMD event select 0xFFF (Merge) is the hardware control encoding used by
> Large Increment per Cycle (LIPC) pairs. When written into an odd
> counter's PerfCtl it turns that counter into the upper 16 bits of a
> 64-bit merged accumulator; any subsequent arming write (-(2^47-1)) is
> silently truncated to its low 16 bits, while hwc->prev_count retains the
> full value.
>
> This is particularly problematic with a KVM guest, which will program
> the Merge encoding into its own odd vPMC as a normal part of scheduling
> a LIPC event. KVM intercepts that write and faithfully forwards it to
> the host as a raw event carrying the Merge encoding, where it is
> accepted as an ordinary countable event. Once a counter's PerfCtl holds
> the Merge encoding, every later user of that counter gets a first delta
> inflated by 2^47
>
> Reject Merge (AMD_MERGE_EVENT) in amd_core_hw_config() so it cannot be
> submitted as a user-visible event. The pair mechanism programs it
> itself via x86_pmu.perf_ctr_pair_en; nothing else should do so.
>
> Fixes: 5738891229a2 ("perf/x86/amd: Add support for Large Increment per Cycle Events")
> Reported-by: Yao Zhou <yaoz@meta.com>
> Signed-off-by: Luka Absandze <absandze@amazon.de>
> ---
> arch/x86/events/amd/core.c | 8 ++++++--
> 1 file changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c
> index 49b6b8fce566..cb655c751e5b 100644
> --- a/arch/x86/events/amd/core.c
> +++ b/arch/x86/events/amd/core.c
> @@ -380,8 +380,12 @@ static int amd_core_hw_config(struct perf_event *event)
> else if (event->attr.exclude_guest)
> event->hw.config |= AMD64_EVENTSEL_HOSTONLY;
>
> - if ((x86_pmu.flags & PMU_FL_PAIR) && amd_is_pair_event_code(&event->hw))
> - event->hw.flags |= PERF_X86_EVENT_PAIR;
> + if (x86_pmu.flags & PMU_FL_PAIR) {
> + if ((event->hw.config & AMD64_EVENTSEL_EVENT) == AMD_MERGE_EVENT)
> + return -EINVAL;
> + if (amd_is_pair_event_code(&event->hw))
> + event->hw.flags |= PERF_X86_EVENT_PAIR;
> + }
>
> if (has_branch_stack(event))
> return static_call(amd_pmu_branch_hw_config)(event);
Reviewed-by: Sandipan Das <sandipan.das@amd.com>
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-09-21 5:09 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-16 12:33 [PATCH] perf/x86/amd: Reject AMD Merge event as a countable event Luka Absandze
2026-09-16 12:51 ` sashiko-bot
2026-09-16 14:02 ` Absandze, Luka
2026-09-17 6:44 ` Sandipan Das
2026-09-16 15:04 ` Borislav Petkov
2026-09-21 5:09 ` Sandipan Das
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox