Commit 25eb44841e4125da67338320d8af0b4859c672de

Authored by bellard
1 parent b333af06

better locking - added PowerPC signal handler (add it for the other archs too be…

…cause it needed for full exception support)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@168 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 30 additions and 88 deletions
exec-i386.c
@@ -27,95 +27,16 @@ @@ -27,95 +27,16 @@
27 27
28 /* thread support */ 28 /* thread support */
29 29
30 -#ifdef __powerpc__  
31 -static inline int testandset (int *p)  
32 -{  
33 - int ret;  
34 - __asm__ __volatile__ (  
35 - "0: lwarx %0,0,%1 ;"  
36 - " xor. %0,%3,%0;"  
37 - " bne 1f;"  
38 - " stwcx. %2,0,%1;"  
39 - " bne- 0b;"  
40 - "1: "  
41 - : "=&r" (ret)  
42 - : "r" (p), "r" (1), "r" (0)  
43 - : "cr0", "memory");  
44 - return ret;  
45 -}  
46 -#endif  
47 -  
48 -#ifdef __i386__  
49 -static inline int testandset (int *p)  
50 -{  
51 - char ret;  
52 - long int readval;  
53 -  
54 - __asm__ __volatile__ ("lock; cmpxchgl %3, %1; sete %0"  
55 - : "=q" (ret), "=m" (*p), "=a" (readval)  
56 - : "r" (1), "m" (*p), "a" (0)  
57 - : "memory");  
58 - return ret;  
59 -}  
60 -#endif  
61 -  
62 -#ifdef __s390__  
63 -static inline int testandset (int *p)  
64 -{  
65 - int ret;  
66 -  
67 - __asm__ __volatile__ ("0: cs %0,%1,0(%2)\n"  
68 - " jl 0b"  
69 - : "=&d" (ret)  
70 - : "r" (1), "a" (p), "0" (*p)  
71 - : "cc", "memory" );  
72 - return ret;  
73 -}  
74 -#endif  
75 -  
76 -#ifdef __alpha__  
77 -int testandset (int *p)  
78 -{  
79 - int ret;  
80 - unsigned long one;  
81 -  
82 - __asm__ __volatile__ ("0: mov 1,%2\n"  
83 - " ldl_l %0,%1\n"  
84 - " stl_c %2,%1\n"  
85 - " beq %2,1f\n"  
86 - ".subsection 2\n"  
87 - "1: br 0b\n"  
88 - ".previous"  
89 - : "=r" (ret), "=m" (*p), "=r" (one)  
90 - : "m" (*p));  
91 - return ret;  
92 -}  
93 -#endif  
94 -  
95 -#ifdef __sparc__  
96 -static inline int testandset (int *p)  
97 -{  
98 - int ret;  
99 -  
100 - __asm__ __volatile__("ldstub [%1], %0"  
101 - : "=r" (ret)  
102 - : "r" (p)  
103 - : "memory");  
104 -  
105 - return (ret ? 1 : 0);  
106 -}  
107 -#endif  
108 -  
109 -int global_cpu_lock = 0; 30 +spinlock_t global_cpu_lock = SPIN_LOCK_UNLOCKED;
110 31
111 void cpu_lock(void) 32 void cpu_lock(void)
112 { 33 {
113 - while (testandset(&global_cpu_lock)); 34 + spin_lock(&global_cpu_lock);
114 } 35 }
115 36
116 void cpu_unlock(void) 37 void cpu_unlock(void)
117 { 38 {
118 - global_cpu_lock = 0; 39 + spin_unlock(&global_cpu_lock);
119 } 40 }
120 41
121 /* exception support */ 42 /* exception support */
@@ -292,16 +213,16 @@ int cpu_x86_exec(CPUX86State *env1) @@ -292,16 +213,16 @@ int cpu_x86_exec(CPUX86State *env1)
292 flags); 213 flags);
293 if (!tb) { 214 if (!tb) {
294 /* if no translated code available, then translate it now */ 215 /* if no translated code available, then translate it now */
295 - /* XXX: very inefficient: we lock all the cpus when  
296 - generating code */  
297 - cpu_lock(); 216 + /* very inefficient but safe: we lock all the cpus
  217 + when generating code */
  218 + spin_lock(&tb_lock);
298 tc_ptr = code_gen_ptr; 219 tc_ptr = code_gen_ptr;
299 ret = cpu_x86_gen_code(code_gen_ptr, CODE_GEN_MAX_SIZE, 220 ret = cpu_x86_gen_code(code_gen_ptr, CODE_GEN_MAX_SIZE,
300 &code_gen_size, pc, cs_base, flags, 221 &code_gen_size, pc, cs_base, flags,
301 &code_size); 222 &code_size);
302 /* if invalid instruction, signal it */ 223 /* if invalid instruction, signal it */
303 if (ret != 0) { 224 if (ret != 0) {
304 - cpu_unlock(); 225 + spin_unlock(&tb_lock);
305 raise_exception(EXCP06_ILLOP); 226 raise_exception(EXCP06_ILLOP);
306 } 227 }
307 tb = tb_alloc((unsigned long)pc, code_size); 228 tb = tb_alloc((unsigned long)pc, code_size);
@@ -311,7 +232,7 @@ int cpu_x86_exec(CPUX86State *env1) @@ -311,7 +232,7 @@ int cpu_x86_exec(CPUX86State *env1)
311 tb->tc_ptr = tc_ptr; 232 tb->tc_ptr = tc_ptr;
312 tb->hash_next = NULL; 233 tb->hash_next = NULL;
313 code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1)); 234 code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
314 - cpu_unlock(); 235 + spin_unlock(&tb_lock);
315 } 236 }
316 #ifdef DEBUG_EXEC 237 #ifdef DEBUG_EXEC
317 if (loglevel) { 238 if (loglevel) {
@@ -412,6 +333,7 @@ static inline int handle_cpu_signal(unsigned long pc, @@ -412,6 +333,7 @@ static inline int handle_cpu_signal(unsigned long pc,
412 printf("qemu: SIGSEGV pc=0x%08lx address=%08lx wr=%d oldset=0x%08lx\n", 333 printf("qemu: SIGSEGV pc=0x%08lx address=%08lx wr=%d oldset=0x%08lx\n",
413 pc, address, is_write, *(unsigned long *)old_set); 334 pc, address, is_write, *(unsigned long *)old_set);
414 #endif 335 #endif
  336 + /* XXX: locking issue */
415 if (is_write && page_unprotect(address)) { 337 if (is_write && page_unprotect(address)) {
416 sigprocmask(SIG_SETMASK, old_set, NULL); 338 sigprocmask(SIG_SETMASK, old_set, NULL);
417 return 1; 339 return 1;
@@ -454,8 +376,28 @@ int cpu_x86_signal_handler(int host_signum, struct siginfo *info, @@ -454,8 +376,28 @@ int cpu_x86_signal_handler(int host_signum, struct siginfo *info,
454 uc->uc_mcontext.gregs[REG_TRAPNO] == 0xe ? 376 uc->uc_mcontext.gregs[REG_TRAPNO] == 0xe ?
455 (uc->uc_mcontext.gregs[REG_ERR] >> 1) & 1 : 0, 377 (uc->uc_mcontext.gregs[REG_ERR] >> 1) & 1 : 0,
456 pold_set); 378 pold_set);
  379 +#elif defined(__powerpc)
  380 + struct ucontext *uc = puc;
  381 + struct pt_regs *regs = uc->uc_mcontext.regs;
  382 + unsigned long pc;
  383 + sigset_t *pold_set;
  384 + int is_write;
  385 +
  386 + pc = regs->nip;
  387 + pold_set = &uc->uc_sigmask;
  388 + is_write = 0;
  389 +#if 0
  390 + /* ppc 4xx case */
  391 + if (regs->dsisr & 0x00800000)
  392 + is_write = 1;
  393 +#else
  394 + if (regs->trap != 0x400 && (regs->dsisr & 0x02000000))
  395 + is_write = 1;
  396 +#endif
  397 + return handle_cpu_signal(pc, (unsigned long)info->si_addr,
  398 + is_write, pold_set);
457 #else 399 #else
458 -#warning No CPU specific signal handler: cannot handle target SIGSEGV events 400 +#error CPU specific signal handler needed
459 return 0; 401 return 0;
460 #endif 402 #endif
461 } 403 }