]> granicus.if.org Git - strace/commitdiff
memfd_create: decode hugetlb page size
authorDmitry V. Levin <ldv@altlinux.org>
Sat, 18 Nov 2017 00:19:31 +0000 (00:19 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Sat, 18 Nov 2017 00:19:31 +0000 (00:19 +0000)
Decode alternative hugetlb page sizes introduced by kernel commit
v4.14-rc1~126^2~17.

* configure.ac (AC_CHECK_HEADERS): Add linux/memfd.h.
* memfd_create.c [HAVE_LINUX_MEMFD_H]: Include it.
[!MFD_HUGE_SHIFT] (MFD_HUGE_SHIFT): New macro.
[!MFD_HUGE_MASK] (MFD_HUGE_MASK): Likewise.
(SYS_FUNC(memfd_create)): Print hugetlb page size.
* tests/memfd_create.c: Check it.

configure.ac
memfd_create.c
tests/memfd_create.c

index 29285dbf083746bf5e257c23c702fec4a93e01b6..4927a63aa0122ea36bd7799f228767fee388449e 100644 (file)
@@ -395,6 +395,7 @@ AC_CHECK_HEADERS(m4_normalize([
        linux/ip_vs.h
        linux/ipc.h
        linux/kcmp.h
+       linux/memfd.h
        linux/mmtimer.h
        linux/msg.h
        linux/neighbour.h
index 129497066d4670007a055121725c2d08b895ab76..1f6a6d6de9033bac61ce1f72d6f0db14c4a2e1cd 100644 (file)
 
 #include "defs.h"
 
+#ifdef HAVE_LINUX_MEMFD_H
+# include <linux/memfd.h>
+#endif
+
 #include "xlat/memfd_create_flags.h"
 
+#ifndef MFD_HUGE_SHIFT
+# define MFD_HUGE_SHIFT 26
+#endif
+
+#ifndef MFD_HUGE_MASK
+# define MFD_HUGE_MASK 0x3f
+#endif
+
 SYS_FUNC(memfd_create)
 {
        printpathn(tcp, tcp->u_arg[0], 255 - (sizeof("memfd:") - 1));
        tprints(", ");
-       printflags(memfd_create_flags, tcp->u_arg[1], "MFD_???");
+
+       unsigned int flags = tcp->u_arg[1];
+       const unsigned int mask = MFD_HUGE_MASK << MFD_HUGE_SHIFT;
+       const unsigned int hugetlb_value = flags & mask;
+       flags &= ~mask;
+
+       if (flags || !hugetlb_value)
+               printflags(memfd_create_flags, flags, "MFD_???");
+
+       if (hugetlb_value)
+               tprintf("%s%u<<MFD_HUGE_SHIFT",
+                       flags ? "|" : "",
+                       hugetlb_value >> MFD_HUGE_SHIFT);
 
        return RVAL_DECODED | RVAL_FD;
 }
index 3daa8c9c1061e5b55afd878389b6069f380e555f..8334af84b0f3da2c74408ed34e3f874d8b24951b 100644 (file)
 # include <stdint.h>
 # include <unistd.h>
 
+# ifdef HAVE_LINUX_MEMFD_H
+#  include <linux/memfd.h>
+# endif
+
+# ifndef MFD_HUGE_SHIFT
+#  define MFD_HUGE_SHIFT 26
+# endif
+
+# ifndef MFD_HUGE_MASK
+#  define MFD_HUGE_MASK 0x3f
+# endif
+
 static const char *errstr;
 
 static long
@@ -51,17 +63,34 @@ int
 main(void)
 {
        const size_t size = 255 - (sizeof("memfd:") - 1) + 1;
-       char *const pattern = tail_alloc(size);
+       char *pattern = tail_alloc(size);
        fill_memory_ex(pattern, size, '0', 10);
 
-       const kernel_ulong_t flags = (kernel_ulong_t) 0xfacefeed0000000fULL;
-       k_memfd_create((uintptr_t) pattern, flags);
+       k_memfd_create((uintptr_t) pattern, 0);
+       printf("memfd_create(\"%.*s\"..., 0) = %s\n",
+              (int) size - 1, pattern, errstr);
 
+       kernel_ulong_t flags = (kernel_ulong_t) 0xfacefeed00000007ULL;
+       k_memfd_create((uintptr_t) pattern, flags);
        printf("memfd_create(\"%.*s\"..., %s) = %s\n",
               (int) size - 1, pattern,
-              "MFD_CLOEXEC|MFD_ALLOW_SEALING|MFD_HUGETLB|0x8",
+              "MFD_CLOEXEC|MFD_ALLOW_SEALING|MFD_HUGETLB",
               errstr);
 
+       pattern[size - 1] = '\0';
+       flags = 30 << MFD_HUGE_SHIFT;
+       k_memfd_create((uintptr_t) pattern, flags);
+       printf("memfd_create(\"%s\", 30<<MFD_HUGE_SHIFT) = %s\n",
+              pattern, errstr);
+
+       pattern += size - 1;
+       flags = (kernel_ulong_t) -1ULL;
+       k_memfd_create(0, flags);
+       flags = -1U & ~(7 | (MFD_HUGE_MASK << MFD_HUGE_SHIFT));
+       printf("memfd_create(NULL, MFD_CLOEXEC|MFD_ALLOW_SEALING|MFD_HUGETLB"
+              "|%#x|%u<<MFD_HUGE_SHIFT) = %s\n",
+              (unsigned int) flags, MFD_HUGE_MASK, errstr);
+
        puts("+++ exited with 0 +++");
        return 0;
 }