Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 995a0ee9 authored by Eric Auger's avatar Eric Auger Committed by Marc Zyngier
Browse files

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: default avatarEric Auger <eric.auger@redhat.com>
Reviewed-by: default avatarAndre Przywara <andre.przywara@arm.com>
Signed-off-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
parent 180ae7b1
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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

+2 −0
Original line number Diff line number Diff line
@@ -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
+8 −0
Original line number Diff line number Diff line
@@ -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;
	}
+15 −9
Original line number Diff line number Diff line
@@ -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);