Skip to content

Commit

Permalink
KVM: arm/arm64: Enable MSI routing
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Eric Auger authored and Marc Zyngier committed Jul 22, 2016
1 parent 180ae7b commit 995a0ee
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 9 deletions.
3 changes: 3 additions & 0 deletions Documentation/virtual/kvm/api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2381,6 +2381,9 @@ On arm/arm64, gsi routing being supported, the following can happen:
- in case no routing entry is associated to this gsi, injection fails
- in case the gsi is associated to an irqchip routing entry,
irqchip.pin + 32 corresponds to the injected SPI ID.
- in case the gsi is associated to an MSI routing entry, the MSI
message and device ID are translated into an LPI (support restricted
to GICv3 ITS in-kernel emulation).

4.76 KVM_PPC_ALLOCATE_HTAB

Expand Down
2 changes: 2 additions & 0 deletions include/linux/kvm_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -1048,6 +1048,8 @@ static inline int mmu_notifier_retry(struct kvm *kvm, unsigned long mmu_seq)

#ifdef CONFIG_S390
#define KVM_MAX_IRQ_ROUTES 4096 //FIXME: we can have more than that...
#elif defined(CONFIG_ARM64)
#define KVM_MAX_IRQ_ROUTES 4096
#else
#define KVM_MAX_IRQ_ROUTES 1024
#endif
Expand Down
8 changes: 8 additions & 0 deletions virt/kvm/arm/vgic/vgic-irqfd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
24 changes: 15 additions & 9 deletions virt/kvm/irqchip.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
}

Expand All @@ -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);

Expand Down

0 comments on commit 995a0ee

Please sign in to comment.