return -ENODEV;
HAB_HEADER_SET_SIZE(header, sizebytes);
- HAB_HEADER_SET_TYPE(header, HAB_PAYLOAD_TYPE_MSG);
+ if (flags & HABMM_SOCKET_SEND_FLAGS_XING_VM_STAT)
+ HAB_HEADER_SET_TYPE(header, HAB_PAYLOAD_TYPE_PROFILE);
+ else
+ HAB_HEADER_SET_TYPE(header, HAB_PAYLOAD_TYPE_MSG);
+
HAB_HEADER_SET_ID(header, vchan->otherend_id);
while (1) {
uint32_t vchan_id = HAB_HEADER_GET_ID(*header);
struct virtual_channel *vchan = NULL;
struct export_desc *exp_desc;
+ struct timeval tv;
/* get the local virtual channel if it isn't an open message */
if (payload_type != HAB_PAYLOAD_TYPE_INIT &&
hab_vchan_stop(vchan);
break;
+ case HAB_PAYLOAD_TYPE_PROFILE:
+ do_gettimeofday(&tv);
+
+ /* pull down the incoming data */
+ message = hab_msg_alloc(pchan, sizebytes);
+ if (!message) {
+ pr_err("msg alloc failed\n");
+ break;
+ }
+
+ ((uint64_t *)message->data)[2] = tv.tv_sec;
+ ((uint64_t *)message->data)[3] = tv.tv_usec;
+ hab_msg_queue(vchan, message);
+ break;
+
default:
break;
}
int sizebytes = HAB_HEADER_GET_SIZE(*header);
struct qvm_channel *dev = (struct qvm_channel *)pchan->hyp_data;
int total_size = sizeof(*header) + sizebytes;
+ struct timeval tv;
if (total_size > dev->pipe_ep->tx_info.sh_buf->size)
return -EINVAL; /* too much data for ring */
return -EIO;
}
+ if (HAB_HEADER_GET_TYPE(*header) == HAB_PAYLOAD_TYPE_PROFILE) {
+ do_gettimeofday(&tv);
+ ((uint64_t *)payload)[0] = tv.tv_sec;
+ ((uint64_t *)payload)[1] = tv.tv_usec;
+ }
+
if (sizebytes) {
if (hab_pipe_write(dev->pipe_ep,
(unsigned char *)payload,
#define HABMM_SOCKET_SEND_FLAGS_NON_BLOCKING 0x00000001
+/*
+ * Collect cross-VM stats: client provides stat-buffer large enough to allow 2
+ * ets of a 2-uint64_t pair to collect seconds and nano-seconds at the
+ * beginning of the stat-buffer. Stats are collected when the stat-buffer leaves
+ * VM1, then enters VM2
+ */
+#define HABMM_SOCKET_SEND_FLAGS_XING_VM_STAT 0x00000002
+
#define HABMM_SOCKET_RECV_FLAGS_NON_BLOCKING 0x00000001
#define HABMM_EXP_MEM_TYPE_DMA 0x00000001