aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/cxl/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/cxl/file.c')
-rw-r--r--drivers/misc/cxl/file.c24
1 files changed, 22 insertions, 2 deletions
diff --git a/drivers/misc/cxl/file.c b/drivers/misc/cxl/file.c
index 4bfad9f6dc9f..76c0b0ca9388 100644
--- a/drivers/misc/cxl/file.c
+++ b/drivers/misc/cxl/file.c
@@ -19,6 +19,7 @@
19#include <linux/mm.h> 19#include <linux/mm.h>
20#include <linux/slab.h> 20#include <linux/slab.h>
21#include <linux/sched/mm.h> 21#include <linux/sched/mm.h>
22#include <linux/mmu_context.h>
22#include <asm/cputable.h> 23#include <asm/cputable.h>
23#include <asm/current.h> 24#include <asm/current.h>
24#include <asm/copro.h> 25#include <asm/copro.h>
@@ -220,9 +221,12 @@ static long afu_ioctl_start_work(struct cxl_context *ctx,
220 /* ensure this mm_struct can't be freed */ 221 /* ensure this mm_struct can't be freed */
221 cxl_context_mm_count_get(ctx); 222 cxl_context_mm_count_get(ctx);
222 223
223 /* decrement the use count */ 224 if (ctx->mm) {
224 if (ctx->mm) 225 /* decrement the use count from above */
225 mmput(ctx->mm); 226 mmput(ctx->mm);
227 /* make TLBIs for this context global */
228 mm_context_add_copro(ctx->mm);
229 }
226 230
227 /* 231 /*
228 * Increment driver use count. Enables global TLBIs for hash 232 * Increment driver use count. Enables global TLBIs for hash
@@ -230,6 +234,20 @@ static long afu_ioctl_start_work(struct cxl_context *ctx,
230 */ 234 */
231 cxl_ctx_get(); 235 cxl_ctx_get();
232 236
237 /*
238 * A barrier is needed to make sure all TLBIs are global
239 * before we attach and the context starts being used by the
240 * adapter.
241 *
242 * Needed after mm_context_add_copro() for radix and
243 * cxl_ctx_get() for hash/p8.
244 *
245 * The barrier should really be mb(), since it involves a
246 * device. However, it's only useful when we have local
247 * vs. global TLBIs, i.e SMP=y. So keep smp_mb().
248 */
249 smp_mb();
250
233 trace_cxl_attach(ctx, work.work_element_descriptor, work.num_interrupts, amr); 251 trace_cxl_attach(ctx, work.work_element_descriptor, work.num_interrupts, amr);
234 252
235 if ((rc = cxl_ops->attach_process(ctx, false, work.work_element_descriptor, 253 if ((rc = cxl_ops->attach_process(ctx, false, work.work_element_descriptor,
@@ -240,6 +258,8 @@ static long afu_ioctl_start_work(struct cxl_context *ctx,
240 ctx->pid = NULL; 258 ctx->pid = NULL;
241 cxl_ctx_put(); 259 cxl_ctx_put();
242 cxl_context_mm_count_put(ctx); 260 cxl_context_mm_count_put(ctx);
261 if (ctx->mm)
262 mm_context_remove_copro(ctx->mm);
243 goto out; 263 goto out;
244 } 264 }
245 265