aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/kvm_host.h2
-rw-r--r--arch/x86/kvm/x86.c47
2 files changed, 40 insertions, 9 deletions
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index bd57639fd5db..3e03f37f43ea 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -385,6 +385,8 @@ struct kvm_vcpu_arch {
385 /* emulate context */ 385 /* emulate context */
386 386
387 struct x86_emulate_ctxt emulate_ctxt; 387 struct x86_emulate_ctxt emulate_ctxt;
388 bool emulate_regs_need_sync_to_vcpu;
389 bool emulate_regs_need_sync_from_vcpu;
388 390
389 gpa_t time; 391 gpa_t time;
390 struct pvclock_vcpu_time_info hv_clock; 392 struct pvclock_vcpu_time_info hv_clock;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 1d5a7f418795..3416a3473849 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4420,6 +4420,7 @@ static void init_emulate_ctxt(struct kvm_vcpu *vcpu)
4420 vcpu->arch.emulate_ctxt.guest_mode = is_guest_mode(vcpu); 4420 vcpu->arch.emulate_ctxt.guest_mode = is_guest_mode(vcpu);
4421 memset(c, 0, sizeof(struct decode_cache)); 4421 memset(c, 0, sizeof(struct decode_cache));
4422 memcpy(c->regs, vcpu->arch.regs, sizeof c->regs); 4422 memcpy(c->regs, vcpu->arch.regs, sizeof c->regs);
4423 vcpu->arch.emulate_regs_need_sync_from_vcpu = false;
4423} 4424}
4424 4425
4425int kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq) 4426int kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq)
@@ -4502,6 +4503,7 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu,
4502{ 4503{
4503 int r; 4504 int r;
4504 struct decode_cache *c = &vcpu->arch.emulate_ctxt.decode; 4505 struct decode_cache *c = &vcpu->arch.emulate_ctxt.decode;
4506 bool writeback = true;
4505 4507
4506 kvm_clear_exception_queue(vcpu); 4508 kvm_clear_exception_queue(vcpu);
4507 vcpu->arch.mmio_fault_cr2 = cr2; 4509 vcpu->arch.mmio_fault_cr2 = cr2;
@@ -4542,9 +4544,12 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu,
4542 return EMULATE_DONE; 4544 return EMULATE_DONE;
4543 } 4545 }
4544 4546
4545 /* this is needed for vmware backdor interface to work since it 4547 /* this is needed for vmware backdoor interface to work since it
4546 changes registers values during IO operation */ 4548 changes registers values during IO operation */
4547 memcpy(c->regs, vcpu->arch.regs, sizeof c->regs); 4549 if (vcpu->arch.emulate_regs_need_sync_from_vcpu) {
4550 vcpu->arch.emulate_regs_need_sync_from_vcpu = false;
4551 memcpy(c->regs, vcpu->arch.regs, sizeof c->regs);
4552 }
4548 4553
4549restart: 4554restart:
4550 r = x86_emulate_insn(&vcpu->arch.emulate_ctxt); 4555 r = x86_emulate_insn(&vcpu->arch.emulate_ctxt);
@@ -4565,19 +4570,28 @@ restart:
4565 } else if (vcpu->arch.pio.count) { 4570 } else if (vcpu->arch.pio.count) {
4566 if (!vcpu->arch.pio.in) 4571 if (!vcpu->arch.pio.in)
4567 vcpu->arch.pio.count = 0; 4572 vcpu->arch.pio.count = 0;
4573 else
4574 writeback = false;
4568 r = EMULATE_DO_MMIO; 4575 r = EMULATE_DO_MMIO;
4569 } else if (vcpu->mmio_needed) 4576 } else if (vcpu->mmio_needed) {
4577 if (!vcpu->mmio_is_write)
4578 writeback = false;
4570 r = EMULATE_DO_MMIO; 4579 r = EMULATE_DO_MMIO;
4571 else if (r == EMULATION_RESTART) 4580 } else if (r == EMULATION_RESTART)
4572 goto restart; 4581 goto restart;
4573 else 4582 else
4574 r = EMULATE_DONE; 4583 r = EMULATE_DONE;
4575 4584
4576 toggle_interruptibility(vcpu, vcpu->arch.emulate_ctxt.interruptibility); 4585 if (writeback) {
4577 kvm_set_rflags(vcpu, vcpu->arch.emulate_ctxt.eflags); 4586 toggle_interruptibility(vcpu,
4578 kvm_make_request(KVM_REQ_EVENT, vcpu); 4587 vcpu->arch.emulate_ctxt.interruptibility);
4579 memcpy(vcpu->arch.regs, c->regs, sizeof c->regs); 4588 kvm_set_rflags(vcpu, vcpu->arch.emulate_ctxt.eflags);
4580 kvm_rip_write(vcpu, vcpu->arch.emulate_ctxt.eip); 4589 kvm_make_request(KVM_REQ_EVENT, vcpu);
4590 memcpy(vcpu->arch.regs, c->regs, sizeof c->regs);
4591 vcpu->arch.emulate_regs_need_sync_to_vcpu = false;
4592 kvm_rip_write(vcpu, vcpu->arch.emulate_ctxt.eip);
4593 } else
4594 vcpu->arch.emulate_regs_need_sync_to_vcpu = true;
4581 4595
4582 return r; 4596 return r;
4583} 4597}
@@ -5587,6 +5601,18 @@ out:
5587 5601
5588int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) 5602int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
5589{ 5603{
5604 if (vcpu->arch.emulate_regs_need_sync_to_vcpu) {
5605 /*
5606 * We are here if userspace calls get_regs() in the middle of
5607 * instruction emulation. Registers state needs to be copied
5608 * back from emulation context to vcpu. Usrapace shouldn't do
5609 * that usually, but some bad designed PV devices (vmware
5610 * backdoor interface) need this to work
5611 */
5612 struct decode_cache *c = &vcpu->arch.emulate_ctxt.decode;
5613 memcpy(vcpu->arch.regs, c->regs, sizeof c->regs);
5614 vcpu->arch.emulate_regs_need_sync_to_vcpu = false;
5615 }
5590 regs->rax = kvm_register_read(vcpu, VCPU_REGS_RAX); 5616 regs->rax = kvm_register_read(vcpu, VCPU_REGS_RAX);
5591 regs->rbx = kvm_register_read(vcpu, VCPU_REGS_RBX); 5617 regs->rbx = kvm_register_read(vcpu, VCPU_REGS_RBX);
5592 regs->rcx = kvm_register_read(vcpu, VCPU_REGS_RCX); 5618 regs->rcx = kvm_register_read(vcpu, VCPU_REGS_RCX);
@@ -5614,6 +5640,9 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
5614 5640
5615int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) 5641int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
5616{ 5642{
5643 vcpu->arch.emulate_regs_need_sync_from_vcpu = true;
5644 vcpu->arch.emulate_regs_need_sync_to_vcpu = false;
5645
5617 kvm_register_write(vcpu, VCPU_REGS_RAX, regs->rax); 5646 kvm_register_write(vcpu, VCPU_REGS_RAX, regs->rax);
5618 kvm_register_write(vcpu, VCPU_REGS_RBX, regs->rbx); 5647 kvm_register_write(vcpu, VCPU_REGS_RBX, regs->rbx);
5619 kvm_register_write(vcpu, VCPU_REGS_RCX, regs->rcx); 5648 kvm_register_write(vcpu, VCPU_REGS_RCX, regs->rcx);