From patchwork Thu Sep 30 21:23:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Axel Rasmussen X-Patchwork-Id: 12529331 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BB06FC433FE for ; Thu, 30 Sep 2021 21:23:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9CC6F61A61 for ; Thu, 30 Sep 2021 21:23:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349748AbhI3VZD (ORCPT ); Thu, 30 Sep 2021 17:25:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47490 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229701AbhI3VZD (ORCPT ); Thu, 30 Sep 2021 17:25:03 -0400 Received: from mail-qk1-x749.google.com (mail-qk1-x749.google.com [IPv6:2607:f8b0:4864:20::749]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DE027C06176A for ; Thu, 30 Sep 2021 14:23:19 -0700 (PDT) Received: by mail-qk1-x749.google.com with SMTP id az37-20020a05620a172500b0045e43348ee8so14644846qkb.19 for ; Thu, 30 Sep 2021 14:23:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=wbUrvvm0+MYAPUCF6HQK8A4cSFDFNCfNO8ihEMufpf8=; b=DXFhvoYgkBKBGW9TTScr4boM8/R+bDeePetODemKEZwYhJLpOOzrVNl6U0O8viIeqk pp2IrEkYyQyq4j2XkKfWQ4VittBUoFL9eK6QgTF8xsJnQegzB1LmqaFt8EgKiCyym1JF GE/gxRXqPXWqWaj96T8kz7tdyVHIJtP91uuXP/xkt5uGZ9Ozc/hLHZVAjgDUOulIv5Gj JqN+T2CECrPI/0jEt+gTV12f8/TErC9CAukhyWp/vFoE+aRLAIFWUO/ZufY6xbX/VP++ 2SBzxCS4wW06iaipZX8I5I10tTC9VxTqNnPo/gvPYQVZ4WpVfyneUQu3oXKgMzRcQd3o zngA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=wbUrvvm0+MYAPUCF6HQK8A4cSFDFNCfNO8ihEMufpf8=; b=spN2Tl+4DaLviEdiW4q8CMMe36Jzk289VQOOR6Dtye9sGf9uiROd+N800+7l46tCfd vFhoGmJsxyLgewd5qhVXtTdWOdAa91bCxWtt8GQ1pwGY03dXlEFOi8GHwjby9KkLVWKz bWSAKqnY5mkFfKc54uiQgGz/YEs8Kk27wb6S9U/njOmF0sSXOEun6vIWbgBOAi29IB6H bxXYHTCC+MQ3O/P9cP82PRQ/EM+tURbwi72XXPGYh16ZchlwlBj2EfXWzVyZxGlooo/k /sHgI4T6R/QW3kVf4iX6W1BI+y57D7dUbh3rnMos1oNp3wO+Ebc4jhDTyX5cxbTgkI4B Ie3w== X-Gm-Message-State: AOAM533XKX3IaUv2jT6UJwzUSYkhmSuPBHmdyrSB8RkAumv1rBH1tbyh BobFhmvzGr7gjnsbPzaeJ8wATr5eqgj1UByi+jOV X-Google-Smtp-Source: ABdhPJywOpI+b7jm0hToN3nP52PlVum8uravic0hgie7sww9kEWkrOanS+hnSp8P208w/79s1xImwJumjKcifP/pZ7/r X-Received: from ajr0.svl.corp.google.com ([2620:15c:2cd:203:fa06:3b29:d3c:37e6]) (user=axelrasmussen job=sendgmr) by 2002:a05:6214:12af:: with SMTP id w15mr5967689qvu.66.1633036999024; Thu, 30 Sep 2021 14:23:19 -0700 (PDT) Date: Thu, 30 Sep 2021 14:23:07 -0700 In-Reply-To: <20210930212309.4001967-1-axelrasmussen@google.com> Message-Id: <20210930212309.4001967-2-axelrasmussen@google.com> Mime-Version: 1.0 References: <20210930212309.4001967-1-axelrasmussen@google.com> X-Mailer: git-send-email 2.33.0.800.g4c38ced690-goog Subject: [PATCH v2 1/3] userfaultfd/selftests: don't rely on GNU extensions for random numbers From: Axel Rasmussen To: Andrew Morton , Peter Xu , Shuah Khan Cc: linux-mm@kvack.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Axel Rasmussen Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org Two arguments for doing this: First, and maybe most importantly, the resulting code is significantly shorter / simpler. Then, we avoid using GNU libc extensions. Why does this matter? It makes testing userfaultfd with the selftest easier e.g. on distros which use something other than glibc (e.g., Alpine, which uses musl); basically, it makes the test more portable. Reviewed-by: Peter Xu Signed-off-by: Axel Rasmussen --- tools/testing/selftests/vm/userfaultfd.c | 26 ++++-------------------- 1 file changed, 4 insertions(+), 22 deletions(-) diff --git a/tools/testing/selftests/vm/userfaultfd.c b/tools/testing/selftests/vm/userfaultfd.c index 10ab56c2484a..2a71a91559a7 100644 --- a/tools/testing/selftests/vm/userfaultfd.c +++ b/tools/testing/selftests/vm/userfaultfd.c @@ -57,6 +57,7 @@ #include #include #include +#include #include "../kselftest.h" @@ -501,22 +502,10 @@ static void continue_range(int ufd, __u64 start, __u64 len) static void *locking_thread(void *arg) { unsigned long cpu = (unsigned long) arg; - struct random_data rand; unsigned long page_nr = *(&(page_nr)); /* uninitialized warning */ - int32_t rand_nr; unsigned long long count; - char randstate[64]; - unsigned int seed; - if (bounces & BOUNCE_RANDOM) { - seed = (unsigned int) time(NULL) - bounces; - if (!(bounces & BOUNCE_RACINGFAULTS)) - seed += cpu; - bzero(&rand, sizeof(rand)); - bzero(&randstate, sizeof(randstate)); - if (initstate_r(seed, randstate, sizeof(randstate), &rand)) - err("initstate_r failed"); - } else { + if (!(bounces & BOUNCE_RANDOM)) { page_nr = -bounces; if (!(bounces & BOUNCE_RACINGFAULTS)) page_nr += cpu * nr_pages_per_cpu; @@ -524,15 +513,8 @@ static void *locking_thread(void *arg) while (!finished) { if (bounces & BOUNCE_RANDOM) { - if (random_r(&rand, &rand_nr)) - err("random_r failed"); - page_nr = rand_nr; - if (sizeof(page_nr) > sizeof(rand_nr)) { - if (random_r(&rand, &rand_nr)) - err("random_r failed"); - page_nr |= (((unsigned long) rand_nr) << 16) << - 16; - } + if (getrandom(&page_nr, sizeof(page_nr), 0) != sizeof(page_nr)) + err("getrandom failed"); } else page_nr += 1; page_nr %= nr_pages; From patchwork Thu Sep 30 21:23:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Axel Rasmussen X-Patchwork-Id: 12529333 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 88E11C433F5 for ; Thu, 30 Sep 2021 21:23:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6D23761A6D for ; Thu, 30 Sep 2021 21:23:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349730AbhI3VZH (ORCPT ); Thu, 30 Sep 2021 17:25:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47506 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349787AbhI3VZF (ORCPT ); Thu, 30 Sep 2021 17:25:05 -0400 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1D300C06176A for ; Thu, 30 Sep 2021 14:23:22 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id 207-20020a2503d8000000b005b6fc088578so5306876ybd.0 for ; Thu, 30 Sep 2021 14:23:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=O1Wk2DsZzjmvOi9GlXjWLcYlkQVsSE0/3HMwsEB5v90=; b=p5N9OfoJnRryV2eKQy7VJj+QvmddfN6dQLK1yKEYuT0+MEdaPYTk0F1gSb0XuI4m/C UOSfrWwVYnKcg9i4VTVBWBoyzlr5D/4tCJHL+keAjsGNCgUG4CkTUALdSFqGuL1rUIfW eJiSFq5kNK2QYiOhfHBTWkEVNQXnH5xkx3SF77V8LMdO+UwtxoCiJaacEOdGcUhQjaMX LiFJIX6epwBcRsVVwO6fsb777Dm9tQI3wml4GWagAl575ckhhUU4KI4NIuPEbxf2z0yy 9KrwvWJ9b+hSfVCQwJjcfsfhMhG6YWBrH+TQJgm5EXPp85Q0LyoSYm9H6b9xm/wA2pgj OdZw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=O1Wk2DsZzjmvOi9GlXjWLcYlkQVsSE0/3HMwsEB5v90=; b=4I37xgIshz4DcDOkqBG/DV/JY0bWsqlJOYfUpsCt4TYGm0V9ptqCOHmtOQU+wBr9kw IJ7rvwQEWSxgDhXszrj6PLwbtyH1xMQZ/kbqU5KbgbDYx/FwyRWtP3LDeyDdQ1A4Ne0m +1YM8SY4xjljL8MpeJw1m+yljE0603QSlMdhGrBtyyH0wIkRlyVDzbU5PxohJ+bO5xr/ pqDYMZdAiadFUU6dHBJR3/wGp7s44sJHBKlzXstcabLm1uGSY/J+BAJAvW1cxuAlznws d7kcAB+GBYsKZQlEfRjoum1gHsTaTcb1y8JJPxJOaz47SbTYWXgWLpvwMxWln5djeqIS O6fA== X-Gm-Message-State: AOAM531Ox4X3jBTMcjwnEUCpMzDCsfyRSg9ylsqep2+1WG5fQg1cxK0J GxigD8SVHHQU/VRToYw1iH79vAQMY8L1JWMYZPQm X-Google-Smtp-Source: ABdhPJzQJP1Tci6sbmHJjYHkBqAym/flLRBcDla+uZ6luLw59DtIioxJBp4LVRUhA0wkrCyLNd6qTLK3ikD9/a+QM2T2 X-Received: from ajr0.svl.corp.google.com ([2620:15c:2cd:203:fa06:3b29:d3c:37e6]) (user=axelrasmussen job=sendgmr) by 2002:a05:6902:705:: with SMTP id k5mr1886040ybt.490.1633037001347; Thu, 30 Sep 2021 14:23:21 -0700 (PDT) Date: Thu, 30 Sep 2021 14:23:08 -0700 In-Reply-To: <20210930212309.4001967-1-axelrasmussen@google.com> Message-Id: <20210930212309.4001967-3-axelrasmussen@google.com> Mime-Version: 1.0 References: <20210930212309.4001967-1-axelrasmussen@google.com> X-Mailer: git-send-email 2.33.0.800.g4c38ced690-goog Subject: [PATCH v2 2/3] userfaultfd/selftests: fix feature support detection From: Axel Rasmussen To: Andrew Morton , Peter Xu , Shuah Khan Cc: linux-mm@kvack.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Axel Rasmussen Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org Before any tests are run, in set_test_type, we decide what feature(s) we are going to be testing, based upon our command line arguments. However, the supported features are not just a function of the memory type being used, so this is broken. For instance, consider writeprotect support. It is "normally" supported for anonymous memory, but furthermore it requires that the kernel has CONFIG_HAVE_ARCH_USERFAULTFD_WP. So, it is *not* supported at all on aarch64, for example. So, this commit fixes this by querying the kernel for the set of features it supports in set_test_type, by opening a userfaultfd and issuing a UFFDIO_API ioctl. Based upon the reported features, we toggle what tests are enabled. Signed-off-by: Axel Rasmussen Reviewed-by: Peter Xu --- tools/testing/selftests/vm/userfaultfd.c | 54 ++++++++++++++---------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/tools/testing/selftests/vm/userfaultfd.c b/tools/testing/selftests/vm/userfaultfd.c index 2a71a91559a7..00d1b7555865 100644 --- a/tools/testing/selftests/vm/userfaultfd.c +++ b/tools/testing/selftests/vm/userfaultfd.c @@ -346,6 +346,16 @@ static struct uffd_test_ops hugetlb_uffd_test_ops = { 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; @@ -406,7 +416,7 @@ static void uffd_test_ctx_clear(void) 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; @@ -418,7 +428,7 @@ static void uffd_test_ctx_init_ext(uint64_t *features) uffd_test_ops->release_pages(area_src); uffd_test_ops->release_pages(area_dst); - userfaultfd_open(features); + userfaultfd_open(&features); count_verify = malloc(nr_pages * sizeof(unsigned long long)); if (!count_verify) @@ -446,11 +456,6 @@ static void uffd_test_ctx_init_ext(uint64_t *features) 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; @@ -1191,7 +1196,6 @@ static int userfaultfd_minor_test(void) void *expected_page; char c; struct uffd_stats stats = { 0 }; - uint64_t req_features, features_out; if (!test_uffdio_minor) return 0; @@ -1199,21 +1203,7 @@ static int userfaultfd_minor_test(void) 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; @@ -1574,6 +1564,8 @@ unsigned long default_huge_page_size(void) 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; @@ -1607,6 +1599,22 @@ static void set_test_type(const char *type) 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) From patchwork Thu Sep 30 21:23:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Axel Rasmussen X-Patchwork-Id: 12529335 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B5C56C433FE for ; Thu, 30 Sep 2021 21:23:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A671E61A7E for ; Thu, 30 Sep 2021 21:23:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349820AbhI3VZI (ORCPT ); Thu, 30 Sep 2021 17:25:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47528 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349843AbhI3VZH (ORCPT ); Thu, 30 Sep 2021 17:25:07 -0400 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8F992C06176E for ; Thu, 30 Sep 2021 14:23:24 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id x16-20020a25b910000000b005b6b7f2f91cso10593991ybj.1 for ; Thu, 30 Sep 2021 14:23:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=UjO0qfZl4lNdUd4h5vIafSHB+z3WAy5EBdv+I+4Y+ZY=; b=NwuarFTQoOfHoDeTi+T72vz5pPPePDKc9XoOvHlF3UtqrcWcq/q4zZpM9lyS9Dlvzs TDWAzKLsIqRyzDiC80gjehJ1c3jkH0Rp/76tPNGNrRsROUR6aItI+jWag7kVz2hf8lXM 89gjvFOzpkmUhKvmIGNiD2lX1alvv/LXDEXmnfI6zmACXz8tr6d5xocMf6/fg+7IZUI6 YJynVNW1ymb1mMfmCCim0mtKOP13wyRX1K+fJGasZWuTRBl86+XRyoqzjbaxOw6/W4ZA LpsFDih4sVtkpTTF7XcBvYGehyRz6yQI2ZdZw9TzhNXiofpVcpK/m/7kKXKkDHk0je3N MYQQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=UjO0qfZl4lNdUd4h5vIafSHB+z3WAy5EBdv+I+4Y+ZY=; b=QgmJJPL06kMrnE80oL1LE/lmMKpFT1NgujUP7a803/Yp7mWH4bkq284W8BPRsXHKDs L2jCr3YqGXMO6cQPb7tFFwokXjFY5k5O6GitxylD9t1OaEr8acAVVTozSARtW6bmQ2li relwMT054Of3BsCa8xEwHh8xoBuVINMkR5Q5EHf/HWVqwLwcceD+FF6cNcMCyi60uFeA CvCauzICH5UKc3m+dikUFWGYTVWcTYSp+3VVC7Lcn6mwEz4vK0FUNK9NGMA3xyZMXK9Q dUgzizSX5U3/plnFMU+a04G9mwKccKUsOQHpUlgUomVif2ny+Ve8aURd5+37AsIWHrW1 pJlg== X-Gm-Message-State: AOAM5308KBVyK1yS8svrPyzGjjZXVssPplI5OsYAcTSK8g+hKMkkmyZ/ AXDPEMrPP3ctpxMbpxKmnropHx/lwUxuUQhlWvHW X-Google-Smtp-Source: ABdhPJwUW2K57dvjts7mcKwjlfEPksJiGD50c7w8aBNiDKCiLJOXQKw/OsBEXOhZjEve/HLM7Ff5UwDrF+MYno8HeNIG X-Received: from ajr0.svl.corp.google.com ([2620:15c:2cd:203:fa06:3b29:d3c:37e6]) (user=axelrasmussen job=sendgmr) by 2002:a25:47d6:: with SMTP id u205mr766836yba.193.1633037003842; Thu, 30 Sep 2021 14:23:23 -0700 (PDT) Date: Thu, 30 Sep 2021 14:23:09 -0700 In-Reply-To: <20210930212309.4001967-1-axelrasmussen@google.com> Message-Id: <20210930212309.4001967-4-axelrasmussen@google.com> Mime-Version: 1.0 References: <20210930212309.4001967-1-axelrasmussen@google.com> X-Mailer: git-send-email 2.33.0.800.g4c38ced690-goog Subject: [PATCH v2 3/3] userfaultfd/selftests: fix calculation of expected ioctls From: Axel Rasmussen To: Andrew Morton , Peter Xu , Shuah Khan Cc: linux-mm@kvack.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Axel Rasmussen Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org Today, we assert that the ioctls the kernel reports as supported for a registration match a precomputed list. We decide which ioctls are supported by examining the memory type. Then, in several locations we "fix up" this list by adding or removing things this initial decision got wrong. What ioctls the kernel reports is actually a function of several things: - The memory type - Kernel feature support (e.g., no writeprotect on aarch64) - The registration type (e.g., CONTINUE only supported for MINOR mode) So, we can't fully compute this at the start, in set_test_type. It varies per test, depending on what registration mode(s) those tests use. Instead, introduce a new function which computes the correct list. This centralizes the add/remove of ioctls depending on these function inputs in one place, so we don't have to repeat ourselves in various tests. Not only is the resulting code a bit shorter, but it fixes a real bug in the existing code: previously, we would incorrectly require the writeprotect ioctl to be present on aarch64, where it isn't actually supported. Signed-off-by: Axel Rasmussen --- tools/testing/selftests/vm/userfaultfd.c | 77 ++++++++++++------------ 1 file changed, 38 insertions(+), 39 deletions(-) diff --git a/tools/testing/selftests/vm/userfaultfd.c b/tools/testing/selftests/vm/userfaultfd.c index 00d1b7555865..2348b6371ec8 100644 --- a/tools/testing/selftests/vm/userfaultfd.c +++ b/tools/testing/selftests/vm/userfaultfd.c @@ -308,37 +308,24 @@ static void shmem_alias_mapping(__u64 *start, size_t len, unsigned long offset) } struct uffd_test_ops { - unsigned long expected_ioctls; void (*allocate_area)(void **alloc_area); void (*release_pages)(char *rel_area); void (*alias_mapping)(__u64 *start, size_t len, unsigned long offset); }; -#define SHMEM_EXPECTED_IOCTLS ((1 << _UFFDIO_WAKE) | \ - (1 << _UFFDIO_COPY) | \ - (1 << _UFFDIO_ZEROPAGE)) - -#define ANON_EXPECTED_IOCTLS ((1 << _UFFDIO_WAKE) | \ - (1 << _UFFDIO_COPY) | \ - (1 << _UFFDIO_ZEROPAGE) | \ - (1 << _UFFDIO_WRITEPROTECT)) - static struct uffd_test_ops anon_uffd_test_ops = { - .expected_ioctls = ANON_EXPECTED_IOCTLS, .allocate_area = anon_allocate_area, .release_pages = anon_release_pages, .alias_mapping = noop_alias_mapping, }; static struct uffd_test_ops shmem_uffd_test_ops = { - .expected_ioctls = SHMEM_EXPECTED_IOCTLS, .allocate_area = shmem_allocate_area, .release_pages = shmem_release_pages, .alias_mapping = shmem_alias_mapping, }; static struct uffd_test_ops hugetlb_uffd_test_ops = { - .expected_ioctls = UFFD_API_RANGE_IOCTLS_BASIC & ~(1 << _UFFDIO_CONTINUE), .allocate_area = hugetlb_allocate_area, .release_pages = hugetlb_release_pages, .alias_mapping = hugetlb_alias_mapping, @@ -356,6 +343,33 @@ static inline uint64_t uffd_minor_feature(void) return 0; } +static uint64_t get_expected_ioctls(uint64_t mode) +{ + uint64_t ioctls = UFFD_API_RANGE_IOCTLS; + + if (test_type == TEST_HUGETLB) + ioctls &= ~(1 << _UFFDIO_ZEROPAGE); + + if (!((mode & UFFDIO_REGISTER_MODE_WP) && test_uffdio_wp)) + ioctls &= ~(1 << _UFFDIO_WRITEPROTECT); + + if (!((mode & UFFDIO_REGISTER_MODE_MINOR) && test_uffdio_minor)) + ioctls &= ~(1 << _UFFDIO_CONTINUE); + + return ioctls; +} + +static void assert_expected_ioctls_present(uint64_t mode, uint64_t ioctls) +{ + uint64_t expected = get_expected_ioctls(mode); + uint64_t actual = ioctls & expected; + + if (actual != expected) { + err("missing ioctl(s): expected %"PRIx64" actual: %"PRIx64, + expected, actual); + } +} + static void userfaultfd_open(uint64_t *features) { struct uffdio_api uffdio_api; @@ -1000,11 +1014,9 @@ static int __uffdio_zeropage(int ufd, unsigned long offset, bool retry) { struct uffdio_zeropage uffdio_zeropage; int ret; - unsigned long has_zeropage; + bool has_zeropage = get_expected_ioctls(0) & (1 << _UFFDIO_ZEROPAGE); __s64 res; - has_zeropage = uffd_test_ops->expected_ioctls & (1 << _UFFDIO_ZEROPAGE); - if (offset >= nr_pages * page_size) err("unexpected offset %lu", offset); uffdio_zeropage.range.start = (unsigned long) area_dst + offset; @@ -1044,7 +1056,6 @@ static int uffdio_zeropage(int ufd, unsigned long offset) static int userfaultfd_zeropage_test(void) { struct uffdio_register uffdio_register; - unsigned long expected_ioctls; printf("testing UFFDIO_ZEROPAGE: "); fflush(stdout); @@ -1059,9 +1070,8 @@ static int userfaultfd_zeropage_test(void) if (ioctl(uffd, UFFDIO_REGISTER, &uffdio_register)) err("register failure"); - expected_ioctls = uffd_test_ops->expected_ioctls; - if ((uffdio_register.ioctls & expected_ioctls) != expected_ioctls) - err("unexpected missing ioctl for anon memory"); + assert_expected_ioctls_present( + uffdio_register.mode, uffdio_register.ioctls); if (uffdio_zeropage(uffd, 0)) if (my_bcmp(area_dst, zeropage, page_size)) @@ -1074,7 +1084,6 @@ static int userfaultfd_zeropage_test(void) static int userfaultfd_events_test(void) { struct uffdio_register uffdio_register; - unsigned long expected_ioctls; pthread_t uffd_mon; int err, features; pid_t pid; @@ -1098,9 +1107,8 @@ static int userfaultfd_events_test(void) if (ioctl(uffd, UFFDIO_REGISTER, &uffdio_register)) err("register failure"); - expected_ioctls = uffd_test_ops->expected_ioctls; - if ((uffdio_register.ioctls & expected_ioctls) != expected_ioctls) - err("unexpected missing ioctl for anon memory"); + assert_expected_ioctls_present( + uffdio_register.mode, uffdio_register.ioctls); if (pthread_create(&uffd_mon, &attr, uffd_poll_thread, &stats)) err("uffd_poll_thread create"); @@ -1128,7 +1136,6 @@ static int userfaultfd_events_test(void) static int userfaultfd_sig_test(void) { struct uffdio_register uffdio_register; - unsigned long expected_ioctls; unsigned long userfaults; pthread_t uffd_mon; int err, features; @@ -1152,9 +1159,8 @@ static int userfaultfd_sig_test(void) if (ioctl(uffd, UFFDIO_REGISTER, &uffdio_register)) err("register failure"); - expected_ioctls = uffd_test_ops->expected_ioctls; - if ((uffdio_register.ioctls & expected_ioctls) != expected_ioctls) - err("unexpected missing ioctl for anon memory"); + assert_expected_ioctls_present( + uffdio_register.mode, uffdio_register.ioctls); if (faulting_process(1)) err("faulting process failed"); @@ -1189,7 +1195,6 @@ static int userfaultfd_sig_test(void) static int userfaultfd_minor_test(void) { struct uffdio_register uffdio_register; - unsigned long expected_ioctls; unsigned long p; pthread_t uffd_mon; uint8_t expected_byte; @@ -1211,10 +1216,8 @@ static int userfaultfd_minor_test(void) if (ioctl(uffd, UFFDIO_REGISTER, &uffdio_register)) err("register failure"); - expected_ioctls = uffd_test_ops->expected_ioctls; - expected_ioctls |= 1 << _UFFDIO_CONTINUE; - if ((uffdio_register.ioctls & expected_ioctls) != expected_ioctls) - err("unexpected missing ioctl(s)"); + assert_expected_ioctls_present( + uffdio_register.mode, uffdio_register.ioctls); /* * After registering with UFFD, populate the non-UFFD-registered side of @@ -1411,8 +1414,6 @@ static int userfaultfd_stress(void) pthread_attr_setstacksize(&attr, 16*1024*1024); while (bounces--) { - unsigned long expected_ioctls; - printf("bounces: %d, mode:", bounces); if (bounces & BOUNCE_RANDOM) printf(" rnd"); @@ -1440,10 +1441,8 @@ static int userfaultfd_stress(void) uffdio_register.mode |= UFFDIO_REGISTER_MODE_WP; if (ioctl(uffd, UFFDIO_REGISTER, &uffdio_register)) err("register failure"); - expected_ioctls = uffd_test_ops->expected_ioctls; - if ((uffdio_register.ioctls & expected_ioctls) != - expected_ioctls) - err("unexpected missing ioctl for anon memory"); + assert_expected_ioctls_present( + uffdio_register.mode, uffdio_register.ioctls); if (area_dst_alias) { uffdio_register.range.start = (unsigned long)