From: Pu Lehui <pulehui@huawei.com>
Add test about uprobe pte be orphan during vma merge.
Signed-off-by: Pu Lehui <pulehui@huawei.com>
---
tools/testing/selftests/mm/merge.c | 42 ++++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/tools/testing/selftests/mm/merge.c b/tools/testing/selftests/mm/merge.c
index c76646cdf6e6..8e1f38d23384 100644
--- a/tools/testing/selftests/mm/merge.c
+++ b/tools/testing/selftests/mm/merge.c
@@ -2,11 +2,13 @@
#define _GNU_SOURCE
#include "../kselftest_harness.h"
+#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/wait.h>
+#include <linux/perf_event.h>
#include "vm_util.h"
FIXTURE(merge)
@@ -452,4 +454,44 @@ TEST_F(merge, forked_source_vma)
ASSERT_EQ(procmap->query.vma_end, (unsigned long)ptr2 + 5 * page_size);
}
+TEST_F(merge, handle_uprobe_upon_merged_vma)
+{
+ const size_t attr_sz = sizeof(struct perf_event_attr);
+ unsigned int page_size = self->page_size;
+ const char *probe_file = "./foo";
+ char *carveout = self->carveout;
+ struct perf_event_attr attr;
+ unsigned long type;
+ void *ptr1, *ptr2;
+ int fd;
+
+ fd = open(probe_file, O_RDWR|O_CREAT, 0600);
+ ASSERT_GE(fd, 0);
+
+ ASSERT_EQ(ftruncate(fd, page_size), 0);
+ ASSERT_EQ(read_sysfs("/sys/bus/event_source/devices/uprobe/type", &type), 0);
+
+ memset(&attr, 0, attr_sz);
+ attr.size = attr_sz;
+ attr.type = type;
+ attr.config1 = (__u64)(long)probe_file;
+ attr.config2 = 0x0;
+
+ ASSERT_GE(syscall(__NR_perf_event_open, &attr, 0, -1, -1, 0), 0);
+
+ ptr1 = mmap(&carveout[page_size], 10 * page_size, PROT_EXEC,
+ MAP_PRIVATE | MAP_FIXED, fd, 0);
+ ASSERT_NE(ptr1, MAP_FAILED);
+
+ ptr2 = mremap(ptr1, page_size, 2 * page_size,
+ MREMAP_MAYMOVE | MREMAP_FIXED, ptr1 + 5 * page_size);
+ ASSERT_NE(ptr2, MAP_FAILED);
+
+ ASSERT_NE(mremap(ptr2, page_size, page_size,
+ MREMAP_MAYMOVE | MREMAP_FIXED, ptr1), MAP_FAILED);
+
+ close(fd);
+ remove(probe_file);
+}
+
TEST_HARNESS_MAIN
--
2.34.1
Hi,
kselftest-mm test 'merge.handle_uprobe_upon_merged_vma' is failing
against mainline master v6.16-rc1 with Arm64 on Ampere Altra/TX2 in our
CI. The kernel was built using defconfig along with the additional
config fragment from:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/testing/selftests/mm/config
I understand the failure is already being discussed and is expected to be
addressed by including sys/syscall.h.Sharing this observation here
for reference.
A bisect identified commit efe99fabeb11b030c89a7dc5a5e7a7558d0dc7ec as the
first bad commit. This was bisected against tag v6.16-rc1 from:
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
This test passes on Linux version v6.15-13627-g119b1e61a769.
Failure log:
7151 12:46:54.627936 # # # RUN merge.handle_uprobe_upon_merged_vma ...
7152 12:46:54.639014 # # f /sys/bus/event_source/devices/uprobe/type
7153 12:46:54.639306 # # fopen: No such file or directory
7154 12:46:54.650451 # # # merge.c:473:handle_uprobe_upon_merged_vma:Expected read_sysfs("/sys/bus/event_source/devices/uprobe/type", &type) (1) == 0 (0)
7155 12:46:54.650730 # # # handle_uprobe_upon_merged_vma: Test terminated by assertion
7156 12:46:54.661750 # # # FAIL merge.handle_uprobe_upon_merged_vma
7157 12:46:54.662030 # # not ok 8 merge.handle_uprobe_upon_merged_vma
Git bisection log:
git bisect start
# status: waiting for both good and bad commits
# good: [119b1e61a769aa98e68599f44721661a4d8c55f3] Merge tag 'riscv-for-linus-6.16-mw1' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux
git bisect good 119b1e61a769aa98e68599f44721661a4d8c55f3
# status: waiting for bad commit, 1 good commit known
# bad: [19272b37aa4f83ca52bdf9c16d5d81bdd1354494] Linux 6.16-rc1
git bisect bad 19272b37aa4f83ca52bdf9c16d5d81bdd1354494
# bad: [b3154a6ff1f53b794c01096577700f35b1be9cc2] Merge tag 'sh-for-v6.16-tag1' of git://git.kernel.org/pub/scm/linux/kernel/git/glaubitz/sh-linux
git bisect bad b3154a6ff1f53b794c01096577700f35b1be9cc2
# bad: [5b032cac622533631b8f9b7826498b7ce75001c6] Merge tag 'ubifs-for-linus-6.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/ubifs
git bisect bad 5b032cac622533631b8f9b7826498b7ce75001c6
# good: [2da20fd904f87f7bb31b79719bc3dda4093f8cdb] kernel/rcu/tree_stall: add /sys/kernel/rcu_stall_count
git bisect good 2da20fd904f87f7bb31b79719bc3dda4093f8cdb
# good: [d3c82f618a9c2b764b7651afe16594ffeb50ade9] Merge tag 'mm-hotfixes-stable-2025-06-06-16-02' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
git bisect good d3c82f618a9c2b764b7651afe16594ffeb50ade9
# bad: [efe99fabeb11b030c89a7dc5a5e7a7558d0dc7ec] selftests/mm: add test about uprobe pte be orphan during vma merge
git bisect bad efe99fabeb11b030c89a7dc5a5e7a7558d0dc7ec
# good: [2b12d06c37fd3a394376f42f026a7478d826ed63] mm: fix uprobe pte be overwritten when expanding vma
git bisect good 2b12d06c37fd3a394376f42f026a7478d826ed63
# good: [6fb6223347d5d9512875120267c117e7437f0db6] selftests/mm: extract read_sysfs and write_sysfs into vm_util
git bisect good 6fb6223347d5d9512875120267c117e7437f0db6
# first bad commit: [efe99fabeb11b030c89a7dc5a5e7a7558d0dc7ec] selftests/mm: add test about uprobe pte be orphan during vma merge
Thanks,
Aishwarya
On Tue, Jun 10, 2025 at 11:37:29AM +0100, Aishwarya wrote:
> Hi,
>
> kselftest-mm test 'merge.handle_uprobe_upon_merged_vma' is failing
> against mainline master v6.16-rc1 with Arm64 on Ampere Altra/TX2 in our
> CI. The kernel was built using defconfig along with the additional
> config fragment from:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/testing/selftests/mm/config
>
> I understand the failure is already being discussed and is expected to be
> addressed by including sys/syscall.h.Sharing this observation here
> for reference.
This is a different problem.
>
> A bisect identified commit efe99fabeb11b030c89a7dc5a5e7a7558d0dc7ec as the
> first bad commit. This was bisected against tag v6.16-rc1 from:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
>
> This test passes on Linux version v6.15-13627-g119b1e61a769.
>
> Failure log:
>
> 7151 12:46:54.627936 # # # RUN merge.handle_uprobe_upon_merged_vma ...
> 7152 12:46:54.639014 # # f /sys/bus/event_source/devices/uprobe/type
> 7153 12:46:54.639306 # # fopen: No such file or directory
> 7154 12:46:54.650451 # # # merge.c:473:handle_uprobe_upon_merged_vma:Expected read_sysfs("/sys/bus/event_source/devices/uprobe/type", &type) (1) == 0 (0)
> 7155 12:46:54.650730 # # # handle_uprobe_upon_merged_vma: Test terminated by assertion
> 7156 12:46:54.661750 # # # FAIL merge.handle_uprobe_upon_merged_vma
> 7157 12:46:54.662030 # # not ok 8 merge.handle_uprobe_upon_merged_vma
>
So, basically we're not finding the uprobe (I guess CONFIG_UPROBES isn't set in
defconfig, and it's not in the mm/config either), and the test just fails instead
of skipping.
--
Pedro
On Tue, Jun 10, 2025 at 12:27:28PM +0100, Pedro Falcato wrote: > On Tue, Jun 10, 2025 at 11:37:29AM +0100, Aishwarya wrote: > > 7155 12:46:54.650730 # # # handle_uprobe_upon_merged_vma: Test terminated by assertion > > 7156 12:46:54.661750 # # # FAIL merge.handle_uprobe_upon_merged_vma > > 7157 12:46:54.662030 # # not ok 8 merge.handle_uprobe_upon_merged_vma > So, basically we're not finding the uprobe (I guess CONFIG_UPROBES isn't set in > defconfig, and it's not in the mm/config either), and the test just fails instead > of skipping. Indeed: $ grep UPROBES arch/arm64/configs/defconfig tools/testing/selftests/mm/config $
On Thu, May 29, 2025 at 03:56:50PM +0000, Pu Lehui wrote:
> From: Pu Lehui <pulehui@huawei.com>
>
> Add test about uprobe pte be orphan during vma merge.
>
> Signed-off-by: Pu Lehui <pulehui@huawei.com>
> ---
> tools/testing/selftests/mm/merge.c | 42 ++++++++++++++++++++++++++++++
> 1 file changed, 42 insertions(+)
>
> diff --git a/tools/testing/selftests/mm/merge.c b/tools/testing/selftests/mm/merge.c
> index c76646cdf6e6..8e1f38d23384 100644
> --- a/tools/testing/selftests/mm/merge.c
> +++ b/tools/testing/selftests/mm/merge.c
> @@ -2,11 +2,13 @@
>
> #define _GNU_SOURCE
> #include "../kselftest_harness.h"
> +#include <fcntl.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <unistd.h>
> #include <sys/mman.h>
> #include <sys/wait.h>
> +#include <linux/perf_event.h>
> #include "vm_util.h"
Need to include sys/syscall.h...
>
> FIXTURE(merge)
> @@ -452,4 +454,44 @@ TEST_F(merge, forked_source_vma)
> ASSERT_EQ(procmap->query.vma_end, (unsigned long)ptr2 + 5 * page_size);
> }
>
> +TEST_F(merge, handle_uprobe_upon_merged_vma)
> +{
> + const size_t attr_sz = sizeof(struct perf_event_attr);
> + unsigned int page_size = self->page_size;
> + const char *probe_file = "./foo";
> + char *carveout = self->carveout;
> + struct perf_event_attr attr;
> + unsigned long type;
> + void *ptr1, *ptr2;
> + int fd;
> +
> + fd = open(probe_file, O_RDWR|O_CREAT, 0600);
> + ASSERT_GE(fd, 0);
> +
> + ASSERT_EQ(ftruncate(fd, page_size), 0);
> + ASSERT_EQ(read_sysfs("/sys/bus/event_source/devices/uprobe/type", &type), 0);
> +
> + memset(&attr, 0, attr_sz);
> + attr.size = attr_sz;
> + attr.type = type;
> + attr.config1 = (__u64)(long)probe_file;
> + attr.config2 = 0x0;
> +
> + ASSERT_GE(syscall(__NR_perf_event_open, &attr, 0, -1, -1, 0), 0);
...Because this results in:
In file included from merge.c:4:
merge.c: In function ‘merge_handle_uprobe_upon_merged_vma’:
merge.c:480:27: error: ‘__NR_perf_event_open’ undeclared (first use in this function)
480 | ASSERT_GE(syscall(__NR_perf_event_open, &attr, 0, -1, -1, 0), 0);
Otherwise :>)
> +
> + ptr1 = mmap(&carveout[page_size], 10 * page_size, PROT_EXEC,
> + MAP_PRIVATE | MAP_FIXED, fd, 0);
> + ASSERT_NE(ptr1, MAP_FAILED);
> +
> + ptr2 = mremap(ptr1, page_size, 2 * page_size,
> + MREMAP_MAYMOVE | MREMAP_FIXED, ptr1 + 5 * page_size);
> + ASSERT_NE(ptr2, MAP_FAILED);
> +
> + ASSERT_NE(mremap(ptr2, page_size, page_size,
> + MREMAP_MAYMOVE | MREMAP_FIXED, ptr1), MAP_FAILED);
> +
> + close(fd);
> + remove(probe_file);
> +}
> +
> TEST_HARNESS_MAIN
> --
> 2.34.1
>
On 2025/5/30 19:32, Lorenzo Stoakes wrote:
> On Thu, May 29, 2025 at 03:56:50PM +0000, Pu Lehui wrote:
>> From: Pu Lehui <pulehui@huawei.com>
>>
>> Add test about uprobe pte be orphan during vma merge.
>>
>> Signed-off-by: Pu Lehui <pulehui@huawei.com>
>> ---
>> tools/testing/selftests/mm/merge.c | 42 ++++++++++++++++++++++++++++++
>> 1 file changed, 42 insertions(+)
>>
>> diff --git a/tools/testing/selftests/mm/merge.c b/tools/testing/selftests/mm/merge.c
>> index c76646cdf6e6..8e1f38d23384 100644
>> --- a/tools/testing/selftests/mm/merge.c
>> +++ b/tools/testing/selftests/mm/merge.c
>> @@ -2,11 +2,13 @@
>>
>> #define _GNU_SOURCE
>> #include "../kselftest_harness.h"
>> +#include <fcntl.h>
>> #include <stdio.h>
>> #include <stdlib.h>
>> #include <unistd.h>
>> #include <sys/mman.h>
>> #include <sys/wait.h>
>> +#include <linux/perf_event.h>
>> #include "vm_util.h"
>
> Need to include sys/syscall.h...
>
>>
>> FIXTURE(merge)
>> @@ -452,4 +454,44 @@ TEST_F(merge, forked_source_vma)
>> ASSERT_EQ(procmap->query.vma_end, (unsigned long)ptr2 + 5 * page_size);
>> }
>>
>> +TEST_F(merge, handle_uprobe_upon_merged_vma)
>> +{
>> + const size_t attr_sz = sizeof(struct perf_event_attr);
>> + unsigned int page_size = self->page_size;
>> + const char *probe_file = "./foo";
>> + char *carveout = self->carveout;
>> + struct perf_event_attr attr;
>> + unsigned long type;
>> + void *ptr1, *ptr2;
>> + int fd;
>> +
>> + fd = open(probe_file, O_RDWR|O_CREAT, 0600);
>> + ASSERT_GE(fd, 0);
>> +
>> + ASSERT_EQ(ftruncate(fd, page_size), 0);
>> + ASSERT_EQ(read_sysfs("/sys/bus/event_source/devices/uprobe/type", &type), 0);
>> +
>> + memset(&attr, 0, attr_sz);
>> + attr.size = attr_sz;
>> + attr.type = type;
>> + attr.config1 = (__u64)(long)probe_file;
>> + attr.config2 = 0x0;
>> +
>> + ASSERT_GE(syscall(__NR_perf_event_open, &attr, 0, -1, -1, 0), 0);
>
> ...Because this results in:
>
> In file included from merge.c:4:
> merge.c: In function ‘merge_handle_uprobe_upon_merged_vma’:
> merge.c:480:27: error: ‘__NR_perf_event_open’ undeclared (first use in this function)
> 480 | ASSERT_GE(syscall(__NR_perf_event_open, &attr, 0, -1, -1, 0), 0);
>
I did not encounter this problem when compiling in the
tools/testing/selftests/mm directory, but in any case, adding the
sys/syscall.h header file makes sense.
> Otherwise :>)
>
>> +
>> + ptr1 = mmap(&carveout[page_size], 10 * page_size, PROT_EXEC,
>> + MAP_PRIVATE | MAP_FIXED, fd, 0);
>> + ASSERT_NE(ptr1, MAP_FAILED);
>> +
>> + ptr2 = mremap(ptr1, page_size, 2 * page_size,
>> + MREMAP_MAYMOVE | MREMAP_FIXED, ptr1 + 5 * page_size);
>> + ASSERT_NE(ptr2, MAP_FAILED);
>> +
>> + ASSERT_NE(mremap(ptr2, page_size, page_size,
>> + MREMAP_MAYMOVE | MREMAP_FIXED, ptr1), MAP_FAILED);
>> +
>> + close(fd);
>> + remove(probe_file);
>> +}
>> +
>> TEST_HARNESS_MAIN
>> --
>> 2.34.1
>>
On Tue, Jun 03, 2025 at 03:08:22PM +0800, Pu Lehui wrote:
>
>
> On 2025/5/30 19:32, Lorenzo Stoakes wrote:
> > On Thu, May 29, 2025 at 03:56:50PM +0000, Pu Lehui wrote:
> > > From: Pu Lehui <pulehui@huawei.com>
> > >
> > > Add test about uprobe pte be orphan during vma merge.
> > >
> > > Signed-off-by: Pu Lehui <pulehui@huawei.com>
> > > ---
> > > tools/testing/selftests/mm/merge.c | 42 ++++++++++++++++++++++++++++++
> > > 1 file changed, 42 insertions(+)
> > >
> > > diff --git a/tools/testing/selftests/mm/merge.c b/tools/testing/selftests/mm/merge.c
> > > index c76646cdf6e6..8e1f38d23384 100644
> > > --- a/tools/testing/selftests/mm/merge.c
> > > +++ b/tools/testing/selftests/mm/merge.c
> > > @@ -2,11 +2,13 @@
> > >
> > > #define _GNU_SOURCE
> > > #include "../kselftest_harness.h"
> > > +#include <fcntl.h>
> > > #include <stdio.h>
> > > #include <stdlib.h>
> > > #include <unistd.h>
> > > #include <sys/mman.h>
> > > #include <sys/wait.h>
> > > +#include <linux/perf_event.h>
> > > #include "vm_util.h"
> >
> > Need to include sys/syscall.h...
> >
> > >
> > > FIXTURE(merge)
> > > @@ -452,4 +454,44 @@ TEST_F(merge, forked_source_vma)
> > > ASSERT_EQ(procmap->query.vma_end, (unsigned long)ptr2 + 5 * page_size);
> > > }
> > >
> > > +TEST_F(merge, handle_uprobe_upon_merged_vma)
> > > +{
> > > + const size_t attr_sz = sizeof(struct perf_event_attr);
> > > + unsigned int page_size = self->page_size;
> > > + const char *probe_file = "./foo";
> > > + char *carveout = self->carveout;
> > > + struct perf_event_attr attr;
> > > + unsigned long type;
> > > + void *ptr1, *ptr2;
> > > + int fd;
> > > +
> > > + fd = open(probe_file, O_RDWR|O_CREAT, 0600);
> > > + ASSERT_GE(fd, 0);
> > > +
> > > + ASSERT_EQ(ftruncate(fd, page_size), 0);
> > > + ASSERT_EQ(read_sysfs("/sys/bus/event_source/devices/uprobe/type", &type), 0);
> > > +
> > > + memset(&attr, 0, attr_sz);
> > > + attr.size = attr_sz;
> > > + attr.type = type;
> > > + attr.config1 = (__u64)(long)probe_file;
> > > + attr.config2 = 0x0;
> > > +
> > > + ASSERT_GE(syscall(__NR_perf_event_open, &attr, 0, -1, -1, 0), 0);
> >
> > ...Because this results in:
> >
> > In file included from merge.c:4:
> > merge.c: In function ‘merge_handle_uprobe_upon_merged_vma’:
> > merge.c:480:27: error: ‘__NR_perf_event_open’ undeclared (first use in this function)
> > 480 | ASSERT_GE(syscall(__NR_perf_event_open, &attr, 0, -1, -1, 0), 0);
> >
>
> I did not encounter this problem when compiling in the
> tools/testing/selftests/mm directory, but in any case, adding the
> sys/syscall.h header file makes sense.
Weird, it can depend on what system headers are implicitly included due to a
header in the dependency chain including something else. At any rate, I think
Andrew has already updated this?
If you send a respin obviously do include this fix.
>
> > Otherwise :>)
> >
> > > +
> > > + ptr1 = mmap(&carveout[page_size], 10 * page_size, PROT_EXEC,
> > > + MAP_PRIVATE | MAP_FIXED, fd, 0);
> > > + ASSERT_NE(ptr1, MAP_FAILED);
> > > +
> > > + ptr2 = mremap(ptr1, page_size, 2 * page_size,
> > > + MREMAP_MAYMOVE | MREMAP_FIXED, ptr1 + 5 * page_size);
> > > + ASSERT_NE(ptr2, MAP_FAILED);
> > > +
> > > + ASSERT_NE(mremap(ptr2, page_size, page_size,
> > > + MREMAP_MAYMOVE | MREMAP_FIXED, ptr1), MAP_FAILED);
> > > +
> > > + close(fd);
> > > + remove(probe_file);
> > > +}
> > > +
> > > TEST_HARNESS_MAIN
> > > --
> > > 2.34.1
> > >
>
© 2016 - 2026 Red Hat, Inc.