.. | .. |
---|
1 | 1 | // SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note |
---|
2 | 2 | /* |
---|
3 | 3 | * |
---|
4 | | - * (C) COPYRIGHT 2019-2021 ARM Limited. All rights reserved. |
---|
| 4 | + * (C) COPYRIGHT 2019-2023 ARM Limited. All rights reserved. |
---|
5 | 5 | * |
---|
6 | 6 | * This program is free software and is provided to you under the terms of the |
---|
7 | 7 | * GNU General Public License version 2 as published by the Free Software |
---|
.. | .. |
---|
88 | 88 | * context's address space, when the page fault occurs for |
---|
89 | 89 | * MCU's address space. |
---|
90 | 90 | */ |
---|
91 | | - if (!queue_work(as->pf_wq, &as->work_pagefault)) |
---|
92 | | - kbase_ctx_sched_release_ctx(kctx); |
---|
93 | | - else { |
---|
| 91 | + if (!queue_work(as->pf_wq, &as->work_pagefault)) { |
---|
94 | 92 | dev_dbg(kbdev->dev, |
---|
95 | | - "Page fault is already pending for as %u\n", |
---|
96 | | - as_nr); |
---|
| 93 | + "Page fault is already pending for as %u", as_nr); |
---|
| 94 | + kbase_ctx_sched_release_ctx(kctx); |
---|
| 95 | + } else { |
---|
97 | 96 | atomic_inc(&kbdev->faults_pending); |
---|
98 | 97 | } |
---|
99 | 98 | } |
---|
.. | .. |
---|
122 | 121 | access_type, kbase_gpu_access_type_name(fault->status), |
---|
123 | 122 | source_id); |
---|
124 | 123 | |
---|
| 124 | + kbase_debug_csf_fault_notify(kbdev, NULL, DF_GPU_PAGE_FAULT); |
---|
| 125 | + |
---|
125 | 126 | /* Report MMU fault for all address spaces (except MCU_AS_NR) */ |
---|
126 | 127 | for (as_no = 1; as_no < kbdev->nr_hw_address_spaces; as_no++) |
---|
127 | 128 | submit_work_pagefault(kbdev, as_no, fault); |
---|
.. | .. |
---|
130 | 131 | if (kbase_prepare_to_reset_gpu(kbdev, |
---|
131 | 132 | RESET_FLAGS_HWC_UNRECOVERABLE_ERROR)) |
---|
132 | 133 | kbase_reset_gpu(kbdev); |
---|
| 134 | + |
---|
133 | 135 | } |
---|
134 | 136 | KBASE_EXPORT_TEST_API(kbase_mmu_report_mcu_as_fault_and_reset); |
---|
135 | 137 | |
---|
.. | .. |
---|
148 | 150 | "true" : "false"; |
---|
149 | 151 | int as_no = as->number; |
---|
150 | 152 | unsigned long flags; |
---|
| 153 | + const uintptr_t fault_addr = fault->addr; |
---|
151 | 154 | |
---|
152 | 155 | /* terminal fault, print info about the fault */ |
---|
153 | 156 | dev_err(kbdev->dev, |
---|
154 | | - "GPU bus fault in AS%d at VA 0x%016llX\n" |
---|
155 | | - "VA_VALID: %s\n" |
---|
| 157 | + "GPU bus fault in AS%d at PA %pK\n" |
---|
| 158 | + "PA_VALID: %s\n" |
---|
156 | 159 | "raw fault status: 0x%X\n" |
---|
157 | 160 | "exception type 0x%X: %s\n" |
---|
158 | 161 | "access type 0x%X: %s\n" |
---|
159 | 162 | "source id 0x%X\n" |
---|
160 | 163 | "pid: %d\n", |
---|
161 | | - as_no, fault->addr, |
---|
| 164 | + as_no, (void *)fault_addr, |
---|
162 | 165 | addr_valid, |
---|
163 | 166 | status, |
---|
164 | 167 | exception_type, kbase_gpu_exception_name(exception_type), |
---|
.. | .. |
---|
187 | 190 | kbase_reg_write(kbdev, GPU_CONTROL_REG(GPU_COMMAND), |
---|
188 | 191 | GPU_COMMAND_CLEAR_FAULT); |
---|
189 | 192 | spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags); |
---|
| 193 | + |
---|
190 | 194 | } |
---|
191 | 195 | |
---|
192 | 196 | /* |
---|
.. | .. |
---|
248 | 252 | mutex_unlock(&kbdev->mmu_hw_mutex); |
---|
249 | 253 | /* AS transaction end */ |
---|
250 | 254 | |
---|
| 255 | + kbase_debug_csf_fault_notify(kbdev, kctx, DF_GPU_PAGE_FAULT); |
---|
251 | 256 | /* Switching to UNMAPPED mode above would have enabled the firmware to |
---|
252 | 257 | * recover from the fault (if the memory access was made by firmware) |
---|
253 | 258 | * and it can then respond to CSG termination requests to be sent now. |
---|
.. | .. |
---|
261 | 266 | KBASE_MMU_FAULT_TYPE_PAGE_UNEXPECTED); |
---|
262 | 267 | kbase_mmu_hw_enable_fault(kbdev, as, |
---|
263 | 268 | KBASE_MMU_FAULT_TYPE_PAGE_UNEXPECTED); |
---|
| 269 | + |
---|
264 | 270 | } |
---|
265 | 271 | |
---|
266 | 272 | /** |
---|
.. | .. |
---|
482 | 488 | kbase_csf_ctx_handle_fault(kctx, fault); |
---|
483 | 489 | kbase_ctx_sched_release_ctx_lock(kctx); |
---|
484 | 490 | |
---|
485 | | - atomic_dec(&kbdev->faults_pending); |
---|
486 | | - |
---|
487 | 491 | /* A work for GPU fault is complete. |
---|
488 | 492 | * Till reaching here, no further GPU fault will be reported. |
---|
489 | 493 | * Now clear the GPU fault to allow next GPU fault interrupt report. |
---|
.. | .. |
---|
492 | 496 | kbase_reg_write(kbdev, GPU_CONTROL_REG(GPU_COMMAND), |
---|
493 | 497 | GPU_COMMAND_CLEAR_FAULT); |
---|
494 | 498 | spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags); |
---|
| 499 | + |
---|
| 500 | + atomic_dec(&kbdev->faults_pending); |
---|
495 | 501 | } |
---|
496 | 502 | |
---|
497 | 503 | /** |
---|
.. | .. |
---|
546 | 552 | } |
---|
547 | 553 | KBASE_EXPORT_TEST_API(kbase_mmu_gpu_fault_interrupt); |
---|
548 | 554 | |
---|
549 | | -int kbase_mmu_as_init(struct kbase_device *kbdev, int i) |
---|
| 555 | +int kbase_mmu_as_init(struct kbase_device *kbdev, unsigned int i) |
---|
550 | 556 | { |
---|
551 | 557 | kbdev->as[i].number = i; |
---|
552 | 558 | kbdev->as[i].bf_data.addr = 0ULL; |
---|
553 | 559 | kbdev->as[i].pf_data.addr = 0ULL; |
---|
554 | 560 | kbdev->as[i].gf_data.addr = 0ULL; |
---|
| 561 | + kbdev->as[i].is_unresponsive = false; |
---|
555 | 562 | |
---|
556 | | - kbdev->as[i].pf_wq = alloc_workqueue("mali_mmu%d", 0, 1, i); |
---|
| 563 | + kbdev->as[i].pf_wq = alloc_workqueue("mali_mmu%d", WQ_UNBOUND, 1, i); |
---|
557 | 564 | if (!kbdev->as[i].pf_wq) |
---|
558 | 565 | return -ENOMEM; |
---|
559 | 566 | |
---|