diff options
Diffstat (limited to 'virt/kvm/arm/arch_timer.c')
-rw-r--r-- | virt/kvm/arm/arch_timer.c | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c index 48c6e1ac6827..b9d3a32cbc04 100644 --- a/virt/kvm/arm/arch_timer.c +++ b/virt/kvm/arm/arch_timer.c | |||
@@ -137,6 +137,8 @@ bool kvm_timer_should_fire(struct kvm_vcpu *vcpu) | |||
137 | void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu) | 137 | void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu) |
138 | { | 138 | { |
139 | struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; | 139 | struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; |
140 | bool phys_active; | ||
141 | int ret; | ||
140 | 142 | ||
141 | /* | 143 | /* |
142 | * We're about to run this vcpu again, so there is no need to | 144 | * We're about to run this vcpu again, so there is no need to |
@@ -151,6 +153,23 @@ void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu) | |||
151 | */ | 153 | */ |
152 | if (kvm_timer_should_fire(vcpu)) | 154 | if (kvm_timer_should_fire(vcpu)) |
153 | kvm_timer_inject_irq(vcpu); | 155 | kvm_timer_inject_irq(vcpu); |
156 | |||
157 | /* | ||
158 | * We keep track of whether the edge-triggered interrupt has been | ||
159 | * signalled to the vgic/guest, and if so, we mask the interrupt and | ||
160 | * the physical distributor to prevent the timer from raising a | ||
161 | * physical interrupt whenever we run a guest, preventing forward | ||
162 | * VCPU progress. | ||
163 | */ | ||
164 | if (kvm_vgic_get_phys_irq_active(timer->map)) | ||
165 | phys_active = true; | ||
166 | else | ||
167 | phys_active = false; | ||
168 | |||
169 | ret = irq_set_irqchip_state(timer->map->irq, | ||
170 | IRQCHIP_STATE_ACTIVE, | ||
171 | phys_active); | ||
172 | WARN_ON(ret); | ||
154 | } | 173 | } |
155 | 174 | ||
156 | /** | 175 | /** |