diff options
Diffstat (limited to 'kernel/compat.c')
| -rw-r--r-- | kernel/compat.c | 49 |
1 files changed, 30 insertions, 19 deletions
diff --git a/kernel/compat.c b/kernel/compat.c index 8eafe3eb50d9..d52e2ec1deb5 100644 --- a/kernel/compat.c +++ b/kernel/compat.c | |||
| @@ -454,16 +454,16 @@ asmlinkage long compat_sys_waitid(int which, compat_pid_t pid, | |||
| 454 | } | 454 | } |
| 455 | 455 | ||
| 456 | static int compat_get_user_cpu_mask(compat_ulong_t __user *user_mask_ptr, | 456 | static int compat_get_user_cpu_mask(compat_ulong_t __user *user_mask_ptr, |
| 457 | unsigned len, cpumask_t *new_mask) | 457 | unsigned len, struct cpumask *new_mask) |
| 458 | { | 458 | { |
| 459 | unsigned long *k; | 459 | unsigned long *k; |
| 460 | 460 | ||
| 461 | if (len < sizeof(cpumask_t)) | 461 | if (len < cpumask_size()) |
| 462 | memset(new_mask, 0, sizeof(cpumask_t)); | 462 | memset(new_mask, 0, cpumask_size()); |
| 463 | else if (len > sizeof(cpumask_t)) | 463 | else if (len > cpumask_size()) |
| 464 | len = sizeof(cpumask_t); | 464 | len = cpumask_size(); |
| 465 | 465 | ||
| 466 | k = cpus_addr(*new_mask); | 466 | k = cpumask_bits(new_mask); |
| 467 | return compat_get_bitmap(k, user_mask_ptr, len * 8); | 467 | return compat_get_bitmap(k, user_mask_ptr, len * 8); |
| 468 | } | 468 | } |
| 469 | 469 | ||
| @@ -471,40 +471,51 @@ asmlinkage long compat_sys_sched_setaffinity(compat_pid_t pid, | |||
| 471 | unsigned int len, | 471 | unsigned int len, |
| 472 | compat_ulong_t __user *user_mask_ptr) | 472 | compat_ulong_t __user *user_mask_ptr) |
| 473 | { | 473 | { |
| 474 | cpumask_t new_mask; | 474 | cpumask_var_t new_mask; |
| 475 | int retval; | 475 | int retval; |
| 476 | 476 | ||
| 477 | retval = compat_get_user_cpu_mask(user_mask_ptr, len, &new_mask); | 477 | if (!alloc_cpumask_var(&new_mask, GFP_KERNEL)) |
| 478 | return -ENOMEM; | ||
| 479 | |||
| 480 | retval = compat_get_user_cpu_mask(user_mask_ptr, len, new_mask); | ||
| 478 | if (retval) | 481 | if (retval) |
| 479 | return retval; | 482 | goto out; |
| 480 | 483 | ||
| 481 | return sched_setaffinity(pid, &new_mask); | 484 | retval = sched_setaffinity(pid, new_mask); |
| 485 | out: | ||
| 486 | free_cpumask_var(new_mask); | ||
| 487 | return retval; | ||
| 482 | } | 488 | } |
| 483 | 489 | ||
| 484 | asmlinkage long compat_sys_sched_getaffinity(compat_pid_t pid, unsigned int len, | 490 | asmlinkage long compat_sys_sched_getaffinity(compat_pid_t pid, unsigned int len, |
| 485 | compat_ulong_t __user *user_mask_ptr) | 491 | compat_ulong_t __user *user_mask_ptr) |
| 486 | { | 492 | { |
| 487 | int ret; | 493 | int ret; |
| 488 | cpumask_t mask; | 494 | cpumask_var_t mask; |
| 489 | unsigned long *k; | 495 | unsigned long *k; |
| 490 | unsigned int min_length = sizeof(cpumask_t); | 496 | unsigned int min_length = cpumask_size(); |
| 491 | 497 | ||
| 492 | if (NR_CPUS <= BITS_PER_COMPAT_LONG) | 498 | if (nr_cpu_ids <= BITS_PER_COMPAT_LONG) |
| 493 | min_length = sizeof(compat_ulong_t); | 499 | min_length = sizeof(compat_ulong_t); |
| 494 | 500 | ||
| 495 | if (len < min_length) | 501 | if (len < min_length) |
| 496 | return -EINVAL; | 502 | return -EINVAL; |
| 497 | 503 | ||
| 498 | ret = sched_getaffinity(pid, &mask); | 504 | if (!alloc_cpumask_var(&mask, GFP_KERNEL)) |
| 505 | return -ENOMEM; | ||
| 506 | |||
| 507 | ret = sched_getaffinity(pid, mask); | ||
| 499 | if (ret < 0) | 508 | if (ret < 0) |
| 500 | return ret; | 509 | goto out; |
| 501 | 510 | ||
| 502 | k = cpus_addr(mask); | 511 | k = cpumask_bits(mask); |
| 503 | ret = compat_put_bitmap(user_mask_ptr, k, min_length * 8); | 512 | ret = compat_put_bitmap(user_mask_ptr, k, min_length * 8); |
| 504 | if (ret) | 513 | if (ret == 0) |
| 505 | return ret; | 514 | ret = min_length; |
| 506 | 515 | ||
| 507 | return min_length; | 516 | out: |
| 517 | free_cpumask_var(mask); | ||
| 518 | return ret; | ||
| 508 | } | 519 | } |
| 509 | 520 | ||
| 510 | int get_compat_itimerspec(struct itimerspec *dst, | 521 | int get_compat_itimerspec(struct itimerspec *dst, |
