summaryrefslogtreecommitdiffstats
path: root/virt
diff options
context:
space:
mode:
authorEric Auger <eric.auger@redhat.com>2016-07-22 18:20:42 +0200
committerMarc Zyngier <marc.zyngier@arm.com>2016-07-22 19:52:03 +0200
commit995a0ee9809b6948bb7bfea77f129fe1d5157cc1 (patch)
treeaa87eb8de3f3e111b9dcc4b470a24a660cd6bb8a /virt
parentKVM: arm/arm64: Enable irqchip routing (diff)
downloadlinux-995a0ee9809b6948bb7bfea77f129fe1d5157cc1.tar.xz
linux-995a0ee9809b6948bb7bfea77f129fe1d5157cc1.zip
KVM: arm/arm64: Enable MSI routing
Up to now, only irqchip routing entries could be set. This patch adds the capability to insert MSI routing entries. For ARM64, let's also increase KVM_MAX_IRQ_ROUTES to 4096: this include SPI irqchip routes plus MSI routes. In the future this might be extended. Signed-off-by: Eric Auger <eric.auger@redhat.com> Reviewed-by: Andre Przywara <andre.przywara@arm.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Diffstat (limited to 'virt')
-rw-r--r--virt/kvm/arm/vgic/vgic-irqfd.c8
-rw-r--r--virt/kvm/irqchip.c24
2 files changed, 23 insertions, 9 deletions
diff --git a/virt/kvm/arm/vgic/vgic-irqfd.c b/virt/kvm/arm/vgic/vgic-irqfd.c
index 6e84d530d9f7..683a589711b0 100644
--- a/virt/kvm/arm/vgic/vgic-irqfd.c
+++ b/virt/kvm/arm/vgic/vgic-irqfd.c
@@ -59,6 +59,14 @@ int kvm_set_routing_entry(struct kvm_kernel_irq_routing_entry *e,
(e->irqchip.irqchip >= KVM_NR_IRQCHIPS))
goto out;
break;
+ case KVM_IRQ_ROUTING_MSI:
+ e->set = kvm_set_msi;
+ e->msi.address_lo = ue->u.msi.address_lo;
+ e->msi.address_hi = ue->u.msi.address_hi;
+ e->msi.data = ue->u.msi.data;
+ e->msi.flags = ue->flags;
+ e->msi.devid = ue->u.msi.devid;
+ break;
default:
goto out;
}
diff --git a/virt/kvm/irqchip.c b/virt/kvm/irqchip.c
index 0c000546aedc..c6202199e505 100644
--- a/virt/kvm/irqchip.c
+++ b/virt/kvm/irqchip.c
@@ -178,6 +178,7 @@ int kvm_set_irq_routing(struct kvm *kvm,
unsigned flags)
{
struct kvm_irq_routing_table *new, *old;
+ struct kvm_kernel_irq_routing_entry *e;
u32 i, j, nr_rt_entries = 0;
int r;
@@ -201,23 +202,25 @@ int kvm_set_irq_routing(struct kvm *kvm,
new->chip[i][j] = -1;
for (i = 0; i < nr; ++i) {
- struct kvm_kernel_irq_routing_entry *e;
-
r = -ENOMEM;
e = kzalloc(sizeof(*e), GFP_KERNEL);
if (!e)
goto out;
r = -EINVAL;
- if (ue->flags) {
- kfree(e);
- goto out;
+ switch (ue->type) {
+ case KVM_IRQ_ROUTING_MSI:
+ if (ue->flags & ~KVM_MSI_VALID_DEVID)
+ goto free_entry;
+ break;
+ default:
+ if (ue->flags)
+ goto free_entry;
+ break;
}
r = setup_routing_entry(new, e, ue);
- if (r) {
- kfree(e);
- goto out;
- }
+ if (r)
+ goto free_entry;
++ue;
}
@@ -234,7 +237,10 @@ int kvm_set_irq_routing(struct kvm *kvm,
new = old;
r = 0;
+ goto out;
+free_entry:
+ kfree(e);
out:
free_irq_routing_table(new);