nouveau: add exported GEM handles to the global list

Adding GEM handles to the global list is necessary to allow
maintaining a single reference count for handles that are shared
between multiple buffer objects.

Since exported handles can end up being shared with other buffer
objects, as in the case that drmPrimeHandleToFD() and gbm_bo_import()
are called externally to Mesa, they too must be added to the global
list.

Unfortunately, doing this properly requires a new libdrm API. Use
the best possible option for now.

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/9552

Signed-off-by: Dor Askayo <dor.askayo@gmail.com>
Acked-by: Karol Herbst <git@karolherbst.de>
Cc: mesa-stable
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24648>
(cherry picked from commit daa1f789b57aae7a23eecd4c337b79cfe1f081cf)
diff --git a/.pick_status.json b/.pick_status.json
index 0b112f0..690d853 100644
--- a/.pick_status.json
+++ b/.pick_status.json
@@ -5394,7 +5394,7 @@
         "description": "nouveau: add exported GEM handles to the global list",
         "nominated": true,
         "nomination_type": 0,
-        "resolution": 0,
+        "resolution": 1,
         "main_sha": null,
         "because_sha": null,
         "notes": null
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c
index 2b37fa0..ed57592 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.c
+++ b/src/gallium/drivers/nouveau/nouveau_screen.c
@@ -145,6 +145,21 @@
    if (whandle->type == WINSYS_HANDLE_TYPE_SHARED) {
       return nouveau_bo_name_get(bo, &whandle->handle) == 0;
    } else if (whandle->type == WINSYS_HANDLE_TYPE_KMS) {
+      int fd;
+      int ret;
+
+      /* The handle is exported in this case, but the global list of
+       * handles is in libdrm and there is no libdrm API to add
+       * handles to the list without additional side effects. The
+       * closest API available also gets a fd for the handle, which
+       * is not necessary in this case. Call it and close the fd.
+       */
+      ret = nouveau_bo_set_prime(bo, &fd);
+      if (ret != 0)
+        return false;
+
+      close(fd);
+
       whandle->handle = bo->handle;
       return true;
    } else if (whandle->type == WINSYS_HANDLE_TYPE_FD) {