aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm/kvm_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/kvm/kvm_main.c')
-rw-r--r--drivers/kvm/kvm_main.c48
1 files changed, 45 insertions, 3 deletions
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 42be8a8f299d..ff8bcfee76e5 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -1504,6 +1504,44 @@ void save_msrs(struct vmx_msr_entry *e, int n)
1504} 1504}
1505EXPORT_SYMBOL_GPL(save_msrs); 1505EXPORT_SYMBOL_GPL(save_msrs);
1506 1506
1507static void complete_pio(struct kvm_vcpu *vcpu)
1508{
1509 struct kvm_io *io = &vcpu->run->io;
1510 long delta;
1511
1512 kvm_arch_ops->cache_regs(vcpu);
1513
1514 if (!io->string) {
1515 if (io->direction == KVM_EXIT_IO_IN)
1516 memcpy(&vcpu->regs[VCPU_REGS_RAX], &io->value,
1517 io->size);
1518 } else {
1519 delta = 1;
1520 if (io->rep) {
1521 delta *= io->count;
1522 /*
1523 * The size of the register should really depend on
1524 * current address size.
1525 */
1526 vcpu->regs[VCPU_REGS_RCX] -= delta;
1527 }
1528 if (io->string_down)
1529 delta = -delta;
1530 delta *= io->size;
1531 if (io->direction == KVM_EXIT_IO_IN)
1532 vcpu->regs[VCPU_REGS_RDI] += delta;
1533 else
1534 vcpu->regs[VCPU_REGS_RSI] += delta;
1535 }
1536
1537 vcpu->pio_pending = 0;
1538 vcpu->run->io_completed = 0;
1539
1540 kvm_arch_ops->decache_regs(vcpu);
1541
1542 kvm_arch_ops->skip_emulated_instruction(vcpu);
1543}
1544
1507static int kvm_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) 1545static int kvm_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
1508{ 1546{
1509 int r; 1547 int r;
@@ -1518,9 +1556,13 @@ static int kvm_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
1518 kvm_run->emulated = 0; 1556 kvm_run->emulated = 0;
1519 } 1557 }
1520 1558
1521 if (kvm_run->mmio_completed) { 1559 if (kvm_run->io_completed) {
1522 memcpy(vcpu->mmio_data, kvm_run->mmio.data, 8); 1560 if (vcpu->pio_pending)
1523 vcpu->mmio_read_completed = 1; 1561 complete_pio(vcpu);
1562 else {
1563 memcpy(vcpu->mmio_data, kvm_run->mmio.data, 8);
1564 vcpu->mmio_read_completed = 1;
1565 }
1524 } 1566 }
1525 1567
1526 vcpu->mmio_needed = 0; 1568 vcpu->mmio_needed = 0;