vhost: wrong value return for VHOST_USER_VRING_GET_BASE 00/5700/4
authorSteven <sluong@cisco.com>
Fri, 10 Mar 2017 07:49:32 +0000 (23:49 -0800)
committerJohn Lo <loj@cisco.com>
Thu, 16 Mar 2017 14:00:12 +0000 (14:00 +0000)
When the VM is migrated, the driver sends VHOST_USER_VRING_GET_BASE
message to the device to get the vring offset. The device is
supposed to shut down the vring, and return the current vring offset.
What the code did was to shutdown the vring, initialize the vring,
and return 0 to the driver.

The fix is to first store last_avail_idx in the message and then close
the vring.

Change-Id: I432e9f50f36d89fe53a45e050edcf5e1218caf7a
Signed-off-by: Steven <sluong@cisco.com>
src/vnet/devices/virtio/vhost-user.c

index 100ec61..3cbeca9 100644 (file)
@@ -583,7 +583,10 @@ vhost_user_vring_close (vhost_user_intf_t * vui, u32 qid)
       vring->callfd_idx = ~0;
     }
   if (vring->errfd != -1)
-    close (vring->errfd);
+    {
+      close (vring->errfd);
+      vring->errfd = -1;
+    }
   vhost_user_vring_init (vui, qid);
 }
 
@@ -1026,12 +1029,16 @@ vhost_user_socket_read (unix_file_t * uf)
          goto close_socket;
        }
 
-      /* Spec says: Client must [...] stop ring upon receiving VHOST_USER_GET_VRING_BASE. */
-      vhost_user_vring_close (vui, msg.state.index);
-
+      /*
+       * Copy last_avail_idx from the vring before closing it because
+       * closing the vring also initializes the vring last_avail_idx
+       */
       msg.state.num = vui->vrings[msg.state.index].last_avail_idx;
       msg.flags |= 4;
       msg.size = sizeof (msg.state);
+
+      /* Spec says: Client must [...] stop ring upon receiving VHOST_USER_GET_VRING_BASE. */
+      vhost_user_vring_close (vui, msg.state.index);
       break;
 
     case VHOST_USER_NONE: