static int rdmacm_mux_check_op_status(CharBackend *mad_chr_be) { RdmaCmMuxMsg msg = {}; int ret; ret = qemu_chr_fe_read_all(mad_chr_be, (uint8_t *)&msg, sizeof(msg)); if (ret != sizeof(msg)) { rdma_error_report("Got invalid message from mux: size %d, expecting %d", ret, (int)sizeof(msg)); return -EIO; } trace_rdmacm_mux_check_op_status(msg.hdr.msg_type, msg.hdr.op_code, msg.hdr.err_code); if (msg.hdr.msg_type != RDMACM_MUX_MSG_TYPE_RESP) { rdma_error_report("Got invalid message type %d", msg.hdr.msg_type); return -EIO; } if (msg.hdr.err_code != RDMACM_MUX_ERR_CODE_OK) { rdma_error_report("Operation failed in mux, error code %d", msg.hdr.err_code); return -EIO; } return 0; }
static int tpm_emulator_ctrlcmd(TPMEmulator *tpm, unsigned long cmd, void *msg, size_t msg_len_in, size_t msg_len_out) { CharBackend *dev = &tpm->ctrl_chr; uint32_t cmd_no = cpu_to_be32(cmd); ssize_t n = sizeof(uint32_t) + msg_len_in; uint8_t *buf = NULL; int ret = -1; qemu_mutex_lock(&tpm->mutex); buf = g_alloca(n); memcpy(buf, &cmd_no, sizeof(cmd_no)); memcpy(buf + sizeof(cmd_no), msg, msg_len_in); n = qemu_chr_fe_write_all(dev, buf, n); if (n <= 0) { goto end; } if (msg_len_out != 0) { n = qemu_chr_fe_read_all(dev, msg, msg_len_out); if (n <= 0) { goto end; } } ret = 0; end: qemu_mutex_unlock(&tpm->mutex); return ret; }
static int vhost_user_read(struct vhost_dev *dev, VhostUserMsg *msg) { CharDriverState *chr = dev->opaque; uint8_t *p = (uint8_t *) msg; int r, size = VHOST_USER_HDR_SIZE; r = qemu_chr_fe_read_all(chr, p, size); if (r != size) { error_report("Failed to read msg header. Read %d instead of %d.", r, size); goto fail; } /* validate received flags */ if (msg->flags != (VHOST_USER_REPLY_MASK | VHOST_USER_VERSION)) { error_report("Failed to read msg header." " Flags 0x%x instead of 0x%x.", msg->flags, VHOST_USER_REPLY_MASK | VHOST_USER_VERSION); goto fail; } /* validate message size is sane */ if (msg->size > VHOST_USER_PAYLOAD_SIZE) { error_report("Failed to read msg header." " Size %d exceeds the maximum %zu.", msg->size, VHOST_USER_PAYLOAD_SIZE); goto fail; } if (msg->size) { p += VHOST_USER_HDR_SIZE; size = msg->size; r = qemu_chr_fe_read_all(chr, p, size); if (r != size) { error_report("Failed to read msg payload." " Read %d instead of %d.", r, msg->size); goto fail; } } return 0; fail: return -1; }
static gboolean net_vhost_user_watch(GIOChannel *chan, GIOCondition cond, void *opaque) { VhostUserState *s = opaque; uint8_t buf[1]; /* We don't actually want to read anything, but CHR_EVENT_CLOSED will be * raised as a side-effect of the read. */ qemu_chr_fe_read_all(s->chr, buf, sizeof(buf)); return FALSE; }
static int64_t ivshmem_recv_msg(IVShmemState *s, int *pfd, Error **errp) { int64_t msg; int n, ret; n = 0; do { ret = qemu_chr_fe_read_all(s->server_chr, (uint8_t *)&msg + n, sizeof(msg) - n); if (ret < 0 && ret != -EINTR) { error_setg_errno(errp, -ret, "read from server failed"); return INT64_MIN; } n += ret; } while (n < sizeof(msg)); *pfd = qemu_chr_fe_get_msgfd(s->server_chr); return msg; }
static void chr_read(void *opaque, const uint8_t *buf, int size) { TestServer *s = opaque; CharBackend *chr = &s->chr; VhostUserMsg msg; uint8_t *p = (uint8_t *) &msg; int fd = -1; if (s->test_fail) { qemu_chr_fe_disconnect(chr); /* now switch to non-failure */ s->test_fail = false; } if (size != VHOST_USER_HDR_SIZE) { g_test_message("Wrong message size received %d", size); return; } g_mutex_lock(&s->data_mutex); memcpy(p, buf, VHOST_USER_HDR_SIZE); if (msg.size) { p += VHOST_USER_HDR_SIZE; size = qemu_chr_fe_read_all(chr, p, msg.size); if (size != msg.size) { g_test_message("Wrong message size received %d != %d", size, msg.size); return; } } switch (msg.request) { case VHOST_USER_GET_FEATURES: /* send back features to qemu */ msg.flags |= VHOST_USER_REPLY_MASK; msg.size = sizeof(m.payload.u64); msg.payload.u64 = 0x1ULL << VHOST_F_LOG_ALL | 0x1ULL << VHOST_USER_F_PROTOCOL_FEATURES; if (s->queues > 1) { msg.payload.u64 |= 0x1ULL << VIRTIO_NET_F_MQ; } if (s->test_flags >= TEST_FLAGS_BAD) { msg.payload.u64 = 0; s->test_flags = TEST_FLAGS_END; } p = (uint8_t *) &msg; qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE + msg.size); break; case VHOST_USER_SET_FEATURES: g_assert_cmpint(msg.payload.u64 & (0x1ULL << VHOST_USER_F_PROTOCOL_FEATURES), !=, 0ULL); if (s->test_flags == TEST_FLAGS_DISCONNECT) { qemu_chr_fe_disconnect(chr); s->test_flags = TEST_FLAGS_BAD; } break; case VHOST_USER_GET_PROTOCOL_FEATURES: /* send back features to qemu */ msg.flags |= VHOST_USER_REPLY_MASK; msg.size = sizeof(m.payload.u64); msg.payload.u64 = 1 << VHOST_USER_PROTOCOL_F_LOG_SHMFD; msg.payload.u64 |= 1 << VHOST_USER_PROTOCOL_F_CROSS_ENDIAN; if (s->queues > 1) { msg.payload.u64 |= 1 << VHOST_USER_PROTOCOL_F_MQ; } p = (uint8_t *) &msg; qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE + msg.size); break; case VHOST_USER_GET_VRING_BASE: /* send back vring base to qemu */ msg.flags |= VHOST_USER_REPLY_MASK; msg.size = sizeof(m.payload.state); msg.payload.state.num = 0; p = (uint8_t *) &msg; qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE + msg.size); assert(msg.payload.state.index < s->queues * 2); s->rings &= ~(0x1ULL << msg.payload.state.index); g_cond_broadcast(&s->data_cond); break; case VHOST_USER_SET_MEM_TABLE: /* received the mem table */ memcpy(&s->memory, &msg.payload.memory, sizeof(msg.payload.memory)); s->fds_num = qemu_chr_fe_get_msgfds(chr, s->fds, G_N_ELEMENTS(s->fds)); /* signal the test that it can continue */ g_cond_broadcast(&s->data_cond); break; case VHOST_USER_SET_VRING_KICK: case VHOST_USER_SET_VRING_CALL: /* consume the fd */ qemu_chr_fe_get_msgfds(chr, &fd, 1); /* * This is a non-blocking eventfd. * The receive function forces it to be blocking, * so revert it back to non-blocking. */ qemu_set_nonblock(fd); break; case VHOST_USER_SET_LOG_BASE: if (s->log_fd != -1) { close(s->log_fd); s->log_fd = -1; } qemu_chr_fe_get_msgfds(chr, &s->log_fd, 1); msg.flags |= VHOST_USER_REPLY_MASK; msg.size = 0; p = (uint8_t *) &msg; qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE); g_cond_broadcast(&s->data_cond); break; case VHOST_USER_SET_VRING_BASE: assert(msg.payload.state.index < s->queues * 2); s->rings |= 0x1ULL << msg.payload.state.index; g_cond_broadcast(&s->data_cond); break; case VHOST_USER_GET_QUEUE_NUM: msg.flags |= VHOST_USER_REPLY_MASK; msg.size = sizeof(m.payload.u64); msg.payload.u64 = s->queues; p = (uint8_t *) &msg; qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE + msg.size); break; default: break; } g_mutex_unlock(&s->data_mutex); }
static void chr_read(void *opaque, const uint8_t *buf, int size) { CharDriverState *chr = opaque; VhostUserMsg msg; uint8_t *p = (uint8_t *) &msg; int fd; if (size != VHOST_USER_HDR_SIZE) { g_test_message("Wrong message size received %d\n", size); return; } g_mutex_lock(data_mutex); memcpy(p, buf, VHOST_USER_HDR_SIZE); if (msg.size) { p += VHOST_USER_HDR_SIZE; qemu_chr_fe_read_all(chr, p, msg.size); } switch (msg.request) { case VHOST_USER_GET_FEATURES: /* send back features to qemu */ msg.flags |= VHOST_USER_REPLY_MASK; msg.size = sizeof(m.u64); msg.u64 = 0; p = (uint8_t *) &msg; qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE + msg.size); break; case VHOST_USER_GET_VRING_BASE: /* send back vring base to qemu */ msg.flags |= VHOST_USER_REPLY_MASK; msg.size = sizeof(m.state); msg.state.num = 0; p = (uint8_t *) &msg; qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE + msg.size); break; case VHOST_USER_SET_MEM_TABLE: /* received the mem table */ memcpy(&memory, &msg.memory, sizeof(msg.memory)); fds_num = qemu_chr_fe_get_msgfds(chr, fds, sizeof(fds) / sizeof(int)); /* signal the test that it can continue */ g_cond_signal(data_cond); break; case VHOST_USER_SET_VRING_KICK: case VHOST_USER_SET_VRING_CALL: /* consume the fd */ qemu_chr_fe_get_msgfds(chr, &fd, 1); /* * This is a non-blocking eventfd. * The receive function forces it to be blocking, * so revert it back to non-blocking. */ qemu_set_nonblock(fd); break; default: break; } g_mutex_unlock(data_mutex); }