qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] semaphore syscalls - refresh
@ 2007-03-30  1:30 Stuart Anderson
  2007-03-31 18:58 ` Thiemo Seufer
  0 siblings, 1 reply; 4+ messages in thread
From: Stuart Anderson @ 2007-03-30  1:30 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: TEXT/PLAIN, Size: 599 bytes --]


This is a refresh of a prior patch to fix the semaphore system calls
sem*() in user-linux mode. Some additional cases have been dealt with,
and a small amount of code re-arrainging to prepare for the EFAULT patch.
Tested using Linux Test Project in the target.



                                 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: 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] semaphore syscalls - refresh
  2007-03-30  1:30 [Qemu-devel] [PATCH] semaphore syscalls - refresh Stuart Anderson
@ 2007-03-31 18:58 ` Thiemo Seufer
  2007-04-01  1:18   ` Stuart Anderson
  0 siblings, 1 reply; 4+ messages in thread
From: Thiemo Seufer @ 2007-03-31 18:58 UTC (permalink / raw)
  To: Stuart Anderson; +Cc: qemu-devel

Stuart Anderson wrote:
> 
> This is a refresh of a prior patch to fix the semaphore system calls
> sem*() in user-linux mode. Some additional cases have been dealt with,
> and a small amount of code re-arrainging to prepare for the EFAULT patch.
> Tested using Linux Test Project in the target.
[snip]
> +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;

I don't see how this can work with target_su being an uninitialized pointer.


Thiemo

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

* Re: [Qemu-devel] [PATCH] semaphore syscalls - refresh
  2007-03-31 18:58 ` Thiemo Seufer
@ 2007-04-01  1:18   ` Stuart Anderson
  2007-04-17 20:58     ` Stuart Anderson
  0 siblings, 1 reply; 4+ messages in thread
From: Stuart Anderson @ 2007-04-01  1:18 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: qemu-devel

On Sat, 31 Mar 2007, Thiemo Seufer wrote:

>> +    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;
>
> I don't see how this can work with target_su being an uninitialized pointer.

#define lock_user_struct(host_ptr, guest_addr, copy) \
     host_ptr = lock_user(guest_addr, sizeof(*host_ptr), copy)

target_su is the left hand side of the assignment. The macro just hides it.


                                 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] semaphore syscalls - refresh
  2007-04-01  1:18   ` Stuart Anderson
@ 2007-04-17 20:58     ` Stuart Anderson
  0 siblings, 0 replies; 4+ messages in thread
From: Stuart Anderson @ 2007-04-17 20:58 UTC (permalink / raw)
  To: qemu-devel


Thiemo,
 	Just wondering if you had a chance to take another look at
this.


On Sat, 31 Mar 2007, Stuart Anderson wrote:

> On Sat, 31 Mar 2007, Thiemo Seufer wrote:
>
>>> +    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;
>> 
>> I don't see how this can work with target_su being an uninitialized 
>> pointer.
>
> #define lock_user_struct(host_ptr, guest_addr, copy) \
>    host_ptr = lock_user(guest_addr, sizeof(*host_ptr), copy)
>
> target_su is the left hand side of the assignment. The macro just hides it.
>
>
>                                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

end of thread, other threads:[~2007-04-17 21:03 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-03-30  1:30 [Qemu-devel] [PATCH] semaphore syscalls - refresh Stuart Anderson
2007-03-31 18:58 ` Thiemo Seufer
2007-04-01  1:18   ` Stuart Anderson
2007-04-17 20:58     ` 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).