diff options
-rw-r--r-- | meta/packages/qemu/files/31_syscalls.patch | 13 | ||||
-rw-r--r-- | meta/packages/qemu/files/fix_segfault.patch | 46 | ||||
-rw-r--r-- | meta/packages/qemu/files/qemu-0.9.0-nptl-update.patch | 294 | ||||
-rw-r--r-- | meta/packages/qemu/files/qemu-0.9.0-nptl.patch (renamed from meta/packages/qemu/files/94-oh-arm-nptl.patch) | 504 | ||||
-rw-r--r-- | meta/packages/qemu/qemu_cvs.bb | 7 |
5 files changed, 593 insertions, 271 deletions
diff --git a/meta/packages/qemu/files/31_syscalls.patch b/meta/packages/qemu/files/31_syscalls.patch index e7a1b338f..3878079f1 100644 --- a/meta/packages/qemu/files/31_syscalls.patch +++ b/meta/packages/qemu/files/31_syscalls.patch @@ -47,16 +47,3 @@ Index: linux-user/syscall.c #endif #ifdef TARGET_NR_setxattr case TARGET_NR_setxattr: -Index: Makefile.target -=================================================================== ---- Makefile.target.orig 2007-06-13 11:51:52.000000000 +0100 -+++ Makefile.target 2007-06-13 11:51:54.000000000 +0100 -@@ -215,7 +215,7 @@ OP_LDFLAGS+=$(OS_LDFLAGS) $(ARCH_LDFLAGS - ######################################################### - - CPPFLAGS+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE --LIBS+=-lm -+LIBS+=-lm -lrt - ifndef CONFIG_USER_ONLY - LIBS+=-lz - endif diff --git a/meta/packages/qemu/files/fix_segfault.patch b/meta/packages/qemu/files/fix_segfault.patch new file mode 100644 index 000000000..976c75cd6 --- /dev/null +++ b/meta/packages/qemu/files/fix_segfault.patch @@ -0,0 +1,46 @@ +Index: qemu/Makefile.target +=================================================================== +--- qemu.orig/Makefile.target 2007-06-29 10:57:58.000000000 +0000 ++++ qemu/Makefile.target 2007-06-29 10:58:01.000000000 +0000 +@@ -241,7 +241,6 @@ + ifdef CONFIG_LINUX_USER + OBJS= main.o syscall.o mmap.o signal.o path.o osdep.o thunk.o \ + elfload.o linuxload.o +-LIBS+= $(AIOLIBS) + ifdef TARGET_HAS_BFLT + OBJS+= flatload.o + endif +Index: qemu/linux-user/syscall.c +=================================================================== +--- qemu.orig/linux-user/syscall.c 2007-06-29 10:58:01.000000000 +0000 ++++ qemu/linux-user/syscall.c 2007-06-29 10:58:30.000000000 +0000 +@@ -4872,29 +4872,6 @@ + goto unimplemented_nowarn; + #endif + +-#ifdef TARGET_NR_clock_gettime +- case TARGET_NR_clock_gettime: +- { +- struct timespec ts; +- ret = get_errno(clock_gettime(arg1, &ts)); +- if (!is_error(ret)) { +- host_to_target_timespec(arg2, &ts); +- } +- break; +- } +-#endif +-#ifdef TARGET_NR_clock_getres +- case TARGET_NR_clock_getres: +- { +- struct timespec ts; +- ret = get_errno(clock_getres(arg1, &ts)); +- if (!is_error(ret)) { +- host_to_target_timespec(arg2, &ts); +- } +- break; +- } +-#endif +- + default: + unimplemented: + gemu_log("qemu: Unsupported syscall: %d\n", num); diff --git a/meta/packages/qemu/files/qemu-0.9.0-nptl-update.patch b/meta/packages/qemu/files/qemu-0.9.0-nptl-update.patch new file mode 100644 index 000000000..869acba2c --- /dev/null +++ b/meta/packages/qemu/files/qemu-0.9.0-nptl-update.patch @@ -0,0 +1,294 @@ +Index: qemu/linux-user/main.c +=================================================================== +--- qemu.orig/linux-user/main.c 2007-06-29 10:47:58.000000000 +0000 ++++ qemu/linux-user/main.c 2007-06-29 10:47:58.000000000 +0000 +@@ -156,7 +156,7 @@ + p[1] = tswapl(e2); + } + +-uint64_t gdt_table[6]; ++uint64_t gdt_table[9]; + uint64_t idt_table[256]; + + /* only dpl matters as we do only user space emulation */ +@@ -1768,7 +1768,11 @@ + int optind; + const char *r; + int gdbstub_port = 0; +- ++ char *assume_kernel = getenv("QEMU_ASSUME_KERNEL"); ++ ++ if (assume_kernel) ++ setenv("LD_ASSUME_KERNEL", assume_kernel, 1); ++ + if (argc <= 1) + usage(); + +Index: qemu/linux-user/syscall.c +=================================================================== +--- qemu.orig/linux-user/syscall.c 2007-06-29 10:47:58.000000000 +0000 ++++ qemu/linux-user/syscall.c 2007-06-29 10:53:44.000000000 +0000 +@@ -60,6 +60,7 @@ + #define tchars host_tchars /* same as target */ + #define ltchars host_ltchars /* same as target */ + ++#include <linux/futex.h> + #include <linux/termios.h> + #include <linux/unistd.h> + #include <linux/utsname.h> +@@ -2122,6 +2123,80 @@ + return ret; + } + ++int do_set_thread_area(CPUX86State *env, target_ulong ptr) ++{ ++ uint64_t *gdt_table = g2h(env->gdt.base); ++ struct target_modify_ldt_ldt_s ldt_info; ++ struct target_modify_ldt_ldt_s *target_ldt_info; ++ int seg_32bit, contents, read_exec_only, limit_in_pages; ++ int seg_not_present, useable; ++ uint32_t *lp, entry_1, entry_2; ++ int i; ++ ++ lock_user_struct(target_ldt_info, ptr, 1); ++ ldt_info.entry_number = tswap32(target_ldt_info->entry_number); ++ ldt_info.base_addr = tswapl(target_ldt_info->base_addr); ++ ldt_info.limit = tswap32(target_ldt_info->limit); ++ ldt_info.flags = tswap32(target_ldt_info->flags); ++ if (ldt_info.entry_number == -1) { ++ for (i=6; i<8; i++) ++ if (gdt_table[i] == 0) { ++ ldt_info.entry_number = i; ++ target_ldt_info->entry_number = tswap32(i); ++ break; ++ } ++ } ++ unlock_user_struct(target_ldt_info, ptr, 0); ++ ++ if (ldt_info.entry_number < 6 || ldt_info.entry_number > 8) ++ return -EINVAL; ++ seg_32bit = ldt_info.flags & 1; ++ contents = (ldt_info.flags >> 1) & 3; ++ read_exec_only = (ldt_info.flags >> 3) & 1; ++ limit_in_pages = (ldt_info.flags >> 4) & 1; ++ seg_not_present = (ldt_info.flags >> 5) & 1; ++ useable = (ldt_info.flags >> 6) & 1; ++ ++ if (contents == 3) { ++ if (seg_not_present == 0) ++ return -EINVAL; ++ } ++ ++ /* NOTE: same code as Linux kernel */ ++ /* Allow LDTs to be cleared by the user. */ ++ if (ldt_info.base_addr == 0 && ldt_info.limit == 0) { ++ if ((contents == 0 && ++ read_exec_only == 1 && ++ seg_32bit == 0 && ++ limit_in_pages == 0 && ++ seg_not_present == 1 && ++ useable == 0 )) { ++ entry_1 = 0; ++ entry_2 = 0; ++ goto install; ++ } ++ } ++ ++ entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) | ++ (ldt_info.limit & 0x0ffff); ++ entry_2 = (ldt_info.base_addr & 0xff000000) | ++ ((ldt_info.base_addr & 0x00ff0000) >> 16) | ++ (ldt_info.limit & 0xf0000) | ++ ((read_exec_only ^ 1) << 9) | ++ (contents << 10) | ++ ((seg_not_present ^ 1) << 15) | ++ (seg_32bit << 22) | ++ (limit_in_pages << 23) | ++ (useable << 20) | ++ 0x7000; ++ ++ /* Install the new entry ... */ ++install: ++ lp = (uint32_t *)(gdt_table + ldt_info.entry_number); ++ lp[0] = tswap32(entry_1); ++ lp[1] = tswap32(entry_2); ++ return 0; ++} + #endif /* defined(TARGET_I386) */ + + /* this stack is the equivalent of the kernel stack associated with a +@@ -2154,15 +2229,20 @@ + TaskState *ts; + uint8_t *new_stack; + CPUState *new_env; ++#if defined(TARGET_I386) ++ uint64_t *new_gdt_table; ++#endif + #ifdef USE_NPTL + unsigned int nptl_flags; + + if (flags & CLONE_PARENT_SETTID) + *parent_tidptr = gettid(); + #endif +- ++ + if (flags & CLONE_VM) { + ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE); ++ if (!ts) ++ return -ENOMEM; + memset(ts, 0, sizeof(TaskState)); + new_stack = ts->stack; + ts->used = 1; +@@ -2174,6 +2254,29 @@ + #if defined(TARGET_I386) + if (!newsp) + newsp = env->regs[R_ESP]; ++ new_gdt_table = malloc(9 * 8); ++ if (!new_gdt_table) { ++ free(new_env); ++ return -ENOMEM; ++ } ++ /* Copy main GDT table from parent, but clear TLS entries */ ++ memcpy(new_gdt_table, g2h(env->gdt.base), 6 * 8); ++ memset(&new_gdt_table[6], 0, 3 * 8); ++ new_env->gdt.base = h2g(new_gdt_table); ++ if (flags & 0x00080000 /* CLONE_SETTLS */) { ++ ret = do_set_thread_area(new_env, new_env->regs[R_ESI]); ++ if (ret) { ++ free(new_gdt_table); ++ free(new_env); ++ return ret; ++ } ++ } ++ cpu_x86_load_seg(env, R_CS, new_env->regs[R_CS]); ++ cpu_x86_load_seg(env, R_DS, new_env->regs[R_DS]); ++ cpu_x86_load_seg(env, R_ES, new_env->regs[R_ES]); ++ cpu_x86_load_seg(env, R_SS, new_env->regs[R_SS]); ++ cpu_x86_load_seg(env, R_FS, new_env->regs[R_FS]); ++ cpu_x86_load_seg(env, R_GS, new_env->regs[R_GS]); + new_env->regs[R_ESP] = newsp; + new_env->regs[R_EAX] = 0; + #elif defined(TARGET_ARM) +@@ -2517,6 +2620,68 @@ + unlock_user_struct(target_ts, target_addr, 1); + } + ++static long do_futex(target_ulong uaddr, int op, uint32_t val, ++ target_ulong utime, target_ulong uaddr2, ++ uint32_t val3) ++{ ++ struct timespec host_utime; ++ unsigned long val2 = utime; ++ ++ if (utime && (op == FUTEX_WAIT || op == FUTEX_LOCK_PI)) { ++ target_to_host_timespec(&host_utime, utime); ++ val2 = (unsigned long)&host_utime; ++ } ++ ++#ifdef BSWAP_NEEDED ++ switch(op) { ++ case FUTEX_CMP_REQUEUE: ++ val3 = tswap32(val3); ++ case FUTEX_REQUEUE: ++ val2 = tswap32(val2); ++ case FUTEX_WAIT: ++ case FUTEX_WAKE: ++ val = tswap32(val); ++ case FUTEX_LOCK_PI: /* This one's icky, but comes out OK */ ++ case FUTEX_UNLOCK_PI: ++ break; ++ default: ++ gemu_log("qemu: Unsupported futex op %d\n", op); ++ return -ENOSYS; ++ } ++#if 0 /* No, it's worse than this */ ++ if (op == FUTEX_WAKE_OP) { ++ /* Need to munge the secondary operation (val3) */ ++ val3 = tswap32(val3); ++ int op2 = (val3 >> 28) & 7; ++ int cmp = (val3 >> 24) & 15; ++ int oparg = (val3 << 8) >> 20; ++ int cmparg = (val3 << 20) >> 20; ++ int shift = val3 & (FUTEX_OP_OPARG_SHIFT << 28); ++ ++ if (shift) ++ oparg = (oparg & 7) + 24 - (oparg & 24); ++ else oparg = ++ if (op2 == FUTEX_OP_ADD) { ++ gemu_log("qemu: Unsupported wrong-endian FUTEX_OP_ADD\n"); ++ return -ENOSYS; ++ } ++ if (cmparg == FUTEX_OP_CMP_LT || cmparg == FUTEX_OP_CMP_GE || ++ cmparg == FUTEX_OP_CMP_LE || cmparg == FUTEX_OP_CMP_GT) { ++ gemu_log("qemu: Unsupported wrong-endian futex cmparg %d\n", cmparg); ++ return -ENOSYS; ++ } ++ val3 = shift | (op2<<28) | (cmp<<24) | (oparg<<12) | cmparg; ++ } ++#endif ++#endif ++ return syscall(__NR_futex, g2h(uaddr), op, val, val2, g2h(uaddr2), val3); ++} ++ ++int do_set_tid_address(target_ulong tidptr) ++{ ++ return syscall(__NR_set_tid_address, g2h(tidptr)); ++} ++ + long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, + long arg4, long arg5, long arg6) + { +@@ -2534,7 +2699,7 @@ + _mcleanup(); + #endif + gdb_exit(cpu_env, arg1); +- /* XXX: should free thread stack and CPU env */ ++ /* XXX: should free thread stack, GDT and CPU env */ + _exit(arg1); + ret = 0; /* avoid warning */ + break; +@@ -4642,6 +4807,9 @@ + ((CPUMIPSState *) cpu_env)->tls_value = arg1; + ret = 0; + break; ++#elif TARGET_i386 ++ ret = get_errno(do_set_thread_area(cpu_env, arg1)); ++ break; + #else + goto unimplemented_nowarn; + #endif +@@ -4655,6 +4823,21 @@ + goto unimplemented_nowarn; + #endif + ++#ifdef TARGET_NR_futex ++ case TARGET_NR_futex: ++ ret = get_errno(do_futex(arg1, arg2, arg3, arg4, arg5, arg6)); ++ break; ++#endif ++#ifdef TARGET_NR_set_tid_address ++ case TARGET_NR_set_tid_address: ++ ret = get_errno(do_set_tid_address(arg1)); ++ break; ++#endif ++#ifdef TARGET_NR_set_robust_list ++ case TARGET_NR_set_robust_list: ++ goto unimplemented_nowarn; ++#endif ++ + #ifdef TARGET_NR_clock_gettime + case TARGET_NR_clock_gettime: + { +@@ -4678,12 +4861,6 @@ + } + #endif + +-#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address) +- case TARGET_NR_set_tid_address: +- ret = get_errno(set_tid_address((int *) arg1)); +- break; +-#endif +- + default: + unimplemented: + gemu_log("qemu: Unsupported syscall: %d\n", num); diff --git a/meta/packages/qemu/files/94-oh-arm-nptl.patch b/meta/packages/qemu/files/qemu-0.9.0-nptl.patch index 37d717198..fc7b0cfa4 100644 --- a/meta/packages/qemu/files/94-oh-arm-nptl.patch +++ b/meta/packages/qemu/files/qemu-0.9.0-nptl.patch @@ -1,22 +1,24 @@ ---- - configure | 29 ++++++ - exec-all.h | 165 -------------------------------------- - linux-user/arm/syscall.h | 4 - linux-user/main.c | 94 ++++++++++++++++++--- - linux-user/qemu.h | 3 - linux-user/syscall.c | 90 ++++++++++++++++++-- - qemu_spinlock.h | 204 +++++++++++++++++++++++++++++++++++++++++++++++ - target-arm/cpu.h | 19 ++++ - target-arm/exec.h | 2 - target-arm/op.c | 6 + - target-arm/translate.c | 10 ++ - 11 files changed, 437 insertions(+), 189 deletions(-) +These are Paul Brook's patches to QEMU-0.8.2 to enable the running of single +ARM binaries under QEMU's user-emulation mode. Without them, QEMU-0.8.1 +immediately dies saying: + Error: f0005 + qemu: uncaught target signal 6 (Aborted) - exiting +while qemu-0.8.2 dies saying: + qemu: Unsupported syscall: 983045 + cannot set up thread-local storage: unknown error + +This file is a rediffing of the patches visible at +https://nowt.dyndns.org/patch.qemu_nptl on 27 Sept 2006 +which "patch" fails to apply automatically. +See also http://lists.gnu.org/archive/html/qemu-devel/2006-09/msg00194.html + + Martin Guy, 27 Sept 2006 Index: qemu/configure =================================================================== ---- qemu.orig/configure 2007-06-13 11:51:56.000000000 +0100 -+++ qemu/configure 2007-06-13 11:51:57.000000000 +0100 -@@ -101,6 +101,7 @@ linux_user="no" +--- qemu.orig/configure 2007-06-29 10:47:39.000000000 +0000 ++++ qemu/configure 2007-06-29 10:47:58.000000000 +0000 +@@ -101,6 +101,7 @@ darwin_user="no" build_docs="no" uname_release="" @@ -24,7 +26,7 @@ Index: qemu/configure # OS specific targetos=`uname -s` -@@ -287,6 +288,8 @@ for opt do +@@ -281,6 +282,8 @@ *) echo "undefined SPARC architecture. Exiting";exit 1;; esac ;; @@ -33,7 +35,15 @@ Index: qemu/configure esac done -@@ -530,6 +533,23 @@ int main(void) { +@@ -355,6 +358,7 @@ + echo " --disable-linux-user disable all linux usermode emulation targets" + echo " --enable-darwin-user enable all darwin usermode emulation targets" + echo " --disable-darwin-user disable all darwin usermode emulation targets" ++echo " --disable-nptl disable usermode NPTL guest support" + echo " --fmod-lib path to FMOD library" + echo " --fmod-inc path to FMOD includes" + echo " --enable-uname-release=R Return R for uname -r in usermode emulation" +@@ -524,6 +528,23 @@ } EOF @@ -57,15 +67,15 @@ Index: qemu/configure ########################################## # SDL probe -@@ -681,6 +701,7 @@ if test -n "$sparc_cpu"; then - echo "Target Sparc Arch $sparc_cpu" - fi - echo "kqemu support $kqemu" -+echo "NPTL support $nptl" +@@ -678,6 +699,7 @@ echo "Documentation $build_docs" [ ! -z "$uname_release" ] && \ echo "uname -r $uname_release" -@@ -1063,6 +1084,14 @@ if test "$target_user_only" = "no"; then ++echo "NPTL support $nptl" + + if test $sdl_too_old = "yes"; then + echo "-> Your SDL version is too old - please upgrade to have SDL support" +@@ -1057,6 +1079,14 @@ echo "SDL_CFLAGS=`$sdl_config --cflags`" >> $config_mak fi fi @@ -82,9 +92,9 @@ Index: qemu/configure if test "$cocoa" = "yes" ; then Index: qemu/exec-all.h =================================================================== ---- qemu.orig/exec-all.h 2007-06-13 11:48:22.000000000 +0100 -+++ qemu/exec-all.h 2007-06-13 11:51:57.000000000 +0100 -@@ -360,170 +360,7 @@ extern CPUWriteMemoryFunc *io_mem_write[ +--- qemu.orig/exec-all.h 2007-06-29 10:47:39.000000000 +0000 ++++ qemu/exec-all.h 2007-06-29 10:47:58.000000000 +0000 +@@ -360,170 +360,7 @@ extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4]; extern void *io_mem_opaque[IO_MEM_NB_ENTRIES]; @@ -258,9 +268,9 @@ Index: qemu/exec-all.h Index: qemu/linux-user/arm/syscall.h =================================================================== ---- qemu.orig/linux-user/arm/syscall.h 2007-06-13 11:48:22.000000000 +0100 -+++ qemu/linux-user/arm/syscall.h 2007-06-13 11:51:57.000000000 +0100 -@@ -28,7 +28,9 @@ struct target_pt_regs { +--- qemu.orig/linux-user/arm/syscall.h 2007-06-29 10:47:39.000000000 +0000 ++++ qemu/linux-user/arm/syscall.h 2007-06-29 10:47:58.000000000 +0000 +@@ -28,7 +28,9 @@ #define ARM_SYSCALL_BASE 0x900000 #define ARM_THUMB_SYSCALL 0 @@ -273,9 +283,9 @@ Index: qemu/linux-user/arm/syscall.h #define ARM_NR_thumb_semihosting 0xAB Index: qemu/linux-user/main.c =================================================================== ---- qemu.orig/linux-user/main.c 2007-06-13 11:51:55.000000000 +0100 -+++ qemu/linux-user/main.c 2007-06-13 11:51:57.000000000 +0100 -@@ -325,6 +325,50 @@ static void arm_cache_flush(target_ulong +--- qemu.orig/linux-user/main.c 2007-06-29 10:47:39.000000000 +0000 ++++ qemu/linux-user/main.c 2007-06-29 10:53:47.000000000 +0000 +@@ -325,6 +325,50 @@ } } @@ -326,7 +336,7 @@ Index: qemu/linux-user/main.c void cpu_loop(CPUARMState *env) { int trapnr; -@@ -430,10 +474,8 @@ void cpu_loop(CPUARMState *env) +@@ -381,10 +425,8 @@ } } @@ -339,7 +349,7 @@ Index: qemu/linux-user/main.c env->regs[0] = do_arm_semihosting (env); } else if (n == 0 || n >= ARM_SYSCALL_BASE || (env->thumb && n == ARM_THUMB_SYSCALL)) { -@@ -444,14 +486,34 @@ void cpu_loop(CPUARMState *env) +@@ -395,14 +437,34 @@ n -= ARM_SYSCALL_BASE; env->eabi = 0; } @@ -382,7 +392,7 @@ Index: qemu/linux-user/main.c } else { goto error; } -@@ -490,6 +552,10 @@ void cpu_loop(CPUARMState *env) +@@ -441,6 +503,10 @@ } } break; @@ -393,7 +403,7 @@ Index: qemu/linux-user/main.c default: error: fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", -@@ -2096,6 +2162,10 @@ int main(int argc, char **argv) +@@ -2047,6 +2113,10 @@ ts->heap_base = info->brk; /* This will be filled in on the first SYS_HEAPINFO call. */ ts->heap_limit = 0; @@ -406,23 +416,23 @@ Index: qemu/linux-user/main.c if (gdbstub_port) { Index: qemu/linux-user/qemu.h =================================================================== ---- qemu.orig/linux-user/qemu.h 2007-06-13 11:48:22.000000000 +0100 -+++ qemu/linux-user/qemu.h 2007-06-13 11:51:57.000000000 +0100 -@@ -81,6 +81,9 @@ typedef struct TaskState { +--- qemu.orig/linux-user/qemu.h 2007-06-29 10:47:39.000000000 +0000 ++++ qemu/linux-user/qemu.h 2007-06-29 10:47:58.000000000 +0000 +@@ -80,6 +80,9 @@ + uint32_t heap_base; uint32_t heap_limit; #endif - int used; /* non zero if used */ +#ifdef USE_NPTL + uint32_t *child_tidptr; +#endif + int used; /* non zero if used */ struct image_info *info; uint8_t stack[0]; - } __attribute__((aligned(16))) TaskState; Index: qemu/linux-user/syscall.c =================================================================== ---- qemu.orig/linux-user/syscall.c 2007-06-13 11:51:55.000000000 +0100 -+++ qemu/linux-user/syscall.c 2007-06-13 11:51:57.000000000 +0100 -@@ -71,9 +71,18 @@ +--- qemu.orig/linux-user/syscall.c 2007-06-29 10:47:39.000000000 +0000 ++++ qemu/linux-user/syscall.c 2007-06-29 10:53:47.000000000 +0000 +@@ -70,9 +70,18 @@ #include <linux/kd.h> #include "qemu.h" @@ -441,7 +451,7 @@ Index: qemu/linux-user/syscall.c #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \ || defined(TARGET_M68K) || defined(TARGET_SH4) /* 16 bit uid wrappers emulation */ -@@ -2121,20 +2130,38 @@ int do_modify_ldt(CPUX86State *env, int +@@ -2119,20 +2128,38 @@ thread/process */ #define NEW_STACK_SIZE 8192 @@ -481,72 +491,76 @@ Index: qemu/linux-user/syscall.c if (flags & CLONE_VM) { ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE); -@@ -2197,16 +2224,60 @@ int do_fork(CPUState *env, unsigned int +@@ -2199,16 +2226,67 @@ #error unsupported target CPU #endif new_env->opaque = ts; +#ifdef USE_NPTL -+ nptl_flags = flags; -+ flags &= ~CLONE_NPTL_FLAGS2; -+ if (nptl_flags & CLONE_CHILD_CLEARTID) { -+ ts->child_tidptr = child_tidptr; -+ } -+ if (nptl_flags & CLONE_SETTLS) -+ cpu_set_tls (new_env, newtls); -+ /* Grab the global cpu lock so that the thread setup appears -+ atomic. */ -+ if (nptl_flags & CLONE_CHILD_SETTID) -+ spin_lock(&nptl_lock); ++ nptl_flags = flags; ++ flags &= ~CLONE_NPTL_FLAGS2; ++ ++ if (nptl_flags & CLONE_CHILD_CLEARTID) { ++ ts->child_tidptr = child_tidptr; ++ } ++ ++ if (nptl_flags & CLONE_SETTLS) ++ cpu_set_tls (new_env, newtls); ++ ++ /* Grab the global cpu lock so that the thread setup appears ++ atomic. */ ++ if (nptl_flags & CLONE_CHILD_SETTID) ++ spin_lock(&nptl_lock); ++ +#else -+ if (flags & CLONE_NPTL_FLAGS2) -+ return -EINVAL; ++ if (flags & CLONE_NPTL_FLAGS2) ++ return -EINVAL; +#endif + ++ if (CLONE_VFORK & flags) ++ flags ^= CLONE_VM; #ifdef __ia64__ ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env); #else ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env); #endif +#ifdef USE_NPTL -+ if (ret != -1) { -+ if (nptl_flags & CLONE_CHILD_SETTID) -+ *child_tidptr = ret; -+ } -+ /* Allow the child to continue. */ -+ if (nptl_flags & CLONE_CHILD_SETTID) -+ spin_unlock(&nptl_lock); ++ if (ret != -1) { ++ if (nptl_flags & CLONE_CHILD_SETTID) ++ *child_tidptr = ret; ++ } ++ ++ /* Allow the child to continue. */ ++ if (nptl_flags & CLONE_CHILD_SETTID) ++ spin_unlock(&nptl_lock); +#endif } else { -- /* if no CLONE_VM, we consider it is a fork */ + /* if no CLONE_VM, we consider it is a fork */ - if ((flags & ~CSIGNAL) != 0) -- return -EINVAL; -- ret = fork(); -+ /* if no CLONE_VM, we consider it is a fork */ -+ if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0) -+ return -EINVAL; -+ ret = fork(); ++ if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0) + return -EINVAL; + ret = fork(); +#ifdef USE_NPTL -+ /* There is a race condition here. The parent process could -+ theoretically read the TID in the child process before the child -+ tid is set. This would require using either ptrace -+ (not implemented) or having *_tidptr to point at a shared memory -+ mapping. We can't repeat the spinlock hack used above because -+ the child process gets its own copy of the lock. */ -+ if (ret == 0) { -+ /* Child Process. */ -+ if (flags & CLONE_CHILD_SETTID) -+ *child_tidptr = gettid(); -+ ts = (TaskState *)env->opaque; -+ if (flags & CLONE_CHILD_CLEARTID) -+ ts->child_tidptr = child_tidptr; -+ if (flags & CLONE_SETTLS) -+ cpu_set_tls (env, newtls); -+ } ++ /* There is a race condition here. The parent process could ++ theoretically read the TID in the child process before the child ++ tid is set. This would require using either ptrace ++ (not implemented) or having *_tidptr to point at a shared memory ++ mapping. We can't repeat the spinlock hack used above because ++ the child process gets its own copy of the lock. */ ++ if (ret == 0) { ++ /* Child Process. */ ++ if (flags & CLONE_CHILD_SETTID) ++ *child_tidptr = gettid(); ++ ts = (TaskState *)env->opaque; ++ if (flags & CLONE_CHILD_CLEARTID) ++ ts->child_tidptr = child_tidptr; ++ if (flags & CLONE_SETTLS) ++ cpu_set_tls (env, newtls); ++ } +#endif } return ret; } -@@ -2483,7 +2554,7 @@ long do_syscall(void *cpu_env, int num, +@@ -2485,7 +2563,7 @@ ret = do_brk(arg1); break; case TARGET_NR_fork: @@ -555,7 +569,7 @@ Index: qemu/linux-user/syscall.c break; #ifdef TARGET_NR_waitpid case TARGET_NR_waitpid: -@@ -3648,7 +3719,8 @@ long do_syscall(void *cpu_env, int num, +@@ -3649,7 +3727,8 @@ ret = get_errno(fsync(arg1)); break; case TARGET_NR_clone: @@ -565,7 +579,7 @@ Index: qemu/linux-user/syscall.c break; #ifdef __NR_exit_group /* new thread calls */ -@@ -4062,7 +4134,8 @@ long do_syscall(void *cpu_env, int num, +@@ -4037,7 +4116,8 @@ #endif #ifdef TARGET_NR_vfork case TARGET_NR_vfork: @@ -575,129 +589,20 @@ Index: qemu/linux-user/syscall.c break; #endif #ifdef TARGET_NR_ugetrlimit -@@ -4660,4 +4733,3 @@ long do_syscall(void *cpu_env, int num, +@@ -4619,4 +4699,3 @@ #endif return ret; } - -Index: qemu/target-arm/cpu.h -=================================================================== ---- qemu.orig/target-arm/cpu.h 2007-06-13 11:48:22.000000000 +0100 -+++ qemu/target-arm/cpu.h 2007-06-13 11:51:57.000000000 +0100 -@@ -37,6 +37,9 @@ - #define EXCP_IRQ 5 - #define EXCP_FIQ 6 - #define EXCP_BKPT 7 -+#define EXCP_KERNEL_TRAP 8 /* Jumped to kernel code page. */ -+ -+ - - typedef void ARMWriteCPFunc(void *opaque, int cp_info, - int srcreg, int operand, uint32_t value); -@@ -97,6 +100,7 @@ typedef struct CPUARMState { - uint32_t c9_data; - uint32_t c13_fcse; /* FCSE PID. */ - uint32_t c13_context; /* Context ID. */ -+ uint32_t c13_tls; /* Paul Brook told me to just add this ;) */ - uint32_t c15_cpar; /* XScale Coprocessor Access Register */ - } cp15; - -@@ -169,6 +173,15 @@ void switch_mode(CPUARMState *, int); - int cpu_arm_signal_handler(int host_signum, void *pinfo, - void *puc); - -+void cpu_lock(void); -+void cpu_unlock(void); -+#if defined(USE_NPTL) -+static inline void cpu_set_tls(CPUARMState *env, void *newtls) -+{ -+ env->cp15.c13_tls = (uint32_t)newtls; -+} -+#endif -+ - #define CPSR_M (0x1f) - #define CPSR_T (1 << 5) - #define CPSR_F (1 << 6) -@@ -180,7 +193,11 @@ int cpu_arm_signal_handler(int host_sign - #define CPSR_J (1 << 24) - #define CPSR_IT_0_1 (3 << 25) - #define CPSR_Q (1 << 27) --#define CPSR_NZCV (0xf << 28) -+#define CPSR_V (1 << 28) -+#define CPSR_C (1 << 29) -+#define CPSR_Z (1 << 30) -+#define CPSR_N (1 << 31) -+#define CPSR_NZCV (CPSR_N | CPSR_Z | CPSR_C | CPSR_V) - - #define CACHED_CPSR_BITS (CPSR_T | CPSR_Q | CPSR_NZCV) - /* Return the current CPSR value. */ -Index: qemu/target-arm/exec.h -=================================================================== ---- qemu.orig/target-arm/exec.h 2007-06-13 11:48:22.000000000 +0100 -+++ qemu/target-arm/exec.h 2007-06-13 11:51:57.000000000 +0100 -@@ -68,8 +68,6 @@ static inline int cpu_halted(CPUState *e - - /* In op_helper.c */ - --void cpu_lock(void); --void cpu_unlock(void); - void helper_set_cp(CPUState *, uint32_t, uint32_t); - uint32_t helper_get_cp(CPUState *, uint32_t); - void helper_set_cp15(CPUState *, uint32_t, uint32_t); -Index: qemu/target-arm/op.c -=================================================================== ---- qemu.orig/target-arm/op.c 2007-06-13 11:48:22.000000000 +0100 -+++ qemu/target-arm/op.c 2007-06-13 11:51:57.000000000 +0100 -@@ -891,6 +891,12 @@ void OPPROTO op_bkpt(void) - cpu_loop_exit(); - } - -+void OPPROTO op_kernel_trap(void) -+{ -+ env->exception_index = EXCP_KERNEL_TRAP; -+ cpu_loop_exit(); -+} -+ - /* VFP support. We follow the convention used for VFP instrunctions: - Single precition routines have a "s" suffix, double precision a - "d" suffix. */ -Index: qemu/target-arm/translate.c -=================================================================== ---- qemu.orig/target-arm/translate.c 2007-06-13 11:48:22.000000000 +0100 -+++ qemu/target-arm/translate.c 2007-06-13 11:51:57.000000000 +0100 -@@ -3513,6 +3513,7 @@ undef: - s->is_jmp = DISAS_JUMP; - } - -+ - /* generate intermediate code in gen_opc_buf and gen_opparam_buf for - basic block 'tb'. If search_pc is TRUE, also generate PC - information for each intermediate instruction. */ -@@ -3548,6 +3549,15 @@ static inline int gen_intermediate_code_ - nb_gen_labels = 0; - lj = -1; - do { -+#ifdef CONFIG_USER_ONLY -+ /* Intercept jump to the magic kernel page. */ -+ if (dc->pc > 0xffff0000) { -+ gen_op_kernel_trap(); -+ dc->is_jmp = DISAS_UPDATE; -+ break; -+ } -+#endif -+ - if (env->nb_breakpoints > 0) { - for(j = 0; j < env->nb_breakpoints; j++) { - if (env->breakpoints[j] == dc->pc) { Index: qemu/qemu_spinlock.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ qemu/qemu_spinlock.h 2007-06-13 11:51:57.000000000 +0100 -@@ -0,0 +1,204 @@ ++++ qemu/qemu_spinlock.h 2007-06-29 10:47:58.000000000 +0000 +@@ -0,0 +1,181 @@ +/* -+ * internal execution defines for qemu -+ * -+ * Copyright (c) 2003 Fabrice Bellard ++ * Atomic operation helper include ++ * ++ * Copyright (c) 2005 Fabrice Bellard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public @@ -713,9 +618,8 @@ Index: qemu/qemu_spinlock.h + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ -+ -+#ifndef _QEMU_SPINLOCK_H -+#define _QEMU_SPINLOCK_H ++#ifndef QEMU_SPINLOCK_H ++#define QEMU_SPINLOCK_H + +#ifdef __powerpc__ +static inline int testandset (int *p) @@ -739,7 +643,7 @@ Index: qemu/qemu_spinlock.h +static inline int testandset (int *p) +{ + long int readval = 0; -+ ++ + __asm__ __volatile__ ("lock; cmpxchgl %2, %0" + : "+m" (*p), "+a" (readval) + : "r" (1) @@ -752,7 +656,7 @@ Index: qemu/qemu_spinlock.h +static inline int testandset (int *p) +{ + long int readval = 0; -+ ++ + __asm__ __volatile__ ("lock; cmpxchgl %2, %0" + : "+m" (*p), "+a" (readval) + : "r" (1) @@ -767,10 +671,10 @@ Index: qemu/qemu_spinlock.h + int ret; + + __asm__ __volatile__ ("0: cs %0,%1,0(%2)\n" -+ " jl 0b" -+ : "=&d" (ret) -+ : "r" (1), "a" (p), "0" (*p) -+ : "cc", "memory" ); ++ " jl 0b" ++ : "=&d" (ret) ++ : "r" (1), "a" (p), "0" (*p) ++ : "cc", "memory" ); + return ret; +} +#endif @@ -781,15 +685,15 @@ Index: qemu/qemu_spinlock.h + int ret; + unsigned long one; + -+ __asm__ __volatile__ ("0: mov 1,%2\n" -+ " ldl_l %0,%1\n" -+ " stl_c %2,%1\n" -+ " beq %2,1f\n" -+ ".subsection 2\n" -+ "1: br 0b\n" -+ ".previous" -+ : "=r" (ret), "=m" (*p), "=r" (one) -+ : "m" (*p)); ++ __asm__ __volatile__ ("0: mov 1,%2\n" ++ " ldl_l %0,%1\n" ++ " stl_c %2,%1\n" ++ " beq %2,1f\n" ++ ".subsection 2\n" ++ "1: br 0b\n" ++ ".previous" ++ : "=r" (ret), "=m" (*p), "=r" (one) ++ : "m" (*p)); + return ret; +} +#endif @@ -797,14 +701,14 @@ Index: qemu/qemu_spinlock.h +#ifdef __sparc__ +static inline int testandset (int *p) +{ -+ int ret; ++ int ret; + -+ __asm__ __volatile__("ldstub [%1], %0" -+ : "=r" (ret) -+ : "r" (p) -+ : "memory"); ++ __asm__ __volatile__("ldstub [%1], %0" ++ : "=r" (ret) ++ : "r" (p) ++ : "memory"); + -+ return (ret ? 1 : 0); ++ return (ret ? 1 : 0); +} +#endif + @@ -815,7 +719,7 @@ Index: qemu/qemu_spinlock.h + __asm__ __volatile__("swp %0, %1, [%2]" + : "=r"(ret) + : "0"(1), "r"(spinlock)); -+ ++ + return ret; +} +#endif @@ -841,28 +745,6 @@ Index: qemu/qemu_spinlock.h +} +#endif + -+#ifdef __mips__ -+static inline int testandset (int *p) -+{ -+ int ret; -+ -+ __asm__ __volatile__ ( -+ " .set push \n" -+ " .set noat \n" -+ " .set mips2 \n" -+ "1: li $1, 1 \n" -+ " ll %0, %1 \n" -+ " sc $1, %1 \n" -+ " beqz $1, 1b \n" -+ " .set pop " -+ : "=r" (ret), "+R" (*p) -+ : -+ : "memory"); -+ -+ return ret; -+} -+#endif -+ +typedef int spinlock_t; + +#define SPIN_LOCK_UNLOCKED 0 @@ -897,4 +779,114 @@ Index: qemu/qemu_spinlock.h +} +#endif + -+#endif /* ! _QEMU_SPINLOCK_H */ ++#endif +Index: qemu/target-arm/cpu.h +=================================================================== +--- qemu.orig/target-arm/cpu.h 2007-06-29 10:47:39.000000000 +0000 ++++ qemu/target-arm/cpu.h 2007-06-29 10:47:58.000000000 +0000 +@@ -37,6 +37,7 @@ + #define EXCP_IRQ 5 + #define EXCP_FIQ 6 + #define EXCP_BKPT 7 ++#define EXCP_KERNEL_TRAP 8 /* Jumped to kernel code page. */ + + typedef void ARMWriteCPFunc(void *opaque, int cp_info, + int srcreg, int operand, uint32_t value); +@@ -97,6 +98,7 @@ + uint32_t c9_data; + uint32_t c13_fcse; /* FCSE PID. */ + uint32_t c13_context; /* Context ID. */ ++ uint32_t c13_tls; /* Context ID. */ + uint32_t c15_cpar; /* XScale Coprocessor Access Register */ + } cp15; + +@@ -169,6 +171,15 @@ + int cpu_arm_signal_handler(int host_signum, void *pinfo, + void *puc); + ++void cpu_lock(void); ++void cpu_unlock(void); ++#if defined(USE_NPTL) ++static inline void cpu_set_tls(CPUARMState *env, void *newtls) ++{ ++ env->cp15.c13_tls = (uint32_t)(long)newtls; ++} ++#endif ++ + #define CPSR_M (0x1f) + #define CPSR_T (1 << 5) + #define CPSR_F (1 << 6) +@@ -180,7 +191,11 @@ + #define CPSR_J (1 << 24) + #define CPSR_IT_0_1 (3 << 25) + #define CPSR_Q (1 << 27) +-#define CPSR_NZCV (0xf << 28) ++#define CPSR_V (1 << 28) ++#define CPSR_C (1 << 29) ++#define CPSR_Z (1 << 30) ++#define CPSR_N (1 << 31) ++#define CPSR_NZCV (CPSR_N | CPSR_Z | CPSR_C | CPSR_V) + + #define CACHED_CPSR_BITS (CPSR_T | CPSR_Q | CPSR_NZCV) + /* Return the current CPSR value. */ +Index: qemu/target-arm/exec.h +=================================================================== +--- qemu.orig/target-arm/exec.h 2007-06-29 10:47:39.000000000 +0000 ++++ qemu/target-arm/exec.h 2007-06-29 10:47:58.000000000 +0000 +@@ -68,8 +68,6 @@ + + /* In op_helper.c */ + +-void cpu_lock(void); +-void cpu_unlock(void); + void helper_set_cp(CPUState *, uint32_t, uint32_t); + uint32_t helper_get_cp(CPUState *, uint32_t); + void helper_set_cp15(CPUState *, uint32_t, uint32_t); +Index: qemu/target-arm/op.c +=================================================================== +--- qemu.orig/target-arm/op.c 2007-06-29 10:47:39.000000000 +0000 ++++ qemu/target-arm/op.c 2007-06-29 10:47:58.000000000 +0000 +@@ -891,6 +891,12 @@ + cpu_loop_exit(); + } + ++void OPPROTO op_kernel_trap(void) ++{ ++ env->exception_index = EXCP_KERNEL_TRAP; ++ cpu_loop_exit(); ++} ++ + /* VFP support. We follow the convention used for VFP instrunctions: + Single precition routines have a "s" suffix, double precision a + "d" suffix. */ +Index: qemu/target-arm/op_mem.h +=================================================================== +--- qemu.orig/target-arm/op_mem.h 2007-06-29 10:47:39.000000000 +0000 ++++ qemu/target-arm/op_mem.h 2007-06-29 10:47:58.000000000 +0000 +@@ -1,5 +1,6 @@ + /* ARM memory operations. */ + ++void helper_ld(uint32_t); + /* Load from address T1 into T0. */ + #define MEM_LD_OP(name) \ + void OPPROTO glue(op_ld##name,MEMSUFFIX)(void) \ +Index: qemu/target-arm/translate.c +=================================================================== +--- qemu.orig/target-arm/translate.c 2007-06-29 10:47:39.000000000 +0000 ++++ qemu/target-arm/translate.c 2007-06-29 10:47:58.000000000 +0000 +@@ -3548,6 +3548,15 @@ + nb_gen_labels = 0; + lj = -1; + do { ++#ifdef CONFIG_USER_ONLY ++ /* Intercept jump to the magic kernel page. */ ++ if (dc->pc > 0xffff0000) { ++ gen_op_kernel_trap(); ++ dc->is_jmp = DISAS_UPDATE; ++ break; ++ } ++#endif ++ + if (env->nb_breakpoints > 0) { + for(j = 0; j < env->nb_breakpoints; j++) { + if (env->breakpoints[j] == dc->pc) { diff --git a/meta/packages/qemu/qemu_cvs.bb b/meta/packages/qemu/qemu_cvs.bb index 4148a4835..3392b8804 100644 --- a/meta/packages/qemu/qemu_cvs.bb +++ b/meta/packages/qemu/qemu_cvs.bb @@ -1,7 +1,7 @@ LICENSE = "GPL" DEPENDS = "zlib" PV = "0.9.0+cvs${SRCDATE}" -PR = "r0" +PR = "r1" FILESDIR = "${WORKDIR}" @@ -29,7 +29,9 @@ SRC_URI = "\ file://66_tls_ld.patch;patch=1;pnum=0 \ file://91-oh-sdl-cursor.patch;patch=1;pnum=0 \ file://93-oh-pl110-rgb.patch;patch=1;pnum=0 \ - file://94-oh-arm-nptl.patch;patch=1;pnum=1" + file://qemu-0.9.0-nptl.patch;patch=1 \ + file://qemu-0.9.0-nptl-update.patch;patch=1 \ + file://fix_segfault.patch;patch=1" # svn://svn.o-hand.com/repos/misc/trunk/qemu-packaging/qemu;module=debian;proto=http;srcdate=20070119 \ # file://debian/patches/21_net_soopts.patch;patch=1;pnum=0 \ @@ -43,6 +45,7 @@ SRC_URI = "\ S = "${WORKDIR}/qemu" #EXTRA_OECONF = "--disable-sdl" +#EXTRA_OECONF = "--disable-gfx-check --target-list=arm-linux-user" EXTRA_OECONF = "--disable-gfx-check" inherit autotools |