Signed-off-by: Tonis Tiigi <tonisti...@gmail.com> --- linux-user/syscall.c | 72 +++++++++++++++++++++++++++++++++++++++ linux-user/syscall_defs.h | 14 ++++++++ 2 files changed, 86 insertions(+)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c index f1cfcc8104..a447ce1f92 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -339,6 +339,12 @@ _syscall3(int, sys_sched_getaffinity, pid_t, pid, unsigned int, len, #define __NR_sys_sched_setaffinity __NR_sched_setaffinity _syscall3(int, sys_sched_setaffinity, pid_t, pid, unsigned int, len, unsigned long *, user_mask_ptr); +#define __NR_sys_sched_getattr __NR_sched_getattr +_syscall4(int, sys_sched_getattr, pid_t, pid, struct target_sched_attr *, attr, + unsigned int, size, unsigned int, flags); +#define __NR_sys_sched_setattr __NR_sched_setattr +_syscall3(int, sys_sched_setattr, pid_t, pid, struct target_sched_attr *, attr, + unsigned int, flags); #define __NR_sys_getcpu __NR_getcpu _syscall3(int, sys_getcpu, unsigned *, cpu, unsigned *, node, void *, tcache); _syscall4(int, reboot, int, magic1, int, magic2, unsigned int, cmd, @@ -10593,6 +10599,72 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, } case TARGET_NR_sched_getscheduler: return get_errno(sched_getscheduler(arg1)); + case TARGET_NR_sched_getattr: + { + struct target_sched_attr *target_scha; + struct target_sched_attr scha; + if (arg2 == 0) { + return -TARGET_EINVAL; + } + if (arg3 > sizeof(scha)) { + arg3 = sizeof(scha); + } + ret = get_errno(sys_sched_getattr(arg1, &scha, arg3, arg4)); + if (!is_error(ret)) { + target_scha = lock_user(VERIFY_WRITE, arg2, arg3, 0); + if (!target_scha) { + return -TARGET_EFAULT; + } + target_scha->size = tswap32(scha.size); + target_scha->sched_policy = tswap32(scha.sched_policy); + target_scha->sched_flags = tswap64(scha.sched_policy); + target_scha->sched_nice = tswap32(scha.sched_nice); + target_scha->sched_priority = tswap32(scha.sched_priority); + target_scha->sched_runtime = tswap64(scha.sched_runtime); + target_scha->sched_deadline = tswap64(scha.sched_deadline); + target_scha->sched_period = tswap64(scha.sched_period); + if (scha.size > offsetof(struct target_sched_attr, sched_util_min)) { + target_scha->sched_util_min = tswap32(scha.sched_util_min); + target_scha->sched_util_max = tswap32(scha.sched_util_max); + } + unlock_user(target_scha, arg2, arg3); + } + return ret; + } + case TARGET_NR_sched_setattr: + { + struct target_sched_attr *target_scha; + struct target_sched_attr scha; + uint32_t *size; + if (arg2 == 0) { + return -TARGET_EINVAL; + } + + if (!lock_user_struct(VERIFY_READ, size, arg2, 1)) { + return -TARGET_EFAULT; + } + unlock_user_struct(size, arg2, 0); + *size = tswap32(*size); + + target_scha = lock_user(VERIFY_READ, arg2, *size, 1); + if (!target_scha) { + return -TARGET_EFAULT; + } + scha.size = *size; + scha.sched_policy = tswap32(target_scha->sched_policy); + scha.sched_flags = tswap64(target_scha->sched_flags); + scha.sched_nice = tswap32(target_scha->sched_nice); + scha.sched_priority = tswap32(target_scha->sched_priority); + scha.sched_runtime = tswap64(target_scha->sched_runtime); + scha.sched_deadline = tswap64(target_scha->sched_deadline); + scha.sched_period = tswap64(target_scha->sched_period); + if (scha.size > offsetof(struct target_sched_attr, sched_util_min)) { + scha.sched_util_min = tswap32(target_scha->sched_util_min); + scha.sched_util_max = tswap32(target_scha->sched_util_max); + } + unlock_user(target_scha, arg2, 0); + return get_errno(sys_sched_setattr(arg1, &scha, arg3)); + } case TARGET_NR_sched_yield: return get_errno(sched_yield()); case TARGET_NR_sched_get_priority_max: diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 0b13975937..310d6ce8ad 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -2914,4 +2914,18 @@ struct target_statx { /* 0x100 */ }; +/* from kernel's include/linux/sched/types.h */ +struct target_sched_attr { + abi_uint size; + abi_uint sched_policy; + abi_ullong sched_flags; + abi_int sched_nice; + abi_uint sched_priority; + abi_ullong sched_runtime; + abi_ullong sched_deadline; + abi_ullong sched_period; + abi_uint sched_util_min; + abi_uint sched_util_max; +}; + #endif -- 2.32.0 (Apple Git-132)