Fall back to INTx in case an ivshmem device comes without MSI-X vectors. This is now implemented for ARM, using standard PCI pin rotation based on the device slot.
x86 has no need for INTx as MSI-X is always supported (plus there is a less uniform legacy INTx injection path which prevents a generic solution). Signed-off-by: Jan Kiszka <[email protected]> --- hypervisor/arch/arm-common/ivshmem.c | 8 ++++++++ hypervisor/ivshmem.c | 11 ++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/hypervisor/arch/arm-common/ivshmem.c b/hypervisor/arch/arm-common/ivshmem.c index d484bbd..5e010b3 100644 --- a/hypervisor/arch/arm-common/ivshmem.c +++ b/hypervisor/arch/arm-common/ivshmem.c @@ -31,6 +31,9 @@ int arch_ivshmem_update_msix(struct pci_device *device) struct ivshmem_endpoint *ive = device->ivshmem_endpoint; unsigned int irq_id = 0; + if (device->info->num_msix_vectors == 0) + return 0; + if (!ivshmem_is_msix_masked(ive)) { /* FIXME: validate MSI-X target address */ irq_id = device->msix_vectors[0].data; @@ -45,4 +48,9 @@ int arch_ivshmem_update_msix(struct pci_device *device) void arch_ivshmem_init(struct ivshmem_endpoint *ive, struct cell *cell) { + if (ive->device->info->num_msix_vectors == 0) { + u8 pin = ive->cspace[PCI_CFG_INT/4] >> 8; + + ive->arch.irq_id = 32 + cell->config->vpci_irq_base + pin - 1; + } } diff --git a/hypervisor/ivshmem.c b/hypervisor/ivshmem.c index 6f50b96..d282f2e 100644 --- a/hypervisor/ivshmem.c +++ b/hypervisor/ivshmem.c @@ -267,6 +267,14 @@ static void ivshmem_connect_cell(struct ivshmem_data *iv, struct cell *cell, 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; @@ -366,9 +374,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); -- 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.
