Fix inconsistencies with nvproxy ioctl structs compared to the Nvidia driver.

This adds specific handling for NV0000_CTRL_GPU_GET_ID_INFO_PARAMS and
NV0000_CTRL_SYSTEM_GET_P2P_CAPS_PARAMS since they contain pointer fields.
This also fixes the layout of NV0000_CTRL_OS_UNIX_GET_EXPORT_OBJECT_INFO_PARAMS
and NV_CONFIDENTIAL_COMPUTE_ALLOC_PARAMS, and the typing of fields for
NV0000_CTRL_OS_UNIX_EXPORT_OBJECT and UVM_MAP_EXTERNAL_ALLOCATION_PARAMS.

PiperOrigin-RevId: 659630154
This commit is contained in:
Anthony Cui
2024-08-05 11:54:06 -07:00
committed by gVisor bot
parent 5e00026dc9
commit 34f8c3f24e
6 changed files with 167 additions and 16 deletions
-1
View File
@@ -396,5 +396,4 @@ type NV00FD_ALLOCATION_PARAMETERS_V545 struct {
// +marshal
type NV_CONFIDENTIAL_COMPUTE_ALLOC_PARAMS struct {
Handle Handle `nvproxy:"same"`
_ uint32
}
+46 -7
View File
@@ -72,6 +72,22 @@ const (
NV0000_CTRL_CMD_GPU_WAIT_ATTACH_ID = 0x290
)
// NV0000_CTRL_GPU_GET_ID_INFO_PARAMS is the param type for NV0000_CTRL_CMD_GPU_GET_ID_INFO,
// from src/common/sdk/nvidia/inc/ctrl/ctrl0000/ctrl0000gpu.h.
//
// +marshal
type NV0000_CTRL_GPU_GET_ID_INFO_PARAMS struct {
GpuID uint32 `nvproxy:"same"`
GpuFlags uint32
DeviceInstance uint32
SubDeviceInstance uint32
SzName P64
SliStatus uint32
BoardID uint32
GpuInstance uint32
NumaID int32
}
// From src/common/sdk/nvidia/inc/ctrl/ctrl0000/ctrl0000syncgpuboost.h:
const (
NV0000_CTRL_CMD_SYNC_GPU_BOOST_GROUP_INFO = 0xa04
@@ -85,8 +101,34 @@ const (
NV0000_CTRL_CMD_SYSTEM_GET_FABRIC_STATUS = 0x136
NV0000_CTRL_CMD_SYSTEM_GET_P2P_CAPS_MATRIX = 0x13a
NV0000_CTRL_CMD_SYSTEM_GET_FEATURES = 0x1f0
NV0000_CTRL_SYSTEM_MAX_ATTACHED_GPUS = 32
NV0000_CTRL_P2P_CAPS_INDEX_TABLE_SIZE = 9
)
// NV0000_CTRL_SYSTEM_GET_P2P_CAPS_PARAMS is the param type for NV0000_CTRL_CMD_SYSTEM_GET_P2P_CAPS,
// from src/common/sdk/nvidia/inc/ctrl/ctrl0000/ctrl0000system.h.
//
// +marshal
type NV0000_CTRL_SYSTEM_GET_P2P_CAPS_PARAMS struct {
GpuIDs [NV0000_CTRL_SYSTEM_MAX_ATTACHED_GPUS]uint32 `nvproxy:"same"`
GpuCount uint32
P2PCaps uint32
P2POptimalReadCEs uint32
P2POptimalWriteCEs uint32
P2PCapsStatus [NV0000_CTRL_P2P_CAPS_INDEX_TABLE_SIZE]uint8
_ [7]byte
BusPeerIDs P64
}
// NV0000_CTRL_SYSTEM_GET_P2P_CAPS_PARAMS_V550 is the updated version of
// NV0000_CTRL_SYSTEM_GET_P2P_CAPS_PARAMS since 550.40.07.
//
// +marshal
type NV0000_CTRL_SYSTEM_GET_P2P_CAPS_PARAMS_V550 struct {
NV0000_CTRL_SYSTEM_GET_P2P_CAPS_PARAMS `nvproxy:"NV0000_CTRL_SYSTEM_GET_P2P_CAPS_PARAMS"`
BusEgmPeerIDs P64
}
// From src/common/sdk/nvidia/inc/ctrl/ctrl0000/ctrl0000unix.h:
const (
NV0000_CTRL_CMD_OS_UNIX_EXPORT_OBJECT_TO_FD = 0x3d05
@@ -100,8 +142,8 @@ type NV0000_CTRL_OS_UNIX_GET_EXPORT_OBJECT_INFO_PARAMS struct {
FD int32 `nvproxy:"same"`
DeviceInstance uint32
MaxObjects uint16
Pad [2]byte
Metadata [NV0000_OS_UNIX_EXPORT_OBJECT_FD_BUFFER_SIZE]uint8
Pad [2]byte
}
// GetFrontendFD implements HasFrontendFD.GetFrontendFD.
@@ -120,8 +162,8 @@ type NV0000_CTRL_OS_UNIX_GET_EXPORT_OBJECT_INFO_PARAMS_V545 struct {
DeviceInstance uint32
GpuInstanceID uint32
MaxObjects uint16
Pad [2]byte
Metadata [NV0000_OS_UNIX_EXPORT_OBJECT_FD_BUFFER_SIZE]uint8
Pad [2]byte
}
// GetFrontendFD implements HasFrontendFD.GetFrontendFD.
@@ -136,11 +178,8 @@ func (p *NV0000_CTRL_OS_UNIX_GET_EXPORT_OBJECT_INFO_PARAMS_V545) SetFrontendFD(f
// +marshal
type NV0000_CTRL_OS_UNIX_EXPORT_OBJECT struct {
Type uint32 // enum NV0000_CTRL_OS_UNIX_EXPORT_OBJECT_TYPE
// These fields are inside union `data`, in struct `rmObject`.
HDevice Handle
HParent Handle
HObject Handle
Type uint32 // enum NV0000_CTRL_OS_UNIX_EXPORT_OBJECT_TYPE
Data [12]byte // union
}
// +marshal
+4 -4
View File
@@ -161,8 +161,8 @@ type UVM_MAP_EXTERNAL_ALLOCATION_PARAMS struct {
PerGPUAttributes [UVM_MAX_GPUS]UvmGpuMappingAttributes
GPUAttributesCount uint64
RMCtrlFD int32
HClient Handle
HMemory Handle
HClient uint32 // These are treated like NvHandle, but the driver uses NvU32.
HMemory uint32 // These are treated like NvHandle, but the driver uses NvU32.
RMStatus uint32
}
@@ -184,8 +184,8 @@ type UVM_MAP_EXTERNAL_ALLOCATION_PARAMS_V550 struct {
PerGPUAttributes [UVM_MAX_GPUS_V2]UvmGpuMappingAttributes
GPUAttributesCount uint64
RMCtrlFD int32
HClient Handle
HMemory Handle
HClient uint32 // These are treated like NvHandle, but the driver uses NvU32.
HMemory uint32 // These are treated like NvHandle, but the driver uses NvU32.
RMStatus uint32
}
+21
View File
@@ -765,6 +765,27 @@ func ctrlSubdevFIFODisableChannels(fi *frontendIoctlState, ioctlParams *nvgpu.NV
return n, nil
}
func ctrlGpuGetIDInfo(fi *frontendIoctlState, ioctlParams *nvgpu.NVOS54Parameters) (uintptr, error) {
var ctrlParams nvgpu.NV0000_CTRL_GPU_GET_ID_INFO_PARAMS
if ctrlParams.SizeBytes() != int(ioctlParams.ParamsSize) {
return 0, linuxerr.EINVAL
}
if _, err := ctrlParams.CopyIn(fi.t, addrFromP64(ioctlParams.Params)); err != nil {
return 0, err
}
// szName is not used anywhere in the driver, so we explicitly set it to null.
// See src/nvidia/src/kernel/gpu_mgr/gpu_mgr.c::gpumgrGetGpuIdInfo().
ctrlParams.SzName = 0
n, err := rmControlInvoke(fi, ioctlParams, &ctrlParams)
if err != nil {
return n, err
}
_, err = ctrlParams.CopyOut(fi.t, addrFromP64(ioctlParams.Params))
return n, err
}
func rmAlloc(fi *frontendIoctlState) (uintptr, error) {
var isNVOS64 bool
switch fi.ioctlParamsSize {
@@ -175,6 +175,96 @@ func ctrlDevFIFOGetChannelList(fi *frontendIoctlState, ioctlParams *nvgpu.NVOS54
return n, nil
}
func ctrlClientSystemGetP2PCapsInitializeArray(origArr nvgpu.P64, gpuCount uint32) (nvgpu.P64, []uint32, bool) {
// The driver doesn't try and copy memory if the array is null. See
// src/nvidia/src/kernel/rmapi/embedded_param_copy.c::embeddedParamCopyIn(),
// case NV0000_CTRL_CMD_SYSTEM_GET_P2P_CAPS.
if origArr == 0 {
return 0, nil, true
}
// Params size is gpuCount * gpuCount * sizeof(NvU32).
numEntries := gpuCount * gpuCount
if numEntries*4 > nvgpu.RMAPI_PARAM_COPY_MAX_PARAMS_SIZE {
return 0, nil, false
}
arr := make([]uint32, numEntries)
return p64FromPtr(unsafe.Pointer(&arr[0])), arr, true
}
func ctrlClientSystemGetP2PCaps(fi *frontendIoctlState, ioctlParams *nvgpu.NVOS54Parameters) (uintptr, error) {
var ctrlParams nvgpu.NV0000_CTRL_SYSTEM_GET_P2P_CAPS_PARAMS
if ctrlParams.SizeBytes() != int(ioctlParams.ParamsSize) {
return 0, linuxerr.EINVAL
}
if _, err := ctrlParams.CopyIn(fi.t, addrFromP64(ioctlParams.Params)); err != nil {
return 0, err
}
origBusPeerIDs := ctrlParams.BusPeerIDs
busPeerIDs, busPeerIDsBuf, ok := ctrlClientSystemGetP2PCapsInitializeArray(origBusPeerIDs, ctrlParams.GpuCount)
if !ok {
return 0, ctrlCmdFailWithStatus(fi, ioctlParams, nvgpu.NV_ERR_INVALID_ARGUMENT)
}
ctrlParams.BusPeerIDs = busPeerIDs
n, err := rmControlInvoke(fi, ioctlParams, &ctrlParams)
ctrlParams.BusPeerIDs = origBusPeerIDs
if err != nil {
return n, err
}
if _, err := primitive.CopyUint32SliceOut(fi.t, addrFromP64(origBusPeerIDs), busPeerIDsBuf); err != nil {
return n, err
}
_, err = ctrlParams.CopyOut(fi.t, addrFromP64(ioctlParams.Params))
return n, err
}
func ctrlClientSystemGetP2PCapsV550(fi *frontendIoctlState, ioctlParams *nvgpu.NVOS54Parameters) (uintptr, error) {
var ctrlParams nvgpu.NV0000_CTRL_SYSTEM_GET_P2P_CAPS_PARAMS_V550
if ctrlParams.SizeBytes() != int(ioctlParams.ParamsSize) {
return 0, linuxerr.EINVAL
}
if _, err := ctrlParams.CopyIn(fi.t, addrFromP64(ioctlParams.Params)); err != nil {
return 0, err
}
origBusPeerIDs := ctrlParams.BusPeerIDs
busPeerIDs, busPeerIDsBuf, ok := ctrlClientSystemGetP2PCapsInitializeArray(origBusPeerIDs, ctrlParams.GpuCount)
if !ok {
return 0, ctrlCmdFailWithStatus(fi, ioctlParams, nvgpu.NV_ERR_INVALID_ARGUMENT)
}
ctrlParams.BusPeerIDs = busPeerIDs
origBusEgmPeerIDs := ctrlParams.BusEgmPeerIDs
busEgmPeerIDs, busEgmPeerIDsBuf, ok := ctrlClientSystemGetP2PCapsInitializeArray(origBusEgmPeerIDs, ctrlParams.GpuCount)
if !ok {
return 0, ctrlCmdFailWithStatus(fi, ioctlParams, nvgpu.NV_ERR_INVALID_ARGUMENT)
}
ctrlParams.BusEgmPeerIDs = busEgmPeerIDs
n, err := rmControlInvoke(fi, ioctlParams, &ctrlParams)
ctrlParams.BusPeerIDs = origBusPeerIDs
ctrlParams.BusEgmPeerIDs = origBusEgmPeerIDs
if err != nil {
return n, err
}
// If origBufPeerIDS or origBusEgmPeerIDs is null, the corresponding buffer will be nil
// and CopyUint32SliceOut() will be a no-op.
if _, err := primitive.CopyUint32SliceOut(fi.t, addrFromP64(origBusPeerIDs), busPeerIDsBuf); err != nil {
return n, err
}
if _, err := primitive.CopyUint32SliceOut(fi.t, addrFromP64(origBusEgmPeerIDs), busEgmPeerIDsBuf); err != nil {
return n, err
}
_, err = ctrlParams.CopyOut(fi.t, addrFromP64(ioctlParams.Params))
return n, err
}
func rmAllocInvoke[Params any](fi *frontendIoctlState, ioctlParams *nvgpu.NVOS64Parameters, allocParams *Params, isNVOS64 bool, addObjLocked func(fi *frontendIoctlState, ioctlParams *nvgpu.NVOS64Parameters, rightsRequested nvgpu.RS_ACCESS_MASK, allocParams *Params)) (uintptr, error) {
defer runtime.KeepAlive(allocParams) // since we convert to non-pointer-typed P64
+6 -4
View File
@@ -225,7 +225,6 @@ func Init() {
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: 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,
@@ -234,7 +233,6 @@ func Init() {
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: 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,
@@ -315,7 +313,9 @@ func Init() {
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],
@@ -420,7 +420,6 @@ func Init() {
nvgpu.NV0000_CTRL_CMD_CLIENT_GET_ADDR_SPACE_TYPE: simpleIoctl("NV0000_CTRL_CLIENT_GET_ADDR_SPACE_TYPE_PARAMS"),
nvgpu.NV0000_CTRL_CMD_CLIENT_SET_INHERITED_SHARE_POLICY: simpleIoctl("NV0000_CTRL_CLIENT_SET_INHERITED_SHARE_POLICY_PARAMS"),
nvgpu.NV0000_CTRL_CMD_GPU_GET_ATTACHED_IDS: simpleIoctl("NV0000_CTRL_GPU_GET_ATTACHED_IDS_PARAMS"),
nvgpu.NV0000_CTRL_CMD_GPU_GET_ID_INFO: simpleIoctl("NV0000_CTRL_GPU_GET_ID_INFO_PARAMS"),
nvgpu.NV0000_CTRL_CMD_GPU_GET_ID_INFO_V2: simpleIoctl("NV0000_CTRL_GPU_GET_ID_INFO_V2_PARAMS"),
nvgpu.NV0000_CTRL_CMD_GPU_GET_PROBED_IDS: simpleIoctl("NV0000_CTRL_GPU_GET_PROBED_IDS_PARAMS"),
nvgpu.NV0000_CTRL_CMD_GPU_ATTACH_IDS: simpleIoctl("NV0000_CTRL_GPU_ATTACH_IDS_PARAMS"),
@@ -429,7 +428,6 @@ func Init() {
nvgpu.NV0000_CTRL_CMD_GPU_QUERY_DRAIN_STATE: simpleIoctl("NV0000_CTRL_GPU_QUERY_DRAIN_STATE_PARAMS"),
nvgpu.NV0000_CTRL_CMD_GPU_GET_MEMOP_ENABLE: simpleIoctl("NV0000_CTRL_GPU_GET_MEMOP_ENABLE_PARAMS"),
nvgpu.NV0000_CTRL_CMD_SYNC_GPU_BOOST_GROUP_INFO: simpleIoctl("NV0000_SYNC_GPU_BOOST_GROUP_INFO_PARAMS"),
nvgpu.NV0000_CTRL_CMD_SYSTEM_GET_P2P_CAPS: simpleIoctl("NV0000_CTRL_SYSTEM_GET_P2P_CAPS_PARAMS"),
nvgpu.NV0000_CTRL_CMD_SYSTEM_GET_P2P_CAPS_V2: simpleIoctl("NV0000_CTRL_SYSTEM_GET_P2P_CAPS_V2_PARAMS"),
nvgpu.NV0000_CTRL_CMD_SYSTEM_GET_FABRIC_STATUS: simpleIoctl("NV0000_CTRL_SYSTEM_GET_FABRIC_STATUS_PARAMS"),
nvgpu.NV0000_CTRL_CMD_SYSTEM_GET_P2P_CAPS_MATRIX: simpleIoctl("NV0000_CTRL_SYSTEM_GET_P2P_CAPS_MATRIX_PARAMS"),
@@ -510,7 +508,9 @@ func Init() {
nvgpu.NVA06C_CTRL_CMD_PREEMPT: simpleIoctl("NVA06C_CTRL_PREEMPT_PARAMS"),
nvgpu.NVA06F_CTRL_CMD_GPFIFO_SCHEDULE: simpleIoctl("NVA06F_CTRL_GPFIFO_SCHEDULE_PARAMS"),
nvgpu.NVC56F_CTRL_CMD_GET_KMB: simpleIoctl("NVC56F_CTRL_CMD_GET_KMB_PARAMS"),
nvgpu.NV0000_CTRL_CMD_GPU_GET_ID_INFO: getStructName(nvgpu.NV0000_CTRL_GPU_GET_ID_INFO_PARAMS{}),
nvgpu.NV0000_CTRL_CMD_SYSTEM_GET_BUILD_VERSION: getStructName(nvgpu.NV0000_CTRL_SYSTEM_GET_BUILD_VERSION_PARAMS{}),
nvgpu.NV0000_CTRL_CMD_SYSTEM_GET_P2P_CAPS: getStructName(nvgpu.NV0000_CTRL_SYSTEM_GET_P2P_CAPS_PARAMS{}),
nvgpu.NV0000_CTRL_CMD_OS_UNIX_EXPORT_OBJECT_TO_FD: getStructName(nvgpu.NV0000_CTRL_OS_UNIX_EXPORT_OBJECT_TO_FD_PARAMS{}),
nvgpu.NV0000_CTRL_CMD_OS_UNIX_IMPORT_OBJECT_FROM_FD: getStructName(nvgpu.NV0000_CTRL_OS_UNIX_IMPORT_OBJECT_FROM_FD_PARAMS{}),
nvgpu.NV0000_CTRL_CMD_OS_UNIX_GET_EXPORT_OBJECT_INFO: getStructName(nvgpu.NV0000_CTRL_OS_UNIX_GET_EXPORT_OBJECT_INFO_PARAMS{}),
@@ -616,6 +616,7 @@ func Init() {
// 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]
prevNames := abi.getStructNames
@@ -630,6 +631,7 @@ func Init() {
// src/nvidia/src/kernel/rmapi/binary_api.c:binapiControl_IMPL().
// As such, there are no structs defined in the driver for this.
names.controlNames[(nvgpu.NV2081_BINAPI<<16)|0x0108] = nil
names.controlNames[nvgpu.NV0000_CTRL_CMD_SYSTEM_GET_P2P_CAPS] = getStructName(nvgpu.NV0000_CTRL_SYSTEM_GET_P2P_CAPS_PARAMS_V550{})
names.uvmNames[nvgpu.UVM_SET_PREFERRED_LOCATION] = getStructName(nvgpu.UVM_SET_PREFERRED_LOCATION_PARAMS_V550{})
return names