linux/drivers/misc/cxl/file.c
<<
>>
Prefs
   1/*
   2 * Copyright 2014 IBM Corp.
   3 *
   4 * This program is free software; you can redistribute it and/or
   5 * modify it under the terms of the GNU General Public License
   6 * as published by the Free Software Foundation; either version
   7 * 2 of the License, or (at your option) any later version.
   8 */
   9
  10#include <linux/spinlock.h>
  11#include <linux/module.h>
  12#include <linux/export.h>
  13#include <linux/kernel.h>
  14#include <linux/bitmap.h>
  15#include <linux/sched.h>
  16#include <linux/poll.h>
  17#include <linux/pid.h>
  18#include <linux/fs.h>
  19#include <linux/mm.h>
  20#include <linux/slab.h>
  21#include <asm/cputable.h>
  22#include <asm/current.h>
  23#include <asm/copro.h>
  24
  25#include "cxl.h"
  26#include "trace.h"
  27
  28#define CXL_NUM_MINORS 256 /* Total to reserve */
  29#define CXL_DEV_MINORS 13   /* 1 control + 4 AFUs * 3 (dedicated/master/shared) */
  30
  31#define CXL_CARD_MINOR(adapter) (adapter->adapter_num * CXL_DEV_MINORS)
  32#define CXL_AFU_MINOR_D(afu) (CXL_CARD_MINOR(afu->adapter) + 1 + (3 * afu->slice))
  33#define CXL_AFU_MINOR_M(afu) (CXL_AFU_MINOR_D(afu) + 1)
  34#define CXL_AFU_MINOR_S(afu) (CXL_AFU_MINOR_D(afu) + 2)
  35#define CXL_AFU_MKDEV_D(afu) MKDEV(MAJOR(cxl_dev), CXL_AFU_MINOR_D(afu))
  36#define CXL_AFU_MKDEV_M(afu) MKDEV(MAJOR(cxl_dev), CXL_AFU_MINOR_M(afu))
  37#define CXL_AFU_MKDEV_S(afu) MKDEV(MAJOR(cxl_dev), CXL_AFU_MINOR_S(afu))
  38
  39#define CXL_DEVT_ADAPTER(dev) (MINOR(dev) / CXL_DEV_MINORS)
  40#define CXL_DEVT_AFU(dev) ((MINOR(dev) % CXL_DEV_MINORS - 1) / 3)
  41
  42#define CXL_DEVT_IS_CARD(dev) (MINOR(dev) % CXL_DEV_MINORS == 0)
  43
  44static dev_t cxl_dev;
  45
  46static struct class *cxl_class;
  47
  48static int __afu_open(struct inode *inode, struct file *file, bool master)
  49{
  50        struct cxl *adapter;
  51        struct cxl_afu *afu;
  52        struct cxl_context *ctx;
  53        int adapter_num = CXL_DEVT_ADAPTER(inode->i_rdev);
  54        int slice = CXL_DEVT_AFU(inode->i_rdev);
  55        int rc = -ENODEV;
  56
  57        pr_devel("afu_open afu%i.%i\n", slice, adapter_num);
  58
  59        if (!(adapter = get_cxl_adapter(adapter_num)))
  60                return -ENODEV;
  61
  62        if (slice > adapter->slices)
  63                goto err_put_adapter;
  64
  65        spin_lock(&adapter->afu_list_lock);
  66        if (!(afu = adapter->afu[slice])) {
  67                spin_unlock(&adapter->afu_list_lock);
  68                goto err_put_adapter;
  69        }
  70        get_device(&afu->dev);
  71        spin_unlock(&adapter->afu_list_lock);
  72
  73        if (!afu->current_mode)
  74                goto err_put_afu;
  75
  76        if (!(ctx = cxl_context_alloc())) {
  77                rc = -ENOMEM;
  78                goto err_put_afu;
  79        }
  80
  81        if ((rc = cxl_context_init(ctx, afu, master, inode->i_mapping)))
  82                goto err_put_afu;
  83
  84        pr_devel("afu_open pe: %i\n", ctx->pe);
  85        file->private_data = ctx;
  86        cxl_ctx_get();
  87
  88        /* Our ref on the AFU will now hold the adapter */
  89        put_device(&adapter->dev);
  90
  91        return 0;
  92
  93err_put_afu:
  94        put_device(&afu->dev);
  95err_put_adapter:
  96        put_device(&adapter->dev);
  97        return rc;
  98}
  99static int afu_open(struct inode *inode, struct file *file)
 100{
 101        return __afu_open(inode, file, false);
 102}
 103
 104static int afu_master_open(struct inode *inode, struct file *file)
 105{
 106        return __afu_open(inode, file, true);
 107}
 108
 109static int afu_release(struct inode *inode, struct file *file)
 110{
 111        struct cxl_context *ctx = file->private_data;
 112
 113        pr_devel("%s: closing cxl file descriptor. pe: %i\n",
 114                 __func__, ctx->pe);
 115        cxl_context_detach(ctx);
 116
 117        mutex_lock(&ctx->mapping_lock);
 118        ctx->mapping = NULL;
 119        mutex_unlock(&ctx->mapping_lock);
 120
 121        put_device(&ctx->afu->dev);
 122
 123        /*
 124         * At this this point all bottom halfs have finished and we should be
 125         * getting no more IRQs from the hardware for this context.  Once it's
 126         * removed from the IDR (and RCU synchronised) it's safe to free the
 127         * sstp and context.
 128         */
 129        cxl_context_free(ctx);
 130
 131        cxl_ctx_put();
 132        return 0;
 133}
 134
 135static long afu_ioctl_start_work(struct cxl_context *ctx,
 136                                 struct cxl_ioctl_start_work __user *uwork)
 137{
 138        struct cxl_ioctl_start_work work;
 139        u64 amr = 0;
 140        int rc;
 141
 142        pr_devel("%s: pe: %i\n", __func__, ctx->pe);
 143
 144        /* Do this outside the status_mutex to avoid a circular dependency with
 145         * the locking in cxl_mmap_fault() */
 146        if (copy_from_user(&work, uwork,
 147                           sizeof(struct cxl_ioctl_start_work))) {
 148                rc = -EFAULT;
 149                goto out;
 150        }
 151
 152        mutex_lock(&ctx->status_mutex);
 153        if (ctx->status != OPENED) {
 154                rc = -EIO;
 155                goto out;
 156        }
 157
 158        /*
 159         * if any of the reserved fields are set or any of the unused
 160         * flags are set it's invalid
 161         */
 162        if (work.reserved1 || work.reserved2 || work.reserved3 ||
 163            work.reserved4 || work.reserved5 || work.reserved6 ||
 164            (work.flags & ~CXL_START_WORK_ALL)) {
 165                rc = -EINVAL;
 166                goto out;
 167        }
 168
 169        if (!(work.flags & CXL_START_WORK_NUM_IRQS))
 170                work.num_interrupts = ctx->afu->pp_irqs;
 171        else if ((work.num_interrupts < ctx->afu->pp_irqs) ||
 172                 (work.num_interrupts > ctx->afu->irqs_max)) {
 173                rc =  -EINVAL;
 174                goto out;
 175        }
 176        if ((rc = afu_register_irqs(ctx, work.num_interrupts)))
 177                goto out;
 178
 179        if (work.flags & CXL_START_WORK_AMR)
 180                amr = work.amr & mfspr(SPRN_UAMOR);
 181
 182        /*
 183         * We grab the PID here and not in the file open to allow for the case
 184         * where a process (master, some daemon, etc) has opened the chardev on
 185         * behalf of another process, so the AFU's mm gets bound to the process
 186         * that performs this ioctl and not the process that opened the file.
 187         */
 188        ctx->pid = get_pid(get_task_pid(current, PIDTYPE_PID));
 189
 190        trace_cxl_attach(ctx, work.work_element_descriptor, work.num_interrupts, amr);
 191
 192        if ((rc = cxl_attach_process(ctx, false, work.work_element_descriptor,
 193                                     amr))) {
 194                afu_release_irqs(ctx);
 195                goto out;
 196        }
 197
 198        ctx->status = STARTED;
 199        rc = 0;
 200out:
 201        mutex_unlock(&ctx->status_mutex);
 202        return rc;
 203}
 204static long afu_ioctl_process_element(struct cxl_context *ctx,
 205                                      int __user *upe)
 206{
 207        pr_devel("%s: pe: %i\n", __func__, ctx->pe);
 208
 209        if (copy_to_user(upe, &ctx->pe, sizeof(__u32)))
 210                return -EFAULT;
 211
 212        return 0;
 213}
 214
 215static long afu_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 216{
 217        struct cxl_context *ctx = file->private_data;
 218
 219        if (ctx->status == CLOSED)
 220                return -EIO;
 221
 222        pr_devel("afu_ioctl\n");
 223        switch (cmd) {
 224        case CXL_IOCTL_START_WORK:
 225                return afu_ioctl_start_work(ctx, (struct cxl_ioctl_start_work __user *)arg);
 226        case CXL_IOCTL_GET_PROCESS_ELEMENT:
 227                return afu_ioctl_process_element(ctx, (__u32 __user *)arg);
 228        }
 229        return -EINVAL;
 230}
 231
 232static long afu_compat_ioctl(struct file *file, unsigned int cmd,
 233                             unsigned long arg)
 234{
 235        return afu_ioctl(file, cmd, arg);
 236}
 237
 238static int afu_mmap(struct file *file, struct vm_area_struct *vm)
 239{
 240        struct cxl_context *ctx = file->private_data;
 241
 242        /* AFU must be started before we can MMIO */
 243        if (ctx->status != STARTED)
 244                return -EIO;
 245
 246        return cxl_context_iomap(ctx, vm);
 247}
 248
 249static unsigned int afu_poll(struct file *file, struct poll_table_struct *poll)
 250{
 251        struct cxl_context *ctx = file->private_data;
 252        int mask = 0;
 253        unsigned long flags;
 254
 255
 256        poll_wait(file, &ctx->wq, poll);
 257
 258        pr_devel("afu_poll wait done pe: %i\n", ctx->pe);
 259
 260        spin_lock_irqsave(&ctx->lock, flags);
 261        if (ctx->pending_irq || ctx->pending_fault ||
 262            ctx->pending_afu_err)
 263                mask |= POLLIN | POLLRDNORM;
 264        else if (ctx->status == CLOSED)
 265                /* Only error on closed when there are no futher events pending
 266                 */
 267                mask |= POLLERR;
 268        spin_unlock_irqrestore(&ctx->lock, flags);
 269
 270        pr_devel("afu_poll pe: %i returning %#x\n", ctx->pe, mask);
 271
 272        return mask;
 273}
 274
 275static inline int ctx_event_pending(struct cxl_context *ctx)
 276{
 277        return (ctx->pending_irq || ctx->pending_fault ||
 278            ctx->pending_afu_err || (ctx->status == CLOSED));
 279}
 280
 281static ssize_t afu_read(struct file *file, char __user *buf, size_t count,
 282                        loff_t *off)
 283{
 284        struct cxl_context *ctx = file->private_data;
 285        struct cxl_event event;
 286        unsigned long flags;
 287        int rc;
 288        DEFINE_WAIT(wait);
 289
 290        if (count < CXL_READ_MIN_SIZE)
 291                return -EINVAL;
 292
 293        spin_lock_irqsave(&ctx->lock, flags);
 294
 295        for (;;) {
 296                prepare_to_wait(&ctx->wq, &wait, TASK_INTERRUPTIBLE);
 297                if (ctx_event_pending(ctx))
 298                        break;
 299
 300                if (file->f_flags & O_NONBLOCK) {
 301                        rc = -EAGAIN;
 302                        goto out;
 303                }
 304
 305                if (signal_pending(current)) {
 306                        rc = -ERESTARTSYS;
 307                        goto out;
 308                }
 309
 310                spin_unlock_irqrestore(&ctx->lock, flags);
 311                pr_devel("afu_read going to sleep...\n");
 312                schedule();
 313                pr_devel("afu_read woken up\n");
 314                spin_lock_irqsave(&ctx->lock, flags);
 315        }
 316
 317        finish_wait(&ctx->wq, &wait);
 318
 319        memset(&event, 0, sizeof(event));
 320        event.header.process_element = ctx->pe;
 321        event.header.size = sizeof(struct cxl_event_header);
 322        if (ctx->pending_irq) {
 323                pr_devel("afu_read delivering AFU interrupt\n");
 324                event.header.size += sizeof(struct cxl_event_afu_interrupt);
 325                event.header.type = CXL_EVENT_AFU_INTERRUPT;
 326                event.irq.irq = find_first_bit(ctx->irq_bitmap, ctx->irq_count) + 1;
 327                clear_bit(event.irq.irq - 1, ctx->irq_bitmap);
 328                if (bitmap_empty(ctx->irq_bitmap, ctx->irq_count))
 329                        ctx->pending_irq = false;
 330        } else if (ctx->pending_fault) {
 331                pr_devel("afu_read delivering data storage fault\n");
 332                event.header.size += sizeof(struct cxl_event_data_storage);
 333                event.header.type = CXL_EVENT_DATA_STORAGE;
 334                event.fault.addr = ctx->fault_addr;
 335                event.fault.dsisr = ctx->fault_dsisr;
 336                ctx->pending_fault = false;
 337        } else if (ctx->pending_afu_err) {
 338                pr_devel("afu_read delivering afu error\n");
 339                event.header.size += sizeof(struct cxl_event_afu_error);
 340                event.header.type = CXL_EVENT_AFU_ERROR;
 341                event.afu_error.error = ctx->afu_err;
 342                ctx->pending_afu_err = false;
 343        } else if (ctx->status == CLOSED) {
 344                pr_devel("afu_read fatal error\n");
 345                spin_unlock_irqrestore(&ctx->lock, flags);
 346                return -EIO;
 347        } else
 348                WARN(1, "afu_read must be buggy\n");
 349
 350        spin_unlock_irqrestore(&ctx->lock, flags);
 351
 352        if (copy_to_user(buf, &event, event.header.size))
 353                return -EFAULT;
 354        return event.header.size;
 355
 356out:
 357        finish_wait(&ctx->wq, &wait);
 358        spin_unlock_irqrestore(&ctx->lock, flags);
 359        return rc;
 360}
 361
 362static const struct file_operations afu_fops = {
 363        .owner          = THIS_MODULE,
 364        .open           = afu_open,
 365        .poll           = afu_poll,
 366        .read           = afu_read,
 367        .release        = afu_release,
 368        .unlocked_ioctl = afu_ioctl,
 369        .compat_ioctl   = afu_compat_ioctl,
 370        .mmap           = afu_mmap,
 371};
 372
 373static const struct file_operations afu_master_fops = {
 374        .owner          = THIS_MODULE,
 375        .open           = afu_master_open,
 376        .poll           = afu_poll,
 377        .read           = afu_read,
 378        .release        = afu_release,
 379        .unlocked_ioctl = afu_ioctl,
 380        .compat_ioctl   = afu_compat_ioctl,
 381        .mmap           = afu_mmap,
 382};
 383
 384
 385static char *cxl_devnode(struct device *dev, umode_t *mode)
 386{
 387        if (CXL_DEVT_IS_CARD(dev->devt)) {
 388                /*
 389                 * These minor numbers will eventually be used to program the
 390                 * PSL and AFUs once we have dynamic reprogramming support
 391                 */
 392                return NULL;
 393        }
 394        return kasprintf(GFP_KERNEL, "cxl/%s", dev_name(dev));
 395}
 396
 397extern struct class *cxl_class;
 398
 399static int cxl_add_chardev(struct cxl_afu *afu, dev_t devt, struct cdev *cdev,
 400                           struct device **chardev, char *postfix, char *desc,
 401                           const struct file_operations *fops)
 402{
 403        struct device *dev;
 404        int rc;
 405
 406        cdev_init(cdev, fops);
 407        if ((rc = cdev_add(cdev, devt, 1))) {
 408                dev_err(&afu->dev, "Unable to add %s chardev: %i\n", desc, rc);
 409                return rc;
 410        }
 411
 412        dev = device_create(cxl_class, &afu->dev, devt, afu,
 413                        "afu%i.%i%s", afu->adapter->adapter_num, afu->slice, postfix);
 414        if (IS_ERR(dev)) {
 415                dev_err(&afu->dev, "Unable to create %s chardev in sysfs: %i\n", desc, rc);
 416                rc = PTR_ERR(dev);
 417                goto err;
 418        }
 419
 420        *chardev = dev;
 421
 422        return 0;
 423err:
 424        cdev_del(cdev);
 425        return rc;
 426}
 427
 428int cxl_chardev_d_afu_add(struct cxl_afu *afu)
 429{
 430        return cxl_add_chardev(afu, CXL_AFU_MKDEV_D(afu), &afu->afu_cdev_d,
 431                               &afu->chardev_d, "d", "dedicated",
 432                               &afu_master_fops); /* Uses master fops */
 433}
 434
 435int cxl_chardev_m_afu_add(struct cxl_afu *afu)
 436{
 437        return cxl_add_chardev(afu, CXL_AFU_MKDEV_M(afu), &afu->afu_cdev_m,
 438                               &afu->chardev_m, "m", "master",
 439                               &afu_master_fops);
 440}
 441
 442int cxl_chardev_s_afu_add(struct cxl_afu *afu)
 443{
 444        return cxl_add_chardev(afu, CXL_AFU_MKDEV_S(afu), &afu->afu_cdev_s,
 445                               &afu->chardev_s, "s", "shared",
 446                               &afu_fops);
 447}
 448
 449void cxl_chardev_afu_remove(struct cxl_afu *afu)
 450{
 451        if (afu->chardev_d) {
 452                cdev_del(&afu->afu_cdev_d);
 453                device_unregister(afu->chardev_d);
 454                afu->chardev_d = NULL;
 455        }
 456        if (afu->chardev_m) {
 457                cdev_del(&afu->afu_cdev_m);
 458                device_unregister(afu->chardev_m);
 459                afu->chardev_m = NULL;
 460        }
 461        if (afu->chardev_s) {
 462                cdev_del(&afu->afu_cdev_s);
 463                device_unregister(afu->chardev_s);
 464                afu->chardev_s = NULL;
 465        }
 466}
 467
 468int cxl_register_afu(struct cxl_afu *afu)
 469{
 470        afu->dev.class = cxl_class;
 471
 472        return device_register(&afu->dev);
 473}
 474
 475int cxl_register_adapter(struct cxl *adapter)
 476{
 477        adapter->dev.class = cxl_class;
 478
 479        /*
 480         * Future: When we support dynamically reprogramming the PSL & AFU we
 481         * will expose the interface to do that via a chardev:
 482         * adapter->dev.devt = CXL_CARD_MKDEV(adapter);
 483         */
 484
 485        return device_register(&adapter->dev);
 486}
 487
 488int __init cxl_file_init(void)
 489{
 490        int rc;
 491
 492        /*
 493         * If these change we really need to update API.  Either change some
 494         * flags or update API version number CXL_API_VERSION.
 495         */
 496        BUILD_BUG_ON(CXL_API_VERSION != 1);
 497        BUILD_BUG_ON(sizeof(struct cxl_ioctl_start_work) != 64);
 498        BUILD_BUG_ON(sizeof(struct cxl_event_header) != 8);
 499        BUILD_BUG_ON(sizeof(struct cxl_event_afu_interrupt) != 8);
 500        BUILD_BUG_ON(sizeof(struct cxl_event_data_storage) != 32);
 501        BUILD_BUG_ON(sizeof(struct cxl_event_afu_error) != 16);
 502
 503        if ((rc = alloc_chrdev_region(&cxl_dev, 0, CXL_NUM_MINORS, "cxl"))) {
 504                pr_err("Unable to allocate CXL major number: %i\n", rc);
 505                return rc;
 506        }
 507
 508        pr_devel("CXL device allocated, MAJOR %i\n", MAJOR(cxl_dev));
 509
 510        cxl_class = class_create(THIS_MODULE, "cxl");
 511        if (IS_ERR(cxl_class)) {
 512                pr_err("Unable to create CXL class\n");
 513                rc = PTR_ERR(cxl_class);
 514                goto err;
 515        }
 516        cxl_class->devnode = cxl_devnode;
 517
 518        return 0;
 519
 520err:
 521        unregister_chrdev_region(cxl_dev, CXL_NUM_MINORS);
 522        return rc;
 523}
 524
 525void cxl_file_exit(void)
 526{
 527        unregister_chrdev_region(cxl_dev, CXL_NUM_MINORS);
 528        class_destroy(cxl_class);
 529}
 530