qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] Race condition between signal handler and cpu_exec()


From: Aurelien Jarno
Subject: [Qemu-devel] Race condition between signal handler and cpu_exec()
Date: Thu, 5 Mar 2009 23:14:12 +0100
User-agent: Mutt/1.5.18 (2008-05-17)

Hi,

I have just found the root of a long standing but rare problem, the 
freeze of QEMU for a few seconds when using -clock dynticks. Laurent
Vivier, while working on the DMA support in MACIO remarked that running
'dbench 1' in the PPC target almost always trigger the bug after some
time. This helped finding the problem.

The problem is caused by a race condition between the signal handler and
cpu_exec():
- host_alarm_handler() calls cpu_interrupt(env, CPU_INTERRUPT_EXIT);
- cpu_interrupt(CPUState *env, int mask) does env->interrupt_request |= mask;
- it can happen while cpu_exec() does:

|  if (env->interrupt_request & CPU_INTERRUPT_EXITTB) {
|      env->interrupt_request &= ~CPU_INTERRUPT_EXITTB; 

- the corresponding x86_64 assembly code is:
|       movl    624(%r14), %eax
|       testb   $4, %al
|       je      .L26
|       andl    $-5, %eax
|       movl    %eax, 624(%r14)

That is a non atomic operation. This cause an endless loop in cpu_exec().
I guess it can happens at other place modifying env->interrupt_request,
but this seems to occurs that as this code is executed very often.

This does not happens with clocks other than dynticks, as they trigger
SIGALRM again and again which at the end sets the correct value.

I am currently too tired to find a proper solution (which should only
use read/write to a variable to keep the operations atomic), I'll look
at that tomorrow, but patches are welcome in the meanwhile.

-- 
Aurelien Jarno                          GPG: 1024D/F1BCDB73
address@hidden                 http://www.aurel32.net




reply via email to

[Prev in Thread] Current Thread [Next in Thread]