[hypervisor] Add Join to Guest to wait on all VCPUs.

Corresponding change to Garnet to follow.

Change-Id: I728ba3b56758c1ad7697aafb10671af3cab4a4fd
diff --git a/system/ulib/hypervisor/guest.cpp b/system/ulib/hypervisor/guest.cpp
index 93c179a..7d24fc0 100644
--- a/system/ulib/hypervisor/guest.cpp
+++ b/system/ulib/hypervisor/guest.cpp
@@ -192,3 +192,21 @@
 
     return ZX_OK;
 }
+
+zx_status_t Guest::Join() {
+    // We assume that the VCPU-0 thread will be started first, and that no additional VCPUs will
+    // be brought up after it terminates.
+    zx_status_t status = vcpus_[0]->Join();
+
+    // Once the initial VCPU has terminated, wait for any additional VCPUs.
+    for (size_t id = 1; id != kMaxVcpus; ++id) {
+        if (vcpus_[id] != nullptr) {
+            zx_status_t vcpu_status = vcpus_[id]->Join();
+            if (vcpu_status != ZX_OK) {
+                status = vcpu_status;
+            }
+        }
+    }
+
+    return status;
+}
diff --git a/system/ulib/hypervisor/include/hypervisor/guest.h b/system/ulib/hypervisor/include/hypervisor/guest.h
index 0e19d49..ecae767 100644
--- a/system/ulib/hypervisor/include/hypervisor/guest.h
+++ b/system/ulib/hypervisor/include/hypervisor/guest.h
@@ -41,11 +41,16 @@
     zx_status_t CreateMapping(TrapType type, uint64_t addr, size_t size, uint64_t offset,
                               IoHandler* handler);
 
-    // Setup a handler function to run when an additional VCPU is brought up.
+    // Setup a handler function to run when an additional VCPU is brought up. The factory should
+    // call Start on the new VCPU to begin executing the guest on a new thread.
     void RegisterVcpuFactory(VcpuFactory factory);
 
+    // Initializes a VCPU by calling the VCPU factory. The first VCPU must have id 0.
     zx_status_t StartVcpu(uintptr_t entry, uint64_t id);
 
+    // Waits for all VCPUs associated with the guest to finish executing.
+    zx_status_t Join();
+
 private:
     // TODO(alexlegg): Consolidate this constant with other definitions in Garnet.
     static constexpr size_t kMaxVcpus = 16u;