gpt4 book ai didi

c - 使用带有 virtio 设备/驱动程序的 virtqueue 从主机到 guest 时清空缓冲区

转载 作者:太空宇宙 更新时间:2023-11-03 23:41:38 41 4
gpt4 key购买 nike

我正在测试 virtio 驱动程序,以便在 Qemu 中从 guest 计算机与主机通信。现在我只想发送一个缓冲区。

我的问题是,当调用与虚拟队列关联的回调时,设备接收到一个空缓冲区。

奇怪的是,当驱动程序发送的缓冲区长度发生变化时,设备接收到的缓冲区长度也会发生变化。

在我的驱动程序中:

static int virt_test_probe(struct virtio_device *vdev)
{
struct virt_test_info *vi;
int retvalue = 0;
struct scatterlist sg[1];
char *str = vmalloc(1000*sizeof(char));
int err;
memset(str, 121, 1000*sizeof(char));
vi = kzalloc(sizeof(struct virt_test_info), GFP_KERNEL);
if (!vi)
return -ENOMEM;

printk(KERN_ERR "TEST VIRTIO LINUX: %s. Value of str: %s\n", __FUNCTION__, str);

vi->vq = virtio_find_single_vq(vdev, protector_recv_done, "input");
if (IS_ERR(vi->vq)) {
retvalue = PTR_ERR(vi->vq);
goto err_free;
}

vdev->priv = vi;
virtio_device_ready(vdev);
sg_init_one(sg, str, 1000*sizeof(char));
err = virtqueue_add_outbuf(vi->vq, sg, 1, str, GFP_ATOMIC);
virtqueue_kick(vi->vq);

return 0;

err_free:
kfree(vi);
return retvalue;
}

在我的 QEMU 设备中:

static void handle_output(VirtIODevice *vdev, VirtQueue *vq)
{
//VirtIOTEST *vtest = VIRTIO_TEST(vdev);
char *buf = malloc(1000*sizeof(char));
VirtQueueElement *elem;
int len;
printf("TEST VIRTIO: %s\n", __FUNCTION__);

for(;;) {
elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
if (elem)
break;
}
memset(buf,122, 1000*sizeof(char)); // I nitialised the buffer with y char

len = iov_to_buf(elem->out_sg, elem->out_num, 0, buf, 1000*sizeof(char));

printf("TEST VIRTIO: %s: content %s, len:%i\n", __FUNCTION__, buf, len); //the value length here changes with the the length of the driver's buffer
for(len=0; len<10; len++) {
printf("%02x",buf[len]); // here we're printing 0s
}
}

我使用的是 arm64 Linux。缓冲区的值似乎通过 qemu 的调用是一致的。所以我猜问题出在 linux 内核或其他方面。我检查了分散列表是否正常,据我所知,我没有收到来自 add_output_buf 的错误。

最佳答案

我刚刚发现它不起作用的原因:使用 kmalloc 而不是 vmalloc 来分配要传递给 sg_init_one 的缓冲区。原因如下:

scatterlist 将缓冲区存储为一个页面。因此它必须使用 page_to_virt 将缓冲区转换为页面,这基本上是将偏移量应用于虚拟地址以获得页面物理地址。

现在,vmalloc 不像kmalloc 那样将内存映射到连续的物理地址空间。因此它更改页表以将不连续的物理地址映射到连续的虚拟地址。所以函数 page_to_virt 似乎不适用于 vmalloc,因为它需要的不仅仅是应用偏移量来进入物理地址空间。

关于c - 使用带有 virtio 设备/驱动程序的 virtqueue 从主机到 guest 时清空缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43985619/

41 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com