diff --git a/include/hsakmt.h b/include/hsakmt.h index ca586ba36b..63ac299511 100644 --- a/include/hsakmt.h +++ b/include/hsakmt.h @@ -436,6 +436,26 @@ hsaKmtRegisterGraphicsHandleToNodes( HSAuint32* NodeArray //IN ); +/** + * Export a dmabuf handle and offset for a given memory address + * + * Validates that @MemoryAddress belongs to a valid allocation and that the + * @MemorySizeInBytes doesn't exceed the end of that allocation. Returns a + * dmabuf fd of the allocation and the offset of MemoryAddress within that + * allocation. The memory will remain allocated even after the allocation is + * freed by hsaKmtFreeMemory for as long as a dmabuf fd remains open or any + * importer of that fd maintains an active reference to the memory. + */ + +HSAKMT_STATUS +HSAKMTAPI +hsaKmtExportDMABufHandle( + void *MemoryAddress, //IN + HSAuint64 MemorySizeInBytes, //IN + int *DMABufFd, //OUT + HSAuint64 *Offset //OUT + ); + /** Export a memory buffer for sharing with other processes diff --git a/include/linux/kfd_ioctl.h b/include/linux/kfd_ioctl.h index 4898451b22..8dc670a4d6 100644 --- a/include/linux/kfd_ioctl.h +++ b/include/linux/kfd_ioctl.h @@ -37,9 +37,10 @@ * - 1.9 - Add available_memory ioctl * - 1.10 - Add SMI profiler event log * - 1.11 - Add unified memory for ctx save/restore area + * - 1.12 - Add DMA buf export ioctl */ #define KFD_IOCTL_MAJOR_VERSION 1 -#define KFD_IOCTL_MINOR_VERSION 11 +#define KFD_IOCTL_MINOR_VERSION 12 /* * Debug revision change log @@ -847,6 +848,12 @@ struct kfd_ioctl_import_dmabuf_args { __u32 dmabuf_fd; /* to KFD */ }; +struct kfd_ioctl_export_dmabuf_args { + __u64 handle; /* to KFD */ + __u32 flags; /* to KFD */ + __u32 dmabuf_fd; /* from KFD */ +}; + /* * KFD SMI(System Management Interface) events */ @@ -1345,8 +1352,11 @@ struct kfd_ioctl_set_xnack_mode_args { #define AMDKFD_IOC_AVAILABLE_MEMORY \ AMDKFD_IOWR(0x23, struct kfd_ioctl_get_available_memory_args) +#define AMDKFD_IOC_EXPORT_DMABUF \ + AMDKFD_IOWR(0x24, struct kfd_ioctl_export_dmabuf_args) + #define AMDKFD_COMMAND_START 0x01 -#define AMDKFD_COMMAND_END 0x24 +#define AMDKFD_COMMAND_END 0x25 /* non-upstream ioctls */ #define AMDKFD_IOC_IPC_IMPORT_HANDLE \ diff --git a/src/fmm.c b/src/fmm.c index 9f099c5a34..774f9e0cab 100644 --- a/src/fmm.c +++ b/src/fmm.c @@ -3309,6 +3309,48 @@ error_free_metadata: return status; } +HSAKMT_STATUS fmm_export_dma_buf_fd(void *MemoryAddress, + HSAuint64 MemorySizeInBytes, + int *DMABufFd, + HSAuint64 *Offset) +{ + struct kfd_ioctl_export_dmabuf_args exportArgs = {0}; + manageable_aperture_t *aperture; + HsaApertureInfo ApeInfo; + vm_object_t *obj; + HSAuint64 offset; + int r; + + aperture = fmm_find_aperture(MemoryAddress, &ApeInfo); + if (!aperture) + return HSAKMT_STATUS_INVALID_PARAMETER; + + pthread_mutex_lock(&aperture->fmm_mutex); + obj = vm_find_object_by_address_range(aperture, MemoryAddress); + if (obj) { + offset = VOID_PTRS_SUB(MemoryAddress, obj->start); + if (offset + MemorySizeInBytes <= obj->size) { + exportArgs.handle = obj->handle; + exportArgs.flags = O_CLOEXEC; + exportArgs.dmabuf_fd = 0; + } else { + obj = NULL; + } + } + pthread_mutex_unlock(&aperture->fmm_mutex); + if (!obj) + return HSAKMT_STATUS_INVALID_PARAMETER; + + r = kmtIoctl(kfd_fd, AMDKFD_IOC_EXPORT_DMABUF, (void *)&exportArgs); + if (r) + return HSAKMT_STATUS_ERROR; + + *DMABufFd = exportArgs.dmabuf_fd; + *Offset = offset; + + return HSAKMT_STATUS_SUCCESS; +} + HSAKMT_STATUS fmm_share_memory(void *MemoryAddress, HSAuint64 SizeInBytes, HsaSharedMemoryHandle *SharedMemoryHandle) diff --git a/src/fmm.h b/src/fmm.h index 498366e7a0..d0146d74cd 100644 --- a/src/fmm.h +++ b/src/fmm.h @@ -78,6 +78,10 @@ HSAKMT_STATUS fmm_register_graphics_handle(HSAuint64 GraphicsResourceHandle, uint32_t *gpu_id_array, uint32_t gpu_id_array_size); HSAKMT_STATUS fmm_deregister_memory(void *address); +HSAKMT_STATUS fmm_export_dma_buf_fd(void *MemoryAddress, + HSAuint64 MemorySizeInBytes, + int *DMABufFd, + HSAuint64 *Offset); HSAKMT_STATUS fmm_share_memory(void *MemoryAddress, HSAuint64 SizeInBytes, HsaSharedMemoryHandle *SharedMemoryHandle); diff --git a/src/libhsakmt.ver b/src/libhsakmt.ver index 46370c6eee..50564de31b 100644 --- a/src/libhsakmt.ver +++ b/src/libhsakmt.ver @@ -70,6 +70,7 @@ hsaKmtSVMGetAttr; hsaKmtSetXNACKMode; hsaKmtGetXNACKMode; hsaKmtOpenSMI; +hsaKmtExportDMABufHandle; local: *; }; diff --git a/src/memory.c b/src/memory.c index 7f8e45b6e0..4cb05057ad 100644 --- a/src/memory.c +++ b/src/memory.c @@ -318,6 +318,20 @@ HSAKMT_STATUS HSAKMTAPI hsaKmtRegisterGraphicsHandleToNodes(HSAuint64 GraphicsRe return ret; } +HSAKMT_STATUS HSAKMTAPI hsaKmtExportDMABufHandle(void *MemoryAddress, + HSAuint64 MemorySizeInBytes, + int *DMABufFd, + HSAuint64 *Offset) +{ + CHECK_KFD_OPEN(); + CHECK_KFD_MINOR_VERSION(12); + + pr_debug("[%s] address %p\n", __func__, MemoryAddress); + + return fmm_export_dma_buf_fd(MemoryAddress, MemorySizeInBytes, + DMABufFd, Offset); +} + HSAKMT_STATUS HSAKMTAPI hsaKmtShareMemory(void *MemoryAddress, HSAuint64 SizeInBytes, HsaSharedMemoryHandle *SharedMemoryHandle)