mirror of
https://github.com/hanzoai/visor.git
synced 2026-09-24 17:04:14 +00:00
Before this change, there were 2 places in which the driver struct names were defined for nvproxy structs: 1. As struct field tags. The first field of structs had a tag `nvproxy:*`. This was kind of awkward. Such metadata is usually a struct comment. 2. In version.go while registering the struct with a name. Not all structs are defined in nvproxy (for example simple structs). In such cases, the driver struct name is directly assigned while registering struct info. This change gets rid of (1). Most of the struct tags were `nvproxy:"same"`. Now driverStructs() always infers the driver struct name using the nvproxy struct name itself. The few cases where the nvproxy tag was needed, because driver struct name was lower cased, were handled by defining driverStructWithName() which allows specifying a different name. Now all driver struct names definitions are in one place. Along the way, also made the following fixes: - For some reason, many structs defined in pkg/abi/nvgpu/frontend.go had camel-cased naming, while all other structs in pkg/abi/nvgpu/ctrl.go and pkg/abi/nvgpu/classes.go were named the same as their driver structs. The convention in the abi/* packages is to follow the kernel source naming. This is against Go sytle guide, but is more readable for gVisor purposes and has been a long accepted convention. This also makes the task of removing (1) easier. So renamed all such structs as per their driver names. - A lot of code in pkg/sentry/devices/nvproxy/version.go was still referring to driver struct info as "struct names", even though it was representing more than just struct names. It also contains the reflect.Type of the struct which is used to compare the nvproxy struct layout to the driver struct layout. PiperOrigin-RevId: 710648105
157 lines
5.5 KiB
Go
157 lines
5.5 KiB
Go
// 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.NVOS54_PARAMETERS) (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.NVOS54_PARAMETERS) (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.NVOS54_PARAMETERS) (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.NVOS64_PARAMETERS, 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.NVOS64_PARAMETERS, 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.NVOS64_PARAMETERS, 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)
|
|
}
|