public inbox for passt-dev@passt.top
 help / color / mirror / code / Atom feed
blob 3b0df343d6b62bdeab067f15c04ba66647f12266 5077 bytes (raw)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
 
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * virtio API, vring and virtqueue functions definition
 *
 * Copyright Red Hat
 * Author: Laurent Vivier <lvivier@redhat.com>
 */

#ifndef VIRTIO_H
#define VIRTIO_H

#include <stdbool.h>
#include <linux/vhost_types.h>

/* Maximum size of a virtqueue */
#define VIRTQUEUE_MAX_SIZE 1024

/**
 * struct vu_ring - Virtqueue rings
 * @num:		Size of the queue
 * @desc:		Descriptor ring
 * @avail:		Available ring
 * @used:		Used ring
 * @log_guest_addr:	Guest address for logging
 * @flags:		Vring flags
 * 			VHOST_VRING_F_LOG is set if log address is valid
 */
struct vu_ring {
	unsigned int num;
	struct vring_desc *desc;
	struct vring_avail *avail;
	struct vring_used *used;
	uint64_t log_guest_addr;
	uint32_t flags;
};

/**
 * struct vu_virtq - Virtqueue definition
 * @vring:			Virtqueue rings
 * @last_avail_idx:		Next head to pop
 * @shadow_avail_idx:		Last avail_idx read from VQ.
 * @used_idx:			Descriptor ring current index
 * @signalled_used:		Last used index value we have signalled on
 * @signalled_used_valid:	True if signalled_used if valid
 * @notification:		True if the queues notify (via event
 * 				index or interrupt)
 * @inuse:			Number of entries in use
 * @call_fd:			The event file descriptor to signal when
 * 				buffers are used.
 * @kick_fd:			The event file descriptor for adding
 * 				buffers to the vring
 * @err_fd:			The event file descriptor to signal when
 * 				error occurs
 * @enable:			True if the virtqueue is enabled
 * @started:			True if the virtqueue is started
 * @vra:			QEMU address of our rings
 */
struct vu_virtq {
	struct vu_ring vring;
	uint16_t last_avail_idx;
	uint16_t shadow_avail_idx;
	uint16_t used_idx;
	uint16_t signalled_used;
	bool signalled_used_valid;
	bool notification;
	unsigned int inuse;
	int call_fd;
	int kick_fd;
	int err_fd;
	unsigned int enable;
	bool started;
	struct vhost_vring_addr vra;
};

/**
 * struct vu_dev_region - guest shared memory region
 * @gpa:		Guest physical address of the region
 * @size:		Memory size in bytes
 * @qva:		QEMU virtual address
 * @mmap_offset:	Offset where the region starts in the mapped memory
 * @mmap_addr:		Address of the mapped memory
 */
struct vu_dev_region {
	uint64_t gpa;
	uint64_t size;
	uint64_t qva;
	uint64_t mmap_offset;
	uint64_t mmap_addr;
};

#define VHOST_USER_MAX_QUEUES 2

/*
 * Set a reasonable maximum number of ram slots, which will be supported by
 * any architecture.
 */
#define VHOST_USER_MAX_RAM_SLOTS 32

/**
 * struct vu_dev - vhost-user device information
 * @context:		Execution context
 * @nregions:		Number of shared memory regions
 * @regions:		Guest shared memory regions
 * @features:		Vhost-user features
 * @protocol_features:	Vhost-user protocol features
 * @log_call_fd:	Eventfd to report logging update
 */
struct vu_dev {
	struct ctx *context;
	uint32_t nregions;
	struct vu_dev_region regions[VHOST_USER_MAX_RAM_SLOTS];
	struct vu_virtq vq[VHOST_USER_MAX_QUEUES];
	uint64_t features;
	uint64_t protocol_features;
	int log_call_fd;
};

/**
 * struct vu_virtq_element - virtqueue element
 * @index:	Descriptor ring index
 * @out_num:	Number of outgoing iovec buffers
 * @in_num:	Number of incoming iovec buffers
 * @in_sg:	Incoming iovec buffers
 * @out_sg:	Outgoing iovec buffers
 */
struct vu_virtq_element {
	unsigned int index;
	unsigned int out_num;
	unsigned int in_num;
	struct iovec *in_sg;
	struct iovec *out_sg;
};

/**
 * has_feature() - Check a feature bit in a features set
 * @features:	Features set
 * @fb:		Feature bit to check
 *
 * Return:	True if the feature bit is set
 */
static inline bool has_feature(uint64_t features, unsigned int fbit)
{
	return !!(features & (1ULL << fbit));
}

/**
 * vu_has_feature() - Check if a virtio-net feature is available
 * @vdev:	Vhost-user device
 * @bit:	Feature to check
 *
 * Return:	True if the feature is available
 */
static inline bool vu_has_feature(const struct vu_dev *vdev,
				  unsigned int fbit)
{
	return has_feature(vdev->features, fbit);
}

/**
 * vu_has_protocol_feature() - Check if a vhost-user feature is available
 * @vdev:	Vhost-user device
 * @bit:	Feature to check
 *
 * Return:	True if the feature is available
 */
/* cppcheck-suppress unusedFunction */
static inline bool vu_has_protocol_feature(const struct vu_dev *vdev,
					   unsigned int fbit)
{
	return has_feature(vdev->protocol_features, fbit);
}

bool vu_queue_empty(struct vu_virtq *vq);
void vu_queue_notify(const struct vu_dev *dev, struct vu_virtq *vq);
int vu_queue_pop(const struct vu_dev *dev, struct vu_virtq *vq,
		 struct vu_virtq_element *elem);
void vu_queue_detach_element(struct vu_virtq *vq);
void vu_queue_unpop(struct vu_virtq *vq);
bool vu_queue_rewind(struct vu_virtq *vq, unsigned int num);
void vu_queue_fill_by_index(struct vu_virtq *vq, unsigned int index,
			    unsigned int len, unsigned int idx);
void vu_queue_fill(struct vu_virtq *vq,
		   const struct vu_virtq_element *elem, unsigned int len,
		   unsigned int idx);
void vu_queue_flush(struct vu_virtq *vq, unsigned int count);
#endif /* VIRTIO_H */

debug log:

solving 3b0df343d6b6 ...
found 3b0df343d6b6 in https://passt.top/passt

Code repositories for project(s) associated with this public inbox

	https://passt.top/passt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for IMAP folder(s).