Kernel KVM virtualization development
 help / color / mirror / Atom feed
* [PATCH 1/1] target/i386/kvm: Use logical counter index for AMD PMU getter
@ 2026-03-25  2:12 Dongli Zhang
  2026-03-26 16:44 ` Chen, Zide
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Dongli Zhang @ 2026-03-25  2:12 UTC (permalink / raw)
  To: qemu-devel
  Cc: kvm, pbonzini, mtosatti, dapeng1.mi, zhao1.liu, sandipan.das,
	zide.chen, joe.jin

For Intel PMU, the counter and selector MSR ranges are disjoint. AMD PMU
behaves the same way when PerfCore is unavailable.

However, once PerfCore is present, AMD PMU switches to an interleaved
layout in which selector and counter MSRs share a single alternating range.

MSR_F15H_PERF_CTL0 = 0xc0010200
MSR_F15H_PERF_CTR0 = 0xc0010201
... ...
... ...
MSR_F15H_PERF_CTL5 = 0xc001020a
MSR_F15H_PERF_CTR5 = 0xc001020b

The commit 4c7f05232c ("target/i386/kvm: reset AMD PMU registers during VM
reset") added the getter/putter pair for AMD PMU MSRs to clear them on
reset, but it ignored that, without PerfCore, AMD reuses alternating MSR
addresses for selectors and counters. env->msr_gp_counters[] holds the raw
counts and env->msr_gp_evtsel[] holds the selectors, so with the
interleaved layout we must translate the MSR address back to the logical
counter index instead of treating the interleaved slot as the array index.

The arrays are sized to MAX_GP_COUNTERS = 18, so the code never writes past
the end. And in the reset path QEMU simply zeroes everything, so that use
case still works.

However, the live migration is broken. The PMU state is stored at the
wrong indices, so the destination VM reloads mismatched selector/counter
pairs. Fix the getter to use the logical counter index rather than the raw
interleaved offset.

Fixes: 4c7f05232c ("target/i386/kvm: reset AMD PMU registers during VM reset")
Signed-off-by: Dongli Zhang <dongli.zhang@oracle.com>
---
 target/i386/kvm/kvm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 9e352882c8..b4e549c62b 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -5239,9 +5239,9 @@ static int kvm_get_msrs(X86CPU *cpu)
              MSR_F15H_PERF_CTL0 + AMD64_NUM_COUNTERS_CORE * 2 - 1:
             index = index - MSR_F15H_PERF_CTL0;
             if (index & 0x1) {
-                env->msr_gp_counters[index] = msrs[i].data;
+                env->msr_gp_counters[index >> 1] = msrs[i].data;
             } else {
-                env->msr_gp_evtsel[index] = msrs[i].data;
+                env->msr_gp_evtsel[index >> 1] = msrs[i].data;
             }
             break;
         case HV_X64_MSR_HYPERCALL:
-- 
2.39.3


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* RE: [PATCH 1/1] target/i386/kvm: Use logical counter index for AMD PMU getter
  2026-03-25  2:12 [PATCH 1/1] target/i386/kvm: Use logical counter index for AMD PMU getter Dongli Zhang
@ 2026-03-26 16:44 ` Chen, Zide
  2026-04-06 15:17   ` Dongli Zhang
  2026-06-05  6:09   ` Dongli Zhang
  2026-06-05 14:45 ` Sandipan Das
  2026-06-09 14:09 ` Zhao Liu
  2 siblings, 2 replies; 6+ messages in thread
From: Chen, Zide @ 2026-03-26 16:44 UTC (permalink / raw)
  To: Dongli Zhang, qemu-devel@nongnu.org
  Cc: kvm@vger.kernel.org, pbonzini@redhat.com, mtosatti@redhat.com,
	dapeng1.mi@linux.intel.com, Liu, Zhao1, sandipan.das@amd.com,
	joe.jin@oracle.com



> -----Original Message-----
> From: Dongli Zhang <dongli.zhang@oracle.com>
> Sent: Tuesday, March 24, 2026 7:13 PM
> To: qemu-devel@nongnu.org
> Cc: kvm@vger.kernel.org; pbonzini@redhat.com; mtosatti@redhat.com;
> dapeng1.mi@linux.intel.com; Liu, Zhao1 <zhao1.liu@intel.com>;
> sandipan.das@amd.com; Chen, Zide <zide.chen@intel.com>;
> joe.jin@oracle.com
> Subject: [PATCH 1/1] target/i386/kvm: Use logical counter index for AMD PMU
> getter
> 
> For Intel PMU, the counter and selector MSR ranges are disjoint. AMD PMU
> behaves the same way when PerfCore is unavailable.
> 
> However, once PerfCore is present, AMD PMU switches to an interleaved
> layout in which selector and counter MSRs share a single alternating range.
> 
> MSR_F15H_PERF_CTL0 = 0xc0010200
> MSR_F15H_PERF_CTR0 = 0xc0010201
> ... ...
> ... ...
> MSR_F15H_PERF_CTL5 = 0xc001020a
> MSR_F15H_PERF_CTR5 = 0xc001020b
> 
> The commit 4c7f05232c ("target/i386/kvm: reset AMD PMU registers during
> VM
> reset") added the getter/putter pair for AMD PMU MSRs to clear them on
> reset, but it ignored that, without PerfCore, AMD reuses alternating MSR
> addresses for selectors and counters. env->msr_gp_counters[] holds the raw
> counts and env->msr_gp_evtsel[] holds the selectors, so with the interleaved
> layout we must translate the MSR address back to the logical counter index
> instead of treating the interleaved slot as the array index.
> 
> The arrays are sized to MAX_GP_COUNTERS = 18, so the code never writes
> past the end. And in the reset path QEMU simply zeroes everything, so that
> use case still works.
> 
> However, the live migration is broken. The PMU state is stored at the wrong
> indices, so the destination VM reloads mismatched selector/counter pairs. Fix
> the getter to use the logical counter index rather than the raw interleaved
> offset.
> 
> Fixes: 4c7f05232c ("target/i386/kvm: reset AMD PMU registers during VM
> reset")
> Signed-off-by: Dongli Zhang <dongli.zhang@oracle.com>
> ---

Reviewed-by: Zide Chen <zide.chen@intel.com>

>  target/i386/kvm/kvm.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c index
> 9e352882c8..b4e549c62b 100644
> --- a/target/i386/kvm/kvm.c
> +++ b/target/i386/kvm/kvm.c
> @@ -5239,9 +5239,9 @@ static int kvm_get_msrs(X86CPU *cpu)
>               MSR_F15H_PERF_CTL0 + AMD64_NUM_COUNTERS_CORE * 2 - 1:
>              index = index - MSR_F15H_PERF_CTL0;
>              if (index & 0x1) {
> -                env->msr_gp_counters[index] = msrs[i].data;
> +                env->msr_gp_counters[index >> 1] = msrs[i].data;
>              } else {
> -                env->msr_gp_evtsel[index] = msrs[i].data;
> +                env->msr_gp_evtsel[index >> 1] = msrs[i].data;
>              }
>              break;
>          case HV_X64_MSR_HYPERCALL:
> --
> 2.39.3


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/1] target/i386/kvm: Use logical counter index for AMD PMU getter
  2026-03-26 16:44 ` Chen, Zide
@ 2026-04-06 15:17   ` Dongli Zhang
  2026-06-05  6:09   ` Dongli Zhang
  1 sibling, 0 replies; 6+ messages in thread
From: Dongli Zhang @ 2026-04-06 15:17 UTC (permalink / raw)
  To: qemu-devel@nongnu.org
  Cc: kvm@vger.kernel.org, pbonzini@redhat.com, mtosatti@redhat.com,
	dapeng1.mi@linux.intel.com, Liu, Zhao1, sandipan.das@amd.com,
	joe.jin@oracle.com, Chen, Zide

Ping?

Any chance we can merge this bugfix? This change fixes AMD vPMU live migration
for the upcoming v11.0.0.

Thank you very much!

Dongli Zhang

On 3/26/26 9:44 AM, Chen, Zide wrote:
> 
> 
[snip]
>>
>> Fixes: 4c7f05232c ("target/i386/kvm: reset AMD PMU registers during VM
>> reset")
>> Signed-off-by: Dongli Zhang <dongli.zhang@oracle.com>
>> ---
> 
> Reviewed-by: Zide Chen <zide.chen@intel.com>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/1] target/i386/kvm: Use logical counter index for AMD PMU getter
  2026-03-26 16:44 ` Chen, Zide
  2026-04-06 15:17   ` Dongli Zhang
@ 2026-06-05  6:09   ` Dongli Zhang
  1 sibling, 0 replies; 6+ messages in thread
From: Dongli Zhang @ 2026-06-05  6:09 UTC (permalink / raw)
  To: Chen, Zide, qemu-devel@nongnu.org, pbonzini@redhat.com
  Cc: kvm@vger.kernel.org, mtosatti@redhat.com,
	dapeng1.mi@linux.intel.com, Liu, Zhao1, sandipan.das@amd.com,
	joe.jin@oracle.com

Hi Paolo,

Apologies for bothering you.

Would it be possible to merge this bugfix? It has already been reviewed by Cide,
and I have verified that it still applies cleanly to the latest mainline QEMU
commit.

Live migration of AMD PMUs will not work correctly without this fix.

At the moment, there is no actual out-of-bounds memory access because
MAX_GP_COUNTERS is large enough. A recent patch will reduce MAX_GP_COUNTERS to
15, which is still safe.

[PATCH v4 3/6] target/i386: Adjust maximum number of PMU counters
https://lore.kernel.org/qemu-devel/20260604025546.19378-4-zide.chen@intel.com

However, if MAX_GP_COUNTERS is reduced further to fewer than 12 in the future,
this could result in an out-of-bounds memory access.

Thank you very much!

Dongli Zhang

On 2026-03-26 9:44 AM, Chen, Zide wrote:
> 
> 
>> -----Original Message-----
>> From: Dongli Zhang <dongli.zhang@oracle.com>
>> Sent: Tuesday, March 24, 2026 7:13 PM
>> To: qemu-devel@nongnu.org
>> Cc: kvm@vger.kernel.org; pbonzini@redhat.com; mtosatti@redhat.com;
>> dapeng1.mi@linux.intel.com; Liu, Zhao1 <zhao1.liu@intel.com>;
>> sandipan.das@amd.com; Chen, Zide <zide.chen@intel.com>;
>> joe.jin@oracle.com
>> Subject: [PATCH 1/1] target/i386/kvm: Use logical counter index for AMD PMU
>> getter
>>
>> For Intel PMU, the counter and selector MSR ranges are disjoint. AMD PMU
>> behaves the same way when PerfCore is unavailable.
>>
>> However, once PerfCore is present, AMD PMU switches to an interleaved
>> layout in which selector and counter MSRs share a single alternating range.
>>
>> MSR_F15H_PERF_CTL0 = 0xc0010200
>> MSR_F15H_PERF_CTR0 = 0xc0010201
>> ... ...
>> ... ...
>> MSR_F15H_PERF_CTL5 = 0xc001020a
>> MSR_F15H_PERF_CTR5 = 0xc001020b
>>
>> The commit 4c7f05232c ("target/i386/kvm: reset AMD PMU registers during
>> VM
>> reset") added the getter/putter pair for AMD PMU MSRs to clear them on
>> reset, but it ignored that, without PerfCore, AMD reuses alternating MSR
>> addresses for selectors and counters. env->msr_gp_counters[] holds the raw
>> counts and env->msr_gp_evtsel[] holds the selectors, so with the interleaved
>> layout we must translate the MSR address back to the logical counter index
>> instead of treating the interleaved slot as the array index.
>>
>> The arrays are sized to MAX_GP_COUNTERS = 18, so the code never writes
>> past the end. And in the reset path QEMU simply zeroes everything, so that
>> use case still works.
>>
>> However, the live migration is broken. The PMU state is stored at the wrong
>> indices, so the destination VM reloads mismatched selector/counter pairs. Fix
>> the getter to use the logical counter index rather than the raw interleaved
>> offset.
>>
>> Fixes: 4c7f05232c ("target/i386/kvm: reset AMD PMU registers during VM
>> reset")
>> Signed-off-by: Dongli Zhang <dongli.zhang@oracle.com>
>> ---
> 
> Reviewed-by: Zide Chen <zide.chen@intel.com>
> 
>>  target/i386/kvm/kvm.c | 4 ++--
>>  1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c index
>> 9e352882c8..b4e549c62b 100644
>> --- a/target/i386/kvm/kvm.c
>> +++ b/target/i386/kvm/kvm.c
>> @@ -5239,9 +5239,9 @@ static int kvm_get_msrs(X86CPU *cpu)
>>               MSR_F15H_PERF_CTL0 + AMD64_NUM_COUNTERS_CORE * 2 - 1:
>>              index = index - MSR_F15H_PERF_CTL0;
>>              if (index & 0x1) {
>> -                env->msr_gp_counters[index] = msrs[i].data;
>> +                env->msr_gp_counters[index >> 1] = msrs[i].data;
>>              } else {
>> -                env->msr_gp_evtsel[index] = msrs[i].data;
>> +                env->msr_gp_evtsel[index >> 1] = msrs[i].data;
>>              }
>>              break;
>>          case HV_X64_MSR_HYPERCALL:
>> --
>> 2.39.3
> 


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/1] target/i386/kvm: Use logical counter index for AMD PMU getter
  2026-03-25  2:12 [PATCH 1/1] target/i386/kvm: Use logical counter index for AMD PMU getter Dongli Zhang
  2026-03-26 16:44 ` Chen, Zide
@ 2026-06-05 14:45 ` Sandipan Das
  2026-06-09 14:09 ` Zhao Liu
  2 siblings, 0 replies; 6+ messages in thread
From: Sandipan Das @ 2026-06-05 14:45 UTC (permalink / raw)
  To: Dongli Zhang, qemu-devel
  Cc: kvm, pbonzini, mtosatti, dapeng1.mi, zhao1.liu, zide.chen,
	joe.jin

On 25-03-2026 07:42, Dongli Zhang wrote:
> For Intel PMU, the counter and selector MSR ranges are disjoint. AMD PMU
> behaves the same way when PerfCore is unavailable.
> 
> However, once PerfCore is present, AMD PMU switches to an interleaved
> layout in which selector and counter MSRs share a single alternating range.
> 
> MSR_F15H_PERF_CTL0 = 0xc0010200
> MSR_F15H_PERF_CTR0 = 0xc0010201
> ... ...
> ... ...
> MSR_F15H_PERF_CTL5 = 0xc001020a
> MSR_F15H_PERF_CTR5 = 0xc001020b
> 
> The commit 4c7f05232c ("target/i386/kvm: reset AMD PMU registers during VM
> reset") added the getter/putter pair for AMD PMU MSRs to clear them on
> reset, but it ignored that, without PerfCore, AMD reuses alternating MSR
> addresses for selectors and counters. env->msr_gp_counters[] holds the raw
> counts and env->msr_gp_evtsel[] holds the selectors, so with the
> interleaved layout we must translate the MSR address back to the logical
> counter index instead of treating the interleaved slot as the array index.
> 
> The arrays are sized to MAX_GP_COUNTERS = 18, so the code never writes past
> the end. And in the reset path QEMU simply zeroes everything, so that use
> case still works.
> 
> However, the live migration is broken. The PMU state is stored at the
> wrong indices, so the destination VM reloads mismatched selector/counter
> pairs. Fix the getter to use the logical counter index rather than the raw
> interleaved offset.
> 
> Fixes: 4c7f05232c ("target/i386/kvm: reset AMD PMU registers during VM reset")
> Signed-off-by: Dongli Zhang <dongli.zhang@oracle.com>
> ---

Reviewed-by: Sandipan Das <sandipan.das@amd.com>


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/1] target/i386/kvm: Use logical counter index for AMD PMU getter
  2026-03-25  2:12 [PATCH 1/1] target/i386/kvm: Use logical counter index for AMD PMU getter Dongli Zhang
  2026-03-26 16:44 ` Chen, Zide
  2026-06-05 14:45 ` Sandipan Das
@ 2026-06-09 14:09 ` Zhao Liu
  2 siblings, 0 replies; 6+ messages in thread
From: Zhao Liu @ 2026-06-09 14:09 UTC (permalink / raw)
  To: Dongli Zhang
  Cc: qemu-devel, kvm, pbonzini, mtosatti, dapeng1.mi, sandipan.das,
	zide.chen, joe.jin, qemu-stable

Cc: qemu-stable@nongnu.org

On Tue, Mar 24, 2026 at 07:12:36PM -0700, Dongli Zhang wrote:
> Date: Tue, 24 Mar 2026 19:12:36 -0700
> From: Dongli Zhang <dongli.zhang@oracle.com>
> Subject: [PATCH 1/1] target/i386/kvm: Use logical counter index for AMD PMU
>  getter
> X-Mailer: git-send-email 2.43.5
> 
> For Intel PMU, the counter and selector MSR ranges are disjoint. AMD PMU
> behaves the same way when PerfCore is unavailable.
> 
> However, once PerfCore is present, AMD PMU switches to an interleaved
> layout in which selector and counter MSRs share a single alternating range.
> 
> MSR_F15H_PERF_CTL0 = 0xc0010200
> MSR_F15H_PERF_CTR0 = 0xc0010201
> ... ...
> ... ...
> MSR_F15H_PERF_CTL5 = 0xc001020a
> MSR_F15H_PERF_CTR5 = 0xc001020b
> 
> The commit 4c7f05232c ("target/i386/kvm: reset AMD PMU registers during VM
> reset") added the getter/putter pair for AMD PMU MSRs to clear them on
> reset, but it ignored that, without PerfCore, AMD reuses alternating MSR
> addresses for selectors and counters. env->msr_gp_counters[] holds the raw
> counts and env->msr_gp_evtsel[] holds the selectors, so with the
> interleaved layout we must translate the MSR address back to the logical
> counter index instead of treating the interleaved slot as the array index.
> 
> The arrays are sized to MAX_GP_COUNTERS = 18, so the code never writes past
> the end. And in the reset path QEMU simply zeroes everything, so that use
> case still works.
> 
> However, the live migration is broken. The PMU state is stored at the
> wrong indices, so the destination VM reloads mismatched selector/counter
> pairs. Fix the getter to use the logical counter index rather than the raw
> interleaved offset.
> 
> Fixes: 4c7f05232c ("target/i386/kvm: reset AMD PMU registers during VM reset")
> Signed-off-by: Dongli Zhang <dongli.zhang@oracle.com>
> ---
>  target/i386/kvm/kvm.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

Sorry for late response, LGTM,

Reviewed-by: Zhao Liu <zhao1.liu@intel.com>



^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-06-09 13:41 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-25  2:12 [PATCH 1/1] target/i386/kvm: Use logical counter index for AMD PMU getter Dongli Zhang
2026-03-26 16:44 ` Chen, Zide
2026-04-06 15:17   ` Dongli Zhang
2026-06-05  6:09   ` Dongli Zhang
2026-06-05 14:45 ` Sandipan Das
2026-06-09 14:09 ` Zhao Liu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox