| .. | .. |
|---|
| 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); |
|---|