qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] linux-user sysinfo support & do_sigreturn fix for i386-user
@ 2004-06-18 17:27 François Guimond
  2004-06-19 17:01 ` Fabrice Bellard
  0 siblings, 1 reply; 2+ messages in thread
From: François Guimond @ 2004-06-18 17:27 UTC (permalink / raw)
  To: qemu-devel


Heya folks...

I posted here I think a week or two ago about about deadlocks I had with 
qemu-i386 hoping one of the qemu developpers would be faster at finding the 
culprits.  Due to lack of feedback I guess my post was simply ignored.  
Anyway, since then I have successfully found the bug and fixed it, so this 
post includes the patch for it.  Also, in order to get the software I was 
attempting to run working, I had to implement the sysinfo syscall 
(previously 'unimplemented') so I figured I'd share that patch here too.

First is the fix to signal handling.  When I paid attention to strace's 
changes in sigprocmask, I realize that masks entering linux-user's signal 
processing handler would be wrong leaving the handler.  Upon further 
investigation I noticed that the mask was getting written in the sig frame 
using __put_user but getting restored by simple assignment, so in this case 
it would result in the wrong value as qemu-i386 was running on a PowerPC 
with a different endianess than a x86.   Looking around in the code I saw 
the 'generic' do_sigreturn used __get_user properly to retrieve it, so I 
copied over that bit of code into the x86 do_sigreturn, and it fixed the 
deadlock problem I was experiencing (which was caused by wrong sigprocmask). 
  Here's the related patch:

Index: linux-user/signal.c
===================================================================
RCS file: /cvsroot/qemu/qemu/linux-user/signal.c,v
retrieving revision 1.22
diff -u -r1.22 signal.c
--- linux-user/signal.c 22 Feb 2004 13:40:13 -0000      1.22
+++ linux-user/signal.c 18 Jun 2004 17:12:16 -0000
@@ -823,15 +823,17 @@
     struct sigframe *frame = (struct sigframe *)(env->regs[R_ESP] - 8);
     target_sigset_t target_set;
     sigset_t set;
-    int eax, i;
+    int eax;

#if defined(DEBUG_SIGNAL)
     fprintf(stderr, "do_sigreturn\n");
#endif
     /* set blocked signals */
-    target_set.sig[0] = frame->sc.oldmask;
-    for(i = 1; i < TARGET_NSIG_WORDS; i++)
-        target_set.sig[i] = frame->extramask[i - 1];
+    if (__get_user(target_set.sig[0], &frame->sc.oldmask)
+        || (TARGET_NSIG_WORDS > 1
+            && __copy_from_user(&target_set.sig[1], &frame->extramask,
+                                sizeof(frame->extramask))))
+            goto badframe;

     target_to_host_sigset(&set, &target_set);
     sigprocmask(SIG_SETMASK, &set, NULL);


The next problem I was running into was the sysinfo not implemented syscall. 
  The problem would just run in a loop waiting to get a decent result from 
it, so I had to implement (so far tested by me and two others, all running 
PowerMac G3s with qemu-i386 as the target).

Index: linux-user/syscall.c
===================================================================
RCS file: /cvsroot/qemu/qemu/linux-user/syscall.c,v
retrieving revision 1.49
diff -u -r1.49 syscall.c
--- linux-user/syscall.c        3 May 2004 19:23:07 -0000       1.49
+++ linux-user/syscall.c        18 Jun 2004 17:12:26 -0000
@@ -62,6 +62,9 @@
#include <linux/soundcard.h>
#include <linux/dirent.h>
#include <linux/kd.h>
+/* SYSINFO PATCH STARTS HERE */
+#include <sys/sysinfo.h>
+/* SYSINFO PATCH ENDS HERE */

#include "qemu.h"

@@ -230,6 +233,9 @@
#ifdef __NR_exit_group
_syscall1(int,exit_group,int,error_code)
#endif
+/* SYSINFO PATCH STARTS HERE */
+_syscall1(int,sysinfo,struct sysinfo *,info)
+/* SYSINFO PATCH ENDS HERE */

extern int personality(int);
extern int flock(int, int);
@@ -2348,7 +2354,31 @@
         ret = get_errno(swapoff((const char *)arg1));
         break;
     case TARGET_NR_sysinfo:
-        goto unimplemented;
+/* SYSINFO PATCH STARTS HERE */
+        {
+            struct target_sysinfo *target_value = (void *)arg1;
+            struct sysinfo value;
+            ret = get_errno(sysinfo(&value));
+            if (!is_error(ret) && target_value)
+            {
+                target_value->uptime = tswapl(value.uptime);
+                target_value->loads[0] = tswapl(value.loads[0]);
+                target_value->loads[1] = tswapl(value.loads[1]);
+                target_value->loads[2] = tswapl(value.loads[2]);
+                target_value->totalram = tswapl(value.totalram);
+                target_value->freeram = tswapl(value.freeram);
+                target_value->sharedram = tswapl(value.sharedram);
+                target_value->bufferram = tswapl(value.bufferram);
+                target_value->totalswap = tswapl(value.totalswap);
+                target_value->freeswap = tswapl(value.freeswap);
+                target_value->procs = tswap16(value.procs);
+                target_value->totalhigh = tswapl(value.totalhigh);
+                target_value->freehigh = tswapl(value.freehigh);
+                target_value->mem_unit = tswap32(value.mem_unit);
+            }
+        }
+        break;
+/* SYSINFO PATCH ENDS HERE */
     case TARGET_NR_ipc:
        ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
        break;
Index: linux-user/syscall_defs.h
===================================================================
RCS file: /cvsroot/qemu/qemu/linux-user/syscall_defs.h,v
retrieving revision 1.20
diff -u -r1.20 syscall_defs.h
--- linux-user/syscall_defs.h   22 Feb 2004 14:57:26 -0000      1.20
+++ linux-user/syscall_defs.h   18 Jun 2004 17:12:27 -0000
@@ -1133,3 +1133,22 @@
/* vfat ioctls */
#define TARGET_VFAT_IOCTL_READDIR_BOTH    TARGET_IORU('r', 1)
#define TARGET_VFAT_IOCTL_READDIR_SHORT   TARGET_IORU('r', 2)
+/* SYSINFO PATCH STARTS HERE */
+/* from <linux/kernel.h> */
+struct target_sysinfo {
+    target_long uptime;             /* Seconds since boot */
+    target_ulong loads[3];          /* 1, 5, and 15 minute load averages */
+    target_ulong totalram;          /* Total usable main memory size */
+    target_ulong freeram;           /* Available memory size */
+    target_ulong sharedram;         /* Amount of shared memory */
+    target_ulong bufferram;         /* Memory used by buffers */
+    target_ulong totalswap;         /* Total swap space size */
+    target_ulong freeswap;          /* swap space still available */
+    unsigned short procs;           /* Number of current processes */
+    unsigned short pad;             /* explicit padding for m68k */
+    target_ulong totalhigh;         /* Total high memory size */
+    target_ulong freehigh;          /* Available high memory size */
+    unsigned int mem_unit;          /* Memory unit size in bytes */
+    char _f[20-2*sizeof(target_long)-sizeof(int)]; /* Padding: libc5 uses 
this.. */
+};
+/* SYSINFO PATCH ENDS HERE */

_________________________________________________________________
STOP MORE SPAM with the MSN Premium and get 2 months FREE*    
http://join.msn.com/?pgmarket=en-ca&page=byoa/prem&xAPID=1994&DI=1034&SU=http://hotmail.com/enca&HL=Market_MSNIS_Taglines

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

end of thread, other threads:[~2004-06-19 17:00 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-06-18 17:27 [Qemu-devel] [PATCH] linux-user sysinfo support & do_sigreturn fix for i386-user François Guimond
2004-06-19 17:01 ` Fabrice Bellard

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).