1/* 2 * sysirix.c: IRIX system call emulation. 3 * 4 * Copyright (C) 1996 David S. Miller 5 * Copyright (C) 1997 Miguel de Icaza 6 * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle 7 */ 8#include <linux/kernel.h> 9#include <linux/sched.h> 10#include <linux/binfmts.h> 11#include <linux/capability.h> 12#include <linux/highuid.h> 13#include <linux/pagemap.h> 14#include <linux/mm.h> 15#include <linux/mman.h> 16#include <linux/slab.h> 17#include <linux/swap.h> 18#include <linux/errno.h> 19#include <linux/time.h> 20#include <linux/timex.h> 21#include <linux/times.h> 22#include <linux/elf.h> 23#include <linux/msg.h> 24#include <linux/shm.h> 25#include <linux/smp.h> 26#include <linux/smp_lock.h> 27#include <linux/utsname.h> 28#include <linux/file.h> 29#include <linux/vfs.h> 30#include <linux/namei.h> 31#include <linux/socket.h> 32#include <linux/security.h> 33#include <linux/syscalls.h> 34#include <linux/resource.h> 35 36#include <asm/ptrace.h> 37#include <asm/page.h> 38#include <asm/uaccess.h> 39#include <asm/inventory.h> 40 41/* 2,191 lines of complete and utter shit coming up... */ 42 43extern int max_threads; 44 45/* The sysmp commands supported thus far. */ 46#define MP_NPROCS 1 /* # processor in complex */ 47#define MP_NAPROCS 2 /* # active processors in complex */ 48#define MP_PGSIZE 14 /* Return system page size in v1. */ 49 50asmlinkage int irix_sysmp(struct pt_regs *regs) 51{ 52 unsigned long cmd; 53 int base = 0; 54 int error = 0; 55 56 if(regs->regs[2] == 1000) 57 base = 1; 58 cmd = regs->regs[base + 4]; 59 switch(cmd) { 60 case MP_PGSIZE: 61 error = PAGE_SIZE; 62 break; 63 case MP_NPROCS: 64 case MP_NAPROCS: 65 error = num_online_cpus(); 66 break; 67 default: 68 printk("SYSMP[%s:%d]: Unsupported opcode %d\n", 69 current->comm, current->pid, (int)cmd); 70 error = -EINVAL; 71 break; 72 } 73 74 return error; 75} 76 77/* The prctl commands. */ 78#define PR_MAXPROCS 1 /* Tasks/user. */ 79#define PR_ISBLOCKED 2 /* If blocked, return 1. */ 80#define PR_SETSTACKSIZE 3 /* Set largest task stack size. */ 81#define PR_GETSTACKSIZE 4 /* Get largest task stack size. */ 82#define PR_MAXPPROCS 5 /* Num parallel tasks. */ 83#define PR_UNBLKONEXEC 6 /* When task exec/exit's, unblock. */ 84#define PR_SETEXITSIG 8 /* When task exit's, set signal. */ 85#define PR_RESIDENT 9 /* Make task unswappable. */ 86#define PR_ATTACHADDR 10 /* (Re-)Connect a vma to a task. */ 87#define PR_DETACHADDR 11 /* Disconnect a vma from a task. */ 88#define PR_TERMCHILD 12 /* Kill child if the parent dies. */ 89#define PR_GETSHMASK 13 /* Get the sproc() share mask. */ 90#define PR_GETNSHARE 14 /* Number of share group members. */ 91#define PR_COREPID 15 /* Add task pid to name when it core. */ 92#define PR_ATTACHADDRPERM 16 /* (Re-)Connect vma, with specified prot. */ 93#define PR_PTHREADEXIT 17 /* Kill a pthread, only for IRIX 6.[234] */ 94 95asmlinkage int irix_prctl(unsigned option, ...) 96{ 97 va_list args; 98 int error = 0; 99 100 va_start(args, option); 101 switch (option) { 102 case PR_MAXPROCS: 103 printk("irix_prctl[%s:%d]: Wants PR_MAXPROCS\n", 104 current->comm, current->pid); 105 error = max_threads; 106 break; 107 108 case PR_ISBLOCKED: { 109 struct task_struct *task; 110 111 printk("irix_prctl[%s:%d]: Wants PR_ISBLOCKED\n", 112 current->comm, current->pid); 113 read_lock(&tasklist_lock); 114 task = find_task_by_pid(va_arg(args, pid_t)); 115 error = -ESRCH; 116 if (error) 117 error = (task->run_list.next != NULL); 118 read_unlock(&tasklist_lock); 119 /* Can _your_ OS find this out that fast? */ 120 break; 121 } 122 123 case PR_SETSTACKSIZE: { 124 long value = va_arg(args, long); 125 126 printk("irix_prctl[%s:%d]: Wants PR_SETSTACKSIZE<%08lx>\n", 127 current->comm, current->pid, (unsigned long) value); 128 if (value > RLIM_INFINITY) 129 value = RLIM_INFINITY; 130 if (capable(CAP_SYS_ADMIN)) { 131 task_lock(current->group_leader); 132 current->signal->rlim[RLIMIT_STACK].rlim_max = 133 current->signal->rlim[RLIMIT_STACK].rlim_cur = value; 134 task_unlock(current->group_leader); 135 error = value; 136 break; 137 } 138 task_lock(current->group_leader); 139 if (value > current->signal->rlim[RLIMIT_STACK].rlim_max) { 140 error = -EINVAL; 141 task_unlock(current->group_leader); 142 break; 143 } 144 current->signal->rlim[RLIMIT_STACK].rlim_cur = value; 145 task_unlock(current->group_leader); 146 error = value; 147 break; 148 } 149 150 case PR_GETSTACKSIZE: 151 printk("irix_prctl[%s:%d]: Wants PR_GETSTACKSIZE\n", 152 current->comm, current->pid); 153 error = current->signal->rlim[RLIMIT_STACK].rlim_cur; 154 break; 155 156 case PR_MAXPPROCS: 157 printk("irix_prctl[%s:%d]: Wants PR_MAXPROCS\n", 158 current->comm, current->pid); 159 error = 1; 160 break; 161 162 case PR_UNBLKONEXEC: 163 printk("irix_prctl[%s:%d]: Wants PR_UNBLKONEXEC\n", 164 current->comm, current->pid); 165 error = -EINVAL; 166 break; 167 168 case PR_SETEXITSIG: 169 printk("irix_prctl[%s:%d]: Wants PR_SETEXITSIG\n", 170 current->comm, current->pid); 171 172 /* We can probably play some game where we set the task 173 * exit_code to some non-zero value when this is requested, 174 * and check whether exit_code is already set in do_exit(). 175 */ 176 error = -EINVAL; 177 break; 178 179 case PR_RESIDENT: 180 printk("irix_prctl[%s:%d]: Wants PR_RESIDENT\n", 181 current->comm, current->pid); 182 error = 0; /* Compatibility indeed. */ 183 break; 184 185 case PR_ATTACHADDR: 186 printk("irix_prctl[%s:%d]: Wants PR_ATTACHADDR\n", 187 current->comm, current->pid); 188 error = -EINVAL; 189 break; 190 191 case PR_DETACHADDR: 192 printk("irix_prctl[%s:%d]: Wants PR_DETACHADDR\n", 193 current->comm, current->pid); 194 error = -EINVAL; 195 break; 196 197 case PR_TERMCHILD: 198 printk("irix_prctl[%s:%d]: Wants PR_TERMCHILD\n", 199 current->comm, current->pid); 200 error = -EINVAL; 201 break; 202 203 case PR_GETSHMASK: 204 printk("irix_prctl[%s:%d]: Wants PR_GETSHMASK\n", 205 current->comm, current->pid); 206 error = -EINVAL; /* Until I have the sproc() stuff in. */ 207 break; 208 209 case PR_GETNSHARE: 210 error = 0; /* Until I have the sproc() stuff in. */ 211 break; 212 213 case PR_COREPID: 214 printk("irix_prctl[%s:%d]: Wants PR_COREPID\n", 215 current->comm, current->pid); 216 error = -EINVAL; 217 break; 218 219 case PR_ATTACHADDRPERM: 220 printk("irix_prctl[%s:%d]: Wants PR_ATTACHADDRPERM\n", 221 current->comm, current->pid); 222 error = -EINVAL; 223 break; 224 225 default: 226 printk("irix_prctl[%s:%d]: Non-existant opcode %d\n", 227 current->comm, current->pid, option); 228 error = -EINVAL; 229 break; 230 } 231 va_end(args); 232 233 return error; 234} 235 236#undef DEBUG_PROCGRPS 237 238extern unsigned long irix_mapelf(int fd, struct elf_phdr __user *user_phdrp, int cnt); 239extern char *prom_getenv(char *name); 240extern long prom_setenv(char *name, char *value); 241 242/* The syssgi commands supported thus far. */ 243#define SGI_SYSID 1 /* Return unique per-machine identifier. */ 244#define SGI_INVENT 5 /* Fetch inventory */ 245# define SGI_INV_SIZEOF 1 246# define SGI_INV_READ 2 247#define SGI_RDNAME 6 /* Return string name of a process. */ 248#define SGI_SETNVRAM 8 /* Set PROM variable. */ 249#define SGI_GETNVRAM 9 /* Get PROM variable. */ 250#define SGI_SETPGID 21 /* Set process group id. */ 251#define SGI_SYSCONF 22 /* POSIX sysconf garbage. */ 252#define SGI_PATHCONF 24 /* POSIX sysconf garbage. */ 253#define SGI_SETGROUPS 40 /* POSIX sysconf garbage. */ 254#define SGI_GETGROUPS 41 /* POSIX sysconf garbage. */ 255#define SGI_RUSAGE 56 /* BSD style rusage(). */ 256#define SGI_SSYNC 62 /* Synchronous fs sync. */ 257#define SGI_GETSID 65 /* SysVr4 get session id. */ 258#define SGI_ELFMAP 68 /* Map an elf image. */ 259#define SGI_TOSSTSAVE 108 /* Toss saved vma's. */ 260#define SGI_FP_BCOPY 129 /* Should FPU bcopy be used on this machine? */ 261#define SGI_PHYSP 1011 /* Translate virtual into physical page. */ 262 263asmlinkage int irix_syssgi(struct pt_regs *regs) 264{ 265 unsigned long cmd; 266 int retval, base = 0; 267 268 if (regs->regs[2] == 1000) 269 base = 1; 270 271 cmd = regs->regs[base + 4]; 272 switch(cmd) { 273 case SGI_SYSID: { 274 char __user *buf = (char __user *) regs->regs[base + 5]; 275 276 retval = clear_user(buf, 64) ? -EFAULT : 0; 277 break; 278 } 279 280 case SGI_SETPGID: { 281#ifdef DEBUG_PROCGRPS 282 printk("[%s:%d] setpgid(%d, %d) ", 283 current->comm, current->pid, 284 (int) regs->regs[base + 5], (int)regs->regs[base + 6]); 285#endif 286 retval = sys_setpgid(regs->regs[base + 5], regs->regs[base + 6]); 287 288#ifdef DEBUG_PROCGRPS 289 printk("retval=%d\n", retval); 290#endif 291 } 292 293 case SGI_SYSCONF: { 294 switch(regs->regs[base + 5]) { 295 case 1: 296 retval = (MAX_ARG_PAGES >> 4); 297 goto out; 298 case 2: 299 retval = max_threads; 300 goto out; 301 case 3: 302 retval = HZ; 303 goto out; 304 case 4: 305 retval = NGROUPS_MAX; 306 goto out; 307 case 5: 308 retval = NR_OPEN; 309 goto out; 310 case 6: 311 retval = 1; 312 goto out; 313 case 7: 314 retval = 1; 315 goto out; 316 case 8: 317 retval = 199009; 318 goto out; 319 case 11: 320 retval = PAGE_SIZE; 321 goto out; 322 case 12: 323 retval = 4; 324 goto out; 325 case 25: 326 case 26: 327 case 27: 328 case 28: 329 case 29: 330 case 30: 331 retval = 0; 332 goto out; 333 case 31: 334 retval = 32; 335 goto out; 336 default: 337 retval = -EINVAL; 338 goto out; 339 }; 340 } 341 342 case SGI_SETGROUPS: 343 retval = sys_setgroups((int) regs->regs[base + 5], 344 (gid_t __user *) regs->regs[base + 6]); 345 break; 346 347 case SGI_GETGROUPS: 348 retval = sys_getgroups((int) regs->regs[base + 5], 349 (gid_t __user *) regs->regs[base + 6]); 350 break; 351 352 case SGI_RUSAGE: { 353 struct rusage __user *ru = (struct rusage __user *) regs->regs[base + 6]; 354 355 switch((int) regs->regs[base + 5]) { 356 case 0: 357 /* rusage self */ 358 retval = getrusage(current, RUSAGE_SELF, ru); 359 goto out; 360 361 case -1: 362 /* rusage children */ 363 retval = getrusage(current, RUSAGE_CHILDREN, ru); 364 goto out; 365 366 default: 367 retval = -EINVAL; 368 goto out; 369 }; 370 } 371 372 case SGI_SSYNC: 373 sys_sync(); 374 retval = 0; 375 break; 376 377 case SGI_GETSID: 378#ifdef DEBUG_PROCGRPS 379 printk("[%s:%d] getsid(%d) ", current->comm, current->pid, 380 (int) regs->regs[base + 5]); 381#endif 382 retval = sys_getsid(regs->regs[base + 5]); 383#ifdef DEBUG_PROCGRPS 384 printk("retval=%d\n", retval); 385#endif 386 break; 387 388 case SGI_ELFMAP: 389 retval = irix_mapelf((int) regs->regs[base + 5], 390 (struct elf_phdr __user *) regs->regs[base + 6], 391 (int) regs->regs[base + 7]); 392 break; 393 394 case SGI_TOSSTSAVE: 395 retval = 0; 396 break; 397 398 case SGI_FP_BCOPY: 399 retval = 0; 400 break; 401 402 case SGI_PHYSP: { 403 unsigned long addr = regs->regs[base + 5]; 404 int __user *pageno = (int __user *) (regs->regs[base + 6]); 405 struct mm_struct *mm = current->mm; 406 pgd_t *pgdp; 407 pud_t *pudp; 408 pmd_t *pmdp; 409 pte_t *ptep; 410 411 down_read(&mm->mmap_sem); 412 pgdp = pgd_offset(mm, addr); 413 pudp = pud_offset(pgdp, addr); 414 pmdp = pmd_offset(pudp, addr); 415 ptep = pte_offset(pmdp, addr); 416 retval = -EINVAL; 417 if (ptep) { 418 pte_t pte = *ptep; 419 420 if (pte_val(pte) & (_PAGE_VALID | _PAGE_PRESENT)) { 421 /* b0rked on 64-bit */ 422 retval = put_user((pte_val(pte) & PAGE_MASK) >> 423 PAGE_SHIFT, pageno); 424 } 425 } 426 up_read(&mm->mmap_sem); 427 break; 428 } 429 430 case SGI_INVENT: { 431 int arg1 = (int) regs->regs [base + 5]; 432 void __user *buffer = (void __user *) regs->regs [base + 6]; 433 int count = (int) regs->regs [base + 7]; 434 435 switch (arg1) { 436 case SGI_INV_SIZEOF: 437 retval = sizeof (inventory_t); 438 break; 439 case SGI_INV_READ: 440 retval = dump_inventory_to_user (buffer, count); 441 break; 442 default: 443 retval = -EINVAL; 444 } 445 break; 446 } 447 448 default: 449 printk("irix_syssgi: Unsupported command %d\n", (int)cmd); 450 retval = -EINVAL; 451 break; 452 }; 453 454out: 455 return retval; 456} 457 458asmlinkage int irix_gtime(struct pt_regs *regs) 459{ 460 return get_seconds(); 461} 462 463/* 464 * IRIX is completely broken... it returns 0 on success, otherwise 465 * ENOMEM. 466 */ 467asmlinkage int irix_brk(unsigned long brk) 468{ 469 unsigned long rlim; 470 unsigned long newbrk, oldbrk; 471 struct mm_struct *mm = current->mm; 472 int ret; 473 474 down_write(&mm->mmap_sem); 475 if (brk < mm->end_code) { 476 ret = -ENOMEM; 477 goto out; 478 } 479 480 newbrk = PAGE_ALIGN(brk); 481 oldbrk = PAGE_ALIGN(mm->brk); 482 if (oldbrk == newbrk) { 483 mm->brk = brk; 484 ret = 0; 485 goto out; 486 } 487 488 /* 489 * Always allow shrinking brk 490 */ 491 if (brk <= mm->brk) { 492 mm->brk = brk; 493 do_munmap(mm, newbrk, oldbrk-newbrk); 494 ret = 0; 495 goto out; 496 } 497 /* 498 * Check against rlimit and stack.. 499 */ 500 rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur; 501 if (rlim >= RLIM_INFINITY) 502 rlim = ~0; 503 if (brk - mm->end_code > rlim) { 504 ret = -ENOMEM; 505 goto out; 506 } 507 508 /* 509 * Check against existing mmap mappings. 510 */ 511 if (find_vma_intersection(mm, oldbrk, newbrk+PAGE_SIZE)) { 512 ret = -ENOMEM; 513 goto out; 514 } 515 516 /* 517 * Ok, looks good - let it rip. 518 */ 519 if (do_brk(oldbrk, newbrk-oldbrk) != oldbrk) { 520 ret = -ENOMEM; 521 goto out; 522 } 523 mm->brk = brk; 524 ret = 0; 525 526out: 527 up_write(&mm->mmap_sem); 528 return ret; 529} 530 531asmlinkage int irix_getpid(struct pt_regs *regs) 532{ 533 regs->regs[3] = current->real_parent->pid; 534 return current->pid; 535} 536 537asmlinkage int irix_getuid(struct pt_regs *regs) 538{ 539 regs->regs[3] = current->euid; 540 return current->uid; 541} 542 543asmlinkage int irix_getgid(struct pt_regs *regs) 544{ 545 regs->regs[3] = current->egid; 546 return current->gid; 547} 548 549asmlinkage int irix_stime(int value) 550{ 551 int err; 552 struct timespec tv; 553 554 tv.tv_sec = value; 555 tv.tv_nsec = 0; 556 err = security_settime(&tv, NULL); 557 if (err) 558 return err; 559 560 write_seqlock_irq(&xtime_lock); 561 xtime.tv_sec = value; 562 xtime.tv_nsec = 0; 563 ntp_clear(); 564 write_sequnlock_irq(&xtime_lock); 565 566 return 0; 567} 568 569static inline void jiffiestotv(unsigned long jiffies, struct timeval *value) 570{ 571 value->tv_usec = (jiffies % HZ) * (1000000 / HZ); 572 value->tv_sec = jiffies / HZ; 573} 574 575static inline void getitimer_real(struct itimerval *value) 576{ 577 register unsigned long val, interval; 578 579 interval = current->it_real_incr; 580 val = 0; 581 if (del_timer(¤t->real_timer)) { 582 unsigned long now = jiffies; 583 val = current->real_timer.expires; 584 add_timer(¤t->real_timer); 585 /* look out for negative/zero itimer.. */ 586 if (val <= now) 587 val = now+1; 588 val -= now; 589 } 590 jiffiestotv(val, &value->it_value); 591 jiffiestotv(interval, &value->it_interval); 592} 593 594asmlinkage unsigned int irix_alarm(unsigned int seconds) 595{ 596 return alarm_setitimer(seconds); 597} 598 599asmlinkage int irix_pause(void) 600{ 601 current->state = TASK_INTERRUPTIBLE; 602 schedule(); 603 604 return -EINTR; 605} 606 607asmlinkage int irix_mount(char __user *dev_name, char __user *dir_name, 608 unsigned long flags, char __user *type, void __user *data, int datalen) 609{ 610 printk("[%s:%d] irix_mount(%p,%p,%08lx,%p,%p,%d)\n", 611 current->comm, current->pid, 612 dev_name, dir_name, flags, type, data, datalen); 613 614 return sys_mount(dev_name, dir_name, type, flags, data); 615} 616 617struct irix_statfs { 618 short f_type; 619 long f_bsize, f_frsize, f_blocks, f_bfree, f_files, f_ffree; 620 char f_fname[6], f_fpack[6]; 621}; 622 623asmlinkage int irix_statfs(const char __user *path, 624 struct irix_statfs __user *buf, int len, int fs_type) 625{ 626 struct nameidata nd; 627 struct kstatfs kbuf; 628 int error, i; 629 630 /* We don't support this feature yet. */ 631 if (fs_type) { 632 error = -EINVAL; 633 goto out; 634 } 635 if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statfs))) { 636 error = -EFAULT; 637 goto out; 638 } 639 640 error = user_path_walk(path, &nd); 641 if (error) 642 goto out; 643 644 error = vfs_statfs(nd.dentry, &kbuf); 645 if (error) 646 goto dput_and_out; 647 648 error = __put_user(kbuf.f_type, &buf->f_type); 649 error |= __put_user(kbuf.f_bsize, &buf->f_bsize); 650 error |= __put_user(kbuf.f_frsize, &buf->f_frsize); 651 error |= __put_user(kbuf.f_blocks, &buf->f_blocks); 652 error |= __put_user(kbuf.f_bfree, &buf->f_bfree); 653 error |= __put_user(kbuf.f_files, &buf->f_files); 654 error |= __put_user(kbuf.f_ffree, &buf->f_ffree); 655 for (i = 0; i < 6; i++) { 656 error |= __put_user(0, &buf->f_fname[i]); 657 error |= __put_user(0, &buf->f_fpack[i]); 658 } 659 660dput_and_out: 661 path_release(&nd); 662out: 663 return error; 664} 665 666asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs __user *buf) 667{ 668 struct kstatfs kbuf; 669 struct file *file; 670 int error, i; 671 672 if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statfs))) { 673 error = -EFAULT; 674 goto out; 675 } 676 677 if (!(file = fget(fd))) { 678 error = -EBADF; 679 goto out; 680 } 681 682 error = vfs_statfs(file->f_path.dentry, &kbuf); 683 if (error) 684 goto out_f; 685 686 error = __put_user(kbuf.f_type, &buf->f_type); 687 error |= __put_user(kbuf.f_bsize, &buf->f_bsize); 688 error |= __put_user(kbuf.f_frsize, &buf->f_frsize); 689 error |= __put_user(kbuf.f_blocks, &buf->f_blocks); 690 error |= __put_user(kbuf.f_bfree, &buf->f_bfree); 691 error |= __put_user(kbuf.f_files, &buf->f_files); 692 error |= __put_user(kbuf.f_ffree, &buf->f_ffree); 693 694 for (i = 0; i < 6; i++) { 695 error |= __put_user(0, &buf->f_fname[i]); 696 error |= __put_user(0, &buf->f_fpack[i]); 697 } 698 699out_f: 700 fput(file); 701out: 702 return error; 703} 704 705asmlinkage int irix_setpgrp(int flags) 706{ 707 int error; 708 709#ifdef DEBUG_PROCGRPS 710 printk("[%s:%d] setpgrp(%d) ", current->comm, current->pid, flags); 711#endif 712 if(!flags) 713 error = process_group(current); 714 else 715 error = sys_setsid(); 716#ifdef DEBUG_PROCGRPS 717 printk("returning %d\n", process_group(current)); 718#endif 719 720 return error; 721} 722 723asmlinkage int irix_times(struct tms __user *tbuf) 724{ 725 int err = 0; 726 727 if (tbuf) { 728 if (!access_ok(VERIFY_WRITE,tbuf,sizeof *tbuf)) 729 return -EFAULT; 730 731 err = __put_user(current->utime, &tbuf->tms_utime); 732 err |= __put_user(current->stime, &tbuf->tms_stime); 733 err |= __put_user(current->signal->cutime, &tbuf->tms_cutime); 734 err |= __put_user(current->signal->cstime, &tbuf->tms_cstime); 735 } 736 737 return err; 738} 739 740asmlinkage int irix_exec(struct pt_regs *regs) 741{ 742 int error, base = 0; 743 char *filename; 744 745 if(regs->regs[2] == 1000) 746 base = 1; 747 filename = getname((char __user *) (long)regs->regs[base + 4]); 748 error = PTR_ERR(filename); 749 if (IS_ERR(filename)) 750 return error; 751 752 error = do_execve(filename, (char __user * __user *) (long)regs->regs[base + 5], 753 NULL, regs); 754 putname(filename); 755 756 return error; 757} 758 759asmlinkage int irix_exece(struct pt_regs *regs) 760{ 761 int error, base = 0; 762 char *filename; 763 764 if (regs->regs[2] == 1000) 765 base = 1; 766 filename = getname((char __user *) (long)regs->regs[base + 4]); 767 error = PTR_ERR(filename); 768 if (IS_ERR(filename)) 769 return error; 770 error = do_execve(filename, (char __user * __user *) (long)regs->regs[base + 5], 771 (char __user * __user *) (long)regs->regs[base + 6], regs); 772 putname(filename); 773 774 return error; 775} 776 777asmlinkage unsigned long irix_gethostid(void) 778{ 779 printk("[%s:%d]: irix_gethostid() called...\n", 780 current->comm, current->pid); 781 782 return -EINVAL; 783} 784 785asmlinkage unsigned long irix_sethostid(unsigned long val) 786{ 787 printk("[%s:%d]: irix_sethostid(%08lx) called...\n", 788 current->comm, current->pid, val); 789 790 return -EINVAL; 791} 792 793asmlinkage int irix_socket(int family, int type, int protocol) 794{ 795 switch(type) { 796 case 1: 797 type = SOCK_DGRAM; 798 break; 799 800 case 2: 801 type = SOCK_STREAM; 802 break; 803 804 case 3: 805 type = 9; /* Invalid... */ 806 break; 807 808 case 4: 809 type = SOCK_RAW; 810 break; 811 812 case 5: 813 type = SOCK_RDM; 814 break; 815 816 case 6: 817 type = SOCK_SEQPACKET; 818 break; 819 820 default: 821 break; 822 } 823 824 return sys_socket(family, type, protocol); 825} 826 827asmlinkage int irix_getdomainname(char __user *name, int len) 828{ 829 int err; 830 831 down_read(&uts_sem); 832 if (len > __NEW_UTS_LEN) 833 len = __NEW_UTS_LEN; 834 err = copy_to_user(name, utsname()->domainname, len) ? -EFAULT : 0; 835 up_read(&uts_sem); 836 837 return err; 838} 839 840asmlinkage unsigned long irix_getpagesize(void) 841{ 842 return PAGE_SIZE; 843} 844 845asmlinkage int irix_msgsys(int opcode, unsigned long arg0, unsigned long arg1, 846 unsigned long arg2, unsigned long arg3, 847 unsigned long arg4) 848{ 849 switch (opcode) { 850 case 0: 851 return sys_msgget((key_t) arg0, (int) arg1); 852 case 1: 853 return sys_msgctl((int) arg0, (int) arg1, 854 (struct msqid_ds __user *)arg2); 855 case 2: 856 return sys_msgrcv((int) arg0, (struct msgbuf __user *) arg1, 857 (size_t) arg2, (long) arg3, (int) arg4); 858 case 3: 859 return sys_msgsnd((int) arg0, (struct msgbuf __user *) arg1, 860 (size_t) arg2, (int) arg3); 861 default: 862 return -EINVAL; 863 } 864} 865 866asmlinkage int irix_shmsys(int opcode, unsigned long arg0, unsigned long arg1, 867 unsigned long arg2, unsigned long arg3) 868{ 869 switch (opcode) { 870 case 0: 871 return do_shmat((int) arg0, (char __user *) arg1, (int) arg2, 872 (unsigned long *) arg3); 873 case 1: 874 return sys_shmctl((int)arg0, (int)arg1, 875 (struct shmid_ds __user *)arg2); 876 case 2: 877 return sys_shmdt((char __user *)arg0); 878 case 3: 879 return sys_shmget((key_t) arg0, (int) arg1, (int) arg2); 880 default: 881 return -EINVAL; 882 } 883} 884 885asmlinkage int irix_semsys(int opcode, unsigned long arg0, unsigned long arg1, 886 unsigned long arg2, int arg3) 887{ 888 switch (opcode) { 889 case 0: 890 return sys_semctl((int) arg0, (int) arg1, (int) arg2, 891 (union semun) arg3); 892 case 1: 893 return sys_semget((key_t) arg0, (int) arg1, (int) arg2); 894 case 2: 895 return sys_semop((int) arg0, (struct sembuf __user *)arg1, 896 (unsigned int) arg2); 897 default: 898 return -EINVAL; 899 } 900} 901 902static inline loff_t llseek(struct file *file, loff_t offset, int origin) 903{ 904 loff_t (*fn)(struct file *, loff_t, int); 905 loff_t retval; 906 907 fn = default_llseek; 908 if (file->f_op && file->f_op->llseek) 909 fn = file->f_op->llseek; 910 lock_kernel(); 911 retval = fn(file, offset, origin); 912 unlock_kernel(); 913 914 return retval; 915} 916 917asmlinkage int irix_lseek64(int fd, int _unused, int offhi, int offlow, 918 int origin) 919{ 920 struct file * file; 921 loff_t offset; 922 int retval; 923 924 retval = -EBADF; 925 file = fget(fd); 926 if (!file) 927 goto bad; 928 retval = -EINVAL; 929 if (origin > 2) 930 goto out_putf; 931 932 offset = llseek(file, ((loff_t) offhi << 32) | offlow, origin); 933 retval = (int) offset; 934 935out_putf: 936 fput(file); 937bad: 938 return retval; 939} 940 941asmlinkage int irix_sginap(int ticks) 942{ 943 schedule_timeout_interruptible(ticks); 944 return 0; 945} 946 947asmlinkage int irix_sgikopt(char __user *istring, char __user *ostring, int len) 948{ 949 return -EINVAL; 950} 951 952asmlinkage int irix_gettimeofday(struct timeval __user *tv) 953{ 954 time_t sec; 955 long nsec, seq; 956 int err; 957 958 if (!access_ok(VERIFY_WRITE, tv, sizeof(struct timeval))) 959 return -EFAULT; 960 961 do { 962 seq = read_seqbegin(&xtime_lock); 963 sec = xtime.tv_sec; 964 nsec = xtime.tv_nsec; 965 } while (read_seqretry(&xtime_lock, seq)); 966 967 err = __put_user(sec, &tv->tv_sec); 968 err |= __put_user((nsec / 1000), &tv->tv_usec); 969 970 return err; 971} 972 973#define IRIX_MAP_AUTOGROW 0x40 974 975asmlinkage unsigned long irix_mmap32(unsigned long addr, size_t len, int prot, 976 int flags, int fd, off_t offset) 977{ 978 struct file *file = NULL; 979 unsigned long retval; 980 981 if (!(flags & MAP_ANONYMOUS)) { 982 if (!(file = fget(fd))) 983 return -EBADF; 984 985 /* Ok, bad taste hack follows, try to think in something else 986 * when reading this. */ 987 if (flags & IRIX_MAP_AUTOGROW) { 988 unsigned long old_pos; 989 long max_size = offset + len; 990 991 if (max_size > file->f_path.dentry->d_inode->i_size) { 992 old_pos = sys_lseek (fd, max_size - 1, 0); 993 sys_write (fd, (void __user *) "", 1); 994 sys_lseek (fd, old_pos, 0); 995 } 996 } 997 } 998 999 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); 1000 1001 down_write(¤t->mm->mmap_sem); 1002 retval = do_mmap(file, addr, len, prot, flags, offset); 1003 up_write(¤t->mm->mmap_sem); 1004 if (file) 1005 fput(file); 1006 1007 return retval; 1008} 1009 1010asmlinkage int irix_madvise(unsigned long addr, int len, int behavior) 1011{ 1012 printk("[%s:%d] Wheee.. irix_madvise(%08lx,%d,%d)\n", 1013 current->comm, current->pid, addr, len, behavior); 1014 1015 return -EINVAL; 1016} 1017 1018asmlinkage int irix_pagelock(char __user *addr, int len, int op) 1019{ 1020 printk("[%s:%d] Wheee.. irix_pagelock(%p,%d,%d)\n", 1021 current->comm, current->pid, addr, len, op); 1022 1023 return -EINVAL; 1024} 1025 1026asmlinkage int irix_quotactl(struct pt_regs *regs) 1027{ 1028 printk("[%s:%d] Wheee.. irix_quotactl()\n", 1029 current->comm, current->pid); 1030 1031 return -EINVAL; 1032} 1033 1034asmlinkage int irix_BSDsetpgrp(int pid, int pgrp) 1035{ 1036 int error; 1037 1038#ifdef DEBUG_PROCGRPS 1039 printk("[%s:%d] BSDsetpgrp(%d, %d) ", current->comm, current->pid, 1040 pid, pgrp); 1041#endif 1042 if(!pid) 1043 pid = current->pid; 1044 1045 /* Wheee, weird sysv thing... */ 1046 if ((pgrp == 0) && (pid == current->pid)) 1047 error = sys_setsid(); 1048 else 1049 error = sys_setpgid(pid, pgrp); 1050 1051#ifdef DEBUG_PROCGRPS 1052 printk("error = %d\n", error); 1053#endif 1054 1055 return error; 1056} 1057 1058asmlinkage int irix_systeminfo(int cmd, char __user *buf, int cnt) 1059{ 1060 printk("[%s:%d] Wheee.. irix_systeminfo(%d,%p,%d)\n", 1061 current->comm, current->pid, cmd, buf, cnt); 1062 1063 return -EINVAL; 1064} 1065 1066struct iuname { 1067 char sysname[257], nodename[257], release[257]; 1068 char version[257], machine[257]; 1069 char m_type[257], base_rel[257]; 1070 char _unused0[257], _unused1[257], _unused2[257]; 1071 char _unused3[257], _unused4[257], _unused5[257]; 1072}; 1073 1074asmlinkage int irix_uname(struct iuname __user *buf) 1075{ 1076 down_read(&uts_sem); 1077 if (copy_from_user(utsname()->sysname, buf->sysname, 65) 1078 || copy_from_user(utsname()->nodename, buf->nodename, 65) 1079 || copy_from_user(utsname()->release, buf->release, 65) 1080 || copy_from_user(utsname()->version, buf->version, 65) 1081 || copy_from_user(utsname()->machine, buf->machine, 65)) { 1082 return -EFAULT; 1083 } 1084 up_read(&uts_sem); 1085 1086 return 1; 1087} 1088 1089#undef DEBUG_XSTAT 1090 1091static int irix_xstat32_xlate(struct kstat *stat, void __user *ubuf) 1092{ 1093 struct xstat32 { 1094 u32 st_dev, st_pad1[3], st_ino, st_mode, st_nlink, st_uid, st_gid; 1095 u32 st_rdev, st_pad2[2], st_size, st_pad3; 1096 u32 st_atime0, st_atime1; 1097 u32 st_mtime0, st_mtime1; 1098 u32 st_ctime0, st_ctime1; 1099 u32 st_blksize, st_blocks; 1100 char st_fstype[16]; 1101 u32 st_pad4[8]; 1102 } ub; 1103 1104 if (!sysv_valid_dev(stat->dev) || !sysv_valid_dev(stat->rdev)) 1105 return -EOVERFLOW; 1106 ub.st_dev = sysv_encode_dev(stat->dev); 1107 ub.st_ino = stat->ino; 1108 ub.st_mode = stat->mode; 1109 ub.st_nlink = stat->nlink; 1110 SET_UID(ub.st_uid, stat->uid); 1111 SET_GID(ub.st_gid, stat->gid); 1112 ub.st_rdev = sysv_encode_dev(stat->rdev); 1113#if BITS_PER_LONG == 32 1114 if (stat->size > MAX_NON_LFS) 1115 return -EOVERFLOW; 1116#endif 1117 ub.st_size = stat->size; 1118 ub.st_atime0 = stat->atime.tv_sec; 1119 ub.st_atime1 = stat->atime.tv_nsec; 1120 ub.st_mtime0 = stat->mtime.tv_sec; 1121 ub.st_mtime1 = stat->atime.tv_nsec; 1122 ub.st_ctime0 = stat->ctime.tv_sec; 1123 ub.st_ctime1 = stat->atime.tv_nsec; 1124 ub.st_blksize = stat->blksize; 1125 ub.st_blocks = stat->blocks; 1126 strcpy (ub.st_fstype, "efs"); 1127 1128 return copy_to_user(ubuf, &ub, sizeof(ub)) ? -EFAULT : 0; 1129} 1130 1131static int irix_xstat64_xlate(struct kstat *stat, void __user *ubuf) 1132{ 1133 struct xstat64 { 1134 u32 st_dev; s32 st_pad1[3]; 1135 unsigned long long st_ino; 1136 u32 st_mode; 1137 u32 st_nlink; s32 st_uid; s32 st_gid; u32 st_rdev; 1138 s32 st_pad2[2]; 1139 long long st_size; 1140 s32 st_pad3; 1141 struct { s32 tv_sec, tv_nsec; } st_atime, st_mtime, st_ctime; 1142 s32 st_blksize; 1143 long long st_blocks; 1144 char st_fstype[16]; 1145 s32 st_pad4[8]; 1146 } ks; 1147 1148 if (!sysv_valid_dev(stat->dev) || !sysv_valid_dev(stat->rdev)) 1149 return -EOVERFLOW; 1150 1151 ks.st_dev = sysv_encode_dev(stat->dev); 1152 ks.st_pad1[0] = ks.st_pad1[1] = ks.st_pad1[2] = 0; 1153 ks.st_ino = (unsigned long long) stat->ino; 1154 ks.st_mode = (u32) stat->mode; 1155 ks.st_nlink = (u32) stat->nlink; 1156 ks.st_uid = (s32) stat->uid; 1157 ks.st_gid = (s32) stat->gid; 1158 ks.st_rdev = sysv_encode_dev (stat->rdev); 1159 ks.st_pad2[0] = ks.st_pad2[1] = 0; 1160 ks.st_size = (long long) stat->size; 1161 ks.st_pad3 = 0; 1162 1163 ks.st_atime.tv_sec = (s32) stat->atime.tv_sec; 1164 ks.st_atime.tv_nsec = stat->atime.tv_nsec; 1165 ks.st_mtime.tv_sec = (s32) stat->mtime.tv_sec; 1166 ks.st_mtime.tv_nsec = stat->mtime.tv_nsec; 1167 ks.st_ctime.tv_sec = (s32) stat->ctime.tv_sec; 1168 ks.st_ctime.tv_nsec = stat->ctime.tv_nsec; 1169 1170 ks.st_blksize = (s32) stat->blksize; 1171 ks.st_blocks = (long long) stat->blocks; 1172 memset(ks.st_fstype, 0, 16); 1173 ks.st_pad4[0] = ks.st_pad4[1] = ks.st_pad4[2] = ks.st_pad4[3] = 0; 1174 ks.st_pad4[4] = ks.st_pad4[5] = ks.st_pad4[6] = ks.st_pad4[7] = 0; 1175 1176 /* Now write it all back. */ 1177 return copy_to_user(ubuf, &ks, sizeof(ks)) ? -EFAULT : 0; 1178} 1179 1180asmlinkage int irix_xstat(int version, char __user *filename, struct stat __user *statbuf) 1181{ 1182 int retval; 1183 struct kstat stat; 1184 1185#ifdef DEBUG_XSTAT 1186 printk("[%s:%d] Wheee.. irix_xstat(%d,%s,%p) ", 1187 current->comm, current->pid, version, filename, statbuf); 1188#endif 1189 1190 retval = vfs_stat(filename, &stat); 1191 if (!retval) { 1192 switch(version) { 1193 case 2: 1194 retval = irix_xstat32_xlate(&stat, statbuf); 1195 break; 1196 case 3: 1197 retval = irix_xstat64_xlate(&stat, statbuf); 1198 break; 1199 default: 1200 retval = -EINVAL; 1201 } 1202 } 1203 return retval; 1204} 1205 1206asmlinkage int irix_lxstat(int version, char __user *filename, struct stat __user *statbuf) 1207{ 1208 int error; 1209 struct kstat stat; 1210 1211#ifdef DEBUG_XSTAT 1212 printk("[%s:%d] Wheee.. irix_lxstat(%d,%s,%p) ", 1213 current->comm, current->pid, version, filename, statbuf); 1214#endif 1215 1216 error = vfs_lstat(filename, &stat); 1217 1218 if (!error) { 1219 switch (version) { 1220 case 2: 1221 error = irix_xstat32_xlate(&stat, statbuf); 1222 break; 1223 case 3: 1224 error = irix_xstat64_xlate(&stat, statbuf); 1225 break; 1226 default: 1227 error = -EINVAL; 1228 } 1229 } 1230 return error; 1231} 1232 1233asmlinkage int irix_fxstat(int version, int fd, struct stat __user *statbuf) 1234{ 1235 int error; 1236 struct kstat stat; 1237 1238#ifdef DEBUG_XSTAT 1239 printk("[%s:%d] Wheee.. irix_fxstat(%d,%d,%p) ", 1240 current->comm, current->pid, version, fd, statbuf); 1241#endif 1242 1243 error = vfs_fstat(fd, &stat); 1244 if (!error) { 1245 switch (version) { 1246 case 2: 1247 error = irix_xstat32_xlate(&stat, statbuf); 1248 break; 1249 case 3: 1250 error = irix_xstat64_xlate(&stat, statbuf); 1251 break; 1252 default: 1253 error = -EINVAL; 1254 } 1255 } 1256 return error; 1257} 1258 1259asmlinkage int irix_xmknod(int ver, char __user *filename, int mode, unsigned dev) 1260{ 1261 int retval; 1262 printk("[%s:%d] Wheee.. irix_xmknod(%d,%s,%x,%x)\n", 1263 current->comm, current->pid, ver, filename, mode, dev); 1264 1265 switch(ver) { 1266 case 2: 1267 /* shouldn't we convert here as well as on stat()? */ 1268 retval = sys_mknod(filename, mode, dev); 1269 break; 1270 1271 default: 1272 retval = -EINVAL; 1273 break; 1274 }; 1275 1276 return retval; 1277} 1278 1279asmlinkage int irix_swapctl(int cmd, char __user *arg) 1280{ 1281 printk("[%s:%d] Wheee.. irix_swapctl(%d,%p)\n", 1282 current->comm, current->pid, cmd, arg); 1283 1284 return -EINVAL; 1285} 1286 1287struct irix_statvfs { 1288 u32 f_bsize; u32 f_frsize; u32 f_blocks; 1289 u32 f_bfree; u32 f_bavail; u32 f_files; u32 f_ffree; u32 f_favail; 1290 u32 f_fsid; char f_basetype[16]; 1291 u32 f_flag; u32 f_namemax; 1292 char f_fstr[32]; u32 f_filler[16]; 1293}; 1294 1295asmlinkage int irix_statvfs(char __user *fname, struct irix_statvfs __user *buf) 1296{ 1297 struct nameidata nd; 1298 struct kstatfs kbuf; 1299 int error, i; 1300 1301 printk("[%s:%d] Wheee.. irix_statvfs(%s,%p)\n", 1302 current->comm, current->pid, fname, buf); 1303 if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statvfs))) 1304 return -EFAULT; 1305 1306 error = user_path_walk(fname, &nd); 1307 if (error) 1308 goto out; 1309 error = vfs_statfs(nd.dentry, &kbuf); 1310 if (error) 1311 goto dput_and_out; 1312 1313 error |= __put_user(kbuf.f_bsize, &buf->f_bsize); 1314 error |= __put_user(kbuf.f_frsize, &buf->f_frsize); 1315 error |= __put_user(kbuf.f_blocks, &buf->f_blocks); 1316 error |= __put_user(kbuf.f_bfree, &buf->f_bfree); 1317 error |= __put_user(kbuf.f_bfree, &buf->f_bavail); 1318 error |= __put_user(kbuf.f_files, &buf->f_files); 1319 error |= __put_user(kbuf.f_ffree, &buf->f_ffree); 1320 error |= __put_user(kbuf.f_ffree, &buf->f_favail); 1321#ifdef __MIPSEB__ 1322 error |= __put_user(kbuf.f_fsid.val[1], &buf->f_fsid); 1323#else 1324 error |= __put_user(kbuf.f_fsid.val[0], &buf->f_fsid); 1325#endif 1326 for (i = 0; i < 16; i++) 1327 error |= __put_user(0, &buf->f_basetype[i]); 1328 error |= __put_user(0, &buf->f_flag); 1329 error |= __put_user(kbuf.f_namelen, &buf->f_namemax); 1330 for (i = 0; i < 32; i++) 1331 error |= __put_user(0, &buf->f_fstr[i]); 1332 1333dput_and_out: 1334 path_release(&nd); 1335out: 1336 return error; 1337} 1338 1339asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs __user *buf) 1340{ 1341 struct kstatfs kbuf; 1342 struct file *file; 1343 int error, i; 1344 1345 printk("[%s:%d] Wheee.. irix_fstatvfs(%d,%p)\n", 1346 current->comm, current->pid, fd, buf); 1347 1348 if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statvfs))) 1349 return -EFAULT; 1350 1351 if (!(file = fget(fd))) { 1352 error = -EBADF; 1353 goto out; 1354 } 1355 error = vfs_statfs(file->f_path.dentry, &kbuf); 1356 if (error) 1357 goto out_f; 1358 1359 error = __put_user(kbuf.f_bsize, &buf->f_bsize); 1360 error |= __put_user(kbuf.f_frsize, &buf->f_frsize); 1361 error |= __put_user(kbuf.f_blocks, &buf->f_blocks); 1362 error |= __put_user(kbuf.f_bfree, &buf->f_bfree); 1363 error |= __put_user(kbuf.f_bfree, &buf->f_bavail); 1364 error |= __put_user(kbuf.f_files, &buf->f_files); 1365 error |= __put_user(kbuf.f_ffree, &buf->f_ffree); 1366 error |= __put_user(kbuf.f_ffree, &buf->f_favail); 1367#ifdef __MIPSEB__ 1368 error |= __put_user(kbuf.f_fsid.val[1], &buf->f_fsid); 1369#else 1370 error |= __put_user(kbuf.f_fsid.val[0], &buf->f_fsid); 1371#endif 1372 for(i = 0; i < 16; i++) 1373 error |= __put_user(0, &buf->f_basetype[i]); 1374 error |= __put_user(0, &buf->f_flag); 1375 error |= __put_user(kbuf.f_namelen, &buf->f_namemax); 1376 error |= __clear_user(&buf->f_fstr, sizeof(buf->f_fstr)) ? -EFAULT : 0; 1377 1378out_f: 1379 fput(file); 1380out: 1381 return error; 1382} 1383 1384asmlinkage int irix_priocntl(struct pt_regs *regs) 1385{ 1386 printk("[%s:%d] Wheee.. irix_priocntl()\n", 1387 current->comm, current->pid); 1388 1389 return -EINVAL; 1390} 1391 1392asmlinkage int irix_sigqueue(int pid, int sig, int code, int val) 1393{ 1394 printk("[%s:%d] Wheee.. irix_sigqueue(%d,%d,%d,%d)\n", 1395 current->comm, current->pid, pid, sig, code, val); 1396 1397 return -EINVAL; 1398} 1399 1400asmlinkage int irix_truncate64(char __user *name, int pad, int size1, int size2) 1401{ 1402 int retval; 1403 1404 if (size1) { 1405 retval = -EINVAL; 1406 goto out; 1407 } 1408 retval = sys_truncate(name, size2); 1409 1410out: 1411 return retval; 1412} 1413 1414asmlinkage int irix_ftruncate64(int fd, int pad, int size1, int size2) 1415{ 1416 int retval; 1417 1418 if (size1) { 1419 retval = -EINVAL; 1420 goto out; 1421 } 1422 retval = sys_ftruncate(fd, size2); 1423 1424out: 1425 return retval; 1426} 1427 1428asmlinkage int irix_mmap64(struct pt_regs *regs) 1429{ 1430 int len, prot, flags, fd, off1, off2, error, base = 0; 1431 unsigned long addr, pgoff, *sp; 1432 struct file *file = NULL; 1433 int err; 1434 1435 if (regs->regs[2] == 1000) 1436 base = 1; 1437 sp = (unsigned long *) (regs->regs[29] + 16); 1438 addr = regs->regs[base + 4]; 1439 len = regs->regs[base + 5]; 1440 prot = regs->regs[base + 6]; 1441 if (!base) { 1442 flags = regs->regs[base + 7]; 1443 if (!access_ok(VERIFY_READ, sp, (4 * sizeof(unsigned long)))) 1444 return -EFAULT; 1445 fd = sp[0]; 1446 err = __get_user(off1, &sp[1]); 1447 err |= __get_user(off2, &sp[2]); 1448 } else { 1449 if (!access_ok(VERIFY_READ, sp, (5 * sizeof(unsigned long)))) 1450 return -EFAULT; 1451 err = __get_user(flags, &sp[0]); 1452 err |= __get_user(fd, &sp[1]); 1453 err |= __get_user(off1, &sp[2]); 1454 err |= __get_user(off2, &sp[3]); 1455 } 1456 1457 if (err) 1458 return err; 1459 1460 if (off1 & PAGE_MASK) 1461 return -EOVERFLOW; 1462 1463 pgoff = (off1 << (32 - PAGE_SHIFT)) | (off2 >> PAGE_SHIFT); 1464 1465 if (!(flags & MAP_ANONYMOUS)) { 1466 if (!(file = fget(fd))) 1467 return -EBADF; 1468 1469 /* Ok, bad taste hack follows, try to think in something else 1470 when reading this */ 1471 if (flags & IRIX_MAP_AUTOGROW) { 1472 unsigned long old_pos; 1473 long max_size = off2 + len; 1474 1475 if (max_size > file->f_path.dentry->d_inode->i_size) { 1476 old_pos = sys_lseek (fd, max_size - 1, 0); 1477 sys_write (fd, (void __user *) "", 1); 1478 sys_lseek (fd, old_pos, 0); 1479 } 1480 } 1481 } 1482 1483 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); 1484 1485 down_write(¤t->mm->mmap_sem); 1486 error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); 1487 up_write(¤t->mm->mmap_sem); 1488 1489 if (file) 1490 fput(file); 1491 1492 return error; 1493} 1494 1495asmlinkage int irix_dmi(struct pt_regs *regs) 1496{ 1497 printk("[%s:%d] Wheee.. irix_dmi()\n", 1498 current->comm, current->pid); 1499 1500 return -EINVAL; 1501} 1502 1503asmlinkage int irix_pread(int fd, char __user *buf, int cnt, int off64, 1504 int off1, int off2) 1505{ 1506 printk("[%s:%d] Wheee.. irix_pread(%d,%p,%d,%d,%d,%d)\n", 1507 current->comm, current->pid, fd, buf, cnt, off64, off1, off2); 1508 1509 return -EINVAL; 1510} 1511 1512asmlinkage int irix_pwrite(int fd, char __user *buf, int cnt, int off64, 1513 int off1, int off2) 1514{ 1515 printk("[%s:%d] Wheee.. irix_pwrite(%d,%p,%d,%d,%d,%d)\n", 1516 current->comm, current->pid, fd, buf, cnt, off64, off1, off2); 1517 1518 return -EINVAL; 1519} 1520 1521asmlinkage int irix_sgifastpath(int cmd, unsigned long arg0, unsigned long arg1, 1522 unsigned long arg2, unsigned long arg3, 1523 unsigned long arg4, unsigned long arg5) 1524{ 1525 printk("[%s:%d] Wheee.. irix_fastpath(%d,%08lx,%08lx,%08lx,%08lx," 1526 "%08lx,%08lx)\n", 1527 current->comm, current->pid, cmd, arg0, arg1, arg2, 1528 arg3, arg4, arg5); 1529 1530 return -EINVAL; 1531} 1532 1533struct irix_statvfs64 { 1534 u32 f_bsize; u32 f_frsize; 1535 u64 f_blocks; u64 f_bfree; u64 f_bavail; 1536 u64 f_files; u64 f_ffree; u64 f_favail; 1537 u32 f_fsid; 1538 char f_basetype[16]; 1539 u32 f_flag; u32 f_namemax; 1540 char f_fstr[32]; 1541 u32 f_filler[16]; 1542}; 1543 1544asmlinkage int irix_statvfs64(char __user *fname, struct irix_statvfs64 __user *buf) 1545{ 1546 struct nameidata nd; 1547 struct kstatfs kbuf; 1548 int error, i; 1549 1550 printk("[%s:%d] Wheee.. irix_statvfs64(%s,%p)\n", 1551 current->comm, current->pid, fname, buf); 1552 if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statvfs64))) { 1553 error = -EFAULT; 1554 goto out; 1555 } 1556 1557 error = user_path_walk(fname, &nd); 1558 if (error) 1559 goto out; 1560 error = vfs_statfs(nd.dentry, &kbuf); 1561 if (error) 1562 goto dput_and_out; 1563 1564 error = __put_user(kbuf.f_bsize, &buf->f_bsize); 1565 error |= __put_user(kbuf.f_frsize, &buf->f_frsize); 1566 error |= __put_user(kbuf.f_blocks, &buf->f_blocks); 1567 error |= __put_user(kbuf.f_bfree, &buf->f_bfree); 1568 error |= __put_user(kbuf.f_bfree, &buf->f_bavail); 1569 error |= __put_user(kbuf.f_files, &buf->f_files); 1570 error |= __put_user(kbuf.f_ffree, &buf->f_ffree); 1571 error |= __put_user(kbuf.f_ffree, &buf->f_favail); 1572#ifdef __MIPSEB__ 1573 error |= __put_user(kbuf.f_fsid.val[1], &buf->f_fsid); 1574#else 1575 error |= __put_user(kbuf.f_fsid.val[0], &buf->f_fsid); 1576#endif 1577 for(i = 0; i < 16; i++) 1578 error |= __put_user(0, &buf->f_basetype[i]); 1579 error |= __put_user(0, &buf->f_flag); 1580 error |= __put_user(kbuf.f_namelen, &buf->f_namemax); 1581 for(i = 0; i < 32; i++) 1582 error |= __put_user(0, &buf->f_fstr[i]); 1583 1584dput_and_out: 1585 path_release(&nd); 1586out: 1587 return error; 1588} 1589 1590asmlinkage int irix_fstatvfs64(int fd, struct irix_statvfs __user *buf) 1591{ 1592 struct kstatfs kbuf; 1593 struct file *file; 1594 int error, i; 1595 1596 printk("[%s:%d] Wheee.. irix_fstatvfs64(%d,%p)\n", 1597 current->comm, current->pid, fd, buf); 1598 1599 if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statvfs))) { 1600 error = -EFAULT; 1601 goto out; 1602 } 1603 if (!(file = fget(fd))) { 1604 error = -EBADF; 1605 goto out; 1606 } 1607 error = vfs_statfs(file->f_path.dentry, &kbuf); 1608 if (error) 1609 goto out_f; 1610 1611 error = __put_user(kbuf.f_bsize, &buf->f_bsize); 1612 error |= __put_user(kbuf.f_frsize, &buf->f_frsize); 1613 error |= __put_user(kbuf.f_blocks, &buf->f_blocks); 1614 error |= __put_user(kbuf.f_bfree, &buf->f_bfree); 1615 error |= __put_user(kbuf.f_bfree, &buf->f_bavail); 1616 error |= __put_user(kbuf.f_files, &buf->f_files); 1617 error |= __put_user(kbuf.f_ffree, &buf->f_ffree); 1618 error |= __put_user(kbuf.f_ffree, &buf->f_favail); 1619#ifdef __MIPSEB__ 1620 error |= __put_user(kbuf.f_fsid.val[1], &buf->f_fsid); 1621#else 1622 error |= __put_user(kbuf.f_fsid.val[0], &buf->f_fsid); 1623#endif 1624 for(i = 0; i < 16; i++) 1625 error |= __put_user(0, &buf->f_basetype[i]); 1626 error |= __put_user(0, &buf->f_flag); 1627 error |= __put_user(kbuf.f_namelen, &buf->f_namemax); 1628 error |= __clear_user(buf->f_fstr, sizeof(buf->f_fstr[i])) ? -EFAULT : 0; 1629 1630out_f: 1631 fput(file); 1632out: 1633 return error; 1634} 1635 1636asmlinkage int irix_getmountid(char __user *fname, unsigned long __user *midbuf) 1637{ 1638 int err; 1639 1640 printk("[%s:%d] irix_getmountid(%s, %p)\n", 1641 current->comm, current->pid, fname, midbuf); 1642 if (!access_ok(VERIFY_WRITE, midbuf, (sizeof(unsigned long) * 4))) 1643 return -EFAULT; 1644 1645 err = __put_user(0, &midbuf[0]); 1646 err |= __put_user(0, &midbuf[1]); 1647 err |= __put_user(0, &midbuf[2]); 1648 err |= __put_user(0, &midbuf[3]); 1649 1650 return err; 1651} 1652 1653asmlinkage int irix_nsproc(unsigned long entry, unsigned long mask, 1654 unsigned long arg, unsigned long sp, int slen) 1655{ 1656 printk("[%s:%d] Wheee.. irix_nsproc(%08lx,%08lx,%08lx,%08lx,%d)\n", 1657 current->comm, current->pid, entry, mask, arg, sp, slen); 1658 1659 return -EINVAL; 1660} 1661 1662#undef DEBUG_GETDENTS 1663 1664struct irix_dirent32 { 1665 u32 d_ino; 1666 u32 d_off; 1667 unsigned short d_reclen; 1668 char d_name[1]; 1669}; 1670 1671struct irix_dirent32_callback { 1672 struct irix_dirent32 __user *current_dir; 1673 struct irix_dirent32 __user *previous; 1674 int count; 1675 int error; 1676}; 1677 1678#define NAME_OFFSET32(de) ((int) ((de)->d_name - (char *) (de))) 1679#define ROUND_UP32(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1)) 1680 1681static int irix_filldir32(void *__buf, const char *name, 1682 int namlen, loff_t offset, u64 ino, unsigned int d_type) 1683{ 1684 struct irix_dirent32 __user *dirent; 1685 struct irix_dirent32_callback *buf = __buf; 1686 unsigned short reclen = ROUND_UP32(NAME_OFFSET32(dirent) + namlen + 1); 1687 int err = 0; 1688 u32 d_ino; 1689 1690#ifdef DEBUG_GETDENTS 1691 printk("\nirix_filldir32[reclen<%d>namlen<%d>count<%d>]", 1692 reclen, namlen, buf->count); 1693#endif 1694 buf->error = -EINVAL; /* only used if we fail.. */ 1695 if (reclen > buf->count) 1696 return -EINVAL; 1697 d_ino = ino; 1698 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) 1699 return -EOVERFLOW; 1700 dirent = buf->previous; 1701 if (dirent) 1702 err = __put_user(offset, &dirent->d_off); 1703 dirent = buf->current_dir; 1704 err |= __put_user(dirent, &buf->previous); 1705 err |= __put_user(d_ino, &dirent->d_ino); 1706 err |= __put_user(reclen, &dirent->d_reclen); 1707 err |= copy_to_user((char __user *)dirent->d_name, name, namlen) ? -EFAULT : 0; 1708 err |= __put_user(0, &dirent->d_name[namlen]); 1709 dirent = (struct irix_dirent32 __user *) ((char __user *) dirent + reclen); 1710 1711 buf->current_dir = dirent; 1712 buf->count -= reclen; 1713 1714 return err; 1715} 1716 1717asmlinkage int irix_ngetdents(unsigned int fd, void __user * dirent, 1718 unsigned int count, int __user *eob) 1719{ 1720 struct file *file; 1721 struct irix_dirent32 __user *lastdirent; 1722 struct irix_dirent32_callback buf; 1723 int error; 1724 1725#ifdef DEBUG_GETDENTS 1726 printk("[%s:%d] ngetdents(%d, %p, %d, %p) ", current->comm, 1727 current->pid, fd, dirent, count, eob); 1728#endif 1729 error = -EBADF; 1730 file = fget(fd); 1731 if (!file) 1732 goto out; 1733 1734 buf.current_dir = (struct irix_dirent32 __user *) dirent; 1735 buf.previous = NULL; 1736 buf.count = count; 1737 buf.error = 0; 1738 1739 error = vfs_readdir(file, irix_filldir32, &buf); 1740 if (error < 0) 1741 goto out_putf; 1742 1743 error = buf.error; 1744 lastdirent = buf.previous; 1745 if (lastdirent) { 1746 put_user(file->f_pos, &lastdirent->d_off); 1747 error = count - buf.count; 1748 } 1749 1750 if (put_user(0, eob) < 0) { 1751 error = -EFAULT; 1752 goto out_putf; 1753 } 1754 1755#ifdef DEBUG_GETDENTS 1756 printk("eob=%d returning %d\n", *eob, count - buf.count); 1757#endif 1758 error = count - buf.count; 1759 1760out_putf: 1761 fput(file); 1762out: 1763 return error; 1764} 1765 1766struct irix_dirent64 { 1767 u64 d_ino; 1768 u64 d_off; 1769 unsigned short d_reclen; 1770 char d_name[1]; 1771}; 1772 1773struct irix_dirent64_callback { 1774 struct irix_dirent64 __user *curr; 1775 struct irix_dirent64 __user *previous; 1776 int count; 1777 int error; 1778}; 1779 1780#define NAME_OFFSET64(de) ((int) ((de)->d_name - (char *) (de))) 1781#define ROUND_UP64(x) (((x)+sizeof(u64)-1) & ~(sizeof(u64)-1)) 1782 1783static int irix_filldir64(void *__buf, const char *name, 1784 int namlen, loff_t offset, u64 ino, unsigned int d_type) 1785{ 1786 struct irix_dirent64 __user *dirent; 1787 struct irix_dirent64_callback * buf = __buf; 1788 unsigned short reclen = ROUND_UP64(NAME_OFFSET64(dirent) + namlen + 1); 1789 int err = 0; 1790 1791 if (!access_ok(VERIFY_WRITE, buf, sizeof(*buf))) 1792 return -EFAULT; 1793 1794 if (__put_user(-EINVAL, &buf->error)) /* only used if we fail.. */ 1795 return -EFAULT; 1796 if (reclen > buf->count) 1797 return -EINVAL; 1798 dirent = buf->previous; 1799 if (dirent) 1800 err = __put_user(offset, &dirent->d_off); 1801 dirent = buf->curr; 1802 buf->previous = dirent; 1803 err |= __put_user(ino, &dirent->d_ino); 1804 err |= __put_user(reclen, &dirent->d_reclen); 1805 err |= __copy_to_user((char __user *)dirent->d_name, name, namlen) 1806 ? -EFAULT : 0; 1807 err |= __put_user(0, &dirent->d_name[namlen]); 1808 1809 dirent = (struct irix_dirent64 __user *) ((char __user *) dirent + reclen); 1810 1811 buf->curr = dirent; 1812 buf->count -= reclen; 1813 1814 return err; 1815} 1816 1817asmlinkage int irix_getdents64(int fd, void __user *dirent, int cnt) 1818{ 1819 struct file *file; 1820 struct irix_dirent64 __user *lastdirent; 1821 struct irix_dirent64_callback buf; 1822 int error; 1823 1824#ifdef DEBUG_GETDENTS 1825 printk("[%s:%d] getdents64(%d, %p, %d) ", current->comm, 1826 current->pid, fd, dirent, cnt); 1827#endif 1828 error = -EBADF; 1829 if (!(file = fget(fd))) 1830 goto out; 1831 1832 error = -EFAULT; 1833 if (!access_ok(VERIFY_WRITE, dirent, cnt)) 1834 goto out_f; 1835 1836 error = -EINVAL; 1837 if (cnt < (sizeof(struct irix_dirent64) + 255)) 1838 goto out_f; 1839 1840 buf.curr = (struct irix_dirent64 __user *) dirent; 1841 buf.previous = NULL; 1842 buf.count = cnt; 1843 buf.error = 0; 1844 error = vfs_readdir(file, irix_filldir64, &buf); 1845 if (error < 0) 1846 goto out_f; 1847 lastdirent = buf.previous; 1848 if (!lastdirent) { 1849 error = buf.error; 1850 goto out_f; 1851 } 1852 if (put_user(file->f_pos, &lastdirent->d_off)) 1853 return -EFAULT; 1854#ifdef DEBUG_GETDENTS 1855 printk("returning %d\n", cnt - buf.count); 1856#endif 1857 error = cnt - buf.count; 1858 1859out_f: 1860 fput(file); 1861out: 1862 return error; 1863} 1864 1865asmlinkage int irix_ngetdents64(int fd, void __user *dirent, int cnt, int *eob) 1866{ 1867 struct file *file; 1868 struct irix_dirent64 __user *lastdirent; 1869 struct irix_dirent64_callback buf; 1870 int error; 1871 1872#ifdef DEBUG_GETDENTS 1873 printk("[%s:%d] ngetdents64(%d, %p, %d) ", current->comm, 1874 current->pid, fd, dirent, cnt); 1875#endif 1876 error = -EBADF; 1877 if (!(file = fget(fd))) 1878 goto out; 1879 1880 error = -EFAULT; 1881 if (!access_ok(VERIFY_WRITE, dirent, cnt) || 1882 !access_ok(VERIFY_WRITE, eob, sizeof(*eob))) 1883 goto out_f; 1884 1885 error = -EINVAL; 1886 if (cnt < (sizeof(struct irix_dirent64) + 255)) 1887 goto out_f; 1888 1889 *eob = 0; 1890 buf.curr = (struct irix_dirent64 __user *) dirent; 1891 buf.previous = NULL; 1892 buf.count = cnt; 1893 buf.error = 0; 1894 error = vfs_readdir(file, irix_filldir64, &buf); 1895 if (error < 0) 1896 goto out_f; 1897 lastdirent = buf.previous; 1898 if (!lastdirent) { 1899 error = buf.error; 1900 goto out_f; 1901 } 1902 if (put_user(file->f_pos, &lastdirent->d_off)) 1903 return -EFAULT; 1904#ifdef DEBUG_GETDENTS 1905 printk("eob=%d returning %d\n", *eob, cnt - buf.count); 1906#endif 1907 error = cnt - buf.count; 1908 1909out_f: 1910 fput(file); 1911out: 1912 return error; 1913} 1914 1915asmlinkage int irix_uadmin(unsigned long op, unsigned long func, unsigned long arg) 1916{ 1917 int retval; 1918 1919 switch (op) { 1920 case 1: 1921 /* Reboot */ 1922 printk("[%s:%d] irix_uadmin: Wants to reboot...\n", 1923 current->comm, current->pid); 1924 retval = -EINVAL; 1925 goto out; 1926 1927 case 2: 1928 /* Shutdown */ 1929 printk("[%s:%d] irix_uadmin: Wants to shutdown...\n", 1930 current->comm, current->pid); 1931 retval = -EINVAL; 1932 goto out; 1933 1934 case 4: 1935 /* Remount-root */ 1936 printk("[%s:%d] irix_uadmin: Wants to remount root...\n", 1937 current->comm, current->pid); 1938 retval = -EINVAL; 1939 goto out; 1940 1941 case 8: 1942 /* Kill all tasks. */ 1943 printk("[%s:%d] irix_uadmin: Wants to kill all tasks...\n", 1944 current->comm, current->pid); 1945 retval = -EINVAL; 1946 goto out; 1947 1948 case 256: 1949 /* Set magic mushrooms... */ 1950 printk("[%s:%d] irix_uadmin: Wants to set magic mushroom[%d]...\n", 1951 current->comm, current->pid, (int) func); 1952 retval = -EINVAL; 1953 goto out; 1954 1955 default: 1956 printk("[%s:%d] irix_uadmin: Unknown operation [%d]...\n", 1957 current->comm, current->pid, (int) op); 1958 retval = -EINVAL; 1959 goto out; 1960 }; 1961 1962out: 1963 return retval; 1964} 1965 1966asmlinkage int irix_utssys(char __user *inbuf, int arg, int type, char __user *outbuf) 1967{ 1968 int retval; 1969 1970 switch(type) { 1971 case 0: 1972 /* uname() */ 1973 retval = irix_uname((struct iuname __user *)inbuf); 1974 goto out; 1975 1976 case 2: 1977 /* ustat() */ 1978 printk("[%s:%d] irix_utssys: Wants to do ustat()\n", 1979 current->comm, current->pid); 1980 retval = -EINVAL; 1981 goto out; 1982 1983 case 3: 1984 /* fusers() */ 1985 printk("[%s:%d] irix_utssys: Wants to do fusers()\n", 1986 current->comm, current->pid); 1987 retval = -EINVAL; 1988 goto out; 1989 1990 default: 1991 printk("[%s:%d] irix_utssys: Wants to do unknown type[%d]\n", 1992 current->comm, current->pid, (int) type); 1993 retval = -EINVAL; 1994 goto out; 1995 } 1996 1997out: 1998 return retval; 1999} 2000 2001#undef DEBUG_FCNTL 2002 2003#define IRIX_F_ALLOCSP 10 2004 2005asmlinkage int irix_fcntl(int fd, int cmd, int arg) 2006{ 2007 int retval; 2008 2009#ifdef DEBUG_FCNTL 2010 printk("[%s:%d] irix_fcntl(%d, %d, %d) ", current->comm, 2011 current->pid, fd, cmd, arg); 2012#endif 2013 if (cmd == IRIX_F_ALLOCSP){ 2014 return 0; 2015 } 2016 retval = sys_fcntl(fd, cmd, arg); 2017#ifdef DEBUG_FCNTL 2018 printk("%d\n", retval); 2019#endif 2020 return retval; 2021} 2022 2023asmlinkage int irix_ulimit(int cmd, int arg) 2024{ 2025 int retval; 2026 2027 switch(cmd) { 2028 case 1: 2029 printk("[%s:%d] irix_ulimit: Wants to get file size limit.\n", 2030 current->comm, current->pid); 2031 retval = -EINVAL; 2032 goto out; 2033 2034 case 2: 2035 printk("[%s:%d] irix_ulimit: Wants to set file size limit.\n", 2036 current->comm, current->pid); 2037 retval = -EINVAL; 2038 goto out; 2039 2040 case 3: 2041 printk("[%s:%d] irix_ulimit: Wants to get brk limit.\n", 2042 current->comm, current->pid); 2043 retval = -EINVAL; 2044 goto out; 2045 2046 case 4: 2047 retval = current->signal->rlim[RLIMIT_NOFILE].rlim_cur; 2048 goto out; 2049 2050 case 5: 2051 printk("[%s:%d] irix_ulimit: Wants to get txt offset.\n", 2052 current->comm, current->pid); 2053 retval = -EINVAL; 2054 goto out; 2055 2056 default: 2057 printk("[%s:%d] irix_ulimit: Unknown command [%d].\n", 2058 current->comm, current->pid, cmd); 2059 retval = -EINVAL; 2060 goto out; 2061 } 2062out: 2063 return retval; 2064} 2065 2066asmlinkage int irix_unimp(struct pt_regs *regs) 2067{ 2068 printk("irix_unimp [%s:%d] v0=%d v1=%d a0=%08lx a1=%08lx a2=%08lx " 2069 "a3=%08lx\n", current->comm, current->pid, 2070 (int) regs->regs[2], (int) regs->regs[3], 2071 regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]); 2072 2073 return -ENOSYS; 2074} 2075