From 73ab8676c757355925bcf7ffd721c4b4d99cfe1c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 17 Oct 2025 09:46:49 +0200 Subject: [PATCH] 6.6-stable patches added patches: selftests-mm-skip-soft-dirty-tests-when-config_mem_soft_dirty-is-disabled.patch --- ...en-config_mem_soft_dirty-is-disabled.patch | 192 ++++++++++++++++++ queue-6.6/series | 1 + 2 files changed, 193 insertions(+) create mode 100644 queue-6.6/selftests-mm-skip-soft-dirty-tests-when-config_mem_soft_dirty-is-disabled.patch 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 index 0000000000..e51c0d9a7d --- /dev/null +++ b/queue-6.6/selftests-mm-skip-soft-dirty-tests-when-config_mem_soft_dirty-is-disabled.patch @@ -0,0 +1,192 @@ +From 0389c305ef56cbadca4cbef44affc0ec3213ed30 Mon Sep 17 00:00:00 2001 +From: Lance Yang +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 + +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 +Acked-by: David Hildenbrand +Suggested-by: David Hildenbrand +Cc: Lorenzo Stoakes +Cc: Shuah Khan +Cc: Gabriel Krisman Bertazi +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + 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 diff --git a/queue-6.6/series b/queue-6.6/series index a06ba7a66f..2a91e8bb89 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -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 -- 2.47.3