]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/mini-os.git/commitdiff
mini-os/tpm{back, front}: Allow device repoens
authorDaniel De Graaf <dgdegra@tycho.nsa.gov>
Thu, 21 Mar 2013 20:11:19 +0000 (16:11 -0400)
committerIan Campbell <ian.campbell@citrix.com>
Fri, 12 Apr 2013 13:28:17 +0000 (14:28 +0100)
Allow the vtpm device to be disconnected and reconnected so that a
bootloader (like pv-grub) can submit measurements and return the vtpm
device to its initial state before booting the target kernel.

Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
tpmback.c
tpmfront.c

index d68ad2b8768d4950ba22e0f7a3d6b0ca291cce7c..99177651332face57abf0f44d1fae3bf31fc73de 100644 (file)
--- a/tpmback.c
+++ b/tpmback.c
@@ -645,6 +645,24 @@ error_post_map:
    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, XenbusStateInitWait);
+
+   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);
@@ -671,8 +689,11 @@ static int frontend_changed(tpmif_t* tpmif)
         tpmif_change_state(tpmif, XenbusStateClosing);
         break;
 
-      case XenbusStateUnknown: /* keep it here */
       case XenbusStateClosed:
+         disconnect_fe(tpmif);
+        break;
+
+      case XenbusStateUnknown: /* keep it here */
         free_tpmif(tpmif);
         break;
 
index 9f930b5c6f31adbddd652e1301836a5139eb95e6..95d86f6fcceba2471d8f33778220be86044df2ea 100644 (file)
@@ -156,6 +156,9 @@ static int wait_for_backend_closed(xenbus_event_queue* events, char* path)
         case XenbusStateClosed:
            TPMFRONT_LOG("Backend Closed\n");
            return 0;
+        case XenbusStateInitWait:
+           TPMFRONT_LOG("Backend Closed (waiting for reconnect)\n");
+           return 0;
         default:
            xenbus_wait_for_watch(events);
       }
@@ -339,10 +342,10 @@ void shutdown_tpmfront(struct tpmfront_dev* dev)
    TPMFRONT_LOG("Shutting down tpmfront\n");
    /* disconnect */
    if(dev->state == XenbusStateConnected) {
-      dev->state = XenbusStateClosing;
-      //FIXME: Transaction for this?
       /* Tell backend we are closing */
+      dev->state = XenbusStateClosing;
       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);
       }
 
@@ -366,6 +369,13 @@ 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);
 
+      /* Prepare for a later reopen (possibly by a kexec'd kernel) */
+      dev->state = XenbusStateInitialising;
+      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);
+      }
+
       /* Close event channel and unmap shared page */
       mask_evtchn(dev->evtchn);
       unbind_evtchn(dev->evtchn);