[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH v11 3/3] iommu: add rmrr Xen command line option for extra rmrrs



On Mon, Oct 26, 2015 at 07:38:06AM -0600, Jan Beulich wrote:
> >>> On 22.10.15 at 19:13, <elena.ufimtseva@xxxxxxxxxx> wrote:
> > From: Elena Ufimtseva <elena.ufimtseva@xxxxxxxxxx>
> > 
> > On some platforms RMRR regions may be not specified in ACPI and thus will 
> > not
> > be mapped 1:1 in dom0.
>

Thanks Jan for review.

> I think this may be misleading to readers: It sounds as if there was
> the option for RMRRs to not be specified in ACPI tables, while in
> fact this is a firmware bug. How about "On some platforms firmware
> fails to specify RMRR regions may in ACPI tables, and thus those
> regions will not be mapped in dom0 or guests the respective device(s)
> get passed through to"?
>
Agree, makes more sense.

> > +static void __init add_extra_rmrr(void)
> > +{
> > +    struct acpi_rmrr_unit *acpi_rmrr;
> > +    struct acpi_rmrr_unit *rmrru;
> > +    unsigned int dev, seg, i;
> > +    unsigned long pfn;
> > +    bool_t overlap;
> > +
> > +    for ( i = 0; i < nr_rmrr; i++ )
> > +    {
> > +        if ( extra_rmrr_units[i].base_pfn > extra_rmrr_units[i].end_pfn )
> > +        {
> > +            printk(XENLOG_ERR VTDPREFIX
> > +                   "Invalid RMRR Range "ERMRRU_FMT"\n",
> > +                   ERMRRU_ARG(extra_rmrr_units[i]));
> > +            continue;
> > +        }
> > +
> > +        if ( extra_rmrr_units[i].end_pfn - extra_rmrr_units[i].base_pfn >=
> > +             MAX_EXTRA_RMRR_PAGES )
> > +        {
> > +            printk(XENLOG_ERR VTDPREFIX
> > +                   "RMRR range "ERMRRU_FMT" exceeds 
> > "__stringify(MAX_EXTRA_RMRR_PAGES)" pages\n",
> > +                   ERMRRU_ARG(extra_rmrr_units[i]));
> > +            continue;
> > +        }
> > +
> > +        overlap = 0;
> > +        list_for_each_entry(rmrru, &acpi_rmrr_units, list)
> > +        {
> > +            if ( pfn_to_paddr(extra_rmrr_units[i].base_pfn ) < 
> > rmrru->end_address &&
> 
> Stray blank inside the inner parentheses.
> 
> > +                 rmrru->base_address < 
> > pfn_to_paddr(extra_rmrr_units[i].end_pfn + 1) )
> > +            {
> > +                printk(XENLOG_ERR VTDPREFIX
> > +                       "Overlapping RMRRs: "ERMRRU_FMT" and [%lx - %lx]\n",
> 
> ERMRRU_FMT doesn't have any blanks inside the square brackets,
> so I'd suggest the other format to nt have them either.
> 
> > +                       ERMRRU_ARG(extra_rmrr_units[i]),
> > +                       paddr_to_pfn(rmrru->base_address),
> > +                       paddr_to_pfn(rmrru->end_address));
> > +                overlap = 1;
> > +                break;
> > +            }
> > +        }
> > +        /* Dont add overlapping RMRR */
> 
> "Don't" and missing full stop.
> 
> > +        if ( overlap )
> > +            continue;
> > +
> > +        pfn = extra_rmrr_units[i].base_pfn;
> > +        do
> > +        {
> > +            if ( !mfn_valid(pfn) || (pfn >> (paddr_bits - PAGE_SHIFT)) )
> 
> Actually I think the right side is redundant with the max_pfn check
> mfn_valid() does.
> 
> > +            {
> > +                printk(XENLOG_ERR VTDPREFIX
> > +                       "Invalid pfn in RMRR range "ERMRRU_FMT"\n",
> > +                       ERMRRU_ARG(extra_rmrr_units[i]));
> > +            break;
> 
> Wrong indentation.
> 
> > +            }
> > +
> > +        } while ( pfn++ < extra_rmrr_units[i].end_pfn );
> 
> Stray blank line before the end of the do/while body.
> 
> > +
> > +        /* Invalid pfn in range as the loop ended before end_pfn was 
> > reached. */
> > +        if ( pfn <= extra_rmrr_units[i].end_pfn )
> > +            continue;
> > +
> > +        acpi_rmrr = xzalloc(struct acpi_rmrr_unit);
> > +        if ( !acpi_rmrr )
> > +            return;
> > +
> > +        acpi_rmrr->scope.devices = xmalloc_array(u16,
> > +                                                 
> > extra_rmrr_units[i].dev_count);
> > +        if ( !acpi_rmrr->scope.devices )
> > +        {
> > +            xfree(acpi_rmrr);
> > +            return;
> > +        }
> > +
> > +        seg = 0;
> > +        for ( dev = 0; dev < extra_rmrr_units[i].dev_count; dev++ )
> > +        {
> > +            acpi_rmrr->scope.devices[dev] = extra_rmrr_units[i].sbdf[dev];
> > +            seg = seg | PCI_SEG(extra_rmrr_units[i].sbdf[dev]);
> 
> |=
> 
> > +static void __init parse_rmrr_param(const char *str)
> > +{
> > +    const char *s = str, *cur, *stmp;
> > +    unsigned int seg, bus, dev, func;
> > +    unsigned long start, end;
> > +
> > +    do {
> > +        start = simple_strtoul(cur = s, &s, 0);
> > +        if ( cur == s )
> > +            break;
> > +
> > +        if ( *s == '-' )
> > +        {
> > +            end = simple_strtoul(cur = s + 1, &s, 0);
> > +            if ( cur == s )
> > +                break;
> > +        }
> > +        else
> > +            end = start;
> > +
> > +        extra_rmrr_units[nr_rmrr].base_pfn = start;
> > +        extra_rmrr_units[nr_rmrr].end_pfn = end;
> > +        extra_rmrr_units[nr_rmrr].dev_count = 0;
> 
> The last assignment isn't really needed.
> 
> > +        if ( *s != '=' )
> > +            continue;
> > +
> > +        do {
> > +            bool_t default_segment = 0;
> > +
> > +            if ( *s == ';' )
> > +                break;
> 
> Can this if() ever be true? *s == '=' on the first iteration, and *s == ','
> on any subsequent one afaics.
Right, thats from the old format parsing code I think.
> 
> > +            stmp = __parse_pci(s + 1, &seg, &bus, &dev, &func, 
> > &default_segment);
> > +            if ( !stmp )
> > +                break;
> > +
> > +            /* Not specified segment will be replaced with one from first 
> > device. */
> > +            if ( extra_rmrr_units[nr_rmrr].dev_count && default_segment )
> > +                seg = PCI_SEG(extra_rmrr_units[nr_rmrr].sbdf[0]);
> > +
> > +            /* Keep sbdf's even if they differ and later report an error. 
> > */
> > +            
> > extra_rmrr_units[nr_rmrr].sbdf[extra_rmrr_units[nr_rmrr].dev_count]         
> >                                     = PCI_SBDF(seg, bus, dev, func);
> 
> This line for sure is too long.

Ok, will send with fixes!
Thank you.

Elena
> 
> Jan

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.