aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoffer Dall <christoffer.dall@linaro.org>2016-06-04 10:41:00 -0400
committerChristoffer Dall <christoffer.dall@linaro.org>2016-05-20 09:39:39 -0400
commitb452cb52072d21f026e38ac7af36a969bab2ed22 (patch)
tree49cf39fe6636b87c2c206adfcac3759ddf621dcc
parent63306c28ac92bdf9e41aef367708d762f9f725f2 (diff)
KVM: arm/arm64: Remove the IRQ field from struct irq_phys_map
The communication of a Linux IRQ number from outside the VGIC to the vgic was a leftover from the day when the vgic code cared about how a particular device injects virtual interrupts mapped to a physical interrupt. We can safely remove this notion, leaving all physical IRQ handling to be done in the device driver (the arch timer in this case), which makes room for a saner API for the new VGIC. Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org> Signed-off-by: Andre Przywara <andre.przywara@arm.com> Reviewed-by: Eric Auger <eric.auger@linaro.org>
-rw-r--r--include/kvm/arm_vgic.h3
-rw-r--r--virt/kvm/arm/arch_timer.c23
-rw-r--r--virt/kvm/arm/vgic.c28
3 files changed, 28 insertions, 26 deletions
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index c7bb184c79eb..9ad7625c0e79 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -158,7 +158,6 @@ struct vgic_io_device {
158struct irq_phys_map { 158struct irq_phys_map {
159 u32 virt_irq; 159 u32 virt_irq;
160 u32 phys_irq; 160 u32 phys_irq;
161 u32 irq;
162}; 161};
163 162
164struct irq_phys_map_entry { 163struct irq_phys_map_entry {
@@ -346,7 +345,7 @@ int kvm_vgic_inject_mapped_irq(struct kvm *kvm, int cpuid,
346void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg); 345void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);
347int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu); 346int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
348struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, 347struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu,
349 int virt_irq, int irq); 348 int virt_irq, int phys_irq);
350int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int virt_irq); 349int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int virt_irq);
351bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int virt_irq); 350bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int virt_irq);
352 351
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
index 962b442d0d77..e45895a0153d 100644
--- a/virt/kvm/arm/arch_timer.c
+++ b/virt/kvm/arm/arch_timer.c
@@ -20,6 +20,7 @@
20#include <linux/kvm.h> 20#include <linux/kvm.h>
21#include <linux/kvm_host.h> 21#include <linux/kvm_host.h>
22#include <linux/interrupt.h> 22#include <linux/interrupt.h>
23#include <linux/irq.h>
23 24
24#include <clocksource/arm_arch_timer.h> 25#include <clocksource/arm_arch_timer.h>
25#include <asm/arch_timer.h> 26#include <asm/arch_timer.h>
@@ -300,7 +301,7 @@ void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu)
300 if (timer->active_cleared_last && !phys_active) 301 if (timer->active_cleared_last && !phys_active)
301 return; 302 return;
302 303
303 ret = irq_set_irqchip_state(timer->map->irq, 304 ret = irq_set_irqchip_state(host_vtimer_irq,
304 IRQCHIP_STATE_ACTIVE, 305 IRQCHIP_STATE_ACTIVE,
305 phys_active); 306 phys_active);
306 WARN_ON(ret); 307 WARN_ON(ret);
@@ -333,6 +334,9 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
333{ 334{
334 struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; 335 struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
335 struct irq_phys_map *map; 336 struct irq_phys_map *map;
337 struct irq_desc *desc;
338 struct irq_data *data;
339 int phys_irq;
336 340
337 /* 341 /*
338 * The vcpu timer irq number cannot be determined in 342 * The vcpu timer irq number cannot be determined in
@@ -352,10 +356,25 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
352 kvm_timer_update_state(vcpu); 356 kvm_timer_update_state(vcpu);
353 357
354 /* 358 /*
359 * Find the physical IRQ number corresponding to the host_vtimer_irq
360 */
361 desc = irq_to_desc(host_vtimer_irq);
362 if (!desc) {
363 kvm_err("%s: no interrupt descriptor\n", __func__);
364 return -EINVAL;
365 }
366
367 data = irq_desc_get_irq_data(desc);
368 while (data->parent_data)
369 data = data->parent_data;
370
371 phys_irq = data->hwirq;
372
373 /*
355 * Tell the VGIC that the virtual interrupt is tied to a 374 * Tell the VGIC that the virtual interrupt is tied to a
356 * physical interrupt. We do that once per VCPU. 375 * physical interrupt. We do that once per VCPU.
357 */ 376 */
358 map = kvm_vgic_map_phys_irq(vcpu, irq->irq, host_vtimer_irq); 377 map = kvm_vgic_map_phys_irq(vcpu, irq->irq, phys_irq);
359 if (WARN_ON(IS_ERR(map))) 378 if (WARN_ON(IS_ERR(map)))
360 return PTR_ERR(map); 379 return PTR_ERR(map);
361 380
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 06abd59dcbe3..a7e496abfca2 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -1711,38 +1711,24 @@ static struct list_head *vgic_get_irq_phys_map_list(struct kvm_vcpu *vcpu,
1711/** 1711/**
1712 * kvm_vgic_map_phys_irq - map a virtual IRQ to a physical IRQ 1712 * kvm_vgic_map_phys_irq - map a virtual IRQ to a physical IRQ
1713 * @vcpu: The VCPU pointer 1713 * @vcpu: The VCPU pointer
1714 * @virt_irq: The virtual irq number 1714 * @virt_irq: The virtual IRQ number for the guest
1715 * @irq: The Linux IRQ number 1715 * @phys_irq: The hardware IRQ number of the host
1716 * 1716 *
1717 * Establish a mapping between a guest visible irq (@virt_irq) and a 1717 * Establish a mapping between a guest visible irq (@virt_irq) and a
1718 * Linux irq (@irq). On injection, @virt_irq will be associated with 1718 * hardware irq (@phys_irq). On injection, @virt_irq will be associated with
1719 * the physical interrupt represented by @irq. This mapping can be 1719 * the physical interrupt represented by @phys_irq. This mapping can be
1720 * established multiple times as long as the parameters are the same. 1720 * established multiple times as long as the parameters are the same.
1721 * 1721 *
1722 * Returns a valid pointer on success, and an error pointer otherwise 1722 * Returns a valid pointer on success, and an error pointer otherwise
1723 */ 1723 */
1724struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, 1724struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu,
1725 int virt_irq, int irq) 1725 int virt_irq, int phys_irq)
1726{ 1726{
1727 struct vgic_dist *dist = &vcpu->kvm->arch.vgic; 1727 struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
1728 struct list_head *root = vgic_get_irq_phys_map_list(vcpu, virt_irq); 1728 struct list_head *root = vgic_get_irq_phys_map_list(vcpu, virt_irq);
1729 struct irq_phys_map *map; 1729 struct irq_phys_map *map;
1730 struct irq_phys_map_entry *entry; 1730 struct irq_phys_map_entry *entry;
1731 struct irq_desc *desc;
1732 struct irq_data *data;
1733 int phys_irq;
1734 1731
1735 desc = irq_to_desc(irq);
1736 if (!desc) {
1737 kvm_err("%s: no interrupt descriptor\n", __func__);
1738 return ERR_PTR(-EINVAL);
1739 }
1740
1741 data = irq_desc_get_irq_data(desc);
1742 while (data->parent_data)
1743 data = data->parent_data;
1744
1745 phys_irq = data->hwirq;
1746 1732
1747 /* Create a new mapping */ 1733 /* Create a new mapping */
1748 entry = kzalloc(sizeof(*entry), GFP_KERNEL); 1734 entry = kzalloc(sizeof(*entry), GFP_KERNEL);
@@ -1755,8 +1741,7 @@ struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu,
1755 map = vgic_irq_map_search(vcpu, virt_irq); 1741 map = vgic_irq_map_search(vcpu, virt_irq);
1756 if (map) { 1742 if (map) {
1757 /* Make sure this mapping matches */ 1743 /* Make sure this mapping matches */
1758 if (map->phys_irq != phys_irq || 1744 if (map->phys_irq != phys_irq)
1759 map->irq != irq)
1760 map = ERR_PTR(-EINVAL); 1745 map = ERR_PTR(-EINVAL);
1761 1746
1762 /* Found an existing, valid mapping */ 1747 /* Found an existing, valid mapping */
@@ -1766,7 +1751,6 @@ struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu,
1766 map = &entry->map; 1751 map = &entry->map;
1767 map->virt_irq = virt_irq; 1752 map->virt_irq = virt_irq;
1768 map->phys_irq = phys_irq; 1753 map->phys_irq = phys_irq;
1769 map->irq = irq;
1770 1754
1771 list_add_tail_rcu(&entry->entry, root); 1755 list_add_tail_rcu(&entry->entry, root);
1772 1756