On 2016-11-24 10:21, Jan Kiszka wrote:
> 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);
>  
> 

Just realized that this lacks an important feature for cells that only
want to poll: A control switch to turn off the INTx line, just like
there is for MSI-X (via the standardized interface). INTx should be
opt-in, so the bit in the config space register isn't enough.

We need to introduce what ivshmem has (had in rev 0) for its INTx
support. Updates will follow.

Jan

-- 
Siemens AG, Corporate Technology, CT RDA ITP SES-DE
Corporate Competence Center Embedded Linux

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