qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] Add readahead syscall
@ 2008-10-08 18:54 Kirill A. Shutemov
  2008-10-08 18:54 ` [Qemu-devel] [PATCH] Fix getdents* syscalls Kirill A. Shutemov
  2008-10-13 21:09 ` [Qemu-devel] [PATCH] Add readahead syscall Aurelien Jarno
  0 siblings, 2 replies; 17+ messages in thread
From: Kirill A. Shutemov @ 2008-10-08 18:54 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kirill A. Shutemov

Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
---
 linux-user/syscall.c |   15 ++++++++++++++-
 1 files changed, 14 insertions(+), 1 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index f1f050e..dc7e561 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5761,7 +5761,20 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         break;
 #ifdef TARGET_NR_readahead
     case TARGET_NR_readahead:
-        goto unimplemented;
+#if TARGET_ABI_BITS == 32
+#ifdef TARGET_ARM
+        if (((CPUARMState *)cpu_env)->eabi)
+        {
+            arg2 = arg3;
+            arg3 = arg4;
+            arg4 = arg5;
+        }
+#endif
+        ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
+#else
+        ret = get_errno(readahead(arg1, arg2, arg3));
+#endif
+        break;
 #endif
 #ifdef TARGET_NR_setxattr
     case TARGET_NR_setxattr:
-- 
1.5.6.5.GIT

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH] Fix getdents* syscalls
  2008-10-08 18:54 [Qemu-devel] [PATCH] Add readahead syscall Kirill A. Shutemov
@ 2008-10-08 18:54 ` Kirill A. Shutemov
  2008-10-08 18:54   ` [Qemu-devel] [PATCH] Fix and cleanup IPCOP_msg* ipc calls handling Kirill A. Shutemov
  2008-10-13 21:09   ` [Qemu-devel] [PATCH] Fix getdents* syscalls Aurelien Jarno
  2008-10-13 21:09 ` [Qemu-devel] [PATCH] Add readahead syscall Aurelien Jarno
  1 sibling, 2 replies; 17+ messages in thread
From: Kirill A. Shutemov @ 2008-10-08 18:54 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kirill A. Shutemov

glibc's structs dirent and dirent64 is different from in-kernel dirent
and dirent64. Kernel headers doesn't provide structs dirent(64) any
more. So we should add it to qemu headers.

To avoid conflict with glibc it called struct linux_dirent(64).

Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
---
 linux-user/syscall.c      |   27 +++++++++++++--------------
 linux-user/syscall_defs.h |   15 +++++++++++++++
 2 files changed, 28 insertions(+), 14 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index dc7e561..40e985a 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -28,7 +28,6 @@
 #include <fcntl.h>
 #include <time.h>
 #include <limits.h>
-#include <dirent.h>
 #include <sys/types.h>
 #include <sys/ipc.h>
 #include <sys/msg.h>
@@ -94,8 +93,8 @@
 #endif
 
 //#include <linux/msdos_fs.h>
-#define	VFAT_IOCTL_READDIR_BOTH		_IOR('r', 1, struct dirent [2])
-#define	VFAT_IOCTL_READDIR_SHORT	_IOR('r', 2, struct dirent [2])
+#define	VFAT_IOCTL_READDIR_BOTH		_IOR('r', 1, struct linux_dirent [2])
+#define	VFAT_IOCTL_READDIR_SHORT	_IOR('r', 2, struct linux_dirent [2])
 
 
 #undef _syscall0
@@ -216,10 +215,10 @@ _syscall3(int,sys_futimesat,int,dirfd,const char *,pathname,
 #endif
 _syscall2(int,sys_getcwd1,char *,buf,size_t,size)
 #if TARGET_ABI_BITS == 32
-_syscall3(int, sys_getdents, uint, fd, struct dirent *, dirp, uint, count);
+_syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
 #endif
 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
-_syscall3(int, sys_getdents64, uint, fd, struct dirent64 *, dirp, uint, count);
+_syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
 #endif
 _syscall2(int, sys_getpriority, int, which, int, who);
 #if !defined (__x86_64__)
@@ -4879,7 +4878,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 #elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
         {
             struct target_dirent *target_dirp;
-            struct dirent *dirp;
+            struct linux_dirent *dirp;
             abi_long count = arg3;
 
 	    dirp = malloc(count);
@@ -4890,7 +4889,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 
             ret = get_errno(sys_getdents(arg1, dirp, count));
             if (!is_error(ret)) {
-                struct dirent *de;
+                struct linux_dirent *de;
 		struct target_dirent *tde;
                 int len = ret;
                 int reclen, treclen;
@@ -4912,7 +4911,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
                         tnamelen = 256;
                     /* XXX: may not be correct */
 		    strncpy(tde->d_name, de->d_name, tnamelen);
-                    de = (struct dirent *)((char *)de + reclen);
+                    de = (struct linux_dirent *)((char *)de + reclen);
                     len -= reclen;
                     tde = (struct target_dirent *)((char *)tde + treclen);
 		    count1 += treclen;
@@ -4924,14 +4923,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         }
 #else
         {
-            struct dirent *dirp;
+            struct linux_dirent *dirp;
             abi_long count = arg3;
 
             if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
                 goto efault;
             ret = get_errno(sys_getdents(arg1, dirp, count));
             if (!is_error(ret)) {
-                struct dirent *de;
+                struct linux_dirent *de;
                 int len = ret;
                 int reclen;
                 de = dirp;
@@ -4942,7 +4941,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
                     de->d_reclen = tswap16(reclen);
                     tswapls(&de->d_ino);
                     tswapls(&de->d_off);
-                    de = (struct dirent *)((char *)de + reclen);
+                    de = (struct linux_dirent *)((char *)de + reclen);
                     len -= reclen;
                 }
             }
@@ -4953,13 +4952,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
     case TARGET_NR_getdents64:
         {
-            struct dirent64 *dirp;
+            struct linux_dirent64 *dirp;
             abi_long count = arg3;
             if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
                 goto efault;
             ret = get_errno(sys_getdents64(arg1, dirp, count));
             if (!is_error(ret)) {
-                struct dirent64 *de;
+                struct linux_dirent64 *de;
                 int len = ret;
                 int reclen;
                 de = dirp;
@@ -4970,7 +4969,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
                     de->d_reclen = tswap16(reclen);
                     tswap64s((uint64_t *)&de->d_ino);
                     tswap64s((uint64_t *)&de->d_off);
-                    de = (struct dirent64 *)((char *)de + reclen);
+                    de = (struct linux_dirent64 *)((char *)de + reclen);
                     len -= reclen;
                 }
             }
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index c30bb15..5a58010 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -1963,6 +1963,21 @@ struct target_sysinfo {
     char _f[20-2*sizeof(abi_long)-sizeof(int)]; /* Padding: libc5 uses this.. */
 };
 
+struct linux_dirent {
+    long            d_ino;
+    unsigned long   d_off;
+    unsigned short  d_reclen;
+    char            d_name[256]; /* We must not include limits.h! */
+};
+
+struct linux_dirent64 {
+    uint64_t        d_ino;
+    int64_t         d_off;
+    unsigned short  d_reclen;
+    unsigned char   d_type;
+    char            d_name[256];
+};
+
 #include "socket.h"
 
 #include "errno_defs.h"
-- 
1.5.6.5.GIT

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH] Fix and cleanup IPCOP_msg* ipc calls handling
  2008-10-08 18:54 ` [Qemu-devel] [PATCH] Fix getdents* syscalls Kirill A. Shutemov
@ 2008-10-08 18:54   ` Kirill A. Shutemov
  2008-10-08 18:54     ` [Qemu-devel] [PATCH] Implement msg* syscalls Kirill A. Shutemov
  2008-10-13 21:09   ` [Qemu-devel] [PATCH] Fix getdents* syscalls Aurelien Jarno
  1 sibling, 1 reply; 17+ messages in thread
From: Kirill A. Shutemov @ 2008-10-08 18:54 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kirill A. Shutemov

Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
---
 linux-user/syscall.c |  173 ++++++++++++++++++++++++++++++++++----------------
 1 files changed, 117 insertions(+), 56 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 40e985a..7e67093 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -1611,7 +1611,6 @@ static abi_long do_socketcall(int num, abi_ulong vptr)
 }
 #endif
 
-#ifdef TARGET_NR_ipc
 #define N_SHM_REGIONS	32
 
 static struct shm_region {
@@ -1845,20 +1844,26 @@ static inline abi_long do_semctl(int first, int second, int third,
 
 struct target_msqid_ds
 {
-  struct target_ipc_perm msg_perm;
-  abi_ulong msg_stime;
-  abi_ulong __unused1;
-  abi_ulong msg_rtime;
-  abi_ulong __unused2;
-  abi_ulong msg_ctime;
-  abi_ulong __unused3;
-  abi_ulong __msg_cbytes;
-  abi_ulong msg_qnum;
-  abi_ulong msg_qbytes;
-  abi_ulong msg_lspid;
-  abi_ulong msg_lrpid;
-  abi_ulong __unused4;
-  abi_ulong __unused5;
+    struct target_ipc_perm msg_perm;
+    abi_ulong msg_stime;
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused1;
+#endif
+    abi_ulong msg_rtime;
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused2;
+#endif
+    abi_ulong msg_ctime;
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused3;
+#endif
+    abi_ulong __msg_cbytes;
+    abi_ulong msg_qnum;
+    abi_ulong msg_qbytes;
+    abi_ulong msg_lspid;
+    abi_ulong msg_lrpid;
+    abi_ulong __unused4;
+    abi_ulong __unused5;
 };
 
 static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
@@ -1868,7 +1873,8 @@ static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
 
     if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
         return -TARGET_EFAULT;
-    target_to_host_ipc_perm(&(host_md->msg_perm),target_addr);
+    if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
+        return -TARGET_EFAULT;
     host_md->msg_stime = tswapl(target_md->msg_stime);
     host_md->msg_rtime = tswapl(target_md->msg_rtime);
     host_md->msg_ctime = tswapl(target_md->msg_ctime);
@@ -1888,7 +1894,8 @@ static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
 
     if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
         return -TARGET_EFAULT;
-    host_to_target_ipc_perm(target_addr,&(host_md->msg_perm));
+    if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
+        return -TARGET_EFAULT;
     target_md->msg_stime = tswapl(host_md->msg_stime);
     target_md->msg_rtime = tswapl(host_md->msg_rtime);
     target_md->msg_ctime = tswapl(host_md->msg_ctime);
@@ -1901,26 +1908,69 @@ static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
     return 0;
 }
 
-static inline abi_long do_msgctl(int first, int second, abi_long ptr)
+struct target_msginfo {
+    int msgpool;
+    int msgmap;
+    int msgmax;
+    int msgmnb;
+    int msgmni;
+    int msgssz;
+    int msgtql;
+    unsigned short int msgseg;
+};
+
+static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
+                                              struct msginfo *host_msginfo)
+{
+    struct target_msginfo *target_msginfo;
+    if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
+        return -TARGET_EFAULT;
+    __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
+    __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
+    __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
+    __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
+    __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
+    __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
+    __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
+    __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
+    unlock_user_struct(target_msginfo, target_addr, 1);
+}
+
+static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
 {
     struct msqid_ds dsarg;
-    int cmd = second&0xff;
-    abi_long ret = 0;
-    switch( cmd ) {
+    struct msginfo msginfo;
+    abi_long ret = -TARGET_EINVAL;
+
+    cmd &= 0xff;
+
+    switch (cmd) {
     case IPC_STAT:
     case IPC_SET:
-        target_to_host_msqid_ds(&dsarg,ptr);
-        ret = get_errno(msgctl(first, cmd, &dsarg));
-        host_to_target_msqid_ds(ptr,&dsarg);
-    default:
-        ret = get_errno(msgctl(first, cmd, &dsarg));
+    case MSG_STAT:
+        if (target_to_host_msqid_ds(&dsarg,ptr))
+            return -TARGET_EFAULT;
+        ret = get_errno(msgctl(msgid, cmd, &dsarg));
+        if (host_to_target_msqid_ds(ptr,&dsarg))
+            return -TARGET_EFAULT;
+        break;
+    case IPC_RMID:
+        ret = get_errno(msgctl(msgid, cmd, NULL));
+        break;
+    case IPC_INFO:
+    case MSG_INFO:
+        ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
+        if (host_to_target_msginfo(ptr, &msginfo))
+            return -TARGET_EFAULT;
+        break;
     }
+
     return ret;
 }
 
 struct target_msgbuf {
-	abi_ulong mtype;
-	char	mtext[1];
+    abi_long mtype;
+    char	mtext[1];
 };
 
 static inline abi_long do_msgsnd(int msqid, abi_long msgp,
@@ -1933,8 +1983,8 @@ static inline abi_long do_msgsnd(int msqid, abi_long msgp,
     if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
         return -TARGET_EFAULT;
     host_mb = malloc(msgsz+sizeof(long));
-    host_mb->mtype = tswapl(target_mb->mtype);
-    memcpy(host_mb->mtext,target_mb->mtext,msgsz);
+    host_mb->mtype = (abi_long) tswapl(target_mb->mtype);
+    memcpy(host_mb->mtext, target_mb->mtext, msgsz);
     ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
     free(host_mb);
     unlock_user_struct(target_mb, msgp, 0);
@@ -1943,7 +1993,7 @@ static inline abi_long do_msgsnd(int msqid, abi_long msgp,
 }
 
 static inline abi_long do_msgrcv(int msqid, abi_long msgp,
-                                 unsigned int msgsz, int msgtype,
+                                 unsigned int msgsz, abi_long msgtyp,
                                  int msgflg)
 {
     struct target_msgbuf *target_mb;
@@ -1953,8 +2003,10 @@ static inline abi_long do_msgrcv(int msqid, abi_long msgp,
 
     if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
         return -TARGET_EFAULT;
+
     host_mb = malloc(msgsz+sizeof(long));
-    ret = get_errno(msgrcv(msqid, host_mb, msgsz, 1, msgflg));
+    ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapl(msgtyp), msgflg));
+
     if (ret > 0) {
         abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
         target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
@@ -1962,9 +2014,10 @@ static inline abi_long do_msgrcv(int msqid, abi_long msgp,
             ret = -TARGET_EFAULT;
             goto end;
         }
-    	memcpy(target_mb->mtext, host_mb->mtext, ret);
+        memcpy(target_mb->mtext, host_mb->mtext, ret);
         unlock_user(target_mtext, target_mtext_addr, ret);
     }
+
     target_mb->mtype = tswapl(host_mb->mtype);
     free(host_mb);
 
@@ -1974,6 +2027,7 @@ end:
     return ret;
 }
 
+#ifdef TARGET_NR_ipc
 /* ??? This only works with linear mappings.  */
 /* do_ipc() must return target values and target errnos. */
 static abi_long do_ipc(unsigned int call, int first,
@@ -2006,34 +2060,41 @@ static abi_long do_ipc(unsigned int call, int first,
         ret = -TARGET_ENOSYS;
         break;
 
-	case IPCOP_msgget:
-		ret = get_errno(msgget(first, second));
-		break;
+    case IPCOP_msgget:
+        ret = get_errno(msgget(first, second));
+        break;
 
-	case IPCOP_msgsnd:
-		ret = do_msgsnd(first, ptr, second, third);
-		break;
+    case IPCOP_msgsnd:
+        ret = do_msgsnd(first, ptr, second, third);
+        break;
 
-	case IPCOP_msgctl:
-        	ret = do_msgctl(first, second, ptr);
-		break;
+    case IPCOP_msgctl:
+        ret = do_msgctl(first, second, ptr);
+        break;
 
-	case IPCOP_msgrcv:
-                {
-                      /* XXX: this code is not correct */
-                      struct ipc_kludge
-                      {
-                              void *__unbounded msgp;
-                              long int msgtyp;
-                      };
+    case IPCOP_msgrcv:
+        switch (version) {
+        case 0:
+            {
+                struct target_ipc_kludge {
+                    abi_long msgp;
+                    abi_long msgtyp;
+                } *tmp;
 
-                      struct ipc_kludge *foo = (struct ipc_kludge *)g2h(ptr);
-                      struct msgbuf *msgp = (struct msgbuf *) foo->msgp;
+                if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
+                    ret = -TARGET_EFAULT;
+                    break;
+                }
 
-                      ret = do_msgrcv(first, (long)msgp, second, 0, third);
+                ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
 
-                }
-		break;
+                unlock_user_struct(tmp, ptr, 0);
+                break;
+            }
+        default:
+            ret = do_msgrcv(first, ptr, second, fifth, third);
+        }
+        break;
 
     case IPCOP_shmat:
         {
-- 
1.5.6.5.GIT

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH] Implement msg* syscalls
  2008-10-08 18:54   ` [Qemu-devel] [PATCH] Fix and cleanup IPCOP_msg* ipc calls handling Kirill A. Shutemov
@ 2008-10-08 18:54     ` Kirill A. Shutemov
  2008-10-08 18:54       ` [Qemu-devel] [PATCH] Fix and cleanup IPCOP_sem* ipc calls handling Kirill A. Shutemov
  0 siblings, 1 reply; 17+ messages in thread
From: Kirill A. Shutemov @ 2008-10-08 18:54 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kirill A. Shutemov

Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
---
 linux-user/syscall.c |   21 +++++++++++++++++++++
 1 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 7e67093..cf0834f 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4829,6 +4829,27 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 	ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
 	break;
 #endif
+
+#ifdef TARGET_NR_msgctl
+    case TARGET_NR_msgctl:
+        ret = do_msgctl(arg1, arg2, arg3);
+        break;
+#endif
+#ifdef TARGET_NR_msgget
+    case TARGET_NR_msgget:
+        ret = get_errno(msgget(arg1, arg2));
+        break;
+#endif
+#ifdef TARGET_NR_msgrcv
+    case TARGET_NR_msgrcv:
+        ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
+        break;
+#endif
+#ifdef TARGET_NR_msgsnd
+    case TARGET_NR_msgsnd:
+        ret = do_msgsnd(arg1, arg2, arg3, arg4);
+        break;
+#endif
     case TARGET_NR_fsync:
         ret = get_errno(fsync(arg1));
         break;
-- 
1.5.6.5.GIT

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH] Fix and cleanup IPCOP_sem* ipc calls handling
  2008-10-08 18:54     ` [Qemu-devel] [PATCH] Implement msg* syscalls Kirill A. Shutemov
@ 2008-10-08 18:54       ` Kirill A. Shutemov
  2008-10-08 18:54         ` [Qemu-devel] [PATCH] Implement sem* syscalls Kirill A. Shutemov
  2008-10-09 17:41         ` [Qemu-devel] [PATCH, v2] Fix and cleanup IPCOP_sem* ipc calls handling Kirill A. Shutemov
  0 siblings, 2 replies; 17+ messages in thread
From: Kirill A. Shutemov @ 2008-10-08 18:54 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kirill A. Shutemov

Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
---
 linux-user/syscall.c |  319 +++++++++++++++++++++++++++++++-------------------
 1 files changed, 198 insertions(+), 121 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index cf0834f..54c53c2 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -1635,14 +1635,14 @@ struct target_ipc_perm
 
 struct target_semid_ds
 {
-  struct target_ipc_perm sem_perm;
-  abi_ulong sem_otime;
-  abi_ulong __unused1;
-  abi_ulong sem_ctime;
-  abi_ulong __unused2;
-  abi_ulong sem_nsems;
-  abi_ulong __unused3;
-  abi_ulong __unused4;
+    struct target_ipc_perm sem_perm;
+    abi_ulong sem_otime;
+    abi_ulong __unused1;
+    abi_ulong sem_ctime;
+    abi_ulong __unused2;
+    abi_ulong sem_nsems;
+    abi_ulong __unused3;
+    abi_ulong __unused4;
 };
 
 static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
@@ -1690,7 +1690,8 @@ static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
 
     if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
         return -TARGET_EFAULT;
-    target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr);
+    if (target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr))
+        return -TARGET_EFAULT;
     host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
     host_sd->sem_otime = tswapl(target_sd->sem_otime);
     host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
@@ -1705,7 +1706,8 @@ static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
 
     if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
         return -TARGET_EFAULT;
-    host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm));
+    if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)))
+        return -TARGET_EFAULT;;
     target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
     target_sd->sem_otime = tswapl(host_sd->sem_otime);
     target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
@@ -1713,135 +1715,215 @@ static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
     return 0;
 }
 
+struct target_seminfo {
+    int semmap;
+    int semmni;
+    int semmns;
+    int semmnu;
+    int semmsl;
+    int semopm;
+    int semume;
+    int semusz;
+    int semvmx;
+    int semaem;
+};
+
+static inline abi_long host_to_target_seminfo(abi_ulong target_addr,
+                                              struct seminfo *host_seminfo)
+{
+    struct target_seminfo *target_seminfo;
+    if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0))
+        return -TARGET_EFAULT;
+    __put_user(host_seminfo->semmap, &target_seminfo->semmap);
+    __put_user(host_seminfo->semmni, &target_seminfo->semmni);
+    __put_user(host_seminfo->semmns, &target_seminfo->semmns);
+    __put_user(host_seminfo->semmnu, &target_seminfo->semmnu);
+    __put_user(host_seminfo->semmsl, &target_seminfo->semmsl);
+    __put_user(host_seminfo->semopm, &target_seminfo->semopm);
+    __put_user(host_seminfo->semume, &target_seminfo->semume);
+    __put_user(host_seminfo->semusz, &target_seminfo->semusz);
+    __put_user(host_seminfo->semvmx, &target_seminfo->semvmx);
+    __put_user(host_seminfo->semaem, &target_seminfo->semaem);
+    unlock_user_struct(target_seminfo, target_addr, 1);
+    return 0;
+}
+
 union semun {
-	int val;
-	struct semid_ds *buf;
-	unsigned short *array;
+    int val;
+    struct semid_ds *buf;
+    unsigned short *array;
+    struct seminfo *__buf;
 };
 
 union target_semun {
-	int val;
-	abi_long buf;
-	unsigned short int *array;
+    int val;
+    abi_ulong buf;
+    abi_ulong array;
+    abi_ulong __buf;
 };
 
-static inline abi_long target_to_host_semun(int cmd,
-                                            union semun *host_su,
-                                            abi_ulong target_addr,
-                                            struct semid_ds *ds)
+static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array,
+                                               abi_ulong target_addr)
 {
-    union target_semun *target_su;
-
-    switch( cmd ) {
-	case IPC_STAT:
-	case IPC_SET:
-           if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
-               return -TARGET_EFAULT;
-	   target_to_host_semid_ds(ds,target_su->buf);
-	   host_su->buf = ds;
-           unlock_user_struct(target_su, target_addr, 0);
-	   break;
-	case GETVAL:
-	case SETVAL:
-           if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
-               return -TARGET_EFAULT;
-	   host_su->val = tswapl(target_su->val);
-           unlock_user_struct(target_su, target_addr, 0);
-	   break;
-	case GETALL:
-	case SETALL:
-           if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
-               return -TARGET_EFAULT;
-	   *host_su->array = tswap16(*target_su->array);
-           unlock_user_struct(target_su, target_addr, 0);
-	   break;
-	default:
-           gemu_log("semun operation not fully supported: %d\n", (int)cmd);
+    int nsems;
+    unsigned short *array;
+    union semun semun;
+    struct semid_ds semid_ds;
+    int i, ret;
+
+    semun.buf = &semid_ds;
+
+    ret = semctl(semid, 0, IPC_STAT, semun);
+    if (ret == -1)
+        return get_errno(ret);
+
+    nsems = semid_ds.sem_nsems;
+
+    *host_array = malloc(nsems*sizeof(unsigned short));
+    array = lock_user(VERIFY_READ, target_addr,
+                      nsems*sizeof(unsigned short), 1);
+    if (!array)
+        return -TARGET_EFAULT;
+
+    for(i=0; i<nsems; i++) {
+        __get_user((*host_array)[i], &array[i]);
     }
+    unlock_user(array, target_addr, 0);
+
     return 0;
 }
 
-static inline abi_long host_to_target_semun(int cmd,
-                                            abi_ulong target_addr,
-                                            union semun *host_su,
-                                            struct semid_ds *ds)
+static inline abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
+                                               unsigned short **host_array)
 {
-    union target_semun *target_su;
-
-    switch( cmd ) {
-	case IPC_STAT:
-	case IPC_SET:
-           if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
-               return -TARGET_EFAULT;
-	   host_to_target_semid_ds(target_su->buf,ds);
-           unlock_user_struct(target_su, target_addr, 1);
-	   break;
-	case GETVAL:
-	case SETVAL:
-           if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
-               return -TARGET_EFAULT;
-	   target_su->val = tswapl(host_su->val);
-           unlock_user_struct(target_su, target_addr, 1);
-	   break;
-	case GETALL:
-	case SETALL:
-           if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
-               return -TARGET_EFAULT;
-	   *target_su->array = tswap16(*host_su->array);
-           unlock_user_struct(target_su, target_addr, 1);
-	   break;
-        default:
-           gemu_log("semun operation not fully supported: %d\n", (int)cmd);
+    int nsems;
+    unsigned short *array;
+    union semun semun;
+    struct semid_ds semid_ds;
+    int i, ret;
+
+    semun.buf = &semid_ds;
+
+    ret = semctl(semid, 0, IPC_STAT, semun);
+    if (ret == -1)
+        return get_errno(ret);
+
+    nsems = semid_ds.sem_nsems;
+
+    array = lock_user(VERIFY_WRITE, target_addr,
+                      nsems*sizeof(unsigned short), 0);
+    if (!array)
+        return -TARGET_EFAULT;
+
+    for(i=0; i<nsems; i++) {
+        __put_user((*host_array)[i], &array[i]);
     }
+    free(*host_array);
+    unlock_user(array, target_addr, 1);
+
     return 0;
 }
 
-static inline abi_long do_semctl(int first, int second, int third,
-                                 abi_long ptr)
+static inline abi_long do_semctl(int semid, int semnum, int cmd,
+                                 union target_semun target_su)
 {
     union semun arg;
     struct semid_ds dsarg;
-    int cmd = third&0xff;
-    abi_long ret = 0;
+    unsigned short *array;
+    struct seminfo seminfo;
+    abi_long ret = -TARGET_EINVAL;
+    abi_long err;
 
-    switch( cmd ) {
-	case GETVAL:
-            target_to_host_semun(cmd,&arg,ptr,&dsarg);
-            ret = get_errno(semctl(first, second, cmd, arg));
-            host_to_target_semun(cmd,ptr,&arg,&dsarg);
-            break;
-	case SETVAL:
-            target_to_host_semun(cmd,&arg,ptr,&dsarg);
-            ret = get_errno(semctl(first, second, cmd, arg));
-            host_to_target_semun(cmd,ptr,&arg,&dsarg);
-            break;
-	case GETALL:
-            target_to_host_semun(cmd,&arg,ptr,&dsarg);
-            ret = get_errno(semctl(first, second, cmd, arg));
-            host_to_target_semun(cmd,ptr,&arg,&dsarg);
-            break;
-	case SETALL:
-            target_to_host_semun(cmd,&arg,ptr,&dsarg);
-            ret = get_errno(semctl(first, second, cmd, arg));
-            host_to_target_semun(cmd,ptr,&arg,&dsarg);
-            break;
-	case IPC_STAT:
-            target_to_host_semun(cmd,&arg,ptr,&dsarg);
-            ret = get_errno(semctl(first, second, cmd, arg));
-            host_to_target_semun(cmd,ptr,&arg,&dsarg);
-            break;
-	case IPC_SET:
-            target_to_host_semun(cmd,&arg,ptr,&dsarg);
-            ret = get_errno(semctl(first, second, cmd, arg));
-            host_to_target_semun(cmd,ptr,&arg,&dsarg);
-            break;
-    default:
-            ret = get_errno(semctl(first, second, cmd, arg));
+    cmd &= 0xff;
+
+    switch (cmd) {
+    case IPC_STAT:
+    case IPC_SET:
+    case SEM_STAT:
+        err = target_to_host_semid_ds(&dsarg, target_su.buf);
+        if (err)
+            return err;
+        arg.buf = &dsarg;
+        ret = get_errno(semctl(semid, semnum, cmd, arg));
+        err = host_to_target_semid_ds(target_su.buf, &dsarg);
+        if (err)
+            return err;
+        break;
+    case GETVAL:
+    case SETVAL:
+        arg.val = tswapl(target_su.val);
+        ret = get_errno(semctl(semid, semnum, cmd, arg));
+        target_su.val = tswapl(arg.val);
+        break;
+    case GETALL:
+    case SETALL:
+        err = target_to_host_semarray(semid, &array, target_su.array);
+        if (err)
+            return err;
+        arg.array = array;
+        ret = get_errno(semctl(semid, semnum, cmd, arg));
+        err = host_to_target_semarray(semid, target_su.array, &array);
+        if (err)
+            return err;
+        break;
+    case IPC_INFO:
+    case SEM_INFO:
+        arg.__buf = &seminfo;
+        ret = get_errno(semctl(semid, semnum, cmd, arg));
+        err = host_to_target_seminfo(target_su.__buf, &seminfo);
+        if (err)
+            return err;
+        break;
+    case IPC_RMID:
+    case GETPID:
+    case GETNCNT:
+    case GETZCNT:
+        ret = get_errno(semctl(semid, semnum, cmd, NULL));
+        break;
     }
 
     return ret;
 }
 
+struct target_sembuf {
+    unsigned short sem_num;
+    short sem_op;
+    short sem_flg;
+};
+
+static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
+                                             abi_ulong target_addr,
+                                             unsigned nsops)
+{
+    struct target_sembuf *target_sembuf;
+    int i;
+
+    target_sembuf = lock_user(VERIFY_READ, target_addr,
+                              nsops*sizeof(struct target_sembuf), 1);
+    if (!target_sembuf)
+        return -TARGET_EFAULT;
+
+    for(i=0; i<nsops; i++) {
+        __put_user(target_sembuf[i].sem_num, &host_sembuf[i].sem_num);
+        __put_user(target_sembuf[i].sem_op, &host_sembuf[i].sem_op);
+        __put_user(target_sembuf[i].sem_flg, &host_sembuf[i].sem_flg);
+    }
+
+    unlock_user(target_sembuf, target_addr, 0);
+
+    return 0;
+}
+
+static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
+{
+    struct sembuf sops[nsops];
+
+    if (target_to_host_sembuf(sops, ptr, nsops))
+        return -TARGET_EFAULT;
+
+    return semop(semid, sops, nsops);
+}
+
 struct target_msqid_ds
 {
     struct target_ipc_perm msg_perm;
@@ -2044,7 +2126,7 @@ static abi_long do_ipc(unsigned int call, int first,
 
     switch (call) {
     case IPCOP_semop:
-        ret = get_errno(semop(first,(struct sembuf *)g2h(ptr), second));
+        ret = do_semop(first, ptr, second);
         break;
 
     case IPCOP_semget:
@@ -2052,12 +2134,7 @@ static abi_long do_ipc(unsigned int call, int first,
         break;
 
     case IPCOP_semctl:
-        ret = do_semctl(first, second, third, ptr);
-        break;
-
-    case IPCOP_semtimedop:
-        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
-        ret = -TARGET_ENOSYS;
+        ret = do_semctl(first, second, third, (union target_semun) ptr);
         break;
 
     case IPCOP_msgget:
-- 
1.5.6.5.GIT

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH] Implement sem* syscalls
  2008-10-08 18:54       ` [Qemu-devel] [PATCH] Fix and cleanup IPCOP_sem* ipc calls handling Kirill A. Shutemov
@ 2008-10-08 18:54         ` Kirill A. Shutemov
  2008-10-08 18:54           ` [Qemu-devel] [PATCH] Fix and cleanup IPCOP_shm* ipc calls handling Kirill A. Shutemov
  2008-10-09 17:42           ` [Qemu-devel] [PATCH, v2] Implement sem* syscalls Kirill A. Shutemov
  2008-10-09 17:41         ` [Qemu-devel] [PATCH, v2] Fix and cleanup IPCOP_sem* ipc calls handling Kirill A. Shutemov
  1 sibling, 2 replies; 17+ messages in thread
From: Kirill A. Shutemov @ 2008-10-08 18:54 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kirill A. Shutemov

Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
---
 linux-user/syscall.c |   16 +++++++++++++++-
 1 files changed, 15 insertions(+), 1 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 54c53c2..33dc269 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4906,7 +4906,21 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 	ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
 	break;
 #endif
-
+#ifdef TARGET_NR_semget
+    case TARGET_NR_semget:
+        ret = get_errno(semget(arg1, arg2, arg3));
+        break;
+#endif
+#ifdef TARGET_NR_semop
+    case TARGET_NR_semop:
+        ret = get_errno(do_semop(arg1, arg2, arg3));
+        break;
+#endif
+#ifdef TARGET_NR_semctl
+    case TARGET_NR_semctl:
+        ret = do_semctl(arg1, arg2, arg3, (union target_semun)arg4);
+        break;
+#endif
 #ifdef TARGET_NR_msgctl
     case TARGET_NR_msgctl:
         ret = do_msgctl(arg1, arg2, arg3);
-- 
1.5.6.5.GIT

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH] Fix and cleanup IPCOP_shm* ipc calls handling
  2008-10-08 18:54         ` [Qemu-devel] [PATCH] Implement sem* syscalls Kirill A. Shutemov
@ 2008-10-08 18:54           ` Kirill A. Shutemov
  2008-10-08 18:54             ` [Qemu-devel] [PATCH] Implement shm* syscalls Kirill A. Shutemov
  2008-10-09 17:42           ` [Qemu-devel] [PATCH, v2] Implement sem* syscalls Kirill A. Shutemov
  1 sibling, 1 reply; 17+ messages in thread
From: Kirill A. Shutemov @ 2008-10-08 18:54 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kirill A. Shutemov

Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
---
 linux-user/syscall.c |  282 +++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 224 insertions(+), 58 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 33dc269..4ee6087 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -2109,6 +2109,206 @@ end:
     return ret;
 }
 
+struct target_shmid_ds
+{
+    struct target_ipc_perm shm_perm;
+    abi_ulong shm_segsz;
+    abi_ulong shm_atime;
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused1;
+#endif
+    abi_ulong shm_dtime;
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused2;
+#endif
+    abi_ulong shm_ctime;
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused3;
+#endif
+    int shm_cpid;
+    int shm_lpid;
+    abi_ulong shm_nattch;
+    unsigned long int __unused4;
+    unsigned long int __unused5;
+};
+
+static inline abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd,
+                                               abi_ulong target_addr)
+{
+    struct target_shmid_ds *target_sd;
+
+    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
+        return -TARGET_EFAULT;
+    if (target_to_host_ipc_perm(&(host_sd->shm_perm), target_addr))
+        return -TARGET_EFAULT;
+    __put_user(target_sd->shm_segsz, &host_sd->shm_segsz);
+    __put_user(target_sd->shm_atime, &host_sd->shm_atime);
+    __put_user(target_sd->shm_dtime, &host_sd->shm_dtime);
+    __put_user(target_sd->shm_ctime, &host_sd->shm_ctime);
+    __put_user(target_sd->shm_cpid, &host_sd->shm_cpid);
+    __put_user(target_sd->shm_lpid, &host_sd->shm_lpid);
+    __put_user(target_sd->shm_nattch, &host_sd->shm_nattch);
+    unlock_user_struct(target_sd, target_addr, 0);
+    return 0;
+}
+
+static inline abi_long host_to_target_shmid_ds(abi_ulong target_addr,
+                                               struct shmid_ds *host_sd)
+{
+    struct target_shmid_ds *target_sd;
+
+    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
+        return -TARGET_EFAULT;
+    if (host_to_target_ipc_perm(target_addr, &(host_sd->shm_perm)))
+        return -TARGET_EFAULT;
+    __put_user(host_sd->shm_segsz, &target_sd->shm_segsz);
+    __put_user(host_sd->shm_atime, &target_sd->shm_atime);
+    __put_user(host_sd->shm_dtime, &target_sd->shm_dtime);
+    __put_user(host_sd->shm_ctime, &target_sd->shm_ctime);
+    __put_user(host_sd->shm_cpid, &target_sd->shm_cpid);
+    __put_user(host_sd->shm_lpid, &target_sd->shm_lpid);
+    __put_user(host_sd->shm_nattch, &target_sd->shm_nattch);
+    unlock_user_struct(target_sd, target_addr, 1);
+    return 0;
+}
+
+struct  target_shminfo {
+    abi_ulong shmmax;
+    abi_ulong shmmin;
+    abi_ulong shmmni;
+    abi_ulong shmseg;
+    abi_ulong shmall;
+};
+
+static inline abi_long host_to_target_shminfo(abi_ulong target_addr,
+                                              struct shminfo *host_shminfo)
+{
+    struct target_shminfo *target_shminfo;
+    if (!lock_user_struct(VERIFY_WRITE, target_shminfo, target_addr, 0))
+        return -TARGET_EFAULT;
+    __put_user(host_shminfo->shmmax, &target_shminfo->shmmax);
+    __put_user(host_shminfo->shmmin, &target_shminfo->shmmin);
+    __put_user(host_shminfo->shmmni, &target_shminfo->shmmni);
+    __put_user(host_shminfo->shmseg, &target_shminfo->shmseg);
+    __put_user(host_shminfo->shmall, &target_shminfo->shmall);
+    unlock_user_struct(target_shminfo, target_addr, 1);
+}
+
+struct target_shm_info {
+    int used_ids;
+    abi_ulong shm_tot;
+    abi_ulong shm_rss;
+    abi_ulong shm_swp;
+    abi_ulong swap_attempts;
+    abi_ulong swap_successes;
+};
+
+static inline abi_long host_to_target_shm_info(abi_ulong target_addr,
+                                               struct shm_info *host_shm_info)
+{
+    struct target_shm_info *target_shm_info;
+    if (!lock_user_struct(VERIFY_WRITE, target_shm_info, target_addr, 0))
+        return -TARGET_EFAULT;
+    __put_user(host_shm_info->used_ids, &target_shm_info->used_ids);
+    __put_user(host_shm_info->shm_tot, &target_shm_info->shm_tot);
+    __put_user(host_shm_info->shm_rss, &target_shm_info->shm_rss);
+    __put_user(host_shm_info->shm_swp, &target_shm_info->shm_swp);
+    __put_user(host_shm_info->swap_attempts, &target_shm_info->swap_attempts);
+    __put_user(host_shm_info->swap_successes, &target_shm_info->swap_successes);
+    unlock_user_struct(target_shm_info, target_addr, 1);
+}
+
+static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf)
+{
+    struct shmid_ds dsarg;
+    struct shminfo shminfo;
+    struct shm_info shm_info;
+    abi_long ret = -TARGET_EINVAL;
+
+    cmd &= 0xff;
+
+    switch(cmd) {
+    case IPC_STAT:
+    case IPC_SET:
+    case SHM_STAT:
+        if (target_to_host_shmid_ds(&dsarg, buf))
+            return -TARGET_EFAULT;
+        ret = get_errno(shmctl(shmid, cmd, &dsarg));
+        if (host_to_target_shmid_ds(buf, &dsarg))
+            return -TARGET_EFAULT;
+        break;
+    case IPC_INFO:
+        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shminfo));
+        if (host_to_target_shminfo(buf, &shminfo))
+            return -TARGET_EFAULT;
+        break;
+    case SHM_INFO:
+        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shm_info));
+        if (host_to_target_shm_info(buf, &shm_info))
+            return -TARGET_EFAULT;
+        break;
+    case IPC_RMID:
+    case SHM_LOCK:
+    case SHM_UNLOCK:
+        ret = get_errno(shmctl(shmid, cmd, NULL));
+        break;
+    }
+
+    return ret;
+}
+
+static inline abi_long do_shmat(int shmid, abi_ulong shmaddr, int shmflg,
+                                unsigned long *raddr)
+{
+    abi_long ret;
+    struct shmid_ds shm_info;
+    int i;
+
+    /* SHM_* flags are the same on all linux platforms */
+    *raddr = (unsigned long) shmat(shmid, g2h(shmaddr), shmflg);
+
+    if (*raddr == -1) {
+        return get_errno(*raddr);
+    }
+
+    /* find out the length of the shared memory segment */
+    ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
+    if (is_error(ret)) {
+        /* can't get length, bail out */
+        shmdt((void *) *raddr);
+        return get_errno(ret);
+    }
+
+    page_set_flags(h2g(*raddr), h2g(*raddr) + shm_info.shm_segsz,
+                   PAGE_VALID | PAGE_READ |
+                   ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));
+
+    for (i = 0; i < N_SHM_REGIONS; i++) {
+        if (shm_regions[i].start == 0) {
+            shm_regions[i].start = h2g(*raddr);
+            shm_regions[i].size = shm_info.shm_segsz;
+            break;
+        }
+    }
+
+    return 0;
+}
+
+static inline abi_long do_shmdt(abi_ulong shmaddr)
+{
+    int i;
+
+    for (i = 0; i < N_SHM_REGIONS; ++i) {
+        if (shm_regions[i].start == shmaddr) {
+            shm_regions[i].start = 0;
+            page_set_flags(shmaddr, shm_regions[i].size, 0);
+            break;
+        }
+    }
+
+    return get_errno(shmdt(g2h(shmaddr)));
+}
+
 #ifdef TARGET_NR_ipc
 /* ??? This only works with linear mappings.  */
 /* do_ipc() must return target values and target errnos. */
@@ -2118,8 +2318,6 @@ static abi_long do_ipc(unsigned int call, int first,
 {
     int version;
     abi_long ret = 0;
-    struct shmid_ds shm_info;
-    int i;
 
     version = call >> 16;
     call &= 0xffff;
@@ -2174,72 +2372,40 @@ static abi_long do_ipc(unsigned int call, int first,
         break;
 
     case IPCOP_shmat:
-        {
-            abi_ulong raddr;
-            void *host_addr;
-            /* SHM_* flags are the same on all linux platforms */
-            host_addr = shmat(first, (void *)g2h(ptr), second);
-            if (host_addr == (void *)-1) {
-                ret = get_errno((long)host_addr);
-                break;
-            }
-            raddr = h2g((unsigned long)host_addr);
-            /* find out the length of the shared memory segment */
-            
-            ret = get_errno(shmctl(first, IPC_STAT, &shm_info));
-            if (is_error(ret)) {
-                /* can't get length, bail out */
-                shmdt(host_addr);
-                break;
-            }
-            page_set_flags(raddr, raddr + shm_info.shm_segsz,
-                           PAGE_VALID | PAGE_READ |
-                           ((second & SHM_RDONLY)? 0: PAGE_WRITE));
-            for (i = 0; i < N_SHM_REGIONS; ++i) {
-                if (shm_regions[i].start == 0) {
-                    shm_regions[i].start = raddr;
-                    shm_regions[i].size = shm_info.shm_segsz;
+        switch (version) {
+        default:
+            {
+                unsigned long raddr;
+
+                ret = do_shmat(first, ptr, second, &raddr);
+                if (ret)
                     break;
-                }
+
+                ret = put_user_ual(raddr, third);
+                break;
             }
-            if (put_user_ual(raddr, third))
-                return -TARGET_EFAULT;
-            ret = 0;
+        case 1:
+            ret = -TARGET_EINVAL;
+            break;
         }
-	break;
+        break;
+
     case IPCOP_shmdt:
-	for (i = 0; i < N_SHM_REGIONS; ++i) {
-	    if (shm_regions[i].start == ptr) {
-		shm_regions[i].start = 0;
-		page_set_flags(ptr, shm_regions[i].size, 0);
-		break;
-	    }
-	}
-	ret = get_errno(shmdt((void *)g2h(ptr)));
-	break;
+        ret = do_shmdt(ptr);
+        break;
 
     case IPCOP_shmget:
-	/* IPC_* flag values are the same on all linux platforms */
-	ret = get_errno(shmget(first, second, third));
-	break;
+        ret = get_errno(shmget(first, second, third));
+        break;
 
-	/* IPC_* and SHM_* command values are the same on all linux platforms */
     case IPCOP_shmctl:
-        switch(second) {
-        case IPC_RMID:
-        case SHM_LOCK:
-        case SHM_UNLOCK:
-            ret = get_errno(shmctl(first, second, NULL));
-            break;
-        default:
-            goto unimplemented;
-        }
+        ret = do_shmctl(first, second, third);
         break;
+
     default:
-    unimplemented:
-	gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
-	ret = -TARGET_ENOSYS;
-	break;
+        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
+        ret = -TARGET_ENOSYS;
+        break;
     }
     return ret;
 }
-- 
1.5.6.5.GIT

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH] Implement shm* syscalls
  2008-10-08 18:54           ` [Qemu-devel] [PATCH] Fix and cleanup IPCOP_shm* ipc calls handling Kirill A. Shutemov
@ 2008-10-08 18:54             ` Kirill A. Shutemov
  2008-10-08 18:54               ` [Qemu-devel] [PATCH] Fix fstatat64()/newfstatat() syscall implementation Kirill A. Shutemov
  0 siblings, 1 reply; 17+ messages in thread
From: Kirill A. Shutemov @ 2008-10-08 18:54 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kirill A. Shutemov

Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
---
 linux-user/syscall.c |   26 ++++++++++++++++++++++++++
 1 files changed, 26 insertions(+), 0 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 4ee6087..5b69b5d 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5107,6 +5107,32 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         ret = do_msgsnd(arg1, arg2, arg3, arg4);
         break;
 #endif
+#ifdef TARGET_NR_shmget
+    case TARGET_NR_shmget:
+        ret = get_errno(shmget(arg1, arg2, arg3));
+        break;
+#endif
+#ifdef TARGET_NR_shmctl
+    case TARGET_NR_shmctl:
+        ret = do_shmctl(arg1, arg2, arg3);
+        break;
+#endif
+#ifdef TARGET_NR_shmat
+    case TARGET_NR_shmat:
+        {
+            abi_long err;
+            unsigned long _ret;
+
+            err = do_shmat(arg1, arg2, arg3, &_ret);
+            ret = err ? err : _ret;
+        }
+        break;
+#endif
+#ifdef TARGET_NR_shmdt
+    case TARGET_NR_shmdt:
+        ret = do_shmdt(arg1);
+        break;
+#endif
     case TARGET_NR_fsync:
         ret = get_errno(fsync(arg1));
         break;
-- 
1.5.6.5.GIT

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH] Fix fstatat64()/newfstatat() syscall implementation
  2008-10-08 18:54             ` [Qemu-devel] [PATCH] Implement shm* syscalls Kirill A. Shutemov
@ 2008-10-08 18:54               ` Kirill A. Shutemov
  2008-10-08 18:54                 ` [Qemu-devel] [PATCH] Introduce --enable-binfmt-misc configure option Kirill A. Shutemov
  2008-10-09 17:40                 ` [Qemu-devel] [PATCH, v2] Fix fstatat64()/newfstatat() syscall implementation Kirill A. Shutemov
  0 siblings, 2 replies; 17+ messages in thread
From: Kirill A. Shutemov @ 2008-10-08 18:54 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kirill A. Shutemov

There are two different syscall names for the same goal.

On systems with sizeof(long) == 64 it calls newfstatat.
On systems with sizeof(long) == 32 it calls fstatat64.

Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
---
 linux-user/syscall.c |   21 +++++++++++++++++++--
 1 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 5b69b5d..6e55a74 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -165,6 +165,7 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,	\
 #define __NR_sys_linkat __NR_linkat
 #define __NR_sys_mkdirat __NR_mkdirat
 #define __NR_sys_mknodat __NR_mknodat
+#define __NR_sys_newfstatat __NR_newfstatat
 #define __NR_sys_openat __NR_openat
 #define __NR_sys_readlinkat __NR_readlinkat
 #define __NR_sys_renameat __NR_renameat
@@ -205,7 +206,8 @@ _syscall4(int,sys_fchmodat,int,dirfd,const char *,pathname,
 _syscall5(int,sys_fchownat,int,dirfd,const char *,pathname,
           uid_t,owner,gid_t,group,int,flags)
 #endif
-#if defined(TARGET_NR_fstatat64) && defined(__NR_fstatat64)
+#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
+        defined(__NR_fstatat64)
 _syscall4(int,sys_fstatat64,int,dirfd,const char *,pathname,
           struct stat *,buf,int,flags)
 #endif
@@ -236,6 +238,11 @@ _syscall3(int,sys_mkdirat,int,dirfd,const char *,pathname,mode_t,mode)
 _syscall4(int,sys_mknodat,int,dirfd,const char *,pathname,
           mode_t,mode,dev_t,dev)
 #endif
+#if (defined(TARGET_NR_newfstatat) || defined(TARGET_NR_fstatat64) ) && \
+        defined(__NR_newfstatat)
+_syscall4(int,sys_newfstatat,int,dirfd,const char *,pathname,
+          struct stat *,buf,int,flags)
+#endif
 #if defined(TARGET_NR_openat) && defined(__NR_openat)
 _syscall4(int,sys_openat,int,dirfd,const char *,pathname,int,flags,mode_t,mode)
 #endif
@@ -5645,11 +5652,21 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             ret = host_to_target_stat64(cpu_env, arg2, &st);
         break;
 #endif
-#if defined(TARGET_NR_fstatat64) && defined(__NR_fstatat64)
+#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
+        (defined(__NR_fstatat64) || defined(__NR_newfstatat))
+#ifdef TARGET_NR_fstatat64
+    case TARGET_NR_fstatat64:
+#endif
+#ifdef TARGET_NR_newfstatat
     case TARGET_NR_fstatat64:
+#endif
         if (!(p = lock_user_string(arg2)))
             goto efault;
+#ifdef __NR_fstatat64
         ret = get_errno(sys_fstatat64(arg1, path(p), &st, arg4));
+#else
+        ret = get_errno(sys_newfstatat(arg1, path(p), &st, arg4));
+#endif
         if (!is_error(ret))
             ret = host_to_target_stat64(cpu_env, arg3, &st);
         break;
-- 
1.5.6.5.GIT

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH] Introduce --enable-binfmt-misc configure option
  2008-10-08 18:54               ` [Qemu-devel] [PATCH] Fix fstatat64()/newfstatat() syscall implementation Kirill A. Shutemov
@ 2008-10-08 18:54                 ` Kirill A. Shutemov
  2008-10-09 17:40                 ` [Qemu-devel] [PATCH, v2] Fix fstatat64()/newfstatat() syscall implementation Kirill A. Shutemov
  1 sibling, 0 replies; 17+ messages in thread
From: Kirill A. Shutemov @ 2008-10-08 18:54 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kirill A. Shutemov

It makes qemu compatible with binfmt_misc's flags 'P' and 'O'.

'P' - preserve-argv[0].  Legacy behavior of binfmt_misc is to overwrite the
      original argv[0] with the full path to the binary.  When this flag is
      included, binfmt_misc will add an argument to the argument vector for
      this purpose, thus preserving the original argv[0].

'O' - open-binary. Legacy behavior of binfmt_misc is to pass the full path
      of the binary to the interpreter as an argument. When this flag is
      included, binfmt_misc will open the file for reading and pass its
      descriptor as an argument, instead of the full path, thus allowing
      the interpreter to execute non-readable binaries.

Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
---
 configure              |   86 ++++++++++++++++++++++++++----------------------
 linux-user/linuxload.c |    7 +---
 linux-user/main.c      |   39 ++++++++++++++++++++-
 linux-user/qemu.h      |    2 +-
 4 files changed, 87 insertions(+), 47 deletions(-)

diff --git a/configure b/configure
index 9192fcf..c58ae9c 100755
--- a/configure
+++ b/configure
@@ -115,6 +115,7 @@ mixemu="no"
 bluez="yes"
 signalfd="no"
 eventfd="no"
+binfmt_misc="no"
 
 # OS specific
 targetos=`uname -s`
@@ -351,6 +352,8 @@ for opt do
   ;;
   --disable-aio) aio="no"
   ;;
+  --enable-binfmt-misc) binfmt_misc="yes"
+  ;;
   *) echo "ERROR: unknown option $opt"; show_help="yes"
   ;;
   esac
@@ -455,6 +458,7 @@ echo "  --enable-uname-release=R Return R for uname -r in usermode emulation"
 echo "  --sparc_cpu=V            Build qemu for Sparc architecture v7, v8, v8plus, v8plusa, v9"
 echo "  --disable-vde            disable support for vde network"
 echo "  --disable-aio            disable AIO support"
+echo "  --enable-binfmt-misc     makes usermode compatible with binfmt_misc's flags 'P' and 'O'"
 echo ""
 echo "NOTE: The object files are built at the place where configure is launched"
 exit 1
@@ -981,55 +985,56 @@ else
   binsuffix="/bin"
 fi
 
-echo "Install prefix    $prefix"
-echo "BIOS directory    $prefix$datasuffix"
-echo "binary directory  $prefix$binsuffix"
+echo "Install prefix      $prefix"
+echo "BIOS directory      $prefix$datasuffix"
+echo "binary directory    $prefix$binsuffix"
 if test "$mingw32" = "no" ; then
-echo "Manual directory  $prefix$mansuffix"
-echo "ELF interp prefix $interp_prefix"
-fi
-echo "Source path       $source_path"
-echo "C compiler        $cc"
-echo "Host C compiler   $host_cc"
-echo "ARCH_CFLAGS       $ARCH_CFLAGS"
-echo "make              $make"
-echo "install           $install"
-echo "host CPU          $cpu"
-echo "host big endian   $bigendian"
-echo "target list       $target_list"
-echo "gprof enabled     $gprof"
-echo "sparse enabled    $sparse"
-echo "profiler          $profiler"
-echo "static build      $static"
-echo "-Werror enabled   $werror"
+echo "Manual directory    $prefix$mansuffix"
+echo "ELF interp prefix   $interp_prefix"
+fi
+echo "Source path         $source_path"
+echo "C compiler          $cc"
+echo "Host C compiler     $host_cc"
+echo "ARCH_CFLAGS         $ARCH_CFLAGS"
+echo "make                $make"
+echo "install             $install"
+echo "host CPU            $cpu"
+echo "host big endian     $bigendian"
+echo "target list         $target_list"
+echo "gprof enabled       $gprof"
+echo "sparse enabled      $sparse"
+echo "profiler            $profiler"
+echo "static build        $static"
+echo "-Werror enabled     $werror"
 if test "$darwin" = "yes" ; then
-    echo "Cocoa support     $cocoa"
+    echo "Cocoa support       $cocoa"
 fi
 echo "SDL support       $sdl"
 if test "$sdl" != "no" ; then
-    echo "SDL static link   $sdl_static"
-fi
-echo "curses support    $curses"
-echo "mingw32 support   $mingw32"
-echo "Audio drivers     $audio_drv_list"
-echo "Extra audio cards $audio_card_list"
-echo "Mixer emulation   $mixemu"
-echo "VNC TLS support   $vnc_tls"
+    echo "SDL static link     $sdl_static"
+fi
+echo "curses support      $curses"
+echo "mingw32 support     $mingw32"
+echo "Audio drivers       $audio_drv_list"
+echo "Extra audio cards   $audio_card_list"
+echo "Mixer emulation     $mixemu"
+echo "VNC TLS support     $vnc_tls"
 if test "$vnc_tls" = "yes" ; then
-    echo "    TLS CFLAGS    $vnc_tls_cflags"
-    echo "    TLS LIBS      $vnc_tls_libs"
+    echo "    TLS CFLAGS      $vnc_tls_cflags"
+    echo "    TLS LIBS        $vnc_tls_libs"
 fi
 if test -n "$sparc_cpu"; then
-    echo "Target Sparc Arch $sparc_cpu"
+    echo "Target Sparc Arch   $sparc_cpu"
 fi
-echo "kqemu support     $kqemu"
-echo "brlapi support    $brlapi"
-echo "Documentation     $build_docs"
+echo "kqemu support       $kqemu"
+echo "brlapi support      $brlapi"
+echo "Documentation       $build_docs"
 [ ! -z "$uname_release" ] && \
-echo "uname -r          $uname_release"
-echo "NPTL support      $nptl"
-echo "vde support       $vde"
-echo "AIO support       $aio"
+echo "uname -r            $uname_release"
+echo "NPTL support        $nptl"
+echo "vde support         $vde"
+echo "AIO support         $aio"
+echo "binfmt_misc support $binfmt_misc"
 
 if test $sdl_too_old = "yes"; then
 echo "-> Your SDL version is too old - please upgrade to have SDL support"
@@ -1592,6 +1597,9 @@ if test "$target_user_only" = "yes" -a "$elfload32" = "yes"; then
   echo "TARGET_HAS_ELFLOAD32=yes" >> $config_mak
   echo "#define TARGET_HAS_ELFLOAD32 1" >> $config_h
 fi
+if test "$target_user_only" = "yes" -a "$binfmt_misc" = "yes"; then
+  echo "#define BINFMT_MISC 1" >> $config_h
+fi
 
 test -f ${config_h}~ && cmp -s $config_h ${config_h}~ && mv ${config_h}~ $config_h
 
diff --git a/linux-user/linuxload.c b/linux-user/linuxload.c
index ada7c69..cbd90f7 100644
--- a/linux-user/linuxload.c
+++ b/linux-user/linuxload.c
@@ -154,7 +154,7 @@ abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp,
     return sp;
 }
 
-int loader_exec(const char * filename, char ** argv, char ** envp,
+int loader_exec(int fd, const char * filename, char ** argv, char ** envp,
              struct target_pt_regs * regs, struct image_info *infop)
 {
     struct linux_binprm bprm;
@@ -164,10 +164,7 @@ int loader_exec(const char * filename, char ** argv, char ** envp,
     bprm.p = TARGET_PAGE_SIZE*MAX_ARG_PAGES-sizeof(unsigned int);
     for (i=0 ; i<MAX_ARG_PAGES ; i++)       /* clear page-table */
             bprm.page[i] = 0;
-    retval = open(filename, O_RDONLY);
-    if (retval < 0)
-        return retval;
-    bprm.fd = retval;
+    bprm.fd = fd;
     bprm.filename = (char *)filename;
     bprm.argc = count(argv);
     bprm.argv = argv;
diff --git a/linux-user/main.c b/linux-user/main.c
index fef4bf7..25b2867 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -26,6 +26,7 @@
 
 #include "qemu.h"
 #include "qemu-common.h"
+#include "elf.h"
 /* For tb_lock */
 #include "exec-all.h"
 
@@ -2217,9 +2218,10 @@ void init_task_state(TaskState *ts)
     ts->sigqueue_table[i].next = NULL;
 }
  
-int main(int argc, char **argv)
+int main(int argc, char **argv, char **envp)
 {
     const char *filename;
+    int fd = -1;
     const char *cpu_model;
     struct target_pt_regs regs1, *regs = &regs1;
     struct image_info info1, *info = &info1;
@@ -2380,7 +2382,40 @@ int main(int argc, char **argv)
     }
     *dst = NULL; /* NULL terminate target_environ */
 
-    if (loader_exec(filename, argv+optind, target_environ, regs, info) != 0) {
+#ifdef BINFMT_MISC
+#if HOST_LONG_BITS == 32
+#define Elf_Dyn Elf32_Dyn
+#else
+#define Elf_Dyn Elf64_Dyn
+#endif
+    {
+        Elf_Dyn *auxv;
+
+        optind++; /* Handle binfmt_misc's option 'P' */
+
+        /* Handle binfmt_misc's option 'O' */
+        while(*envp++ != NULL); /* skip envp. we are on auxv now */
+        for(auxv = (Elf_Dyn *)envp; auxv->d_tag != AT_NULL; auxv++) {
+            if( auxv->d_tag == AT_EXECFD) {
+                fd = auxv->d_un.d_val;
+                break;
+            }
+        }
+
+        if (fd < 0) {
+            printf("Cannot find binary file descriptor\n");
+            _exit(1);
+        }
+    }
+#else
+    fd = open(filename, O_RDONLY);
+    if (fd < 0) {
+        printf("Cannot open file %s: %s\n", filename, strerror(errno));
+        _exit(1);
+    }
+#endif
+
+    if (loader_exec(fd, filename, argv+optind, target_environ, regs, info) != 0) {
         printf("Error loading %s\n", filename);
         _exit(1);
     }
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index a2abe51..52835ec 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -168,7 +168,7 @@ struct linux_binprm {
 void do_init_thread(struct target_pt_regs *regs, struct image_info *infop);
 abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp,
                               abi_ulong stringp, int push_ptr);
-int loader_exec(const char * filename, char ** argv, char ** envp,
+int loader_exec(int fd, const char * filename, char ** argv, char ** envp,
              struct target_pt_regs * regs, struct image_info *infop);
 
 int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
-- 
1.5.6.5.GIT

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH, v2] Fix fstatat64()/newfstatat() syscall implementation
  2008-10-08 18:54               ` [Qemu-devel] [PATCH] Fix fstatat64()/newfstatat() syscall implementation Kirill A. Shutemov
  2008-10-08 18:54                 ` [Qemu-devel] [PATCH] Introduce --enable-binfmt-misc configure option Kirill A. Shutemov
@ 2008-10-09 17:40                 ` Kirill A. Shutemov
  1 sibling, 0 replies; 17+ messages in thread
From: Kirill A. Shutemov @ 2008-10-09 17:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kirill A. Shutemov

There are two different syscall names for the same goal.

On systems with sizeof(long) == 64 it calls newfstatat.
On systems with sizeof(long) == 32 it calls fstatat64.

Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
---
 linux-user/syscall.c |   29 +++++++++++++++++++++++++----
 1 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index c85fea4..3fa205f 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -165,6 +165,7 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,	\
 #define __NR_sys_linkat __NR_linkat
 #define __NR_sys_mkdirat __NR_mkdirat
 #define __NR_sys_mknodat __NR_mknodat
+#define __NR_sys_newfstatat __NR_newfstatat
 #define __NR_sys_openat __NR_openat
 #define __NR_sys_readlinkat __NR_readlinkat
 #define __NR_sys_renameat __NR_renameat
@@ -205,7 +206,8 @@ _syscall4(int,sys_fchmodat,int,dirfd,const char *,pathname,
 _syscall5(int,sys_fchownat,int,dirfd,const char *,pathname,
           uid_t,owner,gid_t,group,int,flags)
 #endif
-#if defined(TARGET_NR_fstatat64) && defined(__NR_fstatat64)
+#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
+        defined(__NR_fstatat64)
 _syscall4(int,sys_fstatat64,int,dirfd,const char *,pathname,
           struct stat *,buf,int,flags)
 #endif
@@ -236,6 +238,11 @@ _syscall3(int,sys_mkdirat,int,dirfd,const char *,pathname,mode_t,mode)
 _syscall4(int,sys_mknodat,int,dirfd,const char *,pathname,
           mode_t,mode,dev_t,dev)
 #endif
+#if (defined(TARGET_NR_newfstatat) || defined(TARGET_NR_fstatat64) ) && \
+        defined(__NR_newfstatat)
+_syscall4(int,sys_newfstatat,int,dirfd,const char *,pathname,
+          struct stat *,buf,int,flags)
+#endif
 #if defined(TARGET_NR_openat) && defined(__NR_openat)
 _syscall4(int,sys_openat,int,dirfd,const char *,pathname,int,flags,mode_t,mode)
 #endif
@@ -3481,7 +3488,7 @@ static inline abi_long host_to_target_timespec(abi_ulong target_addr,
     return 0;
 }
 
-#ifdef TARGET_NR_stat64
+#if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
 static inline abi_long host_to_target_stat64(void *cpu_env,
                                              abi_ulong target_addr,
                                              struct stat *host_st)
@@ -3513,11 +3520,15 @@ static inline abi_long host_to_target_stat64(void *cpu_env,
     } else
 #endif
     {
+#if TARGET_LONG_BITS == 64
+        struct target_stat *target_st;
+#else
         struct target_stat64 *target_st;
+#endif
 
         if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
             return -TARGET_EFAULT;
-        memset(target_st, 0, sizeof(struct target_stat64));
+        memset(target_st, 0, sizeof(*target_st));
         __put_user(host_st->st_dev, &target_st->st_dev);
         __put_user(host_st->st_ino, &target_st->st_ino);
 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
@@ -5645,11 +5656,21 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             ret = host_to_target_stat64(cpu_env, arg2, &st);
         break;
 #endif
-#if defined(TARGET_NR_fstatat64) && defined(__NR_fstatat64)
+#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
+        (defined(__NR_fstatat64) || defined(__NR_newfstatat))
+#ifdef TARGET_NR_fstatat64
     case TARGET_NR_fstatat64:
+#endif
+#ifdef TARGET_NR_newfstatat
+    case TARGET_NR_newfstatat:
+#endif
         if (!(p = lock_user_string(arg2)))
             goto efault;
+#ifdef __NR_fstatat64
         ret = get_errno(sys_fstatat64(arg1, path(p), &st, arg4));
+#else
+        ret = get_errno(sys_newfstatat(arg1, path(p), &st, arg4));
+#endif
         if (!is_error(ret))
             ret = host_to_target_stat64(cpu_env, arg3, &st);
         break;
-- 
1.5.6.5.GIT

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH, v2] Fix and cleanup IPCOP_sem* ipc calls handling
  2008-10-08 18:54       ` [Qemu-devel] [PATCH] Fix and cleanup IPCOP_sem* ipc calls handling Kirill A. Shutemov
  2008-10-08 18:54         ` [Qemu-devel] [PATCH] Implement sem* syscalls Kirill A. Shutemov
@ 2008-10-09 17:41         ` Kirill A. Shutemov
  1 sibling, 0 replies; 17+ messages in thread
From: Kirill A. Shutemov @ 2008-10-09 17:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kirill A. Shutemov

Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
---
 linux-user/syscall.c |  319 +++++++++++++++++++++++++++++++-------------------
 1 files changed, 198 insertions(+), 121 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index cf0834f..1852f35 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -1635,14 +1635,14 @@ struct target_ipc_perm
 
 struct target_semid_ds
 {
-  struct target_ipc_perm sem_perm;
-  abi_ulong sem_otime;
-  abi_ulong __unused1;
-  abi_ulong sem_ctime;
-  abi_ulong __unused2;
-  abi_ulong sem_nsems;
-  abi_ulong __unused3;
-  abi_ulong __unused4;
+    struct target_ipc_perm sem_perm;
+    abi_ulong sem_otime;
+    abi_ulong __unused1;
+    abi_ulong sem_ctime;
+    abi_ulong __unused2;
+    abi_ulong sem_nsems;
+    abi_ulong __unused3;
+    abi_ulong __unused4;
 };
 
 static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
@@ -1690,7 +1690,8 @@ static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
 
     if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
         return -TARGET_EFAULT;
-    target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr);
+    if (target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr))
+        return -TARGET_EFAULT;
     host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
     host_sd->sem_otime = tswapl(target_sd->sem_otime);
     host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
@@ -1705,7 +1706,8 @@ static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
 
     if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
         return -TARGET_EFAULT;
-    host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm));
+    if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)))
+        return -TARGET_EFAULT;;
     target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
     target_sd->sem_otime = tswapl(host_sd->sem_otime);
     target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
@@ -1713,135 +1715,215 @@ static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
     return 0;
 }
 
+struct target_seminfo {
+    int semmap;
+    int semmni;
+    int semmns;
+    int semmnu;
+    int semmsl;
+    int semopm;
+    int semume;
+    int semusz;
+    int semvmx;
+    int semaem;
+};
+
+static inline abi_long host_to_target_seminfo(abi_ulong target_addr,
+                                              struct seminfo *host_seminfo)
+{
+    struct target_seminfo *target_seminfo;
+    if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0))
+        return -TARGET_EFAULT;
+    __put_user(host_seminfo->semmap, &target_seminfo->semmap);
+    __put_user(host_seminfo->semmni, &target_seminfo->semmni);
+    __put_user(host_seminfo->semmns, &target_seminfo->semmns);
+    __put_user(host_seminfo->semmnu, &target_seminfo->semmnu);
+    __put_user(host_seminfo->semmsl, &target_seminfo->semmsl);
+    __put_user(host_seminfo->semopm, &target_seminfo->semopm);
+    __put_user(host_seminfo->semume, &target_seminfo->semume);
+    __put_user(host_seminfo->semusz, &target_seminfo->semusz);
+    __put_user(host_seminfo->semvmx, &target_seminfo->semvmx);
+    __put_user(host_seminfo->semaem, &target_seminfo->semaem);
+    unlock_user_struct(target_seminfo, target_addr, 1);
+    return 0;
+}
+
 union semun {
-	int val;
-	struct semid_ds *buf;
-	unsigned short *array;
+    int val;
+    struct semid_ds *buf;
+    unsigned short *array;
+    struct seminfo *__buf;
 };
 
 union target_semun {
-	int val;
-	abi_long buf;
-	unsigned short int *array;
+    int val;
+    abi_ulong buf;
+    abi_ulong array;
+    abi_ulong __buf;
 };
 
-static inline abi_long target_to_host_semun(int cmd,
-                                            union semun *host_su,
-                                            abi_ulong target_addr,
-                                            struct semid_ds *ds)
+static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array,
+                                               abi_ulong target_addr)
 {
-    union target_semun *target_su;
-
-    switch( cmd ) {
-	case IPC_STAT:
-	case IPC_SET:
-           if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
-               return -TARGET_EFAULT;
-	   target_to_host_semid_ds(ds,target_su->buf);
-	   host_su->buf = ds;
-           unlock_user_struct(target_su, target_addr, 0);
-	   break;
-	case GETVAL:
-	case SETVAL:
-           if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
-               return -TARGET_EFAULT;
-	   host_su->val = tswapl(target_su->val);
-           unlock_user_struct(target_su, target_addr, 0);
-	   break;
-	case GETALL:
-	case SETALL:
-           if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
-               return -TARGET_EFAULT;
-	   *host_su->array = tswap16(*target_su->array);
-           unlock_user_struct(target_su, target_addr, 0);
-	   break;
-	default:
-           gemu_log("semun operation not fully supported: %d\n", (int)cmd);
+    int nsems;
+    unsigned short *array;
+    union semun semun;
+    struct semid_ds semid_ds;
+    int i, ret;
+
+    semun.buf = &semid_ds;
+
+    ret = semctl(semid, 0, IPC_STAT, semun);
+    if (ret == -1)
+        return get_errno(ret);
+
+    nsems = semid_ds.sem_nsems;
+
+    *host_array = malloc(nsems*sizeof(unsigned short));
+    array = lock_user(VERIFY_READ, target_addr,
+                      nsems*sizeof(unsigned short), 1);
+    if (!array)
+        return -TARGET_EFAULT;
+
+    for(i=0; i<nsems; i++) {
+        __get_user((*host_array)[i], &array[i]);
     }
+    unlock_user(array, target_addr, 0);
+
     return 0;
 }
 
-static inline abi_long host_to_target_semun(int cmd,
-                                            abi_ulong target_addr,
-                                            union semun *host_su,
-                                            struct semid_ds *ds)
+static inline abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
+                                               unsigned short **host_array)
 {
-    union target_semun *target_su;
-
-    switch( cmd ) {
-	case IPC_STAT:
-	case IPC_SET:
-           if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
-               return -TARGET_EFAULT;
-	   host_to_target_semid_ds(target_su->buf,ds);
-           unlock_user_struct(target_su, target_addr, 1);
-	   break;
-	case GETVAL:
-	case SETVAL:
-           if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
-               return -TARGET_EFAULT;
-	   target_su->val = tswapl(host_su->val);
-           unlock_user_struct(target_su, target_addr, 1);
-	   break;
-	case GETALL:
-	case SETALL:
-           if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
-               return -TARGET_EFAULT;
-	   *target_su->array = tswap16(*host_su->array);
-           unlock_user_struct(target_su, target_addr, 1);
-	   break;
-        default:
-           gemu_log("semun operation not fully supported: %d\n", (int)cmd);
+    int nsems;
+    unsigned short *array;
+    union semun semun;
+    struct semid_ds semid_ds;
+    int i, ret;
+
+    semun.buf = &semid_ds;
+
+    ret = semctl(semid, 0, IPC_STAT, semun);
+    if (ret == -1)
+        return get_errno(ret);
+
+    nsems = semid_ds.sem_nsems;
+
+    array = lock_user(VERIFY_WRITE, target_addr,
+                      nsems*sizeof(unsigned short), 0);
+    if (!array)
+        return -TARGET_EFAULT;
+
+    for(i=0; i<nsems; i++) {
+        __put_user((*host_array)[i], &array[i]);
     }
+    free(*host_array);
+    unlock_user(array, target_addr, 1);
+
     return 0;
 }
 
-static inline abi_long do_semctl(int first, int second, int third,
-                                 abi_long ptr)
+static inline abi_long do_semctl(int semid, int semnum, int cmd,
+                                 union target_semun target_su)
 {
     union semun arg;
     struct semid_ds dsarg;
-    int cmd = third&0xff;
-    abi_long ret = 0;
+    unsigned short *array;
+    struct seminfo seminfo;
+    abi_long ret = -TARGET_EINVAL;
+    abi_long err;
 
-    switch( cmd ) {
-	case GETVAL:
-            target_to_host_semun(cmd,&arg,ptr,&dsarg);
-            ret = get_errno(semctl(first, second, cmd, arg));
-            host_to_target_semun(cmd,ptr,&arg,&dsarg);
-            break;
-	case SETVAL:
-            target_to_host_semun(cmd,&arg,ptr,&dsarg);
-            ret = get_errno(semctl(first, second, cmd, arg));
-            host_to_target_semun(cmd,ptr,&arg,&dsarg);
-            break;
-	case GETALL:
-            target_to_host_semun(cmd,&arg,ptr,&dsarg);
-            ret = get_errno(semctl(first, second, cmd, arg));
-            host_to_target_semun(cmd,ptr,&arg,&dsarg);
-            break;
-	case SETALL:
-            target_to_host_semun(cmd,&arg,ptr,&dsarg);
-            ret = get_errno(semctl(first, second, cmd, arg));
-            host_to_target_semun(cmd,ptr,&arg,&dsarg);
-            break;
-	case IPC_STAT:
-            target_to_host_semun(cmd,&arg,ptr,&dsarg);
-            ret = get_errno(semctl(first, second, cmd, arg));
-            host_to_target_semun(cmd,ptr,&arg,&dsarg);
-            break;
-	case IPC_SET:
-            target_to_host_semun(cmd,&arg,ptr,&dsarg);
-            ret = get_errno(semctl(first, second, cmd, arg));
-            host_to_target_semun(cmd,ptr,&arg,&dsarg);
-            break;
-    default:
-            ret = get_errno(semctl(first, second, cmd, arg));
+    cmd &= 0xff;
+
+    switch (cmd) {
+    case IPC_STAT:
+    case IPC_SET:
+    case SEM_STAT:
+        err = target_to_host_semid_ds(&dsarg, target_su.buf);
+        if (err)
+            return err;
+        arg.buf = &dsarg;
+        ret = get_errno(semctl(semid, semnum, cmd, arg));
+        err = host_to_target_semid_ds(target_su.buf, &dsarg);
+        if (err)
+            return err;
+        break;
+    case GETVAL:
+    case SETVAL:
+        arg.val = tswapl(target_su.val);
+        ret = get_errno(semctl(semid, semnum, cmd, arg));
+        target_su.val = tswapl(arg.val);
+        break;
+    case GETALL:
+    case SETALL:
+        err = target_to_host_semarray(semid, &array, target_su.array);
+        if (err)
+            return err;
+        arg.array = array;
+        ret = get_errno(semctl(semid, semnum, cmd, arg));
+        err = host_to_target_semarray(semid, target_su.array, &array);
+        if (err)
+            return err;
+        break;
+    case IPC_INFO:
+    case SEM_INFO:
+        arg.__buf = &seminfo;
+        ret = get_errno(semctl(semid, semnum, cmd, arg));
+        err = host_to_target_seminfo(target_su.__buf, &seminfo);
+        if (err)
+            return err;
+        break;
+    case IPC_RMID:
+    case GETPID:
+    case GETNCNT:
+    case GETZCNT:
+        ret = get_errno(semctl(semid, semnum, cmd, NULL));
+        break;
     }
 
     return ret;
 }
 
+struct target_sembuf {
+    unsigned short sem_num;
+    short sem_op;
+    short sem_flg;
+};
+
+static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
+                                             abi_ulong target_addr,
+                                             unsigned nsops)
+{
+    struct target_sembuf *target_sembuf;
+    int i;
+
+    target_sembuf = lock_user(VERIFY_READ, target_addr,
+                              nsops*sizeof(struct target_sembuf), 1);
+    if (!target_sembuf)
+        return -TARGET_EFAULT;
+
+    for(i=0; i<nsops; i++) {
+        __put_user(target_sembuf[i].sem_num, &host_sembuf[i].sem_num);
+        __put_user(target_sembuf[i].sem_op, &host_sembuf[i].sem_op);
+        __put_user(target_sembuf[i].sem_flg, &host_sembuf[i].sem_flg);
+    }
+
+    unlock_user(target_sembuf, target_addr, 0);
+
+    return 0;
+}
+
+static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
+{
+    struct sembuf sops[nsops];
+
+    if (target_to_host_sembuf(sops, ptr, nsops))
+        return -TARGET_EFAULT;
+
+    return semop(semid, sops, nsops);
+}
+
 struct target_msqid_ds
 {
     struct target_ipc_perm msg_perm;
@@ -2044,7 +2126,7 @@ static abi_long do_ipc(unsigned int call, int first,
 
     switch (call) {
     case IPCOP_semop:
-        ret = get_errno(semop(first,(struct sembuf *)g2h(ptr), second));
+        ret = do_semop(first, ptr, second);
         break;
 
     case IPCOP_semget:
@@ -2052,12 +2134,7 @@ static abi_long do_ipc(unsigned int call, int first,
         break;
 
     case IPCOP_semctl:
-        ret = do_semctl(first, second, third, ptr);
-        break;
-
-    case IPCOP_semtimedop:
-        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
-        ret = -TARGET_ENOSYS;
+        ret = do_semctl(first, second, third, (union target_semun)(abi_ulong) ptr);
         break;
 
     case IPCOP_msgget:
-- 
1.5.6.5.GIT

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH, v2] Implement sem* syscalls
  2008-10-08 18:54         ` [Qemu-devel] [PATCH] Implement sem* syscalls Kirill A. Shutemov
  2008-10-08 18:54           ` [Qemu-devel] [PATCH] Fix and cleanup IPCOP_shm* ipc calls handling Kirill A. Shutemov
@ 2008-10-09 17:42           ` Kirill A. Shutemov
  1 sibling, 0 replies; 17+ messages in thread
From: Kirill A. Shutemov @ 2008-10-09 17:42 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kirill A. Shutemov

Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
---
 linux-user/syscall.c |   16 +++++++++++++++-
 1 files changed, 15 insertions(+), 1 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 1852f35..1a09d90 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4906,7 +4906,21 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 	ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
 	break;
 #endif
-
+#ifdef TARGET_NR_semget
+    case TARGET_NR_semget:
+        ret = get_errno(semget(arg1, arg2, arg3));
+        break;
+#endif
+#ifdef TARGET_NR_semop
+    case TARGET_NR_semop:
+        ret = get_errno(do_semop(arg1, arg2, arg3));
+        break;
+#endif
+#ifdef TARGET_NR_semctl
+    case TARGET_NR_semctl:
+        ret = do_semctl(arg1, arg2, arg3, (union target_semun)(abi_ulong)arg4);
+        break;
+#endif
 #ifdef TARGET_NR_msgctl
     case TARGET_NR_msgctl:
         ret = do_msgctl(arg1, arg2, arg3);
-- 
1.5.6.5.GIT

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH] Fix fstatat64()/newfstatat() syscall implementation
  2008-10-13 10:10             ` [Qemu-devel] [PATCH] Implement shm* syscalls Kirill A. Shutemov
@ 2008-10-13 10:10               ` Kirill A. Shutemov
  0 siblings, 0 replies; 17+ messages in thread
From: Kirill A. Shutemov @ 2008-10-13 10:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kirill A. Shutemov, Paul Brook

There are two different syscall names for the same goal.

On systems with sizeof(long) == 64 it calls newfstatat.
On systems with sizeof(long) == 32 it calls fstatat64.

Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
---
 linux-user/syscall.c |   29 +++++++++++++++++++++++++----
 1 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index c85fea4..3fa205f 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -165,6 +165,7 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,	\
 #define __NR_sys_linkat __NR_linkat
 #define __NR_sys_mkdirat __NR_mkdirat
 #define __NR_sys_mknodat __NR_mknodat
+#define __NR_sys_newfstatat __NR_newfstatat
 #define __NR_sys_openat __NR_openat
 #define __NR_sys_readlinkat __NR_readlinkat
 #define __NR_sys_renameat __NR_renameat
@@ -205,7 +206,8 @@ _syscall4(int,sys_fchmodat,int,dirfd,const char *,pathname,
 _syscall5(int,sys_fchownat,int,dirfd,const char *,pathname,
           uid_t,owner,gid_t,group,int,flags)
 #endif
-#if defined(TARGET_NR_fstatat64) && defined(__NR_fstatat64)
+#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
+        defined(__NR_fstatat64)
 _syscall4(int,sys_fstatat64,int,dirfd,const char *,pathname,
           struct stat *,buf,int,flags)
 #endif
@@ -236,6 +238,11 @@ _syscall3(int,sys_mkdirat,int,dirfd,const char *,pathname,mode_t,mode)
 _syscall4(int,sys_mknodat,int,dirfd,const char *,pathname,
           mode_t,mode,dev_t,dev)
 #endif
+#if (defined(TARGET_NR_newfstatat) || defined(TARGET_NR_fstatat64) ) && \
+        defined(__NR_newfstatat)
+_syscall4(int,sys_newfstatat,int,dirfd,const char *,pathname,
+          struct stat *,buf,int,flags)
+#endif
 #if defined(TARGET_NR_openat) && defined(__NR_openat)
 _syscall4(int,sys_openat,int,dirfd,const char *,pathname,int,flags,mode_t,mode)
 #endif
@@ -3481,7 +3488,7 @@ static inline abi_long host_to_target_timespec(abi_ulong target_addr,
     return 0;
 }
 
-#ifdef TARGET_NR_stat64
+#if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
 static inline abi_long host_to_target_stat64(void *cpu_env,
                                              abi_ulong target_addr,
                                              struct stat *host_st)
@@ -3513,11 +3520,15 @@ static inline abi_long host_to_target_stat64(void *cpu_env,
     } else
 #endif
     {
+#if TARGET_LONG_BITS == 64
+        struct target_stat *target_st;
+#else
         struct target_stat64 *target_st;
+#endif
 
         if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
             return -TARGET_EFAULT;
-        memset(target_st, 0, sizeof(struct target_stat64));
+        memset(target_st, 0, sizeof(*target_st));
         __put_user(host_st->st_dev, &target_st->st_dev);
         __put_user(host_st->st_ino, &target_st->st_ino);
 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
@@ -5645,11 +5656,21 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             ret = host_to_target_stat64(cpu_env, arg2, &st);
         break;
 #endif
-#if defined(TARGET_NR_fstatat64) && defined(__NR_fstatat64)
+#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
+        (defined(__NR_fstatat64) || defined(__NR_newfstatat))
+#ifdef TARGET_NR_fstatat64
     case TARGET_NR_fstatat64:
+#endif
+#ifdef TARGET_NR_newfstatat
+    case TARGET_NR_newfstatat:
+#endif
         if (!(p = lock_user_string(arg2)))
             goto efault;
+#ifdef __NR_fstatat64
         ret = get_errno(sys_fstatat64(arg1, path(p), &st, arg4));
+#else
+        ret = get_errno(sys_newfstatat(arg1, path(p), &st, arg4));
+#endif
         if (!is_error(ret))
             ret = host_to_target_stat64(cpu_env, arg3, &st);
         break;
-- 
1.5.6.5.GIT

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH] Add readahead syscall
  2008-10-08 18:54 [Qemu-devel] [PATCH] Add readahead syscall Kirill A. Shutemov
  2008-10-08 18:54 ` [Qemu-devel] [PATCH] Fix getdents* syscalls Kirill A. Shutemov
@ 2008-10-13 21:09 ` Aurelien Jarno
  1 sibling, 0 replies; 17+ messages in thread
From: Aurelien Jarno @ 2008-10-13 21:09 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kirill A. Shutemov

Applied, thanks.

On Wed, Oct 08, 2008 at 09:54:25PM +0300, Kirill A. Shutemov wrote:
> Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
> ---
>  linux-user/syscall.c |   15 ++++++++++++++-
>  1 files changed, 14 insertions(+), 1 deletions(-)
> 
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index f1f050e..dc7e561 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -5761,7 +5761,20 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
>          break;
>  #ifdef TARGET_NR_readahead
>      case TARGET_NR_readahead:
> -        goto unimplemented;
> +#if TARGET_ABI_BITS == 32
> +#ifdef TARGET_ARM
> +        if (((CPUARMState *)cpu_env)->eabi)
> +        {
> +            arg2 = arg3;
> +            arg3 = arg4;
> +            arg4 = arg5;
> +        }
> +#endif
> +        ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
> +#else
> +        ret = get_errno(readahead(arg1, arg2, arg3));
> +#endif
> +        break;
>  #endif
>  #ifdef TARGET_NR_setxattr
>      case TARGET_NR_setxattr:
> -- 
> 1.5.6.5.GIT
> 
> 
> 
> 

-- 
  .''`.  Aurelien Jarno	            | GPG: 1024D/F1BCDB73
 : :' :  Debian developer           | Electrical Engineer
 `. `'   aurel32@debian.org         | aurelien@aurel32.net
   `-    people.debian.org/~aurel32 | www.aurel32.net

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH] Fix getdents* syscalls
  2008-10-08 18:54 ` [Qemu-devel] [PATCH] Fix getdents* syscalls Kirill A. Shutemov
  2008-10-08 18:54   ` [Qemu-devel] [PATCH] Fix and cleanup IPCOP_msg* ipc calls handling Kirill A. Shutemov
@ 2008-10-13 21:09   ` Aurelien Jarno
  1 sibling, 0 replies; 17+ messages in thread
From: Aurelien Jarno @ 2008-10-13 21:09 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kirill A. Shutemov

Applied, thanks.

On Wed, Oct 08, 2008 at 09:54:26PM +0300, Kirill A. Shutemov wrote:
> glibc's structs dirent and dirent64 is different from in-kernel dirent
> and dirent64. Kernel headers doesn't provide structs dirent(64) any
> more. So we should add it to qemu headers.
> 
> To avoid conflict with glibc it called struct linux_dirent(64).
> 
> Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
> ---
>  linux-user/syscall.c      |   27 +++++++++++++--------------
>  linux-user/syscall_defs.h |   15 +++++++++++++++
>  2 files changed, 28 insertions(+), 14 deletions(-)
> 
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index dc7e561..40e985a 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -28,7 +28,6 @@
>  #include <fcntl.h>
>  #include <time.h>
>  #include <limits.h>
> -#include <dirent.h>
>  #include <sys/types.h>
>  #include <sys/ipc.h>
>  #include <sys/msg.h>
> @@ -94,8 +93,8 @@
>  #endif
>  
>  //#include <linux/msdos_fs.h>
> -#define	VFAT_IOCTL_READDIR_BOTH		_IOR('r', 1, struct dirent [2])
> -#define	VFAT_IOCTL_READDIR_SHORT	_IOR('r', 2, struct dirent [2])
> +#define	VFAT_IOCTL_READDIR_BOTH		_IOR('r', 1, struct linux_dirent [2])
> +#define	VFAT_IOCTL_READDIR_SHORT	_IOR('r', 2, struct linux_dirent [2])
>  
>  
>  #undef _syscall0
> @@ -216,10 +215,10 @@ _syscall3(int,sys_futimesat,int,dirfd,const char *,pathname,
>  #endif
>  _syscall2(int,sys_getcwd1,char *,buf,size_t,size)
>  #if TARGET_ABI_BITS == 32
> -_syscall3(int, sys_getdents, uint, fd, struct dirent *, dirp, uint, count);
> +_syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
>  #endif
>  #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
> -_syscall3(int, sys_getdents64, uint, fd, struct dirent64 *, dirp, uint, count);
> +_syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
>  #endif
>  _syscall2(int, sys_getpriority, int, which, int, who);
>  #if !defined (__x86_64__)
> @@ -4879,7 +4878,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
>  #elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
>          {
>              struct target_dirent *target_dirp;
> -            struct dirent *dirp;
> +            struct linux_dirent *dirp;
>              abi_long count = arg3;
>  
>  	    dirp = malloc(count);
> @@ -4890,7 +4889,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
>  
>              ret = get_errno(sys_getdents(arg1, dirp, count));
>              if (!is_error(ret)) {
> -                struct dirent *de;
> +                struct linux_dirent *de;
>  		struct target_dirent *tde;
>                  int len = ret;
>                  int reclen, treclen;
> @@ -4912,7 +4911,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
>                          tnamelen = 256;
>                      /* XXX: may not be correct */
>  		    strncpy(tde->d_name, de->d_name, tnamelen);
> -                    de = (struct dirent *)((char *)de + reclen);
> +                    de = (struct linux_dirent *)((char *)de + reclen);
>                      len -= reclen;
>                      tde = (struct target_dirent *)((char *)tde + treclen);
>  		    count1 += treclen;
> @@ -4924,14 +4923,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
>          }
>  #else
>          {
> -            struct dirent *dirp;
> +            struct linux_dirent *dirp;
>              abi_long count = arg3;
>  
>              if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
>                  goto efault;
>              ret = get_errno(sys_getdents(arg1, dirp, count));
>              if (!is_error(ret)) {
> -                struct dirent *de;
> +                struct linux_dirent *de;
>                  int len = ret;
>                  int reclen;
>                  de = dirp;
> @@ -4942,7 +4941,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
>                      de->d_reclen = tswap16(reclen);
>                      tswapls(&de->d_ino);
>                      tswapls(&de->d_off);
> -                    de = (struct dirent *)((char *)de + reclen);
> +                    de = (struct linux_dirent *)((char *)de + reclen);
>                      len -= reclen;
>                  }
>              }
> @@ -4953,13 +4952,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
>  #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
>      case TARGET_NR_getdents64:
>          {
> -            struct dirent64 *dirp;
> +            struct linux_dirent64 *dirp;
>              abi_long count = arg3;
>              if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
>                  goto efault;
>              ret = get_errno(sys_getdents64(arg1, dirp, count));
>              if (!is_error(ret)) {
> -                struct dirent64 *de;
> +                struct linux_dirent64 *de;
>                  int len = ret;
>                  int reclen;
>                  de = dirp;
> @@ -4970,7 +4969,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
>                      de->d_reclen = tswap16(reclen);
>                      tswap64s((uint64_t *)&de->d_ino);
>                      tswap64s((uint64_t *)&de->d_off);
> -                    de = (struct dirent64 *)((char *)de + reclen);
> +                    de = (struct linux_dirent64 *)((char *)de + reclen);
>                      len -= reclen;
>                  }
>              }
> diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
> index c30bb15..5a58010 100644
> --- a/linux-user/syscall_defs.h
> +++ b/linux-user/syscall_defs.h
> @@ -1963,6 +1963,21 @@ struct target_sysinfo {
>      char _f[20-2*sizeof(abi_long)-sizeof(int)]; /* Padding: libc5 uses this.. */
>  };
>  
> +struct linux_dirent {
> +    long            d_ino;
> +    unsigned long   d_off;
> +    unsigned short  d_reclen;
> +    char            d_name[256]; /* We must not include limits.h! */
> +};
> +
> +struct linux_dirent64 {
> +    uint64_t        d_ino;
> +    int64_t         d_off;
> +    unsigned short  d_reclen;
> +    unsigned char   d_type;
> +    char            d_name[256];
> +};
> +
>  #include "socket.h"
>  
>  #include "errno_defs.h"
> -- 
> 1.5.6.5.GIT
> 
> 
> 
> 

-- 
  .''`.  Aurelien Jarno	            | GPG: 1024D/F1BCDB73
 : :' :  Debian developer           | Electrical Engineer
 `. `'   aurel32@debian.org         | aurelien@aurel32.net
   `-    people.debian.org/~aurel32 | www.aurel32.net

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH] Fix fstatat64()/newfstatat() syscall implementation
  2008-12-03 11:29 [Qemu-devel] [PATCH] Introduce --enable-binfmt-misc configure option Kirill A. Shutemov
@ 2008-12-03 11:29 ` Kirill A. Shutemov
  0 siblings, 0 replies; 17+ messages in thread
From: Kirill A. Shutemov @ 2008-12-03 11:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kirill A. Shutemov

There are two different syscall names for the same goal.

On systems with sizeof(long) == 64 it calls newfstatat.
On systems with sizeof(long) == 32 it calls fstatat64.

Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
---
 linux-user/syscall.c |   29 +++++++++++++++++++++++++----
 1 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 4065917..dc65a77 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -169,6 +169,7 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,	\
 #define __NR_sys_linkat __NR_linkat
 #define __NR_sys_mkdirat __NR_mkdirat
 #define __NR_sys_mknodat __NR_mknodat
+#define __NR_sys_newfstatat __NR_newfstatat
 #define __NR_sys_openat __NR_openat
 #define __NR_sys_readlinkat __NR_readlinkat
 #define __NR_sys_renameat __NR_renameat
@@ -210,7 +211,8 @@ _syscall4(int,sys_fchmodat,int,dirfd,const char *,pathname,
 _syscall5(int,sys_fchownat,int,dirfd,const char *,pathname,
           uid_t,owner,gid_t,group,int,flags)
 #endif
-#if defined(TARGET_NR_fstatat64) && defined(__NR_fstatat64)
+#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
+        defined(__NR_fstatat64)
 _syscall4(int,sys_fstatat64,int,dirfd,const char *,pathname,
           struct stat *,buf,int,flags)
 #endif
@@ -241,6 +243,11 @@ _syscall3(int,sys_mkdirat,int,dirfd,const char *,pathname,mode_t,mode)
 _syscall4(int,sys_mknodat,int,dirfd,const char *,pathname,
           mode_t,mode,dev_t,dev)
 #endif
+#if (defined(TARGET_NR_newfstatat) || defined(TARGET_NR_fstatat64) ) && \
+        defined(__NR_newfstatat)
+_syscall4(int,sys_newfstatat,int,dirfd,const char *,pathname,
+          struct stat *,buf,int,flags)
+#endif
 #if defined(TARGET_NR_openat) && defined(__NR_openat)
 _syscall4(int,sys_openat,int,dirfd,const char *,pathname,int,flags,mode_t,mode)
 #endif
@@ -3246,7 +3253,7 @@ static inline abi_long host_to_target_timespec(abi_ulong target_addr,
     return 0;
 }
 
-#ifdef TARGET_NR_stat64
+#if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
 static inline abi_long host_to_target_stat64(void *cpu_env,
                                              abi_ulong target_addr,
                                              struct stat *host_st)
@@ -3278,11 +3285,15 @@ static inline abi_long host_to_target_stat64(void *cpu_env,
     } else
 #endif
     {
+#if TARGET_LONG_BITS == 64
+        struct target_stat *target_st;
+#else
         struct target_stat64 *target_st;
+#endif
 
         if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
             return -TARGET_EFAULT;
-        memset(target_st, 0, sizeof(struct target_stat64));
+        memset(target_st, 0, sizeof(*target_st));
         __put_user(host_st->st_dev, &target_st->st_dev);
         __put_user(host_st->st_ino, &target_st->st_ino);
 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
@@ -5373,11 +5384,21 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             ret = host_to_target_stat64(cpu_env, arg2, &st);
         break;
 #endif
-#if defined(TARGET_NR_fstatat64) && defined(__NR_fstatat64)
+#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
+        (defined(__NR_fstatat64) || defined(__NR_newfstatat))
+#ifdef TARGET_NR_fstatat64
     case TARGET_NR_fstatat64:
+#endif
+#ifdef TARGET_NR_newfstatat
+    case TARGET_NR_newfstatat:
+#endif
         if (!(p = lock_user_string(arg2)))
             goto efault;
+#ifdef __NR_fstatat64
         ret = get_errno(sys_fstatat64(arg1, path(p), &st, arg4));
+#else
+        ret = get_errno(sys_newfstatat(arg1, path(p), &st, arg4));
+#endif
         if (!is_error(ret))
             ret = host_to_target_stat64(cpu_env, arg3, &st);
         break;
-- 
1.6.0.2.GIT

^ permalink raw reply related	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2008-12-03 11:28 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-10-08 18:54 [Qemu-devel] [PATCH] Add readahead syscall Kirill A. Shutemov
2008-10-08 18:54 ` [Qemu-devel] [PATCH] Fix getdents* syscalls Kirill A. Shutemov
2008-10-08 18:54   ` [Qemu-devel] [PATCH] Fix and cleanup IPCOP_msg* ipc calls handling Kirill A. Shutemov
2008-10-08 18:54     ` [Qemu-devel] [PATCH] Implement msg* syscalls Kirill A. Shutemov
2008-10-08 18:54       ` [Qemu-devel] [PATCH] Fix and cleanup IPCOP_sem* ipc calls handling Kirill A. Shutemov
2008-10-08 18:54         ` [Qemu-devel] [PATCH] Implement sem* syscalls Kirill A. Shutemov
2008-10-08 18:54           ` [Qemu-devel] [PATCH] Fix and cleanup IPCOP_shm* ipc calls handling Kirill A. Shutemov
2008-10-08 18:54             ` [Qemu-devel] [PATCH] Implement shm* syscalls Kirill A. Shutemov
2008-10-08 18:54               ` [Qemu-devel] [PATCH] Fix fstatat64()/newfstatat() syscall implementation Kirill A. Shutemov
2008-10-08 18:54                 ` [Qemu-devel] [PATCH] Introduce --enable-binfmt-misc configure option Kirill A. Shutemov
2008-10-09 17:40                 ` [Qemu-devel] [PATCH, v2] Fix fstatat64()/newfstatat() syscall implementation Kirill A. Shutemov
2008-10-09 17:42           ` [Qemu-devel] [PATCH, v2] Implement sem* syscalls Kirill A. Shutemov
2008-10-09 17:41         ` [Qemu-devel] [PATCH, v2] Fix and cleanup IPCOP_sem* ipc calls handling Kirill A. Shutemov
2008-10-13 21:09   ` [Qemu-devel] [PATCH] Fix getdents* syscalls Aurelien Jarno
2008-10-13 21:09 ` [Qemu-devel] [PATCH] Add readahead syscall Aurelien Jarno
  -- strict thread matches above, loose matches on Subject: below --
2008-10-13 10:10 Kirill A. Shutemov
2008-10-13 10:10 ` [Qemu-devel] [PATCH] Fix getdents* syscalls Kirill A. Shutemov
2008-10-13 10:10   ` [Qemu-devel] [PATCH] Fix and cleanup IPCOP_msg* ipc calls handling Kirill A. Shutemov
2008-10-13 10:10     ` [Qemu-devel] [PATCH] Implement msg* syscalls Kirill A. Shutemov
2008-10-13 10:10       ` [Qemu-devel] [PATCH] Fix and cleanup IPCOP_sem* ipc calls handling Kirill A. Shutemov
2008-10-13 10:10         ` [Qemu-devel] [PATCH] Implement sem* syscalls Kirill A. Shutemov
2008-10-13 10:10           ` [Qemu-devel] [PATCH] Fix and cleanup IPCOP_shm* ipc calls handling Kirill A. Shutemov
2008-10-13 10:10             ` [Qemu-devel] [PATCH] Implement shm* syscalls Kirill A. Shutemov
2008-10-13 10:10               ` [Qemu-devel] [PATCH] Fix fstatat64()/newfstatat() syscall implementation Kirill A. Shutemov
2008-12-03 11:29 [Qemu-devel] [PATCH] Introduce --enable-binfmt-misc configure option Kirill A. Shutemov
2008-12-03 11:29 ` [Qemu-devel] [PATCH] Fix fstatat64()/newfstatat() syscall implementation Kirill A. Shutemov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).