diff options
author | Gleb Natapov <gleb@redhat.com> | 2010-04-28 12:15:42 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2010-08-01 03:35:36 -0400 |
commit | 4d2179e1e9cb74b25a8181a506600d96e15504fb (patch) | |
tree | 142bb9f234bf52d5b021cb6248049e7ee2d12cff /arch/x86/kvm/x86.c | |
parent | bdb475a323858101f4a5ad6a1a04b1dd8885325a (diff) |
KVM: x86 emulator: handle shadowed registers outside emulator
Emulator shouldn't access vcpu directly.
Signed-off-by: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/x86.c')
-rw-r--r-- | arch/x86/kvm/x86.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 04ca343ee512..21d36081a9d9 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -3844,7 +3844,7 @@ int emulate_instruction(struct kvm_vcpu *vcpu, | |||
3844 | int emulation_type) | 3844 | int emulation_type) |
3845 | { | 3845 | { |
3846 | int r, shadow_mask; | 3846 | int r, shadow_mask; |
3847 | struct decode_cache *c; | 3847 | struct decode_cache *c = &vcpu->arch.emulate_ctxt.decode; |
3848 | 3848 | ||
3849 | kvm_clear_exception_queue(vcpu); | 3849 | kvm_clear_exception_queue(vcpu); |
3850 | vcpu->arch.mmio_fault_cr2 = cr2; | 3850 | vcpu->arch.mmio_fault_cr2 = cr2; |
@@ -3869,13 +3869,14 @@ int emulate_instruction(struct kvm_vcpu *vcpu, | |||
3869 | ? X86EMUL_MODE_VM86 : cs_l | 3869 | ? X86EMUL_MODE_VM86 : cs_l |
3870 | ? X86EMUL_MODE_PROT64 : cs_db | 3870 | ? X86EMUL_MODE_PROT64 : cs_db |
3871 | ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16; | 3871 | ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16; |
3872 | memset(c, 0, sizeof(struct decode_cache)); | ||
3873 | memcpy(c->regs, vcpu->arch.regs, sizeof c->regs); | ||
3872 | 3874 | ||
3873 | r = x86_decode_insn(&vcpu->arch.emulate_ctxt, &emulate_ops); | 3875 | r = x86_decode_insn(&vcpu->arch.emulate_ctxt, &emulate_ops); |
3874 | trace_kvm_emulate_insn_start(vcpu); | 3876 | trace_kvm_emulate_insn_start(vcpu); |
3875 | 3877 | ||
3876 | /* Only allow emulation of specific instructions on #UD | 3878 | /* Only allow emulation of specific instructions on #UD |
3877 | * (namely VMMCALL, sysenter, sysexit, syscall)*/ | 3879 | * (namely VMMCALL, sysenter, sysexit, syscall)*/ |
3878 | c = &vcpu->arch.emulate_ctxt.decode; | ||
3879 | if (emulation_type & EMULTYPE_TRAP_UD) { | 3880 | if (emulation_type & EMULTYPE_TRAP_UD) { |
3880 | if (!c->twobyte) | 3881 | if (!c->twobyte) |
3881 | return EMULATE_FAIL; | 3882 | return EMULATE_FAIL; |
@@ -3916,6 +3917,10 @@ int emulate_instruction(struct kvm_vcpu *vcpu, | |||
3916 | return EMULATE_DONE; | 3917 | return EMULATE_DONE; |
3917 | } | 3918 | } |
3918 | 3919 | ||
3920 | /* this is needed for vmware backdor interface to work since it | ||
3921 | changes registers values during IO operation */ | ||
3922 | memcpy(c->regs, vcpu->arch.regs, sizeof c->regs); | ||
3923 | |||
3919 | restart: | 3924 | restart: |
3920 | r = x86_emulate_insn(&vcpu->arch.emulate_ctxt, &emulate_ops); | 3925 | r = x86_emulate_insn(&vcpu->arch.emulate_ctxt, &emulate_ops); |
3921 | 3926 | ||
@@ -3936,6 +3941,7 @@ restart: | |||
3936 | shadow_mask = vcpu->arch.emulate_ctxt.interruptibility; | 3941 | shadow_mask = vcpu->arch.emulate_ctxt.interruptibility; |
3937 | kvm_x86_ops->set_interrupt_shadow(vcpu, shadow_mask); | 3942 | kvm_x86_ops->set_interrupt_shadow(vcpu, shadow_mask); |
3938 | kvm_x86_ops->set_rflags(vcpu, vcpu->arch.emulate_ctxt.eflags); | 3943 | kvm_x86_ops->set_rflags(vcpu, vcpu->arch.emulate_ctxt.eflags); |
3944 | memcpy(vcpu->arch.regs, c->regs, sizeof c->regs); | ||
3939 | kvm_rip_write(vcpu, vcpu->arch.emulate_ctxt.eip); | 3945 | kvm_rip_write(vcpu, vcpu->arch.emulate_ctxt.eip); |
3940 | 3946 | ||
3941 | if (vcpu->arch.pio.count) { | 3947 | if (vcpu->arch.pio.count) { |
@@ -4919,6 +4925,7 @@ int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu, | |||
4919 | int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason, | 4925 | int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason, |
4920 | bool has_error_code, u32 error_code) | 4926 | bool has_error_code, u32 error_code) |
4921 | { | 4927 | { |
4928 | struct decode_cache *c = &vcpu->arch.emulate_ctxt.decode; | ||
4922 | int cs_db, cs_l, ret; | 4929 | int cs_db, cs_l, ret; |
4923 | cache_all_regs(vcpu); | 4930 | cache_all_regs(vcpu); |
4924 | 4931 | ||
@@ -4933,6 +4940,8 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason, | |||
4933 | ? X86EMUL_MODE_VM86 : cs_l | 4940 | ? X86EMUL_MODE_VM86 : cs_l |
4934 | ? X86EMUL_MODE_PROT64 : cs_db | 4941 | ? X86EMUL_MODE_PROT64 : cs_db |
4935 | ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16; | 4942 | ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16; |
4943 | memset(c, 0, sizeof(struct decode_cache)); | ||
4944 | memcpy(c->regs, vcpu->arch.regs, sizeof c->regs); | ||
4936 | 4945 | ||
4937 | ret = emulator_task_switch(&vcpu->arch.emulate_ctxt, &emulate_ops, | 4946 | ret = emulator_task_switch(&vcpu->arch.emulate_ctxt, &emulate_ops, |
4938 | tss_selector, reason, has_error_code, | 4947 | tss_selector, reason, has_error_code, |
@@ -4941,6 +4950,7 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason, | |||
4941 | if (ret) | 4950 | if (ret) |
4942 | return EMULATE_FAIL; | 4951 | return EMULATE_FAIL; |
4943 | 4952 | ||
4953 | memcpy(vcpu->arch.regs, c->regs, sizeof c->regs); | ||
4944 | kvm_rip_write(vcpu, vcpu->arch.emulate_ctxt.eip); | 4954 | kvm_rip_write(vcpu, vcpu->arch.emulate_ctxt.eip); |
4945 | kvm_x86_ops->set_rflags(vcpu, vcpu->arch.emulate_ctxt.eflags); | 4955 | kvm_x86_ops->set_rflags(vcpu, vcpu->arch.emulate_ctxt.eflags); |
4946 | return EMULATE_DONE; | 4956 | return EMULATE_DONE; |