Skip to content

Commit 15097e9

Browse files
Farah-kassabrigregkh
authored andcommitted
habanalabs: fix debugfs address translation
when user uses virtual addresses to access dram through debugfs, driver translate this address to physical and use it for the access through the pcie bar. in case dram page size is different than the dmmu page size, we need to have special treatment for adding the page offset to the actual address, which is to use the dram page size mask to fetch the page offset from the virtual address, instead of the dmmu last hop shift. Signed-off-by: farah kassabri <fkassabri@habana.ai> Reviewed-by: Oded Gabbay <ogabbay@kernel.org> Signed-off-by: Oded Gabbay <ogabbay@kernel.org>
1 parent ffd123f commit 15097e9

1 file changed

Lines changed: 26 additions & 12 deletions

File tree

  • drivers/misc/habanalabs/common/mmu

drivers/misc/habanalabs/common/mmu/mmu.c

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -499,18 +499,32 @@ static void hl_mmu_pa_page_with_offset(struct hl_ctx *ctx, u64 virt_addr,
499499
else /* HL_VA_RANGE_TYPE_DRAM */
500500
p = &prop->dmmu;
501501

502-
/*
503-
* find the correct hop shift field in hl_mmu_properties structure
504-
* in order to determine the right maks for the page offset.
505-
*/
506-
hop0_shift_off = offsetof(struct hl_mmu_properties, hop0_shift);
507-
p = (char *)p + hop0_shift_off;
508-
p = (char *)p + ((hops->used_hops - 1) * sizeof(u64));
509-
hop_shift = *(u64 *)p;
510-
offset_mask = (1ull << hop_shift) - 1;
511-
addr_mask = ~(offset_mask);
512-
*phys_addr = (tmp_phys_addr & addr_mask) |
513-
(virt_addr & offset_mask);
502+
if ((hops->range_type == HL_VA_RANGE_TYPE_DRAM) &&
503+
!is_power_of_2(prop->dram_page_size)) {
504+
u32 bit;
505+
u64 page_offset_mask;
506+
u64 phys_addr_mask;
507+
508+
bit = __ffs64((u64)prop->dram_page_size);
509+
page_offset_mask = ((1ull << bit) - 1);
510+
phys_addr_mask = ~page_offset_mask;
511+
*phys_addr = (tmp_phys_addr & phys_addr_mask) |
512+
(virt_addr & page_offset_mask);
513+
} else {
514+
/*
515+
* find the correct hop shift field in hl_mmu_properties
516+
* structure in order to determine the right masks
517+
* for the page offset.
518+
*/
519+
hop0_shift_off = offsetof(struct hl_mmu_properties, hop0_shift);
520+
p = (char *)p + hop0_shift_off;
521+
p = (char *)p + ((hops->used_hops - 1) * sizeof(u64));
522+
hop_shift = *(u64 *)p;
523+
offset_mask = (1ull << hop_shift) - 1;
524+
addr_mask = ~(offset_mask);
525+
*phys_addr = (tmp_phys_addr & addr_mask) |
526+
(virt_addr & offset_mask);
527+
}
514528
}
515529

516530
int hl_mmu_va_to_pa(struct hl_ctx *ctx, u64 virt_addr, u64 *phys_addr)

0 commit comments

Comments
 (0)