Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

cxl: Add support for ASB_Notify on POWER9

The POWER9 core supports a new feature: ASB_Notify which requires the
support of the Special Purpose Register: TIDR.

The ASB_Notify command, generated by the AFU, will attempt to
wake-up the host thread identified by the particular LPID:PID:TID.

This patch assign a unique TIDR (thread id) for the current thread which
will be used in the process element entry.

Signed-off-by: Christophe Lombard <clombard@linux.vnet.ibm.com>
Reviewed-by: Philippe Bergheaud <felix@linux.vnet.ibm.com>
Acked-by: Frederic Barrat <fbarrat@linux.vnet.ibm.com>
Reviewed-by: Vaibhav Jain <vaibhav@linux.vnet.ibm.com>
Acked-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>

authored by

Christophe Lombard and committed by
Michael Ellerman
b1db5513 074db39e

+39 -8
+1
arch/powerpc/kernel/process.c
··· 1590 1590 1591 1591 return 0; 1592 1592 } 1593 + EXPORT_SYMBOL_GPL(set_thread_tidr); 1593 1594 1594 1595 #endif /* CONFIG_PPC64 */ 1595 1596
+2
drivers/misc/cxl/context.c
··· 45 45 ctx->pid = NULL; /* Set in start work ioctl */ 46 46 mutex_init(&ctx->mapping_lock); 47 47 ctx->mapping = NULL; 48 + ctx->tidr = 0; 49 + ctx->assign_tidr = false; 48 50 49 51 if (cxl_is_power8()) { 50 52 spin_lock_init(&ctx->sste_lock);
+3
drivers/misc/cxl/cxl.h
··· 630 630 struct list_head extra_irq_contexts; 631 631 632 632 struct mm_struct *mm; 633 + 634 + u16 tidr; 635 + bool assign_tidr; 633 636 }; 634 637 635 638 struct cxl_irq_info;
+2 -1
drivers/misc/cxl/cxllib.c
··· 199 199 */ 200 200 attr->pid = mm->context.id; 201 201 mmput(mm); 202 + attr->tid = task->thread.tidr; 202 203 } else { 203 204 attr->pid = 0; 205 + attr->tid = 0; 204 206 } 205 - attr->tid = 0; 206 207 return 0; 207 208 } 208 209 EXPORT_SYMBOL_GPL(cxllib_get_PE_attributes);
+13 -2
drivers/misc/cxl/file.c
··· 173 173 * flags are set it's invalid 174 174 */ 175 175 if (work.reserved1 || work.reserved2 || work.reserved3 || 176 - work.reserved4 || work.reserved5 || work.reserved6 || 176 + work.reserved4 || work.reserved5 || 177 177 (work.flags & ~CXL_START_WORK_ALL)) { 178 178 rc = -EINVAL; 179 179 goto out; ··· 186 186 rc = -EINVAL; 187 187 goto out; 188 188 } 189 + 189 190 if ((rc = afu_register_irqs(ctx, work.num_interrupts))) 190 191 goto out; 191 192 192 193 if (work.flags & CXL_START_WORK_AMR) 193 194 amr = work.amr & mfspr(SPRN_UAMOR); 195 + 196 + if (work.flags & CXL_START_WORK_TID) 197 + ctx->assign_tidr = true; 194 198 195 199 ctx->mmio_err_ff = !!(work.flags & CXL_START_WORK_ERR_FF); 196 200 ··· 267 263 goto out; 268 264 } 269 265 270 - ctx->status = STARTED; 271 266 rc = 0; 267 + if (work.flags & CXL_START_WORK_TID) { 268 + work.tid = ctx->tidr; 269 + if (copy_to_user(uwork, &work, sizeof(work))) 270 + rc = -EFAULT; 271 + } 272 + 273 + ctx->status = STARTED; 274 + 272 275 out: 273 276 mutex_unlock(&ctx->status_mutex); 274 277 return rc;
+12 -1
drivers/misc/cxl/native.c
··· 16 16 #include <linux/uaccess.h> 17 17 #include <linux/delay.h> 18 18 #include <asm/synch.h> 19 + #include <asm/switch_to.h> 19 20 #include <misc/cxl-base.h> 20 21 21 22 #include "cxl.h" ··· 656 655 static int process_element_entry_psl9(struct cxl_context *ctx, u64 wed, u64 amr) 657 656 { 658 657 u32 pid; 658 + int rc; 659 659 660 660 cxl_assign_psn_space(ctx); 661 661 ··· 675 673 pid = ctx->mm->context.id; 676 674 } 677 675 678 - ctx->elem->common.tid = 0; 676 + /* Assign a unique TIDR (thread id) for the current thread */ 677 + if (!(ctx->tidr) && (ctx->assign_tidr)) { 678 + rc = set_thread_tidr(current); 679 + if (rc) 680 + return -ENODEV; 681 + ctx->tidr = current->thread.tidr; 682 + pr_devel("%s: current tidr: %d\n", __func__, ctx->tidr); 683 + } 684 + 685 + ctx->elem->common.tid = cpu_to_be32(ctx->tidr); 679 686 ctx->elem->common.pid = cpu_to_be32(pid); 680 687 681 688 ctx->elem->sr = cpu_to_be64(calculate_sr(ctx));
+6 -4
include/uapi/misc/cxl.h
··· 20 20 __u64 work_element_descriptor; 21 21 __u64 amr; 22 22 __s16 num_interrupts; 23 - __s16 reserved1; 24 - __s32 reserved2; 23 + __u16 tid; 24 + __s32 reserved1; 25 + __u64 reserved2; 25 26 __u64 reserved3; 26 27 __u64 reserved4; 27 28 __u64 reserved5; 28 - __u64 reserved6; 29 29 }; 30 30 31 31 #define CXL_START_WORK_AMR 0x0000000000000001ULL 32 32 #define CXL_START_WORK_NUM_IRQS 0x0000000000000002ULL 33 33 #define CXL_START_WORK_ERR_FF 0x0000000000000004ULL 34 + #define CXL_START_WORK_TID 0x0000000000000008ULL 34 35 #define CXL_START_WORK_ALL (CXL_START_WORK_AMR |\ 35 36 CXL_START_WORK_NUM_IRQS |\ 36 - CXL_START_WORK_ERR_FF) 37 + CXL_START_WORK_ERR_FF |\ 38 + CXL_START_WORK_TID) 37 39 38 40 39 41 /* Possible modes that an afu can be in */