static size_t send_buffer(VirtIOCrypto *crdev, const uint8_t *buf, size_t size) { VirtQueueElement elem; VirtQueue *vq; unsigned int len; vq = crdev->ivq; /* Is the virtqueue ready? */ if (!virtio_queue_ready(vq)) { return 0; } /* Is there a buffer in the queue? */ /* If not we can not send data to the Guest. */ /* ? */ if( (!virtqueue_pop(vq,&elem)) ){ return 0; } memcpy(elem.in_sg[0].iov_base,buf, size); virtqueue_push(vq,&elem,size); virtio_notify(&crdev->vdev,vq); len = size; return len; }
/* * Send a control event to the guest. */ static size_t send_control_event(VirtIOCrypto *crdev, uint16_t event, uint16_t value) { struct virtio_crypto_control cpkt; VirtQueueElement elem; VirtQueue *vq; FUNC_IN; stw_p(&cpkt.event, event); stw_p(&cpkt.value, value); vq = crdev->c_ivq; if (!virtio_queue_ready(vq)) { return 0; } if (!virtqueue_pop(vq, &elem)) { return 0; } memcpy(elem.in_sg[0].iov_base, &cpkt, sizeof(cpkt)); virtqueue_push(vq, &elem, sizeof(cpkt)); virtio_notify(&crdev->vdev, vq); FUNC_OUT; return sizeof(cpkt); }
static bool is_guest_ready(VirtIORNG *vrng) { VirtIODevice *vdev = VIRTIO_DEVICE(vrng); if (virtio_queue_ready(vrng->vq) && (vdev->status & VIRTIO_CONFIG_S_DRIVER_OK)) { return true; } trace_virtio_rng_guest_not_ready(vrng); return false; }
static int do_virtio_net_can_receive(VirtIONet *n, int bufsize) { if (!virtio_queue_ready(n->rx_vq) || !(n->vdev.status & VIRTIO_CONFIG_S_DRIVER_OK)) return 0; if (virtio_queue_empty(n->rx_vq) || (n->mergeable_rx_bufs && !virtqueue_avail_bytes(n->rx_vq, bufsize, 0))) { virtio_queue_set_notification(n->rx_vq, 1); return 0; } virtio_queue_set_notification(n->rx_vq, 0); return 1; }
static int vcon_can_read(void *opaque) { VirtIOConsole *s = (VirtIOConsole *) opaque; if (!virtio_queue_ready(s->ivq) || !(s->vdev.status & VIRTIO_CONFIG_S_DRIVER_OK) || virtio_queue_empty(s->ivq)) return 0; /* current implementations have a page sized buffer. * We fall back to a one byte per read if there is not enough room. * It would be cool to have a function that returns the available byte * instead of checking for a limit */ if (virtqueue_avail_bytes(s->ivq, TARGET_PAGE_SIZE, 0)) return TARGET_PAGE_SIZE; if (virtqueue_avail_bytes(s->ivq, 1, 0)) return 1; return 0; }