diff options
Diffstat (limited to 'drivers/kvm/kvm_main.c')
-rw-r--r-- | drivers/kvm/kvm_main.c | 48 |
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 | } |
1505 | EXPORT_SYMBOL_GPL(save_msrs); | 1505 | EXPORT_SYMBOL_GPL(save_msrs); |
1506 | 1506 | ||
1507 | static 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 | |||
1507 | static int kvm_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | 1545 | static 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; |