[PATCH 58/60] microblaze_v4: sys_microblaze.c
From: Michal Simek [EMAIL PROTECTED] Signed-off-by: Michal Simek [EMAIL PROTECTED] --- arch/microblaze/kernel/sys_microblaze.c | 283 +++ 1 files changed, 283 insertions(+), 0 deletions(-) create mode 100644 arch/microblaze/kernel/sys_microblaze.c diff --git a/arch/microblaze/kernel/sys_microblaze.c b/arch/microblaze/kernel/sys_microblaze.c new file mode 100644 index 000..4ff008b --- /dev/null +++ b/arch/microblaze/kernel/sys_microblaze.c @@ -0,0 +1,283 @@ +/* + * Copyright (C) 2007 PetaLogix + * John Williams [EMAIL PROTECTED] + * Copyright (C) 2006 Atmark Techno, Inc. + * Yasushi SHOJI [EMAIL PROTECTED] + * Tetsuya OHKAWA [EMAIL PROTECTED] + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +#include linux/errno.h +#include linux/mm.h +#include linux/smp.h +#include linux/smp_lock.h +#include linux/syscalls.h +#include linux/sem.h +#include linux/msg.h +#include linux/shm.h +#include linux/stat.h +#include linux/mman.h +#include linux/sys.h +#include linux/ipc.h +#include linux/utsname.h +#include linux/file.h +#include linux/module.h +#include linux/err.h +#include linux/fs.h + +#include asm/uaccess.h +#include linux/ipc.h +#include asm/semaphore.h +#include asm/unistd.h + +/* + * sys_ipc() is the de-multiplexer for the SysV IPC calls.. + * + * This is really horribly ugly. + */ +int +sys_ipc(uint call, int first, int second, int third, void *ptr, long fifth) +{ + int version, ret; + + version = call 16; /* hack for backward compatibility */ + call = 0x; + + ret = -EINVAL; + switch (call) { + case SEMOP: + ret = sys_semop(first, (struct sembuf *)ptr, second); + break; + case SEMGET: + ret = sys_semget(first, second, third); + break; + case SEMCTL: + { + union semun fourth; + + if (!ptr) + break; + if ((ret = access_ok(VERIFY_READ, ptr, + sizeof(long)) ? 0 : -EFAULT) + || (ret = get_user(fourth.__pad, (void **)ptr))) + break; + ret = sys_semctl(first, second, third, fourth); + break; + } + case MSGSND: + ret = sys_msgsnd(first, (struct msgbuf *) ptr, second, third); + break; + case MSGRCV: + switch (version) { + case 0: { + struct ipc_kludge tmp; + + if (!ptr) + break; + if ((ret = access_ok(VERIFY_READ, ptr, + sizeof(tmp)) ? 0 : -EFAULT) + || (ret = copy_from_user(tmp, + (struct ipc_kludge *) ptr, + sizeof(tmp + break; + ret = sys_msgrcv(first, tmp.msgp, second, tmp.msgtyp, + third); + break; + } + default: + ret = sys_msgrcv(first, (struct msgbuf *) ptr, + second, fifth, third); + break; + } + break; + case MSGGET: + ret = sys_msgget((key_t) first, second); + break; + case MSGCTL: + ret = sys_msgctl(first, second, (struct msqid_ds *) ptr); + break; + case SHMAT: + switch (version) { + default: { + ulong raddr; + + if ((ret = access_ok(VERIFY_WRITE, (ulong *) third, + sizeof(ulong)) ? 0 : -EFAULT)) + break; + ret = do_shmat(first, (char *) ptr, second, raddr); + if (ret) + break; + ret = put_user(raddr, (ulong *) third); + break; + } + case 1: /* iBCS2 emulator entry point */ + if (!segment_eq(get_fs(), get_ds())) + break; + ret = do_shmat(first, (char *) ptr, second, + (ulong *) third); + break; + } + break; + case SHMDT: + ret = sys_shmdt((char *)ptr); + break; + case SHMGET: + ret = sys_shmget(first, second, third); + break; + case SHMCTL: + ret = sys_shmctl(first, second, (struct shmid_ds *) ptr); + break; + } + + return
Re: [PATCH 58/60] microblaze_v4: sys_microblaze.c
On Thursday 26 June 2008, [EMAIL PROTECTED] wrote: + +/* + * sys_ipc() is the de-multiplexer for the SysV IPC calls.. + * + * This is really horribly ugly. + */ If it's so horribly ugly, don't do it this way ;-) +int +sys_ipc(uint call, int first, int second, int third, void *ptr, long fifth) +{ + int version, ret; + + version = call 16; /* hack for backward compatibility */ + call = 0x; Backwards compatibility with what? +static inline unsigned long +do_mmap2(unsigned long addr, size_t len, + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long pgoff) +{ + struct file *file = NULL; + int ret = -EBADF; + + flags = ~(MAP_EXECUTABLE | MAP_DENYWRITE); + if (!(flags MAP_ANONYMOUS)) + if (!(file = fget(fd))) { + printk(KERN_INFO no fd in mmap\r\n); + goto out; + } + + down_write(current-mm-mmap_sem); + ret = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); + up_write(current-mm-mmap_sem); + if (file) + fput(file); +out: + return ret; +} + +unsigned long sys_mmap2(unsigned long addr, size_t len, + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long pgoff) +{ + return do_mmap2(addr, len, prot, flags, fd, pgoff); +} + +unsigned long sys_mmap(unsigned long addr, size_t len, + unsigned long prot, unsigned long flags, + unsigned long fd, off_t offset) +{ + int err = -EINVAL; + + if (offset ~PAGE_MASK) { + printk(KERN_INFO no pagemask in mmap\r\n); + goto out; + } + + err = do_mmap2(addr, len, prot, flags, fd, offset PAGE_SHIFT); +out: + return err; +} Which mmap is uClibc really using? I suppose you only need mmap2, even for compatibility with any binary ever built for microblaze. Arnd ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [PATCH 58/60] microblaze_v4: sys_microblaze.c
On Thursday 26 June 2008, [EMAIL PROTECTED] wrote: + +int sys_uname(struct old_utsname *name) +{ + int err = -EFAULT; + + down_read(uts_sem); + if (name !copy_to_user(name, utsname(), sizeof(*name))) + err = 0; + up_read(uts_sem); + return err; +} This actually seems to be dead code, as your sys_call_table only contains sys_newuname but not sys_uname. Arnd ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [PATCH 58/60] microblaze_v4: sys_microblaze.c
+ +/* + * sys_ipc() is the de-multiplexer for the SysV IPC calls.. + * + * This is really horribly ugly. + */ If it's so horribly ugly, don't do it this way ;-) :-) this is not my part of code. I'll remove it with syscall changes. +int +sys_ipc(uint call, int first, int second, int third, void *ptr, long fifth) +{ +int version, ret; + +version = call 16; /* hack for backward compatibility */ +call = 0x; Backwards compatibility with what? I don't know. John: I suppose this is your comment. +static inline unsigned long +do_mmap2(unsigned long addr, size_t len, +unsigned long prot, unsigned long flags, +unsigned long fd, unsigned long pgoff) +{ +struct file *file = NULL; +int ret = -EBADF; + +flags = ~(MAP_EXECUTABLE | MAP_DENYWRITE); +if (!(flags MAP_ANONYMOUS)) +if (!(file = fget(fd))) { +printk(KERN_INFO no fd in mmap\r\n); +goto out; +} + +down_write(current-mm-mmap_sem); +ret = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); +up_write(current-mm-mmap_sem); +if (file) +fput(file); +out: +return ret; +} + +unsigned long sys_mmap2(unsigned long addr, size_t len, +unsigned long prot, unsigned long flags, +unsigned long fd, unsigned long pgoff) +{ +return do_mmap2(addr, len, prot, flags, fd, pgoff); +} + +unsigned long sys_mmap(unsigned long addr, size_t len, +unsigned long prot, unsigned long flags, +unsigned long fd, off_t offset) +{ +int err = -EINVAL; + +if (offset ~PAGE_MASK) { +printk(KERN_INFO no pagemask in mmap\r\n); +goto out; +} + +err = do_mmap2(addr, len, prot, flags, fd, offset PAGE_SHIFT); +out: +return err; +} Which mmap is uClibc really using? I suppose you only need mmap2, even for compatibility with any binary ever built for microblaze. I don't know. Microblaze should be compiled with uClibc and glibc. In case you need mmap2 for uClibc and mmap for glibc it is ok. M Arnd ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [PATCH 58/60] microblaze_v4: sys_microblaze.c
On Thursday 26 June 2008, Michal Simek wrote: + +/* + * sys_ipc() is the de-multiplexer for the SysV IPC calls.. + * + * This is really horribly ugly. + */ If it's so horribly ugly, don't do it this way ;-) :-) this is not my part of code. I'll remove it with syscall changes. Yes, I was aware of that. I believe the comment was initially done in order to prevent people from copying it to new architectures, but it never worked. +int +sys_ipc(uint call, int first, int second, int third, void *ptr, long fifth) +{ + int version, ret; + + version = call 16; /* hack for backward compatibility */ + call = 0x; Backwards compatibility with what? I don't know. John: I suppose this is your comment. No, it was a trick question, this is also copied from i386. It was meant for the iBCS2 compatibility layer that provides support for running Unix binaries from the late 80s, but never quite made it into the Linux kernel. +unsigned long sys_mmap2(unsigned long addr, size_t len, + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long pgoff) +{ + return do_mmap2(addr, len, prot, flags, fd, pgoff); +} + +unsigned long sys_mmap(unsigned long addr, size_t len, + unsigned long prot, unsigned long flags, + unsigned long fd, off_t offset) +{ + int err = -EINVAL; + + if (offset ~PAGE_MASK) { + printk(KERN_INFO no pagemask in mmap\r\n); + goto out; + } + + err = do_mmap2(addr, len, prot, flags, fd, offset PAGE_SHIFT); +out: + return err; +} Which mmap is uClibc really using? I suppose you only need mmap2, even for compatibility with any binary ever built for microblaze. I don't know. Microblaze should be compiled with uClibc and glibc. In case you need mmap2 for uClibc and mmap for glibc it is ok. I looked at uClibc again and found that you probably need both for compatibility and functionality, same as for other calls that can take either an off_t or a loff_t. Only if you changed the libc/sysdeps/linux/microblaze/mmap.c code, you could get rid of sys_mmap(). I don't think you need to worry about glibc at this point, because as I understand it the old port is broken anyway and it's easier to do a new microblaze glibc port from scratch than trying to update it to the latest glibc version... Arnd ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev