memfd_create: decode hugetlb page size

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.
This commit is contained in:
Дмитрий Левин 2017-11-18 00:19:31 +00:00
parent c75392f67a
commit 1898689dbf
3 changed files with 59 additions and 5 deletions

View 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

View File

@ -28,13 +28,37 @@
#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;
}

View File

@ -37,6 +37,18 @@
# 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;
}