Index: root/xen-unstable.hg/linux-2.6-xen-sparse/drivers/char/tpm/tpm.c =================================================================== --- root.orig/xen-unstable.hg/linux-2.6-xen-sparse/drivers/char/tpm/tpm.c +++ root/xen-unstable.hg/linux-2.6-xen-sparse/drivers/char/tpm/tpm.c @@ -67,9 +67,6 @@ static ssize_t tpm_transmit(struct tpm_c u32 count; unsigned long stop; - if (!chip) - return -ENODEV; - count = be32_to_cpu(*((__be32 *) (buf + 2))); if (count == 0) Index: root/xen-unstable.hg/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c =================================================================== --- root.orig/xen-unstable.hg/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c +++ root/xen-unstable.hg/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c @@ -42,7 +42,6 @@ struct transmission { unsigned int request_len; unsigned char *rcv_buffer; unsigned int buffersize; - struct tpm_chip *chip; unsigned int flags; }; @@ -75,6 +74,8 @@ static struct data_exchange dataex; static unsigned long disconnect_time; +static struct tpmfe_device tpmfe; + /* local function prototypes */ static void __exit cleanup_xen(void); @@ -119,7 +120,7 @@ transmission_free(struct transmission *t static int tpm_recv(const u8 *buffer, size_t count, const void *ptr) { int ret_size = 0; - struct transmission *t, *temp; + struct transmission *t; /* * The list with requests must contain one request @@ -127,8 +128,9 @@ static int tpm_recv(const u8 *buffer, si * was passed to me from the front-end. */ if (dataex.current_request != ptr) { - printk("WARNING: The request pointer is different than the pointer " - "the shared memory driver returned to me. %p != %p\n", + printk("WARNING: The request pointer is different than the " + "pointer the shared memory driver returned to me. " + "%p != %p\n", dataex.current_request, ptr); } @@ -144,16 +146,16 @@ static int tpm_recv(const u8 *buffer, si return 0; } - if (NULL != (temp = dataex.current_request)) { - transmission_free(temp); + if (NULL != (t = dataex.current_request)) { + transmission_free(t); dataex.current_request = NULL; } t = transmission_alloc(); - if (NULL != t) { + if (t) { unsigned long flags; t->rcv_buffer = kmalloc(count, GFP_KERNEL); - if (NULL == t->rcv_buffer) { + if (! t->rcv_buffer) { transmission_free(t); return -ENOMEM; } @@ -258,10 +260,6 @@ static int tpm_xen_send(struct tpm_chip if (t != NULL) { unsigned int error = 0; - t->rcv_buffer = NULL; - t->buffersize = 0; - t->chip = chip; - /* * Queue the packet if the driver below is not * ready, yet, or there is any packet already @@ -304,9 +302,11 @@ static int tpm_xen_send(struct tpm_chip struct transmission *qt = (struct transmission *) dataex.queued_requests.next; list_del(&qt->next); dataex.current_request = qt; - spin_unlock_irqrestore(&dataex.req_list_lock, flags); + spin_unlock_irqrestore(&dataex.req_list_lock, + flags); - rc = tpm_fe_send(qt->request, + rc = tpm_fe_send(tpmfe.tpm_private, + qt->request, qt->request_len, qt); @@ -351,7 +351,8 @@ static int tpm_xen_send(struct tpm_chip * amount of bytes in the request and * a void * pointer (here: transmission structure) */ - rc = tpm_fe_send(buf, count, t); + rc = tpm_fe_send(tpmfe.tpm_private, + buf, count, t); /* * The generic TPM driver will call * the function to receive the response. @@ -373,7 +374,8 @@ queue_it: * queue it. */ dataex.flags |= DATAEX_FLAG_QUEUED_ONLY; - list_add_tail(&t->next, &dataex.queued_requests); + list_add_tail(&t->next, + &dataex.queued_requests); rc = 0; } } @@ -512,7 +514,7 @@ static void __exit cleanup_xen(void) tpm_fe_unregister_receiver(); } -fs_initcall(init_xen); +module_init(init_xen); module_exit(cleanup_xen); MODULE_AUTHOR("Stefan Berger (stefanb@xxxxxxxxxx)"); Index: root/xen-unstable.hg/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c =================================================================== --- root.orig/xen-unstable.hg/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c +++ root/xen-unstable.hg/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c @@ -56,14 +56,14 @@ /* locally visible variables */ static grant_ref_t gref_head; -static struct tpm_private my_private; +static struct tpm_private *my_priv; /* local function prototypes */ static irqreturn_t tpmif_int(int irq, void *tpm_priv, struct pt_regs *ptregs); static void tpmif_rx_action(unsigned long unused); -static void tpmif_connect(u16 evtchn, domid_t domid); +static void tpmif_connect(struct tpm_private *tp, domid_t domid); static DECLARE_TASKLET(tpmif_rx_tasklet, tpmif_rx_action, 0); static int tpm_allocate_buffers(struct tpm_private *tp); static void tpmif_set_connected_state(struct tpm_private *tp, @@ -101,7 +101,7 @@ tx_buffer_copy(struct tx_buffer *txb, co static inline struct tx_buffer *tx_buffer_alloc(void) { - struct tx_buffer *txb = kmalloc(sizeof (struct tx_buffer), + struct tx_buffer *txb = kzalloc(sizeof (struct tx_buffer), GFP_KERNEL); if (txb) { @@ -118,6 +118,31 @@ static inline struct tx_buffer *tx_buffe /************************************************************** + Utility function for the tpm_private structure +**************************************************************/ +static inline void tpm_private_init(struct tpm_private *tp) +{ + spin_lock_init(&tp->tx_lock); + init_waitqueue_head(&tp->wait_q); +} + +static struct tpm_private *tpm_private_get(void) +{ + if (!my_priv) { + my_priv = kzalloc(sizeof(struct tpm_private), GFP_KERNEL); + if (my_priv) { + tpm_private_init(my_priv); + } + } + return my_priv; +} + +static inline void tpm_private_free(struct tpm_private *tp) +{ + kfree(tp); +} + +/************************************************************** The interface to let the tpm plugin register its callback function and send data to another partition using this module @@ -131,10 +156,9 @@ static struct tpmfe_device *upperlayer_t /* * Send data via this module by calling this function */ -int tpm_fe_send(const u8 * buf, size_t count, void *ptr) +int tpm_fe_send(struct tpm_private *tp, const u8 * buf, size_t count, void *ptr) { int sent = 0; - struct tpm_private *tp = &my_private; down(&suspend_lock); sent = tpm_xmit(tp, buf, count, 0, ptr); @@ -155,6 +179,7 @@ int tpm_fe_register_receiver(struct tpmf if (NULL == upperlayer_tpmfe) { upperlayer_tpmfe = tpmfe_dev; tpmfe_dev->max_tx_size = TPMIF_TX_RING_SIZE * PAGE_SIZE; + tpmfe_dev->tpm_private = tpm_private_get(); } else { rc = -EBUSY; } @@ -197,10 +222,9 @@ static int tpm_fe_send_upperlayer(const **************************************************************/ static int setup_tpmring(struct xenbus_device *dev, - struct tpmfront_info * info) + struct tpm_private *tp) { tpmif_tx_interface_t *sring; - struct tpm_private *tp = &my_private; int err; sring = (void *)__get_free_page(GFP_KERNEL); @@ -219,13 +243,13 @@ static int setup_tpmring(struct xenbus_d xenbus_dev_fatal(dev, err, "allocating grant reference"); goto fail; } - info->ring_ref = err; + tp->ring_ref = err; err = xenbus_alloc_evtchn(dev, &tp->evtchn); if (err) goto fail; - tpmif_connect(tp->evtchn, dev->otherend_id); + tpmif_connect(tp, dev->otherend_id); return 0; fail: @@ -233,11 +257,11 @@ fail: } -static void destroy_tpmring(struct tpmfront_info *info, struct tpm_private *tp) +static void destroy_tpmring(struct tpm_private *tp) { tpmif_set_connected_state(tp, 0); if (tp->tx != NULL) { - gnttab_end_foreign_access(info->ring_ref, 0, + gnttab_end_foreign_access(tp->ring_ref, 0, (unsigned long)tp->tx); tp->tx = NULL; } @@ -249,13 +273,13 @@ static void destroy_tpmring(struct tpmfr static int talk_to_backend(struct xenbus_device *dev, - struct tpmfront_info *info) + struct tpm_private *tp) { const char *message = NULL; int err; xenbus_transaction_t xbt; - err = setup_tpmring(dev, info); + err = setup_tpmring(dev, tp); if (err) { xenbus_dev_fatal(dev, err, "setting up ring"); goto out; @@ -269,14 +293,14 @@ again: } err = xenbus_printf(xbt, dev->nodename, - "ring-ref","%u", info->ring_ref); + "ring-ref","%u", tp->ring_ref); if (err) { message = "writing ring-ref"; goto abort_transaction; } err = xenbus_printf(xbt, dev->nodename, - "event-channel", "%u", my_private.evtchn); + "event-channel", "%u", tp->evtchn); if (err) { message = "writing event-channel"; goto abort_transaction; @@ -301,7 +325,7 @@ abort_transaction: if (message) xenbus_dev_error(dev, err, "%s", message); destroy_tpmring: - destroy_tpmring(info, &my_private); + destroy_tpmring(tp); out: return err; } @@ -312,7 +336,7 @@ out: static void backend_changed(struct xenbus_device *dev, XenbusState backend_state) { - struct tpm_private *tp = &my_private; + struct tpm_private *tp = dev->data; DPRINTK("\n"); switch (backend_state) { @@ -343,8 +367,8 @@ static int tpmfront_probe(struct xenbus_ const struct xenbus_device_id *id) { int err; - struct tpmfront_info *info; int handle; + struct tpm_private *tp = tpm_private_get(); err = xenbus_scanf(XBT_NULL, dev->nodename, "handle", "%i", &handle); @@ -356,20 +380,12 @@ static int tpmfront_probe(struct xenbus_ return err; } - info = kmalloc(sizeof(*info), GFP_KERNEL); - if (!info) { - err = -ENOMEM; - xenbus_dev_fatal(dev,err,"allocating info structure"); - return err; - } - memset(info, 0x0, sizeof(*info)); - - info->dev = dev; - dev->data = info; + tp->dev = dev; + dev->data = tp; - err = talk_to_backend(dev, info); + err = talk_to_backend(dev, tp); if (err) { - kfree(info); + tpm_private_free(tp); dev->data = NULL; return err; } @@ -379,18 +395,15 @@ static int tpmfront_probe(struct xenbus_ static int tpmfront_remove(struct xenbus_device *dev) { - struct tpmfront_info *info = dev->data; - - destroy_tpmring(info, &my_private); - - kfree(info); + struct tpm_private *tp = dev->data; + destroy_tpmring(tp); return 0; } static int tpmfront_suspend(struct xenbus_device *dev) { - struct tpm_private *tp = &my_private; + struct tpm_private *tp = dev->data; u32 ctr; /* lock, so no app can send */ @@ -420,17 +433,15 @@ tpmfront_suspend(struct xenbus_device *d static int tpmfront_resume(struct xenbus_device *dev) { - struct tpmfront_info *info = dev->data; - return talk_to_backend(dev, info); + struct tpm_private *tp = dev->data; + return talk_to_backend(dev, tp); } static void -tpmif_connect(u16 evtchn, domid_t domid) +tpmif_connect(struct tpm_private *tp, domid_t domid) { int err; - struct tpm_private *tp = &my_private; - tp->evtchn = evtchn; tp->backend_id = domid; err = bind_evtchn_to_irqhandler(tp->evtchn, @@ -477,9 +488,9 @@ tpm_allocate_buffers(struct tpm_private } static void -tpmif_rx_action(unsigned long unused) +tpmif_rx_action(unsigned long priv) { - struct tpm_private *tp = &my_private; + struct tpm_private *tp = (struct tpm_private *)priv; int i = 0; unsigned int received; @@ -529,6 +540,7 @@ tpmif_int(int irq, void *tpm_priv, struc unsigned long flags; spin_lock_irqsave(&tp->tx_lock, flags); + tpmif_rx_tasklet.data = (unsigned long)tp; tasklet_schedule(&tpmif_rx_tasklet); spin_unlock_irqrestore(&tp->tx_lock, flags); @@ -678,12 +690,6 @@ tpmif_init(void) &gref_head ) < 0) { return -EFAULT; } - /* - * Only don't send the driver status when we are in the - * INIT domain. - */ - spin_lock_init(&my_private.tx_lock); - init_waitqueue_head(&my_private.wait_q); init_tpm_xenbus(); Index: root/xen-unstable.hg/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h =================================================================== --- root.orig/xen-unstable.hg/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h +++ root/xen-unstable.hg/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h @@ -17,9 +17,6 @@ struct tpm_private { domid_t backend_id; wait_queue_head_t wait_q; -}; - -struct tpmfront_info { struct xenbus_device *dev; int ring_ref; }; Index: root/xen-unstable.hg/linux-2.6-xen-sparse/include/xen/tpmfe.h =================================================================== --- root.orig/xen-unstable.hg/linux-2.6-xen-sparse/include/xen/tpmfe.h +++ root/xen-unstable.hg/linux-2.6-xen-sparse/include/xen/tpmfe.h @@ -1,6 +1,8 @@ #ifndef TPM_FE_H #define TPM_FE_H +struct tpm_private; + struct tpmfe_device { /* * Let upper layer receive data from front-end @@ -19,6 +21,11 @@ struct tpmfe_device { * for allocation of buffers. */ unsigned int max_tx_size; + /* + * The following is a private structure of the underlying + * driver. It's expected as first parameter in the send function. + */ + struct tpm_private *tpm_private; }; enum { @@ -26,7 +33,7 @@ enum { TPMFE_STATUS_CONNECTED = 0x1 }; -int tpm_fe_send(const u8 * buf, size_t count, void *ptr); +int tpm_fe_send(struct tpm_private * tp, const u8 * buf, size_t count, void *ptr); int tpm_fe_register_receiver(struct tpmfe_device *); void tpm_fe_unregister_receiver(void);