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>
This commit is contained in:
parent
180ae7b118
commit
995a0ee980
|
@ -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 no routing entry is associated to this gsi, injection fails
|
||||||
- in case the gsi is associated to an irqchip routing entry,
|
- in case the gsi is associated to an irqchip routing entry,
|
||||||
irqchip.pin + 32 corresponds to the injected SPI ID.
|
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
|
4.76 KVM_PPC_ALLOCATE_HTAB
|
||||||
|
|
||||||
|
|
|
@ -1048,6 +1048,8 @@ static inline int mmu_notifier_retry(struct kvm *kvm, unsigned long mmu_seq)
|
||||||
|
|
||||||
#ifdef CONFIG_S390
|
#ifdef CONFIG_S390
|
||||||
#define KVM_MAX_IRQ_ROUTES 4096 //FIXME: we can have more than that...
|
#define KVM_MAX_IRQ_ROUTES 4096 //FIXME: we can have more than that...
|
||||||
|
#elif defined(CONFIG_ARM64)
|
||||||
|
#define KVM_MAX_IRQ_ROUTES 4096
|
||||||
#else
|
#else
|
||||||
#define KVM_MAX_IRQ_ROUTES 1024
|
#define KVM_MAX_IRQ_ROUTES 1024
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -59,6 +59,14 @@ int kvm_set_routing_entry(struct kvm_kernel_irq_routing_entry *e,
|
||||||
(e->irqchip.irqchip >= KVM_NR_IRQCHIPS))
|
(e->irqchip.irqchip >= KVM_NR_IRQCHIPS))
|
||||||
goto out;
|
goto out;
|
||||||
break;
|
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:
|
default:
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -178,6 +178,7 @@ int kvm_set_irq_routing(struct kvm *kvm,
|
||||||
unsigned flags)
|
unsigned flags)
|
||||||
{
|
{
|
||||||
struct kvm_irq_routing_table *new, *old;
|
struct kvm_irq_routing_table *new, *old;
|
||||||
|
struct kvm_kernel_irq_routing_entry *e;
|
||||||
u32 i, j, nr_rt_entries = 0;
|
u32 i, j, nr_rt_entries = 0;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
@ -201,23 +202,25 @@ int kvm_set_irq_routing(struct kvm *kvm,
|
||||||
new->chip[i][j] = -1;
|
new->chip[i][j] = -1;
|
||||||
|
|
||||||
for (i = 0; i < nr; ++i) {
|
for (i = 0; i < nr; ++i) {
|
||||||
struct kvm_kernel_irq_routing_entry *e;
|
|
||||||
|
|
||||||
r = -ENOMEM;
|
r = -ENOMEM;
|
||||||
e = kzalloc(sizeof(*e), GFP_KERNEL);
|
e = kzalloc(sizeof(*e), GFP_KERNEL);
|
||||||
if (!e)
|
if (!e)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
r = -EINVAL;
|
r = -EINVAL;
|
||||||
if (ue->flags) {
|
switch (ue->type) {
|
||||||
kfree(e);
|
case KVM_IRQ_ROUTING_MSI:
|
||||||
goto out;
|
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);
|
r = setup_routing_entry(new, e, ue);
|
||||||
if (r) {
|
if (r)
|
||||||
kfree(e);
|
goto free_entry;
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
++ue;
|
++ue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,7 +237,10 @@ int kvm_set_irq_routing(struct kvm *kvm,
|
||||||
|
|
||||||
new = old;
|
new = old;
|
||||||
r = 0;
|
r = 0;
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
free_entry:
|
||||||
|
kfree(e);
|
||||||
out:
|
out:
|
||||||
free_irq_routing_table(new);
|
free_irq_routing_table(new);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue