Beispiel #1
0
int main(int argc, char *argv[])
{
	long hpage_size;
	int fd;
	void *p;
	volatile unsigned long *q;
	int err;
	cpu_set_t cpu0, cpu1;

	test_init(argc, argv);

	hpage_size = check_hugepagesize();

	fd = hugetlbfs_unlinked_fd();
	if (fd < 0)
		FAIL("hugetlbfs_unlinked_fd()");

	CPU_ZERO(&cpu0);
	CPU_SET(0, &cpu0);
	CPU_ZERO(&cpu1);
	CPU_SET(1, &cpu1);

	err = sched_setaffinity(getpid(), CPU_SETSIZE/8, &cpu0);
	if (err != 0)
		CONFIG("sched_setaffinity(cpu0): %s", strerror(errno));

	err = sched_setaffinity(getpid(), CPU_SETSIZE/8, &cpu1);
	if (err != 0)
		CONFIG("sched_setaffinity(): %s", strerror(errno));

	p = mmap(NULL, hpage_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
	if (p == MAP_FAILED)
		FAIL("mmap()");

	err = sched_setaffinity(getpid(), CPU_SETSIZE/8, &cpu0);
	if (err != 0)
		CONFIG("sched_setaffinity(cpu0): %s", strerror(errno));

	q = (volatile unsigned long *)(p + getpagesize());
	*q = 0xdeadbeef;

	PASS_INCONCLUSIVE();
}
int main(int argc, char *argv[])
{
	int page_size;
	long hpage_size;
	off_t buggy_offset;
	int fd;
	void *p, *q;
	volatile int *pi;
	int err;

	test_init(argc, argv);

	page_size = getpagesize();
	hpage_size = check_hugepagesize();

	fd = hugetlbfs_unlinked_fd();
	if (fd < 0)
		FAIL("hugetlbfs_unlinked_fd()");

	/* First, we make a 2 page sane hugepage mapping.  Then we
	 * memset() it to ensure that the ptes are instantiated for
	 * it.  Then we attempt to replace the second half of the map
	 * with one at a bogus offset.  We leave the first page of
	 * sane mapping in place to ensure that the corresponding
	 * pud/pmd/whatever entries aren't cleaned away.  It's those
	 * bad entries which can trigger bad_pud() checks if the
	 * backout path for the bogus mapping is buggy, which it was
	 * in some kernels. */

	verbose_printf("Free hugepages: %lu\n",
		get_huge_page_counter(hpage_size, HUGEPAGES_FREE));

	verbose_printf("Mapping reference map...");
	/* First get arena of three hpages size, at file offset 4GB */
	p = mmap(NULL, 2*hpage_size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
	if (p == MAP_FAILED)
		FAIL("mmap() offset 4GB: %s", strerror(errno));
	verbose_printf("%p-%p\n", p, p+2*hpage_size-1);

	verbose_printf("Free hugepages: %lu\n",
		get_huge_page_counter(hpage_size, HUGEPAGES_FREE));

	/* Instantiate the pages */
	verbose_printf("Instantiating...");
	memset(p, 0, 2*hpage_size);
	pi = p;
	*pi = RANDOM_CONSTANT;
	verbose_printf("done.\n");

	verbose_printf("Free hugepages: %lu\n",
		get_huge_page_counter(hpage_size, HUGEPAGES_FREE));

	/* Toggle the permissions on the first page.  This forces TLB
	 * entries (including hash page table on powerpc) to be
	 * flushed, so that the page tables must be accessed for the
	 * test further down.  In the buggy case, those page tables
	 * can get thrown away by a pud_clear() */
	err = mprotect(p, hpage_size, PROT_READ);
	if (err)
		FAIL("mprotect(%p, 0x%lx, PROT_READ): %s", p, hpage_size,
							strerror(errno));

	/* Replace top hpage by hpage mapping at confusing file offset */
	buggy_offset = page_size;
	verbose_printf("Replacing map at %p with map from offset 0x%lx...",
		       p + hpage_size, (unsigned long)buggy_offset);
	q = mmap(p + hpage_size, hpage_size, PROT_READ|PROT_WRITE,
		 MAP_FIXED|MAP_PRIVATE, fd, buggy_offset);
	if (q != MAP_FAILED)
		FAIL("bogus offset mmap() succeeded at %p: %s", q, strerror(errno));
	if (errno != EINVAL)
		FAIL("bogus mmap() failed with \"%s\" instead of \"%s\"",
		     strerror(errno), strerror(EINVAL));
	verbose_printf("%s\n", strerror(errno));

	verbose_printf("Free hugepages: %lu\n",
		get_huge_page_counter(hpage_size, HUGEPAGES_FREE));

	if (*pi != RANDOM_CONSTANT)
		FAIL("Pre-existing mapping clobbered: %x instead of %x",
		     *pi, RANDOM_CONSTANT);

	verbose_printf("Free hugepages: %lu\n",
		get_huge_page_counter(hpage_size, HUGEPAGES_FREE));

	/* The real test is whether we got a bad_pud() or similar
	 * during the run.  The check above, combined with the earlier
	 * mprotect()s to flush the TLB are supposed to catch it, but
	 * it's hard to be certain.  Once bad_pud() is called
	 * behaviour can be very strange. */
	PASS_INCONCLUSIVE();
}
int main(int argc, char *argv[])
{
	long hpage_size;
	int fd;
	void *p;
	unsigned long straddle_addr;

	test_init(argc, argv);

	hpage_size = check_hugepagesize();

	if (sizeof(void *) <= 4)
		TEST_BUG("64-bit only");

	if (hpage_size > FOURGB)
		CONFIG("Huge page size too large");

	fd = hugetlbfs_unlinked_fd();
	if (fd < 0)
		FAIL("hugetlbfs_unlinked_fd()");

	straddle_addr = FOURGB - hpage_size;

	/* We first try to get the mapping without MAP_FIXED */
	verbose_printf("Mapping without MAP_FIXED at %lx...", straddle_addr);
	p = mmap((void *)straddle_addr, 2*hpage_size, PROT_READ|PROT_WRITE,
		 MAP_SHARED, fd, 0);
	if (p == (void *)straddle_addr) {
		/* These tests irrelevant if we didn't get the
		 * straddle address */
		verbose_printf("done\n");

		if (test_addr_huge(p) != 1)
			FAIL("Mapped address is not hugepage");

		if (test_addr_huge(p + hpage_size) != 1)
			FAIL("Mapped address is not hugepage");

		verbose_printf("Clearing below 4GB...");
		memset(p, 0, hpage_size);
		verbose_printf("done\n");

		verbose_printf("Clearing above 4GB...");
		memset(p + hpage_size, 0, hpage_size);
		verbose_printf("done\n");
	} else {
		verbose_printf("got %p instead, never mind\n", p);
		munmap(p, 2*hpage_size);
	}

	verbose_printf("Mapping with MAP_FIXED at %lx...", straddle_addr);
	p = mmap((void *)straddle_addr, 2*hpage_size, PROT_READ|PROT_WRITE,
		 MAP_SHARED|MAP_FIXED, fd, 0);
	if (p == MAP_FAILED) {
		/* this area crosses last low slice and first high slice */
		unsigned long below_start = FOURGB - 256L*1024*1024;
		unsigned long above_end = 1024L*1024*1024*1024;
		if (range_is_mapped(below_start, above_end) == 1) {
			verbose_printf("region (4G-256M)-1T is not free\n");
			verbose_printf("mmap() failed: %s\n", strerror(errno));
			PASS_INCONCLUSIVE();
		} else
			FAIL("mmap() FIXED failed: %s\n", strerror(errno));
	}
	if (p != (void *)straddle_addr) {
		verbose_printf("got %p instead\n", p);
		FAIL("Wrong address with MAP_FIXED");
	}
	verbose_printf("done\n");

	if (test_addr_huge(p) != 1)
		FAIL("Mapped address is not hugepage");

	if (test_addr_huge(p + hpage_size) != 1)
		FAIL("Mapped address is not hugepage");

	verbose_printf("Clearing below 4GB...");
	memset(p, 0, hpage_size);
	verbose_printf("done\n");

	verbose_printf("Clearing above 4GB...");
	memset(p + hpage_size, 0, hpage_size);
	verbose_printf("done\n");

	verbose_printf("Tested above 4GB\n");

	PASS();
}