Skip to content

Commit 0e6f467

Browse files
committed
KVM: x86/pmu: mask the result of rdpmc according to the width of the counters
This patch will simplify the changes in the next, by enforcing the masking of the counters to RDPMC and RDMSR. Signed-off-by: Paolo Bonzini <[email protected]>
1 parent a80c4ec commit 0e6f467

File tree

4 files changed

+15
-13
lines changed

4 files changed

+15
-13
lines changed

arch/x86/kvm/pmu.c

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -283,23 +283,19 @@ int kvm_pmu_rdpmc(struct kvm_vcpu *vcpu, unsigned idx, u64 *data)
283283
bool fast_mode = idx & (1u << 31);
284284
struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
285285
struct kvm_pmc *pmc;
286-
u64 ctr_val;
286+
u64 mask = fast_mode ? ~0u : ~0ull;
287287

288288
if (!pmu->version)
289289
return 1;
290290

291291
if (is_vmware_backdoor_pmc(idx))
292292
return kvm_pmu_rdpmc_vmware(vcpu, idx, data);
293293

294-
pmc = kvm_x86_ops->pmu_ops->msr_idx_to_pmc(vcpu, idx);
294+
pmc = kvm_x86_ops->pmu_ops->msr_idx_to_pmc(vcpu, idx, &mask);
295295
if (!pmc)
296296
return 1;
297297

298-
ctr_val = pmc_read_counter(pmc);
299-
if (fast_mode)
300-
ctr_val = (u32)ctr_val;
301-
302-
*data = ctr_val;
298+
*data = pmc_read_counter(pmc) & mask;
303299
return 0;
304300
}
305301

arch/x86/kvm/pmu.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ struct kvm_pmu_ops {
2525
unsigned (*find_fixed_event)(int idx);
2626
bool (*pmc_is_enabled)(struct kvm_pmc *pmc);
2727
struct kvm_pmc *(*pmc_idx_to_pmc)(struct kvm_pmu *pmu, int pmc_idx);
28-
struct kvm_pmc *(*msr_idx_to_pmc)(struct kvm_vcpu *vcpu, unsigned idx);
28+
struct kvm_pmc *(*msr_idx_to_pmc)(struct kvm_vcpu *vcpu, unsigned idx,
29+
u64 *mask);
2930
int (*is_valid_msr_idx)(struct kvm_vcpu *vcpu, unsigned idx);
3031
bool (*is_valid_msr)(struct kvm_vcpu *vcpu, u32 msr);
3132
int (*get_msr)(struct kvm_vcpu *vcpu, u32 msr, u64 *data);

arch/x86/kvm/pmu_amd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ static int amd_is_valid_msr_idx(struct kvm_vcpu *vcpu, unsigned idx)
186186
}
187187

188188
/* idx is the ECX register of RDPMC instruction */
189-
static struct kvm_pmc *amd_msr_idx_to_pmc(struct kvm_vcpu *vcpu, unsigned idx)
189+
static struct kvm_pmc *amd_msr_idx_to_pmc(struct kvm_vcpu *vcpu, unsigned idx, u64 *mask)
190190
{
191191
struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
192192
struct kvm_pmc *counters;

arch/x86/kvm/vmx/pmu_intel.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ static int intel_is_valid_msr_idx(struct kvm_vcpu *vcpu, unsigned idx)
126126
}
127127

128128
static struct kvm_pmc *intel_msr_idx_to_pmc(struct kvm_vcpu *vcpu,
129-
unsigned idx)
129+
unsigned idx, u64 *mask)
130130
{
131131
struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
132132
bool fixed = idx & (1u << 30);
@@ -138,6 +138,7 @@ static struct kvm_pmc *intel_msr_idx_to_pmc(struct kvm_vcpu *vcpu,
138138
if (fixed && idx >= pmu->nr_arch_fixed_counters)
139139
return NULL;
140140
counters = fixed ? pmu->fixed_counters : pmu->gp_counters;
141+
*mask &= pmu->counter_bitmask[fixed ? KVM_PMC_FIXED : KVM_PMC_GP];
141142

142143
return &counters[idx];
143144
}
@@ -183,9 +184,13 @@ static int intel_pmu_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *data)
183184
*data = pmu->global_ovf_ctrl;
184185
return 0;
185186
default:
186-
if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0)) ||
187-
(pmc = get_fixed_pmc(pmu, msr))) {
188-
*data = pmc_read_counter(pmc);
187+
if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0))) {
188+
u64 val = pmc_read_counter(pmc);
189+
*data = val & pmu->counter_bitmask[KVM_PMC_GP];
190+
return 0;
191+
} else if ((pmc = get_fixed_pmc(pmu, msr))) {
192+
u64 val = pmc_read_counter(pmc);
193+
*data = val & pmu->counter_bitmask[KVM_PMC_FIXED];
189194
return 0;
190195
} else if ((pmc = get_gp_pmc(pmu, msr, MSR_P6_EVNTSEL0))) {
191196
*data = pmc->eventsel;

0 commit comments

Comments
 (0)