Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

ocxl: Expose the thread_id needed for wait on POWER9



In order to successfully issue as_notify, an AFU needs to know the TID
to notify, which in turn means that this information should be
available in userspace so it can be communicated to the AFU.

Signed-off-by: default avatarAlastair D'Silva <alastair@d-silva.org>
Acked-by: default avatarAndrew Donnellan <andrew.donnellan@au1.ibm.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent 19df3958
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -34,6 +34,8 @@ int ocxl_context_init(struct ocxl_context *ctx, struct ocxl_afu *afu,
	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
@@ -65,6 +67,7 @@ int ocxl_context_attach(struct ocxl_context *ctx, u64 amr)
{
	int rc;

	// Locks both status & tidr
	mutex_lock(&ctx->status_mutex);
	if (ctx->status != OPENED) {
		rc = -EIO;
@@ -72,7 +75,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, 0, amr, current->mm,
			current->mm->context.id, ctx->tidr, amr, current->mm,
			xsl_fault_error, ctx);
	if (rc)
		goto out;
+53 −0
Original line number Diff line number Diff line
@@ -5,6 +5,8 @@
#include <linux/sched/signal.h>
#include <linux/uaccess.h>
#include <uapi/misc/ocxl.h>
#include <asm/reg.h>
#include <asm/switch_to.h>
#include "ocxl_internal.h"


@@ -123,11 +125,55 @@ static long afu_ioctl_get_metadata(struct ocxl_context *ctx,
	return 0;
}

#ifdef CONFIG_PPC64
static long afu_ioctl_enable_p9_wait(struct ocxl_context *ctx,
		struct ocxl_ioctl_p9_wait __user *uarg)
{
	struct ocxl_ioctl_p9_wait arg;

	memset(&arg, 0, sizeof(arg));

	if (cpu_has_feature(CPU_FTR_P9_TIDR)) {
		enum ocxl_context_status status;

		// Locks both status & tidr
		mutex_lock(&ctx->status_mutex);
		if (!ctx->tidr) {
			if (set_thread_tidr(current))
				return -ENOENT;

			ctx->tidr = current->thread.tidr;
		}

		status = ctx->status;
		mutex_unlock(&ctx->status_mutex);

		if (status == ATTACHED) {
			int rc;
			struct link *link = ctx->afu->fn->link;

			rc = ocxl_link_update_pe(link, ctx->pasid, ctx->tidr);
			if (rc)
				return rc;
		}

		arg.thread_id = ctx->tidr;
	} else
		return -ENOENT;

	if (copy_to_user(uarg, &arg, sizeof(arg)))
		return -EFAULT;

	return 0;
}
#endif

#define CMD_STR(x) (x == OCXL_IOCTL_ATTACH ? "ATTACH" :			\
			x == OCXL_IOCTL_IRQ_ALLOC ? "IRQ_ALLOC" :	\
			x == OCXL_IOCTL_IRQ_FREE ? "IRQ_FREE" :		\
			x == OCXL_IOCTL_IRQ_SET_FD ? "IRQ_SET_FD" :	\
			x == OCXL_IOCTL_GET_METADATA ? "GET_METADATA" :	\
			x == OCXL_IOCTL_ENABLE_P9_WAIT ? "ENABLE_P9_WAIT" :	\
			"UNKNOWN")

static long afu_ioctl(struct file *file, unsigned int cmd,
@@ -186,6 +232,13 @@ static long afu_ioctl(struct file *file, unsigned int cmd,
				(struct ocxl_ioctl_metadata __user *) args);
		break;

#ifdef CONFIG_PPC64
	case OCXL_IOCTL_ENABLE_P9_WAIT:
		rc = afu_ioctl_enable_p9_wait(ctx,
				(struct ocxl_ioctl_p9_wait __user *) args);
		break;
#endif

	default:
		rc = -EINVAL;
	}
+36 −0
Original line number Diff line number Diff line
@@ -544,6 +544,42 @@ int ocxl_link_add_pe(void *link_handle, int pasid, u32 pidr, u32 tidr,
}
EXPORT_SYMBOL_GPL(ocxl_link_add_pe);

int ocxl_link_update_pe(void *link_handle, int pasid, __u16 tid)
{
	struct link *link = (struct link *) link_handle;
	struct spa *spa = link->spa;
	struct ocxl_process_element *pe;
	int pe_handle, rc;

	if (pasid > SPA_PASID_MAX)
		return -EINVAL;

	pe_handle = pasid & SPA_PE_MASK;
	pe = spa->spa_mem + pe_handle;

	mutex_lock(&spa->spa_lock);

	pe->tid = tid;

	/*
	 * The barrier makes sure the PE is updated
	 * before we clear the NPU context cache below, so that the
	 * old PE cannot be reloaded erroneously.
	 */
	mb();

	/*
	 * hook to platform code
	 * On powerpc, the entry needs to be cleared from the context
	 * cache of the NPU.
	 */
	rc = pnv_ocxl_spa_remove_pe_from_cache(link->platform_data, pe_handle);
	WARN_ON(rc);

	mutex_unlock(&spa->spa_lock);
	return rc;
}

int ocxl_link_remove_pe(void *link_handle, int pasid)
{
	struct link *link = (struct link *) link_handle;
+1 −0
Original line number Diff line number Diff line
@@ -77,6 +77,7 @@ struct ocxl_context {
	struct ocxl_xsl_error xsl_error;
	struct mutex irq_lock;
	struct idr irq_idr;
	u16 tidr; // Thread ID used for P9 wait implementation
};

struct ocxl_process_element {
+9 −0
Original line number Diff line number Diff line
@@ -188,6 +188,15 @@ extern int ocxl_link_add_pe(void *link_handle, int pasid, u32 pidr, u32 tidr,
		void (*xsl_err_cb)(void *data, u64 addr, u64 dsisr),
		void *xsl_err_data);

/**
 * Update values within a Process Element
 *
 * link_handle: the link handle associated with the process element
 * pasid: the PASID for the AFU context
 * tid: the new thread id for the process element
 */
extern int ocxl_link_update_pe(void *link_handle, int pasid, __u16 tid);

/*
 * Remove a Process Element from the Shared Process Area for a link
 */
Loading