diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index bfdd783..370fec9 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1557,6 +1557,7 @@ void clear_thread_tidr(struct task_struct *t)
 	free_thread_tidr(t->thread.tidr);
 	t->thread.tidr = 0;
 }
+EXPORT_SYMBOL_GPL(clear_thread_tidr);
 
 void arch_release_task_struct(struct task_struct *t)
 {
@@ -1583,6 +1584,7 @@ int set_thread_tidr(struct task_struct *t)
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(set_thread_tidr);
 
 #endif /* CONFIG_PPC64 */
 
diff --git a/drivers/misc/cxl/api.c b/drivers/misc/cxl/api.c
index 7c11bad..121bfbc 100644
--- a/drivers/misc/cxl/api.c
+++ b/drivers/misc/cxl/api.c
@@ -684,3 +684,12 @@ void _cxl_cx4_teardown_msi_irqs(struct pci_dev *pdev)
 	}
 }
 /* Exported via cxl_base */
+
+int cxl_thread_tidr(struct cxl_context *ctx, int assign)
+{
+	if (!ctx)
+		return -EINVAL;
+
+	return cxl_context_thread_tidr(ctx, assign);
+}
+EXPORT_SYMBOL_GPL(cxl_thread_tidr);
diff --git a/drivers/misc/cxl/context.c b/drivers/misc/cxl/context.c
index 12a41b2..6fd61a8 100644
--- a/drivers/misc/cxl/context.c
+++ b/drivers/misc/cxl/context.c
@@ -22,6 +22,7 @@
 #include <asm/cputable.h>
 #include <asm/current.h>
 #include <asm/copro.h>
+#include <asm/switch_to.h>
 
 #include "cxl.h"
 
@@ -42,6 +43,7 @@ int cxl_context_init(struct cxl_context *ctx, struct cxl_afu *afu, bool master)
 
 	ctx->afu = afu;
 	ctx->master = master;
+	ctx->tid = 0;
 	ctx->pid = NULL; /* Set in start work ioctl */
 	mutex_init(&ctx->mapping_lock);
 	ctx->mapping = NULL;
@@ -362,3 +364,22 @@ void cxl_context_mm_count_put(struct cxl_context *ctx)
 	if (ctx->mm)
 		mmdrop(ctx->mm);
 }
+
+int cxl_context_thread_tidr(struct cxl_context *ctx, int assign)
+{
+	int rc = 0;
+
+	/* Clear any TIDR value assigned to the current thread */
+	if (!assign) {
+		clear_thread_tidr(current);
+		ctx->tid = 0;
+	} else {
+		/* Assign a unique TIDR (thread id) for the current thread */
+		rc = set_thread_tidr(current);
+		if (!rc)
+			ctx->tid = current->thread.tidr;
+	}
+	pr_devel("%s: current tidr: %d\n", __func__, ctx->tid);
+
+	return rc;
+}
diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h
index e46a406..5f8678f 100644
--- a/drivers/misc/cxl/cxl.h
+++ b/drivers/misc/cxl/cxl.h
@@ -561,6 +561,7 @@ struct cxl_context {
 	unsigned int sst_size, sst_lru;
 
 	wait_queue_head_t wq;
+	u32 tid;
 	/* use mm context associated with this pid for ds faults */
 	struct pid *pid;
 	spinlock_t lock; /* Protects pending_irq_mask, pending_fault and fault_addr */
@@ -1169,4 +1170,9 @@ void cxl_context_mm_count_get(struct cxl_context *ctx);
 /* Decrements the reference count to "struct mm_struct" */
 void cxl_context_mm_count_put(struct cxl_context *ctx);
 
+/* Clear any TIDR value or assign a unique TIDR (thread id) for the
+ * current thread
+ */
+int cxl_context_thread_tidr(struct cxl_context *ctx, int assign);
+
 #endif
diff --git a/drivers/misc/cxl/cxllib.c b/drivers/misc/cxl/cxllib.c
index dc9bc18..126d988 100644
--- a/drivers/misc/cxl/cxllib.c
+++ b/drivers/misc/cxl/cxllib.c
@@ -202,7 +202,7 @@ int cxllib_get_PE_attributes(struct task_struct *task,
 	} else {
 		attr->pid = 0;
 	}
-	attr->tid = 0;
+	attr->tid = current->thread.tidr;
 	return 0;
 }
 EXPORT_SYMBOL_GPL(cxllib_get_PE_attributes);
diff --git a/drivers/misc/cxl/file.c b/drivers/misc/cxl/file.c
index 76c0b0c..f0666ee 100644
--- a/drivers/misc/cxl/file.c
+++ b/drivers/misc/cxl/file.c
@@ -300,6 +300,17 @@ static long afu_ioctl_get_afu_id(struct cxl_context *ctx,
 	return 0;
 }
 
+static long afu_ioctl_thread_tidr(struct cxl_context *ctx,
+				  int __user *uassign)
+{
+	int assign;
+
+	if (copy_from_user(&assign, uassign, sizeof(assign)))
+		return -EFAULT;
+
+	return cxl_context_thread_tidr(ctx, assign);
+}
+
 long afu_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
 	struct cxl_context *ctx = file->private_data;
@@ -319,6 +330,8 @@ long afu_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 	case CXL_IOCTL_GET_AFU_ID:
 		return afu_ioctl_get_afu_id(ctx, (struct cxl_afu_id __user *)
 					    arg);
+	case CXL_IOCTL_THREAD_TIDR:
+		return afu_ioctl_thread_tidr(ctx, (int __user *)arg);
 	}
 	return -EINVAL;
 }
diff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c
index 02b6b45..657c4a9 100644
--- a/drivers/misc/cxl/native.c
+++ b/drivers/misc/cxl/native.c
@@ -673,7 +673,7 @@ static int process_element_entry_psl9(struct cxl_context *ctx, u64 wed, u64 amr)
 		pid = ctx->mm->context.id;
 	}
 
-	ctx->elem->common.tid = 0;
+	ctx->elem->common.tid = cpu_to_be32(ctx->tid);
 	ctx->elem->common.pid = cpu_to_be32(pid);
 
 	ctx->elem->sr = cpu_to_be64(calculate_sr(ctx));
diff --git a/include/uapi/misc/cxl.h b/include/uapi/misc/cxl.h
index 49e8fd0..78b5eb5 100644
--- a/include/uapi/misc/cxl.h
+++ b/include/uapi/misc/cxl.h
@@ -81,7 +81,8 @@ struct cxl_adapter_image {
 /* AFU devices */
 #define CXL_IOCTL_START_WORK		_IOW(CXL_MAGIC, 0x00, struct cxl_ioctl_start_work)
 #define CXL_IOCTL_GET_PROCESS_ELEMENT	_IOR(CXL_MAGIC, 0x01, __u32)
-#define CXL_IOCTL_GET_AFU_ID            _IOR(CXL_MAGIC, 0x02, struct cxl_afu_id)
+#define CXL_IOCTL_GET_AFU_ID		_IOR(CXL_MAGIC, 0x02, struct cxl_afu_id)
+#define CXL_IOCTL_THREAD_TIDR		_IOR(CXL_MAGIC, 0x03, int)
 /* adapter devices */
 #define CXL_IOCTL_DOWNLOAD_IMAGE        _IOW(CXL_MAGIC, 0x0A, struct cxl_adapter_image)
 #define CXL_IOCTL_VALIDATE_IMAGE        _IOW(CXL_MAGIC, 0x0B, struct cxl_adapter_image)
