diff mbox series

[testsuite] tests/userfaultfd: handle __NR_userfaultfd not being defined

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

Commit Message

Ondrej Mosnacek March 24, 2021, 12:26 p.m. UTC
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(-)

Comments

Ondrej Mosnacek March 24, 2021, 2:08 p.m. UTC | #1
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
>>
Ondrej Mosnacek March 29, 2021, 8:42 a.m. UTC | #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 mbox series

Patch

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");