diff --git a/kernel-open/nvidia/nv-pci.c b/kernel-open/nvidia/nv-pci.c index 996d5c0e50..d204b99960 100644 --- a/kernel-open/nvidia/nv-pci.c +++ b/kernel-open/nvidia/nv-pci.c @@ -2672,7 +2672,22 @@ NvBool nv_pci_is_valid_topology_for_direct_pci( if (!nv->coherent) { - return NV_FALSE; + nvidia_stack_t *sp = NULL; + NvU32 allow_p2p = 0; + + // Experimental: NVreg_AllowP2PWithoutCoherentMapping=1 bypasses the gate. + if (nv_kmem_cache_alloc_stack(&sp) != 0) + { + return NV_FALSE; + } + (void) rm_read_registry_dword(sp, nv, + NV_REG_ALLOW_P2P_WITHOUT_COHERENT_MAPPING, &allow_p2p); + nv_kmem_cache_free_stack(sp); + + if (!allow_p2p) + { + return NV_FALSE; + } } return (pdev0->dev.iommu_group == pdev1->dev.iommu_group); diff --git a/kernel-open/nvidia/nv-reg.h b/kernel-open/nvidia/nv-reg.h index bb62d7cd29..3968927d92 100644 --- a/kernel-open/nvidia/nv-reg.h +++ b/kernel-open/nvidia/nv-reg.h @@ -329,6 +329,37 @@ #define __NV_ENABLE_PCIE_GEN3 EnablePCIeGen3 #define NV_REG_ENABLE_PCIE_GEN3 NV_REG_STRING(__NV_ENABLE_PCIE_GEN3) +/* + * Option: AllowP2PWithoutCoherentMapping + * + * Description: + * + * DMA-BUF and GPUDirect RDMA paths are gated behind + * PDB_PROP_GPU_COHERENT_CPU_MAPPING, which is set on platforms with + * NVLink/C2C interconnects (Grace Superchip) or zero-framebuffer SoCs + * (GB10B/Thor). On all other hardware the paths return + * NV_ERR_NOT_SUPPORTED. + * + * When this option is set to a non-zero value, the coherent-mapping + * check is bypassed, permitting DMA-BUF export of CUDA memory to + * other kernel drivers (e.g. mlx5_ib) on hardware NVIDIA does not + * officially validate for this path. The operator is responsible for + * the P2P feasibility constraints: IOMMU in 1:1 / passthrough / + * disabled mode, GPU and importing device behind the same PCIe root + * complex, no ACS isolation between them. + * + * This is completely unsupported! + * + * Possible Values: + * + * 0: enforce coherent-mapping gate (default) + * 1: bypass coherent-mapping gate + */ + +#define __NV_ALLOW_P2P_WITHOUT_COHERENT_MAPPING AllowP2PWithoutCoherentMapping +#define NV_REG_ALLOW_P2P_WITHOUT_COHERENT_MAPPING \ + NV_REG_STRING(__NV_ALLOW_P2P_WITHOUT_COHERENT_MAPPING) + /* * Option: MemoryPoolSize * @@ -1043,6 +1074,7 @@ NV_DEFINE_REG_ENTRY(__NV_DEVICE_FILE_MODE, 0666); NV_DEFINE_REG_ENTRY(__NV_INITIALIZE_SYSTEM_MEMORY_ALLOCATIONS, 1); NV_DEFINE_REG_ENTRY(__NV_USE_PAGE_ATTRIBUTE_TABLE, ~0); NV_DEFINE_REG_ENTRY(__NV_ENABLE_PCIE_GEN3, 0); +NV_DEFINE_REG_ENTRY(__NV_ALLOW_P2P_WITHOUT_COHERENT_MAPPING, 0); NV_DEFINE_REG_ENTRY(__NV_ENABLE_MSI, 1); NV_DEFINE_REG_ENTRY(__NV_ENABLE_STREAM_MEMOPS, 0); NV_DEFINE_REG_ENTRY(__NV_RM_PROFILING_ADMIN_ONLY_PARAMETER, 1); @@ -1111,6 +1143,7 @@ nv_parm_t nv_parms[] = { NV_DEFINE_PARAMS_TABLE_ENTRY(__NV_USE_PAGE_ATTRIBUTE_TABLE), NV_DEFINE_PARAMS_TABLE_ENTRY(__NV_ENABLE_MSI), NV_DEFINE_PARAMS_TABLE_ENTRY(__NV_ENABLE_PCIE_GEN3), + NV_DEFINE_PARAMS_TABLE_ENTRY(__NV_ALLOW_P2P_WITHOUT_COHERENT_MAPPING), NV_DEFINE_PARAMS_TABLE_ENTRY(__NV_MEMORY_POOL_SIZE), NV_DEFINE_PARAMS_TABLE_ENTRY(__NV_KMALLOC_HEAP_MAX_SIZE), NV_DEFINE_PARAMS_TABLE_ENTRY(__NV_VMALLOC_HEAP_MAX_SIZE), diff --git a/src/nvidia/arch/nvalloc/unix/include/nv-reg.h b/src/nvidia/arch/nvalloc/unix/include/nv-reg.h index bb62d7cd29..d941c561cc 100644 --- a/src/nvidia/arch/nvalloc/unix/include/nv-reg.h +++ b/src/nvidia/arch/nvalloc/unix/include/nv-reg.h @@ -329,6 +329,11 @@ #define __NV_ENABLE_PCIE_GEN3 EnablePCIeGen3 #define NV_REG_ENABLE_PCIE_GEN3 NV_REG_STRING(__NV_ENABLE_PCIE_GEN3) +/* Option: AllowP2PWithoutCoherentMapping — see kernel-open/nvidia/nv-reg.h. */ +#define __NV_ALLOW_P2P_WITHOUT_COHERENT_MAPPING AllowP2PWithoutCoherentMapping +#define NV_REG_ALLOW_P2P_WITHOUT_COHERENT_MAPPING \ + NV_REG_STRING(__NV_ALLOW_P2P_WITHOUT_COHERENT_MAPPING) + /* * Option: MemoryPoolSize * @@ -1043,6 +1048,7 @@ NV_DEFINE_REG_ENTRY(__NV_DEVICE_FILE_MODE, 0666); NV_DEFINE_REG_ENTRY(__NV_INITIALIZE_SYSTEM_MEMORY_ALLOCATIONS, 1); NV_DEFINE_REG_ENTRY(__NV_USE_PAGE_ATTRIBUTE_TABLE, ~0); NV_DEFINE_REG_ENTRY(__NV_ENABLE_PCIE_GEN3, 0); +NV_DEFINE_REG_ENTRY(__NV_ALLOW_P2P_WITHOUT_COHERENT_MAPPING, 0); NV_DEFINE_REG_ENTRY(__NV_ENABLE_MSI, 1); NV_DEFINE_REG_ENTRY(__NV_ENABLE_STREAM_MEMOPS, 0); NV_DEFINE_REG_ENTRY(__NV_RM_PROFILING_ADMIN_ONLY_PARAMETER, 1); @@ -1111,6 +1117,7 @@ nv_parm_t nv_parms[] = { NV_DEFINE_PARAMS_TABLE_ENTRY(__NV_USE_PAGE_ATTRIBUTE_TABLE), NV_DEFINE_PARAMS_TABLE_ENTRY(__NV_ENABLE_MSI), NV_DEFINE_PARAMS_TABLE_ENTRY(__NV_ENABLE_PCIE_GEN3), + NV_DEFINE_PARAMS_TABLE_ENTRY(__NV_ALLOW_P2P_WITHOUT_COHERENT_MAPPING), NV_DEFINE_PARAMS_TABLE_ENTRY(__NV_MEMORY_POOL_SIZE), NV_DEFINE_PARAMS_TABLE_ENTRY(__NV_KMALLOC_HEAP_MAX_SIZE), NV_DEFINE_PARAMS_TABLE_ENTRY(__NV_VMALLOC_HEAP_MAX_SIZE), diff --git a/src/nvidia/arch/nvalloc/unix/src/osapi.c b/src/nvidia/arch/nvalloc/unix/src/osapi.c index 4b61bd5d40..f45858004b 100644 --- a/src/nvidia/arch/nvalloc/unix/src/osapi.c +++ b/src/nvidia/arch/nvalloc/unix/src/osapi.c @@ -1452,8 +1452,13 @@ RmDmabufGetClientAndDevice( if (mappingType == NV_DMABUF_EXPORT_MAPPING_TYPE_FORCE_PCIE) { KernelBus *pKernelBus = GPU_GET_KERNEL_BUS(pGpu); + NvU32 allow_p2p = 0; - if (!pGpu->getProperty(pGpu, PDB_PROP_GPU_COHERENT_CPU_MAPPING) || + // Experimental: NVreg_AllowP2PWithoutCoherentMapping=1 bypasses the gate. + (void) osReadRegistryDword(pGpu, + NV_REG_STR_ALLOW_P2P_WITHOUT_COHERENT_MAPPING, &allow_p2p); + if ((!allow_p2p && + !pGpu->getProperty(pGpu, PDB_PROP_GPU_COHERENT_CPU_MAPPING)) || pKernelBus->bBar1Disabled || IS_MIG_ENABLED(pGpu)) { diff --git a/src/nvidia/interface/nvrm_registry.h b/src/nvidia/interface/nvrm_registry.h index 3f23c642da..a86bbd51de 100644 --- a/src/nvidia/interface/nvrm_registry.h +++ b/src/nvidia/interface/nvrm_registry.h @@ -3053,6 +3053,10 @@ #define NV_REG_STR_RM_GPUDIRECT_RDMA_FORCE_SPA_NO (0x00000000) #define NV_REG_STR_RM_GPUDIRECT_RDMA_FORCE_SPA_DEFAULT NV_REG_STR_RM_GPUDIRECT_RDMA_FORCE_SPA_NO +// Type DWORD (Boolean) +// Experimental opt-in to bypass coherent-mapping gate; see kernel-open/nvidia/nv-reg.h. +#define NV_REG_STR_ALLOW_P2P_WITHOUT_COHERENT_MAPPING "AllowP2PWithoutCoherentMapping" + // Type DWORD (Boolean) // Disable the check for FSP's fuse error detection status during boot. // By default, the check would be enabled and we would bail out during boot on error. diff --git a/src/nvidia/src/kernel/gpu/bus/kern_bus.c b/src/nvidia/src/kernel/gpu/bus/kern_bus.c index 3eb21ff079..43d2be415a 100644 --- a/src/nvidia/src/kernel/gpu/bus/kern_bus.c +++ b/src/nvidia/src/kernel/gpu/bus/kern_bus.c @@ -1304,10 +1304,16 @@ kbusGetGpuFbPhysAddressForRdma_IMPL NvU64 *pPhysAddr ) { - if((bForcePcie) && - (!pGpu->getProperty(pGpu, PDB_PROP_GPU_COHERENT_CPU_MAPPING))) + if (bForcePcie && + !pGpu->getProperty(pGpu, PDB_PROP_GPU_COHERENT_CPU_MAPPING)) { - return NV_ERR_NOT_SUPPORTED; + NvU32 allow_p2p = 0; + + // Experimental: NVreg_AllowP2PWithoutCoherentMapping=1 bypasses the gate. + (void) osReadRegistryDword(pGpu, + NV_REG_STR_ALLOW_P2P_WITHOUT_COHERENT_MAPPING, &allow_p2p); + if (!allow_p2p) + return NV_ERR_NOT_SUPPORTED; } //