diff options
Diffstat (limited to 'meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/1561-drm-amdkfd-initial-implementation-of-handle-based-IP.patch')
-rw-r--r-- | meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/1561-drm-amdkfd-initial-implementation-of-handle-based-IP.patch | 690 |
1 files changed, 0 insertions, 690 deletions
diff --git a/meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/1561-drm-amdkfd-initial-implementation-of-handle-based-IP.patch b/meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/1561-drm-amdkfd-initial-implementation-of-handle-based-IP.patch deleted file mode 100644 index ca0a437f..00000000 --- a/meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/1561-drm-amdkfd-initial-implementation-of-handle-based-IP.patch +++ /dev/null @@ -1,690 +0,0 @@ -From 67115bb6b36683f65f4baf1c3e4c47b6799bd663 Mon Sep 17 00:00:00 2001 -From: Harish Kasiviswanathan <Harish.Kasiviswanathan@amd.com> -Date: Sun, 20 Nov 2016 10:14:05 -0500 -Subject: [PATCH 1561/4131] drm/amdkfd: initial implementation of handle based - IPC - -To implement IPC support for legacy compute APIs, we need a handle based -sharing interface. The interfaces are incompatible with DMABUF, which -would be preferable for enhanced security (explicit sharing, and no -extra code for handle management that increases the attack vectors). - -The handles are 128bit wide to prevent inter-process snooping. - -The buffer lifetime is refcounted. As long as one process maintains a -reference to the buffer, the handle and the memory will be valid. - -Change-Id: I9f9b8e149eb1c540f6b1ef6429e56bf9533f0a9a -Signed-off-by: Harish Kasiviswanathan <Harish.Kasiviswanathan@amd.com> ---- - drivers/gpu/drm/amd/amdkfd/Makefile | 2 +- - drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 87 +++++--- - drivers/gpu/drm/amd/amdkfd/kfd_ipc.c | 331 +++++++++++++++++++++++++++++++ - drivers/gpu/drm/amd/amdkfd/kfd_ipc.h | 52 +++++ - drivers/gpu/drm/amd/amdkfd/kfd_module.c | 4 + - drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 9 +- - drivers/gpu/drm/amd/amdkfd/kfd_process.c | 10 +- - 7 files changed, 459 insertions(+), 36 deletions(-) - create mode 100644 drivers/gpu/drm/amd/amdkfd/kfd_ipc.c - create mode 100644 drivers/gpu/drm/amd/amdkfd/kfd_ipc.h - -diff --git a/drivers/gpu/drm/amd/amdkfd/Makefile b/drivers/gpu/drm/amd/amdkfd/Makefile -index 8f3cbf6..84646ed 100644 ---- a/drivers/gpu/drm/amd/amdkfd/Makefile -+++ b/drivers/gpu/drm/amd/amdkfd/Makefile -@@ -17,7 +17,7 @@ amdkfd-y := kfd_module.o kfd_device.o kfd_chardev.o kfd_topology.o \ - kfd_device_queue_manager_cik.o kfd_device_queue_manager_vi.o \ - kfd_interrupt.o kfd_events.o cik_event_interrupt.o \ - kfd_dbgdev.o kfd_dbgmgr.o kfd_flat_memory.o kfd_crat.o kfd_rdma.o \ -- kfd_peerdirect.o -+ kfd_peerdirect.o kfd_ipc.o - - amdkfd-$(CONFIG_DEBUG_FS) += kfd_debugfs.o - -diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c -index f28b1c3..e664471 100644 ---- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c -+++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c -@@ -37,6 +37,7 @@ - #include "kfd_priv.h" - #include "kfd_device_queue_manager.h" - #include "kfd_dbgmgr.h" -+#include "kfd_ipc.h" - #include "cik_regs.h" - - static long kfd_ioctl(struct file *, unsigned int, unsigned long); -@@ -1179,7 +1180,7 @@ static int kfd_ioctl_alloc_memory_of_gpu(struct file *filep, - - down_write(&p->lock); - idr_handle = kfd_process_device_create_obj_handle(pdd, mem, -- args->va_addr, args->size); -+ args->va_addr, args->size, NULL); - up_write(&p->lock); - if (idr_handle < 0) { - dev->kfd2kgd->free_memory_of_gpu(dev->kgd, -@@ -1320,7 +1321,7 @@ static int kfd_ioctl_alloc_memory_of_gpu_new(struct file *filep, - - down_write(&p->lock); - idr_handle = kfd_process_device_create_obj_handle(pdd, mem, -- args->va_addr, args->size); -+ args->va_addr, args->size, NULL); - up_write(&p->lock); - if (idr_handle < 0) { - dev->kfd2kgd->free_memory_of_gpu(dev->kgd, -@@ -1671,7 +1672,7 @@ static int kfd_ioctl_open_graphic_handle(struct file *filep, - * the corresponding interval tree. We need to know the size of - * the buffer through open_graphic_handle(). We use 1 for now.*/ - idr_handle = kfd_process_device_create_obj_handle(pdd, mem, -- args->va_addr, 1); -+ args->va_addr, 1, NULL); - up_write(&p->lock); - if (idr_handle < 0) { - /* FIXME: destroy_process_gpumem doesn't seem to be -@@ -1776,47 +1777,62 @@ static int kfd_ioctl_get_dmabuf_info(struct file *filep, - } - - static int kfd_ioctl_import_dmabuf(struct file *filep, -- struct kfd_process *p, void *data) -+ struct kfd_process *p, void *data) - { - struct kfd_ioctl_import_dmabuf_args *args = data; - struct kfd_dev *dev; -- struct kfd_process_device *pdd; -- void *mem; -- uint64_t size; -- int idr_handle; - int r; - - dev = kfd_device_by_id(args->gpu_id); -- if (!dev || !dev->kfd2kgd->import_dmabuf) -+ if (!dev) - return -EINVAL; - -- down_write(&p->lock); -- pdd = kfd_bind_process_to_device(dev, p); -- up_write(&p->lock); -- if (IS_ERR(pdd) < 0) -- return PTR_ERR(pdd); -+ r = kfd_ipc_import_dmabuf(dev, p, args->gpu_id, args->dmabuf_fd, -+ args->va_addr, &args->handle, NULL); -+ if (r) -+ dev_err(kfd_device, "Failed to import dmabuf\n"); -+ -+ return r; -+} -+ -+static int kfd_ioctl_ipc_export_handle(struct file *filep, -+ struct kfd_process *p, -+ void *data) -+{ -+ struct kfd_ioctl_ipc_export_handle_args *args = data; -+ struct kfd_dev *dev; -+ int r; - -- r = dev->kfd2kgd->import_dmabuf(dev->kgd, args->dmabuf_fd, -- args->va_addr, pdd->vm, -- (struct kgd_mem **)&mem, &size, -- NULL); -+ dev = kfd_device_by_id(args->gpu_id); -+ if (!dev) -+ return -EINVAL; -+ -+ r = kfd_ipc_export_as_handle(dev, p, args->handle, args->share_handle); - if (r) -- return r; -+ dev_err(kfd_device, "Failed to export IPC handle\n"); - -- down_write(&p->lock); -- idr_handle = kfd_process_device_create_obj_handle(pdd, mem, -- args->va_addr, size); -- up_write(&p->lock); -- if (idr_handle < 0) { -- dev->kfd2kgd->free_memory_of_gpu(dev->kgd, -- (struct kgd_mem *)mem, -- pdd->vm); -- return -EFAULT; -- } -+ return r; -+} - -- args->handle = MAKE_HANDLE(args->gpu_id, idr_handle); -+static int kfd_ioctl_ipc_import_handle(struct file *filep, -+ struct kfd_process *p, -+ void *data) -+{ -+ struct kfd_ioctl_ipc_import_handle_args *args = data; -+ struct kfd_dev *dev = NULL; -+ int r; - -- return 0; -+ dev = kfd_device_by_id(args->gpu_id); -+ if (!dev) -+ return -EINVAL; -+ -+ r = kfd_ipc_import_handle(dev, p, args->gpu_id, args->share_handle, -+ args->va_addr, &args->handle, -+ &args->mmap_offset); -+ if (r) -+ dev_err(kfd_device, "Failed to import IPC handle\n"); -+ -+ return r; - } - - static int kfd_ioctl_get_tile_config(struct file *filep, -@@ -1958,7 +1974,14 @@ static const struct amdkfd_ioctl_desc amdkfd_ioctls[] = { - kfd_ioctl_import_dmabuf, 0), - - AMDKFD_IOCTL_DEF(AMDKFD_IOC_GET_TILE_CONFIG, -- kfd_ioctl_get_tile_config, 0) -+ kfd_ioctl_get_tile_config, 0), -+ -+ AMDKFD_IOCTL_DEF(AMDKFD_IOC_IPC_IMPORT_HANDLE, -+ kfd_ioctl_ipc_import_handle, 0), -+ -+ AMDKFD_IOCTL_DEF(AMDKFD_IOC_IPC_EXPORT_HANDLE, -+ kfd_ioctl_ipc_export_handle, 0) -+ - }; - - #define AMDKFD_CORE_IOCTL_COUNT ARRAY_SIZE(amdkfd_ioctls) -diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_ipc.c b/drivers/gpu/drm/amd/amdkfd/kfd_ipc.c -new file mode 100644 -index 0000000..edd2d43 ---- /dev/null -+++ b/drivers/gpu/drm/amd/amdkfd/kfd_ipc.c -@@ -0,0 +1,331 @@ -+/* -+ * Copyright 2014 Advanced Micro Devices, Inc. -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+ -+#include <linux/dma-buf.h> -+#include <linux/assoc_array.h> -+#include <linux/slab.h> -+#include <linux/random.h> -+ -+#include "kfd_ipc.h" -+#include "kfd_priv.h" -+ -+/** -+ * The assoc_array data structure provides a non-intrusive -+ * key-value data store mechanism where the key can be -+ * arbitratily long (and value is just a void*). -+ * -+ * This provides us good control for managing IPC handle length -+ * in case we require extra entropy to discourage handle-guessing. -+ */ -+static struct assoc_array ipc_handles; -+ -+static unsigned long ipc_get_key_chunk(const void *index_key, int level) -+{ -+ unsigned long chunk; -+ int index = level/ASSOC_ARRAY_KEY_CHUNK_SIZE; -+ -+ /* no more data, but we can't fail */ -+ if (level > IPC_KEY_SIZE_BYTES*8) -+ return 0; -+ -+ chunk = ((unsigned long *)index_key)[index]; -+ return chunk; -+} -+ -+static unsigned long ipc_get_object_key_chunk(const void *object, int level) -+{ -+ const struct kfd_ipc_obj *obj = (const struct kfd_ipc_obj *)object; -+ -+ return ipc_get_key_chunk(&obj->key, level); -+} -+ -+static bool ipc_compare_object(const void *object, const void *index_key) -+{ -+ const struct kfd_ipc_obj *obj = (const struct kfd_ipc_obj *)object; -+ -+ return memcmp(obj->key, index_key, IPC_KEY_SIZE_BYTES) == 0; -+} -+ -+/* -+ * Compare the index keys of a pair of objects and determine the bit position -+ * at which they differ - if they differ. -+ */ -+static int ipc_diff_objects(const void *object, const void *index_key) -+{ -+ const struct kfd_ipc_obj *obj = (const struct kfd_ipc_obj *)object; -+ int i; -+ -+ /* naive linear byte search */ -+ for (i = 0; i < IPC_KEY_SIZE_BYTES; ++i) { -+ if (obj->key[i] != ((char *)index_key)[i]) -+ return i * 8; -+ } -+ -+ return -1; -+} -+ -+/* -+ * Free an object after stripping the ipc flag off of the pointer. -+ */ -+static void ipc_free_object(void *object) -+{ -+} -+ -+/* -+ * Operations for ipc management by the index-tree routines. -+ */ -+static const struct assoc_array_ops ipc_assoc_array_ops = { -+ .get_key_chunk = ipc_get_key_chunk, -+ .get_object_key_chunk = ipc_get_object_key_chunk, -+ .compare_object = ipc_compare_object, -+ .diff_objects = ipc_diff_objects, -+ .free_object = ipc_free_object, -+}; -+ -+static void ipc_gen_key(void *buf) -+{ -+ uint32_t *key = (uint32_t *) buf; -+ -+ get_random_bytes(buf, IPC_KEY_SIZE_BYTES); -+ -+ /* last byte of the key is reserved */ -+ key[3] = (key[3] & ~0xFF) | 0x1; -+} -+ -+static int ipc_store_insert(void *val, void *key, struct kfd_ipc_obj **ipc_obj) -+{ -+ struct kfd_ipc_obj *obj; -+ struct assoc_array_edit *edit; -+ -+ obj = kmalloc(sizeof(struct kfd_ipc_obj), GFP_KERNEL); -+ if (!obj) -+ return -ENOMEM; -+ -+ /* The initial ref belongs to the allocator process. -+ * The IPC object store itself does not hold a ref since -+ * there is no specific moment in time where that ref should -+ * be dropped, except "when there are no more userspace processes -+ * holding a ref to the object". Therefore the removal from IPC -+ * storage happens at ipc_obj release time. -+ */ -+ kref_init(&obj->ref); -+ obj->data = val; -+ ipc_gen_key(obj->key); -+ -+ memcpy(key, obj->key, IPC_KEY_SIZE_BYTES); -+ -+ pr_debug("ipc: val::%p ref:%p\n", val, &obj->ref); -+ -+ edit = assoc_array_insert(&ipc_handles, -+ &ipc_assoc_array_ops, -+ obj->key, obj); -+ assoc_array_apply_edit(edit); -+ -+ if (ipc_obj) -+ *ipc_obj = obj; -+ -+ return 0; -+} -+ -+static int ipc_store_remove(void *key) -+{ -+ struct assoc_array_edit *edit; -+ -+ edit = assoc_array_delete(&ipc_handles, &ipc_assoc_array_ops, key); -+ assoc_array_apply_edit(edit); -+ return 0; -+} -+ -+static void ipc_obj_release(struct kref *r) -+{ -+ struct kfd_ipc_obj *obj; -+ -+ obj = container_of(r, struct kfd_ipc_obj, ref); -+ -+ ipc_store_remove(obj->key); -+ dma_buf_put(obj->data); -+ kfree(obj); -+} -+ -+void ipc_obj_get(struct kfd_ipc_obj *obj) -+{ -+ kref_get(&obj->ref); -+} -+ -+void ipc_obj_put(struct kfd_ipc_obj **obj) -+{ -+ kref_put(&(*obj)->ref, ipc_obj_release); -+ *obj = NULL; -+} -+ -+int kfd_ipc_init(void) -+{ -+ assoc_array_init(&ipc_handles); -+ return 0; -+} -+ -+static int kfd_import_dmabuf_create_kfd_bo(struct kfd_dev *dev, -+ struct kfd_process *p, -+ uint32_t gpu_id, int dmabuf_fd, -+ uint64_t va_addr, uint64_t *handle, -+ uint64_t *mmap_offset, -+ struct kfd_ipc_obj *ipc_obj) -+{ -+ int r; -+ void *mem; -+ uint64_t size; -+ int idr_handle; -+ struct kfd_process_device *pdd = NULL; -+ uint64_t kfd_mmap_flags = KFD_MMAP_TYPE_MAP_BO | -+ KFD_MMAP_GPU_ID(gpu_id); -+ -+ if (!handle) -+ return -EINVAL; -+ -+ if (!dev || !dev->kfd2kgd->import_dmabuf) -+ return -EINVAL; -+ -+ down_write(&p->lock); -+ pdd = kfd_bind_process_to_device(dev, p); -+ up_write(&p->lock); -+ if (IS_ERR(pdd) < 0) -+ return PTR_ERR(pdd); -+ -+ r = dev->kfd2kgd->import_dmabuf(dev->kgd, dmabuf_fd, -+ va_addr, pdd->vm, -+ (struct kgd_mem **)&mem, &size, -+ mmap_offset); -+ if (r) -+ return r; -+ -+ down_write(&p->lock); -+ idr_handle = kfd_process_device_create_obj_handle(pdd, mem, -+ va_addr, size, -+ ipc_obj); -+ up_write(&p->lock); -+ if (idr_handle < 0) { -+ dev->kfd2kgd->free_memory_of_gpu(dev->kgd, -+ (struct kgd_mem *)mem, -+ pdd->vm); -+ return -EFAULT; -+ } -+ -+ *handle = MAKE_HANDLE(gpu_id, idr_handle); -+ -+ if (mmap_offset) -+ *mmap_offset = (kfd_mmap_flags << PAGE_SHIFT) | *mmap_offset; -+ -+ return r; -+} -+ -+int kfd_ipc_import_dmabuf(struct kfd_dev *dev, -+ struct kfd_process *p, -+ uint32_t gpu_id, int dmabuf_fd, -+ uint64_t va_addr, uint64_t *handle, -+ uint64_t *mmap_offset) -+{ -+ return kfd_import_dmabuf_create_kfd_bo(dev, p, gpu_id, dmabuf_fd, -+ va_addr, handle, mmap_offset, -+ NULL); -+} -+ -+int kfd_ipc_import_handle(struct kfd_dev *dev, struct kfd_process *p, -+ uint32_t gpu_id, uint32_t *share_handle, -+ uint64_t va_addr, uint64_t *handle, -+ uint64_t *mmap_offset) -+{ -+ int r; -+ int dmabuf_fd; -+ struct kfd_ipc_obj *found; -+ -+ found = assoc_array_find(&ipc_handles, -+ &ipc_assoc_array_ops, -+ share_handle); -+ if (!found) -+ return -EINVAL; -+ ipc_obj_get(found); -+ -+ pr_debug("ipc: found ipc_dma_buf: %p\n", found->data); -+ -+ dmabuf_fd = dma_buf_fd(found->data, 0); -+ r = kfd_import_dmabuf_create_kfd_bo(dev, p, gpu_id, dmabuf_fd, -+ va_addr, handle, mmap_offset, -+ found); -+ if (r) -+ goto error_unref; -+ -+ return r; -+ -+error_unref: -+ ipc_obj_put(&found); -+ return r; -+} -+ -+int kfd_ipc_export_as_handle(struct kfd_dev *dev, struct kfd_process *p, -+ uint64_t handle, uint32_t *ipc_handle) -+{ -+ struct kfd_process_device *pdd = NULL; -+ struct kfd_ipc_obj *obj; -+ struct kfd_bo *kfd_bo = NULL; -+ int dmabuf_fd; -+ int r; -+ -+ if (!dev || !ipc_handle) -+ return -EINVAL; -+ -+ down_write(&p->lock); -+ pdd = kfd_bind_process_to_device(dev, p); -+ up_write(&p->lock); -+ -+ if (IS_ERR(pdd) < 0) { -+ pr_err("failed to get pdd\n"); -+ return PTR_ERR(pdd); -+ } -+ -+ down_write(&p->lock); -+ kfd_bo = kfd_process_device_find_bo(pdd, GET_IDR_HANDLE(handle)); -+ up_write(&p->lock); -+ -+ if (!kfd_bo) { -+ pr_err("failed to get bo"); -+ return -EINVAL; -+ } -+ if (kfd_bo->kfd_ipc_obj) { -+ memcpy(ipc_handle, kfd_bo->kfd_ipc_obj->key, -+ sizeof(kfd_bo->kfd_ipc_obj->key)); -+ return 0; -+ } -+ -+ r = dev->kfd2kgd->export_dmabuf(dev->kgd, pdd->vm, -+ (struct kgd_mem *)kfd_bo->mem, -+ &dmabuf_fd); -+ if (r) -+ goto err; -+ -+ r = ipc_store_insert(dma_buf_get(dmabuf_fd), ipc_handle, &obj); -+ if (r) -+ goto err; -+ -+ kfd_bo->kfd_ipc_obj = obj; -+err: -+ return r; -+} -diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_ipc.h b/drivers/gpu/drm/amd/amdkfd/kfd_ipc.h -new file mode 100644 -index 0000000..52049d2 ---- /dev/null -+++ b/drivers/gpu/drm/amd/amdkfd/kfd_ipc.h -@@ -0,0 +1,52 @@ -+/* -+ * Copyright 2014 Advanced Micro Devices, Inc. -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ * -+ */ -+ -+#ifndef KFD_IPC_H_ -+#define KFD_IPC_H_ -+ -+#include <linux/types.h> -+#include "kfd_priv.h" -+ -+#define IPC_KEY_SIZE_BYTES 16 -+ -+struct kfd_ipc_obj { -+ struct kref ref; -+ void *data; -+ char key[IPC_KEY_SIZE_BYTES]; -+}; -+ -+int kfd_ipc_import_handle(struct kfd_dev *dev, struct kfd_process *p, -+ uint32_t gpu_id, uint32_t *share_handle, -+ uint64_t va_addr, uint64_t *handle, -+ uint64_t *mmap_offset); -+int kfd_ipc_import_dmabuf(struct kfd_dev *kfd, struct kfd_process *p, -+ uint32_t gpu_id, int dmabuf_fd, -+ uint64_t va_addr, uint64_t *handle, -+ uint64_t *mmap_offset); -+int kfd_ipc_export_as_handle(struct kfd_dev *dev, struct kfd_process *p, -+ uint64_t handle, uint32_t *ipc_handle); -+ -+void ipc_obj_get(struct kfd_ipc_obj *obj); -+void ipc_obj_put(struct kfd_ipc_obj **obj); -+ -+#endif /* KFD_IPC_H_ */ -diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_module.c b/drivers/gpu/drm/amd/amdkfd/kfd_module.c -index ca82a02..274312f 100644 ---- a/drivers/gpu/drm/amd/amdkfd/kfd_module.c -+++ b/drivers/gpu/drm/amd/amdkfd/kfd_module.c -@@ -133,6 +133,10 @@ static int __init kfd_module_init(void) - if (err < 0) - goto err_topology; - -+ err = kfd_ipc_init(); -+ if (err < 0) -+ goto err_topology; -+ - kfd_process_create_wq(); - - kfd_init_peer_direct(); -diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h -index d96d256..40dd5db 100644 ---- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h -+++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h -@@ -280,11 +280,14 @@ struct kfd_dev { - uint32_t ib_size; - }; - -+struct kfd_ipc_obj; -+ - struct kfd_bo { - void *mem; - struct interval_tree_node it; - struct kfd_dev *dev; - struct list_head cb_data_head; -+ struct kfd_ipc_obj *kfd_ipc_obj; - }; - - /* KGD2KFD callbacks */ -@@ -729,7 +732,8 @@ int kfd_reserved_mem_mmap(struct kfd_process *process, struct vm_area_struct *vm - /* KFD process API for creating and translating handles */ - int kfd_process_device_create_obj_handle(struct kfd_process_device *pdd, - void *mem, uint64_t start, -- uint64_t length); -+ uint64_t length, -+ struct kfd_ipc_obj *ipc_obj); - void *kfd_process_device_translate_handle(struct kfd_process_device *p, - int handle); - struct kfd_bo *kfd_process_device_find_bo(struct kfd_process_device *pdd, -@@ -964,6 +968,9 @@ int dbgdev_wave_reset_wavefronts(struct kfd_dev *dev, struct kfd_process *p); - void kfd_init_peer_direct(void); - void kfd_close_peer_direct(void); - -+/* IPC Support */ -+int kfd_ipc_init(void); -+ - /* Debugfs */ - #if defined(CONFIG_DEBUG_FS) - -diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c -index fa13696..63e85de 100644 ---- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c -+++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c -@@ -32,6 +32,7 @@ - #include <asm/tlb.h> - #include <linux/highmem.h> - #include <uapi/asm-generic/mman-common.h> -+#include "kfd_ipc.h" - - struct mm_struct; - -@@ -118,7 +119,7 @@ static int kfd_process_alloc_gpuvm(struct kfd_process *p, - * created and the ioctls have not had the chance to run. - */ - if (kfd_process_device_create_obj_handle( -- pdd, mem, gpu_va, size) < 0) { -+ pdd, mem, gpu_va, size, NULL) < 0) { - err = -ENOMEM; - *kptr = NULL; - goto free_gpuvm; -@@ -803,7 +804,8 @@ bool kfd_has_process_device_data(struct kfd_process *p) - * Assumes that the process lock is held. */ - int kfd_process_device_create_obj_handle(struct kfd_process_device *pdd, - void *mem, uint64_t start, -- uint64_t length) -+ uint64_t length, -+ struct kfd_ipc_obj *ipc_obj) - { - int handle; - struct kfd_bo *buf_obj; -@@ -825,6 +827,7 @@ int kfd_process_device_create_obj_handle(struct kfd_process_device *pdd, - - buf_obj->mem = mem; - buf_obj->dev = pdd->dev; -+ buf_obj->kfd_ipc_obj = ipc_obj; - - INIT_LIST_HEAD(&buf_obj->cb_data_head); - -@@ -904,6 +907,9 @@ void kfd_process_device_remove_obj_handle(struct kfd_process_device *pdd, - - buf_obj = kfd_process_device_find_bo(pdd, handle); - -+ if (buf_obj->kfd_ipc_obj) -+ ipc_obj_put(&buf_obj->kfd_ipc_obj); -+ - idr_remove(&pdd->alloc_idr, handle); - - interval_tree_remove(&buf_obj->it, &p->bo_interval_tree); --- -2.7.4 - |