Commit b9721d27 authored by Alastair D'Silva's avatar Alastair D'Silva Committed by Michael Ellerman
Browse files

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: default avatarAlastair D'Silva <alastair@d-silva.org>
Reviewed-by: default avatarGreg Kurz <groug@kaod.org>
Acked-by: default avatarFrederic Barrat <fbarrat@linux.ibm.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent 75ca758a
Loading
Loading
Loading
Loading
+14 −8
Original line number Diff line number Diff line
@@ -4,15 +4,17 @@
#include "trace.h"
#include "ocxl_internal.h"

struct ocxl_context *ocxl_context_alloc(void)
{
	return kzalloc(sizeof(struct ocxl_context), GFP_KERNEL);
}

int ocxl_context_init(struct ocxl_context *ctx, struct ocxl_afu *afu,
int ocxl_context_alloc(struct ocxl_context **context, struct ocxl_afu *afu,
		struct address_space *mapping)
{
	int pasid;
	struct ocxl_context *ctx;

	*context = kzalloc(sizeof(struct ocxl_context), GFP_KERNEL);
	if (!*context)
		return -ENOMEM;

	ctx = *context;

	ctx->afu = afu;
	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);
	return 0;
}
EXPORT_SYMBOL_GPL(ocxl_context_alloc);

/*
 * 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);
}

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;

@@ -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,
			current->mm->context.id, ctx->tidr, amr, current->mm,
			mm->context.id, ctx->tidr, amr, mm,
			xsl_fault_error, ctx);
	if (rc)
		goto out;
@@ -85,6 +88,7 @@ out:
	mutex_unlock(&ctx->status_mutex);
	return rc;
}
EXPORT_SYMBOL_GPL(ocxl_context_attach);

static vm_fault_t map_afu_irq(struct vm_area_struct *vma, unsigned long address,
		u64 offset, struct ocxl_context *ctx)
@@ -243,6 +247,7 @@ int ocxl_context_detach(struct ocxl_context *ctx)
	}
	return 0;
}
EXPORT_SYMBOL_GPL(ocxl_context_detach);

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);
	kfree(ctx);
}
EXPORT_SYMBOL_GPL(ocxl_context_free);
+2 −6
Original line number Diff line number Diff line
@@ -61,11 +61,7 @@ static int afu_open(struct inode *inode, struct file *file)
	if (!info)
		return -ENODEV;

	ctx = ocxl_context_alloc();
	if (!ctx)
		return -ENOMEM;

	rc = ocxl_context_init(ctx, info->afu, inode->i_mapping);
	rc = ocxl_context_alloc(&ctx, info->afu, inode->i_mapping);
	if (rc)
		return rc;

@@ -90,7 +86,7 @@ static long afu_ioctl_attach(struct ocxl_context *ctx,
		return -EINVAL;

	amr = arg.amr & mfspr(SPRN_UAMOR);
	rc = ocxl_context_attach(ctx, amr);
	rc = ocxl_context_attach(ctx, amr, current->mm);
	return rc;
}

+0 −6
Original line number Diff line number Diff line
@@ -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);

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,
			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_free(struct ocxl_context *ctx);

int ocxl_sysfs_register_afu(struct ocxl_file_info *info);
void ocxl_sysfs_unregister_afu(struct ocxl_file_info *info);
+39 −0
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ struct ocxl_fn_config {
// These are opaque outside the ocxl driver
struct ocxl_afu;
struct ocxl_fn;
struct ocxl_context;

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

// 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

/**