aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2011-11-10 07:57:30 -0500
committerAvi Kivity <avi@redhat.com>2011-12-27 04:24:43 -0500
commit222d21aa070a4885ce3c7125a1b7ce07429ea4a1 (patch)
treedbbfa00ef566c75bf7e412a894745ee050b35b26 /arch
parent80bdec64c05b645708b0dd97919783ad077fcdc8 (diff)
KVM: x86 emulator: implement RDPMC (0F 33)
Signed-off-by: Avi Kivity <avi@redhat.com> Signed-off-by: Gleb Natapov <gleb@redhat.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/include/asm/kvm_emulate.h1
-rw-r--r--arch/x86/kvm/emulate.c13
-rw-r--r--arch/x86/kvm/x86.c7
3 files changed, 20 insertions, 1 deletions
diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
index 9a4acf41709c..ab4092e3214e 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -181,6 +181,7 @@ struct x86_emulate_ops {
181 int (*set_dr)(struct x86_emulate_ctxt *ctxt, int dr, ulong value); 181 int (*set_dr)(struct x86_emulate_ctxt *ctxt, int dr, ulong value);
182 int (*set_msr)(struct x86_emulate_ctxt *ctxt, u32 msr_index, u64 data); 182 int (*set_msr)(struct x86_emulate_ctxt *ctxt, u32 msr_index, u64 data);
183 int (*get_msr)(struct x86_emulate_ctxt *ctxt, u32 msr_index, u64 *pdata); 183 int (*get_msr)(struct x86_emulate_ctxt *ctxt, u32 msr_index, u64 *pdata);
184 int (*read_pmc)(struct x86_emulate_ctxt *ctxt, u32 pmc, u64 *pdata);
184 void (*halt)(struct x86_emulate_ctxt *ctxt); 185 void (*halt)(struct x86_emulate_ctxt *ctxt);
185 void (*wbinvd)(struct x86_emulate_ctxt *ctxt); 186 void (*wbinvd)(struct x86_emulate_ctxt *ctxt);
186 int (*fix_hypercall)(struct x86_emulate_ctxt *ctxt); 187 int (*fix_hypercall)(struct x86_emulate_ctxt *ctxt);
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index d270f1a817dc..05a562b85025 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2645,6 +2645,17 @@ static int em_rdtsc(struct x86_emulate_ctxt *ctxt)
2645 return X86EMUL_CONTINUE; 2645 return X86EMUL_CONTINUE;
2646} 2646}
2647 2647
2648static int em_rdpmc(struct x86_emulate_ctxt *ctxt)
2649{
2650 u64 pmc;
2651
2652 if (ctxt->ops->read_pmc(ctxt, ctxt->regs[VCPU_REGS_RCX], &pmc))
2653 return emulate_gp(ctxt, 0);
2654 ctxt->regs[VCPU_REGS_RAX] = (u32)pmc;
2655 ctxt->regs[VCPU_REGS_RDX] = pmc >> 32;
2656 return X86EMUL_CONTINUE;
2657}
2658
2648static int em_mov(struct x86_emulate_ctxt *ctxt) 2659static int em_mov(struct x86_emulate_ctxt *ctxt)
2649{ 2660{
2650 ctxt->dst.val = ctxt->src.val; 2661 ctxt->dst.val = ctxt->src.val;
@@ -3411,7 +3422,7 @@ static struct opcode twobyte_table[256] = {
3411 II(ImplicitOps | Priv, em_wrmsr, wrmsr), 3422 II(ImplicitOps | Priv, em_wrmsr, wrmsr),
3412 IIP(ImplicitOps, em_rdtsc, rdtsc, check_rdtsc), 3423 IIP(ImplicitOps, em_rdtsc, rdtsc, check_rdtsc),
3413 II(ImplicitOps | Priv, em_rdmsr, rdmsr), 3424 II(ImplicitOps | Priv, em_rdmsr, rdmsr),
3414 DIP(ImplicitOps, rdpmc, check_rdpmc), 3425 IIP(ImplicitOps, em_rdpmc, rdpmc, check_rdpmc),
3415 I(ImplicitOps | VendorSpecific, em_sysenter), 3426 I(ImplicitOps | VendorSpecific, em_sysenter),
3416 I(ImplicitOps | Priv | VendorSpecific, em_sysexit), 3427 I(ImplicitOps | Priv | VendorSpecific, em_sysexit),
3417 N, N, 3428 N, N,
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 27d18b7617f3..1171def5f96b 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4146,6 +4146,12 @@ static int emulator_set_msr(struct x86_emulate_ctxt *ctxt,
4146 return kvm_set_msr(emul_to_vcpu(ctxt), msr_index, data); 4146 return kvm_set_msr(emul_to_vcpu(ctxt), msr_index, data);
4147} 4147}
4148 4148
4149static int emulator_read_pmc(struct x86_emulate_ctxt *ctxt,
4150 u32 pmc, u64 *pdata)
4151{
4152 return kvm_pmu_read_pmc(emul_to_vcpu(ctxt), pmc, pdata);
4153}
4154
4149static void emulator_halt(struct x86_emulate_ctxt *ctxt) 4155static void emulator_halt(struct x86_emulate_ctxt *ctxt)
4150{ 4156{
4151 emul_to_vcpu(ctxt)->arch.halt_request = 1; 4157 emul_to_vcpu(ctxt)->arch.halt_request = 1;
@@ -4198,6 +4204,7 @@ static struct x86_emulate_ops emulate_ops = {
4198 .set_dr = emulator_set_dr, 4204 .set_dr = emulator_set_dr,
4199 .set_msr = emulator_set_msr, 4205 .set_msr = emulator_set_msr,
4200 .get_msr = emulator_get_msr, 4206 .get_msr = emulator_get_msr,
4207 .read_pmc = emulator_read_pmc,
4201 .halt = emulator_halt, 4208 .halt = emulator_halt,
4202 .wbinvd = emulator_wbinvd, 4209 .wbinvd = emulator_wbinvd,
4203 .fix_hypercall = emulator_fix_hypercall, 4210 .fix_hypercall = emulator_fix_hypercall,