Re: [Qemu-devel] RFC: x86_64 Best way to fix 'cast to pointer from integer of different size' problems?

2007-11-06 Thread Stuart Anderson

On Tue, 6 Nov 2007, Paul Brook wrote:


If you're not careful you get double-copying. Once copying the struct from
guest to host space, and then again when converting layout/endianess.


Yes, it would be easy to do that by mistake. The approach that has been
taken has been to use typed copy_*_user_() routines for the structs
instead of using a seperate untyped copy_*_user() followed by a
convert_() routine. The copy_*_user_() routines do the copy
and convert in a single step.

This will never be as fast as an optimized buffer copy, but it will also
not be as slow as having seperate routines.



Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149




Re: [Qemu-devel] RFC: x86_64 Best way to fix 'cast to pointer from integer of different size' problems?

2007-11-06 Thread Stuart Anderson

On Tue, 6 Nov 2007, Fabrice Bellard wrote:


Paul Brook wrote:

[...]
Personally I like the locking interface as it allows a zero-copy
implementation. However the kernel uses a copying interface, and my
understanding is that other qemu maintainers also prefer the copying
interface.


At least I don't think it is critical performance wise, especially if
the page flag checks are added ! Before you added the current zero copy
interface, my plan was to use a zero copy interface just for big buffers
such as the one for read/write.


By the time you consider the different combinations of targets & hosts,
most of the opportunities for zero copy are eliminated anyway. Byte
ordering and structure packing amd content differences mean that we can't
do zero-copy except in the rare circumstance that the host & target
match is all of these respects. The read & write buffers would still
benefit from zero copy, but nearly everything else has to be touched
anyway.


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149




Re: [Qemu-devel] Re: [PATCH] linux-user utimensat() syscall

2007-09-23 Thread Stuart Anderson


On Sun, 23 Sep 2007, Thiemo Seufer wrote:


Thayne Harbaugh wrote:

This patch adds the utimensat syscall to linux-user.


Doesn't build:

gcc-3.4 -g  -Wl,-T,/home/ths/qemu/qemu-work/ppc.ld   -o qemu-arm main.o 
syscall.o mmap.o signal.o path.o osdep.o thunk.o elfload.o linuxload.o 
flatload.o nwfpe/fpa11.o nwfpe/fpa11_cpdo.o nwfpe/fpa11_cpdt.o 
nwfpe/fpa11_cprt.o nwfpe/fpopcode.o nwfpe/single_cpdo.o nwfpe/double_cpdo.o 
nwfpe/extended_cpdo.o arm-semi.o libqemu.a gdbstub.o   -lm -lrt
syscall.o: In function `do_syscall':
/home/ths/qemu/qemu-work/linux-user/syscall.c:4665: undefined reference to 
`copy_from_user_timespec'
/home/ths/qemu/qemu-work/linux-user/syscall.c:4665: undefined reference to 
`copy_from_user_timespec'


It's looking for something that is in the EFAULT patch.


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149




Re: [Qemu-devel] RFC: [0/11] EFAULT patch

2007-09-19 Thread Stuart Anderson

On Wed, 19 Sep 2007, Paul Brook wrote:


No. We're doing more than most 32-64 syscall thunks. To a first approximation
the syscall thunks can bindly zero extend all values. In qemu we need to know
whether something is a pointer or a value.


Isn't that was the code in do_syscall() does? or am I looking at something
in the wrong way?


Kernel and userspace addresses are not interchangeable in the kernel. Any
place that does so is probably a bug.


I said co-exist, not interchangeable. My point was that the 32-on-64
code didn't do any explicit mapping of pointers passed to it other than
the normal API.

I'm having trouble determining how you would like for things to be. Could
you maybe provide a small sample of how all of this should work, and then
I can probably see what I'm not quite getting.


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149




Re: [Qemu-devel] RFC: [0/11] EFAULT patch

2007-09-19 Thread Stuart Anderson

On Wed, 19 Sep 2007, J. Mayer wrote:


Then, the changes you've done, changing long arguments (which should be
target_long to be correct, you can take a look at the last patch I sent
on the list) to pointers, for example in function prototypes, are
incorrect.


I just went, and looked at the linux code again for 32 on 64 for x86_64 and
powerpc.  In both of these cases (and I suspect the others as well), the
parameters which are passed via registers are 0 extended from 32 bits to
64 bit in the syscall entry asm code. This way, once the C code is
called via the sys_call_table, everything is dealt with as 64 bits. This
actually keeps the rest of the code simpler as the rest of the kernel
doesn't have to be extending & truncating pointers everywhere else.

On x86_64 and powerpc, it appears that both user (ie target) and kernel
pointers co-exist and that the code that maps structures assume that the
__get_user()/__put_user() and copy_*_user() routines can handle any
special situation. The pointers passed into functions like
cp_compat_stat() are 64-bits for both the structure located in the
kernel, and the one located in user space.

My understanding is that we want to do as the kernel does as much as
possible. In light of this, wouldn't we want to be decreasing the use
of target_long where pointers may be involved instead of increasing it?


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149




Re: [Qemu-devel] RFC: [0/11] EFAULT patch

2007-09-19 Thread Stuart Anderson

On Wed, 19 Sep 2007, J. Mayer wrote:


The idea is great but there seem to be a problem in those patches:
you directly cast syscall arguments, which are (or should be)
target_ulong to pointers in the host environment. You should to use the
g2h / h2g macros to get the pointer in the host memory from the offset
in the target address space.


I was explicitly told to _not_ use these in this code.


Offset in the target address  space can not
be assumed to be the same size as an address in the host address space,


And in fact, they definitely are not the same in certain cobinations.


thus can never be casted directly to host pointer.


At some point, we have to convert things from target_long to a host
pointer. If we can agree on what that right mechanism it to do this, I'd
be glad to use it. So far, everything I've seen involved some form of
type casting.



This used to be handled by the lock_user functions and should be handled
in your patch too...


It was handled by g2h() which was just a typecast hidden behind the
macro.


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149




[Qemu-devel] RFC: [11/11] EFAULT patch

2007-09-18 Thread Stuart Anderson


Last, but not least, this part contains the changes to the function that
read and write iovec structures. This part will require one more pass to
eliminate the inner calls to the old API.


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149Index: qemu/linux-user/syscall.c
===
--- qemu.orig/linux-user/syscall.c  2007-09-16 16:03:46.0 -0400
+++ qemu/linux-user/syscall.c   2007-09-16 16:06:36.0 -0400
@@ -855,7 +855,7 @@
 return ret;
 }
 
-static void lock_iovec(struct iovec *vec, target_ulong target_addr,
+static long copy_from_iovec(struct iovec *vec, target_ulong target_addr,
int count, int copy)
 {
 struct target_iovec *target_vec;
@@ -863,15 +863,18 @@
 int i;
 
 target_vec = lock_user(target_addr, count * sizeof(struct target_iovec), 
1);
+if( !access_ok(VERIFY_READ, target_vec, count * sizeof(struct 
target_iovec)) ) return -1;
 for(i = 0;i < count; i++) {
 base = tswapl(target_vec[i].iov_base);
 vec[i].iov_len = tswapl(target_vec[i].iov_len);
 vec[i].iov_base = lock_user(base, vec[i].iov_len, copy);
 }
 unlock_user (target_vec, target_addr, 0);
+
+return 0;
 }
 
-static void unlock_iovec(struct iovec *vec, target_ulong target_addr,
+static long copy_to_iovec(struct iovec *vec, target_ulong target_addr,
  int count, int copy)
 {
 struct target_iovec *target_vec;
@@ -879,11 +882,14 @@
 int i;
 
 target_vec = lock_user(target_addr, count * sizeof(struct target_iovec), 
1);
+if( !access_ok(VERIFY_WRITE, target_vec, count * sizeof(struct 
target_iovec)) ) return -1;
 for(i = 0;i < count; i++) {
 base = tswapl(target_vec[i].iov_base);
 unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
 }
 unlock_user (target_vec, target_addr, 0);
+
+return 0;
 }
 
 static long do_socket(int domain, int type, int protocol)
@@ -959,7 +965,7 @@
 count = tswapl(msgp->msg_iovlen);
 vec = alloca(count * sizeof(struct iovec));
 target_vec = tswapl(msgp->msg_iov);
-lock_iovec(vec, target_vec, count, send);
+if( copy_from_iovec(vec, target_vec, count, send) ) return -EFAULT;
 msg.msg_iovlen = count;
 msg.msg_iov = vec;
 
@@ -971,7 +977,7 @@
 if (!is_error(ret))
 host_to_target_cmsg(msgp, &msg);
 }
-unlock_iovec(vec, target_vec, count, !send);
+if( copy_to_iovec(vec, target_vec, count, !send) ) return -EFAULT;
 return ret;
 }
 
@@ -3913,9 +3919,9 @@
 struct iovec *vec;
 
 vec = alloca(count * sizeof(struct iovec));
-lock_iovec(vec, arg2, count, 0);
+if( copy_from_iovec(vec, arg2, count, 0) ) return -EFAULT;
 ret = get_errno(readv(arg1, vec, count));
-unlock_iovec(vec, arg2, count, 1);
+if( copy_to_iovec(vec, arg2, count, 1) ) return -EFAULT;
 }
 break;
 case TARGET_NR_writev:
@@ -3924,9 +3930,9 @@
 struct iovec *vec;
 
 vec = alloca(count * sizeof(struct iovec));
-lock_iovec(vec, arg2, count, 1);
+if( copy_from_iovec(vec, arg2, count, 1) ) return -EFAULT;
 ret = get_errno(writev(arg1, vec, count));
-unlock_iovec(vec, arg2, count, 0);
+if( copy_to_iovec(vec, arg2, count, 0) )  return -EFAULT;
 }
 break;
 case TARGET_NR_getsid:


[Qemu-devel] RFC: [10/11] EFAULT patch

2007-09-18 Thread Stuart Anderson


This part contains the rest of the updates to do_syscall() that contain
the changes to the new API for several systcalls, including utime(),
sigaction(), rt_sigaction(), rt_sigpending(), sigsuspend(),
rt_sigtimedwait(), rt_sigqueueinfo(), stat() and stat64().


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149Index: qemu/linux-user/syscall.c
===
--- qemu.orig/linux-user/syscall.c  2007-09-17 01:09:25.0 -0400
+++ qemu/linux-user/syscall.c   2007-09-17 01:12:47.0 -0400
@@ -2687,12 +2687,11 @@
 case TARGET_NR_utime:
 {
 struct utimbuf tbuf, *host_tbuf;
-struct target_utimbuf *target_tbuf;
+struct target_utimbuf *target_tbuf = (struct target_utimbuf *)arg2;
 if (arg2) {
-lock_user_struct(target_tbuf, arg2, 1);
+   if( !access_ok(VERIFY_READ,target_tbuf,sizeof(struct 
target_utimbuf)) ) return -EFAULT;
 tbuf.actime = tswapl(target_tbuf->actime);
 tbuf.modtime = tswapl(target_tbuf->modtime);
-unlock_user_struct(target_tbuf, arg2, 0);
 host_tbuf = &tbuf;
 } else {
 host_tbuf = NULL;
@@ -2878,37 +2877,35 @@
 case TARGET_NR_sigaction:
 {
 #if !defined(TARGET_MIPS)
-struct target_old_sigaction *old_act;
+struct target_old_sigaction *old_act = (struct 
target_old_sigaction *)arg2;
 struct target_sigaction act, oact, *pact;
 if (arg2) {
-lock_user_struct(old_act, arg2, 1);
+   if( !access_ok(VERIFY_READ,old_act,sizeof(*old_act)) ) return 
-EFAULT;
 act._sa_handler = old_act->_sa_handler;
 target_siginitset(&act.sa_mask, old_act->sa_mask);
 act.sa_flags = old_act->sa_flags;
 act.sa_restorer = old_act->sa_restorer;
-unlock_user_struct(old_act, arg2, 0);
 pact = &act;
 } else {
 pact = NULL;
 }
 ret = get_errno(do_sigaction(arg1, pact, &oact));
 if (!is_error(ret) && arg3) {
-lock_user_struct(old_act, arg3, 0);
+old_act = (struct target_old_sigaction *)arg3;
+   if( !access_ok(VERIFY_WRITE,old_act,sizeof(*old_act)) ) return 
-EFAULT;
 old_act->_sa_handler = oact._sa_handler;
 old_act->sa_mask = oact.sa_mask.sig[0];
 old_act->sa_flags = oact.sa_flags;
 old_act->sa_restorer = oact.sa_restorer;
-unlock_user_struct(old_act, arg3, 1);
 }
 #else
struct target_sigaction act, oact, *pact, *old_act;
 
if (arg2) {
-   lock_user_struct(old_act, arg2, 1);
+   if( !access_ok(VERIFY_READ,old_act,sizeof(*old_act)) ) return 
-EFAULT;
act._sa_handler = old_act->_sa_handler;
target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
act.sa_flags = old_act->sa_flags;
-   unlock_user_struct(old_act, arg2, 0);
pact = &act;
} else {
pact = NULL;
@@ -2917,14 +2914,14 @@
ret = get_errno(do_sigaction(arg1, pact, &oact));
 
if (!is_error(ret) && arg3) {
-   lock_user_struct(old_act, arg3, 0);
+old_act = (struct target_old_sigaction *)arg3;
+   if( !access_ok(VERIFY_WRITE,old_act,sizeof(*old_act)) ) return 
-EFAULT;
old_act->_sa_handler = oact._sa_handler;
old_act->sa_flags = oact.sa_flags;
old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
old_act->sa_mask.sig[1] = 0;
old_act->sa_mask.sig[2] = 0;
old_act->sa_mask.sig[3] = 0;
-   unlock_user_struct(old_act, arg3, 1);
}
 #endif
 }
@@ -2932,22 +2929,20 @@
 #endif
 case TARGET_NR_rt_sigaction:
 {
-struct target_sigaction *act;
-struct target_sigaction *oact;
+struct target_sigaction *act = (struct target_sigaction *)arg2;
+struct target_sigaction *oact = (struct target_sigaction *)arg3;
 
-if (arg2)
-lock_user_struct(act, arg2, 1);
+if (arg2) {
+   if( !access_ok(VERIFY_READ,act,sizeof(*act)) ) return -EFAULT;
+}
 else
 act = NULL;
-if (arg3)
-lock_user_struct(oact, arg3, 0);
+if (arg3) {
+   if( !access_ok(VERIFY_WRITE,oact,sizeof(*oact)) ) return 
-EF

[Qemu-devel] RFC: [9/11] EFAULT patch

2007-09-18 Thread Stuart Anderson


Thsi part updates stat(64)fs and fstat(64)fs implementations to use the
new APIs in a more optimal manner.


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149Index: qemu/linux-user/syscall.c
===
--- qemu.orig/linux-user/syscall.c  2007-09-17 01:06:41.0 -0400
+++ qemu/linux-user/syscall.c   2007-09-17 01:09:25.0 -0400
@@ -2462,7 +2462,7 @@
 long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
 long arg4, long arg5, long arg6)
 {
-long ret;
+long ret = 0;
 struct stat st;
 struct statfs stfs;
 void *p;
@@ -3352,25 +3352,25 @@
 #endif
 case TARGET_NR_statfs:
 p = lock_user_string(arg1);
+if( !access_ok(VERIFY_READ,p,1) ) return -EFAULT;
 ret = get_errno(statfs(path(p), &stfs));
 unlock_user(p, arg1, 0);
 convert_statfs:
 if (!is_error(ret)) {
-struct target_statfs *target_stfs;
+struct target_statfs *target_stfs = (struct target_statfs *)arg2;;

-lock_user_struct(target_stfs, arg2, 0);
-/* ??? put_user is probably wrong.  */
-put_user(stfs.f_type, &target_stfs->f_type);
-put_user(stfs.f_bsize, &target_stfs->f_bsize);
-put_user(stfs.f_blocks, &target_stfs->f_blocks);
-put_user(stfs.f_bfree, &target_stfs->f_bfree);
-put_user(stfs.f_bavail, &target_stfs->f_bavail);
-put_user(stfs.f_files, &target_stfs->f_files);
-put_user(stfs.f_ffree, &target_stfs->f_ffree);
-put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
-put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
-put_user(stfs.f_namelen, &target_stfs->f_namelen);
-unlock_user_struct(target_stfs, arg2, 1);
+if( !access_ok(VERIFY_WRITE,target_stfs,sizeof(struct 
target_statfs)) ) return -EFAULT;
+/* use __put_user since we just validated the entire bufffer.  */
+__put_user(stfs.f_type, &target_stfs->f_type);
+__put_user(stfs.f_bsize, &target_stfs->f_bsize);
+__put_user(stfs.f_blocks, &target_stfs->f_blocks);
+__put_user(stfs.f_bfree, &target_stfs->f_bfree);
+__put_user(stfs.f_bavail, &target_stfs->f_bavail);
+__put_user(stfs.f_files, &target_stfs->f_files);
+__put_user(stfs.f_ffree, &target_stfs->f_ffree);
+__put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
+__put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
+__put_user(stfs.f_namelen, &target_stfs->f_namelen);
 }
 break;
 case TARGET_NR_fstatfs:
@@ -3379,25 +3379,25 @@
 #ifdef TARGET_NR_statfs64
 case TARGET_NR_statfs64:
 p = lock_user_string(arg1);
+if( !access_ok(VERIFY_READ,p,1) ) return -EFAULT;
 ret = get_errno(statfs(path(p), &stfs));
 unlock_user(p, arg1, 0);
 convert_statfs64:
 if (!is_error(ret)) {
-struct target_statfs64 *target_stfs;
+struct target_statfs64 *target_stfs = (struct target_statfs64 
*)arg3;

-lock_user_struct(target_stfs, arg3, 0);
-/* ??? put_user is probably wrong.  */
-put_user(stfs.f_type, &target_stfs->f_type);
-put_user(stfs.f_bsize, &target_stfs->f_bsize);
-put_user(stfs.f_blocks, &target_stfs->f_blocks);
-put_user(stfs.f_bfree, &target_stfs->f_bfree);
-put_user(stfs.f_bavail, &target_stfs->f_bavail);
-put_user(stfs.f_files, &target_stfs->f_files);
-put_user(stfs.f_ffree, &target_stfs->f_ffree);
-put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
-put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
-put_user(stfs.f_namelen, &target_stfs->f_namelen);
-unlock_user_struct(target_stfs, arg3, 0);
+if( !access_ok(VERIFY_WRITE,target_stfs,sizeof(struct 
target_statfs64)) ) return -EFAULT;
+/* use __put_user since we just validated the entire bufffer.  */
+__put_user(stfs.f_type, &target_stfs->f_type);
+__put_user(stfs.f_bsize, &target_stfs->f_bsize);
+__put_user(stfs.f_blocks, &target_stfs->f_blocks);
+__put_user(stfs.f_bfree, &target_stfs->f_bfree);
+__put_user(stfs.f_bavail, &target_stfs->f_bavail);
+__put_user(stfs.f_files, &target_stfs->f_files);
+__put_user(stfs.f_ffree, &target_stfs->f_ffree);
+__put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
+  

[Qemu-devel] RFC: [8/11] EFAULT patch

2007-09-18 Thread Stuart Anderson


This part updates the functions that read and write struct timespec, and
adjusts the places in do_syscall() that use it.


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149Index: qemu/linux-user/syscall.c
===
--- qemu.orig/linux-user/syscall.c  2007-09-16 15:56:47.0 -0400
+++ qemu/linux-user/syscall.c   2007-09-16 15:56:49.0 -0400
@@ -2436,26 +2436,24 @@
 }
 #endif
 
-static inline void target_to_host_timespec(struct timespec *host_ts,
-   target_ulong target_addr)
+static inline long copy_from_user_timespec(struct timespec *host_ts,
+   struct target_timespec *target_ts)
 {
-struct target_timespec *target_ts;
-
-lock_user_struct(target_ts, target_addr, 1);
+if( copy_from_user(host_ts,target_ts,sizeof(*target_ts)) ) return -1;
 host_ts->tv_sec = tswapl(target_ts->tv_sec);
 host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
-unlock_user_struct(target_ts, target_addr, 0);
+
+return 0;
 }
 
-static inline void host_to_target_timespec(target_ulong target_addr,
+static inline long copy_to_user_timespec(struct target_timespec *target_ts,
struct timespec *host_ts)
 {
-struct target_timespec *target_ts;
-
-lock_user_struct(target_ts, target_addr, 0);
+if( copy_to_user(target_ts, host_ts, sizeof(*target_ts)) ) return -1;
 target_ts->tv_sec = tswapl(host_ts->tv_sec);
 target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
-unlock_user_struct(target_ts, target_addr, 1);
+
+return 0;
 }
 
 long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, 
@@ -3102,7 +3100,7 @@
 unlock_user(p, arg1, 0);
 if (arg3) {
 puts = &uts;
-target_to_host_timespec(puts, arg3);
+copy_from_user_timespec(puts, (struct target_timespec *)arg3);
 } else {
 puts = NULL;
 }
@@ -3997,17 +3995,17 @@
 struct timespec ts;
 ret = get_errno(sched_rr_get_interval(arg1, &ts));
 if (!is_error(ret)) {
-host_to_target_timespec(arg2, &ts);
+if( copy_to_user_timespec((struct target_timespec *)arg2, &ts) 
) return -EFAULT;
 }
 }
 break;
 case TARGET_NR_nanosleep:
 {
 struct timespec req, rem;
-target_to_host_timespec(&req, arg1);
+if( copy_from_user_timespec(&req, (struct target_timespec *)arg1) 
) return -EFAULT;
 ret = get_errno(nanosleep(&req, &rem));
 if (is_error(ret) && arg2) {
-host_to_target_timespec(arg2, &rem);
+if( copy_to_user_timespec((struct target_timespec *)arg2, 
&rem) ) return -EFAULT;
 }
 }
 break;
@@ -4615,7 +4613,7 @@
 struct timespec ts;
 ret = get_errno(clock_gettime(arg1, &ts));
 if (!is_error(ret)) {
-host_to_target_timespec(arg2, &ts);
+if( copy_to_user_timespec((struct target_timespec *)arg2, &ts) ) 
return -EFAULT;
 }
 break;
 }
@@ -4626,7 +4624,7 @@
 struct timespec ts;
 ret = get_errno(clock_getres(arg1, &ts));
 if (!is_error(ret)) {
-host_to_target_timespec(arg2, &ts);
+if( copy_to_user_timespec((struct target_timespec *)arg2, &ts) ) 
return -EFAULT;
 }
 break;
 }


[Qemu-devel] RFC: [7/11] EFAULT patch

2007-09-18 Thread Stuart Anderson


This part updates do_fcntl() to use the new kernel-like APIs.


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149Index: qemu/linux-user/syscall.c
===
--- qemu.orig/linux-user/syscall.c  2007-09-17 01:02:17.0 -0400
+++ qemu/linux-user/syscall.c   2007-09-17 01:06:30.0 -0400
@@ -2242,73 +2242,69 @@
 static long do_fcntl(int fd, int cmd, target_ulong arg)
 {
 struct flock fl;
-struct target_flock *target_fl;
+struct target_flock *target_fl = (struct target_flock *)arg;
 struct flock64 fl64;
-struct target_flock64 *target_fl64;
+struct target_flock64 *target_fl64 = (struct target_flock64 *)arg;
 long ret;
 
 switch(cmd) {
 case TARGET_F_GETLK:
-lock_user_struct(target_fl, arg, 1);
-fl.l_type = tswap16(target_fl->l_type);
-fl.l_whence = tswap16(target_fl->l_whence);
-fl.l_start = tswapl(target_fl->l_start);
-fl.l_len = tswapl(target_fl->l_len);
-fl.l_pid = tswapl(target_fl->l_pid);
-unlock_user_struct(target_fl, arg, 0);
+if( !access_ok(VERIFY_READ,target_fl,sizeof(struct target_flock)) ) 
return -EFAULT;
+__get_user(fl.l_type, &target_fl->l_type);
+__get_user(fl.l_whence, &target_fl->l_whence);
+__get_user(fl.l_start, &target_fl->l_start);
+__get_user(fl.l_len, &target_fl->l_len);
+__get_user(fl.l_pid, &target_fl->l_pid);
 ret = fcntl(fd, cmd, &fl);
 if (ret == 0) {
-lock_user_struct(target_fl, arg, 0);
-target_fl->l_type = tswap16(fl.l_type);
-target_fl->l_whence = tswap16(fl.l_whence);
-target_fl->l_start = tswapl(fl.l_start);
-target_fl->l_len = tswapl(fl.l_len);
-target_fl->l_pid = tswapl(fl.l_pid);
-unlock_user_struct(target_fl, arg, 1);
+if( !access_ok(VERIFY_WRITE,target_fl,sizeof(struct target_flock)) 
) return -EFAULT;
+__put_user(fl.l_type, &target_fl->l_type);
+__put_user(fl.l_whence, &target_fl->l_whence);
+__put_user(fl.l_start, &target_fl->l_start);
+__put_user(fl.l_len, &target_fl->l_len);
+__put_user(fl.l_pid, &target_fl->l_pid);
 }
 break;

 case TARGET_F_SETLK:
 case TARGET_F_SETLKW:
-lock_user_struct(target_fl, arg, 1);
-fl.l_type = tswap16(target_fl->l_type);
-fl.l_whence = tswap16(target_fl->l_whence);
-fl.l_start = tswapl(target_fl->l_start);
-fl.l_len = tswapl(target_fl->l_len);
-fl.l_pid = tswapl(target_fl->l_pid);
-unlock_user_struct(target_fl, arg, 0);
+if( !access_ok(VERIFY_READ,target_fl,sizeof(struct target_flock)) ) 
return -EFAULT;
+__get_user(fl.l_type, &target_fl->l_type);
+__get_user(fl.l_whence, &target_fl->l_whence);
+__get_user(fl.l_start, &target_fl->l_start);
+__get_user(fl.l_len, &target_fl->l_len);
 ret = fcntl(fd, cmd, &fl);
 break;

 case TARGET_F_GETLK64:
-lock_user_struct(target_fl64, arg, 1);
-fl64.l_type = tswap16(target_fl64->l_type) >> 1;
-fl64.l_whence = tswap16(target_fl64->l_whence);
-fl64.l_start = tswapl(target_fl64->l_start);
-fl64.l_len = tswapl(target_fl64->l_len);
-fl64.l_pid = tswap16(target_fl64->l_pid);
-unlock_user_struct(target_fl64, arg, 0);
+if( !access_ok(VERIFY_READ,target_fl64,sizeof(struct target_flock64)) 
) return -EFAULT;
+__get_user(fl64.l_type, &target_fl64->l_type);
+fl64.l_type >>= 1;
+__get_user(fl64.l_whence, &target_fl64->l_whence);
+__get_user(fl64.l_start, &target_fl64->l_start);
+__get_user(fl64.l_len, &target_fl64->l_len);
+__get_user(fl64.l_pid, &target_fl64->l_pid);
 ret = fcntl(fd, cmd >> 1, &fl64);
 if (ret == 0) {
-lock_user_struct(target_fl64, arg, 0);
-target_fl64->l_type = tswap16(fl64.l_type) >> 1;
-target_fl64->l_whence = tswap16(fl64.l_whence);
-target_fl64->l_start = tswapl(fl64.l_start);
-target_fl64->l_len = tswapl(fl64.l_len);
-target_fl64->l_pid = tswapl(fl64.l_pid);
-unlock_user_struct(target_fl64, arg, 1);
+if( !access_ok(VERIFY_WRITE,target_fl64,sizeof(struct 
target_flock64)) ) return -EFAULT;
+__put_user(fl64.l_type, &target_fl64->l_type);
+target_fl64->l_type >>= 1;
+__put_user(fl64.l_whence, &target_fl64->l_whence);
+__put_user(fl64.l_start, &target_fl64->l_start);
+__put_user(fl64.l_len, &target_fl64->l_len);

[Qemu-devel] RFC: [6/11] EFAULT patch

2007-09-18 Thread Stuart Anderson


This part contains the changes to write_ldt() to use the newer APIs.


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149Index: qemu/linux-user/syscall.c
===
--- qemu.orig/linux-user/syscall.c  2007-09-17 01:37:05.0 -0400
+++ qemu/linux-user/syscall.c   2007-09-17 01:37:26.0 -0400
@@ -2040,22 +2040,21 @@
 
 /* XXX: add locking support */
 static int write_ldt(CPUX86State *env,
- target_ulong ptr, unsigned long bytecount, int oldmode)
+ struct target_modify_ldt_ldt_s *target_ldt_info, unsigned 
long bytecount, int oldmode)
 {
+long ret = 0;
 struct target_modify_ldt_ldt_s ldt_info;
-struct target_modify_ldt_ldt_s *target_ldt_info;
 int seg_32bit, contents, read_exec_only, limit_in_pages;
 int seg_not_present, useable;
 uint32_t *lp, entry_1, entry_2;
 
 if (bytecount != sizeof(ldt_info))
 return -EINVAL;
-lock_user_struct(target_ldt_info, ptr, 1);
+if( !access_ok(&target_ldt_info,target_ldt_info,sizeof(struct 
target_modify_ldt_ldt_s)) ) return -EFAULT;
 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
 ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
 ldt_info.limit = tswap32(target_ldt_info->limit);
 ldt_info.flags = tswap32(target_ldt_info->flags);
-unlock_user_struct(target_ldt_info, ptr, 0);

 if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
 return -EINVAL;
@@ -2130,10 +2129,10 @@
 ret = read_ldt(ptr, bytecount);
 break;
 case 1:
-ret = write_ldt(env, ptr, bytecount, 1);
+ret = write_ldt(env, (struct target_modify_ldt_ldt_s *)ptr, bytecount, 
1);
 break;
 case 0x11:
-ret = write_ldt(env, ptr, bytecount, 0);
+ret = write_ldt(env, (struct target_modify_ldt_ldt_s *)ptr, bytecount, 
0);
 break;
 }
 return ret;


[Qemu-devel] RFC: [5/11] EFAULT patch

2007-09-18 Thread Stuart Anderson


This part contains the changes to the message queue IPC syscalls. The
functions for reading and writing the msqid_ds structure have been
updated to use the kernel-like APIs. Also, additional checking has been
added to the implementations of msgsnd() and msgrecv().



Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149Index: qemu/linux-user/syscall.c
===
--- qemu.orig/linux-user/syscall.c  2007-09-16 15:56:37.0 -0400
+++ qemu/linux-user/syscall.c   2007-09-16 15:56:42.0 -0400
@@ -1468,53 +1468,59 @@
   target_ulong __unused5;
 };
 
-static inline void target_to_host_msqid_ds(struct msqid_ds *host_md,
-  target_ulong target_addr)
+static inline long copy_from_user_msqid_ds(struct msqid_ds *host_md,
+  struct target_msqid_ds *target_md)
 {
-struct target_msqid_ds *target_md;
+/* access has already been checked */
+copy_from_user_ipc_perm(&(host_md->msg_perm),&(target_md->msg_perm));
+__get_user(host_md->msg_stime, &target_md->msg_stime);
+__get_user(host_md->msg_rtime, &target_md->msg_rtime);
+__get_user(host_md->msg_ctime, &target_md->msg_ctime);
+__get_user(host_md->__msg_cbytes, &target_md->__msg_cbytes);
+__get_user(host_md->msg_qnum, &target_md->msg_qnum);
+__get_user(host_md->msg_qbytes, &target_md->msg_qbytes);
+__get_user(host_md->msg_lspid, &target_md->msg_lspid);
+__get_user(host_md->msg_lrpid, &target_md->msg_lrpid);
 
-lock_user_struct(target_md, target_addr, 1);
-copy_from_user_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);
+return 0;
 }
 
-static inline void host_to_target_msqid_ds(target_ulong target_addr,
+static inline long copy_to_usermsqid_ds(struct target_msqid_ds *target_md,
struct msqid_ds *host_md)
 {
-struct target_msqid_ds *target_md;
+/* access has already been checked */
+copy_to_user_ipc_perm(&(target_md->msg_perm),&(host_md->msg_perm));
+__put_user(host_md->msg_stime, &target_md->msg_stime);
+__put_user(host_md->msg_rtime, &target_md->msg_rtime);
+__put_user(host_md->msg_ctime, &target_md->msg_ctime);
+__put_user(host_md->__msg_cbytes, &target_md->__msg_cbytes);
+__put_user(host_md->msg_qnum, &target_md->msg_qnum);
+__put_user(host_md->msg_qbytes, &target_md->msg_qbytes);
+__put_user(host_md->msg_lspid, &target_md->msg_lspid);
+__put_user(host_md->msg_lrpid, &target_md->msg_lrpid);
 
-lock_user_struct(target_md, target_addr, 0);
-copy_to_user_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);
+return 0;
 }
 
 static inline long do_msgctl(long first, long second, long ptr)
 {
 struct msqid_ds dsarg;
+struct target_msqid_ds *target_ds = (struct target_msqid_ds *)ptr;
 int cmd = second&0xff;
 long ret = 0;
 switch( cmd ) {
 case IPC_STAT:
+   if( copy_from_user(&dsarg,target_ds,sizeof(struct msqid_ds)) ) return 
-EFAULT;
+copy_from_user_msqid_ds(&dsarg,target_ds);
+ret = get_errno(msgctl(first, cmd, &dsarg));
+if( copy_to_usermsqid_ds(target_ds,&dsarg) ) return -EFAULT;
+   break;
 case IPC_SET:
-target_to_host_msqid_ds(&dsarg,ptr);
+   if( copy_from_user(&dsarg,target_ds,sizeof(struct msqid_ds)) ) return 
-EFAULT;
+copy_from_user_msqid_ds(&dsarg,target_ds);
 ret = get_errno(msgctl(first, cmd, &dsarg));
-host_to_target_msqid_ds(ptr,&dsarg);
+if( copy_to_usermsqid_ds(target_ds,&dsarg) ) return -EFAULT;
+   break;
 default:
 ret = get_errno(msgctl(first, cmd, &dsarg));
 }
@@ -1522,41 +1528,45 @

[Qemu-devel] RFC: [4/11] EFAULT patch

2007-09-18 Thread Stuart Anderson


This part contains the updates for the semaphore IPC syscalls. In
addition to the changes to use the new APIs, there are also fixes for
some of the semop() and semctl() actions.


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149Index: qemu/linux-user/syscall.c
===
--- qemu.orig/linux-user/syscall.c  2007-09-16 15:56:36.0 -0400
+++ qemu/linux-user/syscall.c   2007-09-16 15:56:37.0 -0400
@@ -1289,64 +1289,50 @@
   target_ulong __unused4;
 };
 
-static inline void target_to_host_ipc_perm(struct ipc_perm *host_ip,
-   target_ulong target_addr)
+static inline void copy_from_user_ipc_perm(struct ipc_perm *host_ip,
+   struct target_ipc_perm *target_ip)
 {
-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);
+/* access has already been checked */
+__get_user(host_ip->__key, &target_ip->__key);
+__get_user(host_ip->uid, &target_ip->uid);
+__get_user(host_ip->gid, &target_ip->gid);
+__get_user(host_ip->cuid, &target_ip->cuid);
+__get_user(host_ip->cgid, &target_ip->cgid);
+__get_user(host_ip->mode, &target_ip->mode);
+__get_user(host_ip->__seq, &target_ip->__seq);
 }
 
-static inline void host_to_target_ipc_perm(target_ulong target_addr,
+static inline void copy_to_user_ipc_perm(struct target_ipc_perm *target_ip,
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);
+/* access has already been checked */
+__put_user(host_ip->__key, &target_ip->__key);
+__put_user(host_ip->uid, &target_ip->uid);
+__put_user(host_ip->gid, &target_ip->gid);
+__put_user(host_ip->cuid, &target_ip->cuid);
+__put_user(host_ip->cgid, &target_ip->cgid);
+__put_user(host_ip->mode, &target_ip->mode);
+__put_user(host_ip->__seq, &target_ip->__seq);
+}
+
+static inline void copy_from_user_semid_ds(struct semid_ds *host_sd,
+  struct target_semid_ds *target_sd)
+{
+/* access has already been checked */
+copy_from_user_ipc_perm(&(host_sd->sem_perm),&(target_sd->sem_perm));
+__get_user(host_sd->sem_nsems, &target_sd->sem_nsems);
+__get_user(host_sd->sem_otime, &target_sd->sem_otime);
+__get_user(host_sd->sem_ctime, &target_sd->sem_ctime);
 }
 
-static inline void host_to_target_semid_ds(target_ulong target_addr,
+static inline void copy_to_user_semid_ds(struct target_semid_ds *target_sd,
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);
+/* access has already been checked */
+copy_to_user_ipc_perm(&(target_sd->sem_perm),&(host_sd->sem_perm));
+__put_user(host_sd->sem_nsems, &target_sd->sem_nsems);
+__put_user(host_sd->sem_otime, &target_sd->sem_otime);
+__put_user(host_sd->sem_ctime, &target_sd->sem_ctime);
 }
 
 union se

[Qemu-devel] RFC: [3/11] EFAULT patch

2007-09-18 Thread Stuart Anderson


This part contains the changes to teh socket interfaces. This includes
updates to the functions for reading and writing struct sockaddr, as
well as updates and some fixes to do_setsockopt() and do_getsockopt().

The implementations of bind() connect(), accept(), getpeername() and
getsockname() have adjustments to use the newer kernel-like apis.
the same is true for the functions that implement send(), sendto(),
recv() and recvfrom().


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149Index: qemu/linux-user/syscall.c
===
--- qemu.orig/linux-user/syscall.c  2007-09-17 00:55:34.0 -0400
+++ qemu/linux-user/syscall.c   2007-09-17 01:00:36.0 -0400
@@ -527,28 +527,24 @@
 return ret;
 }
 
-static inline void target_to_host_sockaddr(struct sockaddr *addr,
-   target_ulong target_addr,
+static inline long copy_from_user_sockaddr(struct sockaddr *addr,
+   struct target_sockaddr * 
target_saddr,
socklen_t len)
 {
-struct target_sockaddr *target_saddr;
+if( copy_from_user(addr,target_saddr,len) ) return -1;
+__get_user(addr->sa_family, &target_saddr->sa_family);
 
-target_saddr = lock_user(target_addr, len, 1);
-memcpy(addr, target_saddr, len);
-addr->sa_family = tswap16(target_saddr->sa_family);
-unlock_user(target_saddr, target_addr, 0);
+return 0;
 }
 
-static inline void host_to_target_sockaddr(target_ulong target_addr,
+static inline long copy_to_user_sockaddr(struct target_sockaddr *target_saddr,
struct sockaddr *addr,
socklen_t len)
 {
-struct target_sockaddr *target_saddr;
+if( copy_to_user(target_saddr,addr,len) ) return -1;
+__put_user(addr->sa_family, &target_saddr->sa_family);
 
-target_saddr = lock_user(target_addr, len, 0);
-memcpy(target_saddr, addr, len);
-target_saddr->sa_family = tswap16(addr->sa_family);
-unlock_user(target_saddr, target_addr, len);
+return 0;
 }
 
 /* ??? Should this also swap msgh->name?  */
@@ -651,6 +647,8 @@
 if (optlen < sizeof(uint32_t))
 return -EINVAL;

+  if( !access_ok(VERIFY_READ, optval, optlen) )
+return -EFAULT;
 val = tget32(optval);
 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
 break;
@@ -672,6 +670,8 @@
 case IP_MULTICAST_TTL:
 case IP_MULTICAST_LOOP:
 val = 0;
+   if( !access_ok(VERIFY_READ, optval, optlen) )
+return -EFAULT;
 if (optlen >= sizeof(uint32_t)) {
 val = tget32(optval);
 } else if (optlen >= 1) {
@@ -680,7 +680,7 @@
 ret = get_errno(setsockopt(sockfd, level, optname, &val, 
sizeof(val)));
 break;
 default:
-goto unimplemented;
+goto unimplemented;
 }
 break;
 case TARGET_SOL_SOCKET:
@@ -746,8 +746,11 @@
 default:
 goto unimplemented;
 }
-   if (optlen < sizeof(uint32_t))
-   return -EINVAL;
+if (optlen < sizeof(uint32_t))
+ return -EINVAL;
+if( !access_ok(VERIFY_READ, optval, optlen) )
+  return -EFAULT;
+
 
val = tget32(optval);
ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, 
sizeof(val)));
@@ -755,13 +758,13 @@
 default:
 unimplemented:
 gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, 
optname);
-ret = -ENOSYS;
+ret = -ENOPROTOOPT;
 }
 return ret;
 }
 
 static long do_getsockopt(int sockfd, int level, int optname,
-  target_ulong optval, target_ulong optlen)
+  target_ulong optval, socklen_t *optlen)
 {
 int len, lv, val, ret;
 
@@ -783,7 +786,10 @@
 case SOL_TCP:
 /* TCP options all take an 'int' value.  */
 int_case:
-len = tget32(optlen);
+   if( get_user(len,optlen) )
+return -EFAULT;
+   if( !access_ok(VERIFY_WRITE, optval,len) )
+return -EFAULT;
 if (len < 0)
 return -EINVAL;
 lv = sizeof(int);
@@ -816,7 +822,10 @@
 #endif
 case IP_MULTICAST_TTL:
 case IP_MULTICAST_LOOP:
-len = tget32(optlen);
+   if( get_user(len,optlen) )
+return -EINVAL;
+   if( !access_ok(VERIFY_WRITE, optval,len) )
+return -EFAULT;
 if (len < 0)
 return -EINVAL;
 lv = sizeof(int);
@@ -835

[Qemu-devel] RCF: [2/11] EFAULT patch

2007-09-18 Thread Stuart Anderson


In this section, the functions for reading and writing fdsets, reading
rusage, and reading and writing timevals have been updated to use the
new kernel like interfaces.

Also, places where these function have been used are adjusted to match,
this includes do_select(), and the do_syscall() code for getrusage(),
gettimeofday(), settimeofday() and setitimer().


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149Index: qemu/linux-user/syscall.c
===
--- qemu.orig/linux-user/syscall.c  2007-09-17 16:17:38.0 -0400
+++ qemu/linux-user/syscall.c   2007-09-17 21:07:35.0 -0400
@@ -363,13 +363,15 @@
 }
 }
 
-static inline fd_set *target_to_host_fds(fd_set *fds,
+#define FD_MASK_SIZE (FD_SETSIZE/NFDBITS)
+
+static inline long copy_from_user_fdset(fd_set *fds,
  target_long *target_fds, int n)
 {
-#if !defined(BSWAP_NEEDED) && !defined(WORDS_BIGENDIAN)
-return (fd_set *)target_fds;
-#else
 int i, b;
+
+if( !access_ok(VERIFY_READ,target_fds,FD_MASK_SIZE) ) return -1;
+
 if (target_fds) {
 FD_ZERO(fds);
 for(i = 0;i < n; i++) {
@@ -378,22 +380,18 @@
 if (b)
 FD_SET(i, fds);
 }
-return fds;
-} else {
-return NULL;
 }
-#endif
+return 0;
 }
 
-static inline void host_to_target_fds(target_long *target_fds,
+static inline long copy_to_user_fdset(target_long *target_fds,
   fd_set *fds, int n)
 {
-#if !defined(BSWAP_NEEDED) && !defined(WORDS_BIGENDIAN)
-/* nothing to do */
-#else
 int i, nw, j, k;
 target_long v;
 
+if( !access_ok(VERIFY_WRITE,target_fds,FD_MASK_SIZE) ) return -1;
+
 if (target_fds) {
 nw = (n + TARGET_LONG_BITS - 1) / TARGET_LONG_BITS;
 k = 0;
@@ -406,7 +404,7 @@
 target_fds[i] = tswapl(v);
 }
 }
-#endif
+return 0;
 }
 
 #if defined(__alpha__)
@@ -424,53 +422,50 @@
 #endif
 }
 
-static inline void host_to_target_rusage(target_ulong target_addr,
+static inline long copy_to_user_rusage(struct target_rusage *target_rusage,
  const struct rusage *rusage)
 {
-struct target_rusage *target_rusage;
+if( !access_ok(VERIFY_WRITE,target_rusage,sizeof(*target_rusage)) ) return 
-1;
+__put_user(rusage->ru_utime.tv_sec, &target_rusage->ru_utime.tv_sec);
+__put_user(rusage->ru_utime.tv_usec, &target_rusage->ru_utime.tv_usec);
+__put_user(rusage->ru_stime.tv_sec, &target_rusage->ru_stime.tv_sec);
+__put_user(rusage->ru_stime.tv_usec, &target_rusage->ru_stime.tv_usec);
+__put_user(rusage->ru_maxrss, &target_rusage->ru_maxrss);
+__put_user(rusage->ru_ixrss, &target_rusage->ru_ixrss);
+__put_user(rusage->ru_idrss, &target_rusage->ru_idrss);
+__put_user(rusage->ru_isrss, &target_rusage->ru_isrss);
+__put_user(rusage->ru_minflt, &target_rusage->ru_minflt);
+__put_user(rusage->ru_majflt, &target_rusage->ru_majflt);
+__put_user(rusage->ru_nswap, &target_rusage->ru_nswap);
+__put_user(rusage->ru_inblock, &target_rusage->ru_inblock);
+__put_user(rusage->ru_oublock, &target_rusage->ru_oublock);
+__put_user(rusage->ru_msgsnd, &target_rusage->ru_msgsnd);
+__put_user(rusage->ru_msgrcv, &target_rusage->ru_msgrcv);
+__put_user(rusage->ru_nsignals, &target_rusage->ru_nsignals);
+__put_user(rusage->ru_nvcsw, &target_rusage->ru_nvcsw);
+__put_user(rusage->ru_nivcsw, &target_rusage->ru_nivcsw);
 
-lock_user_struct(target_rusage, target_addr, 0);
-target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec);
-target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec);
-target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec);
-target_rusage->ru_stime.tv_usec = tswapl(rusage->ru_stime.tv_usec);
-target_rusage->ru_maxrss = tswapl(rusage->ru_maxrss);
-target_rusage->ru_ixrss = tswapl(rusage->ru_ixrss);
-target_rusage->ru_idrss = tswapl(rusage->ru_idrss);
-target_rusage->ru_isrss = tswapl(rusage->ru_isrss);
-target_rusage->ru_minflt = tswapl(rusage->ru_minflt);
-target_rusage->ru_majflt = tswapl(rusage->ru_majflt);
-target_rusage->ru_nswap = tswapl(rusage->ru_nswap);
-target_rusage->ru_inblock = tswapl(rusage->ru_inblock);
-target_rusage->ru_oublock = tswapl(rusage->ru_oublock);
-target_rusage->ru_msgsnd = tswapl(rusage->ru_msgsnd);
-target_rusage->ru_msgrcv = tswapl(rusage->ru_msgrcv);
-target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals);
-target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw);
-target_rusage->ru_nivcsw = tswapl(rusage->ru_niv

[Qemu-devel] RFC: [1/11] EFAULT patch

2007-09-18 Thread Stuart Anderson


This first part contains the additions to the existing infrastructure
needed to implement the new interfaces used in the rest of the patch.

In exec.c, page_check_range() has been added to take an address and a
size and and check to see if it is contained in a valid page that
belongs to the target. A flag is passed t indicate wether read or write
access should be checked.

In qemu.h, the access_ok macro has been given a real implemention, and
implementations of copy_from_user() and copy_to_user() have been added.


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149Index: qemu/exec.c
===
--- qemu.orig/exec.c2007-08-07 21:44:10.0 -0400
+++ qemu/exec.c 2007-08-07 21:44:16.0 -0400
@@ -1862,6 +1862,29 @@
 spin_unlock(&tb_lock);
 }
 
+int page_check_range(target_ulong start, target_ulong len, int flags)
+{
+PageDesc *p;
+target_ulong end;
+target_ulong addr;
+
+end = TARGET_PAGE_ALIGN(start+len); /* must do before we loose bits in the 
next step */
+start = start & TARGET_PAGE_MASK;
+
+if( end < start ) return -1;  /* we've wrapped around */
+for(addr = start; addr < end; addr += TARGET_PAGE_SIZE) {
+p = page_find(addr >> TARGET_PAGE_BITS);
+   if( !p ) return -1;
+   if( !(p->flags & PAGE_VALID) ) return -1;
+
+if (!(p->flags & PAGE_READ) &&
+(flags & PAGE_READ) ) return -1;
+if (!(p->flags & PAGE_WRITE) &&
+(flags & PAGE_WRITE) ) return -1;
+}
+return 0;
+}
+
 /* called from signal handler: invalidate the code and unprotect the
page. Return TRUE if the fault was succesfully handled. */
 int page_unprotect(target_ulong address, unsigned long pc, void *puc)
Index: qemu/cpu-all.h
===
--- qemu.orig/cpu-all.h 2007-08-07 21:44:10.0 -0400
+++ qemu/cpu-all.h  2007-08-07 21:44:16.0 -0400
@@ -691,6 +691,7 @@
 int page_get_flags(target_ulong address);
 void page_set_flags(target_ulong start, target_ulong end, int flags);
 void page_unprotect_range(target_ulong data, target_ulong data_size);
+int page_check_range(target_ulong start, target_ulong len, int flags);
 
 CPUState *cpu_copy(CPUState *env);
 
Index: qemu/linux-user/qemu.h
===
--- qemu.orig/linux-user/qemu.h 2007-08-07 21:44:10.0 -0400
+++ qemu/linux-user/qemu.h  2007-08-08 17:54:18.0 -0400
@@ -171,7 +171,8 @@
 #define VERIFY_READ 0
 #define VERIFY_WRITE 1
 
-#define access_ok(type,addr,size) (1)
+#define access_ok(type,addr,size) \
+
(page_check_range((target_ulong)addr,size,(type==VERIFY_READ)?PAGE_READ:PAGE_WRITE)==0)
 
 /* NOTE get_user and put_user use host addresses.  */
 #define __put_user(x,ptr)\
@@ -238,6 +239,26 @@
 __ret;\
 })
 
+#define copy_from_user(hptr, gptr, len) \
+({ \
+int __cfu_ret=0;\
+if( access_ok(VERIFY_READ, gptr, (len) ) )\
+memcpy(hptr,gptr,(len)); \
+else \
+__cfu_ret=1;\
+__cfu_ret; \
+})
+
+#define copy_to_user(gptr, hptr, len) \
+({ \
+int __ctu_ret=0;\
+if( access_ok(VERIFY_WRITE, gptr, (len)) )\
+memcpy(gptr,hptr,(len)); \
+else \
+__ctu_ret=1;\
+__ctu_ret; \
+})
+
 /* Functions for accessing guest memory.  The tget and tput functions
read/write single values, byteswapping as neccessary.  The lock_user
gets a pointer to a contiguous area of guest memory, but does not perform


[Qemu-devel] RFC: [0/11] EFAULT patch

2007-09-18 Thread Stuart Anderson


Following this message, are the 11 parts of the patch that implements
EFAULT detection in the linux-user mode. Hopefully, this reflects what
was discussed following the first RFC of this patch. Also, hopefully, it
is easier to digest in smaller pieces like this.

In short, the (un)lock_user*() interfaces have been replaced by access_ok
and copy_(to|from)_user() style interfaces. This code should now look
more like some of the 32_on_64 code in the Linux kernel.

As a side effect of these changes, and the more thorough testing that
went along with them, several other bugs have been fixed in areas such
as IPC and sockets.

As before, the Linux Test Project test suite was used in an armel on
x86_64 environment.

Your comments would be appreciated as I'd like to finish beating these
changes into shape so they can be accepted into the repository.


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149




Re: [Qemu-devel] [PATCH] linux-user strace

2007-07-21 Thread Stuart Anderson

On Sat, 21 Jul 2007, Andreas Schwab wrote:


That's the problem.  It does not return the string associated with the
target errno, but something else.


It depends on what is being passed in to it. Looking over it again this
morning, I can see some paths where it is passed the host errno, and
some paths where it is passed a target errno via "ret". So in the later
case, it would be double mapping the errno, which would be wrong.

I had suspected there may be a bit more work left in mapping errno values,
but I wasn't yet sure what was needed where. I'd like to clear up the use
of target_strerr() as part of that fix if that's ok with everyone.


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149




Re: [Qemu-devel] [PATCH] linux-user strace

2007-07-21 Thread Stuart Anderson

On Fri, 20 Jul 2007, Andreas Schwab wrote:


Stuart Anderson <[EMAIL PROTECTED]> writes:


Index: qemu/linux-user/syscall.c
===
--- qemu.orig/linux-user/syscall.c  2007-07-19 01:42:43.0 -0400
+++ qemu/linux-user/syscall.c   2007-07-19 01:43:18.0 -0400
@@ -312,6 +312,11 @@
 return (unsigned long)ret >= (unsigned long)(-4096);
 }

+char *target_strerror(int err)
+{
+   return strerror(host_to_target_errno(err));
+}
+


That looks backwards.  strerror surely expects a host errno value, but
host_to_target_errno returns the errno value for the target, doesn't it?


The function is called target_strerror() 8-). It is used to display the
errno string for the target, not the host. strerror() is just a simple
map, so it doesn't really care. Regular strace on qemu itself will give
the host error strings. This is used for gettign the error string of the
target.


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149




[Qemu-devel] [PATCH] linux-user discrete IPC calls

2007-07-20 Thread Stuart Anderson


At least armel implements discreet IPC calls instead of multiplexing
them through a single syscall. This patch adds support for this.


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149Index: qemu/linux-user/syscall.c
===
--- qemu.orig/linux-user/syscall.c	2007-07-20 13:09:03.0 -0400
+++ qemu/linux-user/syscall.c	2007-07-20 13:10:08.0 -0400
@@ -3742,6 +3742,41 @@
 	ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
 	break;
 #endif
+#ifdef TARGET_NR_semop
+case TARGET_NR_semop:
+ret = get_errno(semop(arg1,(struct sembuf *) arg2, arg3));
+break;
+#endif
+#ifdef TARGET_NR_semget
+case TARGET_NR_semget:
+ret = get_errno(semget(arg1, arg2, arg3));
+break;
+#endif
+#ifdef TARGET_NR_semctl
+case TARGET_NR_semctl:
+ret = do_semctl(arg1, arg2, arg3, arg4);
+break;
+#endif
+#ifdef TARGET_NR_msgsnd
+case TARGET_NR_msgsnd:
+ret = do_msgsnd(arg1, arg2, arg3, arg4);
+break;
+#endif
+#ifdef TARGET_NR_msgrcv
+case TARGET_NR_msgrcv:
+ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
+break;
+#endif
+#ifdef TARGET_NR_msgget
+case TARGET_NR_msgget:
+	ret = get_errno(msgget(arg1, arg2));
+break;
+#endif
+#ifdef TARGET_NR_msgctl
+case TARGET_NR_msgctl:
+ret = do_msgctl(arg1, arg2, arg3);
+break;
+#endif
 case TARGET_NR_fsync:
 ret = get_errno(fsync(arg1));
 break;


Re: [Qemu-devel] [PATCH] linux-user EFAULT implementation

2007-07-10 Thread Stuart Anderson

On Tue, 10 Jul 2007, Fabrice Bellard wrote:

I confirm that I expected g2h() to be completely removed in case the Linux 
user access API is used.


I agree too that it should not be used. I'm testing ARM on x86_64, and
used it in a few places to clean up some warnings. The real fix is to
change what I was doing to not need this asignment anyway. I will take
another look at how to bury this part in the copy* interfaces.

Would it be OK to use g2h() inside the implementation of copy* ?

Since you agree for the copying interface, I suggest to convert all the code 
to it.


OK, I'll continue in this direction, after taking a fresh look at what I
did yesterday.

Thanks for the feedback.


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Solutions Architect  http://www.c2.net/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149




Re: [Qemu-devel] [PATCH] linux-user EFAULT implementation

2007-07-09 Thread Stuart Anderson

On Mon, 9 Jul 2007, Stuart Anderson wrote:


Attached is a diff ...


Here's the diff.


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149*** linux-user/syscall.c	2007-07-09 07:33:46.0 -0400
--- linux-user/syscall.c.stu	2007-07-09 07:01:12.0 -0400
***
*** 522,550 
  return ret;
  }
  
! static inline long copy_from_user_sockaddr(struct sockaddr *addr,
 target_ulong target_addr,
!socklen_t len)
  {
  long ret = 0;
! struct target_sockaddr *target_saddr = (struct target_sockaddr *)target_addr;
  
! if( (ret=access_ok(VERIFY_READ,target_saddr,len)) != 0 ) return ret;
  memcpy(addr, target_saddr, len);
  addr->sa_family = tswap16(target_saddr->sa_family);
  return ret;
  }
  
! static inline long copy_to_user_sockaddr(target_ulong target_addr,
 struct sockaddr *addr,
!socklen_t len)
  {
  long ret = 0;
! struct target_sockaddr *target_saddr = (struct target_sockaddr *)target_addr;
  
! if( (ret=access_ok(VERIFY_WRITE,target_saddr,len)) != 0 ) return ret;
  memcpy(target_saddr, addr, len);
  target_saddr->sa_family = tswap16(addr->sa_family);
  return ret;
  }
  
--- 522,554 
  return ret;
  }
  
! static inline long target_to_host_sockaddr(struct sockaddr *addr,
 target_ulong target_addr,
!socklen_t len,
!int pg_access)
  {
  long ret = 0;
! struct target_sockaddr *target_saddr;
  
! if( (ret=lock_and_check_user_struct(&target_saddr,target_addr,len,1,pg_access)) != 0 ) return ret;
  memcpy(addr, target_saddr, len);
  addr->sa_family = tswap16(target_saddr->sa_family);
+ unlock_user(target_saddr, target_addr, 0);
  return ret;
  }
  
! static inline long host_to_target_sockaddr(target_ulong target_addr,
 struct sockaddr *addr,
!socklen_t len,
!int pg_access)
  {
  long ret = 0;
! struct target_sockaddr *target_saddr;
  
! if( (ret=lock_and_check_user_struct(&target_saddr,target_addr,len,1,pg_access)) != 0 ) return ret;
  memcpy(target_saddr, addr, len);
  target_saddr->sa_family = tswap16(addr->sa_family);
+ unlock_user(target_saddr, target_addr, len);
  return ret;
  }
  
***
*** 909,915 
  long ret = 0;
  void *addr = alloca(addrlen);
  
! if( (ret=copy_from_user_sockaddr(addr, target_addr, addrlen)) != 0 ) return ret;
  return get_errno(bind(sockfd, addr, addrlen));
  }
  
--- 913,919 
  long ret = 0;
  void *addr = alloca(addrlen);
  
! if( (ret=target_to_host_sockaddr(addr, target_addr, addrlen,PAGE_READ)) != 0 ) return ret;
  return get_errno(bind(sockfd, addr, addrlen));
  }
  
***
*** 919,925 
  long ret = 0;
  void *addr = alloca(addrlen);
  
! if( (ret=copy_from_user_sockaddr(addr, target_addr, addrlen)) != 0 ) return ret;
  return get_errno(connect(sockfd, addr, addrlen));
  }
  
--- 923,929 
  long ret = 0;
  void *addr = alloca(addrlen);
  
! if( (ret=target_to_host_sockaddr(addr, target_addr, addrlen,PAGE_READ)) != 0 ) return ret;
  return get_errno(connect(sockfd, addr, addrlen));
  }
  
***
*** 944,956 
  msg.msg_namelen = tswap32(msgp->msg_namelen);
  msg.msg_name = alloca(msg.msg_namelen);
  if( send ) {
!   if( (ret=copy_from_user_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
! msg.msg_namelen)) != 0 ) return ret;
  } else {
! 	  /* FIXME
!   if( (ret=copy_from_user_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
  msg.msg_namelen,PAGE_WRITE)) != 0 ) return ret;
- */
  	}
  } else {
  msg.msg_name = NULL;
--- 948,958 
  msg.msg_namelen = tswap32(msgp->msg_namelen);
  msg.msg_name = alloca(msg.msg_namelen);
  if( send ) {
!   if( (ret=target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
! msg.msg_namelen,PAGE_READ)) != 0 ) return ret;
  } else {
!   if( (ret=target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
  msg.msg_namelen,PAGE_WRITE)) != 0 ) return ret;
  	}
  } else {

Re: [Qemu-devel] [PATCH] linux-user EFAULT implementation

2007-07-09 Thread Stuart Anderson

On Fri, 6 Jul 2007, Stuart Anderson wrote:


So, the question is:

Can I simplify this code to assume that guest and
host addresses coexist and use the copy_*_user() or
just the access_ok() interfaces?


Attached is a diff that shows what this will look like for the struct
sockaddr handling case. In short, the two functions for mapping this
structure get renamed

target_to_host_sockaddr -> copy_from_user_sockaddr
host_to_target_sockaddr -> copy_to_user_sockaddr

and lose the pg_access parameter as read/write access is determined
by wether we are copying to or from "user space". The macro access_ok()
is used to check the validity of the memory being accessed.

This change also completely drops the notion of locking and unlocking memory,
which was the previous model being used.

Fabrice,

Is this change what you had in mind? Does it cause a problem for anyone
else?



Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149




Re: [Qemu-devel] [PATCH] linux-user EFAULT implementation

2007-07-06 Thread Stuart Anderson

On Fri, 6 Jul 2007, Stuart Anderson wrote:

Moreover, I believe using similar functions as Linux for memory access 
(copyfromuser, copytouser, get_user, put_user) would be cleaner.


This makes sense. That code that I sent was based on the idea that I was
just extending the model that was already there, instead of giving it a
complete overhaul. I'll look into how much work the overhaul would be.


After some digging, the one "design-level" issue I have found is that the
current lock_user_struct() and the new lock_and_check_user_struct(),
interfaces are based on the assumption that we need to map addresses
between guest and host, so they provide a place to call g2h() and return the
new address. This is different from copy_{to|from}_user(), which assumes
all addresses are valid as is, but that the system just needs to ensure
they are correctly mapped in for the data copy.

Contrary to this, cpu-all.h has the following comment & code:

#define GUEST_BASE 0

/* All direct uses of g2h and h2g need to go away for usermode softmmu.  */
#define g2h(x) ((void *)((unsigned long)(x) + GUEST_BASE))
#define h2g(x) ((target_ulong)(x - GUEST_BASE))

It appears that g2h() and h2g() are mostly no-ops, with the typecasting
being the only possible useful part remaining.

So, the question is:

Can I simplify this code to assume that guest and
host addresses coexist and use the copy_*_user() or
just the access_ok() interfaces?

This would be one step closer to eliminating the use of g2h() and h2g() in
the usermode code as is suggested by the comment in cpu-all.h.

One other comment to make, is that in most cases, a simple copy is not
sufficient. Unlike the real Linux kernel, in many places, we are doing
structure mapping instead of a simple buffer copy.


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149




Re: [Qemu-devel] [PATCH] linux-user EFAULT implementation

2007-07-06 Thread Stuart Anderson

On Fri, 6 Jul 2007, Fabrice Bellard wrote:

Please update page_check_range() (and other related functions) to return 
-EFAULT instead of EFAULT in case of error.


Will do.


Moreover, I believe using similar functions as Linux for memory access 
(copyfromuser, copytouser, get_user, put_user) would be cleaner.


This makes sense. That code that I sent was based on the idea that I was
just extending the model that was already there, instead of giving it a
complete overhaul. I'll look into how much work the overhaul would be.


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149




[Qemu-devel] [PATCH] tkill

2007-07-06 Thread Stuart Anderson


This small patch implements tkill(). It parallels the tgkill() implementation
that was added recently.


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149Index: qemu/linux-user/syscall.c
===
--- qemu.orig/linux-user/syscall.c	2007-07-06 09:50:23.0 -0400
+++ qemu/linux-user/syscall.c	2007-07-06 10:00:55.0 -0400
@@ -154,6 +154,7 @@
 #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
 #define __NR_sys_syslog __NR_syslog
 #define __NR_sys_tgkill __NR_tgkill
+#define __NR_sys_tkill __NR_tkill
 
 #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
 #define __NR__llseek __NR_lseek
@@ -174,7 +175,12 @@
   loff_t *, res, uint, wh);
 _syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
 _syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
+#ifdef TARGET_NR_tgkill
 _syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
+#endif
+#ifdef TARGET_NR_tkill
+_syscall2(int,sys_tkill,int,tid,int,sig)
+#endif
 #ifdef __NR_exit_group
 _syscall1(int,exit_group,int,error_code)
 #endif
@@ -4774,6 +4780,12 @@
   break;
 #endif
 
+#ifdef TARGET_NR_tkill
+case TARGET_NR_tkill:
+ret = get_errno(sys_tkill((int)arg1, (int)arg2));
+break;
+#endif
+
 #ifdef TARGET_NR_tgkill
 case TARGET_NR_tgkill:
 	ret = get_errno(sys_tgkill((int)arg1, (int)arg2, (int)arg3));


Re: [Qemu-devel] [RFC] strace-like output for user-linux

2007-06-03 Thread Stuart Anderson

On Mon, 4 Jun 2007, Mulyadi Santosa wrote:


Hi Stuart

I hope my little advice is correct... but overall, I think you add a nice 
usefuk feature here.


+}--> don't you think we should break() here since we already found 
correct syscall num? otherwise we will continue the loop


Yes indeed. Thanks for catching that.


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149




Re: [Qemu-devel] [PATCH] linux-user semaphore structure mapping

2007-06-02 Thread Stuart Anderson

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   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149Index: qemu/linux-user/i386/syscall.h
===
--- qemu.orig/linux-user/i386/syscall.h	2007-06-01 16:52:07.0 -0400
+++ qemu/linux-user/i386/syscall.h	2007-06-01 17:08:29.0 -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.0 -0400
+++ qemu/linux-user/ppc/syscall.h	2007-06-01 17:08:29.0 -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

Re: [Qemu-devel] [PATCH] message queue IPC structures

2007-06-01 Thread Stuart Anderson

On Fri, 1 Jun 2007, Thiemo Seufer wrote:


Stuart Anderson wrote:


This is a refresh (vs 05/28 cvs) of a patch sent several weeks ago. This
patch implements the structure handling for the structures used by the
Message queue IPC interfaces msgctl(), msgrcv() and msgsnd().

This was tested using LTP on an ARM target.


Breaks building i386-linux-user.


I forgot to mention that this patch should be applied on top of the 
semaphore patch that was sent at the same time. It seems to be building

OK for me when stacked as intended.


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149




Re: [Qemu-devel] [PATCH] linux-user semaphore structure mapping

2007-06-01 Thread Stuart Anderson

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   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149




Re: [Qemu-devel] [PATCH] mips-linux-user errno mapping

2007-05-31 Thread Stuart Anderson

On Thu, 31 May 2007, Thiemo Seufer wrote:


Please clean up the compiler warnings. This one ist just the most obvious,
I also see many more of the form:


Sorry. I missed those in the noise caused by another, yet to be completed
patch, which is also in my patch stack.

Attached is the cleaned up patch.



Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149Index: qemu/linux-user/errno_defs.h
===
--- /dev/null	1970-01-01 00:00:00.0 +
+++ qemu/linux-user/errno_defs.h	2007-05-31 08:15:03.0 -0400
@@ -0,0 +1,142 @@
+/*
+ * Target definitions of errnos. These may be overridden by an
+ * architecture specific header if needed.
+ *
+ * Taken from asm-generic/errno-base.h and asm-generic/errno.h
+ */
+#define TARGET_EPERM1  /* Operation not permitted */
+#define TARGET_ENOENT   2  /* No such file or directory */
+#define TARGET_ESRCH3  /* No such process */
+#define TARGET_EINTR4  /* Interrupted system call */
+#define TARGET_EIO  5  /* I/O error */
+#define TARGET_ENXIO6  /* No such device or address */
+#define TARGET_E2BIG7  /* Argument list too long */
+#define TARGET_ENOEXEC  8  /* TARGET_Exec format error */
+#define TARGET_EBADF9  /* Bad file number */
+#define TARGET_ECHILD  10  /* No child processes */
+#define TARGET_EAGAIN  11  /* Try again */
+#define TARGET_ENOMEM  12  /* Out of memory */
+#define TARGET_EACCES  13  /* Permission denied */
+#define TARGET_EFAULT  14  /* Bad address */
+#define TARGET_ENOTBLK 15  /* Block device required */
+#define TARGET_EBUSY   16  /* Device or resource busy */
+#define TARGET_EEXIST  17  /* File exists */
+#define TARGET_EXDEV   18  /* Cross-device link */
+#define TARGET_ENODEV  19  /* No such device */
+#define TARGET_ENOTDIR 20  /* Not a directory */
+#define TARGET_EISDIR  21  /* Is a directory */
+#define TARGET_EINVAL  22  /* Invalid argument */
+#define TARGET_ENFILE  23  /* File table overflow */
+#define TARGET_EMFILE  24  /* Too many open files */
+#define TARGET_ENOTTY  25  /* Not a typewriter */
+#define TARGET_ETXTBSY 26  /* Text file busy */
+#define TARGET_EFBIG   27  /* File too large */
+#define TARGET_ENOSPC  28  /* No space left on device */
+#define TARGET_ESPIPE  29  /* Illegal seek */
+#define TARGET_EROFS   30  /* Read-only file system */
+#define TARGET_EMLINK  31  /* Too many links */
+#define TARGET_EPIPE   32  /* Broken pipe */
+#define TARGET_EDOM33  /* Math argument out of domain of func */
+#define TARGET_ERANGE  34  /* Math result not representable */
+
+#define TARGET_EDEADLK 35  /* Resource deadlock would occur */
+#define TARGET_ENAMETOOLONG36  /* File name too long */
+#define TARGET_ENOLCK  37  /* No record locks available */
+#define TARGET_ENOSYS  38  /* Function not implemented */
+#define TARGET_ENOTEMPTY   39  /* Directory not empty */
+#define TARGET_ELOOP   40  /* Too many symbolic links encountered */
+
+#define TARGET_ENOMSG  42  /* No message of desired type */
+#define TARGET_EIDRM   43  /* Identifier removed */
+#define TARGET_ECHRNG  44  /* Channel number out of range */
+#define TARGET_EL2NSYNC45  /* Level 2 not synchronized */
+#define TARGET_EL3HLT  46  /* Level 3 halted */
+#define TARGET_EL3RST  47  /* Level 3 reset */
+#define TARGET_ELNRNG  48  /* Link number out of range */
+#define TARGET_EUNATCH 49  /* Protocol driver not attached */
+#define TARGET_ENOCSI  50  /* No CSI structure available */
+#define TARGET_EL2HLT  51  /* Level 2 halted */
+#define TARGET_EBADE   52  /* Invalid exchange */
+#define TARGET_EBADR   53  /* Invalid request descriptor */
+#define TARGET_EXFULL  54  /* TARGET_Exchange full */
+#define TARGET_ENOANO  55  /* No anode */
+#define TARGET_EBADRQC 56  /* Invalid request code */
+#define TARGET_EBADSLT 57  /* Invalid slot */
+
+#define TARGET_EBFONT  59  /* Bad font file format */
+#define TARGET_ENOSTR  60  /* Device not a stream */
+#define TARGET_ENODATA 61  /* No data available */
+#define TARGET_ETIME

[Qemu-devel] [PATCH] mips-linux-user errno mapping

2007-05-30 Thread Stuart Anderson


The linux user code was completely missing the ability to map errnos
from the host to the target. This patch adds this ability, with the
mapping needed for MIPS. With this patch, an appreciable number of the
tests in LTP now PASS (remaining failures are due to other bugs not yet
fixed).


  Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
   BD03 0A62 E534 37A7 9149Index: qemu/linux-user/errno_defs.h
===
--- /dev/null	1970-01-01 00:00:00.0 +
+++ qemu/linux-user/errno_defs.h	2007-05-30 13:29:13.0 -0400
@@ -0,0 +1,143 @@
+#warning "errno_defs"
+/*
+ * Target definitions of errnos. These may be overridden by an
+ * architecture specific header if needed.
+ *
+ * Taken from asm-generic/errno-base.h and asm-generic/errno.h
+ */
+#define TARGET_EPERM1  /* Operation not permitted */
+#define TARGET_ENOENT   2  /* No such file or directory */
+#define TARGET_ESRCH3  /* No such process */
+#define TARGET_EINTR4  /* Interrupted system call */
+#define TARGET_EIO  5  /* I/O error */
+#define TARGET_ENXIO6  /* No such device or address */
+#define TARGET_E2BIG7  /* Argument list too long */
+#define TARGET_ENOEXEC  8  /* TARGET_Exec format error */
+#define TARGET_EBADF9  /* Bad file number */
+#define TARGET_ECHILD  10  /* No child processes */
+#define TARGET_EAGAIN  11  /* Try again */
+#define TARGET_ENOMEM  12  /* Out of memory */
+#define TARGET_EACCES  13  /* Permission denied */
+#define TARGET_EFAULT  14  /* Bad address */
+#define TARGET_ENOTBLK 15  /* Block device required */
+#define TARGET_EBUSY   16  /* Device or resource busy */
+#define TARGET_EEXIST  17  /* File exists */
+#define TARGET_EXDEV   18  /* Cross-device link */
+#define TARGET_ENODEV  19  /* No such device */
+#define TARGET_ENOTDIR 20  /* Not a directory */
+#define TARGET_EISDIR  21  /* Is a directory */
+#define TARGET_EINVAL  22  /* Invalid argument */
+#define TARGET_ENFILE  23  /* File table overflow */
+#define TARGET_EMFILE  24  /* Too many open files */
+#define TARGET_ENOTTY  25  /* Not a typewriter */
+#define TARGET_ETXTBSY 26  /* Text file busy */
+#define TARGET_EFBIG   27  /* File too large */
+#define TARGET_ENOSPC  28  /* No space left on device */
+#define TARGET_ESPIPE  29  /* Illegal seek */
+#define TARGET_EROFS   30  /* Read-only file system */
+#define TARGET_EMLINK  31  /* Too many links */
+#define TARGET_EPIPE   32  /* Broken pipe */
+#define TARGET_EDOM33  /* Math argument out of domain of func */
+#define TARGET_ERANGE  34  /* Math result not representable */
+
+#define TARGET_EDEADLK 35  /* Resource deadlock would occur */
+#define TARGET_ENAMETOOLONG36  /* File name too long */
+#define TARGET_ENOLCK  37  /* No record locks available */
+#define TARGET_ENOSYS  38  /* Function not implemented */
+#define TARGET_ENOTEMPTY   39  /* Directory not empty */
+#define TARGET_ELOOP   40  /* Too many symbolic links encountered */
+
+#define TARGET_ENOMSG  42  /* No message of desired type */
+#define TARGET_EIDRM   43  /* Identifier removed */
+#define TARGET_ECHRNG  44  /* Channel number out of range */
+#define TARGET_EL2NSYNC45  /* Level 2 not synchronized */
+#define TARGET_EL3HLT  46  /* Level 3 halted */
+#define TARGET_EL3RST  47  /* Level 3 reset */
+#define TARGET_ELNRNG  48  /* Link number out of range */
+#define TARGET_EUNATCH 49  /* Protocol driver not attached */
+#define TARGET_ENOCSI  50  /* No CSI structure available */
+#define TARGET_EL2HLT  51  /* Level 2 halted */
+#define TARGET_EBADE   52  /* Invalid exchange */
+#define TARGET_EBADR   53  /* Invalid request descriptor */
+#define TARGET_EXFULL  54  /* TARGET_Exchange full */
+#define TARGET_ENOANO  55  /* No anode */
+#define TARGET_EBADRQC 56  /* Invalid request code */
+#define TARGET_EBADSLT 57  /* Invalid slot */
+
+#define TARGET_EBFONT  59  /* Bad font file format */
+#define TARGET_ENOSTR  60  /* Device not a stream */
+#define TARGET_ENODATA 61  /* No data available */
+#define TARGET_ET

[Qemu-devel] [mips-linux-user] patch for pipe() result handling

2007-05-29 Thread Stuart Anderson


pipe(2) on MIPS does some funny, non-standard stuff with it's return
data. This patch implments this unusual handling. Without this patch,
bash closes it's own stdin by mistake and therefore exits immediately
after presenting the prompt.

The LTP test results for the pipe() tests are improved with this patch
as well.


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149Index: qemu/linux-user/syscall.c
===
--- qemu.orig/linux-user/syscall.c	2007-05-29 22:42:04.0 -0400
+++ qemu/linux-user/syscall.c	2007-05-29 22:47:00.0 -0400
@@ -2916,8 +2916,13 @@
 int host_pipe[2];
 ret = get_errno(pipe(host_pipe));
 if (!is_error(ret)) {
+#if defined(TARGET_MIPS)
+		((CPUMIPSState*)cpu_env)->gpr[3] = host_pipe[1];
+		ret = host_pipe[0];
+#else
 tput32(arg1, host_pipe[0]);
 tput32(arg1 + 4, host_pipe[1]);
+#endif
 }
 }
 break;


[Qemu-devel] [PATCH] message queue IPC structures

2007-05-29 Thread Stuart Anderson


This is a refresh (vs 05/28 cvs) of a patch sent several weeks ago. This
patch implements the structure handling for the structures used by the 
Message queue IPC interfaces msgctl(), msgrcv() and msgsnd().


This was tested using LTP on an ARM target.


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149Index: qemu/linux-user/syscall.c
===
--- qemu.orig/linux-user/syscall.c	2007-03-23 09:06:14.0 -0400
+++ qemu/linux-user/syscall.c	2007-03-23 09:06:16.0 -0400
@@ -1322,6 +1322,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)
@@ -1358,27 +1469,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
-

[Qemu-devel] [PATCH] linux-user semaphore structure mapping

2007-05-29 Thread Stuart Anderson


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   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149Index: qemu/linux-user/i386/syscall.h
===
--- qemu.orig/linux-user/i386/syscall.h	2007-03-23 09:05:19.0 -0400
+++ qemu/linux-user/i386/syscall.h	2007-03-23 09:05:32.0 -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.0 -0400
+++ qemu/linux-user/ppc/syscall.h	2007-03-23 09:05:32.0 -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

[Qemu-devel] [mips-linux-user] patch for struct stat mapping

2007-05-29 Thread Stuart Anderson


The code that maps struct stat is wrong for MIPS. It uses the wrong
sized calls (16 vs 32) for swapping some of the structure members. A
patch to fix this is attached.


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149Index: qemu/linux-user/syscall.c
===
--- qemu.orig/linux-user/syscall.c	2007-05-29 22:17:15.0 -0400
+++ qemu/linux-user/syscall.c	2007-05-29 22:18:16.0 -0400
@@ -3698,7 +3698,11 @@
 
 lock_user_struct(target_st, arg2, 0);
 if( ret=page_check_range(target_st,sizeof(*target_st),PAGE_WRITE) ) return -ret;
+#if defined(TARGET_MIPS)
+target_st->st_dev = tswapl(st.st_dev);
+#else
 target_st->st_dev = tswap16(st.st_dev);
+#endif
 target_st->st_ino = tswapl(st.st_ino);
 #if defined(TARGET_PPC) || defined(TARGET_MIPS)
 target_st->st_mode = tswapl(st.st_mode); /* XXX: check this */
@@ -3709,8 +3713,14 @@
 target_st->st_uid = tswap16(st.st_uid);
 target_st->st_gid = tswap16(st.st_gid);
 #endif
+#if defined(TARGET_MIPS)
+		/* If this is the same on PPC, then just merge w/ the above ifdef */
+target_st->st_nlink = tswapl(st.st_nlink);
+target_st->st_rdev = tswapl(st.st_rdev);
+#else
 target_st->st_nlink = tswap16(st.st_nlink);
 target_st->st_rdev = tswap16(st.st_rdev);
+#endif
 target_st->st_size = tswapl(st.st_size);
 target_st->st_blksize = tswapl(st.st_blksize);
 target_st->st_blocks = tswapl(st.st_blocks);


Re: [Qemu-devel] linux-user target

2007-04-19 Thread Stuart Anderson
On Thu, 19 Apr 2007, J. Mayer wrote:

> And I checked the code generated on my machine.
> I got the repz at the end of the op_goto_tb0 and op_goto_tb1 and it
> seems to work well here with the bash version I got.

IIrc from yesterday, they ended up in front of lea instuctions, which
I think always resulted in the same value being used, so no harm could
be done.


More digging last night, and this morning, and I have disovered that
a 32-bit build from the x86 system that works fine on the 32-bit system
will crash when run inside a 32-bit chroot on the x86_64 system (with
the save version of libraries in the chroot as are on the 32-bit system).
This suggests that there may be something in the execution environment
that is causing the problem. I traced both runs, and am comparing the
results. The first difference is where things get placed in the address
space. Stuff that is at 0x5xxx on one is at 0x7xxx on the other.
Same for 0xa and 0xfxxx. This doesn't seem to cause much of
a problem becasue if I use a simple text substitution on the log files, the
differences almost completely go away. At least that is true for the first
50,000 lines of the logs. Then, for some reason I haven't figured out yet,
the two instances start executing different instructions inside the guest.
I'll need to dig more to figure out it going on when that happens.


Another test which might be interesting is to trade executables with someone
that has a working build on an x86_64 system. The crash will either follow
my executable to someone elses system or their perfectly good executables
will start crashing on my system. I suspect it will be the latter, but it
would be nice to confirm it.

Note that I've had this system running under stress for quite a while now,
including a lot of runtime w/ qemu-arm, so I'm pretty certain it isn't
something mundane like bad RAM.

Sigh... it saddens me to think of the improvements to the rest of linux-user
that I could have finished in the amount of time I've spent on thhis one
problem 8-(.

Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149




Re: [Qemu-devel] linux-user target

2007-04-18 Thread Stuart Anderson

On Thu, 19 Apr 2007, Igor Kovalenko wrote:


as discussed before, to do this in dyngen you need to know the context
better or you'll skip more than intended; that amounts to moving a
large bit of decoder there as far as I understand that


Yes, it was a quick hack along w/ visual inspection of the results.

I have since tried the -mtune=nocona change, and it still crashes.



Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149




Re: [Qemu-devel] linux-user target

2007-04-18 Thread Stuart Anderson

On Wed, 18 Apr 2007, Igor Kovalenko wrote:


This should be solved for x86_64 host with "-mtune=nocona" patch
posted a while ago.


I'll go dig that up.


The problem is with dyngen being confused by "repz retq" sequence.


That's what caught my attention earlier today. It was only showing up in
two places in the generated code. I fixed it by hand by tweaking dyngen to
skip the repz as well as the retq, but I still got the crash.

It is of course possible that I'm seeing multiple crashes and not
recognizing when I have actually fixed something.



Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149




Re: [Qemu-devel] linux-user target

2007-04-18 Thread Stuart Anderson

On Wed, 18 Apr 2007, J. Mayer wrote:


You're right: I think all TLS specific code is located in the glibc.


In my last tracing through qemu.log, I did check for r2 references, and
there was one store near the beginning that looked like what glibc would
do (r2 = ptr+0x700), and the rest of the access were reads of r2.



It may be related to some of the library versions installed in
your 64 bits environment that would not be the same as the one used in
the 32 bits environment.


Both are current Debian etch systems, a real x86_64, and a real x86.
Both are running the same library versions.

ii  libc6  2.3.6.ds1-13 GNU C Library: Shared libraries



One important
precision that may make a big difference: I always use gcc 3.4 to
compile because I know several  gcc 4.x bugs (crash during ISO C
compliant code and/or incorrect generated asm instructions), then I do
not consider gcc 4.x as usable for a production environment today.


I'm using gcc-3.4 as well.

ii  gcc-3.43.4.6-5 The GNU C compiler
ii  gcc-3.4-base   3.4.6-5 The GNU Compiler Collection (base package)



Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149




Re: [Qemu-devel] [PATCH] PPC termios structure ordering

2007-04-18 Thread Stuart Anderson

On Wed, 18 Apr 2007, J. Mayer wrote:


With this change, both host and target 'stty -a' give the same output.


Thanks. I'll take a better look to this patch then apply. There maybe
the same issue in the ppc64 strucutre ?


Yes, it looks like the same changes it needed in linux-user/ppc64/termbits.h
as well.


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149




Re: [Qemu-devel] linux-user target

2007-04-18 Thread Stuart Anderson

On Tue, 17 Apr 2007, Stuart Anderson wrote:


I've continued to work on this all week, and I still haven't managed to
solve it. I've chased down a lot of paths, but none of them have lead to
a solution. Here is a summary of the situation now.

* programs other than bash will run
* bash --version will run
* bash --noediting will run
* occasionally, bash has run if I'm stracing it, but I can't always
  reproduce it.
* when it runs, I occasionally see some odd behavior, but not always.
  The termios patch I just sent cleared up a lot of the oddness.
* when it runs, it hangs on exit. Killing it logs me all the way out
  of the system (ssh conection).
* when it crashes, gdb looses the user level thread, so I can't do any
  debugging
* I don't see any of the TLS related system calls being called. I also
  don't see any concrete proof one way or another that it is used in
  the executable (ie No R_PPC_*TLS relocations). I've been digging in
  the kernel & glibc source, and I don't see a lot of special code to
  support TLS on ppc. It mostly seems to be just taking care to not
  step on R2. Glibc seems to be the only place where it knows something
  specific about TLS, which leads me to think that TLS is mostly
  contain within the userspace on PPC.
* I've tried turning on most of the DEBUG_ defines under linux-user,
  but none of them has yielded anything useful, or noteworthy.


This morning, I went back and tried a 32-bit x86 host (instead of the
x86_64 host), and discovered that everything works just fine. This makes
me think it's a 64 bit issue, so I took a closer look at the build warnings
that exist on x86_64 but not on x86. This pointed to PPC_OP(goto_tb0) &
PPC_OP(goto_tb1) in target-ppc/op.c. It appears that x86_64 is using the
generic portable code, but one of the fields that it is taking as a
pointer (tb_next) is only an int. Changing it to a ulong didn't fix
things though, but it did eliminate the warning.

After more digging in the qemu.log, I noticed this difference that is
related to those two functions (op_goto_tb0 & op_goto_tb1).

On x86:
0ebf :
 ebf:   e9 fc ff ff ff  jmpec0 
 ec4:   c3  ret

0ec5 :
 ec5:   e9 fc ff ff ff  jmpec6 
 eca:   c3  ret

On x86_64:
154e :
154e:   8b 05 00 00 00 00   mov0(%rip),%eax
1554:   ff e0   jmpq   *%rax
1556:   f3 c3   repz retq

1558 :
1558:   8b 05 00 00 00 00   mov0(%rip),%eax
155e:   ff e0   jmpq   *%rax
1560:   f3 c3   repz retq

Note repz before retq which is not in x86 code or in any other x86_64 op.


In use the micro ops are:
0x000d: goto_tb1 0x60233800
0x000e: set_T1 0x100a4df8
0x000f: b_T1

For which the generated code becomes
0x61a5998d:  mov-25321811(%rip),%eax# 0x60233840
0x61a59993:  jmpq   *%eax
0x61a59995:  repz lea -1369131941(%rip),%r12d# 0x100a4df8
0x61a5999d:  mov%r12d,%eax
0x61a599a0:  and$0xfffc,%eax
0x61a599a3:  mov%eax,0xc7f4(%r14)
0x61a599aa:  lea-25321904(%rip),%r15d# 0x60233801
0x61a599b1:  retq

The repz is still there from the goto_tb1 OP, but is now applied to the lea
isn from the set_T1 op.

Is this correct? Would it cause any kind of a problem?




Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149




Re: [Qemu-devel] [PATCH] semaphore syscalls - refresh

2007-04-17 Thread Stuart Anderson


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   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
BD03 0A62 E534 37A7 9149





Re: [Qemu-devel] linux-user target

2007-04-17 Thread Stuart Anderson

On Tue, 10 Apr 2007, Jocelyn Mayer wrote:


PPC:

I am unable to get any executable to run.


projects:~/upstream/qemu# ./ppc-linux-user/qemu-ppc -L /mirror0/chroots/ppc/ 
/mirror0/chroots/ppc/bin/bash
init_ppc_proc: PVR 0008 mask  => 0008
Segmentation fault
projects:~/upstream/qemu#


Just checked, on an amd64 host with a random powerpc bash version I got
on my hard disk drive:

./ppc-linux-user/qemu-ppc
-L /mnt/local/hdc/part3/PPC/linux/archives 
/mnt/local/hdc/part3/PPC/linux/archives/bin/bash --version
init_ppc_proc: PVR 0008 mask  => 0008
GNU bash, version 2.05a.0(1)-release (powerpc-unknown-linux-gnu)
Copyright 2001 Free Software Foundation, Inc.

I also tried to really launch the shell and use it and it worked.

... I have to admit there are some strange behaviors with some
features...

But I think recent builds using glibc with TLS/NPTL would not run.



I've continued to work on this all week, and I still haven't managed to
solve it. I've chased down a lot of paths, but none of them have lead to
a solution. Here is a summary of the situation now.

 * programs other than bash will run
 * bash --version will run
 * bash --noediting will run
 * occasionally, bash has run if I'm stracing it, but I can't always
   reproduce it.
 * when it runs, I occasionally see some odd behavior, but not always.
   The termios patch I just sent cleared up a lot of the oddness.
 * when it runs, it hangs on exit. Killing it logs me all the way out
   of the system (ssh conection).
 * when it crashes, gdb looses the user level thread, so I can't do any
   debugging
 * I don't see any of the TLS related system calls being called. I also
   don't see any concrete proof one way or another that it is used in
   the executable (ie No R_PPC_*TLS relocations). I've been digging in
   the kernel & glibc source, and I don't see a lot of special code to
   support TLS on ppc. It mostly seems to be just taking care to not
   step on R2. Glibc seems to be the only place where it knows something
   specific about TLS, which leads me to think that TLS is mostly
   contain within the userspace on PPC.
 * I've tried turning on most of the DEBUG_ defines under linux-user,
   but none of them has yielded anything useful, or noteworthy.

Whew..

I'm in need a of a fresh idea or three.


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149




[Qemu-devel] [PATCH] PPC termios structure ordering

2007-04-17 Thread Stuart Anderson


Just found a small problem w/ the termios structure as defined for PPC
linux user. It doesn't match the one in include/asm-powerpc/termbits.h.

Index: linux-user/ppc/termbits.h
===
--- linux-user/ppc/termbits.h   (revision 44)
+++ linux-user/ppc/termbits.h   (working copy)
@@ -7,8 +7,8 @@
 unsigned int c_oflag;   /* output mode flags */
 unsigned int c_cflag;   /* control mode flags */
 unsigned int c_lflag;   /* local mode flags */
+unsigned char c_cc[TARGET_NCCS];/* control
characters */
 unsigned char c_line;/* line discipline */
-unsigned char c_cc[TARGET_NCCS];/* control
 characters */
 unsigned int c_ispeed; /* input speed */
 unsigned int c_ospeed; /* output speed */
 };


With this change, both host and target 'stty -a' give the same output.


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149




Re: [Qemu-devel] linux-user target

2007-04-10 Thread Stuart Anderson
On Tue, 10 Apr 2007, Jocelyn Mayer wrote:

> Just checked, on an amd64 host with a random powerpc bash version I got
> on my hard disk drive:
>
> I also tried to really launch the shell and use it and it worked.

Interesting...

> But I think recent builds using glibc with TLS/NPTL would not run.

Ahh. that's probably it.  The executables I'm using are build with libc-2.3.6.

> If this can help.

Indeed, it has probably narrowed the search space considerably.

Thanks.


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149




[Qemu-devel] (no subject)

2007-04-10 Thread Stuart Anderson


I'm trying to test my fixes to the linux-user emulation on some additonal
architectures now, but I'm running into problems. I can debug these some,
but any suggestions or guidence, especially from people more familiar
with the architecture core code, would be appreciated.

The environment is a Debian x86_64 server running Etch, with target
environments built using debootstrap.


MIPS:

Bash seems to start up ok, but when I run a command in it, it hangs
until I hit return a second time, and then bash exits w/ an uncaught
target signal.

projects:~/upstream/qemu# mips-linux-user/qemu-mips -L /mirror0/chroots/mips/ 
/mirror0/chroots/mips/bin/bash
projects:~/upstream/qemu# ps

  PID TTY  TIME CMD
  18786 pts/100:00:00 bash
  20057 pts/100:00:00 ps
  20058 pts/100:00:00 qemu-mips
qemu: uncaught target signal 25 (Continued) - exiting
projects:~/upstream/qemu#

PPC:

I am unable to get any executable to run.


projects:~/upstream/qemu# ./ppc-linux-user/qemu-ppc -L /mirror0/chroots/ppc/ 
/mirror0/chroots/ppc/bin/bash
init_ppc_proc: PVR 0008 mask  => 0008
Segmentation fault
projects:~/upstream/qemu#


Thanks,


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149




Re: [Qemu-devel] [PATCH] clone syscall fix

2007-03-31 Thread Stuart Anderson

On Sat, 31 Mar 2007, Thiemo Seufer wrote:


Stuart Anderson wrote:


Even though clone() and fork() are related, they don't seem to be close
enough to allow a single routine to be used to implement both. With this
patch, the LTP tests for clone now pass.


But it still does the same, assuming VM_CLONE is set, except for passing
additional arguments to the host call.


I'm not so sure that the VM_CLONE flag should control wether the new
stack is set up or not. There are tests for newsp == NULL inside that
block anyway. The LTP certainly tests combination for which the
do_fork() code doesn't work.



Passing untranslated regs looks
like a bug to me, I'm unsure about the tls_val.


Hmm, could be, but that's the way it is in the current code. I think
more testing on additional combination sof target &host will be needed.


It may be possible to fold this back into do_fork(), but this just seemed to
be a little bit more straightforward.


Since Linux's fork() is just a specialcase of clone() this should be
done eventually.


I'll try just dropping do_fork completely, and see if this new do_clone()
works for the fork case also. If so, then that effectively folds the
changes back into do_fork(), and more closely resembles that non-emulated
case of fork() being implemnted on top of clone( anyway.


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149




Re: [Qemu-devel] [PATCH] semaphore syscalls - refresh

2007-03-31 Thread Stuart Anderson

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   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149




[Qemu-devel] [PATCH] EFAULT refresh

2007-03-29 Thread Stuart Anderson


Here is a refresh of the EFAULT patch. This fixes a lot of crashes in
LTP, and presumably in regular applications too. This still needs to
have the checking foldded into lock_user(), but there were a handful
of small fixes since this patch was last sent out.


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149Index: qemu/exec.c
===
--- qemu.orig/exec.c	2007-03-26 11:18:49.0 -0400
+++ qemu/exec.c	2007-03-26 11:20:06.0 -0400
@@ -1785,6 +1785,29 @@
 spin_unlock(&tb_lock);
 }
 
+int page_check_range(target_ulong start, target_ulong len, int flags)
+{
+PageDesc *p;
+target_ulong end;
+target_ulong addr;
+
+end = TARGET_PAGE_ALIGN(start+len); /* must do before we loose bits in the next step */
+start = start & TARGET_PAGE_MASK;
+
+if( end < start ) return EFAULT;  /* we've wrapped around */
+for(addr = start; addr < end; addr += TARGET_PAGE_SIZE) {
+p = page_find(addr >> TARGET_PAGE_BITS);
+	if( !p ) return EFAULT;
+	if( !(p->flags & PAGE_VALID) ) return EFAULT;
+
+if (!(p->flags & PAGE_READ) &&
+(flags & PAGE_READ) ) return EFAULT;
+if (!(p->flags & PAGE_WRITE) &&
+(flags & PAGE_WRITE) ) return EFAULT;
+}
+return 0;
+}
+
 /* called from signal handler: invalidate the code and unprotect the
page. Return TRUE if the fault was succesfully handled. */
 int page_unprotect(target_ulong address, unsigned long pc, void *puc)
Index: qemu/cpu-all.h
===
--- qemu.orig/cpu-all.h	2007-03-26 11:18:49.0 -0400
+++ qemu/cpu-all.h	2007-03-26 11:20:06.0 -0400
@@ -689,6 +689,7 @@
 int page_get_flags(target_ulong address);
 void page_set_flags(target_ulong start, target_ulong end, int flags);
 void page_unprotect_range(target_ulong data, target_ulong data_size);
+int page_check_range(target_ulong start, target_ulong len, int flags);
 
 #define SINGLE_CPU_DEFINES
 #ifdef SINGLE_CPU_DEFINES
Index: qemu/linux-user/syscall.c
===
--- qemu.orig/linux-user/syscall.c	2007-03-26 11:20:05.0 -0400
+++ qemu/linux-user/syscall.c	2007-03-26 14:11:21.0 -0400
@@ -406,28 +406,36 @@
 return ret;
 }
 
-static inline void target_to_host_sockaddr(struct sockaddr *addr,
+static inline long target_to_host_sockaddr(struct sockaddr *addr,
target_ulong target_addr,
-   socklen_t len)
+   socklen_t len,
+   int pg_access)
 {
+long ret = 0;
 struct target_sockaddr *target_saddr;
 
 target_saddr = lock_user(target_addr, len, 1);
+if( ret=page_check_range(target_saddr,len,pg_access) ) return ret;
 memcpy(addr, target_saddr, len);
 addr->sa_family = tswap16(target_saddr->sa_family);
 unlock_user(target_saddr, target_addr, 0);
+return ret;
 }
 
-static inline void host_to_target_sockaddr(target_ulong target_addr,
+static inline long host_to_target_sockaddr(target_ulong target_addr,
struct sockaddr *addr,
-   socklen_t len)
+   socklen_t len,
+   int pg_access)
 {
+long ret = 0;
 struct target_sockaddr *target_saddr;
 
 target_saddr = lock_user(target_addr, len, 0);
+if( ret=page_check_range(target_saddr,len,pg_access) ) return ret;
 memcpy(target_saddr, addr, len);
 target_saddr->sa_family = tswap16(addr->sa_family);
 unlock_user(target_saddr, target_addr, len);
+return ret;
 }
 
 /* ??? Should this also swap msgh->name?  */
@@ -788,18 +796,20 @@
 static long do_bind(int sockfd, target_ulong target_addr,
 socklen_t addrlen)
 {
+long ret = 0;
 void *addr = alloca(addrlen);
 
-target_to_host_sockaddr(addr, target_addr, addrlen);
+if( ret=target_to_host_sockaddr(addr, target_addr, addrlen,PAGE_READ) ) return -ret;
 return get_errno(bind(sockfd, addr, addrlen));
 }
 
 static long do_connect(int sockfd, target_ulong target_addr,
 socklen_t addrlen)
 {
+long ret = 0;
 void *addr = alloca(addrlen);
 
-target_to_host_sockaddr(addr, target_addr, addrlen);
+if( ret=target_to_host_sockaddr(addr, target_addr, addrlen,PAGE_READ) ) return -ret;
 return get_errno(connect(sockfd, addr, addrlen));
 }
 
@@ -814,11 +824,19 @@
 target_ulong target_vec;
 
 lock_user_struct(msgp, target_msg, 1);
+if

[Qemu-devel] [PATCH] signal syscall fixes

2007-03-29 Thread Stuart Anderson


This patch fixes a couple of problems with signals().

The first fix, in cpu-exec.c, is needed for the case where a process
does a kill(SIGSEGV) on itself (as is done in a test suite). This fix
for ARM is similar to what is done for some of the other architectures.
I'm not 100% certain this is the best fix, but it does yield the right
results when running the test suite.

The second fix is simple. sigaction() is supposed to fail if SIGKILL or
SIGSTOP is passed in. Those signals may not be blocked or ignored.


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149Index: qemu/cpu-exec.c
===
--- qemu.orig/cpu-exec.c	2007-03-26 13:51:50.0 -0400
+++ qemu/cpu-exec.c	2007-03-26 13:52:21.0 -0400
@@ -952,10 +952,15 @@
a virtual CPU fault */
 cpu_restore_state(tb, env, pc, puc);
 }
+if( ret == 1 ) {
+sigprocmask(SIG_SETMASK, old_set, NULL);
+//raise_exception_err(env->exception_index, env->error_code);
+} else {
 /* we restore the process signal mask as the sigreturn should
do it (XXX: use sigsetjmp) */
 sigprocmask(SIG_SETMASK, old_set, NULL);
 cpu_loop_exit();
+}
 }
 #elif defined(TARGET_SPARC)
 static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
Index: qemu/linux-user/signal.c
===
--- qemu.orig/linux-user/signal.c	2007-03-26 13:51:50.0 -0400
+++ qemu/linux-user/signal.c	2007-03-26 13:52:21.0 -0400
@@ -422,7 +422,7 @@
 struct sigaction act1;
 int host_sig;
 
-if (sig < 1 || sig > TARGET_NSIG)
+if (sig < 1 || sig > TARGET_NSIG || sig == SIGKILL || sig == SIGSTOP)
 return -EINVAL;
 k = &sigact_table[sig - 1];
 #if defined(DEBUG_SIGNAL)


[Qemu-devel] [PATCH] clone syscall fix

2007-03-29 Thread Stuart Anderson


Even though clone() and fork() are related, they don't seem to be close
enough to allow a single routine to be used to implement both. With this
patch, the LTP tests for clone now pass.

It may be possible to fold this back into do_fork(), but this just seemed to
be a little bit more straightforward.


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149Index: qemu/linux-user/syscall.c
===
--- qemu.orig/linux-user/syscall.c	2007-03-26 11:20:06.0 -0400
+++ qemu/linux-user/syscall.c	2007-03-26 11:28:01.0 -0400
@@ -2088,6 +2088,75 @@
 return 0;
 }
 
+int do_clone(CPUState *env, unsigned int flags, unsigned long newsp,
+ unsigned long parent_tidptr, unsigned long tls_val,
+ unsigned long child_tidptr, unsigned long regs)
+{
+int ret;
+TaskState *ts = NULL;
+uint8_t *new_stack;
+CPUState *new_env;
+
+ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE);
+memset(ts, 0, sizeof(TaskState));
+new_stack = ts->stack;
+ts->used = 1;
+/* add in task state list */
+ts->next = first_task_state;
+first_task_state = ts;
+/* we create a new CPU instance. */
+new_env = cpu_copy(env);
+#if defined(TARGET_I386)
+if (!newsp)
+newsp = env->regs[R_ESP];
+new_env->regs[R_ESP] = newsp;
+new_env->regs[R_EAX] = 0;
+#elif defined(TARGET_ARM)
+if (!newsp)
+newsp = env->regs[13];
+new_env->regs[13] = newsp;
+new_env->regs[0] = 0;
+#elif defined(TARGET_SPARC)
+if (!newsp)
+newsp = env->regwptr[22];
+new_env->regwptr[22] = newsp;
+new_env->regwptr[0] = 0;
+	/* X */
+printf ("HELPME: %s:%d\n", __FILE__, __LINE__);
+#elif defined(TARGET_M68K)
+if (!newsp)
+newsp = env->aregs[7];
+new_env->aregs[7] = newsp;
+new_env->dregs[0] = 0;
+/* ??? is this sufficient?  */
+#elif defined(TARGET_MIPS)
+printf ("HELPME: %s:%d\n", __FILE__, __LINE__);
+#elif defined(TARGET_PPC)
+if (!newsp)
+newsp = env->gpr[1];
+new_env->gpr[1] = newsp;
+{
+int i;
+for (i = 7; i < 32; i++)
+new_env->gpr[i] = 0;
+}
+#elif defined(TARGET_SH4)
+	if (!newsp)
+	  newsp = env->gregs[15];
+	new_env->gregs[15] = newsp;
+	/* X */
+#else
+#error unsupported target CPU
+#endif
+new_env->opaque = ts;
+#ifdef __ia64__
+ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
+#else
+	ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
+#endif
+return ret;
+}
+
 int do_fork(CPUState *env, unsigned int flags, unsigned long newsp)
 {
 int ret;
@@ -3529,7 +3598,7 @@
 ret = get_errno(fsync(arg1));
 break;
 case TARGET_NR_clone:
-ret = get_errno(do_fork(cpu_env, arg1, arg2));
+ret = get_errno(do_clone(cpu_env, arg1, arg2, arg3, arg4, arg5, arg6));
 break;
 #ifdef __NR_exit_group
 /* new thread calls */


[Qemu-devel] [PATCH] message queue fixes - refresh

2007-03-29 Thread Stuart Anderson


Here is a refresh of the message queue syscall (msg*()) fixes. These
are analgous to the just posted sempahore fixes. Tested with LTP on the
target.


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149Index: qemu/linux-user/syscall.c
===
--- qemu.orig/linux-user/syscall.c	2007-03-23 09:06:14.0 -0400
+++ qemu/linux-user/syscall.c	2007-03-23 09:06:16.0 -0400
@@ -1322,6 +1322,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)
@@ -1358,27 +1469,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;
-			};
+{
+ 

[Qemu-devel] [PATCH] fcntl() remaining fix

2007-03-29 Thread Stuart Anderson


There is still one bit left after the last fcntl() fix went in. For
TARGET_F_GETLK and TARGET_F_GETLK64, the structure being passed *in*
needs to be mapped from target to host.


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149Index: qemu/linux-user/syscall.c
===
--- qemu.orig/linux-user/syscall.c	2007-03-23 09:06:00.0 -0400
+++ qemu/linux-user/syscall.c	2007-03-23 09:06:06.0 -0400
@@ -1985,6 +1985,13 @@
 
 switch(cmd) {
 case TARGET_F_GETLK:
+lock_user_struct(target_fl, arg, 1);
+fl.l_type = tswap16(target_fl->l_type);
+fl.l_whence = tswap16(target_fl->l_whence);
+fl.l_start = tswapl(target_fl->l_start);
+fl.l_len = tswapl(target_fl->l_len);
+fl.l_pid = tswapl(target_fl->l_pid);
+unlock_user_struct(target_fl, arg, 0);
 ret = fcntl(fd, cmd, &fl);
 if (ret == 0) {
 lock_user_struct(target_fl, arg, 0);
@@ -2010,6 +2017,13 @@
 break;
 
 case TARGET_F_GETLK64:
+lock_user_struct(target_fl64, arg, 1);
+fl64.l_type = tswap16(target_fl64->l_type) >> 1;
+fl64.l_whence = tswap16(target_fl64->l_whence);
+fl64.l_start = tswapl(target_fl64->l_start);
+fl64.l_len = tswapl(target_fl64->l_len);
+fl64.l_pid = tswap16(target_fl64->l_pid);
+unlock_user_struct(target_fl64, arg, 0);
 ret = fcntl(fd, cmd >> 1, &fl64);
 if (ret == 0) {
 lock_user_struct(target_fl64, arg, 0);
@@ -4088,6 +4102,26 @@
 
 switch(arg2) {
 case TARGET_F_GETLK64:
+#ifdef TARGET_ARM
+if (((CPUARMState *)cpu_env)->eabi) {
+lock_user_struct(target_efl, arg3, 1);
+fl.l_type = tswap16(target_efl->l_type);
+fl.l_whence = tswap16(target_efl->l_whence);
+fl.l_start = tswap64(target_efl->l_start);
+fl.l_len = tswap64(target_efl->l_len);
+fl.l_pid = tswapl(target_efl->l_pid);
+unlock_user_struct(target_efl, arg3, 0);
+} else
+#endif
+{
+lock_user_struct(target_fl, arg3, 1);
+fl.l_type = tswap16(target_fl->l_type);
+fl.l_whence = tswap16(target_fl->l_whence);
+fl.l_start = tswap64(target_fl->l_start);
+fl.l_len = tswap64(target_fl->l_len);
+fl.l_pid = tswapl(target_fl->l_pid);
+unlock_user_struct(target_fl, arg3, 0);
+}
 ret = get_errno(fcntl(arg1, cmd, &fl));
 	if (ret == 0) {
 #ifdef TARGET_ARM


[Qemu-devel] [PATCH] semaphore syscalls - refresh

2007-03-29 Thread Stuart Anderson


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   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149Index: qemu/linux-user/i386/syscall.h
===
--- qemu.orig/linux-user/i386/syscall.h	2007-03-23 09:05:19.0 -0400
+++ qemu/linux-user/i386/syscall.h	2007-03-23 09:05:32.0 -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.0 -0400
+++ qemu/linux-user/ppc/syscall.h	2007-03-23 09:05:32.0 -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;
-	s

Re: [Qemu-devel] generating EFAULT in linux-user

2007-03-23 Thread Stuart Anderson


Here is an updated patch that show more of the changes that are needed
to detect EFAULT situations in linux-user. The areas I focused on are
the socket, semaphore, and message queue family of syscalls as they all
make interesting use of pointers to structures. This patch does sit on
top of the other patches I sent to this list this week for semaphores
and message queues, so it can't be 'test driven' without them.

With this patch, more of the Linux Test Project test suite is able to
PASS, and qemu SEGVs less frequently.

Still to be done is to actually fold this into lock_user(), and finish
applying it in the other applicable syscalls.

Comments would be appreciated.


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149Index: qemu/exec.c
===
--- qemu.orig/exec.c	2007-03-23 09:05:45.0 -0400
+++ qemu/exec.c	2007-03-23 09:06:23.0 -0400
@@ -1785,6 +1785,29 @@
 spin_unlock(&tb_lock);
 }
 
+int page_check_range(target_ulong start, target_ulong len, int flags)
+{
+PageDesc *p;
+target_ulong end;
+target_ulong addr;
+
+end = TARGET_PAGE_ALIGN(start+len); /* must do before we loose bits in the next step */
+start = start & TARGET_PAGE_MASK;
+
+if( end < start ) return EFAULT;  /* we've wrapped around */
+for(addr = start; addr < end; addr += TARGET_PAGE_SIZE) {
+p = page_find(addr >> TARGET_PAGE_BITS);
+	if( !p ) return EFAULT;
+	if( !(p->flags & PAGE_VALID) ) return EFAULT;
+
+if (!(p->flags & PAGE_READ) &&
+(flags & PAGE_READ) ) return EFAULT;
+if (!(p->flags & PAGE_WRITE) &&
+(flags & PAGE_WRITE) ) return EFAULT;
+}
+return 0;
+}
+
 /* called from signal handler: invalidate the code and unprotect the
page. Return TRUE if the fault was succesfully handled. */
 int page_unprotect(target_ulong address, unsigned long pc, void *puc)
Index: qemu/cpu-all.h
===
--- qemu.orig/cpu-all.h	2007-03-23 09:05:45.0 -0400
+++ qemu/cpu-all.h	2007-03-23 10:52:16.0 -0400
@@ -689,6 +689,7 @@
 int page_get_flags(target_ulong address);
 void page_set_flags(target_ulong start, target_ulong end, int flags);
 void page_unprotect_range(target_ulong data, target_ulong data_size);
+int page_check_range(target_ulong start, target_ulong len, int flags);
 
 #define SINGLE_CPU_DEFINES
 #ifdef SINGLE_CPU_DEFINES
Index: qemu/linux-user/syscall.c
===
--- qemu.orig/linux-user/syscall.c	2007-03-23 09:06:16.0 -0400
+++ qemu/linux-user/syscall.c	2007-03-23 10:55:01.0 -0400
@@ -406,28 +406,36 @@
 return ret;
 }
 
-static inline void target_to_host_sockaddr(struct sockaddr *addr,
+static inline long target_to_host_sockaddr(struct sockaddr *addr,
target_ulong target_addr,
-   socklen_t len)
+   socklen_t len,
+   int pg_access)
 {
+long ret = 0;
 struct target_sockaddr *target_saddr;
 
 target_saddr = lock_user(target_addr, len, 1);
+if( ret=page_check_range(target_saddr,len,pg_access) ) return ret;
 memcpy(addr, target_saddr, len);
 addr->sa_family = tswap16(target_saddr->sa_family);
 unlock_user(target_saddr, target_addr, 0);
+return ret;
 }
 
-static inline void host_to_target_sockaddr(target_ulong target_addr,
+static inline long host_to_target_sockaddr(target_ulong target_addr,
struct sockaddr *addr,
-   socklen_t len)
+   socklen_t len,
+   int pg_access)
 {
+long ret = 0;
 struct target_sockaddr *target_saddr;
 
 target_saddr = lock_user(target_addr, len, 0);
+if( ret=page_check_range(target_saddr,len,pg_access) ) return ret;
 memcpy(target_saddr, addr, len);
 target_saddr->sa_family = tswap16(addr->sa_family);
 unlock_user(target_saddr, target_addr, len);
+return ret;
 }
 
 /* ??? Should this also swap msgh->name?  */
@@ -788,18 +796,20 @@
 static long do_bind(int sockfd, target_ulong target_addr,
 socklen_t addrlen)
 {
+long ret = 0;
 void *addr = alloca(addrlen);
 
-target_to_host_sockaddr(addr, target_addr, addrlen);
+if( ret=target_to_host_sockaddr(addr, target_addr, addrlen,PAGE_READ) ) return -ret;
 return get_errno(bind(sockfd, addr, addrlen));
 }
 
 static long do_connect(int sockfd, target_ulong target_addr,

[Qemu-devel] [PATCH] Refresh of sem* implementation

2007-03-22 Thread Stuart Anderson


Attached is a refreshed patch w/ a couple of additional fixes. This
patch provides an implementation of semaphore interfaces (semget(),
semctl(), semop()) that consists mostly of the structure mapping 
needed for 32 bit guest on 64 host such as arm on x86_64.




Stuart


Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149Index: qemu/linux-user/i386/syscall.h
===
--- qemu.orig/linux-user/i386/syscall.h	2007-03-22 18:20:20.0 -0400
+++ qemu/linux-user/i386/syscall.h	2007-03-22 18:20:23.0 -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-22 18:20:20.0 -0400
+++ qemu/linux-user/ppc/syscall.h	2007-03-22 18:20:23.0 -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;
-	

[Qemu-devel] generating EFAULT in linux-user

2007-03-22 Thread Stuart Anderson


With a little help from Paul yesterday, I was able to come up with a
scheme for detecting bad pointers passed to system calls in linux-user
mode. This is used to return EFAULT as would be done on a real kernel.

The attached patch is very preliminary, but shows how it can be done.
I'm sending it now to solicit comments.

The patch currently just add a seperate call to validate the address. Per
yesterdays discussion, the checking should be folded into lock_user(),
but it's not a trivial drop in as lock_user() and lock_user_struct() are
used in different ways in different places, and none of them are actually
checking a return value. I'm still thinking on how best to accomplish
this part.

The end result, is that the tests in LTPs msg* tests that try to
generate EFAULT can now do so (and thus PASS).


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149Index: qemu/exec.c
===
--- qemu.orig/exec.c	2007-03-22 17:18:32.0 -0400
+++ qemu/exec.c	2007-03-22 17:42:30.0 -0400
@@ -1785,6 +1785,29 @@
 spin_unlock(&tb_lock);
 }
 
+int page_check_range(target_ulong start, target_ulong len, int flags)
+{
+PageDesc *p;
+target_ulong end;
+target_ulong addr;
+
+end = TARGET_PAGE_ALIGN(start+len); /* must do before we loose bits in the next step */
+start = start & TARGET_PAGE_MASK;
+
+if( end < start ) return EFAULT;  /* we've wrapped around */
+for(addr = start; addr < end; addr += TARGET_PAGE_SIZE) {
+p = page_find(addr >> TARGET_PAGE_BITS);
+	if( !p ) return EFAULT;
+	if( !(p->flags & PAGE_VALID) ) return EFAULT;
+
+if (!(p->flags & PAGE_READ) &&
+(flags & PAGE_READ) ) return EFAULT;
+if (!(p->flags & PAGE_WRITE) &&
+(flags & PAGE_WRITE) ) return EFAULT;
+}
+return 0;
+}
+
 /* called from signal handler: invalidate the code and unprotect the
page. Return TRUE if the fault was succesfully handled. */
 int page_unprotect(target_ulong address, unsigned long pc, void *puc)
Index: qemu/cpu-all.h
===
--- qemu.orig/cpu-all.h	2007-03-22 17:18:32.0 -0400
+++ qemu/cpu-all.h	2007-03-22 17:19:10.0 -0400
@@ -689,6 +689,7 @@
 int page_get_flags(target_ulong address);
 void page_set_flags(target_ulong start, target_ulong end, int flags);
 void page_unprotect_range(target_ulong data, target_ulong data_size);
+int page_check_range(target_ulong start, target_ulong len, int flags);
 
 #define SINGLE_CPU_DEFINES
 #ifdef SINGLE_CPU_DEFINES
Index: qemu/linux-user/syscall.c
===
--- qemu.orig/linux-user/syscall.c	2007-03-22 17:19:00.0 -0400
+++ qemu/linux-user/syscall.c	2007-03-22 17:26:17.0 -0400
@@ -1287,12 +1287,15 @@
   target_ulong __unused5;
 };
 
-static inline void target_to_host_msqid_ds(struct msqid_ds *host_md,
-  target_ulong target_addr)
+/* static inline */ long target_to_host_msqid_ds(struct msqid_ds *host_md,
+  target_ulong target_addr,
+  int pg_access)
 {
+long ret = 0;
 struct target_msqid_ds *target_md;
 
 lock_user_struct(target_md, target_addr, 1);
+if( ret=page_check_range(target_md,sizeof(*target_md),pg_access) ) return -ret;
 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);
@@ -1303,9 +1306,10 @@
 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);
+return ret;
 }
 
-static inline void host_to_target_msqid_ds(target_ulong target_addr,
+/* static inline */ void host_to_target_msqid_ds(target_ulong target_addr,
struct msqid_ds *host_md)
 {
 struct target_msqid_ds *target_md;
@@ -1323,17 +1327,22 @@
 unlock_user_struct(target_md, target_addr, 1);
 }
 
-static inline long do_msgctl(long first, long second, long ptr)
+/* 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:
+if( ret=target_to_host_msqid_ds(&dsarg,ptr,PAGE_WRITE) ) return -ret;
+ret = get_errno(msgctl(first, cmd, &dsarg));
+host_to_target_msqid_ds(ptr,&dsarg);
+	break;
 case IPC_SET:
-target_to_host_msqid_ds(&dsarg,ptr);
+if( ret=target_to_host_msqid_ds(&dsarg,ptr,PAG

[Qemu-devel] [PATCH] message queue completion

2007-03-21 Thread Stuart Anderson


Like the semaphore patch a couple of days ago, this patch completes the
implementation of the message queue syscalls. With this patch, most
of the message queue tests in LTP now pass in the guest. The remaining
ones will require fixes in other syscall to fix, or at least eliminate
the noise to identify any lingering issues.

This was testing using ARM guest on a x86_64 host.


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149Index: qemu/linux-user/syscall.c
===
--- qemu.orig/linux-user/syscall.c	2007-03-21 20:32:30.0 -0400
+++ qemu/linux-user/syscall.c	2007-03-21 21:07:50.0 -0400
@@ -1381,6 +1381,115 @@
 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_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_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)
@@ -1417,27 +1526,15 @@
 		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

Re: [Qemu-devel] [PATCH] fcntl64 fix

2007-03-21 Thread Stuart Anderson

On Tue, 20 Mar 2007, Paul Brook wrote:


Now that the dust has settled, I see where the change is probably a
no-op anyway. A quick little test program indicates that on x86_64,
l_start will have an offset of 8 wether the structure is packed or not,
and wether the __pad member is present or not. The unsigned long long is
always going to be aligned to a 8 byte boundary.


The __pad member is essential. Your logic is wrong is two ways:

a) The struct is packed. This overrides normal alignment and ensures the
structure contains no padding.


And in this case, it does remove some tail padding at the end of the
structure.


b) long long has whatever alignment the host feels like giving it. There's no
guarantee it's going to be 8 byte aligned.


No there isn't. This was just an observation of what occurs when
building a simple test case on x86_64.


 Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
  BD03 0A62 E534 37A7 9149


___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


Re: [Qemu-devel] [PATCH] fcntl64 fix

2007-03-21 Thread Stuart Anderson

On Wed, 21 Mar 2007, Kirill A. Shutemov wrote:


Primarily, I also thought that problem is in padding, because, without the
patch F_GETLK, on 32-bit target recognises as F_GETLK64 on 64-bit host.
It's happen because on 64-bit host and 32-bit target F_GETLK == F_GETLK64 ==
TARGET_F_GETLK. So if you're using qemu-arm on 64-bit host and a target eabi
program calls fcntl(fd,F_GETLK,...), target_eabi_flock64 will be used by
mistake. Disabling padding can helps in some trivial cases to pass
pseudo-correct args to fcntl. I guess this part of patch wrong.

Stuart, am I right?


Yes, this is a good summary of the trap I initially fell into.


  Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
   BD03 0A62 E534 37A7 9149


___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


Re: [Qemu-devel] [PATCH] fcntl64 fix

2007-03-20 Thread Stuart Anderson

On Tue, 20 Mar 2007, Thiemo Seufer wrote:


Still, this part makes no sense to me since it is in a packed struct.
Can you explain why this works better for you?


It worked better, in that it fixed a problem that let me continue on to
fix other issues. After revisiting fcntl() and coming up with the more
comprehensive patch, this change now seems to have no effect, so I
must conceed that it is not needed, please drop that part of the patch.

Now that the dust has settled, I see where the change is probably a
no-op anyway. A quick little test program indicates that on x86_64,
l_start will have an offset of 8 wether the structure is packed or not,
and wether the __pad member is present or not. The unsigned long long is
always going to be aligned to a 8 byte boundary.

Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149


___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


Re: [Qemu-devel] [PATCH] fcntl64 fix

2007-03-20 Thread Stuart Anderson


OK, I think I finally have it all sorted out. Sorry if I sounded dense
along the way.. there were multiple variable, which increases the number
of possible combinations quickly.

The patch from Kirill is needed, and makes things better. One thing I
notice with it is that we now handle TARGET_F_GETLK64 in two places,
first in the case for TARGET_NR_fcntl64 (around line 4300), and then
again in do_fcntl(), which is called in the default case of the first
location. Once difference between the two locations is wether or not
the case for EABI is handled.

In addition to Kirill's patch, my original patch for target_eabi_flock64
is still needed as well as an expanded version of the revised patch I
sent later that does target->host strcture mapping for the F_GETLK*
cases.

I have used the fcntl test sets out of the Linux Test Projects to
measure with an without the different parts of these patches. With
the entire set (Which is attached), 16 of the 18 test sets pass
completely, and a significant portion of test14 (one of the two that
don't pass completely) passes as well. The tests in test14 that fail
may be do to a problem with a syscall other than fcntl(), but I haven't
completely resulved it yet. Without my portion of the patch, the results
are much worse (maybe half-ish are passing).

There is something interesting about test18 (the other one that doesn't
pass). It intentionally passes in a bad value (-1) as the 3rd argument
to fcntl(). It is testing wether it will get EFAULT. With these fixes,
qemu will SEGV as it tries to convert the struct flock (or struct
flock64) from target->host, and encounters the bad address that was
passed in. The initial SEGV is caught, but the handler for it then
SEGVs again. Ideally, we could detect that we are inside an emulated
system call, and be able to just return the EFAULT.

I ran the LTP tests for both old ABI and EABI, and got the same results.


Attached is the combined patch for fcntl().




Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149--- linux-user/syscall_defs.h.orig  2007-02-23 15:44:47.0 -0500
+++ linux-user/syscall_defs.h   2007-02-23 15:44:26.0 -0500
@@ -1414,7 +1414,9 @@
 struct target_eabi_flock64 {
short  l_type;
short  l_whence;
+#if HOST_LONG_BITS == 32
 int __pad;
+#endif
unsigned long long l_start;
unsigned long long l_len;
int  l_pid;
Index: linux-user/syscall.c
===
--- linux-user/syscall.c.orig   2007-03-20 16:19:11.0 -0400
+++ linux-user/syscall.c2007-03-20 17:04:40.0 -0400
@@ -2107,6 +2107,13 @@
 
 switch(cmd) {
 case TARGET_F_GETLK:
+lock_user_struct(target_fl, arg, 1);
+fl.l_type = tswap16(target_fl->l_type);
+fl.l_whence = tswap16(target_fl->l_whence);
+fl.l_start = tswapl(target_fl->l_start);
+fl.l_len = tswapl(target_fl->l_len);
+fl.l_pid = tswapl(target_fl->l_pid);
+unlock_user_struct(target_fl, arg, 0);
 ret = fcntl(fd, cmd, &fl);
 if (ret == 0) {
 lock_user_struct(target_fl, arg, 0);
@@ -2132,6 +2139,13 @@
 break;
 
 case TARGET_F_GETLK64:
+lock_user_struct(target_fl64, arg, 1);
+fl64.l_type = tswap16(target_fl64->l_type) >> 1;
+fl64.l_whence = tswap16(target_fl64->l_whence);
+fl64.l_start = tswapl(target_fl64->l_start);
+fl64.l_len = tswapl(target_fl64->l_len);
+fl64.l_pid = tswap16(target_fl64->l_pid);
+unlock_user_struct(target_fl64, arg, 0);
 ret = fcntl(fd, cmd >> 1, &fl64);
 if (ret == 0) {
 lock_user_struct(target_fl64, arg, 0);
@@ -4201,15 +4215,47 @@
 #if TARGET_LONG_BITS == 32
 case TARGET_NR_fcntl64:
 {
+   int cmd;
struct flock64 fl;
struct target_flock64 *target_fl;
 #ifdef TARGET_ARM
struct target_eabi_flock64 *target_efl;
 #endif
 
+   switch(arg2){
+   case TARGET_F_GETLK64:
+   cmd = F_GETLK64;
+   case TARGET_F_SETLK64:
+   cmd = F_SETLK64;
+   case TARGET_F_SETLKW64:
+   cmd = F_SETLKW64;
+   default:
+   cmd = arg2;
+   }
+
 switch(arg2) {
-case F_GETLK64:
-ret = get_errno(fcntl(arg1, arg2, &fl));
+case TARGET_F_GETLK64:
+#ifdef TARGET_ARM
+if (((CPUARMState *)cpu_env)->eabi) {
+lock_user_struct(target_efl, arg3, 1);
+fl.l_type = tswap16(target_efl->l_type);
+fl.l_whence = tswap16(target_efl->l_whence);
+fl.l_start = tswap64(target_efl->l_start);
+fl.l_len = tswap64(target_efl->l_len)

Re: [Qemu-devel] [PATCH] fcntl64 fix

2007-03-20 Thread Stuart Anderson

On Tue, 20 Mar 2007, Kirill A. Shutemov wrote:


No. Remap is needed:

$ uname -m; echo -e '#include \nF_GETLK64' | cpp | tail -1
x86_64
5

$ uname -m; echo -e '#include \nF_GETLK64' | cpp | tail -1
armv5l
12

Same for F_SETLK64 and F_SETLKW64.


You are right. I had previously printed out the non-64 versions, and
they are the same, but we not using those.

TARGET_F_GETLK 5
F_GETLK 5
TARGET_F_GETLK64 12
F_GETLK64 5

My confusion...



Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149


___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


Re: [Qemu-devel] [PATCH] fcntl64 fix

2007-03-20 Thread Stuart Anderson

On Tue, 20 Mar 2007, Kirill A. Shutemov wrote:


What are you using as a test app?


I got error when runing Debian's apt-get and tried to fix it.


OK, that's what got me started on this one, but I switched to using the
ltp-kernel-test package for a more comprehensive set of tests once I got
past that first eabi structure change.


I think that remapping the constants
is needed, but I'm just curious how we seem to be coming up with different
parts of the fix when we have the same target/host combination.


I'm not sure that I understand you...


On the arm/x86_64 combination, I think the host & target cmd values are
the same, so the remapping is a noop. It may be needed for other
combinations though. Some architectures have very different values for
constants like this in their ABI.

I was trying to understand how your fix made apt-get/dpkg happy, or if
you were just using a different app that was hitting a different case
for fcntl().


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149


___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


Re: [Qemu-devel] [PATCH] fcntl64 fix

2007-03-20 Thread Stuart Anderson

On Tue, 20 Mar 2007, Kirill A. Shutemov wrote:


Kiril,
What 32 bit host and 64 bit host are you using? I'm working on
arm on x86_64, and I'm starting to think that perhaps all of the different
parts of the fix are needed to ensure it works correctly on all target/host
combinations.



I'm using arm(little-endian) on x86_64.


That blows that theory 8-).

What are you using as a test app? I think that remapping the constants
is needed, but I'm just curious how we seem to be coming up with different
parts of the fix when we have the same target/host combination.



Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149


___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


Re: [Qemu-devel] [PATCH] fcntl64 fix

2007-03-19 Thread Stuart Anderson

On Mon, 19 Mar 2007, Stuart Anderson wrote:



My initial fix was before I started using LTP, and just took care of a
single case that was holding me up. Now I have run the fcntl tests in
LTP on ARM (both oABI and EABI) and there are a lot of failures indicating
that there is a lot more work to be done yet on fcntl().

I'll take a look into it, and probably resubmit a bigger patch later.


One more small fix to repack a structure from taget -> host before using
it clears up most of the fcntl() errors that showed up in LTP. This is
one of those that probably doesn't happen when runngin 32 on 32, but I'm
running 32 on 64.



Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149--- linux-user/syscall.c.orig   2007-03-20 01:25:39.0 -0400
+++ linux-user/syscall.c2007-03-20 02:32:39.0 -0400
@@ -2107,6 +2107,13 @@
 
 switch(cmd) {
 case TARGET_F_GETLK:
+lock_user_struct(target_fl, arg, 1);
+fl.l_type = tswap16(target_fl->l_type);
+fl.l_whence = tswap16(target_fl->l_whence);
+fl.l_start = tswapl(target_fl->l_start);
+fl.l_len = tswapl(target_fl->l_len);
+fl.l_pid = tswapl(target_fl->l_pid);
+unlock_user_struct(target_fl, arg, 0);
 ret = fcntl(fd, cmd, &fl);
 if (ret == 0) {
 lock_user_struct(target_fl, arg, 0);
___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


Re: [Qemu-devel] [PATCH] fcntl64 fix

2007-03-19 Thread Stuart Anderson


My initial fix was before I started using LTP, and just took care of a
single case that was holding me up. Now I have run the fcntl tests in
LTP on ARM (both oABI and EABI) and there are a lot of failures indicating
that there is a lot more work to be done yet on fcntl().

I'll take a look into it, and probably resubmit a bigger patch later.



Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149


___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


Re: [Qemu-devel] [PATCH] EABI fcntl on x86_64

2007-03-19 Thread Stuart Anderson

On Mon, 19 Mar 2007, Stuart Anderson wrote:


I have a debian arm chroot setup.


Just to clarify, this is from the applieddata.net repository, not the
normal debian one (which is not eabi).


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149


___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


[Qemu-devel] [PATCH] semctl support is incomplete

2007-03-19 Thread Stuart Anderson


The attached patch finishes adding support for semctl(). This was
verified on ARM using the semctl test from LTP in the target.


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149Index: linux-user/syscall.c
===
RCS file: /sources/qemu/qemu/linux-user/syscall.c,v
retrieving revision 1.93
diff -u -r1.93 syscall.c
--- linux-user/syscall.c19 Mar 2007 13:32:45 -  1.93
+++ linux-user/syscall.c19 Mar 2007 15:40:57 -
@@ -1123,12 +1123,152 @@
 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 *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);
+ip->__key = tswapl(target_ip->__key);
+ip->uid = tswapl(target_ip->uid);
+ip->gid = tswapl(target_ip->gid);
+ip->cuid = tswapl(target_ip->cuid);
+ip->cgid = tswapl(target_ip->cgid);
+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;
+
+lock_user_struct(target_su, target_addr, 1);
+switch( cmd ) {
+   case IPC_STAT:
+   case IPC_SET:
+  target_to_host_semid_ds(ds,target_su->buf);
+  host_su->buf = ds;
+  break;
+   default:
+  host_su->array = tswapl(target_su->array);
+}
+unlock_user_struct(target_su, target_addr, 0);
+}
+
+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;
+
+lock_user_struct(target_su, target_addr, 0);
+switch( cmd ) {
+   case IPC_STAT:
+   case IPC_SET:
+  host_to_target_semid_ds(target_su->buf,ds);
+  break;
+default:
+   target_su->arra

Re: [Qemu-devel] [PATCH] EABI fcntl on x86_64

2007-03-19 Thread Stuart Anderson

On Mon, 19 Mar 2007, Paul Brook wrote:


On Monday 19 March 2007 15:30, Stuart Anderson wrote:

When running ARM EABI binaries on x86_64, the target_eabi_flock64
structure is already padded correct so the padding is not needed.
This patch adds an #ifdef to only include the _pad member on 32-but
hosts.


This is wrong. The struct is packed, so its layout should be independent of
the host. How did you test your change?


I have a debian arm chroot setup. dpkg was unhappy, and I used gdb to
observe that there seemed to an extra 4 bytes of data in the middle of
the structure being passed into the host function.

I missed Kirill's patch as it came across before I got back on the list,
(and I missedit  when I browsed the archive as well). Since I should be
able to reproduce this, I'll test w/ his fix as well.



Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149


___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


[Qemu-devel] [PATCH] EABI fcntl on x86_64

2007-03-19 Thread Stuart Anderson


When running ARM EABI binaries on x86_64, the target_eabi_flock64
structure is already padded correct so the padding is not needed.
This patch adds an #ifdef to only include the _pad member on 32-but
hosts.


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149Index: linux-user/syscall_defs.h
===
RCS file: /sources/qemu/qemu/linux-user/syscall_defs.h,v
retrieving revision 1.30
diff -u -r1.30 syscall_defs.h
--- linux-user/syscall_defs.h   22 Oct 2006 00:18:54 -  1.30
+++ linux-user/syscall_defs.h   19 Mar 2007 15:25:58 -
@@ -1409,7 +1409,9 @@
 struct target_eabi_flock64 {
short  l_type;
short  l_whence;
+#if HOST_LONG_BITS == 32
 int __pad;
+#endif
unsigned long long l_start;
unsigned long long l_len;
int  l_pid;
___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


[Qemu-devel] [PATCH] Correct setuid behavious in linux-user

2007-03-19 Thread Stuart Anderson


The attached patch is needed to correctly emulate setuid executables.
With this change, and by making qemu be setuid root (and assumming all
of the risks and responsibilites of doing so), executables such as
/bin/su will be able to create the correct environment.


Stuart

Stuart R. Anderson   [EMAIL PROTECTED]
Network & Software Engineering   http://www.netsweng.com/
1024D/37A79149:  0791 D3B8 9A4C 2CDC A31F
 BD03 0A62 E534 37A7 9149Index: linux-user/linuxload.c
===
RCS file: /sources/qemu/qemu/linux-user/linuxload.c,v
retrieving revision 1.2
diff -u -r1.2 linuxload.c
--- linux-user/linuxload.c  19 Nov 2006 20:29:35 -  1.2
+++ linux-user/linuxload.c  19 Mar 2007 15:09:50 -
@@ -78,6 +78,8 @@
if(bprm->e_uid != geteuid()) {
id_change = 1;
}
+} else {
+  seteuid(getuid());
 }
 
 /* Set-gid? */
@@ -91,6 +93,8 @@
if (!in_group_p(bprm->e_gid)) {
id_change = 1;
}
+} else {
+  setegid(getgid());
 }
 
 memset(bprm->buf, 0, sizeof(bprm->buf));
___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel