Index: linux-2.6.17-rc1-ptsh/mm/memory.c =================================================================== --- linux-2.6.17-rc1-ptsh.orig/mm/memory.c +++ linux-2.6.17-rc1-ptsh/mm/memory.c @@ -2463,3 +2463,80 @@ int in_gate_area_no_task(unsigned long a } #endif /* __HAVE_ARCH_GATE_AREA */ + +#define VMINFO_RESULTS 3 +asmlinkage long +sys_get_vminfo(pid_t pid, unsigned long addr, long *user_addr) +{ + int ret; + struct page *p; + struct task_struct *task = NULL; + struct mm_struct *mm = NULL; + pgd_t *pgd; + pud_t *pud; + pmd_t *pmd; + pte_t *ptep = NULL; + unsigned long results[VMINFO_RESULTS]; + + if (pid >= 0) { + read_lock(&tasklist_lock); + task = find_task_by_pid(pid); + if (task) { + task_lock(task); + mm = task->mm; + if (mm) + atomic_inc(&mm->mm_users); + } else { + read_unlock(&tasklist_lock); + return -ESRCH; + } + read_unlock(&tasklist_lock); + } else + return -1; + + ret = get_user_pages(task, mm, addr, 1, 0, 0, &p, NULL); + results[0] = 0; + results[1] = -1; + if (ret >= 0) { + results[0] = page_to_pfn(p); + results[1] = page_to_nid(p); + put_page(p); + } else + ret = EINVAL; + + pgd = pgd_offset(mm, addr); + if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd))) + goto no_page_table; + + pud = pud_offset(pgd, addr); + if (pud_none(*pud) || unlikely(pud_bad(*pud))) + goto no_page_table; + + pmd = pmd_offset(pud, addr); + if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd))) + goto no_page_table; + + ptep = pte_offset_map(pmd, addr); + pte_unmap(ptep); + + if (mm) + mmput(mm); + + task_unlock(task); + +copy_vminfo_to_user: + results[2] = (unsigned long) ptep; + + if (copy_to_user(user_addr, results, VMINFO_RESULTS*sizeof(long))) + ret = -EFAULT; + + return ret; + +no_page_table: + ptep = NULL; + + ret = ENOMEM; + + goto copy_vminfo_to_user; + +} Index: linux-2.6.17-rc1-ptsh/include/asm-x86_64/unistd.h =================================================================== --- linux-2.6.17-rc1-ptsh.orig/include/asm-x86_64/unistd.h +++ linux-2.6.17-rc1-ptsh/include/asm-x86_64/unistd.h @@ -611,8 +611,10 @@ __SYSCALL(__NR_set_robust_list, sys_set_ __SYSCALL(__NR_get_robust_list, sys_get_robust_list) #define __NR_splice 275 __SYSCALL(__NR_splice, sys_splice) - -#define __NR_syscall_max __NR_splice +#define __NR_get_vminfo 276 +__SYSCALL(__NR_get_vminfo, sys_get_vminfo) + +#define __NR_syscall_max __NR_get_vminfo #ifndef __NO_STUBS