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:
Родитель
180ae7b118
Коммит
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 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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче