From patchwork Thu Jun 29 20:50:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Axel Rasmussen X-Patchwork-Id: 13297315 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 kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 97BB5C001DE for ; Thu, 29 Jun 2023 20:51:00 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id DBF258D0007; Thu, 29 Jun 2023 16:50:58 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id D235C8D0001; Thu, 29 Jun 2023 16:50:58 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id B74A38D0007; Thu, 29 Jun 2023 16:50:58 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0015.hostedemail.com [216.40.44.15]) by kanga.kvack.org (Postfix) with ESMTP id A4EAE8D0001 for ; Thu, 29 Jun 2023 16:50:58 -0400 (EDT) Received: from smtpin22.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay06.hostedemail.com (Postfix) with ESMTP id 59854B0783 for ; Thu, 29 Jun 2023 20:50:58 +0000 (UTC) X-FDA: 80956979796.22.2DB9239 Received: from mail-yw1-f201.google.com (mail-yw1-f201.google.com [209.85.128.201]) by imf01.hostedemail.com (Postfix) with ESMTP id 7A7E040013 for ; Thu, 29 Jun 2023 20:50:56 +0000 (UTC) Authentication-Results: imf01.hostedemail.com; dkim=pass header.d=google.com header.s=20221208 header.b=b9ic7m0u; spf=pass (imf01.hostedemail.com: domain of 3r-6dZA0KCDAMjQXdMeYgeeQZSaaSXQ.OaYXUZgj-YYWhMOW.adS@flex--axelrasmussen.bounces.google.com designates 209.85.128.201 as permitted sender) smtp.mailfrom=3r-6dZA0KCDAMjQXdMeYgeeQZSaaSXQ.OaYXUZgj-YYWhMOW.adS@flex--axelrasmussen.bounces.google.com; dmarc=pass (policy=reject) header.from=google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1688071856; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=FDMn97NE4k9ts/MbSvQk7TIpBtwkvtlY8wmg3pzMxc0=; b=8eo8OzAeHBKXxbG8uSqiOIRwwCkk9FqEvCvwNPuKB3+TFdAVyOS1dRq3ckZLNlIWgSiqTv jfav0ybrrSjDUGKDusMsWr+TSZlz234Ghqjg1lS4wjvBghaV5/Df4FD02XHeCmmDLt6QfL 3E5gEOhDnlGYL7ggHvVarF3Mk47qIK4= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1688071856; a=rsa-sha256; cv=none; b=p4tP0ZDTeObhvUKb/y/zywitjB0z0hdd3X3HOEG7ZHaYMSQ8bnSEIsOLBmHPq2OcgJZ7Vs K0H+vuRxyqweekpFUowvNpSKeL9CEsjSwB/2i1pFFSTcwPEhJer3VdLZH5A10OQ59LROpF 06jP+hlJJbO6HE3wLjbGSbQPTAj1f9E= ARC-Authentication-Results: i=1; imf01.hostedemail.com; dkim=pass header.d=google.com header.s=20221208 header.b=b9ic7m0u; spf=pass (imf01.hostedemail.com: domain of 3r-6dZA0KCDAMjQXdMeYgeeQZSaaSXQ.OaYXUZgj-YYWhMOW.adS@flex--axelrasmussen.bounces.google.com designates 209.85.128.201 as permitted sender) smtp.mailfrom=3r-6dZA0KCDAMjQXdMeYgeeQZSaaSXQ.OaYXUZgj-YYWhMOW.adS@flex--axelrasmussen.bounces.google.com; dmarc=pass (policy=reject) header.from=google.com Received: by mail-yw1-f201.google.com with SMTP id 00721157ae682-573d70da2dcso9724617b3.1 for ; Thu, 29 Jun 2023 13:50:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1688071855; x=1690663855; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=FDMn97NE4k9ts/MbSvQk7TIpBtwkvtlY8wmg3pzMxc0=; b=b9ic7m0uviwwst/a/b6ej/KmTI1fbXLL05tIs7ZZktU/1u1vjioSSlgudRjzPPssiy tp8Df963g7Gw9okHBP74jobr3AMGXd284bnbTndsz/MzbhN8YGVA8qDN4fDKB/ndeZVg QJI4l1QU+fC4jjOAj9fa1B2eKR2xgGeEAW2jObEdLCiYk4pjpamRXhIA/AvCrm3AxS1A S57uq/giJWwpOzsio0l1XJxDbLPkIQcot63aSrBC/XjE/hIXayLN7QhrNIf6De7X0ojG MHaKy6jVInPl550XNyYzoiSALiiydqGt38OXbmQvLutW7JTQFw252iMVADLjBUBo1bab iXag== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1688071855; x=1690663855; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=FDMn97NE4k9ts/MbSvQk7TIpBtwkvtlY8wmg3pzMxc0=; b=E94e83U7Uc7jKEkQb3k8GQuTmxyZRVFRDGiJv9Csx+YfXOFgRKXQmBa7eInY98PwvQ O4Oe0HW+BDL2KrfTCnvzx1PJQuhVwjTRmk7rKRYH5cFW9tvG7K9QiOdts+llY4nPkZom gM8biIMj27axiVPgrsiYrJ2nHeC3Gu/Y/Bkbu7lgVuD8/MiZFZszxvQpnsE2aNfOxN16 ww8ZePSxpPHauhAlEVOhUL1h1SNF83ct6eJUABChXjwMbrjdl6uGiUpjv7+h1MLi+szs WRHzVrr2ho12ufd6pI6EEOqh7c8QZ5Jlhzmb0W419QLc3xXVn2ssdpU/PV/UkcuEUvkc Ok+A== X-Gm-Message-State: ABy/qLbMFQrXLldkzxSAeIVuhKiFEMVCQ7x8pBCDlpp8tX4NvKDFKAcj un7rmTHS/gV7ZmkthZqW0D6dsmb2XARKjP0/OLgK X-Google-Smtp-Source: APBJJlFEeXNU5wkKYldS4vdZYkexQZAWshF/qAuKQS3UJdZOiHvOTMlytCrLVWGNw78bI6vNEGHYZeLbYDtkVMX51oUg X-Received: from axel.svl.corp.google.com ([2620:15c:2a3:200:e20f:5917:3efa:d4bb]) (user=axelrasmussen job=sendgmr) by 2002:a25:d243:0:b0:c38:b4b5:13d5 with SMTP id j64-20020a25d243000000b00c38b4b513d5mr6655ybg.3.1688071855661; Thu, 29 Jun 2023 13:50:55 -0700 (PDT) Date: Thu, 29 Jun 2023 13:50:39 -0700 In-Reply-To: <20230629205040.665834-1-axelrasmussen@google.com> Mime-Version: 1.0 References: <20230629205040.665834-1-axelrasmussen@google.com> X-Mailer: git-send-email 2.41.0.255.g8b1d071c50-goog Message-ID: <20230629205040.665834-5-axelrasmussen@google.com> Subject: [PATCH v2 5/6] selftests/mm: add uffd unit test for UFFDIO_POISON From: Axel Rasmussen To: Alexander Viro , Andrew Morton , Christian Brauner , David Hildenbrand , Huang Ying , Hugh Dickins , James Houghton , Jiaqi Yan , Jonathan Corbet , "Liam R. Howlett" , Miaohe Lin , Mike Kravetz , "Mike Rapoport (IBM)" , Muchun Song , Nadav Amit , Naoya Horiguchi , Peter Xu , Shuah Khan , ZhangPeng Cc: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-kselftest@vger.kernel.org, Axel Rasmussen X-Stat-Signature: 5im7y8tpj8b7cg63f139eo6ugtiyrhdb X-Rspamd-Server: rspam10 X-Rspamd-Queue-Id: 7A7E040013 X-Rspam-User: X-HE-Tag: 1688071856-972192 X-HE-Meta: U2FsdGVkX1/PwZEitkLWDMVn6tMqtYOS1C7m+1aPMPu72gnmCNa17xflbF2oyDeK81xrTFpf0M+Ehwty1RNneSUfn0lZx6AuuZg9IHU1g2GJaPRUacs9JbsUxquX6skLK0l66uVJvWT38UlM8JHBIbghZpzimGwhnnO0b6D0LX3yGzbOZHLc2hl1zY7R0NhUIn6x+dLLr6/IMASqr/op88oLF35JSSJg4Bh5EJ0Xt83CA+62JozPViAnJYTVImchek57s7rxSkRaoyMZv2+zWLTjtJTYR2elfizhDE59o+3N/+Pv+ZA1R5TdDd5SLTsh7RroOOum/I9KB+qnqPd9rA4qYfROViAqbx4rFuGNFEF76LhAHke3BAVJZvULNRMWLBjjBFFkVFXuosIHmOJWeFhrmJ84/x9MIw8LpLvc7WM1IU+Yser+xSHEqtj8g4wh4J7PjuabkiP8V9+SEMyL2RKbBgw62oC/1+V0CqZcrmZCLaz3mwY14YBw3a3VDYw33yFYKRQ/2psHUdGgf45EW76uQF4M8nh+GP13ebPj4qD3wmqeAw7YevmkZzPqh9u2ysh1PgBAirxIIYVjbmBPZk0DR/vha07af+xPy8eQPE/zH02STex/9LVzKQRe3i7Ze5nAtb2tTZd2HCqAx0GVlncmam+l1r9MnSjg4b68dwNg/YYDZJCDzJ61rOurazpRDyE8aDK5u+7S9QllE+WaQQ4EmuLzMYtW3BmwZPThUAJxsEJu+VMcWqpXaCOkBxuMqmnPEjS7k/90BoOPWhDI2ncLlW2g+Lr4ci6+CI2iHXvYk9zzPo4GW964oqEJb4nMmGmMR2TRiN7pifw/qG1CU5JJ4Yu8sy58M9GhMleRwk5L1tr2pd2IrWAnUxx/849DLZuf327UFNNqJSinSYN/ZwpwFwV7nBcxQpVC6VEyxvRxLxgr+L4Z8i1a1BKHEu7Jte+xC4P2fZ48nozy6Cm 6m6ed8yP fj8pHAiN/yckr4z2qFvBXXSfO0ThKQdyUiQfQB3h/s4mSTs0JAy3DK0h2LF8TEG9DBlaGzAJCxwoGEiLDcWSGMoJD+7ATSHPkMvODNy39qtUE6J1apnQ2R5mhVz+el6CT1LN6dzGEHNBa5RepeqlxrmdugMKdTnCrEQ8YRu9oi9bNOzXP6obHMo4puVdKuGpSi6tJUltEuFH5UHIe/a4/G7SF5EzXrEpL8ALF9j6F5Zt9Up4avUFdZz2f2zoQ4c3H94s8LC0FvfZpVmZTl1uHy3x7r3wOpx5h6aa87LP5RBM6GZEAizLsFki4YR/+RUm84CR22wv7ygivfQ7Yej+ZSjeU+WVAVWa8vdwLqHXpUvjzvL8A9N/rsiSYzRcnH2rxUlX+I/x06JJK1w01zY0fg9wrHuLFW+ZJbpvhXE9TOYlw+SDadIrrr3DK0sGPaDbUWf3W9XgR675uyUPwZC/QQIsb9w/oh82eWc9EM6m7GoaXvlcj92wNxMV8qx23g72uL7qBGvKNtIlsK4SLFFwR7DA9MYAPUavo9jvNQjImOy9KyjbmSvI1T6I/Xl1WwLvWQjN/bk4Gq+KhPR4U3WqCud3JrP4VOgSRwqj3YTKvHsJ3HxcOUu2fxOvNGBbLVehDjscOfpQFbkb6T0YjKMjcUTuMc5FNoG+fm457j4ejTU7qVHgwQwxHiB1QBqZqA4IGohTUeGbQSqGIkMO0tssK+9T1Nw== X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: The test is pretty basic, and exercises UFFDIO_POISON straightforwardly. We register a region with userfaultfd, in missing fault mode. For each fault, we either UFFDIO_COPY a zeroed page (odd pages) or UFFDIO_POISON (even pages). We do this mix to test "something like a real use case", where guest memory would be some mix of poisoned and non-poisoned pages. We read each page in the region, and assert that the odd pages are zeroed as expected, and the even pages yield a SIGBUS as expected. Why UFFDIO_COPY instead of UFFDIO_ZEROPAGE? Because hugetlb doesn't support UFFDIO_ZEROPAGE, and we don't want to have special case code. Signed-off-by: Axel Rasmussen Acked-by: Peter Xu --- tools/testing/selftests/mm/uffd-unit-tests.c | 117 +++++++++++++++++++ 1 file changed, 117 insertions(+) diff --git a/tools/testing/selftests/mm/uffd-unit-tests.c b/tools/testing/selftests/mm/uffd-unit-tests.c index 04d91f144d1c..2709a34a39c5 100644 --- a/tools/testing/selftests/mm/uffd-unit-tests.c +++ b/tools/testing/selftests/mm/uffd-unit-tests.c @@ -951,6 +951,117 @@ static void uffd_zeropage_test(uffd_test_args_t *args) uffd_test_pass(); } +static void uffd_register_poison(int uffd, void *addr, uint64_t len) +{ + uint64_t ioctls = 0; + uint64_t expected = (1 << _UFFDIO_COPY) | (1 << _UFFDIO_POISON); + + if (uffd_register_with_ioctls(uffd, addr, len, true, + false, false, &ioctls)) + err("poison register fail"); + + if ((ioctls & expected) != expected) + err("registered area doesn't support COPY and POISON ioctls"); +} + +static void do_uffdio_poison(int uffd, unsigned long offset) +{ + struct uffdio_poison uffdio_poison = { 0 }; + int ret; + __s64 res; + + uffdio_poison.range.start = (unsigned long) area_dst + offset; + uffdio_poison.range.len = page_size; + uffdio_poison.mode = 0; + ret = ioctl(uffd, UFFDIO_POISON, &uffdio_poison); + res = uffdio_poison.updated; + + if (ret) + err("UFFDIO_POISON error: %"PRId64, (int64_t)res); + else if (res != page_size) + err("UFFDIO_POISON unexpected size: %"PRId64, (int64_t)res); +} + +static void uffd_poison_handle_fault( + struct uffd_msg *msg, struct uffd_args *args) +{ + unsigned long offset; + + if (msg->event != UFFD_EVENT_PAGEFAULT) + err("unexpected msg event %u", msg->event); + + if (msg->arg.pagefault.flags & + (UFFD_PAGEFAULT_FLAG_WP | UFFD_PAGEFAULT_FLAG_MINOR)) + err("unexpected fault type %llu", msg->arg.pagefault.flags); + + offset = (char *)(unsigned long)msg->arg.pagefault.address - area_dst; + offset &= ~(page_size-1); + + /* Odd pages -> copy zeroed page; even pages -> poison. */ + if (offset & page_size) + copy_page(uffd, offset, false); + else + do_uffdio_poison(uffd, offset); +} + +static void uffd_poison_test(uffd_test_args_t *targs) +{ + pthread_t uffd_mon; + char c; + struct uffd_args args = { 0 }; + struct sigaction act = { 0 }; + unsigned long nr_sigbus = 0; + unsigned long nr; + + fcntl(uffd, F_SETFL, uffd_flags | O_NONBLOCK); + + uffd_register_poison(uffd, area_dst, nr_pages * page_size); + memset(area_src, 0, nr_pages * page_size); + + args.handle_fault = uffd_poison_handle_fault; + if (pthread_create(&uffd_mon, NULL, uffd_poll_thread, &args)) + err("uffd_poll_thread create"); + + sigbuf = &jbuf; + act.sa_sigaction = sighndl; + act.sa_flags = SA_SIGINFO; + if (sigaction(SIGBUS, &act, 0)) + err("sigaction"); + + for (nr = 0; nr < nr_pages; ++nr) { + unsigned long offset = nr * page_size; + const char *bytes = (const char *) area_dst + offset; + const char *i; + + if (sigsetjmp(*sigbuf, 1)) { + /* + * Access below triggered a SIGBUS, which was caught by + * sighndl, which then jumped here. Count this SIGBUS, + * and move on to next page. + */ + ++nr_sigbus; + continue; + } + + for (i = bytes; i < bytes + page_size; ++i) { + if (*i) + err("nonzero byte in area_dst (%p) at %p: %u", + area_dst, i, *i); + } + } + + if (write(pipefd[1], &c, sizeof(c)) != sizeof(c)) + err("pipe write"); + if (pthread_join(uffd_mon, NULL)) + err("pthread_join()"); + + if (nr_sigbus != nr_pages / 2) + err("expected to receive %lu SIGBUS, actually received %lu", + nr_pages / 2, nr_sigbus); + + uffd_test_pass(); +} + /* * Test the returned uffdio_register.ioctls with different register modes. * Note that _UFFDIO_ZEROPAGE is tested separately in the zeropage test. @@ -1126,6 +1237,12 @@ uffd_test_case_t uffd_tests[] = { UFFD_FEATURE_PAGEFAULT_FLAG_WP | UFFD_FEATURE_WP_HUGETLBFS_SHMEM, }, + { + .name = "poison", + .uffd_fn = uffd_poison_test, + .mem_targets = MEM_ALL, + .uffd_feature_required = UFFD_FEATURE_POISON, + }, }; static void usage(const char *prog)