1 /* 2 * Check decoding of get_mempolicy syscall. 3 * 4 * Copyright (c) 2016 Dmitry V. Levin <ldv (at) altlinux.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include "tests.h" 31 #include <asm/unistd.h> 32 33 #ifdef __NR_get_mempolicy 34 35 # include <stdio.h> 36 # include <unistd.h> 37 38 # include "xlat.h" 39 # include "xlat/policies.h" 40 41 # define MAX_STRLEN 3 42 # define NLONGS(n) ((n + 8 * sizeof(long) - 2) \ 43 / (8 * sizeof(long))) 44 45 static void 46 print_nodes(unsigned long maxnode) 47 { 48 unsigned long *const nodemask = 49 tail_alloc(sizeof(*nodemask) * NLONGS(maxnode)); 50 51 if (syscall(__NR_get_mempolicy, 0, nodemask, maxnode, 0, 0)) { 52 printf("get_mempolicy(NULL, %p, %lu, NULL, 0) = -1 %s (%m)\n", 53 nodemask, maxnode, errno2name()); 54 return; 55 } 56 57 printf("get_mempolicy(NULL, ["); 58 59 unsigned int nlongs = NLONGS(maxnode); 60 unsigned int i; 61 for (i = 0; i < nlongs; ++i) { 62 if (i) 63 fputs(", ", stdout); 64 if (i >= MAX_STRLEN) { 65 fputs("...", stdout); 66 break; 67 } 68 printf("%#0*lx", (int) sizeof(*nodemask) * 2 + 2, nodemask[i]); 69 } 70 71 printf("], %lu, NULL, 0) = 0\n", maxnode); 72 } 73 74 int 75 main(void) 76 { 77 long rc; 78 79 if (syscall(__NR_get_mempolicy, 0, 0, 0, 0, 0)) 80 perror_msg_and_skip("get_mempolicy"); 81 puts("get_mempolicy(NULL, NULL, 0, NULL, 0) = 0"); 82 83 int *mode = (void *) 0xdefaced1baddeed2; 84 unsigned long maxnode = (unsigned long) 0xcafef00dbadc0dedULL; 85 const unsigned long *nodemask = (void *) 0xfacedad3bebefed4ULL; 86 const unsigned long addr = (unsigned long) 0xfacefeeddeadbeefULL; 87 const unsigned long flags = -1U; 88 rc = syscall(__NR_get_mempolicy, mode, nodemask, maxnode, addr, flags); 89 printf("get_mempolicy(%p, %p, %lu, %#lx, %s|%#lx) = %ld %s (%m)\n", 90 mode, nodemask, maxnode, addr, 91 "MPOL_F_NODE|MPOL_F_ADDR", 92 flags & ~3, rc, errno2name()); 93 94 mode = tail_alloc(sizeof(*mode)); 95 96 rc = syscall(__NR_get_mempolicy, mode, 0, 0, 0, 0); 97 printf("get_mempolicy(["); 98 printxval(policies, (unsigned) *mode, "MPOL_???"); 99 printf("], NULL, 0, NULL, 0) = %ld\n", rc); 100 101 *mode = -1; 102 rc = syscall(__NR_get_mempolicy, mode, 0, 0, mode - 1, 2); 103 printf("get_mempolicy(["); 104 printxval(policies, (unsigned) *mode, "MPOL_???"); 105 printf("], NULL, 0, %p, MPOL_F_ADDR) = %ld\n", mode - 1, rc); 106 107 maxnode = get_page_size() * 8; 108 109 print_nodes(maxnode); 110 print_nodes(maxnode + 1); 111 print_nodes(maxnode + 2); 112 113 maxnode = sizeof(*nodemask) * 8; 114 print_nodes(maxnode - 1); 115 print_nodes(maxnode ); 116 print_nodes(maxnode + 1); 117 print_nodes(maxnode + 2); 118 print_nodes(maxnode * 2 - 1); 119 print_nodes(maxnode * 2 ); 120 print_nodes(maxnode * 2 + 1); 121 print_nodes(maxnode * 2 + 2); 122 print_nodes(maxnode * 3 - 1); 123 print_nodes(maxnode * 3 ); 124 print_nodes(maxnode * 3 + 1); 125 print_nodes(maxnode * 3 + 2); 126 127 puts("+++ exited with 0 +++"); 128 return 0; 129 } 130 131 #else 132 133 SKIP_MAIN_UNDEFINED("__NR_get_mempolicy") 134 135 #endif 136