.. | .. |
---|
4 | 4 | #include "trace.h" |
---|
5 | 5 | #include "ocxl_internal.h" |
---|
6 | 6 | |
---|
7 | | -struct ocxl_context *ocxl_context_alloc(void) |
---|
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, |
---|
| 7 | +int ocxl_context_alloc(struct ocxl_context **context, struct ocxl_afu *afu, |
---|
13 | 8 | struct address_space *mapping) |
---|
14 | 9 | { |
---|
15 | 10 | int pasid; |
---|
| 11 | + struct ocxl_context *ctx; |
---|
| 12 | + |
---|
| 13 | + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); |
---|
| 14 | + if (!ctx) |
---|
| 15 | + return -ENOMEM; |
---|
16 | 16 | |
---|
17 | 17 | ctx->afu = afu; |
---|
18 | 18 | mutex_lock(&afu->contexts_lock); |
---|
.. | .. |
---|
20 | 20 | afu->pasid_base + afu->pasid_max, GFP_KERNEL); |
---|
21 | 21 | if (pasid < 0) { |
---|
22 | 22 | mutex_unlock(&afu->contexts_lock); |
---|
| 23 | + kfree(ctx); |
---|
23 | 24 | return pasid; |
---|
24 | 25 | } |
---|
25 | 26 | afu->pasid_count++; |
---|
.. | .. |
---|
41 | 42 | * duration of the life of the context |
---|
42 | 43 | */ |
---|
43 | 44 | ocxl_afu_get(afu); |
---|
| 45 | + *context = ctx; |
---|
44 | 46 | return 0; |
---|
45 | 47 | } |
---|
| 48 | +EXPORT_SYMBOL_GPL(ocxl_context_alloc); |
---|
46 | 49 | |
---|
47 | 50 | /* |
---|
48 | 51 | * Callback for when a translation fault triggers an error |
---|
.. | .. |
---|
63 | 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 | 71 | int rc; |
---|
| 72 | + unsigned long pidr = 0; |
---|
69 | 73 | |
---|
70 | 74 | // Locks both status & tidr |
---|
71 | 75 | mutex_lock(&ctx->status_mutex); |
---|
.. | .. |
---|
74 | 78 | goto out; |
---|
75 | 79 | } |
---|
76 | 80 | |
---|
77 | | - rc = ocxl_link_add_pe(ctx->afu->fn->link, ctx->pasid, |
---|
78 | | - current->mm->context.id, ctx->tidr, amr, current->mm, |
---|
79 | | - xsl_fault_error, ctx); |
---|
| 81 | + if (mm) |
---|
| 82 | + pidr = mm->context.id; |
---|
| 83 | + |
---|
| 84 | + rc = ocxl_link_add_pe(ctx->afu->fn->link, ctx->pasid, pidr, ctx->tidr, |
---|
| 85 | + amr, mm, xsl_fault_error, ctx); |
---|
80 | 86 | if (rc) |
---|
81 | 87 | goto out; |
---|
82 | 88 | |
---|
.. | .. |
---|
85 | 91 | mutex_unlock(&ctx->status_mutex); |
---|
86 | 92 | return rc; |
---|
87 | 93 | } |
---|
| 94 | +EXPORT_SYMBOL_GPL(ocxl_context_attach); |
---|
88 | 95 | |
---|
89 | 96 | static vm_fault_t map_afu_irq(struct vm_area_struct *vma, unsigned long address, |
---|
90 | 97 | u64 offset, struct ocxl_context *ctx) |
---|
91 | 98 | { |
---|
92 | 99 | u64 trigger_addr; |
---|
| 100 | + int irq_id = ocxl_irq_offset_to_id(ctx, offset); |
---|
93 | 101 | |
---|
94 | | - trigger_addr = ocxl_afu_irq_get_addr(ctx, offset); |
---|
| 102 | + trigger_addr = ocxl_afu_irq_get_addr(ctx, irq_id); |
---|
95 | 103 | if (!trigger_addr) |
---|
96 | 104 | return VM_FAULT_SIGBUS; |
---|
97 | 105 | |
---|
.. | .. |
---|
151 | 159 | static int check_mmap_afu_irq(struct ocxl_context *ctx, |
---|
152 | 160 | struct vm_area_struct *vma) |
---|
153 | 161 | { |
---|
| 162 | + int irq_id = ocxl_irq_offset_to_id(ctx, vma->vm_pgoff << PAGE_SHIFT); |
---|
| 163 | + |
---|
154 | 164 | /* only one page */ |
---|
155 | 165 | if (vma_pages(vma) != 1) |
---|
156 | 166 | return -EINVAL; |
---|
157 | 167 | |
---|
158 | 168 | /* check offset validty */ |
---|
159 | | - if (!ocxl_afu_irq_get_addr(ctx, vma->vm_pgoff << PAGE_SHIFT)) |
---|
| 169 | + if (!ocxl_afu_irq_get_addr(ctx, irq_id)) |
---|
160 | 170 | return -EINVAL; |
---|
161 | 171 | |
---|
162 | 172 | /* |
---|
.. | .. |
---|
238 | 248 | } |
---|
239 | 249 | rc = ocxl_link_remove_pe(ctx->afu->fn->link, ctx->pasid); |
---|
240 | 250 | if (rc) { |
---|
241 | | - dev_warn(&ctx->afu->dev, |
---|
| 251 | + dev_warn(&dev->dev, |
---|
242 | 252 | "Couldn't remove PE entry cleanly: %d\n", rc); |
---|
243 | 253 | } |
---|
244 | 254 | return 0; |
---|
245 | 255 | } |
---|
| 256 | +EXPORT_SYMBOL_GPL(ocxl_context_detach); |
---|
246 | 257 | |
---|
247 | 258 | void ocxl_context_detach_all(struct ocxl_afu *afu) |
---|
248 | 259 | { |
---|
.. | .. |
---|
276 | 287 | |
---|
277 | 288 | ocxl_afu_irq_free_all(ctx); |
---|
278 | 289 | idr_destroy(&ctx->irq_idr); |
---|
279 | | - /* reference to the AFU taken in ocxl_context_init */ |
---|
| 290 | + /* reference to the AFU taken in ocxl_context_alloc() */ |
---|
280 | 291 | ocxl_afu_put(ctx->afu); |
---|
281 | 292 | kfree(ctx); |
---|
282 | 293 | } |
---|
| 294 | +EXPORT_SYMBOL_GPL(ocxl_context_free); |
---|