Re: userfaultfd: two-step UFFDIO_API always gives -EINVAL

From: stsp
Date: Mon Nov 25 2024 - 04:07:20 EST


23.11.2024 18:13, stsp пишет:
Hello.

I tried to use userfaultfd and got
that strange result: when I first do
UFFDIO_API ioctl with features = 0,
it succeeds. I check the needed
features, and they are all in place.
But on the second step, where I
request the needed features,
UFFDIO_API gives -EINVAL no matter
what features I requested (or even
set features to 0 again).
With the test patch below, the
problem can be reproduced. All
the code in selftests suggest
that UFFDIO_API should not be
called twice, whereas man page
says this:

```
       After the userfaultfd object is created with userfaultfd(), the applica‐
       tion must enable it using the UFFDIO_API ioctl(2) operation. This oper‐
       ation allows a two-step handshake between the kernel and user  space  to
       determine what API version and features the kernel supports, and then to
       enable  those  features  user  space wants.
```
But the second part doesn't work and
is never being tested in selftests.
So is this a documentation problem?

This patch can be used to make
sure the second call doesn't work:

--- a/tools/testing/selftests/mm/uffd-unit-tests.c
+++ b/tools/testing/selftests/mm/uffd-unit-tests.c
@@ -171,6 +171,14 @@ static int test_uffd_api(bool use_dev)
                goto out;
        }

+       /* Request valid feature via UFFDIO_API */
+       uffdio_api.api = UFFD_API;
+       uffdio_api.features = UFFD_FEATURE_PAGEFAULT_FLAG_WP;
+       if (ioctl(uffd, UFFDIO_API, &uffdio_api)) {
+               uffd_test_fail("UFFDIO_API should succeed but failed");
+               exit(1);
+       }
+
        uffd_test_pass();
 out:
        close(uffd);