|
@@ -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;
|
|
|
}
|