Skip to content
  • David Gibson's avatar
    Barriers in qemu-barrier.h should not be x86 specific · e2251708
    David Gibson authored
    
    
    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: default avatarAlexey Kardashevskiy <aik@ozlabs.ru>
    Signed-off-by: default avatarDavid Gibson <david@gibson.dropbear.id.au>
    Signed-off-by: default avatarAnthony Liguori <aliguori@us.ibm.com>
    e2251708