From patchwork Fri Apr 28 00:41:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiaqi Yan X-Patchwork-Id: 13225921 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 7DA0FC77B73 for ; Fri, 28 Apr 2023 00:42:01 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id E29B06B007E; Thu, 27 Apr 2023 20:41:59 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id B68466B0080; Thu, 27 Apr 2023 20:41:59 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 9932F900002; Thu, 27 Apr 2023 20:41:59 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0013.hostedemail.com [216.40.44.13]) by kanga.kvack.org (Postfix) with ESMTP id 7A5046B007E for ; Thu, 27 Apr 2023 20:41:59 -0400 (EDT) Received: from smtpin24.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay03.hostedemail.com (Postfix) with ESMTP id 49942A0148 for ; Fri, 28 Apr 2023 00:41:59 +0000 (UTC) X-FDA: 80728947558.24.473966D Received: from mail-pg1-f202.google.com (mail-pg1-f202.google.com [209.85.215.202]) by imf09.hostedemail.com (Postfix) with ESMTP id 5B701140011 for ; Fri, 28 Apr 2023 00:41:57 +0000 (UTC) Authentication-Results: imf09.hostedemail.com; dkim=pass header.d=google.com header.s=20221208 header.b=cBpNq4kD; spf=pass (imf09.hostedemail.com: domain of 3VBZLZAgKCNUA91H9P1E7FF7C5.3FDC9ELO-DDBM13B.FI7@flex--jiaqiyan.bounces.google.com designates 209.85.215.202 as permitted sender) smtp.mailfrom=3VBZLZAgKCNUA91H9P1E7FF7C5.3FDC9ELO-DDBM13B.FI7@flex--jiaqiyan.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=1682642517; 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=Ezb/mtBWXto18t5BMeGyfP88KWTxkli4FptKeY/x46M=; b=ZKpP2/yx/mteFIaYYNvI1O6acXku2v8M6D0+NA+ThcvKnVzB4JOpfJzgCGkJuamwLx1x2B g3jFBBdYq/Okuk0WJNYOYRux4itfeGYIQlw2Gcha4wSC0HShmHGFiaD2iDuuq73NpMZI0X pAt3Xiy9j9LlSbQypT2w694ZA68gpKU= ARC-Authentication-Results: i=1; imf09.hostedemail.com; dkim=pass header.d=google.com header.s=20221208 header.b=cBpNq4kD; spf=pass (imf09.hostedemail.com: domain of 3VBZLZAgKCNUA91H9P1E7FF7C5.3FDC9ELO-DDBM13B.FI7@flex--jiaqiyan.bounces.google.com designates 209.85.215.202 as permitted sender) smtp.mailfrom=3VBZLZAgKCNUA91H9P1E7FF7C5.3FDC9ELO-DDBM13B.FI7@flex--jiaqiyan.bounces.google.com; dmarc=pass (policy=reject) header.from=google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1682642517; a=rsa-sha256; cv=none; b=uFanllB9NJPP1d/Ap1DpjXP0KhO2gFcn4kxw7CcwCbQ7feSdphGxgUpUjuGZZJVrmp3YtR 8HTUGbaCvZjt5gVGv1k9AHJn54EGzu+Q59HAD5avybH419yn6DMDrgpn6RJFPC5l4LHtKf f2xH91+8nD0McKtpg3rp4DO/96jFHE4= Received: by mail-pg1-f202.google.com with SMTP id 41be03b00d2f7-51b67183546so5484435a12.0 for ; Thu, 27 Apr 2023 17:41:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1682642516; x=1685234516; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=Ezb/mtBWXto18t5BMeGyfP88KWTxkli4FptKeY/x46M=; b=cBpNq4kDOoS1KXNAw36+zGssSnylFqMaR3rTdo/Bbi9j+uSIW0zcOYI0md0xbW4j6W +PHFxJ/rOe3KUn/hfS4DGeQhcETYJOxEfXjZyGlSMKsv+CSEvmuki2TM5s9h+sqzZXkm zFMImG52kUZ92kxbvfqyxdPPLXjw/DJeyVb7bUVcVONfdKFL8z9+VjLIhMS0+re2GE2O zEwtBtEBHkyndAa1lteLDV2QAeqC8zrgH0gfV610xTUo+Pm8uYlqrCTPp0id3O0nqgM8 EO4A4dGanmX/FeoSb2uM1T+dObQeuLR3ZhqUU9X+KEIF6pPvyCLlK8E7wcVNgFeDCjlE Uraw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1682642516; x=1685234516; 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=Ezb/mtBWXto18t5BMeGyfP88KWTxkli4FptKeY/x46M=; b=iO2Go+oTEN0oq05aKGX+Z49nlUsCrlfYil4M2k5PzcxaxAzKMoljtoeagtOpGDvXLl +2fKwXj0swYyIfxLzK6M+dP+xt9ppDEhOkEPF/zakFJ4zC785Gfx5edSed2o4oO4koiO C+xX/3/efXdKF5CxurbeqrCvyIpNa2YDYEVZLPmXFNzEPxNB2xSO/LJFW5801v5fhtgi 6r9YBZREXu8MpRMube5uyh4XqUpEY+hiz3GjAVO/ub4szo4dWaZCHk6ev+RVUCKbeaFi kxoJH4oJBFXIcnzh47xxXBy2RGZ+hkRSxvNtvckHqOig/5ONzkOQEYbyyXQKhNDtjPD+ W4LA== X-Gm-Message-State: AC+VfDye12lzLFh2f0zqxunRgGnotFU1GpQI1eAkwU0kxXh7FBmSEuPC wg8wSEczrS4F4wwc5W92dDxZJvXhSb0+zg== X-Google-Smtp-Source: ACHHUZ4uSTJSvROEy8sBOqqJIAEA7UBFzhEBDJSv45cu5mSBlwmubK7GVOYVl6ekjsL6kpRFWsParYbdrONO0g== X-Received: from yjq3.c.googlers.com ([fda3:e722:ac3:cc00:24:72f4:c0a8:272f]) (user=jiaqiyan job=sendgmr) by 2002:a63:2885:0:b0:513:953f:fee4 with SMTP id bs127-20020a632885000000b00513953ffee4mr815399pgb.10.1682642516710; Thu, 27 Apr 2023 17:41:56 -0700 (PDT) Date: Fri, 28 Apr 2023 00:41:39 +0000 In-Reply-To: <20230428004139.2899856-1-jiaqiyan@google.com> Mime-Version: 1.0 References: <20230428004139.2899856-1-jiaqiyan@google.com> X-Mailer: git-send-email 2.40.1.495.gc816e09b53d-goog Message-ID: <20230428004139.2899856-8-jiaqiyan@google.com> Subject: [RFC PATCH v1 7/7] selftest/mm: test PAGESIZE unmapping UFFD WP marker HWPOISON pages From: Jiaqi Yan To: mike.kravetz@oracle.com, peterx@redhat.com, naoya.horiguchi@nec.com Cc: songmuchun@bytedance.com, duenwen@google.com, axelrasmussen@google.com, jthoughton@google.com, rientjes@google.com, linmiaohe@huawei.com, shy828301@gmail.com, baolin.wang@linux.alibaba.com, wangkefeng.wang@huawei.com, akpm@linux-foundation.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, Jiaqi Yan X-Rspam-User: X-Rspamd-Server: rspam03 X-Stat-Signature: nbugnt7c7iosfjci4jqn93u3h1idgx45 X-Rspamd-Queue-Id: 5B701140011 X-HE-Tag: 1682642517-624822 X-HE-Meta: U2FsdGVkX188yX30+75/yXR+ksg5VL/Gro7+z5b1eHpIo5rdIT9qNRdr65B5gwOYvcj6zq/z5nkIVIreqYZXA2kCweP2XaynJalc13yL3ypY9WF0ZhK4W3w4WdFY8iaa9cOhTWmzPoNN5116NhisZaySCr8y/muAI1jxVbsIcCQwmr90mhnAQe13rMHNLa0Y97dSTkw/R4euBVZS+AcbwiUmQlb12JR285rJMZpsDpmkl/+c8RauQagsUCspCLD5DSIn4yDES6L/6InfoEGRO8N/YVgGe5hR8Agi0y+K/zF7UrcuztdgsYyIXM/NdRpOs6TdJHZrZMv+G6txjfPu5B30i9RquIjw8Mt3YDH0w9kgFHhxeOsTYYy24M8kf3+JxKXOUs4m0KvOqMLjGC9ozfhrNgB2LWXUtP/Mr/3tObBQP5bzBOdVLS35PrJ+6d/5ohH3HLQvvaEr2gH5DG1O+tacQuIzXJqhACXhU29mCwMFLGeOaXfcmfNx7CbocUp03WDZVPl5Yo66GDtKPlMs4j21djdd7A4CrL7JP0drP9GbsbzdqFKdBSnJO5AdijijIVkPKVDjUmogwu9GHo3Q7hqlPzRIY0py4Qof0sbYzlyxwSn9ebcCJswtRuDi6Pj/PcP3dkezg84iZ7LTeOcGdIvEWPYHSYmV0blmji+btJGRaKZEMO7dlobhkBxsy+enjbH9BOPJj84JU/IQ/xlQ6OZqE3n8zkWhUy8PbSUdsFrsz3Zs0IC9zqzeM2hdMmbpXz+Jxad1wjT30FzBRHBNWTT4KnfjuiHThMOAf0TuJgXqmYIgo2YmU42Xvr6LaWnnZDrGyn7s8ZBGLm/dX89mfN6pPTBpT7/UQ/+KBYONzE6ttA31td6Dt8T2R3RBp66oeCAj74fvtD3eQ2yCUdXG2SztuNB0MSmzp2diSTTWnqUbJkNNQn4UONkITu0cGeEmdvTA1Mw77kgjIXX/eJz glTARqCF renHi7ps+YlWnmtfT6J7sxg4pfkUpn61DIFUqSipDMBxJMgEY+OR2JUQjuYXOBZn4C9ug5BTVEKbww5+9asmPxLY5v/S3ixDdUSJ+DfK54EUsu/c69DADX+c/gzr5EHJfAnBq4Rw81E0IpI5jP/QjGCR1e/URnwAjhjwwm0rcwNpSDy6oR4CrCnPSmFmR2i/GsDnncMGegQNvyOOiDhtCvbB4kHFPO73oI4dV1uaTsN8xxmjZia+m+xnEF0McMJsJAiw75lU7GZFCqYBNdzqVxVm8XxmSvXFa1sJZn6NX19Zyqf0mM8ijIKjAscc2FGDjYSDnnQ88bjTWASdVAC061AOc7Nkq3NwW7Echsx8R6bMZCUezam5oA+sOXlNqxRgen9rksSZOfgEEHU6COyMiF9nZTah03jvxE8DT97mFm552SyyGOSIguCIh05QoRtPr3cEebwgrBGMcNHN30e/N53ak423DHVNp47t2oSYQj21P/ZJgmw+PJg/yKKzjK0rcCD3+pb82Kla3fXMEyr28/slSXnSogEjZE3PRkHuHa6asit79X6tjvR7WJh4LNmFsKjmix+VyOcxP8idyLvfpu58ySHXe/NojBFv+m5l8t6GxONS3usqugONgOQ== 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: For not-yet-faulted hugepage containing HWPOISON raw page, test 1. only HWPOISON raw page will not be faulted, and a BUS_MCEERR_AR SIGBUS will be sent to userspace. 2. healthy raw pages are faulted in as normal. Since the hugepage has been writeprotect by UFFD, non BUS_MCEERR_AR SIGBUS will be sent to userspace. Signed-off-by: Jiaqi Yan --- tools/testing/selftests/mm/hugetlb-hgm.c | 170 +++++++++++++++++++++++ 1 file changed, 170 insertions(+) diff --git a/tools/testing/selftests/mm/hugetlb-hgm.c b/tools/testing/selftests/mm/hugetlb-hgm.c index bc9529986b66..81ee2d99fea8 100644 --- a/tools/testing/selftests/mm/hugetlb-hgm.c +++ b/tools/testing/selftests/mm/hugetlb-hgm.c @@ -515,6 +515,169 @@ static int uffd_register(int uffd, char *primary_map, unsigned long len, return ioctl(uffd, UFFDIO_REGISTER, ®); } +static int setup_present_map(char *present_map, size_t len) +{ + size_t offset = 0; + unsigned char iter = 0; + unsigned long pagesize = getpagesize(); + uint64_t size; + + for (size = len/2; size >= pagesize; + offset += size, size /= 2) { + iter++; + memset(present_map + offset, iter, size); + } + return 0; +} + +static enum test_status test_hwpoison_absent_uffd_wp(int fd, size_t hugepagesize, size_t len) +{ + int uffd; + char *absent_map, *present_map; + struct uffdio_api api; + int register_args; + struct sigaction new, old; + enum test_status status = TEST_SKIPPED; + const unsigned long pagesize = getpagesize(); + const unsigned long hwpoison_index = 128; + char *hwpoison_addr; + + if (hwpoison_index >= (len / pagesize)) { + printf(ERROR_PREFIX "hwpoison_index out of range"); + return TEST_FAILED; + } + + if (ftruncate(fd, len) < 0) { + perror(ERROR_PREFIX "ftruncate failed"); + return TEST_FAILED; + } + + uffd = userfaultfd(O_CLOEXEC); + if (uffd < 0) { + perror(ERROR_PREFIX "uffd not created"); + return TEST_FAILED; + } + + absent_map = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (absent_map == MAP_FAILED) { + perror(ERROR_PREFIX "mmap for ABSENT mapping failed"); + goto close_uffd; + } + printf(PREFIX "ABSENT mapping: %p\n", absent_map); + + api.api = UFFD_API; + api.features = UFFD_FEATURE_SIGBUS | UFFD_FEATURE_EXACT_ADDRESS | + UFFD_FEATURE_EVENT_FORK; + if (ioctl(uffd, UFFDIO_API, &api) == -1) { + perror(ERROR_PREFIX "UFFDIO_API failed"); + goto unmap_absent; + } + + /* + * Register with UFFDIO_REGISTER_MODE_WP to have UFFD WP bit on + * the HugeTLB page table entry. + */ + register_args = UFFDIO_REGISTER_MODE_MISSING | UFFDIO_REGISTER_MODE_WP; + if (uffd_register(uffd, absent_map, len, register_args)) { + perror(ERROR_PREFIX "UFFDIO_REGISTER failed"); + goto unmap_absent; + } + + new.sa_sigaction = &sigbus_handler; + new.sa_flags = SA_SIGINFO; + if (sigaction(SIGBUS, &new, &old) < 0) { + perror(ERROR_PREFIX "could not setup SIGBUS handler"); + goto unmap_absent; + } + + /* + * Set WP markers to the absent huge mapping. With HGM enabled in + * kernel CONFIG, memory_failure will enabled HGM in kernel, + * so no need to enable HGM from userspace. + */ + if (userfaultfd_writeprotect(uffd, absent_map, len, true) < 0) { + status = TEST_FAILED; + goto unmap_absent; + } + + status = TEST_PASSED; + + /* + * With MAP_SHARED hugetlb memory, we cna inject memory error to + * not-yet-faulted mapping (absent_map) by injecting memory error + * to a already faulted mapping (present_map). + */ + present_map = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (present_map == MAP_FAILED) { + perror(ERROR_PREFIX "mmap for non present mapping failed"); + goto close_uffd; + } + printf(PREFIX "PRESENT mapping: %p\n", present_map); + setup_present_map(present_map, len); + + hwpoison_addr = present_map + hwpoison_index * pagesize; + if (madvise(hwpoison_addr, pagesize, MADV_HWPOISON)) { + perror(PREFIX "MADV_HWPOISON a page in PRESENT mapping failed"); + status = TEST_FAILED; + goto unmap_present; + } + + printf(PREFIX "checking poisoned range [%p, %p) (len=%#lx) in PRESENT mapping\n", + hwpoison_addr, hwpoison_addr + pagesize, pagesize); + if (test_sigbus(hwpoison_addr, true) < 0) { + status = TEST_FAILED; + goto done; + } + printf(PREFIX "checking healthy pages in PRESENT mapping\n"); + unsigned long hwpoison_addrs[] = { + (unsigned long)hwpoison_addr, + (unsigned long)hwpoison_addr, + (unsigned long)hwpoison_addr + }; + status = verify_raw_pages(present_map, len, hwpoison_addrs); + if (status != TEST_PASSED) { + printf(ERROR_PREFIX "checking healthy pages failed\n"); + goto done; + } + + for (int i = 0; i < len; i += pagesize) { + if (i == hwpoison_index * pagesize) { + printf(PREFIX "checking poisoned range [%p, %p) (len=%#lx) in ABSENT mapping\n", + absent_map + i, absent_map + i + pagesize, pagesize); + if (test_sigbus(absent_map + i, true) < 0) { + status = TEST_FAILED; + break; + } + } else { + /* + * With UFFD_FEATURE_SIGBUS, we should get a SIGBUS for + * every not faulted (non present) page/byte. + */ + if (test_sigbus(absent_map + i, false) < 0) { + printf(PREFIX "checking healthy range [%p, %p) (len=%#lx) in ABSENT mapping failed\n", + absent_map + i, absent_map + i + pagesize, pagesize); + status = TEST_FAILED; + break; + } + } + } +done: + if (ftruncate(fd, 0) < 0) { + perror(ERROR_PREFIX "ftruncate back to 0 failed"); + status = TEST_FAILED; + } +unmap_present: + printf(PREFIX "Unmap PRESENT mapping=%p\n", absent_map); + munmap(present_map, len); +unmap_absent: + printf(PREFIX "Unmap ABSENT mapping=%p\n", absent_map); + munmap(absent_map, len); +close_uffd: + printf(PREFIX "Close UFFD\n"); + close(uffd); + return status; +} + enum test_type { TEST_DEFAULT, TEST_UFFDWP, @@ -744,6 +907,13 @@ int main(void) printf("HGM hwpoison test: %s\n", status_to_str(status)); if (status == TEST_FAILED) ret = -1; + + printf("HGM hwpoison UFFD-WP marker test...\n"); + status = test_hwpoison_absent_uffd_wp(fd, hugepagesize, len); + printf("HGM hwpoison UFFD-WP marker test: %s\n", + status_to_str(status)); + if (status == TEST_FAILED) + ret = -1; close: close(fd);