[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH] linux-user sysinfo support & do_sigreturn fix for i
From: |
François Guimond |
Subject: |
[Qemu-devel] [PATCH] linux-user sysinfo support & do_sigreturn fix for i386-user |
Date: |
Fri, 18 Jun 2004 13:27:37 -0400 |
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
- [Qemu-devel] [PATCH] linux-user sysinfo support & do_sigreturn fix for i386-user,
François Guimond <=