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>
This commit is contained in:
parent
75ca758adb
commit
b9721d275c
|
@ -4,15 +4,17 @@
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
#include "ocxl_internal.h"
|
#include "ocxl_internal.h"
|
||||||
|
|
||||||
struct ocxl_context *ocxl_context_alloc(void)
|
int ocxl_context_alloc(struct ocxl_context **context, struct ocxl_afu *afu,
|
||||||
{
|
|
||||||
return kzalloc(sizeof(struct ocxl_context), GFP_KERNEL);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ocxl_context_init(struct ocxl_context *ctx, struct ocxl_afu *afu,
|
|
||||||
struct address_space *mapping)
|
struct address_space *mapping)
|
||||||
{
|
{
|
||||||
int pasid;
|
int pasid;
|
||||||
|
struct ocxl_context *ctx;
|
||||||
|
|
||||||
|
*context = kzalloc(sizeof(struct ocxl_context), GFP_KERNEL);
|
||||||
|
if (!*context)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
ctx = *context;
|
||||||
|
|
||||||
ctx->afu = afu;
|
ctx->afu = afu;
|
||||||
mutex_lock(&afu->contexts_lock);
|
mutex_lock(&afu->contexts_lock);
|
||||||
|
@ -43,6 +45,7 @@ int ocxl_context_init(struct ocxl_context *ctx, struct ocxl_afu *afu,
|
||||||
ocxl_afu_get(afu);
|
ocxl_afu_get(afu);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(ocxl_context_alloc);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Callback for when a translation fault triggers an error
|
* Callback for when a translation fault triggers an error
|
||||||
|
@ -63,7 +66,7 @@ static void xsl_fault_error(void *data, u64 addr, u64 dsisr)
|
||||||
wake_up_all(&ctx->events_wq);
|
wake_up_all(&ctx->events_wq);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ocxl_context_attach(struct ocxl_context *ctx, u64 amr)
|
int ocxl_context_attach(struct ocxl_context *ctx, u64 amr, struct mm_struct *mm)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
@ -75,7 +78,7 @@ int ocxl_context_attach(struct ocxl_context *ctx, u64 amr)
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = ocxl_link_add_pe(ctx->afu->fn->link, ctx->pasid,
|
rc = ocxl_link_add_pe(ctx->afu->fn->link, ctx->pasid,
|
||||||
current->mm->context.id, ctx->tidr, amr, current->mm,
|
mm->context.id, ctx->tidr, amr, mm,
|
||||||
xsl_fault_error, ctx);
|
xsl_fault_error, ctx);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -85,6 +88,7 @@ int ocxl_context_attach(struct ocxl_context *ctx, u64 amr)
|
||||||
mutex_unlock(&ctx->status_mutex);
|
mutex_unlock(&ctx->status_mutex);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(ocxl_context_attach);
|
||||||
|
|
||||||
static vm_fault_t map_afu_irq(struct vm_area_struct *vma, unsigned long address,
|
static vm_fault_t map_afu_irq(struct vm_area_struct *vma, unsigned long address,
|
||||||
u64 offset, struct ocxl_context *ctx)
|
u64 offset, struct ocxl_context *ctx)
|
||||||
|
@ -243,6 +247,7 @@ int ocxl_context_detach(struct ocxl_context *ctx)
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(ocxl_context_detach);
|
||||||
|
|
||||||
void ocxl_context_detach_all(struct ocxl_afu *afu)
|
void ocxl_context_detach_all(struct ocxl_afu *afu)
|
||||||
{
|
{
|
||||||
|
@ -280,3 +285,4 @@ void ocxl_context_free(struct ocxl_context *ctx)
|
||||||
ocxl_afu_put(ctx->afu);
|
ocxl_afu_put(ctx->afu);
|
||||||
kfree(ctx);
|
kfree(ctx);
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(ocxl_context_free);
|
||||||
|
|
|
@ -61,11 +61,7 @@ static int afu_open(struct inode *inode, struct file *file)
|
||||||
if (!info)
|
if (!info)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
ctx = ocxl_context_alloc();
|
rc = ocxl_context_alloc(&ctx, info->afu, inode->i_mapping);
|
||||||
if (!ctx)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
rc = ocxl_context_init(ctx, info->afu, inode->i_mapping);
|
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
|
@ -90,7 +86,7 @@ static long afu_ioctl_attach(struct ocxl_context *ctx,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
amr = arg.amr & mfspr(SPRN_UAMOR);
|
amr = arg.amr & mfspr(SPRN_UAMOR);
|
||||||
rc = ocxl_context_attach(ctx, amr);
|
rc = ocxl_context_attach(ctx, amr, current->mm);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -130,15 +130,9 @@ int ocxl_config_check_afu_index(struct pci_dev *dev,
|
||||||
*/
|
*/
|
||||||
int ocxl_link_update_pe(void *link_handle, int pasid, __u16 tid);
|
int ocxl_link_update_pe(void *link_handle, int pasid, __u16 tid);
|
||||||
|
|
||||||
struct ocxl_context *ocxl_context_alloc(void);
|
|
||||||
int ocxl_context_init(struct ocxl_context *ctx, struct ocxl_afu *afu,
|
|
||||||
struct address_space *mapping);
|
|
||||||
int ocxl_context_attach(struct ocxl_context *ctx, u64 amr);
|
|
||||||
int ocxl_context_mmap(struct ocxl_context *ctx,
|
int ocxl_context_mmap(struct ocxl_context *ctx,
|
||||||
struct vm_area_struct *vma);
|
struct vm_area_struct *vma);
|
||||||
int ocxl_context_detach(struct ocxl_context *ctx);
|
|
||||||
void ocxl_context_detach_all(struct ocxl_afu *afu);
|
void ocxl_context_detach_all(struct ocxl_afu *afu);
|
||||||
void ocxl_context_free(struct ocxl_context *ctx);
|
|
||||||
|
|
||||||
int ocxl_sysfs_register_afu(struct ocxl_file_info *info);
|
int ocxl_sysfs_register_afu(struct ocxl_file_info *info);
|
||||||
void ocxl_sysfs_unregister_afu(struct ocxl_file_info *info);
|
void ocxl_sysfs_unregister_afu(struct ocxl_file_info *info);
|
||||||
|
|
|
@ -48,6 +48,7 @@ struct ocxl_fn_config {
|
||||||
// These are opaque outside the ocxl driver
|
// These are opaque outside the ocxl driver
|
||||||
struct ocxl_afu;
|
struct ocxl_afu;
|
||||||
struct ocxl_fn;
|
struct ocxl_fn;
|
||||||
|
struct ocxl_context;
|
||||||
|
|
||||||
// Device detection & initialisation
|
// Device detection & initialisation
|
||||||
|
|
||||||
|
@ -116,6 +117,44 @@ const struct ocxl_fn_config *ocxl_function_config(struct ocxl_fn *fn);
|
||||||
*/
|
*/
|
||||||
void ocxl_function_close(struct ocxl_fn *fn);
|
void ocxl_function_close(struct ocxl_fn *fn);
|
||||||
|
|
||||||
|
// Context allocation
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocate an OpenCAPI context
|
||||||
|
*
|
||||||
|
* @context: The OpenCAPI context to allocate, must be freed with ocxl_context_free
|
||||||
|
* @afu: The AFU the context belongs to
|
||||||
|
* @mapping: The mapping to unmap when the context is closed (may be NULL)
|
||||||
|
*/
|
||||||
|
int ocxl_context_alloc(struct ocxl_context **context, struct ocxl_afu *afu,
|
||||||
|
struct address_space *mapping);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free an OpenCAPI context
|
||||||
|
*
|
||||||
|
* @ctx: The OpenCAPI context to free
|
||||||
|
*/
|
||||||
|
void ocxl_context_free(struct ocxl_context *ctx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Grant access to an MM to an OpenCAPI context
|
||||||
|
* @ctx: The OpenCAPI context to attach
|
||||||
|
* @amr: The value of the AMR register to restrict access
|
||||||
|
* @mm: The mm to attach to the context
|
||||||
|
*
|
||||||
|
* Returns 0 on success, negative on failure
|
||||||
|
*/
|
||||||
|
int ocxl_context_attach(struct ocxl_context *ctx, u64 amr,
|
||||||
|
struct mm_struct *mm);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detach an MM from an OpenCAPI context
|
||||||
|
* @ctx: The OpenCAPI context to attach
|
||||||
|
*
|
||||||
|
* Returns 0 on success, negative on failure
|
||||||
|
*/
|
||||||
|
int ocxl_context_detach(struct ocxl_context *ctx);
|
||||||
|
|
||||||
// AFU Metadata
|
// AFU Metadata
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue