mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Add NVIDIA driver capability segmentation support to nvproxy.
This wraps `nvproxy`'s `ioctl` handlers with wrappers that are driver-capability-aware, and initially populates the ABI tree with all functions marked as being available for capabilities `compute` and `utility`. It is not yet possible for the user to specify which capability they want to enable. This should not cause a regression for users because the hardcoded effective capability set is the one that is currently specified for all current handlers. Updates #9452. Updates #10856. PiperOrigin-RevId: 697824737
This commit is contained in:
committed by
gVisor bot
parent
03a28d158e
commit
6953ca0ca3
@@ -48,6 +48,7 @@ go_library(
|
||||
"frontend_mmap_mutex.go",
|
||||
"frontend_mmap_unsafe.go",
|
||||
"frontend_unsafe.go",
|
||||
"handlers.go",
|
||||
"nvproxy.go",
|
||||
"nvproxy_unsafe.go",
|
||||
"object.go",
|
||||
@@ -82,6 +83,7 @@ go_library(
|
||||
"//pkg/safemem",
|
||||
"//pkg/seccomp",
|
||||
"//pkg/sentry/arch",
|
||||
"//pkg/sentry/devices/nvproxy/nvconf",
|
||||
"//pkg/sentry/kernel",
|
||||
"//pkg/sentry/memmap",
|
||||
"//pkg/sentry/mm",
|
||||
@@ -98,6 +100,10 @@ go_test(
|
||||
name = "nvproxy_test",
|
||||
srcs = ["nvproxy_test.go"],
|
||||
library = ":nvproxy",
|
||||
deps = [
|
||||
"//pkg/abi/nvgpu",
|
||||
"//pkg/sentry/devices/nvproxy/nvconf",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
|
||||
@@ -260,12 +260,14 @@ func (fd *frontendFD) Ioctl(ctx context.Context, uio usermem.IO, sysno uintptr,
|
||||
// - Add symbol and parameter type definitions to //pkg/abi/nvgpu.
|
||||
// - Add filter to seccomp_filters.go.
|
||||
// - Add handling below.
|
||||
handler := fd.dev.nvp.abi.frontendIoctl[nr]
|
||||
if handler == nil {
|
||||
ctx.Warningf("nvproxy: unknown frontend ioctl %d == %#x (argSize=%d, cmd=%#x)", nr, nr, argSize, cmd)
|
||||
return 0, linuxerr.EINVAL
|
||||
result, err := fd.dev.nvp.abi.frontendIoctl[nr].handle(&fi)
|
||||
if err != nil {
|
||||
if handleErr, ok := err.(*errHandler); ok {
|
||||
fi.ctx.Warningf("nvproxy: %v for frontend ioctl %d == %#x (argSize=%d, cmd=%#x)", handleErr, nr, nr, argSize, cmd)
|
||||
return 0, linuxerr.EINVAL
|
||||
}
|
||||
}
|
||||
return handler(&fi)
|
||||
return result, err
|
||||
}
|
||||
|
||||
// IsNvidiaDeviceFD implements NvidiaDeviceFD.IsNvidiaDeviceFD.
|
||||
@@ -558,12 +560,14 @@ func rmControl(fi *frontendIoctlState) (uintptr, error) {
|
||||
// - Add symbol definition to //pkg/abi/nvgpu. Parameter type definition is
|
||||
// only required for non-simple commands.
|
||||
// - Add handling below.
|
||||
handler := fi.fd.dev.nvp.abi.controlCmd[ioctlParams.Cmd]
|
||||
if handler == nil {
|
||||
fi.ctx.Warningf("nvproxy: unknown control command %#x (paramsSize=%d)", ioctlParams.Cmd, ioctlParams.ParamsSize)
|
||||
return 0, linuxerr.EINVAL
|
||||
result, err := fi.fd.dev.nvp.abi.controlCmd[ioctlParams.Cmd].handle(fi, &ioctlParams)
|
||||
if err != nil {
|
||||
if handleErr, ok := err.(*errHandler); ok {
|
||||
fi.ctx.Warningf("nvproxy: %v for control command %#x (paramsSize=%d)", handleErr, ioctlParams.Cmd, ioctlParams.ParamsSize)
|
||||
return 0, linuxerr.EINVAL
|
||||
}
|
||||
}
|
||||
return handler(fi, &ioctlParams)
|
||||
return result, err
|
||||
}
|
||||
|
||||
func rmControlSimple(fi *frontendIoctlState, ioctlParams *nvgpu.NVOS54Parameters) (uintptr, error) {
|
||||
@@ -830,22 +834,24 @@ func rmAlloc(fi *frontendIoctlState) (uintptr, error) {
|
||||
// sessionAddDependant(), or sessionAddDependency(), which need to be
|
||||
// mirrored by dependencies in the call to nvproxy.objAddLocked().
|
||||
// - Add handling below.
|
||||
handler := fi.fd.dev.nvp.abi.allocationClass[ioctlParams.HClass]
|
||||
if handler == nil {
|
||||
fi.ctx.Warningf("nvproxy: unknown allocation class %v", ioctlParams.HClass)
|
||||
// Compare
|
||||
// src/nvidia/src/kernel/rmapi/alloc_free.c:serverAllocResourceUnderLock(),
|
||||
// when RsResInfoByExternalClassId() is null.
|
||||
ioctlParams.Status = nvgpu.NV_ERR_INVALID_CLASS
|
||||
outIoctlParams := nvgpu.GetRmAllocParamObj(isNVOS64)
|
||||
outIoctlParams.FromOS64(ioctlParams)
|
||||
// Any copy-out error from
|
||||
// src/nvidia/src/kernel/rmapi/alloc_free.c:serverAllocApiCopyOut() is
|
||||
// discarded.
|
||||
outIoctlParams.CopyOut(fi.t, fi.ioctlParamsAddr)
|
||||
return 0, nil
|
||||
result, err := fi.fd.dev.nvp.abi.allocationClass[ioctlParams.HClass].handle(fi, &ioctlParams, isNVOS64)
|
||||
if err != nil {
|
||||
if handleErr, ok := err.(*errHandler); ok {
|
||||
fi.ctx.Warningf("nvproxy: %v for allocation class %v", handleErr, ioctlParams.HClass)
|
||||
// Compare
|
||||
// src/nvidia/src/kernel/rmapi/alloc_free.c:serverAllocResourceUnderLock(),
|
||||
// when RsResInfoByExternalClassId() is null.
|
||||
ioctlParams.Status = nvgpu.NV_ERR_INVALID_CLASS
|
||||
outIoctlParams := nvgpu.GetRmAllocParamObj(isNVOS64)
|
||||
outIoctlParams.FromOS64(ioctlParams)
|
||||
// Any copy-out error from
|
||||
// src/nvidia/src/kernel/rmapi/alloc_free.c:serverAllocApiCopyOut() is
|
||||
// discarded.
|
||||
outIoctlParams.CopyOut(fi.t, fi.ioctlParamsAddr)
|
||||
return 0, nil
|
||||
}
|
||||
}
|
||||
return handler(fi, &ioctlParams, isNVOS64)
|
||||
return result, err
|
||||
}
|
||||
|
||||
// rmAllocSimple implements NV_ESC_RM_ALLOC for classes whose parameters don't
|
||||
|
||||
@@ -0,0 +1,156 @@
|
||||
// Copyright 2024 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package nvproxy
|
||||
|
||||
import (
|
||||
"gvisor.dev/gvisor/pkg/abi/nvgpu"
|
||||
"gvisor.dev/gvisor/pkg/sentry/devices/nvproxy/nvconf"
|
||||
)
|
||||
|
||||
// errHandler is an error returned by an ioctl handler function.
|
||||
type errHandler struct {
|
||||
Err string
|
||||
}
|
||||
|
||||
// Error implements the error interface.
|
||||
func (e *errHandler) Error() string {
|
||||
return e.Err
|
||||
}
|
||||
|
||||
// ioctl handler errors.
|
||||
var (
|
||||
errUndefinedHandler = errHandler{"handler is undefined"}
|
||||
errMissingCapability = errHandler{"missing capability"}
|
||||
)
|
||||
|
||||
type frontendIoctlHandler struct {
|
||||
// handler is the function to call if a capability in capSet is enabled.
|
||||
handler func(*frontendIoctlState) (uintptr, error)
|
||||
// capSet is a bitmask of capabilities that this handler is available for.
|
||||
capSet nvconf.DriverCaps
|
||||
}
|
||||
|
||||
// feHandler returns a frontendIoctlHandler that wraps the given function.
|
||||
// The handler will be called if any of the given capabilities are enabled.
|
||||
func feHandler(handler func(*frontendIoctlState) (uintptr, error), caps nvconf.DriverCaps) frontendIoctlHandler {
|
||||
return frontendIoctlHandler{
|
||||
handler: handler,
|
||||
capSet: caps,
|
||||
}
|
||||
}
|
||||
|
||||
// handle calls the handler if the capability is enabled.
|
||||
// Returns errMissingCapability if the caller is missing the required
|
||||
// capabilities for this handler.
|
||||
// Returns errUndefinedHandler if the handler does not exist.
|
||||
func (h frontendIoctlHandler) handle(fi *frontendIoctlState) (uintptr, error) {
|
||||
if h.handler == nil {
|
||||
return 0, &errUndefinedHandler
|
||||
}
|
||||
if h.capSet&fi.fd.dev.nvp.capsEnabled == 0 {
|
||||
return 0, &errMissingCapability
|
||||
}
|
||||
return h.handler(fi)
|
||||
}
|
||||
|
||||
type controlCmdHandler struct {
|
||||
// handler is the function to call if a capability in capSet is enabled.
|
||||
handler func(*frontendIoctlState, *nvgpu.NVOS54Parameters) (uintptr, error)
|
||||
// capSet is a bitmask of capabilities that this handler is available for.
|
||||
capSet nvconf.DriverCaps
|
||||
}
|
||||
|
||||
// ctrlHandler returns a controlCmdHandler that wraps the given function.
|
||||
// The handler will be called if any of the given capabilities are enabled.
|
||||
func ctrlHandler(handler func(*frontendIoctlState, *nvgpu.NVOS54Parameters) (uintptr, error), caps nvconf.DriverCaps) controlCmdHandler {
|
||||
return controlCmdHandler{
|
||||
handler: handler,
|
||||
capSet: caps,
|
||||
}
|
||||
}
|
||||
|
||||
// handle calls the handler if the capability is enabled.
|
||||
// Returns errMissingCapability if the caller is missing the required
|
||||
// capabilities for this handler.
|
||||
// Returns errUndefinedHandler if the handler does not exist.
|
||||
func (h controlCmdHandler) handle(fi *frontendIoctlState, params *nvgpu.NVOS54Parameters) (uintptr, error) {
|
||||
if h.handler == nil {
|
||||
return 0, &errUndefinedHandler
|
||||
}
|
||||
if h.capSet&fi.fd.dev.nvp.capsEnabled == 0 {
|
||||
return 0, &errMissingCapability
|
||||
}
|
||||
return h.handler(fi, params)
|
||||
}
|
||||
|
||||
type allocationClassHandler struct {
|
||||
// handler is the function to call if a capability in capSet is enabled.
|
||||
handler func(fi *frontendIoctlState, ioctlParams *nvgpu.NVOS64Parameters, isNVOS64 bool) (uintptr, error)
|
||||
// capSet is a bitmask of capabilities that this handler is available for.
|
||||
capSet nvconf.DriverCaps
|
||||
}
|
||||
|
||||
// allocHandler returns a allocationClassHandler that wraps the given function.
|
||||
// The handler will be called if any of the given capabilities are enabled.
|
||||
func allocHandler(handler func(fi *frontendIoctlState, ioctlParams *nvgpu.NVOS64Parameters, isNVOS64 bool) (uintptr, error), caps nvconf.DriverCaps) allocationClassHandler {
|
||||
return allocationClassHandler{
|
||||
handler: handler,
|
||||
capSet: caps,
|
||||
}
|
||||
}
|
||||
|
||||
// handle calls the handler if the capability is enabled.
|
||||
// Returns errMissingCapability if the caller is missing the required
|
||||
// capabilities for this handler.
|
||||
// Returns errUndefinedHandler if the handler does not exist.
|
||||
func (h allocationClassHandler) handle(fi *frontendIoctlState, ioctlParams *nvgpu.NVOS64Parameters, isNVOS64 bool) (uintptr, error) {
|
||||
if h.handler == nil {
|
||||
return 0, &errUndefinedHandler
|
||||
}
|
||||
if h.capSet&fi.fd.dev.nvp.capsEnabled == 0 {
|
||||
return 0, &errMissingCapability
|
||||
}
|
||||
return h.handler(fi, ioctlParams, isNVOS64)
|
||||
}
|
||||
|
||||
type uvmIoctlHandler struct {
|
||||
// handler is the function to call if a capability in capSet is enabled.
|
||||
handler func(*uvmIoctlState) (uintptr, error)
|
||||
// capSet is a bitmask of capabilities that this handler is available for.
|
||||
capSet nvconf.DriverCaps
|
||||
}
|
||||
|
||||
// uvmHandler returns a uvmIoctlHandler that wraps the given function.
|
||||
// The handler will be called if any of the given capabilities are enabled.
|
||||
func uvmHandler(handler func(*uvmIoctlState) (uintptr, error), caps nvconf.DriverCaps) uvmIoctlHandler {
|
||||
return uvmIoctlHandler{
|
||||
handler: handler,
|
||||
capSet: caps,
|
||||
}
|
||||
}
|
||||
|
||||
// handle calls the handler if the capability is enabled.
|
||||
// Returns errMissingCapability if the caller is missing the required
|
||||
// capabilities for this handler.
|
||||
// Returns errUndefinedHandler if the handler does not exist.
|
||||
func (h uvmIoctlHandler) handle(ui *uvmIoctlState) (uintptr, error) {
|
||||
if h.handler == nil {
|
||||
return 0, &errUndefinedHandler
|
||||
}
|
||||
if h.capSet&ui.fd.dev.nvp.capsEnabled == 0 {
|
||||
return 0, &errMissingCapability
|
||||
}
|
||||
return h.handler(ui)
|
||||
}
|
||||
@@ -14,94 +14,151 @@
|
||||
|
||||
package nvconf
|
||||
|
||||
import "strings"
|
||||
|
||||
// DriverCap is a GPU driver capability (like compute, graphics, etc.).
|
||||
type DriverCap string
|
||||
|
||||
// Driver capabilities understood by nvproxy.
|
||||
const (
|
||||
// AllCap is a special value that means all supported driver capabilities.
|
||||
AllCap DriverCap = "all"
|
||||
|
||||
Compat32Cap DriverCap = "compat32"
|
||||
ComputeCap DriverCap = "compute"
|
||||
DisplayCap DriverCap = "display"
|
||||
GraphicsCap DriverCap = "graphics"
|
||||
NGXCap DriverCap = "ngx"
|
||||
UtilityCap DriverCap = "utility"
|
||||
VideoCap DriverCap = "video"
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ToFlag converts the driver capability to a flag for nvidia-container-cli.
|
||||
// See nvidia-container-toolkit/cmd/nvidia-container-runtime-hook/capabilities.go:capabilityToCLI().
|
||||
func (c DriverCap) ToFlag() string {
|
||||
return "--" + string(c)
|
||||
// DriverCaps is a set of NVIDIA driver capabilities as a bitmask.
|
||||
type DriverCaps uint8
|
||||
|
||||
// Individual NVIDIA driver capabilities.
|
||||
const (
|
||||
CapCompute DriverCaps = 1 << iota
|
||||
CapDisplay
|
||||
CapGraphics
|
||||
CapNGX
|
||||
CapUtility
|
||||
CapVideo
|
||||
CapCompat32
|
||||
numValidCaps int = iota
|
||||
)
|
||||
|
||||
const (
|
||||
// AllCapabilitiesName is a special capability name
|
||||
// that can be used to represent all capabilities.
|
||||
AllCapabilitiesName = "all"
|
||||
|
||||
// ValidCapabilities is the set of all valid capabilities.
|
||||
ValidCapabilities = DriverCaps(1<<numValidCaps - 1)
|
||||
|
||||
// SupportedDriverCaps is the set of driver capabilities that are supported by
|
||||
// nvproxy. Similar to
|
||||
// nvidia-container-toolkit/internal/config/image/capabilities.go:SupportedDriverCapabilities.
|
||||
SupportedDriverCaps = DriverCaps(CapCompute | CapUtility)
|
||||
|
||||
// DefaultDriverCaps is the set of driver capabilities that are enabled by
|
||||
// default in the absence of any other configuration. See
|
||||
// nvidia-container-toolkit/internal/config/image/capabilities.go:DefaultDriverCapabilities.
|
||||
DefaultDriverCaps = DriverCaps(CapCompute | CapUtility)
|
||||
)
|
||||
|
||||
// individualString returns the string representation of the given capability.
|
||||
// It must be one of the individual capabilities, or this will panic.
|
||||
func (c DriverCaps) individualString() string {
|
||||
switch c {
|
||||
case CapCompute:
|
||||
return "compute"
|
||||
case CapDisplay:
|
||||
return "display"
|
||||
case CapGraphics:
|
||||
return "graphics"
|
||||
case CapNGX:
|
||||
return "ngx"
|
||||
case CapUtility:
|
||||
return "utility"
|
||||
case CapVideo:
|
||||
return "video"
|
||||
case CapCompat32:
|
||||
return "compat32"
|
||||
default:
|
||||
panic(fmt.Sprintf("capability has no string mapping: %x", uint8(c)))
|
||||
}
|
||||
}
|
||||
|
||||
// DriverCaps is a set of GPU driver capabilities.
|
||||
type DriverCaps map[DriverCap]struct{}
|
||||
|
||||
// DefaultDriverCaps is the set of driver capabilities that are enabled by
|
||||
// default in the absence of any other configuration. See
|
||||
// nvidia-container-toolkit/internal/config/image/capabilities.go:DefaultDriverCapabilities.
|
||||
var DefaultDriverCaps = DriverCaps{
|
||||
ComputeCap: struct{}{},
|
||||
UtilityCap: struct{}{},
|
||||
// individualNVIDIAFlag returns the flag that can be passed to
|
||||
// nvidia-container-cli to enable the given capability.
|
||||
// See nvidia-container-toolkit/blob/main/cmd/nvidia-container-runtime-hook/capabilities.go:capabilityToCLI
|
||||
func (c DriverCaps) individualNVIDIAFlag() string {
|
||||
switch c {
|
||||
case CapCompute, CapDisplay, CapGraphics, CapNGX, CapUtility, CapVideo, CapCompat32:
|
||||
return fmt.Sprintf("--%s", c.individualString())
|
||||
default:
|
||||
panic(fmt.Sprintf("capability has no NVIDIA flag mapping: %x", uint8(c)))
|
||||
}
|
||||
}
|
||||
|
||||
// SupportedDriverCaps is the set of driver capabilities that are supported by
|
||||
// nvproxy. Similar to
|
||||
// nvidia-container-toolkit/internal/config/image/capabilities.go:SupportedDriverCapabilities.
|
||||
var SupportedDriverCaps = DriverCaps{
|
||||
ComputeCap: struct{}{},
|
||||
UtilityCap: struct{}{},
|
||||
// individualCapabilityFromString returns the individual capability for the
|
||||
// given string.
|
||||
func individualCapabilityFromString(capName string) (DriverCaps, bool) {
|
||||
for i := 0; i < numValidCaps; i++ {
|
||||
cap := DriverCaps(1 << i)
|
||||
if cap.String() == capName {
|
||||
return cap, true
|
||||
}
|
||||
}
|
||||
return 0, false
|
||||
}
|
||||
|
||||
// KnownDriverCapValues is the set of understood driver capability values.
|
||||
var KnownDriverCapValues = DriverCaps{
|
||||
Compat32Cap: struct{}{},
|
||||
ComputeCap: struct{}{},
|
||||
DisplayCap: struct{}{},
|
||||
GraphicsCap: struct{}{},
|
||||
NGXCap: struct{}{},
|
||||
UtilityCap: struct{}{},
|
||||
VideoCap: struct{}{},
|
||||
}
|
||||
|
||||
// DriverCapsFromString constructs NvidiaDriverCaps from a comma-separated list
|
||||
// of driver capabilities.
|
||||
func DriverCapsFromString(caps string) DriverCaps {
|
||||
res := make(DriverCaps)
|
||||
for _, cap := range strings.Split(caps, ",") {
|
||||
trimmed := strings.TrimSpace(cap)
|
||||
if len(trimmed) == 0 {
|
||||
// DriverCapsFromString creates a new capability set from the given
|
||||
// comma-separated list of capability names.
|
||||
// The returned boolean represents whether the "all" keyword was used.
|
||||
// Note that the "all" keyword is not actually expanded into the set of
|
||||
// capabilities returned here; it is up to the caller to decide how to
|
||||
// handle it.
|
||||
func DriverCapsFromString(commaSeparatedCaps string) (DriverCaps, bool, error) {
|
||||
cs := DriverCaps(0)
|
||||
hasAll := false
|
||||
for _, capName := range strings.Split(commaSeparatedCaps, ",") {
|
||||
capName = strings.TrimSpace(capName)
|
||||
if capName == "" {
|
||||
continue
|
||||
}
|
||||
res[DriverCap(trimmed)] = struct{}{}
|
||||
if capName == AllCapabilitiesName {
|
||||
hasAll = true
|
||||
continue
|
||||
}
|
||||
cap, ok := individualCapabilityFromString(capName)
|
||||
if !ok {
|
||||
return 0, false, fmt.Errorf("invalid capability: %q", capName)
|
||||
}
|
||||
cs |= DriverCaps(cap)
|
||||
}
|
||||
return res
|
||||
return cs, hasAll, nil
|
||||
}
|
||||
|
||||
// HasAll returns true if the set of driver capabilities contains "all".
|
||||
func (c DriverCaps) HasAll() bool {
|
||||
_, ok := c[AllCap]
|
||||
return ok
|
||||
}
|
||||
|
||||
// Intersect returns the intersection of two sets of driver capabilities.
|
||||
func (c DriverCaps) Intersect(c2 DriverCaps) DriverCaps {
|
||||
if c2.HasAll() {
|
||||
return c
|
||||
// String returns the string representation of the capability set.
|
||||
func (c DriverCaps) String() string {
|
||||
if c == 0 {
|
||||
return ""
|
||||
}
|
||||
if c.HasAll() {
|
||||
return c2
|
||||
}
|
||||
res := make(DriverCaps)
|
||||
for cap := range c2 {
|
||||
if _, ok := c[cap]; ok {
|
||||
res[cap] = struct{}{}
|
||||
firstCap := true
|
||||
var sb strings.Builder
|
||||
for i := 0; i < numValidCaps; i++ {
|
||||
cap := DriverCaps(1 << i)
|
||||
if c&cap != 0 {
|
||||
if !firstCap {
|
||||
sb.WriteString(",")
|
||||
}
|
||||
firstCap = false
|
||||
sb.WriteString(cap.individualString())
|
||||
}
|
||||
}
|
||||
return res
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
// NVIDIAFlags returns the nvidia-container-cli flags that can be passed to
|
||||
// enable the capabilities in the set.
|
||||
func (c DriverCaps) NVIDIAFlags() []string {
|
||||
if c == 0 {
|
||||
return nil
|
||||
}
|
||||
caps := make([]string, 0, numValidCaps)
|
||||
for i := 0; i < numValidCaps; i++ {
|
||||
cap := DriverCaps(1 << i)
|
||||
if c&cap != 0 {
|
||||
caps = append(caps, cap.individualNVIDIAFlag())
|
||||
}
|
||||
}
|
||||
return caps
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/hostarch"
|
||||
"gvisor.dev/gvisor/pkg/log"
|
||||
"gvisor.dev/gvisor/pkg/marshal"
|
||||
"gvisor.dev/gvisor/pkg/sentry/devices/nvproxy/nvconf"
|
||||
"gvisor.dev/gvisor/pkg/sentry/vfs"
|
||||
)
|
||||
|
||||
@@ -44,6 +45,7 @@ func Register(vfsObj *vfs.VirtualFilesystem, versionStr string, uvmDevMajor uint
|
||||
nvp := &nvproxy{
|
||||
abi: abiCons.cons(),
|
||||
version: version,
|
||||
capsEnabled: nvconf.SupportedDriverCaps, // TODO(gvisor.dev/issues/10856): Let the user specify this.
|
||||
frontendFDs: make(map[*frontendFD]struct{}),
|
||||
clients: make(map[nvgpu.Handle]*rootClient),
|
||||
objsFreeSet: make(map[*object]struct{}),
|
||||
@@ -70,8 +72,9 @@ func Register(vfsObj *vfs.VirtualFilesystem, versionStr string, uvmDevMajor uint
|
||||
|
||||
// +stateify savable
|
||||
type nvproxy struct {
|
||||
abi *driverABI `state:"nosave"`
|
||||
version DriverVersion
|
||||
abi *driverABI `state:"nosave"`
|
||||
version DriverVersion
|
||||
capsEnabled nvconf.DriverCaps
|
||||
|
||||
fdsMu fdsMutex `state:"nosave"`
|
||||
frontendFDs map[*frontendFD]struct{}
|
||||
|
||||
@@ -16,6 +16,9 @@ package nvproxy
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/abi/nvgpu"
|
||||
"gvisor.dev/gvisor/pkg/sentry/devices/nvproxy/nvconf"
|
||||
)
|
||||
|
||||
func TestInit(t *testing.T) {
|
||||
@@ -70,3 +73,140 @@ func TestABIStructNamesInSync(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// testHandler is a helper function to test an ioctl handler type.
|
||||
// `handleFn` must call the `Handler`'s `handle` method with the given `Input`.
|
||||
// `validHandler` must accept `CapCompute` and return 42.
|
||||
// `validInput` must be a valid input for the handler that enables `CapCompute`.
|
||||
// `invalidInput` must not enable `CapCompute`.
|
||||
func testHandler[Handler, Input any](
|
||||
t *testing.T,
|
||||
handleFn func(Handler, Input) (uintptr, error),
|
||||
validHandler Handler,
|
||||
validInput, invalidInput Input,
|
||||
) {
|
||||
t.Helper()
|
||||
for _, test := range []struct {
|
||||
name string
|
||||
handler Handler
|
||||
input Input
|
||||
wantResult uintptr
|
||||
wantErr error
|
||||
}{
|
||||
{
|
||||
name: "valid",
|
||||
handler: validHandler,
|
||||
input: validInput,
|
||||
wantResult: 42,
|
||||
},
|
||||
{
|
||||
name: "undefined handler",
|
||||
wantErr: &errUndefinedHandler,
|
||||
},
|
||||
{
|
||||
name: "missing capability",
|
||||
handler: validHandler,
|
||||
input: invalidInput,
|
||||
wantErr: &errMissingCapability,
|
||||
},
|
||||
} {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
got, err := handleFn(test.handler, test.input)
|
||||
if err != test.wantErr {
|
||||
t.Errorf("handle returned err=%v wantErr=%t", err, test.wantErr)
|
||||
}
|
||||
if got != test.wantResult {
|
||||
t.Errorf("handle returned got=%v want=%v", got, test.wantResult)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandlers(t *testing.T) {
|
||||
capComputeNVP := &nvproxy{
|
||||
capsEnabled: nvconf.CapCompute,
|
||||
}
|
||||
capComputeState := &frontendIoctlState{
|
||||
fd: &frontendFD{
|
||||
dev: &frontendDevice{nvp: capComputeNVP},
|
||||
},
|
||||
}
|
||||
capUtilityNVP := &nvproxy{
|
||||
capsEnabled: nvconf.CapUtility,
|
||||
}
|
||||
capUtilityState := &frontendIoctlState{
|
||||
fd: &frontendFD{
|
||||
dev: &frontendDevice{nvp: capUtilityNVP},
|
||||
},
|
||||
}
|
||||
capCompute := nvconf.CapCompute
|
||||
t.Run("frontend", func(t *testing.T) {
|
||||
testHandler(
|
||||
t,
|
||||
func(handler frontendIoctlHandler, fi *frontendIoctlState) (uintptr, error) {
|
||||
return handler.handle(fi)
|
||||
},
|
||||
feHandler(func(*frontendIoctlState) (uintptr, error) {
|
||||
return 42, nil
|
||||
}, capCompute),
|
||||
capComputeState,
|
||||
capUtilityState,
|
||||
)
|
||||
})
|
||||
t.Run("control command", func(t *testing.T) {
|
||||
type controlCmdInput struct {
|
||||
fi *frontendIoctlState
|
||||
params *nvgpu.NVOS54Parameters
|
||||
}
|
||||
testHandler(
|
||||
t,
|
||||
func(handler controlCmdHandler, input controlCmdInput) (uintptr, error) {
|
||||
return handler.handle(input.fi, input.params)
|
||||
},
|
||||
ctrlHandler(func(*frontendIoctlState, *nvgpu.NVOS54Parameters) (uintptr, error) {
|
||||
return 42, nil
|
||||
}, capCompute),
|
||||
controlCmdInput{fi: capComputeState},
|
||||
controlCmdInput{fi: capUtilityState},
|
||||
)
|
||||
})
|
||||
t.Run("allocation class", func(t *testing.T) {
|
||||
type allocClassInput struct {
|
||||
fi *frontendIoctlState
|
||||
ioctlParams *nvgpu.NVOS64Parameters
|
||||
isNVOS64 bool
|
||||
}
|
||||
testHandler(
|
||||
t,
|
||||
func(handler allocationClassHandler, input allocClassInput) (uintptr, error) {
|
||||
return handler.handle(input.fi, input.ioctlParams, input.isNVOS64)
|
||||
},
|
||||
allocHandler(func(*frontendIoctlState, *nvgpu.NVOS64Parameters, bool) (uintptr, error) {
|
||||
return 42, nil
|
||||
}, capCompute),
|
||||
allocClassInput{fi: capComputeState},
|
||||
allocClassInput{fi: capUtilityState},
|
||||
)
|
||||
})
|
||||
t.Run("uvm", func(t *testing.T) {
|
||||
testHandler(
|
||||
t,
|
||||
func(handler uvmIoctlHandler, ui *uvmIoctlState) (uintptr, error) {
|
||||
return handler.handle(ui)
|
||||
},
|
||||
uvmHandler(func(*uvmIoctlState) (uintptr, error) {
|
||||
return 42, nil
|
||||
}, capCompute),
|
||||
&uvmIoctlState{
|
||||
fd: &uvmFD{
|
||||
dev: &uvmDevice{nvp: capComputeNVP},
|
||||
},
|
||||
},
|
||||
&uvmIoctlState{
|
||||
fd: &uvmFD{
|
||||
dev: &uvmDevice{nvp: capUtilityNVP},
|
||||
},
|
||||
},
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -143,12 +143,14 @@ func (fd *uvmFD) Ioctl(ctx context.Context, uio usermem.IO, sysno uintptr, args
|
||||
cmd: cmd,
|
||||
ioctlParamsAddr: argPtr,
|
||||
}
|
||||
handler := fd.dev.nvp.abi.uvmIoctl[cmd]
|
||||
if handler == nil {
|
||||
ctx.Warningf("nvproxy: unknown uvm ioctl %d = %#x", cmd, cmd)
|
||||
return 0, linuxerr.EINVAL
|
||||
result, err := fd.dev.nvp.abi.uvmIoctl[cmd].handle(&ui)
|
||||
if err != nil {
|
||||
if handleErr, ok := err.(*errHandler); ok {
|
||||
ctx.Warningf("nvproxy: %v for uvm ioctl %d = %#x", handleErr, cmd, cmd)
|
||||
return 0, linuxerr.EINVAL
|
||||
}
|
||||
}
|
||||
return handler(&ui)
|
||||
return result, err
|
||||
}
|
||||
|
||||
// IsNvidiaDeviceFD implements NvidiaDeviceFD.IsNvidiaDeviceFD.
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/abi/nvgpu"
|
||||
"gvisor.dev/gvisor/pkg/sentry/devices/nvproxy/nvconf"
|
||||
"gvisor.dev/gvisor/pkg/sync"
|
||||
)
|
||||
|
||||
@@ -95,11 +96,6 @@ func (v DriverVersion) isGreaterThan(other DriverVersion) bool {
|
||||
}
|
||||
}
|
||||
|
||||
type frontendIoctlHandler func(fi *frontendIoctlState) (uintptr, error)
|
||||
type controlCmdHandler func(fi *frontendIoctlState, ioctlParams *nvgpu.NVOS54Parameters) (uintptr, error)
|
||||
type allocationClassHandler func(fi *frontendIoctlState, ioctlParams *nvgpu.NVOS64Parameters, isNVOS64 bool) (uintptr, error)
|
||||
type uvmIoctlHandler func(ui *uvmIoctlState) (uintptr, error)
|
||||
|
||||
// A driverABIFunc constructs and returns a driverABI.
|
||||
// This indirection exists to avoid memory usage from unused driver ABIs.
|
||||
type driverABIFunc func() *driverABI
|
||||
@@ -176,206 +172,211 @@ func addDriverABI(major, minor, patch int, runfileChecksum string, cons driverAB
|
||||
// Init initializes abis global map.
|
||||
func Init() {
|
||||
abisOnce.Do(func() {
|
||||
// Shorthands for capabilities, to keep the code below readable.
|
||||
const (
|
||||
compUtil = nvconf.CapCompute | nvconf.CapUtility
|
||||
)
|
||||
|
||||
v535_104_05 := func() *driverABI {
|
||||
// Since there is no parent to inherit from, the driverABI needs to be
|
||||
// constructed with the entirety of the nvproxy functionality.
|
||||
return &driverABI{
|
||||
frontendIoctl: map[uint32]frontendIoctlHandler{
|
||||
nvgpu.NV_ESC_CARD_INFO: frontendIoctlSimple, // nv_ioctl_card_info_t array
|
||||
nvgpu.NV_ESC_CHECK_VERSION_STR: frontendIoctlSimple, // nv_rm_api_version_t
|
||||
nvgpu.NV_ESC_ATTACH_GPUS_TO_FD: frontendIoctlSimple, // NvU32 array containing GPU IDs
|
||||
nvgpu.NV_ESC_SYS_PARAMS: frontendIoctlSimple, // nv_ioctl_sys_params_t
|
||||
nvgpu.NV_ESC_RM_DUP_OBJECT: frontendIoctlSimple, // NVOS55_PARAMETERS
|
||||
nvgpu.NV_ESC_RM_SHARE: frontendIoctlSimple, // NVOS57_PARAMETERS
|
||||
nvgpu.NV_ESC_RM_UNMAP_MEMORY: frontendIoctlSimple, // NVOS34_PARAMETERS
|
||||
nvgpu.NV_ESC_RM_UPDATE_DEVICE_MAPPING_INFO: frontendIoctlSimple, // NVOS56_PARAMETERS
|
||||
nvgpu.NV_ESC_REGISTER_FD: frontendRegisterFD,
|
||||
nvgpu.NV_ESC_ALLOC_OS_EVENT: frontendIoctHasFD[nvgpu.IoctlAllocOSEvent],
|
||||
nvgpu.NV_ESC_FREE_OS_EVENT: frontendIoctHasFD[nvgpu.IoctlFreeOSEvent],
|
||||
nvgpu.NV_ESC_NUMA_INFO: rmNumaInfo,
|
||||
nvgpu.NV_ESC_RM_ALLOC_MEMORY: rmAllocMemory,
|
||||
nvgpu.NV_ESC_RM_FREE: rmFree,
|
||||
nvgpu.NV_ESC_RM_CONTROL: rmControl,
|
||||
nvgpu.NV_ESC_RM_ALLOC: rmAlloc,
|
||||
nvgpu.NV_ESC_RM_VID_HEAP_CONTROL: rmVidHeapControl,
|
||||
nvgpu.NV_ESC_RM_MAP_MEMORY: rmMapMemory,
|
||||
nvgpu.NV_ESC_CARD_INFO: feHandler(frontendIoctlSimple, compUtil), // nv_ioctl_card_info_t array
|
||||
nvgpu.NV_ESC_CHECK_VERSION_STR: feHandler(frontendIoctlSimple, compUtil), // nv_rm_api_version_t
|
||||
nvgpu.NV_ESC_ATTACH_GPUS_TO_FD: feHandler(frontendIoctlSimple, compUtil), // NvU32 array containing GPU IDs
|
||||
nvgpu.NV_ESC_SYS_PARAMS: feHandler(frontendIoctlSimple, compUtil), // nv_ioctl_sys_params_t
|
||||
nvgpu.NV_ESC_RM_DUP_OBJECT: feHandler(frontendIoctlSimple, compUtil), // NVOS55_PARAMETERS
|
||||
nvgpu.NV_ESC_RM_SHARE: feHandler(frontendIoctlSimple, compUtil), // NVOS57_PARAMETERS
|
||||
nvgpu.NV_ESC_RM_UNMAP_MEMORY: feHandler(frontendIoctlSimple, compUtil), // NVOS34_PARAMETERS
|
||||
nvgpu.NV_ESC_RM_UPDATE_DEVICE_MAPPING_INFO: feHandler(frontendIoctlSimple, compUtil), // NVOS56_PARAMETERS
|
||||
nvgpu.NV_ESC_REGISTER_FD: feHandler(frontendRegisterFD, compUtil),
|
||||
nvgpu.NV_ESC_ALLOC_OS_EVENT: feHandler(frontendIoctHasFD[nvgpu.IoctlAllocOSEvent], compUtil),
|
||||
nvgpu.NV_ESC_FREE_OS_EVENT: feHandler(frontendIoctHasFD[nvgpu.IoctlFreeOSEvent], compUtil),
|
||||
nvgpu.NV_ESC_NUMA_INFO: feHandler(rmNumaInfo, compUtil),
|
||||
nvgpu.NV_ESC_RM_ALLOC_MEMORY: feHandler(rmAllocMemory, compUtil),
|
||||
nvgpu.NV_ESC_RM_FREE: feHandler(rmFree, compUtil),
|
||||
nvgpu.NV_ESC_RM_CONTROL: feHandler(rmControl, compUtil),
|
||||
nvgpu.NV_ESC_RM_ALLOC: feHandler(rmAlloc, compUtil),
|
||||
nvgpu.NV_ESC_RM_VID_HEAP_CONTROL: feHandler(rmVidHeapControl, compUtil),
|
||||
nvgpu.NV_ESC_RM_MAP_MEMORY: feHandler(rmMapMemory, compUtil),
|
||||
},
|
||||
uvmIoctl: map[uint32]uvmIoctlHandler{
|
||||
nvgpu.UVM_INITIALIZE: uvmInitialize,
|
||||
nvgpu.UVM_DEINITIALIZE: uvmIoctlNoParams,
|
||||
nvgpu.UVM_CREATE_RANGE_GROUP: uvmIoctlSimple[nvgpu.UVM_CREATE_RANGE_GROUP_PARAMS],
|
||||
nvgpu.UVM_DESTROY_RANGE_GROUP: uvmIoctlSimple[nvgpu.UVM_DESTROY_RANGE_GROUP_PARAMS],
|
||||
nvgpu.UVM_REGISTER_GPU_VASPACE: uvmIoctlHasFrontendFD[nvgpu.UVM_REGISTER_GPU_VASPACE_PARAMS],
|
||||
nvgpu.UVM_UNREGISTER_GPU_VASPACE: uvmIoctlSimple[nvgpu.UVM_UNREGISTER_GPU_VASPACE_PARAMS],
|
||||
nvgpu.UVM_REGISTER_CHANNEL: uvmIoctlHasFrontendFD[nvgpu.UVM_REGISTER_CHANNEL_PARAMS],
|
||||
nvgpu.UVM_UNREGISTER_CHANNEL: uvmIoctlSimple[nvgpu.UVM_UNREGISTER_CHANNEL_PARAMS],
|
||||
nvgpu.UVM_ENABLE_PEER_ACCESS: uvmIoctlSimple[nvgpu.UVM_ENABLE_PEER_ACCESS_PARAMS],
|
||||
nvgpu.UVM_DISABLE_PEER_ACCESS: uvmIoctlSimple[nvgpu.UVM_DISABLE_PEER_ACCESS_PARAMS],
|
||||
nvgpu.UVM_SET_RANGE_GROUP: uvmIoctlSimple[nvgpu.UVM_SET_RANGE_GROUP_PARAMS],
|
||||
nvgpu.UVM_MAP_EXTERNAL_ALLOCATION: uvmIoctlHasFrontendFD[nvgpu.UVM_MAP_EXTERNAL_ALLOCATION_PARAMS],
|
||||
nvgpu.UVM_FREE: uvmIoctlSimple[nvgpu.UVM_FREE_PARAMS],
|
||||
nvgpu.UVM_REGISTER_GPU: uvmIoctlHasFrontendFD[nvgpu.UVM_REGISTER_GPU_PARAMS],
|
||||
nvgpu.UVM_UNREGISTER_GPU: uvmIoctlSimple[nvgpu.UVM_UNREGISTER_GPU_PARAMS],
|
||||
nvgpu.UVM_PAGEABLE_MEM_ACCESS: uvmIoctlSimple[nvgpu.UVM_PAGEABLE_MEM_ACCESS_PARAMS],
|
||||
nvgpu.UVM_SET_PREFERRED_LOCATION: uvmIoctlSimple[nvgpu.UVM_SET_PREFERRED_LOCATION_PARAMS],
|
||||
nvgpu.UVM_UNSET_PREFERRED_LOCATION: uvmIoctlSimple[nvgpu.UVM_UNSET_PREFERRED_LOCATION_PARAMS],
|
||||
nvgpu.UVM_DISABLE_READ_DUPLICATION: uvmIoctlSimple[nvgpu.UVM_DISABLE_READ_DUPLICATION_PARAMS],
|
||||
nvgpu.UVM_UNSET_ACCESSED_BY: uvmIoctlSimple[nvgpu.UVM_UNSET_ACCESSED_BY_PARAMS],
|
||||
nvgpu.UVM_MIGRATE: uvmIoctlSimple[nvgpu.UVM_MIGRATE_PARAMS],
|
||||
nvgpu.UVM_MIGRATE_RANGE_GROUP: uvmIoctlSimple[nvgpu.UVM_MIGRATE_RANGE_GROUP_PARAMS],
|
||||
nvgpu.UVM_MAP_DYNAMIC_PARALLELISM_REGION: uvmIoctlSimple[nvgpu.UVM_MAP_DYNAMIC_PARALLELISM_REGION_PARAMS],
|
||||
nvgpu.UVM_UNMAP_EXTERNAL: uvmIoctlSimple[nvgpu.UVM_UNMAP_EXTERNAL_PARAMS],
|
||||
nvgpu.UVM_ALLOC_SEMAPHORE_POOL: uvmIoctlSimple[nvgpu.UVM_ALLOC_SEMAPHORE_POOL_PARAMS],
|
||||
nvgpu.UVM_VALIDATE_VA_RANGE: uvmIoctlSimple[nvgpu.UVM_VALIDATE_VA_RANGE_PARAMS],
|
||||
nvgpu.UVM_CREATE_EXTERNAL_RANGE: uvmIoctlSimple[nvgpu.UVM_CREATE_EXTERNAL_RANGE_PARAMS],
|
||||
nvgpu.UVM_MM_INITIALIZE: uvmMMInitialize,
|
||||
nvgpu.UVM_INITIALIZE: uvmHandler(uvmInitialize, compUtil),
|
||||
nvgpu.UVM_DEINITIALIZE: uvmHandler(uvmIoctlNoParams, compUtil),
|
||||
nvgpu.UVM_CREATE_RANGE_GROUP: uvmHandler(uvmIoctlSimple[nvgpu.UVM_CREATE_RANGE_GROUP_PARAMS], compUtil),
|
||||
nvgpu.UVM_DESTROY_RANGE_GROUP: uvmHandler(uvmIoctlSimple[nvgpu.UVM_DESTROY_RANGE_GROUP_PARAMS], compUtil),
|
||||
nvgpu.UVM_REGISTER_GPU_VASPACE: uvmHandler(uvmIoctlHasFrontendFD[nvgpu.UVM_REGISTER_GPU_VASPACE_PARAMS], compUtil),
|
||||
nvgpu.UVM_UNREGISTER_GPU_VASPACE: uvmHandler(uvmIoctlSimple[nvgpu.UVM_UNREGISTER_GPU_VASPACE_PARAMS], compUtil),
|
||||
nvgpu.UVM_REGISTER_CHANNEL: uvmHandler(uvmIoctlHasFrontendFD[nvgpu.UVM_REGISTER_CHANNEL_PARAMS], compUtil),
|
||||
nvgpu.UVM_UNREGISTER_CHANNEL: uvmHandler(uvmIoctlSimple[nvgpu.UVM_UNREGISTER_CHANNEL_PARAMS], compUtil),
|
||||
nvgpu.UVM_ENABLE_PEER_ACCESS: uvmHandler(uvmIoctlSimple[nvgpu.UVM_ENABLE_PEER_ACCESS_PARAMS], compUtil),
|
||||
nvgpu.UVM_DISABLE_PEER_ACCESS: uvmHandler(uvmIoctlSimple[nvgpu.UVM_DISABLE_PEER_ACCESS_PARAMS], compUtil),
|
||||
nvgpu.UVM_SET_RANGE_GROUP: uvmHandler(uvmIoctlSimple[nvgpu.UVM_SET_RANGE_GROUP_PARAMS], compUtil),
|
||||
nvgpu.UVM_MAP_EXTERNAL_ALLOCATION: uvmHandler(uvmIoctlHasFrontendFD[nvgpu.UVM_MAP_EXTERNAL_ALLOCATION_PARAMS], compUtil),
|
||||
nvgpu.UVM_FREE: uvmHandler(uvmIoctlSimple[nvgpu.UVM_FREE_PARAMS], compUtil),
|
||||
nvgpu.UVM_REGISTER_GPU: uvmHandler(uvmIoctlHasFrontendFD[nvgpu.UVM_REGISTER_GPU_PARAMS], compUtil),
|
||||
nvgpu.UVM_UNREGISTER_GPU: uvmHandler(uvmIoctlSimple[nvgpu.UVM_UNREGISTER_GPU_PARAMS], compUtil),
|
||||
nvgpu.UVM_PAGEABLE_MEM_ACCESS: uvmHandler(uvmIoctlSimple[nvgpu.UVM_PAGEABLE_MEM_ACCESS_PARAMS], compUtil),
|
||||
nvgpu.UVM_SET_PREFERRED_LOCATION: uvmHandler(uvmIoctlSimple[nvgpu.UVM_SET_PREFERRED_LOCATION_PARAMS], compUtil),
|
||||
nvgpu.UVM_UNSET_PREFERRED_LOCATION: uvmHandler(uvmIoctlSimple[nvgpu.UVM_UNSET_PREFERRED_LOCATION_PARAMS], compUtil),
|
||||
nvgpu.UVM_DISABLE_READ_DUPLICATION: uvmHandler(uvmIoctlSimple[nvgpu.UVM_DISABLE_READ_DUPLICATION_PARAMS], compUtil),
|
||||
nvgpu.UVM_UNSET_ACCESSED_BY: uvmHandler(uvmIoctlSimple[nvgpu.UVM_UNSET_ACCESSED_BY_PARAMS], compUtil),
|
||||
nvgpu.UVM_MIGRATE: uvmHandler(uvmIoctlSimple[nvgpu.UVM_MIGRATE_PARAMS], compUtil),
|
||||
nvgpu.UVM_MIGRATE_RANGE_GROUP: uvmHandler(uvmIoctlSimple[nvgpu.UVM_MIGRATE_RANGE_GROUP_PARAMS], compUtil),
|
||||
nvgpu.UVM_MAP_DYNAMIC_PARALLELISM_REGION: uvmHandler(uvmIoctlSimple[nvgpu.UVM_MAP_DYNAMIC_PARALLELISM_REGION_PARAMS], compUtil),
|
||||
nvgpu.UVM_UNMAP_EXTERNAL: uvmHandler(uvmIoctlSimple[nvgpu.UVM_UNMAP_EXTERNAL_PARAMS], compUtil),
|
||||
nvgpu.UVM_ALLOC_SEMAPHORE_POOL: uvmHandler(uvmIoctlSimple[nvgpu.UVM_ALLOC_SEMAPHORE_POOL_PARAMS], compUtil),
|
||||
nvgpu.UVM_VALIDATE_VA_RANGE: uvmHandler(uvmIoctlSimple[nvgpu.UVM_VALIDATE_VA_RANGE_PARAMS], compUtil),
|
||||
nvgpu.UVM_CREATE_EXTERNAL_RANGE: uvmHandler(uvmIoctlSimple[nvgpu.UVM_CREATE_EXTERNAL_RANGE_PARAMS], compUtil),
|
||||
nvgpu.UVM_MM_INITIALIZE: uvmHandler(uvmMMInitialize, compUtil),
|
||||
},
|
||||
controlCmd: map[uint32]controlCmdHandler{
|
||||
nvgpu.NV0000_CTRL_CMD_CLIENT_GET_ADDR_SPACE_TYPE: rmControlSimple,
|
||||
nvgpu.NV0000_CTRL_CMD_CLIENT_SET_INHERITED_SHARE_POLICY: rmControlSimple,
|
||||
nvgpu.NV0000_CTRL_CMD_GPU_GET_ATTACHED_IDS: rmControlSimple,
|
||||
nvgpu.NV0000_CTRL_CMD_GPU_GET_ID_INFO_V2: rmControlSimple,
|
||||
nvgpu.NV0000_CTRL_CMD_GPU_GET_PROBED_IDS: rmControlSimple,
|
||||
nvgpu.NV0000_CTRL_CMD_GPU_ATTACH_IDS: rmControlSimple,
|
||||
nvgpu.NV0000_CTRL_CMD_GPU_DETACH_IDS: rmControlSimple,
|
||||
nvgpu.NV0000_CTRL_CMD_GPU_GET_PCI_INFO: rmControlSimple,
|
||||
nvgpu.NV0000_CTRL_CMD_GPU_QUERY_DRAIN_STATE: rmControlSimple,
|
||||
nvgpu.NV0000_CTRL_CMD_GPU_GET_MEMOP_ENABLE: rmControlSimple,
|
||||
nvgpu.NV0000_CTRL_CMD_SYNC_GPU_BOOST_GROUP_INFO: rmControlSimple,
|
||||
nvgpu.NV0000_CTRL_CMD_SYSTEM_GET_P2P_CAPS_V2: rmControlSimple,
|
||||
nvgpu.NV0000_CTRL_CMD_SYSTEM_GET_FABRIC_STATUS: rmControlSimple,
|
||||
nvgpu.NV0000_CTRL_CMD_SYSTEM_GET_P2P_CAPS_MATRIX: rmControlSimple,
|
||||
nvgpu.NV0000_CTRL_CMD_SYSTEM_GET_FEATURES: rmControlSimple,
|
||||
nvgpu.NV0080_CTRL_CMD_FB_GET_CAPS_V2: rmControlSimple,
|
||||
nvgpu.NV0080_CTRL_CMD_GPU_GET_NUM_SUBDEVICES: rmControlSimple,
|
||||
nvgpu.NV0080_CTRL_CMD_GPU_QUERY_SW_STATE_PERSISTENCE: rmControlSimple,
|
||||
nvgpu.NV0080_CTRL_CMD_GPU_GET_VIRTUALIZATION_MODE: rmControlSimple,
|
||||
0x80028b: rmControlSimple, // unknown, paramsSize == 1
|
||||
nvgpu.NV0080_CTRL_CMD_GPU_GET_CLASSLIST_V2: rmControlSimple,
|
||||
nvgpu.NV0080_CTRL_CMD_HOST_GET_CAPS_V2: rmControlSimple,
|
||||
nvgpu.NV00F8_CTRL_CMD_ATTACH_MEM: rmControlSimple,
|
||||
nvgpu.NV00FD_CTRL_CMD_GET_INFO: rmControlSimple,
|
||||
nvgpu.NV00FD_CTRL_CMD_ATTACH_MEM: rmControlSimple,
|
||||
nvgpu.NV00FD_CTRL_CMD_DETACH_MEM: rmControlSimple,
|
||||
nvgpu.NV2080_CTRL_CMD_BUS_GET_PCI_INFO: rmControlSimple,
|
||||
nvgpu.NV2080_CTRL_CMD_BUS_GET_PCI_BAR_INFO: rmControlSimple,
|
||||
nvgpu.NV2080_CTRL_CMD_BUS_GET_INFO_V2: rmControlSimple,
|
||||
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,
|
||||
nvgpu.NV2080_CTRL_CMD_GPU_GET_NAME_STRING: rmControlSimple,
|
||||
nvgpu.NV2080_CTRL_CMD_GPU_GET_SHORT_NAME_STRING: rmControlSimple,
|
||||
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_QUERY_ECC_CONFIGURATION: 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_OBJECT_VERSION: rmControlSimple,
|
||||
nvgpu.NV2080_CTRL_CMD_GPU_GET_INFOROM_IMAGE_VERSION: rmControlSimple,
|
||||
nvgpu.NV2080_CTRL_CMD_GPU_QUERY_INFOROM_ECC_SUPPORT: 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,
|
||||
nvgpu.NV2080_CTRL_CMD_GR_GET_CTX_BUFFER_SIZE: rmControlSimple,
|
||||
nvgpu.NV2080_CTRL_CMD_GR_GET_GLOBAL_SM_ORDER: rmControlSimple,
|
||||
nvgpu.NV2080_CTRL_CMD_GR_GET_CAPS_V2: rmControlSimple,
|
||||
nvgpu.NV2080_CTRL_CMD_GR_GET_GPC_MASK: rmControlSimple,
|
||||
nvgpu.NV2080_CTRL_CMD_GR_GET_TPC_MASK: rmControlSimple,
|
||||
nvgpu.NV2080_CTRL_CMD_GR_GET_SM_ISSUE_RATE_MODIFIER: rmControlSimple,
|
||||
nvgpu.NV2080_CTRL_CMD_GRMGR_GET_GR_FS_INFO: rmControlSimple,
|
||||
nvgpu.NV2080_CTRL_CMD_GSP_GET_FEATURES: rmControlSimple,
|
||||
nvgpu.NV2080_CTRL_CMD_MC_GET_ARCH_INFO: rmControlSimple,
|
||||
nvgpu.NV2080_CTRL_CMD_MC_SERVICE_INTERRUPTS: rmControlSimple,
|
||||
nvgpu.NV2080_CTRL_CMD_NVLINK_GET_NVLINK_CAPS: rmControlSimple,
|
||||
nvgpu.NV2080_CTRL_CMD_NVLINK_GET_NVLINK_STATUS: rmControlSimple,
|
||||
nvgpu.NV2080_CTRL_CMD_PERF_BOOST: rmControlSimple,
|
||||
nvgpu.NV2080_CTRL_CMD_RC_GET_WATCHDOG_INFO: rmControlSimple,
|
||||
nvgpu.NV2080_CTRL_CMD_RC_RELEASE_WATCHDOG_REQUESTS: rmControlSimple,
|
||||
nvgpu.NV2080_CTRL_CMD_RC_SOFT_DISABLE_WATCHDOG: rmControlSimple,
|
||||
nvgpu.NV2080_CTRL_CMD_TIMER_GET_GPU_CPU_TIME_CORRELATION_INFO: rmControlSimple,
|
||||
nvgpu.NV2080_CTRL_CMD_TIMER_SET_GR_TICK_FREQ: rmControlSimple,
|
||||
nvgpu.NV503C_CTRL_CMD_REGISTER_VIDMEM: rmControlSimple,
|
||||
nvgpu.NV503C_CTRL_CMD_UNREGISTER_VIDMEM: rmControlSimple,
|
||||
nvgpu.NV83DE_CTRL_CMD_DEBUG_SET_EXCEPTION_MASK: rmControlSimple,
|
||||
nvgpu.NV83DE_CTRL_CMD_DEBUG_READ_ALL_SM_ERROR_STATES: rmControlSimple,
|
||||
nvgpu.NV83DE_CTRL_CMD_DEBUG_CLEAR_ALL_SM_ERROR_STATES: rmControlSimple,
|
||||
nvgpu.NV906F_CTRL_GET_CLASS_ENGINEID: rmControlSimple,
|
||||
nvgpu.NV906F_CTRL_CMD_RESET_CHANNEL: rmControlSimple,
|
||||
nvgpu.NV90E6_CTRL_CMD_MASTER_GET_VIRTUAL_FUNCTION_ERROR_CONT_INTR_MASK: rmControlSimple,
|
||||
nvgpu.NVC36F_CTRL_GET_CLASS_ENGINEID: rmControlSimple,
|
||||
nvgpu.NVC36F_CTRL_CMD_GPFIFO_GET_WORK_SUBMIT_TOKEN: rmControlSimple,
|
||||
nvgpu.NV_CONF_COMPUTE_CTRL_CMD_SYSTEM_GET_CAPABILITIES: rmControlSimple,
|
||||
nvgpu.NV_CONF_COMPUTE_CTRL_CMD_SYSTEM_GET_GPUS_STATE: rmControlSimple,
|
||||
nvgpu.NV_CONF_COMPUTE_CTRL_CMD_GPU_GET_NUM_SECURE_CHANNELS: rmControlSimple,
|
||||
nvgpu.NVA06C_CTRL_CMD_GPFIFO_SCHEDULE: rmControlSimple,
|
||||
nvgpu.NVA06C_CTRL_CMD_SET_TIMESLICE: rmControlSimple,
|
||||
nvgpu.NVA06C_CTRL_CMD_PREEMPT: rmControlSimple,
|
||||
nvgpu.NVA06F_CTRL_CMD_GPFIFO_SCHEDULE: rmControlSimple,
|
||||
nvgpu.NVC56F_CTRL_CMD_GET_KMB: rmControlSimple,
|
||||
nvgpu.NV0000_CTRL_CMD_GPU_GET_ID_INFO: ctrlGpuGetIDInfo,
|
||||
nvgpu.NV0000_CTRL_CMD_SYSTEM_GET_BUILD_VERSION: ctrlClientSystemGetBuildVersion,
|
||||
nvgpu.NV0000_CTRL_CMD_SYSTEM_GET_P2P_CAPS: ctrlClientSystemGetP2PCaps,
|
||||
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: 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_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,
|
||||
nvgpu.NV0000_CTRL_CMD_CLIENT_GET_ADDR_SPACE_TYPE: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV0000_CTRL_CMD_CLIENT_SET_INHERITED_SHARE_POLICY: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV0000_CTRL_CMD_GPU_GET_ATTACHED_IDS: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV0000_CTRL_CMD_GPU_GET_ID_INFO_V2: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV0000_CTRL_CMD_GPU_GET_PROBED_IDS: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV0000_CTRL_CMD_GPU_ATTACH_IDS: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV0000_CTRL_CMD_GPU_DETACH_IDS: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV0000_CTRL_CMD_GPU_GET_PCI_INFO: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV0000_CTRL_CMD_GPU_QUERY_DRAIN_STATE: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV0000_CTRL_CMD_GPU_GET_MEMOP_ENABLE: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV0000_CTRL_CMD_SYNC_GPU_BOOST_GROUP_INFO: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV0000_CTRL_CMD_SYSTEM_GET_P2P_CAPS_V2: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV0000_CTRL_CMD_SYSTEM_GET_FABRIC_STATUS: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV0000_CTRL_CMD_SYSTEM_GET_P2P_CAPS_MATRIX: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV0000_CTRL_CMD_SYSTEM_GET_FEATURES: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV0080_CTRL_CMD_FB_GET_CAPS_V2: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV0080_CTRL_CMD_GPU_GET_NUM_SUBDEVICES: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV0080_CTRL_CMD_GPU_QUERY_SW_STATE_PERSISTENCE: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV0080_CTRL_CMD_GPU_GET_VIRTUALIZATION_MODE: ctrlHandler(rmControlSimple, compUtil),
|
||||
0x80028b: ctrlHandler(rmControlSimple, compUtil), // unknown, paramsSize == 1
|
||||
nvgpu.NV0080_CTRL_CMD_GPU_GET_CLASSLIST_V2: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV0080_CTRL_CMD_HOST_GET_CAPS_V2: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV00F8_CTRL_CMD_ATTACH_MEM: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV00FD_CTRL_CMD_GET_INFO: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV00FD_CTRL_CMD_ATTACH_MEM: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV00FD_CTRL_CMD_DETACH_MEM: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_BUS_GET_PCI_INFO: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_BUS_GET_PCI_BAR_INFO: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_BUS_GET_INFO_V2: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_BUS_GET_PCIE_SUPPORTED_GPU_ATOMICS: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_BUS_GET_C2C_INFO: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_CE_GET_ALL_CAPS: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_EVENT_SET_NOTIFICATION: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_FB_GET_INFO_V2: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_GPU_GET_INFO_V2: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_FLCN_GET_CTX_BUFFER_SIZE: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_GPU_GET_NAME_STRING: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_GPU_GET_SHORT_NAME_STRING: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_GPU_GET_SIMULATION_INFO: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_GPU_QUERY_ECC_STATUS: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_GPU_QUERY_COMPUTE_MODE_RULES: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_GPU_QUERY_ECC_CONFIGURATION: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_GPU_GET_OEM_BOARD_INFO: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_GPU_ACQUIRE_COMPUTE_MODE_RESERVATION: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_GPU_RELEASE_COMPUTE_MODE_RESERVATION: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_GPU_GET_GID_INFO: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_GPU_GET_INFOROM_OBJECT_VERSION: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_GPU_GET_INFOROM_IMAGE_VERSION: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_GPU_QUERY_INFOROM_ECC_SUPPORT: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_GPU_GET_ENGINES_V2: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_GPU_GET_ACTIVE_PARTITION_IDS: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_GPU_GET_PIDS: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_GPU_GET_PID_INFO: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_GPU_GET_COMPUTE_POLICY_CONFIG: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_GET_GPU_FABRIC_PROBE_INFO: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_GR_SET_CTXSW_PREEMPTION_MODE: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_GR_GET_CTX_BUFFER_SIZE: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_GR_GET_GLOBAL_SM_ORDER: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_GR_GET_CAPS_V2: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_GR_GET_GPC_MASK: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_GR_GET_TPC_MASK: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_GR_GET_SM_ISSUE_RATE_MODIFIER: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_GRMGR_GET_GR_FS_INFO: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_GSP_GET_FEATURES: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_MC_GET_ARCH_INFO: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_MC_SERVICE_INTERRUPTS: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_NVLINK_GET_NVLINK_CAPS: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_NVLINK_GET_NVLINK_STATUS: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_PERF_BOOST: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_RC_GET_WATCHDOG_INFO: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_RC_RELEASE_WATCHDOG_REQUESTS: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_RC_SOFT_DISABLE_WATCHDOG: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_TIMER_GET_GPU_CPU_TIME_CORRELATION_INFO: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_TIMER_SET_GR_TICK_FREQ: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV503C_CTRL_CMD_REGISTER_VIDMEM: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV503C_CTRL_CMD_UNREGISTER_VIDMEM: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV83DE_CTRL_CMD_DEBUG_SET_EXCEPTION_MASK: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV83DE_CTRL_CMD_DEBUG_READ_ALL_SM_ERROR_STATES: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV83DE_CTRL_CMD_DEBUG_CLEAR_ALL_SM_ERROR_STATES: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV906F_CTRL_GET_CLASS_ENGINEID: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV906F_CTRL_CMD_RESET_CHANNEL: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV90E6_CTRL_CMD_MASTER_GET_VIRTUAL_FUNCTION_ERROR_CONT_INTR_MASK: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NVC36F_CTRL_GET_CLASS_ENGINEID: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NVC36F_CTRL_CMD_GPFIFO_GET_WORK_SUBMIT_TOKEN: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV_CONF_COMPUTE_CTRL_CMD_SYSTEM_GET_CAPABILITIES: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV_CONF_COMPUTE_CTRL_CMD_SYSTEM_GET_GPUS_STATE: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV_CONF_COMPUTE_CTRL_CMD_GPU_GET_NUM_SECURE_CHANNELS: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NVA06C_CTRL_CMD_GPFIFO_SCHEDULE: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NVA06C_CTRL_CMD_SET_TIMESLICE: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NVA06C_CTRL_CMD_PREEMPT: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NVA06F_CTRL_CMD_GPFIFO_SCHEDULE: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NVC56F_CTRL_CMD_GET_KMB: ctrlHandler(rmControlSimple, compUtil),
|
||||
nvgpu.NV0000_CTRL_CMD_GPU_GET_ID_INFO: ctrlHandler(ctrlGpuGetIDInfo, compUtil),
|
||||
nvgpu.NV0000_CTRL_CMD_SYSTEM_GET_BUILD_VERSION: ctrlHandler(ctrlClientSystemGetBuildVersion, compUtil),
|
||||
nvgpu.NV0000_CTRL_CMD_SYSTEM_GET_P2P_CAPS: ctrlHandler(ctrlClientSystemGetP2PCaps, compUtil),
|
||||
nvgpu.NV0000_CTRL_CMD_OS_UNIX_EXPORT_OBJECT_TO_FD: ctrlHandler(ctrlHasFrontendFD[nvgpu.NV0000_CTRL_OS_UNIX_EXPORT_OBJECT_TO_FD_PARAMS], compUtil),
|
||||
nvgpu.NV0000_CTRL_CMD_OS_UNIX_IMPORT_OBJECT_FROM_FD: ctrlHandler(ctrlHasFrontendFD[nvgpu.NV0000_CTRL_OS_UNIX_IMPORT_OBJECT_FROM_FD_PARAMS], compUtil),
|
||||
nvgpu.NV0000_CTRL_CMD_OS_UNIX_GET_EXPORT_OBJECT_INFO: ctrlHandler(ctrlHasFrontendFD[nvgpu.NV0000_CTRL_OS_UNIX_GET_EXPORT_OBJECT_INFO_PARAMS], compUtil),
|
||||
nvgpu.NV0041_CTRL_CMD_GET_SURFACE_INFO: ctrlHandler(ctrlIoctlHasInfoList[nvgpu.NV0041_CTRL_GET_SURFACE_INFO_PARAMS], compUtil),
|
||||
nvgpu.NV0080_CTRL_CMD_FIFO_GET_CHANNELLIST: ctrlHandler(ctrlDevFIFOGetChannelList, compUtil),
|
||||
nvgpu.NV00FD_CTRL_CMD_ATTACH_GPU: ctrlHandler(ctrlMemoryMulticastFabricAttachGPU, compUtil),
|
||||
nvgpu.NV0080_CTRL_CMD_GPU_GET_CLASSLIST: ctrlHandler(ctrlDevGpuGetClasslist, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_FIFO_DISABLE_CHANNELS: ctrlHandler(ctrlSubdevFIFODisableChannels, compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_BIOS_GET_INFO: ctrlHandler(ctrlIoctlHasInfoList[nvgpu.NV2080_CTRL_BIOS_GET_INFO_PARAMS], compUtil),
|
||||
nvgpu.NV2080_CTRL_CMD_GR_GET_INFO: ctrlHandler(ctrlIoctlHasInfoList[nvgpu.NV2080_CTRL_GR_GET_INFO_PARAMS], compUtil),
|
||||
nvgpu.NV503C_CTRL_CMD_REGISTER_VA_SPACE: ctrlHandler(ctrlRegisterVASpace, compUtil),
|
||||
},
|
||||
allocationClass: map[nvgpu.ClassID]allocationClassHandler{
|
||||
nvgpu.NV01_ROOT: rmAllocRootClient,
|
||||
nvgpu.NV01_ROOT_NON_PRIV: rmAllocRootClient,
|
||||
nvgpu.NV01_MEMORY_SYSTEM: rmAllocSimple[nvgpu.NV_MEMORY_ALLOCATION_PARAMS],
|
||||
nvgpu.NV01_MEMORY_LOCAL_USER: rmAllocSimple[nvgpu.NV_MEMORY_ALLOCATION_PARAMS],
|
||||
nvgpu.NV01_ROOT_CLIENT: rmAllocRootClient,
|
||||
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],
|
||||
nvgpu.NV50_MEMORY_VIRTUAL: rmAllocSimple[nvgpu.NV_MEMORY_ALLOCATION_PARAMS],
|
||||
nvgpu.NV50_P2P: rmAllocSimple[nvgpu.NV503B_ALLOC_PARAMETERS],
|
||||
nvgpu.NV50_THIRD_PARTY_P2P: rmAllocSimple[nvgpu.NV503C_ALLOC_PARAMETERS],
|
||||
nvgpu.GF100_PROFILER: rmAllocNoParams,
|
||||
nvgpu.GT200_DEBUGGER: rmAllocSMDebuggerSession,
|
||||
nvgpu.FERMI_CONTEXT_SHARE_A: rmAllocContextShare,
|
||||
nvgpu.FERMI_VASPACE_A: rmAllocSimple[nvgpu.NV_VASPACE_ALLOCATION_PARAMETERS],
|
||||
nvgpu.KEPLER_CHANNEL_GROUP_A: rmAllocChannelGroup,
|
||||
nvgpu.TURING_CHANNEL_GPFIFO_A: rmAllocChannel,
|
||||
nvgpu.AMPERE_CHANNEL_GPFIFO_A: rmAllocChannel,
|
||||
nvgpu.HOPPER_CHANNEL_GPFIFO_A: rmAllocChannel,
|
||||
nvgpu.TURING_DMA_COPY_A: rmAllocSimple[nvgpu.NVB0B5_ALLOCATION_PARAMETERS],
|
||||
nvgpu.AMPERE_DMA_COPY_A: rmAllocSimple[nvgpu.NVB0B5_ALLOCATION_PARAMETERS],
|
||||
nvgpu.AMPERE_DMA_COPY_B: rmAllocSimple[nvgpu.NVB0B5_ALLOCATION_PARAMETERS],
|
||||
nvgpu.HOPPER_DMA_COPY_A: rmAllocSimple[nvgpu.NVB0B5_ALLOCATION_PARAMETERS],
|
||||
nvgpu.TURING_COMPUTE_A: rmAllocSimple[nvgpu.NV_GR_ALLOCATION_PARAMETERS],
|
||||
nvgpu.AMPERE_COMPUTE_A: rmAllocSimple[nvgpu.NV_GR_ALLOCATION_PARAMETERS],
|
||||
nvgpu.AMPERE_COMPUTE_B: rmAllocSimple[nvgpu.NV_GR_ALLOCATION_PARAMETERS],
|
||||
nvgpu.ADA_COMPUTE_A: rmAllocSimple[nvgpu.NV_GR_ALLOCATION_PARAMETERS],
|
||||
nvgpu.NV_CONFIDENTIAL_COMPUTE: rmAllocSimple[nvgpu.NV_CONFIDENTIAL_COMPUTE_ALLOC_PARAMS],
|
||||
nvgpu.HOPPER_COMPUTE_A: rmAllocSimple[nvgpu.NV_GR_ALLOCATION_PARAMETERS],
|
||||
nvgpu.HOPPER_USERMODE_A: rmAllocSimple[nvgpu.NV_HOPPER_USERMODE_A_PARAMS],
|
||||
nvgpu.GF100_SUBDEVICE_MASTER: rmAllocNoParams,
|
||||
nvgpu.TURING_USERMODE_A: rmAllocNoParams,
|
||||
nvgpu.HOPPER_SEC2_WORK_LAUNCH_A: rmAllocNoParams,
|
||||
nvgpu.NV01_ROOT: allocHandler(rmAllocRootClient, compUtil),
|
||||
nvgpu.NV01_ROOT_NON_PRIV: allocHandler(rmAllocRootClient, compUtil),
|
||||
nvgpu.NV01_MEMORY_SYSTEM: allocHandler(rmAllocSimple[nvgpu.NV_MEMORY_ALLOCATION_PARAMS], compUtil),
|
||||
nvgpu.NV01_MEMORY_LOCAL_USER: allocHandler(rmAllocSimple[nvgpu.NV_MEMORY_ALLOCATION_PARAMS], compUtil),
|
||||
nvgpu.NV01_ROOT_CLIENT: allocHandler(rmAllocRootClient, compUtil),
|
||||
nvgpu.NV01_EVENT_OS_EVENT: allocHandler(rmAllocEventOSEvent, compUtil),
|
||||
nvgpu.NV2081_BINAPI: allocHandler(rmAllocSimple[nvgpu.NV2081_ALLOC_PARAMETERS], compUtil),
|
||||
nvgpu.NV01_DEVICE_0: allocHandler(rmAllocSimple[nvgpu.NV0080_ALLOC_PARAMETERS], compUtil),
|
||||
nvgpu.RM_USER_SHARED_DATA: allocHandler(rmAllocSimple[nvgpu.NV00DE_ALLOC_PARAMETERS], compUtil),
|
||||
nvgpu.NV_MEMORY_FABRIC: allocHandler(rmAllocSimple[nvgpu.NV00F8_ALLOCATION_PARAMETERS], compUtil),
|
||||
nvgpu.NV_MEMORY_MULTICAST_FABRIC: allocHandler(rmAllocSimple[nvgpu.NV00FD_ALLOCATION_PARAMETERS], compUtil),
|
||||
nvgpu.NV20_SUBDEVICE_0: allocHandler(rmAllocSimple[nvgpu.NV2080_ALLOC_PARAMETERS], compUtil),
|
||||
nvgpu.NV50_MEMORY_VIRTUAL: allocHandler(rmAllocSimple[nvgpu.NV_MEMORY_ALLOCATION_PARAMS], compUtil),
|
||||
nvgpu.NV50_P2P: allocHandler(rmAllocSimple[nvgpu.NV503B_ALLOC_PARAMETERS], compUtil),
|
||||
nvgpu.NV50_THIRD_PARTY_P2P: allocHandler(rmAllocSimple[nvgpu.NV503C_ALLOC_PARAMETERS], compUtil),
|
||||
nvgpu.GF100_PROFILER: allocHandler(rmAllocNoParams, compUtil),
|
||||
nvgpu.GT200_DEBUGGER: allocHandler(rmAllocSMDebuggerSession, compUtil),
|
||||
nvgpu.FERMI_CONTEXT_SHARE_A: allocHandler(rmAllocContextShare, compUtil),
|
||||
nvgpu.FERMI_VASPACE_A: allocHandler(rmAllocSimple[nvgpu.NV_VASPACE_ALLOCATION_PARAMETERS], compUtil),
|
||||
nvgpu.KEPLER_CHANNEL_GROUP_A: allocHandler(rmAllocChannelGroup, compUtil),
|
||||
nvgpu.TURING_CHANNEL_GPFIFO_A: allocHandler(rmAllocChannel, compUtil),
|
||||
nvgpu.AMPERE_CHANNEL_GPFIFO_A: allocHandler(rmAllocChannel, compUtil),
|
||||
nvgpu.HOPPER_CHANNEL_GPFIFO_A: allocHandler(rmAllocChannel, compUtil),
|
||||
nvgpu.TURING_DMA_COPY_A: allocHandler(rmAllocSimple[nvgpu.NVB0B5_ALLOCATION_PARAMETERS], compUtil),
|
||||
nvgpu.AMPERE_DMA_COPY_A: allocHandler(rmAllocSimple[nvgpu.NVB0B5_ALLOCATION_PARAMETERS], compUtil),
|
||||
nvgpu.AMPERE_DMA_COPY_B: allocHandler(rmAllocSimple[nvgpu.NVB0B5_ALLOCATION_PARAMETERS], compUtil),
|
||||
nvgpu.HOPPER_DMA_COPY_A: allocHandler(rmAllocSimple[nvgpu.NVB0B5_ALLOCATION_PARAMETERS], compUtil),
|
||||
nvgpu.TURING_COMPUTE_A: allocHandler(rmAllocSimple[nvgpu.NV_GR_ALLOCATION_PARAMETERS], compUtil),
|
||||
nvgpu.AMPERE_COMPUTE_A: allocHandler(rmAllocSimple[nvgpu.NV_GR_ALLOCATION_PARAMETERS], compUtil),
|
||||
nvgpu.AMPERE_COMPUTE_B: allocHandler(rmAllocSimple[nvgpu.NV_GR_ALLOCATION_PARAMETERS], compUtil),
|
||||
nvgpu.ADA_COMPUTE_A: allocHandler(rmAllocSimple[nvgpu.NV_GR_ALLOCATION_PARAMETERS], compUtil),
|
||||
nvgpu.NV_CONFIDENTIAL_COMPUTE: allocHandler(rmAllocSimple[nvgpu.NV_CONFIDENTIAL_COMPUTE_ALLOC_PARAMS], compUtil),
|
||||
nvgpu.HOPPER_COMPUTE_A: allocHandler(rmAllocSimple[nvgpu.NV_GR_ALLOCATION_PARAMETERS], compUtil),
|
||||
nvgpu.HOPPER_USERMODE_A: allocHandler(rmAllocSimple[nvgpu.NV_HOPPER_USERMODE_A_PARAMS], compUtil),
|
||||
nvgpu.GF100_SUBDEVICE_MASTER: allocHandler(rmAllocNoParams, compUtil),
|
||||
nvgpu.TURING_USERMODE_A: allocHandler(rmAllocNoParams, compUtil),
|
||||
nvgpu.HOPPER_SEC2_WORK_LAUNCH_A: allocHandler(rmAllocNoParams, compUtil),
|
||||
},
|
||||
|
||||
getStructNames: func() *driverStructNames {
|
||||
@@ -594,12 +595,12 @@ 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.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]
|
||||
abi.allocationClass[nvgpu.NV50_MEMORY_VIRTUAL] = rmAllocSimple[nvgpu.NV_MEMORY_ALLOCATION_PARAMS_V545]
|
||||
abi.controlCmd[nvgpu.NV0000_CTRL_CMD_OS_UNIX_GET_EXPORT_OBJECT_INFO] = ctrlHandler(ctrlHasFrontendFD[nvgpu.NV0000_CTRL_OS_UNIX_GET_EXPORT_OBJECT_INFO_PARAMS_V545], compUtil)
|
||||
abi.allocationClass[nvgpu.RM_USER_SHARED_DATA] = allocHandler(rmAllocSimple[nvgpu.NV00DE_ALLOC_PARAMETERS_V545], compUtil)
|
||||
abi.allocationClass[nvgpu.NV_MEMORY_MULTICAST_FABRIC] = allocHandler(rmAllocSimple[nvgpu.NV00FD_ALLOCATION_PARAMETERS_V545], compUtil)
|
||||
abi.allocationClass[nvgpu.NV01_MEMORY_SYSTEM] = allocHandler(rmAllocSimple[nvgpu.NV_MEMORY_ALLOCATION_PARAMS_V545], compUtil)
|
||||
abi.allocationClass[nvgpu.NV01_MEMORY_LOCAL_USER] = allocHandler(rmAllocSimple[nvgpu.NV_MEMORY_ALLOCATION_PARAMS_V545], compUtil)
|
||||
abi.allocationClass[nvgpu.NV50_MEMORY_VIRTUAL] = allocHandler(rmAllocSimple[nvgpu.NV_MEMORY_ALLOCATION_PARAMS_V545], compUtil)
|
||||
|
||||
prevNames := abi.getStructNames
|
||||
abi.getStructNames = func() *driverStructNames {
|
||||
@@ -620,17 +621,17 @@ func Init() {
|
||||
// 550.40.07 is an intermediate unqualified version from the main branch.
|
||||
v550_40_07 := func() *driverABI {
|
||||
abi := v545_23_06()
|
||||
abi.frontendIoctl[nvgpu.NV_ESC_WAIT_OPEN_COMPLETE] = frontendIoctlSimple // nv_ioctl_wait_open_complete_t
|
||||
abi.controlCmd[nvgpu.NV0000_CTRL_CMD_GPU_ASYNC_ATTACH_ID] = rmControlSimple
|
||||
abi.controlCmd[nvgpu.NV0000_CTRL_CMD_GPU_WAIT_ATTACH_ID] = rmControlSimple
|
||||
abi.controlCmd[nvgpu.NV0080_CTRL_CMD_PERF_CUDA_LIMIT_SET_CONTROL] = rmControlSimple // NV0080_CTRL_PERF_CUDA_LIMIT_CONTROL_PARAMS
|
||||
abi.controlCmd[nvgpu.NV2080_CTRL_CMD_PERF_GET_CURRENT_PSTATE] = rmControlSimple
|
||||
abi.frontendIoctl[nvgpu.NV_ESC_WAIT_OPEN_COMPLETE] = feHandler(frontendIoctlSimple, compUtil) // nv_ioctl_wait_open_complete_t
|
||||
abi.controlCmd[nvgpu.NV0000_CTRL_CMD_GPU_ASYNC_ATTACH_ID] = ctrlHandler(rmControlSimple, compUtil)
|
||||
abi.controlCmd[nvgpu.NV0000_CTRL_CMD_GPU_WAIT_ATTACH_ID] = ctrlHandler(rmControlSimple, compUtil)
|
||||
abi.controlCmd[nvgpu.NV0080_CTRL_CMD_PERF_CUDA_LIMIT_SET_CONTROL] = ctrlHandler(rmControlSimple, compUtil) // NV0080_CTRL_PERF_CUDA_LIMIT_CONTROL_PARAMS
|
||||
abi.controlCmd[nvgpu.NV2080_CTRL_CMD_PERF_GET_CURRENT_PSTATE] = ctrlHandler(rmControlSimple, compUtil)
|
||||
// NV2081_BINAPI forwards all control commands to the GSP in
|
||||
// src/nvidia/src/kernel/rmapi/binary_api.c:binapiControl_IMPL().
|
||||
abi.controlCmd[(nvgpu.NV2081_BINAPI<<16)|0x0108] = rmControlSimple
|
||||
abi.controlCmd[nvgpu.NV0000_CTRL_CMD_SYSTEM_GET_P2P_CAPS] = ctrlClientSystemGetP2PCapsV550
|
||||
abi.uvmIoctl[nvgpu.UVM_SET_PREFERRED_LOCATION] = uvmIoctlSimple[nvgpu.UVM_SET_PREFERRED_LOCATION_PARAMS_V550]
|
||||
abi.uvmIoctl[nvgpu.UVM_MIGRATE] = uvmIoctlSimple[nvgpu.UVM_MIGRATE_PARAMS_V550]
|
||||
abi.controlCmd[(nvgpu.NV2081_BINAPI<<16)|0x0108] = ctrlHandler(rmControlSimple, compUtil)
|
||||
abi.controlCmd[nvgpu.NV0000_CTRL_CMD_SYSTEM_GET_P2P_CAPS] = ctrlHandler(ctrlClientSystemGetP2PCapsV550, compUtil)
|
||||
abi.uvmIoctl[nvgpu.UVM_SET_PREFERRED_LOCATION] = uvmHandler(uvmIoctlSimple[nvgpu.UVM_SET_PREFERRED_LOCATION_PARAMS_V550], compUtil)
|
||||
abi.uvmIoctl[nvgpu.UVM_MIGRATE] = uvmHandler(uvmIoctlSimple[nvgpu.UVM_MIGRATE_PARAMS_V550], compUtil)
|
||||
|
||||
prevNames := abi.getStructNames
|
||||
abi.getStructNames = func() *driverStructNames {
|
||||
@@ -656,8 +657,8 @@ func Init() {
|
||||
|
||||
v550_54_14 := addDriverABI(550, 54, 14, "8c497ff1cfc7c310fb875149bc30faa4fd26d2237b2cba6cd2e8b0780157cfe3", func() *driverABI {
|
||||
abi := v550_40_07()
|
||||
abi.uvmIoctl[nvgpu.UVM_ALLOC_SEMAPHORE_POOL] = uvmIoctlSimple[nvgpu.UVM_ALLOC_SEMAPHORE_POOL_PARAMS_V550]
|
||||
abi.uvmIoctl[nvgpu.UVM_MAP_EXTERNAL_ALLOCATION] = uvmIoctlHasFrontendFD[nvgpu.UVM_MAP_EXTERNAL_ALLOCATION_PARAMS_V550]
|
||||
abi.uvmIoctl[nvgpu.UVM_ALLOC_SEMAPHORE_POOL] = uvmHandler(uvmIoctlSimple[nvgpu.UVM_ALLOC_SEMAPHORE_POOL_PARAMS_V550], compUtil)
|
||||
abi.uvmIoctl[nvgpu.UVM_MAP_EXTERNAL_ALLOCATION] = uvmHandler(uvmIoctlHasFrontendFD[nvgpu.UVM_MAP_EXTERNAL_ALLOCATION_PARAMS_V550], compUtil)
|
||||
|
||||
prevNames := abi.getStructNames
|
||||
abi.getStructNames = func() *driverStructNames {
|
||||
@@ -673,7 +674,7 @@ func Init() {
|
||||
|
||||
v550_90_07 := addDriverABI(550, 90, 07, "51acf579d5a9884f573a1d3f522e7fafa5e7841e22a9cec0b4bbeae31b0b9733", func() *driverABI {
|
||||
abi := v550_54_14()
|
||||
abi.controlCmd[nvgpu.NV_CONF_COMPUTE_CTRL_CMD_GPU_GET_KEY_ROTATION_STATE] = rmControlSimple
|
||||
abi.controlCmd[nvgpu.NV_CONF_COMPUTE_CTRL_CMD_GPU_GET_KEY_ROTATION_STATE] = ctrlHandler(rmControlSimple, compUtil)
|
||||
|
||||
prevNames := abi.getStructNames
|
||||
abi.getStructNames = func() *driverStructNames {
|
||||
|
||||
@@ -847,7 +847,7 @@ func (l *Loader) installSeccompFilters() error {
|
||||
HostNetworkRawSockets: hostnet && l.root.conf.EnableRaw,
|
||||
HostFilesystem: l.root.conf.DirectFS,
|
||||
ProfileEnable: l.root.conf.ProfileEnable,
|
||||
NVProxy: specutils.NVProxyEnabled(l.root.spec, l.root.conf),
|
||||
NVProxy: specutils.NVProxyEnabled(l.root.spec, l.root.conf), // TODO(gvisor.dev/issues/10856): Plumb capabilities here.
|
||||
TPUProxy: specutils.TPUProxyIsEnabled(l.root.spec, l.root.conf),
|
||||
ControllerFD: uint32(l.ctrl.srv.FD()),
|
||||
CgoEnabled: config.CgoEnabled,
|
||||
|
||||
+6
-11
@@ -419,17 +419,12 @@ func (c *Config) validate() error {
|
||||
if len(c.ProfilingMetrics) > 0 && len(c.ProfilingMetricsLog) == 0 {
|
||||
return fmt.Errorf("profiling-metrics flag requires defining a profiling-metrics-log for output")
|
||||
}
|
||||
for _, cap := range strings.Split(c.NVProxyAllowedDriverCapabilities, ",") {
|
||||
nvcap := nvconf.DriverCap(cap)
|
||||
if nvcap == nvconf.AllCap {
|
||||
continue
|
||||
}
|
||||
if _, ok := nvconf.KnownDriverCapValues[nvcap]; !ok {
|
||||
return fmt.Errorf("nvproxy-allowed-driver-capabilities contains invalid capability %q", cap)
|
||||
}
|
||||
if _, ok := nvconf.SupportedDriverCaps[nvcap]; !ok {
|
||||
log.Warningf("nvproxy-allowed-driver-capabilities contains unsupported capability %q", cap)
|
||||
}
|
||||
allowedCaps, _, err := nvconf.DriverCapsFromString(c.NVProxyAllowedDriverCapabilities)
|
||||
if err != nil {
|
||||
return fmt.Errorf("--nvproxy-allowed-driver-capabilities=%q: %w", c.NVProxyAllowedDriverCapabilities, err)
|
||||
}
|
||||
if unsupported := allowedCaps & ^nvconf.SupportedDriverCaps; unsupported != 0 {
|
||||
return fmt.Errorf("--nvproxy-allowed-driver-capabilities=%q: unsupported capabilities: %v", c.NVProxyAllowedDriverCapabilities, unsupported)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -2035,9 +2035,7 @@ func nvproxySetupAfterGoferUserns(spec *specs.Spec, conf *config.Config, goferCm
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get driver capabilities: %w", err)
|
||||
}
|
||||
for cap := range driverCaps {
|
||||
argv = append(argv, cap.ToFlag())
|
||||
}
|
||||
argv = append(argv, driverCaps.NVIDIAFlags()...)
|
||||
// Add rootfs path as the final argument.
|
||||
argv = append(argv, spec.Root.Path)
|
||||
log.Debugf("Executing %q", argv)
|
||||
|
||||
+35
-16
@@ -20,6 +20,7 @@ import (
|
||||
"strings"
|
||||
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
"gvisor.dev/gvisor/pkg/log"
|
||||
"gvisor.dev/gvisor/pkg/sentry/devices/nvproxy/nvconf"
|
||||
"gvisor.dev/gvisor/runsc/config"
|
||||
)
|
||||
@@ -148,13 +149,15 @@ func ParseNvidiaVisibleDevices(spec *specs.Spec) (string, error) {
|
||||
// nvidia-container-toolkit/cmd/nvidia-container-runtime-hook/container_config.go:getDriverCapabilities().
|
||||
func NVProxyDriverCapsFromEnv(spec *specs.Spec, conf *config.Config) (nvconf.DriverCaps, error) {
|
||||
// Construct the set of allowed driver capabilities.
|
||||
allowedDriverCaps := nvconf.DriverCapsFromString(conf.NVProxyAllowedDriverCapabilities)
|
||||
// allowedDriverCaps is already a subset of nvconf.SupportedDriverCaps
|
||||
// as this was checked by `config.Config.validate`.
|
||||
allowedDriverCaps, hasAll, err := nvconf.DriverCapsFromString(conf.NVProxyAllowedDriverCapabilities)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("invalid set of allowed NVIDIA driver capabilities %q: %w", conf.NVProxyAllowedDriverCapabilities, err)
|
||||
}
|
||||
// Resolve "all" to nvconf.SupportedDriverCaps.
|
||||
if allowedDriverCaps.HasAll() {
|
||||
delete(allowedDriverCaps, nvconf.AllCap)
|
||||
for cap := range nvconf.SupportedDriverCaps {
|
||||
allowedDriverCaps[cap] = struct{}{}
|
||||
}
|
||||
if hasAll {
|
||||
allowedDriverCaps |= nvconf.SupportedDriverCaps
|
||||
}
|
||||
|
||||
// Extract the set of driver capabilities requested by the application.
|
||||
@@ -164,21 +167,37 @@ func NVProxyDriverCapsFromEnv(spec *specs.Spec, conf *config.Config) (nvconf.Dri
|
||||
if IsLegacyCudaImage(spec) {
|
||||
return allowedDriverCaps, nil
|
||||
}
|
||||
return nvconf.DefaultDriverCaps, nil
|
||||
return nvconf.DefaultDriverCaps & allowedDriverCaps, nil
|
||||
}
|
||||
if len(driverCapsEnvStr) == 0 {
|
||||
// Empty. Fallback to nvconf.DefaultDriverCaps.
|
||||
return nvconf.DefaultDriverCaps, nil
|
||||
return nvconf.DefaultDriverCaps & allowedDriverCaps, nil
|
||||
}
|
||||
envDriverCaps := nvconf.DriverCapsFromString(driverCapsEnvStr)
|
||||
|
||||
// Intersect what's requested with what's allowed. Since allowedDriverCaps
|
||||
// doesn't contain "all", the result will also not contain "all".
|
||||
driverCaps := allowedDriverCaps.Intersect(envDriverCaps)
|
||||
if !envDriverCaps.HasAll() && len(driverCaps) != len(envDriverCaps) {
|
||||
return nil, fmt.Errorf("disallowed driver capabilities requested: '%v' (allowed '%v'), update --nvproxy-allowed-driver-capabilities to allow them", envDriverCaps, driverCaps)
|
||||
envDriverCaps, enableAll, err := nvconf.DriverCapsFromString(driverCapsEnvStr)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("invalid set of requested NVIDIA driver capabilities %q: %w", driverCapsEnvStr, err)
|
||||
}
|
||||
return driverCaps, nil
|
||||
if enableAll {
|
||||
// The "all" keyword here is confusing but we need to match the behavior of
|
||||
// nvidia-container-toolkit:cmd/nvidia-container-runtime-hook/container_config.go:getDriverCapabilities.
|
||||
// If the environment variable contains "all", the intuitive thing to do
|
||||
// would be to expand it to mean "all allowed capabilities". Rather, in
|
||||
// nvidia-container-toolkit, it means "expand to the entire set of
|
||||
// capabilities, then silently drop all disallowed or unsupported
|
||||
// capabilities from this set".
|
||||
// We aim to be drop-in compatible with this behavior so we need to
|
||||
// implement it too, but log a warning when these behaviors result in a
|
||||
// different outcome.
|
||||
if intuitiveCaps := envDriverCaps | allowedDriverCaps; intuitiveCaps != allowedDriverCaps {
|
||||
log.Warningf("Container requested NVIDIA driver capabilities %q; this expands to %v which is a larger set than allowed capabilities (%v). The extra capabilities (%v) will be dropped.", driverCapsEnvStr, intuitiveCaps, allowedDriverCaps, intuitiveCaps&^allowedDriverCaps)
|
||||
}
|
||||
return allowedDriverCaps, nil
|
||||
}
|
||||
// Intersect what's requested with what's allowed.
|
||||
if driverCaps := allowedDriverCaps & envDriverCaps; driverCaps != envDriverCaps {
|
||||
return 0, fmt.Errorf(`disallowed driver capabilities requested: "%v" (allowed "%v"), update --nvproxy-allowed-driver-capabilities to allow them`, envDriverCaps, driverCaps)
|
||||
}
|
||||
return envDriverCaps, nil
|
||||
}
|
||||
|
||||
// IsLegacyCudaImage returns true if spec represents a legacy CUDA image.
|
||||
|
||||
@@ -17,7 +17,6 @@ package specutils
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -385,61 +384,67 @@ func TestSeccomp(t *testing.T) {
|
||||
|
||||
func TestNvidiaDriverCapabilities(t *testing.T) {
|
||||
testAllowedCapsFlag := "utility,compute,graphics"
|
||||
testAllowedCaps := nvconf.DriverCapsFromString(testAllowedCapsFlag)
|
||||
testAllowedCaps, _, err := nvconf.DriverCapsFromString(testAllowedCapsFlag)
|
||||
if err != nil {
|
||||
t.Fatalf("nvconf.DriverCapsFromString(%q) failed: %v", testAllowedCapsFlag, err)
|
||||
}
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
allowedCaps string
|
||||
envCaps []nvconf.DriverCap
|
||||
noEnv bool // If true, no env variable is set.
|
||||
envCaps string
|
||||
legacy bool
|
||||
want nvconf.DriverCaps
|
||||
}{
|
||||
{
|
||||
name: "unspecified",
|
||||
allowedCaps: testAllowedCapsFlag,
|
||||
noEnv: true,
|
||||
want: nvconf.DefaultDriverCaps,
|
||||
},
|
||||
{
|
||||
name: "unspecified-legacy",
|
||||
allowedCaps: testAllowedCapsFlag,
|
||||
noEnv: true,
|
||||
legacy: true,
|
||||
want: testAllowedCaps,
|
||||
},
|
||||
{
|
||||
name: "empty",
|
||||
allowedCaps: testAllowedCapsFlag,
|
||||
envCaps: []nvconf.DriverCap{""},
|
||||
envCaps: "",
|
||||
want: nvconf.DefaultDriverCaps,
|
||||
},
|
||||
{
|
||||
name: "empty-legacy",
|
||||
allowedCaps: testAllowedCapsFlag,
|
||||
envCaps: []nvconf.DriverCap{""},
|
||||
envCaps: "",
|
||||
legacy: true,
|
||||
want: nvconf.DefaultDriverCaps,
|
||||
},
|
||||
{
|
||||
name: "compute",
|
||||
allowedCaps: testAllowedCapsFlag,
|
||||
envCaps: []nvconf.DriverCap{nvconf.ComputeCap},
|
||||
want: nvconf.DriverCaps{nvconf.ComputeCap: struct{}{}},
|
||||
envCaps: nvconf.CapCompute.String(),
|
||||
want: nvconf.CapCompute,
|
||||
},
|
||||
{
|
||||
name: "utility,graphics-legacy",
|
||||
allowedCaps: testAllowedCapsFlag,
|
||||
envCaps: []nvconf.DriverCap{nvconf.UtilityCap, nvconf.GraphicsCap},
|
||||
envCaps: (nvconf.CapUtility | nvconf.CapGraphics).String(),
|
||||
legacy: true,
|
||||
want: nvconf.DriverCaps{nvconf.UtilityCap: struct{}{}, nvconf.GraphicsCap: struct{}{}},
|
||||
want: nvconf.CapUtility | nvconf.CapGraphics,
|
||||
},
|
||||
{
|
||||
name: "all",
|
||||
allowedCaps: testAllowedCapsFlag,
|
||||
envCaps: []nvconf.DriverCap{nvconf.AllCap},
|
||||
envCaps: nvconf.AllCapabilitiesName,
|
||||
want: testAllowedCaps,
|
||||
},
|
||||
{
|
||||
name: "all-all",
|
||||
allowedCaps: "all",
|
||||
envCaps: []nvconf.DriverCap{nvconf.AllCap},
|
||||
envCaps: nvconf.AllCapabilitiesName,
|
||||
want: nvconf.SupportedDriverCaps,
|
||||
},
|
||||
} {
|
||||
@@ -448,15 +453,8 @@ func TestNvidiaDriverCapabilities(t *testing.T) {
|
||||
if tc.legacy {
|
||||
env = append(env, fmt.Sprintf("%s=%s", cudaVersionEnv, "10.2.89"))
|
||||
}
|
||||
if len(tc.envCaps) > 0 {
|
||||
var sb strings.Builder
|
||||
for i, cap := range tc.envCaps {
|
||||
if i > 0 {
|
||||
sb.WriteString(",")
|
||||
}
|
||||
sb.WriteString(string(cap))
|
||||
}
|
||||
env = append(env, fmt.Sprintf("%s=%s", nvidiaDriverCapsEnv, sb.String()))
|
||||
if tc.envCaps != "" || !tc.noEnv {
|
||||
env = append(env, fmt.Sprintf("%s=%s", nvidiaDriverCapsEnv, tc.envCaps))
|
||||
}
|
||||
got, err := NVProxyDriverCapsFromEnv(
|
||||
&specs.Spec{Process: &specs.Process{Env: env}},
|
||||
@@ -465,7 +463,7 @@ func TestNvidiaDriverCapabilities(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Errorf("NVProxyDriverCapsFromEnv() failed, err: %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(got, tc.want) {
|
||||
if got != tc.want {
|
||||
t.Errorf("NVProxyDriverCapsFromEnv() got: %v, want: %v", got, tc.want)
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user