Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions arch/alpha/kernel/syscalls/syscall.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -509,3 +509,6 @@
577 common open_tree_attr sys_open_tree_attr
578 common file_getattr sys_file_getattr
579 common file_setattr sys_file_setattr
580 common process_ksm_enable sys_process_ksm_enable
581 common process_ksm_disable sys_process_ksm_disable
582 common process_ksm_status sys_process_ksm_status
3 changes: 3 additions & 0 deletions arch/arm/tools/syscall.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -484,3 +484,6 @@
467 common open_tree_attr sys_open_tree_attr
468 common file_getattr sys_file_getattr
469 common file_setattr sys_file_setattr
470 common process_ksm_enable sys_process_ksm_enable
471 common process_ksm_disable sys_process_ksm_disable
472 common process_ksm_status sys_process_ksm_status
3 changes: 3 additions & 0 deletions arch/m68k/kernel/syscalls/syscall.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -469,3 +469,6 @@
467 common open_tree_attr sys_open_tree_attr
468 common file_getattr sys_file_getattr
469 common file_setattr sys_file_setattr
470 common process_ksm_enable sys_process_ksm_enable
471 common process_ksm_disable sys_process_ksm_disable
472 common process_ksm_status sys_process_ksm_status
3 changes: 3 additions & 0 deletions arch/microblaze/kernel/syscalls/syscall.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -475,3 +475,6 @@
467 common open_tree_attr sys_open_tree_attr
468 common file_getattr sys_file_getattr
469 common file_setattr sys_file_setattr
470 common process_ksm_enable sys_process_ksm_enable
471 common process_ksm_disable sys_process_ksm_disable
472 common process_ksm_status sys_process_ksm_status
3 changes: 3 additions & 0 deletions arch/mips/kernel/syscalls/syscall_n32.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -408,3 +408,6 @@
467 n32 open_tree_attr sys_open_tree_attr
468 n32 file_getattr sys_file_getattr
469 n32 file_setattr sys_file_setattr
470 n32 process_ksm_enable sys_process_ksm_enable
471 n32 process_ksm_disable sys_process_ksm_disable
472 n32 process_ksm_status sys_process_ksm_status
3 changes: 3 additions & 0 deletions arch/mips/kernel/syscalls/syscall_n64.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -384,3 +384,6 @@
467 n64 open_tree_attr sys_open_tree_attr
468 n64 file_getattr sys_file_getattr
469 n64 file_setattr sys_file_setattr
470 n64 process_ksm_enable sys_process_ksm_enable
471 n64 process_ksm_disable sys_process_ksm_disable
472 n64 process_ksm_status sys_process_ksm_status
3 changes: 3 additions & 0 deletions arch/mips/kernel/syscalls/syscall_o32.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -457,3 +457,6 @@
467 o32 open_tree_attr sys_open_tree_attr
468 o32 file_getattr sys_file_getattr
469 o32 file_setattr sys_file_setattr
470 o32 process_ksm_enable sys_process_ksm_enable
471 o32 process_ksm_disable sys_process_ksm_disable
472 o32 process_ksm_status sys_process_ksm_status
3 changes: 3 additions & 0 deletions arch/parisc/kernel/syscalls/syscall.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -468,3 +468,6 @@
467 common open_tree_attr sys_open_tree_attr
468 common file_getattr sys_file_getattr
469 common file_setattr sys_file_setattr
470 common process_ksm_enable sys_process_ksm_enable
471 common process_ksm_disable sys_process_ksm_disable
472 common process_ksm_status sys_process_ksm_status
3 changes: 3 additions & 0 deletions arch/powerpc/kernel/syscalls/syscall.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -560,3 +560,6 @@
467 common open_tree_attr sys_open_tree_attr
468 common file_getattr sys_file_getattr
469 common file_setattr sys_file_setattr
470 common process_ksm_enable sys_process_ksm_enable
471 common process_ksm_disable sys_process_ksm_disable
472 common process_ksm_status sys_process_ksm_status
3 changes: 3 additions & 0 deletions arch/s390/kernel/syscalls/syscall.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -472,3 +472,6 @@
467 common open_tree_attr sys_open_tree_attr sys_open_tree_attr
468 common file_getattr sys_file_getattr sys_file_getattr
469 common file_setattr sys_file_setattr sys_file_setattr
470 common process_ksm_enable sys_process_ksm_enable sys_process_ksm_enable
471 common process_ksm_disable sys_process_ksm_disable sys_process_ksm_disable
472 common process_ksm_status sys_process_ksm_status sys_process_ksm_status
3 changes: 3 additions & 0 deletions arch/sh/kernel/syscalls/syscall.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -473,3 +473,6 @@
467 common open_tree_attr sys_open_tree_attr
468 common file_getattr sys_file_getattr
469 common file_setattr sys_file_setattr
470 common process_ksm_enable sys_process_ksm_enable
471 common process_ksm_disable sys_process_ksm_disable
472 common process_ksm_status sys_process_ksm_status
3 changes: 3 additions & 0 deletions arch/sparc/kernel/syscalls/syscall.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -515,3 +515,6 @@
467 common open_tree_attr sys_open_tree_attr
468 common file_getattr sys_file_getattr
469 common file_setattr sys_file_setattr
470 common process_ksm_enable sys_process_ksm_enable
471 common process_ksm_disable sys_process_ksm_disable
472 common process_ksm_status sys_process_ksm_status
3 changes: 3 additions & 0 deletions arch/x86/entry/syscalls/syscall_32.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -475,3 +475,6 @@
467 i386 open_tree_attr sys_open_tree_attr
468 i386 file_getattr sys_file_getattr
469 i386 file_setattr sys_file_setattr
470 i386 process_ksm_enable sys_process_ksm_enable
471 i386 process_ksm_disable sys_process_ksm_disable
472 i386 process_ksm_status sys_process_ksm_status
3 changes: 3 additions & 0 deletions arch/x86/entry/syscalls/syscall_64.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,9 @@
467 common open_tree_attr sys_open_tree_attr
468 common file_getattr sys_file_getattr
469 common file_setattr sys_file_setattr
470 common process_ksm_enable sys_process_ksm_enable
471 common process_ksm_disable sys_process_ksm_disable
472 common process_ksm_status sys_process_ksm_status

#
# Due to a historical design error, certain syscalls are numbered differently
Expand Down
3 changes: 3 additions & 0 deletions arch/xtensa/kernel/syscalls/syscall.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -440,3 +440,6 @@
467 common open_tree_attr sys_open_tree_attr
468 common file_getattr sys_file_getattr
469 common file_setattr sys_file_setattr
470 common process_ksm_enable sys_process_ksm_enable
471 common process_ksm_disable sys_process_ksm_disable
472 common process_ksm_status sys_process_ksm_status
3 changes: 3 additions & 0 deletions include/linux/syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -838,6 +838,9 @@ asmlinkage long sys_madvise(unsigned long start, size_t len, int behavior);
asmlinkage long sys_process_madvise(int pidfd, const struct iovec __user *vec,
size_t vlen, int behavior, unsigned int flags);
asmlinkage long sys_process_mrelease(int pidfd, unsigned int flags);
asmlinkage long sys_process_ksm_enable(int pidfd, unsigned int flags);
asmlinkage long sys_process_ksm_disable(int pidfd, unsigned int flags);
asmlinkage long sys_process_ksm_status(int pidfd, unsigned int flags);
asmlinkage long sys_remap_file_pages(unsigned long start, unsigned long size,
unsigned long prot, unsigned long pgoff,
unsigned long flags);
Expand Down
9 changes: 8 additions & 1 deletion include/uapi/asm-generic/unistd.h
Original file line number Diff line number Diff line change
Expand Up @@ -858,8 +858,15 @@ __SYSCALL(__NR_file_getattr, sys_file_getattr)
#define __NR_file_setattr 469
__SYSCALL(__NR_file_setattr, sys_file_setattr)

#define __NR_process_ksm_enable 470
__SYSCALL(__NR_process_ksm_enable, sys_process_ksm_enable)
#define __NR_process_ksm_disable 471
__SYSCALL(__NR_process_ksm_disable, sys_process_ksm_disable)
#define __NR_process_ksm_status 472
__SYSCALL(__NR_process_ksm_status, sys_process_ksm_status)

#undef __NR_syscalls
#define __NR_syscalls 470
#define __NR_syscalls 473

/*
* 32 bit systems traditionally used different
Expand Down
138 changes: 138 additions & 0 deletions kernel/sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -2876,6 +2876,144 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
return error;
}

#ifdef CONFIG_KSM
enum pkc_action {
PKSM_ENABLE = 0,
PKSM_DISABLE,
PKSM_STATUS,
};

static long do_process_ksm_control(int pidfd, enum pkc_action action)
{
long ret;
struct task_struct *task;
struct mm_struct *mm;
unsigned int f_flags;

task = pidfd_get_task(pidfd, &f_flags);
if (IS_ERR(task)) {
ret = PTR_ERR(task);
goto out;
}

/* Require PTRACE_MODE_READ to avoid leaking ASLR metadata. */
mm = mm_access(task, PTRACE_MODE_READ_FSCREDS);
if (IS_ERR_OR_NULL(mm)) {
ret = IS_ERR(mm) ? PTR_ERR(mm) : -ESRCH;
goto release_task;
}

/* Require CAP_SYS_NICE for influencing process performance. */
if (!capable(CAP_SYS_NICE)) {
ret = -EPERM;
goto release_mm;
}

if (mmap_write_lock_killable(mm)) {
ret = -EINTR;
goto release_mm;
}

switch (action) {
case PKSM_ENABLE:
ret = ksm_enable_merge_any(mm);
break;
case PKSM_DISABLE:
ret = ksm_disable_merge_any(mm);
break;
case PKSM_STATUS:
ret = mm_flags_test(MMF_VM_MERGE_ANY, mm);
break;
}

mmap_write_unlock(mm);

release_mm:
mmput(mm);
release_task:
put_task_struct(task);
out:
return ret;
}
#endif /* CONFIG_KSM */

SYSCALL_DEFINE2(process_ksm_enable, int, pidfd, unsigned int, flags)
{
#ifdef CONFIG_KSM
if (flags != 0)
return -EINVAL;

return do_process_ksm_control(pidfd, PKSM_ENABLE);
#else /* CONFIG_KSM */
return -ENOSYS;
#endif /* CONFIG_KSM */
}

SYSCALL_DEFINE2(process_ksm_disable, int, pidfd, unsigned int, flags)
{
#ifdef CONFIG_KSM
if (flags != 0)
return -EINVAL;

return do_process_ksm_control(pidfd, PKSM_DISABLE);
#else /* CONFIG_KSM */
return -ENOSYS;
#endif /* CONFIG_KSM */
}

SYSCALL_DEFINE2(process_ksm_status, int, pidfd, unsigned int, flags)
{
#ifdef CONFIG_KSM
if (flags != 0)
return -EINVAL;

return do_process_ksm_control(pidfd, PKSM_STATUS);
#else /* CONFIG_KSM */
return -ENOSYS;
#endif /* CONFIG_KSM */
}

#ifdef CONFIG_KSM
static ssize_t process_ksm_enable_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%u\n", __NR_process_ksm_enable);
}
static struct kobj_attribute process_ksm_enable_attr = __ATTR_RO(process_ksm_enable);

static ssize_t process_ksm_disable_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%u\n", __NR_process_ksm_disable);
}
static struct kobj_attribute process_ksm_disable_attr = __ATTR_RO(process_ksm_disable);

static ssize_t process_ksm_status_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%u\n", __NR_process_ksm_status);
}
static struct kobj_attribute process_ksm_status_attr = __ATTR_RO(process_ksm_status);

static struct attribute *process_ksm_sysfs_attrs[] = {
&process_ksm_enable_attr.attr,
&process_ksm_disable_attr.attr,
&process_ksm_status_attr.attr,
NULL,
};

static const struct attribute_group process_ksm_sysfs_attr_group = {
.attrs = process_ksm_sysfs_attrs,
.name = "process_ksm",
};

static int __init process_ksm_sysfs_init(void)
{
return sysfs_create_group(kernel_kobj, &process_ksm_sysfs_attr_group);
}
subsys_initcall(process_ksm_sysfs_init);
#endif /* CONFIG_KSM */

SYSCALL_DEFINE3(getcpu, unsigned __user *, cpup, unsigned __user *, nodep,
struct getcpu_cache __user *, unused)
{
Expand Down
3 changes: 3 additions & 0 deletions kernel/sys_ni.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,9 @@ COND_SYSCALL(mincore);
COND_SYSCALL(madvise);
COND_SYSCALL(process_madvise);
COND_SYSCALL(process_mrelease);
COND_SYSCALL(process_ksm_enable);
COND_SYSCALL(process_ksm_disable);
COND_SYSCALL(process_ksm_status);
COND_SYSCALL(remap_file_pages);
COND_SYSCALL(mbind);
COND_SYSCALL(get_mempolicy);
Expand Down
3 changes: 3 additions & 0 deletions scripts/syscall.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -410,3 +410,6 @@
467 common open_tree_attr sys_open_tree_attr
468 common file_getattr sys_file_getattr
469 common file_setattr sys_file_setattr
470 common process_ksm_enable sys_process_ksm_enable
471 common process_ksm_disable sys_process_ksm_disable
472 common process_ksm_status sys_process_ksm_status
3 changes: 3 additions & 0 deletions tools/perf/arch/powerpc/entry/syscalls/syscall.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -560,3 +560,6 @@
467 common open_tree_attr sys_open_tree_attr
468 common file_getattr sys_file_getattr
469 common file_setattr sys_file_setattr
470 common process_ksm_enable sys_process_ksm_enable
471 common process_ksm_disable sys_process_ksm_disable
472 common process_ksm_status sys_process_ksm_status
3 changes: 3 additions & 0 deletions tools/perf/arch/s390/entry/syscalls/syscall.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -472,3 +472,6 @@
467 common open_tree_attr sys_open_tree_attr sys_open_tree_attr
468 common file_getattr sys_file_getattr sys_file_getattr
469 common file_setattr sys_file_setattr sys_file_setattr
470 common process_ksm_enable sys_process_ksm_enable sys_process_ksm_enable
471 common process_ksm_disable sys_process_ksm_disable sys_process_ksm_disable
472 common process_ksm_status sys_process_ksm_status sys_process_ksm_status