* [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).