Message ID | 20210324122616.406572-1-omosnace@redhat.com (mailing list archive) |
---|---|
State | Accepted |
Delegated to: | Ondrej Mosnáček |
Headers | show |
Series | [testsuite] tests/userfaultfd: handle __NR_userfaultfd not being defined | expand |
On Wed, Mar 24, 2021 at 1:41 PM Lokesh Gidra <lokeshgidra@google.com> wrote: > > > > On Wed, Mar 24, 2021 at 5:56 PM Ondrej Mosnacek <omosnace@redhat.com> wrote: >> >> On some old kernels (think RHEL-7) __NR_userfaultfd may not be defined >> on certain arches, even though the <linux/userfaultfd.h> header is >> available. To avoid build errors in such environments, abstract the >> userfaultfd syscall into a helper function and make it fail with ENOSYS >> when __NR_userfaultfd is not defined. >> >> Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com> > > > Reviewed-by: Lokesh Gidra <lokeshgidra@google.com> Thanks! > > Thanks for this fix. > > BTW, does it make sense to keep this test enabled on old kernels which don't have SELinux support for userfaultfd? No, it doesn't - that's why I made it return ENOSYS in this case, which will lead to the test being skipped. >> >> --- >> tests/userfaultfd/userfaultfd.c | 17 ++++++++++++++--- >> 1 file changed, 14 insertions(+), 3 deletions(-) >> >> diff --git a/tests/userfaultfd/userfaultfd.c b/tests/userfaultfd/userfaultfd.c >> index a283a83..dd3a9f3 100644 >> --- a/tests/userfaultfd/userfaultfd.c >> +++ b/tests/userfaultfd/userfaultfd.c >> @@ -19,7 +19,7 @@ int page_size; >> >> void *fault_handler_thread(void *arg) >> { >> - long uffd = (long)arg; >> + int uffd = (int)(intptr_t)arg; >> struct uffd_msg msg = {0}; >> struct uffdio_copy uffdio_copy = {0}; >> ssize_t nread; >> @@ -83,6 +83,16 @@ void *fault_handler_thread(void *arg) >> } >> } >> >> +int syscall_userfaultfd(int flags) >> +{ >> +#ifdef __NR_userfaultfd >> + return (int)syscall(__NR_userfaultfd, flags); >> +#else >> + errno = ENOSYS; >> + return -1; >> +#endif >> +} >> + >> int main (int argc, char *argv[]) >> { >> char *addr; >> @@ -92,7 +102,7 @@ int main (int argc, char *argv[]) >> pthread_t thr; // ID of thread that handles page faults >> ssize_t ret; >> >> - long uffd = syscall(__NR_userfaultfd, O_CLOEXEC | O_NONBLOCK); >> + int uffd = syscall_userfaultfd(O_CLOEXEC | O_NONBLOCK); >> if (uffd < 0) { >> if (errno == ENOSYS) { >> return 8; >> @@ -159,7 +169,8 @@ int main (int argc, char *argv[]) >> } >> >> // Create a thread that will process the userfaultfd events >> - ret = pthread_create(&thr, NULL, fault_handler_thread, (void *) uffd); >> + ret = pthread_create(&thr, NULL, fault_handler_thread, >> + (void *)(intptr_t)uffd); >> if (ret != 0) { >> errno = ret; >> perror("pthread_create"); >> -- >> 2.30.2 >>
On Wed, Mar 24, 2021 at 3:08 PM Ondrej Mosnacek <omosnace@redhat.com> wrote: > On Wed, Mar 24, 2021 at 1:41 PM Lokesh Gidra <lokeshgidra@google.com> wrote: > > > > > > > > On Wed, Mar 24, 2021 at 5:56 PM Ondrej Mosnacek <omosnace@redhat.com> wrote: > >> > >> On some old kernels (think RHEL-7) __NR_userfaultfd may not be defined > >> on certain arches, even though the <linux/userfaultfd.h> header is > >> available. To avoid build errors in such environments, abstract the > >> userfaultfd syscall into a helper function and make it fail with ENOSYS > >> when __NR_userfaultfd is not defined. > >> > >> Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com> > > > > > > Reviewed-by: Lokesh Gidra <lokeshgidra@google.com> > > Thanks! And now it's applied: https://github.com/SELinuxProject/selinux-testsuite/commit/611d5247e464c69c343e4c5268f346809cf09bbd
diff --git a/tests/userfaultfd/userfaultfd.c b/tests/userfaultfd/userfaultfd.c index a283a83..dd3a9f3 100644 --- a/tests/userfaultfd/userfaultfd.c +++ b/tests/userfaultfd/userfaultfd.c @@ -19,7 +19,7 @@ int page_size; void *fault_handler_thread(void *arg) { - long uffd = (long)arg; + int uffd = (int)(intptr_t)arg; struct uffd_msg msg = {0}; struct uffdio_copy uffdio_copy = {0}; ssize_t nread; @@ -83,6 +83,16 @@ void *fault_handler_thread(void *arg) } } +int syscall_userfaultfd(int flags) +{ +#ifdef __NR_userfaultfd + return (int)syscall(__NR_userfaultfd, flags); +#else + errno = ENOSYS; + return -1; +#endif +} + int main (int argc, char *argv[]) { char *addr; @@ -92,7 +102,7 @@ int main (int argc, char *argv[]) pthread_t thr; // ID of thread that handles page faults ssize_t ret; - long uffd = syscall(__NR_userfaultfd, O_CLOEXEC | O_NONBLOCK); + int uffd = syscall_userfaultfd(O_CLOEXEC | O_NONBLOCK); if (uffd < 0) { if (errno == ENOSYS) { return 8; @@ -159,7 +169,8 @@ int main (int argc, char *argv[]) } // Create a thread that will process the userfaultfd events - ret = pthread_create(&thr, NULL, fault_handler_thread, (void *) uffd); + ret = pthread_create(&thr, NULL, fault_handler_thread, + (void *)(intptr_t)uffd); if (ret != 0) { errno = ret; perror("pthread_create");
On some old kernels (think RHEL-7) __NR_userfaultfd may not be defined on certain arches, even though the <linux/userfaultfd.h> header is available. To avoid build errors in such environments, abstract the userfaultfd syscall into a helper function and make it fail with ENOSYS when __NR_userfaultfd is not defined. Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com> --- tests/userfaultfd/userfaultfd.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-)