diff --git a/pkg/abi/nvgpu/ctrl.go b/pkg/abi/nvgpu/ctrl.go index 6d56811f9..dd39e8891 100644 --- a/pkg/abi/nvgpu/ctrl.go +++ b/pkg/abi/nvgpu/ctrl.go @@ -73,9 +73,51 @@ const ( // From src/common/sdk/nvidia/inc/ctrl/ctrl0000/ctrl0000unix.h: const ( - NV0000_CTRL_CMD_OS_UNIX_EXPORT_OBJECT_TO_FD = 0x3d05 + NV0000_CTRL_CMD_OS_UNIX_EXPORT_OBJECT_TO_FD = 0x3d05 + NV0000_CTRL_CMD_OS_UNIX_IMPORT_OBJECT_FROM_FD = 0x3d06 + NV0000_CTRL_CMD_OS_UNIX_GET_EXPORT_OBJECT_INFO = 0x3d08 + NV0000_OS_UNIX_EXPORT_OBJECT_FD_BUFFER_SIZE = 64 ) +// +marshal +type NV0000_CTRL_OS_UNIX_GET_EXPORT_OBJECT_INFO_PARAMS struct { + FD int32 + DeviceInstance uint32 + MaxObjects uint16 + Pad [2]byte + Metadata [NV0000_OS_UNIX_EXPORT_OBJECT_FD_BUFFER_SIZE]uint8 +} + +// GetFrontendFD implements HasFrontendFD.GetFrontendFD. +func (p *NV0000_CTRL_OS_UNIX_GET_EXPORT_OBJECT_INFO_PARAMS) GetFrontendFD() int32 { + return p.FD +} + +// SetFrontendFD implements HasFrontendFD.SetFrontendFD. +func (p *NV0000_CTRL_OS_UNIX_GET_EXPORT_OBJECT_INFO_PARAMS) SetFrontendFD(fd int32) { + p.FD = fd +} + +// +marshal +type NV0000_CTRL_OS_UNIX_GET_EXPORT_OBJECT_INFO_PARAMS_V545 struct { + FD int32 + DeviceInstance uint32 + GpuInstanceID uint32 + MaxObjects uint16 + Pad [2]byte + Metadata [NV0000_OS_UNIX_EXPORT_OBJECT_FD_BUFFER_SIZE]uint8 +} + +// GetFrontendFD implements HasFrontendFD.GetFrontendFD. +func (p *NV0000_CTRL_OS_UNIX_GET_EXPORT_OBJECT_INFO_PARAMS_V545) GetFrontendFD() int32 { + return p.FD +} + +// SetFrontendFD implements HasFrontendFD.SetFrontendFD. +func (p *NV0000_CTRL_OS_UNIX_GET_EXPORT_OBJECT_INFO_PARAMS_V545) SetFrontendFD(fd int32) { + p.FD = fd +} + // +marshal type NV0000_CTRL_OS_UNIX_EXPORT_OBJECT struct { Type uint32 // enum NV0000_CTRL_OS_UNIX_EXPORT_OBJECT_TYPE @@ -102,6 +144,22 @@ func (p *NV0000_CTRL_OS_UNIX_EXPORT_OBJECT_TO_FD_PARAMS) SetFrontendFD(fd int32) p.FD = fd } +// +marshal +type NV0000_CTRL_OS_UNIX_IMPORT_OBJECT_FROM_FD_PARAMS struct { + FD int32 + Object NV0000_CTRL_OS_UNIX_EXPORT_OBJECT +} + +// GetFrontendFD implements HasFrontendFD.GetFrontendFD. +func (p *NV0000_CTRL_OS_UNIX_IMPORT_OBJECT_FROM_FD_PARAMS) GetFrontendFD() int32 { + return p.FD +} + +// SetFrontendFD implements HasFrontendFD.SetFrontendFD. +func (p *NV0000_CTRL_OS_UNIX_IMPORT_OBJECT_FROM_FD_PARAMS) SetFrontendFD(fd int32) { + p.FD = fd +} + // +marshal type NV0000_CTRL_SYSTEM_GET_BUILD_VERSION_PARAMS struct { SizeOfStrings uint32 @@ -113,6 +171,18 @@ type NV0000_CTRL_SYSTEM_GET_BUILD_VERSION_PARAMS struct { OfficialChangelistNumber uint32 } +// From src/common/sdk/nvidia/inc/ctrl/ctrl0041.h +const ( + NV0041_CTRL_CMD_GET_SURFACE_INFO = 0x410110 +) + +// +marshal +type NV0041_CTRL_GET_SURFACE_INFO_PARAMS struct { + SurfaceInfoListSize uint32 + Pad [4]byte + SurfaceInfoList P64 +} + // From src/common/sdk/nvidia/inc/ctrl/ctrl0080/ctrl0080fb.h: const ( NV0080_CTRL_CMD_FB_GET_CAPS_V2 = 0x801307 diff --git a/pkg/sentry/devices/nvproxy/frontend_unsafe.go b/pkg/sentry/devices/nvproxy/frontend_unsafe.go index 75d5efa4f..af6d330ac 100644 --- a/pkg/sentry/devices/nvproxy/frontend_unsafe.go +++ b/pkg/sentry/devices/nvproxy/frontend_unsafe.go @@ -70,6 +70,42 @@ func ctrlClientSystemGetBuildVersionInvoke(fi *frontendIoctlState, ioctlParams * return n, nil } +func ctrlClientGetSurfaceInfo(fi *frontendIoctlState, ioctlParams *nvgpu.NVOS54Parameters) (uintptr, error) { + var ctrlParams nvgpu.NV0041_CTRL_GET_SURFACE_INFO_PARAMS + if ctrlParams.SizeBytes() != int(ioctlParams.ParamsSize) { + return 0, linuxerr.EINVAL + } + if _, err := ctrlParams.CopyIn(fi.t, addrFromP64(ioctlParams.Params)); err != nil { + return 0, err + } + if ctrlParams.SurfaceInfoListSize == 0 { + // Compare + // src/nvidia/src/kernel/gpu/mem_mgr/mem_ctrl.c:memCtrlCmdGetSurfaceInfoLvm_IMPL(). + return 0, nil + } + surfaceInfoList := make([]byte, int(ctrlParams.SurfaceInfoListSize)*(*nvgpu.NVXXXX_CTRL_XXX_INFO)(nil).SizeBytes()) + if _, err := fi.t.CopyInBytes(addrFromP64(ctrlParams.SurfaceInfoList), surfaceInfoList); err != nil { + return 0, err + } + + origSurfaceInfoList := ctrlParams.SurfaceInfoList + ctrlParams.SurfaceInfoList = p64FromPtr(unsafe.Pointer(&surfaceInfoList[0])) + n, err := rmControlInvoke(fi, ioctlParams, &ctrlParams) + ctrlParams.SurfaceInfoList = origSurfaceInfoList + if err != nil { + return n, err + } + + if _, err := fi.t.CopyOutBytes(addrFromP64(origSurfaceInfoList), surfaceInfoList); err != nil { + return 0, err + } + if _, err := ctrlParams.CopyOut(fi.t, addrFromP64(ioctlParams.Params)); err != nil { + return n, err + } + + return n, nil +} + func ctrlDevGpuGetClasslistInvoke(fi *frontendIoctlState, ioctlParams *nvgpu.NVOS54Parameters, ctrlParams *nvgpu.NV0080_CTRL_GPU_GET_CLASSLIST_PARAMS, classList []uint32) (uintptr, error) { origClassList := ctrlParams.ClassList ctrlParams.ClassList = p64FromPtr(unsafe.Pointer(&classList[0])) diff --git a/pkg/sentry/devices/nvproxy/version.go b/pkg/sentry/devices/nvproxy/version.go index 8523ef0e4..7daf32498 100644 --- a/pkg/sentry/devices/nvproxy/version.go +++ b/pkg/sentry/devices/nvproxy/version.go @@ -279,6 +279,9 @@ func Init() { nvgpu.NVC56F_CTRL_CMD_GET_KMB: rmControlSimple, nvgpu.NV0000_CTRL_CMD_SYSTEM_GET_BUILD_VERSION: ctrlClientSystemGetBuildVersion, nvgpu.NV0000_CTRL_CMD_OS_UNIX_EXPORT_OBJECT_TO_FD: ctrlHasFrontendFD[nvgpu.NV0000_CTRL_OS_UNIX_EXPORT_OBJECT_TO_FD_PARAMS], + nvgpu.NV0000_CTRL_CMD_OS_UNIX_IMPORT_OBJECT_FROM_FD: ctrlHasFrontendFD[nvgpu.NV0000_CTRL_OS_UNIX_IMPORT_OBJECT_FROM_FD_PARAMS], + nvgpu.NV0000_CTRL_CMD_OS_UNIX_GET_EXPORT_OBJECT_INFO: ctrlHasFrontendFD[nvgpu.NV0000_CTRL_OS_UNIX_GET_EXPORT_OBJECT_INFO_PARAMS], + nvgpu.NV0041_CTRL_CMD_GET_SURFACE_INFO: ctrlClientGetSurfaceInfo, nvgpu.NV0080_CTRL_CMD_FIFO_GET_CHANNELLIST: ctrlDevFIFOGetChannelList, nvgpu.NV0080_CTRL_CMD_GPU_GET_CLASSLIST: ctrlDevGpuGetClasslist, nvgpu.NV2080_CTRL_CMD_FIFO_DISABLE_CHANNELS: ctrlSubdevFIFODisableChannels, @@ -340,6 +343,7 @@ func Init() { // 545.23.06 is an intermediate unqualified version from the main branch. v545_23_06 := func() *driverABI { abi := v535_113_01() + abi.controlCmd[nvgpu.NV0000_CTRL_CMD_OS_UNIX_GET_EXPORT_OBJECT_INFO] = ctrlHasFrontendFD[nvgpu.NV0000_CTRL_OS_UNIX_GET_EXPORT_OBJECT_INFO_PARAMS_V545] abi.allocationClass[nvgpu.NV01_MEMORY_SYSTEM] = rmAllocSimple[nvgpu.NV_MEMORY_ALLOCATION_PARAMS_V545] abi.allocationClass[nvgpu.NV01_MEMORY_LOCAL_USER] = rmAllocSimple[nvgpu.NV_MEMORY_ALLOCATION_PARAMS_V545] abi.allocationClass[nvgpu.NV50_MEMORY_VIRTUAL] = rmAllocSimple[nvgpu.NV_MEMORY_ALLOCATION_PARAMS_V545]