DRM_DEBUG_DRIVER("IOMMU aperture initialized (%#llx-%#llx)\n",
                                 start, end);
                drm_mm_init(&tegra->mm, start, end - start + 1);
+               mutex_init(&tegra->mm_lock);
        }
 
        mutex_init(&tegra->clients_lock);
        if (tegra->domain) {
                iommu_domain_free(tegra->domain);
                drm_mm_takedown(&tegra->mm);
+               mutex_destroy(&tegra->mm_lock);
        }
 free:
        kfree(tegra);
        if (tegra->domain) {
                iommu_domain_free(tegra->domain);
                drm_mm_takedown(&tegra->mm);
+               mutex_destroy(&tegra->mm_lock);
        }
 
        kfree(tegra);
        struct tegra_drm *tegra = drm->dev_private;
        struct drm_printer p = drm_seq_file_printer(s);
 
+       mutex_lock(&tegra->mm_lock);
        drm_mm_print(&tegra->mm, &p);
+       mutex_unlock(&tegra->mm_lock);
 
        return 0;
 }
 
        if (!bo->mm)
                return -ENOMEM;
 
+       mutex_lock(&tegra->mm_lock);
+
        err = drm_mm_insert_node_generic(&tegra->mm,
                                         bo->mm, bo->gem.size, PAGE_SIZE, 0, 0);
        if (err < 0) {
                dev_err(tegra->drm->dev, "out of I/O virtual memory: %zd\n",
                        err);
-               goto free;
+               goto unlock;
        }
 
        bo->paddr = bo->mm->start;
 
        bo->size = err;
 
+       mutex_unlock(&tegra->mm_lock);
+
        return 0;
 
 remove:
        drm_mm_remove_node(bo->mm);
-free:
+unlock:
+       mutex_unlock(&tegra->mm_lock);
        kfree(bo->mm);
        return err;
 }
        if (!bo->mm)
                return 0;
 
+       mutex_lock(&tegra->mm_lock);
        iommu_unmap(tegra->domain, bo->paddr, bo->size);
        drm_mm_remove_node(bo->mm);
+       mutex_unlock(&tegra->mm_lock);
+
        kfree(bo->mm);
 
        return 0;