Index: sys/kern/kern_cpuset.c =================================================================== --- sys/kern/kern_cpuset.c +++ sys/kern/kern_cpuset.c @@ -674,20 +674,29 @@ if (error) return (error); /* - * In case we are called from within the jail + * In case we are called from within the jail, * we do not allow modifying the dedicated root * cpuset of the jail but may still allow to - * change child sets. + * change child sets, including subordinate jails' + * roots. */ - if (jailed(curthread->td_ucred) && - set->cs_flags & CPU_SET_ROOT) + if ((set->cs_flags & CPU_SET_ROOT) != 0 && + jailed(curthread->td_ucred) && + set == curthread->td_ucred->cr_prison->pr_cpuset) return (EPERM); /* * Verify that we have access to this set of * cpus. */ - root = cpuset_getroot(set); mtx_lock_spin(&cpuset_lock); + if ((set->cs_flags & (CPU_SET_ROOT | CPU_SET_RDONLY)) == CPU_SET_ROOT) { + KASSERT(set->cs_parent != NULL, + ("jail.cpuset=%d is not a proper child of parent jail's root.", + set->cs_id)); + root = cpuset_getroot(set->cs_parent); + } else { + root = cpuset_getroot(set); + } if (root && !CPU_SUBSET(&root->cs_mask, mask)) { error = EINVAL; goto out;