diff options
author | Joerg Roedel <joerg.roedel@amd.com> | 2011-04-04 06:39:32 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2011-05-11 07:57:02 -0400 |
commit | d7eb82030699e6151f1356e90d495bf292564fb7 (patch) | |
tree | bfb62406b52f4c5bafc501236d8ea7cbf33d88af /arch/x86/kvm | |
parent | 01de8b09e6068936f7f5e386cb85637cf926468c (diff) |
KVM: SVM: Add intercept checks for remaining group7 instructions
This patch implements the emulator intercept checks for the
RDTSCP, MONITOR, and MWAIT instructions.
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm')
-rw-r--r-- | arch/x86/kvm/emulate.c | 25 | ||||
-rw-r--r-- | arch/x86/kvm/svm.c | 7 |
2 files changed, 30 insertions, 2 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index a3aba9552b39..b4adb4cbb5f3 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -2604,6 +2604,16 @@ static int check_svme_pa(struct x86_emulate_ctxt *ctxt) | |||
2604 | return check_svme(ctxt); | 2604 | return check_svme(ctxt); |
2605 | } | 2605 | } |
2606 | 2606 | ||
2607 | static int check_rdtsc(struct x86_emulate_ctxt *ctxt) | ||
2608 | { | ||
2609 | u64 cr4 = ctxt->ops->get_cr(4, ctxt->vcpu); | ||
2610 | |||
2611 | if (cr4 & X86_CR4_TSD && ctxt->ops->cpl(ctxt->vcpu)) | ||
2612 | return emulate_ud(ctxt); | ||
2613 | |||
2614 | return X86EMUL_CONTINUE; | ||
2615 | } | ||
2616 | |||
2607 | #define D(_y) { .flags = (_y) } | 2617 | #define D(_y) { .flags = (_y) } |
2608 | #define DI(_y, _i) { .flags = (_y), .intercept = x86_intercept_##_i } | 2618 | #define DI(_y, _i) { .flags = (_y), .intercept = x86_intercept_##_i } |
2609 | #define DIP(_y, _i, _p) { .flags = (_y), .intercept = x86_intercept_##_i, \ | 2619 | #define DIP(_y, _i, _p) { .flags = (_y), .intercept = x86_intercept_##_i, \ |
@@ -2627,6 +2637,12 @@ static int check_svme_pa(struct x86_emulate_ctxt *ctxt) | |||
2627 | D2bv(((_f) | DstReg | SrcMem | ModRM) & ~Lock), \ | 2637 | D2bv(((_f) | DstReg | SrcMem | ModRM) & ~Lock), \ |
2628 | D2bv(((_f) & ~Lock) | DstAcc | SrcImm) | 2638 | D2bv(((_f) & ~Lock) | DstAcc | SrcImm) |
2629 | 2639 | ||
2640 | static struct opcode group7_rm1[] = { | ||
2641 | DI(SrcNone | ModRM | Priv, monitor), | ||
2642 | DI(SrcNone | ModRM | Priv, mwait), | ||
2643 | N, N, N, N, N, N, | ||
2644 | }; | ||
2645 | |||
2630 | static struct opcode group7_rm3[] = { | 2646 | static struct opcode group7_rm3[] = { |
2631 | DIP(SrcNone | ModRM | Prot | Priv, vmrun, check_svme_pa), | 2647 | DIP(SrcNone | ModRM | Prot | Priv, vmrun, check_svme_pa), |
2632 | DIP(SrcNone | ModRM | Prot , vmmcall, check_svme), | 2648 | DIP(SrcNone | ModRM | Prot , vmmcall, check_svme), |
@@ -2638,6 +2654,11 @@ static struct opcode group7_rm3[] = { | |||
2638 | DIP(SrcNone | ModRM | Prot | Priv, invlpga, check_svme), | 2654 | DIP(SrcNone | ModRM | Prot | Priv, invlpga, check_svme), |
2639 | }; | 2655 | }; |
2640 | 2656 | ||
2657 | static struct opcode group7_rm7[] = { | ||
2658 | N, | ||
2659 | DIP(SrcNone | ModRM, rdtscp, check_rdtsc), | ||
2660 | N, N, N, N, N, N, | ||
2661 | }; | ||
2641 | static struct opcode group1[] = { | 2662 | static struct opcode group1[] = { |
2642 | X7(D(Lock)), N | 2663 | X7(D(Lock)), N |
2643 | }; | 2664 | }; |
@@ -2681,10 +2702,10 @@ static struct group_dual group7 = { { | |||
2681 | DI(SrcMem16 | ModRM | Mov | Priv, lmsw), | 2702 | DI(SrcMem16 | ModRM | Mov | Priv, lmsw), |
2682 | DI(SrcMem | ModRM | ByteOp | Priv | NoAccess, invlpg), | 2703 | DI(SrcMem | ModRM | ByteOp | Priv | NoAccess, invlpg), |
2683 | }, { | 2704 | }, { |
2684 | D(SrcNone | ModRM | Priv | VendorSpecific), N, | 2705 | D(SrcNone | ModRM | Priv | VendorSpecific), EXT(0, group7_rm1), |
2685 | N, EXT(0, group7_rm3), | 2706 | N, EXT(0, group7_rm3), |
2686 | DI(SrcNone | ModRM | DstMem | Mov, smsw), N, | 2707 | DI(SrcNone | ModRM | DstMem | Mov, smsw), N, |
2687 | DI(SrcMem16 | ModRM | Mov | Priv, lmsw), N, | 2708 | DI(SrcMem16 | ModRM | Mov | Priv, lmsw), EXT(0, group7_rm7), |
2688 | } }; | 2709 | } }; |
2689 | 2710 | ||
2690 | static struct opcode group8[] = { | 2711 | static struct opcode group8[] = { |
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index b98d00bfaf8a..1eb5504ca6f5 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
@@ -3871,6 +3871,9 @@ static void svm_fpu_deactivate(struct kvm_vcpu *vcpu) | |||
3871 | #define POST_EX(exit) { .exit_code = (exit), \ | 3871 | #define POST_EX(exit) { .exit_code = (exit), \ |
3872 | .stage = X86_ICPT_POST_EXCEPT, \ | 3872 | .stage = X86_ICPT_POST_EXCEPT, \ |
3873 | .valid = true } | 3873 | .valid = true } |
3874 | #define POST_MEM(exit) { .exit_code = (exit), \ | ||
3875 | .stage = X86_ICPT_POST_MEMACCESS, \ | ||
3876 | .valid = true } | ||
3874 | 3877 | ||
3875 | static struct __x86_intercept { | 3878 | static struct __x86_intercept { |
3876 | u32 exit_code; | 3879 | u32 exit_code; |
@@ -3900,9 +3903,13 @@ static struct __x86_intercept { | |||
3900 | [x86_intercept_clgi] = POST_EX(SVM_EXIT_CLGI), | 3903 | [x86_intercept_clgi] = POST_EX(SVM_EXIT_CLGI), |
3901 | [x86_intercept_skinit] = POST_EX(SVM_EXIT_SKINIT), | 3904 | [x86_intercept_skinit] = POST_EX(SVM_EXIT_SKINIT), |
3902 | [x86_intercept_invlpga] = POST_EX(SVM_EXIT_INVLPGA), | 3905 | [x86_intercept_invlpga] = POST_EX(SVM_EXIT_INVLPGA), |
3906 | [x86_intercept_rdtscp] = POST_EX(SVM_EXIT_RDTSCP), | ||
3907 | [x86_intercept_monitor] = POST_MEM(SVM_EXIT_MONITOR), | ||
3908 | [x86_intercept_mwait] = POST_EX(SVM_EXIT_MWAIT), | ||
3903 | }; | 3909 | }; |
3904 | 3910 | ||
3905 | #undef POST_EX | 3911 | #undef POST_EX |
3912 | #undef POST_MEM | ||
3906 | 3913 | ||
3907 | static int svm_check_intercept(struct kvm_vcpu *vcpu, | 3914 | static int svm_check_intercept(struct kvm_vcpu *vcpu, |
3908 | struct x86_instruction_info *info, | 3915 | struct x86_instruction_info *info, |