From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1LBwVU-0007Ec-U4 for qemu-devel@nongnu.org; Sun, 14 Dec 2008 14:20:00 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1LBwVU-0007EE-FN for qemu-devel@nongnu.org; Sun, 14 Dec 2008 14:20:00 -0500 Received: from [199.232.76.173] (port=36770 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1LBwVU-0007E9-6u for qemu-devel@nongnu.org; Sun, 14 Dec 2008 14:20:00 -0500 Received: from soufre.accelance.net ([213.162.48.15]:51327) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1LBwVT-0007rB-Bo for qemu-devel@nongnu.org; Sun, 14 Dec 2008 14:19:59 -0500 Received: from [192.168.0.3] (potipota.net [88.168.176.51]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by soufre.accelance.net (Postfix) with ESMTP id A7ECF45068 for ; Sun, 14 Dec 2008 20:19:56 +0100 (CET) Subject: Re: [Qemu-devel] [linux-user] Added posix message queue syscalls except mq_notify From: Lionel Landwerlin In-Reply-To: <20081214181152.GC7343@epbyminw8406h.minsk.epam.com> References: <1229171967.3898.59.camel@cocoduo.atr> <20081214181152.GC7343@epbyminw8406h.minsk.epam.com> Content-Type: text/plain; charset=UTF-8 Date: Sun, 14 Dec 2008 20:19:51 +0100 Message-Id: <1229282391.3898.78.camel@cocoduo.atr> Mime-Version: 1.0 Content-Transfer-Encoding: quoted-printable Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Le dimanche 14 d=C3=A9cembre 2008 =C3=A0 20:11 +0200, Kirill A. Shutemov = a =C3=A9crit : > On Sat, Dec 13, 2008 at 01:39:27PM +0100, Lionel Landwerlin wrote: > > >From 57a528de47a737e59f391ff7df2f87367b40529e Mon Sep 17 00:00:00 20= 01 > > From: Lionel Landwerlin > > Date: Mon, 1 Dec 2008 02:42:24 +0100 > > Subject: [PATCH] Added posix message queue syscalls except mq_notify > >=20 > > Signed-off-by: Lionel Landwerlin > >=20 > > --- > > linux-user/syscall.c | 151 ++++++++++++++++++++++++++++++++++++++++= ++++------ > > 1 files changed, 117 insertions(+), 0 deletions(-) > >=20 > > diff --git a/linux-user/syscall.c b/linux-user/syscall.c > > index 4065917..c4dd38a 100644 > > --- a/linux-user/syscall.c > > +++ b/linux-user/syscall.c > > @@ -28,6 +28,7 @@ > > #include > > #include > > #include > > +#include > > #include > > #include > > #include > > @@ -629,6 +630,43 @@ static inline abi_long copy_to_user_timeval(abi_= ulong target_tv_addr, > > return 0; > > } > > =20 > > +static inline abi_long copy_from_user_mq_attr(struct mq_attr *attr, > > + abi_ulong target_mq_at= tr_addr) > > +{ > > + struct mq_attr *target_mq_attr; >=20 > It's wrong. struct mq_attr has long int fields, so you should define > struct target_mq_attr using abi_long. I will do that, thx. >=20 > > + > > + if (!lock_user_struct(VERIFY_READ, target_mq_attr, > > + target_mq_attr_addr, 1)) > > + return -TARGET_EFAULT; > > + > > + __get_user(attr->mq_flags, &target_mq_attr->mq_flags); > > + __get_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg); > > + __get_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize); > > + __get_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs); > > + > > + unlock_user_struct(target_mq_attr, target_mq_attr_addr, 0); > > + > > + return 0; > > +} > > + > > +static inline abi_long copy_to_user_mq_attr(abi_ulong target_mq_attr= _addr, > > + const struct mq_attr *at= tr) > > +{ > > + struct mq_attr *target_mq_attr; > > + > > + if (!lock_user_struct(VERIFY_WRITE, target_mq_attr, > > + target_mq_attr_addr, 0)) > > + return -TARGET_EFAULT; > > + > > + __put_user(attr->mq_flags, &target_mq_attr->mq_flags); > > + __put_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg); > > + __put_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize); > > + __put_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs); > > + > > + unlock_user_struct(target_mq_attr, target_mq_attr_addr, 1); > > + > > + return 0; > > +} > > =20 > > /* do_select() must return target values and target errnos. */ > > static abi_long do_select(int n, > > @@ -6033,6 +6071,85 @@ abi_long do_syscall(void *cpu_env, int num, ab= i_long arg1, > > break; > > #endif > > =20 > > +#ifdef TARGET_NR_mq_open > > + case TARGET_NR_mq_open: > > + { > > + struct mq_attr posix_mq_attr; > > + > > + p =3D lock_user_string(arg1 - 1); >=20 > Why - 1? Look at glibc/uclibc implementation, the string argument is (str + 1). >=20 > > + if (arg4 !=3D 0) > > + copy_from_user_mq_attr (&posix_mq_attr, arg4); > > + ret =3D get_errno(mq_open(p, arg2, arg3, &posix_mq_attr)); > > + unlock_user (p, arg1, 0); > > + break; > > + } > > + > > + case TARGET_NR_mq_unlink: > > + p =3D lock_user_string(arg1 - 1); >=20 > ? Same thing. >=20 > > + ret =3D get_errno(mq_unlink(p)); > > + unlock_user (p, arg1, 0); > > + break; > > + > > + case TARGET_NR_mq_timedsend: > > + { > > + struct timespec ts; > > + > > + if (arg5 !=3D 0) { > > + p =3D lock_user (VERIFY_READ, arg2, arg3, 1); > > + target_to_host_timespec(&ts, arg5); > > + ret =3D get_errno(mq_timedsend(arg1, p, arg3, arg4, &ts)= ); > > + host_to_target_timespec(arg5, &ts); > > + unlock_user (p, arg2, arg3); > > + } else { > > + p =3D lock_user (VERIFY_READ, arg2, arg3, 1); > > + ret =3D get_errno(mq_send(arg1, p, arg3, arg4)); > > + unlock_user (p, arg2, arg3); > > + } >=20 > We can lock and unlock outside of if startament, I think. Right. >=20 > > + break; > > + } > > + > > + case TARGET_NR_mq_timedreceive: > > + { > > + struct timespec ts; > > + unsigned int prio; > > + > > + if (arg5 !=3D 0) { > > + p =3D lock_user (VERIFY_READ, arg2, arg3, 1); > > + target_to_host_timespec(&ts, arg5); > > + ret =3D get_errno(mq_timedreceive(arg1, p, arg3, &prio, = &ts)); > > + host_to_target_timespec(arg5, &ts); > > + unlock_user (p, arg2, arg3); > > + } else { > > + p =3D lock_user (VERIFY_READ, arg2, arg3, 1); > > + ret =3D get_errno(mq_receive(arg1, p, arg3, &prio)); > > + unlock_user (p, arg2, arg3); > > + } >=20 > The same about locking. >=20 > > + if (arg4 !=3D 0) > > + put_user_u32(prio, arg4); > > + break; > > + } > > + > > + /* Not implemented for now... */ > > +/* case TARGET_NR_mq_notify: */ > > +/* break; */ >=20 > Is there any problem with this syscall? This syscall is a little bit more complicated. The implementation would be a kind of signal handler. >=20 > > + > > + case TARGET_NR_mq_getsetattr: > > + { > > + struct mq_attr posix_mq_attr_in, posix_mq_attr_out; > > + > > + if (arg3 !=3D 0) { > > + ret =3D mq_getattr(arg1, &posix_mq_attr_out); > > + copy_to_user_mq_attr(arg3, &posix_mq_attr_out); > > + } > > + if (arg2 !=3D 0) { > > + copy_from_user_mq_attr(&posix_mq_attr_in, arg2); > > + ret |=3D mq_setattr(arg1, &posix_mq_attr_in, &posix_mq_a= ttr_out); > > + } > > + > > + break; > > + } > > +#endif > > + > > default: > > unimplemented: > > gemu_log("qemu: Unsupported syscall: %d\n", num); > > --=20 > > 1.5.6.5