File qemu-cvs-ipc.patch of Package qemu

Index: qemu/linux-user/syscall.c
================================================================================
--- qemu-0.10.1/linux-user/syscall.c
+++ qemu-0.10.1/linux-user/syscall.c
@@ -29,7 +29,7 @@
 #include <fcntl.h>
 #include <time.h>
 #include <limits.h>
-#include <sys/types.h>
+#include <linux/types.h>
 #include <sys/ipc.h>
 #include <sys/msg.h>
 #include <sys/wait.h>
@@ -46,6 +46,9 @@
 #include <sys/uio.h>
 #include <sys/poll.h>
 #include <sys/times.h>
+#include <asm/ipcbuf.h>
+#include <asm/shmbuf.h>
+#include <asm/sembuf.h>
 #include <sys/shm.h>
 #include <sys/sem.h>
 #include <sys/statfs.h>
@@ -158,6 +161,7 @@
 
 #define __NR_sys_exit __NR_exit
 #define __NR_sys_sched_getaffinity __NR_sched_getaffinity
+#define __NR_sys_ipc __NR_ipc
 #define __NR_sys_uname __NR_uname
 #define __NR_sys_faccessat __NR_faccessat
 #define __NR_sys_fchmodat __NR_fchmodat
@@ -266,6 +270,10 @@
 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
 _syscall2(int,sys_tkill,int,tid,int,sig)
 #endif
+#ifdef __NR_ipc
+_syscall6(int,sys_ipc, long, call, long, first, long, second, long, third, void *, ptr, long, fifth)
+#define semctl(a,b,c,d) sys_ipc(IPCOP_semctl,a,b,c,&d,0l)
+#endif
 #ifdef __NR_sys_sched_getaffinity
 _syscall3(int,sys_sched_getaffinity,pid_t,pid,unsigned int,cpusetsize,void*,mask)
 #endif
@@ -1687,6 +1695,18 @@
   abi_ulong __unused4;
 };
 
+struct target_semid64_ds
+{
+  struct target_ipc64_perm sem_perm;
+  target_ulong sem_otime;
+  target_ulong __unused1;
+  target_ulong sem_ctime;
+  target_ulong __unused2;
+  target_ulong sem_nsems;
+  target_ulong __unused3;
+  target_ulong __unused4;
+};
+
 static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
                                                abi_ulong target_addr)
 {
@@ -1725,6 +1745,43 @@
     return 0;
 }
 
+static inline abi_long target_to_host_ipc64_perm( struct ipc64_perm *host_ip, target_ulong target_addr )
+{
+    struct target_ipc64_perm *target_ip;
+    struct target_semid64_ds *target_sd;
+
+    lock_user_struct(VERIFY_READ, target_sd, target_addr, 1);
+    target_ip=&(target_sd->sem_perm);
+    host_ip->key = tswapl(target_ip->key);
+    host_ip->uid = tswapl(target_ip->uid);
+    host_ip->gid = tswapl(target_ip->gid);
+    host_ip->cuid = tswapl(target_ip->cuid);
+    host_ip->cgid = tswapl(target_ip->cgid);
+    host_ip->mode = tswap16(target_ip->mode);
+    host_ip->seq = tswap16(target_ip->seq);
+    unlock_user_struct(target_sd, target_addr, 1);
+    return 0;
+}
+
+static inline abi_long host_to_target_ipc64_perm(target_ulong target_addr,
+                                           struct ipc64_perm *host_ip)
+{
+    struct target_ipc64_perm *target_ip;
+    struct target_semid64_ds *target_sd;
+
+    lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0);
+    target_ip = &(target_sd->sem_perm);
+    target_ip->key = tswapl(host_ip->key);
+    target_ip->uid = tswapl(host_ip->uid);
+    target_ip->gid = tswapl(host_ip->gid);
+    target_ip->cuid = tswapl(host_ip->cuid);
+    target_ip->cgid = tswapl(host_ip->cgid);
+    target_ip->mode = tswap16(host_ip->mode);
+    target_ip->seq = tswap16(host_ip->seq);
+    unlock_user_struct(target_sd, target_addr, 1);
+    return 0;
+}
+
 static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
                                                abi_ulong target_addr)
 {
@@ -1755,6 +1812,32 @@
     return 0;
 }
 
+static inline void target_to_host_semid64_ds(struct semid64_ds *host_sd,
+                                          target_ulong target_addr)
+{
+    struct target_semid64_ds *target_sd;
+
+    lock_user_struct(VERIFY_READ, target_sd, target_addr, 1);
+    target_to_host_ipc64_perm(&(host_sd->sem_perm),target_addr);
+    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);
+    unlock_user_struct(target_sd, target_addr, 0);
+}
+
+static inline void host_to_target_semid64_ds(target_ulong target_addr,
+                                           struct semid64_ds *host_sd)
+{
+    struct target_semid64_ds *target_sd;
+
+    lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0);
+    host_to_target_ipc64_perm(target_addr,&(host_sd->sem_perm));
+    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);
+    unlock_user_struct(target_sd, target_addr, 1);
+}
+
 union semun {
 	int val;
 	struct semid_ds *buf;
@@ -1767,6 +1850,10 @@
 	unsigned short int *array;
 };
 
+#ifndef IPC_64
+#define IPC_64 0x100
+#endif
+
 static inline abi_long target_to_host_semun(int cmd,
                                             union semun *host_su,
                                             abi_ulong target_addr,
@@ -1779,7 +1866,15 @@
 	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);
+	   target_to_host_semid_ds(ds,tswapl(target_su->buf));
+	   host_su->buf = ds;
+           unlock_user_struct(target_su, target_addr, 0);
+	   break;
+	case IPC_STAT + IPC_64:
+	case IPC_SET + IPC_64:
+           if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
+               return -TARGET_EFAULT;
+	   target_to_host_semid64_ds((struct semid64_ds*)ds,tswapl(target_su->buf));
 	   host_su->buf = ds;
            unlock_user_struct(target_su, target_addr, 0);
 	   break;
@@ -1815,7 +1910,14 @@
 	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);
+	   host_to_target_semid_ds(tswapl(target_su->buf),ds);
+           unlock_user_struct(target_su, target_addr, 1);
+	   break;
+	case IPC_STAT + IPC_64:
+	case IPC_SET + IPC_64:
+           if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
+               return -TARGET_EFAULT;
+	   host_to_target_semid64_ds(tswapl(target_su->buf),(struct semid64_ds*)ds);
            unlock_user_struct(target_su, target_addr, 1);
 	   break;
 	case GETVAL:
@@ -1843,7 +1945,8 @@
 {
     union semun arg;
     struct semid_ds dsarg;
-    int cmd = third&0xff;
+    struct semid64_ds dsarg64;
+    int cmd = third; // &0xff;
     abi_long ret = 0;
 
     switch( cmd ) {
@@ -1872,13 +1975,23 @@
             ret = get_errno(semctl(first, second, cmd, arg));
             host_to_target_semun(cmd,ptr,&arg,&dsarg);
             break;
+	case IPC_STAT + IPC_64:
+            target_to_host_semun(cmd,&arg,ptr,(struct semid_ds *)&dsarg64);
+            ret = get_errno(semctl(first, second, cmd, arg));
+            host_to_target_semun(cmd,ptr,&arg,(struct semid_ds *)&dsarg64);
+            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:
+	case IPC_SET + IPC_64:
+            target_to_host_semun(cmd,&arg,ptr,(struct semid_ds *)&dsarg64);
             ret = get_errno(semctl(first, second, cmd, arg));
+            host_to_target_semun(cmd,ptr,&arg,(struct semid_ds *)&dsarg64);
+            break;
+    default:
+            ret = get_errno(semctl(first, second, cmd & 0xff, arg));
     }
 
     return ret;
@@ -1908,6 +2021,41 @@
     abi_ulong __unused5;
 };
 
+struct target_shmid64_ds {
+	struct target_ipc64_perm shm_perm;	/* operation perms */
+	target_ulong		shm_segsz;	/* size of segment (bytes) */
+	target_ulong		shm_atime;	/* last attach time */
+	target_ulong		__unused1;
+	target_ulong		shm_dtime;	/* last detach time */
+	target_ulong		__unused2;
+	target_ulong		shm_ctime;	/* last change time */
+	target_ulong		__unused3;
+	int32_t			shm_cpid;	/* pid of creator */
+	int32_t			shm_lpid;	/* pid of last operator */
+	target_ulong		shm_nattch;	/* no. of current attaches */
+	target_ulong		__unused4;
+	target_ulong		__unused5;
+};
+
+/* Data structure describing a set of semaphores.  */
+struct target_shmid_ds
+  {
+    struct target_ipc_perm shm_perm;          /* operation permission struct */
+    unsigned int __unused1;
+    target_ulong shm_atime;                        /* time of last shmat() */
+    unsigned int __unused2;
+    target_ulong shm_dtime;                        /* time of last shmdt() */
+    unsigned int __unused3;
+    target_ulong shm_ctime;			/* time of last change by shmctl() */
+    unsigned int __unused4;
+    target_ulong shm_segsz;                  /* size of segment in bytes */
+    unsigned int shm_cpid;                  /* pid of creator */
+    unsigned int shm_lpid;                  /* pid of last shmop */
+    target_ulong shm_nattch;               /* number of current attaches */
+    unsigned long __unused5;
+    unsigned long __unused6;
+  };
+
 static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
                                                abi_ulong target_addr)
 {
@@ -2193,11 +2341,59 @@
     case IPCOP_shmctl:
         switch(second) {
         case IPC_RMID:
+	case IPC_RMID + IPC_64:
         case SHM_LOCK:
+	case SHM_LOCK + IPC_64:
         case SHM_UNLOCK:
+	case SHM_UNLOCK + IPC_64:
             ret = get_errno(shmctl(first, second, NULL));
             break;
+	case IPC_STAT + IPC_64:
+	{
+	    struct shmid64_ds buf;
+	    struct target_shmid64_ds *target_buf;
+#ifdef DEBUG
+	    gemu_log("qemu: doing IPC_STAT\n");
+#endif
+	    lock_user_struct(VERIFY_WRITE, target_buf, ptr, 1); 
+	    ret = get_errno(shmctl(first, second, (struct shmid_ds*)&buf));
+	    
+	    host_to_target_ipc64_perm(ptr, &buf.shm_perm);
+	    target_buf->shm_atime  = tswapl(buf.shm_atime);
+	    target_buf->shm_dtime  = tswapl(buf.shm_dtime);
+	    target_buf->shm_ctime  = tswapl(buf.shm_ctime);
+	    target_buf->shm_segsz  = tswapl(buf.shm_segsz);
+	    target_buf->shm_cpid   = tswap32(buf.shm_cpid);
+	    target_buf->shm_lpid   = tswap32(buf.shm_lpid);
+	    target_buf->shm_nattch = tswapl(buf.shm_nattch);
+	    unlock_user_struct(target_buf, ptr, 0);
+	    break;
+	}
+	case IPC_SET + IPC_64:
+	{
+	    struct shmid64_ds buf;
+	    struct target_shmid64_ds *target_buf;
+#ifdef DEBUG
+	    gemu_log("qemu: doing IPC_SET\n");
+#endif
+	    lock_user_struct(VERIFY_READ, target_buf, ptr, 1); 
+
+	    target_to_host_ipc64_perm(&buf.shm_perm, ptr);
+	    buf.shm_atime  = tswapl(target_buf->shm_atime);
+	    buf.shm_dtime  = tswapl(target_buf->shm_dtime);
+	    buf.shm_ctime  = tswapl(target_buf->shm_ctime);
+	    buf.shm_segsz  = tswapl(target_buf->shm_segsz);
+	    buf.shm_cpid   = tswap32(target_buf->shm_cpid);
+	    buf.shm_lpid   = tswap32(target_buf->shm_lpid);
+	    buf.shm_nattch = tswapl(target_buf->shm_nattch);
+
+	    ret = get_errno(shmctl(first, second, (struct shmid_ds*)&buf));
+	    
+	    unlock_user_struct(target_buf, ptr, 0);
+	    break;
+	}
         default:
+	    gemu_log("Unsopported shmctl(%ld,%#lx)\n", second, second);
             goto unimplemented;
         }
         break;
--- qemu-0.10.1/linux-user/syscall_defs.h
+++ qemu-0.10.1/linux-user/syscall_defs.h
@@ -2001,3 +2001,18 @@
 #include "socket.h"
 
 #include "errno_defs.h"
+
+struct target_ipc64_perm
+{
+	int		key;
+	uint32_t	uid;
+	uint32_t	gid;
+	uint32_t	cuid;
+	uint32_t	cgid;
+	unsigned short		mode;
+	unsigned short		__pad1;
+	unsigned short		seq;
+	unsigned short		__pad2;
+	abi_ulong		__unused1;
+	abi_ulong		__unused2;
+};
--- qemu-0.10.1/linux-user/x86_64/syscall.h
+++ qemu-0.10.1/linux-user/x86_64/syscall.h
@@ -61,21 +61,6 @@
 };
 #endif
 
-struct target_ipc64_perm
-{
-	int		key;
-	uint32_t	uid;
-	uint32_t	gid;
-	uint32_t	cuid;
-	uint32_t	cgid;
-	unsigned short		mode;
-	unsigned short		__pad1;
-	unsigned short		seq;
-	unsigned short		__pad2;
-	abi_ulong		__unused1;
-	abi_ulong		__unused2;
-};
-
 struct target_msqid64_ds {
 	struct target_ipc64_perm msg_perm;
 	unsigned int msg_stime;	/* last msgsnd time */
openSUSE Build Service is sponsored by