[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 1/2] arm: vgic: Add the ability to trigger MSIs from the Hypervisor



Hi,

On 14/01/2024 10:01, Mykyta Poturai wrote:
Add the vgic_its_trigger_msi() function to the vgic interface. This
function allows to inject MSIs from the Hypervisor to the guest.
Which is useful for userspace PCI backend drivers.

Signed-off-by: Mykyta Poturai <mykyta_poturai@xxxxxxxx>
---
  xen/arch/arm/include/asm/vgic.h | 11 +++++++++++
  xen/arch/arm/vgic-v3-its.c      | 35 +++++++++++++++++++++++++++++++++
  2 files changed, 46 insertions(+)

diff --git a/xen/arch/arm/include/asm/vgic.h b/xen/arch/arm/include/asm/vgic.h
index 922779ce14..4695743848 100644
--- a/xen/arch/arm/include/asm/vgic.h
+++ b/xen/arch/arm/include/asm/vgic.h
@@ -317,6 +317,17 @@ extern bool vgic_migrate_irq(struct vcpu *old, struct vcpu 
*new, unsigned int ir
  extern void vgic_check_inflight_irqs_pending(struct domain *d, struct vcpu *v,
                                               unsigned int rank, uint32_t r);
+#ifdef CONFIG_HAS_ITS
+int vgic_its_trigger_msi(struct domain *d, paddr_t doorbell_address,
+                                u32 devid, u32 eventid);
+#else
+static inline int vgic_its_trigger_msi(struct domain *d, paddr_t 
doorbell_address,
+                                u32 devid, u32 eventid)
+{
+    return -EOPNOTSUPP;
+}
+#endif /* CONFIG_HAS_ITS */
+
  #endif /* !CONFIG_NEW_VGIC */
/*** Common VGIC functions used by Xen arch code ****/
diff --git a/xen/arch/arm/vgic-v3-its.c b/xen/arch/arm/vgic-v3-its.c
index 70b5aeb822..683a378f6e 100644
--- a/xen/arch/arm/vgic-v3-its.c
+++ b/xen/arch/arm/vgic-v3-its.c
@@ -1484,6 +1484,41 @@ static int vgic_v3_its_init_virtual(struct domain *d, 
paddr_t guest_addr,
      return 0;
  }
+int vgic_its_trigger_msi(struct domain *d, paddr_t doorbell_address,
+                                u32 devid, u32 eventid)
+{
+    struct vcpu *vcpu;
+    struct virt_its *pos, *temp;
+    struct virt_its *its = NULL;
+    uint32_t vlpi;
+    bool ret;
+
+    list_for_each_entry_safe( pos, temp, &d->arch.vgic.vits_list, vits_list )
+    {
+        if ( pos->doorbell_address == doorbell_address )
+        {
+            its = pos;
+            break;
+        }
+    }
+
+    if ( !its )
+        return -EINVAL;
+
+    spin_lock(&its->its_lock);
+    ret = read_itte(its, devid, eventid, &vcpu, &vlpi);
+    spin_unlock(&its->its_lock);
+    if ( !ret )
+        return -1;
+
+    if ( vlpi == INVALID_LPI )
+        return -1;

Reading the code, I think you want to use get_event_pending_irq(). This will return the associated pending_irq. Then you can...

+
+    vgic_vcpu_inject_lpi(its->d, vlpi);

... open-code vgic_vcpu_inject_lpi(). This would avoid access the guest memory (done by read_itte) and reduce to just one lookup (today you are doing two: read_itte() and irq_to_pending()).

Cheers,

--
Julien Grall



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.