Qemu에서 게스트 시스템에서 호스트 시스템으로 통신하기 위해 virtio 드라이버를 테스트하고 있습니다. 지금은 하나의 버퍼 만 보내고 싶습니다.virtio 장치/드라이버와 함께 virtqueue를 사용하여 호스트에서 게스트로가는 동안 빈 버퍼
제 문제는 가상 대기열과 관련된 콜백이 호출 될 때 장치가 빈 버퍼를 수신한다는 것입니다.
이상한 점은 드라이버에서 보낸 버퍼의 길이가 변경되면 장치에서 수신 된 버퍼의 길이가 변경된다는 것입니다. 내 드라이버에서
:
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 장치에서 : 내가 arm64 리눅스를 사용하고
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
}
}
. 버퍼의 값은 qemu의 호출을 통해 일관성이있는 것처럼 보입니다. 그래서 문제는 리눅스 커널이나 다른 것에서 오는 것 같습니다. 나는 scatterlist가 내가 알 수있는 것에서 ok로 갔다. 그리고 add_output_buf에서 어떤 에러도받지 못했다.