PATCH: sched_{s,g}etaffinity compat

Marcus Meissner meissner at suse.de
Sun May 9 21:52:05 EST 2004


Hi,

On "real" hardware with NR_CPUS > sizeof(long)*8, the
sys_sched_setaffinity and getaffinity compatibility functions break,
because they just convert long masks instead of the full CPU masks.

This patches fixes this problem.

Spotted by a ppc32 glibc make check, on a ppc64 Kernel.

Ciao, Marcus
-------------- next part --------------
Changelog:
	Map the whole cpumask_t in the compat get and setaffinity calls.

--- linux-2.6.5/kernel/compat.c.orig	2004-04-04 05:37:07.000000000 +0200
+++ linux-2.6.5/kernel/compat.c	2004-05-09 09:39:52.000000000 +0200
@@ -376,18 +377,19 @@
 					     unsigned int len,
 					     compat_ulong_t *user_mask_ptr)
 {
-	unsigned long kernel_mask;
+	cpumask_t kernel_mask;
 	mm_segment_t old_fs;
 	int ret;

-	if (get_user(kernel_mask, user_mask_ptr))
+	memset(&kernel_mask,0,sizeof(kernel_mask));
+	if (copy_from_user(&kernel_mask, user_mask_ptr, min((unsigned int)sizeof( kernel_mask),len)))
 		return -EFAULT;

 	old_fs = get_fs();
 	set_fs(KERNEL_DS);
 	ret = sys_sched_setaffinity(pid,
 				    sizeof(kernel_mask),
-				    &kernel_mask);
+				    (unsigned long*)&kernel_mask);
 	set_fs(old_fs);

 	return ret;
@@ -396,7 +397,7 @@
 asmlinkage int compat_sys_sched_getaffinity(compat_pid_t pid, unsigned int len,
 					    compat_ulong_t *user_mask_ptr)
 {
-	unsigned long kernel_mask;
+	cpumask_t kernel_mask;
 	mm_segment_t old_fs;
 	int ret;

@@ -404,12 +405,12 @@
 	set_fs(KERNEL_DS);
 	ret = sys_sched_getaffinity(pid,
 				    sizeof(kernel_mask),
-				    &kernel_mask);
+				    (unsigned long*)&kernel_mask);
 	set_fs(old_fs);

 	if (ret > 0) {
-		ret = sizeof(compat_ulong_t);
-		if (put_user(kernel_mask, user_mask_ptr))
+	    	ret = min(len,(unsigned int)sizeof(kernel_mask));
+		if (copy_to_user(user_mask_ptr, &kernel_mask, ret))
 			return -EFAULT;
 	}


More information about the Linuxppc64-dev mailing list