]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.6-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 17 Oct 2025 07:46:49 +0000 (09:46 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 17 Oct 2025 07:46:49 +0000 (09:46 +0200)
added patches:
selftests-mm-skip-soft-dirty-tests-when-config_mem_soft_dirty-is-disabled.patch

queue-6.6/selftests-mm-skip-soft-dirty-tests-when-config_mem_soft_dirty-is-disabled.patch [new file with mode: 0644]
queue-6.6/series

diff --git a/queue-6.6/selftests-mm-skip-soft-dirty-tests-when-config_mem_soft_dirty-is-disabled.patch b/queue-6.6/selftests-mm-skip-soft-dirty-tests-when-config_mem_soft_dirty-is-disabled.patch
new file mode 100644 (file)
index 0000000..e51c0d9
--- /dev/null
@@ -0,0 +1,192 @@
+From 0389c305ef56cbadca4cbef44affc0ec3213ed30 Mon Sep 17 00:00:00 2001
+From: Lance Yang <lance.yang@linux.dev>
+Date: Wed, 17 Sep 2025 21:31:37 +0800
+Subject: selftests/mm: skip soft-dirty tests when CONFIG_MEM_SOFT_DIRTY is disabled
+
+From: Lance Yang <lance.yang@linux.dev>
+
+commit 0389c305ef56cbadca4cbef44affc0ec3213ed30 upstream.
+
+The madv_populate and soft-dirty kselftests currently fail on systems
+where CONFIG_MEM_SOFT_DIRTY is disabled.
+
+Introduce a new helper softdirty_supported() into vm_util.c/h to ensure
+tests are properly skipped when the feature is not enabled.
+
+Link: https://lkml.kernel.org/r/20250917133137.62802-1-lance.yang@linux.dev
+Fixes: 9f3265db6ae8 ("selftests: vm: add test for Soft-Dirty PTE bit")
+Signed-off-by: Lance Yang <lance.yang@linux.dev>
+Acked-by: David Hildenbrand <david@redhat.com>
+Suggested-by: David Hildenbrand <david@redhat.com>
+Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
+Cc: Shuah Khan <shuah@kernel.org>
+Cc: Gabriel Krisman Bertazi <krisman@collabora.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/mm/madv_populate.c |   21 -------
+ tools/testing/selftests/mm/soft-dirty.c    |    5 +
+ tools/testing/selftests/mm/vm_util.c       |   77 +++++++++++++++++++++++++++++
+ tools/testing/selftests/mm/vm_util.h       |    1 
+ 4 files changed, 84 insertions(+), 20 deletions(-)
+
+--- a/tools/testing/selftests/mm/madv_populate.c
++++ b/tools/testing/selftests/mm/madv_populate.c
+@@ -264,23 +264,6 @@ static void test_softdirty(void)
+       munmap(addr, SIZE);
+ }
+-static int system_has_softdirty(void)
+-{
+-      /*
+-       * There is no way to check if the kernel supports soft-dirty, other
+-       * than by writing to a page and seeing if the bit was set. But the
+-       * tests are intended to check that the bit gets set when it should, so
+-       * doing that check would turn a potentially legitimate fail into a
+-       * skip. Fortunately, we know for sure that arm64 does not support
+-       * soft-dirty. So for now, let's just use the arch as a corse guide.
+-       */
+-#if defined(__aarch64__)
+-      return 0;
+-#else
+-      return 1;
+-#endif
+-}
+-
+ int main(int argc, char **argv)
+ {
+       int nr_tests = 16;
+@@ -288,7 +271,7 @@ int main(int argc, char **argv)
+       pagesize = getpagesize();
+-      if (system_has_softdirty())
++      if (softdirty_supported())
+               nr_tests += 5;
+       ksft_print_header();
+@@ -300,7 +283,7 @@ int main(int argc, char **argv)
+       test_holes();
+       test_populate_read();
+       test_populate_write();
+-      if (system_has_softdirty())
++      if (softdirty_supported())
+               test_softdirty();
+       err = ksft_get_fail_cnt();
+--- a/tools/testing/selftests/mm/soft-dirty.c
++++ b/tools/testing/selftests/mm/soft-dirty.c
+@@ -193,8 +193,11 @@ int main(int argc, char **argv)
+       int pagesize;
+       ksft_print_header();
+-      ksft_set_plan(15);
++      if (!softdirty_supported())
++              ksft_exit_skip("soft-dirty is not support\n");
++
++      ksft_set_plan(15);
+       pagemap_fd = open(PAGEMAP_FILE_PATH, O_RDONLY);
+       if (pagemap_fd < 0)
+               ksft_exit_fail_msg("Failed to open %s\n", PAGEMAP_FILE_PATH);
+--- a/tools/testing/selftests/mm/vm_util.c
++++ b/tools/testing/selftests/mm/vm_util.c
+@@ -97,6 +97,42 @@ uint64_t read_pmd_pagesize(void)
+       return strtoul(buf, NULL, 10);
+ }
++char *__get_smap_entry(void *addr, const char *pattern, char *buf, size_t len)
++{
++      int ret;
++      FILE *fp;
++      char *entry = NULL;
++      char addr_pattern[MAX_LINE_LENGTH];
++
++      ret = snprintf(addr_pattern, MAX_LINE_LENGTH, "%08lx-",
++                     (unsigned long)addr);
++      if (ret >= MAX_LINE_LENGTH)
++              ksft_exit_fail_msg("%s: Pattern is too long\n", __func__);
++
++      fp = fopen(SMAP_FILE_PATH, "r");
++      if (!fp)
++              ksft_exit_fail_msg("%s: Failed to open file %s\n", __func__,
++                                 SMAP_FILE_PATH);
++
++      if (!check_for_pattern(fp, addr_pattern, buf, len))
++              goto err_out;
++
++      /* Fetch the pattern in the same block */
++      if (!check_for_pattern(fp, pattern, buf, len))
++              goto err_out;
++
++      /* Trim trailing newline */
++      entry = strchr(buf, '\n');
++      if (entry)
++              *entry = '\0';
++
++      entry = buf + strlen(pattern);
++
++err_out:
++      fclose(fp);
++      return entry;
++}
++
+ bool __check_huge(void *addr, char *pattern, int nr_hpages,
+                 uint64_t hpage_size)
+ {
+@@ -269,3 +305,44 @@ int uffd_unregister(int uffd, void *addr
+       return ret;
+ }
++
++static bool check_vmflag(void *addr, const char *flag)
++{
++      char buffer[MAX_LINE_LENGTH];
++      const char *flags;
++      size_t flaglen;
++
++      flags = __get_smap_entry(addr, "VmFlags:", buffer, sizeof(buffer));
++      if (!flags)
++              ksft_exit_fail_msg("%s: No VmFlags for %p\n", __func__, addr);
++
++      while (true) {
++              flags += strspn(flags, " ");
++
++              flaglen = strcspn(flags, " ");
++              if (!flaglen)
++                      return false;
++
++              if (flaglen == strlen(flag) && !memcmp(flags, flag, flaglen))
++                      return true;
++
++              flags += flaglen;
++      }
++}
++
++bool softdirty_supported(void)
++{
++      char *addr;
++      bool supported = false;
++      const size_t pagesize = getpagesize();
++
++      /* New mappings are expected to be marked with VM_SOFTDIRTY (sd). */
++      addr = mmap(0, pagesize, PROT_READ | PROT_WRITE,
++                  MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
++      if (!addr)
++              ksft_exit_fail_msg("mmap failed\n");
++
++      supported = check_vmflag(addr, "sd");
++      munmap(addr, pagesize);
++      return supported;
++}
+--- a/tools/testing/selftests/mm/vm_util.h
++++ b/tools/testing/selftests/mm/vm_util.h
+@@ -51,6 +51,7 @@ int uffd_register(int uffd, void *addr,
+ int uffd_unregister(int uffd, void *addr, uint64_t len);
+ int uffd_register_with_ioctls(int uffd, void *addr, uint64_t len,
+                             bool miss, bool wp, bool minor, uint64_t *ioctls);
++bool softdirty_supported(void);
+ /*
+  * On ppc64 this will only work with radix 2M hugepage size
index a06ba7a66f0a6fda57e95a9ceb8dd12f51bcd03d..2a91e8bb8934e91188805d370035a54605715fb9 100644 (file)
@@ -187,3 +187,4 @@ s390-bpf-centralize-frame-offset-calculations.patch
 s390-bpf-describe-the-frame-using-a-struct-instead-of-constants.patch
 s390-bpf-write-back-tail-call-counter-for-bpf_pseudo_call.patch
 s390-bpf-write-back-tail-call-counter-for-bpf_tramp_f_call_orig.patch
+selftests-mm-skip-soft-dirty-tests-when-config_mem_soft_dirty-is-disabled.patch