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 #include <linux/ipc.h> 45 46 #include <asm/ptrace.h> 47 #include <asm/types.h> 48 #include <asm/uaccess.h> 49 #include <asm/unistd.h> 50 #include <asm/time.h> 51 #include <asm/mmu_context.h> 52 #include <asm/ppc-pci.h> 53 #include <asm/syscalls.h> 54 55 56 asmlinkage long ppc32_select(u32 n, compat_ulong_t __user *inp, 57 compat_ulong_t __user *outp, compat_ulong_t __user *exp, 58 compat_uptr_t tvp_x) 59 { 60 /* sign extend n */ 61 return compat_sys_select((int)n, inp, outp, exp, compat_ptr(tvp_x)); 62 } 63 64 int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) 65 { 66 compat_ino_t ino; 67 long err; 68 69 if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) || 70 !new_valid_dev(stat->rdev)) 71 return -EOVERFLOW; 72 73 ino = stat->ino; 74 if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino) 75 return -EOVERFLOW; 76 77 err = access_ok(VERIFY_WRITE, statbuf, sizeof(*statbuf)) ? 0 : -EFAULT; 78 err |= __put_user(new_encode_dev(stat->dev), &statbuf->st_dev); 79 err |= __put_user(ino, &statbuf->st_ino); 80 err |= __put_user(stat->mode, &statbuf->st_mode); 81 err |= __put_user(stat->nlink, &statbuf->st_nlink); 82 err |= __put_user(stat->uid, &statbuf->st_uid); 83 err |= __put_user(stat->gid, &statbuf->st_gid); 84 err |= __put_user(new_encode_dev(stat->rdev), &statbuf->st_rdev); 85 err |= __put_user(stat->size, &statbuf->st_size); 86 err |= __put_user(stat->atime.tv_sec, &statbuf->st_atime); 87 err |= __put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec); 88 err |= __put_user(stat->mtime.tv_sec, &statbuf->st_mtime); 89 err |= __put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec); 90 err |= __put_user(stat->ctime.tv_sec, &statbuf->st_ctime); 91 err |= __put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec); 92 err |= __put_user(stat->blksize, &statbuf->st_blksize); 93 err |= __put_user(stat->blocks, &statbuf->st_blocks); 94 err |= __put_user(0, &statbuf->__unused4[0]); 95 err |= __put_user(0, &statbuf->__unused4[1]); 96 97 return err; 98 } 99 100 /* Note: it is necessary to treat option as an unsigned int, 101 * with the corresponding cast to a signed int to insure that the 102 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 103 * and the register representation of a signed int (msr in 64-bit mode) is performed. 104 */ 105 asmlinkage long compat_sys_sysfs(u32 option, u32 arg1, u32 arg2) 106 { 107 return sys_sysfs((int)option, arg1, arg2); 108 } 109 110 asmlinkage long compat_sys_pause(void) 111 { 112 current->state = TASK_INTERRUPTIBLE; 113 schedule(); 114 115 return -ERESTARTNOHAND; 116 } 117 118 static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i) 119 { 120 long usec; 121 122 if (!access_ok(VERIFY_READ, i, sizeof(*i))) 123 return -EFAULT; 124 if (__get_user(o->tv_sec, &i->tv_sec)) 125 return -EFAULT; 126 if (__get_user(usec, &i->tv_usec)) 127 return -EFAULT; 128 o->tv_nsec = usec * 1000; 129 return 0; 130 } 131 132 static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i) 133 { 134 return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) || 135 (__put_user(i->tv_sec, &o->tv_sec) | 136 __put_user(i->tv_usec, &o->tv_usec))); 137 } 138 139 140 141 142 /* Translations due to time_t size differences. Which affects all 143 sorts of things, like timeval and itimerval. */ 144 extern struct timezone sys_tz; 145 146 asmlinkage long compat_sys_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz) 147 { 148 if (tv) { 149 struct timeval ktv; 150 do_gettimeofday(&ktv); 151 if (put_tv32(tv, &ktv)) 152 return -EFAULT; 153 } 154 if (tz) { 155 if (copy_to_user(tz, &sys_tz, sizeof(sys_tz))) 156 return -EFAULT; 157 } 158 159 return 0; 160 } 161 162 163 164 asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz) 165 { 166 struct timespec kts; 167 struct timezone ktz; 168 169 if (tv) { 170 if (get_ts32(&kts, tv)) 171 return -EFAULT; 172 } 173 if (tz) { 174 if (copy_from_user(&ktz, tz, sizeof(ktz))) 175 return -EFAULT; 176 } 177 178 return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL); 179 } 180 181 #ifdef CONFIG_SYSVIPC 182 long compat_sys_ipc(u32 call, u32 first, u32 second, u32 third, compat_uptr_t ptr, 183 u32 fifth) 184 { 185 int version; 186 187 version = call >> 16; /* hack for backward compatibility */ 188 call &= 0xffff; 189 190 switch (call) { 191 192 case SEMTIMEDOP: 193 if (fifth) 194 /* sign extend semid */ 195 return compat_sys_semtimedop((int)first, 196 compat_ptr(ptr), second, 197 compat_ptr(fifth)); 198 /* else fall through for normal semop() */ 199 case SEMOP: 200 /* struct sembuf is the same on 32 and 64bit :)) */ 201 /* sign extend semid */ 202 return sys_semtimedop((int)first, compat_ptr(ptr), second, 203 NULL); 204 case SEMGET: 205 /* sign extend key, nsems */ 206 return sys_semget((int)first, (int)second, third); 207 case SEMCTL: 208 /* sign extend semid, semnum */ 209 return compat_sys_semctl((int)first, (int)second, third, 210 compat_ptr(ptr)); 211 212 case MSGSND: 213 /* sign extend msqid */ 214 return compat_sys_msgsnd((int)first, (int)second, third, 215 compat_ptr(ptr)); 216 case MSGRCV: 217 /* sign extend msqid, msgtyp */ 218 return compat_sys_msgrcv((int)first, second, (int)fifth, 219 third, version, compat_ptr(ptr)); 220 case MSGGET: 221 /* sign extend key */ 222 return sys_msgget((int)first, second); 223 case MSGCTL: 224 /* sign extend msqid */ 225 return compat_sys_msgctl((int)first, second, compat_ptr(ptr)); 226 227 case SHMAT: 228 /* sign extend shmid */ 229 return compat_sys_shmat((int)first, second, third, version, 230 compat_ptr(ptr)); 231 case SHMDT: 232 return sys_shmdt(compat_ptr(ptr)); 233 case SHMGET: 234 /* sign extend key_t */ 235 return sys_shmget((int)first, second, third); 236 case SHMCTL: 237 /* sign extend shmid */ 238 return compat_sys_shmctl((int)first, second, compat_ptr(ptr)); 239 240 default: 241 return -ENOSYS; 242 } 243 244 return -ENOSYS; 245 } 246 #endif 247 248 /* Note: it is necessary to treat out_fd and in_fd as unsigned ints, 249 * with the corresponding cast to a signed int to insure that the 250 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 251 * and the register representation of a signed int (msr in 64-bit mode) is performed. 252 */ 253 asmlinkage long compat_sys_sendfile(u32 out_fd, u32 in_fd, compat_off_t __user * offset, u32 count) 254 { 255 mm_segment_t old_fs = get_fs(); 256 int ret; 257 off_t of; 258 off_t __user *up; 259 260 if (offset && get_user(of, offset)) 261 return -EFAULT; 262 263 /* The __user pointer cast is valid because of the set_fs() */ 264 set_fs(KERNEL_DS); 265 up = offset ? (off_t __user *) &of : NULL; 266 ret = sys_sendfile((int)out_fd, (int)in_fd, up, count); 267 set_fs(old_fs); 268 269 if (offset && put_user(of, offset)) 270 return -EFAULT; 271 272 return ret; 273 } 274 275 asmlinkage int compat_sys_sendfile64(int out_fd, int in_fd, compat_loff_t __user *offset, s32 count) 276 { 277 mm_segment_t old_fs = get_fs(); 278 int ret; 279 loff_t lof; 280 loff_t __user *up; 281 282 if (offset && get_user(lof, offset)) 283 return -EFAULT; 284 285 /* The __user pointer cast is valid because of the set_fs() */ 286 set_fs(KERNEL_DS); 287 up = offset ? (loff_t __user *) &lof : NULL; 288 ret = sys_sendfile64(out_fd, in_fd, up, count); 289 set_fs(old_fs); 290 291 if (offset && put_user(lof, offset)) 292 return -EFAULT; 293 294 return ret; 295 } 296 297 long compat_sys_execve(unsigned long a0, unsigned long a1, unsigned long a2, 298 unsigned long a3, unsigned long a4, unsigned long a5, 299 struct pt_regs *regs) 300 { 301 int error; 302 char * filename; 303 304 filename = getname((char __user *) a0); 305 error = PTR_ERR(filename); 306 if (IS_ERR(filename)) 307 goto out; 308 flush_fp_to_thread(current); 309 flush_altivec_to_thread(current); 310 311 error = compat_do_execve(filename, compat_ptr(a1), compat_ptr(a2), regs); 312 313 putname(filename); 314 315 out: 316 return error; 317 } 318 319 /* Note: it is necessary to treat option as an unsigned int, 320 * with the corresponding cast to a signed int to insure that the 321 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 322 * and the register representation of a signed int (msr in 64-bit mode) is performed. 323 */ 324 asmlinkage long compat_sys_prctl(u32 option, u32 arg2, u32 arg3, u32 arg4, u32 arg5) 325 { 326 return sys_prctl((int)option, 327 (unsigned long) arg2, 328 (unsigned long) arg3, 329 (unsigned long) arg4, 330 (unsigned long) arg5); 331 } 332 333 /* Note: it is necessary to treat pid as an unsigned int, 334 * with the corresponding cast to a signed int to insure that the 335 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 336 * and the register representation of a signed int (msr in 64-bit mode) is performed. 337 */ 338 asmlinkage long compat_sys_sched_rr_get_interval(u32 pid, struct compat_timespec __user *interval) 339 { 340 struct timespec t; 341 int ret; 342 mm_segment_t old_fs = get_fs (); 343 344 /* The __user pointer cast is valid because of the set_fs() */ 345 set_fs (KERNEL_DS); 346 ret = sys_sched_rr_get_interval((int)pid, (struct timespec __user *) &t); 347 set_fs (old_fs); 348 if (put_compat_timespec(&t, interval)) 349 return -EFAULT; 350 return ret; 351 } 352 353 /* Note: it is necessary to treat mode as an unsigned int, 354 * with the corresponding cast to a signed int to insure that the 355 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 356 * and the register representation of a signed int (msr in 64-bit mode) is performed. 357 */ 358 asmlinkage long compat_sys_access(const char __user * filename, u32 mode) 359 { 360 return sys_access(filename, (int)mode); 361 } 362 363 364 /* Note: it is necessary to treat mode as an unsigned int, 365 * with the corresponding cast to a signed int to insure that the 366 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 367 * and the register representation of a signed int (msr in 64-bit mode) is performed. 368 */ 369 asmlinkage long compat_sys_creat(const char __user * pathname, u32 mode) 370 { 371 return sys_creat(pathname, (int)mode); 372 } 373 374 375 /* Note: it is necessary to treat pid and options as unsigned ints, 376 * with the corresponding cast to a signed int to insure that the 377 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 378 * and the register representation of a signed int (msr in 64-bit mode) is performed. 379 */ 380 asmlinkage long compat_sys_waitpid(u32 pid, unsigned int __user * stat_addr, u32 options) 381 { 382 return sys_waitpid((int)pid, stat_addr, (int)options); 383 } 384 385 386 /* Note: it is necessary to treat gidsetsize as an unsigned int, 387 * with the corresponding cast to a signed int to insure that the 388 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 389 * and the register representation of a signed int (msr in 64-bit mode) is performed. 390 */ 391 asmlinkage long compat_sys_getgroups(u32 gidsetsize, gid_t __user *grouplist) 392 { 393 return sys_getgroups((int)gidsetsize, grouplist); 394 } 395 396 397 /* Note: it is necessary to treat pid as an unsigned int, 398 * with the corresponding cast to a signed int to insure that the 399 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 400 * and the register representation of a signed int (msr in 64-bit mode) is performed. 401 */ 402 asmlinkage long compat_sys_getpgid(u32 pid) 403 { 404 return sys_getpgid((int)pid); 405 } 406 407 408 409 /* Note: it is necessary to treat pid as an unsigned int, 410 * with the corresponding cast to a signed int to insure that the 411 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 412 * and the register representation of a signed int (msr in 64-bit mode) is performed. 413 */ 414 asmlinkage long compat_sys_getsid(u32 pid) 415 { 416 return sys_getsid((int)pid); 417 } 418 419 420 /* Note: it is necessary to treat pid and sig as unsigned ints, 421 * with the corresponding cast to a signed int to insure that the 422 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 423 * and the register representation of a signed int (msr in 64-bit mode) is performed. 424 */ 425 asmlinkage long compat_sys_kill(u32 pid, u32 sig) 426 { 427 return sys_kill((int)pid, (int)sig); 428 } 429 430 431 /* Note: it is necessary to treat mode as an unsigned int, 432 * with the corresponding cast to a signed int to insure that the 433 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 434 * and the register representation of a signed int (msr in 64-bit mode) is performed. 435 */ 436 asmlinkage long compat_sys_mkdir(const char __user * pathname, u32 mode) 437 { 438 return sys_mkdir(pathname, (int)mode); 439 } 440 441 long compat_sys_nice(u32 increment) 442 { 443 /* sign extend increment */ 444 return sys_nice((int)increment); 445 } 446 447 off_t ppc32_lseek(unsigned int fd, u32 offset, unsigned int origin) 448 { 449 /* sign extend n */ 450 return sys_lseek(fd, (int)offset, origin); 451 } 452 453 /* Note: it is necessary to treat bufsiz 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_readlink(const char __user * path, char __user * buf, u32 bufsiz) 459 { 460 return sys_readlink(path, buf, (int)bufsiz); 461 } 462 463 /* Note: it is necessary to treat option as an unsigned int, 464 * with the corresponding cast to a signed int to insure that the 465 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 466 * and the register representation of a signed int (msr in 64-bit mode) is performed. 467 */ 468 asmlinkage long compat_sys_sched_get_priority_max(u32 policy) 469 { 470 return sys_sched_get_priority_max((int)policy); 471 } 472 473 474 /* Note: it is necessary to treat policy as an unsigned int, 475 * with the corresponding cast to a signed int to insure that the 476 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 477 * and the register representation of a signed int (msr in 64-bit mode) is performed. 478 */ 479 asmlinkage long compat_sys_sched_get_priority_min(u32 policy) 480 { 481 return sys_sched_get_priority_min((int)policy); 482 } 483 484 485 /* Note: it is necessary to treat pid as an unsigned int, 486 * with the corresponding cast to a signed int to insure that the 487 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 488 * and the register representation of a signed int (msr in 64-bit mode) is performed. 489 */ 490 asmlinkage long compat_sys_sched_getparam(u32 pid, struct sched_param __user *param) 491 { 492 return sys_sched_getparam((int)pid, param); 493 } 494 495 496 /* Note: it is necessary to treat pid as an unsigned int, 497 * with the corresponding cast to a signed int to insure that the 498 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 499 * and the register representation of a signed int (msr in 64-bit mode) is performed. 500 */ 501 asmlinkage long compat_sys_sched_getscheduler(u32 pid) 502 { 503 return sys_sched_getscheduler((int)pid); 504 } 505 506 507 /* Note: it is necessary to treat pid as an unsigned int, 508 * with the corresponding cast to a signed int to insure that the 509 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 510 * and the register representation of a signed int (msr in 64-bit mode) is performed. 511 */ 512 asmlinkage long compat_sys_sched_setparam(u32 pid, struct sched_param __user *param) 513 { 514 return sys_sched_setparam((int)pid, param); 515 } 516 517 518 /* Note: it is necessary to treat pid and policy as unsigned ints, 519 * with the corresponding cast to a signed int to insure that the 520 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 521 * and the register representation of a signed int (msr in 64-bit mode) is performed. 522 */ 523 asmlinkage long compat_sys_sched_setscheduler(u32 pid, u32 policy, struct sched_param __user *param) 524 { 525 return sys_sched_setscheduler((int)pid, (int)policy, param); 526 } 527 528 529 /* Note: it is necessary to treat len as an unsigned int, 530 * with the corresponding cast to a signed int to insure that the 531 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 532 * and the register representation of a signed int (msr in 64-bit mode) is performed. 533 */ 534 asmlinkage long compat_sys_setdomainname(char __user *name, u32 len) 535 { 536 return sys_setdomainname(name, (int)len); 537 } 538 539 540 /* Note: it is necessary to treat gidsetsize as an unsigned int, 541 * with the corresponding cast to a signed int to insure that the 542 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 543 * and the register representation of a signed int (msr in 64-bit mode) is performed. 544 */ 545 asmlinkage long compat_sys_setgroups(u32 gidsetsize, gid_t __user *grouplist) 546 { 547 return sys_setgroups((int)gidsetsize, grouplist); 548 } 549 550 551 asmlinkage long compat_sys_sethostname(char __user *name, u32 len) 552 { 553 /* sign extend len */ 554 return sys_sethostname(name, (int)len); 555 } 556 557 558 /* Note: it is necessary to treat pid and pgid as unsigned ints, 559 * with the corresponding cast to a signed int to insure that the 560 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 561 * and the register representation of a signed int (msr in 64-bit mode) is performed. 562 */ 563 asmlinkage long compat_sys_setpgid(u32 pid, u32 pgid) 564 { 565 return sys_setpgid((int)pid, (int)pgid); 566 } 567 568 long compat_sys_getpriority(u32 which, u32 who) 569 { 570 /* sign extend which and who */ 571 return sys_getpriority((int)which, (int)who); 572 } 573 574 long compat_sys_setpriority(u32 which, u32 who, u32 niceval) 575 { 576 /* sign extend which, who and niceval */ 577 return sys_setpriority((int)which, (int)who, (int)niceval); 578 } 579 580 long compat_sys_ioprio_get(u32 which, u32 who) 581 { 582 /* sign extend which and who */ 583 return sys_ioprio_get((int)which, (int)who); 584 } 585 586 long compat_sys_ioprio_set(u32 which, u32 who, u32 ioprio) 587 { 588 /* sign extend which, who and ioprio */ 589 return sys_ioprio_set((int)which, (int)who, (int)ioprio); 590 } 591 592 /* Note: it is necessary to treat newmask as an unsigned int, 593 * with the corresponding cast to a signed int to insure that the 594 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 595 * and the register representation of a signed int (msr in 64-bit mode) is performed. 596 */ 597 asmlinkage long compat_sys_ssetmask(u32 newmask) 598 { 599 return sys_ssetmask((int) newmask); 600 } 601 602 asmlinkage long compat_sys_syslog(u32 type, char __user * buf, u32 len) 603 { 604 /* sign extend len */ 605 return sys_syslog(type, buf, (int)len); 606 } 607 608 609 /* Note: it is necessary to treat mask as an unsigned int, 610 * with the corresponding cast to a signed int to insure that the 611 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 612 * and the register representation of a signed int (msr in 64-bit mode) is performed. 613 */ 614 asmlinkage long compat_sys_umask(u32 mask) 615 { 616 return sys_umask((int)mask); 617 } 618 619 #ifdef CONFIG_SYSCTL_SYSCALL 620 struct __sysctl_args32 { 621 u32 name; 622 int nlen; 623 u32 oldval; 624 u32 oldlenp; 625 u32 newval; 626 u32 newlen; 627 u32 __unused[4]; 628 }; 629 630 asmlinkage long compat_sys_sysctl(struct __sysctl_args32 __user *args) 631 { 632 struct __sysctl_args32 tmp; 633 int error; 634 size_t oldlen; 635 size_t __user *oldlenp = NULL; 636 unsigned long addr = (((unsigned long)&args->__unused[0]) + 7) & ~7; 637 638 if (copy_from_user(&tmp, args, sizeof(tmp))) 639 return -EFAULT; 640 641 if (tmp.oldval && tmp.oldlenp) { 642 /* Duh, this is ugly and might not work if sysctl_args 643 is in read-only memory, but do_sysctl does indirectly 644 a lot of uaccess in both directions and we'd have to 645 basically copy the whole sysctl.c here, and 646 glibc's __sysctl uses rw memory for the structure 647 anyway. */ 648 oldlenp = (size_t __user *)addr; 649 if (get_user(oldlen, (compat_size_t __user *)compat_ptr(tmp.oldlenp)) || 650 put_user(oldlen, oldlenp)) 651 return -EFAULT; 652 } 653 654 lock_kernel(); 655 error = do_sysctl(compat_ptr(tmp.name), tmp.nlen, 656 compat_ptr(tmp.oldval), oldlenp, 657 compat_ptr(tmp.newval), tmp.newlen); 658 unlock_kernel(); 659 if (oldlenp) { 660 if (!error) { 661 if (get_user(oldlen, oldlenp) || 662 put_user(oldlen, (compat_size_t __user *)compat_ptr(tmp.oldlenp))) 663 error = -EFAULT; 664 } 665 copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused)); 666 } 667 return error; 668 } 669 #endif 670 671 unsigned long compat_sys_mmap2(unsigned long addr, size_t len, 672 unsigned long prot, unsigned long flags, 673 unsigned long fd, unsigned long pgoff) 674 { 675 /* This should remain 12 even if PAGE_SIZE changes */ 676 return sys_mmap(addr, len, prot, flags, fd, pgoff << 12); 677 } 678 679 long compat_sys_tgkill(u32 tgid, u32 pid, int sig) 680 { 681 /* sign extend tgid, pid */ 682 return sys_tgkill((int)tgid, (int)pid, sig); 683 } 684 685 /* 686 * long long munging: 687 * The 32 bit ABI passes long longs in an odd even register pair. 688 */ 689 690 compat_ssize_t compat_sys_pread64(unsigned int fd, char __user *ubuf, compat_size_t count, 691 u32 reg6, u32 poshi, u32 poslo) 692 { 693 return sys_pread64(fd, ubuf, count, ((loff_t)poshi << 32) | poslo); 694 } 695 696 compat_ssize_t compat_sys_pwrite64(unsigned int fd, char __user *ubuf, compat_size_t count, 697 u32 reg6, u32 poshi, u32 poslo) 698 { 699 return sys_pwrite64(fd, ubuf, count, ((loff_t)poshi << 32) | poslo); 700 } 701 702 compat_ssize_t compat_sys_readahead(int fd, u32 r4, u32 offhi, u32 offlo, u32 count) 703 { 704 return sys_readahead(fd, ((loff_t)offhi << 32) | offlo, count); 705 } 706 707 asmlinkage int compat_sys_truncate64(const char __user * path, u32 reg4, 708 unsigned long high, unsigned long low) 709 { 710 return sys_truncate(path, (high << 32) | low); 711 } 712 713 asmlinkage long compat_sys_fallocate(int fd, int mode, u32 offhi, u32 offlo, 714 u32 lenhi, u32 lenlo) 715 { 716 return sys_fallocate(fd, mode, ((loff_t)offhi << 32) | offlo, 717 ((loff_t)lenhi << 32) | lenlo); 718 } 719 720 asmlinkage int compat_sys_ftruncate64(unsigned int fd, u32 reg4, unsigned long high, 721 unsigned long low) 722 { 723 return sys_ftruncate(fd, (high << 32) | low); 724 } 725 726 long ppc32_lookup_dcookie(u32 cookie_high, u32 cookie_low, char __user *buf, 727 size_t len) 728 { 729 return sys_lookup_dcookie((u64)cookie_high << 32 | cookie_low, 730 buf, len); 731 } 732 733 long ppc32_fadvise64(int fd, u32 unused, u32 offset_high, u32 offset_low, 734 size_t len, int advice) 735 { 736 return sys_fadvise64(fd, (u64)offset_high << 32 | offset_low, len, 737 advice); 738 } 739 740 asmlinkage long compat_sys_add_key(const char __user *_type, 741 const char __user *_description, 742 const void __user *_payload, 743 u32 plen, 744 u32 ringid) 745 { 746 return sys_add_key(_type, _description, _payload, plen, ringid); 747 } 748 749 asmlinkage long compat_sys_request_key(const char __user *_type, 750 const char __user *_description, 751 const char __user *_callout_info, 752 u32 destringid) 753 { 754 return sys_request_key(_type, _description, _callout_info, destringid); 755 } 756 757 asmlinkage long compat_sys_sync_file_range2(int fd, unsigned int flags, 758 unsigned offset_hi, unsigned offset_lo, 759 unsigned nbytes_hi, unsigned nbytes_lo) 760 { 761 loff_t offset = ((loff_t)offset_hi << 32) | offset_lo; 762 loff_t nbytes = ((loff_t)nbytes_hi << 32) | nbytes_lo; 763 764 return sys_sync_file_range(fd, offset, nbytes, flags); 765 } 766