1 /*
2 * SPDX-FileCopyrightText: Copyright (c) 2020-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3 * SPDX-License-Identifier: MIT
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24 //******************************************************************************
25 //
26 // Description:
27 // This file implements RPC code common to all builds.
28 //
29 //******************************************************************************
30
31 #include "gpu/gpu.h"
32 #include "gpu/device/device.h"
33 #include "vgpu/rpc.h"
34 #include "os/os.h"
35
36 #include "virtualization/kernel_vgpu_mgr.h"
37
38 #include "vgpu/vgpu_version.h"
39 #include "gpu/gsp/kernel_gsp.h"
40
41 #define RPC_STRUCTURES
42 #define RPC_GENERIC_UNION
43 #include "g_rpc-structures.h"
44 #undef RPC_STRUCTURES
45 #undef RPC_GENERIC_UNION
46
47 #define RPC_MESSAGE_STRUCTURES
48 #define RPC_MESSAGE_GENERIC_UNION
49 #include "g_rpc-message-header.h"
50 #undef RPC_MESSAGE_STRUCTURES
51 #undef RPC_MESSAGE_GENERIC_UNION
52
rpcRmApiSetup(OBJGPU * pGpu)53 static void rpcRmApiSetup(OBJGPU *pGpu)
54 {
55 //
56 // Physical RMAPI is already initialized for monolithic, and this function
57 // just needs to overwrite individual methods as needed
58 //
59 RM_API *pRmApi = GPU_GET_PHYSICAL_RMAPI(pGpu);
60 PORT_UNREFERENCED_VARIABLE(pRmApi);
61
62 if (IS_VIRTUAL(pGpu))
63 {
64 // none for now
65 }
66 else if (IS_GSP_CLIENT(pGpu))
67 {
68 pRmApi->Control = rpcRmApiControl_GSP;
69 pRmApi->AllocWithHandle = rpcRmApiAlloc_GSP;
70 pRmApi->Free = rpcRmApiFree_GSP;
71 pRmApi->DupObject = rpcRmApiDupObject_GSP;
72 }
73 }
74
initRpcObject(OBJGPU * pGpu)75 OBJRPC *initRpcObject(OBJGPU *pGpu)
76 {
77 OBJRPC *pRpc = NULL;
78
79 pRpc = portMemAllocNonPaged(sizeof(OBJRPC));
80 if (pRpc == NULL)
81 {
82 NV_PRINTF(LEVEL_ERROR,
83 "cannot allocate memory for OBJRPC (instance %d)\n",
84 gpuGetInstance(pGpu));
85 return NULL;
86 }
87 pRpc->timeoutCount = 0;
88 pRpc->bQuietPrints = NV_FALSE;
89
90 // VIRTUALIZATION is disabled on DCE. Only run the below code on VGPU and GSP.
91 rpcSetIpVersion(pGpu, pRpc,
92 RPC_VERSION_FROM_VGX_VERSION(VGX_MAJOR_VERSION_NUMBER,
93 VGX_MINOR_VERSION_NUMBER));
94 rpcObjIfacesSetup(pRpc);
95
96 rpcRmApiSetup(pGpu);
97
98 if (
99 !IS_GSP_CLIENT(pGpu))
100 {
101 if (NV_OK != rpcConstruct(pGpu, pRpc))
102 {
103 NV_PRINTF(LEVEL_ERROR, "rpcConstruct failed\n");
104 portMemFree(pRpc);
105 return NULL;
106 }
107 }
108
109 return pRpc;
110 }
111
rpcWriteCommonHeader(OBJGPU * pGpu,OBJRPC * pRpc,NvU32 func,NvU32 paramLength)112 NV_STATUS rpcWriteCommonHeader(OBJGPU *pGpu, OBJRPC *pRpc, NvU32 func, NvU32 paramLength)
113 {
114 NV_STATUS status = NV_OK;
115
116 if (!pRpc)
117 {
118 NV_PRINTF(LEVEL_ERROR,
119 "NVRM_RPC: called with NULL pRpc. Function %d.\n", func);
120 NV_ASSERT(0);
121 return NV_ERR_INVALID_STATE;
122 }
123
124 if (func == NV_VGPU_MSG_FUNCTION_RM_API_CONTROL)
125 portMemSet(pRpc->message_buffer, 0, pRpc->largeRpcSize);
126 else
127 portMemSet(pRpc->message_buffer, 0, pRpc->maxRpcSize);
128
129 vgpu_rpc_message_header_v->header_version = DRF_DEF(_VGPU, _MSG_HEADER_VERSION, _MAJOR, _TOT) |
130 DRF_DEF(_VGPU, _MSG_HEADER_VERSION, _MINOR, _TOT);
131 vgpu_rpc_message_header_v->signature = NV_VGPU_MSG_SIGNATURE_VALID;
132 vgpu_rpc_message_header_v->rpc_result = NV_VGPU_MSG_RESULT_RPC_PENDING;
133 vgpu_rpc_message_header_v->rpc_result_private = NV_VGPU_MSG_RESULT_RPC_PENDING;
134 if (gpuIsSriovEnabled(pGpu) && IS_GSP_CLIENT(pGpu))
135 {
136 // rpcWriteCommonHeader can be called by NV_RM_RPC_ALLOC_SHARE_DEVICE.
137 // In that moment we have Device with NV_DEVICE_ALLOCATION_FLAGS_HOST_VGPU_DEVICE flag
138 // but without HOST_VGPU_DEVICE pointer. Get GFID from pDevice manually
139 // to avoid HOST_VGPU_DEVICE check in vgpuGetCallingContextHostVgpuDevice.
140 Device *pDevice = vgpuGetCallingContextDevice(pGpu);
141
142 vgpu_rpc_message_header_v->u.cpuRmGfid = 0;
143 if (pDevice != NULL)
144 {
145 if (pDevice->pKernelHostVgpuDevice != NULL)
146 vgpu_rpc_message_header_v->u.cpuRmGfid = pDevice->pKernelHostVgpuDevice->gfid;
147 }
148 }
149 else
150 {
151 vgpu_rpc_message_header_v->u.spare = NV_VGPU_MSG_UNION_INIT;
152 }
153 vgpu_rpc_message_header_v->function = func;
154 vgpu_rpc_message_header_v->length = sizeof(rpc_message_header_v) + paramLength;
155
156 return status;
157 }
158