diff --git a/pkg/abi/nvgpu/ctrl.go b/pkg/abi/nvgpu/ctrl.go index 4ede248be..45f4f76b1 100644 --- a/pkg/abi/nvgpu/ctrl.go +++ b/pkg/abi/nvgpu/ctrl.go @@ -90,12 +90,22 @@ type NV0080_CTRL_FIFO_GET_CHANNELLIST_PARAMS struct { // From src/common/sdk/nvidia/inc/ctrl/ctrl0080/ctrl0080gpu.h: const ( + NV0080_CTRL_CMD_GPU_GET_CLASSLIST = 0x800201 NV0080_CTRL_CMD_GPU_GET_NUM_SUBDEVICES = 0x800280 NV0080_CTRL_CMD_GPU_QUERY_SW_STATE_PERSISTENCE = 0x800288 NV0080_CTRL_CMD_GPU_GET_VIRTUALIZATION_MODE = 0x800289 NV0080_CTRL_CMD_GPU_GET_CLASSLIST_V2 = 0x800292 + + NV0080_CTRL_GPU_CLASSLIST_MAX_SIZE = 160 ) +// +marshal +type NV0080_CTRL_CMD_GPU_GET_CLASSLIST_PARAMS struct { + NumClasses uint32 + Pad [4]byte + ClassList P64 +} + // From src/common/sdk/nvidia/inc/ctrl/ctrl0080/ctrl0080gr.h: // +marshal @@ -161,6 +171,8 @@ const ( NV2080_CTRL_CMD_GPU_GET_GID_INFO = 0x2080014a NV2080_CTRL_CMD_GPU_GET_ENGINES_V2 = 0x20800170 NV2080_CTRL_CMD_GPU_GET_ACTIVE_PARTITION_IDS = 0x2080018b + NV2080_CTRL_CMD_GPU_GET_PIDS = 0x2080018d + NV2080_CTRL_CMD_GPU_GET_PID_INFO = 0x2080018e NV2080_CTRL_CMD_GPU_GET_COMPUTE_POLICY_CONFIG = 0x20800195 NV2080_CTRL_CMD_GET_GPU_FABRIC_PROBE_INFO = 0x208001a3 ) diff --git a/pkg/sentry/devices/nvproxy/frontend.go b/pkg/sentry/devices/nvproxy/frontend.go index 2bd4f06c4..bd8583698 100644 --- a/pkg/sentry/devices/nvproxy/frontend.go +++ b/pkg/sentry/devices/nvproxy/frontend.go @@ -587,6 +587,33 @@ func ctrlClientSystemGetBuildVersion(fi *frontendIoctlState, ioctlParams *nvgpu. return n, nil } +func ctrlDevGpuGetClasslist(fi *frontendIoctlState, ioctlParams *nvgpu.NVOS54Parameters) (uintptr, error) { + var ctrlParams nvgpu.NV0080_CTRL_CMD_GPU_GET_CLASSLIST_PARAMS + + if _, err := ctrlParams.CopyIn(fi.t, addrFromP64(ioctlParams.Params)); err != nil { + return 0, err + } + + // This command has two modes. If the classList pointer is NULL, only simple command handling + // is required; see src/common/sdk/nvidia/inc/ctrl/ctrl0080gpu.h. + if ctrlParams.ClassList == 0 { + return rmControlSimple(fi, ioctlParams) + } + + // classList pointer is not NULL. Do classList buffer management. + if ctrlParams.NumClasses > nvgpu.NV0080_CTRL_GPU_CLASSLIST_MAX_SIZE { + fi.ctx.Warningf("nvproxy: requested classlist size exceeds max (%d > %d)", ctrlParams.NumClasses, nvgpu.NV0080_CTRL_GPU_CLASSLIST_MAX_SIZE) + return 0, linuxerr.EINVAL + } + + classList := make([]uint32, ctrlParams.NumClasses) + n, err := ctrlDevGpuGetClasslistInvoke(fi, ioctlParams, &ctrlParams, classList) + if err != nil { + return n, err + } + return n, nil +} + func ctrlSubdevFIFODisableChannels(fi *frontendIoctlState, ioctlParams *nvgpu.NVOS54Parameters) (uintptr, error) { var ctrlParams nvgpu.NV2080_CTRL_FIFO_DISABLE_CHANNELS_PARAMS if ctrlParams.SizeBytes() != int(ioctlParams.ParamsSize) { diff --git a/pkg/sentry/devices/nvproxy/frontend_unsafe.go b/pkg/sentry/devices/nvproxy/frontend_unsafe.go index e5d569b3b..f23141c05 100644 --- a/pkg/sentry/devices/nvproxy/frontend_unsafe.go +++ b/pkg/sentry/devices/nvproxy/frontend_unsafe.go @@ -75,6 +75,24 @@ func ctrlClientSystemGetBuildVersionInvoke(fi *frontendIoctlState, ioctlParams * return n, nil } +func ctrlDevGpuGetClasslistInvoke(fi *frontendIoctlState, ioctlParams *nvgpu.NVOS54Parameters, ctrlParams *nvgpu.NV0080_CTRL_CMD_GPU_GET_CLASSLIST_PARAMS, classList []uint32) (uintptr, error) { + sentryCtrlParams := *ctrlParams + sentryCtrlParams.ClassList = p64FromPtr(unsafe.Pointer(&classList[0])) + n, err := rmControlInvoke(fi, ioctlParams, &sentryCtrlParams) + if err != nil { + return n, err + } + if _, err := primitive.CopyUint32SliceOut(fi.t, addrFromP64(ctrlParams.ClassList), classList); err != nil { + return 0, err + } + outCtrlParams := sentryCtrlParams + outCtrlParams.ClassList = ctrlParams.ClassList + if _, err := outCtrlParams.CopyOut(fi.t, addrFromP64(ioctlParams.Params)); err != nil { + return n, err + } + return n, nil +} + func ctrlDevFIFOGetChannelList(fi *frontendIoctlState, ioctlParams *nvgpu.NVOS54Parameters) (uintptr, error) { var ctrlParams nvgpu.NV0080_CTRL_FIFO_GET_CHANNELLIST_PARAMS if ctrlParams.SizeBytes() != int(ioctlParams.ParamsSize) { diff --git a/pkg/sentry/devices/nvproxy/version.go b/pkg/sentry/devices/nvproxy/version.go index b12ed67bb..f6a691a6c 100644 --- a/pkg/sentry/devices/nvproxy/version.go +++ b/pkg/sentry/devices/nvproxy/version.go @@ -236,6 +236,8 @@ func Init() { nvgpu.NV2080_CTRL_CMD_GPU_GET_GID_INFO: 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, + nvgpu.NV2080_CTRL_CMD_GPU_GET_PID_INFO: rmControlSimple, nvgpu.NV2080_CTRL_CMD_GPU_GET_COMPUTE_POLICY_CONFIG: rmControlSimple, nvgpu.NV2080_CTRL_CMD_GET_GPU_FABRIC_PROBE_INFO: rmControlSimple, nvgpu.NV2080_CTRL_CMD_GR_SET_CTXSW_PREEMPTION_MODE: rmControlSimple, @@ -268,6 +270,7 @@ func Init() { nvgpu.NVA06C_CTRL_CMD_PREEMPT: rmControlSimple, nvgpu.NV0000_CTRL_CMD_SYSTEM_GET_BUILD_VERSION: ctrlClientSystemGetBuildVersion, nvgpu.NV0080_CTRL_CMD_FIFO_GET_CHANNELLIST: ctrlDevFIFOGetChannelList, + nvgpu.NV0080_CTRL_CMD_GPU_GET_CLASSLIST: ctrlDevGpuGetClasslist, nvgpu.NV2080_CTRL_CMD_FIFO_DISABLE_CHANNELS: ctrlSubdevFIFODisableChannels, nvgpu.NV2080_CTRL_CMD_GR_GET_INFO: ctrlSubdevGRGetInfo, },