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