Regression: memory corruption on Atmel SAMA5D31
Peter Rosin
peda at axentia.se
Thu Mar 10 01:58:56 PST 2022
[bringing this threadlet back to the lists, hope that's ok]
On 2022-03-10 09:27, Nicolas Ferre wrote:
> On 09/03/2022 at 12:42, Peter Rosin wrote:
>> On 2022-03-09 11:38, Nicolas Ferre wrote:
>>> Hi Peter,
>>>
*snip*
>>> One of my colleagues had an idea about this issue and in particular with
>>> the fact that removing some of the entries in the structure triggered
>>> the problem: "isn't it some kind of misalignment between structures that
>>> are supposed to be treated in 64 bits machines and our 32 bits core that
>>> we use?"
>>> This misalignment or "wrong assumption" of using 64 bits machine might
>>> be present in the USB stack as it seems to be related to this sub-system
>>> somehow.
>>
>> Yes, something like that has been creeping around in the back of my
>> head too. And it could be something much later in struct device that
>> is no longer sufficiently aligned when struct dev_links_info changes.
>> But what?
I verified the alignment of various things. With the old working
struct dev_links_info, i.e.
struct dev_links_info {
struct list_head suppliers;
struct list_head consumers;
struct list_head needs_suppliers;
struct list_head defer_sync;
bool need_for_probe;
enum dl_dev_state status;
};
I get
sizeof(struct device) 440
sizeof(struct dev_links_info) 40
offsetof(struct device, links) 80
offsetof(struct device, power) 120
"power" is the next member after "struct dev_links_info links" in
struct device, and I find no other uses of struct dev_links_info.
With the new problematic layout, i.e.
struct dev_links_info {
struct list_head suppliers;
struct list_head consumers;
struct list_head defer_sync;
enum dl_dev_state status;
};
I get:
sizeof(struct device) 432
sizeof(struct dev_links_info) 28
offsetof(struct device, links) 80
offsetof(struct device, power) 112
Which means that everything around and within dev_links_info is 8-byte
aligned in the same way in either case. The exception being that
"status" no longer shares 8-byte space with "need_for_probe" (which is
gone). But that should only make things better, no?
That combined with the test with this permuted version (swapped two
list_heads in the middle):
struct dev_links_info {
struct list_head suppliers;
struct list_head consumers;
struct list_head defer_sync;
struct list_head needs_suppliers;
bool need_for_probe;
enum dl_dev_state status;
};
which displayed a new failure mode (BUG instead of corruption, see
upthread) indicates that this is not an alignment issue. Famous last
words...
> From that article:
> https://lwn.net/Articles/885941/
>
> I read:
> "Koschel included a patch fixing a bug in the USB subsystem where the
> iterator passed to this macro was used after the exit from the macro,
> which is a dangerous thing to do. Depending on what happens within the
> list, the contents of that iterator could be something surprising, even
> in the absence of speculative execution. Koschel fixed the problem by
> reworking the code in question to stop using the iterator after the loop. "
>
> USB subsystem, "struct list_head *next, *prev;"... Some keywords present
> there... worth a try?
>
> Regards,
> Nicolas
gr_udc.c is not built with the config that is in use, which is sad because
it looked like a good candidate.
Cheers,
Peter
More information about the linux-arm-kernel
mailing list