(root)/
strace-6.5/
tests/
set_mempolicy.c
       1  /*
       2   * Check decoding of set_mempolicy syscall.
       3   *
       4   * Copyright (c) 2016 Dmitry V. Levin <ldv@strace.io>
       5   * Copyright (c) 2016-2022 The strace developers.
       6   * All rights reserved.
       7   *
       8   * SPDX-License-Identifier: GPL-2.0-or-later
       9   */
      10  
      11  #include "tests.h"
      12  #include "scno.h"
      13  
      14  #include <stdio.h>
      15  #include <string.h>
      16  #include <unistd.h>
      17  
      18  #define MAX_STRLEN 3
      19  #define NLONGS(n) ((n + 8 * sizeof(long) - 2) \
      20  		      / (8 * sizeof(long)))
      21  
      22  static const char *errstr;
      23  
      24  static long
      25  k_set_mempolicy(const unsigned int mode,
      26  		const void *const nmask,
      27  		const unsigned long maxnode)
      28  {
      29  	const kernel_ulong_t fill = (kernel_ulong_t) 0xdefaced00000000ULL;
      30  	const kernel_ulong_t bad = (kernel_ulong_t) 0xbadc0dedbadc0dedULL;
      31  	const kernel_ulong_t arg1 = fill | mode;
      32  	const kernel_ulong_t arg2 = (unsigned long) nmask;
      33  	const kernel_ulong_t arg3 = maxnode;
      34  	const long rc = syscall(__NR_set_mempolicy,
      35  				arg1, arg2, arg3, bad, bad, bad);
      36  	errstr = sprintrc(rc);
      37  	return rc;
      38  }
      39  
      40  #if XLAT_RAW
      41  # define out_str	raw
      42  #elif XLAT_VERBOSE
      43  # define out_str	verbose
      44  #else
      45  # define out_str	abbrev
      46  #endif
      47  
      48  static struct {
      49  	unsigned int val;
      50  	const char *raw;
      51  	const char *verbose;
      52  	const char *abbrev;
      53  } mpol_modes[] = {
      54  	{ ARG_STR(0),
      55  	  "0 /* MPOL_DEFAULT */",
      56  	  "MPOL_DEFAULT" },
      57  	{ ARG_STR(0x1),
      58  	  "0x1 /* MPOL_PREFERRED */",
      59  	  "MPOL_PREFERRED" },
      60  	{ ARG_STR(0x2),
      61  	  "0x2 /* MPOL_BIND */",
      62  	  "MPOL_BIND" },
      63  	{ ARG_STR(0x3),
      64  	  "0x3 /* MPOL_INTERLEAVE */",
      65  	  "MPOL_INTERLEAVE" },
      66  	{ ARG_STR(0x4),
      67  	  "0x4 /* MPOL_LOCAL */",
      68  	  "MPOL_LOCAL" },
      69  	{ ARG_STR(0x5),
      70  	  "0x5 /* MPOL_PREFERRED_MANY */",
      71  	  "MPOL_PREFERRED_MANY" },
      72  	{ ARG_STR(0x8000),
      73  	  "0x8000 /* MPOL_DEFAULT|MPOL_F_STATIC_NODES */",
      74  	  "MPOL_DEFAULT|MPOL_F_STATIC_NODES" },
      75  	{ ARG_STR(0x4001),
      76  	  "0x4001 /* MPOL_PREFERRED|MPOL_F_RELATIVE_NODES */",
      77  	  "MPOL_PREFERRED|MPOL_F_RELATIVE_NODES" },
      78  	{ ARG_STR(0x2002),
      79  	  "0x2002 /* MPOL_BIND|MPOL_F_NUMA_BALANCING */",
      80  	  "MPOL_BIND|MPOL_F_NUMA_BALANCING" },
      81  	{ ARG_STR(0xe003),
      82  	  "0xe003 /* MPOL_INTERLEAVE|MPOL_F_STATIC_NODES|MPOL_F_RELATIVE_NODES"
      83  		"|MPOL_F_NUMA_BALANCING */",
      84  	  "MPOL_INTERLEAVE|MPOL_F_STATIC_NODES|MPOL_F_RELATIVE_NODES"
      85  		"|MPOL_F_NUMA_BALANCING" },
      86  	{ ARG_STR(0x6),
      87  	  "0x6 /* MPOL_??? */",
      88  	  "0x6 /* MPOL_??? */" },
      89  	{ ARG_STR(0xffff1fff),
      90  	  "0xffff1fff /* MPOL_??? */",
      91  	  "0xffff1fff /* MPOL_??? */" },
      92  	{ ARG_STR(0xffffffff),
      93  	  "0xffffffff /* MPOL_F_STATIC_NODES|MPOL_F_RELATIVE_NODES"
      94  		"|MPOL_F_NUMA_BALANCING|0xffff1fff */",
      95  	  "MPOL_F_STATIC_NODES|MPOL_F_RELATIVE_NODES|MPOL_F_NUMA_BALANCING|0xffff1fff" }
      96  };
      97  
      98  static void
      99  print_nodes(const unsigned long maxnode, unsigned int offset)
     100  {
     101  	unsigned int nlongs = NLONGS(maxnode);
     102  	if (nlongs <= offset)
     103  		nlongs = 0;
     104  	else
     105  		nlongs -= offset;
     106  	const unsigned int size = nlongs * sizeof(long);
     107  	unsigned long *const nodemask =
     108  		tail_alloc(size ? size : (offset ? 1 : 0));
     109  	memset(nodemask, 0, size);
     110  
     111  	k_set_mempolicy(mpol_modes[0].val, nodemask, maxnode);
     112  
     113  	printf("set_mempolicy(%s, ", mpol_modes[0].out_str);
     114  
     115  	if (nlongs) {
     116  		putc('[', stdout);
     117  		for (unsigned int i = 0; i < nlongs + offset; ++i) {
     118  			if (i)
     119  				fputs(", ", stdout);
     120  			if (i < nlongs) {
     121  				if (i >= MAX_STRLEN) {
     122  					fputs("...", stdout);
     123  					break;
     124  				}
     125  				printf("%#0*lx", (int) sizeof(long) * 2,
     126  				       nodemask[i]);
     127  			} else {
     128  				printf("... /* %p */", nodemask + i);
     129  				break;
     130  			}
     131  		}
     132  		putc(']', stdout);
     133  	} else {
     134  		if (maxnode)
     135  			printf("%p", nodemask);
     136  		else
     137  			printf("[]");
     138  	}
     139  
     140  	printf(", %lu) = %s\n", maxnode, errstr);
     141  }
     142  
     143  static void
     144  test_offset(const unsigned int offset)
     145  {
     146  	unsigned long maxnode = get_page_size() * 8;
     147  
     148  	print_nodes(maxnode, offset);
     149  	print_nodes(maxnode + 1, offset);
     150  	print_nodes(maxnode + 2, offset);
     151  
     152  	maxnode = sizeof(long) * 8;
     153  	print_nodes(0, offset);
     154  	print_nodes(1, offset);
     155  	print_nodes(2, offset);
     156  	print_nodes(maxnode - 1, offset);
     157  	print_nodes(maxnode    , offset);
     158  	print_nodes(maxnode + 1, offset);
     159  	print_nodes(maxnode + 2, offset);
     160  	print_nodes(maxnode * 2 - 1, offset);
     161  	print_nodes(maxnode * 2    , offset);
     162  	print_nodes(maxnode * 2 + 1, offset);
     163  	print_nodes(maxnode * 2 + 2, offset);
     164  	print_nodes(maxnode * 3 - 1, offset);
     165  	print_nodes(maxnode * 3    , offset);
     166  	print_nodes(maxnode * 3 + 1, offset);
     167  	print_nodes(maxnode * 3 + 2, offset);
     168  	print_nodes(maxnode * 4 + 2, offset);
     169  }
     170  
     171  int
     172  main(void)
     173  {
     174  	if (k_set_mempolicy(mpol_modes[0].val, 0, 0))
     175  		perror_msg_and_skip("set_mempolicy");
     176  	printf("set_mempolicy(%s, NULL, 0) = 0\n", mpol_modes[0].out_str);
     177  
     178  	const unsigned long *nodemask = (void *) 0xfacefeedfffffffeULL;
     179  	const unsigned long maxnode = (unsigned long) 0xcafef00ddeadbeefULL;
     180  
     181  	for (unsigned int i = 0; i < ARRAY_SIZE(mpol_modes); ++i) {
     182  		if (i) {
     183  			k_set_mempolicy(mpol_modes[i].val, 0, 0);
     184  			printf("set_mempolicy(%s, NULL, 0) = %s\n",
     185  			       mpol_modes[i].out_str, errstr);
     186  		}
     187  
     188  		k_set_mempolicy(mpol_modes[i].val, nodemask, maxnode);
     189  		printf("set_mempolicy(%s, %p, %lu) = %s\n",
     190  		       mpol_modes[i].out_str, nodemask, maxnode, errstr);
     191  	}
     192  
     193  	test_offset(0);
     194  	test_offset(1);
     195  
     196  	puts("+++ exited with 0 +++");
     197  	return 0;
     198  }