qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] Armv5 target
@ 2005-01-31 20:19 Paul Brook
  2005-01-31 22:44 ` Lennert Buytenhek
  0 siblings, 1 reply; 12+ messages in thread
From: Paul Brook @ 2005-01-31 20:19 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 374 bytes --]

The attached patch implements the full armv5te user mode instruction set.

This consists of a few new instructions (saturating arithmetic, dsp multiply, 
doubleword load/store) and thumb mode.

I've successfully run the gcc testsuite in arm mode for both armv4 and 
armv5te. I don't yet have a thumb-capable linux userspace, so thumb mode has 
only had light testing.

Paul

[-- Attachment #2: patch.qemu_5e.gz --]
[-- Type: application/x-gzip, Size: 6813 bytes --]

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

* Re: [Qemu-devel] Armv5 target
  2005-01-31 20:19 [Qemu-devel] Armv5 target Paul Brook
@ 2005-01-31 22:44 ` Lennert Buytenhek
  2005-01-31 23:13   ` Paul Brook
  0 siblings, 1 reply; 12+ messages in thread
From: Lennert Buytenhek @ 2005-01-31 22:44 UTC (permalink / raw)
  To: qemu-devel

Hi,


On Mon, Jan 31, 2005 at 08:19:44PM +0000, Paul Brook wrote:

> The attached patch implements the full armv5te user mode instruction set.

Thanks for persisting on this!

You posted this patch on 20040802 -- is it still needed?


cheers,
Lennert


Index: cpu-exec.c
===================================================================
RCS file: /cvsroot/qemu/qemu/cpu-exec.c,v
retrieving revision 1.38
diff -u -p -r1.38 cpu-exec.c
--- cpu-exec.c  14 Jul 2004 17:20:55 -0000      1.38
+++ cpu-exec.c  2 Aug 2004 00:24:46 -0000
@@ -718,6 +719,10 @@ static inline int handle_cpu_signal(unsi
                                     int is_write, sigset_t *old_set,
                                     void *puc)
 {
+    /* XXX: locking issue */
+    if (is_write && page_unprotect(address, pc, puc)) {
+        return 1;
+    }
     /* XXX: do more */
     return 0;
 }

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

* Re: [Qemu-devel] Armv5 target
  2005-01-31 22:44 ` Lennert Buytenhek
@ 2005-01-31 23:13   ` Paul Brook
  2005-02-02  1:26     ` Paul Brook
  0 siblings, 1 reply; 12+ messages in thread
From: Paul Brook @ 2005-01-31 23:13 UTC (permalink / raw)
  To: qemu-devel

On Monday 31 January 2005 22:44, Lennert Buytenhek wrote:
> Hi,
>
> On Mon, Jan 31, 2005 at 08:19:44PM +0000, Paul Brook wrote:
> > The attached patch implements the full armv5te user mode instruction set.
>
> Thanks for persisting on this!
>
> You posted this patch on 20040802 -- is it still needed?
>
> Index: cpu-exec.c
> ===================================================================
> RCS file: /cvsroot/qemu/qemu/cpu-exec.c,v
> retrieving revision 1.38
> diff -u -p -r1.38 cpu-exec.c
> --- cpu-exec.c  14 Jul 2004 17:20:55 -0000      1.38
> +++ cpu-exec.c  2 Aug 2004 00:24:46 -0000
> @@ -718,6 +719,10 @@ static inline int handle_cpu_signal(unsi
>                                      int is_write, sigset_t *old_set,
>                                      void *puc)
>  {
> +    /* XXX: locking issue */
> +    if (is_write && page_unprotect(address, pc, puc)) {
> +        return 1;
> +    }
>      /* XXX: do more */
>      return 0;
>  }

Sort of. Self-modifying code (e.g. stack trampolines) are still broken, and 
the patch above should work.

However I just tested it and it doesn't seem to work any more. It seems that 
the SEGV handler is being passed an address of 0, rather than the actual 
faulting location.

This may be a host kernel/libc bug.

Paul

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

* Re: [Qemu-devel] Armv5 target
  2005-01-31 23:13   ` Paul Brook
@ 2005-02-02  1:26     ` Paul Brook
  2005-02-02 12:01       ` Lennert Buytenhek
  0 siblings, 1 reply; 12+ messages in thread
From: Paul Brook @ 2005-02-02  1:26 UTC (permalink / raw)
  To: qemu-devel

> > +    /* XXX: locking issue */
> > +    if (is_write && page_unprotect(address, pc, puc)) {
> > +        return 1;
> > +    }
> >      /* XXX: do more */
> >      return 0;
> >  }
>
> Sort of. Self-modifying code (e.g. stack trampolines) are still broken, and
> the patch above should work.
>
> However I just tested it and it doesn't seem to work any more. It seems
> that the SEGV handler is being passed an address of 0, rather than the
> actual faulting location.
>
> This may be a host kernel/libc bug.

I just tried on a few different machines, and this is a host kernel bug 
specific to one particular kernel (custom 2.6.9).

However I don't think this is the best solution.  arm-linux has an instruction 
cache flush syscall, so we should be hooking into that instead.

Paul

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

* Re: [Qemu-devel] Armv5 target
  2005-02-02  1:26     ` Paul Brook
@ 2005-02-02 12:01       ` Lennert Buytenhek
  2005-02-02 15:47         ` Paul Brook
  0 siblings, 1 reply; 12+ messages in thread
From: Lennert Buytenhek @ 2005-02-02 12:01 UTC (permalink / raw)
  To: qemu-devel

On Wed, Feb 02, 2005 at 01:26:37AM +0000, Paul Brook wrote:

> > > +    /* XXX: locking issue */
> > > +    if (is_write && page_unprotect(address, pc, puc)) {
> > > +        return 1;
> > > +    }
> > >      /* XXX: do more */
> > >      return 0;
> > >  }
> >
> > Sort of. Self-modifying code (e.g. stack trampolines) are still broken, and
> > the patch above should work.
> >
> > However I just tested it and it doesn't seem to work any more. It seems
> > that the SEGV handler is being passed an address of 0, rather than the
> > actual faulting location.
> >
> > This may be a host kernel/libc bug.
> 
> I just tried on a few different machines, and this is a host kernel bug 
> specific to one particular kernel (custom 2.6.9).

Do you have some example code that demonstrates this?


thanks,
Lennert

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

* Re: [Qemu-devel] Armv5 target
  2005-02-02 12:01       ` Lennert Buytenhek
@ 2005-02-02 15:47         ` Paul Brook
  2005-02-02 18:18           ` Ulrich Hecht
  2005-02-03  9:59           ` Sylvain Petreolle
  0 siblings, 2 replies; 12+ messages in thread
From: Paul Brook @ 2005-02-02 15:47 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 1225 bytes --]

On Wednesday 02 February 2005 12:01, Lennert Buytenhek wrote:
> On Wed, Feb 02, 2005 at 01:26:37AM +0000, Paul Brook wrote:
> > > > +    /* XXX: locking issue */
> > > > +    if (is_write && page_unprotect(address, pc, puc)) {
> > > > +        return 1;
> > > > +    }
> > > >      /* XXX: do more */
> > > >      return 0;
> > > >  }
> > >
> > > Sort of. Self-modifying code (e.g. stack trampolines) are still broken,
> > > and the patch above should work.
> > >
> > > However I just tested it and it doesn't seem to work any more. It seems
> > > that the SEGV handler is being passed an address of 0, rather than the
> > > actual faulting location.
> > >
> > > This may be a host kernel/libc bug.
> >
> > I just tried on a few different machines, and this is a host kernel bug
> > specific to one particular kernel (custom 2.6.9).
>
> Do you have some example code that demonstrates this?

I've attached two programs. segv-test.c tests for the kernel bug. nest_test.c 
tests stack trampolines, which exposes the bug then run inside qemu-user.

Note that the proper fix for arm is to remove the ||1 hack on the 
TARGET_HAS_SMC tests in exec.c. Comments indicate this hack is to work around 
bugs in the PPC emulation.

Paul

[-- Attachment #2: segv_test.c --]
[-- Type: text/x-csrc, Size: 845 bytes --]

/* Test that gatching SIGSEGV gives the correct fault address.  */
#include <stdio.h>
#include <signal.h>
#include <sys/mman.h>
#include <stdio.h>

void * volatile p = NULL;
void * volatile block;

void foo(int n, siginfo_t *info, void *data)
{
  p = info->si_addr;
  printf ("%p\n", block);
  mprotect(block, sizeof(int), PROT_READ | PROT_WRITE);
}

int main()
{
  struct sigaction sa;

  p = &sa;
  memset (&sa, 0, sizeof(sa));
  sa.sa_sigaction = foo;
  sa.sa_flags = SA_SIGINFO;
  sigaction (SIGSEGV, &sa, NULL);
  block = mmap(NULL, sizeof(int), PROT_READ, MAP_SHARED|MAP_ANONYMOUS, 0, 0);
  if (block == MAP_FAILED)
    {
      printf ("mmap failed\n");
      return 1;
    }
  *(volatile int *) block = 42;
  sleep(1);
  if (p != block)
    printf ("FAIL: expected %p, got %p\n",  block, p);
  else
    printf ("OK\n");
  
  return 0;
}


[-- Attachment #3: nest_test.c --]
[-- Type: text/x-csrc, Size: 273 bytes --]

/* Test stack trampolines (nested functions).  */
/* Should print "Hello nested world". */
#include <stdio.h>

void bar(void (*)())
{
  f();
}
int main()
{
  void f()
    {
      printf ("nested ");
    }
  printf ("Hello ");
  bar(f);
  printf ("world\n");
  return 0;
}


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

* Re: [Qemu-devel] Armv5 target
  2005-02-02 15:47         ` Paul Brook
@ 2005-02-02 18:18           ` Ulrich Hecht
  2005-02-02 19:17             ` Paul Brook
  2005-02-03  9:59           ` Sylvain Petreolle
  1 sibling, 1 reply; 12+ messages in thread
From: Ulrich Hecht @ 2005-02-02 18:18 UTC (permalink / raw)
  To: qemu-devel

Hi!

On Wednesday 02 February 2005 16:47, Paul Brook wrote:
> On Wednesday 02 February 2005 12:01, Lennert Buytenhek wrote:
> > On Wed, Feb 02, 2005 at 01:26:37AM +0000, Paul Brook wrote:
> > > > > +    /* XXX: locking issue */
> > > > > +    if (is_write && page_unprotect(address, pc, puc)) {
> > > > > +        return 1;
> > > > > +    }
> > > > >      /* XXX: do more */
> > > > >      return 0;
> > > > >  }
> > > >
> > > > Sort of. Self-modifying code (e.g. stack trampolines) are still
> > > > broken, and the patch above should work.
> > > >
> > > > However I just tested it and it doesn't seem to work any more.
> > > > It seems that the SEGV handler is being passed an address of 0,
> > > > rather than the actual faulting location.
> > > >
> > > > This may be a host kernel/libc bug.
> > >
> > > I just tried on a few different machines, and this is a host
> > > kernel bug specific to one particular kernel (custom 2.6.9).
> >
> > Do you have some example code that demonstrates this?
>
> I've attached two programs. segv-test.c tests for the kernel bug.

This program hangs in an endless segfault loop when I run it in qemu-arm. 
The kernel version does not seem to matter here, I have tried 2.6.11, 
2.6.5 and 2.4.21. Has anybody ever observed this and/or knows what it is 
caused by? (The test works fine on i386 and on a real ARM machine.)

CU
Uli

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

* Re: [Qemu-devel] Armv5 target
  2005-02-02 18:18           ` Ulrich Hecht
@ 2005-02-02 19:17             ` Paul Brook
  2005-02-03 14:08               ` Ulrich Hecht
  0 siblings, 1 reply; 12+ messages in thread
From: Paul Brook @ 2005-02-02 19:17 UTC (permalink / raw)
  To: qemu-devel

> > I've attached two programs. segv-test.c tests for the kernel bug.
>
> This program hangs in an endless segfault loop when I run it in qemu-arm.
> The kernel version does not seem to matter here, I have tried 2.6.11,
> 2.6.5 and 2.4.21. Has anybody ever observed this and/or knows what it is
> caused by? (The test works fine on i386 and on a real ARM machine.)

The host kernel bug seems specific to this particular kernel. I've tried other 
2.6.9 kernels on different machines, and a 2.6.10 kernel on this machine, and 
they all work ok. I guess it's a fluke miscompilation or something.

The reason it goes into an infinite loop when run under qemu is as follows:

The generated code causes a segfault trying to write to protected memory.
On a real machine the signal handler unprotects the memory, and keeps going.
Inside qemu the host signal handler just queues the target signal. For most 
signals this is ok; the target handler will be invoke at the end of the TB. 
However in this case we need to run the target handler immediately, otherwise 
the segv will occur again when we try and continue.

I think fixing this requires executing the target signal handler code from 
within the host signal handler. As an added complication we only want to do 
this for signals received while executing target code.

Paul

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

* Re: [Qemu-devel] Armv5 target
  2005-02-02 15:47         ` Paul Brook
  2005-02-02 18:18           ` Ulrich Hecht
@ 2005-02-03  9:59           ` Sylvain Petreolle
  2005-02-03 11:25             ` Ulrich Hecht
  1 sibling, 1 reply; 12+ messages in thread
From: Sylvain Petreolle @ 2005-02-03  9:59 UTC (permalink / raw)
  To: qemu-devel

How do you compile nest_test ?
Trying with gcc here I get :
[syl@wine ~]$ LANG=en_US gcc nest_test.c -o nest_test
nest_test.c: In function `bar':
nest_test.c:5: error: parameter name omitted

> 
> I've attached two programs. segv-test.c tests for the kernel bug. nest_test.c 
> tests stack trampolines, which exposes the bug then run inside qemu-user.
> 
> Note that the proper fix for arm is to remove the ||1 hack on the 
> TARGET_HAS_SMC tests in exec.c. Comments indicate this hack is to work around 
> bugs in the PPC emulation.
> 
> Paul


=====
Usurp (aka Sylvain Petreolle)
humans are like computers,
yesterday the BIOS was all
- today its just a word

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

* Re: [Qemu-devel] Armv5 target
  2005-02-03  9:59           ` Sylvain Petreolle
@ 2005-02-03 11:25             ` Ulrich Hecht
  0 siblings, 0 replies; 12+ messages in thread
From: Ulrich Hecht @ 2005-02-03 11:25 UTC (permalink / raw)
  To: qemu-devel

Hi!

On Thursday 03 February 2005 10:59, Sylvain Petreolle wrote:
> How do you compile nest_test ?
> Trying with gcc here I get :
> [syl@wine ~]$ LANG=en_US gcc nest_test.c -o nest_test
> nest_test.c: In function `bar':
> nest_test.c:5: error: parameter name omitted

It's missing an "f" in line 5:
void bar(void (*f)())

CU
Uli

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

* Re: [Qemu-devel] Armv5 target
  2005-02-02 19:17             ` Paul Brook
@ 2005-02-03 14:08               ` Ulrich Hecht
  2005-02-03 15:43                 ` Paul Brook
  0 siblings, 1 reply; 12+ messages in thread
From: Ulrich Hecht @ 2005-02-03 14:08 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 959 bytes --]

Hi!

On Wednesday 02 February 2005 20:17, Paul Brook wrote:
> The generated code causes a segfault trying to write to protected
> memory. On a real machine the signal handler unprotects the memory,
> and keeps going. Inside qemu the host signal handler just queues the
> target signal. For most signals this is ok; the target handler will be
> invoke at the end of the TB. However in this case we need to run the
> target handler immediately, otherwise the segv will occur again when
> we try and continue.
>
> I think fixing this requires executing the target signal handler code
> from within the host signal handler. As an added complication we only
> want to do this for signals received while executing target code.

Copying some code from the i386 and SPARC targets, I made up the attached 
patch. It fixes the segv_test testcase (and my personal use case, the 
GCC 3.3 configure script), and it does not seem to break anything else. 
Comments?

CU
Uli

[-- Attachment #2: qemu-arm-signals.patch --]
[-- Type: text/x-diff, Size: 4080 bytes --]

Index: cpu-exec.c
===================================================================
RCS file: /cvsroot/qemu/qemu/cpu-exec.c,v
retrieving revision 1.46
diff -u -r1.46 cpu-exec.c
--- cpu-exec.c	2 Feb 2005 20:42:01 -0000	1.46
+++ cpu-exec.c	3 Feb 2005 14:04:53 -0000
@@ -731,11 +731,35 @@
                                     int is_write, sigset_t *old_set,
                                     void *puc)
 {
+    TranslationBlock *tb;
+
+    if (cpu_single_env)
+        env = cpu_single_env; /* XXX: find a correct solution for multithread */
+#if defined(DEBUG_SIGNAL)
+    qemu_printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", 
+                pc, address, is_write, *(unsigned long *)old_set);
+#endif
     /* XXX: locking issue */
     if (is_write && page_unprotect(address, pc, puc)) {
         return 1;
     }
-    return 0;
+
+    /* XXX: see if it is an MMU fault */
+    env->address=address;
+    tb = tb_find_pc(pc);
+    if (tb) {
+        /* the PC is inside the translated code. It means that we have
+           a virtual CPU fault */
+        cpu_restore_state(tb, env, pc, puc);
+    }
+
+    /* we restore the process signal mask as the sigreturn should
+       do it (XXX: use sigsetjmp) */
+    sigprocmask(SIG_SETMASK, old_set, NULL);
+    raise_exception(EXCP_PAGE);
+
+    /* never comes here */
+    return 1;
 }
 #elif defined(TARGET_SPARC)
 static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
Index: linux-user/main.c
===================================================================
RCS file: /cvsroot/qemu/qemu/linux-user/main.c,v
retrieving revision 1.58
diff -u -r1.58 main.c
--- linux-user/main.c	12 Jan 2005 22:34:47 -0000	1.58
+++ linux-user/main.c	3 Feb 2005 14:04:53 -0000
@@ -365,6 +365,16 @@
                 }
             }
             break;
+        case EXCP_PAGE:
+            {
+                info.si_signo = SIGSEGV;
+                info.si_errno = 0;
+                /* XXX: check env->error_code */
+                info.si_code = TARGET_SEGV_MAPERR;
+                info._sifields._sigfault._addr = env->address;
+                queue_signal(info.si_signo, &info);
+            }
+            break;
         case EXCP_INTERRUPT:
             /* just indicate that signals should be handled asap */
             break;
Index: target-arm/cpu.h
===================================================================
RCS file: /cvsroot/qemu/qemu/target-arm/cpu.h,v
retrieving revision 1.5
diff -u -r1.5 cpu.h
--- target-arm/cpu.h	31 Jan 2005 20:43:28 -0000	1.5
+++ target-arm/cpu.h	3 Feb 2005 14:04:53 -0000
@@ -26,6 +26,7 @@
 
 #define EXCP_UDEF       1   /* undefined instruction */
 #define EXCP_SWI        2   /* software interrupt */
+#define EXCP_PAGE       3
 
 typedef struct CPUARMState {
     uint32_t regs[16];
@@ -45,6 +46,7 @@
     int interrupt_request;
     struct TranslationBlock *current_tb;
     int user_mode_only;
+    uint32_t address;
 
     /* in order to avoid passing too many arguments to the memory
        write helpers, we store some rarely used information in the CPU
Index: target-arm/exec.h
===================================================================
RCS file: /cvsroot/qemu/qemu/target-arm/exec.h,v
retrieving revision 1.3
diff -u -r1.3 exec.h
--- target-arm/exec.h	31 Jan 2005 20:43:28 -0000	1.3
+++ target-arm/exec.h	3 Feb 2005 14:04:53 -0000
@@ -31,6 +31,8 @@
 void cpu_unlock(void);
 void cpu_loop_exit(void);
 
+void raise_exception(int tt);
+
 /* Implemented CPSR bits.  */
 #define CACHED_CPSR_BITS 0xf8000000
 static inline int compute_cpsr(void)
Index: target-arm/op.c
===================================================================
RCS file: /cvsroot/qemu/qemu/target-arm/op.c,v
retrieving revision 1.7
diff -u -r1.7 op.c
--- target-arm/op.c	2 Feb 2005 20:43:01 -0000	1.7
+++ target-arm/op.c	3 Feb 2005 14:04:53 -0000
@@ -840,6 +840,12 @@
 
 /* exceptions */
 
+void raise_exception(int tt)
+{
+    env->exception_index = tt;
+    cpu_loop_exit();
+}
+
 void OPPROTO op_swi(void)
 {
     env->exception_index = EXCP_SWI;

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

* Re: [Qemu-devel] Armv5 target
  2005-02-03 14:08               ` Ulrich Hecht
@ 2005-02-03 15:43                 ` Paul Brook
  0 siblings, 0 replies; 12+ messages in thread
From: Paul Brook @ 2005-02-03 15:43 UTC (permalink / raw)
  To: qemu-devel

On Thursday 03 February 2005 14:08, Ulrich Hecht wrote:
> Copying some code from the i386 and SPARC targets, I made up the attached
> patch. It fixes the segv_test testcase (and my personal use case, the
> GCC 3.3 configure script), and it does not seem to break anything else.
> Comments?

This works for me too.

Paul

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

end of thread, other threads:[~2005-02-03 16:00 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-01-31 20:19 [Qemu-devel] Armv5 target Paul Brook
2005-01-31 22:44 ` Lennert Buytenhek
2005-01-31 23:13   ` Paul Brook
2005-02-02  1:26     ` Paul Brook
2005-02-02 12:01       ` Lennert Buytenhek
2005-02-02 15:47         ` Paul Brook
2005-02-02 18:18           ` Ulrich Hecht
2005-02-02 19:17             ` Paul Brook
2005-02-03 14:08               ` Ulrich Hecht
2005-02-03 15:43                 ` Paul Brook
2005-02-03  9:59           ` Sylvain Petreolle
2005-02-03 11:25             ` Ulrich Hecht

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).