Skip to content

Commit 47bbd31

Browse files
eaugerchazy
authored andcommitted
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 <[email protected]> Signed-off-by: Eric Auger <[email protected]> Signed-off-by: Marc Zyngier <[email protected]> Signed-off-by: Christoffer Dall <[email protected]>
1 parent 2412405 commit 47bbd31

File tree

3 files changed

+51
-41
lines changed

3 files changed

+51
-41
lines changed

include/kvm/arm_vgic.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ struct vgic_irq {
116116
bool hw; /* Tied to HW IRQ */
117117
struct kref refcount; /* Used for LPIs */
118118
u32 hwintid; /* HW INTID number */
119+
unsigned int host_irq; /* linux irq corresponding to hwintid */
119120
union {
120121
u8 targets; /* GICv2 target VCPUs mask */
121122
u32 mpidr; /* GICv3 target VCPU */
@@ -307,9 +308,10 @@ void kvm_vgic_init_cpu_hardware(void);
307308

308309
int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int intid,
309310
bool level, void *owner);
310-
int kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, u32 virt_irq, u32 phys_irq);
311-
int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int virt_irq);
312-
bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int virt_irq);
311+
int kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, unsigned int host_irq,
312+
u32 vintid);
313+
int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int vintid);
314+
bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int vintid);
313315

314316
int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
315317

virt/kvm/arm/arch_timer.c

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -817,9 +817,6 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu)
817817
{
818818
struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
819819
struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
820-
struct irq_desc *desc;
821-
struct irq_data *data;
822-
int phys_irq;
823820
int ret;
824821

825822
if (timer->enabled)
@@ -837,26 +834,7 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu)
837834
return -EINVAL;
838835
}
839836

840-
/*
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);
837+
ret = kvm_vgic_map_phys_irq(vcpu, host_vtimer_irq, vtimer->irq.irq);
860838
if (ret)
861839
return ret;
862840

virt/kvm/arm/vgic/vgic.c

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
#include <linux/kvm.h>
1818
#include <linux/kvm_host.h>
1919
#include <linux/list_sort.h>
20+
#include <linux/interrupt.h>
21+
#include <linux/irq.h>
2022

2123
#include "vgic.h"
2224

@@ -409,40 +411,68 @@ int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int intid,
409411
return 0;
410412
}
411413

412-
int kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, u32 virt_irq, u32 phys_irq)
414+
/* @irq->irq_lock must be held */
415+
static int kvm_vgic_map_irq(struct kvm_vcpu *vcpu, struct vgic_irq *irq,
416+
unsigned int host_irq)
413417
{
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 */
440+
static inline void kvm_vgic_unmap_irq(struct vgic_irq *irq)
441+
{
442+
irq->hw = false;
443+
irq->hwintid = 0;
444+
}
445+
446+
int 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);
415450
unsigned long flags;
451+
int ret;
416452

417453
BUG_ON(!irq);
418454

419455
spin_lock_irqsave(&irq->irq_lock, flags);
420-
421-
irq->hw = true;
422-
irq->hwintid = phys_irq;
423-
456+
ret = kvm_vgic_map_irq(vcpu, irq, host_irq);
424457
spin_unlock_irqrestore(&irq->irq_lock, flags);
425458
vgic_put_irq(vcpu->kvm, irq);
426459

427-
return 0;
460+
return ret;
428461
}
429462

430-
int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int virt_irq)
463+
int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int vintid)
431464
{
432465
struct vgic_irq *irq;
433466
unsigned long flags;
434467

435468
if (!vgic_initialized(vcpu->kvm))
436469
return -EAGAIN;
437470

438-
irq = vgic_get_irq(vcpu->kvm, vcpu, virt_irq);
471+
irq = vgic_get_irq(vcpu->kvm, vcpu, vintid);
439472
BUG_ON(!irq);
440473

441474
spin_lock_irqsave(&irq->irq_lock, flags);
442-
443-
irq->hw = false;
444-
irq->hwintid = 0;
445-
475+
kvm_vgic_unmap_irq(irq);
446476
spin_unlock_irqrestore(&irq->irq_lock, flags);
447477
vgic_put_irq(vcpu->kvm, irq);
448478

@@ -784,9 +814,9 @@ void vgic_kick_vcpus(struct kvm *kvm)
784814
}
785815
}
786816

787-
bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int virt_irq)
817+
bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int vintid)
788818
{
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);
790820
bool map_is_active;
791821
unsigned long flags;
792822

0 commit comments

Comments
 (0)