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.
