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