xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Matthew Fioravante <matthew.fioravante@jhuapl.edu>
To: Daniel De Graaf <dgdegra@tycho.nsa.gov>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>,
	"Ian.Campbell@citrix.com" <Ian.Campbell@citrix.com>,
	"xen-devel@lists.xen.org" <xen-devel@lists.xen.org>
Subject: Re: [PATCH 01/12] mini-os/tpm{back, front}: Change shared page ABI
Date: Tue, 26 Mar 2013 12:29:45 -0400	[thread overview]
Message-ID: <5151CCF9.1070307@jhuapl.edu> (raw)
In-Reply-To: <1363896689-11086-2-git-send-email-dgdegra@tycho.nsa.gov>


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

I'm going to merge your linux changes into my working linux patch with 
the fixes that are in response to konrad's comments. Will test with this 
on the mini-os end and get back to you.

After that, we can look at the remaining patches.

On 03/21/2013 04:11 PM, Daniel De Graaf wrote:
> This changes the vTPM shared page ABI from a copy of the Xen network
> interface to a single-page interface that better reflects the expected
> behavior of a TPM: only a single request packet can be sent at any given
> time, and every packet sent generates a single response packet. This
> protocol change should also increase efficiency as it avoids mapping and
> unmapping grants when possible. The vtpm xenbus device now requires a
> feature-protocol-v2 node in xenstore to avoid conflicts with existing
> (xen-patched) kernels supporting the old interface.
>
> While the contents of the shared page have been defined to allow packets
> larger than a single page (actually 4088 bytes) by allowing the client
> to add extra grant references, the mapping of these extra references has
> not been implemented; a feature node in xenstore may be used in the
> future to indicate full support for the multi-page protocol. Most uses
> of the TPM should not require this feature.
>
> Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
>
> ---
>
> Changes from v4: use feature-protocol-v2 nodes instead of changing the
> device name; add command cancellation support to the protocol.
> ---
>   extras/mini-os/include/tpmback.h  |   1 +
>   extras/mini-os/include/tpmfront.h |   7 +-
>   extras/mini-os/tpmback.c          | 161 +++++++++++++++++++-------------------
>   extras/mini-os/tpmfront.c         | 143 +++++++++++++++++----------------
>   xen/include/public/io/tpmif.h     |  49 ++++--------
>   5 files changed, 177 insertions(+), 184 deletions(-)
>
> diff --git a/extras/mini-os/include/tpmback.h b/extras/mini-os/include/tpmback.h
> index ff86732..ec9eda4 100644
> --- a/extras/mini-os/include/tpmback.h
> +++ b/extras/mini-os/include/tpmback.h
> @@ -43,6 +43,7 @@
>
>   struct tpmcmd {
>      domid_t domid;              /* Domid of the frontend */
> +   uint8_t locality;    /* Locality requested by the frontend */
>      unsigned int handle;        /* Handle of the frontend */
>      unsigned char uuid[16];                     /* uuid of the tpm interface */
>
> diff --git a/extras/mini-os/include/tpmfront.h b/extras/mini-os/include/tpmfront.h
> index fd2cb17..a0c7c4d 100644
> --- a/extras/mini-os/include/tpmfront.h
> +++ b/extras/mini-os/include/tpmfront.h
> @@ -37,9 +37,7 @@ struct tpmfront_dev {
>      grant_ref_t ring_ref;
>      evtchn_port_t evtchn;
>
> -   tpmif_tx_interface_t* tx;
> -
> -   void** pages;
> +   vtpm_shared_page_t *page;
>
>      domid_t bedomid;
>      char* nodename;
> @@ -77,6 +75,9 @@ void shutdown_tpmfront(struct tpmfront_dev* dev);
>    * */
>   int tpmfront_cmd(struct tpmfront_dev* dev, uint8_t* req, size_t reqlen, uint8_t** resp, size_t* resplen);
>
> +/* Set the locality used for communicating with a vTPM */
> +int tpmfront_set_locality(struct tpmfront_dev* dev, int locality);
> +
>   #ifdef HAVE_LIBC
>   #include <sys/stat.h>
>   /* POSIX IO functions:
> diff --git a/extras/mini-os/tpmback.c b/extras/mini-os/tpmback.c
> index 658fed1..1398b37 100644
> --- a/extras/mini-os/tpmback.c
> +++ b/extras/mini-os/tpmback.c
> @@ -86,10 +86,7 @@ struct tpmif {
>      evtchn_port_t evtchn;
>
>      /* Shared page */
> -   tpmif_tx_interface_t* tx;
> -
> -   /* pointer to TPMIF_RX_RING_SIZE pages */
> -   void** pages;
> +   vtpm_shared_page_t *page;
>
>      enum xenbus_state state;
>      enum { DISCONNECTED, DISCONNECTING, CONNECTED } status;
> @@ -266,6 +263,7 @@ int insert_tpmif(tpmif_t* tpmif)
>      unsigned int i, j;
>      tpmif_t* tmp;
>      char* err;
> +   char path[512];
>
>      local_irq_save(flags);
>
> @@ -303,6 +301,16 @@ int insert_tpmif(tpmif_t* tpmif)
>
>      local_irq_restore(flags);
>
> +   snprintf(path, 512, "backend/vtpm/%u/%u/feature-protocol-v2", (unsigned int) tpmif->domid, tpmif->handle);
> +   if ((err = xenbus_write(XBT_NIL, path, "1")))
> +   {
> +      /* if we got an error here we should carefully remove the interface and then return */
> +      TPMBACK_ERR("Unable to write feature-protocol-v2 node: %s\n", err);
> +      free(err);
> +      remove_tpmif(tpmif);
> +      goto error_post_irq;
> +   }
> +
>      /*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)))
>      {
> @@ -312,7 +320,6 @@ int insert_tpmif(tpmif_t* tpmif)
>         remove_tpmif(tpmif);
>         goto error_post_irq;
>      }
> -
>      return 0;
>   error:
>      local_irq_restore(flags);
> @@ -386,8 +393,7 @@ inline tpmif_t* __init_tpmif(domid_t domid, unsigned int handle)
>      tpmif->fe_state_path = NULL;
>      tpmif->state = XenbusStateInitialising;
>      tpmif->status = DISCONNECTED;
> -   tpmif->tx = NULL;
> -   tpmif->pages = NULL;
> +   tpmif->page = NULL;
>      tpmif->flags = 0;
>      memset(tpmif->uuid, 0, sizeof(tpmif->uuid));
>      return tpmif;
> @@ -395,9 +401,6 @@ inline tpmif_t* __init_tpmif(domid_t domid, unsigned int handle)
>
>   void __free_tpmif(tpmif_t* tpmif)
>   {
> -   if(tpmif->pages) {
> -      free(tpmif->pages);
> -   }
>      if(tpmif->fe_path) {
>         free(tpmif->fe_path);
>      }
> @@ -430,12 +433,6 @@ tpmif_t* new_tpmif(domid_t domid, unsigned int handle)
>         goto error;
>      }
>
> -   /* 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;
>      }
> @@ -486,7 +483,7 @@ void free_tpmif(tpmif_t* tpmif)
>         tpmif->status = DISCONNECTING;
>         mask_evtchn(tpmif->evtchn);
>
> -      if(gntmap_munmap(&gtpmdev.map, (unsigned long)tpmif->tx, 1)) {
> +      if(gntmap_munmap(&gtpmdev.map, (unsigned long)tpmif->page, 1)) {
>           TPMBACK_ERR("%u/%u Error occured while trying to unmap shared page\n", (unsigned int) tpmif->domid, tpmif->handle);
>         }
>
> @@ -529,15 +526,27 @@ void free_tpmif(tpmif_t* tpmif)
>   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, tpmif->handle);
> -   tpmif_req_ready(tpmif);
> -   wake_up(&waitq);
> +   vtpm_shared_page_t* pg = tpmif->page;
>
> +   switch (pg->state)
> +   {
> +   case VTPM_STATE_SUBMIT:
> +      TPMBACK_DEBUG("EVENT CHANNEL FIRE %u/%u\n", (unsigned int) tpmif->domid, tpmif->handle);
> +      tpmif_req_ready(tpmif);
> +      wake_up(&waitq);
> +      break;
> +   case VTPM_STATE_CANCEL:
> +      /* If we are busy with a request, do nothing */
> +      if (tpmif->flags & TPMIF_REQ_READY)
> +         return;
> +      /* Acknowledge the cancellation if we are idle */
> +      pg->state = VTPM_STATE_IDLE;
> +      notify_remote_via_evtchn(tpmif->evtchn);
> +      return;
> +   default:
> +      /* Spurious wakeup; do nothing */
> +      return;
> +   }
>   }
>
>   /* Connect to frontend */
> @@ -584,12 +593,25 @@ int connect_fe(tpmif_t* tpmif)
>      }
>      free(value);
>
> +   /* Check that protocol v2 is being used */
> +   snprintf(path, 512, "%s/feature-protocol-v2", tpmif->fe_path);
> +   if((err = xenbus_read(XBT_NIL, path, &value))) {
> +      TPMBACK_ERR("Unable to read %s during tpmback initialization! error = %s\n", path, err);
> +      free(err);
> +      return -1;
> +   }
> +   if(strcmp(value, "1")) {
> +      TPMBACK_ERR("%s has an invalid value (%s)\n", path, value);
> +      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) {
> +   if((tpmif->page = 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, 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)))
> @@ -618,7 +640,7 @@ error_post_evtchn:
>      mask_evtchn(tpmif->evtchn);
>      unbind_evtchn(tpmif->evtchn);
>   error_post_map:
> -   gntmap_munmap(&gtpmdev.map, (unsigned long)tpmif->tx, 1);
> +   gntmap_munmap(&gtpmdev.map, (unsigned long)tpmif->page, 1);
>      return -1;
>   }
>
> @@ -874,6 +896,7 @@ void shutdown_tpmback(void)
>   inline void init_tpmcmd(tpmcmd_t* tpmcmd, domid_t domid, unsigned int handle, unsigned char uuid[16])
>   {
>      tpmcmd->domid = domid;
> +   tpmcmd->locality = -1;
>      tpmcmd->handle = handle;
>      memcpy(tpmcmd->uuid, uuid, sizeof(tpmcmd->uuid));
>      tpmcmd->req = NULL;
> @@ -884,12 +907,12 @@ inline void init_tpmcmd(tpmcmd_t* tpmcmd, domid_t domid, unsigned int handle, un
>
>   tpmcmd_t* get_request(tpmif_t* tpmif) {
>      tpmcmd_t* cmd;
> -   tpmif_tx_request_t* tx;
> -   int offset;
> -   int tocopy;
> -   int i;
> -   uint32_t domid;
> +   vtpm_shared_page_t* shr;
> +   unsigned int offset;
>      int flags;
> +#ifdef TPMBACK_PRINT_DEBUG
> +   int i;
> +#endif
>
>      local_irq_save(flags);
>
> @@ -899,35 +922,22 @@ tpmcmd_t* get_request(tpmif_t* tpmif) {
>      }
>      init_tpmcmd(cmd, tpmif->domid, tpmif->handle, tpmif->uuid);
>
> -   tx = &tpmif->tx->ring[0].req;
> -   cmd->req_len = tx->size;
> +   shr = tpmif->page;
> +   cmd->req_len = shr->length;
> +   cmd->locality = shr->locality;
> +   offset = sizeof(*shr) + 4*shr->nr_extra_pages;
> +   if (offset > PAGE_SIZE || offset + cmd->req_len > PAGE_SIZE) {
> +      TPMBACK_ERR("%u/%u Command size too long for shared page!\n", (unsigned int) tpmif->domid, tpmif->handle);
> +      goto error;
> +   }
>      /* 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, 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);
> -
> -   }
> +   /* Copy the bits from the shared page(s) */
> +   memcpy(cmd->req, offset + (uint8_t*)shr, cmd->req_len);
>
>   #ifdef TPMBACK_PRINT_DEBUG
>      TPMBACK_DEBUG("Received Tpm Command from %u/%u of size %u", (unsigned int) tpmif->domid, tpmif->handle, cmd->req_len);
> @@ -958,38 +968,24 @@ error:
>
>   void send_response(tpmcmd_t* cmd, tpmif_t* tpmif)
>   {
> -   tpmif_tx_request_t* tx;
> -   int offset;
> -   int i;
> -   uint32_t domid;
> -   int tocopy;
> +   vtpm_shared_page_t* shr;
> +   unsigned int offset;
>      int flags;
> +#ifdef TPMBACK_PRINT_DEBUG
> +int i;
> +#endif
>
>      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, 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);
> +   shr = tpmif->page;
> +   shr->length = cmd->resp_len;
>
> +   offset = sizeof(*shr) + 4*shr->nr_extra_pages;
> +   if (offset > PAGE_SIZE || offset + cmd->resp_len > PAGE_SIZE) {
> +      TPMBACK_ERR("%u/%u Command size too long for shared page!\n", (unsigned int) tpmif->domid, tpmif->handle);
> +      goto error;
>      }
> +   memcpy(offset + (uint8_t*)shr, cmd->resp, cmd->resp_len);
>
>   #ifdef TPMBACK_PRINT_DEBUG
>      TPMBACK_DEBUG("Sent response to %u/%u of size %u", (unsigned int) tpmif->domid, tpmif->handle, cmd->resp_len);
> @@ -1003,6 +999,7 @@ void send_response(tpmcmd_t* cmd, tpmif_t* tpmif)
>   #endif
>      /* clear the ready flag and send the event channel notice to the frontend */
>      tpmif_req_finished(tpmif);
> +   shr->state = VTPM_STATE_FINISH;
>      notify_remote_via_evtchn(tpmif->evtchn);
>   error:
>      local_irq_restore(flags);
> diff --git a/extras/mini-os/tpmfront.c b/extras/mini-os/tpmfront.c
> index 0218d7f..a15b5cf 100644
> --- a/extras/mini-os/tpmfront.c
> +++ b/extras/mini-os/tpmfront.c
> @@ -47,11 +47,21 @@
>
>   void tpmfront_handler(evtchn_port_t port, struct pt_regs *regs, void *data) {
>      struct tpmfront_dev* dev = (struct tpmfront_dev*) data;
> +   vtpm_shared_page_t* shr = dev->page;
>      /*If we get a response when we didnt make a request, just ignore it */
>      if(!dev->waiting) {
>         return;
>      }
>
> +   switch (shr->state) {
> +   case VTPM_STATE_FINISH: /* request was completed */
> +   case VTPM_STATE_IDLE:   /* request was cancelled */
> +      break;
> +   default:
> +      /* Spurious wakeup; do nothing, request is still pending */
> +      return;
> +   }
> +
>      dev->waiting = 0;
>   #ifdef HAVE_LIBC
>      if(dev->fd >= 0) {
> @@ -176,7 +186,7 @@ static int wait_for_backend_state_changed(struct tpmfront_dev* dev, XenbusState
>           ret = wait_for_backend_closed(&events, path);
>           break;
>         default:
> -        break;
> +         TPMFRONT_ERR("Bad wait state %d, ignoring\n", state);
>      }
>
>      if((err = xenbus_unwatch_path_token(XBT_NIL, path, path))) {
> @@ -190,13 +200,13 @@ 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) {
> +   dev->page = (vtpm_shared_page_t*) alloc_page();
> +   if(dev->page == 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);
> +   memset(dev->page, 0, PAGE_SIZE);
> +   dev->ring_ref = gnttab_grant_access(dev->bedomid, virt_to_mfn(dev->page), 0);
>      TPMFRONT_DEBUG("grant ref is %lu\n", (unsigned long) dev->ring_ref);
>
>      /*Create event channel */
> @@ -228,7 +238,7 @@ error_postevtchn:
>         unbind_evtchn(dev->evtchn);
>   error_postmap:
>         gnttab_end_access(dev->ring_ref);
> -      free_page(dev->tx);
> +      free_page(dev->page);
>   error:
>      return -1;
>   }
> @@ -240,7 +250,6 @@ struct tpmfront_dev* init_tpmfront(const char* _nodename)
>      char path[512];
>      char* value, *err;
>      unsigned long long ival;
> -   int i;
>
>      printk("============= Init TPM Front ================\n");
>
> @@ -279,6 +288,15 @@ struct tpmfront_dev* init_tpmfront(const char* _nodename)
>         goto error;
>      }
>
> +   /* Publish protocol v2 feature */
> +   snprintf(path, 512, "%s/feature-protocol-v2", dev->nodename);
> +   if ((err = xenbus_write(XBT_NIL, path, "1")))
> +   {
> +      TPMFRONT_ERR("Unable to write feature-protocol-v2 node: %s\n", err);
> +      free(err);
> +      goto error;
> +   }
> +
>      /* Create and publish grant reference and event channel */
>      if (tpmfront_connect(dev)) {
>         goto error;
> @@ -289,18 +307,19 @@ struct tpmfront_dev* init_tpmfront(const char* _nodename)
>         goto error;
>      }
>
> -   /* Allocate pages that will contain the messages */
> -   dev->pages = malloc(sizeof(void*) * TPMIF_TX_RING_SIZE);
> -   if(dev->pages == NULL) {
> +   /* Ensure backend is also using protocol v2 */
> +   snprintf(path, 512, "%s/feature-protocol-v2", dev->bepath);
> +   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;
>      }
> -   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;
> -      }
> +   if(strcmp(value, "1")) {
> +      TPMFRONT_ERR("%s has an invalid value (%s)\n", path, value);
> +      free(value);
> +      goto error;
>      }
> +   free(value);
>
>      TPMFRONT_LOG("Initialization Completed successfully\n");
>
> @@ -314,8 +333,6 @@ void shutdown_tpmfront(struct tpmfront_dev* dev)
>   {
>      char* err;
>      char path[512];
> -   int i;
> -   tpmif_tx_request_t* tx;
>      if(dev == NULL) {
>         return;
>      }
> @@ -349,27 +366,12 @@ void shutdown_tpmfront(struct tpmfront_dev* dev)
>         /* 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);
> -
> +      free_page(dev->page);
>      }
>
>      /* Cleanup memory usage */
> @@ -387,13 +389,17 @@ void shutdown_tpmfront(struct tpmfront_dev* dev)
>
>   int tpmfront_send(struct tpmfront_dev* dev, const uint8_t* msg, size_t length)
>   {
> +   unsigned int offset;
> +   vtpm_shared_page_t* shr = NULL;
> +#ifdef TPMFRONT_PRINT_DEBUG
>      int i;
> -   tpmif_tx_request_t* tx = NULL;
> +#endif
>      /* Error Checking */
>      if(dev == NULL || dev->state != XenbusStateConnected) {
>         TPMFRONT_ERR("Tried to send message through disconnected frontend\n");
>         return -1;
>      }
> +   shr = dev->page;
>
>   #ifdef TPMFRONT_PRINT_DEBUG
>      TPMFRONT_DEBUG("Sending Msg to backend size=%u", (unsigned int) length);
> @@ -407,19 +413,16 @@ int tpmfront_send(struct tpmfront_dev* dev, const uint8_t* msg, size_t length)
>   #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;
> +   offset = sizeof(*shr);
> +   if (length + offset > PAGE_SIZE) {
> +      TPMFRONT_ERR("Message too long for shared page\n");
> +      return -1;
>      }
> +   memcpy(offset + (uint8_t*)shr, msg, length);
> +   shr->length = length;
> +   barrier();
> +   shr->state = VTPM_STATE_SUBMIT;
> +
>      dev->waiting = 1;
>      dev->resplen = 0;
>   #ifdef HAVE_LIBC
> @@ -434,44 +437,44 @@ int tpmfront_send(struct tpmfront_dev* dev, const uint8_t* msg, size_t length)
>   }
>   int tpmfront_recv(struct tpmfront_dev* dev, uint8_t** msg, size_t *length)
>   {
> -   tpmif_tx_request_t* tx;
> -   int i;
> +   unsigned int offset;
> +   vtpm_shared_page_t* shr = NULL;
> +#ifdef TPMFRONT_PRINT_DEBUG
> +int i;
> +#endif
>      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));
> +   shr = dev->page;
>
>      /* Initialize */
>      *msg = NULL;
>      *length = 0;
> +   offset = sizeof(*shr);
>
> -   /* 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;
> +   if (shr->state != VTPM_STATE_FINISH)
> +      goto quit;
> +
> +   *length = shr->length;
> +
> +   if (*length + offset > PAGE_SIZE) {
> +      TPMFRONT_ERR("Reply too long for shared page\n");
> +      return -1;
>      }
> +
>      /* Alloc the buffer */
>      if(dev->respbuf) {
>         free(dev->respbuf);
>      }
>      *msg = dev->respbuf = malloc(*length);
>      dev->resplen = *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;
> -   }
> +   memcpy(*msg, offset + (uint8_t*)shr, *length);
> +
>   #ifdef TPMFRONT_PRINT_DEBUG
>      TPMFRONT_DEBUG("Received response from backend size=%u", (unsigned int) *length);
>      for(i = 0; i < *length; ++i) {
> @@ -504,6 +507,14 @@ int tpmfront_cmd(struct tpmfront_dev* dev, uint8_t* req, size_t reqlen, uint8_t*
>      return 0;
>   }
>
> +int tpmfront_set_locality(struct tpmfront_dev* dev, int locality)
> +{
> +   if (!dev || !dev->page)
> +      return -1;
> +   dev->page->locality = locality;
> +   return 0;
> +}
> +
>   #ifdef HAVE_LIBC
>   #include <errno.h>
>   int tpmfront_open(struct tpmfront_dev* dev)
> diff --git a/xen/include/public/io/tpmif.h b/xen/include/public/io/tpmif.h
> index fca2c4e..ab0c652 100644
> --- a/xen/include/public/io/tpmif.h
> +++ b/xen/include/public/io/tpmif.h
> @@ -1,7 +1,7 @@
>   /******************************************************************************
>    * tpmif.h
>    *
> - * TPM I/O interface for Xen guest OSes.
> + * TPM I/O interface for Xen guest OSes, v2
>    *
>    * Permission is hereby granted, free of charge, to any person obtaining a copy
>    * of this software and associated documentation files (the "Software"), to
> @@ -21,48 +21,31 @@
>    * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
>    * DEALINGS IN THE SOFTWARE.
>    *
> - * Copyright (c) 2005, IBM Corporation
> - *
> - * Author: Stefan Berger, stefanb@us.ibm.com
> - * Grant table support: Mahadevan Gomathisankaran
> - *
> - * This code has been derived from tools/libxc/xen/io/netif.h
> - *
> - * Copyright (c) 2003-2004, Keir Fraser
>    */
>
>   #ifndef __XEN_PUBLIC_IO_TPMIF_H__
>   #define __XEN_PUBLIC_IO_TPMIF_H__
>
> -#include "../grant_table.h"
> -
> -struct tpmif_tx_request {
> -    unsigned long addr;   /* Machine address of packet.   */
> -    grant_ref_t ref;      /* grant table access reference */
> -    uint16_t unused;
> -    uint16_t size;        /* Packet size in bytes.        */
> +enum vtpm_state {
> +    VTPM_STATE_IDLE,         /* no contents / vTPM idle / cancel complete */
> +    VTPM_STATE_SUBMIT,       /* request ready / vTPM working */
> +    VTPM_STATE_FINISH,       /* response ready / vTPM idle */
> +    VTPM_STATE_CANCEL,       /* cancel requested / vTPM working */
>   };
> -typedef struct tpmif_tx_request tpmif_tx_request_t;
> +/* The backend should only change state to IDLE or FINISH, while the
> + * frontend should only change to SUBMIT or CANCEL. */
>
> -/*
> - * The TPMIF_TX_RING_SIZE defines the number of pages the
> - * front-end and backend can exchange (= size of array).
> - */
> -typedef uint32_t TPMIF_RING_IDX;
> -
> -#define TPMIF_TX_RING_SIZE 1
> +struct vtpm_shared_page {
> +    uint32_t length;         /* request/response length in bytes */
>
> -/* This structure must fit in a memory page. */
> -
> -struct tpmif_ring {
> -    struct tpmif_tx_request req;
> -};
> -typedef struct tpmif_ring tpmif_ring_t;
> +    uint8_t state;           /* enum vtpm_state */
> +    uint8_t locality;        /* for the current request */
> +    uint8_t pad;             /* should be zero */
>
> -struct tpmif_tx_interface {
> -    struct tpmif_ring ring[TPMIF_TX_RING_SIZE];
> +    uint8_t nr_extra_pages;  /* extra pages for long packets; may be zero */
> +    uint32_t extra_pages[0]; /* grant IDs; length is actually nr_extra_pages */
>   };
> -typedef struct tpmif_tx_interface tpmif_tx_interface_t;
> +typedef struct vtpm_shared_page vtpm_shared_page_t;
>
>   #endif
>
> --
> 1.8.1.4
>



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

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

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

  reply	other threads:[~2013-03-26 16:29 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-03-21 20:11 [PATCH v5 00/12] vTPM updates for 4.3 Daniel De Graaf
2013-03-21 20:11 ` [PATCH 01/12] mini-os/tpm{back, front}: Change shared page ABI Daniel De Graaf
2013-03-26 16:29   ` Matthew Fioravante [this message]
2013-03-26 16:52     ` [PATCH] drivers/tpm: add xen tpmfront interface (Re: [PATCH 01/12]...) Daniel De Graaf
2013-03-26 17:16       ` Matthew Fioravante
2013-03-21 20:11 ` [PATCH 02/12] mini-os/tpm{back, front}: Allow device repoens Daniel De Graaf
2013-03-21 20:11 ` [PATCH 03/12] mini-os/tpmback: set up callbacks before enumeration Daniel De Graaf
2013-03-21 20:11 ` [PATCH 04/12] mini-os/tpmback: Replace UUID field with opaque pointer Daniel De Graaf
2013-03-21 20:11 ` [PATCH 05/12] mini-os/tpmback: add tpmback_get_peercontext Daniel De Graaf
2013-03-21 20:11 ` [PATCH 06/12] stubdom/vtpm: correct the buffer size returned by TPM_CAP_PROP_INPUT_BUFFER Daniel De Graaf
2013-03-21 20:11 ` [PATCH 07/12] stubdom/vtpm: Support locality field Daniel De Graaf
2013-03-21 20:11 ` [PATCH 08/12] stubdom/vtpm: make state save operation atomic Daniel De Graaf
2013-03-21 20:11 ` [PATCH 09/12] stubdom/vtpm: support multiple backends Daniel De Graaf
2013-03-21 20:11 ` [PATCH 10/12] stubdom/vtpm: constrain locality by XSM label Daniel De Graaf
2013-03-21 20:11 ` [PATCH 11/12] stubdom/grub: send kernel measurements to vTPM Daniel De Graaf
2013-03-21 20:11 ` [PATCH 12/12] stubdom/Makefile: Fix gmp extract rule Daniel De Graaf
2013-04-11 14:54   ` Ian Campbell
2013-03-21 20:12 ` [PATCH] drivers/tpm-xen: Change vTPM shared page ABI Daniel De Graaf
2013-03-22  8:26   ` Jan Beulich
2013-03-22 14:37     ` Daniel De Graaf
2013-03-22 15:25       ` Jan Beulich
2013-03-22 16:46         ` Daniel De Graaf
2013-03-22 12:41   ` Konrad Rzeszutek Wilk
2013-03-22 14:37     ` Daniel De Graaf
2013-04-12 13:42 ` [PATCH v5 00/12] vTPM updates for 4.3 Ian Campbell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5151CCF9.1070307@jhuapl.edu \
    --to=matthew.fioravante@jhuapl.edu \
    --cc=Ian.Campbell@citrix.com \
    --cc=dgdegra@tycho.nsa.gov \
    --cc=konrad.wilk@oracle.com \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).