(root)/
strace-6.5/
tests/
mbind.c
       1  /*
       2   * Check decoding of mbind syscall.
       3   *
       4   * Copyright (c) 2016-2021 Dmitry V. Levin <ldv@strace.io>
       5   * All rights reserved.
       6   *
       7   * SPDX-License-Identifier: GPL-2.0-or-later
       8   */
       9  
      10  #include "tests.h"
      11  #include "scno.h"
      12  
      13  #include <stdio.h>
      14  #include <unistd.h>
      15  
      16  static const char *errstr;
      17  
      18  static long
      19  k_mbind(const unsigned long start,
      20  	const unsigned long len,
      21  	const unsigned long mode,
      22  	const unsigned long nmask,
      23  	const unsigned long maxnode,
      24  	const unsigned int flags)
      25  {
      26  	const kernel_ulong_t fill = (kernel_ulong_t) 0xdefaced00000000ULL;
      27  	const kernel_ulong_t arg1 = start;
      28  	const kernel_ulong_t arg2 = len;
      29  	const kernel_ulong_t arg3 = mode;
      30  	const kernel_ulong_t arg4 = nmask;
      31  	const kernel_ulong_t arg5 = maxnode;
      32  	const kernel_ulong_t arg6 = fill | flags;
      33  	const long rc = syscall(__NR_mbind, arg1, arg2, arg3, arg4, arg5, arg6);
      34  	errstr = sprintrc(rc);
      35  	return rc;
      36  }
      37  
      38  #if XLAT_RAW
      39  # define out_str	raw
      40  # define flags_str	"0xffffffff"
      41  #elif XLAT_VERBOSE
      42  # define out_str	verbose
      43  # define flags_str	"0xffffffff /* MPOL_MF_STRICT|MPOL_MF_MOVE" \
      44  			"|MPOL_MF_MOVE_ALL|0xfffffff8 */"
      45  #else
      46  # define out_str	abbrev
      47  # define flags_str	"MPOL_MF_STRICT|MPOL_MF_MOVE|MPOL_MF_MOVE_ALL|0xfffffff8"
      48  #endif
      49  
      50  static struct {
      51  	unsigned long val;
      52  	const char *raw;
      53  	const char *verbose;
      54  	const char *abbrev;
      55  } mpol_modes[] = {
      56  	{ ARG_STR(0),
      57  	  "0 /* MPOL_DEFAULT */",
      58  	  "MPOL_DEFAULT" },
      59  	{ ARG_STR(0x1),
      60  	  "0x1 /* MPOL_PREFERRED */",
      61  	  "MPOL_PREFERRED" },
      62  	{ ARG_STR(0x2),
      63  	  "0x2 /* MPOL_BIND */",
      64  	  "MPOL_BIND" },
      65  	{ ARG_STR(0x3),
      66  	  "0x3 /* MPOL_INTERLEAVE */",
      67  	  "MPOL_INTERLEAVE" },
      68  	{ ARG_STR(0x4),
      69  	  "0x4 /* MPOL_LOCAL */",
      70  	  "MPOL_LOCAL" },
      71  	{ ARG_STR(0x5),
      72  	  "0x5 /* MPOL_PREFERRED_MANY */",
      73  	  "MPOL_PREFERRED_MANY" },
      74  	{ ARG_STR(0x8000),
      75  	  "0x8000 /* MPOL_DEFAULT|MPOL_F_STATIC_NODES */",
      76  	  "MPOL_DEFAULT|MPOL_F_STATIC_NODES" },
      77  	{ ARG_STR(0x4001),
      78  	  "0x4001 /* MPOL_PREFERRED|MPOL_F_RELATIVE_NODES */",
      79  	  "MPOL_PREFERRED|MPOL_F_RELATIVE_NODES" },
      80  	{ ARG_STR(0x2002),
      81  	  "0x2002 /* MPOL_BIND|MPOL_F_NUMA_BALANCING */",
      82  	  "MPOL_BIND|MPOL_F_NUMA_BALANCING" },
      83  	{ ARG_STR(0xe003),
      84  	  "0xe003 /* MPOL_INTERLEAVE|MPOL_F_STATIC_NODES|MPOL_F_RELATIVE_NODES"
      85  		"|MPOL_F_NUMA_BALANCING */",
      86  	  "MPOL_INTERLEAVE|MPOL_F_STATIC_NODES|MPOL_F_RELATIVE_NODES"
      87  		"|MPOL_F_NUMA_BALANCING" },
      88  	{ ARG_STR(0x6),
      89  	  "0x6 /* MPOL_??? */",
      90  	  "0x6 /* MPOL_??? */" },
      91  	{ ARG_STR(0xffff1fff),
      92  	  "0xffff1fff /* MPOL_??? */",
      93  	  "0xffff1fff /* MPOL_??? */" },
      94  	{ ARG_STR(0xffffffff),
      95  	  "0xffffffff /* MPOL_F_STATIC_NODES|MPOL_F_RELATIVE_NODES"
      96  		"|MPOL_F_NUMA_BALANCING|0xffff1fff */",
      97  	  "MPOL_F_STATIC_NODES|MPOL_F_RELATIVE_NODES|MPOL_F_NUMA_BALANCING"
      98  		"|0xffff1fff" },
      99  #if SIZEOF_LONG > 4
     100  	{ 0xffffffff00000000UL,
     101  	  "0xffffffff00000000",
     102  	  "0xffffffff00000000 /* MPOL_??? */",
     103  	  "0xffffffff00000000 /* MPOL_??? */" },
     104  	{ 0xffffffffffff1fffUL,
     105  	  "0xffffffffffff1fff",
     106  	  "0xffffffffffff1fff /* MPOL_??? */",
     107  	  "0xffffffffffff1fff /* MPOL_??? */" },
     108  	{ -1UL,
     109  	  "0xffffffffffffffff",
     110  	  "0xffffffffffffffff /* MPOL_F_STATIC_NODES|MPOL_F_RELATIVE_NODES"
     111  		"|MPOL_F_NUMA_BALANCING|0xffffffffffff1fff */",
     112  	  "MPOL_F_STATIC_NODES|MPOL_F_RELATIVE_NODES|MPOL_F_NUMA_BALANCING"
     113  		"|0xffffffffffff1fff" },
     114  #endif
     115  };
     116  
     117  int
     118  main(void)
     119  {
     120  	const unsigned long size = get_page_size();
     121  	unsigned long *const addr = tail_alloc(size);
     122  	const unsigned long start = (unsigned long) 0xfffffff1fffffff2ULL;
     123  	const unsigned long len = (unsigned long) 0xfffffff4fffffff4ULL;
     124  	const unsigned long nodemask = (unsigned long) 0xfffffff5fffffff6ULL;
     125  	const unsigned long maxnode = (unsigned long) 0xfffffff7fffffff8ULL;
     126  
     127  	if (k_mbind((unsigned long) addr, size, mpol_modes[0].val, 0, 0, 0))
     128  		perror_msg_and_skip("mbind");
     129  	printf("mbind(%p, %lu, %s, NULL, 0, 0) = 0\n",
     130  	       addr, size, mpol_modes[0].out_str);
     131  
     132  	for (unsigned int i = 0; i < ARRAY_SIZE(mpol_modes); ++i) {
     133  		if (i) {
     134  			k_mbind((unsigned long) addr, size, mpol_modes[i].val,
     135  				0, 0, 0);
     136  			printf("mbind(%p, %lu, %s, NULL, 0, 0) = %s\n",
     137  			       addr, size, mpol_modes[i].out_str, errstr);
     138  		}
     139  
     140  		k_mbind(start, len, mpol_modes[i].val,
     141  			nodemask, maxnode, -1U);
     142  		printf("mbind(%#lx, %lu, %s, %#lx, %lu, %s) = %s\n",
     143  		       start, len, mpol_modes[i].out_str,
     144  		       nodemask, maxnode, flags_str, errstr);
     145  	}
     146  
     147  	puts("+++ exited with 0 +++");
     148  	return 0;
     149  }