From: Jan Kiszka <[email protected]>

Analogously to arch_ivshmem_update_msix, introduce the arch callback
arch_ivshmem_update_intx which is invoked whenever the new INTx control
register is written.

The INTx control register definition is taken from the original
revision-0 ivshmem device, though without adding the status register at
offset 4 as well. We model INTx as edge-triggered - in deviation from
the PCI spec -, so there is no reason to add such a register with all
its logic.

Furthermore, we fill the interrupt pin register in the absence of MSI-X,
using standard PCI pin rotation based on the device slot.

Signed-off-by: Jan Kiszka <[email protected]>
---

Replaces "[PATCH 16/23] core: ivshmem: Introduce arch_ivshmem_init"

 hypervisor/arch/arm-common/ivshmem.c   |  4 ++++
 hypervisor/arch/x86/ivshmem.c          |  4 ++++
 hypervisor/include/jailhouse/ivshmem.h |  9 +++++++++
 hypervisor/ivshmem.c                   | 22 +++++++++++++++++++---
 4 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/hypervisor/arch/arm-common/ivshmem.c 
b/hypervisor/arch/arm-common/ivshmem.c
index 797d8b5..885d439 100644
--- a/hypervisor/arch/arm-common/ivshmem.c
+++ b/hypervisor/arch/arm-common/ivshmem.c
@@ -42,3 +42,7 @@ int arch_ivshmem_update_msix(struct pci_device *device)
 
        return 0;
 }
+
+void arch_ivshmem_update_intx(struct ivshmem_endpoint *ive)
+{
+}
diff --git a/hypervisor/arch/x86/ivshmem.c b/hypervisor/arch/x86/ivshmem.c
index 49f74e7..0df018c 100644
--- a/hypervisor/arch/x86/ivshmem.c
+++ b/hypervisor/arch/x86/ivshmem.c
@@ -69,3 +69,7 @@ int arch_ivshmem_update_msix(struct pci_device *device)
 
        return 0;
 }
+
+void arch_ivshmem_update_intx(struct ivshmem_endpoint *ive)
+{
+}
diff --git a/hypervisor/include/jailhouse/ivshmem.h 
b/hypervisor/include/jailhouse/ivshmem.h
index c0fd520..742678d 100644
--- a/hypervisor/include/jailhouse/ivshmem.h
+++ b/hypervisor/include/jailhouse/ivshmem.h
@@ -20,6 +20,8 @@
 #define IVSHMEM_CFG_MSIX_CAP   0x50
 #define IVSHMEM_CFG_SIZE       (IVSHMEM_CFG_MSIX_CAP + 12)
 
+#define IVSHMEM_INTX_ENABLE    0x1
+
 /**
  * @defgroup IVSHMEM ivshmem
  * @{
@@ -34,6 +36,7 @@ struct ivshmem_endpoint {
        struct pci_device *device;
        struct ivshmem_endpoint *remote;
        struct arch_pci_ivshmem arch;
+       u32 intx_ctrl_reg;
 };
 
 int ivshmem_init(struct cell *cell, struct pci_device *device);
@@ -60,5 +63,11 @@ void arch_ivshmem_write_doorbell(struct ivshmem_endpoint 
*ive);
  */
 int arch_ivshmem_update_msix(struct pci_device *device);
 
+/**
+ * Update cached INTx state (if any) of the given ivshmem device.
+ * @param ive          Ivshmem endpoint to be updated.
+ */
+void arch_ivshmem_update_intx(struct ivshmem_endpoint *ive);
+
 /** @} IVSHMEM */
 #endif /* !_JAILHOUSE_IVSHMEM_H */
diff --git a/hypervisor/ivshmem.c b/hypervisor/ivshmem.c
index 6f628a7..043fb3c 100644
--- a/hypervisor/ivshmem.c
+++ b/hypervisor/ivshmem.c
@@ -39,6 +39,7 @@
 
 #define IVSHMEM_MSIX_VECTORS   1
 
+#define IVSHMEM_REG_INTX_CTRL  0
 #define IVSHMEM_REG_IVPOS      8
 #define IVSHMEM_REG_DBELL      12
 #define IVSHMEM_REG_LSTATE     16
@@ -72,6 +73,16 @@ static enum mmio_result ivshmem_register_mmio(void *arg,
 {
        struct ivshmem_endpoint *ive = arg;
 
+       if (mmio->address == IVSHMEM_REG_INTX_CTRL) {
+               if (mmio->is_write) {
+                       ive->intx_ctrl_reg = mmio->value & IVSHMEM_INTX_ENABLE;
+                       arch_ivshmem_update_intx(ive);
+               } else {
+                       mmio->value = ive->intx_ctrl_reg;
+               }
+               return MMIO_HANDLED;
+       }
+
        /* read-only IVPosition */
        if (mmio->address == IVSHMEM_REG_IVPOS && !mmio->is_write) {
                mmio->value = ive->ivpos;
@@ -267,6 +278,14 @@ static void ivshmem_connect_cell(struct ivshmem_data *iv,
 
        ive->cspace[0x08/4] |= d->info->shmem_protocol << 8;
 
+       if (d->info->num_msix_vectors == 0) {
+               /* let the PIN rotate based on the device number */
+               ive->cspace[PCI_CFG_INT/4] =
+                       (((d->info->bdf >> 3) & 0x3) + 1) << 8;
+               /* disable MSI-X capability */
+               ive->cspace[PCI_CFG_CAPS/4] = 0;
+       }
+
        ive->cspace[IVSHMEM_CFG_SHMEM_PTR/4] = (u32)mem->virt_start;
        ive->cspace[IVSHMEM_CFG_SHMEM_PTR/4 + 1] = (u32)(mem->virt_start >> 32);
        ive->cspace[IVSHMEM_CFG_SHMEM_SZ/4] = (u32)mem->size;
@@ -364,9 +383,6 @@ int ivshmem_init(struct cell *cell, struct pci_device 
*device)
        struct ivshmem_data **ivp;
        struct pci_device *dev0;
 
-       if (device->info->num_msix_vectors != 1)
-               return trace_error(-EINVAL);
-
        if (device->info->shmem_region >= cell->config->num_memory_regions)
                return trace_error(-EINVAL);
 

-- 
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