aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/x86.c
diff options
context:
space:
mode:
authorAndre Przywara <andre.przywara@amd.com>2009-06-17 09:50:31 -0400
committerAvi Kivity <avi@redhat.com>2009-09-10 01:32:59 -0400
commit0cb5762ed2b3113b3b8aa84d1d26b815aea71787 (patch)
tree72fa0759911a0433bb5cc9f238bc0226bd9748b6 /arch/x86/kvm/x86.c
parent229456fc34b1c9031b04f7581e7b755d1cebfe9c (diff)
KVM: Allow emulation of syscalls instructions on #UD
Add the opcodes for syscall, sysenter and sysexit to the list of instructions handled by the undefined opcode handler. Signed-off-by: Christoph Egger <christoph.egger@amd.com> Signed-off-by: Amit Shah <amit.shah@redhat.com> Signed-off-by: Andre Przywara <andre.przywara@amd.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/x86.c')
-rw-r--r--arch/x86/kvm/x86.c33
1 files changed, 26 insertions, 7 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 892a7a60c815..57e76b37242f 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2667,14 +2667,33 @@ int emulate_instruction(struct kvm_vcpu *vcpu,
2667 2667
2668 r = x86_decode_insn(&vcpu->arch.emulate_ctxt, &emulate_ops); 2668 r = x86_decode_insn(&vcpu->arch.emulate_ctxt, &emulate_ops);
2669 2669
2670 /* Reject the instructions other than VMCALL/VMMCALL when 2670 /* Only allow emulation of specific instructions on #UD
2671 * try to emulate invalid opcode */ 2671 * (namely VMMCALL, sysenter, sysexit, syscall)*/
2672 c = &vcpu->arch.emulate_ctxt.decode; 2672 c = &vcpu->arch.emulate_ctxt.decode;
2673 if ((emulation_type & EMULTYPE_TRAP_UD) && 2673 if (emulation_type & EMULTYPE_TRAP_UD) {
2674 (!(c->twobyte && c->b == 0x01 && 2674 if (!c->twobyte)
2675 (c->modrm_reg == 0 || c->modrm_reg == 3) && 2675 return EMULATE_FAIL;
2676 c->modrm_mod == 3 && c->modrm_rm == 1))) 2676 switch (c->b) {
2677 return EMULATE_FAIL; 2677 case 0x01: /* VMMCALL */
2678 if (c->modrm_mod != 3 || c->modrm_rm != 1)
2679 return EMULATE_FAIL;
2680 break;
2681 case 0x34: /* sysenter */
2682 case 0x35: /* sysexit */
2683 if (c->modrm_mod != 0 || c->modrm_rm != 0)
2684 return EMULATE_FAIL;
2685 break;
2686 case 0x05: /* syscall */
2687 if (c->modrm_mod != 0 || c->modrm_rm != 0)
2688 return EMULATE_FAIL;
2689 break;
2690 default:
2691 return EMULATE_FAIL;
2692 }
2693
2694 if (!(c->modrm_reg == 0 || c->modrm_reg == 3))
2695 return EMULATE_FAIL;
2696 }
2678 2697
2679 ++vcpu->stat.insn_emulation; 2698 ++vcpu->stat.insn_emulation;
2680 if (r) { 2699 if (r) {