]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
accel/habanalabs: support mapping cb with vmalloc-backed coherent memory
authorMoti Haimovski <moti.haimovski@intel.com>
Sun, 8 Sep 2024 12:01:26 +0000 (15:01 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 13 Nov 2025 20:37:31 +0000 (15:37 -0500)
[ Upstream commit 513024d5a0e34fd34247043f1876b6138ca52847 ]

When IOMMU is enabled, dma_alloc_coherent() with GFP_USER may return
addresses from the vmalloc range. If such an address is mapped without
VM_MIXEDMAP, vm_insert_page() will trigger a BUG_ON due to the
VM_PFNMAP restriction.

Fix this by checking for vmalloc addresses and setting VM_MIXEDMAP
in the VMA before mapping. This ensures safe mapping and avoids kernel
crashes. The memory is still driver-allocated and cannot be accessed
directly by userspace.

Signed-off-by: Moti Haimovski <moti.haimovski@intel.com>
Reviewed-by: Koby Elbaz <koby.elbaz@intel.com>
Signed-off-by: Koby Elbaz <koby.elbaz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/accel/habanalabs/gaudi/gaudi.c
drivers/accel/habanalabs/gaudi2/gaudi2.c

index fa893a9b826ec4d9e3fc3c867a969a2621ecaf42..34771d75da9d7e233cc6e3007fcca7c174678860 100644 (file)
@@ -4168,10 +4168,29 @@ static int gaudi_mmap(struct hl_device *hdev, struct vm_area_struct *vma,
        vm_flags_set(vma, VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP |
                        VM_DONTCOPY | VM_NORESERVE);
 
+#ifdef _HAS_DMA_MMAP_COHERENT
+       /*
+        * If dma_alloc_coherent() returns a vmalloc address, set VM_MIXEDMAP
+        * so vm_insert_page() can handle it safely. Without this, the kernel
+        * may BUG_ON due to VM_PFNMAP.
+        */
+       if (is_vmalloc_addr(cpu_addr))
+               vm_flags_set(vma, VM_MIXEDMAP);
+
        rc = dma_mmap_coherent(hdev->dev, vma, cpu_addr,
                                (dma_addr - HOST_PHYS_BASE), size);
        if (rc)
                dev_err(hdev->dev, "dma_mmap_coherent error %d", rc);
+#else
+
+       rc = remap_pfn_range(vma, vma->vm_start,
+                               virt_to_phys(cpu_addr) >> PAGE_SHIFT,
+                               size, vma->vm_page_prot);
+       if (rc)
+               dev_err(hdev->dev, "remap_pfn_range error %d", rc);
+
+ #endif
+
 
        return rc;
 }
index 3df72a5d024a6a05663ef56701c7644956cf1879..b957957df3d3a74eaaa2846057cedcfc4fa93d3c 100644 (file)
@@ -6490,6 +6490,13 @@ static int gaudi2_mmap(struct hl_device *hdev, struct vm_area_struct *vma,
                        VM_DONTCOPY | VM_NORESERVE);
 
 #ifdef _HAS_DMA_MMAP_COHERENT
+       /*
+        * If dma_alloc_coherent() returns a vmalloc address, set VM_MIXEDMAP
+        * so vm_insert_page() can handle it safely. Without this, the kernel
+        * may BUG_ON due to VM_PFNMAP.
+        */
+       if (is_vmalloc_addr(cpu_addr))
+               vm_flags_set(vma, VM_MIXEDMAP);
 
        rc = dma_mmap_coherent(hdev->dev, vma, cpu_addr, dma_addr, size);
        if (rc)