virtio 提供的hw_rng

hwrng 也提供了一种从virtio中获取真随机数的方法,代码在drivers/char/hw_random/virtio-rng.c中,通过前面的分析hw_rng的工作原理都清楚了,那我们看看做核心的read函数的实现
vi->hwrng = (struct hwrng) {
		.read = virtio_read,
		.cleanup = virtio_cleanup,
		.priv = (unsigned long)vi,
		.name = vi->name,
		.quality = 1000,
	};
从这里的qulity等于1000,可以看出virtio提供的hw_rng还是很随进的,比有些硬件提供qulity都高。那我们看看read的实现
static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait)
{
	int ret;
	struct virtrng_info *vi = (struct virtrng_info *)rng->priv;

	if (vi->hwrng_removed)
		return -ENODEV;
#原来只有在virtio工作的时候也就是busy的时候才能提供真随机数,如果不busy的话,就初始化一个完成量
等busy的时候在释放完成量,从而继续往下走获取随机数
	if (!vi->busy) {
		vi->busy = true;
		reinit_completion(&vi->have_data);
		register_buffer(vi, buf, size);
	}

	if (!wait)
		return 0;
#等待virtio提供随机数
	ret = wait_for_completion_killable(&vi->have_data);
	if (ret < 0)
		return ret;

	vi->busy = false;
#返回随机数
	return vi->data_avail;
}
那这里的data_avail 到底是啥呢,可以看看看random_recv_done
static void random_recv_done(struct virtqueue *vq)
{
	struct virtrng_info *vi = vq->vdev->priv;

	/* We can get spurious callbacks, e.g. shared IRQs + virtio_pci. */
	if (!virtqueue_get_buf(vi->vq, &vi->data_avail))
		return;

	complete(&vi->have_data);
}
继续看virtqueue_get_buf
void *virtqueue_get_buf(struct virtqueue *_vq, unsigned int *len)
{
        return virtqueue_get_buf_ctx(_vq, len, NULL);
}

这里基本就可以看到data_avail就是vq中buf,对应的长度len。

猜你喜欢

转载自blog.csdn.net/tiantao2012/article/details/113780177
今日推荐