qemu/qemu-cvs-ipc.patch

365 lines
12 KiB
Diff

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 */