[virtio_magma] Add semaphore import and export
Partial implementation that doesn't satisfy Vulkan
requirements for external semaphore, but is still
useful for benchmarking. Tracking completion with
fxbug.dev/67565.
Change-Id: I7fbbfded3c18ec94ce413ea435e4e8468099275e
diff --git a/drivers/virtio/virtio_magma.c b/drivers/virtio/virtio_magma.c
index e8f4f45..7a9cfa4 100644
--- a/drivers/virtio/virtio_magma.c
+++ b/drivers/virtio/virtio_magma.c
@@ -1100,6 +1100,89 @@
return 0;
}
+static int virtmagma_command_magma_import_semaphore(
+ struct virtmagma_instance *instance,
+ struct virtmagma_virtio_command *command)
+{
+ int ret;
+ struct virtmagma_connection *connection;
+ struct virtmagma_connection_object *object;
+ struct virtio_magma_import_semaphore_ctrl *request =
+ command->request_ptr;
+ struct virtio_magma_import_semaphore_resp *response =
+ command->response_ptr;
+
+ if (!COMMAND_OK(command, request, response))
+ return -EINVAL;
+
+ connection = get_connection(instance, request->connection);
+ if (!connection)
+ return -EINVAL;
+
+ ret = vq_out_send_sync(instance->vi, command);
+ if (ret)
+ return ret;
+
+ ret = virtmagma_check_expected_response_type(request, response);
+ if (ret)
+ return ret;
+
+ /* pass on magma errors without creating a semaphore object */
+ if (response->result_return) {
+ pr_warn("virtmagma: magma_import_semaphore returned %d",
+ (int32_t)response->result_return);
+ return 0; /* the ioctl is still successful */
+ }
+
+ object = kzalloc(sizeof(*object), GFP_KERNEL);
+ if (!object)
+ return -ENOMEM;
+
+ object->parent_connection = connection;
+ object->host_value = response->semaphore_out;
+ object->type = MAGMA_SEMAPHORE;
+
+ hash_add(connection->objects, &object->node, object->host_value);
+
+ return 0;
+}
+
+static int virtmagma_command_magma_export_semaphore(
+ struct virtmagma_instance *instance,
+ struct virtmagma_virtio_command *command)
+{
+ int ret;
+ struct virtmagma_connection *connection;
+ struct virtmagma_connection_object *object;
+ struct virtio_magma_export_semaphore_ctrl *request =
+ command->request_ptr;
+ struct virtio_magma_export_semaphore_resp *response =
+ command->response_ptr;
+ struct virtmagma_semaphore_fd_priv *priv;
+
+ if (!COMMAND_OK(command, request, response))
+ return -EINVAL;
+
+ connection = get_connection(instance, request->connection);
+ if (!connection)
+ return -EINVAL;
+
+ ret = vq_out_send_sync(instance->vi, command);
+ if (ret)
+ return ret;
+
+ ret = virtmagma_check_expected_response_type(request, response);
+ if (ret)
+ return ret;
+
+ /* TODO(fxbug.dev/67565):
+ * Create an anon file here that points to the zircon handle, return
+ * the fd to userspace. For now we return the zircon handle itself.
+ */
+
+ return 0;
+}
+
static int
virtmagma_command_magma_poll(struct virtmagma_instance *instance,
struct virtmagma_virtio_command *command)
@@ -1441,6 +1524,14 @@
ret = virtmagma_command_magma_release_semaphore(instance,
&command);
break;
+ case VIRTIO_MAGMA_CMD_IMPORT_SEMAPHORE:
+ ret = virtmagma_command_magma_import_semaphore(instance,
+ &command);
+ break;
+ case VIRTIO_MAGMA_CMD_EXPORT_SEMAPHORE:
+ ret = virtmagma_command_magma_export_semaphore(instance,
+ &command);
+ break;
case VIRTIO_MAGMA_CMD_POLL:
ret = virtmagma_command_magma_poll(instance, &command);
break;