1 /* 2 * sys_ppc32.c: Conversion between 32bit and 64bit native syscalls. 3 * 4 * Copyright (C) 2001 IBM 5 * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) 6 * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) 7 * 8 * These routines maintain argument size conversion between 32bit and 64bit 9 * environment. 10 * 11 * This program is free software; you can redistribute it and/or 12 * modify it under the terms of the GNU General Public License 13 * as published by the Free Software Foundation; either version 14 * 2 of the License, or (at your option) any later version. 15 */ 16 17 #include <linux/kernel.h> 18 #include <linux/sched.h> 19 #include <linux/fs.h> 20 #include <linux/mm.h> 21 #include <linux/file.h> 22 #include <linux/signal.h> 23 #include <linux/resource.h> 24 #include <linux/times.h> 25 #include <linux/utsname.h> 26 #include <linux/smp.h> 27 #include <linux/smp_lock.h> 28 #include <linux/sem.h> 29 #include <linux/msg.h> 30 #include <linux/shm.h> 31 #include <linux/poll.h> 32 #include <linux/personality.h> 33 #include <linux/stat.h> 34 #include <linux/mman.h> 35 #include <linux/in.h> 36 #include <linux/syscalls.h> 37 #include <linux/unistd.h> 38 #include <linux/sysctl.h> 39 #include <linux/binfmts.h> 40 #include <linux/security.h> 41 #include <linux/compat.h> 42 #include <linux/ptrace.h> 43 #include <linux/elf.h> 44 45 #include <asm/ptrace.h> 46 #include <asm/types.h> 47 #include <asm/ipc.h> 48 #include <asm/uaccess.h> 49 #include <asm/unistd.h> 50 #include <asm/semaphore.h> 51 #include <asm/time.h> 52 #include <asm/mmu_context.h> 53 #include <asm/ppc-pci.h> 54 #include <asm/syscalls.h> 55 56 /* readdir & getdents */ 57 #define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de))) 58 #define ROUND_UP(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1)) 59 60 struct old_linux_dirent32 { 61 u32 d_ino; 62 u32 d_offset; 63 unsigned short d_namlen; 64 char d_name[1]; 65 }; 66 67 struct readdir_callback32 { 68 struct old_linux_dirent32 __user * dirent; 69 int count; 70 }; 71 72 static int fillonedir(void * __buf, const char * name, int namlen, 73 off_t offset, u64 ino, unsigned int d_type) 74 { 75 struct readdir_callback32 * buf = (struct readdir_callback32 *) __buf; 76 struct old_linux_dirent32 __user * dirent; 77 ino_t d_ino; 78 79 if (buf->count) 80 return -EINVAL; 81 d_ino = ino; 82 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) 83 return -EOVERFLOW; 84 buf->count++; 85 dirent = buf->dirent; 86 put_user(d_ino, &dirent->d_ino); 87 put_user(offset, &dirent->d_offset); 88 put_user(namlen, &dirent->d_namlen); 89 copy_to_user(dirent->d_name, name, namlen); 90 put_user(0, dirent->d_name + namlen); 91 return 0; 92 } 93 94 asmlinkage int old32_readdir(unsigned int fd, struct old_linux_dirent32 __user *dirent, unsigned int count) 95 { 96 int error = -EBADF; 97 struct file * file; 98 struct readdir_callback32 buf; 99 100 file = fget(fd); 101 if (!file) 102 goto out; 103 104 buf.count = 0; 105 buf.dirent = dirent; 106 107 error = vfs_readdir(file, (filldir_t)fillonedir, &buf); 108 if (error < 0) 109 goto out_putf; 110 error = buf.count; 111 112 out_putf: 113 fput(file); 114 out: 115 return error; 116 } 117 118 asmlinkage long ppc32_select(u32 n, compat_ulong_t __user *inp, 119 compat_ulong_t __user *outp, compat_ulong_t __user *exp, 120 compat_uptr_t tvp_x) 121 { 122 /* sign extend n */ 123 return compat_sys_select((int)n, inp, outp, exp, compat_ptr(tvp_x)); 124 } 125 126 int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) 127 { 128 compat_ino_t ino; 129 long err; 130 131 if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) || 132 !new_valid_dev(stat->rdev)) 133 return -EOVERFLOW; 134 135 ino = stat->ino; 136 if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino) 137 return -EOVERFLOW; 138 139 err = access_ok(VERIFY_WRITE, statbuf, sizeof(*statbuf)) ? 0 : -EFAULT; 140 err |= __put_user(new_encode_dev(stat->dev), &statbuf->st_dev); 141 err |= __put_user(ino, &statbuf->st_ino); 142 err |= __put_user(stat->mode, &statbuf->st_mode); 143 err |= __put_user(stat->nlink, &statbuf->st_nlink); 144 err |= __put_user(stat->uid, &statbuf->st_uid); 145 err |= __put_user(stat->gid, &statbuf->st_gid); 146 err |= __put_user(new_encode_dev(stat->rdev), &statbuf->st_rdev); 147 err |= __put_user(stat->size, &statbuf->st_size); 148 err |= __put_user(stat->atime.tv_sec, &statbuf->st_atime); 149 err |= __put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec); 150 err |= __put_user(stat->mtime.tv_sec, &statbuf->st_mtime); 151 err |= __put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec); 152 err |= __put_user(stat->ctime.tv_sec, &statbuf->st_ctime); 153 err |= __put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec); 154 err |= __put_user(stat->blksize, &statbuf->st_blksize); 155 err |= __put_user(stat->blocks, &statbuf->st_blocks); 156 err |= __put_user(0, &statbuf->__unused4[0]); 157 err |= __put_user(0, &statbuf->__unused4[1]); 158 159 return err; 160 } 161 162 /* Note: it is necessary to treat option as an unsigned int, 163 * with the corresponding cast to a signed int to insure that the 164 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 165 * and the register representation of a signed int (msr in 64-bit mode) is performed. 166 */ 167 asmlinkage long compat_sys_sysfs(u32 option, u32 arg1, u32 arg2) 168 { 169 return sys_sysfs((int)option, arg1, arg2); 170 } 171 172 asmlinkage long compat_sys_pause(void) 173 { 174 current->state = TASK_INTERRUPTIBLE; 175 schedule(); 176 177 return -ERESTARTNOHAND; 178 } 179 180 static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i) 181 { 182 long usec; 183 184 if (!access_ok(VERIFY_READ, i, sizeof(*i))) 185 return -EFAULT; 186 if (__get_user(o->tv_sec, &i->tv_sec)) 187 return -EFAULT; 188 if (__get_user(usec, &i->tv_usec)) 189 return -EFAULT; 190 o->tv_nsec = usec * 1000; 191 return 0; 192 } 193 194 static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i) 195 { 196 return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) || 197 (__put_user(i->tv_sec, &o->tv_sec) | 198 __put_user(i->tv_usec, &o->tv_usec))); 199 } 200 201 struct sysinfo32 { 202 s32 uptime; 203 u32 loads[3]; 204 u32 totalram; 205 u32 freeram; 206 u32 sharedram; 207 u32 bufferram; 208 u32 totalswap; 209 u32 freeswap; 210 unsigned short procs; 211 unsigned short pad; 212 u32 totalhigh; 213 u32 freehigh; 214 u32 mem_unit; 215 char _f[20-2*sizeof(int)-sizeof(int)]; 216 }; 217 218 asmlinkage long compat_sys_sysinfo(struct sysinfo32 __user *info) 219 { 220 struct sysinfo s; 221 int ret, err; 222 int bitcount=0; 223 mm_segment_t old_fs = get_fs (); 224 225 /* The __user cast is valid due to set_fs() */ 226 set_fs (KERNEL_DS); 227 ret = sys_sysinfo((struct sysinfo __user *)&s); 228 set_fs (old_fs); 229 230 /* Check to see if any memory value is too large for 32-bit and 231 * scale down if needed. 232 */ 233 if ((s.totalram >> 32) || (s.totalswap >> 32)) { 234 while (s.mem_unit < PAGE_SIZE) { 235 s.mem_unit <<= 1; 236 bitcount++; 237 } 238 s.totalram >>=bitcount; 239 s.freeram >>= bitcount; 240 s.sharedram >>= bitcount; 241 s.bufferram >>= bitcount; 242 s.totalswap >>= bitcount; 243 s.freeswap >>= bitcount; 244 s.totalhigh >>= bitcount; 245 s.freehigh >>= bitcount; 246 } 247 248 err = put_user (s.uptime, &info->uptime); 249 err |= __put_user (s.loads[0], &info->loads[0]); 250 err |= __put_user (s.loads[1], &info->loads[1]); 251 err |= __put_user (s.loads[2], &info->loads[2]); 252 err |= __put_user (s.totalram, &info->totalram); 253 err |= __put_user (s.freeram, &info->freeram); 254 err |= __put_user (s.sharedram, &info->sharedram); 255 err |= __put_user (s.bufferram, &info->bufferram); 256 err |= __put_user (s.totalswap, &info->totalswap); 257 err |= __put_user (s.freeswap, &info->freeswap); 258 err |= __put_user (s.procs, &info->procs); 259 err |= __put_user (s.totalhigh, &info->totalhigh); 260 err |= __put_user (s.freehigh, &info->freehigh); 261 err |= __put_user (s.mem_unit, &info->mem_unit); 262 if (err) 263 return -EFAULT; 264 265 return ret; 266 } 267 268 269 270 271 /* Translations due to time_t size differences. Which affects all 272 sorts of things, like timeval and itimerval. */ 273 extern struct timezone sys_tz; 274 275 asmlinkage long compat_sys_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz) 276 { 277 if (tv) { 278 struct timeval ktv; 279 do_gettimeofday(&ktv); 280 if (put_tv32(tv, &ktv)) 281 return -EFAULT; 282 } 283 if (tz) { 284 if (copy_to_user(tz, &sys_tz, sizeof(sys_tz))) 285 return -EFAULT; 286 } 287 288 return 0; 289 } 290 291 292 293 asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz) 294 { 295 struct timespec kts; 296 struct timezone ktz; 297 298 if (tv) { 299 if (get_ts32(&kts, tv)) 300 return -EFAULT; 301 } 302 if (tz) { 303 if (copy_from_user(&ktz, tz, sizeof(ktz))) 304 return -EFAULT; 305 } 306 307 return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL); 308 } 309 310 #ifdef CONFIG_SYSVIPC 311 long compat_sys_ipc(u32 call, u32 first, u32 second, u32 third, compat_uptr_t ptr, 312 u32 fifth) 313 { 314 int version; 315 316 version = call >> 16; /* hack for backward compatibility */ 317 call &= 0xffff; 318 319 switch (call) { 320 321 case SEMTIMEDOP: 322 if (fifth) 323 /* sign extend semid */ 324 return compat_sys_semtimedop((int)first, 325 compat_ptr(ptr), second, 326 compat_ptr(fifth)); 327 /* else fall through for normal semop() */ 328 case SEMOP: 329 /* struct sembuf is the same on 32 and 64bit :)) */ 330 /* sign extend semid */ 331 return sys_semtimedop((int)first, compat_ptr(ptr), second, 332 NULL); 333 case SEMGET: 334 /* sign extend key, nsems */ 335 return sys_semget((int)first, (int)second, third); 336 case SEMCTL: 337 /* sign extend semid, semnum */ 338 return compat_sys_semctl((int)first, (int)second, third, 339 compat_ptr(ptr)); 340 341 case MSGSND: 342 /* sign extend msqid */ 343 return compat_sys_msgsnd((int)first, (int)second, third, 344 compat_ptr(ptr)); 345 case MSGRCV: 346 /* sign extend msqid, msgtyp */ 347 return compat_sys_msgrcv((int)first, second, (int)fifth, 348 third, version, compat_ptr(ptr)); 349 case MSGGET: 350 /* sign extend key */ 351 return sys_msgget((int)first, second); 352 case MSGCTL: 353 /* sign extend msqid */ 354 return compat_sys_msgctl((int)first, second, compat_ptr(ptr)); 355 356 case SHMAT: 357 /* sign extend shmid */ 358 return compat_sys_shmat((int)first, second, third, version, 359 compat_ptr(ptr)); 360 case SHMDT: 361 return sys_shmdt(compat_ptr(ptr)); 362 case SHMGET: 363 /* sign extend key_t */ 364 return sys_shmget((int)first, second, third); 365 case SHMCTL: 366 /* sign extend shmid */ 367 return compat_sys_shmctl((int)first, second, compat_ptr(ptr)); 368 369 default: 370 return -ENOSYS; 371 } 372 373 return -ENOSYS; 374 } 375 #endif 376 377 /* Note: it is necessary to treat out_fd and in_fd as unsigned ints, 378 * with the corresponding cast to a signed int to insure that the 379 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 380 * and the register representation of a signed int (msr in 64-bit mode) is performed. 381 */ 382 asmlinkage long compat_sys_sendfile(u32 out_fd, u32 in_fd, compat_off_t __user * offset, u32 count) 383 { 384 mm_segment_t old_fs = get_fs(); 385 int ret; 386 off_t of; 387 off_t __user *up; 388 389 if (offset && get_user(of, offset)) 390 return -EFAULT; 391 392 /* The __user pointer cast is valid because of the set_fs() */ 393 set_fs(KERNEL_DS); 394 up = offset ? (off_t __user *) &of : NULL; 395 ret = sys_sendfile((int)out_fd, (int)in_fd, up, count); 396 set_fs(old_fs); 397 398 if (offset && put_user(of, offset)) 399 return -EFAULT; 400 401 return ret; 402 } 403 404 asmlinkage int compat_sys_sendfile64(int out_fd, int in_fd, compat_loff_t __user *offset, s32 count) 405 { 406 mm_segment_t old_fs = get_fs(); 407 int ret; 408 loff_t lof; 409 loff_t __user *up; 410 411 if (offset && get_user(lof, offset)) 412 return -EFAULT; 413 414 /* The __user pointer cast is valid because of the set_fs() */ 415 set_fs(KERNEL_DS); 416 up = offset ? (loff_t __user *) &lof : NULL; 417 ret = sys_sendfile64(out_fd, in_fd, up, count); 418 set_fs(old_fs); 419 420 if (offset && put_user(lof, offset)) 421 return -EFAULT; 422 423 return ret; 424 } 425 426 long compat_sys_execve(unsigned long a0, unsigned long a1, unsigned long a2, 427 unsigned long a3, unsigned long a4, unsigned long a5, 428 struct pt_regs *regs) 429 { 430 int error; 431 char * filename; 432 433 filename = getname((char __user *) a0); 434 error = PTR_ERR(filename); 435 if (IS_ERR(filename)) 436 goto out; 437 flush_fp_to_thread(current); 438 flush_altivec_to_thread(current); 439 440 error = compat_do_execve(filename, compat_ptr(a1), compat_ptr(a2), regs); 441 442 if (error == 0) { 443 task_lock(current); 444 current->ptrace &= ~PT_DTRACE; 445 task_unlock(current); 446 } 447 putname(filename); 448 449 out: 450 return error; 451 } 452 453 /* Note: it is necessary to treat option as an unsigned int, 454 * with the corresponding cast to a signed int to insure that the 455 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 456 * and the register representation of a signed int (msr in 64-bit mode) is performed. 457 */ 458 asmlinkage long compat_sys_prctl(u32 option, u32 arg2, u32 arg3, u32 arg4, u32 arg5) 459 { 460 return sys_prctl((int)option, 461 (unsigned long) arg2, 462 (unsigned long) arg3, 463 (unsigned long) arg4, 464 (unsigned long) arg5); 465 } 466 467 /* Note: it is necessary to treat pid as an unsigned int, 468 * with the corresponding cast to a signed int to insure that the 469 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 470 * and the register representation of a signed int (msr in 64-bit mode) is performed. 471 */ 472 asmlinkage long compat_sys_sched_rr_get_interval(u32 pid, struct compat_timespec __user *interval) 473 { 474 struct timespec t; 475 int ret; 476 mm_segment_t old_fs = get_fs (); 477 478 /* The __user pointer cast is valid because of the set_fs() */ 479 set_fs (KERNEL_DS); 480 ret = sys_sched_rr_get_interval((int)pid, (struct timespec __user *) &t); 481 set_fs (old_fs); 482 if (put_compat_timespec(&t, interval)) 483 return -EFAULT; 484 return ret; 485 } 486 487 /* Note: it is necessary to treat mode as an unsigned int, 488 * with the corresponding cast to a signed int to insure that the 489 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 490 * and the register representation of a signed int (msr in 64-bit mode) is performed. 491 */ 492 asmlinkage long compat_sys_access(const char __user * filename, u32 mode) 493 { 494 return sys_access(filename, (int)mode); 495 } 496 497 498 /* Note: it is necessary to treat mode as an unsigned int, 499 * with the corresponding cast to a signed int to insure that the 500 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 501 * and the register representation of a signed int (msr in 64-bit mode) is performed. 502 */ 503 asmlinkage long compat_sys_creat(const char __user * pathname, u32 mode) 504 { 505 return sys_creat(pathname, (int)mode); 506 } 507 508 509 /* Note: it is necessary to treat pid and options as unsigned ints, 510 * with the corresponding cast to a signed int to insure that the 511 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 512 * and the register representation of a signed int (msr in 64-bit mode) is performed. 513 */ 514 asmlinkage long compat_sys_waitpid(u32 pid, unsigned int __user * stat_addr, u32 options) 515 { 516 return sys_waitpid((int)pid, stat_addr, (int)options); 517 } 518 519 520 /* Note: it is necessary to treat gidsetsize as an unsigned int, 521 * with the corresponding cast to a signed int to insure that the 522 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 523 * and the register representation of a signed int (msr in 64-bit mode) is performed. 524 */ 525 asmlinkage long compat_sys_getgroups(u32 gidsetsize, gid_t __user *grouplist) 526 { 527 return sys_getgroups((int)gidsetsize, grouplist); 528 } 529 530 531 /* Note: it is necessary to treat pid as an unsigned int, 532 * with the corresponding cast to a signed int to insure that the 533 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 534 * and the register representation of a signed int (msr in 64-bit mode) is performed. 535 */ 536 asmlinkage long compat_sys_getpgid(u32 pid) 537 { 538 return sys_getpgid((int)pid); 539 } 540 541 542 543 /* Note: it is necessary to treat pid as an unsigned int, 544 * with the corresponding cast to a signed int to insure that the 545 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 546 * and the register representation of a signed int (msr in 64-bit mode) is performed. 547 */ 548 asmlinkage long compat_sys_getsid(u32 pid) 549 { 550 return sys_getsid((int)pid); 551 } 552 553 554 /* Note: it is necessary to treat pid and sig as unsigned ints, 555 * with the corresponding cast to a signed int to insure that the 556 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 557 * and the register representation of a signed int (msr in 64-bit mode) is performed. 558 */ 559 asmlinkage long compat_sys_kill(u32 pid, u32 sig) 560 { 561 return sys_kill((int)pid, (int)sig); 562 } 563 564 565 /* Note: it is necessary to treat mode as an unsigned int, 566 * with the corresponding cast to a signed int to insure that the 567 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 568 * and the register representation of a signed int (msr in 64-bit mode) is performed. 569 */ 570 asmlinkage long compat_sys_mkdir(const char __user * pathname, u32 mode) 571 { 572 return sys_mkdir(pathname, (int)mode); 573 } 574 575 long compat_sys_nice(u32 increment) 576 { 577 /* sign extend increment */ 578 return sys_nice((int)increment); 579 } 580 581 off_t ppc32_lseek(unsigned int fd, u32 offset, unsigned int origin) 582 { 583 /* sign extend n */ 584 return sys_lseek(fd, (int)offset, origin); 585 } 586 587 /* Note: it is necessary to treat bufsiz as an unsigned int, 588 * with the corresponding cast to a signed int to insure that the 589 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 590 * and the register representation of a signed int (msr in 64-bit mode) is performed. 591 */ 592 asmlinkage long compat_sys_readlink(const char __user * path, char __user * buf, u32 bufsiz) 593 { 594 return sys_readlink(path, buf, (int)bufsiz); 595 } 596 597 /* Note: it is necessary to treat option as an unsigned int, 598 * with the corresponding cast to a signed int to insure that the 599 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 600 * and the register representation of a signed int (msr in 64-bit mode) is performed. 601 */ 602 asmlinkage long compat_sys_sched_get_priority_max(u32 policy) 603 { 604 return sys_sched_get_priority_max((int)policy); 605 } 606 607 608 /* Note: it is necessary to treat policy as an unsigned int, 609 * with the corresponding cast to a signed int to insure that the 610 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 611 * and the register representation of a signed int (msr in 64-bit mode) is performed. 612 */ 613 asmlinkage long compat_sys_sched_get_priority_min(u32 policy) 614 { 615 return sys_sched_get_priority_min((int)policy); 616 } 617 618 619 /* Note: it is necessary to treat pid as an unsigned int, 620 * with the corresponding cast to a signed int to insure that the 621 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 622 * and the register representation of a signed int (msr in 64-bit mode) is performed. 623 */ 624 asmlinkage long compat_sys_sched_getparam(u32 pid, struct sched_param __user *param) 625 { 626 return sys_sched_getparam((int)pid, param); 627 } 628 629 630 /* Note: it is necessary to treat pid as an unsigned int, 631 * with the corresponding cast to a signed int to insure that the 632 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 633 * and the register representation of a signed int (msr in 64-bit mode) is performed. 634 */ 635 asmlinkage long compat_sys_sched_getscheduler(u32 pid) 636 { 637 return sys_sched_getscheduler((int)pid); 638 } 639 640 641 /* Note: it is necessary to treat pid as an unsigned int, 642 * with the corresponding cast to a signed int to insure that the 643 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 644 * and the register representation of a signed int (msr in 64-bit mode) is performed. 645 */ 646 asmlinkage long compat_sys_sched_setparam(u32 pid, struct sched_param __user *param) 647 { 648 return sys_sched_setparam((int)pid, param); 649 } 650 651 652 /* Note: it is necessary to treat pid and policy as unsigned ints, 653 * with the corresponding cast to a signed int to insure that the 654 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 655 * and the register representation of a signed int (msr in 64-bit mode) is performed. 656 */ 657 asmlinkage long compat_sys_sched_setscheduler(u32 pid, u32 policy, struct sched_param __user *param) 658 { 659 return sys_sched_setscheduler((int)pid, (int)policy, param); 660 } 661 662 663 /* Note: it is necessary to treat len as an unsigned int, 664 * with the corresponding cast to a signed int to insure that the 665 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 666 * and the register representation of a signed int (msr in 64-bit mode) is performed. 667 */ 668 asmlinkage long compat_sys_setdomainname(char __user *name, u32 len) 669 { 670 return sys_setdomainname(name, (int)len); 671 } 672 673 674 /* Note: it is necessary to treat gidsetsize as an unsigned int, 675 * with the corresponding cast to a signed int to insure that the 676 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 677 * and the register representation of a signed int (msr in 64-bit mode) is performed. 678 */ 679 asmlinkage long compat_sys_setgroups(u32 gidsetsize, gid_t __user *grouplist) 680 { 681 return sys_setgroups((int)gidsetsize, grouplist); 682 } 683 684 685 asmlinkage long compat_sys_sethostname(char __user *name, u32 len) 686 { 687 /* sign extend len */ 688 return sys_sethostname(name, (int)len); 689 } 690 691 692 /* Note: it is necessary to treat pid and pgid as unsigned ints, 693 * with the corresponding cast to a signed int to insure that the 694 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 695 * and the register representation of a signed int (msr in 64-bit mode) is performed. 696 */ 697 asmlinkage long compat_sys_setpgid(u32 pid, u32 pgid) 698 { 699 return sys_setpgid((int)pid, (int)pgid); 700 } 701 702 long compat_sys_getpriority(u32 which, u32 who) 703 { 704 /* sign extend which and who */ 705 return sys_getpriority((int)which, (int)who); 706 } 707 708 long compat_sys_setpriority(u32 which, u32 who, u32 niceval) 709 { 710 /* sign extend which, who and niceval */ 711 return sys_setpriority((int)which, (int)who, (int)niceval); 712 } 713 714 long compat_sys_ioprio_get(u32 which, u32 who) 715 { 716 /* sign extend which and who */ 717 return sys_ioprio_get((int)which, (int)who); 718 } 719 720 long compat_sys_ioprio_set(u32 which, u32 who, u32 ioprio) 721 { 722 /* sign extend which, who and ioprio */ 723 return sys_ioprio_set((int)which, (int)who, (int)ioprio); 724 } 725 726 /* Note: it is necessary to treat newmask as an unsigned int, 727 * with the corresponding cast to a signed int to insure that the 728 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 729 * and the register representation of a signed int (msr in 64-bit mode) is performed. 730 */ 731 asmlinkage long compat_sys_ssetmask(u32 newmask) 732 { 733 return sys_ssetmask((int) newmask); 734 } 735 736 asmlinkage long compat_sys_syslog(u32 type, char __user * buf, u32 len) 737 { 738 /* sign extend len */ 739 return sys_syslog(type, buf, (int)len); 740 } 741 742 743 /* Note: it is necessary to treat mask as an unsigned int, 744 * with the corresponding cast to a signed int to insure that the 745 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 746 * and the register representation of a signed int (msr in 64-bit mode) is performed. 747 */ 748 asmlinkage long compat_sys_umask(u32 mask) 749 { 750 return sys_umask((int)mask); 751 } 752 753 #ifdef CONFIG_SYSCTL_SYSCALL 754 struct __sysctl_args32 { 755 u32 name; 756 int nlen; 757 u32 oldval; 758 u32 oldlenp; 759 u32 newval; 760 u32 newlen; 761 u32 __unused[4]; 762 }; 763 764 asmlinkage long compat_sys_sysctl(struct __sysctl_args32 __user *args) 765 { 766 struct __sysctl_args32 tmp; 767 int error; 768 size_t oldlen; 769 size_t __user *oldlenp = NULL; 770 unsigned long addr = (((unsigned long)&args->__unused[0]) + 7) & ~7; 771 772 if (copy_from_user(&tmp, args, sizeof(tmp))) 773 return -EFAULT; 774 775 if (tmp.oldval && tmp.oldlenp) { 776 /* Duh, this is ugly and might not work if sysctl_args 777 is in read-only memory, but do_sysctl does indirectly 778 a lot of uaccess in both directions and we'd have to 779 basically copy the whole sysctl.c here, and 780 glibc's __sysctl uses rw memory for the structure 781 anyway. */ 782 oldlenp = (size_t __user *)addr; 783 if (get_user(oldlen, (compat_size_t __user *)compat_ptr(tmp.oldlenp)) || 784 put_user(oldlen, oldlenp)) 785 return -EFAULT; 786 } 787 788 lock_kernel(); 789 error = do_sysctl(compat_ptr(tmp.name), tmp.nlen, 790 compat_ptr(tmp.oldval), oldlenp, 791 compat_ptr(tmp.newval), tmp.newlen); 792 unlock_kernel(); 793 if (oldlenp) { 794 if (!error) { 795 if (get_user(oldlen, oldlenp) || 796 put_user(oldlen, (compat_size_t __user *)compat_ptr(tmp.oldlenp))) 797 error = -EFAULT; 798 } 799 copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused)); 800 } 801 return error; 802 } 803 #endif 804 805 unsigned long compat_sys_mmap2(unsigned long addr, size_t len, 806 unsigned long prot, unsigned long flags, 807 unsigned long fd, unsigned long pgoff) 808 { 809 /* This should remain 12 even if PAGE_SIZE changes */ 810 return sys_mmap(addr, len, prot, flags, fd, pgoff << 12); 811 } 812 813 long compat_sys_tgkill(u32 tgid, u32 pid, int sig) 814 { 815 /* sign extend tgid, pid */ 816 return sys_tgkill((int)tgid, (int)pid, sig); 817 } 818 819 /* 820 * long long munging: 821 * The 32 bit ABI passes long longs in an odd even register pair. 822 */ 823 824 compat_ssize_t compat_sys_pread64(unsigned int fd, char __user *ubuf, compat_size_t count, 825 u32 reg6, u32 poshi, u32 poslo) 826 { 827 return sys_pread64(fd, ubuf, count, ((loff_t)poshi << 32) | poslo); 828 } 829 830 compat_ssize_t compat_sys_pwrite64(unsigned int fd, char __user *ubuf, compat_size_t count, 831 u32 reg6, u32 poshi, u32 poslo) 832 { 833 return sys_pwrite64(fd, ubuf, count, ((loff_t)poshi << 32) | poslo); 834 } 835 836 compat_ssize_t compat_sys_readahead(int fd, u32 r4, u32 offhi, u32 offlo, u32 count) 837 { 838 return sys_readahead(fd, ((loff_t)offhi << 32) | offlo, count); 839 } 840 841 asmlinkage int compat_sys_truncate64(const char __user * path, u32 reg4, 842 unsigned long high, unsigned long low) 843 { 844 return sys_truncate(path, (high << 32) | low); 845 } 846 847 asmlinkage int compat_sys_ftruncate64(unsigned int fd, u32 reg4, unsigned long high, 848 unsigned long low) 849 { 850 return sys_ftruncate(fd, (high << 32) | low); 851 } 852 853 long ppc32_lookup_dcookie(u32 cookie_high, u32 cookie_low, char __user *buf, 854 size_t len) 855 { 856 return sys_lookup_dcookie((u64)cookie_high << 32 | cookie_low, 857 buf, len); 858 } 859 860 long ppc32_fadvise64(int fd, u32 unused, u32 offset_high, u32 offset_low, 861 size_t len, int advice) 862 { 863 return sys_fadvise64(fd, (u64)offset_high << 32 | offset_low, len, 864 advice); 865 } 866 867 asmlinkage long compat_sys_add_key(const char __user *_type, 868 const char __user *_description, 869 const void __user *_payload, 870 u32 plen, 871 u32 ringid) 872 { 873 return sys_add_key(_type, _description, _payload, plen, ringid); 874 } 875 876 asmlinkage long compat_sys_request_key(const char __user *_type, 877 const char __user *_description, 878 const char __user *_callout_info, 879 u32 destringid) 880 { 881 return sys_request_key(_type, _description, _callout_info, destringid); 882 } 883 884