summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2024-08-30 04:18:08 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2024-08-30 04:18:08 +0000
commita9d7ba6366d8f58cc4a1ea0ac0362d695eb43e2c (patch)
tree0ab9c3a9537c119df16f79422b6921cb4379233b /sys
parent0f23b77f942621290e4c4156bee968eb6b423dce (diff)
drm/amdkfd: reserve the BO before validating it
From Lang Yu 9b707444bebce5326b8eae5401a2dce55626f8f2 in linux-6.6.y/6.6.48 0c93bd49576677ae1a18817d5ec000ef031d5187 in mainline linux
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/pci/drm/amd/amdgpu/amdgpu_amdkfd.h2
-rw-r--r--sys/dev/pci/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c20
-rw-r--r--sys/dev/pci/drm/amd/amdkfd/kfd_chardev.c4
3 files changed, 21 insertions, 5 deletions
diff --git a/sys/dev/pci/drm/amd/amdgpu/amdgpu_amdkfd.h b/sys/dev/pci/drm/amd/amdgpu/amdgpu_amdkfd.h
index db463d2d6fc..3e166f2bb25 100644
--- a/sys/dev/pci/drm/amd/amdgpu/amdgpu_amdkfd.h
+++ b/sys/dev/pci/drm/amd/amdgpu/amdgpu_amdkfd.h
@@ -303,7 +303,7 @@ int amdgpu_amdkfd_gpuvm_map_memory_to_gpu(struct amdgpu_device *adev,
struct kgd_mem *mem, void *drm_priv);
int amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu(
struct amdgpu_device *adev, struct kgd_mem *mem, void *drm_priv);
-void amdgpu_amdkfd_gpuvm_dmaunmap_mem(struct kgd_mem *mem, void *drm_priv);
+int amdgpu_amdkfd_gpuvm_dmaunmap_mem(struct kgd_mem *mem, void *drm_priv);
int amdgpu_amdkfd_gpuvm_sync_memory(
struct amdgpu_device *adev, struct kgd_mem *mem, bool intr);
int amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(struct kgd_mem *mem,
diff --git a/sys/dev/pci/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/sys/dev/pci/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
index 9fab9940baf..7f904612ea6 100644
--- a/sys/dev/pci/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/sys/dev/pci/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -2038,21 +2038,35 @@ out:
return ret;
}
-void amdgpu_amdkfd_gpuvm_dmaunmap_mem(struct kgd_mem *mem, void *drm_priv)
+int amdgpu_amdkfd_gpuvm_dmaunmap_mem(struct kgd_mem *mem, void *drm_priv)
{
struct kfd_mem_attachment *entry;
struct amdgpu_vm *vm;
+ int ret;
vm = drm_priv_to_vm(drm_priv);
mutex_lock(&mem->lock);
+ ret = amdgpu_bo_reserve(mem->bo, true);
+ if (ret)
+ goto out;
+
list_for_each_entry(entry, &mem->attachments, list) {
- if (entry->bo_va->base.vm == vm)
- kfd_mem_dmaunmap_attachment(mem, entry);
+ if (entry->bo_va->base.vm != vm)
+ continue;
+ if (entry->bo_va->base.bo->tbo.ttm &&
+ !entry->bo_va->base.bo->tbo.ttm->sg)
+ continue;
+
+ kfd_mem_dmaunmap_attachment(mem, entry);
}
+ amdgpu_bo_unreserve(mem->bo);
+out:
mutex_unlock(&mem->lock);
+
+ return ret;
}
int amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu(
diff --git a/sys/dev/pci/drm/amd/amdkfd/kfd_chardev.c b/sys/dev/pci/drm/amd/amdkfd/kfd_chardev.c
index 03a94230e5f..bf9c3dead46 100644
--- a/sys/dev/pci/drm/amd/amdkfd/kfd_chardev.c
+++ b/sys/dev/pci/drm/amd/amdkfd/kfd_chardev.c
@@ -1442,7 +1442,9 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep,
kfd_flush_tlb(peer_pdd, TLB_FLUSH_HEAVYWEIGHT);
/* Remove dma mapping after tlb flush to avoid IO_PAGE_FAULT */
- amdgpu_amdkfd_gpuvm_dmaunmap_mem(mem, peer_pdd->drm_priv);
+ err = amdgpu_amdkfd_gpuvm_dmaunmap_mem(mem, peer_pdd->drm_priv);
+ if (err)
+ goto sync_memory_failed;
}
mutex_unlock(&p->mutex);