}
}
-/*
- * for maximum compatability, we allow programs to use a single (compat)
- * unsigned long bitmask if all cpus will fit. If not, you have to have
- * at least the kernel size available.
- */
-#define USE_COMPAT_ULONG_CPUMASK (NR_CPUS <= BITS_PER_COMPAT_LONG)
-
-asmlinkage long compat_sys_sched_setaffinity(compat_pid_t pid,
- unsigned int len,
- compat_ulong_t __user *user_mask_ptr)
+static int compat_get_user_cpu_mask(compat_ulong_t __user *user_mask_ptr,
+ unsigned len, cpumask_t *new_mask)
{
- cpumask_t kern_mask;
- mm_segment_t old_fs;
- int ret;
+ unsigned long *k;
- if (USE_COMPAT_ULONG_CPUMASK) {
- compat_ulong_t user_mask;
+ if (len < sizeof(cpumask_t))
+ memset(new_mask, 0, sizeof(cpumask_t));
+ else if (len > sizeof(cpumask_t))
+ len = sizeof(cpumask_t);
- if (len < sizeof(user_mask))
- return -EINVAL;
-
- if (get_user(user_mask, user_mask_ptr))
- return -EFAULT;
-
- cpus_addr(kern_mask)[0] = user_mask;
- } else {
- unsigned long *k;
-
- if (len < sizeof(kern_mask))
- return -EINVAL;
+ k = cpus_addr(*new_mask);
+ return compat_get_bitmap(k, user_mask_ptr, len * 8);
+}
- k = cpus_addr(kern_mask);
- ret = compat_get_bitmap(k, user_mask_ptr,
- sizeof(kern_mask) * BITS_PER_LONG);
- if (ret)
- return ret;
- }
+asmlinkage long compat_sys_sched_setaffinity(compat_pid_t pid,
+ unsigned int len,
+ compat_ulong_t __user *user_mask_ptr)
+{
+ cpumask_t new_mask;
+ int retval;
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = sys_sched_setaffinity(pid,
- sizeof(kern_mask),
- (unsigned long __user *) &kern_mask);
- set_fs(old_fs);
+ retval = compat_get_user_cpu_mask(user_mask_ptr, len, &new_mask);
+ if (retval)
+ return retval;
- return ret;
+ return sched_setaffinity(pid, new_mask);
}
asmlinkage long compat_sys_sched_getaffinity(compat_pid_t pid, unsigned int len,
compat_ulong_t __user *user_mask_ptr)
{
- cpumask_t kern_mask;
- mm_segment_t old_fs;
int ret;
+ cpumask_t mask;
+ unsigned long *k;
- if (len < (USE_COMPAT_ULONG_CPUMASK ? sizeof(compat_ulong_t)
- : sizeof(kern_mask)))
+ if (len < sizeof(cpumask_t))
return -EINVAL;
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = sys_sched_getaffinity(pid,
- sizeof(kern_mask),
- (unsigned long __user *) &kern_mask);
- set_fs(old_fs);
-
+ ret = sched_getaffinity(pid, &mask);
if (ret < 0)
return ret;
- if (USE_COMPAT_ULONG_CPUMASK) {
- if (put_user(&cpus_addr(kern_mask)[0], user_mask_ptr))
- return -EFAULT;
- ret = sizeof(compat_ulong_t);
- } else {
- unsigned long *k;
-
- k = cpus_addr(kern_mask);
- ret = compat_put_bitmap(user_mask_ptr, k,
- sizeof(kern_mask) * BITS_PER_LONG);
- if (ret)
- return ret;
-
- ret = sizeof(kern_mask);
- }
+ k = cpus_addr(mask);
+ ret = compat_put_bitmap(user_mask_ptr, k, sizeof(cpumask_t) * 8);
+ if (ret)
+ return ret;
- return ret;
+ return sizeof(cpumask_t);
}
static int get_compat_itimerspec(struct itimerspec *dst,
return retval;
}
-static int get_user_cpu_mask(unsigned long __user *user_mask_ptr, unsigned len,
- cpumask_t *new_mask)
-{
- if (len < sizeof(cpumask_t)) {
- memset(new_mask, 0, sizeof(cpumask_t));
- } else if (len > sizeof(cpumask_t)) {
- len = sizeof(cpumask_t);
- }
- return copy_from_user(new_mask, user_mask_ptr, len) ? -EFAULT : 0;
-}
-
-/**
- * sys_sched_setaffinity - set the cpu affinity of a process
- * @pid: pid of the process
- * @len: length in bytes of the bitmask pointed to by user_mask_ptr
- * @user_mask_ptr: user-space pointer to the new cpu mask
- */
-asmlinkage long sys_sched_setaffinity(pid_t pid, unsigned int len,
- unsigned long __user *user_mask_ptr)
+long sched_setaffinity(pid_t pid, cpumask_t new_mask)
{
- cpumask_t new_mask;
- int retval;
task_t *p;
-
- retval = get_user_cpu_mask(user_mask_ptr, len, &new_mask);
- if (retval)
- return retval;
+ int retval;
lock_cpu_hotplug();
read_lock(&tasklist_lock);
return retval;
}
+static int get_user_cpu_mask(unsigned long __user *user_mask_ptr, unsigned len,
+ cpumask_t *new_mask)
+{
+ if (len < sizeof(cpumask_t)) {
+ memset(new_mask, 0, sizeof(cpumask_t));
+ } else if (len > sizeof(cpumask_t)) {
+ len = sizeof(cpumask_t);
+ }
+ return copy_from_user(new_mask, user_mask_ptr, len) ? -EFAULT : 0;
+}
+
+/**
+ * sys_sched_setaffinity - set the cpu affinity of a process
+ * @pid: pid of the process
+ * @len: length in bytes of the bitmask pointed to by user_mask_ptr
+ * @user_mask_ptr: user-space pointer to the new cpu mask
+ */
+asmlinkage long sys_sched_setaffinity(pid_t pid, unsigned int len,
+ unsigned long __user *user_mask_ptr)
+{
+ cpumask_t new_mask;
+ int retval;
+
+ retval = get_user_cpu_mask(user_mask_ptr, len, &new_mask);
+ if (retval)
+ return retval;
+
+ return sched_setaffinity(pid, new_mask);
+}
+
/*
* Represents all cpu's present in the system
* In systems capable of hotplug, this map could dynamically grow
cpumask_t cpu_possible_map = CPU_MASK_ALL;
#endif
-/**
- * sys_sched_getaffinity - get the cpu affinity of a process
- * @pid: pid of the process
- * @len: length in bytes of the bitmask pointed to by user_mask_ptr
- * @user_mask_ptr: user-space pointer to hold the current cpu mask
- */
-asmlinkage long sys_sched_getaffinity(pid_t pid, unsigned int len,
- unsigned long __user *user_mask_ptr)
+long sched_getaffinity(pid_t pid, cpumask_t *mask)
{
- unsigned int real_len;
- cpumask_t mask;
int retval;
task_t *p;
- real_len = sizeof(mask);
- if (len < real_len)
- return -EINVAL;
-
lock_cpu_hotplug();
read_lock(&tasklist_lock);
goto out_unlock;
retval = 0;
- cpus_and(mask, p->cpus_allowed, cpu_possible_map);
+ cpus_and(*mask, p->cpus_allowed, cpu_possible_map);
out_unlock:
read_unlock(&tasklist_lock);
unlock_cpu_hotplug();
if (retval)
return retval;
- if (copy_to_user(user_mask_ptr, &mask, real_len))
+
+ return 0;
+}
+
+/**
+ * sys_sched_getaffinity - get the cpu affinity of a process
+ * @pid: pid of the process
+ * @len: length in bytes of the bitmask pointed to by user_mask_ptr
+ * @user_mask_ptr: user-space pointer to hold the current cpu mask
+ */
+asmlinkage long sys_sched_getaffinity(pid_t pid, unsigned int len,
+ unsigned long __user *user_mask_ptr)
+{
+ int ret;
+ cpumask_t mask;
+
+ if (len < sizeof(cpumask_t))
+ return -EINVAL;
+
+ ret = sched_getaffinity(pid, &mask);
+ if (ret < 0)
+ return ret;
+
+ if (copy_to_user(user_mask_ptr, &mask, sizeof(cpumask_t)))
return -EFAULT;
- return real_len;
+
+ return sizeof(cpumask_t);
}
/**