[PATCH 49/60] drm/nouveau/gsp: init VMMs with NV0080_CTRL_DMA_SET_PAGE_DIRECTORY
Ben Skeggs
bskeggs at nvidia.com
Tue Apr 29 23:39:17 UTC 2025
The current code using NV90F1_CTRL_CMD_VASPACE_COPY_SERVER_RESERVED_PDES
not only requires changes to support the new page table layout used on
Hopper/Blackwell GPUs, but is also broken in that it always mirrors the
PDEs used for virtual address 0, rather than the area reserved for RM.
Fortunately, it appears that RM never allocates anything within its
reserved area, and the COPY_SERVER_RESERVED_PDES control call primarily
serves to allow RM to locate the root page table when initialising a
channel's instance block.
Instead of fixing the existing code, flag the VASPACE as externally
owned, and use NV0080_CTRL_CMD_DMA_SET_PAGE_DIRECTORY to inform RM of
the root page table in a similar way to NVIDIA's UVM driver.
Signed-off-by: Ben Skeggs <bskeggs at nvidia.com>
---
.../gpu/drm/nouveau/include/nvkm/subdev/mmu.h | 2 -
.../nvkm/subdev/gsp/rm/r535/nvrm/vmm.h | 94 ++++++-------------
.../drm/nouveau/nvkm/subdev/gsp/rm/r535/vmm.c | 41 +++-----
drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c | 1 -
4 files changed, 41 insertions(+), 97 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h
index 1e461d3b53e6..bd0d8c66ccd6 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h
@@ -69,8 +69,6 @@ struct nvkm_vmm {
u64 bar2_pdb;
struct nvkm_gsp_object object;
-
- struct nvkm_vma *rsvd;
} rm;
};
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/vmm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/vmm.h
index f58edf62e4ae..5e33b12a0059 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/vmm.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/vmm.h
@@ -23,68 +23,34 @@ typedef struct
#define NV_VASPACE_ALLOCATION_INDEX_GPU_NEW 0x00 //<! Create new VASpace, by default
-#define GMMU_FMT_MAX_LEVELS 6U
-
-#define NV90F1_CTRL_CMD_VASPACE_COPY_SERVER_RESERVED_PDES (0x90f10106U) /* finn: Evaluated from "(FINN_FERMI_VASPACE_A_VASPACE_INTERFACE_ID << 8) | NV90F1_CTRL_VASPACE_COPY_SERVER_RESERVED_PDES_PARAMS_MESSAGE_ID" */
-typedef struct NV90F1_CTRL_VASPACE_COPY_SERVER_RESERVED_PDES_PARAMS {
- /*!
- * [in] GPU sub-device handle - this API only supports unicast.
- * Pass 0 to use subDeviceId instead.
- */
- NvHandle hSubDevice;
-
- /*!
- * [in] GPU sub-device ID. Ignored if hSubDevice is non-zero.
- */
- NvU32 subDeviceId;
-
- /*!
- * [in] Page size (VA coverage) of the level to reserve.
- * This need not be a leaf (page table) page size - it can be
- * the coverage of an arbitrary level (including root page directory).
- */
- NV_DECLARE_ALIGNED(NvU64 pageSize, 8);
-
- /*!
- * [in] First GPU virtual address of the range to reserve.
- * This must be aligned to pageSize.
- */
- NV_DECLARE_ALIGNED(NvU64 virtAddrLo, 8);
-
- /*!
- * [in] Last GPU virtual address of the range to reserve.
- * This (+1) must be aligned to pageSize.
- */
- NV_DECLARE_ALIGNED(NvU64 virtAddrHi, 8);
-
- /*!
- * [in] Number of PDE levels to copy.
- */
- NvU32 numLevelsToCopy;
-
- /*!
- * [in] Per-level information.
- */
- struct {
- /*!
- * Physical address of this page level instance.
- */
- NV_DECLARE_ALIGNED(NvU64 physAddress, 8);
-
- /*!
- * Size in bytes allocated for this level instance.
- */
- NV_DECLARE_ALIGNED(NvU64 size, 8);
-
- /*!
- * Aperture in which this page level instance resides.
- */
- NvU32 aperture;
-
- /*!
- * Page shift corresponding to the level
- */
- NvU8 pageShift;
- } levels[GMMU_FMT_MAX_LEVELS];
-} NV90F1_CTRL_VASPACE_COPY_SERVER_RESERVED_PDES_PARAMS;
+#define NV_VASPACE_ALLOCATION_FLAGS_IS_EXTERNALLY_OWNED BIT(3)
+
+#define NV0080_CTRL_CMD_DMA_SET_PAGE_DIRECTORY (0x801813U) /* finn: Evaluated from "(FINN_NV01_DEVICE_0_DMA_INTERFACE_ID << 8) | NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_PARAMS_MESSAGE_ID" */
+
+typedef struct NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_PARAMS {
+ NV_DECLARE_ALIGNED(NvU64 physAddress, 8);
+ NvU32 numEntries;
+ NvU32 flags;
+ NvHandle hVASpace;
+ NvU32 chId;
+ NvU32 subDeviceId; // ID+1, 0 for BC
+ NvU32 pasid;
+} NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_PARAMS;
+
+#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_APERTURE 1:0
+#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_APERTURE_VIDMEM (0x00000000U)
+#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_APERTURE_SYSMEM_COH (0x00000001U)
+#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_APERTURE_SYSMEM_NONCOH (0x00000002U)
+#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_PRESERVE_PDES 2:2
+#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_PRESERVE_PDES_FALSE (0x00000000U)
+#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_PRESERVE_PDES_TRUE (0x00000001U)
+#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_ALL_CHANNELS 3:3
+#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_ALL_CHANNELS_FALSE (0x00000000U)
+#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_ALL_CHANNELS_TRUE (0x00000001U)
+#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_IGNORE_CHANNEL_BUSY 4:4
+#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_IGNORE_CHANNEL_BUSY_FALSE (0x00000000U)
+#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_IGNORE_CHANNEL_BUSY_TRUE (0x00000001U)
+#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_EXTEND_VASPACE 5:5
+#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_EXTEND_VASPACE_FALSE (0x00000000U)
+#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_EXTEND_VASPACE_TRUE (0x00000001U)
#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/vmm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/vmm.c
index 9c6f6901ec45..6e1ef05f7f41 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/vmm.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/vmm.c
@@ -21,6 +21,7 @@
*/
#include <subdev/mmu/vmm.h>
+#include <nvhw/drf.h>
#include "nvrm/vmm.h"
static int
@@ -43,47 +44,27 @@ r535_mmu_promote_vmm(struct nvkm_vmm *vmm)
}
args->index = NV_VASPACE_ALLOCATION_INDEX_GPU_NEW;
+ args->flags = NV_VASPACE_ALLOCATION_FLAGS_IS_EXTERNALLY_OWNED;
ret = nvkm_gsp_rm_alloc_wr(&vmm->rm.object, args);
if (ret)
return ret;
{
- NV90F1_CTRL_VASPACE_COPY_SERVER_RESERVED_PDES_PARAMS *ctrl;
+ NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_PARAMS *ctrl;
- mutex_lock(&vmm->mutex.vmm);
- ret = nvkm_vmm_get_locked(vmm, true, false, false, 0x1d, 32, 0x20000000,
- &vmm->rm.rsvd);
- mutex_unlock(&vmm->mutex.vmm);
- if (ret)
- return ret;
-
- ctrl = nvkm_gsp_rm_ctrl_get(&vmm->rm.object,
- NV90F1_CTRL_CMD_VASPACE_COPY_SERVER_RESERVED_PDES,
+ ctrl = nvkm_gsp_rm_ctrl_get(&gsp->internal.device.object,
+ NV0080_CTRL_CMD_DMA_SET_PAGE_DIRECTORY,
sizeof(*ctrl));
if (IS_ERR(ctrl))
return PTR_ERR(ctrl);
- ctrl->pageSize = 0x20000000;
- ctrl->virtAddrLo = vmm->rm.rsvd->addr;
- ctrl->virtAddrHi = vmm->rm.rsvd->addr + vmm->rm.rsvd->size - 1;
- ctrl->numLevelsToCopy = vmm->pd->pde[0]->pde[0] ? 3 : 2;
- ctrl->levels[0].physAddress = vmm->pd->pt[0]->addr;
- ctrl->levels[0].size = 0x20;
- ctrl->levels[0].aperture = 1;
- ctrl->levels[0].pageShift = 0x2f;
- ctrl->levels[1].physAddress = vmm->pd->pde[0]->pt[0]->addr;
- ctrl->levels[1].size = 0x1000;
- ctrl->levels[1].aperture = 1;
- ctrl->levels[1].pageShift = 0x26;
- if (vmm->pd->pde[0]->pde[0]) {
- ctrl->levels[2].physAddress = vmm->pd->pde[0]->pde[0]->pt[0]->addr;
- ctrl->levels[2].size = 0x1000;
- ctrl->levels[2].aperture = 1;
- ctrl->levels[2].pageShift = 0x1d;
- }
-
- ret = nvkm_gsp_rm_ctrl_wr(&vmm->rm.object, ctrl);
+ ctrl->physAddress = vmm->pd->pt[0]->addr;
+ ctrl->numEntries = 1 << vmm->func->page[0].desc->bits;
+ ctrl->flags = NVDEF(NV0080_CTRL_DMA_SET_PAGE_DIRECTORY, FLAGS, APERTURE, VIDMEM);
+ ctrl->hVASpace = vmm->rm.object.handle;
+
+ ret = nvkm_gsp_rm_ctrl_wr(&gsp->internal.device.object, ctrl);
}
return ret;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c
index b6295423c339..158202810db4 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c
@@ -1035,7 +1035,6 @@ nvkm_vmm_dtor(struct nvkm_vmm *vmm)
unsigned int id = vmm->rm.object.handle & 0xffff;
nvkm_gsp_rm_free(&vmm->rm.object);
ida_free(&mmu->rm.vmm_ids, id);
- nvkm_vmm_put(vmm, &vmm->rm.rsvd);
}
if (0)
--
2.49.0
More information about the Nouveau
mailing list