sys_ppc32.c
来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 1,328 行 · 第 1/3 页
C
1,328 行
err |= __put_user (s.freehigh, &info->freehigh); err |= __put_user (s.mem_unit, &info->mem_unit); if (err) return -EFAULT; return ret;}/* Translations due to time_t size differences. Which affects all sorts of things, like timeval and itimerval. */extern struct timezone sys_tz;asmlinkage long sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz){ if (tv) { struct timeval ktv; do_gettimeofday(&ktv); if (put_tv32(tv, &ktv)) return -EFAULT; } if (tz) { if (copy_to_user(tz, &sys_tz, sizeof(sys_tz))) return -EFAULT; } return 0;}asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz){ struct timespec kts; struct timezone ktz; if (tv) { if (get_ts32(&kts, tv)) return -EFAULT; } if (tz) { if (copy_from_user(&ktz, tz, sizeof(ktz))) return -EFAULT; } return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);}long sys32_ipc(u32 call, u32 first, u32 second, u32 third, compat_uptr_t ptr, u32 fifth){ int version; version = call >> 16; /* hack for backward compatibility */ call &= 0xffff; switch (call) { case SEMTIMEDOP: if (third) /* sign extend semid */ return compat_sys_semtimedop((int)first, compat_ptr(ptr), second, compat_ptr(third)); /* else fall through for normal semop() */ case SEMOP: /* struct sembuf is the same on 32 and 64bit :)) */ /* sign extend semid */ return sys_semtimedop((int)first, compat_ptr(ptr), second, NULL); case SEMGET: /* sign extend key, nsems */ return sys_semget((int)first, (int)second, third); case SEMCTL: /* sign extend semid, semnum */ return compat_sys_semctl((int)first, (int)second, third, compat_ptr(ptr)); case MSGSND: /* sign extend msqid */ return compat_sys_msgsnd((int)first, (int)second, third, compat_ptr(ptr)); case MSGRCV: /* sign extend msqid, msgtyp */ return compat_sys_msgrcv((int)first, second, (int)fifth, third, version, compat_ptr(ptr)); case MSGGET: /* sign extend key */ return sys_msgget((int)first, second); case MSGCTL: /* sign extend msqid */ return compat_sys_msgctl((int)first, second, compat_ptr(ptr)); case SHMAT: /* sign extend shmid */ return compat_sys_shmat((int)first, second, third, version, compat_ptr(ptr)); case SHMDT: return sys_shmdt(compat_ptr(ptr)); case SHMGET: /* sign extend key_t */ return sys_shmget((int)first, second, third); case SHMCTL: /* sign extend shmid */ return compat_sys_shmctl((int)first, second, compat_ptr(ptr)); default: return -ENOSYS; } return -ENOSYS;}/* Note: it is necessary to treat out_fd and in_fd as unsigned ints, * with the corresponding cast to a signed int to insure that the * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */asmlinkage long sys32_sendfile(u32 out_fd, u32 in_fd, compat_off_t __user * offset, u32 count){ mm_segment_t old_fs = get_fs(); int ret; off_t of; off_t __user *up; if (offset && get_user(of, offset)) return -EFAULT; /* The __user pointer cast is valid because of the set_fs() */ set_fs(KERNEL_DS); up = offset ? (off_t __user *) &of : NULL; ret = sys_sendfile((int)out_fd, (int)in_fd, up, count); set_fs(old_fs); if (offset && put_user(of, offset)) return -EFAULT; return ret;}asmlinkage int sys32_sendfile64(int out_fd, int in_fd, compat_loff_t __user *offset, s32 count){ mm_segment_t old_fs = get_fs(); int ret; loff_t lof; loff_t __user *up; if (offset && get_user(lof, offset)) return -EFAULT; /* The __user pointer cast is valid because of the set_fs() */ set_fs(KERNEL_DS); up = offset ? (loff_t __user *) &lof : NULL; ret = sys_sendfile64(out_fd, in_fd, up, count); set_fs(old_fs); if (offset && put_user(lof, offset)) return -EFAULT; return ret;}long sys32_execve(unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3, unsigned long a4, unsigned long a5, struct pt_regs *regs){ int error; char * filename; filename = getname((char __user *) a0); error = PTR_ERR(filename); if (IS_ERR(filename)) goto out; flush_fp_to_thread(current); flush_altivec_to_thread(current); error = compat_do_execve(filename, compat_ptr(a1), compat_ptr(a2), regs); if (error == 0) current->ptrace &= ~PT_DTRACE; putname(filename);out: return error;}/* Set up a thread for executing a new program. */void start_thread32(struct pt_regs* regs, unsigned long nip, unsigned long sp){ set_fs(USER_DS); /* * If we exec out of a kernel thread then thread.regs will not be * set. Do it now. */ if (!current->thread.regs) { unsigned long childregs = (unsigned long)current->thread_info + THREAD_SIZE; childregs -= sizeof(struct pt_regs); current->thread.regs = (struct pt_regs *)childregs; } /* * ELF_PLAT_INIT already clears all registers but it also sets r2. * So just clear r2 here. */ regs->gpr[2] = 0; regs->nip = nip; regs->gpr[1] = sp; regs->msr = MSR_USER32;#ifndef CONFIG_SMP if (last_task_used_math == current) last_task_used_math = 0;#endif /* CONFIG_SMP */ current->thread.fpscr = 0; memset(current->thread.fpr, 0, sizeof(current->thread.fpr));#ifdef CONFIG_ALTIVEC#ifndef CONFIG_SMP if (last_task_used_altivec == current) last_task_used_altivec = 0;#endif /* CONFIG_SMP */ memset(current->thread.vr, 0, sizeof(current->thread.vr)); current->thread.vscr.u[0] = 0; current->thread.vscr.u[1] = 0; current->thread.vscr.u[2] = 0; current->thread.vscr.u[3] = 0x00010000; /* Java mode disabled */ current->thread.vrsave = 0; current->thread.used_vr = 0;#endif /* CONFIG_ALTIVEC */}/* Note: it is necessary to treat option as an unsigned int, * with the corresponding cast to a signed int to insure that the * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */asmlinkage long sys32_prctl(u32 option, u32 arg2, u32 arg3, u32 arg4, u32 arg5){ return sys_prctl((int)option, (unsigned long) arg2, (unsigned long) arg3, (unsigned long) arg4, (unsigned long) arg5);}/* Note: it is necessary to treat pid as an unsigned int, * with the corresponding cast to a signed int to insure that the * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */asmlinkage long sys32_sched_rr_get_interval(u32 pid, struct compat_timespec __user *interval){ struct timespec t; int ret; mm_segment_t old_fs = get_fs (); /* The __user pointer cast is valid because of the set_fs() */ set_fs (KERNEL_DS); ret = sys_sched_rr_get_interval((int)pid, (struct timespec __user *) &t); set_fs (old_fs); if (put_compat_timespec(&t, interval)) return -EFAULT; return ret;}asmlinkage int sys32_pciconfig_read(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf){ return sys_pciconfig_read((unsigned long) bus, (unsigned long) dfn, (unsigned long) off, (unsigned long) len, compat_ptr(ubuf));}asmlinkage int sys32_pciconfig_write(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf){ return sys_pciconfig_write((unsigned long) bus, (unsigned long) dfn, (unsigned long) off, (unsigned long) len, compat_ptr(ubuf));}#define IOBASE_BRIDGE_NUMBER 0#define IOBASE_MEMORY 1#define IOBASE_IO 2#define IOBASE_ISA_IO 3#define IOBASE_ISA_MEM 4asmlinkage int sys32_pciconfig_iobase(u32 which, u32 in_bus, u32 in_devfn){ struct pci_controller* hose; struct list_head *ln; struct pci_bus *bus = NULL; struct device_node *hose_node; /* Argh ! Please forgive me for that hack, but that's the * simplest way to get existing XFree to not lockup on some * G5 machines... So when something asks for bus 0 io base * (bus 0 is HT root), we return the AGP one instead. */#ifdef CONFIG_PPC_PMAC if (systemcfg->platform == PLATFORM_POWERMAC && machine_is_compatible("MacRISC4")) if (in_bus == 0) in_bus = 0xf0;#endif /* CONFIG_PPC_PMAC */ /* That syscall isn't quite compatible with PCI domains, but it's * used on pre-domains setup. We return the first match */ for (ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) { bus = pci_bus_b(ln); if (in_bus >= bus->number && in_bus < (bus->number + bus->subordinate)) break; bus = NULL; } if (bus == NULL || bus->sysdata == NULL) return -ENODEV; hose_node = (struct device_node *)bus->sysdata; hose = hose_node->phb; switch (which) { case IOBASE_BRIDGE_NUMBER: return (long)hose->first_busno; case IOBASE_MEMORY: return (long)hose->pci_mem_offset; case IOBASE_IO: return (long)hose->io_base_phys; case IOBASE_ISA_IO: return (long)isa_io_base; case IOBASE_ISA_MEM: return -EINVAL; } return -EOPNOTSUPP;}asmlinkage int ppc64_newuname(struct new_utsname __user * name){ int errno = sys_newuname(name); if (current->personality == PER_LINUX32 && !errno) { if(copy_to_user(name->machine, "ppc\0\0", 8)) { errno = -EFAULT; } } return errno;}asmlinkage int ppc64_personality(unsigned long personality){ int ret; if (current->personality == PER_LINUX32 && personality == PER_LINUX) personality = PER_LINUX32; ret = sys_personality(personality); if (ret == PER_LINUX32) ret = PER_LINUX; return ret;}/* Note: it is necessary to treat mode as an unsigned int, * with the corresponding cast to a signed int to insure that the * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */asmlinkage long sys32_access(const char __user * filename, u32 mode){ return sys_access(filename, (int)mode);}/* Note: it is necessary to treat mode as an unsigned int, * with the corresponding cast to a signed int to insure that the * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */asmlinkage long sys32_creat(const char __user * pathname, u32 mode){ return sys_creat(pathname, (int)mode);}/* Note: it is necessary to treat pid and options as unsigned ints, * with the corresponding cast to a signed int to insure that the * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */asmlinkage long sys32_waitpid(u32 pid, unsigned int __user * stat_addr, u32 options){ return sys_waitpid((int)pid, stat_addr, (int)options);}/* Note: it is necessary to treat gidsetsize as an unsigned int, * with the corresponding cast to a signed int to insure that the * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */asmlinkage long sys32_getgroups(u32 gidsetsize, gid_t __user *grouplist){ return sys_getgroups((int)gidsetsize, grouplist);}/* Note: it is necessary to treat pid as an unsigned int, * with the corresponding cast to a signed int to insure that the * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */asmlinkage long sys32_getpgid(u32 pid){ return sys_getpgid((int)pid);}/* Note: it is necessary to treat which and who as unsigned ints, * with the corresponding cast to a signed int to insure that the * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */asmlinkage long sys32_getpriority(u32 which, u32 who){ return sys_getpriority((int)which, (int)who);}/* Note: it is necessary to treat pid as an unsigned int, * with the corresponding cast to a signed int to insure that the * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */asmlinkage long sys32_getsid(u32 pid){ return sys_getsid((int)pid);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?