> +static int test_fork(int uffd, char *primary_map, size_t len) > +{ > + int status; > + int ret = 0; > + pid_t pid; > + pthread_t uffd_thd; > + > + /* > + * UFFD_FEATURE_EVENT_FORK will put fork event on the userfaultfd, > + * which we must read, otherwise we block fork(). Setup a thread to > + * read that event now. > + * > + * Page fault events should result in a SIGBUS, so we expect only a > + * single event from the uffd (the fork event). > + */ > + if (read_event_from_uffd(&uffd, &uffd_thd)) > + return -1; > + > + pid = fork(); > + > + if (!pid) { > + /* > + * Because we have UFFDIO_REGISTER_MODE_WP and > + * UFFD_FEATURE_EVENT_FORK, the page tables should be copied > + * exactly. > + * > + * Check that everything except that last 4K has correct > + * contents, and then check that the last 4K gets a SIGBUS. > + */ > + printf(PREFIX "child validating...\n"); > + ret = verify_contents(primary_map, len, false) || > + test_sigbus(primary_map + len - 1, false); > + ret = 0; > + exit(ret ? 1 : 0); > + } else { > + /* wait for the child to finish. */ > + waitpid(pid, &status, 0); > + ret = WEXITSTATUS(status); > + if (!ret) { > + printf(PREFIX "parent validating...\n"); > + /* Same check as the child. */ > + ret = verify_contents(primary_map, len, false) || > + test_sigbus(primary_map + len - 1, false); > + ret = 0; I'm not sure how these 'ret = 0's got here -- they will be removed. > + } > + } This else block also runs when fork() fails; we need to fail the test instead. > + > + pthread_join(uffd_thd, NULL); > + return ret; > + > +}