diff options
-rw-r--r-- | arch/x86/include/asm/kvm_host.h | 2 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 47 |
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 | ||
4425 | int kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq) | 4426 | int 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 | ||
4549 | restart: | 4554 | restart: |
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 | ||
5588 | int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) | 5602 | int 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 | ||
5615 | int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) | 5641 | int 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); |