Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2015, 2016 IBM Corporation
0004  * Copyright (C) 2016 Intel Corporation
0005  *
0006  * Author: Stefan Berger <stefanb@us.ibm.com>
0007  *
0008  * Maintained by: <tpmdd-devel@lists.sourceforge.net>
0009  *
0010  * Device driver for vTPM (vTPM proxy driver)
0011  */
0012 
0013 #include <linux/types.h>
0014 #include <linux/spinlock.h>
0015 #include <linux/uaccess.h>
0016 #include <linux/wait.h>
0017 #include <linux/miscdevice.h>
0018 #include <linux/vtpm_proxy.h>
0019 #include <linux/file.h>
0020 #include <linux/anon_inodes.h>
0021 #include <linux/poll.h>
0022 #include <linux/compat.h>
0023 
0024 #include "tpm.h"
0025 
0026 #define VTPM_PROXY_REQ_COMPLETE_FLAG  BIT(0)
0027 
0028 struct proxy_dev {
0029     struct tpm_chip *chip;
0030 
0031     u32 flags;                   /* public API flags */
0032 
0033     wait_queue_head_t wq;
0034 
0035     struct mutex buf_lock;       /* protect buffer and flags */
0036 
0037     long state;                  /* internal state */
0038 #define STATE_OPENED_FLAG        BIT(0)
0039 #define STATE_WAIT_RESPONSE_FLAG BIT(1)  /* waiting for emulator response */
0040 #define STATE_REGISTERED_FLAG    BIT(2)
0041 #define STATE_DRIVER_COMMAND     BIT(3)  /* sending a driver specific command */
0042 
0043     size_t req_len;              /* length of queued TPM request */
0044     size_t resp_len;             /* length of queued TPM response */
0045     u8 buffer[TPM_BUFSIZE];      /* request/response buffer */
0046 
0047     struct work_struct work;     /* task that retrieves TPM timeouts */
0048 };
0049 
0050 /* all supported flags */
0051 #define VTPM_PROXY_FLAGS_ALL  (VTPM_PROXY_FLAG_TPM2)
0052 
0053 static struct workqueue_struct *workqueue;
0054 
0055 static void vtpm_proxy_delete_device(struct proxy_dev *proxy_dev);
0056 
0057 /*
0058  * Functions related to 'server side'
0059  */
0060 
0061 /**
0062  * vtpm_proxy_fops_read - Read TPM commands on 'server side'
0063  *
0064  * @filp: file pointer
0065  * @buf: read buffer
0066  * @count: number of bytes to read
0067  * @off: offset
0068  *
0069  * Return:
0070  *  Number of bytes read or negative error code
0071  */
0072 static ssize_t vtpm_proxy_fops_read(struct file *filp, char __user *buf,
0073                     size_t count, loff_t *off)
0074 {
0075     struct proxy_dev *proxy_dev = filp->private_data;
0076     size_t len;
0077     int sig, rc;
0078 
0079     sig = wait_event_interruptible(proxy_dev->wq,
0080         proxy_dev->req_len != 0 ||
0081         !(proxy_dev->state & STATE_OPENED_FLAG));
0082     if (sig)
0083         return -EINTR;
0084 
0085     mutex_lock(&proxy_dev->buf_lock);
0086 
0087     if (!(proxy_dev->state & STATE_OPENED_FLAG)) {
0088         mutex_unlock(&proxy_dev->buf_lock);
0089         return -EPIPE;
0090     }
0091 
0092     len = proxy_dev->req_len;
0093 
0094     if (count < len || len > sizeof(proxy_dev->buffer)) {
0095         mutex_unlock(&proxy_dev->buf_lock);
0096         pr_debug("Invalid size in recv: count=%zd, req_len=%zd\n",
0097              count, len);
0098         return -EIO;
0099     }
0100 
0101     rc = copy_to_user(buf, proxy_dev->buffer, len);
0102     memset(proxy_dev->buffer, 0, len);
0103     proxy_dev->req_len = 0;
0104 
0105     if (!rc)
0106         proxy_dev->state |= STATE_WAIT_RESPONSE_FLAG;
0107 
0108     mutex_unlock(&proxy_dev->buf_lock);
0109 
0110     if (rc)
0111         return -EFAULT;
0112 
0113     return len;
0114 }
0115 
0116 /**
0117  * vtpm_proxy_fops_write - Write TPM responses on 'server side'
0118  *
0119  * @filp: file pointer
0120  * @buf: write buffer
0121  * @count: number of bytes to write
0122  * @off: offset
0123  *
0124  * Return:
0125  *  Number of bytes read or negative error value
0126  */
0127 static ssize_t vtpm_proxy_fops_write(struct file *filp, const char __user *buf,
0128                      size_t count, loff_t *off)
0129 {
0130     struct proxy_dev *proxy_dev = filp->private_data;
0131 
0132     mutex_lock(&proxy_dev->buf_lock);
0133 
0134     if (!(proxy_dev->state & STATE_OPENED_FLAG)) {
0135         mutex_unlock(&proxy_dev->buf_lock);
0136         return -EPIPE;
0137     }
0138 
0139     if (count > sizeof(proxy_dev->buffer) ||
0140         !(proxy_dev->state & STATE_WAIT_RESPONSE_FLAG)) {
0141         mutex_unlock(&proxy_dev->buf_lock);
0142         return -EIO;
0143     }
0144 
0145     proxy_dev->state &= ~STATE_WAIT_RESPONSE_FLAG;
0146 
0147     proxy_dev->req_len = 0;
0148 
0149     if (copy_from_user(proxy_dev->buffer, buf, count)) {
0150         mutex_unlock(&proxy_dev->buf_lock);
0151         return -EFAULT;
0152     }
0153 
0154     proxy_dev->resp_len = count;
0155 
0156     mutex_unlock(&proxy_dev->buf_lock);
0157 
0158     wake_up_interruptible(&proxy_dev->wq);
0159 
0160     return count;
0161 }
0162 
0163 /*
0164  * vtpm_proxy_fops_poll - Poll status on 'server side'
0165  *
0166  * @filp: file pointer
0167  * @wait: poll table
0168  *
0169  * Return: Poll flags
0170  */
0171 static __poll_t vtpm_proxy_fops_poll(struct file *filp, poll_table *wait)
0172 {
0173     struct proxy_dev *proxy_dev = filp->private_data;
0174     __poll_t ret;
0175 
0176     poll_wait(filp, &proxy_dev->wq, wait);
0177 
0178     ret = EPOLLOUT;
0179 
0180     mutex_lock(&proxy_dev->buf_lock);
0181 
0182     if (proxy_dev->req_len)
0183         ret |= EPOLLIN | EPOLLRDNORM;
0184 
0185     if (!(proxy_dev->state & STATE_OPENED_FLAG))
0186         ret |= EPOLLHUP;
0187 
0188     mutex_unlock(&proxy_dev->buf_lock);
0189 
0190     return ret;
0191 }
0192 
0193 /*
0194  * vtpm_proxy_fops_open - Open vTPM device on 'server side'
0195  *
0196  * @filp: file pointer
0197  *
0198  * Called when setting up the anonymous file descriptor
0199  */
0200 static void vtpm_proxy_fops_open(struct file *filp)
0201 {
0202     struct proxy_dev *proxy_dev = filp->private_data;
0203 
0204     proxy_dev->state |= STATE_OPENED_FLAG;
0205 }
0206 
0207 /**
0208  * vtpm_proxy_fops_undo_open - counter-part to vtpm_fops_open
0209  *       Call to undo vtpm_proxy_fops_open
0210  *
0211  *@proxy_dev: tpm proxy device
0212  */
0213 static void vtpm_proxy_fops_undo_open(struct proxy_dev *proxy_dev)
0214 {
0215     mutex_lock(&proxy_dev->buf_lock);
0216 
0217     proxy_dev->state &= ~STATE_OPENED_FLAG;
0218 
0219     mutex_unlock(&proxy_dev->buf_lock);
0220 
0221     /* no more TPM responses -- wake up anyone waiting for them */
0222     wake_up_interruptible(&proxy_dev->wq);
0223 }
0224 
0225 /*
0226  * vtpm_proxy_fops_release - Close 'server side'
0227  *
0228  * @inode: inode
0229  * @filp: file pointer
0230  * Return:
0231  *      Always returns 0.
0232  */
0233 static int vtpm_proxy_fops_release(struct inode *inode, struct file *filp)
0234 {
0235     struct proxy_dev *proxy_dev = filp->private_data;
0236 
0237     filp->private_data = NULL;
0238 
0239     vtpm_proxy_delete_device(proxy_dev);
0240 
0241     return 0;
0242 }
0243 
0244 static const struct file_operations vtpm_proxy_fops = {
0245     .owner = THIS_MODULE,
0246     .llseek = no_llseek,
0247     .read = vtpm_proxy_fops_read,
0248     .write = vtpm_proxy_fops_write,
0249     .poll = vtpm_proxy_fops_poll,
0250     .release = vtpm_proxy_fops_release,
0251 };
0252 
0253 /*
0254  * Functions invoked by the core TPM driver to send TPM commands to
0255  * 'server side' and receive responses from there.
0256  */
0257 
0258 /*
0259  * Called when core TPM driver reads TPM responses from 'server side'
0260  *
0261  * @chip: tpm chip to use
0262  * @buf: receive buffer
0263  * @count: bytes to read
0264  * Return:
0265  *      Number of TPM response bytes read, negative error value otherwise
0266  */
0267 static int vtpm_proxy_tpm_op_recv(struct tpm_chip *chip, u8 *buf, size_t count)
0268 {
0269     struct proxy_dev *proxy_dev = dev_get_drvdata(&chip->dev);
0270     size_t len;
0271 
0272     /* process gone ? */
0273     mutex_lock(&proxy_dev->buf_lock);
0274 
0275     if (!(proxy_dev->state & STATE_OPENED_FLAG)) {
0276         mutex_unlock(&proxy_dev->buf_lock);
0277         return -EPIPE;
0278     }
0279 
0280     len = proxy_dev->resp_len;
0281     if (count < len) {
0282         dev_err(&chip->dev,
0283             "Invalid size in recv: count=%zd, resp_len=%zd\n",
0284             count, len);
0285         len = -EIO;
0286         goto out;
0287     }
0288 
0289     memcpy(buf, proxy_dev->buffer, len);
0290     proxy_dev->resp_len = 0;
0291 
0292 out:
0293     mutex_unlock(&proxy_dev->buf_lock);
0294 
0295     return len;
0296 }
0297 
0298 static int vtpm_proxy_is_driver_command(struct tpm_chip *chip,
0299                     u8 *buf, size_t count)
0300 {
0301     struct tpm_header *hdr = (struct tpm_header *)buf;
0302 
0303     if (count < sizeof(struct tpm_header))
0304         return 0;
0305 
0306     if (chip->flags & TPM_CHIP_FLAG_TPM2) {
0307         switch (be32_to_cpu(hdr->ordinal)) {
0308         case TPM2_CC_SET_LOCALITY:
0309             return 1;
0310         }
0311     } else {
0312         switch (be32_to_cpu(hdr->ordinal)) {
0313         case TPM_ORD_SET_LOCALITY:
0314             return 1;
0315         }
0316     }
0317     return 0;
0318 }
0319 
0320 /*
0321  * Called when core TPM driver forwards TPM requests to 'server side'.
0322  *
0323  * @chip: tpm chip to use
0324  * @buf: send buffer
0325  * @count: bytes to send
0326  *
0327  * Return:
0328  *      0 in case of success, negative error value otherwise.
0329  */
0330 static int vtpm_proxy_tpm_op_send(struct tpm_chip *chip, u8 *buf, size_t count)
0331 {
0332     struct proxy_dev *proxy_dev = dev_get_drvdata(&chip->dev);
0333 
0334     if (count > sizeof(proxy_dev->buffer)) {
0335         dev_err(&chip->dev,
0336             "Invalid size in send: count=%zd, buffer size=%zd\n",
0337             count, sizeof(proxy_dev->buffer));
0338         return -EIO;
0339     }
0340 
0341     if (!(proxy_dev->state & STATE_DRIVER_COMMAND) &&
0342         vtpm_proxy_is_driver_command(chip, buf, count))
0343         return -EFAULT;
0344 
0345     mutex_lock(&proxy_dev->buf_lock);
0346 
0347     if (!(proxy_dev->state & STATE_OPENED_FLAG)) {
0348         mutex_unlock(&proxy_dev->buf_lock);
0349         return -EPIPE;
0350     }
0351 
0352     proxy_dev->resp_len = 0;
0353 
0354     proxy_dev->req_len = count;
0355     memcpy(proxy_dev->buffer, buf, count);
0356 
0357     proxy_dev->state &= ~STATE_WAIT_RESPONSE_FLAG;
0358 
0359     mutex_unlock(&proxy_dev->buf_lock);
0360 
0361     wake_up_interruptible(&proxy_dev->wq);
0362 
0363     return 0;
0364 }
0365 
0366 static void vtpm_proxy_tpm_op_cancel(struct tpm_chip *chip)
0367 {
0368     /* not supported */
0369 }
0370 
0371 static u8 vtpm_proxy_tpm_op_status(struct tpm_chip *chip)
0372 {
0373     struct proxy_dev *proxy_dev = dev_get_drvdata(&chip->dev);
0374 
0375     if (proxy_dev->resp_len)
0376         return VTPM_PROXY_REQ_COMPLETE_FLAG;
0377 
0378     return 0;
0379 }
0380 
0381 static bool vtpm_proxy_tpm_req_canceled(struct tpm_chip  *chip, u8 status)
0382 {
0383     struct proxy_dev *proxy_dev = dev_get_drvdata(&chip->dev);
0384     bool ret;
0385 
0386     mutex_lock(&proxy_dev->buf_lock);
0387 
0388     ret = !(proxy_dev->state & STATE_OPENED_FLAG);
0389 
0390     mutex_unlock(&proxy_dev->buf_lock);
0391 
0392     return ret;
0393 }
0394 
0395 static int vtpm_proxy_request_locality(struct tpm_chip *chip, int locality)
0396 {
0397     struct tpm_buf buf;
0398     int rc;
0399     const struct tpm_header *header;
0400     struct proxy_dev *proxy_dev = dev_get_drvdata(&chip->dev);
0401 
0402     if (chip->flags & TPM_CHIP_FLAG_TPM2)
0403         rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS,
0404                   TPM2_CC_SET_LOCALITY);
0405     else
0406         rc = tpm_buf_init(&buf, TPM_TAG_RQU_COMMAND,
0407                   TPM_ORD_SET_LOCALITY);
0408     if (rc)
0409         return rc;
0410     tpm_buf_append_u8(&buf, locality);
0411 
0412     proxy_dev->state |= STATE_DRIVER_COMMAND;
0413 
0414     rc = tpm_transmit_cmd(chip, &buf, 0, "attempting to set locality");
0415 
0416     proxy_dev->state &= ~STATE_DRIVER_COMMAND;
0417 
0418     if (rc < 0) {
0419         locality = rc;
0420         goto out;
0421     }
0422 
0423     header = (const struct tpm_header *)buf.data;
0424     rc = be32_to_cpu(header->return_code);
0425     if (rc)
0426         locality = -1;
0427 
0428 out:
0429     tpm_buf_destroy(&buf);
0430 
0431     return locality;
0432 }
0433 
0434 static const struct tpm_class_ops vtpm_proxy_tpm_ops = {
0435     .flags = TPM_OPS_AUTO_STARTUP,
0436     .recv = vtpm_proxy_tpm_op_recv,
0437     .send = vtpm_proxy_tpm_op_send,
0438     .cancel = vtpm_proxy_tpm_op_cancel,
0439     .status = vtpm_proxy_tpm_op_status,
0440     .req_complete_mask = VTPM_PROXY_REQ_COMPLETE_FLAG,
0441     .req_complete_val = VTPM_PROXY_REQ_COMPLETE_FLAG,
0442     .req_canceled = vtpm_proxy_tpm_req_canceled,
0443     .request_locality = vtpm_proxy_request_locality,
0444 };
0445 
0446 /*
0447  * Code related to the startup of the TPM 2 and startup of TPM 1.2 +
0448  * retrieval of timeouts and durations.
0449  */
0450 
0451 static void vtpm_proxy_work(struct work_struct *work)
0452 {
0453     struct proxy_dev *proxy_dev = container_of(work, struct proxy_dev,
0454                            work);
0455     int rc;
0456 
0457     rc = tpm_chip_register(proxy_dev->chip);
0458     if (rc)
0459         vtpm_proxy_fops_undo_open(proxy_dev);
0460     else
0461         proxy_dev->state |= STATE_REGISTERED_FLAG;
0462 }
0463 
0464 /*
0465  * vtpm_proxy_work_stop: make sure the work has finished
0466  *
0467  * This function is useful when user space closed the fd
0468  * while the driver still determines timeouts.
0469  */
0470 static void vtpm_proxy_work_stop(struct proxy_dev *proxy_dev)
0471 {
0472     vtpm_proxy_fops_undo_open(proxy_dev);
0473     flush_work(&proxy_dev->work);
0474 }
0475 
0476 /*
0477  * vtpm_proxy_work_start: Schedule the work for TPM 1.2 & 2 initialization
0478  */
0479 static inline void vtpm_proxy_work_start(struct proxy_dev *proxy_dev)
0480 {
0481     queue_work(workqueue, &proxy_dev->work);
0482 }
0483 
0484 /*
0485  * Code related to creation and deletion of device pairs
0486  */
0487 static struct proxy_dev *vtpm_proxy_create_proxy_dev(void)
0488 {
0489     struct proxy_dev *proxy_dev;
0490     struct tpm_chip *chip;
0491     int err;
0492 
0493     proxy_dev = kzalloc(sizeof(*proxy_dev), GFP_KERNEL);
0494     if (proxy_dev == NULL)
0495         return ERR_PTR(-ENOMEM);
0496 
0497     init_waitqueue_head(&proxy_dev->wq);
0498     mutex_init(&proxy_dev->buf_lock);
0499     INIT_WORK(&proxy_dev->work, vtpm_proxy_work);
0500 
0501     chip = tpm_chip_alloc(NULL, &vtpm_proxy_tpm_ops);
0502     if (IS_ERR(chip)) {
0503         err = PTR_ERR(chip);
0504         goto err_proxy_dev_free;
0505     }
0506     dev_set_drvdata(&chip->dev, proxy_dev);
0507 
0508     proxy_dev->chip = chip;
0509 
0510     return proxy_dev;
0511 
0512 err_proxy_dev_free:
0513     kfree(proxy_dev);
0514 
0515     return ERR_PTR(err);
0516 }
0517 
0518 /*
0519  * Undo what has been done in vtpm_create_proxy_dev
0520  */
0521 static inline void vtpm_proxy_delete_proxy_dev(struct proxy_dev *proxy_dev)
0522 {
0523     put_device(&proxy_dev->chip->dev); /* frees chip */
0524     kfree(proxy_dev);
0525 }
0526 
0527 /*
0528  * Create a /dev/tpm%d and 'server side' file descriptor pair
0529  *
0530  * Return:
0531  *      Returns file pointer on success, an error value otherwise
0532  */
0533 static struct file *vtpm_proxy_create_device(
0534                  struct vtpm_proxy_new_dev *vtpm_new_dev)
0535 {
0536     struct proxy_dev *proxy_dev;
0537     int rc, fd;
0538     struct file *file;
0539 
0540     if (vtpm_new_dev->flags & ~VTPM_PROXY_FLAGS_ALL)
0541         return ERR_PTR(-EOPNOTSUPP);
0542 
0543     proxy_dev = vtpm_proxy_create_proxy_dev();
0544     if (IS_ERR(proxy_dev))
0545         return ERR_CAST(proxy_dev);
0546 
0547     proxy_dev->flags = vtpm_new_dev->flags;
0548 
0549     /* setup an anonymous file for the server-side */
0550     fd = get_unused_fd_flags(O_RDWR);
0551     if (fd < 0) {
0552         rc = fd;
0553         goto err_delete_proxy_dev;
0554     }
0555 
0556     file = anon_inode_getfile("[vtpms]", &vtpm_proxy_fops, proxy_dev,
0557                   O_RDWR);
0558     if (IS_ERR(file)) {
0559         rc = PTR_ERR(file);
0560         goto err_put_unused_fd;
0561     }
0562 
0563     /* from now on we can unwind with put_unused_fd() + fput() */
0564     /* simulate an open() on the server side */
0565     vtpm_proxy_fops_open(file);
0566 
0567     if (proxy_dev->flags & VTPM_PROXY_FLAG_TPM2)
0568         proxy_dev->chip->flags |= TPM_CHIP_FLAG_TPM2;
0569 
0570     vtpm_proxy_work_start(proxy_dev);
0571 
0572     vtpm_new_dev->fd = fd;
0573     vtpm_new_dev->major = MAJOR(proxy_dev->chip->dev.devt);
0574     vtpm_new_dev->minor = MINOR(proxy_dev->chip->dev.devt);
0575     vtpm_new_dev->tpm_num = proxy_dev->chip->dev_num;
0576 
0577     return file;
0578 
0579 err_put_unused_fd:
0580     put_unused_fd(fd);
0581 
0582 err_delete_proxy_dev:
0583     vtpm_proxy_delete_proxy_dev(proxy_dev);
0584 
0585     return ERR_PTR(rc);
0586 }
0587 
0588 /*
0589  * Counter part to vtpm_create_device.
0590  */
0591 static void vtpm_proxy_delete_device(struct proxy_dev *proxy_dev)
0592 {
0593     vtpm_proxy_work_stop(proxy_dev);
0594 
0595     /*
0596      * A client may hold the 'ops' lock, so let it know that the server
0597      * side shuts down before we try to grab the 'ops' lock when
0598      * unregistering the chip.
0599      */
0600     vtpm_proxy_fops_undo_open(proxy_dev);
0601 
0602     if (proxy_dev->state & STATE_REGISTERED_FLAG)
0603         tpm_chip_unregister(proxy_dev->chip);
0604 
0605     vtpm_proxy_delete_proxy_dev(proxy_dev);
0606 }
0607 
0608 /*
0609  * Code related to the control device /dev/vtpmx
0610  */
0611 
0612 /**
0613  * vtpmx_ioc_new_dev - handler for the %VTPM_PROXY_IOC_NEW_DEV ioctl
0614  * @file:   /dev/vtpmx
0615  * @ioctl:  the ioctl number
0616  * @arg:    pointer to the struct vtpmx_proxy_new_dev
0617  *
0618  * Creates an anonymous file that is used by the process acting as a TPM to
0619  * communicate with the client processes. The function will also add a new TPM
0620  * device through which data is proxied to this TPM acting process. The caller
0621  * will be provided with a file descriptor to communicate with the clients and
0622  * major and minor numbers for the TPM device.
0623  */
0624 static long vtpmx_ioc_new_dev(struct file *file, unsigned int ioctl,
0625                   unsigned long arg)
0626 {
0627     void __user *argp = (void __user *)arg;
0628     struct vtpm_proxy_new_dev __user *vtpm_new_dev_p;
0629     struct vtpm_proxy_new_dev vtpm_new_dev;
0630     struct file *vtpm_file;
0631 
0632     if (!capable(CAP_SYS_ADMIN))
0633         return -EPERM;
0634 
0635     vtpm_new_dev_p = argp;
0636 
0637     if (copy_from_user(&vtpm_new_dev, vtpm_new_dev_p,
0638                sizeof(vtpm_new_dev)))
0639         return -EFAULT;
0640 
0641     vtpm_file = vtpm_proxy_create_device(&vtpm_new_dev);
0642     if (IS_ERR(vtpm_file))
0643         return PTR_ERR(vtpm_file);
0644 
0645     if (copy_to_user(vtpm_new_dev_p, &vtpm_new_dev,
0646              sizeof(vtpm_new_dev))) {
0647         put_unused_fd(vtpm_new_dev.fd);
0648         fput(vtpm_file);
0649         return -EFAULT;
0650     }
0651 
0652     fd_install(vtpm_new_dev.fd, vtpm_file);
0653     return 0;
0654 }
0655 
0656 /*
0657  * vtpmx_fops_ioctl: ioctl on /dev/vtpmx
0658  *
0659  * Return:
0660  *      Returns 0 on success, a negative error code otherwise.
0661  */
0662 static long vtpmx_fops_ioctl(struct file *f, unsigned int ioctl,
0663                  unsigned long arg)
0664 {
0665     switch (ioctl) {
0666     case VTPM_PROXY_IOC_NEW_DEV:
0667         return vtpmx_ioc_new_dev(f, ioctl, arg);
0668     default:
0669         return -ENOIOCTLCMD;
0670     }
0671 }
0672 
0673 static const struct file_operations vtpmx_fops = {
0674     .owner = THIS_MODULE,
0675     .unlocked_ioctl = vtpmx_fops_ioctl,
0676     .compat_ioctl = compat_ptr_ioctl,
0677     .llseek = noop_llseek,
0678 };
0679 
0680 static struct miscdevice vtpmx_miscdev = {
0681     .minor = MISC_DYNAMIC_MINOR,
0682     .name = "vtpmx",
0683     .fops = &vtpmx_fops,
0684 };
0685 
0686 static int vtpmx_init(void)
0687 {
0688     return misc_register(&vtpmx_miscdev);
0689 }
0690 
0691 static void vtpmx_cleanup(void)
0692 {
0693     misc_deregister(&vtpmx_miscdev);
0694 }
0695 
0696 static int __init vtpm_module_init(void)
0697 {
0698     int rc;
0699 
0700     rc = vtpmx_init();
0701     if (rc) {
0702         pr_err("couldn't create vtpmx device\n");
0703         return rc;
0704     }
0705 
0706     workqueue = create_workqueue("tpm-vtpm");
0707     if (!workqueue) {
0708         pr_err("couldn't create workqueue\n");
0709         rc = -ENOMEM;
0710         goto err_vtpmx_cleanup;
0711     }
0712 
0713     return 0;
0714 
0715 err_vtpmx_cleanup:
0716     vtpmx_cleanup();
0717 
0718     return rc;
0719 }
0720 
0721 static void __exit vtpm_module_exit(void)
0722 {
0723     destroy_workqueue(workqueue);
0724     vtpmx_cleanup();
0725 }
0726 
0727 module_init(vtpm_module_init);
0728 module_exit(vtpm_module_exit);
0729 
0730 MODULE_AUTHOR("Stefan Berger (stefanb@us.ibm.com)");
0731 MODULE_DESCRIPTION("vTPM Driver");
0732 MODULE_VERSION("0.1");
0733 MODULE_LICENSE("GPL");