Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Freescale Hypervisor Management Driver
0003 
0004  * Copyright (C) 2008-2011 Freescale Semiconductor, Inc.
0005  * Author: Timur Tabi <timur@freescale.com>
0006  *
0007  * This file is licensed under the terms of the GNU General Public License
0008  * version 2.  This program is licensed "as is" without any warranty of any
0009  * kind, whether express or implied.
0010  *
0011  * The Freescale hypervisor management driver provides several services to
0012  * drivers and applications related to the Freescale hypervisor:
0013  *
0014  * 1. An ioctl interface for querying and managing partitions.
0015  *
0016  * 2. A file interface to reading incoming doorbells.
0017  *
0018  * 3. An interrupt handler for shutting down the partition upon receiving the
0019  *    shutdown doorbell from a manager partition.
0020  *
0021  * 4. A kernel interface for receiving callbacks when a managed partition
0022  *    shuts down.
0023  */
0024 
0025 #include <linux/kernel.h>
0026 #include <linux/module.h>
0027 #include <linux/init.h>
0028 #include <linux/types.h>
0029 #include <linux/err.h>
0030 #include <linux/fs.h>
0031 #include <linux/miscdevice.h>
0032 #include <linux/mm.h>
0033 #include <linux/pagemap.h>
0034 #include <linux/slab.h>
0035 #include <linux/poll.h>
0036 #include <linux/of.h>
0037 #include <linux/of_irq.h>
0038 #include <linux/reboot.h>
0039 #include <linux/uaccess.h>
0040 #include <linux/notifier.h>
0041 #include <linux/interrupt.h>
0042 
0043 #include <linux/io.h>
0044 #include <asm/fsl_hcalls.h>
0045 
0046 #include <linux/fsl_hypervisor.h>
0047 
0048 static BLOCKING_NOTIFIER_HEAD(failover_subscribers);
0049 
0050 /*
0051  * Ioctl interface for FSL_HV_IOCTL_PARTITION_RESTART
0052  *
0053  * Restart a running partition
0054  */
0055 static long ioctl_restart(struct fsl_hv_ioctl_restart __user *p)
0056 {
0057     struct fsl_hv_ioctl_restart param;
0058 
0059     /* Get the parameters from the user */
0060     if (copy_from_user(&param, p, sizeof(struct fsl_hv_ioctl_restart)))
0061         return -EFAULT;
0062 
0063     param.ret = fh_partition_restart(param.partition);
0064 
0065     if (copy_to_user(&p->ret, &param.ret, sizeof(__u32)))
0066         return -EFAULT;
0067 
0068     return 0;
0069 }
0070 
0071 /*
0072  * Ioctl interface for FSL_HV_IOCTL_PARTITION_STATUS
0073  *
0074  * Query the status of a partition
0075  */
0076 static long ioctl_status(struct fsl_hv_ioctl_status __user *p)
0077 {
0078     struct fsl_hv_ioctl_status param;
0079     u32 status;
0080 
0081     /* Get the parameters from the user */
0082     if (copy_from_user(&param, p, sizeof(struct fsl_hv_ioctl_status)))
0083         return -EFAULT;
0084 
0085     param.ret = fh_partition_get_status(param.partition, &status);
0086     if (!param.ret)
0087         param.status = status;
0088 
0089     if (copy_to_user(p, &param, sizeof(struct fsl_hv_ioctl_status)))
0090         return -EFAULT;
0091 
0092     return 0;
0093 }
0094 
0095 /*
0096  * Ioctl interface for FSL_HV_IOCTL_PARTITION_START
0097  *
0098  * Start a stopped partition.
0099  */
0100 static long ioctl_start(struct fsl_hv_ioctl_start __user *p)
0101 {
0102     struct fsl_hv_ioctl_start param;
0103 
0104     /* Get the parameters from the user */
0105     if (copy_from_user(&param, p, sizeof(struct fsl_hv_ioctl_start)))
0106         return -EFAULT;
0107 
0108     param.ret = fh_partition_start(param.partition, param.entry_point,
0109                        param.load);
0110 
0111     if (copy_to_user(&p->ret, &param.ret, sizeof(__u32)))
0112         return -EFAULT;
0113 
0114     return 0;
0115 }
0116 
0117 /*
0118  * Ioctl interface for FSL_HV_IOCTL_PARTITION_STOP
0119  *
0120  * Stop a running partition
0121  */
0122 static long ioctl_stop(struct fsl_hv_ioctl_stop __user *p)
0123 {
0124     struct fsl_hv_ioctl_stop param;
0125 
0126     /* Get the parameters from the user */
0127     if (copy_from_user(&param, p, sizeof(struct fsl_hv_ioctl_stop)))
0128         return -EFAULT;
0129 
0130     param.ret = fh_partition_stop(param.partition);
0131 
0132     if (copy_to_user(&p->ret, &param.ret, sizeof(__u32)))
0133         return -EFAULT;
0134 
0135     return 0;
0136 }
0137 
0138 /*
0139  * Ioctl interface for FSL_HV_IOCTL_MEMCPY
0140  *
0141  * The FH_MEMCPY hypercall takes an array of address/address/size structures
0142  * to represent the data being copied.  As a convenience to the user, this
0143  * ioctl takes a user-create buffer and a pointer to a guest physically
0144  * contiguous buffer in the remote partition, and creates the
0145  * address/address/size array for the hypercall.
0146  */
0147 static long ioctl_memcpy(struct fsl_hv_ioctl_memcpy __user *p)
0148 {
0149     struct fsl_hv_ioctl_memcpy param;
0150 
0151     struct page **pages = NULL;
0152     void *sg_list_unaligned = NULL;
0153     struct fh_sg_list *sg_list = NULL;
0154 
0155     unsigned int num_pages;
0156     unsigned long lb_offset; /* Offset within a page of the local buffer */
0157 
0158     unsigned int i;
0159     long ret = 0;
0160     int num_pinned = 0; /* return value from get_user_pages_fast() */
0161     phys_addr_t remote_paddr; /* The next address in the remote buffer */
0162     uint32_t count; /* The number of bytes left to copy */
0163 
0164     /* Get the parameters from the user */
0165     if (copy_from_user(&param, p, sizeof(struct fsl_hv_ioctl_memcpy)))
0166         return -EFAULT;
0167 
0168     /*
0169      * One partition must be local, the other must be remote.  In other
0170      * words, if source and target are both -1, or are both not -1, then
0171      * return an error.
0172      */
0173     if ((param.source == -1) == (param.target == -1))
0174         return -EINVAL;
0175 
0176     /*
0177      * The array of pages returned by get_user_pages_fast() covers only
0178      * page-aligned memory.  Since the user buffer is probably not
0179      * page-aligned, we need to handle the discrepancy.
0180      *
0181      * We calculate the offset within a page of the S/G list, and make
0182      * adjustments accordingly.  This will result in a page list that looks
0183      * like this:
0184      *
0185      *      ----    <-- first page starts before the buffer
0186      *     |    |
0187      *     |////|-> ----
0188      *     |////|  |    |
0189      *      ----   |    |
0190      *             |    |
0191      *      ----   |    |
0192      *     |////|  |    |
0193      *     |////|  |    |
0194      *     |////|  |    |
0195      *      ----   |    |
0196      *             |    |
0197      *      ----   |    |
0198      *     |////|  |    |
0199      *     |////|  |    |
0200      *     |////|  |    |
0201      *      ----   |    |
0202      *             |    |
0203      *      ----   |    |
0204      *     |////|  |    |
0205      *     |////|-> ----
0206      *     |    |   <-- last page ends after the buffer
0207      *      ----
0208      *
0209      * The distance between the start of the first page and the start of the
0210      * buffer is lb_offset.  The hashed (///) areas are the parts of the
0211      * page list that contain the actual buffer.
0212      *
0213      * The advantage of this approach is that the number of pages is
0214      * equal to the number of entries in the S/G list that we give to the
0215      * hypervisor.
0216      */
0217     lb_offset = param.local_vaddr & (PAGE_SIZE - 1);
0218     if (param.count == 0 ||
0219         param.count > U64_MAX - lb_offset - PAGE_SIZE + 1)
0220         return -EINVAL;
0221     num_pages = (param.count + lb_offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
0222 
0223     /* Allocate the buffers we need */
0224 
0225     /*
0226      * 'pages' is an array of struct page pointers that's initialized by
0227      * get_user_pages_fast().
0228      */
0229     pages = kcalloc(num_pages, sizeof(struct page *), GFP_KERNEL);
0230     if (!pages) {
0231         pr_debug("fsl-hv: could not allocate page list\n");
0232         return -ENOMEM;
0233     }
0234 
0235     /*
0236      * sg_list is the list of fh_sg_list objects that we pass to the
0237      * hypervisor.
0238      */
0239     sg_list_unaligned = kmalloc(num_pages * sizeof(struct fh_sg_list) +
0240         sizeof(struct fh_sg_list) - 1, GFP_KERNEL);
0241     if (!sg_list_unaligned) {
0242         pr_debug("fsl-hv: could not allocate S/G list\n");
0243         ret = -ENOMEM;
0244         goto free_pages;
0245     }
0246     sg_list = PTR_ALIGN(sg_list_unaligned, sizeof(struct fh_sg_list));
0247 
0248     /* Get the physical addresses of the source buffer */
0249     num_pinned = get_user_pages_fast(param.local_vaddr - lb_offset,
0250         num_pages, param.source != -1 ? FOLL_WRITE : 0, pages);
0251 
0252     if (num_pinned != num_pages) {
0253         pr_debug("fsl-hv: could not lock source buffer\n");
0254         ret = (num_pinned < 0) ? num_pinned : -EFAULT;
0255         goto exit;
0256     }
0257 
0258     /*
0259      * Build the fh_sg_list[] array.  The first page is special
0260      * because it's misaligned.
0261      */
0262     if (param.source == -1) {
0263         sg_list[0].source = page_to_phys(pages[0]) + lb_offset;
0264         sg_list[0].target = param.remote_paddr;
0265     } else {
0266         sg_list[0].source = param.remote_paddr;
0267         sg_list[0].target = page_to_phys(pages[0]) + lb_offset;
0268     }
0269     sg_list[0].size = min_t(uint64_t, param.count, PAGE_SIZE - lb_offset);
0270 
0271     remote_paddr = param.remote_paddr + sg_list[0].size;
0272     count = param.count - sg_list[0].size;
0273 
0274     for (i = 1; i < num_pages; i++) {
0275         if (param.source == -1) {
0276             /* local to remote */
0277             sg_list[i].source = page_to_phys(pages[i]);
0278             sg_list[i].target = remote_paddr;
0279         } else {
0280             /* remote to local */
0281             sg_list[i].source = remote_paddr;
0282             sg_list[i].target = page_to_phys(pages[i]);
0283         }
0284         sg_list[i].size = min_t(uint64_t, count, PAGE_SIZE);
0285 
0286         remote_paddr += sg_list[i].size;
0287         count -= sg_list[i].size;
0288     }
0289 
0290     param.ret = fh_partition_memcpy(param.source, param.target,
0291         virt_to_phys(sg_list), num_pages);
0292 
0293 exit:
0294     if (pages && (num_pinned > 0)) {
0295         for (i = 0; i < num_pinned; i++)
0296             put_page(pages[i]);
0297     }
0298 
0299     kfree(sg_list_unaligned);
0300 free_pages:
0301     kfree(pages);
0302 
0303     if (!ret)
0304         if (copy_to_user(&p->ret, &param.ret, sizeof(__u32)))
0305             return -EFAULT;
0306 
0307     return ret;
0308 }
0309 
0310 /*
0311  * Ioctl interface for FSL_HV_IOCTL_DOORBELL
0312  *
0313  * Ring a doorbell
0314  */
0315 static long ioctl_doorbell(struct fsl_hv_ioctl_doorbell __user *p)
0316 {
0317     struct fsl_hv_ioctl_doorbell param;
0318 
0319     /* Get the parameters from the user. */
0320     if (copy_from_user(&param, p, sizeof(struct fsl_hv_ioctl_doorbell)))
0321         return -EFAULT;
0322 
0323     param.ret = ev_doorbell_send(param.doorbell);
0324 
0325     if (copy_to_user(&p->ret, &param.ret, sizeof(__u32)))
0326         return -EFAULT;
0327 
0328     return 0;
0329 }
0330 
0331 static long ioctl_dtprop(struct fsl_hv_ioctl_prop __user *p, int set)
0332 {
0333     struct fsl_hv_ioctl_prop param;
0334     char __user *upath, *upropname;
0335     void __user *upropval;
0336     char *path, *propname;
0337     void *propval;
0338     int ret = 0;
0339 
0340     /* Get the parameters from the user. */
0341     if (copy_from_user(&param, p, sizeof(struct fsl_hv_ioctl_prop)))
0342         return -EFAULT;
0343 
0344     upath = (char __user *)(uintptr_t)param.path;
0345     upropname = (char __user *)(uintptr_t)param.propname;
0346     upropval = (void __user *)(uintptr_t)param.propval;
0347 
0348     path = strndup_user(upath, FH_DTPROP_MAX_PATHLEN);
0349     if (IS_ERR(path))
0350         return PTR_ERR(path);
0351 
0352     propname = strndup_user(upropname, FH_DTPROP_MAX_PATHLEN);
0353     if (IS_ERR(propname)) {
0354         ret = PTR_ERR(propname);
0355         goto err_free_path;
0356     }
0357 
0358     if (param.proplen > FH_DTPROP_MAX_PROPLEN) {
0359         ret = -EINVAL;
0360         goto err_free_propname;
0361     }
0362 
0363     propval = kmalloc(param.proplen, GFP_KERNEL);
0364     if (!propval) {
0365         ret = -ENOMEM;
0366         goto err_free_propname;
0367     }
0368 
0369     if (set) {
0370         if (copy_from_user(propval, upropval, param.proplen)) {
0371             ret = -EFAULT;
0372             goto err_free_propval;
0373         }
0374 
0375         param.ret = fh_partition_set_dtprop(param.handle,
0376                             virt_to_phys(path),
0377                             virt_to_phys(propname),
0378                             virt_to_phys(propval),
0379                             param.proplen);
0380     } else {
0381         param.ret = fh_partition_get_dtprop(param.handle,
0382                             virt_to_phys(path),
0383                             virt_to_phys(propname),
0384                             virt_to_phys(propval),
0385                             &param.proplen);
0386 
0387         if (param.ret == 0) {
0388             if (copy_to_user(upropval, propval, param.proplen) ||
0389                 put_user(param.proplen, &p->proplen)) {
0390                 ret = -EFAULT;
0391                 goto err_free_propval;
0392             }
0393         }
0394     }
0395 
0396     if (put_user(param.ret, &p->ret))
0397         ret = -EFAULT;
0398 
0399 err_free_propval:
0400     kfree(propval);
0401 err_free_propname:
0402     kfree(propname);
0403 err_free_path:
0404     kfree(path);
0405 
0406     return ret;
0407 }
0408 
0409 /*
0410  * Ioctl main entry point
0411  */
0412 static long fsl_hv_ioctl(struct file *file, unsigned int cmd,
0413              unsigned long argaddr)
0414 {
0415     void __user *arg = (void __user *)argaddr;
0416     long ret;
0417 
0418     switch (cmd) {
0419     case FSL_HV_IOCTL_PARTITION_RESTART:
0420         ret = ioctl_restart(arg);
0421         break;
0422     case FSL_HV_IOCTL_PARTITION_GET_STATUS:
0423         ret = ioctl_status(arg);
0424         break;
0425     case FSL_HV_IOCTL_PARTITION_START:
0426         ret = ioctl_start(arg);
0427         break;
0428     case FSL_HV_IOCTL_PARTITION_STOP:
0429         ret = ioctl_stop(arg);
0430         break;
0431     case FSL_HV_IOCTL_MEMCPY:
0432         ret = ioctl_memcpy(arg);
0433         break;
0434     case FSL_HV_IOCTL_DOORBELL:
0435         ret = ioctl_doorbell(arg);
0436         break;
0437     case FSL_HV_IOCTL_GETPROP:
0438         ret = ioctl_dtprop(arg, 0);
0439         break;
0440     case FSL_HV_IOCTL_SETPROP:
0441         ret = ioctl_dtprop(arg, 1);
0442         break;
0443     default:
0444         pr_debug("fsl-hv: bad ioctl dir=%u type=%u cmd=%u size=%u\n",
0445              _IOC_DIR(cmd), _IOC_TYPE(cmd), _IOC_NR(cmd),
0446              _IOC_SIZE(cmd));
0447         return -ENOTTY;
0448     }
0449 
0450     return ret;
0451 }
0452 
0453 /* Linked list of processes that have us open */
0454 static struct list_head db_list;
0455 
0456 /* spinlock for db_list */
0457 static DEFINE_SPINLOCK(db_list_lock);
0458 
0459 /* The size of the doorbell event queue.  This must be a power of two. */
0460 #define QSIZE   16
0461 
0462 /* Returns the next head/tail pointer, wrapping around the queue if necessary */
0463 #define nextp(x) (((x) + 1) & (QSIZE - 1))
0464 
0465 /* Per-open data structure */
0466 struct doorbell_queue {
0467     struct list_head list;
0468     spinlock_t lock;
0469     wait_queue_head_t wait;
0470     unsigned int head;
0471     unsigned int tail;
0472     uint32_t q[QSIZE];
0473 };
0474 
0475 /* Linked list of ISRs that we registered */
0476 struct list_head isr_list;
0477 
0478 /* Per-ISR data structure */
0479 struct doorbell_isr {
0480     struct list_head list;
0481     unsigned int irq;
0482     uint32_t doorbell;  /* The doorbell handle */
0483     uint32_t partition; /* The partition handle, if used */
0484 };
0485 
0486 /*
0487  * Add a doorbell to all of the doorbell queues
0488  */
0489 static void fsl_hv_queue_doorbell(uint32_t doorbell)
0490 {
0491     struct doorbell_queue *dbq;
0492     unsigned long flags;
0493 
0494     /* Prevent another core from modifying db_list */
0495     spin_lock_irqsave(&db_list_lock, flags);
0496 
0497     list_for_each_entry(dbq, &db_list, list) {
0498         if (dbq->head != nextp(dbq->tail)) {
0499             dbq->q[dbq->tail] = doorbell;
0500             /*
0501              * This memory barrier eliminates the need to grab
0502              * the spinlock for dbq.
0503              */
0504             smp_wmb();
0505             dbq->tail = nextp(dbq->tail);
0506             wake_up_interruptible(&dbq->wait);
0507         }
0508     }
0509 
0510     spin_unlock_irqrestore(&db_list_lock, flags);
0511 }
0512 
0513 /*
0514  * Interrupt handler for all doorbells
0515  *
0516  * We use the same interrupt handler for all doorbells.  Whenever a doorbell
0517  * is rung, and we receive an interrupt, we just put the handle for that
0518  * doorbell (passed to us as *data) into all of the queues.
0519  */
0520 static irqreturn_t fsl_hv_isr(int irq, void *data)
0521 {
0522     fsl_hv_queue_doorbell((uintptr_t) data);
0523 
0524     return IRQ_HANDLED;
0525 }
0526 
0527 /*
0528  * State change thread function
0529  *
0530  * The state change notification arrives in an interrupt, but we can't call
0531  * blocking_notifier_call_chain() in an interrupt handler.  We could call
0532  * atomic_notifier_call_chain(), but that would require the clients' call-back
0533  * function to run in interrupt context.  Since we don't want to impose that
0534  * restriction on the clients, we use a threaded IRQ to process the
0535  * notification in kernel context.
0536  */
0537 static irqreturn_t fsl_hv_state_change_thread(int irq, void *data)
0538 {
0539     struct doorbell_isr *dbisr = data;
0540 
0541     blocking_notifier_call_chain(&failover_subscribers, dbisr->partition,
0542                      NULL);
0543 
0544     return IRQ_HANDLED;
0545 }
0546 
0547 /*
0548  * Interrupt handler for state-change doorbells
0549  */
0550 static irqreturn_t fsl_hv_state_change_isr(int irq, void *data)
0551 {
0552     unsigned int status;
0553     struct doorbell_isr *dbisr = data;
0554     int ret;
0555 
0556     /* It's still a doorbell, so add it to all the queues. */
0557     fsl_hv_queue_doorbell(dbisr->doorbell);
0558 
0559     /* Determine the new state, and if it's stopped, notify the clients. */
0560     ret = fh_partition_get_status(dbisr->partition, &status);
0561     if (!ret && (status == FH_PARTITION_STOPPED))
0562         return IRQ_WAKE_THREAD;
0563 
0564     return IRQ_HANDLED;
0565 }
0566 
0567 /*
0568  * Returns a bitmask indicating whether a read will block
0569  */
0570 static __poll_t fsl_hv_poll(struct file *filp, struct poll_table_struct *p)
0571 {
0572     struct doorbell_queue *dbq = filp->private_data;
0573     unsigned long flags;
0574     __poll_t mask;
0575 
0576     spin_lock_irqsave(&dbq->lock, flags);
0577 
0578     poll_wait(filp, &dbq->wait, p);
0579     mask = (dbq->head == dbq->tail) ? 0 : (EPOLLIN | EPOLLRDNORM);
0580 
0581     spin_unlock_irqrestore(&dbq->lock, flags);
0582 
0583     return mask;
0584 }
0585 
0586 /*
0587  * Return the handles for any incoming doorbells
0588  *
0589  * If there are doorbell handles in the queue for this open instance, then
0590  * return them to the caller as an array of 32-bit integers.  Otherwise,
0591  * block until there is at least one handle to return.
0592  */
0593 static ssize_t fsl_hv_read(struct file *filp, char __user *buf, size_t len,
0594                loff_t *off)
0595 {
0596     struct doorbell_queue *dbq = filp->private_data;
0597     uint32_t __user *p = (uint32_t __user *) buf; /* for put_user() */
0598     unsigned long flags;
0599     ssize_t count = 0;
0600 
0601     /* Make sure we stop when the user buffer is full. */
0602     while (len >= sizeof(uint32_t)) {
0603         uint32_t dbell; /* Local copy of doorbell queue data */
0604 
0605         spin_lock_irqsave(&dbq->lock, flags);
0606 
0607         /*
0608          * If the queue is empty, then either we're done or we need
0609          * to block.  If the application specified O_NONBLOCK, then
0610          * we return the appropriate error code.
0611          */
0612         if (dbq->head == dbq->tail) {
0613             spin_unlock_irqrestore(&dbq->lock, flags);
0614             if (count)
0615                 break;
0616             if (filp->f_flags & O_NONBLOCK)
0617                 return -EAGAIN;
0618             if (wait_event_interruptible(dbq->wait,
0619                              dbq->head != dbq->tail))
0620                 return -ERESTARTSYS;
0621             continue;
0622         }
0623 
0624         /*
0625          * Even though we have an smp_wmb() in the ISR, the core
0626          * might speculatively execute the "dbell = ..." below while
0627          * it's evaluating the if-statement above.  In that case, the
0628          * value put into dbell could be stale if the core accepts the
0629          * speculation. To prevent that, we need a read memory barrier
0630          * here as well.
0631          */
0632         smp_rmb();
0633 
0634         /* Copy the data to a temporary local buffer, because
0635          * we can't call copy_to_user() from inside a spinlock
0636          */
0637         dbell = dbq->q[dbq->head];
0638         dbq->head = nextp(dbq->head);
0639 
0640         spin_unlock_irqrestore(&dbq->lock, flags);
0641 
0642         if (put_user(dbell, p))
0643             return -EFAULT;
0644         p++;
0645         count += sizeof(uint32_t);
0646         len -= sizeof(uint32_t);
0647     }
0648 
0649     return count;
0650 }
0651 
0652 /*
0653  * Open the driver and prepare for reading doorbells.
0654  *
0655  * Every time an application opens the driver, we create a doorbell queue
0656  * for that file handle.  This queue is used for any incoming doorbells.
0657  */
0658 static int fsl_hv_open(struct inode *inode, struct file *filp)
0659 {
0660     struct doorbell_queue *dbq;
0661     unsigned long flags;
0662 
0663     dbq = kzalloc(sizeof(struct doorbell_queue), GFP_KERNEL);
0664     if (!dbq) {
0665         pr_err("fsl-hv: out of memory\n");
0666         return -ENOMEM;
0667     }
0668 
0669     spin_lock_init(&dbq->lock);
0670     init_waitqueue_head(&dbq->wait);
0671 
0672     spin_lock_irqsave(&db_list_lock, flags);
0673     list_add(&dbq->list, &db_list);
0674     spin_unlock_irqrestore(&db_list_lock, flags);
0675 
0676     filp->private_data = dbq;
0677 
0678     return 0;
0679 }
0680 
0681 /*
0682  * Close the driver
0683  */
0684 static int fsl_hv_close(struct inode *inode, struct file *filp)
0685 {
0686     struct doorbell_queue *dbq = filp->private_data;
0687     unsigned long flags;
0688 
0689     spin_lock_irqsave(&db_list_lock, flags);
0690     list_del(&dbq->list);
0691     spin_unlock_irqrestore(&db_list_lock, flags);
0692 
0693     kfree(dbq);
0694 
0695     return 0;
0696 }
0697 
0698 static const struct file_operations fsl_hv_fops = {
0699     .owner = THIS_MODULE,
0700     .open = fsl_hv_open,
0701     .release = fsl_hv_close,
0702     .poll = fsl_hv_poll,
0703     .read = fsl_hv_read,
0704     .unlocked_ioctl = fsl_hv_ioctl,
0705     .compat_ioctl = compat_ptr_ioctl,
0706 };
0707 
0708 static struct miscdevice fsl_hv_misc_dev = {
0709     MISC_DYNAMIC_MINOR,
0710     "fsl-hv",
0711     &fsl_hv_fops
0712 };
0713 
0714 static irqreturn_t fsl_hv_shutdown_isr(int irq, void *data)
0715 {
0716     orderly_poweroff(false);
0717 
0718     return IRQ_HANDLED;
0719 }
0720 
0721 /*
0722  * Returns the handle of the parent of the given node
0723  *
0724  * The handle is the value of the 'hv-handle' property
0725  */
0726 static int get_parent_handle(struct device_node *np)
0727 {
0728     struct device_node *parent;
0729     const uint32_t *prop;
0730     uint32_t handle;
0731     int len;
0732 
0733     parent = of_get_parent(np);
0734     if (!parent)
0735         /* It's not really possible for this to fail */
0736         return -ENODEV;
0737 
0738     /*
0739      * The proper name for the handle property is "hv-handle", but some
0740      * older versions of the hypervisor used "reg".
0741      */
0742     prop = of_get_property(parent, "hv-handle", &len);
0743     if (!prop)
0744         prop = of_get_property(parent, "reg", &len);
0745 
0746     if (!prop || (len != sizeof(uint32_t))) {
0747         /* This can happen only if the node is malformed */
0748         of_node_put(parent);
0749         return -ENODEV;
0750     }
0751 
0752     handle = be32_to_cpup(prop);
0753     of_node_put(parent);
0754 
0755     return handle;
0756 }
0757 
0758 /*
0759  * Register a callback for failover events
0760  *
0761  * This function is called by device drivers to register their callback
0762  * functions for fail-over events.
0763  */
0764 int fsl_hv_failover_register(struct notifier_block *nb)
0765 {
0766     return blocking_notifier_chain_register(&failover_subscribers, nb);
0767 }
0768 EXPORT_SYMBOL(fsl_hv_failover_register);
0769 
0770 /*
0771  * Unregister a callback for failover events
0772  */
0773 int fsl_hv_failover_unregister(struct notifier_block *nb)
0774 {
0775     return blocking_notifier_chain_unregister(&failover_subscribers, nb);
0776 }
0777 EXPORT_SYMBOL(fsl_hv_failover_unregister);
0778 
0779 /*
0780  * Return TRUE if we're running under FSL hypervisor
0781  *
0782  * This function checks to see if we're running under the Freescale
0783  * hypervisor, and returns zero if we're not, or non-zero if we are.
0784  *
0785  * First, it checks if MSR[GS]==1, which means we're running under some
0786  * hypervisor.  Then it checks if there is a hypervisor node in the device
0787  * tree.  Currently, that means there needs to be a node in the root called
0788  * "hypervisor" and which has a property named "fsl,hv-version".
0789  */
0790 static int has_fsl_hypervisor(void)
0791 {
0792     struct device_node *node;
0793     int ret;
0794 
0795     node = of_find_node_by_path("/hypervisor");
0796     if (!node)
0797         return 0;
0798 
0799     ret = of_find_property(node, "fsl,hv-version", NULL) != NULL;
0800 
0801     of_node_put(node);
0802 
0803     return ret;
0804 }
0805 
0806 /*
0807  * Freescale hypervisor management driver init
0808  *
0809  * This function is called when this module is loaded.
0810  *
0811  * Register ourselves as a miscellaneous driver.  This will register the
0812  * fops structure and create the right sysfs entries for udev.
0813  */
0814 static int __init fsl_hypervisor_init(void)
0815 {
0816     struct device_node *np;
0817     struct doorbell_isr *dbisr, *n;
0818     int ret;
0819 
0820     pr_info("Freescale hypervisor management driver\n");
0821 
0822     if (!has_fsl_hypervisor()) {
0823         pr_info("fsl-hv: no hypervisor found\n");
0824         return -ENODEV;
0825     }
0826 
0827     ret = misc_register(&fsl_hv_misc_dev);
0828     if (ret) {
0829         pr_err("fsl-hv: cannot register device\n");
0830         return ret;
0831     }
0832 
0833     INIT_LIST_HEAD(&db_list);
0834     INIT_LIST_HEAD(&isr_list);
0835 
0836     for_each_compatible_node(np, NULL, "epapr,hv-receive-doorbell") {
0837         unsigned int irq;
0838         const uint32_t *handle;
0839 
0840         handle = of_get_property(np, "interrupts", NULL);
0841         irq = irq_of_parse_and_map(np, 0);
0842         if (!handle || (irq == NO_IRQ)) {
0843             pr_err("fsl-hv: no 'interrupts' property in %pOF node\n",
0844                 np);
0845             continue;
0846         }
0847 
0848         dbisr = kzalloc(sizeof(*dbisr), GFP_KERNEL);
0849         if (!dbisr)
0850             goto out_of_memory;
0851 
0852         dbisr->irq = irq;
0853         dbisr->doorbell = be32_to_cpup(handle);
0854 
0855         if (of_device_is_compatible(np, "fsl,hv-shutdown-doorbell")) {
0856             /* The shutdown doorbell gets its own ISR */
0857             ret = request_irq(irq, fsl_hv_shutdown_isr, 0,
0858                       np->name, NULL);
0859         } else if (of_device_is_compatible(np,
0860             "fsl,hv-state-change-doorbell")) {
0861             /*
0862              * The state change doorbell triggers a notification if
0863              * the state of the managed partition changes to
0864              * "stopped". We need a separate interrupt handler for
0865              * that, and we also need to know the handle of the
0866              * target partition, not just the handle of the
0867              * doorbell.
0868              */
0869             dbisr->partition = ret = get_parent_handle(np);
0870             if (ret < 0) {
0871                 pr_err("fsl-hv: node %pOF has missing or "
0872                        "malformed parent\n", np);
0873                 kfree(dbisr);
0874                 continue;
0875             }
0876             ret = request_threaded_irq(irq, fsl_hv_state_change_isr,
0877                            fsl_hv_state_change_thread,
0878                            0, np->name, dbisr);
0879         } else
0880             ret = request_irq(irq, fsl_hv_isr, 0, np->name, dbisr);
0881 
0882         if (ret < 0) {
0883             pr_err("fsl-hv: could not request irq %u for node %pOF\n",
0884                    irq, np);
0885             kfree(dbisr);
0886             continue;
0887         }
0888 
0889         list_add(&dbisr->list, &isr_list);
0890 
0891         pr_info("fsl-hv: registered handler for doorbell %u\n",
0892             dbisr->doorbell);
0893     }
0894 
0895     return 0;
0896 
0897 out_of_memory:
0898     list_for_each_entry_safe(dbisr, n, &isr_list, list) {
0899         free_irq(dbisr->irq, dbisr);
0900         list_del(&dbisr->list);
0901         kfree(dbisr);
0902     }
0903 
0904     misc_deregister(&fsl_hv_misc_dev);
0905 
0906     return -ENOMEM;
0907 }
0908 
0909 /*
0910  * Freescale hypervisor management driver termination
0911  *
0912  * This function is called when this driver is unloaded.
0913  */
0914 static void __exit fsl_hypervisor_exit(void)
0915 {
0916     struct doorbell_isr *dbisr, *n;
0917 
0918     list_for_each_entry_safe(dbisr, n, &isr_list, list) {
0919         free_irq(dbisr->irq, dbisr);
0920         list_del(&dbisr->list);
0921         kfree(dbisr);
0922     }
0923 
0924     misc_deregister(&fsl_hv_misc_dev);
0925 }
0926 
0927 module_init(fsl_hypervisor_init);
0928 module_exit(fsl_hypervisor_exit);
0929 
0930 MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
0931 MODULE_DESCRIPTION("Freescale hypervisor management driver");
0932 MODULE_LICENSE("GPL v2");