[lavapipe] Close VMO handle on lvp_FreeMemory

Close mem->vmo_handle in lvp_FreeMemory and handle allocation
failures for Zircon VMO memory. Previously, lvp_FreeMemory
only freed the duplicated handle in llvmpipe but leaked the
original vmo_handle stored in lvp_device_memory, causing Sysmem
VMO handle leaks.

Test: Verified memory release without weak VMO leak warnings from
sysmem

Fixed: 541310992
Change-Id: I11b1837281bffcd1cd232cfa17d552ceea729f2c
Reviewed-on: https://fuchsia-review.googlesource.com/c/third_party/mesa/+/1736749
Fuchsia-Auto-Submit: Emircan Uysaler <emircan@google.com>
Reviewed-by: Josh Gargus <jjosh@google.com>
Reviewed-by: David Gilhooley <dgilhooley@google.com>
Commit-Queue: Emircan Uysaler <emircan@google.com>
diff --git a/src/gallium/frontends/lavapipe/lvp_device.c b/src/gallium/frontends/lavapipe/lvp_device.c
index 2cd8950..3aff8a2 100644
--- a/src/gallium/frontends/lavapipe/lvp_device.c
+++ b/src/gallium/frontends/lavapipe/lvp_device.c
@@ -2126,6 +2126,7 @@
    mem->backed_fd = -1;
 #if DETECT_OS_FUCHSIA
    mem->sysmem_coherency_domain = MAGMA_COHERENCY_DOMAIN_CPU;
+   mem->vmo_handle = ZX_HANDLE_INVALID;
 #endif
 
    if (mem->vk.host_ptr) {
@@ -2194,6 +2195,8 @@
       VkDeviceSize aligned_alloc_size =
          align64(pAllocateInfo->allocationSize, zx_system_get_page_size());
 
+      mem->vmo_handle = zircon_handle_info->handle;
+
       if (!device->pscreen->import_memory_zircon_handle(device->pscreen, zircon_handle_info->handle, &mem->pmem, aligned_alloc_size)) {
          error = VK_ERROR_OUT_OF_DEVICE_MEMORY;
          goto fail;
@@ -2249,6 +2252,7 @@
       }
 
       mem->vmo_handle = vmo;
+
       if (!device->pscreen->import_memory_zircon_handle(device->pscreen, mem->vmo_handle, &mem->pmem, aligned_alloc_size)) {
          error = VK_ERROR_OUT_OF_DEVICE_MEMORY;
          goto fail;
@@ -2280,6 +2284,12 @@
    return VK_SUCCESS;
 
 fail:
+#if DETECT_OS_FUCHSIA
+   if (mem->vmo_handle != ZX_HANDLE_INVALID) {
+      zx_handle_close(mem->vmo_handle);
+      mem->vmo_handle = ZX_HANDLE_INVALID;
+   }
+#endif
    vk_device_memory_destroy(&device->vk, pAllocator, &mem->vk);
    return vk_error(device, error);
 }
@@ -2318,6 +2328,10 @@
 #if DETECT_OS_FUCHSIA
    case LVP_DEVICE_MEMORY_TYPE_ZIRCON_VMO:
       device->pscreen->free_memory_zircon_handle(device->pscreen, mem->pmem);
+      if (mem->vmo_handle != ZX_HANDLE_INVALID) {
+         zx_handle_close(mem->vmo_handle);
+         mem->vmo_handle = ZX_HANDLE_INVALID;
+      }
       break;
 #endif
    case LVP_DEVICE_MEMORY_TYPE_USER_PTR: