[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 @@ static int virtmagma_command_magma_release_semaphore( 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 @@ int virtmagma_ioctl_magma_command(struct file *filp, void __user *ptr) 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;