From 6f99dc723608a8e33e05c5e36bfad95cd1ad7ad5 Mon Sep 17 00:00:00 2001
From: Dor Laor <dor@cloudius-systems.com>
Date: Thu, 21 Mar 2013 15:55:08 +0200
Subject: [PATCH] Return the length of the used descriptor. We cannot relay on
 the overlay protocol to provide this length and we must receive it from the
 hypervisor.

---
 drivers/virtio-blk.cc   | 3 ++-
 drivers/virtio-net.cc   | 6 ++++--
 drivers/virtio-vring.cc | 3 ++-
 drivers/virtio-vring.hh | 2 +-
 4 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/virtio-blk.cc b/drivers/virtio-blk.cc
index 31b74f217..18c38b161 100644
--- a/drivers/virtio-blk.cc
+++ b/drivers/virtio-blk.cc
@@ -185,8 +185,9 @@ void virtio_blk::response_worker() {
         virtio_d(fmt("\t ----> IRQ: virtio_d - blk thread awaken"));
 
         int i = 0;
+        u32 len;
 
-        while((req = static_cast<virtio_blk_req*>(queue->get_buf())) != nullptr) {
+        while((req = static_cast<virtio_blk_req*>(queue->get_buf(&len))) != nullptr) {
             virtio_d(fmt("\t got response:%d = %d ") % i++ % (int)req->status->status);
 
             virtio_blk_outhdr* header = reinterpret_cast<virtio_blk_outhdr*>(req->req_header);
diff --git a/drivers/virtio-net.cc b/drivers/virtio-net.cc
index c6bbda8a2..80f22346a 100644
--- a/drivers/virtio-net.cc
+++ b/drivers/virtio-net.cc
@@ -238,9 +238,10 @@ namespace virtio {
             });
 
             int i = 0;
+            u32 len;
             virtio_net_req * req;
 
-            while((req = static_cast<virtio_net_req*>(queue->get_buf())) != nullptr) {
+            while((req = static_cast<virtio_net_req*>(queue->get_buf(&len))) != nullptr) {
 
                 auto ii = req->payload._nodes.begin();
                 ii++;
@@ -398,10 +399,11 @@ namespace virtio {
     void virtio_net::tx_gc()
     {
         int i = 0;
+        u32 len;
         virtio_net_req * req;
         vring* queue = get_virt_queue(1);
 
-        while((req = static_cast<virtio_net_req*>(queue->get_buf())) != nullptr) {
+        while((req = static_cast<virtio_net_req*>(queue->get_buf(&len))) != nullptr) {
             virtio_net_d(fmt("%s: gc %d") % __FUNCTION__ % i++);
 
             delete req;
diff --git a/drivers/virtio-vring.cc b/drivers/virtio-vring.cc
index ed1331992..f55b04e32 100644
--- a/drivers/virtio-vring.cc
+++ b/drivers/virtio-vring.cc
@@ -138,7 +138,7 @@ namespace virtio {
     }
 
     void*
-    vring::get_buf()
+    vring::get_buf(u32 *len)
     {
         return with_lock(_lock, [=] {
             vring_used_elem elem;
@@ -157,6 +157,7 @@ namespace virtio {
             virtio_d(fmt("get used: guest head=%d use_elem[head].id=%d") % used_ptr % _used->_used_elements[used_ptr]._id);
             elem = _used->_used_elements[used_ptr];
             int idx = elem._id;
+            *len = elem._len;
 
             if (_desc[idx]._flags & vring_desc::VRING_DESC_F_INDIRECT) {
                 free(mmu::phys_to_virt(_desc[idx]._paddr));
diff --git a/drivers/virtio-vring.hh b/drivers/virtio-vring.hh
index 8b932ed6d..a6e299ba5 100644
--- a/drivers/virtio-vring.hh
+++ b/drivers/virtio-vring.hh
@@ -119,7 +119,7 @@ class virtio_driver;
 
         // Ring operations
         bool add_buf(sglist* sg, u16 out, u16 in, void* cookie);
-        void* get_buf();
+        void* get_buf(u32 *len);
         bool used_ring_not_empty();
         bool avail_ring_not_empty();
         // when the available ring has x descriptors as room it means that
-- 
GitLab