summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/misc/cxl.h48
-rw-r--r--include/uapi/misc/cxl.h17
2 files changed, 65 insertions, 0 deletions
diff --git a/include/misc/cxl.h b/include/misc/cxl.h
index 56560c5781b4..17419f61e611 100644
--- a/include/misc/cxl.h
+++ b/include/misc/cxl.h
@@ -220,4 +220,52 @@ void cxl_perst_reloads_same_image(struct cxl_afu *afu,
*/
ssize_t cxl_read_adapter_vpd(struct pci_dev *dev, void *buf, size_t count);
+/*
+ * AFU driver ops allow an AFU driver to create their own events to pass to
+ * userspace through the file descriptor as a simpler alternative to overriding
+ * the read() and poll() calls that works with the generic cxl events. These
+ * events are given priority over the generic cxl events, so they will be
+ * delivered first if multiple types of events are pending.
+ *
+ * The AFU driver must call cxl_context_events_pending() to notify the cxl
+ * driver that new events are ready to be delivered for a specific context.
+ * cxl_context_events_pending() will adjust the current count of AFU driver
+ * events for this context, and wake up anyone waiting on the context wait
+ * queue.
+ *
+ * The cxl driver will then call fetch_event() to get a structure defining
+ * the size and address of the driver specific event data. The cxl driver
+ * will build a cxl header with type and process_element fields filled in,
+ * and header.size set to sizeof(struct cxl_event_header) + data_size.
+ * The total size of the event is limited to CXL_READ_MIN_SIZE (4K).
+ *
+ * fetch_event() is called with a spin lock held, so it must not sleep.
+ *
+ * The cxl driver will then deliver the event to userspace, and finally
+ * call event_delivered() to return the status of the operation, identified
+ * by cxl context and AFU driver event data pointers.
+ * 0 Success
+ * -EFAULT copy_to_user() has failed
+ * -EINVAL Event data pointer is NULL, or event size is greater than
+ * CXL_READ_MIN_SIZE.
+ */
+struct cxl_afu_driver_ops {
+ struct cxl_event_afu_driver_reserved *(*fetch_event) (
+ struct cxl_context *ctx);
+ void (*event_delivered) (struct cxl_context *ctx,
+ struct cxl_event_afu_driver_reserved *event,
+ int rc);
+};
+
+/*
+ * Associate the above driver ops with a specific context.
+ * Reset the current count of AFU driver events.
+ */
+void cxl_set_driver_ops(struct cxl_context *ctx,
+ struct cxl_afu_driver_ops *ops);
+
+/* Notify cxl driver that new events are ready to be delivered for context */
+void cxl_context_events_pending(struct cxl_context *ctx,
+ unsigned int new_events);
+
#endif /* _MISC_CXL_H */
diff --git a/include/uapi/misc/cxl.h b/include/uapi/misc/cxl.h
index 8cd334f99ddc..cbae529b7ce0 100644
--- a/include/uapi/misc/cxl.h
+++ b/include/uapi/misc/cxl.h
@@ -93,6 +93,7 @@ enum cxl_event_type {
CXL_EVENT_AFU_INTERRUPT = 1,
CXL_EVENT_DATA_STORAGE = 2,
CXL_EVENT_AFU_ERROR = 3,
+ CXL_EVENT_AFU_DRIVER = 4,
};
struct cxl_event_header {
@@ -124,12 +125,28 @@ struct cxl_event_afu_error {
__u64 error;
};
+struct cxl_event_afu_driver_reserved {
+ /*
+ * Defines the buffer passed to the cxl driver by the AFU driver.
+ *
+ * This is not ABI since the event header.size passed to the user for
+ * existing events is set in the read call to sizeof(cxl_event_header)
+ * + sizeof(whatever event is being dispatched) and the user is already
+ * required to use a 4K buffer on the read call.
+ *
+ * Of course the contents will be ABI, but that's up the AFU driver.
+ */
+ size_t data_size;
+ u8 data[];
+};
+
struct cxl_event {
struct cxl_event_header header;
union {
struct cxl_event_afu_interrupt irq;
struct cxl_event_data_storage fault;
struct cxl_event_afu_error afu_error;
+ struct cxl_event_afu_driver_reserved afu_driver_event;
};
};