vmw_balloon: VMCI_DOORBELL_SET does not check status
authorNadav Amit <namit@vmware.com>
Tue, 19 Jun 2018 23:00:26 +0000 (16:00 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 9 Sep 2018 17:55:57 +0000 (19:55 +0200)
commit ce664331b2487a5d244a51cbdd8cb54f866fbe5d upstream.

When vmballoon_vmci_init() sets a doorbell using VMCI_DOORBELL_SET, for
some reason it does not consider the status and looks at the result.
However, the hypervisor does not update the result - it updates the
status. This might cause VMCI doorbell not to be enabled, resulting in
degraded performance.

Fixes: 48e3d668b790 ("VMware balloon: Enable notification via VMCI")
Cc: stable@vger.kernel.org
Reviewed-by: Xavier Deguillard <xdeguillard@vmware.com>
Signed-off-by: Nadav Amit <namit@vmware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/misc/vmw_balloon.c

index 4967cebddf48f11695e275f6da8904de41a49b90..fe56e72f9463dbd4c02ea9e29425e1518db3c13c 100644 (file)
@@ -1036,29 +1036,30 @@ static void vmballoon_vmci_cleanup(struct vmballoon *b)
  */
 static int vmballoon_vmci_init(struct vmballoon *b)
 {
-       int error = 0;
+       unsigned long error, dummy;
 
-       if ((b->capabilities & VMW_BALLOON_SIGNALLED_WAKEUP_CMD) != 0) {
-               error = vmci_doorbell_create(&b->vmci_doorbell,
-                               VMCI_FLAG_DELAYED_CB,
-                               VMCI_PRIVILEGE_FLAG_RESTRICTED,
-                               vmballoon_doorbell, b);
-
-               if (error == VMCI_SUCCESS) {
-                       VMWARE_BALLOON_CMD(VMCI_DOORBELL_SET,
-                                       b->vmci_doorbell.context,
-                                       b->vmci_doorbell.resource, error);
-                       STATS_INC(b->stats.doorbell_set);
-               }
-       }
+       if ((b->capabilities & VMW_BALLOON_SIGNALLED_WAKEUP_CMD) == 0)
+               return 0;
 
-       if (error != 0) {
-               vmballoon_vmci_cleanup(b);
+       error = vmci_doorbell_create(&b->vmci_doorbell, VMCI_FLAG_DELAYED_CB,
+                                    VMCI_PRIVILEGE_FLAG_RESTRICTED,
+                                    vmballoon_doorbell, b);
 
-               return -EIO;
-       }
+       if (error != VMCI_SUCCESS)
+               goto fail;
+
+       error = VMWARE_BALLOON_CMD(VMCI_DOORBELL_SET, b->vmci_doorbell.context,
+                                  b->vmci_doorbell.resource, dummy);
+
+       STATS_INC(b->stats.doorbell_set);
+
+       if (error != VMW_BALLOON_SUCCESS)
+               goto fail;
 
        return 0;
+fail:
+       vmballoon_vmci_cleanup(b);
+       return -EIO;
 }
 
 /*