|
[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |