xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 00/14] vTPM new ABI, extensions
@ 2012-12-10 19:55 Daniel De Graaf
  2012-12-10 19:55 ` [PATCH 01/14] mini-os/tpm{back, front}: Change shared page ABI Daniel De Graaf
                   ` (15 more replies)
  0 siblings, 16 replies; 36+ messages in thread
From: Daniel De Graaf @ 2012-12-10 19:55 UTC (permalink / raw)
  To: matthew.fioravante; +Cc: xen-devel

This patch queue goes on top of Matthew Fioravante's [VTPM v7 0/8]
series.  The xenbus device name has changed to "vtpm2", and some
documentation has been added about PCRs (those extended by pv-grub and
those added in locality 5).  A new Linux patch is also needed, and will
be posted as a reply to this email; the layout of the shared page has
changed slightly (length field changed from uint16_t to uint32_t).

Patches have been reordered a bit in an attempt to have the series make
the most sense possible if partially applied.  Patch #8 still breaks
automatic vTPM domain shutdown, so only applying #1-6 would be useful if
we would like that feature to continue working while the libxl-based
shutdown request is not finished.

Patch 10-13 are new here; they allow localities to be restricted for
certain domains.  This is an important security feature if multiple
domains are accessing the same vTPM, and without this feature the
locality 5 PCRs introduced by #7 are no different from the lower 24
defined in the TPM specification.

Patch 14 is a build cleanup that fixes the third consecutive build
without an intervening "make clean" when NEWLIB_STAMPFILE is touched
after gmp is extracted.


New ABI patches:
    [PATCH 01/14] mini-os/tpm{back,front}: Change shared page ABI
    [PATCH 02/14] stubdom/vtpm: correct the buffer size returned by
    [PATCH 03/14] stubdom/vtpm: Support locality field

New vTPM features:
    [PATCH 04/14] stubdom/vtpm: Allow repoen of closed devices
    [PATCH 05/14] stubdom/vtpm: make state save operation atomic
    [PATCH 06/14] stubdom/grub: send kernel measurements to vTPM

Support for multiple client domains distinguished by locality:
    [PATCH 07/14] stubdom/vtpm: Add locality-5 PCRs
    [PATCH 08/14] stubdom/vtpm: support multiple backends
    [PATCH 09/14] stubdom/vtpm: Add PCR pass-through to hardware TPM
    [PATCH 10/14] mini-os/tpmback: set up callbacks before enumeration
    [PATCH 11/14] mini-os/tpmback: Replace UUID field with opaque
    [PATCH 12/14] mini-os/tpmback: add tpmback_get_peercontext
    [PATCH 13/14] stubdom/vtpm: constrain locality by XSM label

Other:
    [PATCH 14/14] stubdom/Makefile: Fix gmp extract rule

^ permalink raw reply	[flat|nested] 36+ messages in thread
* [PATCH v5 00/12] vTPM updates for 4.3
@ 2013-03-21 20:11 Daniel De Graaf
  2013-03-21 20:12 ` [PATCH] drivers/tpm-xen: Change vTPM shared page ABI Daniel De Graaf
  0 siblings, 1 reply; 36+ messages in thread
From: Daniel De Graaf @ 2013-03-21 20:11 UTC (permalink / raw)
  To: Matthew.Fioravante; +Cc: dgdegra, Ian.Campbell, xen-devel

This series contains a bit of reworking from v4: command cancellation is
now supported in the protocol, although not yet exposed through the API.
Since the TPM emulator used by Xen doesn't support cancellation anyway,
this is not currently an important requirement.

The xenbus name for the interface has been changed back to "vtpm" -
renaming it to vtpm2 requires changing libxl to only support the new
device name with mismatches between the use of vtpm in the API it
exposes and vtpm2 in the values used internally. Using feature nodes to
denote the protocol change allows also libxl to wire up both the old
interface and the new interface.

Automatic vTPM shutdown is removed by patch #9; however, since patch #8
makes it safe to destroy the vTPM at any point, the cleanup of a vTPM
upon guest shutdown can be relocated to the layer that starts the vTPM.
This is necessary even without these patches because vTPMs have never
automatically shut down if a guest encoutners an error in early boot or
simply does not load (or have) the frontend driver.

Locality-5 PCRs have been dropped since v4: this patch is not really
suited for upstreaming until there is a domain using the extra PCRs.

Mini-os driver patches:
    [PATCH 01/12] mini-os/tpm{back,front}: Change shared page ABI
    [PATCH 02/12] mini-os/tpm{back,front}: Allow device repoens
    [PATCH 03/12] mini-os/tpmback: set up callbacks before enumeration
    [PATCH 04/12] mini-os/tpmback: Replace UUID field with opaque pointer
    [PATCH 05/12] mini-os/tpmback: add tpmback_get_peercontext

Linux driver patch:
    [PATCH] drivers/tpm-xen: Change vTPM shared page ABI

vTPM stub-domain updates:
    [PATCH 06/12] stubdom/vtpm: correct the buffer size returned by
    [PATCH 07/12] stubdom/vtpm: Support locality field
    [PATCH 08/12] stubdom/vtpm: make state save operation atomic
    [PATCH 09/12] stubdom/vtpm: support multiple backends
    [PATCH 10/12] stubdom/vtpm: constrain locality by XSM label

Other stub domain updates:
    [PATCH 11/12] stubdom/grub: send kernel measurements to vTPM
    [PATCH 12/12] stubdom/Makefile: Fix gmp extract rule

^ permalink raw reply	[flat|nested] 36+ messages in thread
* [PATCH v4 00/13] vTPM new ABI, extensions
@ 2013-01-23 18:29 Daniel De Graaf
  2013-01-23 18:43 ` [PATCH] drivers/tpm-xen: Change vTPM shared page ABI Daniel De Graaf
  0 siblings, 1 reply; 36+ messages in thread
From: Daniel De Graaf @ 2013-01-23 18:29 UTC (permalink / raw)
  To: ian.campbell; +Cc: matthew.fioravante, xen-devel

This series is the same as v3, just rebased on the now-applied v9 vtpm
stubdomain patches and with Acks added. One patch has been dropped (PCR
pass-through to the hardware TPM) as its implementation was incomplete.

Automatic vTPM shutdown is removed by patch #8, but this automatic
shutdown breaks the GRUB vTPM support added by patch #6 will also not
handle automatic shutdown if the guest does not use the vTPM (module not
loaded, for example). Now that state saving is atomic (patch #5), the
vTPM can be destroyed using "xl destroy" or similar calls at any time
after the guest is destroyed, or a proper shutdown can be issued (which
should also now be supported).

New ABI patches:
    [PATCH 01/13] mini-os/tpm{back,front}: Change shared page ABI
    [PATCH 02/13] stubdom/vtpm: correct the buffer size returned by
    [PATCH 03/13] stubdom/vtpm: Support locality field

New vTPM features:
    [PATCH 04/13] mini-os/tpm{back,front}: Allow device repoens
    [PATCH 05/13] stubdom/vtpm: make state save operation atomic
    [PATCH 06/13] stubdom/grub: send kernel measurements to vTPM

Support for multiple client domains distinguished by locality:
    [PATCH 07/13] stubdom/vtpm: Add locality-5 PCRs
    [PATCH 08/13] stubdom/vtpm: support multiple backends
    [PATCH 09/13] mini-os/tpmback: set up callbacks before enumeration
    [PATCH 10/13] mini-os/tpmback: Replace UUID field with opaque pointer
    [PATCH 11/13] mini-os/tpmback: add tpmback_get_peercontext
    [PATCH 12/13] stubdom/vtpm: constrain locality by XSM label
    [PATCH 13/13] stubdom/Makefile: Fix gmp extract rule

^ permalink raw reply	[flat|nested] 36+ messages in thread
* Re: [PATCH RFC] stubdom: Change vTPM shared page ABI
@ 2012-11-20 16:16 Fioravante, Matthew E.
  2012-11-20 18:24 ` [PATCH] drivers/tpm-xen: " Daniel De Graaf
  0 siblings, 1 reply; 36+ messages in thread
From: Fioravante, Matthew E. @ 2012-11-20 16:16 UTC (permalink / raw)
  To: Daniel De Graaf; +Cc: Ian.Campbell@citrix.com, xen-devel@lists.xen.org

This was something I've been wanting to do for a while so I'm very happy you went ahead and fixed it yourself. Once you submit the linux version I'll test it on my system.

Acked by: Matthew Fioravante <matthew.fioravante@jhuapl.edu>

-----Original Message-----
From: Daniel De Graaf [mailto:dgdegra@tycho.nsa.gov]
Sent: Tuesday, November 20, 2012 11:11 AM
To: Fioravante, Matthew E.
Cc: xen-devel@lists.xen.org; Ian.Campbell@citrix.com; Daniel De Graaf
Subject: [PATCH RFC] stubdom: Change vTPM shared page ABI

Since the vTPM implementations are being incorproated into Xen and possibly upstream Linux, I would like to see if this protocol change could be added before we have significant legacy implementations. If not, I still think it would be useful as either a v2 or negotiated protocol change.

The current vTPM protocol is a copy of the network protocol. This was likely done for ease of implementation, since support for the network backend/frontend existed in Linux and minios. However, this implementation is overly complex when dealing with vTPM packets: for example, a vTPM never needs to deal with having more than one packet in flight at any given time.

I will send the corresponding patch for the Linux kernel module once I have adapted it for the file names used in the upstream version.

------------------------------------>8----------------------------------

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.

Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
---
 extras/mini-os/include/tpmback.h  |   1 +
 extras/mini-os/include/tpmfront.h |   7 +-
 extras/mini-os/tpmback.c          | 132 ++++++++++++++-------------------
 extras/mini-os/tpmfront.c         | 150 +++++++++++++++++++-------------------
 xen/include/public/io/tpmif.h     |  45 +++---------
 5 files changed, 148 insertions(+), 187 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..29aced9 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; @@ -386,8 +383,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 +391,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 +423,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 +473,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,9 +516,10 @@ 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)
+   vtpm_shared_page_t* pg = tpmif->page;
+
+   /* Only pay attention if the request is ready */
+   if (pg->state == 0)
       return;

    TPMBACK_DEBUG("EVENT CHANNEL FIRE %u/%u\n", (unsigned int) tpmif->domid, tpmif->handle); @@ -585,11 +573,10 @@ int connect_fe(tpmif_t* tpmif)
    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,10 +605,28 @@ 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;
 }

+static void disconnect_fe(tpmif_t* tpmif) {
+   if (tpmif->status == CONNECTED) {
+      tpmif->status = DISCONNECTING;
+      mask_evtchn(tpmif->evtchn);
+
+      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);
+      }
+
+      unbind_evtchn(tpmif->evtchn);
+   }
+   tpmif->status = DISCONNECTED;
+   tpmif_change_state(tpmif, XenbusStateReconfigured);
+
+   TPMBACK_LOG("Frontend %u/%u disconnected\n", (unsigned int)
+tpmif->domid, tpmif->handle); }
+
 static int frontend_changed(tpmif_t* tpmif)  {
    int state = xenbus_read_integer(tpmif->fe_state_path);
@@ -874,6 +879,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 +890,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 +905,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 +951,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 +982,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 = 0;
    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..bcee93d 100644
--- a/extras/mini-os/tpmfront.c
+++ b/extras/mini-os/tpmfront.c
@@ -153,6 +153,32 @@ static int wait_for_backend_closed(xenbus_event_queue* events, char* path)

 }

+static int wait_for_backend_reconfig(xenbus_event_queue* events, char*
+path) {
+   int state;
+
+   TPMFRONT_LOG("Waiting for backend to reconfigure...\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;
+        case XenbusStateReconfigured:
+           TPMFRONT_LOG("Backend Reconfigured\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;
@@ -175,8 +201,11 @@ static int wait_for_backend_state_changed(struct tpmfront_dev* dev, XenbusState
       case XenbusStateClosed:
         ret = wait_for_backend_closed(&events, path);
         break;
-      default:
+      case XenbusStateReconfigured:
+        ret = wait_for_backend_reconfig(&events, path);
         break;
+      default:
+         TPMFRONT_ERR("Bad wait state %d, ignoring\n", state);
    }

    if((err = xenbus_unwatch_path_token(XBT_NIL, path, path))) { @@ -190,13 +219,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 +257,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 +269,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");

@@ -289,19 +317,6 @@ 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) {
-      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;
-      }
-   }
-
    TPMFRONT_LOG("Initialization Completed successfully\n");

    return dev;
@@ -314,12 +329,10 @@ 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");
+   TPMFRONT_LOG("Shutting down tpmfront%s\n", for_reconfig ? " for
+ reconfigure" : "");
    /* disconnect */
    if(dev->state == XenbusStateConnected) {
       dev->state = XenbusStateClosing;
@@ -349,27 +362,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 +385,17 @@ void shutdown_tpmfront(struct tpmfront_dev* dev)

 int tpmfront_send(struct tpmfront_dev* dev, const uint8_t* msg, size_t length)  {
-   int i;
-   tpmif_tx_request_t* tx = NULL;
+   unsigned int offset;
+   vtpm_shared_page_t* shr = NULL;
+#ifdef TPMFRONT_PRINT_DEBUG
+int i;
+#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 +409,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 = 1;
+
    dev->waiting = 1;
    dev->resplen = 0;
 #ifdef HAVE_LIBC
@@ -434,44 +433,41 @@ 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;
+   if (shr->state != 0)
+      goto quit;

    /* Initialize */
    *msg = NULL;
-   *length = 0;
+   *length = shr->length;
+   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 (*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 +500,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 02ccdab..afc9181 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,23 @@
  * 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 vtpm_shared_page {
+    uint16_t length;         /* request/response length in bytes */

-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.        */
-};
-typedef struct tpmif_tx_request tpmif_tx_request_t;
-
-/*
- * 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
-
-/* 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;           /* 0 - response ready / idle
+                              * 1 - request ready / working */
+    uint8_t locality;        /* for the current request */
+    uint8_t padding[3];

-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.7.11.7

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

end of thread, other threads:[~2013-03-22 16:46 UTC | newest]

Thread overview: 36+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-12-10 19:55 [PATCH v3 00/14] vTPM new ABI, extensions Daniel De Graaf
2012-12-10 19:55 ` [PATCH 01/14] mini-os/tpm{back, front}: Change shared page ABI Daniel De Graaf
2012-12-14 20:16   ` [PATCH v3.2] " Daniel De Graaf
2012-12-10 19:55 ` [PATCH 02/14] stubdom/vtpm: correct the buffer size returned by TPM_CAP_PROP_INPUT_BUFFER Daniel De Graaf
2012-12-10 19:55 ` [PATCH 03/14] stubdom/vtpm: Support locality field Daniel De Graaf
2012-12-10 19:55 ` [PATCH 04/14] stubdom/vtpm: Allow repoen of closed devices Daniel De Graaf
2012-12-10 19:55 ` [PATCH 05/14] stubdom/vtpm: make state save operation atomic Daniel De Graaf
2012-12-10 19:55 ` [PATCH 06/14] stubdom/grub: send kernel measurements to vTPM Daniel De Graaf
2012-12-10 19:55 ` [PATCH 07/14] stubdom/vtpm: Add locality-5 PCRs Daniel De Graaf
2012-12-10 19:55 ` [PATCH 08/14] stubdom/vtpm: support multiple backends Daniel De Graaf
2012-12-10 19:55 ` [PATCH 09/14] stubdom/vtpm: Add PCR pass-through to hardware TPM Daniel De Graaf
2012-12-14 20:12   ` Daniel De Graaf
2012-12-10 19:55 ` [PATCH 10/14] mini-os/tpmback: set up callbacks before enumeration Daniel De Graaf
2012-12-10 19:55 ` [PATCH 11/14] mini-os/tpmback: Replace UUID field with opaque pointer Daniel De Graaf
2012-12-10 19:55 ` [PATCH 12/14] mini-os/tpmback: add tpmback_get_peercontext Daniel De Graaf
2012-12-10 21:20   ` Samuel Thibault
2012-12-10 21:22     ` Daniel De Graaf
2012-12-10 21:25       ` Samuel Thibault
2012-12-10 19:55 ` [PATCH 13/14] stubdom/vtpm: constrain locality by XSM label Daniel De Graaf
2012-12-10 19:55 ` [PATCH 14/14] stubdom/Makefile: Fix gmp extract rule Daniel De Graaf
2012-12-10 21:24   ` Samuel Thibault
2012-12-10 21:28     ` Daniel De Graaf
2012-12-10 21:33       ` Samuel Thibault
2012-12-10 20:00 ` [PATCH] drivers/tpm-xen: Change vTPM shared page ABI Daniel De Graaf
2012-12-11 11:52   ` Jan Beulich
2012-12-11 14:55     ` Daniel De Graaf
2013-01-18 15:12 ` [PATCH v3 00/14] vTPM new ABI, extensions Ian Campbell
  -- strict thread matches above, loose matches on Subject: below --
2013-03-21 20:11 [PATCH v5 00/12] vTPM updates for 4.3 Daniel De Graaf
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-01-23 18:29 [PATCH v4 00/13] vTPM new ABI, extensions Daniel De Graaf
2013-01-23 18:43 ` [PATCH] drivers/tpm-xen: Change vTPM shared page ABI Daniel De Graaf
2012-11-20 16:16 [PATCH RFC] stubdom: " Fioravante, Matthew E.
2012-11-20 18:24 ` [PATCH] drivers/tpm-xen: " Daniel De Graaf

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).