diff options
| author | Christophe Lombard <clombard@linux.vnet.ibm.com> | 2018-01-11 03:55:25 -0500 |
|---|---|---|
| committer | Michael Ellerman <mpe@ellerman.id.au> | 2018-01-19 07:19:37 -0500 |
| commit | b1db551324f72fa14ad82ca31237a7ed418104df (patch) | |
| tree | 3e43a06af0f301bf89b3746b82cb2e7bda7f8afc /drivers/misc/cxl | |
| parent | 074db39e00bb0d35cda7de9a4bae3a9b6da557ad (diff) | |
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>
Diffstat (limited to 'drivers/misc/cxl')
| -rw-r--r-- | drivers/misc/cxl/context.c | 2 | ||||
| -rw-r--r-- | drivers/misc/cxl/cxl.h | 3 | ||||
| -rw-r--r-- | drivers/misc/cxl/cxllib.c | 3 | ||||
| -rw-r--r-- | drivers/misc/cxl/file.c | 15 | ||||
| -rw-r--r-- | drivers/misc/cxl/native.c | 13 |
5 files changed, 32 insertions, 4 deletions
diff --git a/drivers/misc/cxl/context.c b/drivers/misc/cxl/context.c index 12a41b2753f0..7ff315ad3692 100644 --- a/drivers/misc/cxl/context.c +++ b/drivers/misc/cxl/context.c | |||
| @@ -45,6 +45,8 @@ int cxl_context_init(struct cxl_context *ctx, struct cxl_afu *afu, bool master) | |||
| 45 | ctx->pid = NULL; /* Set in start work ioctl */ | 45 | ctx->pid = NULL; /* Set in start work ioctl */ |
| 46 | mutex_init(&ctx->mapping_lock); | 46 | mutex_init(&ctx->mapping_lock); |
| 47 | ctx->mapping = NULL; | 47 | ctx->mapping = NULL; |
| 48 | ctx->tidr = 0; | ||
| 49 | ctx->assign_tidr = false; | ||
| 48 | 50 | ||
| 49 | if (cxl_is_power8()) { | 51 | if (cxl_is_power8()) { |
| 50 | spin_lock_init(&ctx->sste_lock); | 52 | spin_lock_init(&ctx->sste_lock); |
diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h index e46a4062904a..53149fbd780e 100644 --- a/drivers/misc/cxl/cxl.h +++ b/drivers/misc/cxl/cxl.h | |||
| @@ -630,6 +630,9 @@ struct cxl_context { | |||
| 630 | struct list_head extra_irq_contexts; | 630 | struct list_head extra_irq_contexts; |
| 631 | 631 | ||
| 632 | struct mm_struct *mm; | 632 | struct mm_struct *mm; |
| 633 | |||
| 634 | u16 tidr; | ||
| 635 | bool assign_tidr; | ||
| 633 | }; | 636 | }; |
| 634 | 637 | ||
| 635 | struct cxl_irq_info; | 638 | struct cxl_irq_info; |
diff --git a/drivers/misc/cxl/cxllib.c b/drivers/misc/cxl/cxllib.c index dc9bc1807fdf..30ccba436b3b 100644 --- a/drivers/misc/cxl/cxllib.c +++ b/drivers/misc/cxl/cxllib.c | |||
| @@ -199,10 +199,11 @@ int cxllib_get_PE_attributes(struct task_struct *task, | |||
| 199 | */ | 199 | */ |
| 200 | attr->pid = mm->context.id; | 200 | attr->pid = mm->context.id; |
| 201 | mmput(mm); | 201 | mmput(mm); |
| 202 | attr->tid = task->thread.tidr; | ||
| 202 | } else { | 203 | } else { |
| 203 | attr->pid = 0; | 204 | attr->pid = 0; |
| 205 | attr->tid = 0; | ||
| 204 | } | 206 | } |
| 205 | attr->tid = 0; | ||
| 206 | return 0; | 207 | return 0; |
| 207 | } | 208 | } |
| 208 | EXPORT_SYMBOL_GPL(cxllib_get_PE_attributes); | 209 | EXPORT_SYMBOL_GPL(cxllib_get_PE_attributes); |
diff --git a/drivers/misc/cxl/file.c b/drivers/misc/cxl/file.c index 76c0b0ca9388..93fd381f6484 100644 --- a/drivers/misc/cxl/file.c +++ b/drivers/misc/cxl/file.c | |||
| @@ -173,7 +173,7 @@ static long afu_ioctl_start_work(struct cxl_context *ctx, | |||
| 173 | * flags are set it's invalid | 173 | * flags are set it's invalid |
| 174 | */ | 174 | */ |
| 175 | if (work.reserved1 || work.reserved2 || work.reserved3 || | 175 | if (work.reserved1 || work.reserved2 || work.reserved3 || |
| 176 | work.reserved4 || work.reserved5 || work.reserved6 || | 176 | work.reserved4 || work.reserved5 || |
| 177 | (work.flags & ~CXL_START_WORK_ALL)) { | 177 | (work.flags & ~CXL_START_WORK_ALL)) { |
| 178 | rc = -EINVAL; | 178 | rc = -EINVAL; |
| 179 | goto out; | 179 | goto out; |
| @@ -186,12 +186,16 @@ static long afu_ioctl_start_work(struct cxl_context *ctx, | |||
| 186 | rc = -EINVAL; | 186 | rc = -EINVAL; |
| 187 | goto out; | 187 | goto out; |
| 188 | } | 188 | } |
| 189 | |||
| 189 | if ((rc = afu_register_irqs(ctx, work.num_interrupts))) | 190 | if ((rc = afu_register_irqs(ctx, work.num_interrupts))) |
| 190 | goto out; | 191 | goto out; |
| 191 | 192 | ||
| 192 | if (work.flags & CXL_START_WORK_AMR) | 193 | if (work.flags & CXL_START_WORK_AMR) |
| 193 | amr = work.amr & mfspr(SPRN_UAMOR); | 194 | amr = work.amr & mfspr(SPRN_UAMOR); |
| 194 | 195 | ||
| 196 | if (work.flags & CXL_START_WORK_TID) | ||
| 197 | ctx->assign_tidr = true; | ||
| 198 | |||
| 195 | ctx->mmio_err_ff = !!(work.flags & CXL_START_WORK_ERR_FF); | 199 | ctx->mmio_err_ff = !!(work.flags & CXL_START_WORK_ERR_FF); |
| 196 | 200 | ||
| 197 | /* | 201 | /* |
| @@ -263,8 +267,15 @@ static long afu_ioctl_start_work(struct cxl_context *ctx, | |||
| 263 | goto out; | 267 | goto out; |
| 264 | } | 268 | } |
| 265 | 269 | ||
| 266 | ctx->status = STARTED; | ||
| 267 | rc = 0; | 270 | rc = 0; |
| 271 | if (work.flags & CXL_START_WORK_TID) { | ||
| 272 | work.tid = ctx->tidr; | ||
| 273 | if (copy_to_user(uwork, &work, sizeof(work))) | ||
| 274 | rc = -EFAULT; | ||
| 275 | } | ||
| 276 | |||
| 277 | ctx->status = STARTED; | ||
| 278 | |||
| 268 | out: | 279 | out: |
| 269 | mutex_unlock(&ctx->status_mutex); | 280 | mutex_unlock(&ctx->status_mutex); |
| 270 | return rc; | 281 | return rc; |
diff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c index 02b6b45b4c20..1b3d7c65ea3f 100644 --- a/drivers/misc/cxl/native.c +++ b/drivers/misc/cxl/native.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #include <linux/uaccess.h> | 16 | #include <linux/uaccess.h> |
| 17 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
| 18 | #include <asm/synch.h> | 18 | #include <asm/synch.h> |
| 19 | #include <asm/switch_to.h> | ||
| 19 | #include <misc/cxl-base.h> | 20 | #include <misc/cxl-base.h> |
| 20 | 21 | ||
| 21 | #include "cxl.h" | 22 | #include "cxl.h" |
| @@ -655,6 +656,7 @@ static void update_ivtes_directed(struct cxl_context *ctx) | |||
| 655 | static int process_element_entry_psl9(struct cxl_context *ctx, u64 wed, u64 amr) | 656 | static int process_element_entry_psl9(struct cxl_context *ctx, u64 wed, u64 amr) |
| 656 | { | 657 | { |
| 657 | u32 pid; | 658 | u32 pid; |
| 659 | int rc; | ||
| 658 | 660 | ||
| 659 | cxl_assign_psn_space(ctx); | 661 | cxl_assign_psn_space(ctx); |
| 660 | 662 | ||
| @@ -673,7 +675,16 @@ static int process_element_entry_psl9(struct cxl_context *ctx, u64 wed, u64 amr) | |||
| 673 | pid = ctx->mm->context.id; | 675 | pid = ctx->mm->context.id; |
| 674 | } | 676 | } |
| 675 | 677 | ||
| 676 | ctx->elem->common.tid = 0; | 678 | /* Assign a unique TIDR (thread id) for the current thread */ |
| 679 | if (!(ctx->tidr) && (ctx->assign_tidr)) { | ||
| 680 | rc = set_thread_tidr(current); | ||
| 681 | if (rc) | ||
| 682 | return -ENODEV; | ||
| 683 | ctx->tidr = current->thread.tidr; | ||
| 684 | pr_devel("%s: current tidr: %d\n", __func__, ctx->tidr); | ||
| 685 | } | ||
| 686 | |||
| 687 | ctx->elem->common.tid = cpu_to_be32(ctx->tidr); | ||
| 677 | ctx->elem->common.pid = cpu_to_be32(pid); | 688 | ctx->elem->common.pid = cpu_to_be32(pid); |
| 678 | 689 | ||
| 679 | ctx->elem->sr = cpu_to_be64(calculate_sr(ctx)); | 690 | ctx->elem->sr = cpu_to_be64(calculate_sr(ctx)); |
