KVM: VMX: Properly handle software interrupt re-injection in real mode
authorGleb Natapov <gleb@redhat.com>
Tue, 19 May 2009 08:07:10 +0000 (11:07 +0300)
committerAvi Kivity <avi@redhat.com>
Thu, 10 Sep 2009 05:32:38 +0000 (08:32 +0300)
When reinjecting a software interrupt or exception, use the correct
instruction length provided by the hardware instead of a hardcoded 1.

Fixes problems running the suse 9.1 livecd boot loader.

Problem introduced by commit f0a3602c20 ("KVM: Move interrupt injection
logic to x86.c").

Signed-off-by: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
arch/x86/kvm/vmx.c

index 29f912927a588bda4e9a3fc06ea2412ec04b5ebc..db0b8b6df198c051f20a0cc45c1cdc3bd470e4db 100644 (file)
@@ -801,8 +801,9 @@ static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr,
                vmx->rmode.irq.pending = true;
                vmx->rmode.irq.vector = nr;
                vmx->rmode.irq.rip = kvm_rip_read(vcpu);
-               if (nr == BP_VECTOR || nr == OF_VECTOR)
-                       vmx->rmode.irq.rip++;
+               if (kvm_exception_is_soft(nr))
+                       vmx->rmode.irq.rip +=
+                               vmx->vcpu.arch.event_exit_inst_len;
                intr_info |= INTR_TYPE_SOFT_INTR;
                vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr_info);
                vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1);
@@ -2468,6 +2469,9 @@ static void vmx_inject_irq(struct kvm_vcpu *vcpu)
                vmx->rmode.irq.pending = true;
                vmx->rmode.irq.vector = irq;
                vmx->rmode.irq.rip = kvm_rip_read(vcpu);
+               if (vcpu->arch.interrupt.soft)
+                       vmx->rmode.irq.rip +=
+                               vmx->vcpu.arch.event_exit_inst_len;
                vmcs_write32(VM_ENTRY_INTR_INFO_FIELD,
                             irq | INTR_TYPE_SOFT_INTR | INTR_INFO_VALID_MASK);
                vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1);