hc
2024-05-10 61598093bbdd283a7edc367d900f223070ead8d2
kernel/include/uapi/linux/virtio_ring.h
....@@ -44,6 +44,13 @@
4444 /* This means the buffer contains a list of buffer descriptors. */
4545 #define VRING_DESC_F_INDIRECT 4
4646
47
+/*
48
+ * Mark a descriptor as available or used in packed ring.
49
+ * Notice: they are defined as shifts instead of shifted values.
50
+ */
51
+#define VRING_PACKED_DESC_F_AVAIL 7
52
+#define VRING_PACKED_DESC_F_USED 15
53
+
4754 /* The Host uses this in used->flags to advise the Guest: don't kick me when
4855 * you add a buffer. It's unreliable, so it's simply an optimization. Guest
4956 * will still kick if it's out of buffers. */
....@@ -53,6 +60,23 @@
5360 * optimization. */
5461 #define VRING_AVAIL_F_NO_INTERRUPT 1
5562
63
+/* Enable events in packed ring. */
64
+#define VRING_PACKED_EVENT_FLAG_ENABLE 0x0
65
+/* Disable events in packed ring. */
66
+#define VRING_PACKED_EVENT_FLAG_DISABLE 0x1
67
+/*
68
+ * Enable events for a specific descriptor in packed ring.
69
+ * (as specified by Descriptor Ring Change Event Offset/Wrap Counter).
70
+ * Only valid if VIRTIO_RING_F_EVENT_IDX has been negotiated.
71
+ */
72
+#define VRING_PACKED_EVENT_FLAG_DESC 0x2
73
+
74
+/*
75
+ * Wrap counter bit shift in event suppression structure
76
+ * of packed ring.
77
+ */
78
+#define VRING_PACKED_EVENT_F_WRAP_CTR 15
79
+
5680 /* We support indirect buffer descriptors */
5781 #define VIRTIO_RING_F_INDIRECT_DESC 28
5882
....@@ -61,6 +85,13 @@
6185 /* The Host publishes the avail index for which it expects a kick
6286 * at the end of the used ring. Guest should ignore the used->flags field. */
6387 #define VIRTIO_RING_F_EVENT_IDX 29
88
+
89
+/* Alignment requirements for vring elements.
90
+ * When using pre-virtio 1.0 layout, these fall out naturally.
91
+ */
92
+#define VRING_AVAIL_ALIGN_SIZE 2
93
+#define VRING_USED_ALIGN_SIZE 4
94
+#define VRING_DESC_ALIGN_SIZE 16
6495
6596 /* Virtio ring descriptors: 16 bytes. These can chain together via "next". */
6697 struct vring_desc {
....@@ -88,28 +119,47 @@
88119 __virtio32 len;
89120 };
90121
122
+typedef struct vring_used_elem __attribute__((aligned(VRING_USED_ALIGN_SIZE)))
123
+ vring_used_elem_t;
124
+
91125 struct vring_used {
92126 __virtio16 flags;
93127 __virtio16 idx;
94
- struct vring_used_elem ring[];
128
+ vring_used_elem_t ring[];
95129 };
130
+
131
+/*
132
+ * The ring element addresses are passed between components with different
133
+ * alignments assumptions. Thus, we might need to decrease the compiler-selected
134
+ * alignment, and so must use a typedef to make sure the aligned attribute
135
+ * actually takes hold:
136
+ *
137
+ * https://gcc.gnu.org/onlinedocs//gcc/Common-Type-Attributes.html#Common-Type-Attributes
138
+ *
139
+ * When used on a struct, or struct member, the aligned attribute can only
140
+ * increase the alignment; in order to decrease it, the packed attribute must
141
+ * be specified as well. When used as part of a typedef, the aligned attribute
142
+ * can both increase and decrease alignment, and specifying the packed
143
+ * attribute generates a warning.
144
+ */
145
+typedef struct vring_desc __attribute__((aligned(VRING_DESC_ALIGN_SIZE)))
146
+ vring_desc_t;
147
+typedef struct vring_avail __attribute__((aligned(VRING_AVAIL_ALIGN_SIZE)))
148
+ vring_avail_t;
149
+typedef struct vring_used __attribute__((aligned(VRING_USED_ALIGN_SIZE)))
150
+ vring_used_t;
96151
97152 struct vring {
98153 unsigned int num;
99154
100
- struct vring_desc *desc;
155
+ vring_desc_t *desc;
101156
102
- struct vring_avail *avail;
157
+ vring_avail_t *avail;
103158
104
- struct vring_used *used;
159
+ vring_used_t *used;
105160 };
106161
107
-/* Alignment requirements for vring elements.
108
- * When using pre-virtio 1.0 layout, these fall out naturally.
109
- */
110
-#define VRING_AVAIL_ALIGN_SIZE 2
111
-#define VRING_USED_ALIGN_SIZE 4
112
-#define VRING_DESC_ALIGN_SIZE 16
162
+#ifndef VIRTIO_RING_NO_LEGACY
113163
114164 /* The standard layout for the ring is a continuous chunk of memory which looks
115165 * like this. We assume num is a power of 2.
....@@ -145,7 +195,7 @@
145195 {
146196 vr->num = num;
147197 vr->desc = p;
148
- vr->avail = p + num*sizeof(struct vring_desc);
198
+ vr->avail = (struct vring_avail *)((char *)p + num * sizeof(struct vring_desc));
149199 vr->used = (void *)(((uintptr_t)&vr->avail->ring[num] + sizeof(__virtio16)
150200 + align-1) & ~(align - 1));
151201 }
....@@ -156,6 +206,8 @@
156206 + align - 1) & ~(align - 1))
157207 + sizeof(__virtio16) * 3 + sizeof(struct vring_used_elem) * num;
158208 }
209
+
210
+#endif /* VIRTIO_RING_NO_LEGACY */
159211
160212 /* The following is used with USED_EVENT_IDX and AVAIL_EVENT_IDX */
161213 /* Assuming a given event_idx value from the other side, if
....@@ -171,4 +223,22 @@
171223 return (__u16)(new_idx - event_idx - 1) < (__u16)(new_idx - old);
172224 }
173225
226
+struct vring_packed_desc_event {
227
+ /* Descriptor Ring Change Event Offset/Wrap Counter. */
228
+ __le16 off_wrap;
229
+ /* Descriptor Ring Change Event Flags. */
230
+ __le16 flags;
231
+};
232
+
233
+struct vring_packed_desc {
234
+ /* Buffer Address. */
235
+ __le64 addr;
236
+ /* Buffer Length. */
237
+ __le32 len;
238
+ /* Buffer ID. */
239
+ __le16 id;
240
+ /* The flags depending on descriptor type. */
241
+ __le16 flags;
242
+};
243
+
174244 #endif /* _UAPI_LINUX_VIRTIO_RING_H */