hc
2023-12-06 08f87f769b595151be1afeff53e144f543faa614
kernel/drivers/gpu/arm/bifrost/mali_kbase_debug_mem_view.c
....@@ -31,6 +31,22 @@
3131
3232 #if IS_ENABLED(CONFIG_DEBUG_FS)
3333
34
+#define SHOW_GPU_MEM_DATA(type, format) \
35
+{ \
36
+ unsigned int i, j; \
37
+ const type *ptr = (type *)cpu_addr; \
38
+ const unsigned int col_width = sizeof(type); \
39
+ const unsigned int row_width = (col_width == sizeof(u64)) ? 32 : 16; \
40
+ const unsigned int num_cols = row_width / col_width; \
41
+ for (i = 0; i < PAGE_SIZE; i += row_width) { \
42
+ seq_printf(m, "%016llx:", gpu_addr + i); \
43
+ for (j = 0; j < num_cols; j++) \
44
+ seq_printf(m, format, ptr[j]); \
45
+ ptr += num_cols; \
46
+ seq_putc(m, '\n'); \
47
+ } \
48
+}
49
+
3450 struct debug_mem_mapping {
3551 struct list_head node;
3652
....@@ -44,6 +60,7 @@
4460 struct debug_mem_data {
4561 struct list_head mapping_list;
4662 struct kbase_context *kctx;
63
+ unsigned int column_width;
4764 };
4865
4966 struct debug_mem_seq_off {
....@@ -111,9 +128,9 @@
111128 struct debug_mem_data *mem_data = m->private;
112129 struct debug_mem_seq_off *data = v;
113130 struct debug_mem_mapping *map;
114
- int i, j;
131
+ unsigned long long gpu_addr;
115132 struct page *page;
116
- uint32_t *mapping;
133
+ void *cpu_addr;
117134 pgprot_t prot = PAGE_KERNEL;
118135
119136 map = list_entry(data->lh, struct debug_mem_mapping, node);
....@@ -130,20 +147,33 @@
130147 prot = pgprot_writecombine(prot);
131148
132149 page = as_page(map->alloc->pages[data->offset]);
133
- mapping = vmap(&page, 1, VM_MAP, prot);
134
- if (!mapping)
150
+ cpu_addr = vmap(&page, 1, VM_MAP, prot);
151
+ if (!cpu_addr)
135152 goto out;
136153
137
- for (i = 0; i < PAGE_SIZE; i += 4*sizeof(*mapping)) {
138
- seq_printf(m, "%016llx:", i + ((map->start_pfn +
139
- data->offset) << PAGE_SHIFT));
154
+ gpu_addr = (map->start_pfn + data->offset) << PAGE_SHIFT;
140155
141
- for (j = 0; j < 4*sizeof(*mapping); j += sizeof(*mapping))
142
- seq_printf(m, " %08x", mapping[(i+j)/sizeof(*mapping)]);
143
- seq_putc(m, '\n');
156
+ /* Cases for 4 supported values of column_width for showing
157
+ * the GPU memory contents.
158
+ */
159
+ switch (mem_data->column_width) {
160
+ case 1:
161
+ SHOW_GPU_MEM_DATA(u8, " %02hhx");
162
+ break;
163
+ case 2:
164
+ SHOW_GPU_MEM_DATA(u16, " %04hx");
165
+ break;
166
+ case 4:
167
+ SHOW_GPU_MEM_DATA(u32, " %08x");
168
+ break;
169
+ case 8:
170
+ SHOW_GPU_MEM_DATA(u64, " %016llx");
171
+ break;
172
+ default:
173
+ dev_warn(mem_data->kctx->kbdev->dev, "Unexpected column width");
144174 }
145175
146
- vunmap(mapping);
176
+ vunmap(cpu_addr);
147177
148178 seq_putc(m, '\n');
149179
....@@ -207,6 +237,14 @@
207237 if (get_file_rcu(kctx->filp) == 0)
208238 return -ENOENT;
209239
240
+ /* Check if file was opened in write mode. GPU memory contents
241
+ * are returned only when the file is not opened in write mode.
242
+ */
243
+ if (file->f_mode & FMODE_WRITE) {
244
+ file->private_data = kctx;
245
+ return 0;
246
+ }
247
+
210248 ret = seq_open(file, &ops);
211249 if (ret)
212250 goto open_fail;
....@@ -222,6 +260,8 @@
222260 INIT_LIST_HEAD(&mem_data->mapping_list);
223261
224262 kbase_gpu_vm_lock(kctx);
263
+
264
+ mem_data->column_width = kctx->mem_view_column_width;
225265
226266 ret = debug_mem_zone_open(&kctx->reg_rbtree_same, mem_data);
227267 if (ret != 0) {
....@@ -240,6 +280,20 @@
240280 kbase_gpu_vm_unlock(kctx);
241281 goto out;
242282 }
283
+
284
+#if MALI_USE_CSF
285
+ ret = debug_mem_zone_open(&kctx->reg_rbtree_exec_fixed, mem_data);
286
+ if (ret != 0) {
287
+ kbase_gpu_vm_unlock(kctx);
288
+ goto out;
289
+ }
290
+
291
+ ret = debug_mem_zone_open(&kctx->reg_rbtree_fixed, mem_data);
292
+ if (ret != 0) {
293
+ kbase_gpu_vm_unlock(kctx);
294
+ goto out;
295
+ }
296
+#endif
243297
244298 kbase_gpu_vm_unlock(kctx);
245299
....@@ -270,25 +324,62 @@
270324 static int debug_mem_release(struct inode *inode, struct file *file)
271325 {
272326 struct kbase_context *const kctx = inode->i_private;
273
- struct seq_file *sfile = file->private_data;
274
- struct debug_mem_data *mem_data = sfile->private;
275
- struct debug_mem_mapping *mapping;
276327
277
- seq_release(inode, file);
328
+ /* If the file wasn't opened in write mode, then release the
329
+ * memory allocated to show the GPU memory contents.
330
+ */
331
+ if (!(file->f_mode & FMODE_WRITE)) {
332
+ struct seq_file *sfile = file->private_data;
333
+ struct debug_mem_data *mem_data = sfile->private;
334
+ struct debug_mem_mapping *mapping;
278335
279
- while (!list_empty(&mem_data->mapping_list)) {
280
- mapping = list_first_entry(&mem_data->mapping_list,
336
+ seq_release(inode, file);
337
+
338
+ while (!list_empty(&mem_data->mapping_list)) {
339
+ mapping = list_first_entry(&mem_data->mapping_list,
281340 struct debug_mem_mapping, node);
282
- kbase_mem_phy_alloc_put(mapping->alloc);
283
- list_del(&mapping->node);
284
- kfree(mapping);
285
- }
341
+ kbase_mem_phy_alloc_put(mapping->alloc);
342
+ list_del(&mapping->node);
343
+ kfree(mapping);
344
+ }
286345
287
- kfree(mem_data);
346
+ kfree(mem_data);
347
+ }
288348
289349 fput(kctx->filp);
290350
291351 return 0;
352
+}
353
+
354
+static ssize_t debug_mem_write(struct file *file, const char __user *ubuf,
355
+ size_t count, loff_t *ppos)
356
+{
357
+ struct kbase_context *const kctx = file->private_data;
358
+ unsigned int column_width = 0;
359
+ int ret = 0;
360
+
361
+ CSTD_UNUSED(ppos);
362
+
363
+ ret = kstrtouint_from_user(ubuf, count, 0, &column_width);
364
+
365
+ if (ret)
366
+ return ret;
367
+ if (!is_power_of_2(column_width)) {
368
+ dev_dbg(kctx->kbdev->dev,
369
+ "Column width %u not a multiple of power of 2", column_width);
370
+ return -EINVAL;
371
+ }
372
+ if (column_width > 8) {
373
+ dev_dbg(kctx->kbdev->dev,
374
+ "Column width %u greater than 8 not supported", column_width);
375
+ return -EINVAL;
376
+ }
377
+
378
+ kbase_gpu_vm_lock(kctx);
379
+ kctx->mem_view_column_width = column_width;
380
+ kbase_gpu_vm_unlock(kctx);
381
+
382
+ return count;
292383 }
293384
294385 static const struct file_operations kbase_debug_mem_view_fops = {
....@@ -296,6 +387,7 @@
296387 .open = debug_mem_open,
297388 .release = debug_mem_release,
298389 .read = seq_read,
390
+ .write = debug_mem_write,
299391 .llseek = seq_lseek
300392 };
301393
....@@ -308,6 +400,9 @@
308400 WARN_ON(IS_ERR_OR_NULL(kctx->kctx_dentry)))
309401 return;
310402
403
+ /* Default column width is 4 */
404
+ kctx->mem_view_column_width = sizeof(u32);
405
+
311406 debugfs_create_file("mem_view", 0400, kctx->kctx_dentry, kctx,
312407 &kbase_debug_mem_view_fops);
313408 }