aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/cxl/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/cxl/file.c')
-rw-r--r--drivers/misc/cxl/file.c64
1 files changed, 56 insertions, 8 deletions
diff --git a/drivers/misc/cxl/file.c b/drivers/misc/cxl/file.c
index eec468f1612f..5fb9894b157f 100644
--- a/drivers/misc/cxl/file.c
+++ b/drivers/misc/cxl/file.c
@@ -293,6 +293,17 @@ int afu_mmap(struct file *file, struct vm_area_struct *vm)
293 return cxl_context_iomap(ctx, vm); 293 return cxl_context_iomap(ctx, vm);
294} 294}
295 295
296static inline bool ctx_event_pending(struct cxl_context *ctx)
297{
298 if (ctx->pending_irq || ctx->pending_fault || ctx->pending_afu_err)
299 return true;
300
301 if (ctx->afu_driver_ops && atomic_read(&ctx->afu_driver_events))
302 return true;
303
304 return false;
305}
306
296unsigned int afu_poll(struct file *file, struct poll_table_struct *poll) 307unsigned int afu_poll(struct file *file, struct poll_table_struct *poll)
297{ 308{
298 struct cxl_context *ctx = file->private_data; 309 struct cxl_context *ctx = file->private_data;
@@ -305,8 +316,7 @@ unsigned int afu_poll(struct file *file, struct poll_table_struct *poll)
305 pr_devel("afu_poll wait done pe: %i\n", ctx->pe); 316 pr_devel("afu_poll wait done pe: %i\n", ctx->pe);
306 317
307 spin_lock_irqsave(&ctx->lock, flags); 318 spin_lock_irqsave(&ctx->lock, flags);
308 if (ctx->pending_irq || ctx->pending_fault || 319 if (ctx_event_pending(ctx))
309 ctx->pending_afu_err)
310 mask |= POLLIN | POLLRDNORM; 320 mask |= POLLIN | POLLRDNORM;
311 else if (ctx->status == CLOSED) 321 else if (ctx->status == CLOSED)
312 /* Only error on closed when there are no futher events pending 322 /* Only error on closed when there are no futher events pending
@@ -319,16 +329,46 @@ unsigned int afu_poll(struct file *file, struct poll_table_struct *poll)
319 return mask; 329 return mask;
320} 330}
321 331
322static inline int ctx_event_pending(struct cxl_context *ctx) 332static ssize_t afu_driver_event_copy(struct cxl_context *ctx,
333 char __user *buf,
334 struct cxl_event *event,
335 struct cxl_event_afu_driver_reserved *pl)
323{ 336{
324 return (ctx->pending_irq || ctx->pending_fault || 337 /* Check event */
325 ctx->pending_afu_err || (ctx->status == CLOSED)); 338 if (!pl) {
339 ctx->afu_driver_ops->event_delivered(ctx, pl, -EINVAL);
340 return -EFAULT;
341 }
342
343 /* Check event size */
344 event->header.size += pl->data_size;
345 if (event->header.size > CXL_READ_MIN_SIZE) {
346 ctx->afu_driver_ops->event_delivered(ctx, pl, -EINVAL);
347 return -EFAULT;
348 }
349
350 /* Copy event header */
351 if (copy_to_user(buf, event, sizeof(struct cxl_event_header))) {
352 ctx->afu_driver_ops->event_delivered(ctx, pl, -EFAULT);
353 return -EFAULT;
354 }
355
356 /* Copy event data */
357 buf += sizeof(struct cxl_event_header);
358 if (copy_to_user(buf, &pl->data, pl->data_size)) {
359 ctx->afu_driver_ops->event_delivered(ctx, pl, -EFAULT);
360 return -EFAULT;
361 }
362
363 ctx->afu_driver_ops->event_delivered(ctx, pl, 0); /* Success */
364 return event->header.size;
326} 365}
327 366
328ssize_t afu_read(struct file *file, char __user *buf, size_t count, 367ssize_t afu_read(struct file *file, char __user *buf, size_t count,
329 loff_t *off) 368 loff_t *off)
330{ 369{
331 struct cxl_context *ctx = file->private_data; 370 struct cxl_context *ctx = file->private_data;
371 struct cxl_event_afu_driver_reserved *pl = NULL;
332 struct cxl_event event; 372 struct cxl_event event;
333 unsigned long flags; 373 unsigned long flags;
334 int rc; 374 int rc;
@@ -344,7 +384,7 @@ ssize_t afu_read(struct file *file, char __user *buf, size_t count,
344 384
345 for (;;) { 385 for (;;) {
346 prepare_to_wait(&ctx->wq, &wait, TASK_INTERRUPTIBLE); 386 prepare_to_wait(&ctx->wq, &wait, TASK_INTERRUPTIBLE);
347 if (ctx_event_pending(ctx)) 387 if (ctx_event_pending(ctx) || (ctx->status == CLOSED))
348 break; 388 break;
349 389
350 if (!cxl_ops->link_ok(ctx->afu->adapter, ctx->afu)) { 390 if (!cxl_ops->link_ok(ctx->afu->adapter, ctx->afu)) {
@@ -374,7 +414,12 @@ ssize_t afu_read(struct file *file, char __user *buf, size_t count,
374 memset(&event, 0, sizeof(event)); 414 memset(&event, 0, sizeof(event));
375 event.header.process_element = ctx->pe; 415 event.header.process_element = ctx->pe;
376 event.header.size = sizeof(struct cxl_event_header); 416 event.header.size = sizeof(struct cxl_event_header);
377 if (ctx->pending_irq) { 417 if (ctx->afu_driver_ops && atomic_read(&ctx->afu_driver_events)) {
418 pr_devel("afu_read delivering AFU driver specific event\n");
419 pl = ctx->afu_driver_ops->fetch_event(ctx);
420 atomic_dec(&ctx->afu_driver_events);
421 event.header.type = CXL_EVENT_AFU_DRIVER;
422 } else if (ctx->pending_irq) {
378 pr_devel("afu_read delivering AFU interrupt\n"); 423 pr_devel("afu_read delivering AFU interrupt\n");
379 event.header.size += sizeof(struct cxl_event_afu_interrupt); 424 event.header.size += sizeof(struct cxl_event_afu_interrupt);
380 event.header.type = CXL_EVENT_AFU_INTERRUPT; 425 event.header.type = CXL_EVENT_AFU_INTERRUPT;
@@ -404,6 +449,9 @@ ssize_t afu_read(struct file *file, char __user *buf, size_t count,
404 449
405 spin_unlock_irqrestore(&ctx->lock, flags); 450 spin_unlock_irqrestore(&ctx->lock, flags);
406 451
452 if (event.header.type == CXL_EVENT_AFU_DRIVER)
453 return afu_driver_event_copy(ctx, buf, &event, pl);
454
407 if (copy_to_user(buf, &event, event.header.size)) 455 if (copy_to_user(buf, &event, event.header.size))
408 return -EFAULT; 456 return -EFAULT;
409 return event.header.size; 457 return event.header.size;
@@ -558,7 +606,7 @@ int __init cxl_file_init(void)
558 * If these change we really need to update API. Either change some 606 * If these change we really need to update API. Either change some
559 * flags or update API version number CXL_API_VERSION. 607 * flags or update API version number CXL_API_VERSION.
560 */ 608 */
561 BUILD_BUG_ON(CXL_API_VERSION != 2); 609 BUILD_BUG_ON(CXL_API_VERSION != 3);
562 BUILD_BUG_ON(sizeof(struct cxl_ioctl_start_work) != 64); 610 BUILD_BUG_ON(sizeof(struct cxl_ioctl_start_work) != 64);
563 BUILD_BUG_ON(sizeof(struct cxl_event_header) != 8); 611 BUILD_BUG_ON(sizeof(struct cxl_event_header) != 8);
564 BUILD_BUG_ON(sizeof(struct cxl_event_afu_interrupt) != 8); 612 BUILD_BUG_ON(sizeof(struct cxl_event_afu_interrupt) != 8);