diff options
Diffstat (limited to 'virt/kvm/arm/arch_timer.c')
-rw-r--r-- | virt/kvm/arm/arch_timer.c | 28 |
1 files changed, 17 insertions, 11 deletions
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c index 21a0ab2d8919..69bca185c471 100644 --- a/virt/kvm/arm/arch_timer.c +++ b/virt/kvm/arm/arch_timer.c | |||
@@ -221,17 +221,23 @@ void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu) | |||
221 | kvm_timer_update_state(vcpu); | 221 | kvm_timer_update_state(vcpu); |
222 | 222 | ||
223 | /* | 223 | /* |
224 | * If we enter the guest with the virtual input level to the VGIC | 224 | * If we enter the guest with the virtual input level to the VGIC |
225 | * asserted, then we have already told the VGIC what we need to, and | 225 | * asserted, then we have already told the VGIC what we need to, and |
226 | * we don't need to exit from the guest until the guest deactivates | 226 | * we don't need to exit from the guest until the guest deactivates |
227 | * the already injected interrupt, so therefore we should set the | 227 | * the already injected interrupt, so therefore we should set the |
228 | * hardware active state to prevent unnecessary exits from the guest. | 228 | * hardware active state to prevent unnecessary exits from the guest. |
229 | * | 229 | * |
230 | * Conversely, if the virtual input level is deasserted, then always | 230 | * Also, if we enter the guest with the virtual timer interrupt active, |
231 | * clear the hardware active state to ensure that hardware interrupts | 231 | * then it must be active on the physical distributor, because we set |
232 | * from the timer triggers a guest exit. | 232 | * the HW bit and the guest must be able to deactivate the virtual and |
233 | */ | 233 | * physical interrupt at the same time. |
234 | if (timer->irq.level) | 234 | * |
235 | * Conversely, if the virtual input level is deasserted and the virtual | ||
236 | * interrupt is not active, then always clear the hardware active state | ||
237 | * to ensure that hardware interrupts from the timer triggers a guest | ||
238 | * exit. | ||
239 | */ | ||
240 | if (timer->irq.level || kvm_vgic_map_is_active(vcpu, timer->map)) | ||
235 | phys_active = true; | 241 | phys_active = true; |
236 | else | 242 | else |
237 | phys_active = false; | 243 | phys_active = false; |