• Jean-Philippe Brucker's avatar
    virtio: Fix ordering of avail index and descriptor read · 15c4e1ef
    Jean-Philippe Brucker authored
    
    
    One barrier seems to be missing from kvmtool's virtio implementation,
    between virt_queue__available() and virt_queue__pop(). In the following
    scenario "avail" represents the shared "available" structure in the virtio
    queue:
    
                   Guest               |               Host
                                       |
        avail.ring[shadow] = desc_idx  | while (avail.idx != shadow)
        smp_wmb()                      |     /* missing smp_rmb() */
        avail.idx = ++shadow           |     desc_idx = avail.ring[shadow++]
    
    If the host observes the avail.idx write before the avail.ring update,
    then it will fetch the wrong desc_idx. Add the missing barrier.
    
    This seems to fix the horrible bug I'm often seeing when running netperf
    in a guest (virtio-net + tap) on AMD Seattle. The TX thread reads the
    wrong descriptor index and either faults when accessing the TX buffer, or
    pushes the wrong index to the used ring. In that case the guest complains
    that "id %u is not a head!" and stops the queue.
    
    Signed-off-by: default avatarJean-Philippe Brucker <jean-philippe.brucker@arm.com>
    Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
    15c4e1ef