diff options
author | Wei Wang <wei.w.wang@intel.com> | 2014-11-04 21:53:43 -0500 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2014-11-07 09:44:00 -0500 |
commit | 4114c27d450bef228be9c7b0c40a888e18a3a636 (patch) | |
tree | 4bc1ec2876070095e191cab210fd2896fdd5ccdf | |
parent | a2ae9df7c991eca6c1ee6f42dbb18701a64175c3 (diff) |
KVM: x86: reset RVI upon system reset
A bug was reported as follows: when running Windows 7 32-bit guests on qemu-kvm,
sometimes the guests run into blue screen during reboot. The problem was that a
guest's RVI was not cleared when it rebooted. This patch has fixed the problem.
Signed-off-by: Wei Wang <wei.w.wang@intel.com>
Signed-off-by: Yang Zhang <yang.z.zhang@intel.com>
Tested-by: Rongrong Liu <rongrongx.liu@intel.com>, Da Chun <ngugc@qq.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r-- | arch/x86/kvm/lapic.c | 3 | ||||
-rw-r--r-- | arch/x86/kvm/vmx.c | 20 |
2 files changed, 15 insertions, 8 deletions
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 5f574b4add90..e7f7fc632a9b 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c | |||
@@ -1714,6 +1714,9 @@ void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu, | |||
1714 | apic->isr_count = kvm_apic_vid_enabled(vcpu->kvm) ? | 1714 | apic->isr_count = kvm_apic_vid_enabled(vcpu->kvm) ? |
1715 | 1 : count_vectors(apic->regs + APIC_ISR); | 1715 | 1 : count_vectors(apic->regs + APIC_ISR); |
1716 | apic->highest_isr_cache = -1; | 1716 | apic->highest_isr_cache = -1; |
1717 | if (kvm_x86_ops->hwapic_irr_update) | ||
1718 | kvm_x86_ops->hwapic_irr_update(vcpu, | ||
1719 | apic_find_highest_irr(apic)); | ||
1717 | kvm_x86_ops->hwapic_isr_update(vcpu->kvm, apic_find_highest_isr(apic)); | 1720 | kvm_x86_ops->hwapic_isr_update(vcpu->kvm, apic_find_highest_isr(apic)); |
1718 | kvm_make_request(KVM_REQ_EVENT, vcpu); | 1721 | kvm_make_request(KVM_REQ_EVENT, vcpu); |
1719 | kvm_rtc_eoi_tracking_restore_one(vcpu); | 1722 | kvm_rtc_eoi_tracking_restore_one(vcpu); |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index d6e3ddace074..f9d56c1945de 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -7419,6 +7419,9 @@ static void vmx_set_rvi(int vector) | |||
7419 | u16 status; | 7419 | u16 status; |
7420 | u8 old; | 7420 | u8 old; |
7421 | 7421 | ||
7422 | if (vector == -1) | ||
7423 | vector = 0; | ||
7424 | |||
7422 | status = vmcs_read16(GUEST_INTR_STATUS); | 7425 | status = vmcs_read16(GUEST_INTR_STATUS); |
7423 | old = (u8)status & 0xff; | 7426 | old = (u8)status & 0xff; |
7424 | if ((u8)vector != old) { | 7427 | if ((u8)vector != old) { |
@@ -7430,22 +7433,23 @@ static void vmx_set_rvi(int vector) | |||
7430 | 7433 | ||
7431 | static void vmx_hwapic_irr_update(struct kvm_vcpu *vcpu, int max_irr) | 7434 | static void vmx_hwapic_irr_update(struct kvm_vcpu *vcpu, int max_irr) |
7432 | { | 7435 | { |
7436 | if (!is_guest_mode(vcpu)) { | ||
7437 | vmx_set_rvi(max_irr); | ||
7438 | return; | ||
7439 | } | ||
7440 | |||
7433 | if (max_irr == -1) | 7441 | if (max_irr == -1) |
7434 | return; | 7442 | return; |
7435 | 7443 | ||
7436 | /* | 7444 | /* |
7437 | * If a vmexit is needed, vmx_check_nested_events handles it. | 7445 | * In guest mode. If a vmexit is needed, vmx_check_nested_events |
7446 | * handles it. | ||
7438 | */ | 7447 | */ |
7439 | if (is_guest_mode(vcpu) && nested_exit_on_intr(vcpu)) | 7448 | if (nested_exit_on_intr(vcpu)) |
7440 | return; | 7449 | return; |
7441 | 7450 | ||
7442 | if (!is_guest_mode(vcpu)) { | ||
7443 | vmx_set_rvi(max_irr); | ||
7444 | return; | ||
7445 | } | ||
7446 | |||
7447 | /* | 7451 | /* |
7448 | * Fall back to pre-APICv interrupt injection since L2 | 7452 | * Else, fall back to pre-APICv interrupt injection since L2 |
7449 | * is run without virtual interrupt delivery. | 7453 | * is run without virtual interrupt delivery. |
7450 | */ | 7454 | */ |
7451 | if (!kvm_event_needs_reinjection(vcpu) && | 7455 | if (!kvm_event_needs_reinjection(vcpu) && |