1 // SPDX-License-Identifier: GPL-2.0
2 
3 /*
4  * Copyright 2016-2019 HabanaLabs, Ltd.
5  * All Rights Reserved.
6  */
7 
8 #include "habanalabs.h"
9 #include "include/hw_ip/mmu/mmu_general.h"
10 
11 #include <linux/pci.h>
12 #include <linux/debugfs.h>
13 #include <linux/uaccess.h>
14 
15 #define MMU_ADDR_BUF_SIZE	40
16 #define MMU_ASID_BUF_SIZE	10
17 #define MMU_KBUF_SIZE		(MMU_ADDR_BUF_SIZE + MMU_ASID_BUF_SIZE)
18 
19 static struct dentry *hl_debug_root;
20 
hl_debugfs_i2c_read(struct hl_device * hdev,u8 i2c_bus,u8 i2c_addr,u8 i2c_reg,u32 * val)21 static int hl_debugfs_i2c_read(struct hl_device *hdev, u8 i2c_bus, u8 i2c_addr,
22 				u8 i2c_reg, u32 *val)
23 {
24 	struct armcp_packet pkt;
25 	int rc;
26 
27 	if (hl_device_disabled_or_in_reset(hdev))
28 		return -EBUSY;
29 
30 	memset(&pkt, 0, sizeof(pkt));
31 
32 	pkt.ctl = cpu_to_le32(ARMCP_PACKET_I2C_RD <<
33 				ARMCP_PKT_CTL_OPCODE_SHIFT);
34 	pkt.i2c_bus = i2c_bus;
35 	pkt.i2c_addr = i2c_addr;
36 	pkt.i2c_reg = i2c_reg;
37 
38 	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
39 					HL_DEVICE_TIMEOUT_USEC, (long *) val);
40 
41 	if (rc)
42 		dev_err(hdev->dev, "Failed to read from I2C, error %d\n", rc);
43 
44 	return rc;
45 }
46 
hl_debugfs_i2c_write(struct hl_device * hdev,u8 i2c_bus,u8 i2c_addr,u8 i2c_reg,u32 val)47 static int hl_debugfs_i2c_write(struct hl_device *hdev, u8 i2c_bus, u8 i2c_addr,
48 				u8 i2c_reg, u32 val)
49 {
50 	struct armcp_packet pkt;
51 	int rc;
52 
53 	if (hl_device_disabled_or_in_reset(hdev))
54 		return -EBUSY;
55 
56 	memset(&pkt, 0, sizeof(pkt));
57 
58 	pkt.ctl = cpu_to_le32(ARMCP_PACKET_I2C_WR <<
59 				ARMCP_PKT_CTL_OPCODE_SHIFT);
60 	pkt.i2c_bus = i2c_bus;
61 	pkt.i2c_addr = i2c_addr;
62 	pkt.i2c_reg = i2c_reg;
63 	pkt.value = cpu_to_le64(val);
64 
65 	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
66 					HL_DEVICE_TIMEOUT_USEC, NULL);
67 
68 	if (rc)
69 		dev_err(hdev->dev, "Failed to write to I2C, error %d\n", rc);
70 
71 	return rc;
72 }
73 
hl_debugfs_led_set(struct hl_device * hdev,u8 led,u8 state)74 static void hl_debugfs_led_set(struct hl_device *hdev, u8 led, u8 state)
75 {
76 	struct armcp_packet pkt;
77 	int rc;
78 
79 	if (hl_device_disabled_or_in_reset(hdev))
80 		return;
81 
82 	memset(&pkt, 0, sizeof(pkt));
83 
84 	pkt.ctl = cpu_to_le32(ARMCP_PACKET_LED_SET <<
85 				ARMCP_PKT_CTL_OPCODE_SHIFT);
86 	pkt.led_index = cpu_to_le32(led);
87 	pkt.value = cpu_to_le64(state);
88 
89 	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
90 						HL_DEVICE_TIMEOUT_USEC, NULL);
91 
92 	if (rc)
93 		dev_err(hdev->dev, "Failed to set LED %d, error %d\n", led, rc);
94 }
95 
command_buffers_show(struct seq_file * s,void * data)96 static int command_buffers_show(struct seq_file *s, void *data)
97 {
98 	struct hl_debugfs_entry *entry = s->private;
99 	struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
100 	struct hl_cb *cb;
101 	bool first = true;
102 
103 	spin_lock(&dev_entry->cb_spinlock);
104 
105 	list_for_each_entry(cb, &dev_entry->cb_list, debugfs_list) {
106 		if (first) {
107 			first = false;
108 			seq_puts(s, "\n");
109 			seq_puts(s, " CB ID   CTX ID   CB size    CB RefCnt    mmap?   CS counter\n");
110 			seq_puts(s, "---------------------------------------------------------------\n");
111 		}
112 		seq_printf(s,
113 			"   %03d        %d    0x%08x      %d          %d          %d\n",
114 			cb->id, cb->ctx_id, cb->size,
115 			kref_read(&cb->refcount),
116 			cb->mmap, cb->cs_cnt);
117 	}
118 
119 	spin_unlock(&dev_entry->cb_spinlock);
120 
121 	if (!first)
122 		seq_puts(s, "\n");
123 
124 	return 0;
125 }
126 
command_submission_show(struct seq_file * s,void * data)127 static int command_submission_show(struct seq_file *s, void *data)
128 {
129 	struct hl_debugfs_entry *entry = s->private;
130 	struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
131 	struct hl_cs *cs;
132 	bool first = true;
133 
134 	spin_lock(&dev_entry->cs_spinlock);
135 
136 	list_for_each_entry(cs, &dev_entry->cs_list, debugfs_list) {
137 		if (first) {
138 			first = false;
139 			seq_puts(s, "\n");
140 			seq_puts(s, " CS ID   CTX ASID   CS RefCnt   Submitted    Completed\n");
141 			seq_puts(s, "------------------------------------------------------\n");
142 		}
143 		seq_printf(s,
144 			"   %llu       %d          %d           %d            %d\n",
145 			cs->sequence, cs->ctx->asid,
146 			kref_read(&cs->refcount),
147 			cs->submitted, cs->completed);
148 	}
149 
150 	spin_unlock(&dev_entry->cs_spinlock);
151 
152 	if (!first)
153 		seq_puts(s, "\n");
154 
155 	return 0;
156 }
157 
command_submission_jobs_show(struct seq_file * s,void * data)158 static int command_submission_jobs_show(struct seq_file *s, void *data)
159 {
160 	struct hl_debugfs_entry *entry = s->private;
161 	struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
162 	struct hl_cs_job *job;
163 	bool first = true;
164 
165 	spin_lock(&dev_entry->cs_job_spinlock);
166 
167 	list_for_each_entry(job, &dev_entry->cs_job_list, debugfs_list) {
168 		if (first) {
169 			first = false;
170 			seq_puts(s, "\n");
171 			seq_puts(s, " JOB ID   CS ID    CTX ASID   H/W Queue\n");
172 			seq_puts(s, "---------------------------------------\n");
173 		}
174 		if (job->cs)
175 			seq_printf(s,
176 				"    %02d       %llu         %d         %d\n",
177 				job->id, job->cs->sequence, job->cs->ctx->asid,
178 				job->hw_queue_id);
179 		else
180 			seq_printf(s,
181 				"    %02d       0         %d         %d\n",
182 				job->id, HL_KERNEL_ASID_ID, job->hw_queue_id);
183 	}
184 
185 	spin_unlock(&dev_entry->cs_job_spinlock);
186 
187 	if (!first)
188 		seq_puts(s, "\n");
189 
190 	return 0;
191 }
192 
userptr_show(struct seq_file * s,void * data)193 static int userptr_show(struct seq_file *s, void *data)
194 {
195 	struct hl_debugfs_entry *entry = s->private;
196 	struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
197 	struct hl_userptr *userptr;
198 	char dma_dir[4][30] = {"DMA_BIDIRECTIONAL", "DMA_TO_DEVICE",
199 				"DMA_FROM_DEVICE", "DMA_NONE"};
200 	bool first = true;
201 
202 	spin_lock(&dev_entry->userptr_spinlock);
203 
204 	list_for_each_entry(userptr, &dev_entry->userptr_list, debugfs_list) {
205 		if (first) {
206 			first = false;
207 			seq_puts(s, "\n");
208 			seq_puts(s, " user virtual address     size             dma dir\n");
209 			seq_puts(s, "----------------------------------------------------------\n");
210 		}
211 		seq_printf(s,
212 			"    0x%-14llx      %-10u    %-30s\n",
213 			userptr->addr, userptr->size, dma_dir[userptr->dir]);
214 	}
215 
216 	spin_unlock(&dev_entry->userptr_spinlock);
217 
218 	if (!first)
219 		seq_puts(s, "\n");
220 
221 	return 0;
222 }
223 
vm_show(struct seq_file * s,void * data)224 static int vm_show(struct seq_file *s, void *data)
225 {
226 	struct hl_debugfs_entry *entry = s->private;
227 	struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
228 	struct hl_ctx *ctx;
229 	struct hl_vm *vm;
230 	struct hl_vm_hash_node *hnode;
231 	struct hl_userptr *userptr;
232 	struct hl_vm_phys_pg_pack *phys_pg_pack = NULL;
233 	enum vm_type_t *vm_type;
234 	bool once = true;
235 	u64 j;
236 	int i;
237 
238 	if (!dev_entry->hdev->mmu_enable)
239 		return 0;
240 
241 	spin_lock(&dev_entry->ctx_mem_hash_spinlock);
242 
243 	list_for_each_entry(ctx, &dev_entry->ctx_mem_hash_list, debugfs_list) {
244 		once = false;
245 		seq_puts(s, "\n\n----------------------------------------------------");
246 		seq_puts(s, "\n----------------------------------------------------\n\n");
247 		seq_printf(s, "ctx asid: %u\n", ctx->asid);
248 
249 		seq_puts(s, "\nmappings:\n\n");
250 		seq_puts(s, "    virtual address        size          handle\n");
251 		seq_puts(s, "----------------------------------------------------\n");
252 		mutex_lock(&ctx->mem_hash_lock);
253 		hash_for_each(ctx->mem_hash, i, hnode, node) {
254 			vm_type = hnode->ptr;
255 
256 			if (*vm_type == VM_TYPE_USERPTR) {
257 				userptr = hnode->ptr;
258 				seq_printf(s,
259 					"    0x%-14llx      %-10u\n",
260 					hnode->vaddr, userptr->size);
261 			} else {
262 				phys_pg_pack = hnode->ptr;
263 				seq_printf(s,
264 					"    0x%-14llx      %-10llu       %-4u\n",
265 					hnode->vaddr, phys_pg_pack->total_size,
266 					phys_pg_pack->handle);
267 			}
268 		}
269 		mutex_unlock(&ctx->mem_hash_lock);
270 
271 		vm = &ctx->hdev->vm;
272 		spin_lock(&vm->idr_lock);
273 
274 		if (!idr_is_empty(&vm->phys_pg_pack_handles))
275 			seq_puts(s, "\n\nallocations:\n");
276 
277 		idr_for_each_entry(&vm->phys_pg_pack_handles, phys_pg_pack, i) {
278 			if (phys_pg_pack->asid != ctx->asid)
279 				continue;
280 
281 			seq_printf(s, "\nhandle: %u\n", phys_pg_pack->handle);
282 			seq_printf(s, "page size: %u\n\n",
283 						phys_pg_pack->page_size);
284 			seq_puts(s, "   physical address\n");
285 			seq_puts(s, "---------------------\n");
286 			for (j = 0 ; j < phys_pg_pack->npages ; j++) {
287 				seq_printf(s, "    0x%-14llx\n",
288 						phys_pg_pack->pages[j]);
289 			}
290 		}
291 		spin_unlock(&vm->idr_lock);
292 
293 	}
294 
295 	spin_unlock(&dev_entry->ctx_mem_hash_spinlock);
296 
297 	if (!once)
298 		seq_puts(s, "\n");
299 
300 	return 0;
301 }
302 
303 /* these inline functions are copied from mmu.c */
get_hop0_addr(struct hl_ctx * ctx)304 static inline u64 get_hop0_addr(struct hl_ctx *ctx)
305 {
306 	return ctx->hdev->asic_prop.mmu_pgt_addr +
307 			(ctx->asid * ctx->hdev->asic_prop.mmu_hop_table_size);
308 }
309 
get_hop0_pte_addr(struct hl_ctx * ctx,u64 hop_addr,u64 virt_addr)310 static inline u64 get_hop0_pte_addr(struct hl_ctx *ctx, u64 hop_addr,
311 		u64 virt_addr)
312 {
313 	return hop_addr + ctx->hdev->asic_prop.mmu_pte_size *
314 			((virt_addr & HOP0_MASK) >> HOP0_SHIFT);
315 }
316 
get_hop1_pte_addr(struct hl_ctx * ctx,u64 hop_addr,u64 virt_addr)317 static inline u64 get_hop1_pte_addr(struct hl_ctx *ctx, u64 hop_addr,
318 		u64 virt_addr)
319 {
320 	return hop_addr + ctx->hdev->asic_prop.mmu_pte_size *
321 			((virt_addr & HOP1_MASK) >> HOP1_SHIFT);
322 }
323 
get_hop2_pte_addr(struct hl_ctx * ctx,u64 hop_addr,u64 virt_addr)324 static inline u64 get_hop2_pte_addr(struct hl_ctx *ctx, u64 hop_addr,
325 		u64 virt_addr)
326 {
327 	return hop_addr + ctx->hdev->asic_prop.mmu_pte_size *
328 			((virt_addr & HOP2_MASK) >> HOP2_SHIFT);
329 }
330 
get_hop3_pte_addr(struct hl_ctx * ctx,u64 hop_addr,u64 virt_addr)331 static inline u64 get_hop3_pte_addr(struct hl_ctx *ctx, u64 hop_addr,
332 		u64 virt_addr)
333 {
334 	return hop_addr + ctx->hdev->asic_prop.mmu_pte_size *
335 			((virt_addr & HOP3_MASK) >> HOP3_SHIFT);
336 }
337 
get_hop4_pte_addr(struct hl_ctx * ctx,u64 hop_addr,u64 virt_addr)338 static inline u64 get_hop4_pte_addr(struct hl_ctx *ctx, u64 hop_addr,
339 		u64 virt_addr)
340 {
341 	return hop_addr + ctx->hdev->asic_prop.mmu_pte_size *
342 			((virt_addr & HOP4_MASK) >> HOP4_SHIFT);
343 }
344 
get_next_hop_addr(u64 curr_pte)345 static inline u64 get_next_hop_addr(u64 curr_pte)
346 {
347 	if (curr_pte & PAGE_PRESENT_MASK)
348 		return curr_pte & PHYS_ADDR_MASK;
349 	else
350 		return ULLONG_MAX;
351 }
352 
mmu_show(struct seq_file * s,void * data)353 static int mmu_show(struct seq_file *s, void *data)
354 {
355 	struct hl_debugfs_entry *entry = s->private;
356 	struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
357 	struct hl_device *hdev = dev_entry->hdev;
358 	struct hl_ctx *ctx;
359 
360 	u64 hop0_addr = 0, hop0_pte_addr = 0, hop0_pte = 0,
361 		hop1_addr = 0, hop1_pte_addr = 0, hop1_pte = 0,
362 		hop2_addr = 0, hop2_pte_addr = 0, hop2_pte = 0,
363 		hop3_addr = 0, hop3_pte_addr = 0, hop3_pte = 0,
364 		hop4_addr = 0, hop4_pte_addr = 0, hop4_pte = 0,
365 		virt_addr = dev_entry->mmu_addr;
366 
367 	if (!hdev->mmu_enable)
368 		return 0;
369 
370 	if (dev_entry->mmu_asid == HL_KERNEL_ASID_ID)
371 		ctx = hdev->kernel_ctx;
372 	else
373 		ctx = hdev->compute_ctx;
374 
375 	if (!ctx) {
376 		dev_err(hdev->dev, "no ctx available\n");
377 		return 0;
378 	}
379 
380 	mutex_lock(&ctx->mmu_lock);
381 
382 	/* the following lookup is copied from unmap() in mmu.c */
383 
384 	hop0_addr = get_hop0_addr(ctx);
385 	hop0_pte_addr = get_hop0_pte_addr(ctx, hop0_addr, virt_addr);
386 	hop0_pte = hdev->asic_funcs->read_pte(hdev, hop0_pte_addr);
387 	hop1_addr = get_next_hop_addr(hop0_pte);
388 
389 	if (hop1_addr == ULLONG_MAX)
390 		goto not_mapped;
391 
392 	hop1_pte_addr = get_hop1_pte_addr(ctx, hop1_addr, virt_addr);
393 	hop1_pte = hdev->asic_funcs->read_pte(hdev, hop1_pte_addr);
394 	hop2_addr = get_next_hop_addr(hop1_pte);
395 
396 	if (hop2_addr == ULLONG_MAX)
397 		goto not_mapped;
398 
399 	hop2_pte_addr = get_hop2_pte_addr(ctx, hop2_addr, virt_addr);
400 	hop2_pte = hdev->asic_funcs->read_pte(hdev, hop2_pte_addr);
401 	hop3_addr = get_next_hop_addr(hop2_pte);
402 
403 	if (hop3_addr == ULLONG_MAX)
404 		goto not_mapped;
405 
406 	hop3_pte_addr = get_hop3_pte_addr(ctx, hop3_addr, virt_addr);
407 	hop3_pte = hdev->asic_funcs->read_pte(hdev, hop3_pte_addr);
408 
409 	if (!(hop3_pte & LAST_MASK)) {
410 		hop4_addr = get_next_hop_addr(hop3_pte);
411 
412 		if (hop4_addr == ULLONG_MAX)
413 			goto not_mapped;
414 
415 		hop4_pte_addr = get_hop4_pte_addr(ctx, hop4_addr, virt_addr);
416 		hop4_pte = hdev->asic_funcs->read_pte(hdev, hop4_pte_addr);
417 		if (!(hop4_pte & PAGE_PRESENT_MASK))
418 			goto not_mapped;
419 	} else {
420 		if (!(hop3_pte & PAGE_PRESENT_MASK))
421 			goto not_mapped;
422 	}
423 
424 	seq_printf(s, "asid: %u, virt_addr: 0x%llx\n",
425 			dev_entry->mmu_asid, dev_entry->mmu_addr);
426 
427 	seq_printf(s, "hop0_addr: 0x%llx\n", hop0_addr);
428 	seq_printf(s, "hop0_pte_addr: 0x%llx\n", hop0_pte_addr);
429 	seq_printf(s, "hop0_pte: 0x%llx\n", hop0_pte);
430 
431 	seq_printf(s, "hop1_addr: 0x%llx\n", hop1_addr);
432 	seq_printf(s, "hop1_pte_addr: 0x%llx\n", hop1_pte_addr);
433 	seq_printf(s, "hop1_pte: 0x%llx\n", hop1_pte);
434 
435 	seq_printf(s, "hop2_addr: 0x%llx\n", hop2_addr);
436 	seq_printf(s, "hop2_pte_addr: 0x%llx\n", hop2_pte_addr);
437 	seq_printf(s, "hop2_pte: 0x%llx\n", hop2_pte);
438 
439 	seq_printf(s, "hop3_addr: 0x%llx\n", hop3_addr);
440 	seq_printf(s, "hop3_pte_addr: 0x%llx\n", hop3_pte_addr);
441 	seq_printf(s, "hop3_pte: 0x%llx\n", hop3_pte);
442 
443 	if (!(hop3_pte & LAST_MASK)) {
444 		seq_printf(s, "hop4_addr: 0x%llx\n", hop4_addr);
445 		seq_printf(s, "hop4_pte_addr: 0x%llx\n", hop4_pte_addr);
446 		seq_printf(s, "hop4_pte: 0x%llx\n", hop4_pte);
447 	}
448 
449 	goto out;
450 
451 not_mapped:
452 	dev_err(hdev->dev, "virt addr 0x%llx is not mapped to phys addr\n",
453 			virt_addr);
454 out:
455 	mutex_unlock(&ctx->mmu_lock);
456 
457 	return 0;
458 }
459 
mmu_write(struct file * file,const char __user * buf,size_t count,loff_t * f_pos)460 static ssize_t mmu_write(struct file *file, const char __user *buf,
461 		size_t count, loff_t *f_pos)
462 {
463 	struct seq_file *s = file->private_data;
464 	struct hl_debugfs_entry *entry = s->private;
465 	struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
466 	struct hl_device *hdev = dev_entry->hdev;
467 	char kbuf[MMU_KBUF_SIZE];
468 	char *c;
469 	ssize_t rc;
470 
471 	if (!hdev->mmu_enable)
472 		return count;
473 
474 	if (count > sizeof(kbuf) - 1)
475 		goto err;
476 	if (copy_from_user(kbuf, buf, count))
477 		goto err;
478 	kbuf[count] = 0;
479 
480 	c = strchr(kbuf, ' ');
481 	if (!c)
482 		goto err;
483 	*c = '\0';
484 
485 	rc = kstrtouint(kbuf, 10, &dev_entry->mmu_asid);
486 	if (rc)
487 		goto err;
488 
489 	if (strncmp(c+1, "0x", 2))
490 		goto err;
491 	rc = kstrtoull(c+3, 16, &dev_entry->mmu_addr);
492 	if (rc)
493 		goto err;
494 
495 	return count;
496 
497 err:
498 	dev_err(hdev->dev, "usage: echo <asid> <0xaddr> > mmu\n");
499 
500 	return -EINVAL;
501 }
502 
engines_show(struct seq_file * s,void * data)503 static int engines_show(struct seq_file *s, void *data)
504 {
505 	struct hl_debugfs_entry *entry = s->private;
506 	struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
507 	struct hl_device *hdev = dev_entry->hdev;
508 
509 	hdev->asic_funcs->is_device_idle(hdev, NULL, s);
510 
511 	return 0;
512 }
513 
hl_is_device_va(struct hl_device * hdev,u64 addr)514 static bool hl_is_device_va(struct hl_device *hdev, u64 addr)
515 {
516 	struct asic_fixed_properties *prop = &hdev->asic_prop;
517 
518 	if (!hdev->mmu_enable)
519 		goto out;
520 
521 	if (hdev->dram_supports_virtual_memory &&
522 			addr >= prop->va_space_dram_start_address &&
523 			addr < prop->va_space_dram_end_address)
524 		return true;
525 
526 	if (addr >= prop->va_space_host_start_address &&
527 			addr < prop->va_space_host_end_address)
528 		return true;
529 out:
530 	return false;
531 }
532 
device_va_to_pa(struct hl_device * hdev,u64 virt_addr,u64 * phys_addr)533 static int device_va_to_pa(struct hl_device *hdev, u64 virt_addr,
534 				u64 *phys_addr)
535 {
536 	struct hl_ctx *ctx = hdev->compute_ctx;
537 	u64 hop_addr, hop_pte_addr, hop_pte;
538 	u64 offset_mask = HOP4_MASK | OFFSET_MASK;
539 	int rc = 0;
540 
541 	if (!ctx) {
542 		dev_err(hdev->dev, "no ctx available\n");
543 		return -EINVAL;
544 	}
545 
546 	mutex_lock(&ctx->mmu_lock);
547 
548 	/* hop 0 */
549 	hop_addr = get_hop0_addr(ctx);
550 	hop_pte_addr = get_hop0_pte_addr(ctx, hop_addr, virt_addr);
551 	hop_pte = hdev->asic_funcs->read_pte(hdev, hop_pte_addr);
552 
553 	/* hop 1 */
554 	hop_addr = get_next_hop_addr(hop_pte);
555 	if (hop_addr == ULLONG_MAX)
556 		goto not_mapped;
557 	hop_pte_addr = get_hop1_pte_addr(ctx, hop_addr, virt_addr);
558 	hop_pte = hdev->asic_funcs->read_pte(hdev, hop_pte_addr);
559 
560 	/* hop 2 */
561 	hop_addr = get_next_hop_addr(hop_pte);
562 	if (hop_addr == ULLONG_MAX)
563 		goto not_mapped;
564 	hop_pte_addr = get_hop2_pte_addr(ctx, hop_addr, virt_addr);
565 	hop_pte = hdev->asic_funcs->read_pte(hdev, hop_pte_addr);
566 
567 	/* hop 3 */
568 	hop_addr = get_next_hop_addr(hop_pte);
569 	if (hop_addr == ULLONG_MAX)
570 		goto not_mapped;
571 	hop_pte_addr = get_hop3_pte_addr(ctx, hop_addr, virt_addr);
572 	hop_pte = hdev->asic_funcs->read_pte(hdev, hop_pte_addr);
573 
574 	if (!(hop_pte & LAST_MASK)) {
575 		/* hop 4 */
576 		hop_addr = get_next_hop_addr(hop_pte);
577 		if (hop_addr == ULLONG_MAX)
578 			goto not_mapped;
579 		hop_pte_addr = get_hop4_pte_addr(ctx, hop_addr, virt_addr);
580 		hop_pte = hdev->asic_funcs->read_pte(hdev, hop_pte_addr);
581 
582 		offset_mask = OFFSET_MASK;
583 	}
584 
585 	if (!(hop_pte & PAGE_PRESENT_MASK))
586 		goto not_mapped;
587 
588 	*phys_addr = (hop_pte & ~offset_mask) | (virt_addr & offset_mask);
589 
590 	goto out;
591 
592 not_mapped:
593 	dev_err(hdev->dev, "virt addr 0x%llx is not mapped to phys addr\n",
594 			virt_addr);
595 	rc = -EINVAL;
596 out:
597 	mutex_unlock(&ctx->mmu_lock);
598 	return rc;
599 }
600 
hl_data_read32(struct file * f,char __user * buf,size_t count,loff_t * ppos)601 static ssize_t hl_data_read32(struct file *f, char __user *buf,
602 					size_t count, loff_t *ppos)
603 {
604 	struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
605 	struct hl_device *hdev = entry->hdev;
606 	char tmp_buf[32];
607 	u64 addr = entry->addr;
608 	u32 val;
609 	ssize_t rc;
610 
611 	if (*ppos)
612 		return 0;
613 
614 	if (hl_is_device_va(hdev, addr)) {
615 		rc = device_va_to_pa(hdev, addr, &addr);
616 		if (rc)
617 			return rc;
618 	}
619 
620 	rc = hdev->asic_funcs->debugfs_read32(hdev, addr, &val);
621 	if (rc) {
622 		dev_err(hdev->dev, "Failed to read from 0x%010llx\n", addr);
623 		return rc;
624 	}
625 
626 	sprintf(tmp_buf, "0x%08x\n", val);
627 	return simple_read_from_buffer(buf, count, ppos, tmp_buf,
628 			strlen(tmp_buf));
629 }
630 
hl_data_write32(struct file * f,const char __user * buf,size_t count,loff_t * ppos)631 static ssize_t hl_data_write32(struct file *f, const char __user *buf,
632 					size_t count, loff_t *ppos)
633 {
634 	struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
635 	struct hl_device *hdev = entry->hdev;
636 	u64 addr = entry->addr;
637 	u32 value;
638 	ssize_t rc;
639 
640 	rc = kstrtouint_from_user(buf, count, 16, &value);
641 	if (rc)
642 		return rc;
643 
644 	if (hl_is_device_va(hdev, addr)) {
645 		rc = device_va_to_pa(hdev, addr, &addr);
646 		if (rc)
647 			return rc;
648 	}
649 
650 	rc = hdev->asic_funcs->debugfs_write32(hdev, addr, value);
651 	if (rc) {
652 		dev_err(hdev->dev, "Failed to write 0x%08x to 0x%010llx\n",
653 			value, addr);
654 		return rc;
655 	}
656 
657 	return count;
658 }
659 
hl_get_power_state(struct file * f,char __user * buf,size_t count,loff_t * ppos)660 static ssize_t hl_get_power_state(struct file *f, char __user *buf,
661 		size_t count, loff_t *ppos)
662 {
663 	struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
664 	struct hl_device *hdev = entry->hdev;
665 	char tmp_buf[200];
666 	int i;
667 
668 	if (*ppos)
669 		return 0;
670 
671 	if (hdev->pdev->current_state == PCI_D0)
672 		i = 1;
673 	else if (hdev->pdev->current_state == PCI_D3hot)
674 		i = 2;
675 	else
676 		i = 3;
677 
678 	sprintf(tmp_buf,
679 		"current power state: %d\n1 - D0\n2 - D3hot\n3 - Unknown\n", i);
680 	return simple_read_from_buffer(buf, count, ppos, tmp_buf,
681 			strlen(tmp_buf));
682 }
683 
hl_set_power_state(struct file * f,const char __user * buf,size_t count,loff_t * ppos)684 static ssize_t hl_set_power_state(struct file *f, const char __user *buf,
685 					size_t count, loff_t *ppos)
686 {
687 	struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
688 	struct hl_device *hdev = entry->hdev;
689 	u32 value;
690 	ssize_t rc;
691 
692 	rc = kstrtouint_from_user(buf, count, 10, &value);
693 	if (rc)
694 		return rc;
695 
696 	if (value == 1) {
697 		pci_set_power_state(hdev->pdev, PCI_D0);
698 		pci_restore_state(hdev->pdev);
699 		rc = pci_enable_device(hdev->pdev);
700 	} else if (value == 2) {
701 		pci_save_state(hdev->pdev);
702 		pci_disable_device(hdev->pdev);
703 		pci_set_power_state(hdev->pdev, PCI_D3hot);
704 	} else {
705 		dev_dbg(hdev->dev, "invalid power state value %u\n", value);
706 		return -EINVAL;
707 	}
708 
709 	return count;
710 }
711 
hl_i2c_data_read(struct file * f,char __user * buf,size_t count,loff_t * ppos)712 static ssize_t hl_i2c_data_read(struct file *f, char __user *buf,
713 					size_t count, loff_t *ppos)
714 {
715 	struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
716 	struct hl_device *hdev = entry->hdev;
717 	char tmp_buf[32];
718 	u32 val;
719 	ssize_t rc;
720 
721 	if (*ppos)
722 		return 0;
723 
724 	rc = hl_debugfs_i2c_read(hdev, entry->i2c_bus, entry->i2c_addr,
725 			entry->i2c_reg, &val);
726 	if (rc) {
727 		dev_err(hdev->dev,
728 			"Failed to read from I2C bus %d, addr %d, reg %d\n",
729 			entry->i2c_bus, entry->i2c_addr, entry->i2c_reg);
730 		return rc;
731 	}
732 
733 	sprintf(tmp_buf, "0x%02x\n", val);
734 	rc = simple_read_from_buffer(buf, count, ppos, tmp_buf,
735 			strlen(tmp_buf));
736 
737 	return rc;
738 }
739 
hl_i2c_data_write(struct file * f,const char __user * buf,size_t count,loff_t * ppos)740 static ssize_t hl_i2c_data_write(struct file *f, const char __user *buf,
741 					size_t count, loff_t *ppos)
742 {
743 	struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
744 	struct hl_device *hdev = entry->hdev;
745 	u32 value;
746 	ssize_t rc;
747 
748 	rc = kstrtouint_from_user(buf, count, 16, &value);
749 	if (rc)
750 		return rc;
751 
752 	rc = hl_debugfs_i2c_write(hdev, entry->i2c_bus, entry->i2c_addr,
753 			entry->i2c_reg, value);
754 	if (rc) {
755 		dev_err(hdev->dev,
756 			"Failed to write 0x%02x to I2C bus %d, addr %d, reg %d\n",
757 			value, entry->i2c_bus, entry->i2c_addr, entry->i2c_reg);
758 		return rc;
759 	}
760 
761 	return count;
762 }
763 
hl_led0_write(struct file * f,const char __user * buf,size_t count,loff_t * ppos)764 static ssize_t hl_led0_write(struct file *f, const char __user *buf,
765 					size_t count, loff_t *ppos)
766 {
767 	struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
768 	struct hl_device *hdev = entry->hdev;
769 	u32 value;
770 	ssize_t rc;
771 
772 	rc = kstrtouint_from_user(buf, count, 10, &value);
773 	if (rc)
774 		return rc;
775 
776 	value = value ? 1 : 0;
777 
778 	hl_debugfs_led_set(hdev, 0, value);
779 
780 	return count;
781 }
782 
hl_led1_write(struct file * f,const char __user * buf,size_t count,loff_t * ppos)783 static ssize_t hl_led1_write(struct file *f, const char __user *buf,
784 					size_t count, loff_t *ppos)
785 {
786 	struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
787 	struct hl_device *hdev = entry->hdev;
788 	u32 value;
789 	ssize_t rc;
790 
791 	rc = kstrtouint_from_user(buf, count, 10, &value);
792 	if (rc)
793 		return rc;
794 
795 	value = value ? 1 : 0;
796 
797 	hl_debugfs_led_set(hdev, 1, value);
798 
799 	return count;
800 }
801 
hl_led2_write(struct file * f,const char __user * buf,size_t count,loff_t * ppos)802 static ssize_t hl_led2_write(struct file *f, const char __user *buf,
803 					size_t count, loff_t *ppos)
804 {
805 	struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
806 	struct hl_device *hdev = entry->hdev;
807 	u32 value;
808 	ssize_t rc;
809 
810 	rc = kstrtouint_from_user(buf, count, 10, &value);
811 	if (rc)
812 		return rc;
813 
814 	value = value ? 1 : 0;
815 
816 	hl_debugfs_led_set(hdev, 2, value);
817 
818 	return count;
819 }
820 
hl_device_read(struct file * f,char __user * buf,size_t count,loff_t * ppos)821 static ssize_t hl_device_read(struct file *f, char __user *buf,
822 					size_t count, loff_t *ppos)
823 {
824 	static const char *help =
825 		"Valid values: disable, enable, suspend, resume, cpu_timeout\n";
826 	return simple_read_from_buffer(buf, count, ppos, help, strlen(help));
827 }
828 
hl_device_write(struct file * f,const char __user * buf,size_t count,loff_t * ppos)829 static ssize_t hl_device_write(struct file *f, const char __user *buf,
830 				     size_t count, loff_t *ppos)
831 {
832 	struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
833 	struct hl_device *hdev = entry->hdev;
834 	char data[30] = {0};
835 
836 	/* don't allow partial writes */
837 	if (*ppos != 0)
838 		return 0;
839 
840 	simple_write_to_buffer(data, 29, ppos, buf, count);
841 
842 	if (strncmp("disable", data, strlen("disable")) == 0) {
843 		hdev->disabled = true;
844 	} else if (strncmp("enable", data, strlen("enable")) == 0) {
845 		hdev->disabled = false;
846 	} else if (strncmp("suspend", data, strlen("suspend")) == 0) {
847 		hdev->asic_funcs->suspend(hdev);
848 	} else if (strncmp("resume", data, strlen("resume")) == 0) {
849 		hdev->asic_funcs->resume(hdev);
850 	} else if (strncmp("cpu_timeout", data, strlen("cpu_timeout")) == 0) {
851 		hdev->device_cpu_disabled = true;
852 	} else {
853 		dev_err(hdev->dev,
854 			"Valid values: disable, enable, suspend, resume, cpu_timeout\n");
855 		count = -EINVAL;
856 	}
857 
858 	return count;
859 }
860 
861 static const struct file_operations hl_data32b_fops = {
862 	.owner = THIS_MODULE,
863 	.read = hl_data_read32,
864 	.write = hl_data_write32
865 };
866 
867 static const struct file_operations hl_i2c_data_fops = {
868 	.owner = THIS_MODULE,
869 	.read = hl_i2c_data_read,
870 	.write = hl_i2c_data_write
871 };
872 
873 static const struct file_operations hl_power_fops = {
874 	.owner = THIS_MODULE,
875 	.read = hl_get_power_state,
876 	.write = hl_set_power_state
877 };
878 
879 static const struct file_operations hl_led0_fops = {
880 	.owner = THIS_MODULE,
881 	.write = hl_led0_write
882 };
883 
884 static const struct file_operations hl_led1_fops = {
885 	.owner = THIS_MODULE,
886 	.write = hl_led1_write
887 };
888 
889 static const struct file_operations hl_led2_fops = {
890 	.owner = THIS_MODULE,
891 	.write = hl_led2_write
892 };
893 
894 static const struct file_operations hl_device_fops = {
895 	.owner = THIS_MODULE,
896 	.read = hl_device_read,
897 	.write = hl_device_write
898 };
899 
900 static const struct hl_info_list hl_debugfs_list[] = {
901 	{"command_buffers", command_buffers_show, NULL},
902 	{"command_submission", command_submission_show, NULL},
903 	{"command_submission_jobs", command_submission_jobs_show, NULL},
904 	{"userptr", userptr_show, NULL},
905 	{"vm", vm_show, NULL},
906 	{"mmu", mmu_show, mmu_write},
907 	{"engines", engines_show, NULL}
908 };
909 
hl_debugfs_open(struct inode * inode,struct file * file)910 static int hl_debugfs_open(struct inode *inode, struct file *file)
911 {
912 	struct hl_debugfs_entry *node = inode->i_private;
913 
914 	return single_open(file, node->info_ent->show, node);
915 }
916 
hl_debugfs_write(struct file * file,const char __user * buf,size_t count,loff_t * f_pos)917 static ssize_t hl_debugfs_write(struct file *file, const char __user *buf,
918 		size_t count, loff_t *f_pos)
919 {
920 	struct hl_debugfs_entry *node = file->f_inode->i_private;
921 
922 	if (node->info_ent->write)
923 		return node->info_ent->write(file, buf, count, f_pos);
924 	else
925 		return -EINVAL;
926 
927 }
928 
929 static const struct file_operations hl_debugfs_fops = {
930 	.owner = THIS_MODULE,
931 	.open = hl_debugfs_open,
932 	.read = seq_read,
933 	.write = hl_debugfs_write,
934 	.llseek = seq_lseek,
935 	.release = single_release,
936 };
937 
hl_debugfs_add_device(struct hl_device * hdev)938 void hl_debugfs_add_device(struct hl_device *hdev)
939 {
940 	struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
941 	int count = ARRAY_SIZE(hl_debugfs_list);
942 	struct hl_debugfs_entry *entry;
943 	struct dentry *ent;
944 	int i;
945 
946 	dev_entry->hdev = hdev;
947 	dev_entry->entry_arr = kmalloc_array(count,
948 					sizeof(struct hl_debugfs_entry),
949 					GFP_KERNEL);
950 	if (!dev_entry->entry_arr)
951 		return;
952 
953 	INIT_LIST_HEAD(&dev_entry->file_list);
954 	INIT_LIST_HEAD(&dev_entry->cb_list);
955 	INIT_LIST_HEAD(&dev_entry->cs_list);
956 	INIT_LIST_HEAD(&dev_entry->cs_job_list);
957 	INIT_LIST_HEAD(&dev_entry->userptr_list);
958 	INIT_LIST_HEAD(&dev_entry->ctx_mem_hash_list);
959 	mutex_init(&dev_entry->file_mutex);
960 	spin_lock_init(&dev_entry->cb_spinlock);
961 	spin_lock_init(&dev_entry->cs_spinlock);
962 	spin_lock_init(&dev_entry->cs_job_spinlock);
963 	spin_lock_init(&dev_entry->userptr_spinlock);
964 	spin_lock_init(&dev_entry->ctx_mem_hash_spinlock);
965 
966 	dev_entry->root = debugfs_create_dir(dev_name(hdev->dev),
967 						hl_debug_root);
968 
969 	debugfs_create_x64("addr",
970 				0644,
971 				dev_entry->root,
972 				&dev_entry->addr);
973 
974 	debugfs_create_file("data32",
975 				0644,
976 				dev_entry->root,
977 				dev_entry,
978 				&hl_data32b_fops);
979 
980 	debugfs_create_file("set_power_state",
981 				0200,
982 				dev_entry->root,
983 				dev_entry,
984 				&hl_power_fops);
985 
986 	debugfs_create_u8("i2c_bus",
987 				0644,
988 				dev_entry->root,
989 				&dev_entry->i2c_bus);
990 
991 	debugfs_create_u8("i2c_addr",
992 				0644,
993 				dev_entry->root,
994 				&dev_entry->i2c_addr);
995 
996 	debugfs_create_u8("i2c_reg",
997 				0644,
998 				dev_entry->root,
999 				&dev_entry->i2c_reg);
1000 
1001 	debugfs_create_file("i2c_data",
1002 				0644,
1003 				dev_entry->root,
1004 				dev_entry,
1005 				&hl_i2c_data_fops);
1006 
1007 	debugfs_create_file("led0",
1008 				0200,
1009 				dev_entry->root,
1010 				dev_entry,
1011 				&hl_led0_fops);
1012 
1013 	debugfs_create_file("led1",
1014 				0200,
1015 				dev_entry->root,
1016 				dev_entry,
1017 				&hl_led1_fops);
1018 
1019 	debugfs_create_file("led2",
1020 				0200,
1021 				dev_entry->root,
1022 				dev_entry,
1023 				&hl_led2_fops);
1024 
1025 	debugfs_create_file("device",
1026 				0200,
1027 				dev_entry->root,
1028 				dev_entry,
1029 				&hl_device_fops);
1030 
1031 	for (i = 0, entry = dev_entry->entry_arr ; i < count ; i++, entry++) {
1032 
1033 		ent = debugfs_create_file(hl_debugfs_list[i].name,
1034 					0444,
1035 					dev_entry->root,
1036 					entry,
1037 					&hl_debugfs_fops);
1038 		entry->dent = ent;
1039 		entry->info_ent = &hl_debugfs_list[i];
1040 		entry->dev_entry = dev_entry;
1041 	}
1042 }
1043 
hl_debugfs_remove_device(struct hl_device * hdev)1044 void hl_debugfs_remove_device(struct hl_device *hdev)
1045 {
1046 	struct hl_dbg_device_entry *entry = &hdev->hl_debugfs;
1047 
1048 	debugfs_remove_recursive(entry->root);
1049 
1050 	mutex_destroy(&entry->file_mutex);
1051 	kfree(entry->entry_arr);
1052 }
1053 
hl_debugfs_add_file(struct hl_fpriv * hpriv)1054 void hl_debugfs_add_file(struct hl_fpriv *hpriv)
1055 {
1056 	struct hl_dbg_device_entry *dev_entry = &hpriv->hdev->hl_debugfs;
1057 
1058 	mutex_lock(&dev_entry->file_mutex);
1059 	list_add(&hpriv->debugfs_list, &dev_entry->file_list);
1060 	mutex_unlock(&dev_entry->file_mutex);
1061 }
1062 
hl_debugfs_remove_file(struct hl_fpriv * hpriv)1063 void hl_debugfs_remove_file(struct hl_fpriv *hpriv)
1064 {
1065 	struct hl_dbg_device_entry *dev_entry = &hpriv->hdev->hl_debugfs;
1066 
1067 	mutex_lock(&dev_entry->file_mutex);
1068 	list_del(&hpriv->debugfs_list);
1069 	mutex_unlock(&dev_entry->file_mutex);
1070 }
1071 
hl_debugfs_add_cb(struct hl_cb * cb)1072 void hl_debugfs_add_cb(struct hl_cb *cb)
1073 {
1074 	struct hl_dbg_device_entry *dev_entry = &cb->hdev->hl_debugfs;
1075 
1076 	spin_lock(&dev_entry->cb_spinlock);
1077 	list_add(&cb->debugfs_list, &dev_entry->cb_list);
1078 	spin_unlock(&dev_entry->cb_spinlock);
1079 }
1080 
hl_debugfs_remove_cb(struct hl_cb * cb)1081 void hl_debugfs_remove_cb(struct hl_cb *cb)
1082 {
1083 	struct hl_dbg_device_entry *dev_entry = &cb->hdev->hl_debugfs;
1084 
1085 	spin_lock(&dev_entry->cb_spinlock);
1086 	list_del(&cb->debugfs_list);
1087 	spin_unlock(&dev_entry->cb_spinlock);
1088 }
1089 
hl_debugfs_add_cs(struct hl_cs * cs)1090 void hl_debugfs_add_cs(struct hl_cs *cs)
1091 {
1092 	struct hl_dbg_device_entry *dev_entry = &cs->ctx->hdev->hl_debugfs;
1093 
1094 	spin_lock(&dev_entry->cs_spinlock);
1095 	list_add(&cs->debugfs_list, &dev_entry->cs_list);
1096 	spin_unlock(&dev_entry->cs_spinlock);
1097 }
1098 
hl_debugfs_remove_cs(struct hl_cs * cs)1099 void hl_debugfs_remove_cs(struct hl_cs *cs)
1100 {
1101 	struct hl_dbg_device_entry *dev_entry = &cs->ctx->hdev->hl_debugfs;
1102 
1103 	spin_lock(&dev_entry->cs_spinlock);
1104 	list_del(&cs->debugfs_list);
1105 	spin_unlock(&dev_entry->cs_spinlock);
1106 }
1107 
hl_debugfs_add_job(struct hl_device * hdev,struct hl_cs_job * job)1108 void hl_debugfs_add_job(struct hl_device *hdev, struct hl_cs_job *job)
1109 {
1110 	struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
1111 
1112 	spin_lock(&dev_entry->cs_job_spinlock);
1113 	list_add(&job->debugfs_list, &dev_entry->cs_job_list);
1114 	spin_unlock(&dev_entry->cs_job_spinlock);
1115 }
1116 
hl_debugfs_remove_job(struct hl_device * hdev,struct hl_cs_job * job)1117 void hl_debugfs_remove_job(struct hl_device *hdev, struct hl_cs_job *job)
1118 {
1119 	struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
1120 
1121 	spin_lock(&dev_entry->cs_job_spinlock);
1122 	list_del(&job->debugfs_list);
1123 	spin_unlock(&dev_entry->cs_job_spinlock);
1124 }
1125 
hl_debugfs_add_userptr(struct hl_device * hdev,struct hl_userptr * userptr)1126 void hl_debugfs_add_userptr(struct hl_device *hdev, struct hl_userptr *userptr)
1127 {
1128 	struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
1129 
1130 	spin_lock(&dev_entry->userptr_spinlock);
1131 	list_add(&userptr->debugfs_list, &dev_entry->userptr_list);
1132 	spin_unlock(&dev_entry->userptr_spinlock);
1133 }
1134 
hl_debugfs_remove_userptr(struct hl_device * hdev,struct hl_userptr * userptr)1135 void hl_debugfs_remove_userptr(struct hl_device *hdev,
1136 				struct hl_userptr *userptr)
1137 {
1138 	struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
1139 
1140 	spin_lock(&dev_entry->userptr_spinlock);
1141 	list_del(&userptr->debugfs_list);
1142 	spin_unlock(&dev_entry->userptr_spinlock);
1143 }
1144 
hl_debugfs_add_ctx_mem_hash(struct hl_device * hdev,struct hl_ctx * ctx)1145 void hl_debugfs_add_ctx_mem_hash(struct hl_device *hdev, struct hl_ctx *ctx)
1146 {
1147 	struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
1148 
1149 	spin_lock(&dev_entry->ctx_mem_hash_spinlock);
1150 	list_add(&ctx->debugfs_list, &dev_entry->ctx_mem_hash_list);
1151 	spin_unlock(&dev_entry->ctx_mem_hash_spinlock);
1152 }
1153 
hl_debugfs_remove_ctx_mem_hash(struct hl_device * hdev,struct hl_ctx * ctx)1154 void hl_debugfs_remove_ctx_mem_hash(struct hl_device *hdev, struct hl_ctx *ctx)
1155 {
1156 	struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
1157 
1158 	spin_lock(&dev_entry->ctx_mem_hash_spinlock);
1159 	list_del(&ctx->debugfs_list);
1160 	spin_unlock(&dev_entry->ctx_mem_hash_spinlock);
1161 }
1162 
hl_debugfs_init(void)1163 void __init hl_debugfs_init(void)
1164 {
1165 	hl_debug_root = debugfs_create_dir("habanalabs", NULL);
1166 }
1167 
hl_debugfs_fini(void)1168 void hl_debugfs_fini(void)
1169 {
1170 	debugfs_remove_recursive(hl_debug_root);
1171 }
1172