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