Exemplo n.º 1
0
void anonymous_hugepage(char *name, int flags)
{
	char buf[100];
	char *p = alloc_anonymous_hugepage(HPS, 1);
	printf("anonymous hugepage\n");
	*(volatile int *)p = 1;
	offline(ndesc(buf, "anonymous hugepage", name), p);
	*(volatile int *)p = 1;
	free_anonymous_hugepage(p, HPS);
}
Exemplo n.º 2
0
int main(int argc, char *argv[])
{
	int PS = getpagesize();
	int nr_hugepages;
	void *addr;
	int ret;

	nr_hugepages = strtol(argv[1], NULL, 10);
	addr = alloc_anonymous_hugepage(nr_hugepages * HPAGE_SIZE, 0);
	write_hugepage(addr, nr_hugepages, NULL);
	ret = madvise(addr, PS, MADV_SOFT_OFFLINE);
	free_anonymous_hugepage(addr, nr_hugepages * HPAGE_SIZE);
	return ret;
}
Exemplo n.º 3
0
int main(int argc, char *argv[])
{
	void *addr;
	int i;
	int ret;
	int fd = 0;
	int semid;
	int semaphore;
	int inject = 0;
	int madvise_code = MADV_HWPOISON;
	int early_kill = 0;
	int avoid_touch = 0;
	int anonflag = 0;
	int shmflag = 0;
	int shmkey = 0;
	int forkflag = 0;
	int privateflag = 0;
	int cowflag = 0;
	char c;
	pid_t pid = 0;
	void *expected_addr = NULL;
	struct sembuf sembuffer;

	PS = getpagesize();
	HPS = HPAGE_SIZE;
	file_size = 1;
	corrupt_page = -1;

	if (argc == 1) {
		usage();
		exit(EXIT_FAILURE);
	}

	while ((c = getopt_long(argc, argv,
				"m:o:xOeSAaFpcf:h", opts, NULL)) != -1) {
		switch (c) {
		case 'm':
			file_size = strtol(optarg, NULL, 10);
			break;
		case 'o':
			corrupt_page = strtol(optarg, NULL, 10);
			break;
		case 'x':
			inject = 1;
			break;
		case 'O':
			madvise_code = MADV_SOFT_OFFLINE;
			break;
		case 'e':
			early_kill = 1;
			break;
		case 'S':
			shmflag = 1;
			break;
		case 'A':
			anonflag = 1;
			break;
		case 'a':
			avoid_touch = 1;
			break;
		case 'F':
			forkflag = 1;
			break;
		case 'p':
			privateflag = 1;
			break;
		case 'c':
			cowflag = 1;
			break;
		case 'f':
			strcat(filename, optarg);
			shmkey = strtol(optarg, NULL, 10);
			break;
		case 'h':
			usage();
			exit(EXIT_SUCCESS);
		default:
			usage();
			exit(EXIT_FAILURE);
		}
	}

	if (inject && corrupt_page * PS > file_size * HPAGE_SIZE)
		errmsg("Target page is out of range.\n");

	if (avoid_touch && corrupt_page == -1)
		errmsg("Avoid which page?\n");

	/* Construct file name */
	if (access(argv[argc - 1], F_OK) == -1) {
		usage();
		exit(EXIT_FAILURE);
	} else {
		strcpy(filepath, argv[argc - 1]);
		strcat(filepath, filename);
	}

	if (shmflag) {
		addr = alloc_shm_hugepage(&shmkey, file_size * HPAGE_SIZE);
		if (!addr)
			errmsg("Failed in alloc_shm_hugepage()");
	} else if (anonflag) {
		addr = alloc_anonymous_hugepage(file_size * HPAGE_SIZE,
						privateflag);
		if (!addr)
			errmsg("Failed in alloc_anonymous_hugepage()");
	} else {
		addr = alloc_filebacked_hugepage(filepath,
						 file_size * HPAGE_SIZE,
						 privateflag, &fd);
		if (!addr)
			errmsg("Failed in alloc_filebacked_hugepage()");
	}

	if (corrupt_page != -1 && avoid_touch)
		expected_addr = (void *)(addr + corrupt_page / 512 * HPAGE_SIZE);

	if (forkflag) {
		semid = semget(IPC_PRIVATE, 1, 0666|IPC_CREAT);
		if (semid == -1) {
			perror("semget");
			goto cleanout;
		}
		semaphore = semctl(semid, 0, SETVAL, 1);
		if (semaphore == -1) {
			perror("semctl");
			goto cleanout;
		}
		if (get_semaphore(semid, &sembuffer)) {
			perror("get_semaphore");
			goto cleanout;
		}
	}

	write_hugepage(addr, file_size, 0);
	read_hugepage(addr, file_size, 0);

	if (early_kill)
		prctl(PR_MCE_KILL, PR_MCE_KILL_SET, PR_MCE_KILL_EARLY,
		      NULL, NULL);

	/*
	 * Intended order:
	 *   1. Child COWs
	 *   2. Parent madvise()s
	 *   3. Child exit()s
	 */
	if (forkflag) {
		pid = fork();
		if (!pid) {
			/* Semaphore is already held */
			if (cowflag) {
				write_hugepage(addr, file_size, 0);
				read_hugepage(addr, file_size, 0);
			}
			if (put_semaphore(semid, &sembuffer))
				err("put_semaphore");
			usleep(1000);
			/* Wait for madvise() to be done */
			if (get_semaphore(semid, &sembuffer))
				err("put_semaphore");
			if (put_semaphore(semid, &sembuffer))
				err("put_semaphore");
			return 0;
		}
	}

	/* Wait for COW */
	if (forkflag && get_semaphore(semid, &sembuffer)) {
		perror("get_semaphore");
		goto cleanout;
	}

	if (inject && corrupt_page != -1) {
		ret = madvise(addr + corrupt_page * PS, PS, madvise_code);
		if (ret) {
			printf("madivise return %d :", ret);
			perror("madvise");
			goto cleanout;
		}
	}

	if (forkflag && put_semaphore(semid, &sembuffer)) {
		perror("put_semaphore");
		goto cleanout;
	}

	if (madvise_code != MADV_SOFT_OFFLINE);
		write_hugepage(addr, file_size, expected_addr);
	read_hugepage(addr, file_size, expected_addr);

	if (forkflag) {
		if (wait(&i) == -1)
			err("wait");
		if (semctl(semid, 0, IPC_RMID) == -1)
			err("semctl(IPC_RMID)");
	}
cleanout:
	if (shmflag) {
		if (free_shm_hugepage(shmkey, addr) == -1)
			exit(2);
	} else if (anonflag) {
		if (free_anonymous_hugepage(addr, file_size * HPAGE_SIZE) == -1)
			exit(2);
	} else {
		if (free_filebacked_hugepage(addr, file_size * HPAGE_SIZE,
					     fd, filepath) == -1)
			exit(2);
	}

	return 0;
}
int main(int argc, char *argv[])
{
	char *addr;
	int i;
	int ret;
	int fd = 0;
	int inject = 0;
	int avoidtouch = 0;
	int privateflag = 0;
	int cowflag = 0;
	char c;
	char filename[BUF_SIZE] = "/test";
	void *exp_addr = (void *)ADDR_INPUT;
	int corrupt_page = -1;
	int nr_hps = 2;
	int offset = 0;

	int hardoffline = 0;
	int softoffline = 0;
	int mceinject = 0;

	signal(SIGUSR1, sig_handle);

	while ((c = getopt(argc, argv, "avp:HScn:")) != -1) {
		switch (c) {
		case 'a':
			avoidtouch = 1;
			break;
		case 'v':
			verbose = 1;
			break;
                case 'p':
                        testpipe = optarg;
                        {
                                struct stat stat;
                                lstat(testpipe, &stat);
                                if (!S_ISFIFO(stat.st_mode))
                                        errmsg("Given file is not fifo.\n");
                        }
                        break;
		case 'H':
			hardoffline = 1;
			break;
		case 'S':
			softoffline = 1;
			break;
		case 'c':
			mceinject = 1;
			break;
		case 'n':
			nr_hps = strtol(optarg, NULL, 10);
			break;
		}
	}

	/* root path of hugetlbfs is set to global variable @filepath */
	/* get_hugetlbfs_filepath(filename); */

	addr = alloc_anonymous_hugepage(nr_hps * HPS, privateflag, exp_addr);

	/* load hugepages on memory */
	write_hugepage(addr, nr_hps, 0);

	if (hardoffline || softoffline) {
		char rbuf[256];
		pprintf("error injection with madvise\n");
		pause();
		pipe_read(rbuf);
		offset = strtol(rbuf, NULL, 0);
		Dprintf("madvise inject to addr %lx\n", addr + offset * PS);
		if (madvise(addr + offset*PS, PS,
			    hardoffline ? MADV_HWPOISON : MADV_SOFT_OFFLINE) != 0)
			perror("madvise");
		pprintf("after madvise injection\n");
		pause();
	} else if (mceinject == 1) {
		pprintf("waiting for injection from outside\n");
		pause();
	} else {
		printf("No memory error injection\n");
		pause();
	}

	if (!avoidtouch) {
		pprintf("writing affected region\n");
		pause();
		write_hugepage(addr, nr_hps, 0);
	}

	pprintf("thugetlb_exit\n");
	pause();
	free_anonymous_hugepage(addr, nr_hps * HPS);
	return 0;
}