drivers/misc/ocxl/context.c

Source file repositories/reference/linux-study-clean/drivers/misc/ocxl/context.c

File Facts

System
Linux kernel
Corpus path
drivers/misc/ocxl/context.c
Extension
.c
Size
7569 bytes
Lines
297
Domain
Driver Families
Bucket
drivers/misc
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0+
// Copyright 2017 IBM Corp.
#include <linux/sched/mm.h>
#include "trace.h"
#include "ocxl_internal.h"

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

	ctx = kzalloc_obj(*ctx);
	if (!ctx)
		return -ENOMEM;

	ctx->afu = afu;
	mutex_lock(&afu->contexts_lock);
	pasid = idr_alloc(&afu->contexts_idr, ctx, afu->pasid_base,
			afu->pasid_base + afu->pasid_max, GFP_KERNEL);
	if (pasid < 0) {
		mutex_unlock(&afu->contexts_lock);
		kfree(ctx);
		return pasid;
	}
	afu->pasid_count++;
	mutex_unlock(&afu->contexts_lock);

	ctx->pasid = pasid;
	ctx->status = OPENED;
	mutex_init(&ctx->status_mutex);
	ctx->mapping = mapping;
	mutex_init(&ctx->mapping_lock);
	init_waitqueue_head(&ctx->events_wq);
	mutex_init(&ctx->xsl_error_lock);
	mutex_init(&ctx->irq_lock);
	idr_init(&ctx->irq_idr);
	ctx->tidr = 0;

	/*
	 * Keep a reference on the AFU to make sure it's valid for the
	 * duration of the life of the context
	 */
	ocxl_afu_get(afu);
	*context = ctx;
	return 0;
}
EXPORT_SYMBOL_GPL(ocxl_context_alloc);

/*
 * Callback for when a translation fault triggers an error
 * data:	a pointer to the context which triggered the fault
 * addr:	the address that triggered the error
 * dsisr:	the value of the PPC64 dsisr register
 */
static void xsl_fault_error(void *data, u64 addr, u64 dsisr)
{
	struct ocxl_context *ctx = data;

	mutex_lock(&ctx->xsl_error_lock);
	ctx->xsl_error.addr = addr;
	ctx->xsl_error.dsisr = dsisr;
	ctx->xsl_error.count++;
	mutex_unlock(&ctx->xsl_error_lock);

	wake_up_all(&ctx->events_wq);
}

int ocxl_context_attach(struct ocxl_context *ctx, u64 amr, struct mm_struct *mm)
{
	int rc;
	unsigned long pidr = 0;
	struct pci_dev *dev;

	// Locks both status & tidr
	mutex_lock(&ctx->status_mutex);
	if (ctx->status != OPENED) {
		rc = -EIO;
		goto out;
	}

	if (mm)
		pidr = mm->context.id;

	dev = to_pci_dev(ctx->afu->fn->dev.parent);
	rc = ocxl_link_add_pe(ctx->afu->fn->link, ctx->pasid, pidr, ctx->tidr,
			      amr, pci_dev_id(dev), mm, xsl_fault_error, ctx);
	if (rc)
		goto out;

Annotation

Implementation Notes