* [Qemu-devel] [PATCH] linux-user semaphore structure mapping
@ 2007-05-30 2:35 Stuart Anderson
2007-06-01 11:59 ` Thiemo Seufer
0 siblings, 1 reply; 4+ messages in thread
From: Stuart Anderson @ 2007-05-30 2:35 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: TEXT/PLAIN, Size: 595 bytes --]
This is a refresh (vs 5/28 cvs) of a patch sent several weeks ago. This
patch implments the structure handling for the semaphore IPC related
structures used by semctl().
This was tested using LTP on an ARM target.
Were there any objections to this patch?
Stuart
Stuart R. Anderson anderson@netsweng.com
Network & Software Engineering http://www.netsweng.com/
1024D/37A79149: 0791 D3B8 9A4C 2CDC A31F
BD03 0A62 E534 37A7 9149
[-- Attachment #2: semctl() patch --]
[-- Type: TEXT/x-diff, Size: 12372 bytes --]
Index: qemu/linux-user/i386/syscall.h
===================================================================
--- qemu.orig/linux-user/i386/syscall.h 2007-03-23 09:05:19.000000000 -0400
+++ qemu/linux-user/i386/syscall.h 2007-03-23 09:05:32.000000000 -0400
@@ -142,80 +142,4 @@
struct target_vm86plus_info_struct vm86plus;
};
-/* ipcs */
-
-#define TARGET_SEMOP 1
-#define TARGET_SEMGET 2
-#define TARGET_SEMCTL 3
-#define TARGET_MSGSND 11
-#define TARGET_MSGRCV 12
-#define TARGET_MSGGET 13
-#define TARGET_MSGCTL 14
-#define TARGET_SHMAT 21
-#define TARGET_SHMDT 22
-#define TARGET_SHMGET 23
-#define TARGET_SHMCTL 24
-
-struct target_msgbuf {
- int mtype;
- char mtext[1];
-};
-
-struct target_ipc_kludge {
- unsigned int msgp; /* Really (struct msgbuf *) */
- int msgtyp;
-};
-
-struct target_ipc_perm {
- int key;
- unsigned short uid;
- unsigned short gid;
- unsigned short cuid;
- unsigned short cgid;
- unsigned short mode;
- unsigned short seq;
-};
-
-struct target_msqid_ds {
- struct target_ipc_perm msg_perm;
- unsigned int msg_first; /* really struct target_msg* */
- unsigned int msg_last; /* really struct target_msg* */
- unsigned int msg_stime; /* really target_time_t */
- unsigned int msg_rtime; /* really target_time_t */
- unsigned int msg_ctime; /* really target_time_t */
- unsigned int wwait; /* really struct wait_queue* */
- unsigned int rwait; /* really struct wait_queue* */
- unsigned short msg_cbytes;
- unsigned short msg_qnum;
- unsigned short msg_qbytes;
- unsigned short msg_lspid;
- unsigned short msg_lrpid;
-};
-
-struct target_shmid_ds {
- struct target_ipc_perm shm_perm;
- int shm_segsz;
- unsigned int shm_atime; /* really target_time_t */
- unsigned int shm_dtime; /* really target_time_t */
- unsigned int shm_ctime; /* really target_time_t */
- unsigned short shm_cpid;
- unsigned short shm_lpid;
- short shm_nattch;
- unsigned short shm_npages;
- unsigned long *shm_pages;
- void *attaches; /* really struct shm_desc * */
-};
-
-#define TARGET_IPC_RMID 0
-#define TARGET_IPC_SET 1
-#define TARGET_IPC_STAT 2
-
-union target_semun {
- int val;
- unsigned int buf; /* really struct semid_ds * */
- unsigned int array; /* really unsigned short * */
- unsigned int __buf; /* really struct seminfo * */
- unsigned int __pad; /* really void* */
-};
-
#define UNAME_MACHINE "i686"
Index: qemu/linux-user/ppc/syscall.h
===================================================================
--- qemu.orig/linux-user/ppc/syscall.h 2007-03-23 09:05:19.000000000 -0400
+++ qemu/linux-user/ppc/syscall.h 2007-03-23 09:05:32.000000000 -0400
@@ -51,80 +51,4 @@
* flags masks
*/
-/* ipcs */
-
-#define TARGET_SEMOP 1
-#define TARGET_SEMGET 2
-#define TARGET_SEMCTL 3
-#define TARGET_MSGSND 11
-#define TARGET_MSGRCV 12
-#define TARGET_MSGGET 13
-#define TARGET_MSGCTL 14
-#define TARGET_SHMAT 21
-#define TARGET_SHMDT 22
-#define TARGET_SHMGET 23
-#define TARGET_SHMCTL 24
-
-struct target_msgbuf {
- int mtype;
- char mtext[1];
-};
-
-struct target_ipc_kludge {
- unsigned int msgp; /* Really (struct msgbuf *) */
- int msgtyp;
-};
-
-struct target_ipc_perm {
- int key;
- unsigned short uid;
- unsigned short gid;
- unsigned short cuid;
- unsigned short cgid;
- unsigned short mode;
- unsigned short seq;
-};
-
-struct target_msqid_ds {
- struct target_ipc_perm msg_perm;
- unsigned int msg_first; /* really struct target_msg* */
- unsigned int msg_last; /* really struct target_msg* */
- unsigned int msg_stime; /* really target_time_t */
- unsigned int msg_rtime; /* really target_time_t */
- unsigned int msg_ctime; /* really target_time_t */
- unsigned int wwait; /* really struct wait_queue* */
- unsigned int rwait; /* really struct wait_queue* */
- unsigned short msg_cbytes;
- unsigned short msg_qnum;
- unsigned short msg_qbytes;
- unsigned short msg_lspid;
- unsigned short msg_lrpid;
-};
-
-struct target_shmid_ds {
- struct target_ipc_perm shm_perm;
- int shm_segsz;
- unsigned int shm_atime; /* really target_time_t */
- unsigned int shm_dtime; /* really target_time_t */
- unsigned int shm_ctime; /* really target_time_t */
- unsigned short shm_cpid;
- unsigned short shm_lpid;
- short shm_nattch;
- unsigned short shm_npages;
- unsigned long *shm_pages;
- void *attaches; /* really struct shm_desc * */
-};
-
-#define TARGET_IPC_RMID 0
-#define TARGET_IPC_SET 1
-#define TARGET_IPC_STAT 2
-
-union target_semun {
- int val;
- unsigned int buf; /* really struct semid_ds * */
- unsigned int array; /* really unsigned short * */
- unsigned int __buf; /* really struct seminfo * */
- unsigned int __pad; /* really void* */
-};
-
#define UNAME_MACHINE "ppc"
Index: qemu/linux-user/syscall.c
===================================================================
--- qemu.orig/linux-user/syscall.c 2007-03-23 09:05:19.000000000 -0400
+++ qemu/linux-user/syscall.c 2007-03-23 09:05:49.000000000 -0400
@@ -1123,12 +1123,205 @@
uint32_t size;
} shm_regions[N_SHM_REGIONS];
+struct target_ipc_perm
+{
+ target_long __key;
+ target_ulong uid;
+ target_ulong gid;
+ target_ulong cuid;
+ target_ulong cgid;
+ unsigned short int mode;
+ unsigned short int __pad1;
+ unsigned short int __seq;
+ unsigned short int __pad2;
+ target_ulong __unused1;
+ target_ulong __unused2;
+};
+
+struct target_semid_ds
+{
+ struct target_ipc_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 void target_to_host_ipc_perm(struct ipc_perm *host_ip,
+ target_ulong target_addr)
+{
+ struct target_ipc_perm *target_ip;
+ struct target_semid_ds *target_sd;
+
+ lock_user_struct(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 = tswapl(target_ip->mode);
+ unlock_user_struct(target_sd, target_addr, 0);
+}
+
+static inline void host_to_target_ipc_perm(target_ulong target_addr,
+ struct ipc_perm *host_ip)
+{
+ struct target_ipc_perm *target_ip;
+ struct target_semid_ds *target_sd;
+
+ lock_user_struct(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 = tswapl(host_ip->mode);
+ unlock_user_struct(target_sd, target_addr, 1);
+}
+
+static inline void target_to_host_semid_ds(struct semid_ds *host_sd,
+ target_ulong target_addr)
+{
+ struct target_semid_ds *target_sd;
+
+ lock_user_struct(target_sd, target_addr, 1);
+ target_to_host_ipc_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_semid_ds(target_ulong target_addr,
+ struct semid_ds *host_sd)
+{
+ struct target_semid_ds *target_sd;
+
+ lock_user_struct(target_sd, target_addr, 0);
+ host_to_target_ipc_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 senid_ds *buf;
+ struct semid_ds *buf;
unsigned short *array;
};
+union target_semun {
+ int val;
+ target_long buf;
+ target_long array;
+};
+
+static inline void target_to_host_semun(unsigned long cmd,
+ union semun *host_su,
+ target_ulong target_addr,
+ struct semid_ds *ds)
+{
+ union target_semun *target_su;
+
+ switch( cmd ) {
+ case GETALL:
+ case SETALL:
+ case IPC_STAT:
+ case IPC_SET:
+ lock_user_struct(target_su, target_addr, 1);
+ 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:
+ lock_user_struct(target_su, target_addr, 1);
+ host_su->val = tswapl(target_su->val);
+ unlock_user_struct(target_su, target_addr, 0);
+ break;
+ default:
+ host_su->array = tswapl(target_su->array);
+ }
+}
+
+static inline void host_to_target_semun(unsigned long cmd,
+ target_ulong target_addr,
+ union semun *host_su,
+ struct semid_ds *ds)
+{
+ union target_semun *target_su;
+
+ switch( cmd ) {
+ case GETALL:
+ case SETALL:
+ case IPC_STAT:
+ case IPC_SET:
+ lock_user_struct(target_su, target_addr, 0);
+ host_to_target_semid_ds(target_su->buf,ds);
+ unlock_user_struct(target_su, target_addr, 1);
+ break;
+ case GETVAL:
+ case SETVAL:
+ lock_user_struct(target_su, target_addr, 0);
+ target_su->val = tswapl(host_su->val);
+ unlock_user_struct(target_su, target_addr, 1);
+ break;
+ default:
+ target_su->array = tswapl(host_su->array);
+ }
+}
+
+static inline long do_semctl(long first, long second, long third, long ptr)
+{
+ union semun arg;
+ struct semid_ds dsarg;
+ int cmd = third&0xff;
+ long ret = 0;
+
+ 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));
+ }
+
+ return ret;
+}
+
/* ??? This only works with linear mappings. */
static long do_ipc(long call, long first, long second, long third,
long ptr, long fifth)
@@ -1152,8 +1345,7 @@
break;
case IPCOP_semctl:
- ret = get_errno(semctl(first, second, third, ((union semun*)ptr)->val));
-
+ ret = do_semctl(first, second, third, ptr);
break;
case IPCOP_semtimedop:
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] [PATCH] linux-user semaphore structure mapping
2007-05-30 2:35 [Qemu-devel] [PATCH] linux-user semaphore structure mapping Stuart Anderson
@ 2007-06-01 11:59 ` Thiemo Seufer
2007-06-01 19:19 ` Stuart Anderson
2007-06-02 16:17 ` Stuart Anderson
0 siblings, 2 replies; 4+ messages in thread
From: Thiemo Seufer @ 2007-06-01 11:59 UTC (permalink / raw)
To: Stuart Anderson; +Cc: qemu-devel
Stuart Anderson wrote:
>
> This is a refresh (vs 5/28 cvs) of a patch sent several weeks ago. This
> patch implments the structure handling for the semaphore IPC related
> structures used by semctl().
>
> This was tested using LTP on an ARM target.
>
> Were there any objections to this patch?
It produces too many compiler warnings to be comfortable with, and
breaks compilation of alpha-linux-user.
Thiemo
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] [PATCH] linux-user semaphore structure mapping
2007-06-01 11:59 ` Thiemo Seufer
@ 2007-06-01 19:19 ` Stuart Anderson
2007-06-02 16:17 ` Stuart Anderson
1 sibling, 0 replies; 4+ messages in thread
From: Stuart Anderson @ 2007-06-01 19:19 UTC (permalink / raw)
To: qemu-devel
On Fri, 1 Jun 2007, Thiemo Seufer wrote:
> Stuart Anderson wrote:
>>
>> This is a refresh (vs 5/28 cvs) of a patch sent several weeks ago. This
>> patch implments the structure handling for the semaphore IPC related
>> structures used by semctl().
>>
>> This was tested using LTP on an ARM target.
>>
>> Were there any objections to this patch?
>
> It produces too many compiler warnings to be comfortable with, and
> breaks compilation of alpha-linux-user.
I think alpha was actually added after I first created this patch, and I
haven't been building it as it's not one of the archs I normally use.
Note to self to do a build w/ everything turned on more often. The fix
for it is to remove the same stuff as is done for a couple of the other
archs.
I'll clean it up, and take another look at the warning for this and the
message queue patch, and resubmit.
Stuart
Stuart R. Anderson anderson@netsweng.com
Network & Software Engineering http://www.netsweng.com/
1024D/37A79149: 0791 D3B8 9A4C 2CDC A31F
BD03 0A62 E534 37A7 9149
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] [PATCH] linux-user semaphore structure mapping
2007-06-01 11:59 ` Thiemo Seufer
2007-06-01 19:19 ` Stuart Anderson
@ 2007-06-02 16:17 ` Stuart Anderson
1 sibling, 0 replies; 4+ messages in thread
From: Stuart Anderson @ 2007-06-02 16:17 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: TEXT/PLAIN, Size: 1068 bytes --]
On Fri, 1 Jun 2007, Thiemo Seufer wrote:
> Stuart Anderson wrote:
>>
>> This is a refresh (vs 5/28 cvs) of a patch sent several weeks ago. This
>> patch implments the structure handling for the semaphore IPC related
>> structures used by semctl().
>>
> It produces too many compiler warnings to be comfortable with, and
> breaks compilation of alpha-linux-user.
Thiemo,
I've attached both the semaphore and message queue patches to
this message since there is a dependency between them (message queue patch
must be applied on top of the semaphore patch).
This is updated to 6/01 cvs, and includes the additional part to
fix alpha the same as is done for the other archs. It also cleans up the
warnings in the new code areas.
Stuart
Stuart R. Anderson anderson@netsweng.com
Network & Software Engineering http://www.netsweng.com/
1024D/37A79149: 0791 D3B8 9A4C 2CDC A31F
BD03 0A62 E534 37A7 9149
[-- Attachment #2: semaphore patch --]
[-- Type: TEXT/x-diff, Size: 15327 bytes --]
Index: qemu/linux-user/i386/syscall.h
===================================================================
--- qemu.orig/linux-user/i386/syscall.h 2007-06-01 16:52:07.000000000 -0400
+++ qemu/linux-user/i386/syscall.h 2007-06-01 17:08:29.000000000 -0400
@@ -142,80 +142,4 @@
struct target_vm86plus_info_struct vm86plus;
};
-/* ipcs */
-
-#define TARGET_SEMOP 1
-#define TARGET_SEMGET 2
-#define TARGET_SEMCTL 3
-#define TARGET_MSGSND 11
-#define TARGET_MSGRCV 12
-#define TARGET_MSGGET 13
-#define TARGET_MSGCTL 14
-#define TARGET_SHMAT 21
-#define TARGET_SHMDT 22
-#define TARGET_SHMGET 23
-#define TARGET_SHMCTL 24
-
-struct target_msgbuf {
- int mtype;
- char mtext[1];
-};
-
-struct target_ipc_kludge {
- unsigned int msgp; /* Really (struct msgbuf *) */
- int msgtyp;
-};
-
-struct target_ipc_perm {
- int key;
- unsigned short uid;
- unsigned short gid;
- unsigned short cuid;
- unsigned short cgid;
- unsigned short mode;
- unsigned short seq;
-};
-
-struct target_msqid_ds {
- struct target_ipc_perm msg_perm;
- unsigned int msg_first; /* really struct target_msg* */
- unsigned int msg_last; /* really struct target_msg* */
- unsigned int msg_stime; /* really target_time_t */
- unsigned int msg_rtime; /* really target_time_t */
- unsigned int msg_ctime; /* really target_time_t */
- unsigned int wwait; /* really struct wait_queue* */
- unsigned int rwait; /* really struct wait_queue* */
- unsigned short msg_cbytes;
- unsigned short msg_qnum;
- unsigned short msg_qbytes;
- unsigned short msg_lspid;
- unsigned short msg_lrpid;
-};
-
-struct target_shmid_ds {
- struct target_ipc_perm shm_perm;
- int shm_segsz;
- unsigned int shm_atime; /* really target_time_t */
- unsigned int shm_dtime; /* really target_time_t */
- unsigned int shm_ctime; /* really target_time_t */
- unsigned short shm_cpid;
- unsigned short shm_lpid;
- short shm_nattch;
- unsigned short shm_npages;
- unsigned long *shm_pages;
- void *attaches; /* really struct shm_desc * */
-};
-
-#define TARGET_IPC_RMID 0
-#define TARGET_IPC_SET 1
-#define TARGET_IPC_STAT 2
-
-union target_semun {
- int val;
- unsigned int buf; /* really struct semid_ds * */
- unsigned int array; /* really unsigned short * */
- unsigned int __buf; /* really struct seminfo * */
- unsigned int __pad; /* really void* */
-};
-
#define UNAME_MACHINE "i686"
Index: qemu/linux-user/ppc/syscall.h
===================================================================
--- qemu.orig/linux-user/ppc/syscall.h 2007-06-01 16:52:07.000000000 -0400
+++ qemu/linux-user/ppc/syscall.h 2007-06-01 17:08:29.000000000 -0400
@@ -51,80 +51,4 @@
* flags masks
*/
-/* ipcs */
-
-#define TARGET_SEMOP 1
-#define TARGET_SEMGET 2
-#define TARGET_SEMCTL 3
-#define TARGET_MSGSND 11
-#define TARGET_MSGRCV 12
-#define TARGET_MSGGET 13
-#define TARGET_MSGCTL 14
-#define TARGET_SHMAT 21
-#define TARGET_SHMDT 22
-#define TARGET_SHMGET 23
-#define TARGET_SHMCTL 24
-
-struct target_msgbuf {
- int mtype;
- char mtext[1];
-};
-
-struct target_ipc_kludge {
- unsigned int msgp; /* Really (struct msgbuf *) */
- int msgtyp;
-};
-
-struct target_ipc_perm {
- int key;
- unsigned short uid;
- unsigned short gid;
- unsigned short cuid;
- unsigned short cgid;
- unsigned short mode;
- unsigned short seq;
-};
-
-struct target_msqid_ds {
- struct target_ipc_perm msg_perm;
- unsigned int msg_first; /* really struct target_msg* */
- unsigned int msg_last; /* really struct target_msg* */
- unsigned int msg_stime; /* really target_time_t */
- unsigned int msg_rtime; /* really target_time_t */
- unsigned int msg_ctime; /* really target_time_t */
- unsigned int wwait; /* really struct wait_queue* */
- unsigned int rwait; /* really struct wait_queue* */
- unsigned short msg_cbytes;
- unsigned short msg_qnum;
- unsigned short msg_qbytes;
- unsigned short msg_lspid;
- unsigned short msg_lrpid;
-};
-
-struct target_shmid_ds {
- struct target_ipc_perm shm_perm;
- int shm_segsz;
- unsigned int shm_atime; /* really target_time_t */
- unsigned int shm_dtime; /* really target_time_t */
- unsigned int shm_ctime; /* really target_time_t */
- unsigned short shm_cpid;
- unsigned short shm_lpid;
- short shm_nattch;
- unsigned short shm_npages;
- unsigned long *shm_pages;
- void *attaches; /* really struct shm_desc * */
-};
-
-#define TARGET_IPC_RMID 0
-#define TARGET_IPC_SET 1
-#define TARGET_IPC_STAT 2
-
-union target_semun {
- int val;
- unsigned int buf; /* really struct semid_ds * */
- unsigned int array; /* really unsigned short * */
- unsigned int __buf; /* really struct seminfo * */
- unsigned int __pad; /* really void* */
-};
-
#define UNAME_MACHINE "ppc"
Index: qemu/linux-user/syscall.c
===================================================================
--- qemu.orig/linux-user/syscall.c 2007-06-01 16:57:05.000000000 -0400
+++ qemu/linux-user/syscall.c 2007-06-01 17:08:29.000000000 -0400
@@ -1230,12 +1230,213 @@
uint32_t size;
} shm_regions[N_SHM_REGIONS];
+struct target_ipc_perm
+{
+ target_long __key;
+ target_ulong uid;
+ target_ulong gid;
+ target_ulong cuid;
+ target_ulong cgid;
+ unsigned short int mode;
+ unsigned short int __pad1;
+ unsigned short int __seq;
+ unsigned short int __pad2;
+ target_ulong __unused1;
+ target_ulong __unused2;
+};
+
+struct target_semid_ds
+{
+ struct target_ipc_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 void target_to_host_ipc_perm(struct ipc_perm *host_ip,
+ target_ulong target_addr)
+{
+ struct target_ipc_perm *target_ip;
+ struct target_semid_ds *target_sd;
+
+ lock_user_struct(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 = tswapl(target_ip->mode);
+ unlock_user_struct(target_sd, target_addr, 0);
+}
+
+static inline void host_to_target_ipc_perm(target_ulong target_addr,
+ struct ipc_perm *host_ip)
+{
+ struct target_ipc_perm *target_ip;
+ struct target_semid_ds *target_sd;
+
+ lock_user_struct(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 = tswapl(host_ip->mode);
+ unlock_user_struct(target_sd, target_addr, 1);
+}
+
+static inline void target_to_host_semid_ds(struct semid_ds *host_sd,
+ target_ulong target_addr)
+{
+ struct target_semid_ds *target_sd;
+
+ lock_user_struct(target_sd, target_addr, 1);
+ target_to_host_ipc_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_semid_ds(target_ulong target_addr,
+ struct semid_ds *host_sd)
+{
+ struct target_semid_ds *target_sd;
+
+ lock_user_struct(target_sd, target_addr, 0);
+ host_to_target_ipc_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 senid_ds *buf;
+ struct semid_ds *buf;
unsigned short *array;
};
+union target_semun {
+ int val;
+ target_long buf;
+ unsigned short int *array;
+};
+
+static inline void target_to_host_semun(unsigned long cmd,
+ union semun *host_su,
+ target_ulong target_addr,
+ struct semid_ds *ds)
+{
+ union target_semun *target_su;
+
+ switch( cmd ) {
+ case IPC_STAT:
+ case IPC_SET:
+ lock_user_struct(target_su, target_addr, 1);
+ 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:
+ lock_user_struct(target_su, target_addr, 1);
+ host_su->val = tswapl(target_su->val);
+ unlock_user_struct(target_su, target_addr, 0);
+ break;
+ case GETALL:
+ case SETALL:
+ lock_user_struct(target_su, target_addr, 1);
+ *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);
+ }
+}
+
+static inline void host_to_target_semun(unsigned long cmd,
+ target_ulong target_addr,
+ union semun *host_su,
+ struct semid_ds *ds)
+{
+ union target_semun *target_su;
+
+ switch( cmd ) {
+ case IPC_STAT:
+ case IPC_SET:
+ lock_user_struct(target_su, target_addr, 0);
+ host_to_target_semid_ds(target_su->buf,ds);
+ unlock_user_struct(target_su, target_addr, 1);
+ break;
+ case GETVAL:
+ case SETVAL:
+ lock_user_struct(target_su, target_addr, 0);
+ target_su->val = tswapl(host_su->val);
+ unlock_user_struct(target_su, target_addr, 1);
+ break;
+ case GETALL:
+ case SETALL:
+ lock_user_struct(target_su, target_addr, 0);
+ *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);
+ }
+}
+
+static inline long do_semctl(long first, long second, long third, long ptr)
+{
+ union semun arg;
+ struct semid_ds dsarg;
+ int cmd = third&0xff;
+ long ret = 0;
+
+ 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));
+ }
+
+ return ret;
+}
+
/* ??? This only works with linear mappings. */
static long do_ipc(long call, long first, long second, long third,
long ptr, long fifth)
@@ -1259,8 +1460,7 @@
break;
case IPCOP_semctl:
- ret = get_errno(semctl(first, second, third, ((union semun*)ptr)->val));
-
+ ret = do_semctl(first, second, third, ptr);
break;
case IPCOP_semtimedop:
Index: qemu/linux-user/alpha/syscall.h
===================================================================
--- qemu.orig/linux-user/alpha/syscall.h 2007-06-01 16:52:07.000000000 -0400
+++ qemu/linux-user/alpha/syscall.h 2007-06-01 17:08:29.000000000 -0400
@@ -38,78 +38,4 @@
target_ulong unique;
};
-#define TARGET_SEMOP 1
-#define TARGET_SEMGET 2
-#define TARGET_SEMCTL 3
-#define TARGET_MSGSND 11
-#define TARGET_MSGRCV 12
-#define TARGET_MSGGET 13
-#define TARGET_MSGCTL 14
-#define TARGET_SHMAT 21
-#define TARGET_SHMDT 22
-#define TARGET_SHMGET 23
-#define TARGET_SHMCTL 24
-
-struct target_msgbuf {
- int mtype;
- char mtext[1];
-};
-
-struct target_ipc_kludge {
- unsigned int msgp; /* Really (struct msgbuf *) */
- int msgtyp;
-};
-
-struct target_ipc_perm {
- int key;
- unsigned short uid;
- unsigned short gid;
- unsigned short cuid;
- unsigned short cgid;
- unsigned short mode;
- unsigned short seq;
-};
-
-struct target_msqid_ds {
- struct target_ipc_perm msg_perm;
- unsigned int msg_first; /* really struct target_msg* */
- unsigned int msg_last; /* really struct target_msg* */
- unsigned int msg_stime; /* really target_time_t */
- unsigned int msg_rtime; /* really target_time_t */
- unsigned int msg_ctime; /* really target_time_t */
- unsigned int wwait; /* really struct wait_queue* */
- unsigned int rwait; /* really struct wait_queue* */
- unsigned short msg_cbytes;
- unsigned short msg_qnum;
- unsigned short msg_qbytes;
- unsigned short msg_lspid;
- unsigned short msg_lrpid;
-};
-
-struct target_shmid_ds {
- struct target_ipc_perm shm_perm;
- int shm_segsz;
- unsigned int shm_atime; /* really target_time_t */
- unsigned int shm_dtime; /* really target_time_t */
- unsigned int shm_ctime; /* really target_time_t */
- unsigned short shm_cpid;
- unsigned short shm_lpid;
- short shm_nattch;
- unsigned short shm_npages;
- unsigned long *shm_pages;
- void *attaches; /* really struct shm_desc * */
-};
-
-#define TARGET_IPC_RMID 0
-#define TARGET_IPC_SET 1
-#define TARGET_IPC_STAT 2
-
-union target_semun {
- int val;
- unsigned int buf; /* really struct semid_ds * */
- unsigned int array; /* really unsigned short * */
- unsigned int __buf; /* really struct seminfo * */
- unsigned int __pad; /* really void* */
-};
-
#define UNAME_MACHINE "alpha"
[-- Attachment #3: mesage queue patch --]
[-- Type: TEXT/x-diff, Size: 5309 bytes --]
Index: qemu/linux-user/syscall.c
===================================================================
--- qemu.orig/linux-user/syscall.c 2007-06-01 17:08:29.000000000 -0400
+++ qemu/linux-user/syscall.c 2007-06-01 17:09:00.000000000 -0400
@@ -1437,6 +1437,117 @@
return ret;
}
+struct target_msqid_ds
+{
+ struct target_ipc_perm msg_perm;
+ target_ulong msg_stime;
+ target_ulong __unused1;
+ target_ulong msg_rtime;
+ target_ulong __unused2;
+ target_ulong msg_ctime;
+ target_ulong __unused3;
+ target_ulong __msg_cbytes;
+ target_ulong msg_qnum;
+ target_ulong msg_qbytes;
+ target_ulong msg_lspid;
+ target_ulong msg_lrpid;
+ target_ulong __unused4;
+ target_ulong __unused5;
+};
+
+static inline void target_to_host_msqid_ds(struct msqid_ds *host_md,
+ target_ulong target_addr)
+{
+ struct target_msqid_ds *target_md;
+
+ lock_user_struct(target_md, target_addr, 1);
+ target_to_host_ipc_perm(&(host_md->msg_perm),target_addr);
+ 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);
+ host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes);
+ host_md->msg_qnum = tswapl(target_md->msg_qnum);
+ host_md->msg_qbytes = tswapl(target_md->msg_qbytes);
+ host_md->msg_lspid = tswapl(target_md->msg_lspid);
+ host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
+ unlock_user_struct(target_md, target_addr, 0);
+}
+
+static inline void host_to_target_msqid_ds(target_ulong target_addr,
+ struct msqid_ds *host_md)
+{
+ struct target_msqid_ds *target_md;
+
+ lock_user_struct(target_md, target_addr, 0);
+ host_to_target_ipc_perm(target_addr,&(host_md->msg_perm));
+ 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);
+ target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
+ target_md->msg_qnum = tswapl(host_md->msg_qnum);
+ target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
+ target_md->msg_lspid = tswapl(host_md->msg_lspid);
+ target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
+ unlock_user_struct(target_md, target_addr, 1);
+}
+
+static inline long do_msgctl(long first, long second, long ptr)
+{
+ struct msqid_ds dsarg;
+ int cmd = second&0xff;
+ long ret = 0;
+ 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));
+ }
+ return ret;
+}
+
+struct target_msgbuf {
+ target_ulong mtype;
+ char mtext[1];
+};
+
+static inline long do_msgsnd(long msqid, long msgp, long msgsz, long msgflg)
+{
+ struct target_msgbuf *target_mb;
+ struct msgbuf *host_mb;
+ long ret = 0;
+
+ lock_user_struct(target_mb,msgp,0);
+ host_mb = malloc(msgsz+sizeof(long));
+ host_mb->mtype = 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);
+
+ return ret;
+}
+
+static inline long do_msgrcv(long msqid, long msgp, long msgsz, long msgtype, long msgflg)
+{
+ struct target_msgbuf *target_mb;
+ struct msgbuf *host_mb;
+ long ret = 0;
+
+ lock_user_struct(target_mb,msgp,0);
+ host_mb = malloc(msgsz+sizeof(long));
+ ret = get_errno(msgrcv(msqid, host_mb, msgsz, 1, msgflg));
+ if( ret > 0 )
+ memcpy(target_mb->mtext,host_mb->mtext,ret);
+ target_mb->mtype = tswapl(host_mb->mtype);
+ free(host_mb);
+ unlock_user_struct(target_mb, msgp, 0);
+
+ return ret;
+}
+
/* ??? This only works with linear mappings. */
static long do_ipc(long call, long first, long second, long third,
long ptr, long fifth)
@@ -1473,27 +1584,27 @@
break;
case IPCOP_msgsnd:
- ret = get_errno(msgsnd(first, (struct msgbuf *) ptr, second, third));
+ ret = do_msgsnd(first, ptr, second, third);
break;
case IPCOP_msgctl:
- ret = get_errno(msgctl(first, second, (struct msqid_ds *) ptr));
+ ret = do_msgctl(first, second, ptr);
break;
case IPCOP_msgrcv:
- {
- struct ipc_kludge
- {
- void *__unbounded msgp;
- long int msgtyp;
- };
+ {
+ struct ipc_kludge
+ {
+ void *__unbounded msgp;
+ long int msgtyp;
+ };
- struct ipc_kludge *foo = (struct ipc_kludge *) ptr;
- struct msgbuf *msgp = (struct msgbuf *) foo->msgp;
+ struct ipc_kludge *foo = (struct ipc_kludge *) ptr;
+ struct msgbuf *msgp = (struct msgbuf *) foo->msgp;
- ret = get_errno(msgrcv(first, msgp, second, 0, third));
+ ret = do_msgrcv(first, msgp, second, 0, third);
- }
+ }
break;
case IPCOP_shmat:
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2007-06-02 16:18 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-05-30 2:35 [Qemu-devel] [PATCH] linux-user semaphore structure mapping Stuart Anderson
2007-06-01 11:59 ` Thiemo Seufer
2007-06-01 19:19 ` Stuart Anderson
2007-06-02 16:17 ` Stuart Anderson
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).