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.

Signed-off-by: Marc Zyngier <marc.zyng...@arm.com>
---
 virt/kvm/arm/vgic/vgic-irqfd.c | 36 ++++++++++++++++++++++++++++------
 1 file changed, 30 insertions(+), 6 deletions(-)

diff --git a/virt/kvm/arm/vgic/vgic-irqfd.c b/virt/kvm/arm/vgic/vgic-irqfd.c
index 99e026d2dade..9f203ed8c8f3 100644
--- a/virt/kvm/arm/vgic/vgic-irqfd.c
+++ b/virt/kvm/arm/vgic/vgic-irqfd.c
@@ -77,6 +77,15 @@ int kvm_set_routing_entry(struct kvm *kvm,
        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
@@ -90,21 +99,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 injecton 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;
-- 
2.20.1

_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

Reply via email to