diff options
author | Gleb Natapov <gleb@redhat.com> | 2009-05-19 04:07:10 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-09-10 01:32:38 -0400 |
commit | ae0bb3e011fec51fa67073d8e23d8ffeb36185d1 (patch) | |
tree | c5bf05ed2bb0ef7365be95636604f89b8815f77c /arch | |
parent | 74fca6a42863ffacaf7ba6f1936a9f228950f657 (diff) |
KVM: VMX: Properly handle software interrupt re-injection in real mode
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>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kvm/vmx.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 29f912927a58..db0b8b6df198 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -801,8 +801,9 @@ static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr, | |||
801 | vmx->rmode.irq.pending = true; | 801 | vmx->rmode.irq.pending = true; |
802 | vmx->rmode.irq.vector = nr; | 802 | vmx->rmode.irq.vector = nr; |
803 | vmx->rmode.irq.rip = kvm_rip_read(vcpu); | 803 | vmx->rmode.irq.rip = kvm_rip_read(vcpu); |
804 | if (nr == BP_VECTOR || nr == OF_VECTOR) | 804 | if (kvm_exception_is_soft(nr)) |
805 | vmx->rmode.irq.rip++; | 805 | vmx->rmode.irq.rip += |
806 | vmx->vcpu.arch.event_exit_inst_len; | ||
806 | intr_info |= INTR_TYPE_SOFT_INTR; | 807 | intr_info |= INTR_TYPE_SOFT_INTR; |
807 | vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr_info); | 808 | vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr_info); |
808 | vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1); | 809 | vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1); |
@@ -2468,6 +2469,9 @@ static void vmx_inject_irq(struct kvm_vcpu *vcpu) | |||
2468 | vmx->rmode.irq.pending = true; | 2469 | vmx->rmode.irq.pending = true; |
2469 | vmx->rmode.irq.vector = irq; | 2470 | vmx->rmode.irq.vector = irq; |
2470 | vmx->rmode.irq.rip = kvm_rip_read(vcpu); | 2471 | vmx->rmode.irq.rip = kvm_rip_read(vcpu); |
2472 | if (vcpu->arch.interrupt.soft) | ||
2473 | vmx->rmode.irq.rip += | ||
2474 | vmx->vcpu.arch.event_exit_inst_len; | ||
2471 | vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, | 2475 | vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, |
2472 | irq | INTR_TYPE_SOFT_INTR | INTR_INFO_VALID_MASK); | 2476 | irq | INTR_TYPE_SOFT_INTR | INTR_INFO_VALID_MASK); |
2473 | vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1); | 2477 | vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1); |