]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - arch/x86/kvm/x86.c
KVM: x86 emulator: Add Virtual-8086 mode of emulation
[karo-tx-linux.git] / arch / x86 / kvm / x86.c
index c91007f81660ead9bc6484578de6a1fc7d89dc56..a28379507d30a44ddf0d8171b8cdab0c77ac4ea8 100644 (file)
@@ -2771,6 +2771,8 @@ long kvm_arch_vm_ioctl(struct file *filp,
                if (vpic) {
                        r = kvm_ioapic_init(kvm);
                        if (r) {
+                               kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS,
+                                                         &vpic->dev);
                                kfree(vpic);
                                goto create_irqchip_unlock;
                        }
@@ -2782,10 +2784,8 @@ long kvm_arch_vm_ioctl(struct file *filp,
                r = kvm_setup_default_irq_routing(kvm);
                if (r) {
                        mutex_lock(&kvm->irq_lock);
-                       kfree(kvm->arch.vpic);
-                       kfree(kvm->arch.vioapic);
-                       kvm->arch.vpic = NULL;
-                       kvm->arch.vioapic = NULL;
+                       kvm_ioapic_destroy(kvm);
+                       kvm_destroy_pic(kvm);
                        mutex_unlock(&kvm->irq_lock);
                }
        create_irqchip_unlock:
@@ -3348,8 +3348,9 @@ int emulate_instruction(struct kvm_vcpu *vcpu,
                vcpu->arch.emulate_ctxt.vcpu = vcpu;
                vcpu->arch.emulate_ctxt.eflags = kvm_get_rflags(vcpu);
                vcpu->arch.emulate_ctxt.mode =
+                       (!is_protmode(vcpu)) ? X86EMUL_MODE_REAL :
                        (vcpu->arch.emulate_ctxt.eflags & X86_EFLAGS_VM)
-                       ? X86EMUL_MODE_REAL : cs_l
+                       ? X86EMUL_MODE_VM86 : cs_l
                        ? X86EMUL_MODE_PROT64 : cs_db
                        ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16;
 
@@ -3551,8 +3552,10 @@ int kvm_emulate_pio(struct kvm_vcpu *vcpu, int in, int size, unsigned port)
        trace_kvm_pio(vcpu->run->io.direction == KVM_EXIT_IO_OUT, port,
                      size, 1);
 
-       val = kvm_register_read(vcpu, VCPU_REGS_RAX);
-       memcpy(vcpu->arch.pio_data, &val, 4);
+       if (!vcpu->arch.pio.in) {
+               val = kvm_register_read(vcpu, VCPU_REGS_RAX);
+               memcpy(vcpu->arch.pio_data, &val, 4);
+       }
 
        if (!kernel_pio(vcpu, vcpu->arch.pio_data)) {
                complete_pio(vcpu);