Files
open-gpu-kernel-modules/src/nvidia/inc/kernel/rmapi/control.h
Andy Ritger 90eb10774f 520.61.05
2022-10-10 14:59:24 -07:00

273 lines
11 KiB
C

/*
* SPDX-FileCopyrightText: Copyright (c) 2004-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef _CONTROL_H_
#define _CONTROL_H_
#include "core/core.h"
#include "resserv/rs_resource.h"
#include "resserv/resserv.h"
#include "utils/nvmacro.h"
#include "rmapi/param_copy.h"
struct NVOC_EXPORTED_METHOD_DEF;
typedef RS_RES_CONTROL_PARAMS_INTERNAL RmCtrlParams;
//
// RmCtrlExecuteCookie
//
// This typedef describes the data used by the rmctrl cmd execution
// path. The data is filled at the beginning of rmControlCmdExecute()
// and used as necessary in the other stages.
//
struct RS_CONTROL_COOKIE
{
// Rmctrl Command ID
NvU32 cmd;
// Rmctrl Flags
NvU32 ctrlFlags;
// Required Access Rights for this command
const RS_ACCESS_MASK rightsRequired;
NvBool bFreeParamCopy; ///< Indicates that param copies should be cleaned up
NvBool bFreeEmbeddedCopy; ///< Indicates embedded param copies should be cleaned up
RMAPI_PARAM_COPY paramCopy;
RMAPI_PARAM_COPY embeddedParamCopies[4]; // Up to 4 embedded pointers per one RmControl identified
};
typedef RS_CONTROL_COOKIE RmCtrlExecuteCookie;
// values for RmCtrlDeferredCmd.pending
#define RMCTRL_DEFERRED_FREE 0 // buffer is free
#define RMCTRL_DEFERRED_ACQUIRED 1 // buffer is acquired to fill in data
#define RMCTRL_DEFERRED_READY 2 // buffer is acquired and data has been copied.
#define RMCTRL_DEFERRED_MAX_PARAM_SIZE 128 // 128 bytes internal buffer for rmctrl param
typedef struct
{
NvS32 volatile pending;
NvU32 cpuInst;
RmCtrlParams rmCtrlDeferredParams;
NvU8 paramBuffer[RMCTRL_DEFERRED_MAX_PARAM_SIZE]; // buffer to hold rmCtrlDeferredParams.pParams
} RmCtrlDeferredCmd;
// catch commands misdirected to non-existent engines
#define VERIFY_OBJ_PTR(p) if (p == NULL) return NV_ERR_INVALID_ARGUMENT
// macros to get/set/clear cap bits
#define RMCTRL_GET_CAP(tbl,cap,field) (((NvU8)tbl[((1?cap##field)>=cap##_TBL_SIZE) ? 0/0 : (1?cap##field)]) & (0?cap##field))
#define RMCTRL_SET_CAP(tbl,cap,field) ((tbl[((1?cap##field)>=cap##_TBL_SIZE) ? 0/0 : (1?cap##field)]) |= (0?cap##field))
#define RMCTRL_CLEAR_CAP(tbl,cap,field) ((tbl[((1?cap##field)>=cap##_TBL_SIZE) ? 0/0 : (1?cap##field)]) &= ~(0?cap##field))
// macros to AND/OR caps between two tables
#define RMCTRL_AND_CAP(finaltbl,tmptbl,tmp,cap,field) \
tmp = ((finaltbl[((1?cap##field)>=cap##_TBL_SIZE) ? 0/0 : (1?cap##field)] & tmptbl[((1?cap##field)>=cap##_TBL_SIZE) ? 0/0 : (1?cap##field)]) & (0?cap##field)); \
finaltbl[((1?cap##field)>=cap##_TBL_SIZE) ? 0/0 : (1?cap##field)] &= ~(0?cap##field); \
finaltbl[((1?cap##field)>=cap##_TBL_SIZE) ? 0/0 : (1?cap##field)] |= tmp;
#define RMCTRL_OR_CAP(finaltbl,tmptbl,tmp,cap,field) \
tmp = ((finaltbl[((1?cap##field)>=cap##_TBL_SIZE) ? 0/0 : (1?cap##field)] | tmptbl[((1?cap##field)>=cap##_TBL_SIZE) ? 0/0 : (1?cap##field)]) & (0?cap##field)); \
finaltbl[((1?cap##field)>=cap##_TBL_SIZE) ? 0/0 : (1?cap##field)] &= ~(0?cap##field); \
finaltbl[((1?cap##field)>=cap##_TBL_SIZE) ? 0/0 : (1?cap##field)] |= tmp;
// Whether the command ID is a NULL command?
// We allow NVXXXX_CTRL_CMD_NULL (0x00000000) as well as the
// per-class NULL cmd ( _CATEGORY==0x00 and _INDEX==0x00 )
#define RMCTRL_IS_NULL_CMD(cmd) ((cmd == NVXXXX_CTRL_CMD_NULL) || \
(FLD_TEST_DRF_NUM(XXXX, _CTRL_CMD, _CATEGORY, 0x00, cmd) && \
FLD_TEST_DRF_NUM(XXXX, _CTRL_CMD, _INDEX, 0x00, cmd)))
// top-level internal RM Control interface
NV_STATUS rmControl_Deferred(RmCtrlDeferredCmd *pRmCtrlDeferredCmd);
// Helper functions for handling embedded parameter copies
NV_STATUS embeddedParamCopyIn(RMAPI_PARAM_COPY *pParamCopy, RmCtrlParams *pRmCtrlParams);
NV_STATUS embeddedParamCopyOut(RMAPI_PARAM_COPY *pParamCopy, RmCtrlParams *pRmCtrlParams);
#define RM_CLIENT_PTR_ACCESS_CHECK_READ NVBIT(0)
#define RM_CLIENT_PTR_ACCESS_CHECK_WRITE NVBIT(1)
//
// For NVOC Exported functions
//
// RMCTRL_FLAGS(A, B, C) is expanded to
// 0 | RMCTRL_FLAGS_A | RMCTRL_FLAGS_B | RMCTRL_FLAGS_C
//
// ACCESS_RIGHTS(A, B, C) is expanded to
// 0 | NVBIT(RS_ACCESS_A) | NVBIT(RS_ACCESS_B) | NVBIT(RS_ACCESS_C)
//
#define RMCTRL_EXPORT(cmdId, ...) [[nvoc::export(cmdId, __VA_ARGS__)]]
#define _RMCTRL_PREP_FLAG_ARG(x) | NV_CONCATENATE(RMCTRL_FLAGS_, x)
#define RMCTRL_FLAGS(...) (0 NV_FOREACH_ARG_NOCOMMA(_RMCTRL_PREP_FLAG_ARG, __VA_ARGS__))
#define _RMCTRL_PREP_ACCESS_ARG(x) | NVBIT(NV_CONCATENATE(RS_ACCESS_, x))
#define ACCESS_RIGHTS(...) (0 NV_FOREACH_ARG_NOCOMMA(_RMCTRL_PREP_ACCESS_ARG, __VA_ARGS__))
#define NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(ctrlFlags) \
( \
(ctrlFlags & RMCTRL_FLAGS_ROUTE_TO_PHYSICAL) && \
!RMCFG_FEATURE_PHYSICAL_RM \
)
//
// 'FLAGS' Attribute
// -----------------
//
// RMCTRL_FLAGS is used to specify per-command state.
//
#define RMCTRL_FLAGS_NONE 0x000000000
//
// If the KERNEL_PRIVILEGED flag is specified, the call will only be allowed
// for kernel mode callers (such as other kernel drivers) using a privileged
// kernel RM client (CliCheckIsKernelClient() returning true). Otherwise,
// NV_ERR_INSUFFICIENT_PERMISSIONS is returned.
//
#define RMCTRL_FLAGS_KERNEL_PRIVILEGED 0x000000000
//
// The resman rmcontrol handler will not grab the "gpus lock"
// before executing the implementing function.
//
// Please be sure you know what you're doing before using this!
//
#define RMCTRL_FLAGS_NO_GPUS_LOCK 0x000000001
//
// Indicate to resman that this rmcontrol does not access any gpu
// resources and can therefore run even when the gpu is powered down.
//
// Please be sure you know what you're doing before using this!
//
#define RMCTRL_FLAGS_NO_GPUS_ACCESS 0x000000002
//
// If the PRIVILEGED flag is specified, the call will only be allowed for
// a) user contexts with admin privleges (osIsAdministrator() returning true), or
// b) kernel mode callers, such as other kernel drivers.
// Otherwise, NV_ERR_INSUFFICIENT_PERMISSIONS is returned.
//
#define RMCTRL_FLAGS_PRIVILEGED 0x000000004
//
// If the NON_PRIVILEGED flag is specified, the call will be allowed from any
// client.
//
#define RMCTRL_FLAGS_NON_PRIVILEGED 0x000000010
//
// The resman rmcontrol handler will grab the per-device lock instead
// of the "gpus lock" before executing the implementing function.
//
// Please be sure you know what you're doing before using this!
//
#define RMCTRL_FLAGS_GPU_LOCK_DEVICE_ONLY 0x000000040
//
// This flag is equivalent to PRIVILEGED when the RM access rights
// implementation is disabled. Otherwise, it has no effect.
//
// The purpose of this flag is to aid in the transition to the access rights
// system, so that access rights can be used for control calls that were
// previously PRIVILEGED. Once access rights are enabled, this flag will no
// longer be necessary.
//
#define RMCTRL_FLAGS_PRIVILEGED_IF_RS_ACCESS_DISABLED 0x000000100 // for Resserv Access Rights migration
//
// This flag specifies that the control shall be directly forwarded to the
// physical object if called on the CPU-RM kernel.
//
#define RMCTRL_FLAGS_ROUTE_TO_PHYSICAL 0x000000200
//
// If the INTERNAL flag is specified, the call will only be allowed
// to be issued from RM itself. Otherwise, NV_ERR_NOT_SUPPORTED is returned.
//
#define RMCTRL_FLAGS_INTERNAL 0x000000400
//
// If the API_LOCK_READONLY flag is specified, the call will acquire the
// read-only API lock and may run concurrently with other operations that have
// also taken the read-only API lock. This flag is ignored if read-only API
// locking is disabled in RM.
//
#define RMCTRL_FLAGS_API_LOCK_READONLY 0x000000800
//
// If the :GPU_LOCK_READONLY flag is specified, the call will acquire a
// read-only GPU lock and may run concurrently with other operations that have
// also taken a read-only GPU lock. This flag is ignored if read-only GPU
// locking is disabled in RM.
//
#define RMCTRL_FLAGS_GPU_LOCK_READONLY 0x000001000
//
// This flag specifies that the control shall be directly forwarded to the
// the VGPU host if called from a guest (where IS_VIRTUAL() is true)
//
#define RMCTRL_FLAGS_ROUTE_TO_VGPU_HOST 0x000002000
//
// This flag specifies that the control output does not depend on the input
// parameters and can be cached on the receiving end.
// The cache is transparent and may not exist on all platforms.
//
#define RMCTRL_FLAGS_CACHEABLE 0x000004000
//
// This flag specifies that the control parameters will be
// copied out back to the caller even if the control call fails.
//
#define RMCTRL_FLAGS_COPYOUT_ON_ERROR 0x000008000
// ??
#define RMCTRL_FLAGS_ALLOW_WITHOUT_SYSMEM_ACCESS 0x000010000
//
// 'ACCESS_RIGHTS' Attribute
// ------------------------
//
// Used to specify a set of access rights that the client must hold on the
// target resource to execute this control call. Note that this can only check
// access rights on the target object; for other objects, such as those
// specified by handles in parameter structs, checks must be done manually.
//
// The definition of each access right and its meaning is provided in the
// README located at drivers/common/shared/accessrights/README. The prefix
// "RS_ACCESS" is appended to each entry in the control call definition;
// for example, :NICE -> RS_ACCESS_NICE.
//
// This attribute only has an effect when the RM access rights implementation
// is enabled; see g_bRsAccessEnabled.
//
#endif // _CONTROL_H_