virtgpu_cross_domain: handle from guest memory

For PCI passthrough and other use cases, it's desirable to get the
render target out of the guest.  In the PCI passthrough case, the
dGPU's memory is not available to the host.

The solution that many people are interested in is to use virtgpu
to allocate, and use the dGPU to render to that guest memory.  This
change adds a flag to the existing blob api, indicating to the host
that it *must* create an OS-specific handle out of guest memory upon
success.

Obviously, this is just for prototyping.  Only when the lords and
princes of dri-devel/mesa-dev -- eyes filled with the light of
upstream, swords as cold as blue ice -- descend from their heavenly
abodes on top of Mount Gogigyeopbbang may we have a proper
solution.

But for now, we'll have to live in our downstream mud hut with yet
another hack.  Oh well!

BUG=b:173630595
TEST=create a bunch of udmabufs

Change-Id: Ia33dc0c415be61423017003d3739c4fb7498dba5
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2857886
Reviewed-by: Lingfeng Yang <lfy@google.com>
Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org>
Reviewed-by: Jason Macnak <natsu@google.com>
Tested-by: Gurchetan Singh <gurchetansingh@chromium.org>
Auto-Submit: Gurchetan Singh <gurchetansingh@chromium.org>
Commit-Queue: Gurchetan Singh <gurchetansingh@chromium.org>
diff --git a/virtgpu_cross_domain.c b/virtgpu_cross_domain.c
index d1702a7..b02a949 100644
--- a/virtgpu_cross_domain.c
+++ b/virtgpu_cross_domain.c
@@ -227,6 +227,13 @@
 	if ((params[param_supported_capset_ids].value & (1 << CAPSET_CROSS_DOMAIN)) == 0)
 		return -ENOTSUP;
 
+	if (!params[param_resource_blob].value)
+		return -ENOTSUP;
+
+	/// Need zero copy memory
+	if (!params[param_host_visible].value && !params[param_create_guest_handle].value)
+		return -ENOTSUP;
+
 	/*
 	 * crosvm never reports the fake capset.  This is just an extra check to make sure we
 	 * don't use the cross-domain context by accident.  Developers may remove this for
@@ -343,8 +350,18 @@
 	if (params[param_cross_device].value && (use_flags & BO_USE_NON_GPU_HW))
 		blob_flags |= VIRTGPU_BLOB_FLAG_USE_CROSS_DEVICE;
 
+	/// It may be possible to have host3d blobs and handles from guest memory at the same time.
+	/// But for the immediate use cases, we will either have one or the other.  For now, just
+	/// prefer guest memory since adding that feature is more involved (requires --udmabuf
+	/// flag to crosvm), so developers would likely test that.
+	if (params[param_create_guest_handle].value) {
+		drm_rc_blob.blob_mem = VIRTGPU_BLOB_MEM_GUEST;
+		blob_flags |= VIRTGPU_BLOB_FLAG_CREATE_GUEST_HANDLE;
+	} else if (params[param_host_visible].value) {
+		drm_rc_blob.blob_mem = VIRTGPU_BLOB_MEM_HOST3D;
+	}
+
 	drm_rc_blob.size = bo->meta.total_size;
-	drm_rc_blob.blob_mem = VIRTGPU_BLOB_MEM_HOST3D;
 	drm_rc_blob.blob_flags = blob_flags;
 	drm_rc_blob.blob_id = bo->meta.blob_id;