1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef _LINUX_VIRTIO_RING_H 3 #define _LINUX_VIRTIO_RING_H 4 5 #include <asm/barrier.h> 6 #include <linux/virtio.h> 7 #include <linux/irqreturn.h> 8 #include <uapi/linux/virtio_ring.h> 9 10 /* 11 * Barriers in virtio are tricky. Non-SMP virtio guests can't assume 12 * they're not on an SMP host system, so they need to assume real 13 * barriers. Non-SMP virtio hosts could skip the barriers, but does 14 * anyone care? 15 * 16 * For virtio_pci on SMP, we don't need to order with respect to MMIO 17 * accesses through relaxed memory I/O windows, so virt_mb() et al are 18 * sufficient. 19 * 20 * For using virtio to talk to real devices (eg. other heterogeneous 21 * CPUs) we do need real barriers. In theory, we could be using both 22 * kinds of virtio, so it's a runtime decision, and the branch is 23 * actually quite cheap. 24 */ 25 26 static inline void virtio_mb(bool weak_barriers) 27 { 28 if (weak_barriers) 29 virt_mb(); 30 else 31 mb(); 32 } 33 34 static inline void virtio_rmb(bool weak_barriers) 35 { 36 if (weak_barriers) 37 virt_rmb(); 38 else 39 dma_rmb(); 40 } 41 42 static inline void virtio_wmb(bool weak_barriers) 43 { 44 if (weak_barriers) 45 virt_wmb(); 46 else 47 dma_wmb(); 48 } 49 50 #define virtio_store_mb(weak_barriers, p, v) \ 51 do { \ 52 if (weak_barriers) { \ 53 virt_store_mb(*p, v); \ 54 } else { \ 55 WRITE_ONCE(*p, v); \ 56 mb(); \ 57 } \ 58 } while (0) \ 59 60 struct virtio_device; 61 struct virtqueue; 62 struct device; 63 64 /* 65 * Creates a virtqueue and allocates the descriptor ring. If 66 * may_reduce_num is set, then this may allocate a smaller ring than 67 * expected. The caller should query virtqueue_get_vring_size to learn 68 * the actual size of the ring. 69 */ 70 struct virtqueue *vring_create_virtqueue(unsigned int index, 71 unsigned int num, 72 unsigned int vring_align, 73 struct virtio_device *vdev, 74 bool weak_barriers, 75 bool may_reduce_num, 76 bool ctx, 77 bool (*notify)(struct virtqueue *vq), 78 void (*callback)(struct virtqueue *vq), 79 const char *name); 80 81 /* 82 * Creates a virtqueue and allocates the descriptor ring with per 83 * virtqueue mapping operations. 84 */ 85 struct virtqueue *vring_create_virtqueue_map(unsigned int index, 86 unsigned int num, 87 unsigned int vring_align, 88 struct virtio_device *vdev, 89 bool weak_barriers, 90 bool may_reduce_num, 91 bool ctx, 92 bool (*notify)(struct virtqueue *vq), 93 void (*callback)(struct virtqueue *vq), 94 const char *name, 95 union virtio_map map); 96 97 /* 98 * Creates a virtqueue with a standard layout but a caller-allocated 99 * ring. 100 */ 101 struct virtqueue *vring_new_virtqueue(unsigned int index, 102 unsigned int num, 103 unsigned int vring_align, 104 struct virtio_device *vdev, 105 bool weak_barriers, 106 bool ctx, 107 void *pages, 108 bool (*notify)(struct virtqueue *vq), 109 void (*callback)(struct virtqueue *vq), 110 const char *name); 111 112 /* 113 * Destroys a virtqueue. If created with vring_create_virtqueue, this 114 * also frees the ring. 115 */ 116 void vring_del_virtqueue(struct virtqueue *vq); 117 118 /* Filter out transport-specific feature bits. */ 119 void vring_transport_features(struct virtio_device *vdev); 120 121 irqreturn_t vring_interrupt(int irq, void *_vq); 122 123 u32 vring_notification_data(struct virtqueue *_vq); 124 #endif /* _LINUX_VIRTIO_RING_H */ 125