summaryrefslogtreecommitdiffstats
path: root/virt
diff options
context:
space:
mode:
authorEric Auger <eric.auger@redhat.com>2017-10-27 10:28:32 -0400
committerChristoffer Dall <christoffer.dall@linaro.org>2017-11-06 11:20:19 -0500
commit47bbd31f740c4e693d01766f367ad3366fb49a6d (patch)
tree54bcec5711d5dd778f654e00949cf685b4148fc0 /virt
parent2412405b3141cfe943d05a28a2160187d45f1c9a (diff)
KVM: arm/arm64: vgic: restructure kvm_vgic_(un)map_phys_irq
We want to reuse the core of the map/unmap functions for IRQ forwarding. Let's move the computation of the hwirq in kvm_vgic_map_phys_irq and pass the linux IRQ as parameter. the host_irq is added to struct vgic_irq. We introduce kvm_vgic_map/unmap_irq which take a struct vgic_irq handle as a parameter. Acked-by: Christoffer Dall <christoffer.dall@linaro.org> Signed-off-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>
Diffstat (limited to 'virt')
-rw-r--r--virt/kvm/arm/arch_timer.c24
-rw-r--r--virt/kvm/arm/vgic/vgic.c60
2 files changed, 46 insertions, 38 deletions
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
index 4db54ff08d9e..4151250ce8da 100644
--- a/virt/kvm/arm/arch_timer.c
+++ b/virt/kvm/arm/arch_timer.c
@@ -817,9 +817,6 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu)
817{ 817{
818 struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; 818 struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
819 struct arch_timer_context *vtimer = vcpu_vtimer(vcpu); 819 struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
820 struct irq_desc *desc;
821 struct irq_data *data;
822 int phys_irq;
823 int ret; 820 int ret;
824 821
825 if (timer->enabled) 822 if (timer->enabled)
@@ -837,26 +834,7 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu)
837 return -EINVAL; 834 return -EINVAL;
838 } 835 }
839 836
840 /* 837 ret = kvm_vgic_map_phys_irq(vcpu, host_vtimer_irq, vtimer->irq.irq);
841 * Find the physical IRQ number corresponding to the host_vtimer_irq
842 */
843 desc = irq_to_desc(host_vtimer_irq);
844 if (!desc) {
845 kvm_err("%s: no interrupt descriptor\n", __func__);
846 return -EINVAL;
847 }
848
849 data = irq_desc_get_irq_data(desc);
850 while (data->parent_data)
851 data = data->parent_data;
852
853 phys_irq = data->hwirq;
854
855 /*
856 * Tell the VGIC that the virtual interrupt is tied to a
857 * physical interrupt. We do that once per VCPU.
858 */
859 ret = kvm_vgic_map_phys_irq(vcpu, vtimer->irq.irq, phys_irq);
860 if (ret) 838 if (ret)
861 return ret; 839 return ret;
862 840
diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c
index e54ef2fdf73d..a05a5700910b 100644
--- a/virt/kvm/arm/vgic/vgic.c
+++ b/virt/kvm/arm/vgic/vgic.c
@@ -17,6 +17,8 @@
17#include <linux/kvm.h> 17#include <linux/kvm.h>
18#include <linux/kvm_host.h> 18#include <linux/kvm_host.h>
19#include <linux/list_sort.h> 19#include <linux/list_sort.h>
20#include <linux/interrupt.h>
21#include <linux/irq.h>
20 22
21#include "vgic.h" 23#include "vgic.h"
22 24
@@ -409,25 +411,56 @@ int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int intid,
409 return 0; 411 return 0;
410} 412}
411 413
412int kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, u32 virt_irq, u32 phys_irq) 414/* @irq->irq_lock must be held */
415static int kvm_vgic_map_irq(struct kvm_vcpu *vcpu, struct vgic_irq *irq,
416 unsigned int host_irq)
413{ 417{
414 struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, virt_irq); 418 struct irq_desc *desc;
419 struct irq_data *data;
420
421 /*
422 * Find the physical IRQ number corresponding to @host_irq
423 */
424 desc = irq_to_desc(host_irq);
425 if (!desc) {
426 kvm_err("%s: no interrupt descriptor\n", __func__);
427 return -EINVAL;
428 }
429 data = irq_desc_get_irq_data(desc);
430 while (data->parent_data)
431 data = data->parent_data;
432
433 irq->hw = true;
434 irq->host_irq = host_irq;
435 irq->hwintid = data->hwirq;
436 return 0;
437}
438
439/* @irq->irq_lock must be held */
440static inline void kvm_vgic_unmap_irq(struct vgic_irq *irq)
441{
442 irq->hw = false;
443 irq->hwintid = 0;
444}
445
446int kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, unsigned int host_irq,
447 u32 vintid)
448{
449 struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, vintid);
415 unsigned long flags; 450 unsigned long flags;
451 int ret;
416 452
417 BUG_ON(!irq); 453 BUG_ON(!irq);
418 454
419 spin_lock_irqsave(&irq->irq_lock, flags); 455 spin_lock_irqsave(&irq->irq_lock, flags);
420 456 ret = kvm_vgic_map_irq(vcpu, irq, host_irq);
421 irq->hw = true;
422 irq->hwintid = phys_irq;
423
424 spin_unlock_irqrestore(&irq->irq_lock, flags); 457 spin_unlock_irqrestore(&irq->irq_lock, flags);
425 vgic_put_irq(vcpu->kvm, irq); 458 vgic_put_irq(vcpu->kvm, irq);
426 459
427 return 0; 460 return ret;
428} 461}
429 462
430int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int virt_irq) 463int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int vintid)
431{ 464{
432 struct vgic_irq *irq; 465 struct vgic_irq *irq;
433 unsigned long flags; 466 unsigned long flags;
@@ -435,14 +468,11 @@ int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int virt_irq)
435 if (!vgic_initialized(vcpu->kvm)) 468 if (!vgic_initialized(vcpu->kvm))
436 return -EAGAIN; 469 return -EAGAIN;
437 470
438 irq = vgic_get_irq(vcpu->kvm, vcpu, virt_irq); 471 irq = vgic_get_irq(vcpu->kvm, vcpu, vintid);
439 BUG_ON(!irq); 472 BUG_ON(!irq);
440 473
441 spin_lock_irqsave(&irq->irq_lock, flags); 474 spin_lock_irqsave(&irq->irq_lock, flags);
442 475 kvm_vgic_unmap_irq(irq);
443 irq->hw = false;
444 irq->hwintid = 0;
445
446 spin_unlock_irqrestore(&irq->irq_lock, flags); 476 spin_unlock_irqrestore(&irq->irq_lock, flags);
447 vgic_put_irq(vcpu->kvm, irq); 477 vgic_put_irq(vcpu->kvm, irq);
448 478
@@ -784,9 +814,9 @@ void vgic_kick_vcpus(struct kvm *kvm)
784 } 814 }
785} 815}
786 816
787bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int virt_irq) 817bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int vintid)
788{ 818{
789 struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, virt_irq); 819 struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, vintid);
790 bool map_is_active; 820 bool map_is_active;
791 unsigned long flags; 821 unsigned long flags;
792 822