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/uaccess.h>
  13#include <linux/vmalloc.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 cpucp_packet pkt;
  25        u64 result;
  26        int rc;
  27
  28        if (!hl_device_operational(hdev, NULL))
  29                return -EBUSY;
  30
  31        memset(&pkt, 0, sizeof(pkt));
  32
  33        pkt.ctl = cpu_to_le32(CPUCP_PACKET_I2C_RD <<
  34                                CPUCP_PKT_CTL_OPCODE_SHIFT);
  35        pkt.i2c_bus = i2c_bus;
  36        pkt.i2c_addr = i2c_addr;
  37        pkt.i2c_reg = i2c_reg;
  38
  39        rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
  40                                                0, &result);
  41
  42        *val = (long) result;
  43
  44        if (rc)
  45                dev_err(hdev->dev, "Failed to read from I2C, error %d\n", rc);
  46
  47        return rc;
  48}
  49
  50static int hl_debugfs_i2c_write(struct hl_device *hdev, u8 i2c_bus, u8 i2c_addr,
  51                                u8 i2c_reg, u32 val)
  52{
  53        struct cpucp_packet pkt;
  54        int rc;
  55
  56        if (!hl_device_operational(hdev, NULL))
  57                return -EBUSY;
  58
  59        memset(&pkt, 0, sizeof(pkt));
  60
  61        pkt.ctl = cpu_to_le32(CPUCP_PACKET_I2C_WR <<
  62                                CPUCP_PKT_CTL_OPCODE_SHIFT);
  63        pkt.i2c_bus = i2c_bus;
  64        pkt.i2c_addr = i2c_addr;
  65        pkt.i2c_reg = i2c_reg;
  66        pkt.value = cpu_to_le64(val);
  67
  68        rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
  69                                                0, NULL);
  70
  71        if (rc)
  72                dev_err(hdev->dev, "Failed to write to I2C, error %d\n", rc);
  73
  74        return rc;
  75}
  76
  77static void hl_debugfs_led_set(struct hl_device *hdev, u8 led, u8 state)
  78{
  79        struct cpucp_packet pkt;
  80        int rc;
  81
  82        if (!hl_device_operational(hdev, NULL))
  83                return;
  84
  85        memset(&pkt, 0, sizeof(pkt));
  86
  87        pkt.ctl = cpu_to_le32(CPUCP_PACKET_LED_SET <<
  88                                CPUCP_PKT_CTL_OPCODE_SHIFT);
  89        pkt.led_index = cpu_to_le32(led);
  90        pkt.value = cpu_to_le64(state);
  91
  92        rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
  93                                                0, NULL);
  94
  95        if (rc)
  96                dev_err(hdev->dev, "Failed to set LED %d, error %d\n", led, rc);
  97}
  98
  99static int command_buffers_show(struct seq_file *s, void *data)
 100{
 101        struct hl_debugfs_entry *entry = s->private;
 102        struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
 103        struct hl_cb *cb;
 104        bool first = true;
 105
 106        spin_lock(&dev_entry->cb_spinlock);
 107
 108        list_for_each_entry(cb, &dev_entry->cb_list, debugfs_list) {
 109                if (first) {
 110                        first = false;
 111                        seq_puts(s, "\n");
 112                        seq_puts(s, " CB ID   CTX ID   CB size    CB RefCnt    mmap?   CS counter\n");
 113                        seq_puts(s, "---------------------------------------------------------------\n");
 114                }
 115                seq_printf(s,
 116                        "   %03llu        %d    0x%08x      %d          %d          %d\n",
 117                        cb->id, cb->ctx->asid, cb->size,
 118                        kref_read(&cb->refcount),
 119                        cb->mmap, atomic_read(&cb->cs_cnt));
 120        }
 121
 122        spin_unlock(&dev_entry->cb_spinlock);
 123
 124        if (!first)
 125                seq_puts(s, "\n");
 126
 127        return 0;
 128}
 129
 130static int command_submission_show(struct seq_file *s, void *data)
 131{
 132        struct hl_debugfs_entry *entry = s->private;
 133        struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
 134        struct hl_cs *cs;
 135        bool first = true;
 136
 137        spin_lock(&dev_entry->cs_spinlock);
 138
 139        list_for_each_entry(cs, &dev_entry->cs_list, debugfs_list) {
 140                if (first) {
 141                        first = false;
 142                        seq_puts(s, "\n");
 143                        seq_puts(s, " CS ID   CTX ASID   CS RefCnt   Submitted    Completed\n");
 144                        seq_puts(s, "------------------------------------------------------\n");
 145                }
 146                seq_printf(s,
 147                        "   %llu       %d          %d           %d            %d\n",
 148                        cs->sequence, cs->ctx->asid,
 149                        kref_read(&cs->refcount),
 150                        cs->submitted, cs->completed);
 151        }
 152
 153        spin_unlock(&dev_entry->cs_spinlock);
 154
 155        if (!first)
 156                seq_puts(s, "\n");
 157
 158        return 0;
 159}
 160
 161static int command_submission_jobs_show(struct seq_file *s, void *data)
 162{
 163        struct hl_debugfs_entry *entry = s->private;
 164        struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
 165        struct hl_cs_job *job;
 166        bool first = true;
 167
 168        spin_lock(&dev_entry->cs_job_spinlock);
 169
 170        list_for_each_entry(job, &dev_entry->cs_job_list, debugfs_list) {
 171                if (first) {
 172                        first = false;
 173                        seq_puts(s, "\n");
 174                        seq_puts(s, " JOB ID   CS ID    CTX ASID   JOB RefCnt   H/W Queue\n");
 175                        seq_puts(s, "----------------------------------------------------\n");
 176                }
 177                if (job->cs)
 178                        seq_printf(s,
 179                                "   %02d      %llu        %d          %d           %d\n",
 180                                job->id, job->cs->sequence, job->cs->ctx->asid,
 181                                kref_read(&job->refcount), job->hw_queue_id);
 182                else
 183                        seq_printf(s,
 184                                "   %02d      0        %d          %d           %d\n",
 185                                job->id, HL_KERNEL_ASID_ID,
 186                                kref_read(&job->refcount), job->hw_queue_id);
 187        }
 188
 189        spin_unlock(&dev_entry->cs_job_spinlock);
 190
 191        if (!first)
 192                seq_puts(s, "\n");
 193
 194        return 0;
 195}
 196
 197static int userptr_show(struct seq_file *s, void *data)
 198{
 199        struct hl_debugfs_entry *entry = s->private;
 200        struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
 201        struct hl_userptr *userptr;
 202        char dma_dir[4][30] = {"DMA_BIDIRECTIONAL", "DMA_TO_DEVICE",
 203                                "DMA_FROM_DEVICE", "DMA_NONE"};
 204        bool first = true;
 205
 206        spin_lock(&dev_entry->userptr_spinlock);
 207
 208        list_for_each_entry(userptr, &dev_entry->userptr_list, debugfs_list) {
 209                if (first) {
 210                        first = false;
 211                        seq_puts(s, "\n");
 212                        seq_puts(s, " user virtual address     size             dma dir\n");
 213                        seq_puts(s, "----------------------------------------------------------\n");
 214                }
 215                seq_printf(s,
 216                        "    0x%-14llx      %-10u    %-30s\n",
 217                        userptr->addr, userptr->size, dma_dir[userptr->dir]);
 218        }
 219
 220        spin_unlock(&dev_entry->userptr_spinlock);
 221
 222        if (!first)
 223                seq_puts(s, "\n");
 224
 225        return 0;
 226}
 227
 228static int vm_show(struct seq_file *s, void *data)
 229{
 230        struct hl_debugfs_entry *entry = s->private;
 231        struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
 232        struct hl_vm_hw_block_list_node *lnode;
 233        struct hl_ctx *ctx;
 234        struct hl_vm *vm;
 235        struct hl_vm_hash_node *hnode;
 236        struct hl_userptr *userptr;
 237        struct hl_vm_phys_pg_pack *phys_pg_pack = NULL;
 238        enum vm_type_t *vm_type;
 239        bool once = true;
 240        u64 j;
 241        int i;
 242
 243        if (!dev_entry->hdev->mmu_enable)
 244                return 0;
 245
 246        spin_lock(&dev_entry->ctx_mem_hash_spinlock);
 247
 248        list_for_each_entry(ctx, &dev_entry->ctx_mem_hash_list, debugfs_list) {
 249                once = false;
 250                seq_puts(s, "\n\n----------------------------------------------------");
 251                seq_puts(s, "\n----------------------------------------------------\n\n");
 252                seq_printf(s, "ctx asid: %u\n", ctx->asid);
 253
 254                seq_puts(s, "\nmappings:\n\n");
 255                seq_puts(s, "    virtual address        size          handle\n");
 256                seq_puts(s, "----------------------------------------------------\n");
 257                mutex_lock(&ctx->mem_hash_lock);
 258                hash_for_each(ctx->mem_hash, i, hnode, node) {
 259                        vm_type = hnode->ptr;
 260
 261                        if (*vm_type == VM_TYPE_USERPTR) {
 262                                userptr = hnode->ptr;
 263                                seq_printf(s,
 264                                        "    0x%-14llx      %-10u\n",
 265                                        hnode->vaddr, userptr->size);
 266                        } else {
 267                                phys_pg_pack = hnode->ptr;
 268                                seq_printf(s,
 269                                        "    0x%-14llx      %-10llu       %-4u\n",
 270                                        hnode->vaddr, phys_pg_pack->total_size,
 271                                        phys_pg_pack->handle);
 272                        }
 273                }
 274                mutex_unlock(&ctx->mem_hash_lock);
 275
 276                if (ctx->asid != HL_KERNEL_ASID_ID &&
 277                    !list_empty(&ctx->hw_block_mem_list)) {
 278                        seq_puts(s, "\nhw_block mappings:\n\n");
 279                        seq_puts(s, "    virtual address    size    HW block id\n");
 280                        seq_puts(s, "-------------------------------------------\n");
 281                        mutex_lock(&ctx->hw_block_list_lock);
 282                        list_for_each_entry(lnode, &ctx->hw_block_mem_list,
 283                                            node) {
 284                                seq_printf(s,
 285                                        "    0x%-14lx   %-6u      %-9u\n",
 286                                        lnode->vaddr, lnode->size, lnode->id);
 287                        }
 288                        mutex_unlock(&ctx->hw_block_list_lock);
 289                }
 290
 291                vm = &ctx->hdev->vm;
 292                spin_lock(&vm->idr_lock);
 293
 294                if (!idr_is_empty(&vm->phys_pg_pack_handles))
 295                        seq_puts(s, "\n\nallocations:\n");
 296
 297                idr_for_each_entry(&vm->phys_pg_pack_handles, phys_pg_pack, i) {
 298                        if (phys_pg_pack->asid != ctx->asid)
 299                                continue;
 300
 301                        seq_printf(s, "\nhandle: %u\n", phys_pg_pack->handle);
 302                        seq_printf(s, "page size: %u\n\n",
 303                                                phys_pg_pack->page_size);
 304                        seq_puts(s, "   physical address\n");
 305                        seq_puts(s, "---------------------\n");
 306                        for (j = 0 ; j < phys_pg_pack->npages ; j++) {
 307                                seq_printf(s, "    0x%-14llx\n",
 308                                                phys_pg_pack->pages[j]);
 309                        }
 310                }
 311                spin_unlock(&vm->idr_lock);
 312
 313        }
 314
 315        spin_unlock(&dev_entry->ctx_mem_hash_spinlock);
 316
 317        if (!once)
 318                seq_puts(s, "\n");
 319
 320        return 0;
 321}
 322
 323static int mmu_show(struct seq_file *s, void *data)
 324{
 325        struct hl_debugfs_entry *entry = s->private;
 326        struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
 327        struct hl_device *hdev = dev_entry->hdev;
 328        struct hl_ctx *ctx;
 329        struct hl_mmu_hop_info hops_info = {0};
 330        u64 virt_addr = dev_entry->mmu_addr, phys_addr;
 331        int i;
 332
 333        if (!hdev->mmu_enable)
 334                return 0;
 335
 336        if (dev_entry->mmu_asid == HL_KERNEL_ASID_ID)
 337                ctx = hdev->kernel_ctx;
 338        else
 339                ctx = hdev->compute_ctx;
 340
 341        if (!ctx) {
 342                dev_err(hdev->dev, "no ctx available\n");
 343                return 0;
 344        }
 345
 346        if (hl_mmu_get_tlb_info(ctx, virt_addr, &hops_info)) {
 347                dev_err(hdev->dev, "virt addr 0x%llx is not mapped to phys addr\n",
 348                                virt_addr);
 349                return 0;
 350        }
 351
 352        phys_addr = hops_info.hop_info[hops_info.used_hops - 1].hop_pte_val;
 353
 354        if (hops_info.scrambled_vaddr &&
 355                (dev_entry->mmu_addr != hops_info.scrambled_vaddr))
 356                seq_printf(s,
 357                        "asid: %u, virt_addr: 0x%llx, scrambled virt_addr: 0x%llx,\nphys_addr: 0x%llx, scrambled_phys_addr: 0x%llx\n",
 358                        dev_entry->mmu_asid, dev_entry->mmu_addr,
 359                        hops_info.scrambled_vaddr,
 360                        hops_info.unscrambled_paddr, phys_addr);
 361        else
 362                seq_printf(s,
 363                        "asid: %u, virt_addr: 0x%llx, phys_addr: 0x%llx\n",
 364                        dev_entry->mmu_asid, dev_entry->mmu_addr, phys_addr);
 365
 366        for (i = 0 ; i < hops_info.used_hops ; i++) {
 367                seq_printf(s, "hop%d_addr: 0x%llx\n",
 368                                i, hops_info.hop_info[i].hop_addr);
 369                seq_printf(s, "hop%d_pte_addr: 0x%llx\n",
 370                                i, hops_info.hop_info[i].hop_pte_addr);
 371                seq_printf(s, "hop%d_pte: 0x%llx\n",
 372                                i, hops_info.hop_info[i].hop_pte_val);
 373        }
 374
 375        return 0;
 376}
 377
 378static ssize_t mmu_asid_va_write(struct file *file, const char __user *buf,
 379                size_t count, loff_t *f_pos)
 380{
 381        struct seq_file *s = file->private_data;
 382        struct hl_debugfs_entry *entry = s->private;
 383        struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
 384        struct hl_device *hdev = dev_entry->hdev;
 385        char kbuf[MMU_KBUF_SIZE];
 386        char *c;
 387        ssize_t rc;
 388
 389        if (!hdev->mmu_enable)
 390                return count;
 391
 392        if (count > sizeof(kbuf) - 1)
 393                goto err;
 394        if (copy_from_user(kbuf, buf, count))
 395                goto err;
 396        kbuf[count] = 0;
 397
 398        c = strchr(kbuf, ' ');
 399        if (!c)
 400                goto err;
 401        *c = '\0';
 402
 403        rc = kstrtouint(kbuf, 10, &dev_entry->mmu_asid);
 404        if (rc)
 405                goto err;
 406
 407        if (strncmp(c+1, "0x", 2))
 408                goto err;
 409        rc = kstrtoull(c+3, 16, &dev_entry->mmu_addr);
 410        if (rc)
 411                goto err;
 412
 413        return count;
 414
 415err:
 416        dev_err(hdev->dev, "usage: echo <asid> <0xaddr> > mmu\n");
 417
 418        return -EINVAL;
 419}
 420
 421static int engines_show(struct seq_file *s, void *data)
 422{
 423        struct hl_debugfs_entry *entry = s->private;
 424        struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
 425        struct hl_device *hdev = dev_entry->hdev;
 426
 427        if (atomic_read(&hdev->in_reset)) {
 428                dev_warn_ratelimited(hdev->dev,
 429                                "Can't check device idle during reset\n");
 430                return 0;
 431        }
 432
 433        hdev->asic_funcs->is_device_idle(hdev, NULL, 0, s);
 434
 435        return 0;
 436}
 437
 438static bool hl_is_device_va(struct hl_device *hdev, u64 addr)
 439{
 440        struct asic_fixed_properties *prop = &hdev->asic_prop;
 441
 442        if (!hdev->mmu_enable)
 443                goto out;
 444
 445        if (prop->dram_supports_virtual_memory &&
 446                (addr >= prop->dmmu.start_addr && addr < prop->dmmu.end_addr))
 447                return true;
 448
 449        if (addr >= prop->pmmu.start_addr &&
 450                addr < prop->pmmu.end_addr)
 451                return true;
 452
 453        if (addr >= prop->pmmu_huge.start_addr &&
 454                addr < prop->pmmu_huge.end_addr)
 455                return true;
 456out:
 457        return false;
 458}
 459
 460static bool hl_is_device_internal_memory_va(struct hl_device *hdev, u64 addr,
 461                                                u32 size)
 462{
 463        struct asic_fixed_properties *prop = &hdev->asic_prop;
 464        u64 dram_start_addr, dram_end_addr;
 465
 466        if (!hdev->mmu_enable)
 467                return false;
 468
 469        if (prop->dram_supports_virtual_memory) {
 470                dram_start_addr = prop->dmmu.start_addr;
 471                dram_end_addr = prop->dmmu.end_addr;
 472        } else {
 473                dram_start_addr = prop->dram_base_address;
 474                dram_end_addr = prop->dram_end_address;
 475        }
 476
 477        if (hl_mem_area_inside_range(addr, size, dram_start_addr,
 478                                        dram_end_addr))
 479                return true;
 480
 481        if (hl_mem_area_inside_range(addr, size, prop->sram_base_address,
 482                                        prop->sram_end_address))
 483                return true;
 484
 485        return false;
 486}
 487
 488static int device_va_to_pa(struct hl_device *hdev, u64 virt_addr, u32 size,
 489                        u64 *phys_addr)
 490{
 491        struct hl_vm_phys_pg_pack *phys_pg_pack;
 492        struct hl_ctx *ctx = hdev->compute_ctx;
 493        struct hl_vm_hash_node *hnode;
 494        struct hl_userptr *userptr;
 495        enum vm_type_t *vm_type;
 496        bool valid = false;
 497        u64 end_address;
 498        u32 range_size;
 499        int i, rc = 0;
 500
 501        if (!ctx) {
 502                dev_err(hdev->dev, "no ctx available\n");
 503                return -EINVAL;
 504        }
 505
 506        /* Verify address is mapped */
 507        mutex_lock(&ctx->mem_hash_lock);
 508        hash_for_each(ctx->mem_hash, i, hnode, node) {
 509                vm_type = hnode->ptr;
 510
 511                if (*vm_type == VM_TYPE_USERPTR) {
 512                        userptr = hnode->ptr;
 513                        range_size = userptr->size;
 514                } else {
 515                        phys_pg_pack = hnode->ptr;
 516                        range_size = phys_pg_pack->total_size;
 517                }
 518
 519                end_address = virt_addr + size;
 520                if ((virt_addr >= hnode->vaddr) &&
 521                                (end_address <= hnode->vaddr + range_size)) {
 522                        valid = true;
 523                        break;
 524                }
 525        }
 526        mutex_unlock(&ctx->mem_hash_lock);
 527
 528        if (!valid) {
 529                dev_err(hdev->dev,
 530                        "virt addr 0x%llx is not mapped\n",
 531                        virt_addr);
 532                return -EINVAL;
 533        }
 534
 535        rc = hl_mmu_va_to_pa(ctx, virt_addr, phys_addr);
 536        if (rc) {
 537                dev_err(hdev->dev,
 538                        "virt addr 0x%llx is not mapped to phys addr\n",
 539                        virt_addr);
 540                rc = -EINVAL;
 541        }
 542
 543        return rc;
 544}
 545
 546static ssize_t hl_data_read32(struct file *f, char __user *buf,
 547                                        size_t count, loff_t *ppos)
 548{
 549        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 550        struct hl_device *hdev = entry->hdev;
 551        u64 addr = entry->addr;
 552        bool user_address;
 553        char tmp_buf[32];
 554        ssize_t rc;
 555        u32 val;
 556
 557        if (atomic_read(&hdev->in_reset)) {
 558                dev_warn_ratelimited(hdev->dev, "Can't read during reset\n");
 559                return 0;
 560        }
 561
 562        if (*ppos)
 563                return 0;
 564
 565        user_address = hl_is_device_va(hdev, addr);
 566        if (user_address) {
 567                rc = device_va_to_pa(hdev, addr, sizeof(val), &addr);
 568                if (rc)
 569                        return rc;
 570        }
 571
 572        rc = hdev->asic_funcs->debugfs_read32(hdev, addr, user_address, &val);
 573        if (rc) {
 574                dev_err(hdev->dev, "Failed to read from 0x%010llx\n", addr);
 575                return rc;
 576        }
 577
 578        sprintf(tmp_buf, "0x%08x\n", val);
 579        return simple_read_from_buffer(buf, count, ppos, tmp_buf,
 580                        strlen(tmp_buf));
 581}
 582
 583static ssize_t hl_data_write32(struct file *f, const char __user *buf,
 584                                        size_t count, loff_t *ppos)
 585{
 586        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 587        struct hl_device *hdev = entry->hdev;
 588        u64 addr = entry->addr;
 589        bool user_address;
 590        u32 value;
 591        ssize_t rc;
 592
 593        if (atomic_read(&hdev->in_reset)) {
 594                dev_warn_ratelimited(hdev->dev, "Can't write during reset\n");
 595                return 0;
 596        }
 597
 598        rc = kstrtouint_from_user(buf, count, 16, &value);
 599        if (rc)
 600                return rc;
 601
 602        user_address = hl_is_device_va(hdev, addr);
 603        if (user_address) {
 604                rc = device_va_to_pa(hdev, addr, sizeof(value), &addr);
 605                if (rc)
 606                        return rc;
 607        }
 608
 609        rc = hdev->asic_funcs->debugfs_write32(hdev, addr, user_address, value);
 610        if (rc) {
 611                dev_err(hdev->dev, "Failed to write 0x%08x to 0x%010llx\n",
 612                        value, addr);
 613                return rc;
 614        }
 615
 616        return count;
 617}
 618
 619static ssize_t hl_data_read64(struct file *f, char __user *buf,
 620                                        size_t count, loff_t *ppos)
 621{
 622        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 623        struct hl_device *hdev = entry->hdev;
 624        u64 addr = entry->addr;
 625        bool user_address;
 626        char tmp_buf[32];
 627        ssize_t rc;
 628        u64 val;
 629
 630        if (atomic_read(&hdev->in_reset)) {
 631                dev_warn_ratelimited(hdev->dev, "Can't read during reset\n");
 632                return 0;
 633        }
 634
 635        if (*ppos)
 636                return 0;
 637
 638        user_address = hl_is_device_va(hdev, addr);
 639        if (user_address) {
 640                rc = device_va_to_pa(hdev, addr, sizeof(val), &addr);
 641                if (rc)
 642                        return rc;
 643        }
 644
 645        rc = hdev->asic_funcs->debugfs_read64(hdev, addr, user_address, &val);
 646        if (rc) {
 647                dev_err(hdev->dev, "Failed to read from 0x%010llx\n", addr);
 648                return rc;
 649        }
 650
 651        sprintf(tmp_buf, "0x%016llx\n", val);
 652        return simple_read_from_buffer(buf, count, ppos, tmp_buf,
 653                        strlen(tmp_buf));
 654}
 655
 656static ssize_t hl_data_write64(struct file *f, const char __user *buf,
 657                                        size_t count, loff_t *ppos)
 658{
 659        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 660        struct hl_device *hdev = entry->hdev;
 661        u64 addr = entry->addr;
 662        bool user_address;
 663        u64 value;
 664        ssize_t rc;
 665
 666        if (atomic_read(&hdev->in_reset)) {
 667                dev_warn_ratelimited(hdev->dev, "Can't write during reset\n");
 668                return 0;
 669        }
 670
 671        rc = kstrtoull_from_user(buf, count, 16, &value);
 672        if (rc)
 673                return rc;
 674
 675        user_address = hl_is_device_va(hdev, addr);
 676        if (user_address) {
 677                rc = device_va_to_pa(hdev, addr, sizeof(value), &addr);
 678                if (rc)
 679                        return rc;
 680        }
 681
 682        rc = hdev->asic_funcs->debugfs_write64(hdev, addr, user_address, value);
 683        if (rc) {
 684                dev_err(hdev->dev, "Failed to write 0x%016llx to 0x%010llx\n",
 685                        value, addr);
 686                return rc;
 687        }
 688
 689        return count;
 690}
 691
 692static ssize_t hl_dma_size_write(struct file *f, const char __user *buf,
 693                                        size_t count, loff_t *ppos)
 694{
 695        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 696        struct hl_device *hdev = entry->hdev;
 697        u64 addr = entry->addr;
 698        ssize_t rc;
 699        u32 size;
 700
 701        if (atomic_read(&hdev->in_reset)) {
 702                dev_warn_ratelimited(hdev->dev, "Can't DMA during reset\n");
 703                return 0;
 704        }
 705        rc = kstrtouint_from_user(buf, count, 16, &size);
 706        if (rc)
 707                return rc;
 708
 709        if (!size) {
 710                dev_err(hdev->dev, "DMA read failed. size can't be 0\n");
 711                return -EINVAL;
 712        }
 713
 714        if (size > SZ_128M) {
 715                dev_err(hdev->dev,
 716                        "DMA read failed. size can't be larger than 128MB\n");
 717                return -EINVAL;
 718        }
 719
 720        if (!hl_is_device_internal_memory_va(hdev, addr, size)) {
 721                dev_err(hdev->dev,
 722                        "DMA read failed. Invalid 0x%010llx + 0x%08x\n",
 723                        addr, size);
 724                return -EINVAL;
 725        }
 726
 727        /* Free the previous allocation, if there was any */
 728        entry->blob_desc.size = 0;
 729        vfree(entry->blob_desc.data);
 730
 731        entry->blob_desc.data = vmalloc(size);
 732        if (!entry->blob_desc.data)
 733                return -ENOMEM;
 734
 735        rc = hdev->asic_funcs->debugfs_read_dma(hdev, addr, size,
 736                                                entry->blob_desc.data);
 737        if (rc) {
 738                dev_err(hdev->dev, "Failed to DMA from 0x%010llx\n", addr);
 739                vfree(entry->blob_desc.data);
 740                entry->blob_desc.data = NULL;
 741                return -EIO;
 742        }
 743
 744        entry->blob_desc.size = size;
 745
 746        return count;
 747}
 748
 749static ssize_t hl_get_power_state(struct file *f, char __user *buf,
 750                size_t count, loff_t *ppos)
 751{
 752        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 753        struct hl_device *hdev = entry->hdev;
 754        char tmp_buf[200];
 755        int i;
 756
 757        if (*ppos)
 758                return 0;
 759
 760        if (hdev->pdev->current_state == PCI_D0)
 761                i = 1;
 762        else if (hdev->pdev->current_state == PCI_D3hot)
 763                i = 2;
 764        else
 765                i = 3;
 766
 767        sprintf(tmp_buf,
 768                "current power state: %d\n1 - D0\n2 - D3hot\n3 - Unknown\n", i);
 769        return simple_read_from_buffer(buf, count, ppos, tmp_buf,
 770                        strlen(tmp_buf));
 771}
 772
 773static ssize_t hl_set_power_state(struct file *f, const char __user *buf,
 774                                        size_t count, loff_t *ppos)
 775{
 776        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 777        struct hl_device *hdev = entry->hdev;
 778        u32 value;
 779        ssize_t rc;
 780
 781        rc = kstrtouint_from_user(buf, count, 10, &value);
 782        if (rc)
 783                return rc;
 784
 785        if (value == 1) {
 786                pci_set_power_state(hdev->pdev, PCI_D0);
 787                pci_restore_state(hdev->pdev);
 788                rc = pci_enable_device(hdev->pdev);
 789        } else if (value == 2) {
 790                pci_save_state(hdev->pdev);
 791                pci_disable_device(hdev->pdev);
 792                pci_set_power_state(hdev->pdev, PCI_D3hot);
 793        } else {
 794                dev_dbg(hdev->dev, "invalid power state value %u\n", value);
 795                return -EINVAL;
 796        }
 797
 798        return count;
 799}
 800
 801static ssize_t hl_i2c_data_read(struct file *f, char __user *buf,
 802                                        size_t count, loff_t *ppos)
 803{
 804        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 805        struct hl_device *hdev = entry->hdev;
 806        char tmp_buf[32];
 807        long val;
 808        ssize_t rc;
 809
 810        if (*ppos)
 811                return 0;
 812
 813        rc = hl_debugfs_i2c_read(hdev, entry->i2c_bus, entry->i2c_addr,
 814                        entry->i2c_reg, &val);
 815        if (rc) {
 816                dev_err(hdev->dev,
 817                        "Failed to read from I2C bus %d, addr %d, reg %d\n",
 818                        entry->i2c_bus, entry->i2c_addr, entry->i2c_reg);
 819                return rc;
 820        }
 821
 822        sprintf(tmp_buf, "0x%02lx\n", val);
 823        rc = simple_read_from_buffer(buf, count, ppos, tmp_buf,
 824                        strlen(tmp_buf));
 825
 826        return rc;
 827}
 828
 829static ssize_t hl_i2c_data_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        u32 value;
 835        ssize_t rc;
 836
 837        rc = kstrtouint_from_user(buf, count, 16, &value);
 838        if (rc)
 839                return rc;
 840
 841        rc = hl_debugfs_i2c_write(hdev, entry->i2c_bus, entry->i2c_addr,
 842                        entry->i2c_reg, value);
 843        if (rc) {
 844                dev_err(hdev->dev,
 845                        "Failed to write 0x%02x to I2C bus %d, addr %d, reg %d\n",
 846                        value, entry->i2c_bus, entry->i2c_addr, entry->i2c_reg);
 847                return rc;
 848        }
 849
 850        return count;
 851}
 852
 853static ssize_t hl_led0_write(struct file *f, const char __user *buf,
 854                                        size_t count, loff_t *ppos)
 855{
 856        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 857        struct hl_device *hdev = entry->hdev;
 858        u32 value;
 859        ssize_t rc;
 860
 861        rc = kstrtouint_from_user(buf, count, 10, &value);
 862        if (rc)
 863                return rc;
 864
 865        value = value ? 1 : 0;
 866
 867        hl_debugfs_led_set(hdev, 0, value);
 868
 869        return count;
 870}
 871
 872static ssize_t hl_led1_write(struct file *f, const char __user *buf,
 873                                        size_t count, loff_t *ppos)
 874{
 875        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 876        struct hl_device *hdev = entry->hdev;
 877        u32 value;
 878        ssize_t rc;
 879
 880        rc = kstrtouint_from_user(buf, count, 10, &value);
 881        if (rc)
 882                return rc;
 883
 884        value = value ? 1 : 0;
 885
 886        hl_debugfs_led_set(hdev, 1, value);
 887
 888        return count;
 889}
 890
 891static ssize_t hl_led2_write(struct file *f, const char __user *buf,
 892                                        size_t count, loff_t *ppos)
 893{
 894        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 895        struct hl_device *hdev = entry->hdev;
 896        u32 value;
 897        ssize_t rc;
 898
 899        rc = kstrtouint_from_user(buf, count, 10, &value);
 900        if (rc)
 901                return rc;
 902
 903        value = value ? 1 : 0;
 904
 905        hl_debugfs_led_set(hdev, 2, value);
 906
 907        return count;
 908}
 909
 910static ssize_t hl_device_read(struct file *f, char __user *buf,
 911                                        size_t count, loff_t *ppos)
 912{
 913        static const char *help =
 914                "Valid values: disable, enable, suspend, resume, cpu_timeout\n";
 915        return simple_read_from_buffer(buf, count, ppos, help, strlen(help));
 916}
 917
 918static ssize_t hl_device_write(struct file *f, const char __user *buf,
 919                                     size_t count, loff_t *ppos)
 920{
 921        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 922        struct hl_device *hdev = entry->hdev;
 923        char data[30] = {0};
 924
 925        /* don't allow partial writes */
 926        if (*ppos != 0)
 927                return 0;
 928
 929        simple_write_to_buffer(data, 29, ppos, buf, count);
 930
 931        if (strncmp("disable", data, strlen("disable")) == 0) {
 932                hdev->disabled = true;
 933        } else if (strncmp("enable", data, strlen("enable")) == 0) {
 934                hdev->disabled = false;
 935        } else if (strncmp("suspend", data, strlen("suspend")) == 0) {
 936                hdev->asic_funcs->suspend(hdev);
 937        } else if (strncmp("resume", data, strlen("resume")) == 0) {
 938                hdev->asic_funcs->resume(hdev);
 939        } else if (strncmp("cpu_timeout", data, strlen("cpu_timeout")) == 0) {
 940                hdev->device_cpu_disabled = true;
 941        } else {
 942                dev_err(hdev->dev,
 943                        "Valid values: disable, enable, suspend, resume, cpu_timeout\n");
 944                count = -EINVAL;
 945        }
 946
 947        return count;
 948}
 949
 950static ssize_t hl_clk_gate_read(struct file *f, char __user *buf,
 951                                        size_t count, loff_t *ppos)
 952{
 953        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 954        struct hl_device *hdev = entry->hdev;
 955        char tmp_buf[200];
 956        ssize_t rc;
 957
 958        if (*ppos)
 959                return 0;
 960
 961        sprintf(tmp_buf, "0x%llx\n", hdev->clock_gating_mask);
 962        rc = simple_read_from_buffer(buf, count, ppos, tmp_buf,
 963                        strlen(tmp_buf) + 1);
 964
 965        return rc;
 966}
 967
 968static ssize_t hl_clk_gate_write(struct file *f, const char __user *buf,
 969                                     size_t count, loff_t *ppos)
 970{
 971        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 972        struct hl_device *hdev = entry->hdev;
 973        u64 value;
 974        ssize_t rc;
 975
 976        if (atomic_read(&hdev->in_reset)) {
 977                dev_warn_ratelimited(hdev->dev,
 978                                "Can't change clock gating during reset\n");
 979                return 0;
 980        }
 981
 982        rc = kstrtoull_from_user(buf, count, 16, &value);
 983        if (rc)
 984                return rc;
 985
 986        hdev->clock_gating_mask = value;
 987        hdev->asic_funcs->set_clock_gating(hdev);
 988
 989        return count;
 990}
 991
 992static ssize_t hl_stop_on_err_read(struct file *f, char __user *buf,
 993                                        size_t count, loff_t *ppos)
 994{
 995        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 996        struct hl_device *hdev = entry->hdev;
 997        char tmp_buf[200];
 998        ssize_t rc;
 999
1000        if (*ppos)
1001                return 0;
1002
1003        sprintf(tmp_buf, "%d\n", hdev->stop_on_err);
1004        rc = simple_read_from_buffer(buf, strlen(tmp_buf) + 1, ppos, tmp_buf,
1005                        strlen(tmp_buf) + 1);
1006
1007        return rc;
1008}
1009
1010static ssize_t hl_stop_on_err_write(struct file *f, const char __user *buf,
1011                                     size_t count, loff_t *ppos)
1012{
1013        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
1014        struct hl_device *hdev = entry->hdev;
1015        u32 value;
1016        ssize_t rc;
1017
1018        if (atomic_read(&hdev->in_reset)) {
1019                dev_warn_ratelimited(hdev->dev,
1020                                "Can't change stop on error during reset\n");
1021                return 0;
1022        }
1023
1024        rc = kstrtouint_from_user(buf, count, 10, &value);
1025        if (rc)
1026                return rc;
1027
1028        hdev->stop_on_err = value ? 1 : 0;
1029
1030        hl_device_reset(hdev, 0);
1031
1032        return count;
1033}
1034
1035static ssize_t hl_security_violations_read(struct file *f, char __user *buf,
1036                                        size_t count, loff_t *ppos)
1037{
1038        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
1039        struct hl_device *hdev = entry->hdev;
1040
1041        hdev->asic_funcs->ack_protection_bits_errors(hdev);
1042
1043        return 0;
1044}
1045
1046static const struct file_operations hl_data32b_fops = {
1047        .owner = THIS_MODULE,
1048        .read = hl_data_read32,
1049        .write = hl_data_write32
1050};
1051
1052static const struct file_operations hl_data64b_fops = {
1053        .owner = THIS_MODULE,
1054        .read = hl_data_read64,
1055        .write = hl_data_write64
1056};
1057
1058static const struct file_operations hl_dma_size_fops = {
1059        .owner = THIS_MODULE,
1060        .write = hl_dma_size_write
1061};
1062
1063static const struct file_operations hl_i2c_data_fops = {
1064        .owner = THIS_MODULE,
1065        .read = hl_i2c_data_read,
1066        .write = hl_i2c_data_write
1067};
1068
1069static const struct file_operations hl_power_fops = {
1070        .owner = THIS_MODULE,
1071        .read = hl_get_power_state,
1072        .write = hl_set_power_state
1073};
1074
1075static const struct file_operations hl_led0_fops = {
1076        .owner = THIS_MODULE,
1077        .write = hl_led0_write
1078};
1079
1080static const struct file_operations hl_led1_fops = {
1081        .owner = THIS_MODULE,
1082        .write = hl_led1_write
1083};
1084
1085static const struct file_operations hl_led2_fops = {
1086        .owner = THIS_MODULE,
1087        .write = hl_led2_write
1088};
1089
1090static const struct file_operations hl_device_fops = {
1091        .owner = THIS_MODULE,
1092        .read = hl_device_read,
1093        .write = hl_device_write
1094};
1095
1096static const struct file_operations hl_clk_gate_fops = {
1097        .owner = THIS_MODULE,
1098        .read = hl_clk_gate_read,
1099        .write = hl_clk_gate_write
1100};
1101
1102static const struct file_operations hl_stop_on_err_fops = {
1103        .owner = THIS_MODULE,
1104        .read = hl_stop_on_err_read,
1105        .write = hl_stop_on_err_write
1106};
1107
1108static const struct file_operations hl_security_violations_fops = {
1109        .owner = THIS_MODULE,
1110        .read = hl_security_violations_read
1111};
1112
1113static const struct hl_info_list hl_debugfs_list[] = {
1114        {"command_buffers", command_buffers_show, NULL},
1115        {"command_submission", command_submission_show, NULL},
1116        {"command_submission_jobs", command_submission_jobs_show, NULL},
1117        {"userptr", userptr_show, NULL},
1118        {"vm", vm_show, NULL},
1119        {"mmu", mmu_show, mmu_asid_va_write},
1120        {"engines", engines_show, NULL}
1121};
1122
1123static int hl_debugfs_open(struct inode *inode, struct file *file)
1124{
1125        struct hl_debugfs_entry *node = inode->i_private;
1126
1127        return single_open(file, node->info_ent->show, node);
1128}
1129
1130static ssize_t hl_debugfs_write(struct file *file, const char __user *buf,
1131                size_t count, loff_t *f_pos)
1132{
1133        struct hl_debugfs_entry *node = file->f_inode->i_private;
1134
1135        if (node->info_ent->write)
1136                return node->info_ent->write(file, buf, count, f_pos);
1137        else
1138                return -EINVAL;
1139
1140}
1141
1142static const struct file_operations hl_debugfs_fops = {
1143        .owner = THIS_MODULE,
1144        .open = hl_debugfs_open,
1145        .read = seq_read,
1146        .write = hl_debugfs_write,
1147        .llseek = seq_lseek,
1148        .release = single_release,
1149};
1150
1151void hl_debugfs_add_device(struct hl_device *hdev)
1152{
1153        struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
1154        int count = ARRAY_SIZE(hl_debugfs_list);
1155        struct hl_debugfs_entry *entry;
1156        int i;
1157
1158        dev_entry->hdev = hdev;
1159        dev_entry->entry_arr = kmalloc_array(count,
1160                                        sizeof(struct hl_debugfs_entry),
1161                                        GFP_KERNEL);
1162        if (!dev_entry->entry_arr)
1163                return;
1164
1165        dev_entry->blob_desc.size = 0;
1166        dev_entry->blob_desc.data = NULL;
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        debugfs_create_file("dump_security_violations",
1265                                0644,
1266                                dev_entry->root,
1267                                dev_entry,
1268                                &hl_security_violations_fops);
1269
1270        debugfs_create_file("dma_size",
1271                                0200,
1272                                dev_entry->root,
1273                                dev_entry,
1274                                &hl_dma_size_fops);
1275
1276        debugfs_create_blob("data_dma",
1277                                0400,
1278                                dev_entry->root,
1279                                &dev_entry->blob_desc);
1280
1281        debugfs_create_x8("skip_reset_on_timeout",
1282                                0644,
1283                                dev_entry->root,
1284                                &hdev->skip_reset_on_timeout);
1285
1286        for (i = 0, entry = dev_entry->entry_arr ; i < count ; i++, entry++) {
1287                debugfs_create_file(hl_debugfs_list[i].name,
1288                                        0444,
1289                                        dev_entry->root,
1290                                        entry,
1291                                        &hl_debugfs_fops);
1292                entry->info_ent = &hl_debugfs_list[i];
1293                entry->dev_entry = dev_entry;
1294        }
1295}
1296
1297void hl_debugfs_remove_device(struct hl_device *hdev)
1298{
1299        struct hl_dbg_device_entry *entry = &hdev->hl_debugfs;
1300
1301        debugfs_remove_recursive(entry->root);
1302
1303        mutex_destroy(&entry->file_mutex);
1304
1305        vfree(entry->blob_desc.data);
1306
1307        kfree(entry->entry_arr);
1308}
1309
1310void hl_debugfs_add_file(struct hl_fpriv *hpriv)
1311{
1312        struct hl_dbg_device_entry *dev_entry = &hpriv->hdev->hl_debugfs;
1313
1314        mutex_lock(&dev_entry->file_mutex);
1315        list_add(&hpriv->debugfs_list, &dev_entry->file_list);
1316        mutex_unlock(&dev_entry->file_mutex);
1317}
1318
1319void hl_debugfs_remove_file(struct hl_fpriv *hpriv)
1320{
1321        struct hl_dbg_device_entry *dev_entry = &hpriv->hdev->hl_debugfs;
1322
1323        mutex_lock(&dev_entry->file_mutex);
1324        list_del(&hpriv->debugfs_list);
1325        mutex_unlock(&dev_entry->file_mutex);
1326}
1327
1328void hl_debugfs_add_cb(struct hl_cb *cb)
1329{
1330        struct hl_dbg_device_entry *dev_entry = &cb->hdev->hl_debugfs;
1331
1332        spin_lock(&dev_entry->cb_spinlock);
1333        list_add(&cb->debugfs_list, &dev_entry->cb_list);
1334        spin_unlock(&dev_entry->cb_spinlock);
1335}
1336
1337void hl_debugfs_remove_cb(struct hl_cb *cb)
1338{
1339        struct hl_dbg_device_entry *dev_entry = &cb->hdev->hl_debugfs;
1340
1341        spin_lock(&dev_entry->cb_spinlock);
1342        list_del(&cb->debugfs_list);
1343        spin_unlock(&dev_entry->cb_spinlock);
1344}
1345
1346void hl_debugfs_add_cs(struct hl_cs *cs)
1347{
1348        struct hl_dbg_device_entry *dev_entry = &cs->ctx->hdev->hl_debugfs;
1349
1350        spin_lock(&dev_entry->cs_spinlock);
1351        list_add(&cs->debugfs_list, &dev_entry->cs_list);
1352        spin_unlock(&dev_entry->cs_spinlock);
1353}
1354
1355void hl_debugfs_remove_cs(struct hl_cs *cs)
1356{
1357        struct hl_dbg_device_entry *dev_entry = &cs->ctx->hdev->hl_debugfs;
1358
1359        spin_lock(&dev_entry->cs_spinlock);
1360        list_del(&cs->debugfs_list);
1361        spin_unlock(&dev_entry->cs_spinlock);
1362}
1363
1364void hl_debugfs_add_job(struct hl_device *hdev, struct hl_cs_job *job)
1365{
1366        struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
1367
1368        spin_lock(&dev_entry->cs_job_spinlock);
1369        list_add(&job->debugfs_list, &dev_entry->cs_job_list);
1370        spin_unlock(&dev_entry->cs_job_spinlock);
1371}
1372
1373void hl_debugfs_remove_job(struct hl_device *hdev, struct hl_cs_job *job)
1374{
1375        struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
1376
1377        spin_lock(&dev_entry->cs_job_spinlock);
1378        list_del(&job->debugfs_list);
1379        spin_unlock(&dev_entry->cs_job_spinlock);
1380}
1381
1382void hl_debugfs_add_userptr(struct hl_device *hdev, struct hl_userptr *userptr)
1383{
1384        struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
1385
1386        spin_lock(&dev_entry->userptr_spinlock);
1387        list_add(&userptr->debugfs_list, &dev_entry->userptr_list);
1388        spin_unlock(&dev_entry->userptr_spinlock);
1389}
1390
1391void hl_debugfs_remove_userptr(struct hl_device *hdev,
1392                                struct hl_userptr *userptr)
1393{
1394        struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
1395
1396        spin_lock(&dev_entry->userptr_spinlock);
1397        list_del(&userptr->debugfs_list);
1398        spin_unlock(&dev_entry->userptr_spinlock);
1399}
1400
1401void hl_debugfs_add_ctx_mem_hash(struct hl_device *hdev, struct hl_ctx *ctx)
1402{
1403        struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
1404
1405        spin_lock(&dev_entry->ctx_mem_hash_spinlock);
1406        list_add(&ctx->debugfs_list, &dev_entry->ctx_mem_hash_list);
1407        spin_unlock(&dev_entry->ctx_mem_hash_spinlock);
1408}
1409
1410void hl_debugfs_remove_ctx_mem_hash(struct hl_device *hdev, struct hl_ctx *ctx)
1411{
1412        struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
1413
1414        spin_lock(&dev_entry->ctx_mem_hash_spinlock);
1415        list_del(&ctx->debugfs_list);
1416        spin_unlock(&dev_entry->ctx_mem_hash_spinlock);
1417}
1418
1419void __init hl_debugfs_init(void)
1420{
1421        hl_debug_root = debugfs_create_dir("habanalabs", NULL);
1422}
1423
1424void hl_debugfs_fini(void)
1425{
1426        debugfs_remove_recursive(hl_debug_root);
1427}
1428