Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef _LINUX_VIRTIO_RING_H
0003 #define _LINUX_VIRTIO_RING_H
0004 
0005 #include <asm/barrier.h>
0006 #include <linux/irqreturn.h>
0007 #include <uapi/linux/virtio_ring.h>
0008 
0009 /*
0010  * Barriers in virtio are tricky.  Non-SMP virtio guests can't assume
0011  * they're not on an SMP host system, so they need to assume real
0012  * barriers.  Non-SMP virtio hosts could skip the barriers, but does
0013  * anyone care?
0014  *
0015  * For virtio_pci on SMP, we don't need to order with respect to MMIO
0016  * accesses through relaxed memory I/O windows, so virt_mb() et al are
0017  * sufficient.
0018  *
0019  * For using virtio to talk to real devices (eg. other heterogeneous
0020  * CPUs) we do need real barriers.  In theory, we could be using both
0021  * kinds of virtio, so it's a runtime decision, and the branch is
0022  * actually quite cheap.
0023  */
0024 
0025 static inline void virtio_mb(bool weak_barriers)
0026 {
0027     if (weak_barriers)
0028         virt_mb();
0029     else
0030         mb();
0031 }
0032 
0033 static inline void virtio_rmb(bool weak_barriers)
0034 {
0035     if (weak_barriers)
0036         virt_rmb();
0037     else
0038         dma_rmb();
0039 }
0040 
0041 static inline void virtio_wmb(bool weak_barriers)
0042 {
0043     if (weak_barriers)
0044         virt_wmb();
0045     else
0046         dma_wmb();
0047 }
0048 
0049 #define virtio_store_mb(weak_barriers, p, v) \
0050 do { \
0051     if (weak_barriers) { \
0052         virt_store_mb(*p, v); \
0053     } else { \
0054         WRITE_ONCE(*p, v); \
0055         mb(); \
0056     } \
0057 } while (0) \
0058 
0059 struct virtio_device;
0060 struct virtqueue;
0061 
0062 /*
0063  * Creates a virtqueue and allocates the descriptor ring.  If
0064  * may_reduce_num is set, then this may allocate a smaller ring than
0065  * expected.  The caller should query virtqueue_get_vring_size to learn
0066  * the actual size of the ring.
0067  */
0068 struct virtqueue *vring_create_virtqueue(unsigned int index,
0069                      unsigned int num,
0070                      unsigned int vring_align,
0071                      struct virtio_device *vdev,
0072                      bool weak_barriers,
0073                      bool may_reduce_num,
0074                      bool ctx,
0075                      bool (*notify)(struct virtqueue *vq),
0076                      void (*callback)(struct virtqueue *vq),
0077                      const char *name);
0078 
0079 /*
0080  * Creates a virtqueue with a standard layout but a caller-allocated
0081  * ring.
0082  */
0083 struct virtqueue *vring_new_virtqueue(unsigned int index,
0084                       unsigned int num,
0085                       unsigned int vring_align,
0086                       struct virtio_device *vdev,
0087                       bool weak_barriers,
0088                       bool ctx,
0089                       void *pages,
0090                       bool (*notify)(struct virtqueue *vq),
0091                       void (*callback)(struct virtqueue *vq),
0092                       const char *name);
0093 
0094 /*
0095  * Destroys a virtqueue.  If created with vring_create_virtqueue, this
0096  * also frees the ring.
0097  */
0098 void vring_del_virtqueue(struct virtqueue *vq);
0099 
0100 /* Filter out transport-specific feature bits. */
0101 void vring_transport_features(struct virtio_device *vdev);
0102 
0103 irqreturn_t vring_interrupt(int irq, void *_vq);
0104 #endif /* _LINUX_VIRTIO_RING_H */