]> granicus.if.org Git - strace/commitdiff
userfaultfd: enhance decoding of struct uffdio_api.features
authorDmitry V. Levin <ldv@altlinux.org>
Wed, 19 Jul 2017 00:33:56 +0000 (00:33 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Wed, 19 Jul 2017 00:33:56 +0000 (00:33 +0000)
As struct uffdio_api.features has read-write semantics,
print the value returned by the kernel only when it differs
from the value passed to the kernel.

* userfaultfd.c (uffdio_ioctl) <UFFDIO_API>: On entering syscall,
save the value of struct uffdio_api.features.  On exiting syscall, do
not print struct uffdio_api.features when it's the same as on entering.
* tests/ioctl_uffdio.c (main): Update expected output.

tests/ioctl_uffdio.c
userfaultfd.c

index a4115c55e3d6c431698b0ecc87d8bc2c99cb6f5d..24c642a710533647f0eb934efc5a9fb7363363ee 100644 (file)
@@ -70,10 +70,12 @@ main(void)
        api_struct->api = UFFD_API;
        api_struct->features = 0;
        rc = ioctl(fd, UFFDIO_API, api_struct);
-       printf("ioctl(%d, UFFDIO_API, {api=0xaa, features=0"
-              " => features=%#" PRIx64 ", ioctls=1<<_UFFDIO_REGISTER|"
-              "1<<_UFFDIO_UNREGISTER|1<<_UFFDIO_API",
-              fd, (uint64_t)api_struct->features);
+       printf("ioctl(%d, UFFDIO_API, {api=0xaa, features=0", fd);
+       if (api_struct->features)
+               printf(" => features=%#" PRIx64,
+                      (uint64_t) api_struct->features);
+       printf(", ioctls=1<<_UFFDIO_REGISTER|"
+              "1<<_UFFDIO_UNREGISTER|1<<_UFFDIO_API");
        api_struct->ioctls &= ~(1ull<<_UFFDIO_REGISTER|
                                1ull<<_UFFDIO_UNREGISTER|
                                1ull<<_UFFDIO_API);
index 41224e2f0d9bbabda6d1e284b560a129be38ae18..07a305b5686656a227326911da009c48d979c27a 100644 (file)
@@ -69,6 +69,7 @@ uffdio_ioctl(struct tcb *const tcp, const unsigned int code,
 {
        switch (code) {
        case UFFDIO_API: {
+               uint64_t *entering_features;
                struct uffdio_api ua;
                if (entering(tcp)) {
                        tprints(", ");
@@ -79,9 +80,18 @@ uffdio_ioctl(struct tcb *const tcp, const unsigned int code,
                         */
                        PRINT_FIELD_X("{", ua, api);
                        PRINT_FIELD_X(", ", ua, features);
+                       entering_features = malloc(sizeof(*entering_features));
+                       if (entering_features) {
+                               *entering_features = ua.features;
+                               set_tcb_priv_data(tcp, entering_features, free);
+                       }
                } else {
                        if (!syserror(tcp) && !umove(tcp, arg, &ua)) {
-                               PRINT_FIELD_X(" => ", ua, features);
+                               entering_features = get_tcb_priv_data(tcp);
+                               if (!entering_features
+                                   || *entering_features != ua.features) {
+                                       PRINT_FIELD_X(" => ", ua, features);
+                               }
                                PRINT_FIELD_FLAGS64(", ", ua, ioctls,
                                                    uffd_api_flags,
                                                    "_UFFDIO_???");