On Wed, Feb 02, 2022 at 09:46:21AM +0000, Oleksandr Andrushchenko wrote:
> 
> >>> +        gdprintk(XENLOG_G_DEBUG,
> >>> +                 "%smap [%lx, %lx] -> %#"PRI_gfn" for %pd\n",
> >>> +                 map->map ? "" : "un", s, e, gfn_x(start_gfn),
> >>> +                 map->d);
> >> That's too chatty IMO, I could be fine with printing something along
> >> this lines from modify_bars, but not here because that function can be
> >> preempted and called multiple times.
> > Ok, will move to modify_bars as these prints are really helpful for debug
> I tried to implement the same, but now in init_bars:
> 
> diff --git a/xen/drivers/vpci/header.c b/xen/drivers/vpci/header.c
> index 667c04cee3ae..92407e617609 100644
> --- a/xen/drivers/vpci/header.c
> +++ b/xen/drivers/vpci/header.c
> @@ -57,10 +57,6 @@ static int map_range(unsigned long s, unsigned long e, 
> void *data,
>            */
>           start_gfn = gfn_add(start_gfn, s - mfn_x(start_mfn));
> 
> -        gdprintk(XENLOG_G_DEBUG,
> -                 "%smap [%lx, %lx] -> %#"PRI_gfn" for %pd\n",
> -                 map->map ? "" : "un", s, e, gfn_x(start_gfn),
> -                 map->d);
>           /*
>            * ARM TODOs:
>            * - On ARM whether the memory is prefetchable or not should be 
> passed
> @@ -258,6 +254,28 @@ static void defer_map(struct domain *d, struct pci_dev 
> *pdev,
>       raise_softirq(SCHEDULE_SOFTIRQ);
>   }
> 
> +static int print_range(unsigned long s, unsigned long e, void *data)
> +{
> +    const struct map_data *map = data;
> +
> +    for ( ; ; )
> +    {
> +        gfn_t start_gfn = _gfn(PFN_DOWN(is_hardware_domain(map->d)
> +                                        ? map->bar->addr
> +                                        : map->bar->guest_reg));
> +        mfn_t start_mfn = _mfn(PFN_DOWN(map->bar->addr));
> +
> +        start_gfn = gfn_add(start_gfn, s - mfn_x(start_mfn));
> +
> +        gdprintk(XENLOG_G_DEBUG,
> +                 "%smap [%lx, %lx] -> %#"PRI_gfn" for %pd\n",
> +                 map->map ? "" : "un", s, e, gfn_x(start_gfn),
> +                 map->d);
> +    }

This is an infinite loop AFAICT. Why do you need the for for?

> +
> +    return 0;
> +}
> +
>   static int modify_bars(const struct pci_dev *pdev, uint16_t cmd, bool 
> rom_only)
>   {
>       struct vpci_header *header = &pdev->vpci->header;
> @@ -423,7 +441,25 @@ static int modify_bars(const struct pci_dev *pdev, 
> uint16_t cmd, bool rom_only)
>       if ( !map_pending )
>           pci_conf_write16(pdev->sbdf, PCI_COMMAND, cmd);
>       else
> +    {
> +        struct map_data data = {
> +            .d = pdev->domain,
> +            .map = cmd & PCI_COMMAND_MEMORY,
> +        };
> +
> +        for ( i = 0; i < ARRAY_SIZE(header->bars); i++ )
> +        {
> +            const struct vpci_bar *bar = &header->bars[i];
> +
> +            if ( rangeset_is_empty(bar->mem) )
> +                continue;
> +
> +            data.bar = bar;
> +            rc = rangeset_report_ranges(bar->mem, 0, ~0ul, print_range, 
> &data);

Since this is per-BAR we should also print that information and the
SBDF of the device, ie:

%pd SBDF: (ROM)BAR%u %map [%lx, %lx] -> ...

> +        }
> +
>           defer_map(dev->domain, dev, cmd, rom_only);
> +    }
> 
>       return 0;
> 
> 
> To me, to implement a single DEBUG print, it is a bit an overkill.
> I do understand your concerns that "that function can be
> preempted and called multiple times", but taking look at the code
> above I think we can accept that for DEBUG builds.

It might be better if you print the per BAR positions at the top of
modify_bars, where each BAR is added to the rangeset? Or do you care
about reporting the holes also?

Thanks, Roger.

Reply via email to