Re: framebuffer corruption due to overlapping stp instructions on arm64

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

 



(- libc-alpha)

On 3 August 2018 at 19:09, Mikulas Patocka <mpatocka@xxxxxxxxxx> wrote:
>
>
> On Fri, 3 Aug 2018, Will Deacon wrote:
>
>> On Fri, Aug 03, 2018 at 09:16:39AM +0200, Ard Biesheuvel wrote:
>> > On 3 August 2018 at 08:35, Mikulas Patocka <mpatocka@xxxxxxxxxx> wrote:
>> > >
>> > >
>> > > On Thu, 2 Aug 2018, Matt Sealey wrote:
>> > >
>> > >> The easiest explanation for this would be that the memory isn?t mapped
>> > >> correctly. You can?t use PCIe memory spaces with anything other than
>> > >> Device-nGnRE or stricter mappings. That?s just differences between the
>> > >> AMBA and PCIe (posted/unposted) memory models.
>> >
>> > Whoa hold on there.
>> >
>> > Are you saying we cannot have PCIe BAR windows with memory semantics on ARM?
>> >
>> > Most accelerated graphics drivers rely heavily on the ability to map
>> > the VRAM normal-non-cacheable (ioremap_wc, basically), and treat it as
>> > ordinary memory.
>>
>> Yeah, I'd expect framebuffers to be mapped as normal NC. That should be
>> fine for prefetchable BARs, no?
>>
>> Will
>
> So - why does it corrupt data then? I've created this program that
> reproduces the data corruption quicky. If I run it on /dev/fb0, I get an
> instant failure. Sometimes a few bytes are not written, sometimes a few
> bytes are written with a value that should be 16 bytes apart.
>

Are we still talking about overlapping unaligned accesses here? Or do
you see other failures as well?

> I tried to run it on system RAM mapped with the NC attribute and I didn't
> get any corruption - that suggests the the bug may be in the PCIE
> subsystem.
>
> Jingoo Han and Joao Pinto are maintainers for the designware PCIE
> controllers. Could you suggest why does the controller corrupt data when
> writing to videoram? Are there any tricks that could be tried to work
> around the corruption?
>
> Mikulas
>
>
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> #include <fcntl.h>
> #include <unistd.h>
> #include <sys/mman.h>
>
> #define LEN             256
> #define PRINT_STRIDE    0x20
>
> static unsigned char data[LEN];
> static unsigned char val = 0;
>
> static unsigned char prev_data[LEN];
>
> static unsigned char map_copy[LEN];
>
> int main(int argc, char *argv[])
> {
>         unsigned long n = 0;
>         int h;
>         unsigned char *map;
>         unsigned start, end, i;
>
>         if (argc < 2) fprintf(stderr, "argc\n"), exit(1);
>         if (argc >= 4) srandom(atoll(argv[3]));
>         h = open(argv[1], O_RDWR | O_DSYNC);
>         if (h == -1) perror("open"), exit(1);
>         map = mmap(NULL, LEN, PROT_READ | PROT_WRITE, MAP_SHARED, h, argc >= 3 ? strtoull(argv[2], NULL, 16) : 0);
>         if (map == MAP_FAILED) perror("mmap"), exit(1);
>
>         memset(data, 0, LEN);
>         memset(prev_data, 0, LEN);
>         memset(map, 0, LEN);
>
>         sleep(1);
>
>         while (1) {
>                 start = (unsigned)random() % (LEN + 1);
>                 end = (unsigned)random() % (LEN + 1);
>                 if (start > end)
>                         continue;
>                 for (i = start; i < end; i++)
>                         data[i] = val++;
>                 memcpy(map + start, data + start, end - start);
>                 if (memcmp(map, data, LEN)) {
>                         unsigned j;
>                         memcpy(map_copy, map, LEN);
>                         fprintf(stderr, "mismatch after %lu loops!\n", n);
>                         fprintf(stderr, "last copied range: 0x%x - 0x%x (0x%x)\n", start, end, (unsigned)(end - start));
>                         for (j = 0; j < LEN; j += PRINT_STRIDE) {
>                                 fprintf(stderr, "p[%03x]", j);
>                                 for (i = j; i < j + PRINT_STRIDE && i < LEN; i++)
>                                         fprintf(stderr, " %s%s%02x\e[0m", !(i % 4) ? " " : "", data[i] != map_copy[i] ? "\e[31m" : "", prev_data[i]);
>                                 fprintf(stderr, "\n");
>                                 fprintf(stderr, "d[%03x]", j);
>                                 for (i = j; i < j + PRINT_STRIDE && i < LEN; i++)
>                                         fprintf(stderr, " %s%s%02x\e[0m", !(i % 4) ? " " : "", data[i] != map_copy[i] ? "\e[31m" : "", data[i]);
>                                 fprintf(stderr, "\n");
>                                 fprintf(stderr, "m[%03x]", j);
>                                 for (i = j; i < j + PRINT_STRIDE && i < LEN; i++)
>                                         fprintf(stderr, " %s%s%02x\e[0m", !(i % 4) ? " " : "", data[i] != map_copy[i] ? "\e[31m" : "", map_copy[i]);
>                                 fprintf(stderr, "\n\n");
>                         }
>                         exit(1);
>                 }
>                 memcpy(prev_data, data, LEN);
>                 n++;
>         }
> }



[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux