Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[6.12] Track PF uksmd patches #37

Draft
wants to merge 2 commits into
base: base-6.12
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
mm: expose per-process KSM control via syscalls
d7597f5 added a new API to enable per-process KSM control. It
however uses prctl, which doesn't allow controlling KSM from outside of
the current process.

Hence, expose this API via 3 syscalls: process_ksm_enable,
process_ksm_disable and process_ksm_status. Given sufficient privileges,
auto-KSM can be enable by another process.

Since these syscalls are not in the upstream kernel, also expose their
numbers under /sys/kernel/process_ksm so that userspace tooling like
uksmd knows how to use them.

Signed-off-by: Oleksandr Natalenko <oleksandr@natalenko.name>
  • Loading branch information
pfactum authored and kakra committed Nov 18, 2024
commit 8d099bfbf256dcccce59fc7997e39b9edf449070
3 changes: 3 additions & 0 deletions arch/alpha/kernel/syscalls/syscall.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -502,3 +502,6 @@
570 common lsm_set_self_attr sys_lsm_set_self_attr
571 common lsm_list_modules sys_lsm_list_modules
572 common mseal sys_mseal
573 common process_ksm_enable sys_process_ksm_enable
574 common process_ksm_disable sys_process_ksm_disable
575 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 @@ -477,3 +477,6 @@
460 common lsm_set_self_attr sys_lsm_set_self_attr
461 common lsm_list_modules sys_lsm_list_modules
462 common mseal sys_mseal
463 common process_ksm_enable sys_process_ksm_enable
464 common process_ksm_disable sys_process_ksm_disable
465 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 @@ -462,3 +462,6 @@
460 common lsm_set_self_attr sys_lsm_set_self_attr
461 common lsm_list_modules sys_lsm_list_modules
462 common mseal sys_mseal
463 common process_ksm_enable sys_process_ksm_enable
464 common process_ksm_disable sys_process_ksm_disable
465 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 @@ -468,3 +468,6 @@
460 common lsm_set_self_attr sys_lsm_set_self_attr
461 common lsm_list_modules sys_lsm_list_modules
462 common mseal sys_mseal
463 common process_ksm_enable sys_process_ksm_enable
464 common process_ksm_disable sys_process_ksm_disable
465 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 @@ -401,3 +401,6 @@
460 n32 lsm_set_self_attr sys_lsm_set_self_attr
461 n32 lsm_list_modules sys_lsm_list_modules
462 n32 mseal sys_mseal
463 n32 process_ksm_enable sys_process_ksm_enable
464 n32 process_ksm_disable sys_process_ksm_disable
465 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 @@ -377,3 +377,6 @@
460 n64 lsm_set_self_attr sys_lsm_set_self_attr
461 n64 lsm_list_modules sys_lsm_list_modules
462 n64 mseal sys_mseal
463 n64 process_ksm_enable sys_process_ksm_enable
464 n64 process_ksm_disable sys_process_ksm_disable
465 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 @@ -450,3 +450,6 @@
460 o32 lsm_set_self_attr sys_lsm_set_self_attr
461 o32 lsm_list_modules sys_lsm_list_modules
462 o32 mseal sys_mseal
463 o32 process_ksm_enable sys_process_ksm_enable
464 o32 process_ksm_disable sys_process_ksm_disable
465 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 @@ -461,3 +461,6 @@
460 common lsm_set_self_attr sys_lsm_set_self_attr
461 common lsm_list_modules sys_lsm_list_modules
462 common mseal sys_mseal
463 common process_ksm_enable sys_process_ksm_enable
464 common process_ksm_disable sys_process_ksm_disable
465 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 @@ -553,3 +553,6 @@
460 common lsm_set_self_attr sys_lsm_set_self_attr
461 common lsm_list_modules sys_lsm_list_modules
462 common mseal sys_mseal
463 common process_ksm_enable sys_process_ksm_enable
464 common process_ksm_disable sys_process_ksm_disable
465 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 @@ -465,3 +465,6 @@
460 common lsm_set_self_attr sys_lsm_set_self_attr sys_lsm_set_self_attr
461 common lsm_list_modules sys_lsm_list_modules sys_lsm_list_modules
462 common mseal sys_mseal sys_mseal
463 common process_ksm_enable sys_process_ksm_enable sys_process_ksm_enable
464 common process_ksm_disable sys_process_ksm_disable sys_process_ksm_disable
465 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 @@ -466,3 +466,6 @@
460 common lsm_set_self_attr sys_lsm_set_self_attr
461 common lsm_list_modules sys_lsm_list_modules
462 common mseal sys_mseal
463 common process_ksm_enable sys_process_ksm_enable
464 common process_ksm_disable sys_process_ksm_disable
465 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 @@ -508,3 +508,6 @@
460 common lsm_set_self_attr sys_lsm_set_self_attr
461 common lsm_list_modules sys_lsm_list_modules
462 common mseal sys_mseal
463 common process_ksm_enable sys_process_ksm_enable
464 common process_ksm_disable sys_process_ksm_disable
465 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 @@ -468,3 +468,6 @@
460 i386 lsm_set_self_attr sys_lsm_set_self_attr
461 i386 lsm_list_modules sys_lsm_list_modules
462 i386 mseal sys_mseal
463 i386 process_ksm_enable sys_process_ksm_enable
464 i386 process_ksm_disable sys_process_ksm_disable
465 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 @@ -386,6 +386,9 @@
460 common lsm_set_self_attr sys_lsm_set_self_attr
461 common lsm_list_modules sys_lsm_list_modules
462 common mseal sys_mseal
463 common process_ksm_enable sys_process_ksm_enable
464 common process_ksm_disable sys_process_ksm_disable
465 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 @@ -433,3 +433,6 @@
460 common lsm_set_self_attr sys_lsm_set_self_attr
461 common lsm_list_modules sys_lsm_list_modules
462 common mseal sys_mseal
463 common process_ksm_enable sys_process_ksm_enable
464 common process_ksm_disable sys_process_ksm_disable
465 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 @@ -818,6 +818,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 @@ -841,8 +841,15 @@ __SYSCALL(__NR_lsm_list_modules, sys_lsm_list_modules)
#define __NR_mseal 462
__SYSCALL(__NR_mseal, sys_mseal)

#define __NR_process_ksm_enable 463
__SYSCALL(__NR_process_ksm_enable, sys_process_ksm_enable)
#define __NR_process_ksm_disable 464
__SYSCALL(__NR_process_ksm_disable, sys_process_ksm_disable)
#define __NR_process_ksm_status 465
__SYSCALL(__NR_process_ksm_status, sys_process_ksm_status)

#undef __NR_syscalls
#define __NR_syscalls 463
#define __NR_syscalls 466

/*
* 32 bit systems traditionally used different
Expand Down
147 changes: 147 additions & 0 deletions kernel/sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -2791,6 +2791,153 @@ 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 pid *pid;
struct task_struct *task;
struct mm_struct *mm;
unsigned int f_flags;

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

task = get_pid_task(pid, PIDTYPE_PID);
if (!task) {
ret = -ESRCH;
goto put_pid;
}

/* 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 = !!test_bit(MMF_VM_MERGE_ANY, &mm->flags);
break;
}

mmap_write_unlock(mm);

release_mm:
mmput(mm);
release_task:
put_task_struct(task);
put_pid:
put_pid(pid);
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 @@ -403,3 +403,6 @@
460 common lsm_set_self_attr sys_lsm_set_self_attr
461 common lsm_list_modules sys_lsm_list_modules
462 common mseal sys_mseal
463 common process_ksm_enable sys_process_ksm_enable
464 common process_ksm_disable sys_process_ksm_disable
465 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 @@ -553,3 +553,6 @@
460 common lsm_set_self_attr sys_lsm_set_self_attr
461 common lsm_list_modules sys_lsm_list_modules
462 common mseal sys_mseal
463 common process_ksm_enable sys_process_ksm_enable
464 common process_ksm_disable sys_process_ksm_disable
465 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 @@ -465,3 +465,6 @@
460 common lsm_set_self_attr sys_lsm_set_self_attr sys_lsm_set_self_attr
461 common lsm_list_modules sys_lsm_list_modules sys_lsm_list_modules
462 common mseal sys_mseal sys_mseal
463 common process_ksm_enable sys_process_ksm_enable sys_process_ksm_enable
464 common process_ksm_disable sys_process_ksm_disable sys_process_ksm_disable
465 common process_ksm_status sys_process_ksm_status sys_process_ksm_status