/* * SYSCALL_DEFINE6(move_pages, pid_t, pid, unsigned long, nr_pages, const void __user * __user *, pages, const int __user *, nodes, int __user *, status, int, flags) */ #define MPOL_MF_MOVE (1<<1) /* Move pages owned by this process to conform to mapping */ #define MPOL_MF_MOVE_ALL (1<<2) /* Move every page to conform to mapping */ #include #include #include #include #include #include "arch.h" #include "maps.h" #include "random.h" #include "sanitise.h" #include "shm.h" #include "syscall.h" #include "trinity.h" #include "utils.h" static unsigned int count; static void sanitise_move_pages(struct syscallrecord *rec) { int *nodes; unsigned long *page_alloc; unsigned int i; /* number of pages to move */ count = rand() % (page_size / sizeof(void *)); count = max(1U, count); rec->a2 = count; /* setup array of ptrs to pages to move */ page_alloc = (unsigned long *) zmalloc(page_size); for (i = 0; i < count; i++) { struct map *map; map = get_map(); page_alloc[i] = (unsigned long) map->ptr; } rec->a3 = (unsigned long) page_alloc; /* nodes = array of ints specifying desired location for each page */ nodes = calloc(count, sizeof(int)); for (i = 0; i < count; i++) nodes[i] = (int) rand() % 2; rec->a4 = (unsigned long) nodes; /* status = array of ints returning status of each page.*/ rec->a5 = (unsigned long) calloc(count, sizeof(int)); /* Needs CAP_SYS_NICE */ if (getuid() != 0) rec->a6 &= ~MPOL_MF_MOVE_ALL; } static void post_move_pages(struct syscallrecord *rec) { free((void *) rec->a3); free((void *) rec->a4); free((void *) rec->a5); } struct syscallentry syscall_move_pages = { .name = "move_pages", .num_args = 6, .arg1name = "pid", .arg1type = ARG_PID, .arg2name = "nr_pages", .arg3name = "pages", .arg4name = "nodes", .arg5name = "status", .arg6name = "flags", .arg6type = ARG_LIST, .arg6list = { .num = 2, .values = { MPOL_MF_MOVE, MPOL_MF_MOVE_ALL }, }, .group = GROUP_VM, .sanitise = sanitise_move_pages, .post = post_move_pages, }; .