Creating a vGPU requires allocating a mgmt heap from the FB memory. The size of the mgmt heap that a vGPU requires is from the vGPU type. Expose the FB memory allocation to NVIDIA vGPU VFIO module to allocate the mgmt heap when creating a vGPU. Signed-off-by: Zhi Wang <zhiw@xxxxxxxxxx> --- .../nouveau/include/nvkm/vgpu_mgr/vgpu_mgr.h | 6 +++ drivers/gpu/drm/nouveau/nvkm/vgpu_mgr/vfio.c | 51 +++++++++++++++++++ include/drm/nvkm_vgpu_mgr_vfio.h | 8 +++ 3 files changed, 65 insertions(+) diff --git a/drivers/gpu/drm/nouveau/include/nvkm/vgpu_mgr/vgpu_mgr.h b/drivers/gpu/drm/nouveau/include/nvkm/vgpu_mgr/vgpu_mgr.h index a351e8bfc772..b6e0321a53ad 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/vgpu_mgr/vgpu_mgr.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/vgpu_mgr/vgpu_mgr.h @@ -6,6 +6,12 @@ #define NVIDIA_MAX_VGPUS 2 +struct nvkm_vgpu_mem { + struct nvidia_vgpu_mem base; + struct nvkm_memory *mem; + struct nvkm_vgpu_mgr *vgpu_mgr; +}; + struct nvkm_vgpu_mgr { bool enabled; struct nvkm_device *nvkm_dev; diff --git a/drivers/gpu/drm/nouveau/nvkm/vgpu_mgr/vfio.c b/drivers/gpu/drm/nouveau/nvkm/vgpu_mgr/vfio.c index 44d901a0474d..2aabb2c5f142 100644 --- a/drivers/gpu/drm/nouveau/nvkm/vgpu_mgr/vfio.c +++ b/drivers/gpu/drm/nouveau/nvkm/vgpu_mgr/vfio.c @@ -3,6 +3,7 @@ #include <core/device.h> #include <engine/chid.h> #include <engine/fifo.h> +#include <subdev/bar.h> #include <subdev/fb.h> #include <subdev/gsp.h> @@ -154,6 +155,54 @@ static int alloc_chids(void *handle, int count) return ret; } +static void free_fbmem(struct nvidia_vgpu_mem *base) +{ + struct nvkm_vgpu_mem *mem = + container_of(base, struct nvkm_vgpu_mem, base); + struct nvkm_vgpu_mgr *vgpu_mgr = mem->vgpu_mgr; + struct nvkm_device *device = vgpu_mgr->nvkm_dev; + + nvdev_debug(device, "free fb mem: addr %llx size %llx\n", + base->addr, base->size); + + nvkm_memory_unref(&mem->mem); + kfree(mem); +} + +static struct nvidia_vgpu_mem *alloc_fbmem(void *handle, u64 size, + bool vmmu_aligned) +{ + struct nvkm_device *device = handle; + struct nvkm_vgpu_mgr *vgpu_mgr = &device->vgpu_mgr; + struct nvidia_vgpu_mem *base; + struct nvkm_vgpu_mem *mem; + u32 shift = vmmu_aligned ? ilog2(vgpu_mgr->vmmu_segment_size) : + NVKM_RAM_MM_SHIFT; + int ret; + + mem = kzalloc(sizeof(*mem), GFP_KERNEL); + if (!mem) + return ERR_PTR(-ENOMEM); + + base = &mem->base; + + ret = nvkm_ram_get(device, NVKM_RAM_MM_NORMAL, 0x1, shift, size, + true, true, &mem->mem); + if (ret) { + kfree(mem); + return ERR_PTR(ret); + } + + mem->vgpu_mgr = vgpu_mgr; + base->addr = mem->mem->func->addr(mem->mem); + base->size = mem->mem->func->size(mem->mem); + + nvdev_debug(device, "alloc fb mem: addr %llx size %llx\n", + base->addr, base->size); + + return base; +} + struct nvkm_vgpu_mgr_vfio_ops nvkm_vgpu_mgr_vfio_ops = { .vgpu_mgr_is_enabled = vgpu_mgr_is_enabled, .get_handle = get_handle, @@ -168,6 +217,8 @@ struct nvkm_vgpu_mgr_vfio_ops nvkm_vgpu_mgr_vfio_ops = { .rm_ctrl_done = rm_ctrl_done, .alloc_chids = alloc_chids, .free_chids = free_chids, + .alloc_fbmem = alloc_fbmem, + .free_fbmem = free_fbmem, }; /** diff --git a/include/drm/nvkm_vgpu_mgr_vfio.h b/include/drm/nvkm_vgpu_mgr_vfio.h index 001306fb0b5b..4841e9cf0d40 100644 --- a/include/drm/nvkm_vgpu_mgr_vfio.h +++ b/include/drm/nvkm_vgpu_mgr_vfio.h @@ -16,6 +16,11 @@ struct nvidia_vgpu_gsp_client { void *gsp_device; }; +struct nvidia_vgpu_mem { + u64 addr; + u64 size; +}; + struct nvkm_vgpu_mgr_vfio_ops { bool (*vgpu_mgr_is_enabled)(void *handle); void (*get_handle)(void *handle, @@ -37,6 +42,9 @@ struct nvkm_vgpu_mgr_vfio_ops { void *ctrl); int (*alloc_chids)(void *handle, int count); void (*free_chids)(void *handle, int offset, int count); + struct nvidia_vgpu_mem *(*alloc_fbmem)(void *handle, u64 size, + bool vmmu_aligned); + void (*free_fbmem)(struct nvidia_vgpu_mem *mem); }; struct nvkm_vgpu_mgr_vfio_ops *nvkm_vgpu_mgr_get_vfio_ops(void *handle); -- 2.34.1