Lines Matching +full:guest +full:- +full:index +full:- +full:bits
1 // SPDX-License-Identifier: GPL-2.0-only
6 * Partial implementation of virtio 0.9. event index is used for signalling,
25 * (which skips index reads on consumer in favor of looking at
26 * high bits of ring id ^ 0x8000).
29 /* enabling the below activates experimental in-order code
41 struct guest { struct
51 unsigned char reserved[HOST_GUEST_PADDING - 10];
52 } guest; argument
55 /* we do not need to track last avail index
60 unsigned char reserved[HOST_GUEST_PADDING - 4];
78 guest.avail_idx = 0; in alloc_ring()
79 guest.kicked_avail_idx = -1; in alloc_ring()
80 guest.last_used_idx = 0; in alloc_ring()
83 guest.free_head = 0; in alloc_ring()
85 for (i = 0; i < ring_size - 1; i++) in alloc_ring()
88 host.called_used_idx = -1; in alloc_ring()
89 guest.num_free = ring_size; in alloc_ring()
98 /* guest side */
107 if (!guest.num_free) in add_inbuf()
108 return -1; in add_inbuf()
111 head = (ring_size - 1) & (guest.avail_idx++); in add_inbuf()
113 head = guest.free_head; in add_inbuf()
115 guest.num_free--; in add_inbuf()
127 guest.free_head = desc[head].next; in add_inbuf()
135 avail = guest.avail_idx++; in add_inbuf()
136 ring.avail->ring[avail & (ring_size - 1)] = in add_inbuf()
137 (head | (avail & ~(ring_size - 1))) ^ 0x8000; in add_inbuf()
142 avail = (ring_size - 1) & (guest.avail_idx++); in add_inbuf()
143 ring.avail->ring[avail] = head; in add_inbuf()
148 ring.avail->idx = guest.avail_idx; in add_inbuf()
155 unsigned index; in get_buf() local
159 head = (ring_size - 1) & guest.last_used_idx; in get_buf()
160 index = ring.used->ring[head].id; in get_buf()
161 if ((index ^ guest.last_used_idx ^ 0x8000) & ~(ring_size - 1)) in get_buf()
165 index &= ring_size - 1; in get_buf()
167 if (ring.used->idx == guest.last_used_idx) in get_buf()
172 head = (ring_size - 1) & guest.last_used_idx; in get_buf()
173 index = head; in get_buf()
175 head = (ring_size - 1) & guest.last_used_idx; in get_buf()
176 index = ring.used->ring[head].id; in get_buf()
181 *lenp = ring.desc[index].len; in get_buf()
183 *lenp = ring.used->ring[head].len; in get_buf()
185 datap = data[index].data; in get_buf()
186 *bufp = (void*)(unsigned long)ring.desc[index].addr; in get_buf()
187 data[index].data = NULL; in get_buf()
189 ring.desc[index].next = guest.free_head; in get_buf()
190 guest.free_head = index; in get_buf()
192 guest.num_free++; in get_buf()
193 guest.last_used_idx++; in get_buf()
199 unsigned short last_used_idx = guest.last_used_idx; in used_empty()
201 unsigned short head = last_used_idx & (ring_size - 1); in used_empty()
202 unsigned index = ring.used->ring[head].id; in used_empty() local
204 return (index ^ last_used_idx ^ 0x8000) & ~(ring_size - 1); in used_empty()
206 return ring.used->idx == last_used_idx; in used_empty()
219 vring_used_event(&ring) = guest.last_used_idx; in enable_call()
220 /* Flush call index write */ in enable_call()
234 guest.avail_idx, in kick_available()
235 guest.kicked_avail_idx); in kick_available()
237 guest.kicked_avail_idx = guest.avail_idx; in kick_available()
262 unsigned index = ring.avail->ring[head & (ring_size - 1)]; in avail_empty() local
264 return ((index ^ head ^ 0x8000) & ~(ring_size - 1)); in avail_empty()
266 return head == ring.avail->idx; in avail_empty()
277 head = ring.avail->ring[used_idx & (ring_size - 1)]; in use_buf()
278 if ((used_idx ^ head ^ 0x8000) & ~(ring_size - 1)) in use_buf()
283 used_idx &= ring_size - 1; in use_buf()
284 desc = &ring.desc[head & (ring_size - 1)]; in use_buf()
286 if (used_idx == ring.avail->idx) in use_buf()
292 used_idx &= ring_size - 1; in use_buf()
296 head = ring.avail->ring[used_idx]; in use_buf()
301 *lenp = desc->len; in use_buf()
302 *bufp = (void *)(unsigned long)desc->addr; in use_buf()
305 desc->len = desc->len - 1; in use_buf()
308 ring.used->ring[used_idx].id = head; in use_buf()
309 ring.used->ring[used_idx].len = desc->len - 1; in use_buf()
314 ring.used->idx = host.used_idx; in use_buf()