X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvirtio-ring.c;h=97a3ffee519bef72d7238deecae32e6474602058;hb=refs%2Fheads%2Fcoreboot;hp=f4a2efe3274ae95e0e1e64b0518b9d2ce04bbf69;hpb=89acfa3fb404bd81eac23bd5a3fb92d4eec50648;p=seabios.git diff --git a/src/virtio-ring.c b/src/virtio-ring.c index f4a2efe..97a3ffe 100644 --- a/src/virtio-ring.c +++ b/src/virtio-ring.c @@ -18,10 +18,12 @@ #include "virtio-ring.h" #include "virtio-pci.h" +#include "biosvar.h" // GET_GLOBAL +#include "util.h" // dprintf #define BUG() do { \ dprintf(1, "BUG: failure at %s:%d/%s()!\n", \ - __FILE__, __LINE__, __FUNCTION__); \ + __FILE__, __LINE__, __func__); \ while(1); \ } while (0) #define BUG_ON(condition) do { if (condition) BUG(); } while (0) @@ -36,8 +38,10 @@ int vring_more_used(struct vring_virtqueue *vq) { struct vring_used *used = GET_FLATPTR(vq->vring.used); - wmb(); - return GET_FLATPTR(vq->last_used_idx) != GET_FLATPTR(used->idx); + int more = GET_FLATPTR(vq->last_used_idx) != GET_FLATPTR(used->idx); + /* Make sure ring reads are done after idx read above. */ + smp_rmb(); + return more; } /* @@ -61,7 +65,6 @@ void vring_detach(struct vring_virtqueue *vq, unsigned int head) /* link it with free list and point to it */ SET_FLATPTR(desc[i].next, GET_FLATPTR(vq->free_head)); - wmb(); SET_FLATPTR(vq->free_head, head); } @@ -83,7 +86,6 @@ int vring_get_buf(struct vring_virtqueue *vq, unsigned int *len) // BUG_ON(!vring_more_used(vq)); elem = &used->ring[GET_FLATPTR(vq->last_used_idx) % GET_FLATPTR(vr->num)]; - wmb(); id = GET_FLATPTR(elem->id); if (len != NULL) *len = GET_FLATPTR(elem->len); @@ -134,19 +136,16 @@ void vring_add_buf(struct vring_virtqueue *vq, av = (GET_FLATPTR(avail->idx) + num_added) % GET_FLATPTR(vr->num); SET_FLATPTR(avail->ring[av], head); - wmb(); } void vring_kick(unsigned int ioaddr, struct vring_virtqueue *vq, int num_added) { struct vring *vr = &vq->vring; struct vring_avail *avail = GET_FLATPTR(vr->avail); - struct vring_used *used = GET_FLATPTR(vq->vring.used); - wmb(); + /* Make sure idx update is done after ring write. */ + smp_wmb(); SET_FLATPTR(avail->idx, GET_FLATPTR(avail->idx) + num_added); - mb(); - if (!(GET_FLATPTR(used->flags) & VRING_USED_F_NO_NOTIFY)) - vp_notify(ioaddr, GET_FLATPTR(vq->queue_index)); + vp_notify(ioaddr, GET_FLATPTR(vq->queue_index)); }