aboutsummaryrefslogtreecommitdiffstats
path: root/vhost_user_loopback.c
diff options
context:
space:
mode:
Diffstat (limited to 'vhost_user_loopback.c')
-rw-r--r--vhost_user_loopback.c211
1 files changed, 120 insertions, 91 deletions
diff --git a/vhost_user_loopback.c b/vhost_user_loopback.c
index 31830ae..1d52f05 100644
--- a/vhost_user_loopback.c
+++ b/vhost_user_loopback.c
@@ -84,7 +84,7 @@ void vmsg_close_fds(VhostUserMsg *vmsg)
}
-bool vu_message_write(int conn_fd, VhostUserMsg *vmsg)
+static int vu_message_write(int conn_fd, VhostUserMsg *vmsg)
{
int rc;
uint8_t *p = (uint8_t *)vmsg;
@@ -134,16 +134,10 @@ bool vu_message_write(int conn_fd, VhostUserMsg *vmsg)
} while (rc < 0 && (errno == EINTR || errno == EAGAIN));
}
- if (rc <= 0) {
- DBG("Error while writing\n");
- return false;
- }
-
- return true;
+ return rc;
}
-
-bool vu_message_read(int conn_fd, VhostUserMsg *vmsg)
+static int vu_message_read(int conn_fd, VhostUserMsg *vmsg)
{
char control[CMSG_SPACE(VHOST_MEMORY_BASELINE_NREGIONS * sizeof(int))] = {};
struct iovec iov = {
@@ -201,12 +195,9 @@ bool vu_message_read(int conn_fd, VhostUserMsg *vmsg)
}
}
- return true;
-
fail:
vmsg_close_fds(vmsg);
-
- return false;
+ return rc;
}
int vhost_user_set_owner(void)
@@ -314,13 +305,14 @@ int enforce_reply(const VhostUserMsg *msg)
int vhost_user_set_u64(int request, uint64_t u64, bool wait_for_reply)
{
+ int ret = 0;
+
VhostUserMsg msg = {
.request = request,
.flags = VHOST_USER_VERSION,
.payload.u64 = u64,
.size = sizeof(msg.payload.u64),
};
- int ret;
print_vhost_user_messages(request);
DBG("\tSet value: 0x%lx\n", u64);
@@ -343,7 +335,7 @@ int vhost_user_set_u64(int request, uint64_t u64, bool wait_for_reply)
return enforce_reply(&msg);
}
- return 0;
+ return ret;
}
int vhost_user_set_features(struct vhost_dev *dev,
@@ -420,8 +412,7 @@ int vhost_setup_slave_channel(struct vhost_dev *dev)
}
ret = vu_message_write(client_sock, &msg);
- if (!ret) {
- DBG("Go out\n");
+ if (ret < 0) {
goto out;
}
@@ -450,9 +441,48 @@ int vhost_user_get_vq_index(struct vhost_dev *dev, int idx)
*
* assert(idx >= dev->vq_index && idx < dev->vq_index + (int)dev->nvqs);
*/
+ (void)dev;
return idx;
}
+static int vhost_user_write_sync(VhostUserMsg *msg,
+ bool wait_for_reply)
+{
+ int ret;
+
+ if (wait_for_reply) {
+ bool reply_supported = virtio_has_feature(dev->protocol_features,
+ VHOST_USER_PROTOCOL_F_REPLY_ACK);
+ if (reply_supported) {
+ msg->flags |= VHOST_USER_NEED_REPLY_MASK;
+ }
+ }
+
+ ret = vu_message_write(client_sock, msg);
+ if (ret < 0) {
+ return ret;
+ }
+
+ if (wait_for_reply) {
+ uint64_t dummy;
+ DBG("Wait for reply\n");
+
+ if (msg->flags & VHOST_USER_NEED_REPLY_MASK) {
+ return process_message_reply(msg);
+ }
+
+ /*
+ * We need to wait for a reply but the backend does not
+ * support replies for the command we just sent.
+ * Send VHOST_USER_GET_FEATURES which makes all backends
+ * send a reply.
+ */
+ return vhost_user_get_features(&dummy);
+ }
+
+ return 0;
+}
+
int vhost_set_vring_file(VhostUserRequest request,
struct vhost_vring_file *file)
{
@@ -465,6 +495,7 @@ int vhost_set_vring_file(VhostUserRequest request,
.size = sizeof(msg.payload.u64),
};
+
if (ioeventfd_enabled() && file->fd > 0) {
fds[fd_num++] = file->fd;
} else {
@@ -483,7 +514,7 @@ int vhost_set_vring_file(VhostUserRequest request,
msg.fd_num = fd_num;
memcpy(msg.fds, &fds, fd_num * sizeof(int));
- return !vu_message_write(client_sock, &msg);
+ return vu_message_write(client_sock, &msg);
}
int vhost_user_set_vring_kick(struct vhost_vring_file *file)
@@ -500,7 +531,8 @@ int vhost_user_set_vring_call(struct vhost_vring_file *file)
static int vhost_set_vring(struct vhost_dev *dev,
unsigned long int request,
- struct vhost_vring_state *ring)
+ struct vhost_vring_state *ring,
+ bool wait_for_reply)
{
VhostUserMsg msg = {
.request = request,
@@ -508,58 +540,36 @@ static int vhost_set_vring(struct vhost_dev *dev,
.payload.state = *ring,
.size = sizeof(msg.payload.state),
};
+ (void)dev;
- return !vu_message_write(client_sock, &msg);
+ return vhost_user_write_sync(&msg, wait_for_reply);
}
int vhost_user_set_vring_num(struct vhost_dev *dev,
struct vhost_vring_state *ring)
{
- return vhost_set_vring(dev, VHOST_USER_SET_VRING_NUM, ring);
+ return vhost_set_vring(dev, VHOST_USER_SET_VRING_NUM, ring, false);
}
int vhost_user_set_vring_base(struct vhost_dev *dev,
struct vhost_vring_state *ring)
{
- return vhost_set_vring(dev, VHOST_USER_SET_VRING_BASE, ring);
+ return vhost_set_vring(dev, VHOST_USER_SET_VRING_BASE, ring, false);
}
int vhost_user_set_vring_addr(struct vhost_dev *dev,
struct vhost_vring_addr *addr)
{
- int ret;
VhostUserMsg msg = {
.request = VHOST_USER_SET_VRING_ADDR,
.flags = VHOST_USER_VERSION,
.payload.addr = *addr,
.size = sizeof(msg.payload.addr),
};
+ (void)dev;
- bool reply_supported = virtio_has_feature(dev->protocol_features,
- VHOST_USER_PROTOCOL_F_REPLY_ACK);
-
- /*
- * wait for a reply if logging is enabled to make sure
- * backend is actually logging changes
- */
- bool wait_for_reply = addr->flags & (1 << VHOST_VRING_F_LOG);
-
- if (reply_supported && wait_for_reply) {
- msg.flags |= VHOST_USER_NEED_REPLY_MASK;
- }
-
- ret = vu_message_write(client_sock, &msg);
- if (ret < 0) {
- DBG("Fail vhost_user_set_vring_addr\n");
- return ret;
- }
-
- if (wait_for_reply) {
- return enforce_reply(&msg);
- }
-
- return 0;
+ return vhost_user_write_sync(&msg, true);
}
@@ -580,7 +590,7 @@ int vhost_virtqueue_init(struct vhost_dev *dev,
file.fd = event_notifier_get_wfd(&vq->masked_notifier);
r = vhost_user_set_vring_call(&file);
- if (r) {
+ if (r < 0) {
DBG("vhost_set_vring_call failed\n");
return r;
}
@@ -615,13 +625,13 @@ int vhost_user_get_config(struct vhost_dev *dev, uint8_t *config,
DBG("vu_message_write return: %d\n", ret);
if (ret < 0) {
DBG("vhost_get_config failed\n");
- return -1;
+ return ret;
}
ret = vu_message_read(client_sock, &msg);
if (ret < 0) {
DBG("vhost_get_config failed\n");
- return -1;
+ return ret;
}
if (msg.request != VHOST_USER_GET_CONFIG) {
@@ -795,7 +805,7 @@ int vhost_user_set_inflight_fd(struct vhost_dev *dev,
msg.fd_num = 1;
memcpy(msg.fds, &inflight->fd, msg.fd_num * sizeof(int));
- return !vu_message_write(client_sock, &msg); /* Returns true or false*/
+ return vu_message_write(client_sock, &msg);
}
@@ -807,7 +817,10 @@ static MemoryRegion *vhost_user_get_mr_data(struct vhost_memory_region *reg,
{
MemoryRegion *mr;
+ (void)reg;
+ mr = (MemoryRegion *)malloc(sizeof(MemoryRegion));
*offset = 0;
+ /* TODO: Dublicate the file descriptor to driscriminate the mmap calls from the driver */
*fd = loopback_fd;
return mr;
@@ -830,7 +843,8 @@ static int vhost_user_fill_set_mem_table_msg(struct vhost_user *u,
int *fds, size_t *fd_num,
bool track_ramblocks)
{
- int i, fd;
+ uint32_t i;
+ int fd;
ram_addr_t offset;
MemoryRegion *mr;
struct vhost_memory_region *reg;
@@ -894,18 +908,22 @@ static void scrub_shadow_regions(struct vhost_dev *dev,
struct vhost_user *u = adev->vudev;
bool found[VHOST_USER_MAX_RAM_SLOTS] = {};
struct vhost_memory_region *reg, *shadow_reg;
- int i, j, fd, add_idx = 0, rm_idx = 0, fd_num = 0;
+ int fd, add_idx = 0, rm_idx = 0, fd_num = 0;
+ uint32_t i, j;
ram_addr_t offset;
MemoryRegion *mr;
bool matching;
+ (void)mr;
+ (void)shadow_pcb;
+ (void)track_ramblocks;
/*
* Find memory regions present in our shadow state which are not in
* the device's current memory state.
*
* Mark regions in both the shadow and device state as "found".
*/
- for (i = 0; i < u->num_shadow_regions; i++) {
+ for (i = 0; i < (uint32_t)u->num_shadow_regions; i++) {
shadow_reg = &u->shadow_regions[i];
matching = false;
@@ -972,12 +990,14 @@ static int send_remove_regions(struct vhost_dev *dev,
int nr_rem_reg, VhostUserMsg *msg,
bool reply_supported)
{
- struct vhost_user *u = adev->vudev;
struct vhost_memory_region *shadow_reg;
- int i, fd, shadow_reg_idx, ret;
+ int i, fd, shadow_reg_idx, ret = 0;
ram_addr_t offset;
VhostUserMemoryRegion region_buffer;
+ (void)ret;
+ (void)dev;
+ (void)shadow_reg_idx;
/*
* The regions in remove_reg appear in the same order they do in the
* shadow table. Therefore we can minimize memory copies by iterating
@@ -999,8 +1019,9 @@ static int send_remove_regions(struct vhost_dev *dev,
msg->fd_num = 1;
memcpy(msg->fds, &loopback_fd, sizeof(int));
- if (vu_message_write(client_sock, msg) < 0) {
- return -1;
+ ret = vu_message_write(client_sock, msg);
+ if (ret < 0) {
+ return ret;
}
if (reply_supported) {
@@ -1018,7 +1039,7 @@ static int send_remove_regions(struct vhost_dev *dev,
}
- return 0;
+ return ret;
}
static int send_add_regions(struct vhost_dev *dev,
@@ -1027,13 +1048,18 @@ static int send_add_regions(struct vhost_dev *dev,
bool reply_supported, bool track_ramblocks)
{
struct vhost_user *u = adev->vudev;
- int i, fd, ret, reg_idx, reg_fd_idx;
+ int i, fd, ret = 0, reg_idx, reg_fd_idx;
struct vhost_memory_region *reg;
MemoryRegion *mr;
ram_addr_t offset;
- VhostUserMsg msg_reply;
VhostUserMemoryRegion region_buffer;
+ (void)dev;
+ (void)shadow_pcb;
+ (void)mr;
+ (void)ret;
+ (void)reg_fd_idx;
+
for (i = 0; i < nr_add_reg; i++) {
reg = add_reg[i].region;
reg_idx = add_reg[i].reg_idx;
@@ -1052,9 +1078,10 @@ static int send_add_regions(struct vhost_dev *dev,
msg->fd_num = 1;
memcpy(msg->fds, &loopback_fd, sizeof(int));
- if (vu_message_write(client_sock, msg) < 0) {
+ ret = vu_message_write(client_sock, msg);
+ if (ret < 0) {
DBG("send_add_regions -> write failed\n");
- return -1;
+ return ret;
}
if (reply_supported) {
@@ -1074,7 +1101,7 @@ static int send_add_regions(struct vhost_dev *dev,
}
}
- return 0;
+ return ret;
}
static int vhost_user_add_remove_regions(struct vhost_dev *dev,
@@ -1127,6 +1154,9 @@ static int vhost_user_set_mem_table_postcopy(struct vhost_dev *dev,
bool reply_supported,
bool config_mem_slots)
{
+ (void)dev;
+ (void)reply_supported;
+ (void)config_mem_slots;
DBG("vhost_user_set_mem_table_postcopy(...) not yet implemented\n");
return 0;
}
@@ -1140,12 +1170,12 @@ int vhost_user_set_mem_table(struct vhost_dev *dev)
{
int fds[VHOST_MEMORY_BASELINE_NREGIONS];
size_t fd_num = 0;
+ int ret = 0;
bool reply_supported = virtio_has_feature(dev->protocol_features,
VHOST_USER_PROTOCOL_F_REPLY_ACK);
bool config_mem_slots =
virtio_has_feature(dev->protocol_features,
VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS);
- int ret;
struct vhost_user *u = adev->vudev;
bool do_postcopy = false;
@@ -1185,17 +1215,18 @@ int vhost_user_set_mem_table(struct vhost_dev *dev)
msg.fd_num = fd_num;
memcpy(msg.fds, fds, fd_num * sizeof(int));
- if (vu_message_write(client_sock, &msg) < 0) {
+ ret = vu_message_write(client_sock, &msg);
+ if (ret < 0) {
DBG("vhost_user_set_mem_table failed write msg\n");
- return -1;
+ return ret;
}
if (reply_supported) {
- return process_message_reply(&msg);
+ ret = process_message_reply(&msg);
}
}
- return 0;
+ return ret;
}
@@ -1205,6 +1236,7 @@ void print_mem_table(struct vhost_dev *dev)
struct vhost_memory_region *cur_vmr;
int i;
+ (void)cur_vmr;
DBG("print_mem_table:\n");
for (i = 0; i < dev->n_mem_sections; i++) {
@@ -1286,24 +1318,25 @@ int last_avail = -1;
void find_add_new_reg(struct vhost_dev *dev)
{
int sglist_elem_num;
- int i;
+ uint64_t i, j;
+ (void)sglist_elem_num;
DBG("Total nvqs: %d\n", dev->nvqs);
- for (int i = 0; i < dev->nvqs; i++) {
+ for (i = 0; (unsigned int)i < dev->nvqs; i++) {
VRing *vring = &dev->vdev->vq[i].vring;
uint64_t vring_num = vring->num;
- DBG("For vq[%d]:\n", i);
- DBG("vqs[%u] hpa 0x%lx\n", i, vring_phys_addrs[i]);
- DBG("vq[%d].vring.num: %ld\n", i, vring_num);
+ DBG("For vq[%lu]:\n", i);
+ DBG("vqs[%lu] hpa 0x%lx\n", i, vring_phys_addrs[i]);
+ DBG("vq[%lu].vring.num: %ld\n", i, vring_num);
DBG("We got avail buf: %d\n",
((VRingAvail *)(dev->vdev->vq[i].vring.avail))->idx);
int avail_diff = ((VRingAvail *)(dev->vdev->vq[i].vring.avail))->idx
- last_avail;
- for (int j = 0; j < vring_num; j++) {
+ for (j = 0; j < vring_num; j++) {
uint64_t desc_addr = dev->vdev->vq[i].vring.desc;
VRingDesc desc_p = ((VRingDesc *)desc_addr)[j];
@@ -1318,10 +1351,10 @@ void find_add_new_reg(struct vhost_dev *dev)
break;
}
- DBG("desc[%u] 0x%lx\n", j, desc_addr);
- DBG("desc[%u].addr 0x%lx\n", j, sg_addr);
- DBG("desc[%u].len 0x%lu\n", j, sg_len);
- DBG("desc[%u].flags 0x%u\n", j, desc_p.flags);
+ DBG("desc[%lu] 0x%lx\n", j, desc_addr);
+ DBG("desc[%lu].addr 0x%lx\n", j, sg_addr);
+ DBG("desc[%lu].len 0x%lu\n", j, sg_len);
+ DBG("desc[%lu].flags 0x%u\n", j, desc_p.flags);
if (!find_reg(dev, sg_addr, sg_len)) {
vhost_add_reg(dev, sg_addr, sg_len);
@@ -1338,14 +1371,8 @@ void find_add_new_reg(struct vhost_dev *dev)
void vhost_commit_init_vqs(struct vhost_dev *dev)
{
- MemoryRegionSection *old_sections;
- int n_old_sections;
- uint64_t log_size;
size_t regions_size;
- int r;
- int i;
- bool changed = false;
- int sglist_elem_num;
+ unsigned int i;
dev->n_mem_sections = dev->nvqs;
@@ -1462,7 +1489,7 @@ int vhost_user_backend_init(struct vhost_dev *vhdev)
vhdev->max_queues = 1;
}
- if (vhdev->num_queues && vhdev->max_queues < vhdev->num_queues) {
+ if (vhdev->num_queues && vhdev->max_queues < (uint64_t)vhdev->num_queues) {
DBG("The maximum number of queues supported by the "
"backend is %ld\n", vhdev->max_queues);
return -EINVAL;
@@ -1592,7 +1619,8 @@ void vhost_dev_init(struct vhost_dev *vhdev)
int vhost_user_set_vring_enable(struct vhost_dev *dev, int enable)
{
- int i;
+ unsigned int i;
+ int ret;
DBG("vhost_user_set_vring_enable:\n");
if (!virtio_has_feature(dev->features, VHOST_USER_F_PROTOCOL_FEATURES)) {
@@ -1601,13 +1629,12 @@ int vhost_user_set_vring_enable(struct vhost_dev *dev, int enable)
}
for (i = 0; i < dev->nvqs; ++i) {
- int ret;
struct vhost_vring_state state = {
.index = dev->vq_index + i,
.num = enable,
};
- ret = vhost_set_vring(dev, VHOST_USER_SET_VRING_ENABLE, &state);
+ ret = vhost_set_vring(dev, VHOST_USER_SET_VRING_ENABLE, &state, true);
if (ret < 0) {
/*
* Restoring the previous state is likely infeasible, as well as
@@ -1623,6 +1650,7 @@ int vhost_user_set_vring_enable(struct vhost_dev *dev, int enable)
static int vhost_user_set_status(struct vhost_dev *dev, uint8_t status)
{
+ (void)dev;
return vhost_user_set_u64(VHOST_USER_SET_STATUS, status, false);
}
@@ -1631,6 +1659,7 @@ static int vhost_user_get_status(struct vhost_dev *dev, uint8_t *status)
uint64_t value;
int ret;
+ (void)dev;
ret = vhost_user_get_u64(VHOST_USER_GET_STATUS, &value);
if (ret < 0) {
return ret;
@@ -1668,7 +1697,7 @@ int vhost_user_dev_start(struct vhost_dev *dev, bool started)
}
/* Set device status only for last queue pair */
- if (dev->vq_index + dev->nvqs != dev->vq_index_end) {
+ if (dev->vq_index + dev->nvqs != (unsigned int)dev->vq_index_end) {
return 0;
}