2004-10-07  Roland McGrath  <roland@redhat.com>

	* mem.c [LINUX] (sys_mbind, sys_set_mempolicy, sys_get_mempolicy):
	New functions.
	* linux/syscall.h: Declare them.
	* linux/x86_64/syscallent.h: Likewise.
	* linux/syscallent.h: Handle mbind, set_mempolicy, get_mempolicy.
	From Ulrich Drepper <drepper@redhat.com>.
diff --git a/linux/syscall.h b/linux/syscall.h
index bcbe827..9940c5d 100644
--- a/linux/syscall.h
+++ b/linux/syscall.h
@@ -98,6 +98,7 @@
 int sys_mq_notify(), sys_mq_getsetattr();
 int sys_epoll_create(), sys_epoll_ctl(), sys_epoll_wait();
 int sys_waitid(), sys_fadvise64(), sys_fadvise64_64();
+int sys_mbind(), sys_get_mempolicy(), sys_set_mempolicy();
 
 /* sys_socketcall subcalls */
 
diff --git a/linux/syscallent.h b/linux/syscallent.h
index 9cceccf..ba81cc1 100644
--- a/linux/syscallent.h
+++ b/linux/syscallent.h
@@ -319,17 +319,17 @@
 	{ 3,	TS,	sys_tgkill,		"tgkill"	}, /* 270 */
 	{ 2,	TF,	sys_utimes,		"utimes"	}, /* 271 */
 	{ 6,	TF,	sys_fadvise64_64,	"fadvise64_64"	}, /* 272 */
-	{ 5,	0,	printargs,		"SYS_273"	}, /* 273 */
-	{ 5,	0,	printargs,		"SYS_274"	}, /* 274 */
-	{ 5,	0,	printargs,		"SYS_275"	}, /* 275 */
-	{ 5,	0,	printargs,		"SYS_276"	}, /* 276 */
+	{ 5,	0,	printargs,		"vserver"	}, /* 273 */
+	{ 6,	0,	sys_mbind,		"mbind"		}, /* 274 */
+	{ 5,	0,	sys_get_mempolicy,	"get_mempolicy"	}, /* 275 */
+	{ 3,	0,	sys_set_mempolicy,	"set_mempolicy"	}, /* 276 */
 	{ 4,	0,	sys_mq_open,		"mq_open"	}, /* 277 */
 	{ 1,	0,	sys_mq_unlink,		"mq_unlink"	}, /* 278 */
 	{ 5,	0,	sys_mq_timedsend,	"mq_timedsend"	}, /* 279 */
 	{ 5,	0,	sys_mq_timedreceive,	"mq_timedreceive" }, /* 280 */
 	{ 2,	0,	sys_mq_notify,		"mq_notify"	}, /* 281 */
 	{ 3,	0,	sys_mq_getsetattr,	"mq_getsetattr"	}, /* 282 */
-	{ 5,	0,	printargs,		"SYS_283"	}, /* 283 */
+	{ 5,	0,	printargs,		"sys_kexec_load" }, /* 283 */
 	{ 5,	TP,	sys_waitid,		"waitid"	}, /* 284 */
 	{ 5,	0,	printargs,		"SYS_285"	}, /* 285 */
 	{ 5,	0,	printargs,		"SYS_286"	}, /* 286 */
diff --git a/linux/x86_64/syscallent.h b/linux/x86_64/syscallent.h
index 87ee170..a7e8c24 100644
--- a/linux/x86_64/syscallent.h
+++ b/linux/x86_64/syscallent.h
@@ -219,7 +219,7 @@
 	{ 5,	0,	printargs,		"SYS_218"	}, /* 218 */
 	{ 5,	0,	printargs,		"SYS_219"	}, /* 219 */
 	{ 5,	0,	printargs,		"SYS_220"	}, /* 220 */
-	{ 5,	0,	printargs,		"SYS_221"	}, /* 221 */
+	{ 5,	0,	sys_fadvise64_64,	"fadvise64"	}, /* 221 */
 	{ 5,	0,	printargs,		"SYS_222"	}, /* 222 */
 	{ 5,	0,	printargs,		"SYS_223"	}, /* 223 */
 	{ 5,	0,	printargs,		"SYS_224"	}, /* 224 */
@@ -249,9 +249,9 @@
 	{ 5,	0,	printargs,		"tgkill"	}, /* 234 */
 	{ 5,	0,	printargs,		"utimes"	}, /* 235 */
 	{ 5,	0,	printargs,		"vserver"	}, /* 236 */
-	{ 5,	0,	printargs,		"mbind"		}, /* 237 */
-	{ 5,	0,	printargs,		"set_mempolicy"	}, /* 238 */
-	{ 5,	0,	printargs,		"get_mempolicy"	}, /* 239 */
+	{ 6,	0,	sys_mbind,		"mbind"		}, /* 237 */
+	{ 3,	0,	sys_set_mempolicy,	"set_mempolicy"	}, /* 238 */
+	{ 5,	0,	sys_get_mempolicy,	"get_mempolicy"	}, /* 239 */
 	{ 4,	0,	sys_mq_open,		"mq_open"	}, /* 240 */
 	{ 1,	0,	sys_mq_unlink,		"mq_unlink"	}, /* 241 */
 	{ 5,	0,	sys_mq_timedsend,	"mq_timedsend"	}, /* 242 */
diff --git a/mem.c b/mem.c
index 885ce2d..7404ef2 100644
--- a/mem.c
+++ b/mem.c
@@ -657,4 +657,112 @@
 	}
 	return 0;
 }
+
+
+#define MPOL_DEFAULT    0
+#define MPOL_PREFERRED  1
+#define MPOL_BIND       2
+#define MPOL_INTERLEAVE 3
+
+#define MPOL_F_NODE     (1<<0)
+#define MPOL_F_ADDR     (1<<1)
+
+#define MPOL_MF_STRICT  (1<<0)
+
+
+static const struct xlat policies[] = {
+	{ MPOL_DEFAULT,		"MPOL_DEFAULT"		},
+	{ MPOL_PREFERRED,	"MPOL_PREFERRED"	},
+	{ MPOL_BIND,		"MPOL_BIND"		},
+	{ MPOL_INTERLEAVE,	"MPOL_INTERLEAVE"	},
+	{ 0,			NULL			}
+};
+
+static const struct xlat mbindflags[] = {
+	{ MPOL_MF_STRICT,	"MPOL_MF_STRICT"	},
+	{ 0,			NULL			}
+};
+
+static const struct xlat mempolicyflags[] = {
+	{ MPOL_F_NODE,		"MPOL_F_NODE"		},
+	{ MPOL_F_ADDR,		"MPOL_F_ADDR"		},
+	{ 0,			NULL			}
+};
+
+
+static void
+get_nodes(tcp, ptr, maxnodes, err)
+struct tcb *tcp;
+unsigned long ptr;
+unsigned long maxnodes;
+int err;
+{
+	int nlongs = (maxnodes + 8 * sizeof(long) - 1) / (8 * sizeof(long));
+	if (err || !abbrev(tcp) || nlongs > getpagesize() / sizeof(long)
+	    || nlongs == 0) {
+		long buf[nlongs];
+		if (umoven(tcp, ptr, nlongs * sizeof(long),
+			   (char *) buf) < 0)
+			tprintf(", %lx", ptr);
+		else {
+			int i;
+			tprintf(", {");
+			for (i = 0; i < nlongs; ++i) {
+				if (i > 0)
+					tprintf(", ");
+				tprintf("%#0*lx", (int) sizeof(long) * 2 + 2,
+					buf[i]);
+			}
+			tprintf("}");
+		}
+	} else
+		tprintf(", %lx", ptr);
+	tprintf(", %lu", maxnodes);
+}
+
+int
+sys_mbind(tcp)
+struct tcb *tcp;
+{
+	if (entering(tcp)) {
+		tprintf("%lu, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
+		printxval(policies, tcp->u_arg[2], "MPOL_???");
+		get_nodes(tcp, tcp->u_arg[3], tcp->u_arg[4], 0);
+		tprintf(", ");
+		if (printflags(mbindflags, tcp->u_arg[5]) == 0)
+			tprintf("0");
+	}
+	return 0;
+}
+
+int
+sys_set_mempolicy(tcp)
+struct tcb *tcp;
+{
+	if (entering(tcp)) {
+		printxval(policies, tcp->u_arg[0], "MPOL_???");
+		get_nodes(tcp, tcp->u_arg[1], tcp->u_arg[2], 0);
+	}
+	return 0;
+}
+
+int
+sys_get_mempolicy(tcp)
+struct tcb *tcp;
+{
+	if (exiting(tcp)) {
+		int pol;
+		if (tcp->u_arg[0] == 0)
+			tprintf("NULL");
+		else if (syserror(tcp) || umove(tcp, tcp->u_arg[0], &pol) < 0)
+			tprintf("%#lx", tcp->u_arg[0]);
+		else
+			printxval(policies, pol, "MPOL_???");
+		get_nodes(tcp, tcp->u_arg[1], tcp->u_arg[2], syserror(tcp));
+		tprintf(", %#lx, ", tcp->u_arg[3]);
+		if (printflags(mempolicyflags, tcp->u_arg[4]) == 0)
+			tprintf("0");
+	}
+	return 0;
+}
 #endif