drivers/accel/habanalabs/common/mmu/mmu.c
Source file repositories/reference/linux-study-clean/drivers/accel/habanalabs/common/mmu/mmu.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/accel/habanalabs/common/mmu/mmu.c- Extension
.c- Size
- 39812 bytes
- Lines
- 1435
- Domain
- Driver Families
- Bucket
- drivers/accel
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/slab.hlinux/pci.h../habanalabs.htrace/events/habanalabs.h
Detected Declarations
function hl_mmu_get_funcsfunction hl_is_dram_vafunction hl_mmu_initfunction hl_mmu_finifunction hl_mmu_ctx_initfunction hl_mmu_ctx_finifunction hl_mmu_get_real_page_sizefunction hl_mmu_unmap_pagefunction hl_mmu_map_pagefunction hl_mmu_map_contiguousfunction hl_mmu_unmap_contiguousfunction hl_mmu_pa_page_with_offsetfunction hl_mmu_va_to_pafunction hl_mmu_get_tlb_infofunction hl_mmu_if_set_funcsfunction hl_mmu_scramble_addrfunction hl_mmu_descramble_addrfunction hl_mmu_invalidate_cachefunction hl_mmu_invalidate_cache_rangefunction hl_mmu_prefetch_work_functionfunction hl_mmu_prefetch_cache_rangefunction hl_mmu_get_next_hop_addrfunction hl_mmu_get_hop_pte_phys_addrfunction mmu_dma_mem_free_from_chunkfunction hl_mmu_hr_flushfunction hl_mmu_hr_pool_destroyfunction hl_mmu_hr_initfunction hl_mmu_hr_finifunction hl_mmu_hr_free_hop_remove_pgtfunction hl_mmu_hr_pte_phys_to_virtfunction hl_mmu_hr_write_ptefunction hl_mmu_hr_clear_ptefunction hl_mmu_hr_put_ptefunction hl_mmu_hr_get_ptefunction hl_mmu_hr_get_next_hop_pgt_infofunction hl_mmu_hr_alloc_hopfunction hl_mmu_hr_get_alloc_next_hopfunction hl_mmu_hr_get_tlb_infofunction hl_mmu_dr_free_hopfunction hl_mmu_dr_free_pgt_nodefunction hl_mmu_dr_get_phys_hop0_addrfunction hl_mmu_dr_get_hop0_addrfunction hl_mmu_dr_get_phys_addrfunction hl_mmu_dr_write_ptefunction hl_mmu_dr_write_final_ptefunction hl_mmu_dr_clear_ptefunction hl_mmu_dr_get_ptefunction hl_mmu_dr_put_pte
Annotated Snippet
if (rc) {
dev_err(hdev->dev,
"Map failed for va 0x%llx to pa 0x%llx\n",
curr_va, curr_pa);
/* last mapping failed so don't try to unmap it - reduce off by page_size */
off -= page_size;
goto unmap;
}
}
return rc;
unmap:
for (; off >= 0 ; off -= page_size) {
curr_va = virt_addr + off;
flush_pte = (off - (s32) page_size) < 0;
if (hl_mmu_unmap_page(ctx, curr_va, page_size, flush_pte))
dev_warn_ratelimited(hdev->dev,
"failed to unmap va 0x%llx\n", curr_va);
}
return rc;
}
/*
* hl_mmu_unmap_contiguous - implements a wrapper for hl_mmu_unmap_page
* for unmapping contiguous physical memory
*
* @ctx: pointer to the context structure
* @virt_addr: virt addr to unmap
* @size: size to unmap
*
*/
int hl_mmu_unmap_contiguous(struct hl_ctx *ctx, u64 virt_addr, u32 size)
{
struct hl_device *hdev = ctx->hdev;
struct asic_fixed_properties *prop = &hdev->asic_prop;
u64 curr_va;
u32 page_size;
bool flush_pte;
int rc = 0, off;
if (hl_mem_area_inside_range(virt_addr, size,
prop->dmmu.start_addr, prop->dmmu.end_addr))
page_size = prop->dmmu.page_size;
else if (hl_mem_area_inside_range(virt_addr, size,
prop->pmmu.start_addr, prop->pmmu.end_addr))
page_size = prop->pmmu.page_size;
else if (hl_mem_area_inside_range(virt_addr, size,
prop->pmmu_huge.start_addr, prop->pmmu_huge.end_addr))
page_size = prop->pmmu_huge.page_size;
else
return -EINVAL;
for (off = 0 ; off < size ; off += page_size) {
curr_va = virt_addr + off;
flush_pte = (off + page_size) >= size;
rc = hl_mmu_unmap_page(ctx, curr_va, page_size, flush_pte);
if (rc)
dev_warn_ratelimited(hdev->dev,
"Unmap failed for va 0x%llx\n", curr_va);
}
return rc;
}
static void hl_mmu_pa_page_with_offset(struct hl_ctx *ctx, u64 virt_addr,
struct hl_mmu_hop_info *hops,
u64 *phys_addr)
{
struct asic_fixed_properties *prop = &ctx->hdev->asic_prop;
u64 offset_mask, addr_mask, hop_shift, tmp_phys_addr;
struct hl_mmu_properties *mmu_prop;
/* last hop holds the phys address and flags */
if (hops->unscrambled_paddr)
tmp_phys_addr = hops->unscrambled_paddr;
else
tmp_phys_addr = hops->hop_info[hops->used_hops - 1].hop_pte_val;
if (hops->range_type == HL_VA_RANGE_TYPE_HOST_HUGE)
mmu_prop = &prop->pmmu_huge;
else if (hops->range_type == HL_VA_RANGE_TYPE_HOST)
mmu_prop = &prop->pmmu;
else /* HL_VA_RANGE_TYPE_DRAM */
mmu_prop = &prop->dmmu;
if ((hops->range_type == HL_VA_RANGE_TYPE_DRAM) &&
!is_power_of_2(prop->dram_page_size)) {
u64 dram_page_size, dram_base, abs_phys_addr, abs_virt_addr,
Annotation
- Immediate include surface: `linux/slab.h`, `linux/pci.h`, `../habanalabs.h`, `trace/events/habanalabs.h`.
- Detected declarations: `function hl_mmu_get_funcs`, `function hl_is_dram_va`, `function hl_mmu_init`, `function hl_mmu_fini`, `function hl_mmu_ctx_init`, `function hl_mmu_ctx_fini`, `function hl_mmu_get_real_page_size`, `function hl_mmu_unmap_page`, `function hl_mmu_map_page`, `function hl_mmu_map_contiguous`.
- Atlas domain: Driver Families / drivers/accel.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.