To talk to the GSP firmware, the first step is allocating a GSP RM client. NVDIA vGPU VFIO module requires a GSP RM client to obtain system information and create and configure vGPUs. Implement the GSP client allocation and free. Signed-off-by: Zhi Wang <zhiw@xxxxxxxxxx> --- drivers/gpu/drm/nouveau/nvkm/vgpu_mgr/vfio.c | 58 ++++++++++++++++++++ include/drm/nvkm_vgpu_mgr_vfio.h | 10 ++++ 2 files changed, 68 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nvkm/vgpu_mgr/vfio.c b/drivers/gpu/drm/nouveau/nvkm/vgpu_mgr/vfio.c index e98c9e83ee60..a0b4be2e1085 100644 --- a/drivers/gpu/drm/nouveau/nvkm/vgpu_mgr/vfio.c +++ b/drivers/gpu/drm/nouveau/nvkm/vgpu_mgr/vfio.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: MIT */ #include <core/device.h> +#include <subdev/gsp.h> #include <vgpu_mgr/vgpu_mgr.h> #include <drm/nvkm_vgpu_mgr_vfio.h> @@ -43,11 +44,68 @@ static int attach_handle(void *handle, return 0; } +static int alloc_gsp_client(void *handle, + struct nvidia_vgpu_gsp_client *client) +{ + struct nvkm_device *device = handle; + struct nvkm_gsp *gsp = device->gsp; + int ret = -ENOMEM; + + client->gsp_device = kzalloc(sizeof(struct nvkm_gsp_device), + GFP_KERNEL); + if (!client->gsp_device) + return ret; + + client->gsp_client = kzalloc(sizeof(struct nvkm_gsp_client), + GFP_KERNEL); + if (!client->gsp_client) + goto fail_alloc_client; + + ret = nvkm_gsp_client_device_ctor(gsp, client->gsp_client, + client->gsp_device); + if (ret) + goto fail_client_device_ctor; + + return 0; + +fail_client_device_ctor: + kfree(client->gsp_client); + client->gsp_client = NULL; + +fail_alloc_client: + kfree(client->gsp_device); + client->gsp_device = NULL; + + return ret; +} + +static void free_gsp_client(struct nvidia_vgpu_gsp_client *client) +{ + nvkm_gsp_device_dtor(client->gsp_device); + nvkm_gsp_client_dtor(client->gsp_client); + + kfree(client->gsp_device); + client->gsp_device = NULL; + + kfree(client->gsp_client); + client->gsp_client = NULL; +} + +static u32 get_gsp_client_handle(struct nvidia_vgpu_gsp_client *client) +{ + struct nvkm_gsp_client *c = client->gsp_client; + + return c->object.handle; +} + struct nvkm_vgpu_mgr_vfio_ops nvkm_vgpu_mgr_vfio_ops = { .vgpu_mgr_is_enabled = vgpu_mgr_is_enabled, .get_handle = get_handle, .attach_handle = attach_handle, .detach_handle = detach_handle, + .alloc_gsp_client = alloc_gsp_client, + .free_gsp_client = free_gsp_client, + .get_gsp_client_handle = get_gsp_client_handle, }; /** diff --git a/include/drm/nvkm_vgpu_mgr_vfio.h b/include/drm/nvkm_vgpu_mgr_vfio.h index 09ecc3dc454f..79920cc27055 100644 --- a/include/drm/nvkm_vgpu_mgr_vfio.h +++ b/include/drm/nvkm_vgpu_mgr_vfio.h @@ -10,6 +10,12 @@ struct nvidia_vgpu_vfio_handle_data { void *priv; }; +/* A combo of handles of RmClient and RmDevice */ +struct nvidia_vgpu_gsp_client { + void *gsp_client; + void *gsp_device; +}; + struct nvkm_vgpu_mgr_vfio_ops { bool (*vgpu_mgr_is_enabled)(void *handle); void (*get_handle)(void *handle, @@ -17,6 +23,10 @@ struct nvkm_vgpu_mgr_vfio_ops { int (*attach_handle)(void *handle, struct nvidia_vgpu_vfio_handle_data *data); void (*detach_handle)(void *handle); + int (*alloc_gsp_client)(void *handle, + struct nvidia_vgpu_gsp_client *client); + void (*free_gsp_client)(struct nvidia_vgpu_gsp_client *client); + u32 (*get_gsp_client_handle)(struct nvidia_vgpu_gsp_client *client); }; struct nvkm_vgpu_mgr_vfio_ops *nvkm_vgpu_mgr_get_vfio_ops(void *handle); -- 2.34.1