Re: [Qemu-devel] [PATCH] qemu: generate signals on tap I/O

2008-02-16 Thread Anders Melchiorsen
Aurelien Jarno [EMAIL PROTECTED] writes:

 The patch below from KVM improves network transfers in a huge way. 
 wget in a MIPS target now gives me a transfer speed of up to 120
 Mbits/s with an e1000 emulated card.

Without I/O signals, qemu is relying on periodic timer events to poll
the I/O. That seems wrong, even though it works reasonably well
because timers are so frequent. In KVM, timers are less frequent, and
it does not work quite as well.

Here is a quick try at a more elaborate patch.

It attaches a signal to all[1] file descriptors that will be used in
select(). Also, it uses a dedicated SIGIO handler rather than
piggybacking on the alarm handler, so alarm I/O is changed to use
SIGALRM.

I copied the handler function from the alarm case, quite frankly I do
not quite understand what is going on. Also, I left _WIN32 out, since
I have no idea how signals work there.


[1] The slirp file descriptors are not included yet.


Anders.




diff --git a/vl.c b/vl.c
index c87e8bc..ff8ceef 100644
--- a/vl.c
+++ b/vl.c
@@ -1148,6 +1148,25 @@ static int timer_load(QEMUFile *f, void *opaque, int 
version_id)
 return 0;
 }
 
+#ifndef _WIN32
+static void host_io_handler(int host_signum)
+{
+CPUState *env = next_cpu;
+
+if (env) {
+/* stop the currently executing cpu because io occured */
+cpu_interrupt(env, CPU_INTERRUPT_EXIT);
+#ifdef USE_KQEMU
+if (env-kqemu_enabled) {
+kqemu_cpu_interrupt(env);
+}
+#endif
+}
+
+event_pending = 1;
+}
+#endif
+
 #ifdef _WIN32
 void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg,
  DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR 
dw2)
@@ -1240,7 +1259,20 @@ static uint64_t qemu_next_deadline(void)
 
 #define RTC_FREQ 1024
 
-static void enable_sigio_timer(int fd)
+static void enable_sigio(int fd)
+{
+struct sigaction act;
+
+sigfillset(act.sa_mask);
+act.sa_flags = 0;
+act.sa_handler = host_io_handler;
+
+sigaction(SIGIO, act, NULL);
+fcntl(fd, F_SETFL, O_ASYNC);
+fcntl(fd, F_SETOWN, getpid());
+}
+
+static void enable_sigalrm(int fd)
 {
 struct sigaction act;
 
@@ -1249,8 +1281,9 @@ static void enable_sigio_timer(int fd)
 act.sa_flags = 0;
 act.sa_handler = host_alarm_handler;
 
-sigaction(SIGIO, act, NULL);
+sigaction(SIGALRM, act, NULL);
 fcntl(fd, F_SETFL, O_ASYNC);
+fcntl(fd, F_SETSIG, SIGALRM);
 fcntl(fd, F_SETOWN, getpid());
 }
 
@@ -1287,7 +1320,7 @@ static int hpet_start_timer(struct qemu_alarm_timer *t)
 if (r  0)
 goto fail;
 
-enable_sigio_timer(fd);
+enable_sigalrm(fd);
 t-priv = (void *)(long)fd;
 
 return 0;
@@ -1325,7 +1358,7 @@ static int rtc_start_timer(struct qemu_alarm_timer *t)
 return -1;
 }
 
-enable_sigio_timer(rtc_fd);
+enable_sigalrm(rtc_fd);
 
 t-priv = (void *)(long)rtc_fd;
 
@@ -5481,6 +5514,10 @@ int qemu_set_fd_handler2(int fd,
 return -1;
 ioh-next = first_io_handler;
 first_io_handler = ioh;
+#ifndef _WIN32
+enable_sigio(fd);
+#endif
+
 found:
 ioh-fd = fd;
 ioh-fd_read_poll = fd_read_poll;




[Qemu-devel] Patch for compiling with GCC 4

2008-02-16 Thread Christian Roue
Hi all,
I tried to compile qemu cvs head on my x86_64 linux with gcc 4.1.2 using
--disable-gcc-check, I found compile fails as stated in configure before i
disabled gcc check..
Error message, points to a problem of dyngen not correctly detecting
function ends on i386 when last instruction is a jump. I applied following
change and successfully compiled/run qemu i386.  This extra test check for
a relative backward jump  to function exit ret,
gcc 4 apparently generates a few of these.

My small change to cvs head is :

--- dyngen.c   2008-02-13 18:54:36.0 +0100
+++ dyngen.c2008-02-13 19:10:14.0 +0100
@@ -1474,7 +1474,7 @@
 len = p_end - p_start;
 if (len == 0)
 error(empty code for %s, name);
-if (p_end[-1] == 0xc3) {
+if (p_end[-1] == 0xc3 || p_end[-2] == 0xeb) {
 len--;
 } else {
 error(ret or jmp expected at the end of %s, name);

Bye
Chris.


[Qemu-devel] Qemu emulation for PXA320 based board

2008-02-16 Thread Arabinda Verma
Hello list!

 

I am a newbie to QEMU.

 

I have a PXA320 based target board and linux kernel which runs on it.

 

I want to emulate the board on QEMU. Kindly, let me know how I can go about.

 

Your help in this regard is highly appreciated. Any pointer, guidelines even
direction to right path will be very helpful.

 

Thanks in advance.

 

Regards

Devel.



Re: [Qemu-devel] BOCHS update with DMI functional

2008-02-16 Thread Robert Riebisch
Ryan Harper wrote:

 I've already built the latest BOCHS and tested it myself, what I'm

Oh, I see.

 looking for is what other testing and such needs to be done prior to
 getting QEMU to pull in a newer version of BOCHS.

Sorry, that nobody else seems to be interested. :-(

Robert Riebisch
-- 
BTTR Software
http://www.bttr-software.de/




Re: [Qemu-devel] How to extract content of a raw image on host?

2008-02-16 Thread Stuart Brady
On Sat, Feb 16, 2008 at 08:55:06AM +0100, Laurent Vivier wrote:
 Loop is not able to manage partition.

You could use kpartx (from util-linux), which will create device nodes 
for each partition.

Cheers,
-- 
Stuart Brady




[Qemu-devel] [PATCH] KQEMU error checking

2008-02-16 Thread Leonardo Reiter
Hello,

in recent days I've been able to consistently panic an OpenSolaris
kernel (build 79b, 64-bit on dual-core Opteron with 4GB of RAM) by
using KQEMU and running qemu with a -m (memory) parameter greater than
about 1750.  The panic would be due to a NULL pointer dereference and
happen mainly in kqemu_init().  On Linux this does not seem to be a
problem for some reason.

Anyway, while nowhere near understanding root cause yet, I did sweep
the code and came up with a patch to check for errors of certain
internal functions - particularly errors that could eventually lead to
NULL pointer dereferences, etc.  So now either the kernel call will
fail (and userspace will deal with it accordingly), or the monitor
will just crash the running qemu process rather than panic the kernel
if one of these error situations happens.  What I discovered is that
almost, if not all of these error situations come from the return
value of the function get_vaddr() in common/common.c not being checked
by its callers.  get_vaddr() can return -1 if there is no virtual
address available, but its callers were often assuming the return
value was valid.  Particularly common/mon_get_ptep_l3() would ignore
it, and quickly lead to a kernel panic.  I did not try the non-PAE
version but I addressed it anyway with my patch.

I was able to identify 2 distinct situations that would lead to a
kernel panic, driven by the -m parameter from userspace.  The first,
if -m 1750, was likely due to mon_user_map() in common/kernel.c
ignoring the return from get_vaddr().  I am not 100% sure about that
as it was very difficult to debug this with the Solaris kernel
debugger, but that's what I believe right now.  The second and more
traceable problem came when using a value greater than or equal to
about 1800 for -m.  That would crash consistently in kqemu_init() in
common/kernel.c around line 564 where the monitor PTE pages are cloned
in each address space.  The result was that mon_get_ptep_l3() was
ignoring a -1 return value from get_vaddr(), and in turn, kqemu_init()
was also ignoring a potential NULL return value from
mon_get_ptep_l3(), leading to a dereference of a NULL pointer.

My patch below may have detected one condition that is not really an
error, in phys_page_find() of common/monitor.c.  The return of
get_vaddr() there is not actually dereferenced, so I'm not sure that
when it gets passed into set_vaddr_page_index() it's okay for it to be
-1.  Still, this situation does happen (the monitor panic) if you run
qemu -m 1500 or so (I didn't compute exact values that trigger it,
sorry), and the guest (i.e. Windows 2000) runs for a while.  Note that
the errors do not seem to be related to using -m values that are
powers of 10 instead of powers of 2 - I tried either.

While it's important that a userspace process never panic a kernel,
I'm sure some of the error checking below is not accurate or may mask
another problem that should be fixed rather than detected.  If someone
who understands the KQEMU code better than me can take a look, I would
appreciate it.  Note that I have both inlined and attached the patch
for easy handling.  The patch is against the latest KQEMU, and applies
to either the one on www.qemu.org or the one from the OpenSolaris
project cleanly.

Special thanks to Juergen Keil for helping me with the Solaris kernel
debugger (off list).

Best regards,

Leo Reiter

diff -Naur kqemu_1.0.3pre11-20070520/common/common.c
kqemu_1.0.3pre11-20070520.new/common/common.c
--- kqemu_1.0.3pre11-20070520/common/common.c   2007-05-20
07:35:07.0 -0400
+++ kqemu_1.0.3pre11-20070520.new/common/common.c   2008-02-15
16:29:21.0 -0500
@@ -252,6 +252,8 @@
 pdp_page_index = pml4e  PAGE_SHIFT;
 }
 pdp_page = page_index_to_addr(s, pdp_page_index);
+if (!pdp_page)
+return NULL;

 pdpe_index = (vaddr  30)  0x1ff;
 pdpe = pdp_page[pdpe_index];
@@ -267,6 +269,8 @@
 pde_page_index = pdpe  PAGE_SHIFT;
 }
 pde_page = page_index_to_addr(s, pde_page_index);
+if (!pde_page)
+return NULL;

 pde_index = (vaddr  21)  0x1ff;
 if (alloc == 2)
@@ -284,6 +288,8 @@
 pte_page_index = pde  PAGE_SHIFT;
 }
 pte_page = page_index_to_addr(s, pte_page_index);
+if (!pte_page)
+return NULL;/* XXX - ?? we don't dereference pte_page here */

 pte_index = (vaddr  12)  0x1ff;
 #ifndef IN_MONITOR
@@ -331,6 +337,8 @@
 pde_page_index = pdpe  PAGE_SHIFT;
 }
 pde_page = page_index_to_addr(s, pde_page_index);
+if (!pde_page)
+return NULL;

 pde_index = (vaddr  21)  0x1ff;
 if (alloc == 2)
@@ -348,6 +356,8 @@
 pte_page_index = pde  PAGE_SHIFT;
 }
 pte_page = page_index_to_addr(s, pte_page_index);
+if (!pte_page)
+return NULL;/* XXX - ?? we don't dereference pte_page here */

 pte_index = (vaddr  12)  0x1ff;
 #ifndef IN_MONITOR
@@ -387,6 +397,9 @@
 pte_page_index = pde  PAGE_SHIFT;
 }
 

[Qemu-devel] qemu-system-amd64 (0.9.1) and freebsd guest - irq patch (pointer)

2008-02-16 Thread Juergen Lock
Hi!

 I received the following posting and patch, sent to the freebsd-emulation
list, can anyone here say if it is correct, and if yes, apply?
http://docs.freebsd.org/cgi/mid.cgi?20080216164331.GJ57756
(You can use the `Raw E-Mail' link to get the unmangled patch out.)

 Thanx,
Juergen




Re: [Qemu-devel] Patch for compiling with GCC 4

2008-02-16 Thread Paul Brook
On Saturday 16 February 2008, Christian Roue wrote:
 Hi all,
 I tried to compile qemu cvs head on my x86_64 linux with gcc 4.1.2 using
 --disable-gcc-check, I found compile fails as stated in configure before i
 disabled gcc check..
 Error message, points to a problem of dyngen not correctly detecting
 function ends on i386 when last instruction is a jump. I applied following
 change and successfully compiled/run qemu i386.  This extra test check for
 a relative backward jump  to function exit ret,
 gcc 4 apparently generates a few of these.

You patch is wrong. The dyngen error is correct.

Paul




[Qemu-devel] [PATCH] mmap.c: Reuse unmapped memory areas.

2008-02-16 Thread Edgar E. Iglesias
Try to rewind mmap_next_start when unmapping memory. Simple tests in 
test-mmap.c now pass.

Best regards
-- 
Edgar E. Iglesias
Axis Communications AB

diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index 6292826..78a8162 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -385,6 +385,9 @@ int target_munmap(abi_ulong start, abi_ulong len)
 real_end -= qemu_host_page_size;
 }
 
+if (start  mmap_next_start)
+   mmap_next_start = start;
+
 /* unmap what we can */
 if (real_start  real_end) {
 ret = munmap(g2h(real_start), real_end - real_start);




Re: [Qemu-devel] [PATCH] possible mmap regression

2008-02-16 Thread Edgar E. Iglesias
On Tue, Feb 12, 2008 at 09:42:15PM +0200, Felipe Contreras wrote:
 Hi,
 
 I don't know what I'm doing but this seems to fix the weird issue I was 
 having.
 http://article.gmane.org/gmane.comp.emulators.qemu/23314
 
 I've found out that this happens on linux 2.6.23, but not 2.6.24.
 
 Cheers.
 
 -- 
 Felipe Contreras
 diff --git a/linux-user/mmap.c b/linux-user/mmap.c
 index 6292826..3050ad9 100644
 --- a/linux-user/mmap.c
 +++ b/linux-user/mmap.c
 @@ -251,7 +251,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int 
 prot,
 especially important if qemu_host_page_size 
 qemu_real_host_page_size */
  p = mmap(g2h(mmap_start),
 - host_len, prot, flags | MAP_FIXED, fd, host_offset);
 + host_len, prot, flags, fd, host_offset);
  if (p == MAP_FAILED)
  return -1;
  /* update start so that it points to the file position at 'offset' */

Hello,

Sorry, but I beleive your patch will break simulations where the targets 
pagesize is larger than the hosts.

Would you mind trying the attach patched and let us know if it helps for you?
If not, it would be great if you could provide a small test case that trigs the 
bug you are seeing so we can debug the problem.

Best regards
-- 
Edgar E. Iglesias
Axis Communications AB

diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index 6292826..78a8162 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -385,6 +385,9 @@ int target_munmap(abi_ulong start, abi_ulong len)
 real_end -= qemu_host_page_size;
 }
 
+if (start  mmap_next_start)
+   mmap_next_start = start;
+
 /* unmap what we can */
 if (real_start  real_end) {
 ret = munmap(g2h(real_start), real_end - real_start);




[Qemu-devel] [PATCH] linux-user/mmap: Testsuite + bugfixes

2008-02-16 Thread Edgar E. Iglesias
Hi again,

I spent some more time creating more mmap test-cases and managed to trig a few
more bugs. Luckily, most of them were straight forward to fix. A few are
related to the funny semantics of MAP_FILE mmaps beyond EOF.
This posts elaborates a bit more on the issue:
http://lists.gnu.org/archive/html/qemu-devel/2008-01/msg00163.html

Tested on my intel centrino duo as host, for CRIS, MIPS and i386 targets. Used
the -p flag to simulate 8K, 16K and 32K page-sizes.

To run the tests for i386 just do a 'make -C tests test-mmap'.

I hope this is helpful to somebody.

Best regards
-- 
Edgar E. Iglesias
Axis Communications AB

diff --git a/configure b/configure
index bbda3f7..3df08ab 100755
--- a/configure
+++ b/configure
@@ -1244,6 +1244,7 @@ if test $source_path_used = yes ; then
 DIRS=tests tests/cris slirp audio
 FILES=Makefile tests/Makefile
 FILES=$FILES tests/cris/Makefile tests/cris/.gdbinit
+FILES=$FILES tests/test-mmap.c
 for dir in $DIRS ; do
 mkdir -p $dir
 done
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index 6292826..3c77cc9 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -23,6 +23,8 @@
 #include string.h
 #include unistd.h
 #include errno.h
+#include sys/types.h
+#include sys/stat.h
 #include sys/mman.h
 
 #include qemu.h
@@ -153,10 +155,12 @@ static int mmap_frag(abi_ulong real_start,
 
 #if defined(__CYGWIN__)
 /* Cygwin doesn't have a whole lot of address space.  */
-static abi_ulong mmap_next_start = 0x1800;
+#define MMAP_BASE 0x1800
 #else
-static abi_ulong mmap_next_start = 0x4000;
+#define MMAP_BASE 0x4000
 #endif
+static abi_ulong mmap_next_start = MMAP_BASE;
+
 
 /* find a free memory area of size 'size'. The search starts at
'start'. If 'start' == 0, then a default start address is used.
@@ -234,8 +238,40 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int 
prot,
 len = TARGET_PAGE_ALIGN(len);
 if (len == 0)
 return start;
-real_start = start  qemu_host_page_mask;
 
+/* When mapping files into a memory area larger than the file, accesses
+   to pages beyond the file size will cause a SIGBUS. 
+
+   For example, if mmaping a file of 100 bytes on a host with 4K pages
+   emulating a target with 8K pages, the target expects to be able to
+   access the first 8K. But the host will trap us on any access beyond
+   4K.  
+
+   When emulating a target with a larger page-size than the hosts, we
+   may need to truncate file maps at EOF and add extra anonymous pages
+   up to the targets page boundary.  */
+
+if (!(flags  MAP_ANONYMOUS)) {
+struct stat sb;
+   
+   if (fstat (fd, sb) == -1)
+   return -1;
+   
+   /* Are trying to create a map beyond the EOF?.  */
+   if (offset + len  sb.st_size) {
+   /* If so, truncate the file map at eof aligned with 
+  the hosts real pagesize. Additional anonymous maps
+  will be created beyond EOF.  */
+   len = (sb.st_size - offset);
+   len += qemu_real_host_page_size - 1;
+   len = ~(qemu_real_host_page_size - 1);
+   }
+}
+
+real_start = start  qemu_host_page_mask;
+end = start + len;
+real_end = HOST_PAGE_ALIGN(end);
+ 
 if (!(flags  MAP_FIXED)) {
 abi_ulong mmap_start;
 void *p;
@@ -251,9 +287,17 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int 
prot,
especially important if qemu_host_page_size 
qemu_real_host_page_size */
 p = mmap(g2h(mmap_start),
- host_len, prot, flags | MAP_FIXED, fd, host_offset);
+ len, prot, flags | MAP_FIXED, fd, host_offset);
 if (p == MAP_FAILED)
 return -1;
+
+   /* If we are dealing with truncated file maps due to pagesize
+* differences between host and target we may need to append
+* an anonymous mapping.  */
+   if (len  host_len)
+   mmap(g2h(mmap_start) + len, qemu_host_page_size, 
+prot, flags | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
+
 /* update start so that it points to the file position at 'offset' */
 host_start = (unsigned long)p;
 if (!(flags  MAP_ANONYMOUS))
@@ -264,8 +308,6 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int 
prot,
 errno = EINVAL;
 return -1;
 }
-end = start + len;
-real_end = HOST_PAGE_ALIGN(end);
 
 /* worst case: we cannot map the file because the offset is not
aligned, so we read it */
@@ -337,7 +379,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int 
prot,
 page_set_flags(start, start + len, prot | PAGE_VALID);
  the_end:
 #ifdef DEBUG_MMAP
-printf(ret=0x%llx\n, start);
+printf(ret=0x TARGET_FMT_lx \n, start);
 page_dump(stdout);
 printf(\n);
 #endif
@@ -385,6 +427,8 @@ int target_munmap(abi_ulong start, abi_ulong len)