summaryrefslogtreecommitdiffstats
path: root/meta/packages/qemu/qemu-0.9.0+cvs20070613/qemu-0.9.0-nptl-update.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/packages/qemu/qemu-0.9.0+cvs20070613/qemu-0.9.0-nptl-update.patch')
-rw-r--r--meta/packages/qemu/qemu-0.9.0+cvs20070613/qemu-0.9.0-nptl-update.patch294
1 files changed, 0 insertions, 294 deletions
diff --git a/meta/packages/qemu/qemu-0.9.0+cvs20070613/qemu-0.9.0-nptl-update.patch b/meta/packages/qemu/qemu-0.9.0+cvs20070613/qemu-0.9.0-nptl-update.patch
deleted file mode 100644
index 869acba2cf..0000000000
--- a/meta/packages/qemu/qemu-0.9.0+cvs20070613/qemu-0.9.0-nptl-update.patch
+++ /dev/null
@@ -1,294 +0,0 @@
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);