Re: [PATCH v2] ACPI/IORT: Fix 'Number of IDs' handling in iort_id_map()

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

 



On Fri, May 01, 2020 at 11:02:48AM +0200, Ard Biesheuvel wrote:
> On Fri, 1 May 2020 at 10:54, Lorenzo Pieralisi
> <lorenzo.pieralisi@xxxxxxx> wrote:
> >
> > On Fri, May 01, 2020 at 10:30:11AM +0200, Ard Biesheuvel wrote:
> > > On Fri, 17 Jan 2020 at 13:32, Lorenzo Pieralisi
> > > <lorenzo.pieralisi@xxxxxxx> wrote:
> > > >
> > > > On Fri, Jan 17, 2020 at 12:14:49PM +0000, Will Deacon wrote:
> > > > > On Tue, Jan 14, 2020 at 08:14:11PM +0800, Hanjun Guo wrote:
> > > > > > The IORT specification [0] (Section 3, table 4, page 9) defines the
> > > > > > 'Number of IDs' as 'The number of IDs in the range minus one'.
> > > > > >
> > > > > > However, the IORT ID mapping function iort_id_map() treats the 'Number
> > > > > > of IDs' field as if it were the full IDs mapping count, with the
> > > > > > following check in place to detect out of boundary input IDs:
> > > > > >
> > > > > > InputID >= Input base + Number of IDs
> > > > > >
> > > > > > This check is flawed in that it considers the 'Number of IDs' field as
> > > > > > the full number of IDs mapping and disregards the 'minus one' from
> > > > > > the IDs count.
> > > > > >
> > > > > > The correct check in iort_id_map() should be implemented as:
> > > > > >
> > > > > > InputID > Input base + Number of IDs
> > > > > >
> > > > > > this implements the specification correctly but unfortunately it breaks
> > > > > > existing firmwares that erroneously set the 'Number of IDs' as the full
> > > > > > IDs mapping count rather than IDs mapping count minus one.
> > > > > >
> > > > > > e.g.
> > > > > >
> > > > > > PCI hostbridge mapping entry 1:
> > > > > > Input base:  0x1000
> > > > > > ID Count:    0x100
> > > > > > Output base: 0x1000
> > > > > > Output reference: 0xC4  //ITS reference
> > > > > >
> > > > > > PCI hostbridge mapping entry 2:
> > > > > > Input base:  0x1100
> > > > > > ID Count:    0x100
> > > > > > Output base: 0x2000
> > > > > > Output reference: 0xD4  //ITS reference
> > > > > >
> > > > > > Two mapping entries which the second entry's Input base = the first
> > > > > > entry's Input base + ID count, so for InputID 0x1100 and with the
> > > > > > correct InputID check in place in iort_id_map() the kernel would map
> > > > > > the InputID to ITS 0xC4 not 0xD4 as it would be expected.
> > > > > >
> > > > > > Therefore, to keep supporting existing flawed firmwares, introduce a
> > > > > > workaround that instructs the kernel to use the old InputID range check
> > > > > > logic in iort_id_map(), so that we can support both firmwares written
> > > > > > with the flawed 'Number of IDs' logic and the correct one as defined in
> > > > > > the specifications.

[...]

> > > I just ran into this while playing with the LX2160 I received this week.
> >
> > Side note: that firmware must be updatable or there is something I am
> > missing in relation to the ongoing ITS/SMMU mapping discussions.
> >
> 
> Sure. But they are following the spec, and they use num_ids = 0x0 for
> regions consisting of a single mapping. This is completely broken
> without this patch.

Yes sure - I thought you were saying that the FW has issues with
the *current* kernel whereas you are asking if this fix can be
rewritten to remove the quirking mechanism - that's always a good
aim :)

> > > I wonder if it would be better to detect the failure case dynamically,
> > > rather than having these hardcoded quirks. It should be rather
> > > straightforward to detect overlaps at the edges of these multi-range
> > > mappings, in which case we could just let the spurious one (living at
> > > the end of the region) be superseded by the correct one (living at the
> > > start of the next region).
> >
> > This could be done I think but probably requires some boot time parsing
> > to create some structure defining ranges (to avoid running the logic you
> > describe above every time a device has to be mapped).
> >
> 
> It could be done much simpler than that: if iort_id_map() matches on
> the last value of a region with size > 1 (so num_ids > 0), we return
> the mapping but don't exit the loop. If we match it again, we use that
> value, otherwise we use the tentative value from the first iteration.

We need to see how the code will look like in both cases, again, I am
not a priori against implementing it.

Instead of relying on ranges, we can precompute structures to define
for a device which mapping+mapping_index should be ignored, this
will save us from doing it dynamically (still require some additional
data).

> > Given that I have not heard of any regressions on the existing crop
> > of platforms and the one you mentioned has FW that is not set in stone
> > I think we can live with the quirk mechanism for the time being,
> > what do you think ?
> >
> 
> The more quirks we keep, the harder it becomes to push back on new ones.
> 
> So if we can fix this cleanly, I'd much prefer it.

I agree with that, more so given that this is not impossible to rewrite
more cleanly.

Thanks,
Lorenzo



[Index of Archives]     [Linux IBM ACPI]     [Linux Power Management]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux