summaryrefslogtreecommitdiffstats
path: root/virtio_loopback.c
diff options
context:
space:
mode:
Diffstat (limited to 'virtio_loopback.c')
-rw-r--r--virtio_loopback.c171
1 files changed, 56 insertions, 115 deletions
diff --git a/virtio_loopback.c b/virtio_loopback.c
index 91110c4..f9e5464 100644
--- a/virtio_loopback.c
+++ b/virtio_loopback.c
@@ -71,7 +71,6 @@
int s; /* To be deleted */
int efd; /* Eventfd file descriptor */
int efd_notify; /* Eventfd file descriptor */
-uint64_t eftd_ctr;
fd_set rfds;
int fd;
int loopback_fd;
@@ -101,6 +100,15 @@ static int virtio_validate_features(VirtIODevice *vdev)
return 0;
}
+bool virtio_device_should_start(VirtIODevice *vdev, uint8_t status)
+{
+ if (!vdev->vm_running) {
+ return false;
+ }
+
+ return virtio_device_started(vdev, status);
+}
+
bool virtio_device_started(VirtIODevice *vdev, uint8_t status)
{
@@ -144,7 +152,7 @@ int virtio_set_status(VirtIODevice *vdev, uint8_t val)
virtio_set_started(vdev, val & VIRTIO_CONFIG_S_DRIVER_OK);
}
- DBG("set vdev->status :%u \n", vdev->status);
+ DBG("set vdev->status:%u\n", vdev->status);
if (k->set_status) {
DBG("k->set_status\n");
@@ -524,88 +532,7 @@ static bool virtqueue_map_desc(VirtIODevice *vdev, unsigned int *p_num_sg,
unsigned int max_num_sg, bool is_write,
uint64_t pa, size_t sz)
{
- unsigned num_sg = *p_num_sg;
- bool ok = false;
- uint64_t mmap_addr;
- int ioctl_res;
-
- if (!sz) {
- DBG("virtio: zero sized buffers are not allowed\n");
- goto out;
- }
-
- while (sz) {
- uint64_t len = sz;
-
- if (num_sg == max_num_sg) {
- DBG("virtio: too many write descriptors in\n"
- "indirect table");
- goto out;
- }
-
- DBG("\tpa address is: 0x%lx\n", pa);
-
- memcpy(&mmap_addr, &pa, sizeof(uint64_t));
- ioctl_res = ioctl(loopback_fd, SHARE_BUF, &mmap_addr);
-
- /* Notify the loopback driver what you want to' mmap' */
- if (ioctl_res < 0) {
- DBG("SHARE_BUF failed\n");
- exit(1);
- } else {
- if (mmap_addr == 0) {
-
- if ((pa & 0xff) == 0) {
- ioctl(loopback_fd, MAP_BLK);
- }
-
- DBG("Try to mmap pa: 0x%lx, size: %lx\n", pa, len);
- iov[num_sg].iov_base = mmap(NULL, len, PROT_READ | PROT_WRITE,
- MAP_SHARED, loopback_fd, 0);
- int retries = 5;
- while ((retries > 0) && ((int64_t)iov[num_sg].iov_base < 0)) {
- iov[num_sg].iov_base = mmap(NULL, len,
- PROT_READ | PROT_WRITE,
- MAP_SHARED, loopback_fd, 0);
- retries--;
- }
-
- if ((int64_t)iov[num_sg].iov_base < 0) {
- DBG("Bad mapping\n");
- exit(1);
- }
- } else {
- iov[num_sg].iov_base = (void *)mmap_addr;
- }
- }
-
- /* Fix the offset */
- iov[num_sg].iov_base += pa & 0xfff;
- DBG("\tMMap address (iov_base): 0x%lx\n",
- (uint64_t)iov[num_sg].iov_base);
-
- /* Update len: Remaining size in the current page */
- if (sz > PAGE_SIZE - (pa & 0xfff)) {
- len = PAGE_SIZE - (pa & 0xfff);
- }
-
- if (!iov[num_sg].iov_base) {
- DBG("virtio: bogus descriptor or out of resources\n");
- goto out;
- }
-
- iov[num_sg].iov_len = len;
- addr[num_sg] = pa;
-
- sz -= len;
- pa += len;
- num_sg++;
- }
- ok = true;
-
-out:
- *p_num_sg = num_sg;
- return ok;
+ DBG("Not implemented\n");
}
static void *virtqueue_alloc_element(size_t sz, unsigned out_num,
@@ -1078,16 +1005,11 @@ static void virtio_queue_guest_notifier_read(EventNotifier *n)
}
}
-
-int eventfd_count = 0;
-
-
-
+int eventfd_count;
void *loopback_event_select(void *_e)
{
int retval;
- uint64_t eftd_ctr;
fd_set rfds;
int s;
EventNotifier *e = (EventNotifier *)_e;
@@ -1286,18 +1208,8 @@ bool virtio_device_disabled(VirtIODevice *vdev)
return vdev->disabled || vdev->broken;
}
-int prev_level = 0;
-
-void *my_notify(void *data) {
-
- int irq_num = 44;
- (void) data;
- (void) ioctl(fd, IRQ, &irq_num);
-
- pthread_exit(NULL);
-}
-
-int int_count = 0;
+static int prev_level;
+static int int_count;
void virtio_loopback_update_irq(VirtIODevice *vdev)
{
@@ -1314,6 +1226,7 @@ void virtio_loopback_update_irq(VirtIODevice *vdev)
DBG("prev_level: %d\n", prev_level);
if (!((level == 1) && (prev_level == 0))) {
+ DBG("!((level == 1) && (prev_level == 0))\n");
prev_level = level;
return;
}
@@ -1322,12 +1235,11 @@ void virtio_loopback_update_irq(VirtIODevice *vdev)
DBG("Trigger interrupt (ioctl)\n");
DBG("Interrupt counter: %d\n", int_count++);
- //(void)pthread_create(&my_thread_id, NULL, my_notify, NULL);
(void) ioctl(fd, IRQ, &irq_num);
}
-bool enable_virtio_interrupt = false;
+bool enable_virtio_interrupt;
/* virtio device */
void virtio_notify_vector(VirtIODevice *vdev)
@@ -1485,6 +1397,8 @@ static uint64_t virtio_loopback_read(VirtIODevice *vdev, uint64_t offset,
uint64_t ret;
+ DBG("READ\n");
+
if (!vdev) {
/*
* If no backend is present, we treat most registers as
@@ -1544,26 +1458,28 @@ static uint64_t virtio_loopback_read(VirtIODevice *vdev, uint64_t offset,
case VIRTIO_MMIO_MAGIC_VALUE:
return VIRT_MAGIC;
case VIRTIO_MMIO_VERSION:
+ DBG("VIRTIO_MMIO_VERSION ->\n");
if (proxy->legacy) {
+ DBG("VIRTIO_MMIO_VERSION -> legacy\n");
return VIRT_VERSION_LEGACY;
} else {
+ DBG("VIRTIO_MMIO_VERSION -> version\n");
return VIRT_VERSION;
}
case VIRTIO_MMIO_DEVICE_ID:
return vdev->device_id;
case VIRTIO_MMIO_VENDOR_ID:
+ DBG("READ\n");
return VIRT_VENDOR;
case VIRTIO_MMIO_DEVICE_FEATURES:
if (proxy->legacy) {
if (proxy->host_features_sel) {
- DBG("vdev->host_features: 0x%lx\n", (vdev->host_features >> 32));
- return (vdev->host_features >> 32);
+ return vdev->host_features >> 32;
} else {
- DBG("vdev->host_features: 0x%lx\n", vdev->host_features & (uint64_t)(((1ULL << 32) - 1)));
- return (vdev->host_features & (uint64_t)(((1ULL << 32) - 1)));
+ return vdev->host_features & (uint64_t)(((1ULL << 32) - 1));
}
} else {
- /* TODO: To be implemented */
+ /* TODO: To be implemented */
}
case VIRTIO_MMIO_QUEUE_NUM_MAX:
/* TODO: To be implemented */
@@ -1587,6 +1503,7 @@ static uint64_t virtio_loopback_read(VirtIODevice *vdev, uint64_t offset,
case VIRTIO_MMIO_INTERRUPT_STATUS:
return vdev->isr;
case VIRTIO_MMIO_STATUS:
+ DBG("Read VIRTIO_MMIO_STATUS: %d\n", vdev->status);
return vdev->status;
case VIRTIO_MMIO_CONFIG_GENERATION:
if (proxy->legacy) {
@@ -1629,7 +1546,8 @@ static uint64_t virtio_loopback_read(VirtIODevice *vdev, uint64_t offset,
}
uint64_t vring_phys_addrs[2] = {0};
-uint32_t vring_phys_addrs_idx = 0;
+uint32_t vring_phys_addrs_idx;
+static int notify_cnt;
void virtio_loopback_write(VirtIODevice *vdev, uint64_t offset,
uint64_t value, unsigned size)
@@ -1673,6 +1591,7 @@ void virtio_loopback_write(VirtIODevice *vdev, uint64_t offset,
}
switch (offset) {
case VIRTIO_MMIO_DEVICE_FEATURES_SEL:
+ DBG("VIRTIO_MMIO_DEVICE_FEATURES_SEL: 0x%lx\n", value);
if (value) {
proxy->host_features_sel = 1;
} else {
@@ -1771,6 +1690,8 @@ void virtio_loopback_write(VirtIODevice *vdev, uint64_t offset,
/* TODO: To be implemented */
break;
case VIRTIO_MMIO_QUEUE_NOTIFY:
+ DBG("\nVIRTIO_MMIO_QUEUE_NOTIFY: vq_index -> %d, notify_cnt: %d\n",
+ value, notify_cnt++);
if (value < VIRTIO_QUEUE_MAX) {
virtio_queue_notify(vdev, value);
}
@@ -1883,7 +1804,7 @@ void adapter_read_write_cb(void)
*
* print_neg_flag (address->notification, address->read);
*/
- print_neg_flag (address->notification, address->read);
+ print_neg_flag(address->notification, address->read);
if (address->read) {
address->data = virtio_loopback_read(global_vdev,
@@ -1907,7 +1828,9 @@ void *notify_select(void *data)
{
int retval;
fd_set rfds;
+ uint64_t eftd_ctr;
int efd = *(int *)data;
+ int32_t vq_index;
DBG("\nWaiting for loopback notify events\n");
@@ -1924,9 +1847,11 @@ void *notify_select(void *data)
DBG("Eventfd read error\n");
exit(1);
} else {
- //rcu_read_lock();
- virtio_queue_notify(global_vdev, 0);
- //rcu_read_unlock();
+ DBG("\nnotify select\n");
+ (void)ioctl(fd, SHARE_NOTIFIED_VQ_INDEX, &vq_index);
+ DBG("\nnotify_select: vq_index -> %d, notify_cnt: %d,"
+ "eventfd_val: %lu\n\n", vq_index, notify_cnt++, eftd_ctr);
+ virtio_queue_notify(global_vdev, vq_index);
}
}
}
@@ -1935,6 +1860,7 @@ void *notify_select(void *data)
void *driver_event_select(void *data)
{
int retval;
+ uint64_t eftd_ctr;
int efd = *(int *)data;
DBG("\nWaiting for loopback read/write events\n");
@@ -1990,6 +1916,7 @@ VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size,
}
if (i == VIRTIO_QUEUE_MAX || queue_size > VIRTQUEUE_MAX_SIZE) {
+ DBG("Error: queue_size > VIRTQUEUE_MAX_SIZE\n");
exit(1);
}
@@ -2008,12 +1935,15 @@ void virtio_dev_init(VirtIODevice *vdev, const char *name,
{
int i;
+ DBG("virtio_dev_init\n");
+
vdev->start_on_kick = false;
vdev->started = false;
vdev->device_id = device_id;
vdev->status = 0;
vdev->queue_sel = 0;
vdev->config_vector = VIRTIO_NO_VECTOR;
+ /* TODO: check malloc return value */
vdev->vq = (VirtQueue *) malloc(sizeof(VirtQueue) * VIRTIO_QUEUE_MAX);
vdev->vm_running = false;
vdev->broken = false;
@@ -2033,6 +1963,7 @@ void virtio_dev_init(VirtIODevice *vdev, const char *name,
}
vdev->use_guest_notifier_mask = true;
+ DBG("virtio_dev_init return\n");
}
static bool virtio_loopback_ioeventfd_enabled(VirtIODevice *d)
@@ -2065,6 +1996,7 @@ void virtio_loopback_bus_init(VirtioBus *k)
k->set_guest_notifiers = virtio_loopback_set_guest_notifiers;
k->ioeventfd_enabled = virtio_loopback_ioeventfd_enabled;
k->ioeventfd_assign = virtio_loopback_ioeventfd_assign;
+ DBG("virtio_loopback_bus_init(...) return\n");
}
@@ -2076,6 +2008,14 @@ int virtio_loopback_start(void)
int ret = -1;
int flags;
+ /* Initialize global variables */
+ prev_level = 0;
+ int_count = 0;
+ eventfd_count = 0;
+ enable_virtio_interrupt = false;
+ vring_phys_addrs_idx = 0;
+ notify_cnt = 0;
+
fd = open("/dev/loopback", O_RDWR);
if (fd < 0) {
perror("Open call failed");
@@ -2121,7 +2061,8 @@ int virtio_loopback_start(void)
}
/* Wait the eventfd */
- ret = pthread_create(&thread_id_notify, NULL, notify_select, (void *)&efd_notify);
+ ret = pthread_create(&thread_id_notify, NULL, notify_select,
+ (void *)&efd_notify);
if (ret != 0) {
exit(1);
}