2 * Copyright (c) 2005, IBM Corporation
4 * Author: Stefan Berger, stefanb@us.ibm.com
5 * Grant table support: Mahadevan Gomathisankaran
7 * This code has been derived from drivers/xen/netfront/netfront.c
9 * Copyright (c) 2002-2004, K A Fraser
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License version 2
13 * as published by the Free Software Foundation; or, when distributed
14 * separately from the Linux kernel or incorporated into other
15 * software packages, subject to the following license:
17 * Permission is hereby granted, free of charge, to any person obtaining a copy
18 * of this source file (the "Software"), to deal in the Software without
19 * restriction, including without limitation the rights to use, copy, modify,
20 * merge, publish, distribute, sublicense, and/or sell copies of the Software,
21 * and to permit persons to whom the Software is furnished to do so, subject to
22 * the following conditions:
24 * The above copyright notice and this permission notice shall be included in
25 * all copies or substantial portions of the Software.
27 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
30 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
32 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
36 #include <linux/errno.h>
37 #include <linux/err.h>
38 #include <linux/interrupt.h>
39 #include <linux/mutex.h>
40 #include <linux/slab.h>
41 #include <asm/uaccess.h>
42 #include <xen/evtchn.h>
43 #include <xen/interface/grant_table.h>
44 #include <xen/interface/io/tpmif.h>
45 #include <xen/gnttab.h>
46 #include <xen/xenbus.h>
52 /* local structures */
54 struct tpm_chip *chip;
56 tpmif_tx_interface_t *tx;
64 struct tx_buffer *tx_buffers[TPMIF_TX_RING_SIZE];
70 wait_queue_head_t wait_q;
72 struct xenbus_device *dev;
77 unsigned int size; // available space in data
78 unsigned int len; // used space in data
79 unsigned char *data; // pointer to a page
83 /* locally visible variables */
84 static grant_ref_t gref_head;
85 static struct tpm_private *my_priv;
87 /* local function prototypes */
88 static irqreturn_t tpmif_int(int irq,
90 static void tpmif_rx_action(unsigned long unused);
91 static int tpmif_connect(struct xenbus_device *dev,
92 struct tpm_private *tp,
94 static DECLARE_TASKLET(tpmif_rx_tasklet, tpmif_rx_action, 0);
95 static int tpmif_allocate_tx_buffers(struct tpm_private *tp);
96 static void tpmif_free_tx_buffers(struct tpm_private *tp);
97 static void tpmif_set_connected_state(struct tpm_private *tp,
99 static int tpm_xmit(struct tpm_private *tp,
100 const u8 * buf, size_t count, int userbuffer,
102 static void destroy_tpmring(struct tpm_private *tp);
103 void __exit tpmif_exit(void);
105 #define DPRINTK(fmt, args...) \
106 pr_debug("xen_tpm_fr (%s:%d) " fmt, __FUNCTION__, __LINE__, ##args)
107 #define IPRINTK(fmt, args...) \
108 pr_info("xen_tpm_fr: " fmt, ##args)
109 #define WPRINTK(fmt, args...) \
110 pr_warning("xen_tpm_fr: " fmt, ##args)
112 #define GRANT_INVALID_REF 0
116 tx_buffer_copy(struct tx_buffer *txb, const u8 *src, int len,
124 if (copy_from_user(txb->data, src, copied))
127 memcpy(txb->data, src, copied);
133 static inline struct tx_buffer *tx_buffer_alloc(void)
135 struct tx_buffer *txb;
137 txb = kzalloc(sizeof(struct tx_buffer), GFP_KERNEL);
142 txb->size = PAGE_SIZE;
143 txb->data = (unsigned char *)__get_free_page(GFP_KERNEL);
144 if (txb->data == NULL) {
153 static inline void tx_buffer_free(struct tx_buffer *txb)
156 free_page((long)txb->data);
161 /**************************************************************
162 Utility function for the tpm_private structure
163 **************************************************************/
164 static void tpm_private_init(struct tpm_private *tp)
166 spin_lock_init(&tp->tx_lock);
167 init_waitqueue_head(&tp->wait_q);
168 atomic_set(&tp->refcnt, 1);
171 static void tpm_private_put(void)
173 if (!atomic_dec_and_test(&my_priv->refcnt))
176 tpmif_free_tx_buffers(my_priv);
181 static struct tpm_private *tpm_private_get(void)
186 atomic_inc(&my_priv->refcnt);
190 my_priv = kzalloc(sizeof(struct tpm_private), GFP_KERNEL);
194 tpm_private_init(my_priv);
195 err = tpmif_allocate_tx_buffers(my_priv);
202 /**************************************************************
204 The interface to let the tpm plugin register its callback
205 function and send data to another partition using this module
207 **************************************************************/
209 static DEFINE_MUTEX(suspend_lock);
211 * Send data via this module by calling this function
213 int vtpm_vd_send(struct tpm_private *tp,
214 const u8 * buf, size_t count, void *ptr)
218 mutex_lock(&suspend_lock);
219 sent = tpm_xmit(tp, buf, count, 0, ptr);
220 mutex_unlock(&suspend_lock);
225 /**************************************************************
227 **************************************************************/
229 static int setup_tpmring(struct xenbus_device *dev,
230 struct tpm_private *tp)
232 tpmif_tx_interface_t *sring;
235 tp->ring_ref = GRANT_INVALID_REF;
237 sring = (void *)__get_free_page(GFP_KERNEL);
239 xenbus_dev_fatal(dev, -ENOMEM, "allocating shared ring");
244 err = xenbus_grant_ring(dev, virt_to_mfn(tp->tx));
246 free_page((unsigned long)sring);
248 xenbus_dev_fatal(dev, err, "allocating grant reference");
253 err = tpmif_connect(dev, tp, dev->otherend_id);
264 static void destroy_tpmring(struct tpm_private *tp)
266 tpmif_set_connected_state(tp, 0);
268 if (tp->ring_ref != GRANT_INVALID_REF) {
269 gnttab_end_foreign_access(tp->ring_ref, (unsigned long)tp->tx);
270 tp->ring_ref = GRANT_INVALID_REF;
275 unbind_from_irqhandler(tp->irq, tp);
281 static int talk_to_backend(struct xenbus_device *dev,
282 struct tpm_private *tp)
284 const char *message = NULL;
286 struct xenbus_transaction xbt;
288 err = setup_tpmring(dev, tp);
290 xenbus_dev_fatal(dev, err, "setting up ring");
295 err = xenbus_transaction_start(&xbt);
297 xenbus_dev_fatal(dev, err, "starting transaction");
298 goto destroy_tpmring;
301 err = xenbus_printf(xbt, dev->nodename,
302 "ring-ref","%u", tp->ring_ref);
304 message = "writing ring-ref";
305 goto abort_transaction;
308 err = xenbus_printf(xbt, dev->nodename, "event-channel", "%u",
309 irq_to_evtchn_port(tp->irq));
311 message = "writing event-channel";
312 goto abort_transaction;
315 err = xenbus_transaction_end(xbt, 0);
319 xenbus_dev_fatal(dev, err, "completing transaction");
320 goto destroy_tpmring;
323 xenbus_switch_state(dev, XenbusStateConnected);
328 xenbus_transaction_end(xbt, 1);
330 xenbus_dev_error(dev, err, "%s", message);
338 * Callback received when the backend's state changes.
340 static void backend_changed(struct xenbus_device *dev,
341 enum xenbus_state backend_state)
343 struct tpm_private *tp = tpm_private_from_dev(&dev->dev);
346 switch (backend_state) {
347 case XenbusStateInitialising:
348 case XenbusStateInitWait:
349 case XenbusStateInitialised:
350 case XenbusStateReconfiguring:
351 case XenbusStateReconfigured:
352 case XenbusStateUnknown:
355 case XenbusStateConnected:
356 tpmif_set_connected_state(tp, 1);
359 case XenbusStateClosing:
360 tpmif_set_connected_state(tp, 0);
361 xenbus_frontend_closed(dev);
364 case XenbusStateClosed:
365 tpmif_set_connected_state(tp, 0);
366 if (tp->is_suspended == 0)
367 device_unregister(&dev->dev);
368 xenbus_frontend_closed(dev);
373 static int tpmfront_probe(struct xenbus_device *dev,
374 const struct xenbus_device_id *id)
378 struct tpm_private *tp = tpm_private_get();
383 tp->chip = init_vtpm(&dev->dev, tp);
384 if (IS_ERR(tp->chip))
385 return PTR_ERR(tp->chip);
387 err = xenbus_scanf(XBT_NIL, dev->nodename,
388 "handle", "%i", &handle);
389 if (XENBUS_EXIST_ERR(err))
393 xenbus_dev_fatal(dev,err,"reading virtual-device");
399 err = talk_to_backend(dev, tp);
409 static int tpmfront_remove(struct xenbus_device *dev)
411 struct tpm_private *tp = tpm_private_from_dev(&dev->dev);
413 cleanup_vtpm(&dev->dev);
417 static int tpmfront_suspend(struct xenbus_device *dev)
419 struct tpm_private *tp = tpm_private_from_dev(&dev->dev);
422 /* Take the lock, preventing any application from sending. */
423 mutex_lock(&suspend_lock);
424 tp->is_suspended = 1;
426 for (ctr = 0; atomic_read(&tp->tx_busy); ctr++) {
428 printk("TPM-FE [INFO]: Waiting for outstanding "
430 /* Wait for a request to be responded to. */
431 interruptible_sleep_on_timeout(&tp->wait_q, 100);
437 static int tpmfront_suspend_finish(struct tpm_private *tp)
439 tp->is_suspended = 0;
440 /* Allow applications to send again. */
441 mutex_unlock(&suspend_lock);
445 static int tpmfront_suspend_cancel(struct xenbus_device *dev)
447 struct tpm_private *tp = tpm_private_from_dev(&dev->dev);
448 return tpmfront_suspend_finish(tp);
451 static int tpmfront_resume(struct xenbus_device *dev)
453 struct tpm_private *tp = tpm_private_from_dev(&dev->dev);
455 return talk_to_backend(dev, tp);
458 static int tpmif_connect(struct xenbus_device *dev,
459 struct tpm_private *tp,
464 tp->backend_id = domid;
466 err = bind_listening_port_to_irqhandler(
467 domid, tpmif_int, IRQF_SAMPLE_RANDOM, "tpmif", tp);
469 WPRINTK("bind_listening_port_to_irqhandler failed "
478 static const struct xenbus_device_id tpmfront_ids[] = {
482 MODULE_ALIAS("xen:vtpm");
484 static DEFINE_XENBUS_DRIVER(tpmfront, ,
485 .probe = tpmfront_probe,
486 .remove = tpmfront_remove,
487 .resume = tpmfront_resume,
488 .otherend_changed = backend_changed,
489 .suspend = tpmfront_suspend,
490 .suspend_cancel = tpmfront_suspend_cancel,
493 static int __init init_tpm_xenbus(void)
495 return xenbus_register_frontend(&tpmfront_driver);
498 static int tpmif_allocate_tx_buffers(struct tpm_private *tp)
502 for (i = 0; i < TPMIF_TX_RING_SIZE; i++) {
503 tp->tx_buffers[i] = tx_buffer_alloc();
504 if (!tp->tx_buffers[i]) {
505 tpmif_free_tx_buffers(tp);
512 static void tpmif_free_tx_buffers(struct tpm_private *tp)
516 for (i = 0; i < TPMIF_TX_RING_SIZE; i++)
517 tx_buffer_free(tp->tx_buffers[i]);
520 static void tpmif_rx_action(unsigned long priv)
522 struct tpm_private *tp = (struct tpm_private *)priv;
524 unsigned int received;
525 unsigned int offset = 0;
527 tpmif_tx_request_t *tx = &tp->tx->ring[i].req;
529 atomic_set(&tp->tx_busy, 0);
530 wake_up_interruptible(&tp->wait_q);
534 buffer = kmalloc(received, GFP_ATOMIC);
538 for (i = 0; i < TPMIF_TX_RING_SIZE && offset < received; i++) {
539 struct tx_buffer *txb = tp->tx_buffers[i];
540 tpmif_tx_request_t *tx;
543 tx = &tp->tx->ring[i].req;
545 if (tocopy > PAGE_SIZE)
548 memcpy(&buffer[offset], txb->data, tocopy);
550 gnttab_release_grant_reference(&gref_head, tx->ref);
555 vtpm_vd_recv(tp->chip, buffer, received, tp->tx_remember);
560 static irqreturn_t tpmif_int(int irq, void *tpm_priv)
562 struct tpm_private *tp = tpm_priv;
565 spin_lock_irqsave(&tp->tx_lock, flags);
566 tpmif_rx_tasklet.data = (unsigned long)tp;
567 tasklet_schedule(&tpmif_rx_tasklet);
568 spin_unlock_irqrestore(&tp->tx_lock, flags);
574 static int tpm_xmit(struct tpm_private *tp,
575 const u8 * buf, size_t count, int isuserbuffer,
578 tpmif_tx_request_t *tx;
580 unsigned int offset = 0;
582 spin_lock_irq(&tp->tx_lock);
584 if (unlikely(atomic_read(&tp->tx_busy))) {
585 printk("tpm_xmit: There's an outstanding request/response "
587 spin_unlock_irq(&tp->tx_lock);
591 if (tp->is_connected != 1) {
592 spin_unlock_irq(&tp->tx_lock);
596 for (i = 0; count > 0 && i < TPMIF_TX_RING_SIZE; i++) {
597 struct tx_buffer *txb = tp->tx_buffers[i];
601 DPRINTK("txb (i=%d) is NULL. buffers initilized?\n"
602 "Not transmitting anything!\n", i);
603 spin_unlock_irq(&tp->tx_lock);
607 copied = tx_buffer_copy(txb, &buf[offset], count,
610 /* An error occurred */
611 spin_unlock_irq(&tp->tx_lock);
617 tx = &tp->tx->ring[i].req;
618 tx->addr = virt_to_machine(txb->data);
622 DPRINTK("First 4 characters sent by TPM-FE are "
623 "0x%02x 0x%02x 0x%02x 0x%02x\n",
624 txb->data[0],txb->data[1],txb->data[2],txb->data[3]);
626 /* Get the granttable reference for this page. */
627 tx->ref = gnttab_claim_grant_reference(&gref_head);
628 if (tx->ref == -ENOSPC) {
629 spin_unlock_irq(&tp->tx_lock);
630 DPRINTK("Grant table claim reference failed in "
631 "func:%s line:%d file:%s\n",
632 __FUNCTION__, __LINE__, __FILE__);
635 gnttab_grant_foreign_access_ref(tx->ref,
637 virt_to_mfn(txb->data),
642 atomic_set(&tp->tx_busy, 1);
643 tp->tx_remember = remember;
647 notify_remote_via_irq(tp->irq);
649 spin_unlock_irq(&tp->tx_lock);
654 static void tpmif_notify_upperlayer(struct tpm_private *tp)
656 /* Notify upper layer about the state of the connection to the BE. */
657 vtpm_vd_status(tp->chip, (tp->is_connected
658 ? TPM_VD_STATUS_CONNECTED
659 : TPM_VD_STATUS_DISCONNECTED));
663 static void tpmif_set_connected_state(struct tpm_private *tp, u8 is_connected)
666 * Don't notify upper layer if we are in suspend mode and
667 * should disconnect - assumption is that we will resume
668 * The mutex keeps apps from sending.
670 if (is_connected == 0 && tp->is_suspended == 1)
674 * Unlock the mutex if we are connected again
675 * after being suspended - now resuming.
676 * This also removes the suspend state.
678 if (is_connected == 1 && tp->is_suspended == 1)
679 tpmfront_suspend_finish(tp);
681 if (is_connected != tp->is_connected) {
682 tp->is_connected = is_connected;
683 tpmif_notify_upperlayer(tp);
689 /* =================================================================
690 * Initialization function.
691 * =================================================================
695 static int __init tpmif_init(void)
697 struct tpm_private *tp;
699 if (is_initial_xendomain())
702 tp = tpm_private_get();
706 IPRINTK("Initialising the vTPM driver.\n");
707 if (gnttab_alloc_grant_references(TPMIF_TX_RING_SIZE,
718 module_init(tpmif_init);
720 MODULE_LICENSE("Dual BSD/GPL");