diff options
Diffstat (limited to 'arch/x86/kvm/emulate.c')
-rw-r--r-- | arch/x86/kvm/emulate.c | 25 |
1 files changed, 23 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[] = { |