1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2018-2020 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 #ifndef _RS_UTILS_H_
24 #define _RS_UTILS_H_
25 
26 /**
27  * @defgroup RsUtilities
28  *
29  * Provides convenience utilities for resserv. Utility functions provide
30  * abstractions that take handles as inputs -- helpful for legacy code that
31  * passes hClient or hResource handles and not underlying objects. Desire
32  * is for pClient and RsResourceRef types to be used for new code instead of
33  * passing handles around and this utility module phased out.
34  *
35  * @{
36  */
37 
38 #include "resserv/rs_server.h"
39 #include "resserv/rs_client.h"
40 #include "resserv/rs_resource.h"
41 
42 #include "rmapi/client.h"
43 
44 #include "containers/list.h"
45 
46 MAKE_LIST(ClientHandlesList, NvHandle);
47 
48 #define serverutilGetDerived(pRmClient, hResource, ppBaseRes, type) \
49     (clientGetResource(staticCast((pRmClient), RsClient),           \
50             (hResource),                                            \
51             classId(type),                                          \
52             (ppBaseRes)) != NV_OK)                                  \
53             ? NULL                                                  \
54             : dynamicCast(*(ppBaseRes), type)
55 
56 /**
57   * Get the reference to a resource
58   * @param[in]   hClient Client handle
59   * @param[in]   hResource The resource to lookup
60   * @param[out]  ppResourceRef The reference to the resource
61   */
62 NV_STATUS serverutilGetResourceRef(NvHandle hClient, NvHandle hObject,
63                                   RsResourceRef **ppResourceRef);
64 
65 /**
66   * Get the reference to a resource (with a type check)
67   * @param[in]   hClient Client handle
68   * @param[in]   hResource The resource to lookup
69   * @param[out]  ppResourceRef The reference to the resource
70   */
71 NV_STATUS serverutilGetResourceRefWithType(NvHandle hClient, NvHandle hObject,
72                                           NvU32 internalClassId, RsResourceRef **ppResourceRef);
73 
74 /**
75   * Get the reference to a resource (with a type and parent check)
76   * @param[in]   hClient Client handle
77   * @param[in]   hResource The resource to lookup
78   * @param[out]  ppResourceRef The reference to the resource
79   */
80 NV_STATUS serverutilGetResourceRefWithParent(NvHandle hClient, NvHandle hParent, NvHandle hObject,
81                                             NvU32 internalClassId, RsResourceRef **ppResourceRef);
82 
83 /**
84  * Find the first child object of given type
85  */
86 RsResourceRef *serverutilFindChildRefByType(NvHandle hClient, NvHandle hParent, NvU32 internalClassId, NvBool bExactMatch);
87 
88 
89 /**
90  * Get an iterator to the elements in the client's resource map
91  *
92  * See clientRefIter for documentation on hScopedObject and iterType
93  */
94 RS_ITERATOR serverutilRefIter(NvHandle hClient, NvHandle hScopedObject, NvU32 internalClassId, RS_ITER_TYPE iterType, NvBool bExactMatch);
95 
96 /**
97  * Get an iterator to the elements in the server's shared object map
98  */
99 RS_SHARE_ITERATOR serverutilShareIter(NvU32 internalClassId);
100 
101 /**
102  * Get an iterator to the elements in the server's shared object map
103  */
104 NvBool serverutilShareIterNext(RS_SHARE_ITERATOR* pIt);
105 
106 /**
107  * Validate that a given resource handle is well-formed and does not already
108  * exist under a given client.
109  */
110 NvBool serverutilValidateNewResourceHandle(NvHandle, NvHandle);
111 
112 /**
113  * Generate an unused handle for a resource. The handle will be generated in the white-listed range that was
114  * specified when the client was allocated.
115  */
116 NV_STATUS serverutilGenResourceHandle(NvHandle, NvHandle*);
117 
118 /**
119  * Get a client pointer from a client handle without taking any locks.
120  *
121  * @param[in]   hClient The client to acquire
122  */
123 RmClient *serverutilGetClientUnderLock(NvHandle hClient);
124 
125 /**
126  * Get a client pointer from a client handle and lock it.
127  *
128  * @param[in]   hClient The client to acquire
129  * @param[in]   access LOCK_ACCESS_*
130  * @param[out]  ppClient Pointer to the RmClient
131  */
132 NV_STATUS serverutilAcquireClient(NvHandle hClient, LOCK_ACCESS_TYPE access, RmClient **ppClient);
133 
134 /**
135  * Unlock a client
136  *
137  * @param[in]   access LOCK_ACCESS_*
138  * @param[in]   pClient Pointer to the RmClient
139  */
140 void serverutilReleaseClient(LOCK_ACCESS_TYPE access, RmClient *pClient);
141 
142 /**
143  * Get the first valid client pointer in resource server without taking any locks.
144  */
145 RmClient **serverutilGetFirstClientUnderLock(void);
146 
147 /**
148  * Get the next valid client pointer in resource server without taking any locks.
149  *
150  * @param[in]   ppClient Pointer returned by a previous call to
151  *                       serverutilGetFirstClientUnderLock or
152  *                       serverutilGetNextClientUnderLock
153  */
154 RmClient **serverutilGetNextClientUnderLock(RmClient **pClient);
155 
156 /*!
157  * @brief Retrieve all hClients allocated for the given (ProcID, SubProcessID)
158  *
159  * This function iterates through all the clients in the resource server and finds
160  * hClients allocated for the given (ProcID, SubProcessID) and returns them to
161  * the caller.
162  *
163  * @param[in]  procID           Process ID
164  * @param[in]  subProcessID     SubProcess ID
165  * @param[out] pClientList      List in which the client handles are returned
166  *
167  * @return NV_STATUS
168  */
169 NV_STATUS serverutilGetClientHandlesFromPid(NvU32 procID, NvU32 subProcessID, ClientHandlesList *pClientList);
170 
171 /**
172  * This is a filtering function intended to be used with refFindCpuMappingWithFilter.
173  * This filter will only match user mappings belonging to the current process.
174  *
175  * @param[in] ppMapping The mapping that is being filtered
176  */
177 NvBool serverutilMappingFilterCurrentUserProc(RsCpuMapping *ppMapping);
178 
179 /**
180  * This is a filtering function intended to be used with refFindCpuMappingWithFilter.
181  * This filter will only match kernel mappings.
182  *
183  * @param[in] ppMapping The mapping that is being filtered
184  */
185 NvBool serverutilMappingFilterKernel(RsCpuMapping *ppMapping);
186 
187 #endif
188