diff --git a/pkg/abi/nvgpu/classes.go b/pkg/abi/nvgpu/classes.go index 6066deb96..16490761c 100644 --- a/pkg/abi/nvgpu/classes.go +++ b/pkg/abi/nvgpu/classes.go @@ -41,6 +41,7 @@ const ( NV01_MEMORY_SYSTEM_OS_DESCRIPTOR = 0x00000071 NV01_EVENT_OS_EVENT = 0x00000079 NV01_DEVICE_0 = 0x00000080 + RM_USER_SHARED_DATA = 0x000000de NV_MEMORY_FABRIC = 0x000000f8 NV_MEMORY_MULTICAST_FABRIC = 0x000000fd NV20_SUBDEVICE_0 = 0x00002080 @@ -314,6 +315,22 @@ type NV_HOPPER_USERMODE_A_PARAMS struct { Priv uint8 } +// NV00DE_ALLOC_PARAMETERS is the alloc param type for RM_USER_SHARED_DATA, +// from src/common/sdk/nvidia/inc/class/cl00de.h. +// +// +marshal +type NV00DE_ALLOC_PARAMETERS struct { + Reserved uint32 +} + +// NV00DE_ALLOC_PARAMETERS_V545 is the updated version of +// NV00DE_ALLOC_PARAMETERS since 545.23.06. +// +// +marshal +type NV00DE_ALLOC_PARAMETERS_V545 struct { + PolledDataMask uint64 +} + // +marshal type nv00f8Map struct { offset uint64 diff --git a/pkg/abi/nvgpu/ctrl.go b/pkg/abi/nvgpu/ctrl.go index f3bcc5026..836b7b1af 100644 --- a/pkg/abi/nvgpu/ctrl.go +++ b/pkg/abi/nvgpu/ctrl.go @@ -29,12 +29,28 @@ const ( // From src/common/sdk/nvidia/inc/ctrl/ctrlxxxx.h: -// +marshal +// NVXXXX_CTRL_XXX_INFO is typedef-ed as the following in the driver: +// - NV2080_CTRL_GR_INFO +// - NV2080_CTRL_BIOS_INFO +// - NV0041_CTRL_SURFACE_INFO +// +// +marshal slice:CtrlXxxInfoSlice type NVXXXX_CTRL_XXX_INFO struct { Index uint32 Data uint32 } +// CtrlXxxInfoSize is sizeof(NVXXXX_CTRL_XXX_INFO). +var CtrlXxxInfoSize = uint32((*NVXXXX_CTRL_XXX_INFO)(nil).SizeBytes()) + +// HasCtrlInfoList is a type constraint for parameter structs containing a list +// of NVXXXX_CTRL_XXX_INFO and are simple otherwise. +type HasCtrlInfoList interface { + ListSize() uint32 + SetCtrlInfoList(ptr P64) + CtrlInfoList() P64 +} + // From src/common/sdk/nvidia/inc/ctrl/ctrl0000/ctrl0000client.h: const ( NV0000_CTRL_CMD_CLIENT_GET_ADDR_SPACE_TYPE = 0xd01 @@ -183,6 +199,21 @@ type NV0041_CTRL_GET_SURFACE_INFO_PARAMS struct { SurfaceInfoList P64 } +// ListSize implements HasCtrlInfoList.ListSize. +func (p *NV0041_CTRL_GET_SURFACE_INFO_PARAMS) ListSize() uint32 { + return p.SurfaceInfoListSize +} + +// SetCtrlInfoList implements HasCtrlInfoList.SetCtrlInfoList. +func (p *NV0041_CTRL_GET_SURFACE_INFO_PARAMS) SetCtrlInfoList(ptr P64) { + p.SurfaceInfoList = ptr +} + +// CtrlInfoList implements HasCtrlInfoList.CtrlInfoList. +func (p *NV0041_CTRL_GET_SURFACE_INFO_PARAMS) CtrlInfoList() P64 { + return p.SurfaceInfoList +} + // From src/common/sdk/nvidia/inc/ctrl/ctrl0080/ctrl0080fb.h: const ( NV0080_CTRL_CMD_FB_GET_CAPS_V2 = 0x801307 @@ -251,6 +282,33 @@ type NV00FD_CTRL_ATTACH_GPU_PARAMS struct { DevDescriptor uint64 } +// From src/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080bios.h: +const ( + NV2080_CTRL_CMD_BIOS_GET_INFO = 0x20800802 +) + +// +marshal +type NV2080_CTRL_BIOS_GET_INFO_PARAMS struct { + BiosInfoListSize uint32 + Pad [4]byte + BiosInfoList P64 +} + +// ListSize implements HasCtrlInfoList.ListSize. +func (p *NV2080_CTRL_BIOS_GET_INFO_PARAMS) ListSize() uint32 { + return p.BiosInfoListSize +} + +// SetCtrlInfoList implements HasCtrlInfoList.SetCtrlInfoList. +func (p *NV2080_CTRL_BIOS_GET_INFO_PARAMS) SetCtrlInfoList(ptr P64) { + p.BiosInfoList = ptr +} + +// CtrlInfoList implements HasCtrlInfoList.CtrlInfoList. +func (p *NV2080_CTRL_BIOS_GET_INFO_PARAMS) CtrlInfoList() P64 { + return p.BiosInfoList +} + // From src/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080bus.h: const ( NV2080_CTRL_CMD_BUS_GET_PCI_INFO = 0x20801801 @@ -265,6 +323,11 @@ const ( NV2080_CTRL_CMD_CE_GET_ALL_CAPS = 0x20802a0a ) +// From src/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080event.h: +const ( + NV2080_CTRL_CMD_EVENT_SET_NOTIFICATION = 0x20800301 +) + // From src/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080fb.h: const ( NV2080_CTRL_CMD_FB_GET_INFO_V2 = 0x20801303 @@ -303,9 +366,11 @@ const ( NV2080_CTRL_CMD_GPU_GET_SIMULATION_INFO = 0x20800119 NV2080_CTRL_CMD_GPU_QUERY_ECC_STATUS = 0x2080012f NV2080_CTRL_CMD_GPU_QUERY_COMPUTE_MODE_RULES = 0x20800131 + NV2080_CTRL_CMD_GPU_GET_OEM_BOARD_INFO = 0x2080013f NV2080_CTRL_CMD_GPU_ACQUIRE_COMPUTE_MODE_RESERVATION = 0x20800145 // undocumented; paramSize == 0 NV2080_CTRL_CMD_GPU_RELEASE_COMPUTE_MODE_RESERVATION = 0x20800146 // undocumented; paramSize == 0 NV2080_CTRL_CMD_GPU_GET_GID_INFO = 0x2080014a + NV2080_CTRL_CMD_GPU_GET_INFOROM_IMAGE_VERSION = 0x20800156 NV2080_CTRL_CMD_GPU_GET_ENGINES_V2 = 0x20800170 NV2080_CTRL_CMD_GPU_GET_ACTIVE_PARTITION_IDS = 0x2080018b NV2080_CTRL_CMD_GPU_GET_PIDS = 0x2080018d @@ -344,6 +409,21 @@ type NV2080_CTRL_GR_GET_INFO_PARAMS struct { GRRouteInfo NV0080_CTRL_GR_ROUTE_INFO } +// ListSize implements HasCtrlInfoList.ListSize. +func (p *NV2080_CTRL_GR_GET_INFO_PARAMS) ListSize() uint32 { + return p.GRInfoListSize +} + +// SetCtrlInfoList implements HasCtrlInfoList.SetCtrlInfoList. +func (p *NV2080_CTRL_GR_GET_INFO_PARAMS) SetCtrlInfoList(ptr P64) { + p.GRInfoList = ptr +} + +// CtrlInfoList implements HasCtrlInfoList.CtrlInfoList. +func (p *NV2080_CTRL_GR_GET_INFO_PARAMS) CtrlInfoList() P64 { + return p.GRInfoList +} + // From src/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080mc.h: const ( NV2080_CTRL_CMD_MC_GET_ARCH_INFO = 0x20801701 diff --git a/pkg/sentry/devices/nvproxy/frontend.go b/pkg/sentry/devices/nvproxy/frontend.go index 4174e7333..ac321ff7e 100644 --- a/pkg/sentry/devices/nvproxy/frontend.go +++ b/pkg/sentry/devices/nvproxy/frontend.go @@ -573,7 +573,23 @@ func ctrlMemoryMulticastFabricAttachGPU(fi *frontendIoctlState, ioctlParams *nvg return 0, err } - return ctrlMemoryMulticastFabricAttachGPUInvoke(fi, ioctlParams, &ctrlParams) + origDevDescriptor := ctrlParams.DevDescriptor + devDescriptor, _ := fi.t.FDTable().Get(int32(origDevDescriptor)) + if devDescriptor == nil { + return 0, linuxerr.EINVAL + } + defer devDescriptor.DecRef(fi.ctx) + devDesc, ok := devDescriptor.Impl().(*frontendFD) + if !ok { + return 0, linuxerr.EINVAL + } + + ctrlParams.DevDescriptor = uint64(devDesc.hostFD) + n, err := rmControlInvoke(fi, ioctlParams, &ctrlParams) + ctrlParams.DevDescriptor = origDevDescriptor + // Note that ctrlParams.CopyOut() is not called here because + // NV00FD_CTRL_ATTACH_GPU_PARAMS is an input-only parameter. + return n, err } func ctrlClientSystemGetBuildVersion(fi *frontendIoctlState, ioctlParams *nvgpu.NVOS54Parameters) (uintptr, error) { diff --git a/pkg/sentry/devices/nvproxy/frontend_unsafe.go b/pkg/sentry/devices/nvproxy/frontend_unsafe.go index 3dfaf4834..0d215c0bf 100644 --- a/pkg/sentry/devices/nvproxy/frontend_unsafe.go +++ b/pkg/sentry/devices/nvproxy/frontend_unsafe.go @@ -47,23 +47,6 @@ func rmControlInvoke[Params any](fi *frontendIoctlState, ioctlParams *nvgpu.NVOS return n, nil } -func ctrlMemoryMulticastFabricAttachGPUInvoke(fi *frontendIoctlState, ioctlParams *nvgpu.NVOS54Parameters, ctrlParams *nvgpu.NV00FD_CTRL_ATTACH_GPU_PARAMS) (uintptr, error) { - origDevDescriptor := ctrlParams.DevDescriptor - devDescriptor, _ := fi.t.FDTable().Get(int32(origDevDescriptor)) - if devDescriptor == nil { - return 0, linuxerr.EINVAL - } - defer devDescriptor.DecRef(fi.ctx) - devDesc, ok := devDescriptor.Impl().(*frontendFD) - if !ok { - return 0, linuxerr.EINVAL - } - ctrlParams.DevDescriptor = uint64(devDesc.hostFD) - n, err := rmControlInvoke(fi, ioctlParams, ctrlParams) - ctrlParams.DevDescriptor = origDevDescriptor - return n, err -} - func ctrlClientSystemGetBuildVersionInvoke(fi *frontendIoctlState, ioctlParams *nvgpu.NVOS54Parameters, ctrlParams *nvgpu.NV0000_CTRL_SYSTEM_GET_BUILD_VERSION_PARAMS, driverVersionBuf, versionBuf, titleBuf *byte) (uintptr, error) { // *Buf arguments don't need runtime.KeepAlive() since our caller // ctrlClientSystemGetBuildVersion() copies them out, keeping them alive @@ -87,34 +70,40 @@ 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 +func ctrlIoctlHasInfoList[Params any, PtrParams hasCtrlInfoListPtr[Params]](fi *frontendIoctlState, ioctlParams *nvgpu.NVOS54Parameters) (uintptr, error) { + var ctrlParamsValue Params + ctrlParams := PtrParams(&ctrlParamsValue) + 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 + var infoList []byte + if listSize := ctrlParams.ListSize(); listSize > 0 { + infoList = make([]byte, listSize*nvgpu.CtrlXxxInfoSize) + if _, err := fi.t.CopyInBytes(addrFromP64(ctrlParams.CtrlInfoList()), infoList); err != nil { + return 0, err + } } - origSurfaceInfoList := ctrlParams.SurfaceInfoList - ctrlParams.SurfaceInfoList = p64FromPtr(unsafe.Pointer(&surfaceInfoList[0])) - n, err := rmControlInvoke(fi, ioctlParams, &ctrlParams) - ctrlParams.SurfaceInfoList = origSurfaceInfoList + origInfoList := ctrlParams.CtrlInfoList() + if infoList == nil { + ctrlParams.SetCtrlInfoList(p64FromPtr(unsafe.Pointer(nil))) + } else { + ctrlParams.SetCtrlInfoList(p64FromPtr(unsafe.Pointer(&infoList[0]))) + } + n, err := rmControlInvoke(fi, ioctlParams, ctrlParams) + ctrlParams.SetCtrlInfoList(origInfoList) if err != nil { return n, err } - if _, err := fi.t.CopyOutBytes(addrFromP64(origSurfaceInfoList), surfaceInfoList); err != nil { - return 0, err + if infoList != nil { + if _, err := fi.t.CopyOutBytes(addrFromP64(origInfoList), infoList); err != nil { + return n, err + } } if _, err := ctrlParams.CopyOut(fi.t, addrFromP64(ioctlParams.Params)); err != nil { return n, err @@ -186,42 +175,6 @@ func ctrlDevFIFOGetChannelList(fi *frontendIoctlState, ioctlParams *nvgpu.NVOS54 return n, nil } -func ctrlSubdevGRGetInfo(fi *frontendIoctlState, ioctlParams *nvgpu.NVOS54Parameters) (uintptr, error) { - var ctrlParams nvgpu.NV2080_CTRL_GR_GET_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.GRInfoListSize == 0 { - // Compare - // src/nvidia/src/kernel/gpu/gr/kernel_graphics.c:_kgraphicsCtrlCmdGrGetInfoV2(). - return 0, linuxerr.EINVAL - } - infoList := make([]byte, int(ctrlParams.GRInfoListSize)*(*nvgpu.NVXXXX_CTRL_XXX_INFO)(nil).SizeBytes()) - if _, err := fi.t.CopyInBytes(addrFromP64(ctrlParams.GRInfoList), infoList); err != nil { - return 0, err - } - - origGRInfoList := ctrlParams.GRInfoList - ctrlParams.GRInfoList = p64FromPtr(unsafe.Pointer(&infoList[0])) - n, err := rmControlInvoke(fi, ioctlParams, &ctrlParams) - ctrlParams.GRInfoList = origGRInfoList - if err != nil { - return n, err - } - - if _, err := fi.t.CopyOutBytes(addrFromP64(origGRInfoList), infoList); err != nil { - return n, err - } - if _, err := ctrlParams.CopyOut(fi.t, addrFromP64(ioctlParams.Params)); err != nil { - return n, err - } - - return n, nil -} - func rmAllocInvoke[Params any](fi *frontendIoctlState, ioctlParams *nvgpu.NVOS64Parameters, allocParams *Params, isNVOS64 bool, addObjLocked func(fi *frontendIoctlState, ioctlParams *nvgpu.NVOS64Parameters, rightsRequested nvgpu.RS_ACCESS_MASK, allocParams *Params)) (uintptr, error) { defer runtime.KeepAlive(allocParams) // since we convert to non-pointer-typed P64 diff --git a/pkg/sentry/devices/nvproxy/nvproxy.go b/pkg/sentry/devices/nvproxy/nvproxy.go index fa5066e8d..511f7bbf8 100644 --- a/pkg/sentry/devices/nvproxy/nvproxy.go +++ b/pkg/sentry/devices/nvproxy/nvproxy.go @@ -101,6 +101,11 @@ type hasFrontendFDPtr[T any] interface { nvgpu.HasFrontendFD } +type hasCtrlInfoListPtr[T any] interface { + marshalPtr[T] + nvgpu.HasCtrlInfoList +} + // NvidiaDeviceFD is an interface that should be implemented by all // vfs.FileDescriptionImpl of Nvidia devices. type NvidiaDeviceFD interface { diff --git a/pkg/sentry/devices/nvproxy/version.go b/pkg/sentry/devices/nvproxy/version.go index 44ea77490..65d18fc5b 100644 --- a/pkg/sentry/devices/nvproxy/version.go +++ b/pkg/sentry/devices/nvproxy/version.go @@ -234,6 +234,7 @@ func Init() { nvgpu.NV2080_CTRL_CMD_BUS_GET_PCIE_SUPPORTED_GPU_ATOMICS: rmControlSimple, nvgpu.NV2080_CTRL_CMD_BUS_GET_C2C_INFO: rmControlSimple, nvgpu.NV2080_CTRL_CMD_CE_GET_ALL_CAPS: rmControlSimple, + nvgpu.NV2080_CTRL_CMD_EVENT_SET_NOTIFICATION: rmControlSimple, nvgpu.NV2080_CTRL_CMD_FB_GET_INFO_V2: rmControlSimple, nvgpu.NV2080_CTRL_CMD_GPU_GET_INFO_V2: rmControlSimple, nvgpu.NV2080_CTRL_CMD_FLCN_GET_CTX_BUFFER_SIZE: rmControlSimple, @@ -242,9 +243,11 @@ func Init() { nvgpu.NV2080_CTRL_CMD_GPU_GET_SIMULATION_INFO: rmControlSimple, nvgpu.NV2080_CTRL_CMD_GPU_QUERY_ECC_STATUS: rmControlSimple, nvgpu.NV2080_CTRL_CMD_GPU_QUERY_COMPUTE_MODE_RULES: rmControlSimple, + nvgpu.NV2080_CTRL_CMD_GPU_GET_OEM_BOARD_INFO: rmControlSimple, nvgpu.NV2080_CTRL_CMD_GPU_ACQUIRE_COMPUTE_MODE_RESERVATION: rmControlSimple, nvgpu.NV2080_CTRL_CMD_GPU_RELEASE_COMPUTE_MODE_RESERVATION: rmControlSimple, nvgpu.NV2080_CTRL_CMD_GPU_GET_GID_INFO: rmControlSimple, + nvgpu.NV2080_CTRL_CMD_GPU_GET_INFOROM_IMAGE_VERSION: rmControlSimple, nvgpu.NV2080_CTRL_CMD_GPU_GET_ENGINES_V2: rmControlSimple, nvgpu.NV2080_CTRL_CMD_GPU_GET_ACTIVE_PARTITION_IDS: rmControlSimple, nvgpu.NV2080_CTRL_CMD_GPU_GET_PIDS: rmControlSimple, @@ -291,12 +294,13 @@ func Init() { 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.NV0041_CTRL_CMD_GET_SURFACE_INFO: ctrlIoctlHasInfoList[nvgpu.NV0041_CTRL_GET_SURFACE_INFO_PARAMS], nvgpu.NV0080_CTRL_CMD_FIFO_GET_CHANNELLIST: ctrlDevFIFOGetChannelList, nvgpu.NV00FD_CTRL_CMD_ATTACH_GPU: ctrlMemoryMulticastFabricAttachGPU, nvgpu.NV0080_CTRL_CMD_GPU_GET_CLASSLIST: ctrlDevGpuGetClasslist, nvgpu.NV2080_CTRL_CMD_FIFO_DISABLE_CHANNELS: ctrlSubdevFIFODisableChannels, - nvgpu.NV2080_CTRL_CMD_GR_GET_INFO: ctrlSubdevGRGetInfo, + nvgpu.NV2080_CTRL_CMD_BIOS_GET_INFO: ctrlIoctlHasInfoList[nvgpu.NV2080_CTRL_BIOS_GET_INFO_PARAMS], + nvgpu.NV2080_CTRL_CMD_GR_GET_INFO: ctrlIoctlHasInfoList[nvgpu.NV2080_CTRL_GR_GET_INFO_PARAMS], nvgpu.NV503C_CTRL_CMD_REGISTER_VA_SPACE: ctrlRegisterVASpace, }, allocationClass: map[nvgpu.ClassID]allocationClassHandler{ @@ -308,6 +312,7 @@ func Init() { nvgpu.NV01_EVENT_OS_EVENT: rmAllocEventOSEvent, nvgpu.NV2081_BINAPI: rmAllocSimple[nvgpu.NV2081_ALLOC_PARAMETERS], nvgpu.NV01_DEVICE_0: rmAllocSimple[nvgpu.NV0080_ALLOC_PARAMETERS], + nvgpu.RM_USER_SHARED_DATA: rmAllocSimple[nvgpu.NV00DE_ALLOC_PARAMETERS], nvgpu.NV_MEMORY_FABRIC: rmAllocSimple[nvgpu.NV00F8_ALLOCATION_PARAMETERS], nvgpu.NV_MEMORY_MULTICAST_FABRIC: rmAllocSimple[nvgpu.NV00FD_ALLOCATION_PARAMETERS], nvgpu.NV20_SUBDEVICE_0: rmAllocSimple[nvgpu.NV2080_ALLOC_PARAMETERS], @@ -356,6 +361,7 @@ func Init() { 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.RM_USER_SHARED_DATA] = rmAllocSimple[nvgpu.NV00DE_ALLOC_PARAMETERS_V545] abi.allocationClass[nvgpu.NV_MEMORY_MULTICAST_FABRIC] = rmAllocSimple[nvgpu.NV00FD_ALLOCATION_PARAMETERS_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]