summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Purdie <richard@openedhand.com>2007-06-29 11:10:33 +0000
committerRichard Purdie <richard@openedhand.com>2007-06-29 11:10:33 +0000
commitf1edd3b119e65256c90230f7d2adb03d52c16dc3 (patch)
treed8563728d668efe0321dee42824664ac518a7815
parent13e87f0a9638168eb7cf5a705a472a1a99113aa2 (diff)
downloadpoky-f1edd3b119e65256c90230f7d2adb03d52c16dc3.tar.gz
qemu: Resolve various segfault issues
git-svn-id: https://svn.o-hand.com/repos/poky/trunk@2060 311d38ba-8fff-0310-9ca6-ca027cbcb966
-rw-r--r--meta/packages/qemu/files/31_syscalls.patch13
-rw-r--r--meta/packages/qemu/files/fix_segfault.patch46
-rw-r--r--meta/packages/qemu/files/qemu-0.9.0-nptl-update.patch294
-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.bb7
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 e7a1b338f3..3878079f19 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
47 #endif 47 #endif
48 #ifdef TARGET_NR_setxattr 48 #ifdef TARGET_NR_setxattr
49 case TARGET_NR_setxattr: 49 case TARGET_NR_setxattr:
50Index: Makefile.target
51===================================================================
52--- Makefile.target.orig 2007-06-13 11:51:52.000000000 +0100
53+++ Makefile.target 2007-06-13 11:51:54.000000000 +0100
54@@ -215,7 +215,7 @@ OP_LDFLAGS+=$(OS_LDFLAGS) $(ARCH_LDFLAGS
55 #########################################################
56
57 CPPFLAGS+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
58-LIBS+=-lm
59+LIBS+=-lm -lrt
60 ifndef CONFIG_USER_ONLY
61 LIBS+=-lz
62 endif
diff --git a/meta/packages/qemu/files/fix_segfault.patch b/meta/packages/qemu/files/fix_segfault.patch
new file mode 100644
index 0000000000..976c75cd60
--- /dev/null
+++ b/meta/packages/qemu/files/fix_segfault.patch
@@ -0,0 +1,46 @@
1Index: qemu/Makefile.target
2===================================================================
3--- qemu.orig/Makefile.target 2007-06-29 10:57:58.000000000 +0000
4+++ qemu/Makefile.target 2007-06-29 10:58:01.000000000 +0000
5@@ -241,7 +241,6 @@
6 ifdef CONFIG_LINUX_USER
7 OBJS= main.o syscall.o mmap.o signal.o path.o osdep.o thunk.o \
8 elfload.o linuxload.o
9-LIBS+= $(AIOLIBS)
10 ifdef TARGET_HAS_BFLT
11 OBJS+= flatload.o
12 endif
13Index: qemu/linux-user/syscall.c
14===================================================================
15--- qemu.orig/linux-user/syscall.c 2007-06-29 10:58:01.000000000 +0000
16+++ qemu/linux-user/syscall.c 2007-06-29 10:58:30.000000000 +0000
17@@ -4872,29 +4872,6 @@
18 goto unimplemented_nowarn;
19 #endif
20
21-#ifdef TARGET_NR_clock_gettime
22- case TARGET_NR_clock_gettime:
23- {
24- struct timespec ts;
25- ret = get_errno(clock_gettime(arg1, &ts));
26- if (!is_error(ret)) {
27- host_to_target_timespec(arg2, &ts);
28- }
29- break;
30- }
31-#endif
32-#ifdef TARGET_NR_clock_getres
33- case TARGET_NR_clock_getres:
34- {
35- struct timespec ts;
36- ret = get_errno(clock_getres(arg1, &ts));
37- if (!is_error(ret)) {
38- host_to_target_timespec(arg2, &ts);
39- }
40- break;
41- }
42-#endif
43-
44 default:
45 unimplemented:
46 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 0000000000..869acba2cf
--- /dev/null
+++ b/meta/packages/qemu/files/qemu-0.9.0-nptl-update.patch
@@ -0,0 +1,294 @@
1Index: qemu/linux-user/main.c
2===================================================================
3--- qemu.orig/linux-user/main.c 2007-06-29 10:47:58.000000000 +0000
4+++ qemu/linux-user/main.c 2007-06-29 10:47:58.000000000 +0000
5@@ -156,7 +156,7 @@
6 p[1] = tswapl(e2);
7 }
8
9-uint64_t gdt_table[6];
10+uint64_t gdt_table[9];
11 uint64_t idt_table[256];
12
13 /* only dpl matters as we do only user space emulation */
14@@ -1768,7 +1768,11 @@
15 int optind;
16 const char *r;
17 int gdbstub_port = 0;
18-
19+ char *assume_kernel = getenv("QEMU_ASSUME_KERNEL");
20+
21+ if (assume_kernel)
22+ setenv("LD_ASSUME_KERNEL", assume_kernel, 1);
23+
24 if (argc <= 1)
25 usage();
26
27Index: qemu/linux-user/syscall.c
28===================================================================
29--- qemu.orig/linux-user/syscall.c 2007-06-29 10:47:58.000000000 +0000
30+++ qemu/linux-user/syscall.c 2007-06-29 10:53:44.000000000 +0000
31@@ -60,6 +60,7 @@
32 #define tchars host_tchars /* same as target */
33 #define ltchars host_ltchars /* same as target */
34
35+#include <linux/futex.h>
36 #include <linux/termios.h>
37 #include <linux/unistd.h>
38 #include <linux/utsname.h>
39@@ -2122,6 +2123,80 @@
40 return ret;
41 }
42
43+int do_set_thread_area(CPUX86State *env, target_ulong ptr)
44+{
45+ uint64_t *gdt_table = g2h(env->gdt.base);
46+ struct target_modify_ldt_ldt_s ldt_info;
47+ struct target_modify_ldt_ldt_s *target_ldt_info;
48+ int seg_32bit, contents, read_exec_only, limit_in_pages;
49+ int seg_not_present, useable;
50+ uint32_t *lp, entry_1, entry_2;
51+ int i;
52+
53+ lock_user_struct(target_ldt_info, ptr, 1);
54+ ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
55+ ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
56+ ldt_info.limit = tswap32(target_ldt_info->limit);
57+ ldt_info.flags = tswap32(target_ldt_info->flags);
58+ if (ldt_info.entry_number == -1) {
59+ for (i=6; i<8; i++)
60+ if (gdt_table[i] == 0) {
61+ ldt_info.entry_number = i;
62+ target_ldt_info->entry_number = tswap32(i);
63+ break;
64+ }
65+ }
66+ unlock_user_struct(target_ldt_info, ptr, 0);
67+
68+ if (ldt_info.entry_number < 6 || ldt_info.entry_number > 8)
69+ return -EINVAL;
70+ seg_32bit = ldt_info.flags & 1;
71+ contents = (ldt_info.flags >> 1) & 3;
72+ read_exec_only = (ldt_info.flags >> 3) & 1;
73+ limit_in_pages = (ldt_info.flags >> 4) & 1;
74+ seg_not_present = (ldt_info.flags >> 5) & 1;
75+ useable = (ldt_info.flags >> 6) & 1;
76+
77+ if (contents == 3) {
78+ if (seg_not_present == 0)
79+ return -EINVAL;
80+ }
81+
82+ /* NOTE: same code as Linux kernel */
83+ /* Allow LDTs to be cleared by the user. */
84+ if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
85+ if ((contents == 0 &&
86+ read_exec_only == 1 &&
87+ seg_32bit == 0 &&
88+ limit_in_pages == 0 &&
89+ seg_not_present == 1 &&
90+ useable == 0 )) {
91+ entry_1 = 0;
92+ entry_2 = 0;
93+ goto install;
94+ }
95+ }
96+
97+ entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
98+ (ldt_info.limit & 0x0ffff);
99+ entry_2 = (ldt_info.base_addr & 0xff000000) |
100+ ((ldt_info.base_addr & 0x00ff0000) >> 16) |
101+ (ldt_info.limit & 0xf0000) |
102+ ((read_exec_only ^ 1) << 9) |
103+ (contents << 10) |
104+ ((seg_not_present ^ 1) << 15) |
105+ (seg_32bit << 22) |
106+ (limit_in_pages << 23) |
107+ (useable << 20) |
108+ 0x7000;
109+
110+ /* Install the new entry ... */
111+install:
112+ lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
113+ lp[0] = tswap32(entry_1);
114+ lp[1] = tswap32(entry_2);
115+ return 0;
116+}
117 #endif /* defined(TARGET_I386) */
118
119 /* this stack is the equivalent of the kernel stack associated with a
120@@ -2154,15 +2229,20 @@
121 TaskState *ts;
122 uint8_t *new_stack;
123 CPUState *new_env;
124+#if defined(TARGET_I386)
125+ uint64_t *new_gdt_table;
126+#endif
127 #ifdef USE_NPTL
128 unsigned int nptl_flags;
129
130 if (flags & CLONE_PARENT_SETTID)
131 *parent_tidptr = gettid();
132 #endif
133-
134+
135 if (flags & CLONE_VM) {
136 ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE);
137+ if (!ts)
138+ return -ENOMEM;
139 memset(ts, 0, sizeof(TaskState));
140 new_stack = ts->stack;
141 ts->used = 1;
142@@ -2174,6 +2254,29 @@
143 #if defined(TARGET_I386)
144 if (!newsp)
145 newsp = env->regs[R_ESP];
146+ new_gdt_table = malloc(9 * 8);
147+ if (!new_gdt_table) {
148+ free(new_env);
149+ return -ENOMEM;
150+ }
151+ /* Copy main GDT table from parent, but clear TLS entries */
152+ memcpy(new_gdt_table, g2h(env->gdt.base), 6 * 8);
153+ memset(&new_gdt_table[6], 0, 3 * 8);
154+ new_env->gdt.base = h2g(new_gdt_table);
155+ if (flags & 0x00080000 /* CLONE_SETTLS */) {
156+ ret = do_set_thread_area(new_env, new_env->regs[R_ESI]);
157+ if (ret) {
158+ free(new_gdt_table);
159+ free(new_env);
160+ return ret;
161+ }
162+ }
163+ cpu_x86_load_seg(env, R_CS, new_env->regs[R_CS]);
164+ cpu_x86_load_seg(env, R_DS, new_env->regs[R_DS]);
165+ cpu_x86_load_seg(env, R_ES, new_env->regs[R_ES]);
166+ cpu_x86_load_seg(env, R_SS, new_env->regs[R_SS]);
167+ cpu_x86_load_seg(env, R_FS, new_env->regs[R_FS]);
168+ cpu_x86_load_seg(env, R_GS, new_env->regs[R_GS]);
169 new_env->regs[R_ESP] = newsp;
170 new_env->regs[R_EAX] = 0;
171 #elif defined(TARGET_ARM)
172@@ -2517,6 +2620,68 @@
173 unlock_user_struct(target_ts, target_addr, 1);
174 }
175
176+static long do_futex(target_ulong uaddr, int op, uint32_t val,
177+ target_ulong utime, target_ulong uaddr2,
178+ uint32_t val3)
179+{
180+ struct timespec host_utime;
181+ unsigned long val2 = utime;
182+
183+ if (utime && (op == FUTEX_WAIT || op == FUTEX_LOCK_PI)) {
184+ target_to_host_timespec(&host_utime, utime);
185+ val2 = (unsigned long)&host_utime;
186+ }
187+
188+#ifdef BSWAP_NEEDED
189+ switch(op) {
190+ case FUTEX_CMP_REQUEUE:
191+ val3 = tswap32(val3);
192+ case FUTEX_REQUEUE:
193+ val2 = tswap32(val2);
194+ case FUTEX_WAIT:
195+ case FUTEX_WAKE:
196+ val = tswap32(val);
197+ case FUTEX_LOCK_PI: /* This one's icky, but comes out OK */
198+ case FUTEX_UNLOCK_PI:
199+ break;
200+ default:
201+ gemu_log("qemu: Unsupported futex op %d\n", op);
202+ return -ENOSYS;
203+ }
204+#if 0 /* No, it's worse than this */
205+ if (op == FUTEX_WAKE_OP) {
206+ /* Need to munge the secondary operation (val3) */
207+ val3 = tswap32(val3);
208+ int op2 = (val3 >> 28) & 7;
209+ int cmp = (val3 >> 24) & 15;
210+ int oparg = (val3 << 8) >> 20;
211+ int cmparg = (val3 << 20) >> 20;
212+ int shift = val3 & (FUTEX_OP_OPARG_SHIFT << 28);
213+
214+ if (shift)
215+ oparg = (oparg & 7) + 24 - (oparg & 24);
216+ else oparg =
217+ if (op2 == FUTEX_OP_ADD) {
218+ gemu_log("qemu: Unsupported wrong-endian FUTEX_OP_ADD\n");
219+ return -ENOSYS;
220+ }
221+ if (cmparg == FUTEX_OP_CMP_LT || cmparg == FUTEX_OP_CMP_GE ||
222+ cmparg == FUTEX_OP_CMP_LE || cmparg == FUTEX_OP_CMP_GT) {
223+ gemu_log("qemu: Unsupported wrong-endian futex cmparg %d\n", cmparg);
224+ return -ENOSYS;
225+ }
226+ val3 = shift | (op2<<28) | (cmp<<24) | (oparg<<12) | cmparg;
227+ }
228+#endif
229+#endif
230+ return syscall(__NR_futex, g2h(uaddr), op, val, val2, g2h(uaddr2), val3);
231+}
232+
233+int do_set_tid_address(target_ulong tidptr)
234+{
235+ return syscall(__NR_set_tid_address, g2h(tidptr));
236+}
237+
238 long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
239 long arg4, long arg5, long arg6)
240 {
241@@ -2534,7 +2699,7 @@
242 _mcleanup();
243 #endif
244 gdb_exit(cpu_env, arg1);
245- /* XXX: should free thread stack and CPU env */
246+ /* XXX: should free thread stack, GDT and CPU env */
247 _exit(arg1);
248 ret = 0; /* avoid warning */
249 break;
250@@ -4642,6 +4807,9 @@
251 ((CPUMIPSState *) cpu_env)->tls_value = arg1;
252 ret = 0;
253 break;
254+#elif TARGET_i386
255+ ret = get_errno(do_set_thread_area(cpu_env, arg1));
256+ break;
257 #else
258 goto unimplemented_nowarn;
259 #endif
260@@ -4655,6 +4823,21 @@
261 goto unimplemented_nowarn;
262 #endif
263
264+#ifdef TARGET_NR_futex
265+ case TARGET_NR_futex:
266+ ret = get_errno(do_futex(arg1, arg2, arg3, arg4, arg5, arg6));
267+ break;
268+#endif
269+#ifdef TARGET_NR_set_tid_address
270+ case TARGET_NR_set_tid_address:
271+ ret = get_errno(do_set_tid_address(arg1));
272+ break;
273+#endif
274+#ifdef TARGET_NR_set_robust_list
275+ case TARGET_NR_set_robust_list:
276+ goto unimplemented_nowarn;
277+#endif
278+
279 #ifdef TARGET_NR_clock_gettime
280 case TARGET_NR_clock_gettime:
281 {
282@@ -4678,12 +4861,6 @@
283 }
284 #endif
285
286-#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
287- case TARGET_NR_set_tid_address:
288- ret = get_errno(set_tid_address((int *) arg1));
289- break;
290-#endif
291-
292 default:
293 unimplemented:
294 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 37d7171983..fc7b0cfa4b 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 @@
1--- 1These are Paul Brook's patches to QEMU-0.8.2 to enable the running of single
2 configure | 29 ++++++ 2ARM binaries under QEMU's user-emulation mode. Without them, QEMU-0.8.1
3 exec-all.h | 165 -------------------------------------- 3immediately dies saying:
4 linux-user/arm/syscall.h | 4 4 Error: f0005
5 linux-user/main.c | 94 ++++++++++++++++++--- 5 qemu: uncaught target signal 6 (Aborted) - exiting
6 linux-user/qemu.h | 3 6while qemu-0.8.2 dies saying:
7 linux-user/syscall.c | 90 ++++++++++++++++++-- 7 qemu: Unsupported syscall: 983045
8 qemu_spinlock.h | 204 +++++++++++++++++++++++++++++++++++++++++++++++ 8 cannot set up thread-local storage: unknown error
9 target-arm/cpu.h | 19 ++++ 9
10 target-arm/exec.h | 2 10This file is a rediffing of the patches visible at
11 target-arm/op.c | 6 + 11https://nowt.dyndns.org/patch.qemu_nptl on 27 Sept 2006
12 target-arm/translate.c | 10 ++ 12which "patch" fails to apply automatically.
13 11 files changed, 437 insertions(+), 189 deletions(-) 13See also http://lists.gnu.org/archive/html/qemu-devel/2006-09/msg00194.html
14
15 Martin Guy, 27 Sept 2006
14 16
15Index: qemu/configure 17Index: qemu/configure
16=================================================================== 18===================================================================
17--- qemu.orig/configure 2007-06-13 11:51:56.000000000 +0100 19--- qemu.orig/configure 2007-06-29 10:47:39.000000000 +0000
18+++ qemu/configure 2007-06-13 11:51:57.000000000 +0100 20+++ qemu/configure 2007-06-29 10:47:58.000000000 +0000
19@@ -101,6 +101,7 @@ linux_user="no" 21@@ -101,6 +101,7 @@
20 darwin_user="no" 22 darwin_user="no"
21 build_docs="no" 23 build_docs="no"
22 uname_release="" 24 uname_release=""
@@ -24,7 +26,7 @@ Index: qemu/configure
24 26
25 # OS specific 27 # OS specific
26 targetos=`uname -s` 28 targetos=`uname -s`
27@@ -287,6 +288,8 @@ for opt do 29@@ -281,6 +282,8 @@
28 *) echo "undefined SPARC architecture. Exiting";exit 1;; 30 *) echo "undefined SPARC architecture. Exiting";exit 1;;
29 esac 31 esac
30 ;; 32 ;;
@@ -33,7 +35,15 @@ Index: qemu/configure
33 esac 35 esac
34 done 36 done
35 37
36@@ -530,6 +533,23 @@ int main(void) { 38@@ -355,6 +358,7 @@
39 echo " --disable-linux-user disable all linux usermode emulation targets"
40 echo " --enable-darwin-user enable all darwin usermode emulation targets"
41 echo " --disable-darwin-user disable all darwin usermode emulation targets"
42+echo " --disable-nptl disable usermode NPTL guest support"
43 echo " --fmod-lib path to FMOD library"
44 echo " --fmod-inc path to FMOD includes"
45 echo " --enable-uname-release=R Return R for uname -r in usermode emulation"
46@@ -524,6 +528,23 @@
37 } 47 }
38 EOF 48 EOF
39 49
@@ -57,15 +67,15 @@ Index: qemu/configure
57 ########################################## 67 ##########################################
58 # SDL probe 68 # SDL probe
59 69
60@@ -681,6 +701,7 @@ if test -n "$sparc_cpu"; then 70@@ -678,6 +699,7 @@
61 echo "Target Sparc Arch $sparc_cpu"
62 fi
63 echo "kqemu support $kqemu"
64+echo "NPTL support $nptl"
65 echo "Documentation $build_docs" 71 echo "Documentation $build_docs"
66 [ ! -z "$uname_release" ] && \ 72 [ ! -z "$uname_release" ] && \
67 echo "uname -r $uname_release" 73 echo "uname -r $uname_release"
68@@ -1063,6 +1084,14 @@ if test "$target_user_only" = "no"; then 74+echo "NPTL support $nptl"
75
76 if test $sdl_too_old = "yes"; then
77 echo "-> Your SDL version is too old - please upgrade to have SDL support"
78@@ -1057,6 +1079,14 @@
69 echo "SDL_CFLAGS=`$sdl_config --cflags`" >> $config_mak 79 echo "SDL_CFLAGS=`$sdl_config --cflags`" >> $config_mak
70 fi 80 fi
71 fi 81 fi
@@ -82,9 +92,9 @@ Index: qemu/configure
82 if test "$cocoa" = "yes" ; then 92 if test "$cocoa" = "yes" ; then
83Index: qemu/exec-all.h 93Index: qemu/exec-all.h
84=================================================================== 94===================================================================
85--- qemu.orig/exec-all.h 2007-06-13 11:48:22.000000000 +0100 95--- qemu.orig/exec-all.h 2007-06-29 10:47:39.000000000 +0000
86+++ qemu/exec-all.h 2007-06-13 11:51:57.000000000 +0100 96+++ qemu/exec-all.h 2007-06-29 10:47:58.000000000 +0000
87@@ -360,170 +360,7 @@ extern CPUWriteMemoryFunc *io_mem_write[ 97@@ -360,170 +360,7 @@
88 extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4]; 98 extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
89 extern void *io_mem_opaque[IO_MEM_NB_ENTRIES]; 99 extern void *io_mem_opaque[IO_MEM_NB_ENTRIES];
90 100
@@ -258,9 +268,9 @@ Index: qemu/exec-all.h
258 268
259Index: qemu/linux-user/arm/syscall.h 269Index: qemu/linux-user/arm/syscall.h
260=================================================================== 270===================================================================
261--- qemu.orig/linux-user/arm/syscall.h 2007-06-13 11:48:22.000000000 +0100 271--- qemu.orig/linux-user/arm/syscall.h 2007-06-29 10:47:39.000000000 +0000
262+++ qemu/linux-user/arm/syscall.h 2007-06-13 11:51:57.000000000 +0100 272+++ qemu/linux-user/arm/syscall.h 2007-06-29 10:47:58.000000000 +0000
263@@ -28,7 +28,9 @@ struct target_pt_regs { 273@@ -28,7 +28,9 @@
264 #define ARM_SYSCALL_BASE 0x900000 274 #define ARM_SYSCALL_BASE 0x900000
265 #define ARM_THUMB_SYSCALL 0 275 #define ARM_THUMB_SYSCALL 0
266 276
@@ -273,9 +283,9 @@ Index: qemu/linux-user/arm/syscall.h
273 #define ARM_NR_thumb_semihosting 0xAB 283 #define ARM_NR_thumb_semihosting 0xAB
274Index: qemu/linux-user/main.c 284Index: qemu/linux-user/main.c
275=================================================================== 285===================================================================
276--- qemu.orig/linux-user/main.c 2007-06-13 11:51:55.000000000 +0100 286--- qemu.orig/linux-user/main.c 2007-06-29 10:47:39.000000000 +0000
277+++ qemu/linux-user/main.c 2007-06-13 11:51:57.000000000 +0100 287+++ qemu/linux-user/main.c 2007-06-29 10:53:47.000000000 +0000
278@@ -325,6 +325,50 @@ static void arm_cache_flush(target_ulong 288@@ -325,6 +325,50 @@
279 } 289 }
280 } 290 }
281 291
@@ -326,7 +336,7 @@ Index: qemu/linux-user/main.c
326 void cpu_loop(CPUARMState *env) 336 void cpu_loop(CPUARMState *env)
327 { 337 {
328 int trapnr; 338 int trapnr;
329@@ -430,10 +474,8 @@ void cpu_loop(CPUARMState *env) 339@@ -381,10 +425,8 @@
330 } 340 }
331 } 341 }
332 342
@@ -339,7 +349,7 @@ Index: qemu/linux-user/main.c
339 env->regs[0] = do_arm_semihosting (env); 349 env->regs[0] = do_arm_semihosting (env);
340 } else if (n == 0 || n >= ARM_SYSCALL_BASE 350 } else if (n == 0 || n >= ARM_SYSCALL_BASE
341 || (env->thumb && n == ARM_THUMB_SYSCALL)) { 351 || (env->thumb && n == ARM_THUMB_SYSCALL)) {
342@@ -444,14 +486,34 @@ void cpu_loop(CPUARMState *env) 352@@ -395,14 +437,34 @@
343 n -= ARM_SYSCALL_BASE; 353 n -= ARM_SYSCALL_BASE;
344 env->eabi = 0; 354 env->eabi = 0;
345 } 355 }
@@ -382,7 +392,7 @@ Index: qemu/linux-user/main.c
382 } else { 392 } else {
383 goto error; 393 goto error;
384 } 394 }
385@@ -490,6 +552,10 @@ void cpu_loop(CPUARMState *env) 395@@ -441,6 +503,10 @@
386 } 396 }
387 } 397 }
388 break; 398 break;
@@ -393,7 +403,7 @@ Index: qemu/linux-user/main.c
393 default: 403 default:
394 error: 404 error:
395 fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", 405 fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
396@@ -2096,6 +2162,10 @@ int main(int argc, char **argv) 406@@ -2047,6 +2113,10 @@
397 ts->heap_base = info->brk; 407 ts->heap_base = info->brk;
398 /* This will be filled in on the first SYS_HEAPINFO call. */ 408 /* This will be filled in on the first SYS_HEAPINFO call. */
399 ts->heap_limit = 0; 409 ts->heap_limit = 0;
@@ -406,23 +416,23 @@ Index: qemu/linux-user/main.c
406 if (gdbstub_port) { 416 if (gdbstub_port) {
407Index: qemu/linux-user/qemu.h 417Index: qemu/linux-user/qemu.h
408=================================================================== 418===================================================================
409--- qemu.orig/linux-user/qemu.h 2007-06-13 11:48:22.000000000 +0100 419--- qemu.orig/linux-user/qemu.h 2007-06-29 10:47:39.000000000 +0000
410+++ qemu/linux-user/qemu.h 2007-06-13 11:51:57.000000000 +0100 420+++ qemu/linux-user/qemu.h 2007-06-29 10:47:58.000000000 +0000
411@@ -81,6 +81,9 @@ typedef struct TaskState { 421@@ -80,6 +80,9 @@
422 uint32_t heap_base;
412 uint32_t heap_limit; 423 uint32_t heap_limit;
413 #endif 424 #endif
414 int used; /* non zero if used */
415+#ifdef USE_NPTL 425+#ifdef USE_NPTL
416+ uint32_t *child_tidptr; 426+ uint32_t *child_tidptr;
417+#endif 427+#endif
428 int used; /* non zero if used */
418 struct image_info *info; 429 struct image_info *info;
419 uint8_t stack[0]; 430 uint8_t stack[0];
420 } __attribute__((aligned(16))) TaskState;
421Index: qemu/linux-user/syscall.c 431Index: qemu/linux-user/syscall.c
422=================================================================== 432===================================================================
423--- qemu.orig/linux-user/syscall.c 2007-06-13 11:51:55.000000000 +0100 433--- qemu.orig/linux-user/syscall.c 2007-06-29 10:47:39.000000000 +0000
424+++ qemu/linux-user/syscall.c 2007-06-13 11:51:57.000000000 +0100 434+++ qemu/linux-user/syscall.c 2007-06-29 10:53:47.000000000 +0000
425@@ -71,9 +71,18 @@ 435@@ -70,9 +70,18 @@
426 #include <linux/kd.h> 436 #include <linux/kd.h>
427 437
428 #include "qemu.h" 438 #include "qemu.h"
@@ -441,7 +451,7 @@ Index: qemu/linux-user/syscall.c
441 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \ 451 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \
442 || defined(TARGET_M68K) || defined(TARGET_SH4) 452 || defined(TARGET_M68K) || defined(TARGET_SH4)
443 /* 16 bit uid wrappers emulation */ 453 /* 16 bit uid wrappers emulation */
444@@ -2121,20 +2130,38 @@ int do_modify_ldt(CPUX86State *env, int 454@@ -2119,20 +2128,38 @@
445 thread/process */ 455 thread/process */
446 #define NEW_STACK_SIZE 8192 456 #define NEW_STACK_SIZE 8192
447 457
@@ -481,72 +491,76 @@ Index: qemu/linux-user/syscall.c
481 491
482 if (flags & CLONE_VM) { 492 if (flags & CLONE_VM) {
483 ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE); 493 ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE);
484@@ -2197,16 +2224,60 @@ int do_fork(CPUState *env, unsigned int 494@@ -2199,16 +2226,67 @@
485 #error unsupported target CPU 495 #error unsupported target CPU
486 #endif 496 #endif
487 new_env->opaque = ts; 497 new_env->opaque = ts;
488+#ifdef USE_NPTL 498+#ifdef USE_NPTL
489+ nptl_flags = flags; 499+ nptl_flags = flags;
490+ flags &= ~CLONE_NPTL_FLAGS2; 500+ flags &= ~CLONE_NPTL_FLAGS2;
491+ if (nptl_flags & CLONE_CHILD_CLEARTID) { 501+
492+ ts->child_tidptr = child_tidptr; 502+ if (nptl_flags & CLONE_CHILD_CLEARTID) {
493+ } 503+ ts->child_tidptr = child_tidptr;
494+ if (nptl_flags & CLONE_SETTLS) 504+ }
495+ cpu_set_tls (new_env, newtls); 505+
496+ /* Grab the global cpu lock so that the thread setup appears 506+ if (nptl_flags & CLONE_SETTLS)
497+ atomic. */ 507+ cpu_set_tls (new_env, newtls);
498+ if (nptl_flags & CLONE_CHILD_SETTID) 508+
499+ spin_lock(&nptl_lock); 509+ /* Grab the global cpu lock so that the thread setup appears
510+ atomic. */
511+ if (nptl_flags & CLONE_CHILD_SETTID)
512+ spin_lock(&nptl_lock);
513+
500+#else 514+#else
501+ if (flags & CLONE_NPTL_FLAGS2) 515+ if (flags & CLONE_NPTL_FLAGS2)
502+ return -EINVAL; 516+ return -EINVAL;
503+#endif 517+#endif
504+ 518+
519+ if (CLONE_VFORK & flags)
520+ flags ^= CLONE_VM;
505 #ifdef __ia64__ 521 #ifdef __ia64__
506 ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env); 522 ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
507 #else 523 #else
508 ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env); 524 ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
509 #endif 525 #endif
510+#ifdef USE_NPTL 526+#ifdef USE_NPTL
511+ if (ret != -1) { 527+ if (ret != -1) {
512+ if (nptl_flags & CLONE_CHILD_SETTID) 528+ if (nptl_flags & CLONE_CHILD_SETTID)
513+ *child_tidptr = ret; 529+ *child_tidptr = ret;
514+ } 530+ }
515+ /* Allow the child to continue. */ 531+
516+ if (nptl_flags & CLONE_CHILD_SETTID) 532+ /* Allow the child to continue. */
517+ spin_unlock(&nptl_lock); 533+ if (nptl_flags & CLONE_CHILD_SETTID)
534+ spin_unlock(&nptl_lock);
518+#endif 535+#endif
519 } else { 536 } else {
520- /* if no CLONE_VM, we consider it is a fork */ 537 /* if no CLONE_VM, we consider it is a fork */
521- if ((flags & ~CSIGNAL) != 0) 538- if ((flags & ~CSIGNAL) != 0)
522- return -EINVAL; 539+ if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
523- ret = fork(); 540 return -EINVAL;
524+ /* if no CLONE_VM, we consider it is a fork */ 541 ret = fork();
525+ if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
526+ return -EINVAL;
527+ ret = fork();
528+#ifdef USE_NPTL 542+#ifdef USE_NPTL
529+ /* There is a race condition here. The parent process could 543+ /* There is a race condition here. The parent process could
530+ theoretically read the TID in the child process before the child 544+ theoretically read the TID in the child process before the child
531+ tid is set. This would require using either ptrace 545+ tid is set. This would require using either ptrace
532+ (not implemented) or having *_tidptr to point at a shared memory 546+ (not implemented) or having *_tidptr to point at a shared memory
533+ mapping. We can't repeat the spinlock hack used above because 547+ mapping. We can't repeat the spinlock hack used above because
534+ the child process gets its own copy of the lock. */ 548+ the child process gets its own copy of the lock. */
535+ if (ret == 0) { 549+ if (ret == 0) {
536+ /* Child Process. */ 550+ /* Child Process. */
537+ if (flags & CLONE_CHILD_SETTID) 551+ if (flags & CLONE_CHILD_SETTID)
538+ *child_tidptr = gettid(); 552+ *child_tidptr = gettid();
539+ ts = (TaskState *)env->opaque; 553+ ts = (TaskState *)env->opaque;
540+ if (flags & CLONE_CHILD_CLEARTID) 554+ if (flags & CLONE_CHILD_CLEARTID)
541+ ts->child_tidptr = child_tidptr; 555+ ts->child_tidptr = child_tidptr;
542+ if (flags & CLONE_SETTLS) 556+ if (flags & CLONE_SETTLS)
543+ cpu_set_tls (env, newtls); 557+ cpu_set_tls (env, newtls);
544+ } 558+ }
545+#endif 559+#endif
546 } 560 }
547 return ret; 561 return ret;
548 } 562 }
549@@ -2483,7 +2554,7 @@ long do_syscall(void *cpu_env, int num, 563@@ -2485,7 +2563,7 @@
550 ret = do_brk(arg1); 564 ret = do_brk(arg1);
551 break; 565 break;
552 case TARGET_NR_fork: 566 case TARGET_NR_fork:
@@ -555,7 +569,7 @@ Index: qemu/linux-user/syscall.c
555 break; 569 break;
556 #ifdef TARGET_NR_waitpid 570 #ifdef TARGET_NR_waitpid
557 case TARGET_NR_waitpid: 571 case TARGET_NR_waitpid:
558@@ -3648,7 +3719,8 @@ long do_syscall(void *cpu_env, int num, 572@@ -3649,7 +3727,8 @@
559 ret = get_errno(fsync(arg1)); 573 ret = get_errno(fsync(arg1));
560 break; 574 break;
561 case TARGET_NR_clone: 575 case TARGET_NR_clone:
@@ -565,7 +579,7 @@ Index: qemu/linux-user/syscall.c
565 break; 579 break;
566 #ifdef __NR_exit_group 580 #ifdef __NR_exit_group
567 /* new thread calls */ 581 /* new thread calls */
568@@ -4062,7 +4134,8 @@ long do_syscall(void *cpu_env, int num, 582@@ -4037,7 +4116,8 @@
569 #endif 583 #endif
570 #ifdef TARGET_NR_vfork 584 #ifdef TARGET_NR_vfork
571 case TARGET_NR_vfork: 585 case TARGET_NR_vfork:
@@ -575,129 +589,20 @@ Index: qemu/linux-user/syscall.c
575 break; 589 break;
576 #endif 590 #endif
577 #ifdef TARGET_NR_ugetrlimit 591 #ifdef TARGET_NR_ugetrlimit
578@@ -4660,4 +4733,3 @@ long do_syscall(void *cpu_env, int num, 592@@ -4619,4 +4699,3 @@
579 #endif 593 #endif
580 return ret; 594 return ret;
581 } 595 }
582- 596-
583Index: qemu/target-arm/cpu.h
584===================================================================
585--- qemu.orig/target-arm/cpu.h 2007-06-13 11:48:22.000000000 +0100
586+++ qemu/target-arm/cpu.h 2007-06-13 11:51:57.000000000 +0100
587@@ -37,6 +37,9 @@
588 #define EXCP_IRQ 5
589 #define EXCP_FIQ 6
590 #define EXCP_BKPT 7
591+#define EXCP_KERNEL_TRAP 8 /* Jumped to kernel code page. */
592+
593+
594
595 typedef void ARMWriteCPFunc(void *opaque, int cp_info,
596 int srcreg, int operand, uint32_t value);
597@@ -97,6 +100,7 @@ typedef struct CPUARMState {
598 uint32_t c9_data;
599 uint32_t c13_fcse; /* FCSE PID. */
600 uint32_t c13_context; /* Context ID. */
601+ uint32_t c13_tls; /* Paul Brook told me to just add this ;) */
602 uint32_t c15_cpar; /* XScale Coprocessor Access Register */
603 } cp15;
604
605@@ -169,6 +173,15 @@ void switch_mode(CPUARMState *, int);
606 int cpu_arm_signal_handler(int host_signum, void *pinfo,
607 void *puc);
608
609+void cpu_lock(void);
610+void cpu_unlock(void);
611+#if defined(USE_NPTL)
612+static inline void cpu_set_tls(CPUARMState *env, void *newtls)
613+{
614+ env->cp15.c13_tls = (uint32_t)newtls;
615+}
616+#endif
617+
618 #define CPSR_M (0x1f)
619 #define CPSR_T (1 << 5)
620 #define CPSR_F (1 << 6)
621@@ -180,7 +193,11 @@ int cpu_arm_signal_handler(int host_sign
622 #define CPSR_J (1 << 24)
623 #define CPSR_IT_0_1 (3 << 25)
624 #define CPSR_Q (1 << 27)
625-#define CPSR_NZCV (0xf << 28)
626+#define CPSR_V (1 << 28)
627+#define CPSR_C (1 << 29)
628+#define CPSR_Z (1 << 30)
629+#define CPSR_N (1 << 31)
630+#define CPSR_NZCV (CPSR_N | CPSR_Z | CPSR_C | CPSR_V)
631
632 #define CACHED_CPSR_BITS (CPSR_T | CPSR_Q | CPSR_NZCV)
633 /* Return the current CPSR value. */
634Index: qemu/target-arm/exec.h
635===================================================================
636--- qemu.orig/target-arm/exec.h 2007-06-13 11:48:22.000000000 +0100
637+++ qemu/target-arm/exec.h 2007-06-13 11:51:57.000000000 +0100
638@@ -68,8 +68,6 @@ static inline int cpu_halted(CPUState *e
639
640 /* In op_helper.c */
641
642-void cpu_lock(void);
643-void cpu_unlock(void);
644 void helper_set_cp(CPUState *, uint32_t, uint32_t);
645 uint32_t helper_get_cp(CPUState *, uint32_t);
646 void helper_set_cp15(CPUState *, uint32_t, uint32_t);
647Index: qemu/target-arm/op.c
648===================================================================
649--- qemu.orig/target-arm/op.c 2007-06-13 11:48:22.000000000 +0100
650+++ qemu/target-arm/op.c 2007-06-13 11:51:57.000000000 +0100
651@@ -891,6 +891,12 @@ void OPPROTO op_bkpt(void)
652 cpu_loop_exit();
653 }
654
655+void OPPROTO op_kernel_trap(void)
656+{
657+ env->exception_index = EXCP_KERNEL_TRAP;
658+ cpu_loop_exit();
659+}
660+
661 /* VFP support. We follow the convention used for VFP instrunctions:
662 Single precition routines have a "s" suffix, double precision a
663 "d" suffix. */
664Index: qemu/target-arm/translate.c
665===================================================================
666--- qemu.orig/target-arm/translate.c 2007-06-13 11:48:22.000000000 +0100
667+++ qemu/target-arm/translate.c 2007-06-13 11:51:57.000000000 +0100
668@@ -3513,6 +3513,7 @@ undef:
669 s->is_jmp = DISAS_JUMP;
670 }
671
672+
673 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
674 basic block 'tb'. If search_pc is TRUE, also generate PC
675 information for each intermediate instruction. */
676@@ -3548,6 +3549,15 @@ static inline int gen_intermediate_code_
677 nb_gen_labels = 0;
678 lj = -1;
679 do {
680+#ifdef CONFIG_USER_ONLY
681+ /* Intercept jump to the magic kernel page. */
682+ if (dc->pc > 0xffff0000) {
683+ gen_op_kernel_trap();
684+ dc->is_jmp = DISAS_UPDATE;
685+ break;
686+ }
687+#endif
688+
689 if (env->nb_breakpoints > 0) {
690 for(j = 0; j < env->nb_breakpoints; j++) {
691 if (env->breakpoints[j] == dc->pc) {
692Index: qemu/qemu_spinlock.h 597Index: qemu/qemu_spinlock.h
693=================================================================== 598===================================================================
694--- /dev/null 1970-01-01 00:00:00.000000000 +0000 599--- /dev/null 1970-01-01 00:00:00.000000000 +0000
695+++ qemu/qemu_spinlock.h 2007-06-13 11:51:57.000000000 +0100 600+++ qemu/qemu_spinlock.h 2007-06-29 10:47:58.000000000 +0000
696@@ -0,0 +1,204 @@ 601@@ -0,0 +1,181 @@
697+/* 602+/*
698+ * internal execution defines for qemu 603+ * Atomic operation helper include
699+ * 604+ *
700+ * Copyright (c) 2003 Fabrice Bellard 605+ * Copyright (c) 2005 Fabrice Bellard
701+ * 606+ *
702+ * This library is free software; you can redistribute it and/or 607+ * This library is free software; you can redistribute it and/or
703+ * modify it under the terms of the GNU Lesser General Public 608+ * modify it under the terms of the GNU Lesser General Public
@@ -713,9 +618,8 @@ Index: qemu/qemu_spinlock.h
713+ * License along with this library; if not, write to the Free Software 618+ * License along with this library; if not, write to the Free Software
714+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 619+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
715+ */ 620+ */
716+ 621+#ifndef QEMU_SPINLOCK_H
717+#ifndef _QEMU_SPINLOCK_H 622+#define QEMU_SPINLOCK_H
718+#define _QEMU_SPINLOCK_H
719+ 623+
720+#ifdef __powerpc__ 624+#ifdef __powerpc__
721+static inline int testandset (int *p) 625+static inline int testandset (int *p)
@@ -739,7 +643,7 @@ Index: qemu/qemu_spinlock.h
739+static inline int testandset (int *p) 643+static inline int testandset (int *p)
740+{ 644+{
741+ long int readval = 0; 645+ long int readval = 0;
742+ 646+
743+ __asm__ __volatile__ ("lock; cmpxchgl %2, %0" 647+ __asm__ __volatile__ ("lock; cmpxchgl %2, %0"
744+ : "+m" (*p), "+a" (readval) 648+ : "+m" (*p), "+a" (readval)
745+ : "r" (1) 649+ : "r" (1)
@@ -752,7 +656,7 @@ Index: qemu/qemu_spinlock.h
752+static inline int testandset (int *p) 656+static inline int testandset (int *p)
753+{ 657+{
754+ long int readval = 0; 658+ long int readval = 0;
755+ 659+
756+ __asm__ __volatile__ ("lock; cmpxchgl %2, %0" 660+ __asm__ __volatile__ ("lock; cmpxchgl %2, %0"
757+ : "+m" (*p), "+a" (readval) 661+ : "+m" (*p), "+a" (readval)
758+ : "r" (1) 662+ : "r" (1)
@@ -767,10 +671,10 @@ Index: qemu/qemu_spinlock.h
767+ int ret; 671+ int ret;
768+ 672+
769+ __asm__ __volatile__ ("0: cs %0,%1,0(%2)\n" 673+ __asm__ __volatile__ ("0: cs %0,%1,0(%2)\n"
770+ " jl 0b" 674+ " jl 0b"
771+ : "=&d" (ret) 675+ : "=&d" (ret)
772+ : "r" (1), "a" (p), "0" (*p) 676+ : "r" (1), "a" (p), "0" (*p)
773+ : "cc", "memory" ); 677+ : "cc", "memory" );
774+ return ret; 678+ return ret;
775+} 679+}
776+#endif 680+#endif
@@ -781,15 +685,15 @@ Index: qemu/qemu_spinlock.h
781+ int ret; 685+ int ret;
782+ unsigned long one; 686+ unsigned long one;
783+ 687+
784+ __asm__ __volatile__ ("0: mov 1,%2\n" 688+ __asm__ __volatile__ ("0: mov 1,%2\n"
785+ " ldl_l %0,%1\n" 689+ " ldl_l %0,%1\n"
786+ " stl_c %2,%1\n" 690+ " stl_c %2,%1\n"
787+ " beq %2,1f\n" 691+ " beq %2,1f\n"
788+ ".subsection 2\n" 692+ ".subsection 2\n"
789+ "1: br 0b\n" 693+ "1: br 0b\n"
790+ ".previous" 694+ ".previous"
791+ : "=r" (ret), "=m" (*p), "=r" (one) 695+ : "=r" (ret), "=m" (*p), "=r" (one)
792+ : "m" (*p)); 696+ : "m" (*p));
793+ return ret; 697+ return ret;
794+} 698+}
795+#endif 699+#endif
@@ -797,14 +701,14 @@ Index: qemu/qemu_spinlock.h
797+#ifdef __sparc__ 701+#ifdef __sparc__
798+static inline int testandset (int *p) 702+static inline int testandset (int *p)
799+{ 703+{
800+ int ret; 704+ int ret;
801+ 705+
802+ __asm__ __volatile__("ldstub [%1], %0" 706+ __asm__ __volatile__("ldstub [%1], %0"
803+ : "=r" (ret) 707+ : "=r" (ret)
804+ : "r" (p) 708+ : "r" (p)
805+ : "memory"); 709+ : "memory");
806+ 710+
807+ return (ret ? 1 : 0); 711+ return (ret ? 1 : 0);
808+} 712+}
809+#endif 713+#endif
810+ 714+
@@ -815,7 +719,7 @@ Index: qemu/qemu_spinlock.h
815+ __asm__ __volatile__("swp %0, %1, [%2]" 719+ __asm__ __volatile__("swp %0, %1, [%2]"
816+ : "=r"(ret) 720+ : "=r"(ret)
817+ : "0"(1), "r"(spinlock)); 721+ : "0"(1), "r"(spinlock));
818+ 722+
819+ return ret; 723+ return ret;
820+} 724+}
821+#endif 725+#endif
@@ -841,28 +745,6 @@ Index: qemu/qemu_spinlock.h
841+} 745+}
842+#endif 746+#endif
843+ 747+
844+#ifdef __mips__
845+static inline int testandset (int *p)
846+{
847+ int ret;
848+
849+ __asm__ __volatile__ (
850+ " .set push \n"
851+ " .set noat \n"
852+ " .set mips2 \n"
853+ "1: li $1, 1 \n"
854+ " ll %0, %1 \n"
855+ " sc $1, %1 \n"
856+ " beqz $1, 1b \n"
857+ " .set pop "
858+ : "=r" (ret), "+R" (*p)
859+ :
860+ : "memory");
861+
862+ return ret;
863+}
864+#endif
865+
866+typedef int spinlock_t; 748+typedef int spinlock_t;
867+ 749+
868+#define SPIN_LOCK_UNLOCKED 0 750+#define SPIN_LOCK_UNLOCKED 0
@@ -897,4 +779,114 @@ Index: qemu/qemu_spinlock.h
897+} 779+}
898+#endif 780+#endif
899+ 781+
900+#endif /* ! _QEMU_SPINLOCK_H */ 782+#endif
783Index: qemu/target-arm/cpu.h
784===================================================================
785--- qemu.orig/target-arm/cpu.h 2007-06-29 10:47:39.000000000 +0000
786+++ qemu/target-arm/cpu.h 2007-06-29 10:47:58.000000000 +0000
787@@ -37,6 +37,7 @@
788 #define EXCP_IRQ 5
789 #define EXCP_FIQ 6
790 #define EXCP_BKPT 7
791+#define EXCP_KERNEL_TRAP 8 /* Jumped to kernel code page. */
792
793 typedef void ARMWriteCPFunc(void *opaque, int cp_info,
794 int srcreg, int operand, uint32_t value);
795@@ -97,6 +98,7 @@
796 uint32_t c9_data;
797 uint32_t c13_fcse; /* FCSE PID. */
798 uint32_t c13_context; /* Context ID. */
799+ uint32_t c13_tls; /* Context ID. */
800 uint32_t c15_cpar; /* XScale Coprocessor Access Register */
801 } cp15;
802
803@@ -169,6 +171,15 @@
804 int cpu_arm_signal_handler(int host_signum, void *pinfo,
805 void *puc);
806
807+void cpu_lock(void);
808+void cpu_unlock(void);
809+#if defined(USE_NPTL)
810+static inline void cpu_set_tls(CPUARMState *env, void *newtls)
811+{
812+ env->cp15.c13_tls = (uint32_t)(long)newtls;
813+}
814+#endif
815+
816 #define CPSR_M (0x1f)
817 #define CPSR_T (1 << 5)
818 #define CPSR_F (1 << 6)
819@@ -180,7 +191,11 @@
820 #define CPSR_J (1 << 24)
821 #define CPSR_IT_0_1 (3 << 25)
822 #define CPSR_Q (1 << 27)
823-#define CPSR_NZCV (0xf << 28)
824+#define CPSR_V (1 << 28)
825+#define CPSR_C (1 << 29)
826+#define CPSR_Z (1 << 30)
827+#define CPSR_N (1 << 31)
828+#define CPSR_NZCV (CPSR_N | CPSR_Z | CPSR_C | CPSR_V)
829
830 #define CACHED_CPSR_BITS (CPSR_T | CPSR_Q | CPSR_NZCV)
831 /* Return the current CPSR value. */
832Index: qemu/target-arm/exec.h
833===================================================================
834--- qemu.orig/target-arm/exec.h 2007-06-29 10:47:39.000000000 +0000
835+++ qemu/target-arm/exec.h 2007-06-29 10:47:58.000000000 +0000
836@@ -68,8 +68,6 @@
837
838 /* In op_helper.c */
839
840-void cpu_lock(void);
841-void cpu_unlock(void);
842 void helper_set_cp(CPUState *, uint32_t, uint32_t);
843 uint32_t helper_get_cp(CPUState *, uint32_t);
844 void helper_set_cp15(CPUState *, uint32_t, uint32_t);
845Index: qemu/target-arm/op.c
846===================================================================
847--- qemu.orig/target-arm/op.c 2007-06-29 10:47:39.000000000 +0000
848+++ qemu/target-arm/op.c 2007-06-29 10:47:58.000000000 +0000
849@@ -891,6 +891,12 @@
850 cpu_loop_exit();
851 }
852
853+void OPPROTO op_kernel_trap(void)
854+{
855+ env->exception_index = EXCP_KERNEL_TRAP;
856+ cpu_loop_exit();
857+}
858+
859 /* VFP support. We follow the convention used for VFP instrunctions:
860 Single precition routines have a "s" suffix, double precision a
861 "d" suffix. */
862Index: qemu/target-arm/op_mem.h
863===================================================================
864--- qemu.orig/target-arm/op_mem.h 2007-06-29 10:47:39.000000000 +0000
865+++ qemu/target-arm/op_mem.h 2007-06-29 10:47:58.000000000 +0000
866@@ -1,5 +1,6 @@
867 /* ARM memory operations. */
868
869+void helper_ld(uint32_t);
870 /* Load from address T1 into T0. */
871 #define MEM_LD_OP(name) \
872 void OPPROTO glue(op_ld##name,MEMSUFFIX)(void) \
873Index: qemu/target-arm/translate.c
874===================================================================
875--- qemu.orig/target-arm/translate.c 2007-06-29 10:47:39.000000000 +0000
876+++ qemu/target-arm/translate.c 2007-06-29 10:47:58.000000000 +0000
877@@ -3548,6 +3548,15 @@
878 nb_gen_labels = 0;
879 lj = -1;
880 do {
881+#ifdef CONFIG_USER_ONLY
882+ /* Intercept jump to the magic kernel page. */
883+ if (dc->pc > 0xffff0000) {
884+ gen_op_kernel_trap();
885+ dc->is_jmp = DISAS_UPDATE;
886+ break;
887+ }
888+#endif
889+
890 if (env->nb_breakpoints > 0) {
891 for(j = 0; j < env->nb_breakpoints; j++) {
892 if (env->breakpoints[j] == dc->pc) {
diff --git a/meta/packages/qemu/qemu_cvs.bb b/meta/packages/qemu/qemu_cvs.bb
index 4148a4835c..3392b8804e 100644
--- a/meta/packages/qemu/qemu_cvs.bb
+++ b/meta/packages/qemu/qemu_cvs.bb
@@ -1,7 +1,7 @@
1LICENSE = "GPL" 1LICENSE = "GPL"
2DEPENDS = "zlib" 2DEPENDS = "zlib"
3PV = "0.9.0+cvs${SRCDATE}" 3PV = "0.9.0+cvs${SRCDATE}"
4PR = "r0" 4PR = "r1"
5 5
6FILESDIR = "${WORKDIR}" 6FILESDIR = "${WORKDIR}"
7 7
@@ -29,7 +29,9 @@ SRC_URI = "\
29 file://66_tls_ld.patch;patch=1;pnum=0 \ 29 file://66_tls_ld.patch;patch=1;pnum=0 \
30 file://91-oh-sdl-cursor.patch;patch=1;pnum=0 \ 30 file://91-oh-sdl-cursor.patch;patch=1;pnum=0 \
31 file://93-oh-pl110-rgb.patch;patch=1;pnum=0 \ 31 file://93-oh-pl110-rgb.patch;patch=1;pnum=0 \
32 file://94-oh-arm-nptl.patch;patch=1;pnum=1" 32 file://qemu-0.9.0-nptl.patch;patch=1 \
33 file://qemu-0.9.0-nptl-update.patch;patch=1 \
34 file://fix_segfault.patch;patch=1"
33 35
34# svn://svn.o-hand.com/repos/misc/trunk/qemu-packaging/qemu;module=debian;proto=http;srcdate=20070119 \ 36# svn://svn.o-hand.com/repos/misc/trunk/qemu-packaging/qemu;module=debian;proto=http;srcdate=20070119 \
35# file://debian/patches/21_net_soopts.patch;patch=1;pnum=0 \ 37# file://debian/patches/21_net_soopts.patch;patch=1;pnum=0 \
@@ -43,6 +45,7 @@ SRC_URI = "\
43S = "${WORKDIR}/qemu" 45S = "${WORKDIR}/qemu"
44 46
45#EXTRA_OECONF = "--disable-sdl" 47#EXTRA_OECONF = "--disable-sdl"
48#EXTRA_OECONF = "--disable-gfx-check --target-list=arm-linux-user"
46EXTRA_OECONF = "--disable-gfx-check" 49EXTRA_OECONF = "--disable-gfx-check"
47 50
48inherit autotools 51inherit autotools