diff options
author | Alastair D'Silva <alastair@d-silva.org> | 2019-03-27 01:31:33 -0400 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2019-05-02 12:55:02 -0400 |
commit | b9721d275cc2c5e6c07371239c827e0faf05a6b9 (patch) | |
tree | 06ac877469c44d3c14a93a013440150818c6567a | |
parent | 75ca758adbafc81804c39b2c200ecdc819a6c042 (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.c | 22 | ||||
-rw-r--r-- | drivers/misc/ocxl/file.c | 8 | ||||
-rw-r--r-- | drivers/misc/ocxl/ocxl_internal.h | 6 | ||||
-rw-r--r-- | include/misc/ocxl.h | 39 |
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 | ||
7 | struct ocxl_context *ocxl_context_alloc(void) | 7 | int ocxl_context_alloc(struct ocxl_context **context, struct ocxl_afu *afu, |
8 | { | ||
9 | return kzalloc(sizeof(struct ocxl_context), GFP_KERNEL); | ||
10 | } | ||
11 | |||
12 | int 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 | } |
48 | EXPORT_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 | ||
66 | int ocxl_context_attach(struct ocxl_context *ctx, u64 amr) | 69 | int 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 | } |
91 | EXPORT_SYMBOL_GPL(ocxl_context_attach); | ||
88 | 92 | ||
89 | static vm_fault_t map_afu_irq(struct vm_area_struct *vma, unsigned long address, | 93 | static 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 | } |
250 | EXPORT_SYMBOL_GPL(ocxl_context_detach); | ||
246 | 251 | ||
247 | void ocxl_context_detach_all(struct ocxl_afu *afu) | 252 | void 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 | } |
288 | EXPORT_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 | */ |
131 | int ocxl_link_update_pe(void *link_handle, int pasid, __u16 tid); | 131 | int ocxl_link_update_pe(void *link_handle, int pasid, __u16 tid); |
132 | 132 | ||
133 | struct ocxl_context *ocxl_context_alloc(void); | ||
134 | int ocxl_context_init(struct ocxl_context *ctx, struct ocxl_afu *afu, | ||
135 | struct address_space *mapping); | ||
136 | int ocxl_context_attach(struct ocxl_context *ctx, u64 amr); | ||
137 | int ocxl_context_mmap(struct ocxl_context *ctx, | 133 | int ocxl_context_mmap(struct ocxl_context *ctx, |
138 | struct vm_area_struct *vma); | 134 | struct vm_area_struct *vma); |
139 | int ocxl_context_detach(struct ocxl_context *ctx); | ||
140 | void ocxl_context_detach_all(struct ocxl_afu *afu); | 135 | void ocxl_context_detach_all(struct ocxl_afu *afu); |
141 | void ocxl_context_free(struct ocxl_context *ctx); | ||
142 | 136 | ||
143 | int ocxl_sysfs_register_afu(struct ocxl_file_info *info); | 137 | int ocxl_sysfs_register_afu(struct ocxl_file_info *info); |
144 | void ocxl_sysfs_unregister_afu(struct ocxl_file_info *info); | 138 | void 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 |
49 | struct ocxl_afu; | 49 | struct ocxl_afu; |
50 | struct ocxl_fn; | 50 | struct ocxl_fn; |
51 | struct 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 | */ |
117 | void ocxl_function_close(struct ocxl_fn *fn); | 118 | void 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 | */ | ||
129 | int 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 | */ | ||
137 | void 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 | */ | ||
147 | int 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 | */ | ||
156 | int ocxl_context_detach(struct ocxl_context *ctx); | ||
157 | |||
119 | // AFU Metadata | 158 | // AFU Metadata |
120 | 159 | ||
121 | /** | 160 | /** |