All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 4/7] vtpm Mini-Os domain: mini-os tpm device drivers
@ 2010-08-25 15:18 Matthew Fioravante
  2010-08-25 15:43 ` Samuel Thibault
  0 siblings, 1 reply; 6+ messages in thread
From: Matthew Fioravante @ 2010-08-25 15:18 UTC (permalink / raw)
  To: xen-devel


[-- Attachment #1.1.1: Type: text/plain, Size: 271 bytes --]

  Signed-off-by: Matthew Fioravante <matthew.fioravante@jhuapl.edu>

This patch adds tpm frontend (tpmfront) and tpm backend (tpmback) device 
drivers to mini-os. While these are used by vtpm-stubdom, they could be 
used by any mini-os domain that needs a vtpm.



[-- Attachment #1.1.2: 4-tpmdevices-minios --]
[-- Type: text/plain, Size: 47765 bytes --]

diff -r 6615dd4045c7 -r 22a23fed2920 extras/mini-os/include/tpmback.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/mini-os/include/tpmback.h	Tue Jul 20 16:38:40 2010 -0400
@@ -0,0 +1,52 @@
+#include <xen/io/tpmif.h>
+#include <xen/io/xenbus.h>
+#include <mini-os/types.h>
+#ifndef TPMBACK_H
+#define TPMBACK_H
+
+struct tpmcmd {
+   domid_t domid;		/* Domid of the frontend */
+   unsigned long handle;	/* Handle of the frontend */
+   unsigned int req_len;		/* Size of the command in buf - set by tpmback driver */
+   uint8_t* req;			/* tpm command bits, allocated by driver, DON'T FREE IT */
+   unsigned int resp_len;	/* Size of the outgoing command, 
+				   you set this before passing the cmd object to tpmback_resp */
+   uint8_t* resp;		/* Buffer for response - YOU MUST ALLOCATE IT, YOU MUST ALSO FREE IT */
+};
+typedef struct tpmcmd tpmcmd_t;
+
+/* Initialize the tpm backend driver */
+void init_tpmback(void);
+/* Shutdown tpm backend driver */
+void shutdown_tpmback(void);
+
+/* Blocks until a tpm command is sent from any front end.
+ * Returns a pointer to the tpm command to handle.
+ * Do not try to free this pointer or the req buffer
+ * This function will return NULL if the tpm backend driver
+ * is shutdown or any other error occurs */
+tpmcmd_t* tpmback_req_any(void);
+
+/* Blocks until a tpm command from the frontend at domid/handle
+ * is sent. 
+ * Returns NULL if domid/handle is not connected, tpmback is
+ * shutdown or shutting down, or if there is an error
+ */
+tpmcmd_t* tpmback_req(domid_t domid, unsigned int handle);
+
+/* Send the response to the tpm command back to the frontend 
+ * This function will free the tpmcmd object, but you must free the resp
+ * buffer yourself */
+void tpmback_resp(tpmcmd_t* tpmcmd);
+
+/* Waits for the first frontend to connect and then sets domid and handle appropriately.
+ * If one or more frontends are already connected, this will set domid and handle to one 
+ * of them arbitrarily. The main use for this function is to wait until a single
+ * frontend connection has occured.
+ * returns 0 on success, non-zero on failure */
+int tpmback_wait_for_frontend_connect(domid_t *domid, unsigned long *handle);
+
+/* returns the number of frontends connected */
+int tpmback_num_frontends(void);
+
+#endif
diff -r 6615dd4045c7 -r 22a23fed2920 extras/mini-os/include/tpmfront.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/mini-os/include/tpmfront.h	Tue Jul 20 16:38:40 2010 -0400
@@ -0,0 +1,51 @@
+#ifndef TPMFRONT_H
+#define TPMFRONT_H
+
+#include <mini-os/types.h>
+#include <mini-os/events.h>
+#include <xen/xen.h>
+#include <xen/io/xenbus.h>
+#include <xen/io/tpmif.h>
+
+struct tpmfront_dev {
+   grant_ref_t ring_ref;
+   evtchn_port_t evtchn;
+
+   tpmif_tx_interface_t* tx;
+
+   void** pages;
+
+   domid_t bedomid;
+   char* nodename;
+   char* bepath;
+
+   XenbusState state;
+
+   uint8_t waiting;
+   struct wait_queue_head waitq;
+
+   uint8_t* respbuf;
+
+   int dmi_id;
+
+};
+
+
+/*Initialize frontend */
+struct tpmfront_dev* init_tpmfront(const char* nodename);
+/*Shutdown frontend */
+void shutdown_tpmfront(struct tpmfront_dev* dev);
+
+/* Send a tpm command to the backend and wait for the response
+ *
+ * @dev - frontend device
+ * @req - request buffer
+ * @reqlen - length of request buffer
+ * @resp - *resp will be set to internal response buffer, don't free it! Value is undefined on error
+ * @resplen - *resplen will be set to the length of the response. Value is undefined on error
+ *
+ * returns 0 on success, non zero on failure. 
+ * */
+int tpmfront_cmd(struct tpmfront_dev* dev, uint8_t* req, size_t reqlen, uint8_t** resp, size_t* resplen);
+
+#endif
diff -r 6615dd4045c7 -r 22a23fed2920 extras/mini-os/tpmback.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/mini-os/tpmback.c	Tue Jul 20 16:38:40 2010 -0400
@@ -0,0 +1,1006 @@
+#include <mini-os/os.h>
+#include <mini-os/xenbus.h>
+#include <mini-os/events.h>
+#include <errno.h>
+#include <mini-os/gnttab.h>
+#include <xen/io/xenbus.h>
+#include <xen/io/tpmif.h>
+#include <xen/io/protocols.h>
+#include <mini-os/xmalloc.h>
+#include <time.h>
+#include <mini-os/tpmback.h>
+#include <mini-os/lib.h>
+#include <fcntl.h>
+#include <mini-os/mm.h>
+#include <mini-os/posix/sys/mman.h>
+#include <mini-os/semaphore.h>
+#include <mini-os/wait.h>
+
+#ifndef NO_TPMBACK
+
+#ifndef HAVE_LIBC
+#define strtoul simple_strtoul
+#endif
+
+//#define TPMBACK_PRINT_DEBUG
+#ifdef TPMBACK_PRINT_DEBUG
+#define TPMBACK_DEBUG(fmt,...) printk("Tpmback:Debug("__FILE__":%d) " fmt, __LINE__, ##__VA_ARGS__)
+#define TPMBACK_DEBUG_MORE(fmt,...) printk(fmt, ##__VA_ARGS__)
+#else
+#define TPMBACK_DEBUG(fmt,...)
+#endif
+#define TPMBACK_ERR(fmt,...) printk("Tpmback:Error " fmt, ##__VA_ARGS__)
+#define TPMBACK_LOG(fmt,...) printk("Tpmback:Info " fmt, ##__VA_ARGS__)
+
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+
+/* Default size of the tpmif array at initialization */
+#define DEF_ARRAY_SIZE 1
+
+/* tpmif and tpmdev flags */
+#define TPMIF_CLOSED 1
+#define TPMIF_REQ_READY 2
+
+struct tpmif {
+   domid_t domid;
+   unsigned int handle;
+
+   char* fe_path;
+   char* fe_state_path;
+
+   /* Locally bound event channel*/
+   evtchn_port_t evtchn;
+
+   /* Shared page */
+   tpmif_tx_interface_t* tx;
+
+   /* pointer to TPMIF_RX_RING_SIZE pages */
+   void** pages;
+
+   enum xenbus_state state;
+   enum { DISCONNECTED, DISCONNECTING, CONNECTED } status;
+
+   /* state flags */
+   int flags;
+};
+typedef struct tpmif tpmif_t;
+
+struct tpmback_dev {
+
+   tpmif_t** tpmlist; 
+   unsigned long num_tpms;
+   unsigned long num_alloc;
+
+   struct gntmap map;
+
+   /* True if at least one tpmif has a request to be handled */
+   int flags;
+
+   xenbus_event_queue events;
+};
+typedef struct tpmback_dev tpmback_dev_t;
+
+enum { EV_NONE, EV_NEWFE, EV_STCHNG } tpm_ev_enum;
+
+/* Global objects */
+static struct thread* eventthread = NULL;
+static tpmback_dev_t gtpmdev = {
+   .tpmlist = NULL,
+   .num_tpms = 0,
+   .num_alloc = 0,
+   .flags = TPMIF_CLOSED,
+   .events = NULL,
+};
+struct wait_queue_head waitq;
+int globalinit = 0;
+
+/************************************
+ * TPMIF SORTED ARRAY FUNCTIONS
+ * tpmback_dev_t.tpmlist is a sorted array, sorted by domid and then handle number
+ * Duplicates are not allowed
+ * **********************************/
+
+inline void tpmif_req_ready(tpmif_t* tpmif) {
+   tpmif->flags |= TPMIF_REQ_READY;
+   gtpmdev.flags |= TPMIF_REQ_READY;
+}
+
+inline void tpmdev_check_req(void) {
+   int i;
+   int flags;
+   local_irq_save(flags);
+   for(i = 0; i < gtpmdev.num_tpms; ++i) {
+      if(gtpmdev.tpmlist[i]->flags & TPMIF_REQ_READY) {
+	 gtpmdev.flags |= TPMIF_REQ_READY;
+	 local_irq_restore(flags);
+	 return;
+      }
+   }
+   gtpmdev.flags &= ~TPMIF_REQ_READY;
+   local_irq_restore(flags);
+}
+
+inline void tpmif_req_finished(tpmif_t* tpmif) {
+   tpmif->flags &= ~TPMIF_REQ_READY;
+   tpmdev_check_req();
+}
+
+int __get_tpmif_index(tpmif_t** list, int n, domid_t domid, unsigned int handle)
+{
+   int i = n /2;
+   tpmif_t* tmp;
+
+   if( n == 0 )
+      return -1;
+
+   tmp = list[i];
+   if(domid == tmp->domid && tmp->handle == handle) {
+      return i;
+   } else if ( (domid < tmp->domid) ||
+	 (domid == tmp->domid && handle <= tmp->handle)) {
+      return __get_tpmif_index(list, i, domid, handle);
+   } else {
+      return i + 1 + __get_tpmif_index(list + i + 1, i -1 + (n % 2), domid, handle);
+   }
+}
+
+/* Returns the array index of the tpmif domid/handle. Returns -1 if no such tpmif exists */
+int get_tpmif_index(domid_t domid, unsigned int handle) 
+{
+   int flags;
+   int index;
+   local_irq_save(flags);
+   index = __get_tpmif_index(gtpmdev.tpmlist, gtpmdev.num_tpms, domid, handle);
+   local_irq_restore(flags);
+   return index;
+}
+
+/* Returns the tpmif domid/handle or NULL if none exists */
+tpmif_t* get_tpmif(domid_t domid, unsigned int handle) 
+{
+   int flags;
+   int i;
+   tpmif_t* ret;
+   local_irq_save(flags);
+   i = get_tpmif_index(domid, handle);
+   if (i < 0) {
+      ret = NULL;
+   } else {
+      ret = gtpmdev.tpmlist[i];
+   }
+   local_irq_restore(flags);
+   return ret;
+}
+
+/* Remove the given tpmif. Returns 0 if it was removed, -1 if it was not removed */
+int remove_tpmif(tpmif_t* tpmif) 
+{
+   int i, j;
+   char* err;
+   int flags;
+   local_irq_save(flags);
+
+   /* Find the index in the array if it exists */
+   i = get_tpmif_index(tpmif->domid, tpmif->handle);
+   if (i < 0) {
+      goto error;
+   }
+
+   /* Remove the interface from the list */
+   for(j = i; j < gtpmdev.num_tpms - 1; ++j) {
+      gtpmdev.tpmlist[j] = gtpmdev.tpmlist[j+1];
+   }
+   gtpmdev.tpmlist[j] = NULL;
+   --gtpmdev.num_tpms;
+
+   /* If removed tpm was the only ready tpm, then we need to check and turn off the ready flag */
+   tpmdev_check_req();
+   
+   local_irq_restore(flags);
+
+   /* Stop listening for events on this tpm interface */
+   if((err = xenbus_unwatch_path_token(XBT_NIL, tpmif->fe_state_path, tpmif->fe_state_path))) {
+      TPMBACK_ERR("Unable to unwatch path token `%s' Error was %s Ignoring..\n", tpmif->fe_state_path, err);
+      free(err);
+   }
+
+   return 0;
+error:
+   local_irq_restore(flags);
+   return -1;
+}
+
+/* Insert tpmif into dev->tpmlist. Returns 0 on success and non zero on error.
+ * It is an error to insert a tpmif with the same domid and handle
+ * number
+ * as something already in the list */
+int insert_tpmif(tpmif_t* tpmif)
+{
+   int flags;
+   unsigned int i, j;
+   tpmif_t* tmp;
+   char* err;
+
+   local_irq_save(flags);
+
+   /*Check if we need to allocate more space */
+   if (gtpmdev.num_tpms == gtpmdev.num_alloc) {
+      gtpmdev.num_alloc *= 2;
+      gtpmdev.tpmlist = realloc(gtpmdev.tpmlist, gtpmdev.num_alloc);
+   }
+
+   /*Find where to put the new interface */
+   for(i = 0; i < gtpmdev.num_tpms; ++i)
+   {
+      tmp = gtpmdev.tpmlist[i];
+      if(tpmif->domid == tmp->domid && tpmif->handle == tmp->handle) {
+	 TPMBACK_ERR("Tried to insert duplicate tpm interface %u/%u\n", (unsigned int) tpmif->domid, (unsigned int) tpmif->handle);
+	 goto error;
+      }
+      if((tpmif->domid < tmp->domid) || 
+	    (tpmif->domid == tmp->domid && tpmif->handle <= tmp->handle)) {
+	 break;
+      }
+   }
+
+   /*Shift all the tpm pointers past i down one */
+   for(j = gtpmdev.num_tpms; j > i; --j) {
+      gtpmdev.tpmlist[j] = gtpmdev.tpmlist[j-1];
+   }
+
+   /*Add the new interface */
+   gtpmdev.tpmlist[i] = tpmif;
+   ++gtpmdev.num_tpms;
+
+   /*Should not be needed, anything inserted with ready flag is probably an error */
+   tpmdev_check_req();
+
+   local_irq_restore(flags);
+
+   /*Listen for state changes on the new interface */
+   if((err = xenbus_watch_path_token(XBT_NIL, tpmif->fe_state_path, tpmif->fe_state_path, &gtpmdev.events)))
+   {
+      /* if we got an error here we should carefully remove the interface and then return */
+      TPMBACK_ERR("Unable to watch path token `%s' Error was %s\n", tpmif->fe_state_path, err);
+      free(err);
+      remove_tpmif(tpmif);
+      goto error_post_irq;
+   }
+
+   return 0;
+error:
+   local_irq_restore(flags);
+error_post_irq:
+   return -1;
+}
+
+
+/*****************
+ * CHANGE BACKEND STATE
+ * *****************/
+/*Attempts to change the backend state in xenstore
+ * returns 0 on success and non-zero on error */
+int tpmif_change_state(tpmif_t* tpmif, enum xenbus_state state)
+{
+   char path[512];
+   char *value;
+   char *err;
+   enum xenbus_state readst;
+   TPMBACK_DEBUG("Backend state change %u/%u from=%d to=%d\n", (unsigned int) tpmif->domid, (unsigned int) tpmif->handle, tpmif->state, state);
+   if (tpmif->state == state)
+      return 0;
+
+   snprintf(path, 512, "backend/vtpm/%u/%u/state", (unsigned int) tpmif->domid, (unsigned int) tpmif->handle);
+
+   if((err = xenbus_read(XBT_NIL, path, &value))) {
+      TPMBACK_ERR("Unable to read backend state %s, error was %s\n", path, err);
+      free(err);
+      return -1;
+   }
+   if(sscanf(value, "%d", &readst) != 1) {
+      TPMBACK_ERR("Non integer value (%s) in %s ??\n", value, path);
+      free(value);
+      return -1;
+   }
+   free(value);
+
+   /* It's possible that the backend state got updated by hotplug or something else behind our back */
+   if(readst != tpmif->state) {
+      TPMBACK_DEBUG("tpm interface state was %d but xenstore state was %d!\n", tpmif->state, readst);
+      tpmif->state = readst;
+   }
+
+   /*If if the state isnt changing, then we dont update xenstore b/c we dont want to fire extraneous events */
+   if(tpmif->state == state) {
+      return 0;
+   }
+
+   /*update xenstore*/
+   snprintf(path, 512, "backend/vtpm/%u/%u", (unsigned int) tpmif->domid, (unsigned int) tpmif->handle);
+   if((err = xenbus_printf(XBT_NIL, path, "state", "%u", state))) {
+      TPMBACK_ERR("Error writing to xenstore %s, error was %s new state=%d\n", path, err, state);
+      free(err);
+      return -1;
+   }
+
+   tpmif->state = state;
+
+   return 0;
+}
+/**********************************
+ * TPMIF CREATION AND DELETION
+ * *******************************/
+inline tpmif_t* __init_tpmif(domid_t domid, unsigned int handle)
+{
+   tpmif_t* tpmif;
+   tpmif = malloc(sizeof(*tpmif));
+   tpmif->domid = domid;
+   tpmif->handle = handle;
+   tpmif->fe_path = NULL;
+   tpmif->fe_state_path = NULL;
+   tpmif->state = XenbusStateInitialising;
+   tpmif->status = DISCONNECTED;
+   tpmif->tx = NULL;
+   tpmif->pages = NULL;
+   tpmif->flags = 0;
+   return tpmif;
+}
+
+void __free_tpmif(tpmif_t* tpmif)
+{
+   if(tpmif->pages) {
+      free(tpmif->pages);
+   }
+   if(tpmif->fe_path) {
+      free(tpmif->fe_path);
+   }
+   if(tpmif->fe_state_path) {
+      free(tpmif->fe_state_path);
+   }
+   free(tpmif);
+}
+/* Creates a new tpm interface, adds it to the sorted array and returns it.
+ * returns NULL on error 
+ * If the tpm interface already exists, it is returned*/
+tpmif_t* new_tpmif(domid_t domid, unsigned int handle)
+{
+   tpmif_t* tpmif;
+   char* err;
+   char path[512];
+
+   /* Make sure we haven't already created this tpm
+    * Double events can occur */
+   if((tpmif = get_tpmif(domid, handle)) != NULL) {
+      return tpmif;
+   }
+
+   tpmif = __init_tpmif(domid, handle);
+
+   /* allocate pages to be used for shared mapping */
+   if((tpmif->pages = malloc(sizeof(void*) * TPMIF_TX_RING_SIZE)) == NULL) {
+      goto error;
+   }
+   memset(tpmif->pages, 0, sizeof(void*) * TPMIF_TX_RING_SIZE);
+
+   if(tpmif_change_state(tpmif, XenbusStateInitWait)) {
+      goto error;
+   }
+
+   snprintf(path, 512, "backend/vtpm/%u/%u/frontend", (unsigned int) domid, (unsigned int) handle);
+   if((err = xenbus_read(XBT_NIL, path, &tpmif->fe_path))) {
+      TPMBACK_ERR("Error creating new tpm instance xenbus_read(%s), Error = %s", path, err);
+      free(err);
+      goto error;
+   }
+
+   /*Set the state path */
+   tpmif->fe_state_path = malloc(strlen(tpmif->fe_path) + 7);
+   strcpy(tpmif->fe_state_path, tpmif->fe_path);
+   strcat(tpmif->fe_state_path, "/state");
+
+   if(insert_tpmif(tpmif)) {
+      goto error;
+   }
+   TPMBACK_DEBUG("New tpmif %u/%u\n", (unsigned int) tpmif->domid, (unsigned int) tpmif->handle);
+   return tpmif;
+error:
+   __free_tpmif(tpmif);
+   return NULL;
+
+}
+
+/* Removes tpmif from dev->tpmlist and frees it's memory usage */
+void free_tpmif(tpmif_t* tpmif)
+{
+   char* err;
+   char path[512];
+   TPMBACK_DEBUG("Free tpmif %u/%u\n", (unsigned int) tpmif->domid, (unsigned int) tpmif->handle);
+   if(tpmif->flags & TPMIF_CLOSED) {
+      TPMBACK_ERR("Tried to free an instance twice! Theres a bug somewhere!\n");
+      BUG();
+   }
+   tpmif->flags = TPMIF_CLOSED;
+
+   tpmif_change_state(tpmif, XenbusStateClosing);
+
+   /* Unmap share page and unbind event channel */
+   if(tpmif->status == CONNECTED) {
+      tpmif->status = DISCONNECTING;
+      mask_evtchn(tpmif->evtchn);
+
+      if(gntmap_munmap(&gtpmdev.map, (unsigned long)tpmif->tx, 1)) {
+	 TPMBACK_ERR("%u/%u Error occured while trying to unmap shared page\n", (unsigned int) tpmif->domid, (unsigned int) tpmif->handle);
+      }
+
+      unbind_evtchn(tpmif->evtchn);
+   }
+   tpmif->status = DISCONNECTED;
+   tpmif_change_state(tpmif, XenbusStateClosed);
+
+   /* remove from array */
+   remove_tpmif(tpmif);
+
+   /* Wake up anyone possibly waiting on this interface and let them exit */
+   wake_up(&waitq);
+   schedule();
+
+   /* Remove the old xenbus entries */
+   snprintf(path, 512, "backend/vtpm/%u/%u", (unsigned int) tpmif->domid, (unsigned int) tpmif->handle);
+   if((err = xenbus_rm(XBT_NIL, path))) {
+      TPMBACK_ERR("Error cleaning up xenbus entries path=%s error=%s\n", path, err);
+      free(err);
+   }
+
+   TPMBACK_LOG("Frontend %u/%u disconnected\n", (unsigned int) tpmif->domid, (unsigned int) tpmif->handle);
+
+   /* free memory */
+   __free_tpmif(tpmif);
+
+}
+
+/**********************
+ * REMAINING TPMBACK FUNCTIONS
+ * ********************/
+
+/*Event channel handler */
+void tpmback_handler(evtchn_port_t port, struct pt_regs *regs, void *data)
+{
+   tpmif_t* tpmif = (tpmif_t*) data;
+   tpmif_tx_request_t* tx = &tpmif->tx->ring[0].req;
+   /* Throw away 0 size events, these can trigger from event channel unmasking */
+   if(tx->size == 0)
+      return;
+
+   TPMBACK_DEBUG("EVENT CHANNEL FIRE %u/%u\n", (unsigned int) tpmif->domid, (unsigned int) tpmif->handle);
+   tpmif_req_ready(tpmif);
+   wake_up(&waitq);
+
+}
+
+/* Connect to frontend */
+int connect_fe(tpmif_t* tpmif)
+{
+   char path[512];
+   char* err, *value;
+   uint32_t domid;
+   grant_ref_t ringref;
+   evtchn_port_t evtchn;
+
+   /* If already connected then quit */
+   if (tpmif->status == CONNECTED) {
+      TPMBACK_DEBUG("%u/%u tried to connect while it was already connected?\n", (unsigned int) tpmif->domid, (unsigned int) tpmif->handle);
+      return 0;
+   }
+
+   /* Fetch the grant reference */
+   snprintf(path, 512, "%s/ring-ref", tpmif->fe_path);
+   if((err = xenbus_read(XBT_NIL, path, &value))) {
+      TPMBACK_ERR("Error creating new tpm instance xenbus_read(%s) Error = %s", path, err);
+      free(err);
+      return -1;
+   }
+   if(sscanf(value, "%d", &ringref) != 1) {
+      TPMBACK_ERR("Non integer value (%s) in %s ??\n", value, path);
+      free(value);
+      return -1;
+   }
+   free(value);
+
+
+   /* Fetch the event channel*/
+   snprintf(path, 512, "%s/event-channel", tpmif->fe_path);
+   if((err = xenbus_read(XBT_NIL, path, &value))) {
+      TPMBACK_ERR("Error creating new tpm instance xenbus_read(%s) Error = %s", path, err);
+      free(err);
+      return -1;
+   }
+   if(sscanf(value, "%d", &evtchn) != 1) {
+      TPMBACK_ERR("Non integer value (%s) in %s ??\n", value, path);
+      free(value);
+      return -1;
+   }
+   free(value);
+
+   domid = tpmif->domid;
+   if((tpmif->tx = gntmap_map_grant_refs(&gtpmdev.map, 1, &domid, 0, &ringref, PROT_READ | PROT_WRITE)) == NULL) {
+      TPMBACK_ERR("Failed to map grant reference %u/%u\n", (unsigned int) tpmif->domid, (unsigned int) tpmif->handle);
+      return -1;
+   }
+   memset(tpmif->tx, 0, PAGE_SIZE);
+
+   /*Bind the event channel */
+   if((evtchn_bind_interdomain(tpmif->domid, evtchn, tpmback_handler, tpmif, &tpmif->evtchn)))
+   {
+      TPMBACK_ERR("%u/%u Unable to bind to interdomain event channel!\n", (unsigned int) tpmif->domid, (unsigned int) tpmif->handle);
+      goto error_post_map;
+   }
+   unmask_evtchn(tpmif->evtchn);
+
+   /* Write the ready flag and change status to connected */
+   snprintf(path, 512, "backend/vtpm/%u/%u", (unsigned int) tpmif->domid, (unsigned int) tpmif->handle);
+   if((err = xenbus_printf(XBT_NIL, path, "ready", "%u", 1))) {
+      TPMBACK_ERR("%u/%u Unable to write ready flag on connect_fe()\n", (unsigned int) tpmif->domid, (unsigned int) tpmif->handle); 
+      free(err);
+      goto error_post_evtchn;
+   }
+   tpmif->status = CONNECTED;
+   if((tpmif_change_state(tpmif, XenbusStateConnected))){
+      goto error_post_evtchn;
+   }
+
+   TPMBACK_LOG("Frontend %u/%u connected\n", (unsigned int) tpmif->domid, (unsigned int) tpmif->handle);
+
+   return 0;
+error_post_evtchn:
+   mask_evtchn(tpmif->evtchn);
+   unbind_evtchn(tpmif->evtchn);
+error_post_map:
+   gntmap_munmap(&gtpmdev.map, (unsigned long)tpmif->tx, 1);
+   return -1;
+}
+
+static int frontend_changed(tpmif_t* tpmif)
+{
+   int state = xenbus_read_integer(tpmif->fe_state_path);
+   if(state < 0) {
+      state = XenbusStateUnknown;
+   }
+
+   TPMBACK_DEBUG("Frontend %u/%u state changed to %d\n", (unsigned int) tpmif->domid, (unsigned int) tpmif->handle, state);
+
+   switch (state) {
+      case XenbusStateInitialising:
+      case XenbusStateInitialised:
+	 break;
+
+      case XenbusStateConnected:
+	 if(connect_fe(tpmif)) {
+	    TPMBACK_ERR("Failed to connect to front end %u/%u\n", (unsigned int) tpmif->domid, (unsigned int) tpmif->handle);
+	    tpmif_change_state(tpmif, XenbusStateClosed);
+	    return -1;
+	 }
+	 break;
+
+      case XenbusStateClosing:
+	 tpmif_change_state(tpmif, XenbusStateClosing);
+	 break;
+
+      case XenbusStateUnknown: /* keep it here */
+      case XenbusStateClosed:
+	 free_tpmif(tpmif);
+	 break;
+
+      default:
+	 TPMBACK_DEBUG("BAD STATE CHANGE %u/%u state = %d for tpmif\n", (unsigned int) tpmif->domid, (unsigned int) tpmif->handle, state);
+	 return -1;
+   }
+   return 0;
+}
+
+
+/* parses the string that comes out of xenbus_watch_wait_return. */
+static int parse_eventstr(const char* evstr, domid_t* domid, unsigned int* handle)
+{
+   int ret;
+   char cmd[40];
+   char* err;
+   char* value;
+   unsigned int udomid = 0;
+   /* First check for new frontends, this occurs when /backend/vtpm/<domid>/<handle> gets created. Note we what the sscanf to fail on the last %s */
+   if (sscanf(evstr, "backend/vtpm/%u/%u/%40s", &udomid, handle, cmd) == 2) {
+      *domid = udomid;
+      /* Make sure the entry exists, if this event triggers because the entry dissapeared then ignore it */
+      if((err = xenbus_read(XBT_NIL, evstr, &value))) {
+	 free(err);
+	 return EV_NONE;
+      }
+      free(value);
+      /* Make sure the tpmif entry does not already exist, this should not happen */
+      if(get_tpmif(*domid, *handle)) {
+	 TPMBACK_DEBUG("Duplicate tpm entries!\n");
+	 return EV_NONE;
+      }
+      return EV_NEWFE;
+   } else if((ret = sscanf(evstr, "/local/domain/%u/device/vtpm/%u/%40s", &udomid, handle, cmd)) == 3) {
+      *domid = udomid;
+      if (!strcmp(cmd, "state"))
+	 return EV_STCHNG;
+   }
+   return EV_NONE;
+}
+
+void handle_backend_event(char* evstr) {
+   tpmif_t* tpmif;
+   domid_t domid;
+   unsigned int handle;
+   int event;
+
+   TPMBACK_DEBUG("Xenbus Event: %s\n", evstr);
+
+   event = parse_eventstr(evstr, &domid, &handle);
+
+   switch(event) {
+      case EV_NEWFE:
+	 if(new_tpmif(domid, handle) == NULL) {
+	    TPMBACK_ERR("Failed to create new tpm instance %u/%u\n", (unsigned int) domid, (unsigned int) handle);
+	 }
+	 wake_up(&waitq);
+	 break;
+      case EV_STCHNG:
+	 if((tpmif = get_tpmif(domid, handle))) {
+	    frontend_changed(tpmif);
+	 } else {
+	    TPMBACK_DEBUG("Event Received for non-existant tpm! instance=%u/%u xenbus_event=%s\n", (unsigned int) domid, (unsigned int) handle, evstr);
+	 }
+	 break;
+   }
+}
+
+/* Runs through the given path and creates events recursively
+ * for all of its children.
+ * @path - xenstore path to scan */
+static void generate_backend_events(const char* path)
+{
+   char* err;
+   int i, len;
+   char **dirs;
+   char *entry;
+
+   if((err = xenbus_ls(XBT_NIL, path, &dirs)) != NULL) {
+      free(err);
+      return;
+   }
+
+   for(i = 0; dirs[i] != NULL; ++i) {
+      len = strlen(path) + strlen(dirs[i]) + 2;
+      entry = malloc(len);
+      snprintf(entry, len, "%s/%s", path, dirs[i]);
+
+      /* Generate and handle event for the entry itself */
+      handle_backend_event(entry);
+
+      /* Do children */
+      generate_backend_events(entry);
+
+      /* Cleanup */
+      free(entry);
+      free(dirs[i]);
+   }
+   free(dirs);
+   return;
+}
+
+
+static void event_listener(void)
+{
+   const char* bepath = "backend/vtpm";
+   char **path;
+   char* err;
+
+   /* Setup the backend device watch */
+   if((err = xenbus_watch_path_token(XBT_NIL, bepath, bepath, &gtpmdev.events)) != NULL) {
+      TPMBACK_ERR("xenbus_watch_path_token(%s) failed with error %s!\n", bepath, err);
+      free(err);
+      goto egress;
+   }
+
+   /* Check for any frontends that connected before we set the watch.
+    * This is almost guaranteed to happen if both domains are started
+    * immediatly one after the other.
+    * We do this by manually generating events on everything in the backend
+    * path */
+   generate_backend_events(bepath);
+
+   /* Wait and listen for changes in frontend connections */
+   while(1) {
+      path = xenbus_wait_for_watch_return(&gtpmdev.events);
+
+      /*If quit flag was set then exit */
+      if(gtpmdev.flags & TPMIF_CLOSED) {
+	 TPMBACK_DEBUG("listener thread got quit event. Exiting..\n");
+	 free(path);
+	 break;
+      }
+      handle_backend_event(*path);
+      free(path);
+
+   }
+
+   if((err = xenbus_unwatch_path_token(XBT_NIL, bepath, bepath)) != NULL) {
+      free(err);
+   }
+egress:
+   return;
+}
+
+void event_thread(void* p) {
+   event_listener();
+}
+
+void init_tpmback(void)
+{
+   if(!globalinit) {
+      init_waitqueue_head(&waitq);
+      globalinit = 1;
+   }
+   printk("============= Init TPM BACK ================\n");
+   gtpmdev.tpmlist = malloc(sizeof(tpmif_t*) * DEF_ARRAY_SIZE);
+   gtpmdev.num_alloc = DEF_ARRAY_SIZE;
+   gtpmdev.num_tpms = 0;
+   gtpmdev.flags = 0;
+
+   eventthread = create_thread("tpmback-listener", event_thread, NULL);
+
+}
+
+void shutdown_tpmback(void)
+{
+   TPMBACK_LOG("Shutting down tpm backend\n");
+   /* Set the quit flag */
+   gtpmdev.flags = TPMIF_CLOSED;
+
+   //printk("num tpms is %d\n", gtpmdev.num_tpms);
+   /*Free all backend instances */
+   while(gtpmdev.num_tpms) {
+      free_tpmif(gtpmdev.tpmlist[0]);
+   }
+   free(gtpmdev.tpmlist);
+   gtpmdev.tpmlist = NULL;
+   gtpmdev.num_alloc = 0;
+
+   /* Wake up anyone possibly waiting on the device and let them exit */
+   wake_up(&waitq);
+   schedule();
+}
+
+inline void init_tpmcmd(tpmcmd_t* tpmcmd, domid_t domid, unsigned int handle) 
+{
+   tpmcmd->domid = domid;
+   tpmcmd->handle = handle;
+   tpmcmd->req = NULL;
+   tpmcmd->req_len = 0;
+   tpmcmd->resp = NULL;
+   tpmcmd->resp_len = 0;
+}
+
+tpmcmd_t* get_request(tpmif_t* tpmif) {
+   tpmcmd_t* cmd;
+   tpmif_tx_request_t* tx;
+   int offset;
+   int tocopy;
+   int i;
+   uint32_t domid;
+   int flags;
+
+   local_irq_save(flags);
+
+   /* Allocate the cmd object to hold the data */
+   if((cmd = malloc(sizeof(*cmd))) == NULL) {
+      goto error;
+   }
+   init_tpmcmd(cmd, tpmif->domid, tpmif->handle);
+
+   tx = &tpmif->tx->ring[0].req;
+   cmd->req_len = tx->size;
+   /* Allocate the buffer */
+   if(cmd->req_len) {
+      if((cmd->req = malloc(cmd->req_len)) == NULL) {
+	 goto error;
+      }
+   }
+   /* Copy the bits from the shared pages */
+   offset = 0;
+   for(i = 0; i < TPMIF_TX_RING_SIZE && offset < cmd->req_len; ++i) {
+      tx = &tpmif->tx->ring[i].req;
+
+      /* Map the page with the data */
+      domid = (uint32_t)tpmif->domid;
+      if((tpmif->pages[i] = gntmap_map_grant_refs(&gtpmdev.map, 1, &domid, 0, &tx->ref, PROT_READ)) == NULL) {
+	 TPMBACK_ERR("%u/%u Unable to map shared page during read!\n", (unsigned int) tpmif->domid, (unsigned int) tpmif->handle);
+	 goto error;
+      }
+
+      /* do the copy now */
+      tocopy = min(cmd->req_len - offset, PAGE_SIZE);
+      memcpy(&cmd->req[offset], tpmif->pages[i], tocopy);
+      offset += tocopy;
+
+      /* release the page */
+      gntmap_munmap(&gtpmdev.map, (unsigned long)tpmif->pages[i], 1);
+
+   }
+
+#ifdef TPMBACK_PRINT_DEBUG
+   TPMBACK_DEBUG("Received Tpm Command from %u/%u of size %u", (unsigned int) tpmif->domid, (unsigned int) tpmif->handle, cmd->req_len);
+   for(i = 0; i < cmd->req_len; ++i) {
+      if (!(i % 30)) {
+	 TPMBACK_DEBUG_MORE("\n");
+      }
+      TPMBACK_DEBUG_MORE("%02hhX ", cmd->req[i]);
+   }
+   TPMBACK_DEBUG_MORE("\n\n");
+#endif
+
+   local_irq_restore(flags);
+   return cmd;
+error:
+   if(cmd != NULL) {
+      if (cmd->req != NULL) {
+	 free(cmd->req);
+	 cmd->req = NULL;
+      }
+      free(cmd);
+      cmd = NULL;
+   }
+   local_irq_restore(flags);
+   return NULL;
+
+}
+
+void send_response(tpmcmd_t* cmd, tpmif_t* tpmif)
+{
+   tpmif_tx_request_t* tx;
+   int offset;
+   int i;
+   uint32_t domid;
+   int tocopy;
+   int flags;
+
+   local_irq_save(flags);
+
+   tx = &tpmif->tx->ring[0].req;
+   tx->size = cmd->resp_len;
+
+   offset = 0;
+   for(i = 0; i < TPMIF_TX_RING_SIZE && offset < cmd->resp_len; ++i) {
+      tx = &tpmif->tx->ring[i].req;
+
+      /* Map the page with the data */
+      domid = (uint32_t)tpmif->domid;
+      if((tpmif->pages[i] = gntmap_map_grant_refs(&gtpmdev.map, 1, &domid, 0, &tx->ref, PROT_WRITE)) == NULL) {
+	 TPMBACK_ERR("%u/%u Unable to map shared page during write!\n", (unsigned int) tpmif->domid, (unsigned int) tpmif->handle);
+	 goto error;
+      }
+
+      /* do the copy now */
+      tocopy = min(cmd->resp_len - offset, PAGE_SIZE);
+      memcpy(tpmif->pages[i], &cmd->resp[offset], tocopy);
+      offset += tocopy;
+
+      /* release the page */
+      gntmap_munmap(&gtpmdev.map, (unsigned long)tpmif->pages[i], 1);
+
+   }
+
+#ifdef TPMBACK_PRINT_DEBUG
+   TPMBACK_DEBUG("Sent response to %u/%u of size %u", (unsigned int) tpmif->domid, (unsigned int) tpmif->handle, cmd->resp_len);
+   for(i = 0; i < cmd->resp_len; ++i) {
+      if (!(i % 30)) {
+	 TPMBACK_DEBUG_MORE("\n");
+      }
+      TPMBACK_DEBUG_MORE("%02hhX ", cmd->resp[i]);
+   }
+   TPMBACK_DEBUG_MORE("\n\n");
+#endif
+   /* clear the ready flag and send the event channel notice to the frontend */
+   tpmif_req_finished(tpmif);
+   notify_remote_via_evtchn(tpmif->evtchn);
+error:
+   local_irq_restore(flags);
+   return;
+}
+
+tpmcmd_t* tpmback_req_any(void)
+{
+   int i;
+   /* Block until something has a request */
+   wait_event(waitq, (gtpmdev.flags & (TPMIF_REQ_READY | TPMIF_CLOSED)));
+
+   /* Check if were shutting down */
+   if(gtpmdev.flags & TPMIF_CLOSED) {
+      /* if something was waiting for us to give up the queue so it can shutdown, let it finish */
+      schedule();
+      return NULL;
+   }
+
+   for(i = 0; i < gtpmdev.num_tpms; ++i) {
+      if(gtpmdev.tpmlist[i]->flags & TPMIF_REQ_READY) {
+	 return get_request(gtpmdev.tpmlist[i]);
+      }
+   }
+
+   TPMBACK_ERR("backend request ready flag was set but no interfaces were actually ready\n");
+   return NULL;
+}
+
+tpmcmd_t* tpmback_req(domid_t domid, unsigned int handle)
+{
+   tpmif_t* tpmif;
+   tpmif = get_tpmif(domid, handle);
+   if(tpmif == NULL) {
+      return NULL;
+   }
+
+   wait_event(waitq, (tpmif->flags & (TPMIF_REQ_READY | TPMIF_CLOSED) || gtpmdev.flags & TPMIF_CLOSED));
+
+   /* Check if were shutting down */
+   if(tpmif->flags & TPMIF_CLOSED || gtpmdev.flags & TPMIF_CLOSED) {
+      /* if something was waiting for us to give up the queue so it can free this instance, let it finish */
+      schedule();
+      return NULL;
+   }
+
+   return get_request(tpmif);
+}
+
+void tpmback_resp(tpmcmd_t* tpmcmd)
+{
+   tpmif_t* tpmif;
+
+   /* Get the associated interface, if it doesnt exist then just quit */
+   tpmif = get_tpmif(tpmcmd->domid, tpmcmd->handle);
+   if(tpmif == NULL) {
+      TPMBACK_ERR("Tried to send a reponse to non existant frontend %u/%u\n", (unsigned int) tpmcmd->domid, (unsigned int) tpmcmd->handle);
+      goto end;
+   }
+
+   if(!(tpmif->flags & TPMIF_REQ_READY)) {
+      TPMBACK_ERR("Tried to send response to a frontend that was not waiting for one %u/%u\n", (unsigned int) tpmcmd->domid, (unsigned int) tpmcmd->handle);
+      goto end;
+   }
+
+   /* Send response to frontend */
+   send_response(tpmcmd, tpmif);
+
+end:
+   if(tpmcmd->req != NULL) {
+      free(tpmcmd->req);
+   }
+   free(tpmcmd);
+   return;
+}
+
+int tpmback_wait_for_frontend_connect(domid_t *domid, unsigned long *handle)
+{
+   tpmif_t* tpmif;
+   int flags;
+   wait_event(waitq, ((gtpmdev.num_tpms > 0) || gtpmdev.flags & TPMIF_CLOSED));
+   if(gtpmdev.flags & TPMIF_CLOSED) {
+      return -1;
+   }
+   local_irq_save(flags);
+   tpmif = gtpmdev.tpmlist[0];
+   *domid = tpmif->domid;
+   *handle = tpmif->handle;
+   local_irq_restore(flags);
+
+   return 0;
+}
+
+int tpmback_num_frontends(void) 
+{
+   return gtpmdev.num_tpms;
+}
+
+#endif
+
diff -r 6615dd4045c7 -r 22a23fed2920 extras/mini-os/tpmfront.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/mini-os/tpmfront.c	Tue Jul 20 16:38:40 2010 -0400
@@ -0,0 +1,470 @@
+#include <mini-os/types.h>
+#include <mini-os/os.h>
+#include <mini-os/xenbus.h>
+#include <mini-os/xmalloc.h>
+#include <mini-os/events.h>
+#include <mini-os/wait.h>
+#include <mini-os/gnttab.h>
+#include <xen/io/xenbus.h>
+#include <xen/io/tpmif.h>
+#include <mini-os/tpmfront.h>
+#ifndef NO_TPMFRONT
+
+//#define TPMFRONT_PRINT_DEBUG
+#ifdef TPMFRONT_PRINT_DEBUG
+#define TPMFRONT_DEBUG(fmt,...) printk("Tpmfront:Debug("__FILE__":%d) " fmt, __LINE__, ##__VA_ARGS__)
+#define TPMFRONT_DEBUG_MORE(fmt,...) printk(fmt, ##__VA_ARGS__)
+#else
+#define TPMFRONT_DEBUG(fmt,...)
+#endif
+#define TPMFRONT_ERR(fmt,...) printk("Tpmfront:Error " fmt, ##__VA_ARGS__)
+#define TPMFRONT_LOG(fmt,...) printk("Tpmfront:Info " fmt, ##__VA_ARGS__)
+
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+
+void tpmfront_handler(evtchn_port_t port, struct pt_regs *regs, void *data) {
+   struct tpmfront_dev* dev = (struct tpmfront_dev*) data;
+   /*If we get a response when we didnt make a request, just ignore it */
+   if(!dev->waiting) {
+      return;
+   }
+
+   dev->waiting = 0;
+   wake_up(&dev->waitq);
+}
+
+static int publish_xenbus(struct tpmfront_dev* dev) {
+   xenbus_transaction_t xbt;
+   int retry;
+   char* err;
+   /* Write the grant reference and event channel to xenstore */
+again:
+   if((err = xenbus_transaction_start(&xbt))) {
+      TPMFRONT_ERR("Unable to start xenbus transaction, error was %s\n", err);
+      free(err);
+      return -1;
+   }
+
+   if((err = xenbus_printf(xbt, dev->nodename, "ring-ref", "%u", (unsigned int) dev->ring_ref))) {
+      TPMFRONT_ERR("Unable to write %s/ring-ref, error was %s\n", dev->nodename, err);
+      free(err);
+      goto abort_transaction;
+   }
+
+   if((err = xenbus_printf(xbt, dev->nodename, "event-channel", "%u", (unsigned int) dev->evtchn))) {
+      TPMFRONT_ERR("Unable to write %s/event-channel, error was %s\n", dev->nodename, err);
+      free(err);
+      goto abort_transaction;
+   }
+
+   if((err = xenbus_transaction_end(xbt, 0, &retry))) {
+      TPMFRONT_ERR("Unable to complete xenbus transaction, error was %s\n", err);
+      free(err);
+      return -1;
+   }
+   if(retry) {
+      goto again;
+   }
+
+   return 0;
+abort_transaction:
+   if((err = xenbus_transaction_end(xbt, 1, &retry))) {
+      free(err);
+   }
+   return -1;
+}
+
+static int wait_for_backend_connect(xenbus_event_queue* events, char* path)
+{
+   int state;
+
+   TPMFRONT_LOG("Waiting for backend connection..\n");
+   /* Wait for the backend to connect */
+   while(1) {
+      state = xenbus_read_integer(path);
+      if ( state < 0)
+	 state = XenbusStateUnknown;
+      switch(state) {
+	 /* Bad states, we quit with error */
+	 case XenbusStateUnknown:
+	 case XenbusStateClosing:
+	 case XenbusStateClosed:
+	    TPMFRONT_ERR("Unable to connect to backend\n");
+	    return -1;
+	 /* If backend is connected then break out of loop */
+	 case XenbusStateConnected:
+	    TPMFRONT_LOG("Backend Connected\n");
+	    return 0;
+	 default:
+	    xenbus_wait_for_watch(events);
+      }
+   }
+
+}
+
+static int wait_for_backend_closed(xenbus_event_queue* events, char* path)
+{
+   int state;
+
+   TPMFRONT_LOG("Waiting for backend to close..\n");
+   while(1) {
+      state = xenbus_read_integer(path);
+      if ( state < 0)
+	 state = XenbusStateUnknown;
+      switch(state) {
+	 case XenbusStateUnknown:
+	    TPMFRONT_ERR("Backend Unknown state, forcing shutdown\n");
+	    return -1;
+	 case XenbusStateClosed:
+	    TPMFRONT_LOG("Backend Closed\n");
+	    return 0;
+	 default:
+	    xenbus_wait_for_watch(events);
+      }
+   }
+
+}
+
+static int wait_for_backend_state_changed(struct tpmfront_dev* dev, XenbusState state) {
+   char* err;
+   int ret = 0;
+   xenbus_event_queue events = NULL;
+   char path[512];
+
+   snprintf(path, 512, "%s/state", dev->bepath);
+   /*Setup the watch to wait for the backend */
+   if((err = xenbus_watch_path_token(XBT_NIL, path, path, &events))) {
+      TPMFRONT_ERR("Could not set a watch on %s, error was %s\n", path, err);
+      free(err);
+      return -1;
+   }
+
+   /* Do the actual wait loop now */
+   switch(state) {
+      case XenbusStateConnected:
+	 ret = wait_for_backend_connect(&events, path);
+	 break;
+      case XenbusStateClosed:
+	 ret = wait_for_backend_closed(&events, path);
+	 break;
+      default:
+	 break;
+   }
+
+   if((err = xenbus_unwatch_path_token(XBT_NIL, path, path))) {
+      TPMFRONT_ERR("Unable to unwatch %s, error was %s, ignoring..\n", path, err);
+      free(err);
+   }
+   return ret;
+}
+
+static int tpmfront_connect(struct tpmfront_dev* dev)
+{
+   char* err;
+   /* Create shared page */
+   dev->tx = (tpmif_tx_interface_t*) alloc_page();
+   if(dev->tx == NULL) {
+      TPMFRONT_ERR("Unable to allocate page for shared memory\n");
+      goto error;
+   }
+   memset(dev->tx, 0, PAGE_SIZE);
+   dev->ring_ref = gnttab_grant_access(dev->bedomid, virt_to_mfn(dev->tx), 0);
+   TPMFRONT_DEBUG("grant ref is %lu\n", (unsigned long) dev->ring_ref);
+
+   /*Create event channel */
+   if(evtchn_alloc_unbound(dev->bedomid, tpmfront_handler, dev, &dev->evtchn)) {
+      TPMFRONT_ERR("Unable to allocate event channel\n");
+      goto error_postmap;
+   }
+   unmask_evtchn(dev->evtchn);
+   TPMFRONT_DEBUG("event channel is %lu\n", (unsigned long) dev->evtchn);
+
+   /* Write the entries to xenstore */
+   if(publish_xenbus(dev)) {
+      goto error_postevtchn;
+   }
+
+   /* Change state to connected */
+   dev->state = XenbusStateConnected;
+
+   /* Tell the backend that we are ready */
+   if((err = xenbus_printf(XBT_NIL, dev->nodename, "state", "%u", dev->state))) {
+      TPMFRONT_ERR("Unable to write to xenstore %s/state, value=%u", dev->nodename, XenbusStateConnected);
+      free(err);
+      goto error;
+   }
+
+   return 0;
+error_postevtchn:
+      mask_evtchn(dev->evtchn);
+      unbind_evtchn(dev->evtchn);
+error_postmap:
+      gnttab_end_access(dev->ring_ref);
+      free_page(dev->tx);
+error:
+   return -1;
+}
+
+struct tpmfront_dev* init_tpmfront(const char* _nodename)
+{
+   struct tpmfront_dev* dev;
+   const char* nodename;
+   char path[512];
+   char* value, *err;
+   unsigned long long ival;
+   int i;
+
+   printk("============= Init TPM Front ================\n");
+
+   dev = malloc(sizeof(struct tpmfront_dev));
+   memset(dev, 0, sizeof(struct tpmfront_dev));
+
+   nodename = _nodename ? _nodename : "device/vtpm/0";
+   dev->nodename = strdup(nodename);
+
+   init_waitqueue_head(&dev->waitq);
+
+   /* Get backend domid */
+   snprintf(path, 512, "%s/backend-id", dev->nodename);
+   if((err = xenbus_read(XBT_NIL, path, &value))) {
+      TPMFRONT_ERR("Unable to read %s during tpmfront initialization! error = %s\n", path, err);
+      free(err);
+      goto error;
+   }
+   if(sscanf(value, "%llu", &ival) != 1) {
+      TPMFRONT_ERR("%s has non-integer value (%s)\n", path, value);
+      free(value);
+      goto error;
+   }
+   free(value);
+   dev->bedomid = ival;
+
+   /* Get backend xenstore path */
+   snprintf(path, 512, "%s/backend", dev->nodename);
+   if((err = xenbus_read(XBT_NIL, path, &dev->bepath))) {
+      TPMFRONT_ERR("Unable to read %s during tpmfront initialization! error = %s\n", path, err);
+      free(err);
+      goto error;
+   }
+
+   /* Create and publish grant reference and event channel */
+   if (tpmfront_connect(dev)) {
+      goto error;
+   }
+   
+   /* Wait for backend to connect */
+   if( wait_for_backend_state_changed(dev, XenbusStateConnected)) {
+      goto error;
+   }
+
+   /* Allocate pages that will contain the messages */
+   dev->pages = malloc(sizeof(void*) * TPMIF_TX_RING_SIZE);
+   if(dev->pages == NULL) {
+      goto error;
+   }
+   memset(dev->pages, 0, sizeof(void*) * TPMIF_TX_RING_SIZE);
+   for(i = 0; i < TPMIF_TX_RING_SIZE; ++i) {
+      dev->pages[i] = (void*)alloc_page();
+      if(dev->pages[i] == NULL) {
+	 goto error;
+      }
+   }
+
+   /*Wait for the DMI instance number */
+   snprintf(path, 512, "%s/instance", dev->bepath);
+   while((err = xenbus_read(XBT_NIL, path, &value)) != NULL) {
+      free(err);
+      msleep(1000);
+   }
+   sscanf(value, "%d", &dev->dmi_id);
+   free(value);
+
+   TPMFRONT_LOG("Initialization Completed successfully\n");
+
+   return dev;
+
+error:
+   shutdown_tpmfront(dev);
+   return NULL;
+}
+void shutdown_tpmfront(struct tpmfront_dev* dev)
+{
+   char* err;
+   char path[512];
+   int i;
+   tpmif_tx_request_t* tx;
+   if(dev == NULL) {
+      return;
+   }
+   TPMFRONT_LOG("Shutting down tpmfront\n");
+   /* disconnect */
+   if(dev->state == XenbusStateConnected) {
+      dev->state = XenbusStateClosing;
+      //FIXME: Transaction for this?
+      /* Tell backend we are closing */
+      if((err = xenbus_printf(XBT_NIL, dev->nodename, "state", "%u", (unsigned int) dev->state))) {
+	 free(err);
+      }
+
+      /* Clean up xenstore entries */
+      snprintf(path, 512, "%s/event-channel", dev->nodename);
+      if((err = xenbus_rm(XBT_NIL, path))) {
+	 free(err);
+      }
+      snprintf(path, 512, "%s/ring-ref", dev->nodename);
+      if((err = xenbus_rm(XBT_NIL, path))) {
+	 free(err);
+      }
+
+      /* Tell backend we are closed */
+      dev->state = XenbusStateClosed;
+      if((err = xenbus_printf(XBT_NIL, dev->nodename, "state", "%u", (unsigned int) dev->state))) {
+	 TPMFRONT_ERR("Unable to write to %s, error was %s", dev->nodename, err);
+	 free(err);
+      }
+
+      /* Wait for the backend to close and unmap shared pages, ignore any errors */
+      wait_for_backend_state_changed(dev, XenbusStateClosed);
+
+      /* Cleanup any shared pages */
+      if(dev->pages) {
+	 for(i = 0; i < TPMIF_TX_RING_SIZE; ++i) {
+	    if(dev->pages[i]) {
+	       tx = &dev->tx->ring[i].req;
+	       if(tx->ref != 0) {
+		  gnttab_end_access(tx->ref);
+	       }
+	       free_page(dev->pages[i]);
+	    }
+	 }
+	 free(dev->pages);
+      }
+
+      /* Close event channel and unmap shared page */
+      mask_evtchn(dev->evtchn);
+      unbind_evtchn(dev->evtchn);
+      gnttab_end_access(dev->ring_ref);
+
+      free_page(dev->tx);
+
+   }
+
+   /* Cleanup memory usage */
+   if(dev->respbuf) {
+      free(dev->respbuf);
+   }
+   if(dev->bepath) {
+      free(dev->bepath);
+   }
+   if(dev->nodename) {
+      free(dev->nodename);
+   }
+   free(dev);
+}
+
+int tpmfront_send(struct tpmfront_dev* dev, uint8_t* msg, size_t length)
+{
+   int i;
+   tpmif_tx_request_t* tx = NULL;
+   /* Error Checking */
+   if(dev == NULL || dev->state != XenbusStateConnected) {
+      TPMFRONT_ERR("Tried to send message through disconnected frontend\n");
+      return -1;
+   }
+
+#ifdef TPMFRONT_PRINT_DEBUG
+   TPMFRONT_DEBUG("Sending Msg to backend size=%u", (unsigned int) length);
+   for(i = 0; i < length; ++i) {
+      if(!(i % 30)) {
+	 TPMFRONT_DEBUG_MORE("\n");
+      }
+      TPMFRONT_DEBUG_MORE("%02X ", msg[i]);
+   }
+   TPMFRONT_DEBUG_MORE("\n");
+#endif
+
+   /* Copy to shared pages now */
+   for(i = 0; length > 0 && i < TPMIF_TX_RING_SIZE; ++i) {
+      /* Share the page */
+      tx = &dev->tx->ring[i].req;
+      tx->unused = 0;
+      tx->addr = virt_to_mach(dev->pages[i]);
+      tx->ref = gnttab_grant_access(dev->bedomid, virt_to_mfn(dev->pages[i]), 0);
+      /* Copy the bits to the page */
+      tx->size = length > PAGE_SIZE ? PAGE_SIZE : length;
+      memcpy(dev->pages[i], &msg[i * PAGE_SIZE], tx->size);
+
+      /* Update counters */
+      length -= tx->size;
+   }
+   dev->waiting = 1;
+   notify_remote_via_evtchn(dev->evtchn);
+   return 0;
+}
+int tpmfront_recv(struct tpmfront_dev* dev, uint8_t** msg, size_t *length)
+{
+   tpmif_tx_request_t* tx;
+   int i;
+   if(dev == NULL || dev->state != XenbusStateConnected) {
+      TPMFRONT_ERR("Tried to receive message from disconnected frontend\n");
+      return -1;
+   }
+   /*Wait for the response */
+   wait_event(dev->waitq, (!dev->waiting));
+
+   /* Initialize */
+   *msg = NULL;
+   *length = 0;
+
+   /* special case, just quit */
+   tx = &dev->tx->ring[0].req;
+   if(tx->size == 0 ) {
+       goto quit;
+   }
+   /* Get the total size */
+   tx = &dev->tx->ring[0].req;
+   for(i = 0; i < TPMIF_TX_RING_SIZE && tx->size > 0; ++i) {
+      tx = &dev->tx->ring[i].req;
+      *length += tx->size;
+   }
+   /* Alloc the buffer */
+   if(dev->respbuf) {
+      free(dev->respbuf);
+   }
+   *msg = dev->respbuf = malloc(*length);
+   /* Copy the bits */
+   tx = &dev->tx->ring[0].req;
+   for(i = 0; i < TPMIF_TX_RING_SIZE && tx->size > 0; ++i) {
+      tx = &dev->tx->ring[i].req;
+      memcpy(&(*msg)[i * PAGE_SIZE], dev->pages[i], tx->size);
+      gnttab_end_access(tx->ref);
+      tx->ref = 0;
+   }
+#ifdef TPMFRONT_PRINT_DEBUG
+   TPMFRONT_DEBUG("Received response from backend size=%u", (unsigned int) *length);
+   for(i = 0; i < *length; ++i) {
+      if(!(i % 30)) {
+	 TPMFRONT_DEBUG_MORE("\n");
+      }
+      TPMFRONT_DEBUG_MORE("%02X ", (*msg)[i]);
+   }
+   TPMFRONT_DEBUG_MORE("\n");
+#endif
+quit:
+   return 0;
+}
+
+int tpmfront_cmd(struct tpmfront_dev* dev, uint8_t* req, size_t reqlen, uint8_t** resp, size_t* resplen)
+{
+   int rc;
+   if((rc = tpmfront_send(dev, req, reqlen))) {
+      return rc;
+   }
+   if((rc = tpmfront_recv(dev, resp, resplen))) {
+      return rc;
+   }
+
+   return 0;
+}
+
+#endif

[-- Attachment #1.2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 2518 bytes --]

[-- Attachment #2: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 4/7] vtpm Mini-Os domain: mini-os tpm device drivers
  2010-08-25 15:18 [PATCH 4/7] vtpm Mini-Os domain: mini-os tpm device drivers Matthew Fioravante
@ 2010-08-25 15:43 ` Samuel Thibault
  2010-09-03 18:54   ` Matthew Fioravante
  0 siblings, 1 reply; 6+ messages in thread
From: Samuel Thibault @ 2010-08-25 15:43 UTC (permalink / raw)
  To: Matthew Fioravante; +Cc: xen-devel

Matthew Fioravante, le Wed 25 Aug 2010 11:18:53 -0400, a écrit :
> diff -r 6615dd4045c7 -r 22a23fed2920 extras/mini-os/include/tpmback.h
> --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
> +++ b/extras/mini-os/include/tpmback.h	Tue Jul 20 16:38:40 2010 -0400
> @@ -0,0 +1,52 @@

You should probably add copyright headers in the files, else it's not
even sure which licence you are providing them under.

Apart from that I'm afraid I don't have the time to review your stubdom
patches, but the principle is probably ok.

Samuel

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 4/7] vtpm Mini-Os domain: mini-os tpm device drivers
  2010-08-25 15:43 ` Samuel Thibault
@ 2010-09-03 18:54   ` Matthew Fioravante
  2010-09-07 18:10     ` Ian Jackson
  0 siblings, 1 reply; 6+ messages in thread
From: Matthew Fioravante @ 2010-09-03 18:54 UTC (permalink / raw)
  To: Samuel Thibault; +Cc: xen-devel


[-- Attachment #1.1.1: Type: text/plain, Size: 802 bytes --]

  Here is a patch that adds the correct license for tpmfront.[ch] and 
tpmback.[ch]. Apply it on top of the previous patch.

Signed-off-by: Matthew Fioravante <matthew.fioravante@jhuapl.edu>


On 08/25/2010 11:43 AM, Samuel Thibault wrote:
> Matthew Fioravante, le Wed 25 Aug 2010 11:18:53 -0400, a écrit :
>> diff -r 6615dd4045c7 -r 22a23fed2920 extras/mini-os/include/tpmback.h
>> --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
>> +++ b/extras/mini-os/include/tpmback.h	Tue Jul 20 16:38:40 2010 -0400
>> @@ -0,0 +1,52 @@
> You should probably add copyright headers in the files, else it's not
> even sure which licence you are providing them under.
>
> Apart from that I'm afraid I don't have the time to review your stubdom
> patches, but the principle is probably ok.
>
> Samuel


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.1.2: 7-license.patch --]
[-- Type: text/x-patch; name="7-license.patch", Size: 8810 bytes --]

diff -r 015a5ecf29e8 extras/mini-os/include/tpmback.h
--- a/extras/mini-os/include/tpmback.h	Tue Jul 20 17:15:08 2010 -0400
+++ b/extras/mini-os/include/tpmback.h	Fri Sep 03 14:49:39 2010 -0400
@@ -1,3 +1,38 @@
+/* LICENSE AND DISCLAIMER
+ *
+ * Copyright © 2010 The Johns Hopkins University/Applied Physics 
+ * Laboratory
+
+ * This software was developed at The Johns Hopkins University/Applied 
+ * Physics Laboratory (“JHU/APL”) that is the author thereof under the 
+ * “work made for hire” provisions of the copyright law.  Permission is 
+ * hereby granted, free of charge, to any person obtaining a copy of this 
+ * software and associated documentation (the “Software”), to use the 
+ * Software without restriction, including without limitation the rights to 
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies 
+ * of the Software, and to permit others to do so, subject to the following 
+ * conditions:
+
+ * 1.  This LICENSE AND DISCLAIMER, including the copyright notice, shall 
+ * be included in all copies of the Software, including copies of 
+ * substantial portions of the Software; 
+
+ * 2.  JHU/APL assumes no obligation to provide support of any kind with 
+ * regard to the Software.  This includes no obligation to provide assistance
+ * in using the Software nor to provide updated versions of the Software; and
+
+ * 3.  THE SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT ANY 
+ * EXPRESS OR IMPLIED WARRANTIES WHATSOEVER.  ALL WARRANTIES INCLUDING, BUT 
+ * NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY, FITNESS FOR A PARTICULAR 
+ * PURPOSE, AND NONINFRINGEMENT ARE HEREBY DISCLAIMED.  USERS ASSUME THE 
+ * ENTIRE RISK AND LIABILITY OF USING THE SOFTWARE.  USERS ARE ADVISED TO 
+ * TEST THE SOFTWARE THOROUGHLY BEFORE RELYING ON IT.  IN NO EVENT SHALL THE 
+ * JOHNS HOPKINS UNIVERSITY BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING, 
+ * WITHOUT LIMITATION, ANY LOST PROFITS, LOST SAVINGS OR OTHER INCIDENTAL OR 
+ * CONSEQUENTIAL DAMAGES, ARISING OUT OF THE USE OR INABILITY TO USE THE 
+ * SOFTWARE.
+ */
+
 #include <xen/io/tpmif.h>
 #include <xen/io/xenbus.h>
 #include <mini-os/types.h>
diff -r 015a5ecf29e8 extras/mini-os/include/tpmfront.h
--- a/extras/mini-os/include/tpmfront.h	Tue Jul 20 17:15:08 2010 -0400
+++ b/extras/mini-os/include/tpmfront.h	Fri Sep 03 14:49:39 2010 -0400
@@ -1,3 +1,38 @@
+/* LICENSE AND DISCLAIMER
+ *
+ * Copyright © 2010 The Johns Hopkins University/Applied Physics 
+ * Laboratory
+
+ * This software was developed at The Johns Hopkins University/Applied 
+ * Physics Laboratory (“JHU/APL”) that is the author thereof under the 
+ * “work made for hire” provisions of the copyright law.  Permission is 
+ * hereby granted, free of charge, to any person obtaining a copy of this 
+ * software and associated documentation (the “Software”), to use the 
+ * Software without restriction, including without limitation the rights to 
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies 
+ * of the Software, and to permit others to do so, subject to the following 
+ * conditions:
+
+ * 1.  This LICENSE AND DISCLAIMER, including the copyright notice, shall 
+ * be included in all copies of the Software, including copies of 
+ * substantial portions of the Software; 
+
+ * 2.  JHU/APL assumes no obligation to provide support of any kind with 
+ * regard to the Software.  This includes no obligation to provide assistance
+ * in using the Software nor to provide updated versions of the Software; and
+
+ * 3.  THE SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT ANY 
+ * EXPRESS OR IMPLIED WARRANTIES WHATSOEVER.  ALL WARRANTIES INCLUDING, BUT 
+ * NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY, FITNESS FOR A PARTICULAR 
+ * PURPOSE, AND NONINFRINGEMENT ARE HEREBY DISCLAIMED.  USERS ASSUME THE 
+ * ENTIRE RISK AND LIABILITY OF USING THE SOFTWARE.  USERS ARE ADVISED TO 
+ * TEST THE SOFTWARE THOROUGHLY BEFORE RELYING ON IT.  IN NO EVENT SHALL THE 
+ * JOHNS HOPKINS UNIVERSITY BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING, 
+ * WITHOUT LIMITATION, ANY LOST PROFITS, LOST SAVINGS OR OTHER INCIDENTAL OR 
+ * CONSEQUENTIAL DAMAGES, ARISING OUT OF THE USE OR INABILITY TO USE THE 
+ * SOFTWARE.
+ */
+
 #ifndef TPMFRONT_H
 #define TPMFRONT_H
 
diff -r 015a5ecf29e8 extras/mini-os/tpmback.c
--- a/extras/mini-os/tpmback.c	Tue Jul 20 17:15:08 2010 -0400
+++ b/extras/mini-os/tpmback.c	Fri Sep 03 14:49:39 2010 -0400
@@ -1,3 +1,37 @@
+/* LICENSE AND DISCLAIMER
+ *
+ * Copyright © 2010 The Johns Hopkins University/Applied Physics 
+ * Laboratory
+
+ * This software was developed at The Johns Hopkins University/Applied 
+ * Physics Laboratory (“JHU/APL”) that is the author thereof under the 
+ * “work made for hire” provisions of the copyright law.  Permission is 
+ * hereby granted, free of charge, to any person obtaining a copy of this 
+ * software and associated documentation (the “Software”), to use the 
+ * Software without restriction, including without limitation the rights to 
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies 
+ * of the Software, and to permit others to do so, subject to the following 
+ * conditions:
+
+ * 1.  This LICENSE AND DISCLAIMER, including the copyright notice, shall 
+ * be included in all copies of the Software, including copies of 
+ * substantial portions of the Software; 
+
+ * 2.  JHU/APL assumes no obligation to provide support of any kind with 
+ * regard to the Software.  This includes no obligation to provide assistance
+ * in using the Software nor to provide updated versions of the Software; and
+
+ * 3.  THE SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT ANY 
+ * EXPRESS OR IMPLIED WARRANTIES WHATSOEVER.  ALL WARRANTIES INCLUDING, BUT 
+ * NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY, FITNESS FOR A PARTICULAR 
+ * PURPOSE, AND NONINFRINGEMENT ARE HEREBY DISCLAIMED.  USERS ASSUME THE 
+ * ENTIRE RISK AND LIABILITY OF USING THE SOFTWARE.  USERS ARE ADVISED TO 
+ * TEST THE SOFTWARE THOROUGHLY BEFORE RELYING ON IT.  IN NO EVENT SHALL THE 
+ * JOHNS HOPKINS UNIVERSITY BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING, 
+ * WITHOUT LIMITATION, ANY LOST PROFITS, LOST SAVINGS OR OTHER INCIDENTAL OR 
+ * CONSEQUENTIAL DAMAGES, ARISING OUT OF THE USE OR INABILITY TO USE THE 
+ * SOFTWARE.
+ */
 #include <mini-os/os.h>
 #include <mini-os/xenbus.h>
 #include <mini-os/events.h>
diff -r 015a5ecf29e8 extras/mini-os/tpmfront.c
--- a/extras/mini-os/tpmfront.c	Tue Jul 20 17:15:08 2010 -0400
+++ b/extras/mini-os/tpmfront.c	Fri Sep 03 14:49:39 2010 -0400
@@ -1,3 +1,37 @@
+/* LICENSE AND DISCLAIMER
+ *
+ * Copyright © 2010 The Johns Hopkins University/Applied Physics 
+ * Laboratory
+
+ * This software was developed at The Johns Hopkins University/Applied 
+ * Physics Laboratory (“JHU/APL”) that is the author thereof under the 
+ * “work made for hire” provisions of the copyright law.  Permission is 
+ * hereby granted, free of charge, to any person obtaining a copy of this 
+ * software and associated documentation (the “Software”), to use the 
+ * Software without restriction, including without limitation the rights to 
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies 
+ * of the Software, and to permit others to do so, subject to the following 
+ * conditions:
+
+ * 1.  This LICENSE AND DISCLAIMER, including the copyright notice, shall 
+ * be included in all copies of the Software, including copies of 
+ * substantial portions of the Software; 
+
+ * 2.  JHU/APL assumes no obligation to provide support of any kind with 
+ * regard to the Software.  This includes no obligation to provide assistance
+ * in using the Software nor to provide updated versions of the Software; and
+
+ * 3.  THE SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT ANY 
+ * EXPRESS OR IMPLIED WARRANTIES WHATSOEVER.  ALL WARRANTIES INCLUDING, BUT 
+ * NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY, FITNESS FOR A PARTICULAR 
+ * PURPOSE, AND NONINFRINGEMENT ARE HEREBY DISCLAIMED.  USERS ASSUME THE 
+ * ENTIRE RISK AND LIABILITY OF USING THE SOFTWARE.  USERS ARE ADVISED TO 
+ * TEST THE SOFTWARE THOROUGHLY BEFORE RELYING ON IT.  IN NO EVENT SHALL THE 
+ * JOHNS HOPKINS UNIVERSITY BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING, 
+ * WITHOUT LIMITATION, ANY LOST PROFITS, LOST SAVINGS OR OTHER INCIDENTAL OR 
+ * CONSEQUENTIAL DAMAGES, ARISING OUT OF THE USE OR INABILITY TO USE THE 
+ * SOFTWARE.
+ */
 #include <mini-os/types.h>
 #include <mini-os/os.h>
 #include <mini-os/xenbus.h>

[-- Attachment #1.2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 2518 bytes --]

[-- Attachment #2: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 4/7] vtpm Mini-Os domain: mini-os tpm device drivers
  2010-09-03 18:54   ` Matthew Fioravante
@ 2010-09-07 18:10     ` Ian Jackson
  2010-09-07 18:53       ` Matthew Fioravante
  2010-09-07 20:11       ` Samuel Thibault
  0 siblings, 2 replies; 6+ messages in thread
From: Ian Jackson @ 2010-09-07 18:10 UTC (permalink / raw)
  To: Matthew Fioravante; +Cc: Samuel Thibault, xen-devel

Matthew Fioravante writes ("Re: [Xen-devel] [PATCH 4/7] vtpm Mini-Os domain: mini-os tpm device drivers"):
>   Here is a patch that adds the correct license for tpmfront.[ch] and 
> tpmback.[ch]. Apply it on top of the previous patch.
> 
> Signed-off-by: Matthew Fioravante <matthew.fioravante@jhuapl.edu>

These files don't seem to exist in a built checkout of xen-unstable.

Ian.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 4/7] vtpm Mini-Os domain: mini-os tpm device drivers
  2010-09-07 18:10     ` Ian Jackson
@ 2010-09-07 18:53       ` Matthew Fioravante
  2010-09-07 20:11       ` Samuel Thibault
  1 sibling, 0 replies; 6+ messages in thread
From: Matthew Fioravante @ 2010-09-07 18:53 UTC (permalink / raw)
  To: Ian Jackson; +Cc: xen-devel


[-- Attachment #1.1: Type: text/plain, Size: 534 bytes --]

  you need to apply my previous set of vtpm patches first. Patch 4 adds 
the files.

On 09/07/2010 02:10 PM, Ian Jackson wrote:
> Matthew Fioravante writes ("Re: [Xen-devel] [PATCH 4/7] vtpm Mini-Os domain: mini-os tpm device drivers"):
>>    Here is a patch that adds the correct license for tpmfront.[ch] and
>> tpmback.[ch]. Apply it on top of the previous patch.
>>
>> Signed-off-by: Matthew Fioravante<matthew.fioravante@jhuapl.edu>
> These files don't seem to exist in a built checkout of xen-unstable.
>
> Ian.



[-- Attachment #1.2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 2518 bytes --]

[-- Attachment #2: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 4/7] vtpm Mini-Os domain: mini-os tpm device drivers
  2010-09-07 18:10     ` Ian Jackson
  2010-09-07 18:53       ` Matthew Fioravante
@ 2010-09-07 20:11       ` Samuel Thibault
  1 sibling, 0 replies; 6+ messages in thread
From: Samuel Thibault @ 2010-09-07 20:11 UTC (permalink / raw)
  To: Ian Jackson; +Cc: Matthew Fioravante, xen-devel

Ian Jackson, le Tue 07 Sep 2010 19:10:38 +0100, a écrit :
> Matthew Fioravante writes ("Re: [Xen-devel] [PATCH 4/7] vtpm Mini-Os domain: mini-os tpm device drivers"):
> >   Here is a patch that adds the correct license for tpmfront.[ch] and 
> > tpmback.[ch]. Apply it on top of the previous patch.
> > 
> > Signed-off-by: Matthew Fioravante <matthew.fioravante@jhuapl.edu>
> 
> These files don't seem to exist in a built checkout of xen-unstable.

They're meant to be applied on top of his previous patch.

Samuel

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2010-09-07 20:11 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-25 15:18 [PATCH 4/7] vtpm Mini-Os domain: mini-os tpm device drivers Matthew Fioravante
2010-08-25 15:43 ` Samuel Thibault
2010-09-03 18:54   ` Matthew Fioravante
2010-09-07 18:10     ` Ian Jackson
2010-09-07 18:53       ` Matthew Fioravante
2010-09-07 20:11       ` Samuel Thibault

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.