diff options
author | Gleb Natapov <gleb@redhat.com> | 2009-05-11 06:35:51 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-06-10 04:48:58 -0400 |
commit | 6a8b1d13121f8226783987dc7ddd861ee2245410 (patch) | |
tree | 269d5858d3a6cb842c72e408260b68fb55828461 | |
parent | 66fd3f7f901f29a557a473af595bf11b270b9ac2 (diff) |
KVM: Always request IRQ/NMI window if an interrupt is pending
Currently they are not requested if there is pending exception.
Signed-off-by: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
-rw-r--r-- | arch/x86/kvm/x86.c | 30 |
1 files changed, 12 insertions, 18 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 73cfe87fba10..199426cc1d0e 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -3152,8 +3152,11 @@ static void update_cr8_intercept(struct kvm_vcpu *vcpu) | |||
3152 | kvm_x86_ops->update_cr8_intercept(vcpu, tpr, max_irr); | 3152 | kvm_x86_ops->update_cr8_intercept(vcpu, tpr, max_irr); |
3153 | } | 3153 | } |
3154 | 3154 | ||
3155 | static void inject_irq(struct kvm_vcpu *vcpu) | 3155 | static void inject_pending_irq(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) |
3156 | { | 3156 | { |
3157 | if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) | ||
3158 | kvm_x86_ops->set_interrupt_shadow(vcpu, 0); | ||
3159 | |||
3157 | /* try to reinject previous events if any */ | 3160 | /* try to reinject previous events if any */ |
3158 | if (vcpu->arch.nmi_injected) { | 3161 | if (vcpu->arch.nmi_injected) { |
3159 | kvm_x86_ops->set_nmi(vcpu); | 3162 | kvm_x86_ops->set_nmi(vcpu); |
@@ -3181,26 +3184,11 @@ static void inject_irq(struct kvm_vcpu *vcpu) | |||
3181 | } | 3184 | } |
3182 | } | 3185 | } |
3183 | 3186 | ||
3184 | static void inject_pending_irq(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | ||
3185 | { | ||
3186 | bool req_int_win = !irqchip_in_kernel(vcpu->kvm) && | ||
3187 | kvm_run->request_interrupt_window; | ||
3188 | |||
3189 | if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) | ||
3190 | kvm_x86_ops->set_interrupt_shadow(vcpu, 0); | ||
3191 | |||
3192 | inject_irq(vcpu); | ||
3193 | |||
3194 | /* enable NMI/IRQ window open exits if needed */ | ||
3195 | if (vcpu->arch.nmi_pending) | ||
3196 | kvm_x86_ops->enable_nmi_window(vcpu); | ||
3197 | else if (kvm_cpu_has_interrupt(vcpu) || req_int_win) | ||
3198 | kvm_x86_ops->enable_irq_window(vcpu); | ||
3199 | } | ||
3200 | |||
3201 | static int vcpu_enter_guest(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | 3187 | static int vcpu_enter_guest(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) |
3202 | { | 3188 | { |
3203 | int r; | 3189 | int r; |
3190 | bool req_int_win = !irqchip_in_kernel(vcpu->kvm) && | ||
3191 | kvm_run->request_interrupt_window; | ||
3204 | 3192 | ||
3205 | if (vcpu->requests) | 3193 | if (vcpu->requests) |
3206 | if (test_and_clear_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests)) | 3194 | if (test_and_clear_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests)) |
@@ -3254,6 +3242,12 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
3254 | else | 3242 | else |
3255 | inject_pending_irq(vcpu, kvm_run); | 3243 | inject_pending_irq(vcpu, kvm_run); |
3256 | 3244 | ||
3245 | /* enable NMI/IRQ window open exits if needed */ | ||
3246 | if (vcpu->arch.nmi_pending) | ||
3247 | kvm_x86_ops->enable_nmi_window(vcpu); | ||
3248 | else if (kvm_cpu_has_interrupt(vcpu) || req_int_win) | ||
3249 | kvm_x86_ops->enable_irq_window(vcpu); | ||
3250 | |||
3257 | if (kvm_lapic_enabled(vcpu)) { | 3251 | if (kvm_lapic_enabled(vcpu)) { |
3258 | if (!vcpu->arch.apic->vapic_addr) | 3252 | if (!vcpu->arch.apic->vapic_addr) |
3259 | update_cr8_intercept(vcpu); | 3253 | update_cr8_intercept(vcpu); |