From: Dmitry V. Levin Date: Wed, 19 Jul 2017 00:33:56 +0000 (+0000) Subject: userfaultfd: enhance decoding of struct uffdio_api.features X-Git-Tag: v4.19~249 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=16eded4c4b53d9ac4fa90860f05abeb96855185a;p=strace userfaultfd: enhance decoding of struct uffdio_api.features 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) : 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. --- diff --git a/tests/ioctl_uffdio.c b/tests/ioctl_uffdio.c index a4115c55..24c642a7 100644 --- a/tests/ioctl_uffdio.c +++ b/tests/ioctl_uffdio.c @@ -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); diff --git a/userfaultfd.c b/userfaultfd.c index 41224e2f..07a305b5 100644 --- a/userfaultfd.c +++ b/userfaultfd.c @@ -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_???");