summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlastair D'Silva <alastair@d-silva.org>2019-03-27 01:31:33 -0400
committerMichael Ellerman <mpe@ellerman.id.au>2019-05-02 12:55:02 -0400
commitb9721d275cc2c5e6c07371239c827e0faf05a6b9 (patch)
tree06ac877469c44d3c14a93a013440150818c6567a
parent75ca758adbafc81804c39b2c200ecdc819a6c042 (diff)
ocxl: Allow external drivers to use OpenCAPI contexts
Most OpenCAPI operations require a valid context, so exposing these functions to external drivers is necessary. Signed-off-by: Alastair D'Silva <alastair@d-silva.org> Reviewed-by: Greg Kurz <groug@kaod.org> Acked-by: Frederic Barrat <fbarrat@linux.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-rw-r--r--drivers/misc/ocxl/context.c22
-rw-r--r--drivers/misc/ocxl/file.c8
-rw-r--r--drivers/misc/ocxl/ocxl_internal.h6
-rw-r--r--include/misc/ocxl.h39
4 files changed, 55 insertions, 20 deletions
diff --git a/drivers/misc/ocxl/context.c b/drivers/misc/ocxl/context.c
index c73a859d2224..b60e674ac019 100644
--- a/drivers/misc/ocxl/context.c
+++ b/drivers/misc/ocxl/context.c
@@ -4,15 +4,17 @@
4#include "trace.h" 4#include "trace.h"
5#include "ocxl_internal.h" 5#include "ocxl_internal.h"
6 6
7struct ocxl_context *ocxl_context_alloc(void) 7int ocxl_context_alloc(struct ocxl_context **context, struct ocxl_afu *afu,
8{
9 return kzalloc(sizeof(struct ocxl_context), GFP_KERNEL);
10}
11
12int ocxl_context_init(struct ocxl_context *ctx, struct ocxl_afu *afu,
13 struct address_space *mapping) 8 struct address_space *mapping)
14{ 9{
15 int pasid; 10 int pasid;
11 struct ocxl_context *ctx;
12
13 *context = kzalloc(sizeof(struct ocxl_context), GFP_KERNEL);
14 if (!*context)
15 return -ENOMEM;
16
17 ctx = *context;
16 18
17 ctx->afu = afu; 19 ctx->afu = afu;
18 mutex_lock(&afu->contexts_lock); 20 mutex_lock(&afu->contexts_lock);
@@ -43,6 +45,7 @@ int ocxl_context_init(struct ocxl_context *ctx, struct ocxl_afu *afu,
43 ocxl_afu_get(afu); 45 ocxl_afu_get(afu);
44 return 0; 46 return 0;
45} 47}
48EXPORT_SYMBOL_GPL(ocxl_context_alloc);
46 49
47/* 50/*
48 * Callback for when a translation fault triggers an error 51 * Callback for when a translation fault triggers an error
@@ -63,7 +66,7 @@ static void xsl_fault_error(void *data, u64 addr, u64 dsisr)
63 wake_up_all(&ctx->events_wq); 66 wake_up_all(&ctx->events_wq);
64} 67}
65 68
66int ocxl_context_attach(struct ocxl_context *ctx, u64 amr) 69int ocxl_context_attach(struct ocxl_context *ctx, u64 amr, struct mm_struct *mm)
67{ 70{
68 int rc; 71 int rc;
69 72
@@ -75,7 +78,7 @@ int ocxl_context_attach(struct ocxl_context *ctx, u64 amr)
75 } 78 }
76 79
77 rc = ocxl_link_add_pe(ctx->afu->fn->link, ctx->pasid, 80 rc = ocxl_link_add_pe(ctx->afu->fn->link, ctx->pasid,
78 current->mm->context.id, ctx->tidr, amr, current->mm, 81 mm->context.id, ctx->tidr, amr, mm,
79 xsl_fault_error, ctx); 82 xsl_fault_error, ctx);
80 if (rc) 83 if (rc)
81 goto out; 84 goto out;
@@ -85,6 +88,7 @@ out:
85 mutex_unlock(&ctx->status_mutex); 88 mutex_unlock(&ctx->status_mutex);
86 return rc; 89 return rc;
87} 90}
91EXPORT_SYMBOL_GPL(ocxl_context_attach);
88 92
89static vm_fault_t map_afu_irq(struct vm_area_struct *vma, unsigned long address, 93static vm_fault_t map_afu_irq(struct vm_area_struct *vma, unsigned long address,
90 u64 offset, struct ocxl_context *ctx) 94 u64 offset, struct ocxl_context *ctx)
@@ -243,6 +247,7 @@ int ocxl_context_detach(struct ocxl_context *ctx)
243 } 247 }
244 return 0; 248 return 0;
245} 249}
250EXPORT_SYMBOL_GPL(ocxl_context_detach);
246 251
247void ocxl_context_detach_all(struct ocxl_afu *afu) 252void ocxl_context_detach_all(struct ocxl_afu *afu)
248{ 253{
@@ -280,3 +285,4 @@ void ocxl_context_free(struct ocxl_context *ctx)
280 ocxl_afu_put(ctx->afu); 285 ocxl_afu_put(ctx->afu);
281 kfree(ctx); 286 kfree(ctx);
282} 287}
288EXPORT_SYMBOL_GPL(ocxl_context_free);
diff --git a/drivers/misc/ocxl/file.c b/drivers/misc/ocxl/file.c
index 7a38ea5af9db..8225892a5d77 100644
--- a/drivers/misc/ocxl/file.c
+++ b/drivers/misc/ocxl/file.c
@@ -61,11 +61,7 @@ static int afu_open(struct inode *inode, struct file *file)
61 if (!info) 61 if (!info)
62 return -ENODEV; 62 return -ENODEV;
63 63
64 ctx = ocxl_context_alloc(); 64 rc = ocxl_context_alloc(&ctx, info->afu, inode->i_mapping);
65 if (!ctx)
66 return -ENOMEM;
67
68 rc = ocxl_context_init(ctx, info->afu, inode->i_mapping);
69 if (rc) 65 if (rc)
70 return rc; 66 return rc;
71 67
@@ -90,7 +86,7 @@ static long afu_ioctl_attach(struct ocxl_context *ctx,
90 return -EINVAL; 86 return -EINVAL;
91 87
92 amr = arg.amr & mfspr(SPRN_UAMOR); 88 amr = arg.amr & mfspr(SPRN_UAMOR);
93 rc = ocxl_context_attach(ctx, amr); 89 rc = ocxl_context_attach(ctx, amr, current->mm);
94 return rc; 90 return rc;
95} 91}
96 92
diff --git a/drivers/misc/ocxl/ocxl_internal.h b/drivers/misc/ocxl/ocxl_internal.h
index 53b6c64a1bf0..de6c16237742 100644
--- a/drivers/misc/ocxl/ocxl_internal.h
+++ b/drivers/misc/ocxl/ocxl_internal.h
@@ -130,15 +130,9 @@ int ocxl_config_check_afu_index(struct pci_dev *dev,
130 */ 130 */
131int ocxl_link_update_pe(void *link_handle, int pasid, __u16 tid); 131int ocxl_link_update_pe(void *link_handle, int pasid, __u16 tid);
132 132
133struct ocxl_context *ocxl_context_alloc(void);
134int ocxl_context_init(struct ocxl_context *ctx, struct ocxl_afu *afu,
135 struct address_space *mapping);
136int ocxl_context_attach(struct ocxl_context *ctx, u64 amr);
137int ocxl_context_mmap(struct ocxl_context *ctx, 133int ocxl_context_mmap(struct ocxl_context *ctx,
138 struct vm_area_struct *vma); 134 struct vm_area_struct *vma);
139int ocxl_context_detach(struct ocxl_context *ctx);
140void ocxl_context_detach_all(struct ocxl_afu *afu); 135void ocxl_context_detach_all(struct ocxl_afu *afu);
141void ocxl_context_free(struct ocxl_context *ctx);
142 136
143int ocxl_sysfs_register_afu(struct ocxl_file_info *info); 137int ocxl_sysfs_register_afu(struct ocxl_file_info *info);
144void ocxl_sysfs_unregister_afu(struct ocxl_file_info *info); 138void ocxl_sysfs_unregister_afu(struct ocxl_file_info *info);
diff --git a/include/misc/ocxl.h b/include/misc/ocxl.h
index 8bafd748e380..e4704632eac5 100644
--- a/include/misc/ocxl.h
+++ b/include/misc/ocxl.h
@@ -48,6 +48,7 @@ struct ocxl_fn_config {
48// These are opaque outside the ocxl driver 48// These are opaque outside the ocxl driver
49struct ocxl_afu; 49struct ocxl_afu;
50struct ocxl_fn; 50struct ocxl_fn;
51struct ocxl_context;
51 52
52// Device detection & initialisation 53// Device detection & initialisation
53 54
@@ -116,6 +117,44 @@ const struct ocxl_fn_config *ocxl_function_config(struct ocxl_fn *fn);
116 */ 117 */
117void ocxl_function_close(struct ocxl_fn *fn); 118void ocxl_function_close(struct ocxl_fn *fn);
118 119
120// Context allocation
121
122/**
123 * Allocate an OpenCAPI context
124 *
125 * @context: The OpenCAPI context to allocate, must be freed with ocxl_context_free
126 * @afu: The AFU the context belongs to
127 * @mapping: The mapping to unmap when the context is closed (may be NULL)
128 */
129int ocxl_context_alloc(struct ocxl_context **context, struct ocxl_afu *afu,
130 struct address_space *mapping);
131
132/**
133 * Free an OpenCAPI context
134 *
135 * @ctx: The OpenCAPI context to free
136 */
137void ocxl_context_free(struct ocxl_context *ctx);
138
139/**
140 * Grant access to an MM to an OpenCAPI context
141 * @ctx: The OpenCAPI context to attach
142 * @amr: The value of the AMR register to restrict access
143 * @mm: The mm to attach to the context
144 *
145 * Returns 0 on success, negative on failure
146 */
147int ocxl_context_attach(struct ocxl_context *ctx, u64 amr,
148 struct mm_struct *mm);
149
150/**
151 * Detach an MM from an OpenCAPI context
152 * @ctx: The OpenCAPI context to attach
153 *
154 * Returns 0 on success, negative on failure
155 */
156int ocxl_context_detach(struct ocxl_context *ctx);
157
119// AFU Metadata 158// AFU Metadata
120 159
121/** 160/**