* [PATCH 1/1] target/i386/kvm: Use logical counter index for AMD PMU getter
@ 2026-03-25 2:12 Dongli Zhang
0 siblings, 0 replies; only message 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] only message in thread
only message in thread, other threads:[~2026-03-25 2:13 UTC | newest]
Thread overview: (only message) (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
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox