diff options
author | Avi Kivity <avi@redhat.com> | 2011-11-10 07:57:30 -0500 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2011-12-27 04:24:43 -0500 |
commit | 222d21aa070a4885ce3c7125a1b7ce07429ea4a1 (patch) | |
tree | dbbfa00ef566c75bf7e412a894745ee050b35b26 /arch | |
parent | 80bdec64c05b645708b0dd97919783ad077fcdc8 (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.h | 1 | ||||
-rw-r--r-- | arch/x86/kvm/emulate.c | 13 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 7 |
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 | ||
2648 | static 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 | |||
2648 | static int em_mov(struct x86_emulate_ctxt *ctxt) | 2659 | static 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 | ||
4149 | static 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 | |||
4149 | static void emulator_halt(struct x86_emulate_ctxt *ctxt) | 4155 | static 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, |