#include #include #include #include #include #include #include #include #define PAGE_SIZE 4096 int main(int argc, char **argv) { int fd, err; int towrite = PAGE_SIZE; char *p; volatile char *map1, *map2; unsigned char b[4]; fd = open (argc>2?argv[1]:"/tmp/testfile", O_CREAT|O_TRUNC|O_RDWR, 0644); if (!fd<0) { perror("open"); close(fd); return 1; } p = malloc(PAGE_SIZE); if (!p) { fprintf(stderr, "malloc failed\n"); return 2; } memset(p, 0, PAGE_SIZE); while(towrite) { err = write(fd, p, PAGE_SIZE); if (err < 0) { perror("write"); close(fd); return 3; } towrite -= err; } map1 = mmap(0, PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (!map1) { perror("mmap 1"); close(fd); return 4; } /* Make sure the second mapping is _immediately_ after the first */ map2 = mmap((void *)map1+PAGE_SIZE, PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, 0); if (!map2) { perror("mmap 2"); munmap((void *)map1, PAGE_SIZE); close(fd); return 5; } printf("Mapped page twice, at 0x%08lx and 0x%08lx\n", (unsigned long)map1, (unsigned long) map2); /* Some arches (ARM) allocate cache lines only on read */ (void)map1[0]; (void)map2[0]; map1[0] = 0x55; map2[1] = 0xaa; map1[2] = 0xa5; map2[3] = 0x5a; b[0] = map2[0]; b[1] = map1[1]; b[2] = map2[2]; b[3] = map1[3]; if (b[0] != 0x55 || b[1] != 0xaa || b[2] != 0xa5 || b[3] != 0x5a) { printf("Your cache is broken\n"); return 6; } else { printf("Your cache appears to be OK\n"); } munmap((void *)map1, PAGE_SIZE); munmap((void *)map2, PAGE_SIZE); close(fd); }