Commit 41108170 authored by Marc Zyngier's avatar Marc Zyngier
Browse files

KVM: arm/arm64: vgic-irqfd: Implement kvm_arch_set_irq_inatomic



Now that we have a cache of MSI->LPI translations, it is pretty
easy to implement kvm_arch_set_irq_inatomic (this cache can be
parsed without sleeping).

Hopefully, this will improve some LPI-heavy workloads.

Tested-by: default avatarAndre Przywara <andre.przywara@arm.com>
Reviewed-by: default avatarEric Auger <eric.auger@redhat.com>
Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
parent 86a7dae8
Loading
Loading
Loading
Loading
+30 −6
Original line number Diff line number Diff line
@@ -66,6 +66,15 @@ out:
	return r;
}

static void kvm_populate_msi(struct kvm_kernel_irq_routing_entry *e,
			     struct kvm_msi *msi)
{
	msi->address_lo = e->msi.address_lo;
	msi->address_hi = e->msi.address_hi;
	msi->data = e->msi.data;
	msi->flags = e->msi.flags;
	msi->devid = e->msi.devid;
}
/**
 * kvm_set_msi: inject the MSI corresponding to the
 * MSI routing entry
@@ -79,21 +88,36 @@ int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
{
	struct kvm_msi msi;

	msi.address_lo = e->msi.address_lo;
	msi.address_hi = e->msi.address_hi;
	msi.data = e->msi.data;
	msi.flags = e->msi.flags;
	msi.devid = e->msi.devid;

	if (!vgic_has_its(kvm))
		return -ENODEV;

	if (!level)
		return -1;

	kvm_populate_msi(e, &msi);
	return vgic_its_inject_msi(kvm, &msi);
}

/**
 * kvm_arch_set_irq_inatomic: fast-path for irqfd injection
 *
 * Currently only direct MSI injection is supported.
 */
int kvm_arch_set_irq_inatomic(struct kvm_kernel_irq_routing_entry *e,
			      struct kvm *kvm, int irq_source_id, int level,
			      bool line_status)
{
	if (e->type == KVM_IRQ_ROUTING_MSI && vgic_has_its(kvm) && level) {
		struct kvm_msi msi;

		kvm_populate_msi(e, &msi);
		if (!vgic_its_inject_cached_translation(kvm, &msi))
			return 0;
	}

	return -EWOULDBLOCK;
}

int kvm_vgic_setup_default_irq_routing(struct kvm *kvm)
{
	struct kvm_irq_routing_entry *entries;