diff options
author | Joerg Roedel <joerg.roedel@amd.com> | 2011-04-04 06:39:33 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2011-05-11 07:57:02 -0400 |
commit | 8061252ee0d21e1289235a4b7fe61f53010c46ff (patch) | |
tree | a6a619255e1aeacb7248593f730fa9cd72d93ec7 /arch/x86/kvm/emulate.c | |
parent | d7eb82030699e6151f1356e90d495bf292564fb7 (diff) |
KVM: SVM: Add intercept checks for remaining twobyte instructions
This patch adds intercepts checks for the remaining twobyte
instructions to the KVM instruction emulator.
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/emulate.c')
-rw-r--r-- | arch/x86/kvm/emulate.c | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index b4adb4cbb5f3..0bf1f68a71c2 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -2425,12 +2425,9 @@ static int em_cwd(struct x86_emulate_ctxt *ctxt) | |||
2425 | 2425 | ||
2426 | static int em_rdtsc(struct x86_emulate_ctxt *ctxt) | 2426 | static int em_rdtsc(struct x86_emulate_ctxt *ctxt) |
2427 | { | 2427 | { |
2428 | unsigned cpl = ctxt->ops->cpl(ctxt->vcpu); | ||
2429 | struct decode_cache *c = &ctxt->decode; | 2428 | struct decode_cache *c = &ctxt->decode; |
2430 | u64 tsc = 0; | 2429 | u64 tsc = 0; |
2431 | 2430 | ||
2432 | if (cpl > 0 && (ctxt->ops->get_cr(4, ctxt->vcpu) & X86_CR4_TSD)) | ||
2433 | return emulate_gp(ctxt, 0); | ||
2434 | ctxt->ops->get_msr(ctxt->vcpu, MSR_IA32_TSC, &tsc); | 2431 | ctxt->ops->get_msr(ctxt->vcpu, MSR_IA32_TSC, &tsc); |
2435 | c->regs[VCPU_REGS_RAX] = (u32)tsc; | 2432 | c->regs[VCPU_REGS_RAX] = (u32)tsc; |
2436 | c->regs[VCPU_REGS_RDX] = tsc >> 32; | 2433 | c->regs[VCPU_REGS_RDX] = tsc >> 32; |
@@ -2614,6 +2611,18 @@ static int check_rdtsc(struct x86_emulate_ctxt *ctxt) | |||
2614 | return X86EMUL_CONTINUE; | 2611 | return X86EMUL_CONTINUE; |
2615 | } | 2612 | } |
2616 | 2613 | ||
2614 | static int check_rdpmc(struct x86_emulate_ctxt *ctxt) | ||
2615 | { | ||
2616 | u64 cr4 = ctxt->ops->get_cr(4, ctxt->vcpu); | ||
2617 | u64 rcx = kvm_register_read(ctxt->vcpu, VCPU_REGS_RCX); | ||
2618 | |||
2619 | if ((!(cr4 & X86_CR4_PCE) && ctxt->ops->cpl(ctxt->vcpu)) || | ||
2620 | (rcx > 3)) | ||
2621 | return emulate_gp(ctxt, 0); | ||
2622 | |||
2623 | return X86EMUL_CONTINUE; | ||
2624 | } | ||
2625 | |||
2617 | #define D(_y) { .flags = (_y) } | 2626 | #define D(_y) { .flags = (_y) } |
2618 | #define DI(_y, _i) { .flags = (_y), .intercept = x86_intercept_##_i } | 2627 | #define DI(_y, _i) { .flags = (_y), .intercept = x86_intercept_##_i } |
2619 | #define DIP(_y, _i, _p) { .flags = (_y), .intercept = x86_intercept_##_i, \ | 2628 | #define DIP(_y, _i, _p) { .flags = (_y), .intercept = x86_intercept_##_i, \ |
@@ -2846,8 +2855,10 @@ static struct opcode twobyte_table[256] = { | |||
2846 | N, N, N, N, | 2855 | N, N, N, N, |
2847 | N, N, N, N, N, N, N, N, | 2856 | N, N, N, N, N, N, N, N, |
2848 | /* 0x30 - 0x3F */ | 2857 | /* 0x30 - 0x3F */ |
2849 | D(ImplicitOps | Priv), II(ImplicitOps, em_rdtsc, rdtsc), | 2858 | DI(ImplicitOps | Priv, wrmsr), |
2850 | D(ImplicitOps | Priv), N, | 2859 | IIP(ImplicitOps, em_rdtsc, rdtsc, check_rdtsc), |
2860 | DI(ImplicitOps | Priv, rdmsr), | ||
2861 | DIP(ImplicitOps | Priv, rdpmc, check_rdpmc), | ||
2851 | D(ImplicitOps | VendorSpecific), D(ImplicitOps | Priv | VendorSpecific), | 2862 | D(ImplicitOps | VendorSpecific), D(ImplicitOps | Priv | VendorSpecific), |
2852 | N, N, | 2863 | N, N, |
2853 | N, N, N, N, N, N, N, N, | 2864 | N, N, N, N, N, N, N, N, |
@@ -2871,12 +2882,12 @@ static struct opcode twobyte_table[256] = { | |||
2871 | X16(D(ByteOp | DstMem | SrcNone | ModRM| Mov)), | 2882 | X16(D(ByteOp | DstMem | SrcNone | ModRM| Mov)), |
2872 | /* 0xA0 - 0xA7 */ | 2883 | /* 0xA0 - 0xA7 */ |
2873 | D(ImplicitOps | Stack), D(ImplicitOps | Stack), | 2884 | D(ImplicitOps | Stack), D(ImplicitOps | Stack), |
2874 | N, D(DstMem | SrcReg | ModRM | BitOp), | 2885 | DI(ImplicitOps, cpuid), D(DstMem | SrcReg | ModRM | BitOp), |
2875 | D(DstMem | SrcReg | Src2ImmByte | ModRM), | 2886 | D(DstMem | SrcReg | Src2ImmByte | ModRM), |
2876 | D(DstMem | SrcReg | Src2CL | ModRM), N, N, | 2887 | D(DstMem | SrcReg | Src2CL | ModRM), N, N, |
2877 | /* 0xA8 - 0xAF */ | 2888 | /* 0xA8 - 0xAF */ |
2878 | D(ImplicitOps | Stack), D(ImplicitOps | Stack), | 2889 | D(ImplicitOps | Stack), D(ImplicitOps | Stack), |
2879 | N, D(DstMem | SrcReg | ModRM | BitOp | Lock), | 2890 | DI(ImplicitOps, rsm), D(DstMem | SrcReg | ModRM | BitOp | Lock), |
2880 | D(DstMem | SrcReg | Src2ImmByte | ModRM), | 2891 | D(DstMem | SrcReg | Src2ImmByte | ModRM), |
2881 | D(DstMem | SrcReg | Src2CL | ModRM), | 2892 | D(DstMem | SrcReg | Src2CL | ModRM), |
2882 | D(ModRM), I(DstReg | SrcMem | ModRM, em_imul), | 2893 | D(ModRM), I(DstReg | SrcMem | ModRM, em_imul), |