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); }
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; }
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; }