Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: "Zhao Gongyi" <zhaogongyi@bytedance.com>
To: "Dev Jain" <dev.jain@arm.com>, <catalin.marinas@arm.com>,
	 <will@kernel.org>
Cc: <ryan.roberts@arm.com>, <baolin.wang@linux.alibaba.com>,
	 <lance.yang@linux.dev>, <mark.rutland@arm.com>,
	 <akpm@linux-foundation.org>, <david@kernel.org>,
	<ljs@kernel.org>,  <liam@infradead.org>, <vbabka@kernel.org>,
	<rppt@kernel.org>,  <surenb@google.com>, <mhocko@suse.com>,
	 <linux-arm-kernel@lists.infradead.org>, <linux-mm@kvack.org>,
	 <linux-kernel@vger.kernel.org>, <stable@vger.kernel.org>
Subject: Re: [PATCH] arm64/mm: restrict transparent contpte mappings to valid PTEs
Date: Wed, 14 Oct 2026 14:16:33 +0800	[thread overview]
Message-ID: <24f01ac6-4935-4702-b6e8-52beff5feea0@bytedance.com> (raw)
In-Reply-To: <6a10b61f-5c4f-4d04-9742-97a358147c39@arm.com>

On 2026/10/13 18:13, Dev Jain wrote:
> 
> 
> Thanks, could you please give the code of the reproducer. That will
> save us some time.
> 
> 

Hi Dev,

Sure, sorry for not including it in the first mail.

The standalone reproducer I used is below. It assumes an arm64 kernel 
with CONFIG_ARM64_CONTPTE=y and a CONT_PTE_SIZE anonymous mTHP order 
available. When run as root, it tries to enable THP and the matching 
mTHP order through sysfs. These sysfs writes are best-effort; if the 
matching order is not available or cannot be enabled, the reproducer
may not hit the issue.

On a 4K-page kernel, CONT_PTE_SIZE is 64KB.

Compile and run:

       gcc -O2 -Wall contpte_guard_repro.c -o contpte_guard_repro
       ./contpte_guard_repro 100

On my unfixed KASAN kernel with panic_on_warn=1, the first iteration hit
the bad swap entry / swap_put_entries_direct() warning. With this patch,
100 iterations completed without warnings.

Here is the reproducer:

   #define _GNU_SOURCE
   #include <errno.h>
   #include <fcntl.h>
   #include <stdio.h>
   #include <stdlib.h>
   #include <string.h>
   #include <sys/mman.h>
   #include <unistd.h>

   #ifndef MADV_HUGEPAGE
   #define MADV_HUGEPAGE 14
   #endif
   #ifndef MADV_POPULATE_WRITE
   #define MADV_POPULATE_WRITE 23
   #endif
   #ifndef MADV_GUARD_INSTALL
   #define MADV_GUARD_INSTALL 102
   #endif
   #ifndef MADV_GUARD_REMOVE
   #define MADV_GUARD_REMOVE 103
   #endif

   static void write_file(const char *path, const char *val)
   {
       int fd = open(path, O_WRONLY | O_CLOEXEC);

       if (fd < 0)
           return;
       (void)write(fd, val, strlen(val));
       close(fd);
   }

   static void write_clear_refs(void)
   {
       int fd = open("/proc/self/clear_refs", O_WRONLY | O_CLOEXEC);

       if (fd < 0) {
           perror("open clear_refs");
           exit(1);
       }
       if (write(fd, "1", 1) != 1) {
           perror("write clear_refs");
           exit(1);
       }
       close(fd);
   }

   static unsigned long contpte_size(unsigned long page_size)
   {
       if (page_size == 4096)
           return 64 * 1024;
       if (page_size == 16384 || page_size == 65536)
           return 2 * 1024 * 1024;

       fprintf(stderr, "unsupported page size %lu\n", page_size);
       exit(1);
   }

   static void enable_mthp(unsigned long size)
   {
       char path[256];

       write_file("/sys/kernel/mm/transparent_hugepage/enabled", 
"always\n");
       write_file("/sys/kernel/mm/transparent_hugepage/defrag", "always\n");

       snprintf(path, sizeof(path),
            "/sys/kernel/mm/transparent_hugepage/hugepages-%lukB/enabled",
            size / 1024);
       write_file(path, "always\n");
   }

   static void touch_range(char *p, unsigned long len, unsigned long 
page_size)
   {
       for (unsigned long off = 0; off < len; off += page_size)
           p[off] = (char)off;
   }

   int main(int argc, char **argv)
   {
       const int loops = argc > 1 ? atoi(argv[1]) : 1;
       const unsigned long page_size = sysconf(_SC_PAGESIZE);
       const unsigned long csize = contpte_size(page_size);
       const unsigned long nr_pages = 2 * csize / page_size;
       const unsigned long len = nr_pages * page_size;
       const unsigned long map_len = len + csize;
       const unsigned long guard_idx = csize / page_size - 3;

       enable_mthp(csize);

       for (int i = 0; i < loops; i++) {
           char *map, *p;

           map = mmap(NULL, map_len, PROT_READ | PROT_WRITE,
                  MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
           if (map == MAP_FAILED) {
               perror("mmap");
               return 1;
           }

           p = (char *)(((unsigned long)map + csize - 1) & ~(csize - 1));

           if (madvise(p, len, MADV_HUGEPAGE))
               perror("madvise MADV_HUGEPAGE");
           if (madvise(p, len, MADV_POPULATE_WRITE))
               perror("madvise MADV_POPULATE_WRITE");

           touch_range(p, len, page_size);

           if (mprotect(p, len, PROT_NONE)) {
               perror("mprotect PROT_NONE");
               return 1;
           }
           if (madvise(p + guard_idx * page_size, page_size,
                   MADV_GUARD_INSTALL)) {
               perror("madvise MADV_GUARD_INSTALL");
               return 1;
           }

           write_clear_refs();

           if (munmap(map, map_len)) {
               perror("munmap");
               return 1;
           }
       }

       return 0;
   }


Thanks,
Zhao


  reply	other threads:[~2026-10-14  6:17 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-13  9:36 [PATCH] arm64/mm: restrict transparent contpte mappings to valid PTEs Zhao Gongyi
2026-10-13 10:13 ` Dev Jain
2026-10-14  6:16   ` Zhao Gongyi [this message]
2026-10-13 15:39 ` Lance Yang
2026-10-14  6:31   ` Zhao Gongyi
2026-10-14  6:46     ` Lance Yang
2026-10-14  8:38       ` Baolin Wang
2026-10-14  9:24         ` Lance Yang
2026-10-14  9:35           ` Baolin Wang
2026-10-14 10:03     ` Dev Jain
2026-10-14 10:45       ` Lance Yang
2026-10-14 11:02         ` Dev Jain
2026-10-14  9:41 ` David Hildenbrand (Arm)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=24f01ac6-4935-4702-b6e8-52beff5feea0@bytedance.com \
    --to=zhaogongyi@bytedance.com \
    --cc=akpm@linux-foundation.org \
    --cc=baolin.wang@linux.alibaba.com \
    --cc=catalin.marinas@arm.com \
    --cc=david@kernel.org \
    --cc=dev.jain@arm.com \
    --cc=lance.yang@linux.dev \
    --cc=liam@infradead.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=ljs@kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=mhocko@suse.com \
    --cc=rppt@kernel.org \
    --cc=ryan.roberts@arm.com \
    --cc=stable@vger.kernel.org \
    --cc=surenb@google.com \
    --cc=vbabka@kernel.org \
    --cc=will@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox