diff options
author | Marc Zyngier <marc.zyngier@arm.com> | 2017-10-27 10:28:49 -0400 |
---|---|---|
committer | Christoffer Dall <christoffer.dall@linaro.org> | 2017-11-10 03:43:22 -0500 |
commit | df9ba95993b9d59e077aa4613f7a4edd20a4064c (patch) | |
tree | 8713bc9daf8417cd984eea21872094fee01a8102 | |
parent | bdb2d2ccac65dfee0db8fa4a8247df788a942439 (diff) |
KVM: arm/arm64: GICv4: Use the doorbell interrupt as an unblocking source
The doorbell interrupt is only useful if the vcpu is blocked on WFI.
In all other cases, recieving a doorbell interrupt is just a waste
of cycles.
So let's only enable the doorbell if a vcpu is getting blocked,
and disable it when it is unblocked. This is very similar to
what we're doing for the background timer.
Reviewed-by: Christoffer Dall <cdall@linaro.org>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
-rw-r--r-- | include/kvm/arm_vgic.h | 3 | ||||
-rw-r--r-- | virt/kvm/arm/arm.c | 2 | ||||
-rw-r--r-- | virt/kvm/arm/vgic/vgic-v4.c | 18 |
3 files changed, 23 insertions, 0 deletions
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index 2f750c770bf2..8c896540a72c 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h | |||
@@ -381,4 +381,7 @@ int kvm_vgic_v4_set_forwarding(struct kvm *kvm, int irq, | |||
381 | int kvm_vgic_v4_unset_forwarding(struct kvm *kvm, int irq, | 381 | int kvm_vgic_v4_unset_forwarding(struct kvm *kvm, int irq, |
382 | struct kvm_kernel_irq_routing_entry *irq_entry); | 382 | struct kvm_kernel_irq_routing_entry *irq_entry); |
383 | 383 | ||
384 | void kvm_vgic_v4_enable_doorbell(struct kvm_vcpu *vcpu); | ||
385 | void kvm_vgic_v4_disable_doorbell(struct kvm_vcpu *vcpu); | ||
386 | |||
384 | #endif /* __KVM_ARM_VGIC_H */ | 387 | #endif /* __KVM_ARM_VGIC_H */ |
diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c index 34a15c0c65ab..01e575b9f78b 100644 --- a/virt/kvm/arm/arm.c +++ b/virt/kvm/arm/arm.c | |||
@@ -315,11 +315,13 @@ int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu) | |||
315 | void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) | 315 | void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) |
316 | { | 316 | { |
317 | kvm_timer_schedule(vcpu); | 317 | kvm_timer_schedule(vcpu); |
318 | kvm_vgic_v4_enable_doorbell(vcpu); | ||
318 | } | 319 | } |
319 | 320 | ||
320 | void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) | 321 | void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) |
321 | { | 322 | { |
322 | kvm_timer_unschedule(vcpu); | 323 | kvm_timer_unschedule(vcpu); |
324 | kvm_vgic_v4_disable_doorbell(vcpu); | ||
323 | } | 325 | } |
324 | 326 | ||
325 | int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) | 327 | int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) |
diff --git a/virt/kvm/arm/vgic/vgic-v4.c b/virt/kvm/arm/vgic/vgic-v4.c index 796e00c77903..1375a53054b9 100644 --- a/virt/kvm/arm/vgic/vgic-v4.c +++ b/virt/kvm/arm/vgic/vgic-v4.c | |||
@@ -233,3 +233,21 @@ out: | |||
233 | mutex_unlock(&its->its_lock); | 233 | mutex_unlock(&its->its_lock); |
234 | return ret; | 234 | return ret; |
235 | } | 235 | } |
236 | |||
237 | void kvm_vgic_v4_enable_doorbell(struct kvm_vcpu *vcpu) | ||
238 | { | ||
239 | if (vgic_supports_direct_msis(vcpu->kvm)) { | ||
240 | int irq = vcpu->arch.vgic_cpu.vgic_v3.its_vpe.irq; | ||
241 | if (irq) | ||
242 | enable_irq(irq); | ||
243 | } | ||
244 | } | ||
245 | |||
246 | void kvm_vgic_v4_disable_doorbell(struct kvm_vcpu *vcpu) | ||
247 | { | ||
248 | if (vgic_supports_direct_msis(vcpu->kvm)) { | ||
249 | int irq = vcpu->arch.vgic_cpu.vgic_v3.its_vpe.irq; | ||
250 | if (irq) | ||
251 | disable_irq(irq); | ||
252 | } | ||
253 | } | ||