Search
j0ke.net Open Build Service
>
Projects
>
virtualization
:
Qemu
>
qemu
> qemu-cvs-ipc.patch
Sign Up
|
Log In
Username
Password
Cancel
Overview
Repositories
Revisions
Requests
Users
Advanced
Attributes
Meta
File qemu-cvs-ipc.patch of Package qemu (Revision 12)
Currently displaying revision
12
,
show latest
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 */