1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2021-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 #include <nv.h>
25 #include <nv-priv.h>
26 #include <osapi.h>
27 #include <core/thread_state.h>
28 #include <core/locks.h>
29 #include <gpu_mgr/gpu_mgr.h>
30 #include <gpu/gpu.h>
31 #include "kernel/gpu/intr/intr.h"
32 #include "gpu/bif/kernel_bif.h"
33 #include "gpu/mmu/kern_gmmu.h"
34 #include "gpu/disp/kern_disp.h"
35 #include <nv_sriov_defines.h>
36 #include "objtmr.h"
37 
osInterruptPending(OBJGPU * pGpu,NvBool * serviced,THREAD_STATE_NODE * pThreadState)38 static NvBool osInterruptPending(
39     OBJGPU            *pGpu,
40     NvBool            *serviced,
41     THREAD_STATE_NODE *pThreadState
42 )
43 {
44     OBJDISP *pDisp;
45     KernelDisplay   *pKernelDisplay;
46     NvBool pending, sema_release;
47     THREAD_STATE_NODE threadState;
48     NvU32 gpuMask, gpuInstance;
49     Intr *pIntr = NULL;
50     MC_ENGINE_BITVECTOR intr0Pending;
51     MC_ENGINE_BITVECTOR intr1Pending;
52 
53     *serviced = NV_FALSE;
54     pending = NV_FALSE;
55     sema_release = NV_TRUE;
56     OBJGPU *pDeviceLockGpu = pGpu;
57     NvU8 stackAllocator[TLS_ISR_ALLOCATOR_SIZE]; // ISR allocations come from this buffer
58     PORT_MEM_ALLOCATOR *pIsrAllocator;
59 
60     //
61     // GPU interrupt servicing ("top half")
62     //
63     // Top-level processing of GPU interrupts is performed using the
64     // steps below; although the code is straight forward, there
65     // are a few points to be aware of:
66     //
67     //  1) The GPUs lock is acquired for two reasons: to allow
68     //       looping over GPUs atomically in SLI and to sanity
69     //       check the PCI configuration space of any initialized
70     //       GPUs. If the acquisition fails, the early return
71     //       is acceptable since GPU interrupts are disabled while
72     //       the lock is held; note that returning success
73     //       in this case could interfere with the processing
74     //       of third-party device interrupts if the IRQ is shared.
75     //       Due to the above, some interrupts may be reported as
76     //       unhandled if invocations of the ISR registered with
77     //       the kernel are not serialized. This is bad, but
78     //       ignored by currently supported kernels, provided most
79     //       interrupts are handled.
80     //
81     //  2) Since acquisition of the lock disables interrupts
82     //       on all initialized GPUs, NV_PMC_INTR_EN_0 can not be
83     //       relied up on to determine whether interrupts are
84     //       expected from a given GPU. The code below is therefore
85     //       forced to rely on software state. NV_PMC_INTR_EN_0
86     //       is read only as a sanity check to guard against
87     //       invalid GPU state (lack of PCI memory access, etc.).
88     //
89     //  3) High priority interrupts (VBLANK, etc.), are serviced in
90     //       this function, service of all other interrupts is
91     //       deferred until a bottom half. If a bottom half needs
92     //       to be scheduled, release of the GPUs lock is
93     //       likewise deferred until completion of the bottom half.
94     //
95     //  4) To reduce the risk of starvation, an effort is made to
96     //       consolidate processing of interrupts pending on
97     //       all GPUs sharing a given IRQ.
98     //
99     //  5) Care is taken to ensure that the consolidated interrupt
100     //       processing is performed in the context of a GPU
101     //       that has interrupts pending. Else if additional ISR
102     //       processing via a bottom-half is required, this
103     //       bottom-half ISR might race against the GPU's shut-down
104     //       path.
105     //
106 
107     pIsrAllocator = portMemAllocatorCreateOnExistingBlock(stackAllocator, sizeof(stackAllocator));
108     tlsIsrInit(pIsrAllocator);
109 
110     //
111     // For SWRL granular locking process the countdown timer interrupt.
112     // GSP-RM handles SWRL interrupts if GSP-RM is active
113     //
114     if ((!IS_GSP_CLIENT(pGpu)) && (pGpu->getProperty(pGpu, PDB_PROP_GPU_SWRL_GRANULAR_LOCKING)))
115     {
116         threadStateInitISRLockless(&threadState, pDeviceLockGpu, THREAD_STATE_FLAGS_IS_ISR_LOCKLESS);
117 
118         gpuMask = gpumgrGetGpuMask(pDeviceLockGpu);
119 
120         gpuInstance = 0;
121         while ((pGpu = gpumgrGetNextGpu(gpuMask, &gpuInstance)) != NULL)
122         {
123             pIntr = GPU_GET_INTR(pGpu);
124 
125             if (INTERRUPT_TYPE_HARDWARE == intrGetIntrEn(pIntr))
126             {
127                 // If interrupt enable is garbage the GPU is probably in a bad state
128                 if (intrGetIntrEnFromHw_HAL(pGpu, pIntr, &threadState) > INTERRUPT_TYPE_MAX)
129                 {
130                    continue;
131                 }
132 
133                 OBJTMR *pTmr = GPU_GET_TIMER(pGpu);
134                 *serviced = tmrServiceSwrlWrapper(pGpu, pTmr, &threadState);
135             }
136         }
137 
138         threadStateFreeISRLockless(&threadState, pDeviceLockGpu, THREAD_STATE_FLAGS_IS_ISR_LOCKLESS);
139     }
140 
141     //
142     // Service nonstall interrupts before possibly acquiring GPUs lock
143     // so that we don't unnecesarily hold the lock while servicing them.
144     //
145     if (pDeviceLockGpu->getProperty(pDeviceLockGpu, PDB_PROP_GPU_ALTERNATE_TREE_ENABLED) &&
146         pDeviceLockGpu->getProperty(pDeviceLockGpu, PDB_PROP_GPU_ALTERNATE_TREE_HANDLE_LOCKLESS))
147     {
148         threadStateInitISRLockless(&threadState, pDeviceLockGpu, THREAD_STATE_FLAGS_IS_ISR_LOCKLESS);
149 
150         gpuMask = gpumgrGetGpuMask(pDeviceLockGpu);
151         gpuInstance = 0;
152         while ((pGpu = gpumgrGetNextGpu(gpuMask, &gpuInstance)) != NULL)
153         {
154             pIntr = GPU_GET_INTR(pGpu);
155             if ((pIntr != NULL) && (INTERRUPT_TYPE_HARDWARE == intrGetIntrEn(pIntr)))
156             {
157                 NvBool bCtxswLog = NV_FALSE;
158                 intrGetPendingNonStall_HAL(pGpu, pIntr, &intr1Pending, &threadState);
159                 intrCheckFecsEventbufferPending(pGpu, pIntr, &intr1Pending, &bCtxswLog);
160                 if (!bitVectorTestAllCleared(&intr1Pending))
161                 {
162                     intrServiceNonStall_HAL(pGpu, pIntr, &intr1Pending, &threadState);
163                     *serviced = NV_TRUE;
164                 }
165             }
166         }
167         threadStateFreeISRLockless(&threadState, pDeviceLockGpu, THREAD_STATE_FLAGS_IS_ISR_LOCKLESS);
168     }
169 
170     // LOCK: try to acquire GPUs lock
171     if (rmDeviceGpuLocksAcquire(pDeviceLockGpu, GPU_LOCK_FLAGS_COND_ACQUIRE, RM_LOCK_MODULES_ISR) == NV_OK)
172     {
173         threadStateInitISRAndDeferredIntHandler(&threadState,
174             pDeviceLockGpu, THREAD_STATE_FLAGS_IS_ISR);
175 
176         gpuMask = gpumgrGetGpuMask(pDeviceLockGpu);
177 
178         gpuInstance = 0;
179         while ((pGpu = gpumgrGetNextGpu(gpuMask, &gpuInstance)) != NULL)
180         {
181             pIntr = GPU_GET_INTR(pGpu);
182             pDisp = GPU_GET_DISP(pGpu);
183             pKernelDisplay = GPU_GET_KERNEL_DISPLAY(pGpu);
184 
185             if ((pDisp != NULL) && pGpu->getProperty(pGpu, PDB_PROP_GPU_TEGRA_SOC_NVDISPLAY))
186             {
187             }
188             else if ((pIntr != NULL) && INTERRUPT_TYPE_HARDWARE == intrGetIntrEn(pIntr))
189             {
190                 // If interrupt enable is garbage the GPU is probably in a bad state
191                 if (intrGetIntrEnFromHw_HAL(pGpu, pIntr, &threadState) > INTERRUPT_TYPE_MAX)
192                    continue;
193 
194                 intrGetPendingStall_HAL(pGpu, pIntr, &intr0Pending, &threadState);
195                 if (bitVectorTest(&intr0Pending, MC_ENGINE_IDX_DISP))
196                 {
197                     if (pKernelDisplay != NULL)
198                     {
199                         kdispServiceVblank_HAL(pGpu, pKernelDisplay, 0,
200                                                (VBLANK_STATE_PROCESS_LOW_LATENCY |
201                                                 VBLANK_STATE_PROCESS_CALLED_FROM_ISR),
202                                                &threadState);
203                         *serviced = NV_TRUE;
204                         intrGetPendingStall_HAL(pGpu, pIntr, &intr0Pending, &threadState);
205                     }
206                 }
207 
208                 if (IS_VGPU_GSP_PLUGIN_OFFLOAD_ENABLED(pGpu) &&
209                     !IS_VIRTUAL(pGpu) && bitVectorTest(&intr0Pending, MC_ENGINE_IDX_TMR))
210                 {
211                     // We have to clear the top level interrupt bit here since otherwise
212                     // the bottom half will attempt to service the interrupt on the CPU
213                     // side before GSP receives the notification and services it
214                     intrClearLeafVector_HAL(pGpu, pIntr, MC_ENGINE_IDX_TMR, &threadState);
215                     bitVectorClr(&intr0Pending, MC_ENGINE_IDX_TMR);
216 
217                     NV_ASSERT_OK(intrTriggerPrivDoorbell_HAL(pGpu, pIntr, NV_DOORBELL_NOTIFY_LEAF_SERVICE_TMR_HANDLE));
218                 }
219 
220                 if (pGpu->getProperty(pGpu, PDB_PROP_GPU_ALTERNATE_TREE_ENABLED) &&
221                     !pGpu->getProperty(pGpu, PDB_PROP_GPU_ALTERNATE_TREE_HANDLE_LOCKLESS))
222                 {
223                     pIntr = GPU_GET_INTR(pGpu);
224                     if (pIntr != NULL)
225                     {
226                         NvBool bCtxswLog = NV_FALSE;
227                         intrGetPendingNonStall_HAL(pGpu, pIntr, &intr1Pending, &threadState);
228                         intrCheckFecsEventbufferPending(pGpu, pIntr, &intr1Pending, &bCtxswLog);
229                     }
230                 }
231 
232                 if (!bitVectorTestAllCleared(&intr0Pending) ||
233                     !bitVectorTestAllCleared(&intr1Pending))
234                 {
235                     pending = NV_TRUE;
236                     sema_release = NV_FALSE;
237                 }
238             }
239         }
240         threadStateFreeISRAndDeferredIntHandler(&threadState,
241                 pDeviceLockGpu, THREAD_STATE_FLAGS_IS_ISR);
242 
243         if (sema_release)
244         {
245             NV_ASSERT(!pending);
246 
247             // UNLOCK: release GPUs lock
248             rmDeviceGpuLocksRelease(pDeviceLockGpu, GPUS_LOCK_FLAGS_NONE, NULL);
249         }
250         else
251         {
252             rmDeviceGpuLockSetOwner(pDeviceLockGpu, GPUS_LOCK_OWNER_PENDING_DPC_REFRESH);
253         }
254     }
255 
256     tlsIsrDestroy(pIsrAllocator);
257     portMemAllocatorRelease(pIsrAllocator);
258 
259     return pending;
260 }
261 
osIsr(OBJGPU * pGpu)262 NV_STATUS osIsr(
263     OBJGPU *pGpu
264 )
265 {
266     NV_STATUS status = NV_OK;
267     nv_state_t *nv = NV_GET_NV_STATE(pGpu);
268     nv_priv_t *nvp = NV_GET_NV_PRIV(nv);
269     NvBool pending = NV_FALSE;
270     NvBool serviced = NV_FALSE;
271     Intr *pIntr;
272 
273     if (nvp->flags & NV_INIT_FLAG_GPU_STATE_LOAD)
274     {
275         if (pGpu->getProperty(pGpu, PDB_PROP_GPU_TEGRA_SOC_NVDISPLAY))
276         {
277             pending = osInterruptPending(pGpu, &serviced, NULL /* threadstate */);
278         }
279         else
280         {
281             pIntr = GPU_GET_INTR(pGpu);
282             if (INTERRUPT_TYPE_HARDWARE == intrGetIntrEn(pIntr))
283             {
284                 KernelBif *pKernelBif = GPU_GET_KERNEL_BIF(pGpu);
285                 pending = osInterruptPending(pGpu, &serviced, NULL /* threadstate */);
286                 kbifCheckAndRearmMSI(pGpu, pKernelBif);
287             }
288         }
289     }
290 
291     if (!pending && (IS_VIRTUAL(pGpu) || !serviced))
292         status = NV_ERR_NO_INTR_PENDING;
293     else if (pending)
294         status = NV_WARN_MORE_PROCESSING_REQUIRED;
295 
296     return status;
297 }
298 
299 /*
300  * Helper function to determine when the RM SEMA/GPUS LOCK should toggle
301  * interrupts.  Based on the state of the GPU - we must add cases here as we
302  * discover them.
303  *
304  * Noteworthy special cases:
305  *
306  *   - Suspend/resume: the GPU could still be suspended and not accessible
307  *     on the bus, while passive-level threads need to grab the GPUs
308  *     lock, or other GPUs are being resumed and triggering interrupts.
309  *
310  *   - SLI state transitions: interrupts are disabled manually prior to
311  *     removing GPUs from the lock mask leading up to SLI link/unlink
312  *     operations on UNIX, but since the GPUs lock is not held by design in
313  *     these paths, it needs to be ensured that GPUs lock acquisitions
314  *     occurring aynchronously do not re-enable interrupts on any of the
315  *     GPUs undergoing the SLI state transition.
316  *
317  * @param[in] pGpu  OBJGPU pointer
318  *
319  * @return NV_TRUE if the RM SEMA/GPUS LOCK should toggle interrupts, NV_FALSE
320  *         otherwise.
321  */
osLockShouldToggleInterrupts(OBJGPU * pGpu)322 NvBool osLockShouldToggleInterrupts(OBJGPU *pGpu)
323 {
324     return (!pGpu->getProperty(pGpu, PDB_PROP_GPU_IN_PM_CODEPATH) &&
325              gpuIsStateLoaded(pGpu) &&
326             !pGpu->getProperty(pGpu, PDB_PROP_GPU_IN_SLI_LINK_CODEPATH));
327 }
328 
osEnableInterrupts(OBJGPU * pGpu)329 void osEnableInterrupts(OBJGPU *pGpu)
330 {
331     if (pGpu->getProperty(pGpu, PDB_PROP_GPU_TEGRA_SOC_NVDISPLAY))
332     {
333         // enable irq through os call
334         nv_control_soc_irqs(NV_GET_NV_STATE(pGpu), NV_TRUE);
335         return;
336     }
337     else
338     {
339         Intr *pIntr = GPU_GET_INTR(pGpu);
340         NvU32 intrEn;
341 
342         if (!pIntr->getProperty(pIntr, PDB_PROP_INTR_USE_INTR_MASK_FOR_LOCKING))
343             NV_ASSERT(intrGetIntrEnFromHw_HAL(pGpu, pIntr, NULL) == INTERRUPT_TYPE_DISABLED);
344 
345         intrEn = intrGetIntrEn(pIntr);
346         intrSetIntrEnInHw_HAL(pGpu, pIntr, intrEn, NULL);
347         intrSetStall_HAL(pGpu, pIntr, intrEn, NULL);
348 
349         if (pGpu->getProperty(pGpu, PDB_PROP_GPU_ALTERNATE_TREE_ENABLED))
350         {
351             intrRestoreNonStall_HAL(pGpu, pIntr, intrGetIntrEn(pIntr), NULL);
352         }
353 
354     }
355 }
356 
osDisableInterrupts(OBJGPU * pGpu,NvBool bIsr)357 void osDisableInterrupts(
358     OBJGPU *pGpu,
359     NvBool  bIsr
360 )
361 {
362     if (pGpu->getProperty(pGpu, PDB_PROP_GPU_TEGRA_SOC_NVDISPLAY))
363     {
364         // disable irq through os call
365         nv_control_soc_irqs(NV_GET_NV_STATE(pGpu), NV_FALSE);
366         return;
367     }
368     else
369     {
370         Intr *pIntr = GPU_GET_INTR(pGpu);
371         NvU32 new_intr_en_0 = INTERRUPT_TYPE_DISABLED;
372 
373         intrSetIntrEnInHw_HAL(pGpu, pIntr, new_intr_en_0, NULL);
374 
375         intrSetStall_HAL(pGpu, pIntr, new_intr_en_0, NULL);
376 
377         if (pGpu->getProperty(pGpu, PDB_PROP_GPU_ALTERNATE_TREE_ENABLED))
378         {
379             if (pGpu->getProperty(pGpu, PDB_PROP_GPU_ALTERNATE_TREE_HANDLE_LOCKLESS))
380             {
381                 intrRestoreNonStall_HAL(pGpu, pIntr, intrGetIntrEn(pIntr), NULL);
382             }
383             else
384             {
385                 intrRestoreNonStall_HAL(pGpu, pIntr, new_intr_en_0, NULL);
386             }
387         }
388     }
389 }
390 
RmIsrBottomHalf(nv_state_t * pNv)391 static void RmIsrBottomHalf(
392     nv_state_t *pNv
393 )
394 {
395     OBJGPU    *pGpu = NV_GET_NV_PRIV_PGPU(pNv);
396     THREAD_STATE_NODE threadState;
397     OS_THREAD_HANDLE threadId;
398     NvU32 gpuMask, gpuInstance;
399     OBJGPU *pDeviceLockGpu = pGpu;
400     Intr *pIntr = NULL;
401     OBJDISP *pDisp = NULL;
402     NvU8 stackAllocator[TLS_ISR_ALLOCATOR_SIZE]; // ISR allocations come from this buffer
403     PORT_MEM_ALLOCATOR *pIsrAllocator;
404 
405     pIsrAllocator = portMemAllocatorCreateOnExistingBlock(stackAllocator, sizeof(stackAllocator));
406     tlsIsrInit(pIsrAllocator);
407 
408     //
409     // The owning thread changes as the ISR acquires the GPUs lock,
410     // but the bottom half releases it.  Refresh the ThreadId owner to be
411     // correct here for the bottom half context.
412     //
413     osGetCurrentThread(&threadId);
414     rmDeviceGpuLockSetOwner(pDeviceLockGpu, threadId);
415 
416     gpuMask = gpumgrGetGpuMask(pGpu);
417 
418     gpuInstance = 0;
419     while ((pGpu = gpumgrGetNextGpu(gpuMask, &gpuInstance)) != NULL)
420     {
421 
422         threadStateInitISRAndDeferredIntHandler(&threadState,
423             pGpu, THREAD_STATE_FLAGS_IS_ISR_DEFERRED_INT_HANDLER);
424 
425         pIntr = GPU_GET_INTR(pGpu);
426         pDisp = GPU_GET_DISP(pGpu);
427 
428         //
429         // Call disp service incase of SOC Display,
430         // TODO : with multi interrupt handling based on irq aux interrupts are serviced by dpAuxService
431         // See JIRA task TDS-4253.
432         //
433         if ((pDisp != NULL) && pGpu->getProperty(pGpu, PDB_PROP_GPU_TEGRA_SOC_NVDISPLAY))
434         {
435         }
436         else if ((pIntr != NULL) && (INTERRUPT_TYPE_HARDWARE == intrGetIntrEn(pIntr)))
437         {
438             intrServiceStall_HAL(pGpu, pIntr);
439 
440             if (pGpu->getProperty(pGpu, PDB_PROP_GPU_ALTERNATE_TREE_ENABLED) &&
441                 !pGpu->getProperty(pGpu, PDB_PROP_GPU_ALTERNATE_TREE_HANDLE_LOCKLESS))
442             {
443                 MC_ENGINE_BITVECTOR intrPending;
444                 intrServiceNonStall_HAL(pGpu, pIntr, &intrPending, &threadState);
445             }
446         }
447 
448         threadStateFreeISRAndDeferredIntHandler(&threadState,
449             pGpu, THREAD_STATE_FLAGS_IS_ISR_DEFERRED_INT_HANDLER);
450     }
451 
452     // UNLOCK: release GPUs lock
453     rmDeviceGpuLocksRelease(pDeviceLockGpu, GPUS_LOCK_FLAGS_NONE, NULL);
454 
455     tlsIsrDestroy(pIsrAllocator);
456     portMemAllocatorRelease(pIsrAllocator);
457 }
458 
RmIsrBottomHalfUnlocked(nv_state_t * pNv)459 static void RmIsrBottomHalfUnlocked(
460     nv_state_t *pNv
461 )
462 {
463     OBJGPU  *pGpu = NV_GET_NV_PRIV_PGPU(pNv);
464     Intr *pIntr;
465     THREAD_STATE_NODE threadState;
466 
467     // In the GSP client scenario, the fatal fault interrupt is not shared
468     // by UVM and CPU-RM.  Instead, it is handled entirely by GSP-RM.  We
469     // therefore do not expect this function to be called.  But if it is, bail
470     // without attempting to service interrupts.
471     if (IS_GSP_CLIENT(pGpu))
472     {
473         return;
474     }
475 
476     // Grab GPU lock here as this kthread-item was enqueued without grabbing GPU lock
477     if (rmDeviceGpuLocksAcquire(pGpu, GPUS_LOCK_FLAGS_NONE, RM_LOCK_MODULES_DPC) == NV_OK)
478     {
479         if (FULL_GPU_SANITY_CHECK(pGpu))
480         {
481             pIntr = GPU_GET_INTR(pGpu);
482 
483             threadStateInit(&threadState, THREAD_STATE_FLAGS_NONE);
484 
485             if (intrGetIntrEn(pIntr) != INTERRUPT_TYPE_DISABLED)
486             {
487                 MC_ENGINE_BITVECTOR intrPending;
488                 intrGetPendingStall_HAL(pGpu, pIntr, &intrPending, &threadState);
489                 intrServiceNonStallBottomHalf(pGpu, pIntr, &intrPending, &threadState);
490             }
491 
492             threadStateFree(&threadState, THREAD_STATE_FLAGS_NONE);
493         }
494 
495         rmDeviceGpuLocksRelease(pGpu, GPUS_LOCK_FLAGS_NONE, NULL);
496     }
497 }
498 
rm_isr(nvidia_stack_t * sp,nv_state_t * nv,NvU32 * NeedBottomHalf)499 NvBool NV_API_CALL rm_isr(
500     nvidia_stack_t *sp,
501     nv_state_t *nv,
502     NvU32      *NeedBottomHalf
503 )
504 {
505     NV_STATUS status;
506     nv_priv_t *nvp = NV_GET_NV_PRIV(nv);
507     OBJGPU *pGpu;
508     NvBool retval;
509     void *fp;
510 
511     if ((nvp->flags & NV_INIT_FLAG_GPU_STATE_LOAD) == 0)
512     {
513         return NV_FALSE;
514     }
515 
516     pGpu = NV_GET_NV_PRIV_PGPU(nv);
517     if (pGpu == NULL)
518     {
519         return NV_FALSE;
520     }
521 
522     NV_ENTER_RM_RUNTIME(sp,fp);
523 
524     // call actual isr function here
525     status = isrWrapper(pGpu->testIntr, pGpu);
526 
527     switch (status)
528     {
529         case NV_OK:
530             *NeedBottomHalf = NV_FALSE;
531             retval = NV_TRUE;
532             break;
533         case NV_WARN_MORE_PROCESSING_REQUIRED:
534             *NeedBottomHalf = NV_TRUE;
535             retval = NV_TRUE;
536             break;
537         case NV_ERR_NO_INTR_PENDING:
538         default:
539             *NeedBottomHalf = NV_FALSE;
540             retval = NV_FALSE;
541             break;
542     }
543 
544     NV_EXIT_RM_RUNTIME(sp,fp);
545 
546     return retval;
547 }
548 
rm_isr_bh(nvidia_stack_t * sp,nv_state_t * pNv)549 void NV_API_CALL rm_isr_bh(
550     nvidia_stack_t *sp,
551     nv_state_t *pNv
552 )
553 {
554     void    *fp;
555 
556     NV_ENTER_RM_RUNTIME(sp,fp);
557 
558     RmIsrBottomHalf(pNv);
559 
560     NV_EXIT_RM_RUNTIME(sp,fp);
561 }
562 
rm_isr_bh_unlocked(nvidia_stack_t * sp,nv_state_t * pNv)563 void NV_API_CALL rm_isr_bh_unlocked(
564     nvidia_stack_t *sp,
565     nv_state_t *pNv
566 )
567 {
568     void    *fp;
569 
570     NV_ENTER_RM_RUNTIME(sp,fp);
571 
572     RmIsrBottomHalfUnlocked(pNv);
573 
574     NV_EXIT_RM_RUNTIME(sp,fp);
575 }
576 
rm_gpu_copy_mmu_faults(nvidia_stack_t * sp,nv_state_t * nv,NvU32 * faultsCopied)577 NV_STATUS NV_API_CALL rm_gpu_copy_mmu_faults(
578     nvidia_stack_t *sp,
579     nv_state_t *nv,
580     NvU32 *faultsCopied
581 )
582 {
583     NV_STATUS status = NV_OK;
584     OBJGPU *pGpu;
585     void   *fp;
586 
587     NV_ENTER_RM_RUNTIME(sp,fp);
588 
589     pGpu = NV_GET_NV_PRIV_PGPU(nv);
590     if (pGpu == NULL || faultsCopied == NULL)
591     {
592         status = NV_ERR_OBJECT_NOT_FOUND;
593         goto done;
594     }
595 
596     if (IS_GSP_CLIENT(pGpu))
597     {
598         // Non-replayable faults are copied to the client shadow buffer by GSP-RM.
599         status = NV_OK;
600         goto done;
601     }
602     else
603     {
604         KernelGmmu *pKernelGmmu = GPU_GET_KERNEL_GMMU(pGpu);
605         PORT_MEM_ALLOCATOR *pIsrAllocator;
606         THREAD_STATE_NODE   threadState;
607         NvU8 stackAllocator[TLS_ISR_ALLOCATOR_SIZE]; // ISR allocations come from this buffer
608 
609         if (pKernelGmmu == NULL)
610         {
611             status = NV_ERR_OBJECT_NOT_FOUND;
612             goto done;
613         }
614 
615         // If MMU fault buffer is not enabled, return early
616         if (!gpuIsVoltaHubIntrSupported(pGpu))
617             goto done;
618 
619         pIsrAllocator = portMemAllocatorCreateOnExistingBlock(stackAllocator, sizeof(stackAllocator));
620         tlsIsrInit(pIsrAllocator);
621         threadStateInitISRAndDeferredIntHandler(&threadState, pGpu, THREAD_STATE_FLAGS_IS_ISR);
622 
623         // Copies all valid packets in RM's and client's shadow buffer
624         status  = kgmmuCopyMmuFaults_HAL(pGpu, pKernelGmmu, &threadState, faultsCopied,
625                                          NON_REPLAYABLE_FAULT_BUFFER, NV_FALSE);
626 
627         threadStateFreeISRAndDeferredIntHandler(&threadState, pGpu, THREAD_STATE_FLAGS_IS_ISR);
628         tlsIsrDestroy(pIsrAllocator);
629         portMemAllocatorRelease(pIsrAllocator);
630 
631     }
632 
633 done:
634     NV_EXIT_RM_RUNTIME(sp,fp);
635 
636     return status;
637 }
638 
639 //
640 // Use this call when MMU faults needs to be copied
641 // outisde of RM lock.
642 //
_rm_gpu_copy_mmu_faults_unlocked(OBJGPU * pGpu,NvU32 * pFaultsCopied,THREAD_STATE_NODE * pThreadState)643 static NV_STATUS _rm_gpu_copy_mmu_faults_unlocked(
644     OBJGPU *pGpu,
645     NvU32 *pFaultsCopied,
646     THREAD_STATE_NODE *pThreadState
647 )
648 {
649     KernelGmmu *pKernelGmmu = GPU_GET_KERNEL_GMMU(pGpu);
650 
651     if (pKernelGmmu == NULL)
652     {
653         return NV_ERR_OBJECT_NOT_FOUND;
654     }
655 
656     // If MMU fault buffer is not enabled, return early
657     if (!gpuIsVoltaHubIntrSupported(pGpu))
658         return NV_OK;
659 
660     // Copies all valid packets in RM's and client's shadow buffer
661     return kgmmuCopyMmuFaults_HAL(pGpu, pKernelGmmu, pThreadState, pFaultsCopied,
662                                   NON_REPLAYABLE_FAULT_BUFFER, NV_FALSE);
663 
664     return NV_OK;
665 }
666 
667 //
668 // Wrapper to handle calls to copy mmu faults
669 //
rm_gpu_handle_mmu_faults(nvidia_stack_t * sp,nv_state_t * nv,NvU32 * faultsCopied)670 NV_STATUS rm_gpu_handle_mmu_faults(
671     nvidia_stack_t *sp,
672     nv_state_t *nv,
673     NvU32 *faultsCopied
674 )
675 {
676     NvU32 status = NV_OK;
677     OBJGPU *pGpu;
678     void *fp;
679 
680     NV_ENTER_RM_RUNTIME(sp,fp);
681 
682     *faultsCopied = 0;
683     pGpu = NV_GET_NV_PRIV_PGPU(nv);
684 
685     if (pGpu == NULL)
686     {
687         NV_EXIT_RM_RUNTIME(sp,fp);
688         return NV_ERR_OBJECT_NOT_FOUND;
689     }
690 
691     {
692         KernelGmmu *pKernelGmmu;
693         PORT_MEM_ALLOCATOR *pIsrAllocator;
694         THREAD_STATE_NODE threadState;
695         NvU8 stackAllocator[TLS_ISR_ALLOCATOR_SIZE]; // ISR allocations come from this buffer
696 
697         pIsrAllocator = portMemAllocatorCreateOnExistingBlock(stackAllocator, sizeof(stackAllocator));
698         tlsIsrInit(pIsrAllocator);
699         threadStateInitISRLockless(&threadState, pGpu, THREAD_STATE_FLAGS_IS_ISR_LOCKLESS);
700 
701         pKernelGmmu = GPU_GET_KERNEL_GMMU(pGpu);
702 
703         if (IS_VGPU_GSP_PLUGIN_OFFLOAD_ENABLED(pGpu) && !IS_VIRTUAL(pGpu))
704         {
705             Intr *pIntr = GPU_GET_INTR(pGpu);
706 
707             if (kgmmuIsNonReplayableFaultPending_HAL(pGpu, pKernelGmmu, &threadState))
708             {
709                 // We have to clear the top level interrupt bit here since otherwise
710                 // the bottom half will attempt to service the interrupt on the CPU
711                 // side before GSP receives the notification and services it
712                 kgmmuClearNonReplayableFaultIntr_HAL(pGpu, pKernelGmmu, &threadState);
713                 status = intrTriggerPrivDoorbell_HAL(pGpu, pIntr, NV_DOORBELL_NOTIFY_LEAF_SERVICE_NON_REPLAYABLE_FAULT_HANDLE);
714 
715             }
716         }
717         else if (IS_VIRTUAL_WITH_SRIOV(pGpu))
718         {
719             if (kgmmuIsNonReplayableFaultPending_HAL(pGpu, pKernelGmmu, &threadState))
720             {
721                 status = _rm_gpu_copy_mmu_faults_unlocked(pGpu, faultsCopied, &threadState);
722             }
723         }
724         else
725         {
726             if (IS_GSP_CLIENT(pGpu))
727             {
728                 // Non-replayable faults are copied to the client shadow buffer by GSP-RM.
729                 status = NV_OK;
730             }
731             else
732             {
733                 status = _rm_gpu_copy_mmu_faults_unlocked(pGpu, faultsCopied, &threadState);
734             }
735         }
736 
737         threadStateFreeISRLockless(&threadState, pGpu, THREAD_STATE_FLAGS_IS_ISR_LOCKLESS);
738         tlsIsrDestroy(pIsrAllocator);
739         portMemAllocatorRelease(pIsrAllocator);
740     }
741 
742     NV_EXIT_RM_RUNTIME(sp,fp);
743     return status;
744 }
745 
rm_is_msix_allowed(nvidia_stack_t * sp,nv_state_t * nv)746 NvBool NV_API_CALL rm_is_msix_allowed(
747     nvidia_stack_t *sp,
748     nv_state_t     *nv
749 )
750 {
751     nv_priv_t           *pNvp = NV_GET_NV_PRIV(nv);
752     THREAD_STATE_NODE    threadState;
753     void                *fp;
754     NvBool               ret = NV_FALSE;
755 
756     NV_ENTER_RM_RUNTIME(sp,fp);
757     threadStateInit(&threadState, THREAD_STATE_FLAGS_NONE);
758 
759     if (rmapiLockAcquire(API_LOCK_FLAGS_NONE, RM_LOCK_MODULES_INIT) == NV_OK)
760     {
761         ret = gpumgrIsDeviceMsixAllowed(nv->regs->cpu_address,
762                                         pNvp->pmc_boot_1, pNvp->pmc_boot_42);
763         rmapiLockRelease();
764     }
765 
766     threadStateFree(&threadState, THREAD_STATE_FLAGS_NONE);
767     NV_EXIT_RM_RUNTIME(sp,fp);
768     return ret;
769 }
770