Index: sys/compat/linux/linux_misc.c =================================================================== --- sys/compat/linux/linux_misc.c +++ sys/compat/linux/linux_misc.c @@ -61,6 +61,7 @@ #include #include #include +#include #include #include #include @@ -2256,22 +2257,22 @@ linux_sched_getaffinity(struct thread *td, struct linux_sched_getaffinity_args *args) { - int error; struct thread *tdt; - - if (args->len < sizeof(cpuset_t)) - return (EINVAL); + int error; + id_t tid; tdt = linux_tdfind(td, args->pid, -1); if (tdt == NULL) return (ESRCH); - + tid = tdt->td_tid; PROC_UNLOCK(tdt->td_proc); error = kern_cpuset_getaffinity(td, CPU_LEVEL_WHICH, CPU_WHICH_TID, - tdt->td_tid, sizeof(cpuset_t), (cpuset_t *)args->user_mask_ptr); + tid, args->len, (cpuset_t *)args->user_mask_ptr); + if (error == ERANGE) + error = EINVAL; if (error == 0) - td->td_retval[0] = sizeof(cpuset_t); + td->td_retval[0] = min(args->len, sizeof(cpuset_t)); return (error); } @@ -2284,18 +2285,24 @@ struct linux_sched_setaffinity_args *args) { struct thread *tdt; - - if (args->len < sizeof(cpuset_t)) - return (EINVAL); + int error; + size_t len; + id_t tid; tdt = linux_tdfind(td, args->pid, -1); if (tdt == NULL) return (ESRCH); - + tid = tdt->td_tid; PROC_UNLOCK(tdt->td_proc); - return (kern_cpuset_setaffinity(td, CPU_LEVEL_WHICH, CPU_WHICH_TID, - tdt->td_tid, sizeof(cpuset_t), (cpuset_t *) args->user_mask_ptr)); + /* Linux ignore high bits */ + len = min(args->len, howmany(smp_cpus, NBBY)); + error = kern_cpuset_setaffinity(td, CPU_LEVEL_WHICH, CPU_WHICH_TID, + tid, len, (cpuset_t *) args->user_mask_ptr); + if (error == EDEADLK) + error = EINVAL; + + return (error); } struct linux_rlimit64 {