github.com/metacubex/gvisor@v0.0.0-20240320004321-933faba989ec/pkg/sentry/devices/nvproxy/version.go (about)

     1  // Copyright 2023 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package nvproxy
    16  
    17  import (
    18  	"fmt"
    19  	"strconv"
    20  	"strings"
    21  
    22  	"github.com/metacubex/gvisor/pkg/abi/nvgpu"
    23  	"github.com/metacubex/gvisor/pkg/sync"
    24  )
    25  
    26  // DriverVersion represents a NVIDIA driver version patch release.
    27  //
    28  // +stateify savable
    29  type DriverVersion struct {
    30  	major int
    31  	minor int
    32  	patch int
    33  }
    34  
    35  // NewDriverVersion returns a new driver version.
    36  func NewDriverVersion(major, minor, patch int) DriverVersion {
    37  	return DriverVersion{major, minor, patch}
    38  }
    39  
    40  // DriverVersionFrom returns a DriverVersion from a string.
    41  func DriverVersionFrom(version string) (DriverVersion, error) {
    42  	parts := strings.Split(version, ".")
    43  	if len(parts) != 3 {
    44  		return DriverVersion{}, fmt.Errorf("invalid format of version string %q", version)
    45  	}
    46  	var (
    47  		res DriverVersion
    48  		err error
    49  	)
    50  	res.major, err = strconv.Atoi(parts[0])
    51  	if err != nil {
    52  		return DriverVersion{}, fmt.Errorf("invalid format for major version %q: %v", version, err)
    53  	}
    54  	res.minor, err = strconv.Atoi(parts[1])
    55  	if err != nil {
    56  		return DriverVersion{}, fmt.Errorf("invalid format for minor version %q: %v", version, err)
    57  	}
    58  	res.patch, err = strconv.Atoi(parts[2])
    59  	if err != nil {
    60  		return DriverVersion{}, fmt.Errorf("invalid format for patch version %q: %v", version, err)
    61  	}
    62  	return res, nil
    63  }
    64  
    65  func (v DriverVersion) String() string {
    66  	return fmt.Sprintf("%02d.%02d.%02d", v.major, v.minor, v.patch)
    67  }
    68  
    69  // Equals returns true if the two driver versions are equal.
    70  func (v DriverVersion) Equals(other DriverVersion) bool {
    71  	return v.major == other.major && v.minor == other.minor && v.patch == other.patch
    72  }
    73  
    74  // isGreaterThan returns true if v is greater than other.
    75  // isGreaterThan returns true if v is more recent than other, assuming v and other are on the same
    76  // dev branch.
    77  func (v DriverVersion) isGreaterThan(other DriverVersion) bool {
    78  	switch {
    79  	case v.major > other.major:
    80  		return true
    81  	case other.major > v.major:
    82  		return false
    83  	case v.minor > other.minor:
    84  		return true
    85  	case other.minor > v.minor:
    86  		return false
    87  	case v.patch > other.patch:
    88  		return true
    89  	case other.patch > v.patch:
    90  		return false
    91  	default:
    92  		return true
    93  	}
    94  }
    95  
    96  type frontendIoctlHandler func(fi *frontendIoctlState) (uintptr, error)
    97  type controlCmdHandler func(fi *frontendIoctlState, ioctlParams *nvgpu.NVOS54Parameters) (uintptr, error)
    98  type allocationClassHandler func(fi *frontendIoctlState, ioctlParams *nvgpu.NVOS64Parameters, isNVOS64 bool) (uintptr, error)
    99  type uvmIoctlHandler func(ui *uvmIoctlState) (uintptr, error)
   100  
   101  // A driverABIFunc constructs and returns a driverABI.
   102  // This indirection exists to avoid memory usage from unused driver ABIs.
   103  type driverABIFunc func() *driverABI
   104  
   105  // abiConAndChecksum couples the driver's abiConstructor to the SHA256 checksum of its linux .run
   106  // driver installer file from NVIDIA.
   107  type abiConAndChecksum struct {
   108  	cons     driverABIFunc
   109  	checksum string
   110  }
   111  
   112  // driverABI defines the Nvidia kernel driver ABI proxied at a given version.
   113  //
   114  // The Nvidia driver's ioctl interface branches widely at various places in the
   115  // kernel driver. As for now, versioning is only supported for the following
   116  // points of branching:
   117  //  1. frontend device ioctls (based on IOC_NR(cmd)).
   118  //  2. uvm device ioctls (based on cmd).
   119  //  3. control commands within NV_ESC_RM_CONTROL in frontend device (based on
   120  //     NVOS54_PARAMETERS.Cmd). Note that commands that have RM_GSS_LEGACY_MASK
   121  //     set are not versioned.
   122  //  4. allocation classes within NV_ESC_RM_ALLOC in frontend device (based on
   123  //     NVOS64_PARAMETERS.HClass).
   124  type driverABI struct {
   125  	frontendIoctl   map[uint32]frontendIoctlHandler
   126  	uvmIoctl        map[uint32]uvmIoctlHandler
   127  	controlCmd      map[uint32]controlCmdHandler
   128  	allocationClass map[uint32]allocationClassHandler
   129  }
   130  
   131  // abis is a global map containing all supported Nvidia driver ABIs. This is
   132  // initialized on Init() and is immutable henceforth.
   133  var abis map[DriverVersion]abiConAndChecksum
   134  var abisOnce sync.Once
   135  
   136  // Note: runfileChecksum is the checksum of the .run file of the driver installer for linux from
   137  // nvidia.
   138  // To add a new version, add in support as normal and add the "addDriverABI" call for your version.
   139  // Run `make sudo TARGETS=//tools/gpu:main ARGS="checksum --version={}"` to get checksum.
   140  func addDriverABI(major, minor, patch int, runfileChecksum string, cons driverABIFunc) driverABIFunc {
   141  	if abis == nil {
   142  		abis = make(map[DriverVersion]abiConAndChecksum)
   143  	}
   144  	version := NewDriverVersion(major, minor, patch)
   145  	abis[version] = abiConAndChecksum{cons: cons, checksum: runfileChecksum}
   146  	return cons
   147  }
   148  
   149  // Init initializes abis global map.
   150  func Init() {
   151  	abisOnce.Do(func() {
   152  		v535_104_05 := addDriverABI(535, 104, 05, "2f9d609d1da770beee757636635c46e7ed8253ade887b87c7a5482e33fcbedc9", func() *driverABI {
   153  			// 535.104.05 is the earliest driver version supported by nvproxy. Since
   154  			// there is no parent to inherit from, the driverABI needs to be constructed
   155  			// with the entirety of the nvproxy functionality at this version.
   156  			return &driverABI{
   157  				frontendIoctl: map[uint32]frontendIoctlHandler{
   158  					nvgpu.NV_ESC_CARD_INFO:                     frontendIoctlSimple, // nv_ioctl_card_info_t
   159  					nvgpu.NV_ESC_CHECK_VERSION_STR:             frontendIoctlSimple, // nv_rm_api_version_t
   160  					nvgpu.NV_ESC_SYS_PARAMS:                    frontendIoctlSimple, // nv_ioctl_sys_params_t
   161  					nvgpu.NV_ESC_RM_DUP_OBJECT:                 frontendIoctlSimple, // NVOS55_PARAMETERS
   162  					nvgpu.NV_ESC_RM_SHARE:                      frontendIoctlSimple, // NVOS57_PARAMETERS
   163  					nvgpu.NV_ESC_RM_UNMAP_MEMORY:               frontendIoctlSimple, // NVOS34_PARAMETERS
   164  					nvgpu.NV_ESC_RM_UPDATE_DEVICE_MAPPING_INFO: frontendIoctlSimple, // NVOS56_PARAMETERS
   165  					nvgpu.NV_ESC_REGISTER_FD:                   frontendRegisterFD,
   166  					nvgpu.NV_ESC_ALLOC_OS_EVENT:                rmAllocOSEvent,
   167  					nvgpu.NV_ESC_FREE_OS_EVENT:                 rmFreeOSEvent,
   168  					nvgpu.NV_ESC_NUMA_INFO:                     rmNumaInfo,
   169  					nvgpu.NV_ESC_RM_ALLOC_MEMORY:               rmAllocMemory,
   170  					nvgpu.NV_ESC_RM_FREE:                       rmFree,
   171  					nvgpu.NV_ESC_RM_CONTROL:                    rmControl,
   172  					nvgpu.NV_ESC_RM_ALLOC:                      rmAlloc,
   173  					nvgpu.NV_ESC_RM_VID_HEAP_CONTROL:           rmVidHeapControl,
   174  					nvgpu.NV_ESC_RM_MAP_MEMORY:                 rmMapMemory,
   175  				},
   176  				uvmIoctl: map[uint32]uvmIoctlHandler{
   177  					nvgpu.UVM_INITIALIZE:                     uvmInitialize,
   178  					nvgpu.UVM_DEINITIALIZE:                   uvmIoctlNoParams,
   179  					nvgpu.UVM_CREATE_RANGE_GROUP:             uvmIoctlSimple[nvgpu.UVM_CREATE_RANGE_GROUP_PARAMS],
   180  					nvgpu.UVM_DESTROY_RANGE_GROUP:            uvmIoctlSimple[nvgpu.UVM_DESTROY_RANGE_GROUP_PARAMS],
   181  					nvgpu.UVM_REGISTER_GPU_VASPACE:           uvmIoctlHasRMCtrlFD[nvgpu.UVM_REGISTER_GPU_VASPACE_PARAMS],
   182  					nvgpu.UVM_UNREGISTER_GPU_VASPACE:         uvmIoctlSimple[nvgpu.UVM_UNREGISTER_GPU_VASPACE_PARAMS],
   183  					nvgpu.UVM_REGISTER_CHANNEL:               uvmIoctlHasRMCtrlFD[nvgpu.UVM_REGISTER_CHANNEL_PARAMS],
   184  					nvgpu.UVM_UNREGISTER_CHANNEL:             uvmIoctlSimple[nvgpu.UVM_UNREGISTER_CHANNEL_PARAMS],
   185  					nvgpu.UVM_MAP_EXTERNAL_ALLOCATION:        uvmIoctlHasRMCtrlFD[nvgpu.UVM_MAP_EXTERNAL_ALLOCATION_PARAMS],
   186  					nvgpu.UVM_FREE:                           uvmIoctlSimple[nvgpu.UVM_FREE_PARAMS],
   187  					nvgpu.UVM_REGISTER_GPU:                   uvmIoctlHasRMCtrlFD[nvgpu.UVM_REGISTER_GPU_PARAMS],
   188  					nvgpu.UVM_UNREGISTER_GPU:                 uvmIoctlSimple[nvgpu.UVM_UNREGISTER_GPU_PARAMS],
   189  					nvgpu.UVM_PAGEABLE_MEM_ACCESS:            uvmIoctlSimple[nvgpu.UVM_PAGEABLE_MEM_ACCESS_PARAMS],
   190  					nvgpu.UVM_DISABLE_READ_DUPLICATION:       uvmIoctlSimple[nvgpu.UVM_DISABLE_READ_DUPLICATION_PARAMS],
   191  					nvgpu.UVM_MAP_DYNAMIC_PARALLELISM_REGION: uvmIoctlSimple[nvgpu.UVM_MAP_DYNAMIC_PARALLELISM_REGION_PARAMS],
   192  					nvgpu.UVM_ALLOC_SEMAPHORE_POOL:           uvmIoctlSimple[nvgpu.UVM_ALLOC_SEMAPHORE_POOL_PARAMS],
   193  					nvgpu.UVM_VALIDATE_VA_RANGE:              uvmIoctlSimple[nvgpu.UVM_VALIDATE_VA_RANGE_PARAMS],
   194  					nvgpu.UVM_CREATE_EXTERNAL_RANGE:          uvmIoctlSimple[nvgpu.UVM_CREATE_EXTERNAL_RANGE_PARAMS],
   195  					nvgpu.UVM_MM_INITIALIZE:                  uvmMMInitialize,
   196  				},
   197  				controlCmd: map[uint32]controlCmdHandler{
   198  					nvgpu.NV0000_CTRL_CMD_CLIENT_GET_ADDR_SPACE_TYPE:        rmControlSimple,
   199  					nvgpu.NV0000_CTRL_CMD_CLIENT_SET_INHERITED_SHARE_POLICY: rmControlSimple,
   200  					nvgpu.NV0000_CTRL_CMD_GPU_GET_ATTACHED_IDS:              rmControlSimple,
   201  					nvgpu.NV0000_CTRL_CMD_GPU_GET_ID_INFO:                   rmControlSimple,
   202  					nvgpu.NV0000_CTRL_CMD_GPU_GET_ID_INFO_V2:                rmControlSimple,
   203  					nvgpu.NV0000_CTRL_CMD_GPU_GET_PROBED_IDS:                rmControlSimple,
   204  					nvgpu.NV0000_CTRL_CMD_GPU_ATTACH_IDS:                    rmControlSimple,
   205  					nvgpu.NV0000_CTRL_CMD_GPU_DETACH_IDS:                    rmControlSimple,
   206  					nvgpu.NV0000_CTRL_CMD_GPU_GET_PCI_INFO:                  rmControlSimple,
   207  					nvgpu.NV0000_CTRL_CMD_GPU_QUERY_DRAIN_STATE:             rmControlSimple,
   208  					nvgpu.NV0000_CTRL_CMD_GPU_GET_MEMOP_ENABLE:              rmControlSimple,
   209  					nvgpu.NV0000_CTRL_CMD_SYNC_GPU_BOOST_GROUP_INFO:         rmControlSimple,
   210  					nvgpu.NV0000_CTRL_CMD_SYSTEM_GET_P2P_CAPS:               rmControlSimple,
   211  					nvgpu.NV0000_CTRL_CMD_SYSTEM_GET_FABRIC_STATUS:          rmControlSimple,
   212  					nvgpu.NV0000_CTRL_CMD_SYSTEM_GET_P2P_CAPS_MATRIX:        rmControlSimple,
   213  					nvgpu.NV0080_CTRL_CMD_FB_GET_CAPS_V2:                    rmControlSimple,
   214  					nvgpu.NV0080_CTRL_CMD_GPU_GET_NUM_SUBDEVICES:            rmControlSimple,
   215  					nvgpu.NV0080_CTRL_CMD_GPU_QUERY_SW_STATE_PERSISTENCE:    rmControlSimple,
   216  					nvgpu.NV0080_CTRL_CMD_GPU_GET_VIRTUALIZATION_MODE:       rmControlSimple,
   217  					0x80028b: rmControlSimple, // unknown, paramsSize == 1
   218  					nvgpu.NV0080_CTRL_CMD_GPU_GET_CLASSLIST_V2:                             rmControlSimple,
   219  					nvgpu.NV0080_CTRL_CMD_HOST_GET_CAPS_V2:                                 rmControlSimple,
   220  					nvgpu.NV2080_CTRL_CMD_BUS_GET_PCI_INFO:                                 rmControlSimple,
   221  					nvgpu.NV2080_CTRL_CMD_BUS_GET_PCI_BAR_INFO:                             rmControlSimple,
   222  					nvgpu.NV2080_CTRL_CMD_BUS_GET_INFO_V2:                                  rmControlSimple,
   223  					nvgpu.NV2080_CTRL_CMD_BUS_GET_PCIE_SUPPORTED_GPU_ATOMICS:               rmControlSimple,
   224  					nvgpu.NV2080_CTRL_CMD_BUS_GET_C2C_INFO:                                 rmControlSimple,
   225  					nvgpu.NV2080_CTRL_CMD_CE_GET_ALL_CAPS:                                  rmControlSimple,
   226  					nvgpu.NV2080_CTRL_CMD_FB_GET_INFO_V2:                                   rmControlSimple,
   227  					nvgpu.NV2080_CTRL_CMD_GPU_GET_INFO_V2:                                  rmControlSimple,
   228  					nvgpu.NV2080_CTRL_CMD_GPU_GET_NAME_STRING:                              rmControlSimple,
   229  					nvgpu.NV2080_CTRL_CMD_GPU_GET_SHORT_NAME_STRING:                        rmControlSimple,
   230  					nvgpu.NV2080_CTRL_CMD_GPU_GET_SIMULATION_INFO:                          rmControlSimple,
   231  					nvgpu.NV2080_CTRL_CMD_GPU_QUERY_ECC_STATUS:                             rmControlSimple,
   232  					nvgpu.NV2080_CTRL_CMD_GPU_QUERY_COMPUTE_MODE_RULES:                     rmControlSimple,
   233  					nvgpu.NV2080_CTRL_CMD_GPU_ACQUIRE_COMPUTE_MODE_RESERVATION:             rmControlSimple,
   234  					nvgpu.NV2080_CTRL_CMD_GPU_RELEASE_COMPUTE_MODE_RESERVATION:             rmControlSimple,
   235  					nvgpu.NV2080_CTRL_CMD_GPU_GET_GID_INFO:                                 rmControlSimple,
   236  					nvgpu.NV2080_CTRL_CMD_GPU_GET_ENGINES_V2:                               rmControlSimple,
   237  					nvgpu.NV2080_CTRL_CMD_GPU_GET_ACTIVE_PARTITION_IDS:                     rmControlSimple,
   238  					nvgpu.NV2080_CTRL_CMD_GPU_GET_PIDS:                                     rmControlSimple,
   239  					nvgpu.NV2080_CTRL_CMD_GPU_GET_PID_INFO:                                 rmControlSimple,
   240  					nvgpu.NV2080_CTRL_CMD_GPU_GET_COMPUTE_POLICY_CONFIG:                    rmControlSimple,
   241  					nvgpu.NV2080_CTRL_CMD_GET_GPU_FABRIC_PROBE_INFO:                        rmControlSimple,
   242  					nvgpu.NV2080_CTRL_CMD_GR_SET_CTXSW_PREEMPTION_MODE:                     rmControlSimple,
   243  					nvgpu.NV2080_CTRL_CMD_GR_GET_CTX_BUFFER_SIZE:                           rmControlSimple,
   244  					nvgpu.NV2080_CTRL_CMD_GR_GET_GLOBAL_SM_ORDER:                           rmControlSimple,
   245  					nvgpu.NV2080_CTRL_CMD_GR_GET_CAPS_V2:                                   rmControlSimple,
   246  					nvgpu.NV2080_CTRL_CMD_GR_GET_GPC_MASK:                                  rmControlSimple,
   247  					nvgpu.NV2080_CTRL_CMD_GR_GET_TPC_MASK:                                  rmControlSimple,
   248  					nvgpu.NV2080_CTRL_CMD_GR_GET_SM_ISSUE_RATE_MODIFIER:                    rmControlSimple,
   249  					nvgpu.NV2080_CTRL_CMD_GSP_GET_FEATURES:                                 rmControlSimple,
   250  					nvgpu.NV2080_CTRL_CMD_MC_GET_ARCH_INFO:                                 rmControlSimple,
   251  					nvgpu.NV2080_CTRL_CMD_MC_SERVICE_INTERRUPTS:                            rmControlSimple,
   252  					nvgpu.NV2080_CTRL_CMD_NVLINK_GET_NVLINK_CAPS:                           rmControlSimple,
   253  					nvgpu.NV2080_CTRL_CMD_NVLINK_GET_NVLINK_STATUS:                         rmControlSimple,
   254  					nvgpu.NV2080_CTRL_CMD_PERF_BOOST:                                       rmControlSimple,
   255  					nvgpu.NV2080_CTRL_CMD_RC_GET_WATCHDOG_INFO:                             rmControlSimple,
   256  					nvgpu.NV2080_CTRL_CMD_RC_RELEASE_WATCHDOG_REQUESTS:                     rmControlSimple,
   257  					nvgpu.NV2080_CTRL_CMD_RC_SOFT_DISABLE_WATCHDOG:                         rmControlSimple,
   258  					nvgpu.NV2080_CTRL_CMD_TIMER_GET_GPU_CPU_TIME_CORRELATION_INFO:          rmControlSimple,
   259  					nvgpu.NV503C_CTRL_CMD_REGISTER_VA_SPACE:                                rmControlSimple,
   260  					nvgpu.NV503C_CTRL_CMD_REGISTER_VIDMEM:                                  rmControlSimple,
   261  					nvgpu.NV503C_CTRL_CMD_UNREGISTER_VIDMEM:                                rmControlSimple,
   262  					nvgpu.NV83DE_CTRL_CMD_DEBUG_SET_EXCEPTION_MASK:                         rmControlSimple,
   263  					nvgpu.NV83DE_CTRL_CMD_DEBUG_READ_ALL_SM_ERROR_STATES:                   rmControlSimple,
   264  					nvgpu.NV83DE_CTRL_CMD_DEBUG_CLEAR_ALL_SM_ERROR_STATES:                  rmControlSimple,
   265  					nvgpu.NV906F_CTRL_CMD_RESET_CHANNEL:                                    rmControlSimple,
   266  					nvgpu.NV90E6_CTRL_CMD_MASTER_GET_VIRTUAL_FUNCTION_ERROR_CONT_INTR_MASK: rmControlSimple,
   267  					nvgpu.NVC36F_CTRL_GET_CLASS_ENGINEID:                                   rmControlSimple,
   268  					nvgpu.NVC36F_CTRL_CMD_GPFIFO_GET_WORK_SUBMIT_TOKEN:                     rmControlSimple,
   269  					nvgpu.NV_CONF_COMPUTE_CTRL_CMD_SYSTEM_GET_CAPABILITIES:                 rmControlSimple,
   270  					nvgpu.NVA06C_CTRL_CMD_GPFIFO_SCHEDULE:                                  rmControlSimple,
   271  					nvgpu.NVA06C_CTRL_CMD_SET_TIMESLICE:                                    rmControlSimple,
   272  					nvgpu.NVA06C_CTRL_CMD_PREEMPT:                                          rmControlSimple,
   273  					nvgpu.NVA06F_CTRL_CMD_GPFIFO_SCHEDULE:                                  rmControlSimple,
   274  					nvgpu.NV0000_CTRL_CMD_SYSTEM_GET_BUILD_VERSION:                         ctrlClientSystemGetBuildVersion,
   275  					nvgpu.NV0080_CTRL_CMD_FIFO_GET_CHANNELLIST:                             ctrlDevFIFOGetChannelList,
   276  					nvgpu.NV0080_CTRL_CMD_GPU_GET_CLASSLIST:                                ctrlDevGpuGetClasslist,
   277  					nvgpu.NV2080_CTRL_CMD_FIFO_DISABLE_CHANNELS:                            ctrlSubdevFIFODisableChannels,
   278  					nvgpu.NV2080_CTRL_CMD_GR_GET_INFO:                                      ctrlSubdevGRGetInfo,
   279  				},
   280  				allocationClass: map[uint32]allocationClassHandler{
   281  					nvgpu.NV01_ROOT:               rmAllocSimple[nvgpu.Handle],
   282  					nvgpu.NV01_ROOT_NON_PRIV:      rmAllocSimple[nvgpu.Handle],
   283  					nvgpu.NV01_MEMORY_SYSTEM:      rmAllocSimple[nvgpu.NV_MEMORY_ALLOCATION_PARAMS],
   284  					nvgpu.NV01_MEMORY_LOCAL_USER:  rmAllocSimple[nvgpu.NV_MEMORY_ALLOCATION_PARAMS],
   285  					nvgpu.NV01_ROOT_CLIENT:        rmAllocSimple[nvgpu.Handle],
   286  					nvgpu.NV01_EVENT_OS_EVENT:     rmAllocEventOSEvent,
   287  					nvgpu.NV01_DEVICE_0:           rmAllocSimple[nvgpu.NV0080_ALLOC_PARAMETERS],
   288  					nvgpu.NV_MEMORY_FABRIC:        rmAllocSimple[nvgpu.NV00F8_ALLOCATION_PARAMETERS],
   289  					nvgpu.NV20_SUBDEVICE_0:        rmAllocSimple[nvgpu.NV2080_ALLOC_PARAMETERS],
   290  					nvgpu.NV50_MEMORY_VIRTUAL:     rmAllocSimple[nvgpu.NV_MEMORY_ALLOCATION_PARAMS],
   291  					nvgpu.NV50_P2P:                rmAllocSimple[nvgpu.NV503B_ALLOC_PARAMETERS],
   292  					nvgpu.NV50_THIRD_PARTY_P2P:    rmAllocSimple[nvgpu.NV503C_ALLOC_PARAMETERS],
   293  					nvgpu.GT200_DEBUGGER:          rmAllocSimple[nvgpu.NV83DE_ALLOC_PARAMETERS],
   294  					nvgpu.FERMI_CONTEXT_SHARE_A:   rmAllocSimple[nvgpu.NV_CTXSHARE_ALLOCATION_PARAMETERS],
   295  					nvgpu.FERMI_VASPACE_A:         rmAllocSimple[nvgpu.NV_VASPACE_ALLOCATION_PARAMETERS],
   296  					nvgpu.KEPLER_CHANNEL_GROUP_A:  rmAllocSimple[nvgpu.NV_CHANNEL_GROUP_ALLOCATION_PARAMETERS],
   297  					nvgpu.TURING_CHANNEL_GPFIFO_A: rmAllocSimple[nvgpu.NV_CHANNEL_ALLOC_PARAMS],
   298  					nvgpu.AMPERE_CHANNEL_GPFIFO_A: rmAllocSimple[nvgpu.NV_CHANNEL_ALLOC_PARAMS],
   299  					nvgpu.TURING_DMA_COPY_A:       rmAllocSimple[nvgpu.NVB0B5_ALLOCATION_PARAMETERS],
   300  					nvgpu.AMPERE_DMA_COPY_A:       rmAllocSimple[nvgpu.NVB0B5_ALLOCATION_PARAMETERS],
   301  					nvgpu.AMPERE_DMA_COPY_B:       rmAllocSimple[nvgpu.NVB0B5_ALLOCATION_PARAMETERS],
   302  					nvgpu.HOPPER_DMA_COPY_A:       rmAllocSimple[nvgpu.NVB0B5_ALLOCATION_PARAMETERS],
   303  					nvgpu.TURING_COMPUTE_A:        rmAllocSimple[nvgpu.NV_GR_ALLOCATION_PARAMETERS],
   304  					nvgpu.AMPERE_COMPUTE_A:        rmAllocSimple[nvgpu.NV_GR_ALLOCATION_PARAMETERS],
   305  					nvgpu.AMPERE_COMPUTE_B:        rmAllocSimple[nvgpu.NV_GR_ALLOCATION_PARAMETERS],
   306  					nvgpu.ADA_COMPUTE_A:           rmAllocSimple[nvgpu.NV_GR_ALLOCATION_PARAMETERS],
   307  					nvgpu.NV_CONFIDENTIAL_COMPUTE: rmAllocSimple[nvgpu.NV_CONFIDENTIAL_COMPUTE_ALLOC_PARAMS],
   308  					nvgpu.HOPPER_COMPUTE_A:        rmAllocSimple[nvgpu.NV_GR_ALLOCATION_PARAMETERS],
   309  					nvgpu.HOPPER_USERMODE_A:       rmAllocSimple[nvgpu.NV_HOPPER_USERMODE_A_PARAMS],
   310  					nvgpu.GF100_SUBDEVICE_MASTER:  rmAllocNoParams,
   311  					nvgpu.TURING_USERMODE_A:       rmAllocNoParams,
   312  				},
   313  			}
   314  		})
   315  
   316  		// 535.104.12 does not exist on the main branch. It branched off the main
   317  		// branch at 535.104.05.
   318  		_ = addDriverABI(535, 104, 12, "ffc2d89e233d2427edb1ff5f436028a94b3ef86e78f97e088e11d905c82e8001", v535_104_05)
   319  
   320  		// 535.113.01 is an intermediate unqualified version from the main branch.
   321  		v535_113_01 := v535_104_05
   322  
   323  		// The following do not exist on the main branch. They branched off the
   324  		// main branch at 535.113.01.
   325  		v535_129_03 := addDriverABI(535, 129, 03, "e6dca5626a2608c6bb2a046cfcb7c1af338b9e961a7dd90ac09bb8a126ff002e", v535_113_01)
   326  		_ = addDriverABI(535, 154, 05, "7e95065caa6b82de926110f14827a61972eb12c200e863a29e9fb47866eaa898", v535_129_03)
   327  
   328  		// TODO: Update NV_MEMORY_ALLOCATION_PARAMS when adding >=545.23.06.
   329  	})
   330  }
   331  
   332  // ForEachSupportDriver calls f on all supported drivers.
   333  // Precondition: Init() must have been called.
   334  func ForEachSupportDriver(f func(version DriverVersion, checksum string)) {
   335  	for version, abi := range abis {
   336  		f(version, abi.checksum)
   337  	}
   338  }
   339  
   340  // LatestDriver returns the latest supported driver.
   341  // Precondition: Init() must have been called.
   342  func LatestDriver() DriverVersion {
   343  	var ret DriverVersion
   344  	for version := range abis {
   345  		if version.isGreaterThan(ret) {
   346  			ret = version
   347  		}
   348  	}
   349  	return ret
   350  }
   351  
   352  // ExpectedDriverChecksum returns the expected checksum for a given version.
   353  // Precondition: Init() must have been called.
   354  func ExpectedDriverChecksum(version DriverVersion) (string, bool) {
   355  	abi, ok := abis[version]
   356  	if !ok {
   357  		return "", false
   358  	}
   359  	return abi.checksum, true
   360  }
   361  
   362  // SupportedIoctls returns the ioctl numbers that are supported by nvproxy at
   363  // a given version.
   364  func SupportedIoctls(version DriverVersion) (frontendIoctls map[uint32]struct{}, uvmIoctls map[uint32]struct{}, controlCmds map[uint32]struct{}, allocClasses map[uint32]struct{}, ok bool) {
   365  	abiCons, ok := abis[version]
   366  	if !ok {
   367  		return nil, nil, nil, nil, false
   368  	}
   369  	abi := abiCons.cons()
   370  	frontendIoctls = make(map[uint32]struct{})
   371  	for ioc := range abi.frontendIoctl {
   372  		frontendIoctls[ioc] = struct{}{}
   373  	}
   374  	uvmIoctls = make(map[uint32]struct{})
   375  	for ioc := range abi.uvmIoctl {
   376  		uvmIoctls[ioc] = struct{}{}
   377  	}
   378  	controlCmds = make(map[uint32]struct{})
   379  	for cmd := range abi.controlCmd {
   380  		controlCmds[cmd] = struct{}{}
   381  	}
   382  	allocClasses = make(map[uint32]struct{})
   383  	for class := range abi.allocationClass {
   384  		allocClasses[class] = struct{}{}
   385  	}
   386  	return
   387  }