#include "kvm/kvm.h"
+#define VIRTIO_IRQ_LOW 0
+#define VIRTIO_IRQ_HIGH 1
+
struct virt_queue {
struct vring vring;
u32 pfn;
u16 virt_queue__get_iov(struct virt_queue *queue, struct iovec iov[], u16 *out, u16 *in, struct kvm *kvm);
+void virt_queue__trigger_irq(struct virt_queue *vq, int irq, u8 *isr, struct kvm *kvm);
+
#endif /* KVM__VIRTIO_H */
return head;
}
+
+void virt_queue__trigger_irq(struct virt_queue *vq, int irq, u8 *isr, struct kvm *kvm)
+{
+ if (*isr == VIRTIO_IRQ_LOW) {
+ *isr = VIRTIO_IRQ_HIGH;
+ kvm__irq_line(kvm, irq, VIRTIO_IRQ_HIGH);
+ }
+}
u32 guest_features;
u16 config_vector;
u8 status;
+ u8 isr;
u16 queue_selector;
pthread_t io_rx_thread;
head = virt_queue__get_iov(vq, iov, &out, &in, self);
len = readv(net_device.tap_fd, iov, in);
virt_queue__set_used_elem(vq, head, len);
+
/* We should interrupt guest right now, otherwise latency is huge. */
- kvm__irq_line(self, VIRTIO_NET_IRQ, 1);
+ virt_queue__trigger_irq(vq, VIRTIO_NET_IRQ, &net_device.isr, self);
}
}
virt_queue__set_used_elem(vq, head, len);
}
- kvm__irq_line(self, VIRTIO_NET_IRQ, 1);
+ virt_queue__trigger_irq(vq, VIRTIO_NET_IRQ, &net_device.isr, self);
+
}
pthread_exit(NULL);
ioport__write8(data, net_device.status);
break;
case VIRTIO_PCI_ISR:
- ioport__write8(data, 0x1);
- kvm__irq_line(self, VIRTIO_NET_IRQ, 0);
+ ioport__write8(data, net_device.isr);
+ kvm__irq_line(self, VIRTIO_NET_IRQ, VIRTIO_IRQ_LOW);
+ net_device.isr = VIRTIO_IRQ_LOW;
break;
case VIRTIO_MSI_CONFIG_VECTOR:
ioport__write16(data, net_device.config_vector);