static struct uffd_test_ops *uffd_test_ops;
 
+static inline uint64_t uffd_minor_feature(void)
+{
+       if (test_type == TEST_HUGETLB && map_shared)
+               return UFFD_FEATURE_MINOR_HUGETLBFS;
+       else if (test_type == TEST_SHMEM)
+               return UFFD_FEATURE_MINOR_SHMEM;
+       else
+               return 0;
+}
+
 static void userfaultfd_open(uint64_t *features)
 {
        struct uffdio_api uffdio_api;
        munmap_area((void **)&area_dst_alias);
 }
 
-static void uffd_test_ctx_init_ext(uint64_t *features)
+static void uffd_test_ctx_init(uint64_t features)
 {
        unsigned long nr, cpu;
 
        uffd_test_ops->allocate_area((void **)&area_src);
        uffd_test_ops->allocate_area((void **)&area_dst);
 
-       userfaultfd_open(features);
+       userfaultfd_open(&features);
 
        count_verify = malloc(nr_pages * sizeof(unsigned long long));
        if (!count_verify)
                        err("pipe");
 }
 
-static inline void uffd_test_ctx_init(uint64_t features)
-{
-       uffd_test_ctx_init_ext(&features);
-}
-
 static int my_bcmp(char *str1, char *str2, size_t n)
 {
        unsigned long i;
        void *expected_page;
        char c;
        struct uffd_stats stats = { 0 };
-       uint64_t req_features, features_out;
 
        if (!test_uffdio_minor)
                return 0;
        printf("testing minor faults: ");
        fflush(stdout);
 
-       if (test_type == TEST_HUGETLB)
-               req_features = UFFD_FEATURE_MINOR_HUGETLBFS;
-       else if (test_type == TEST_SHMEM)
-               req_features = UFFD_FEATURE_MINOR_SHMEM;
-       else
-               return 1;
-
-       features_out = req_features;
-       uffd_test_ctx_init_ext(&features_out);
-       /* If kernel reports required features aren't supported, skip test. */
-       if ((features_out & req_features) != req_features) {
-               printf("skipping test due to lack of feature support\n");
-               fflush(stdout);
-               return 0;
-       }
+       uffd_test_ctx_init(uffd_minor_feature());
 
        uffdio_register.range.start = (unsigned long)area_dst_alias;
        uffdio_register.range.len = nr_pages * page_size;
 
 static void set_test_type(const char *type)
 {
+       uint64_t features = UFFD_API_FEATURES;
+
        if (!strcmp(type, "anon")) {
                test_type = TEST_ANON;
                uffd_test_ops = &anon_uffd_test_ops;
        if ((unsigned long) area_count(NULL, 0) + sizeof(unsigned long long) * 2
            > page_size)
                err("Impossible to run this test");
+
+       /*
+        * Whether we can test certain features depends not just on test type,
+        * but also on whether or not this particular kernel supports the
+        * feature.
+        */
+
+       userfaultfd_open(&features);
+
+       test_uffdio_wp = test_uffdio_wp &&
+               (features & UFFD_FEATURE_PAGEFAULT_FLAG_WP);
+       test_uffdio_minor = test_uffdio_minor &&
+               (features & uffd_minor_feature());
+
+       close(uffd);
+       uffd = -1;
 }
 
 static void sigalrm(int sig)