Barriers in qemu-barrier.h should not be x86 specific
commite22517086bbdf8d09de2b9ba8b3dfa4c42ec0f6c
authorDavid Gibson <david@gibson.dropbear.id.au>
Tue, 20 Sep 2011 02:05:21 +0000 (20 12:05 +1000)
committerAnthony Liguori <aliguori@us.ibm.com>
Fri, 23 Sep 2011 16:51:05 +0000 (23 11:51 -0500)
tree2b9cb6ec0537aa264faab6a209c64da6b65b70e5
parentb90d2f35125490b8f62484c5ea7e6bbecbe43b6f
Barriers in qemu-barrier.h should not be x86 specific

qemu-barrier.h contains a few macros implementing memory barrier
primitives used in several places throughout qemu.  However, apart
from the compiler-only barrier, the defined wmb() is correct only for
x86, or platforms which are similarly strongly ordered.

This patch addresses the FIXME about this by making the wmb() macro
arch dependent.  On x86, it remains a compiler barrier only, but with
a comment explaining in more detail the conditions under which this is
correct.  On weakly-ordered powerpc, an "eieio" instruction is used,
again with explanation of the conditions under which it is sufficient.

On other platforms, we use the __sync_synchronize() primitive,
available in sufficiently recent gcc (4.2 and after?).  This should
implement a full barrier which will be sufficient on all platforms,
although it may be overkill in some cases.  Other platforms can add
optimized versions in future if it's worth it for them.

Without proper memory barriers, it is easy to reproduce ordering
problems with virtio on powerpc; specifically, the QEMU puts new
element into the "used" ring and then updates the ring free-running
counter.  Without a barrier between these under the right
circumstances, the guest linux driver can receive an interrupt, read
the counter change but find the ring element to be handled still has
an old value, leading to an "id %u is not a head!\n" error message.
Similar problems are likely to be possible with kvm on other weakly
ordered platforms.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
qemu-barrier.h