On 29/04/2022 14:05, Jan Beulich wrote:
> [CAUTION - EXTERNAL EMAIL] DO NOT reply, click links, or open attachments 
> unless you have verified the sender and know the content is safe.
>
> IOMMU code mapping / unmapping devices and interrupts will misbehave if
> a wrong command line option declared a function "phantom" when there's a
> real device at that position. Warn about this and adjust the specified
> stride (in the worst case ignoring the option altogether).
>
> Requested-by: Andrew Cooper <[email protected]>
> Signed-off-by: Jan Beulich <[email protected]>
>
> --- a/xen/drivers/passthrough/pci.c
> +++ b/xen/drivers/passthrough/pci.c
> @@ -451,7 +451,24 @@ static struct pci_dev *alloc_pdev(struct
>                           phantom_devs[i].slot == PCI_SLOT(devfn) &&
>                           phantom_devs[i].stride > PCI_FUNC(devfn) )
>                      {
> -                        pdev->phantom_stride = phantom_devs[i].stride;
> +                        pci_sbdf_t sbdf = pdev->sbdf;
> +                        unsigned int stride = phantom_devs[i].stride;
> +
> +                        while ( (sbdf.fn += stride) > PCI_FUNC(devfn) )

I'm fairly sure this doesn't do what you want it to.

.fn is a 3 bit bitfield, meaning the += will be truncated before the
compare.

> +                        {
> +                            if ( pci_conf_read16(sbdf, PCI_VENDOR_ID) == 
> 0xffff &&
> +                                 pci_conf_read16(sbdf, PCI_DEVICE_ID) == 
> 0xffff )
> +                                continue;
> +                            stride <<= 1;
> +                            printk(XENLOG_WARNING
> +                                   "%pp looks to be a real device; bumping 
> %04x:%02x:%02x stride to %u\n",
> +                                   &sbdf, phantom_devs[i].seg,
> +                                   phantom_devs[i].bus, phantom_devs[i].slot,
> +                                   stride);
> +                            sbdf = pdev->sbdf;
> +                        }
> +                        if ( PCI_FUNC(stride) )

This is an obfuscated way of writing stride < 8.

Given the printk(), if we actually find an 8-function device, what gets
printed (AFAICT) will be "bumping to 8" when in fact we mean "totally
ignoring the option".  I think this really wants an else clause.

~Andrew

Reply via email to