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