The check for the remote being present before sending it an interrupt is
actually generic. Factor this out and change the arch-specific callback
to only trigger the interrupt on the destination device.

Signed-off-by: Jan Kiszka <[email protected]>
---
 hypervisor/arch/arm-common/ivshmem.c   |  9 ++-------
 hypervisor/arch/x86/ivshmem.c          | 13 ++++---------
 hypervisor/include/jailhouse/ivshmem.h |  6 +++---
 hypervisor/ivshmem.c                   | 14 +++++++++++---
 4 files changed, 20 insertions(+), 22 deletions(-)

diff --git a/hypervisor/arch/arm-common/ivshmem.c 
b/hypervisor/arch/arm-common/ivshmem.c
index 14da345..19d300d 100644
--- a/hypervisor/arch/arm-common/ivshmem.c
+++ b/hypervisor/arch/arm-common/ivshmem.c
@@ -13,15 +13,10 @@
 #include <jailhouse/ivshmem.h>
 #include <asm/irqchip.h>
 
-void arch_ivshmem_write_doorbell(struct ivshmem_endpoint *ive)
+void arch_ivshmem_trigger_interrupt(struct ivshmem_endpoint *ive)
 {
-       struct ivshmem_endpoint *remote = ive->remote;
-       unsigned int irq_id;
+       unsigned int irq_id = ive->arch.irq_id;
 
-       if (!remote)
-               return;
-
-       irq_id = remote->arch.irq_id;
        if (irq_id)
                irqchip_set_pending(NULL, irq_id);
 }
diff --git a/hypervisor/arch/x86/ivshmem.c b/hypervisor/arch/x86/ivshmem.c
index 0df018c..7ec3ea7 100644
--- a/hypervisor/arch/x86/ivshmem.c
+++ b/hypervisor/arch/x86/ivshmem.c
@@ -16,17 +16,12 @@
 #include <jailhouse/printk.h>
 #include <asm/pci.h>
 
-void arch_ivshmem_write_doorbell(struct ivshmem_endpoint *ive)
+void arch_ivshmem_trigger_interrupt(struct ivshmem_endpoint *ive)
 {
-       struct ivshmem_endpoint *remote = ive->remote;
-       struct apic_irq_message irq_msg;
-
-       if (!remote)
-               return;
+       /* Get a copy of the struct before using it. */
+       struct apic_irq_message irq_msg = ive->arch.irq_msg;
 
-       /* get a copy of the struct before using it, the read barrier makes
-        * sure the copy is consistent */
-       irq_msg = remote->arch.irq_msg;
+       /* The read barrier makes sure the copy is consistent. */
        memory_load_barrier();
        if (irq_msg.valid)
                apic_send_irq(irq_msg);
diff --git a/hypervisor/include/jailhouse/ivshmem.h 
b/hypervisor/include/jailhouse/ivshmem.h
index 742678d..b6a1044 100644
--- a/hypervisor/include/jailhouse/ivshmem.h
+++ b/hypervisor/include/jailhouse/ivshmem.h
@@ -50,10 +50,10 @@ enum pci_access ivshmem_pci_cfg_read(struct pci_device 
*device, u16 address,
 bool ivshmem_is_msix_masked(struct ivshmem_endpoint *ive);
 
 /**
- * Handle write to doorbell register.
- * @param ive          Ivshmem endpoint the write was performed on.
+ * Trigger interrupt on ivshmem endpoint.
+ * @param ive          Ivshmem endpoint the interrupt should be raised at.
  */
-void arch_ivshmem_write_doorbell(struct ivshmem_endpoint *ive);
+void arch_ivshmem_trigger_interrupt(struct ivshmem_endpoint *ive);
 
 /**
  * Update cached MSI-X state (if any) of the given ivshmem device.
diff --git a/hypervisor/ivshmem.c b/hypervisor/ivshmem.c
index 5cedd35..1e3d27d 100644
--- a/hypervisor/ivshmem.c
+++ b/hypervisor/ivshmem.c
@@ -70,6 +70,14 @@ static const u32 default_cspace[IVSHMEM_CFG_SIZE / 
sizeof(u32)] = {
        [(IVSHMEM_CFG_MSIX_CAP + 0x8)/4] = 0x10 * IVSHMEM_MSIX_VECTORS | 4,
 };
 
+static void ivshmem_remote_interrupt(struct ivshmem_endpoint *ive)
+{
+       struct ivshmem_endpoint *remote = ive->remote;
+
+       if (remote)
+               arch_ivshmem_trigger_interrupt(ive->remote);
+}
+
 static enum mmio_result ivshmem_register_mmio(void *arg,
                                              struct mmio_access *mmio)
 {
@@ -93,7 +101,7 @@ static enum mmio_result ivshmem_register_mmio(void *arg,
 
        if (mmio->address == IVSHMEM_REG_DBELL) {
                if (mmio->is_write)
-                       arch_ivshmem_write_doorbell(ive);
+                       ivshmem_remote_interrupt(ive);
                else
                        mmio->value = 0;
                return MMIO_HANDLED;
@@ -103,7 +111,7 @@ static enum mmio_result ivshmem_register_mmio(void *arg,
                if (mmio->is_write) {
                        ive->state = mmio->value;
                        memory_barrier();
-                       arch_ivshmem_write_doorbell(ive);
+                       ivshmem_remote_interrupt(ive);
                } else {
                        mmio->value = ive->state;
                }
@@ -395,7 +403,7 @@ void ivshmem_exit(struct pci_device *device)
        if (ive->remote) {
                ive->remote->remote = NULL;
                memory_barrier();
-               arch_ivshmem_write_doorbell(ive);
+               ivshmem_remote_interrupt(ive);
 
                ive->device = NULL;
        } else {
-- 
2.1.4

-- 
You received this message because you are subscribed to the Google Groups 
"Jailhouse" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to