From: Nadav Amit <namit@cs.technion.ac.il>
To: pbonzini@redhat.com
Cc: gleb@kernel.org, tglx@linutronix.de, mingo@redhat.com,
hpa@zytor.com, x86@kernel.org, kvm@vger.kernel.org,
linux-kernel@vger.kernel.org,
Nadav Amit <namit@cs.technion.ac.il>
Subject: [PATCH 7/9] KVM: x86: rdpmc emulation checks the counter incorrectly
Date: Mon, 2 Jun 2014 18:34:09 +0300 [thread overview]
Message-ID: <1401723251-8034-8-git-send-email-namit@cs.technion.ac.il> (raw)
In-Reply-To: <1401723251-8034-1-git-send-email-namit@cs.technion.ac.il>
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>
---
arch/x86/include/asm/kvm_emulate.h | 1 +
arch/x86/include/asm/kvm_host.h | 1 +
arch/x86/kvm/emulate.c | 2 +-
arch/x86/kvm/pmu.c | 9 +++++++++
arch/x86/kvm/x86.c | 7 +++++++
5 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
index a04fe4e..ffa2671 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -194,6 +194,7 @@ struct x86_emulate_ops {
int (*set_dr)(struct x86_emulate_ctxt *ctxt, int dr, ulong value);
int (*set_msr)(struct x86_emulate_ctxt *ctxt, u32 msr_index, u64 data);
int (*get_msr)(struct x86_emulate_ctxt *ctxt, u32 msr_index, u64 *pdata);
+ int (*check_pmc)(struct x86_emulate_ctxt *ctxt, u32 pmc);
int (*read_pmc)(struct x86_emulate_ctxt *ctxt, u32 pmc, u64 *pdata);
void (*halt)(struct x86_emulate_ctxt *ctxt);
void (*wbinvd)(struct x86_emulate_ctxt *ctxt);
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 4931415..63e020b 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1070,6 +1070,7 @@ void kvm_pmu_cpuid_update(struct kvm_vcpu *vcpu);
bool kvm_pmu_msr(struct kvm_vcpu *vcpu, u32 msr);
int kvm_pmu_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *data);
int kvm_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info);
+int kvm_pmu_check_pmc(struct kvm_vcpu *vcpu, unsigned pmc);
int kvm_pmu_read_pmc(struct kvm_vcpu *vcpu, unsigned pmc, u64 *data);
void kvm_handle_pmu_event(struct kvm_vcpu *vcpu);
void kvm_deliver_pmi(struct kvm_vcpu *vcpu);
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index be3f764..3da8d82 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -3507,7 +3507,7 @@ static int check_rdpmc(struct x86_emulate_ctxt *ctxt)
u64 rcx = reg_read(ctxt, VCPU_REGS_RCX);
if ((!(cr4 & X86_CR4_PCE) && ctxt->ops->cpl(ctxt)) ||
- (rcx > 3))
+ ctxt->ops->check_pmc(ctxt, rcx))
return emulate_gp(ctxt, 0);
return X86EMUL_CONTINUE;
diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
index cbecaa9..3dd6acc 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;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 57eac30..2c6fccd 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4759,6 +4759,12 @@ static int emulator_set_msr(struct x86_emulate_ctxt *ctxt,
return kvm_set_msr(emul_to_vcpu(ctxt), &msr);
}
+static int emulator_check_pmc(struct x86_emulate_ctxt *ctxt,
+ u32 pmc)
+{
+ return kvm_pmu_check_pmc(emul_to_vcpu(ctxt), pmc);
+}
+
static int emulator_read_pmc(struct x86_emulate_ctxt *ctxt,
u32 pmc, u64 *pdata)
{
@@ -4835,6 +4841,7 @@ static const struct x86_emulate_ops emulate_ops = {
.set_dr = emulator_set_dr,
.set_msr = emulator_set_msr,
.get_msr = emulator_get_msr,
+ .check_pmc = emulator_check_pmc,
.read_pmc = emulator_read_pmc,
.halt = emulator_halt,
.wbinvd = emulator_wbinvd,
--
1.9.1
next prev parent reply other threads:[~2014-06-02 15:34 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-06-02 15:34 [PATCH 0/9] KVM: x86: Fixes for various emulator bugs Nadav Amit
2014-06-02 15:34 ` [PATCH 1/9] KVM: x86: Mark VEX-prefix instructions emulation as unimplemented Nadav Amit
2014-06-02 15:34 ` [PATCH 2/9] KVM: x86: Emulator ignores LDTR/TR extended base on LLDT/LTR Nadav Amit
2014-06-02 15:34 ` [PATCH 3/9] KVM: x86: Loading segments on 64-bit mode may be wrong Nadav Amit
2014-06-02 15:34 ` [PATCH 4/9] KVM: x86: sgdt and sidt are not privilaged Nadav Amit
2014-06-02 15:34 ` [PATCH 5/9] KVM: x86: cmpxchg emulation should compare in reverse order Nadav Amit
2014-06-02 15:34 ` [PATCH 6/9] KVM: x86: movnti minimum op size of 32-bit is not kept Nadav Amit
2014-06-02 15:34 ` Nadav Amit [this message]
2014-06-02 15:34 ` [PATCH 8/9] KVM: x86: Return error on cmpxchg16b emulation Nadav Amit
2014-06-02 15:34 ` [PATCH 9/9] KVM: x86: smsw emulation is incorrect in 64-bit mode Nadav Amit
2014-06-05 14:53 ` Paolo Bonzini
2014-06-05 15:02 ` Nadav Amit
2014-06-05 15:04 ` H. Peter Anvin
2014-06-05 15:27 ` Paolo Bonzini
2014-06-05 23:56 ` [PATCH kvm-unit-tests 0/2] x86: Additional smsw tests Nadav Amit
2014-06-05 23:56 ` [PATCH kvm-unit-tests1/2] x86: emulator: additional smsw test-case Nadav Amit
2014-06-09 11:36 ` Paolo Bonzini
2014-06-05 23:56 ` [PATCH kvm-unit-tests 2/2] x86: realmode: test smsw behavior with register operand Nadav Amit
2014-06-06 8:04 ` [PATCH kvm-unit-tests 0/2] x86: Additional smsw tests Paolo Bonzini
2014-06-08 10:02 ` [PATCH kvm-unit-tests v2] x86: emulator: long mode " Nadav Amit
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1401723251-8034-8-git-send-email-namit@cs.technion.ac.il \
--to=namit@cs.technion.ac.il \
--cc=gleb@kernel.org \
--cc=hpa@zytor.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=pbonzini@redhat.com \
--cc=tglx@linutronix.de \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®