diff options
author | Nadav Amit <namit@cs.technion.ac.il> | 2014-06-02 18:34:09 +0300 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2014-06-18 17:46:18 +0200 |
commit | 67f4d4288c353734d29c45f6725971c71af96791 (patch) | |
tree | 6cec4548ccd3e2357512aa028c4ab8f1f61b9ffc /arch/x86/kvm/pmu.c | |
parent | 3b32004a66e96e17d2a031c08d3304245c506dfc (diff) | |
download | linux-67f4d4288c353734d29c45f6725971c71af96791.tar.gz linux-67f4d4288c353734d29c45f6725971c71af96791.tar.bz2 linux-67f4d4288c353734d29c45f6725971c71af96791.zip |
KVM: x86: rdpmc emulation checks the counter incorrectly
The rdpmc emulation checks that the counter (ECX) is not higher than 2, without
taking into considerations bits 30:31 role (e.g., bit 30 marks whether the
counter is fixed). The fix uses the pmu information for checking the validity
of the pmu counter.
Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch/x86/kvm/pmu.c')
-rw-r--r-- | arch/x86/kvm/pmu.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c index cbecaa90399c..3dd6accb64ec 100644 --- a/arch/x86/kvm/pmu.c +++ b/arch/x86/kvm/pmu.c @@ -428,6 +428,15 @@ int kvm_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) return 1; } +int kvm_pmu_check_pmc(struct kvm_vcpu *vcpu, unsigned pmc) +{ + struct kvm_pmu *pmu = &vcpu->arch.pmu; + bool fixed = pmc & (1u << 30); + pmc &= ~(3u << 30); + return (!fixed && pmc >= pmu->nr_arch_gp_counters) || + (fixed && pmc >= pmu->nr_arch_fixed_counters); +} + int kvm_pmu_read_pmc(struct kvm_vcpu *vcpu, unsigned pmc, u64 *data) { struct kvm_pmu *pmu = &vcpu->arch.pmu; |