1. 22 Jan, 2019 4 commits
  2. 02 Nov, 2018 1 commit
    • Jean-Philippe Brucker's avatar
      virtio: Fix ordering of virt_queue__available() · 66ba0bae
      Jean-Philippe Brucker authored
      After adding buffers to the virtio queue, the guest increments the avail
      index. It then reads the event index to check if it needs to notify the
      host. If the event index corresponds to the previous avail value, then
      the guest notifies the host. Otherwise it means that the host is still
      processing the queue and hasn't had a chance to increment the event
      index yet. Once it gets there, the host will see the new avail index and
      process the descriptors, so there is no need for a notification.
      This is only guaranteed to work if both threads write and read the
      indices in the right order. Currently a barrier is missing from
      virt_queue__available(), and the host may not see an up-to-date value of
      event index after writing avail.
                   HOST            |           GUEST
                                   |    write avail = 1
                                   |    mb()
                                   |    read event -> 0
              write event = 0      |      == prev_avail -> notify
              read avail -> 1      |
              write event = 1      |
              read avail -> 1      |
              wait()               |    write avail = 2
                                   |    mb()
                                   |    read event -> 0
                                   |      != prev_avail -> no notification
      By adding a memory barrier on the host side, we ensure that it doesn't
      miss any notification.
      Reviewed-By: Steven Price's avatarSteven Price <steven.price@arm.com>
      Signed-off-by: default avatarJean-Philippe Brucker <jean-philippe.brucker@arm.com>
      Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
  3. 19 Mar, 2018 1 commit
    • 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
                     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>
  4. 29 Jan, 2018 2 commits
  5. 09 Jun, 2017 1 commit
    • Andre Przywara's avatar
      virtio: fix endianness check for vhost support · b960f243
      Andre Przywara authored
      Currently we deny any VHOST_* functionality if the architecture
      supports guests with different endianness than the host. Most of the
      time even on those architectures the endianness of guest and host are
      the same, though, so we are denying the glory of VHOST needlessly.
      Switch from compile time determination to a run time scheme, which
      takes the actual endianness of the guest into account.
      For this we change the semantics of VIRTIO_ENDIAN_HOST to return the
      actual endianness of the host (the endianness of kvmtool at compile
      time, really). The actual check in vhost_net now compares this against
      the guest endianness.
      This enables vhost support on ARM and ARM64.
      Acked-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
      Signed-off-by: Andre Przywara's avatarAndre Przywara <andre.przywara@arm.com>
      Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
  6. 17 Feb, 2017 1 commit
    • Will Deacon's avatar
      kvmtool: virtio-net: fix VIRTIO_NET_F_MRG_RXBUF usage in rx thread · 3fea89a9
      Will Deacon authored
      When merging virtio-net buffers using the VIRTIO_NET_F_MRG_RXBUF feature,
      the first buffer added to the used ring should indicate the total number
      of buffers used to hold the packet. Unfortunately, kvmtool has a number
      of issues when constructing these merged buffers:
        - Commit 5131332e3f1a ("kvmtool: convert net backend to support
          bi-endianness") introduced a strange loop counter, which resulted in
          hdr->num_buffers being set redundantly the first time round
        - When adding the buffers to the ring, we actually add them one-by-one,
          allowing the guest to see the header before we've inserted the rest
          of the data buffers...
        - ... which is made worse because we non-atomically increment the
          num_buffers count in the header each time we insert a new data buffer
      Consequently, the guest quickly becomes confused in its net rx code and
      the whole thing grinds to a halt. This is easily exemplified by trying
      to boot a root filesystem over NFS, which seldom succeeds.
      This patch resolves the issues by allowing us to insert items into the
      used ring without updating the index. Once the full payload has been
      added and num_buffers corresponds to the total size, we *then* publish
      the buffers to the guest.
      Cc: Marc Zyngier <marc.zyngier@arm.com>
      Cc: Sasha Levin <sasha.levin@oracle.com>
      Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
  7. 01 Jun, 2015 26 commits