linux/drivers/misc/habanalabs/common/debugfs.c
<<
>>
Prefs
   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
  19static struct dentry *hl_debug_root;
  20
  21static int hl_debugfs_i2c_read(struct hl_device *hdev, u8 i2c_bus, u8 i2c_addr,
  22                                u8 i2c_reg, long *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                                                0, 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
  47static 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                                                0, 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
  74static 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                                                0, NULL);
  91
  92        if (rc)
  93                dev_err(hdev->dev, "Failed to set LED %d, error %d\n", led, rc);
  94}
  95
  96static 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
 127static 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
 158static 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
 193static 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
 224static 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 */
 304static 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
 310static inline u64 get_hopN_pte_addr(struct hl_ctx *ctx, u64 hop_addr,
 311                                        u64 virt_addr, u64 mask, u64 shift)
 312{
 313        return hop_addr + ctx->hdev->asic_prop.mmu_pte_size *
 314                        ((virt_addr & mask) >> shift);
 315}
 316
 317static inline u64 get_hop0_pte_addr(struct hl_ctx *ctx,
 318                                        struct hl_mmu_properties *mmu_specs,
 319                                        u64 hop_addr, u64 vaddr)
 320{
 321        return get_hopN_pte_addr(ctx, hop_addr, vaddr, mmu_specs->hop0_mask,
 322                                        mmu_specs->hop0_shift);
 323}
 324
 325static inline u64 get_hop1_pte_addr(struct hl_ctx *ctx,
 326                                        struct hl_mmu_properties *mmu_specs,
 327                                        u64 hop_addr, u64 vaddr)
 328{
 329        return get_hopN_pte_addr(ctx, hop_addr, vaddr, mmu_specs->hop1_mask,
 330                                        mmu_specs->hop1_shift);
 331}
 332
 333static inline u64 get_hop2_pte_addr(struct hl_ctx *ctx,
 334                                        struct hl_mmu_properties *mmu_specs,
 335                                        u64 hop_addr, u64 vaddr)
 336{
 337        return get_hopN_pte_addr(ctx, hop_addr, vaddr, mmu_specs->hop2_mask,
 338                                        mmu_specs->hop2_shift);
 339}
 340
 341static inline u64 get_hop3_pte_addr(struct hl_ctx *ctx,
 342                                        struct hl_mmu_properties *mmu_specs,
 343                                        u64 hop_addr, u64 vaddr)
 344{
 345        return get_hopN_pte_addr(ctx, hop_addr, vaddr, mmu_specs->hop3_mask,
 346                                        mmu_specs->hop3_shift);
 347}
 348
 349static inline u64 get_hop4_pte_addr(struct hl_ctx *ctx,
 350                                        struct hl_mmu_properties *mmu_specs,
 351                                        u64 hop_addr, u64 vaddr)
 352{
 353        return get_hopN_pte_addr(ctx, hop_addr, vaddr, mmu_specs->hop4_mask,
 354                                        mmu_specs->hop4_shift);
 355}
 356
 357static inline u64 get_next_hop_addr(u64 curr_pte)
 358{
 359        if (curr_pte & PAGE_PRESENT_MASK)
 360                return curr_pte & HOP_PHYS_ADDR_MASK;
 361        else
 362                return ULLONG_MAX;
 363}
 364
 365static int mmu_show(struct seq_file *s, void *data)
 366{
 367        struct hl_debugfs_entry *entry = s->private;
 368        struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
 369        struct hl_device *hdev = dev_entry->hdev;
 370        struct asic_fixed_properties *prop = &hdev->asic_prop;
 371        struct hl_mmu_properties *mmu_prop;
 372        struct hl_ctx *ctx;
 373        bool is_dram_addr;
 374
 375        u64 hop0_addr = 0, hop0_pte_addr = 0, hop0_pte = 0,
 376                hop1_addr = 0, hop1_pte_addr = 0, hop1_pte = 0,
 377                hop2_addr = 0, hop2_pte_addr = 0, hop2_pte = 0,
 378                hop3_addr = 0, hop3_pte_addr = 0, hop3_pte = 0,
 379                hop4_addr = 0, hop4_pte_addr = 0, hop4_pte = 0,
 380                virt_addr = dev_entry->mmu_addr;
 381
 382        if (!hdev->mmu_enable)
 383                return 0;
 384
 385        if (dev_entry->mmu_asid == HL_KERNEL_ASID_ID)
 386                ctx = hdev->kernel_ctx;
 387        else
 388                ctx = hdev->compute_ctx;
 389
 390        if (!ctx) {
 391                dev_err(hdev->dev, "no ctx available\n");
 392                return 0;
 393        }
 394
 395        is_dram_addr = hl_mem_area_inside_range(virt_addr, prop->dmmu.page_size,
 396                                                prop->dmmu.start_addr,
 397                                                prop->dmmu.end_addr);
 398
 399        /* shifts and masks are the same in PMMU and HPMMU, use one of them */
 400        mmu_prop = is_dram_addr ? &prop->dmmu : &prop->pmmu;
 401
 402        mutex_lock(&ctx->mmu_lock);
 403
 404        /* the following lookup is copied from unmap() in mmu.c */
 405
 406        hop0_addr = get_hop0_addr(ctx);
 407        hop0_pte_addr = get_hop0_pte_addr(ctx, mmu_prop, hop0_addr, virt_addr);
 408        hop0_pte = hdev->asic_funcs->read_pte(hdev, hop0_pte_addr);
 409        hop1_addr = get_next_hop_addr(hop0_pte);
 410
 411        if (hop1_addr == ULLONG_MAX)
 412                goto not_mapped;
 413
 414        hop1_pte_addr = get_hop1_pte_addr(ctx, mmu_prop, hop1_addr, virt_addr);
 415        hop1_pte = hdev->asic_funcs->read_pte(hdev, hop1_pte_addr);
 416        hop2_addr = get_next_hop_addr(hop1_pte);
 417
 418        if (hop2_addr == ULLONG_MAX)
 419                goto not_mapped;
 420
 421        hop2_pte_addr = get_hop2_pte_addr(ctx, mmu_prop, hop2_addr, virt_addr);
 422        hop2_pte = hdev->asic_funcs->read_pte(hdev, hop2_pte_addr);
 423        hop3_addr = get_next_hop_addr(hop2_pte);
 424
 425        if (hop3_addr == ULLONG_MAX)
 426                goto not_mapped;
 427
 428        hop3_pte_addr = get_hop3_pte_addr(ctx, mmu_prop, hop3_addr, virt_addr);
 429        hop3_pte = hdev->asic_funcs->read_pte(hdev, hop3_pte_addr);
 430
 431        if (!(hop3_pte & LAST_MASK)) {
 432                hop4_addr = get_next_hop_addr(hop3_pte);
 433
 434                if (hop4_addr == ULLONG_MAX)
 435                        goto not_mapped;
 436
 437                hop4_pte_addr = get_hop4_pte_addr(ctx, mmu_prop, hop4_addr,
 438                                                        virt_addr);
 439                hop4_pte = hdev->asic_funcs->read_pte(hdev, hop4_pte_addr);
 440                if (!(hop4_pte & PAGE_PRESENT_MASK))
 441                        goto not_mapped;
 442        } else {
 443                if (!(hop3_pte & PAGE_PRESENT_MASK))
 444                        goto not_mapped;
 445        }
 446
 447        seq_printf(s, "asid: %u, virt_addr: 0x%llx\n",
 448                        dev_entry->mmu_asid, dev_entry->mmu_addr);
 449
 450        seq_printf(s, "hop0_addr: 0x%llx\n", hop0_addr);
 451        seq_printf(s, "hop0_pte_addr: 0x%llx\n", hop0_pte_addr);
 452        seq_printf(s, "hop0_pte: 0x%llx\n", hop0_pte);
 453
 454        seq_printf(s, "hop1_addr: 0x%llx\n", hop1_addr);
 455        seq_printf(s, "hop1_pte_addr: 0x%llx\n", hop1_pte_addr);
 456        seq_printf(s, "hop1_pte: 0x%llx\n", hop1_pte);
 457
 458        seq_printf(s, "hop2_addr: 0x%llx\n", hop2_addr);
 459        seq_printf(s, "hop2_pte_addr: 0x%llx\n", hop2_pte_addr);
 460        seq_printf(s, "hop2_pte: 0x%llx\n", hop2_pte);
 461
 462        seq_printf(s, "hop3_addr: 0x%llx\n", hop3_addr);
 463        seq_printf(s, "hop3_pte_addr: 0x%llx\n", hop3_pte_addr);
 464        seq_printf(s, "hop3_pte: 0x%llx\n", hop3_pte);
 465
 466        if (!(hop3_pte & LAST_MASK)) {
 467                seq_printf(s, "hop4_addr: 0x%llx\n", hop4_addr);
 468                seq_printf(s, "hop4_pte_addr: 0x%llx\n", hop4_pte_addr);
 469                seq_printf(s, "hop4_pte: 0x%llx\n", hop4_pte);
 470        }
 471
 472        goto out;
 473
 474not_mapped:
 475        dev_err(hdev->dev, "virt addr 0x%llx is not mapped to phys addr\n",
 476                        virt_addr);
 477out:
 478        mutex_unlock(&ctx->mmu_lock);
 479
 480        return 0;
 481}
 482
 483static ssize_t mmu_asid_va_write(struct file *file, const char __user *buf,
 484                size_t count, loff_t *f_pos)
 485{
 486        struct seq_file *s = file->private_data;
 487        struct hl_debugfs_entry *entry = s->private;
 488        struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
 489        struct hl_device *hdev = dev_entry->hdev;
 490        char kbuf[MMU_KBUF_SIZE];
 491        char *c;
 492        ssize_t rc;
 493
 494        if (!hdev->mmu_enable)
 495                return count;
 496
 497        if (count > sizeof(kbuf) - 1)
 498                goto err;
 499        if (copy_from_user(kbuf, buf, count))
 500                goto err;
 501        kbuf[count] = 0;
 502
 503        c = strchr(kbuf, ' ');
 504        if (!c)
 505                goto err;
 506        *c = '\0';
 507
 508        rc = kstrtouint(kbuf, 10, &dev_entry->mmu_asid);
 509        if (rc)
 510                goto err;
 511
 512        if (strncmp(c+1, "0x", 2))
 513                goto err;
 514        rc = kstrtoull(c+3, 16, &dev_entry->mmu_addr);
 515        if (rc)
 516                goto err;
 517
 518        return count;
 519
 520err:
 521        dev_err(hdev->dev, "usage: echo <asid> <0xaddr> > mmu\n");
 522
 523        return -EINVAL;
 524}
 525
 526static int engines_show(struct seq_file *s, void *data)
 527{
 528        struct hl_debugfs_entry *entry = s->private;
 529        struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
 530        struct hl_device *hdev = dev_entry->hdev;
 531
 532        if (atomic_read(&hdev->in_reset)) {
 533                dev_warn_ratelimited(hdev->dev,
 534                                "Can't check device idle during reset\n");
 535                return 0;
 536        }
 537
 538        hdev->asic_funcs->is_device_idle(hdev, NULL, s);
 539
 540        return 0;
 541}
 542
 543static bool hl_is_device_va(struct hl_device *hdev, u64 addr)
 544{
 545        struct asic_fixed_properties *prop = &hdev->asic_prop;
 546
 547        if (!hdev->mmu_enable)
 548                goto out;
 549
 550        if (hdev->dram_supports_virtual_memory &&
 551                (addr >= prop->dmmu.start_addr && addr < prop->dmmu.end_addr))
 552                return true;
 553
 554        if (addr >= prop->pmmu.start_addr &&
 555                addr < prop->pmmu.end_addr)
 556                return true;
 557
 558        if (addr >= prop->pmmu_huge.start_addr &&
 559                addr < prop->pmmu_huge.end_addr)
 560                return true;
 561out:
 562        return false;
 563}
 564
 565static int device_va_to_pa(struct hl_device *hdev, u64 virt_addr,
 566                                u64 *phys_addr)
 567{
 568        struct hl_ctx *ctx = hdev->compute_ctx;
 569        struct asic_fixed_properties *prop = &hdev->asic_prop;
 570        struct hl_mmu_properties *mmu_prop;
 571        u64 hop_addr, hop_pte_addr, hop_pte;
 572        u64 offset_mask = HOP4_MASK | FLAGS_MASK;
 573        int rc = 0;
 574        bool is_dram_addr;
 575
 576        if (!ctx) {
 577                dev_err(hdev->dev, "no ctx available\n");
 578                return -EINVAL;
 579        }
 580
 581        is_dram_addr = hl_mem_area_inside_range(virt_addr, prop->dmmu.page_size,
 582                                                prop->dmmu.start_addr,
 583                                                prop->dmmu.end_addr);
 584
 585        /* shifts and masks are the same in PMMU and HPMMU, use one of them */
 586        mmu_prop = is_dram_addr ? &prop->dmmu : &prop->pmmu;
 587
 588        mutex_lock(&ctx->mmu_lock);
 589
 590        /* hop 0 */
 591        hop_addr = get_hop0_addr(ctx);
 592        hop_pte_addr = get_hop0_pte_addr(ctx, mmu_prop, hop_addr, virt_addr);
 593        hop_pte = hdev->asic_funcs->read_pte(hdev, hop_pte_addr);
 594
 595        /* hop 1 */
 596        hop_addr = get_next_hop_addr(hop_pte);
 597        if (hop_addr == ULLONG_MAX)
 598                goto not_mapped;
 599        hop_pte_addr = get_hop1_pte_addr(ctx, mmu_prop, hop_addr, virt_addr);
 600        hop_pte = hdev->asic_funcs->read_pte(hdev, hop_pte_addr);
 601
 602        /* hop 2 */
 603        hop_addr = get_next_hop_addr(hop_pte);
 604        if (hop_addr == ULLONG_MAX)
 605                goto not_mapped;
 606        hop_pte_addr = get_hop2_pte_addr(ctx, mmu_prop, hop_addr, virt_addr);
 607        hop_pte = hdev->asic_funcs->read_pte(hdev, hop_pte_addr);
 608
 609        /* hop 3 */
 610        hop_addr = get_next_hop_addr(hop_pte);
 611        if (hop_addr == ULLONG_MAX)
 612                goto not_mapped;
 613        hop_pte_addr = get_hop3_pte_addr(ctx, mmu_prop, hop_addr, virt_addr);
 614        hop_pte = hdev->asic_funcs->read_pte(hdev, hop_pte_addr);
 615
 616        if (!(hop_pte & LAST_MASK)) {
 617                /* hop 4 */
 618                hop_addr = get_next_hop_addr(hop_pte);
 619                if (hop_addr == ULLONG_MAX)
 620                        goto not_mapped;
 621                hop_pte_addr = get_hop4_pte_addr(ctx, mmu_prop, hop_addr,
 622                                                        virt_addr);
 623                hop_pte = hdev->asic_funcs->read_pte(hdev, hop_pte_addr);
 624
 625                offset_mask = FLAGS_MASK;
 626        }
 627
 628        if (!(hop_pte & PAGE_PRESENT_MASK))
 629                goto not_mapped;
 630
 631        *phys_addr = (hop_pte & ~offset_mask) | (virt_addr & offset_mask);
 632
 633        goto out;
 634
 635not_mapped:
 636        dev_err(hdev->dev, "virt addr 0x%llx is not mapped to phys addr\n",
 637                        virt_addr);
 638        rc = -EINVAL;
 639out:
 640        mutex_unlock(&ctx->mmu_lock);
 641        return rc;
 642}
 643
 644static ssize_t hl_data_read32(struct file *f, char __user *buf,
 645                                        size_t count, loff_t *ppos)
 646{
 647        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 648        struct hl_device *hdev = entry->hdev;
 649        char tmp_buf[32];
 650        u64 addr = entry->addr;
 651        u32 val;
 652        ssize_t rc;
 653
 654        if (atomic_read(&hdev->in_reset)) {
 655                dev_warn_ratelimited(hdev->dev, "Can't read during reset\n");
 656                return 0;
 657        }
 658
 659        if (*ppos)
 660                return 0;
 661
 662        if (hl_is_device_va(hdev, addr)) {
 663                rc = device_va_to_pa(hdev, addr, &addr);
 664                if (rc)
 665                        return rc;
 666        }
 667
 668        rc = hdev->asic_funcs->debugfs_read32(hdev, addr, &val);
 669        if (rc) {
 670                dev_err(hdev->dev, "Failed to read from 0x%010llx\n", addr);
 671                return rc;
 672        }
 673
 674        sprintf(tmp_buf, "0x%08x\n", val);
 675        return simple_read_from_buffer(buf, count, ppos, tmp_buf,
 676                        strlen(tmp_buf));
 677}
 678
 679static ssize_t hl_data_write32(struct file *f, const char __user *buf,
 680                                        size_t count, loff_t *ppos)
 681{
 682        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 683        struct hl_device *hdev = entry->hdev;
 684        u64 addr = entry->addr;
 685        u32 value;
 686        ssize_t rc;
 687
 688        if (atomic_read(&hdev->in_reset)) {
 689                dev_warn_ratelimited(hdev->dev, "Can't write during reset\n");
 690                return 0;
 691        }
 692
 693        rc = kstrtouint_from_user(buf, count, 16, &value);
 694        if (rc)
 695                return rc;
 696
 697        if (hl_is_device_va(hdev, addr)) {
 698                rc = device_va_to_pa(hdev, addr, &addr);
 699                if (rc)
 700                        return rc;
 701        }
 702
 703        rc = hdev->asic_funcs->debugfs_write32(hdev, addr, value);
 704        if (rc) {
 705                dev_err(hdev->dev, "Failed to write 0x%08x to 0x%010llx\n",
 706                        value, addr);
 707                return rc;
 708        }
 709
 710        return count;
 711}
 712
 713static ssize_t hl_data_read64(struct file *f, char __user *buf,
 714                                        size_t count, loff_t *ppos)
 715{
 716        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 717        struct hl_device *hdev = entry->hdev;
 718        char tmp_buf[32];
 719        u64 addr = entry->addr;
 720        u64 val;
 721        ssize_t rc;
 722
 723        if (*ppos)
 724                return 0;
 725
 726        if (hl_is_device_va(hdev, addr)) {
 727                rc = device_va_to_pa(hdev, addr, &addr);
 728                if (rc)
 729                        return rc;
 730        }
 731
 732        rc = hdev->asic_funcs->debugfs_read64(hdev, addr, &val);
 733        if (rc) {
 734                dev_err(hdev->dev, "Failed to read from 0x%010llx\n", addr);
 735                return rc;
 736        }
 737
 738        sprintf(tmp_buf, "0x%016llx\n", val);
 739        return simple_read_from_buffer(buf, count, ppos, tmp_buf,
 740                        strlen(tmp_buf));
 741}
 742
 743static ssize_t hl_data_write64(struct file *f, const char __user *buf,
 744                                        size_t count, loff_t *ppos)
 745{
 746        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 747        struct hl_device *hdev = entry->hdev;
 748        u64 addr = entry->addr;
 749        u64 value;
 750        ssize_t rc;
 751
 752        rc = kstrtoull_from_user(buf, count, 16, &value);
 753        if (rc)
 754                return rc;
 755
 756        if (hl_is_device_va(hdev, addr)) {
 757                rc = device_va_to_pa(hdev, addr, &addr);
 758                if (rc)
 759                        return rc;
 760        }
 761
 762        rc = hdev->asic_funcs->debugfs_write64(hdev, addr, value);
 763        if (rc) {
 764                dev_err(hdev->dev, "Failed to write 0x%016llx to 0x%010llx\n",
 765                        value, addr);
 766                return rc;
 767        }
 768
 769        return count;
 770}
 771
 772static ssize_t hl_get_power_state(struct file *f, char __user *buf,
 773                size_t count, loff_t *ppos)
 774{
 775        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 776        struct hl_device *hdev = entry->hdev;
 777        char tmp_buf[200];
 778        int i;
 779
 780        if (*ppos)
 781                return 0;
 782
 783        if (hdev->pdev->current_state == PCI_D0)
 784                i = 1;
 785        else if (hdev->pdev->current_state == PCI_D3hot)
 786                i = 2;
 787        else
 788                i = 3;
 789
 790        sprintf(tmp_buf,
 791                "current power state: %d\n1 - D0\n2 - D3hot\n3 - Unknown\n", i);
 792        return simple_read_from_buffer(buf, count, ppos, tmp_buf,
 793                        strlen(tmp_buf));
 794}
 795
 796static ssize_t hl_set_power_state(struct file *f, const char __user *buf,
 797                                        size_t count, loff_t *ppos)
 798{
 799        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 800        struct hl_device *hdev = entry->hdev;
 801        u32 value;
 802        ssize_t rc;
 803
 804        rc = kstrtouint_from_user(buf, count, 10, &value);
 805        if (rc)
 806                return rc;
 807
 808        if (value == 1) {
 809                pci_set_power_state(hdev->pdev, PCI_D0);
 810                pci_restore_state(hdev->pdev);
 811                rc = pci_enable_device(hdev->pdev);
 812        } else if (value == 2) {
 813                pci_save_state(hdev->pdev);
 814                pci_disable_device(hdev->pdev);
 815                pci_set_power_state(hdev->pdev, PCI_D3hot);
 816        } else {
 817                dev_dbg(hdev->dev, "invalid power state value %u\n", value);
 818                return -EINVAL;
 819        }
 820
 821        return count;
 822}
 823
 824static ssize_t hl_i2c_data_read(struct file *f, char __user *buf,
 825                                        size_t count, loff_t *ppos)
 826{
 827        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 828        struct hl_device *hdev = entry->hdev;
 829        char tmp_buf[32];
 830        long val;
 831        ssize_t rc;
 832
 833        if (*ppos)
 834                return 0;
 835
 836        rc = hl_debugfs_i2c_read(hdev, entry->i2c_bus, entry->i2c_addr,
 837                        entry->i2c_reg, &val);
 838        if (rc) {
 839                dev_err(hdev->dev,
 840                        "Failed to read from I2C bus %d, addr %d, reg %d\n",
 841                        entry->i2c_bus, entry->i2c_addr, entry->i2c_reg);
 842                return rc;
 843        }
 844
 845        sprintf(tmp_buf, "0x%02lx\n", val);
 846        rc = simple_read_from_buffer(buf, count, ppos, tmp_buf,
 847                        strlen(tmp_buf));
 848
 849        return rc;
 850}
 851
 852static ssize_t hl_i2c_data_write(struct file *f, const char __user *buf,
 853                                        size_t count, loff_t *ppos)
 854{
 855        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 856        struct hl_device *hdev = entry->hdev;
 857        u32 value;
 858        ssize_t rc;
 859
 860        rc = kstrtouint_from_user(buf, count, 16, &value);
 861        if (rc)
 862                return rc;
 863
 864        rc = hl_debugfs_i2c_write(hdev, entry->i2c_bus, entry->i2c_addr,
 865                        entry->i2c_reg, value);
 866        if (rc) {
 867                dev_err(hdev->dev,
 868                        "Failed to write 0x%02x to I2C bus %d, addr %d, reg %d\n",
 869                        value, entry->i2c_bus, entry->i2c_addr, entry->i2c_reg);
 870                return rc;
 871        }
 872
 873        return count;
 874}
 875
 876static ssize_t hl_led0_write(struct file *f, const char __user *buf,
 877                                        size_t count, loff_t *ppos)
 878{
 879        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 880        struct hl_device *hdev = entry->hdev;
 881        u32 value;
 882        ssize_t rc;
 883
 884        rc = kstrtouint_from_user(buf, count, 10, &value);
 885        if (rc)
 886                return rc;
 887
 888        value = value ? 1 : 0;
 889
 890        hl_debugfs_led_set(hdev, 0, value);
 891
 892        return count;
 893}
 894
 895static ssize_t hl_led1_write(struct file *f, const char __user *buf,
 896                                        size_t count, loff_t *ppos)
 897{
 898        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 899        struct hl_device *hdev = entry->hdev;
 900        u32 value;
 901        ssize_t rc;
 902
 903        rc = kstrtouint_from_user(buf, count, 10, &value);
 904        if (rc)
 905                return rc;
 906
 907        value = value ? 1 : 0;
 908
 909        hl_debugfs_led_set(hdev, 1, value);
 910
 911        return count;
 912}
 913
 914static ssize_t hl_led2_write(struct file *f, const char __user *buf,
 915                                        size_t count, loff_t *ppos)
 916{
 917        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 918        struct hl_device *hdev = entry->hdev;
 919        u32 value;
 920        ssize_t rc;
 921
 922        rc = kstrtouint_from_user(buf, count, 10, &value);
 923        if (rc)
 924                return rc;
 925
 926        value = value ? 1 : 0;
 927
 928        hl_debugfs_led_set(hdev, 2, value);
 929
 930        return count;
 931}
 932
 933static ssize_t hl_device_read(struct file *f, char __user *buf,
 934                                        size_t count, loff_t *ppos)
 935{
 936        static const char *help =
 937                "Valid values: disable, enable, suspend, resume, cpu_timeout\n";
 938        return simple_read_from_buffer(buf, count, ppos, help, strlen(help));
 939}
 940
 941static ssize_t hl_device_write(struct file *f, const char __user *buf,
 942                                     size_t count, loff_t *ppos)
 943{
 944        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 945        struct hl_device *hdev = entry->hdev;
 946        char data[30] = {0};
 947
 948        /* don't allow partial writes */
 949        if (*ppos != 0)
 950                return 0;
 951
 952        simple_write_to_buffer(data, 29, ppos, buf, count);
 953
 954        if (strncmp("disable", data, strlen("disable")) == 0) {
 955                hdev->disabled = true;
 956        } else if (strncmp("enable", data, strlen("enable")) == 0) {
 957                hdev->disabled = false;
 958        } else if (strncmp("suspend", data, strlen("suspend")) == 0) {
 959                hdev->asic_funcs->suspend(hdev);
 960        } else if (strncmp("resume", data, strlen("resume")) == 0) {
 961                hdev->asic_funcs->resume(hdev);
 962        } else if (strncmp("cpu_timeout", data, strlen("cpu_timeout")) == 0) {
 963                hdev->device_cpu_disabled = true;
 964        } else {
 965                dev_err(hdev->dev,
 966                        "Valid values: disable, enable, suspend, resume, cpu_timeout\n");
 967                count = -EINVAL;
 968        }
 969
 970        return count;
 971}
 972
 973static ssize_t hl_clk_gate_read(struct file *f, char __user *buf,
 974                                        size_t count, loff_t *ppos)
 975{
 976        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 977        struct hl_device *hdev = entry->hdev;
 978        char tmp_buf[200];
 979        ssize_t rc;
 980
 981        if (*ppos)
 982                return 0;
 983
 984        sprintf(tmp_buf, "0x%llx\n", hdev->clock_gating_mask);
 985        rc = simple_read_from_buffer(buf, count, ppos, tmp_buf,
 986                        strlen(tmp_buf) + 1);
 987
 988        return rc;
 989}
 990
 991static ssize_t hl_clk_gate_write(struct file *f, const char __user *buf,
 992                                     size_t count, loff_t *ppos)
 993{
 994        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 995        struct hl_device *hdev = entry->hdev;
 996        u64 value;
 997        ssize_t rc;
 998
 999        if (atomic_read(&hdev->in_reset)) {
1000                dev_warn_ratelimited(hdev->dev,
1001                                "Can't change clock gating during reset\n");
1002                return 0;
1003        }
1004
1005        rc = kstrtoull_from_user(buf, count, 16, &value);
1006        if (rc)
1007                return rc;
1008
1009        hdev->clock_gating_mask = value;
1010        hdev->asic_funcs->set_clock_gating(hdev);
1011
1012        return count;
1013}
1014
1015static ssize_t hl_stop_on_err_read(struct file *f, char __user *buf,
1016                                        size_t count, loff_t *ppos)
1017{
1018        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
1019        struct hl_device *hdev = entry->hdev;
1020        char tmp_buf[200];
1021        ssize_t rc;
1022
1023        if (*ppos)
1024                return 0;
1025
1026        sprintf(tmp_buf, "%d\n", hdev->stop_on_err);
1027        rc = simple_read_from_buffer(buf, strlen(tmp_buf) + 1, ppos, tmp_buf,
1028                        strlen(tmp_buf) + 1);
1029
1030        return rc;
1031}
1032
1033static ssize_t hl_stop_on_err_write(struct file *f, const char __user *buf,
1034                                     size_t count, loff_t *ppos)
1035{
1036        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
1037        struct hl_device *hdev = entry->hdev;
1038        u32 value;
1039        ssize_t rc;
1040
1041        if (atomic_read(&hdev->in_reset)) {
1042                dev_warn_ratelimited(hdev->dev,
1043                                "Can't change stop on error during reset\n");
1044                return 0;
1045        }
1046
1047        rc = kstrtouint_from_user(buf, count, 10, &value);
1048        if (rc)
1049                return rc;
1050
1051        hdev->stop_on_err = value ? 1 : 0;
1052
1053        hl_device_reset(hdev, false, false);
1054
1055        return count;
1056}
1057
1058static const struct file_operations hl_data32b_fops = {
1059        .owner = THIS_MODULE,
1060        .read = hl_data_read32,
1061        .write = hl_data_write32
1062};
1063
1064static const struct file_operations hl_data64b_fops = {
1065        .owner = THIS_MODULE,
1066        .read = hl_data_read64,
1067        .write = hl_data_write64
1068};
1069
1070static const struct file_operations hl_i2c_data_fops = {
1071        .owner = THIS_MODULE,
1072        .read = hl_i2c_data_read,
1073        .write = hl_i2c_data_write
1074};
1075
1076static const struct file_operations hl_power_fops = {
1077        .owner = THIS_MODULE,
1078        .read = hl_get_power_state,
1079        .write = hl_set_power_state
1080};
1081
1082static const struct file_operations hl_led0_fops = {
1083        .owner = THIS_MODULE,
1084        .write = hl_led0_write
1085};
1086
1087static const struct file_operations hl_led1_fops = {
1088        .owner = THIS_MODULE,
1089        .write = hl_led1_write
1090};
1091
1092static const struct file_operations hl_led2_fops = {
1093        .owner = THIS_MODULE,
1094        .write = hl_led2_write
1095};
1096
1097static const struct file_operations hl_device_fops = {
1098        .owner = THIS_MODULE,
1099        .read = hl_device_read,
1100        .write = hl_device_write
1101};
1102
1103static const struct file_operations hl_clk_gate_fops = {
1104        .owner = THIS_MODULE,
1105        .read = hl_clk_gate_read,
1106        .write = hl_clk_gate_write
1107};
1108
1109static const struct file_operations hl_stop_on_err_fops = {
1110        .owner = THIS_MODULE,
1111        .read = hl_stop_on_err_read,
1112        .write = hl_stop_on_err_write
1113};
1114
1115static const struct hl_info_list hl_debugfs_list[] = {
1116        {"command_buffers", command_buffers_show, NULL},
1117        {"command_submission", command_submission_show, NULL},
1118        {"command_submission_jobs", command_submission_jobs_show, NULL},
1119        {"userptr", userptr_show, NULL},
1120        {"vm", vm_show, NULL},
1121        {"mmu", mmu_show, mmu_asid_va_write},
1122        {"engines", engines_show, NULL}
1123};
1124
1125static int hl_debugfs_open(struct inode *inode, struct file *file)
1126{
1127        struct hl_debugfs_entry *node = inode->i_private;
1128
1129        return single_open(file, node->info_ent->show, node);
1130}
1131
1132static ssize_t hl_debugfs_write(struct file *file, const char __user *buf,
1133                size_t count, loff_t *f_pos)
1134{
1135        struct hl_debugfs_entry *node = file->f_inode->i_private;
1136
1137        if (node->info_ent->write)
1138                return node->info_ent->write(file, buf, count, f_pos);
1139        else
1140                return -EINVAL;
1141
1142}
1143
1144static const struct file_operations hl_debugfs_fops = {
1145        .owner = THIS_MODULE,
1146        .open = hl_debugfs_open,
1147        .read = seq_read,
1148        .write = hl_debugfs_write,
1149        .llseek = seq_lseek,
1150        .release = single_release,
1151};
1152
1153void hl_debugfs_add_device(struct hl_device *hdev)
1154{
1155        struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
1156        int count = ARRAY_SIZE(hl_debugfs_list);
1157        struct hl_debugfs_entry *entry;
1158        struct dentry *ent;
1159        int i;
1160
1161        dev_entry->hdev = hdev;
1162        dev_entry->entry_arr = kmalloc_array(count,
1163                                        sizeof(struct hl_debugfs_entry),
1164                                        GFP_KERNEL);
1165        if (!dev_entry->entry_arr)
1166                return;
1167
1168        INIT_LIST_HEAD(&dev_entry->file_list);
1169        INIT_LIST_HEAD(&dev_entry->cb_list);
1170        INIT_LIST_HEAD(&dev_entry->cs_list);
1171        INIT_LIST_HEAD(&dev_entry->cs_job_list);
1172        INIT_LIST_HEAD(&dev_entry->userptr_list);
1173        INIT_LIST_HEAD(&dev_entry->ctx_mem_hash_list);
1174        mutex_init(&dev_entry->file_mutex);
1175        spin_lock_init(&dev_entry->cb_spinlock);
1176        spin_lock_init(&dev_entry->cs_spinlock);
1177        spin_lock_init(&dev_entry->cs_job_spinlock);
1178        spin_lock_init(&dev_entry->userptr_spinlock);
1179        spin_lock_init(&dev_entry->ctx_mem_hash_spinlock);
1180
1181        dev_entry->root = debugfs_create_dir(dev_name(hdev->dev),
1182                                                hl_debug_root);
1183
1184        debugfs_create_x64("addr",
1185                                0644,
1186                                dev_entry->root,
1187                                &dev_entry->addr);
1188
1189        debugfs_create_file("data32",
1190                                0644,
1191                                dev_entry->root,
1192                                dev_entry,
1193                                &hl_data32b_fops);
1194
1195        debugfs_create_file("data64",
1196                                0644,
1197                                dev_entry->root,
1198                                dev_entry,
1199                                &hl_data64b_fops);
1200
1201        debugfs_create_file("set_power_state",
1202                                0200,
1203                                dev_entry->root,
1204                                dev_entry,
1205                                &hl_power_fops);
1206
1207        debugfs_create_u8("i2c_bus",
1208                                0644,
1209                                dev_entry->root,
1210                                &dev_entry->i2c_bus);
1211
1212        debugfs_create_u8("i2c_addr",
1213                                0644,
1214                                dev_entry->root,
1215                                &dev_entry->i2c_addr);
1216
1217        debugfs_create_u8("i2c_reg",
1218                                0644,
1219                                dev_entry->root,
1220                                &dev_entry->i2c_reg);
1221
1222        debugfs_create_file("i2c_data",
1223                                0644,
1224                                dev_entry->root,
1225                                dev_entry,
1226                                &hl_i2c_data_fops);
1227
1228        debugfs_create_file("led0",
1229                                0200,
1230                                dev_entry->root,
1231                                dev_entry,
1232                                &hl_led0_fops);
1233
1234        debugfs_create_file("led1",
1235                                0200,
1236                                dev_entry->root,
1237                                dev_entry,
1238                                &hl_led1_fops);
1239
1240        debugfs_create_file("led2",
1241                                0200,
1242                                dev_entry->root,
1243                                dev_entry,
1244                                &hl_led2_fops);
1245
1246        debugfs_create_file("device",
1247                                0200,
1248                                dev_entry->root,
1249                                dev_entry,
1250                                &hl_device_fops);
1251
1252        debugfs_create_file("clk_gate",
1253                                0200,
1254                                dev_entry->root,
1255                                dev_entry,
1256                                &hl_clk_gate_fops);
1257
1258        debugfs_create_file("stop_on_err",
1259                                0644,
1260                                dev_entry->root,
1261                                dev_entry,
1262                                &hl_stop_on_err_fops);
1263
1264        for (i = 0, entry = dev_entry->entry_arr ; i < count ; i++, entry++) {
1265
1266                ent = debugfs_create_file(hl_debugfs_list[i].name,
1267                                        0444,
1268                                        dev_entry->root,
1269                                        entry,
1270                                        &hl_debugfs_fops);
1271                entry->dent = ent;
1272                entry->info_ent = &hl_debugfs_list[i];
1273                entry->dev_entry = dev_entry;
1274        }
1275}
1276
1277void hl_debugfs_remove_device(struct hl_device *hdev)
1278{
1279        struct hl_dbg_device_entry *entry = &hdev->hl_debugfs;
1280
1281        debugfs_remove_recursive(entry->root);
1282
1283        mutex_destroy(&entry->file_mutex);
1284        kfree(entry->entry_arr);
1285}
1286
1287void hl_debugfs_add_file(struct hl_fpriv *hpriv)
1288{
1289        struct hl_dbg_device_entry *dev_entry = &hpriv->hdev->hl_debugfs;
1290
1291        mutex_lock(&dev_entry->file_mutex);
1292        list_add(&hpriv->debugfs_list, &dev_entry->file_list);
1293        mutex_unlock(&dev_entry->file_mutex);
1294}
1295
1296void hl_debugfs_remove_file(struct hl_fpriv *hpriv)
1297{
1298        struct hl_dbg_device_entry *dev_entry = &hpriv->hdev->hl_debugfs;
1299
1300        mutex_lock(&dev_entry->file_mutex);
1301        list_del(&hpriv->debugfs_list);
1302        mutex_unlock(&dev_entry->file_mutex);
1303}
1304
1305void hl_debugfs_add_cb(struct hl_cb *cb)
1306{
1307        struct hl_dbg_device_entry *dev_entry = &cb->hdev->hl_debugfs;
1308
1309        spin_lock(&dev_entry->cb_spinlock);
1310        list_add(&cb->debugfs_list, &dev_entry->cb_list);
1311        spin_unlock(&dev_entry->cb_spinlock);
1312}
1313
1314void hl_debugfs_remove_cb(struct hl_cb *cb)
1315{
1316        struct hl_dbg_device_entry *dev_entry = &cb->hdev->hl_debugfs;
1317
1318        spin_lock(&dev_entry->cb_spinlock);
1319        list_del(&cb->debugfs_list);
1320        spin_unlock(&dev_entry->cb_spinlock);
1321}
1322
1323void hl_debugfs_add_cs(struct hl_cs *cs)
1324{
1325        struct hl_dbg_device_entry *dev_entry = &cs->ctx->hdev->hl_debugfs;
1326
1327        spin_lock(&dev_entry->cs_spinlock);
1328        list_add(&cs->debugfs_list, &dev_entry->cs_list);
1329        spin_unlock(&dev_entry->cs_spinlock);
1330}
1331
1332void hl_debugfs_remove_cs(struct hl_cs *cs)
1333{
1334        struct hl_dbg_device_entry *dev_entry = &cs->ctx->hdev->hl_debugfs;
1335
1336        spin_lock(&dev_entry->cs_spinlock);
1337        list_del(&cs->debugfs_list);
1338        spin_unlock(&dev_entry->cs_spinlock);
1339}
1340
1341void hl_debugfs_add_job(struct hl_device *hdev, struct hl_cs_job *job)
1342{
1343        struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
1344
1345        spin_lock(&dev_entry->cs_job_spinlock);
1346        list_add(&job->debugfs_list, &dev_entry->cs_job_list);
1347        spin_unlock(&dev_entry->cs_job_spinlock);
1348}
1349
1350void hl_debugfs_remove_job(struct hl_device *hdev, struct hl_cs_job *job)
1351{
1352        struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
1353
1354        spin_lock(&dev_entry->cs_job_spinlock);
1355        list_del(&job->debugfs_list);
1356        spin_unlock(&dev_entry->cs_job_spinlock);
1357}
1358
1359void hl_debugfs_add_userptr(struct hl_device *hdev, struct hl_userptr *userptr)
1360{
1361        struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
1362
1363        spin_lock(&dev_entry->userptr_spinlock);
1364        list_add(&userptr->debugfs_list, &dev_entry->userptr_list);
1365        spin_unlock(&dev_entry->userptr_spinlock);
1366}
1367
1368void hl_debugfs_remove_userptr(struct hl_device *hdev,
1369                                struct hl_userptr *userptr)
1370{
1371        struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
1372
1373        spin_lock(&dev_entry->userptr_spinlock);
1374        list_del(&userptr->debugfs_list);
1375        spin_unlock(&dev_entry->userptr_spinlock);
1376}
1377
1378void hl_debugfs_add_ctx_mem_hash(struct hl_device *hdev, struct hl_ctx *ctx)
1379{
1380        struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
1381
1382        spin_lock(&dev_entry->ctx_mem_hash_spinlock);
1383        list_add(&ctx->debugfs_list, &dev_entry->ctx_mem_hash_list);
1384        spin_unlock(&dev_entry->ctx_mem_hash_spinlock);
1385}
1386
1387void hl_debugfs_remove_ctx_mem_hash(struct hl_device *hdev, struct hl_ctx *ctx)
1388{
1389        struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
1390
1391        spin_lock(&dev_entry->ctx_mem_hash_spinlock);
1392        list_del(&ctx->debugfs_list);
1393        spin_unlock(&dev_entry->ctx_mem_hash_spinlock);
1394}
1395
1396void __init hl_debugfs_init(void)
1397{
1398        hl_debug_root = debugfs_create_dir("habanalabs", NULL);
1399}
1400
1401void hl_debugfs_fini(void)
1402{
1403        debugfs_remove_recursive(hl_debug_root);
1404}
1405