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 <z...@nvidia.com>
---
 .../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

Reply via email to