Revision 25eb4484

b/exec-i386.c
27 27

  
28 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 32
void cpu_lock(void)
112 33
{
113
    while (testandset(&global_cpu_lock));
34
    spin_lock(&global_cpu_lock);
114 35
}
115 36

  
116 37
void cpu_unlock(void)
117 38
{
118
    global_cpu_lock = 0;
39
    spin_unlock(&global_cpu_lock);
119 40
}
120 41

  
121 42
/* exception support */
......
292 213
                         flags);
293 214
            if (!tb) {
294 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 219
                tc_ptr = code_gen_ptr;
299 220
                ret = cpu_x86_gen_code(code_gen_ptr, CODE_GEN_MAX_SIZE, 
300 221
                                       &code_gen_size, pc, cs_base, flags,
301 222
                                       &code_size);
302 223
                /* if invalid instruction, signal it */
303 224
                if (ret != 0) {
304
                    cpu_unlock();
225
                    spin_unlock(&tb_lock);
305 226
                    raise_exception(EXCP06_ILLOP);
306 227
                }
307 228
                tb = tb_alloc((unsigned long)pc, code_size);
......
311 232
                tb->tc_ptr = tc_ptr;
312 233
                tb->hash_next = NULL;
313 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 237
#ifdef DEBUG_EXEC
317 238
	    if (loglevel) {
......
412 333
    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx wr=%d oldset=0x%08lx\n", 
413 334
           pc, address, is_write, *(unsigned long *)old_set);
414 335
#endif
336
    /* XXX: locking issue */
415 337
    if (is_write && page_unprotect(address)) {
416 338
        sigprocmask(SIG_SETMASK, old_set, NULL);
417 339
        return 1;
......
454 376
                             uc->uc_mcontext.gregs[REG_TRAPNO] == 0xe ? 
455 377
                             (uc->uc_mcontext.gregs[REG_ERR] >> 1) & 1 : 0,
456 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 399
#else
458
#warning No CPU specific signal handler: cannot handle target SIGSEGV events
400
#error CPU specific signal handler needed
459 401
    return 0;
460 402
#endif
461 403
}

Also available in: Unified diff