WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] Update vtpm driver following the recent changes to the

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Update vtpm driver following the recent changes to the
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 25 Nov 2005 09:36:06 +0000
Delivery-date: Fri, 25 Nov 2005 09:36:20 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID cb215a84d1af0aa0143e52a459607f54503a51a7
# Parent  b0338759544e116337f25d5cdebc59c38a6d40c5
Update vtpm driver following the recent changes to the 
xenbus driver and its semantics.

Signed-off-by: Stefan Berger <stefanb@xxxxxxxxxx>

diff -r b0338759544e -r cb215a84d1af docs/misc/vtpm.txt
--- a/docs/misc/vtpm.txt        Thu Nov 24 22:21:48 2005
+++ b/docs/misc/vtpm.txt        Fri Nov 25 08:14:01 2005
@@ -73,7 +73,14 @@
 where the TPM backend has been compiled into - this has to be 
 domain 0  at the moment - and which TPM instance the user domain
 is supposed to talk to. Note that each running VM must use a 
-different instance and that using instance 0 is NOT allowed.
+different instance and that using instance 0 is NOT allowed. The
+instance parameter is taken as the desired instance number, but
+the actual instance number that is assigned to the virtual machine
+can be different. This is the case if for example that particular
+instance is already used by another virtual machine. The association
+of which TPM instance number is used by which virtual machine is
+kept in the file /etc/xen/vtpm.db. Associations are maintained by
+domain name and instance number.
 
 Note: If you do not want TPM functionality for your user domain simply
 leave out the 'vtpm' line in the configuration file.
diff -r b0338759544e -r cb215a84d1af 
linux-2.6-xen-sparse/drivers/char/tpm/Kconfig
--- a/linux-2.6-xen-sparse/drivers/char/tpm/Kconfig     Thu Nov 24 22:21:48 2005
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/Kconfig     Fri Nov 25 08:14:01 2005
@@ -17,15 +17,6 @@
          obtained at: <http://sourceforge.net/projects/trousers>.  To 
          compile this driver as a module, choose M here; the module 
          will be called tpm. If unsure, say N.
-
-config TCG_TIS
-       tristate "TPM Interface Specification 1.2 Interface"
-       depends on TCG_TPM
-       ---help---
-         If you have a TPM security chip that is compliant with the
-         TCG TIS 1.2 TPM specification say Yes and it will be accessible
-         from within Linux.  To compile this driver as a module, choose
-         M here; the module will be called tpm_tis.
 
 config TCG_NSC
        tristate "National Semiconductor TPM Interface"
diff -r b0338759544e -r cb215a84d1af 
linux-2.6-xen-sparse/drivers/xen/tpmback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Thu Nov 24 22:21:48 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Fri Nov 25 08:14:01 2005
@@ -28,7 +28,7 @@
 #endif
 
 typedef struct tpmif_st {
-        struct list_head tpmif_list;
+       struct list_head tpmif_list;
        /* Unique identifier for this interface. */
        domid_t domid;
        unsigned int handle;
@@ -83,6 +83,11 @@
 
 #define MMAP_VADDR(t,_req) ((t)->mmap_vstart + ((_req) * PAGE_SIZE))
 
+#ifndef TRUE
+#define TRUE 1
+#define FALSE 0
+#endif
+
 #endif /* __TPMIF__BACKEND__COMMON_H__ */
 
 /*
diff -r b0338759544e -r cb215a84d1af 
linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c      Thu Nov 24 
22:21:48 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c      Fri Nov 25 
08:14:01 2005
@@ -127,6 +127,10 @@
                .u.bind_interdomain.remote_dom = tpmif->domid,
                .u.bind_interdomain.remote_port = evtchn };
 
+        if (tpmif->irq) {
+                return 0;
+        }
+
        if ((tpmif->tx_area = alloc_vm_area(PAGE_SIZE)) == NULL)
                return -ENOMEM;
 
@@ -149,7 +153,6 @@
 
        tpmif->irq = bind_evtchn_to_irqhandler(
                tpmif->evtchn, tpmif_be_int, 0, "tpmif-backend", tpmif);
-       tpmif->status = CONNECTED;
        tpmif->shmem_ref = shared_page;
        tpmif->active = 1;
 
diff -r b0338759544e -r cb215a84d1af 
linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Thu Nov 24 22:21:48 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Fri Nov 25 08:14:01 2005
@@ -1,4 +1,5 @@
 /*  Xenbus code for tpmif backend
+    Copyright (C) 2005 IBM Corporation
     Copyright (C) 2005 Rusty Russell <rusty@xxxxxxxxxxxxxxx>
 
     This program is free software; you can redistribute it and/or modify
@@ -29,72 +30,189 @@
 
        long int frontend_id;
        long int instance; // instance of TPM
+       u8 is_instance_set;// whether instance number has been set
 
        /* watch front end for changes */
        struct xenbus_watch backend_watch;
-
-       struct xenbus_watch watch;
-       char * frontpath;
+       XenbusState frontend_state;
 };
 
+static void maybe_connect(struct backend_info *be);
+static void connect(struct backend_info *be);
+static int connect_ring(struct backend_info *be);
+static void backend_changed(struct xenbus_watch *watch,
+                            const char **vec, unsigned int len);
+static void frontend_changed(struct xenbus_device *dev,
+                             XenbusState frontend_state);
+
 static int tpmback_remove(struct xenbus_device *dev)
 {
        struct backend_info *be = dev->data;
 
-       if (be->watch.node)
-               unregister_xenbus_watch(&be->watch);
-       unregister_xenbus_watch(&be->backend_watch);
-
-       tpmif_vtpm_close(be->instance);
-
-       if (be->tpmif)
+       if (be->backend_watch.node) {
+               unregister_xenbus_watch(&be->backend_watch);
+               kfree(be->backend_watch.node);
+               be->backend_watch.node = NULL;
+       }
+       if (be->tpmif) {
                tpmif_put(be->tpmif);
-
-       kfree(be->frontpath);
+               be->tpmif = NULL;
+       }
        kfree(be);
+       dev->data = NULL;
        return 0;
 }
 
-
-static void frontend_changed(struct xenbus_watch *watch,
-                            const char **vec, unsigned int len)
-{
-       unsigned long ringref;
-       unsigned int evtchn;
-       unsigned long ready = 1;
-       int err;
-       struct xenbus_transaction *xbt;
+static int tpmback_probe(struct xenbus_device *dev,
+                         const struct xenbus_device_id *id)
+{
+       int err;
+       struct backend_info *be = kmalloc(sizeof(struct backend_info),
+                                         GFP_KERNEL);
+
+       if (!be) {
+               xenbus_dev_fatal(dev, -ENOMEM,
+                                "allocating backend structure");
+               return -ENOMEM;
+       }
+
+       memset(be, 0, sizeof(*be));
+
+       be->is_instance_set = FALSE;
+       be->dev = dev;
+       dev->data = be;
+
+       err = xenbus_watch_path2(dev, dev->nodename,
+                               "instance", &be->backend_watch,
+                               backend_changed);
+       if (err) {
+               goto fail;
+       }
+
+       err = xenbus_switch_state(dev, NULL, XenbusStateInitWait);
+       if (err) {
+               goto fail;
+       }
+       return 0;
+fail:
+       tpmback_remove(dev);
+       return err;
+}
+
+
+static void backend_changed(struct xenbus_watch *watch,
+                            const char **vec, unsigned int len)
+{
+       int err;
+       long instance;
        struct backend_info *be
-               = container_of(watch, struct backend_info, watch);
-
-       /* If other end is gone, delete ourself. */
-       if (vec && !xenbus_exists(NULL, be->frontpath, "")) {
-               xenbus_rm(NULL, be->dev->nodename, "");
+               = container_of(watch, struct backend_info, backend_watch);
+       struct xenbus_device *dev = be->dev;
+
+       err = xenbus_scanf(NULL, dev->nodename,
+                          "instance","%li", &instance);
+       if (XENBUS_EXIST_ERR(err)) {
+               return;
+       }
+
+       if (err != 1) {
+               xenbus_dev_fatal(dev, err, "reading instance");
+               return;
+       }
+
+       if (be->is_instance_set != FALSE && be->instance != instance) {
+               printk(KERN_WARNING
+                      "tpmback: changing instance (from %ld to %ld) "
+                      "not allowed.\n",
+                      be->instance, instance);
+               return;
+       }
+
+       if (be->is_instance_set == FALSE) {
+               be->tpmif = tpmif_find(dev->otherend_id,
+                                      instance);
+               if (IS_ERR(be->tpmif)) {
+                       err = PTR_ERR(be->tpmif);
+                       be->tpmif = NULL;
+                       xenbus_dev_fatal(dev,err,"creating block interface");
+                       return;
+               }
+               be->instance = instance;
+               be->is_instance_set = TRUE;
+
+               /*
+                * There's an unfortunate problem:
+                * Sometimes after a suspend/resume the
+                * state switch to XenbusStateInitialised happens
+                * *before* I get to this point here. Since then
+                * the connect_ring() must have failed (be->tpmif is
+                * still NULL), I just call it here again indirectly.
+                */
+               if (be->frontend_state == XenbusStateInitialised) {
+                       frontend_changed(dev, be->frontend_state);
+               }
+       }
+}
+
+
+static void frontend_changed(struct xenbus_device *dev,
+                             XenbusState frontend_state)
+{
+       struct backend_info *be = dev->data;
+       int err;
+
+       be->frontend_state = frontend_state;
+
+       switch (frontend_state) {
+       case XenbusStateInitialising:
+       case XenbusStateConnected:
+               break;
+
+       case XenbusStateInitialised:
+               err = connect_ring(be);
+               if (err) {
+                       return;
+               }
+               maybe_connect(be);
+               break;
+
+       case XenbusStateClosing:
+               xenbus_switch_state(dev, NULL, XenbusStateClosing);
+               break;
+
+       case XenbusStateClosed:
+               /*
+                * Notify the vTPM manager about the front-end
+                * having left.
+                */
+               tpmif_vtpm_close(be->instance);
                device_unregister(&be->dev->dev);
-               return;
-       }
+               break;
+
+       case XenbusStateUnknown:
+       case XenbusStateInitWait:
+       default:
+               xenbus_dev_fatal(dev, -EINVAL,
+                                "saw state %d at frontend",
+                                frontend_state);
+               break;
+       }
+}
+
+
+
+static void maybe_connect(struct backend_info *be)
+{
+       int err;
 
        if (be->tpmif == NULL || be->tpmif->status == CONNECTED)
                return;
 
-       err = xenbus_gather(NULL, be->frontpath,
-                           "ring-ref", "%lu", &ringref,
-                           "event-channel", "%u", &evtchn, NULL);
-       if (err) {
-               xenbus_dev_error(be->dev, err,
-                                "reading %s/ring-ref and event-channel",
-                                be->frontpath);
-               return;
-       }
-
-       err = tpmif_map(be->tpmif, ringref, evtchn);
-       if (err) {
-               xenbus_dev_error(be->dev, err,
-                                "mapping shared-frame %lu port %u",
-                                ringref, evtchn);
-               return;
-       }
-
+       connect(be);
+
+       /*
+        * Notify the vTPM manager about a new front-end.
+        */
        err = tpmif_vtpm_open(be->tpmif,
                              be->frontend_id,
                              be->instance);
@@ -107,157 +225,75 @@
                 */
                return;
        }
-
-       /*
-        * Tell the front-end that we are ready to go -
-        * unless something bad happens
-        */
+}
+
+
+static void connect(struct backend_info *be)
+{
+       struct xenbus_transaction *xbt;
+       int err;
+       struct xenbus_device *dev = be->dev;
+       unsigned long ready = 1;
+
 again:
        xbt = xenbus_transaction_start();
        if (IS_ERR(xbt)) {
-               xenbus_dev_error(be->dev, err, "starting transaction");
+               err = PTR_ERR(xbt);
+               xenbus_dev_fatal(be->dev, err, "starting transaction");
                return;
        }
 
        err = xenbus_printf(xbt, be->dev->nodename,
                            "ready", "%lu", ready);
        if (err) {
-               xenbus_dev_error(be->dev, err, "writing 'ready'");
+               xenbus_dev_fatal(be->dev, err, "writing 'ready'");
                goto abort;
        }
+
+       err = xenbus_switch_state(dev, xbt, XenbusStateConnected);
+       if (err)
+               goto abort;
+
+       be->tpmif->status = CONNECTED;
 
        err = xenbus_transaction_end(xbt, 0);
        if (err == -EAGAIN)
                goto again;
        if (err) {
-               xenbus_dev_error(be->dev, err, "end of transaction");
-               goto abort;
-       }
-
-       xenbus_dev_ok(be->dev);
+               xenbus_dev_fatal(be->dev, err, "end of transaction");
+       }
        return;
 abort:
        xenbus_transaction_end(xbt, 1);
 }
 
 
-static void backend_changed(struct xenbus_watch *watch,
-                           const char **vec, unsigned int len)
-{
-       int err;
-       long int instance;
-       struct backend_info *be
-               = container_of(watch, struct backend_info, backend_watch);
+static int connect_ring(struct backend_info *be)
+{
        struct xenbus_device *dev = be->dev;
-
-       err = xenbus_scanf(NULL, dev->nodename, "instance", "%li", &instance);
-       if (XENBUS_EXIST_ERR(err))
-               return;
-       if (err < 0) {
-               xenbus_dev_error(dev, err, "reading 'instance' variable");
-               return;
-       }
-
-       if (be->instance != -1 && be->instance != instance) {
-               printk(KERN_WARNING
-                      "cannot change the instance\n");
-               return;
-       }
-       be->instance = instance;
-
-       if (be->tpmif == NULL) {
-               unsigned int len = max(XS_WATCH_PATH, XS_WATCH_TOKEN) + 1;
-               const char *vec[len];
-
-               be->tpmif = tpmif_find(be->frontend_id,
-                                      instance);
-               if (IS_ERR(be->tpmif)) {
-                       err = PTR_ERR(be->tpmif);
-                       be->tpmif = NULL;
-                       xenbus_dev_error(dev, err, "creating interface");
-                       return;
+       unsigned long ring_ref;
+       unsigned int evtchn;
+       int err;
+
+       err = xenbus_gather(NULL, dev->otherend,
+                           "ring-ref", "%lu", &ring_ref,
+                           "event-channel", "%u", &evtchn, NULL);
+       if (err) {
+               xenbus_dev_error(dev, err,
+                                "reading %s/ring-ref and event-channel",
+                                dev->otherend);
+               return err;
+       }
+       if (be->tpmif != NULL) {
+               err = tpmif_map(be->tpmif, ring_ref, evtchn);
+               if (err) {
+                       xenbus_dev_error(dev, err,
+                                        "mapping shared-frame %lu port %u",
+                                        ring_ref, evtchn);
+                       return err;
                }
-
-               vec[XS_WATCH_PATH] = be->frontpath;
-               vec[XS_WATCH_TOKEN] = NULL;
-
-               /* Pass in NULL node to skip exist test. */
-               frontend_changed(&be->watch, vec, len);
-       }
-}
-
-
-static int tpmback_probe(struct xenbus_device *dev,
-                        const struct xenbus_device_id *id)
-{
-       struct backend_info *be;
-       char *frontend;
-       int err;
-
-       be = kmalloc(sizeof(*be), GFP_KERNEL);
-       if (!be) {
-               xenbus_dev_error(dev, -ENOMEM, "allocating backend structure");
-               err = -ENOMEM;
-       }
-
-       memset(be, 0, sizeof(*be));
-
-       frontend = NULL;
-       err = xenbus_gather(NULL, dev->nodename,
-                           "frontend-id", "%li", &be->frontend_id,
-                           "frontend", NULL, &frontend,
-                           NULL);
-       if (XENBUS_EXIST_ERR(err))
-               goto free_be;
-       if (err < 0) {
-               xenbus_dev_error(dev, err,
-                                "reading %s/frontend or frontend-id",
-                                dev->nodename);
-               goto free_be;
-       }
-       if (strlen(frontend) == 0 || !xenbus_exists(NULL, frontend, "")) {
-               /* If we can't get a frontend path and a frontend-id,
-                * then our bus-id is no longer valid and we need to
-                * destroy the backend device.
-                */
-               err = -ENOENT;
-               goto free_be;
-       }
-
-       be->dev = dev;
-       be->backend_watch.node     = dev->nodename;
-       /* Implicitly calls backend_changed() once. */
-       be->backend_watch.callback = backend_changed;
-       be->instance = -1;
-       err = register_xenbus_watch(&be->backend_watch);
-       if (err) {
-               be->backend_watch.node = NULL;
-               xenbus_dev_error(dev, err, "adding backend watch on %s",
-                                dev->nodename);
-               goto free_be;
-       }
-
-       be->frontpath = frontend;
-       be->watch.node = be->frontpath;
-       be->watch.callback = frontend_changed;
-       err = register_xenbus_watch(&be->watch);
-       if (err) {
-               be->watch.node = NULL;
-               xenbus_dev_error(dev, err,
-                                "adding frontend watch on %s",
-                                be->frontpath);
-               goto free_be;
-       }
-
-       dev->data = be;
-       return err;
-
-free_be:
-       if (be->backend_watch.node)
-               unregister_xenbus_watch(&be->backend_watch);
-       kfree(frontend);
-       kfree(be);
-       return err;
+       }
+       return 0;
 }
 
 
@@ -273,6 +309,7 @@
        .ids = tpmback_ids,
        .probe = tpmback_probe,
        .remove = tpmback_remove,
+       .otherend_changed = frontend_changed,
 };
 
 
diff -r b0338759544e -r cb215a84d1af 
linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c      Thu Nov 24 
22:21:48 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c      Fri Nov 25 
08:14:01 2005
@@ -73,7 +73,8 @@
 static void tpmif_connect(u16 evtchn, domid_t domid);
 static DECLARE_TASKLET(tpmif_rx_tasklet, tpmif_rx_action, 0);
 static int tpm_allocate_buffers(struct tpm_private *tp);
-static void tpmif_set_connected_state(struct tpm_private *tp, int newstate);
+static void tpmif_set_connected_state(struct tpm_private *tp,
+                                      u8 newstate);
 static int tpm_xmit(struct tpm_private *tp,
                     const u8 * buf, size_t count, int userbuffer,
                     void *remember);
@@ -212,87 +213,46 @@
  XENBUS support code
 **************************************************************/
 
-static void watch_for_status(struct xenbus_watch *watch,
-                            const char **vec, unsigned int len)
-{
-       struct tpmfront_info *info;
-       int err;
-       unsigned long ready;
-       struct tpm_private *tp = &my_private;
-       const char *node = vec[XS_WATCH_PATH];
-
-       info = container_of(watch, struct tpmfront_info, watch);
-       node += strlen(watch->node);
-
-       if (tp->connected)
-               return;
-
-       err = xenbus_gather(NULL, watch->node,
-                           "ready", "%lu", &ready,
-                           NULL);
-       if (err) {
-               xenbus_dev_error(info->dev, err, "reading 'ready' field");
-               return;
-       }
-
-       tpmif_set_connected_state(tp, 1);
-
-       xenbus_dev_ok(info->dev);
-}
-
-
 static int setup_tpmring(struct xenbus_device *dev,
-                         struct tpmfront_info * info,
-                         domid_t backend_id)
+                         struct tpmfront_info * info)
 {
        tpmif_tx_interface_t *sring;
        struct tpm_private *tp = &my_private;
        int err;
-       evtchn_op_t op = {
-               .cmd = EVTCHNOP_alloc_unbound,
-               .u.alloc_unbound.dom = DOMID_SELF,
-               .u.alloc_unbound.remote_dom = backend_id } ;
 
        sring = (void *)__get_free_page(GFP_KERNEL);
        if (!sring) {
-               xenbus_dev_error(dev, -ENOMEM, "allocating shared ring");
+               xenbus_dev_fatal(dev, -ENOMEM, "allocating shared ring");
                return -ENOMEM;
        }
        tp->tx = sring;
 
        tpm_allocate_buffers(tp);
 
-       err = gnttab_grant_foreign_access(backend_id,
-                                         (virt_to_machine(tp->tx) >> 
PAGE_SHIFT),
-                                         0);
-
-       if (err == -ENOSPC) {
+       err = xenbus_grant_ring(dev, virt_to_mfn(tp->tx));
+       if (err < 0) {
                free_page((unsigned long)sring);
                tp->tx = NULL;
-               xenbus_dev_error(dev, err, "allocating grant reference");
-               return err;
+               xenbus_dev_fatal(dev, err, "allocating grant reference");
+               goto fail;
        }
        info->ring_ref = err;
 
-       err = HYPERVISOR_event_channel_op(&op);
-       if (err) {
-               gnttab_end_foreign_access(info->ring_ref, 0,
-                                         (unsigned long)sring);
-               tp->tx = NULL;
-               xenbus_dev_error(dev, err, "allocating event channel");
-               return err;
-       }
-
-       tpmif_connect(op.u.alloc_unbound.port, backend_id);
+       err = xenbus_alloc_evtchn(dev, &tp->evtchn);
+       if (err)
+               goto fail;
+
+       tpmif_connect(tp->evtchn, dev->otherend_id);
 
        return 0;
+fail:
+       return err;
 }
 
 
 static void destroy_tpmring(struct tpmfront_info *info, struct tpm_private *tp)
 {
-       tpmif_set_connected_state(tp,0);
-
+       tpmif_set_connected_state(tp, FALSE);
        if ( tp->tx != NULL ) {
                gnttab_end_foreign_access(info->ring_ref, 0,
                                          (unsigned long)tp->tx);
@@ -308,42 +268,20 @@
 static int talk_to_backend(struct xenbus_device *dev,
                            struct tpmfront_info *info)
 {
-       char *backend;
-       const char *message;
+       const char *message = NULL;
        int err;
-       int backend_id;
        struct xenbus_transaction *xbt;
 
-       backend = NULL;
-       err = xenbus_gather(NULL, dev->nodename,
-                           "backend-id", "%i", &backend_id,
-                           "backend", NULL, &backend,
-                           NULL);
-       if (XENBUS_EXIST_ERR(err))
-               goto out;
-       if (backend && strlen(backend) == 0) {
-               err = -ENOENT;
-               goto out;
-       }
-       if (err < 0) {
-               xenbus_dev_error(dev, err, "reading %s/backend or backend-id",
-                                dev->nodename);
-               goto out;
-       }
-
-       info->backend_id      = backend_id;
-       my_private.backend_id = backend_id;
-
-       err = setup_tpmring(dev, info, backend_id);
+       err = setup_tpmring(dev, info);
        if (err) {
-               xenbus_dev_error(dev, err, "setting up ring");
+               xenbus_dev_fatal(dev, err, "setting up ring");
                goto out;
        }
 
 again:
        xbt = xenbus_transaction_start();
        if (IS_ERR(xbt)) {
-               xenbus_dev_error(dev, err, "starting transaction");
+               xenbus_dev_fatal(dev, err, "starting transaction");
                goto destroy_tpmring;
        }
 
@@ -361,34 +299,60 @@
                goto abort_transaction;
        }
 
+       err = xenbus_switch_state(dev, xbt, XenbusStateInitialised);
+       if (err) {
+               goto abort_transaction;
+       }
+
        err = xenbus_transaction_end(xbt, 0);
        if (err == -EAGAIN)
                goto again;
        if (err) {
-               xenbus_dev_error(dev, err, "completing transaction");
+               xenbus_dev_fatal(dev, err, "completing transaction");
                goto destroy_tpmring;
        }
-
-       info->watch.node = backend;
-       info->watch.callback = watch_for_status;
-       err = register_xenbus_watch(&info->watch);
-       if (err) {
-               xenbus_dev_error(dev, err, "registering watch on backend");
-               goto destroy_tpmring;
-       }
-
-       info->backend = backend;
-
        return 0;
 
 abort_transaction:
        xenbus_transaction_end(xbt, 1);
-       xenbus_dev_error(dev, err, "%s", message);
+       if (message)
+               xenbus_dev_error(dev, err, "%s", message);
 destroy_tpmring:
        destroy_tpmring(info, &my_private);
 out:
-       kfree(backend);
        return err;
+}
+
+/**
+ * Callback received when the backend's state changes.
+ */
+static void backend_changed(struct xenbus_device *dev,
+                           XenbusState backend_state)
+{
+       struct tpm_private *tp = &my_private;
+       DPRINTK("\n");
+
+       switch (backend_state) {
+       case XenbusStateInitialising:
+       case XenbusStateInitWait:
+       case XenbusStateInitialised:
+       case XenbusStateUnknown:
+               break;
+
+       case XenbusStateConnected:
+               tpmif_set_connected_state(tp, TRUE);
+               break;
+
+       case XenbusStateClosing:
+               tpmif_set_connected_state(tp, FALSE);
+               break;
+
+       case XenbusStateClosed:
+               if (tp->is_suspended == FALSE) {
+                       device_unregister(&dev->dev);
+               }
+               break;
+       }
 }
 
 
@@ -398,8 +362,6 @@
        int err;
        struct tpmfront_info *info;
        int handle;
-       int len = max(XS_WATCH_PATH, XS_WATCH_TOKEN) + 1;
-       const char *vec[len];
 
        err = xenbus_scanf(NULL, dev->nodename,
                           "handle", "%i", &handle);
@@ -407,19 +369,19 @@
                return err;
 
        if (err < 0) {
-               xenbus_dev_error(dev,err,"reading virtual-device");
+               xenbus_dev_fatal(dev,err,"reading virtual-device");
                return err;
        }
 
        info = kmalloc(sizeof(*info), GFP_KERNEL);
        if (!info) {
-               xenbus_dev_error(dev,err,"allocating info structure");
+               err = -ENOMEM;
+               xenbus_dev_fatal(dev,err,"allocating info structure");
                return err;
        }
        memset(info, 0x0, sizeof(*info));
 
        info->dev = dev;
-       info->handle = handle;
        dev->data = info;
 
        err = talk_to_backend(dev, info);
@@ -428,41 +390,33 @@
                dev->data = NULL;
                return err;
        }
-
-       vec[XS_WATCH_PATH]  = info->watch.node;
-       vec[XS_WATCH_TOKEN] = NULL;
-       watch_for_status(&info->watch, vec, len);
-
        return 0;
 }
 
+
 static int tpmfront_remove(struct xenbus_device *dev)
 {
        struct tpmfront_info *info = dev->data;
-       if (info->backend)
-               unregister_xenbus_watch(&info->watch);
 
        destroy_tpmring(info, &my_private);
 
-       kfree(info->backend);
        kfree(info);
-
        return 0;
 }
 
 static int
 tpmfront_suspend(struct xenbus_device *dev)
 {
-       struct tpmfront_info *info = dev->data;
        struct tpm_private *tp = &my_private;
        u32 ctr = 0;
 
        /* lock, so no app can send */
        down(&suspend_lock);
+       tp->is_suspended = TRUE;
 
        while (atomic_read(&tp->tx_busy) && ctr <= 25) {
-               if ((ctr % 10) == 0)
-                       printk("INFO: Waiting for outstanding request.\n");
+               if ((ctr % 10) == 0)
+                       printk("TPM-FE [INFO]: Waiting for outstanding 
request.\n");
                /*
                 * Wait for a request to be responded to.
                 */
@@ -474,14 +428,9 @@
                /*
                 * A temporary work-around.
                 */
-               printk("WARNING: Resetting busy flag.");
+               printk("TPM-FE [WARNING]: Resetting busy flag.");
                atomic_set(&tp->tx_busy, 0);
        }
-
-       unregister_xenbus_watch(&info->watch);
-
-       kfree(info->backend);
-       info->backend = NULL;
 
        return 0;
 }
@@ -492,8 +441,6 @@
        struct tpmfront_info *info = dev->data;
        int err = talk_to_backend(dev, info);
 
-       /* unlock, so apps can resume sending */
-       up(&suspend_lock);
 
        return err;
 }
@@ -530,12 +477,13 @@
        .probe = tpmfront_probe,
        .remove =  tpmfront_remove,
        .resume = tpmfront_resume,
+       .otherend_changed = backend_changed,
        .suspend = tpmfront_suspend,
 };
 
 static void __init init_tpm_xenbus(void)
 {
-       xenbus_register_driver(&tpmfront);
+       xenbus_register_frontend(&tpmfront);
 }
 
 
@@ -628,12 +576,13 @@
        spin_lock_irq(&tp->tx_lock);
 
        if (unlikely(atomic_read(&tp->tx_busy))) {
-               printk("There's an outstanding request/response on the way!\n");
+               printk("tpm_xmit: There's an outstanding request/response "
+                      "on the way!\n");
                spin_unlock_irq(&tp->tx_lock);
                return -EBUSY;
        }
 
-       if (tp->connected != 1) {
+       if (tp->is_connected != TRUE) {
                spin_unlock_irq(&tp->tx_lock);
                return -EIO;
        }
@@ -705,24 +654,40 @@
        down(&upperlayer_lock);
 
        if (upperlayer_tpmfe != NULL) {
-               switch (tp->connected) {
-                       case 1:
-                               
upperlayer_tpmfe->status(TPMFE_STATUS_CONNECTED);
-                       break;
-
-                       default:
-                               upperlayer_tpmfe->status(0);
-                       break;
+               if (tp->is_connected) {
+                       upperlayer_tpmfe->status(TPMFE_STATUS_CONNECTED);
+               } else {
+                       upperlayer_tpmfe->status(0);
                }
        }
        up(&upperlayer_lock);
 }
 
 
-static void tpmif_set_connected_state(struct tpm_private *tp, int newstate)
-{
-       if (newstate != tp->connected) {
-               tp->connected = newstate;
+static void tpmif_set_connected_state(struct tpm_private *tp, u8 is_connected)
+{
+       /*
+        * Don't notify upper layer if we are in suspend mode and
+        * should disconnect - assumption is that we will resume
+        * The semaphore keeps apps from sending.
+        */
+       if (is_connected == FALSE && tp->is_suspended == TRUE) {
+               return;
+       }
+
+       /*
+        * Unlock the semaphore if we are connected again
+        * after being suspended - now resuming.
+        * This also removes the suspend state.
+        */
+       if (is_connected == TRUE && tp->is_suspended == TRUE) {
+               tp->is_suspended = FALSE;
+               /* unlock, so apps can resume sending */
+               up(&suspend_lock);
+       }
+
+       if (is_connected != tp->is_connected) {
+               tp->is_connected = is_connected;
                tpmif_notify_upperlayer(tp);
        }
 }
diff -r b0338759544e -r cb215a84d1af 
linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h
--- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h      Thu Nov 24 
22:21:48 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h      Fri Nov 25 
08:14:01 2005
@@ -1,12 +1,17 @@
 #ifndef TPM_FRONT_H
 #define TPM_FRONT_H
 
+#ifndef TRUE
+#define TRUE 1
+#define FALSE 0
+#endif
 
-struct tpm_private
-{
+struct tpm_private {
        tpmif_tx_interface_t *tx;
-       unsigned int evtchn, irq;
-       int connected;
+       unsigned int evtchn;
+       unsigned int irq;
+       u8 is_connected;
+       u8 is_suspended;
 
        spinlock_t tx_lock;
 
@@ -16,25 +21,18 @@
        void *tx_remember;
        domid_t backend_id;
        wait_queue_head_t wait_q;
+
 };
 
-
-struct tpmfront_info
-{
-       struct xenbus_watch watch;
-       int handle;
+struct tpmfront_info {
        struct xenbus_device *dev;
-       char *backend;
        int ring_ref;
-       domid_t backend_id;
 };
 
-
-struct tx_buffer
-{
+struct tx_buffer {
        unsigned int size;      // available space in data
        unsigned int len;       // used space in data
-       unsigned char *data;    // pointer to a page
+       unsigned char *data;    // pointer to a page
 };
 
 #endif
diff -r b0338759544e -r cb215a84d1af tools/examples/Makefile
--- a/tools/examples/Makefile   Thu Nov 24 22:21:48 2005
+++ b/tools/examples/Makefile   Fri Nov 25 08:14:01 2005
@@ -26,9 +26,10 @@
 XEN_SCRIPTS += network-nat vif-nat
 XEN_SCRIPTS += block
 XEN_SCRIPTS += block-enbd block-nbd
+XEN_SCRIPTS += vtpm
 XEN_SCRIPT_DATA = xen-script-common.sh
 XEN_SCRIPT_DATA += xen-hotplug-common.sh xen-network-common.sh vif-common.sh
-XEN_SCRIPT_DATA += block-common.sh
+XEN_SCRIPT_DATA += block-common.sh vtpm-common.sh
 
 XEN_HOTPLUG_DIR = /etc/hotplug
 XEN_HOTPLUG_SCRIPTS = xen-backend.agent
diff -r b0338759544e -r cb215a84d1af tools/examples/xen-backend.agent
--- a/tools/examples/xen-backend.agent  Thu Nov 24 22:21:48 2005
+++ b/tools/examples/xen-backend.agent  Fri Nov 25 08:14:01 2005
@@ -5,6 +5,9 @@
 case "$XENBUS_TYPE" in
   vbd)
     /etc/xen/scripts/block "$ACTION"
+    ;;
+  vtpm)
+    /etc/xen/scripts/vtpm "$ACTION"
     ;;
   vif)
     [ -n "$script" ] && $script "$ACTION"
diff -r b0338759544e -r cb215a84d1af tools/examples/xen-backend.rules
--- a/tools/examples/xen-backend.rules  Thu Nov 24 22:21:48 2005
+++ b/tools/examples/xen-backend.rules  Fri Nov 25 08:14:01 2005
@@ -1,4 +1,5 @@
 SUBSYSTEM=="xen-backend", KERNEL=="vbd*", RUN+="/etc/xen/scripts/block 
$env{ACTION}"
+SUBSYSTEM=="xen-backend", KERNEL=="vtpm*", RUN+="/etc/xen/scripts/vtpm 
$env{ACTION}"
 SUBSYSTEM=="xen-backend", KERNEL=="vif*", ACTION=="online", RUN+="$env{script} 
online"
 SUBSYSTEM=="xen-backend", KERNEL=="vif*", ACTION=="offline", 
RUN+="$env{script} offline"
 SUBSYSTEM=="xen-backend", ACTION=="remove", RUN+="/bin/bash -c 
'/usr/bin/xenstore-rm -t $$(/usr/bin/xenstore-read $env{XENBUS_PATH}/frontend)'"
diff -r b0338759544e -r cb215a84d1af tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py    Thu Nov 24 22:21:48 2005
+++ b/tools/python/xen/xend/image.py    Fri Nov 25 08:14:01 2005
@@ -293,7 +293,7 @@
                ret.append("-bridge")
                ret.append("%s" % bridge)
             if name == 'vtpm':
-               instance = sxp.child_value(info, 'instance')
+               instance = sxp.child_value(info, 'pref_instance')
                ret.append("-instance")
                ret.append("%s" % instance)
         return ret
diff -r b0338759544e -r cb215a84d1af tools/python/xen/xend/server/tpmif.py
--- a/tools/python/xen/xend/server/tpmif.py     Thu Nov 24 22:21:48 2005
+++ b/tools/python/xen/xend/server/tpmif.py     Fri Nov 25 08:14:01 2005
@@ -38,10 +38,10 @@
     def getDeviceDetails(self, config):
         """@see DevController.getDeviceDetails"""
 
-        devid = int(sxp.child_value(config, 'instance', '0'))
+        devid = int(sxp.child_value(config, 'pref_instance', '0'))
         log.info("The domain has a TPM with instance %d." % devid)
 
-        back  = { 'instance' : "%i" % devid }
+        back  = { 'pref_instance' : "%i" % devid }
         front = { 'handle' : "%i" % devid }
 
         return (devid, back, front)
diff -r b0338759544e -r cb215a84d1af tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py     Thu Nov 24 22:21:48 2005
+++ b/tools/python/xen/xm/create.py     Fri Nov 25 08:14:01 2005
@@ -220,11 +220,9 @@
           fn=set_bool, default=0,
           use="Make the domain a network interface backend.")
 
-gopts.var('tpmif', val='frontend=DOM',
-          fn=append_value, default=[],
-          use="""Make the domain a TPM interface backend. If frontend is given,
-          the frontend in that domain is connected to this backend (not
-          completely implemented, yet)""")
+gopts.var('tpmif', val='no|yes',
+          fn=append_value, default=0,
+          use="Make the domain a TPM interface backend.")
 
 gopts.var('disk', val='phy:DEV,VDEV,MODE[,DOM]',
           fn=append_value, default=[],
@@ -273,9 +271,13 @@
 
 gopts.var('vtpm', val="instance=INSTANCE,backend=DOM",
           fn=append_value, default=[],
-          use="""Add a tpm interface. On the backend side us the the given
-          instance as virtual TPM instance. Use the backend in the given
-          domain.""")
+          use="""Add a TPM interface. On the backend side use the given
+          instance as virtual TPM instance. The given number is merely the
+          preferred instance number. The hotplug script will determine
+          which instance number will actually be assigned to the domain.
+          The associtation between virtual machine and the TPM instance
+          number can be found in /etc/xen/vtpm.db. Use the backend in the
+          given domain.""")
 
 gopts.var('nics', val="NUM",
           fn=set_int, default=1,
@@ -465,33 +467,19 @@
             if instance == "VTPMD":
                 instance = "0"
             else:
-                try:
-                    if int(instance) == 0:
-                        err('VM config error: vTPM instance must not be 0.')
-                except ValueError:
-                    err('Vm config error: could not parse instance number.')
+                if instance != None:
+                    try:
+                        if int(instance) == 0:
+                            err('VM config error: vTPM instance must not be 
0.')
+                    except ValueError:
+                        err('Vm config error: could not parse instance 
number.')
             backend = d.get('backend')
             config_vtpm = ['vtpm']
             if instance:
-                config_vtpm.append(['instance', instance])
+                config_vtpm.append(['pref_instance', instance])
             if backend:
                 config_vtpm.append(['backend', backend])
             config_devs.append(['device', config_vtpm])
-
-def configure_tpmif(config_devs, vals):
-    """Create the config for virtual TPM interfaces.
-    """
-    tpmif = vals.tpmif
-    tpmif_n = 1
-    for idx in range(0, tpmif_n):
-        if idx < len(tpmif):
-            d = tpmif[idx]
-            frontend = d.get('frontend')
-            config_tpmif = ['tpmif']
-            if frontend:
-                config_tpmif.append(['frontend', frontend])
-            config_devs.append(['device', config_tpmif])
-
 
 def configure_vifs(config_devs, vals):
     """Create the config for virtual network interfaces.
@@ -685,22 +673,6 @@
         vtpms.append(d)
     vals.vtpm = vtpms
 
-def preprocess_tpmif(vals):
-    if not vals.tpmif: return
-    tpmifs = []
-    for tpmif in vals.tpmif:
-        d = {}
-        a = tpmif.split(',')
-        for b in a:
-            (k, v) = b.strip().split('=', 1)
-            k = k.strip()
-            v = v.strip()
-            if k not in ['frontend']:
-                err('Invalid tpmif specifier: ' + vtpm)
-            d[k] = v
-        tpmifs.append(d)
-    vals.tpmif = tpmifs
-
 def preprocess_ip(vals):
     if vals.ip or vals.dhcp != 'off':
         dummy_nfs_server = '1.2.3.4'
@@ -791,7 +763,6 @@
     preprocess_nfs(vals)
     preprocess_vnc(vals)
     preprocess_vtpm(vals)
-    preprocess_tpmif(vals)
          
 def make_domain(opts, config):
     """Create, build and start a domain.
diff -r b0338759544e -r cb215a84d1af tools/examples/vtpm
--- /dev/null   Thu Nov 24 22:21:48 2005
+++ b/tools/examples/vtpm       Fri Nov 25 08:14:01 2005
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+dir=$(dirname "$0")
+. "$dir/vtpm-common.sh"
+
+
+case "$command" in
+    online | offline)
+        exit 0
+        ;;
+esac
+
+case "$command" in
+  add)
+    vtpm_create_instance
+  ;;
+  remove)
+    vtpm_remove_instance
+  ;;
+esac
+
+log debug "Successful vTPM operation '$command'."
+success
diff -r b0338759544e -r cb215a84d1af tools/examples/vtpm-common.sh
--- /dev/null   Thu Nov 24 22:21:48 2005
+++ b/tools/examples/vtpm-common.sh     Fri Nov 25 08:14:01 2005
@@ -0,0 +1,281 @@
+#
+# Copyright (c) 2005 IBM Corporation
+# Copyright (c) 2005 XenSource Ltd.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#
+
+dir=$(dirname "$0")
+. "$dir/xen-hotplug-common.sh"
+
+findCommand "$@"
+if [ "$command" != "online" ]  &&
+   [ "$command" != "offline" ] &&
+   [ "$command" != "add" ]     &&
+   [ "$command" != "remove" ]
+then
+       log err "Invalid command: $command"
+       exit 1
+fi
+
+
+XENBUS_PATH="${XENBUS_PATH:?}"
+
+
+VTPMDB="/etc/xen/vtpm.db"
+
+#In the vtpm-impl file some commands should be defined:
+#      vtpm_create, vtpm_setup, vtpm_reset, etc. (see below)
+#This should be indicated by setting VTPM_IMPL_DEFINED.
+if [ -r "$dir/vtpm-impl" ]; then
+       . "$dir/vtpm-impl"
+fi
+
+if [ -z "$VTPM_IMPL_DEFINED" ]; then
+       function vtpm_create () {
+               true
+       }
+       function vtpm_setup() {
+               true
+       }
+       function vtpm_reset() {
+               true
+       }
+       function vtpm_suspend() {
+               true
+       }
+       function vtpm_resume() {
+               true
+       }
+fi
+
+#Find the instance number for the vtpm given the name of the domain
+# Parameters
+# - vmname : the name of the vm
+# Return value
+#  Returns '0' if instance number could not be found, otherwise
+#  it returns the instance number in the variable 'instance'
+function find_instance () {
+       local vmname=$1
+       local ret=0
+       instance=`cat $VTPMDB |                    \
+                 awk -vvmname=$vmname             \
+                 '{                               \
+                    if ( 1 != index($1,"#")) {    \
+                      if ( $1 == vmname ) {       \
+                        print $2;                 \
+                        exit;                     \
+                      }                           \
+                    }                             \
+                  }'`
+       if [ "$instance" != "" ]; then
+               ret=1
+       fi
+       return $ret
+}
+
+
+# Check whether a particular instance number is still available
+# returns '1' if it is available
+function is_free_instancenum () {
+       local instance=$1
+       local avail=1
+
+       #Allowed instance number range: 1-255
+       if [ $instance -eq 0 -o $instance -gt 255 ]; then
+               avail=0
+       else
+               instances=`cat $VTPMDB |                 \
+                          gawk                          \
+                          '{                            \
+                              if (1 != index($1,"#")) { \
+                                printf("%s ",$2);       \
+                              }                         \
+                           }'`
+               for i in $instances; do
+                       if [ $i -eq $instance ]; then
+                               avail=0
+                               break
+                       fi
+               done
+       fi
+       return $avail
+}
+
+
+# Get an available instance number given the database
+# Returns an unused instance number
+function get_free_instancenum () {
+       local ctr
+       local instances
+       local don
+       instances=`cat $VTPMDB |                 \
+                  gawk                          \
+                  '{                            \
+                      if (1 != index($1,"#")) { \
+                        printf("%s ",$2);       \
+                      }                         \
+                   }'`
+       ctr=1
+       don=0
+       while [ $don -eq 0 ]; do
+               local found
+               found=0
+               for i in $instances; do
+                       if [ $i -eq $ctr ]; then
+                               found=1;
+                               break;
+                       fi
+               done
+
+               if [ $found -eq 0 ]; then
+                       don=1
+                       break
+               fi
+               let ctr=ctr+1
+       done
+       let instance=$ctr
+}
+
+
+# Add a domain name and instance number to the DB file
+function add_instance () {
+       local vmname=$1
+       local inst=$2
+
+       if [ ! -f $VTPMDB ]; then
+               echo "#Database for VM to vTPM association" > $VTPMDB
+               echo "#1st column: domain name" >> $VTPMDB
+               echo "#2nd column: TPM instance number" >> $VTPMDB
+       fi
+       validate_entry $vmname $inst
+       if [ $? -eq 0 ]; then
+               echo "$vmname $inst" >> $VTPMDB
+       fi
+}
+
+
+#Validate whether an entry is the same as passed to this
+#function
+function validate_entry () {
+       local rc=0
+       local vmname=$1
+       local inst=$2
+       local res
+       res=`cat $VTPMDB |             \
+            gawk -vvmname=$vmname     \
+                 -vinst=$inst         \
+            '{                        \
+                if ( 1 == index($1,"#")) {\
+                } else                \
+                if ( $1 == vmname &&  \
+                     $2 == inst) {    \
+                   printf("1");       \
+                   exit;              \
+                } else                \
+                if ( $1 == vmname ||  \
+                     $2 == inst) {    \
+                   printf("2");       \
+                   exit;              \
+                }                     \
+            }'`
+
+       if [ "$res" == "1" ]; then
+               let rc=1
+       elif [ "$res" == "2" ]; then
+               let rc=2
+       fi
+       return $rc
+}
+
+
+#Remove an entry from the vTPM database given its domain name
+function remove_entry () {
+       local vmname=$1
+       local VTPMDB_TMP="$VTPMDB".tmp
+       `cat $VTPMDB |             \
+        gawk -vvmname=$vmname     \
+        '{                        \
+           if ( $1 != vmname ) {  \
+             print $0;            \
+           }                      \
+        '} > $VTPMDB_TMP`
+       if [ -e $VTPMDB_TMP ]; then
+               mv -f $VTPMDB_TMP $VTPMDB
+       else
+               log err "Error creating temporary file '$VTPMDB_TMP'."
+       fi
+}
+
+
+#Create a vTPM instance
+# If no entry in the TPM database is found, the instance is
+# created and an entry added to the database.
+function vtpm_create_instance () {
+       local domname=$(xenstore_read "$XENBUS_PATH"/domain)
+       local res
+       set +e
+       find_instance $domname
+       res=$?
+       if [ $res -eq 0 ]; then
+               #Try to give the preferred instance to the domain
+               instance=$(xenstore_read "$XENBUS_PATH"/pref_instance)
+               if [ "$instance" != "" ]; then
+                       is_free_instancenum $instance
+                       res=$?
+                       if [ $res -eq 0 ]; then
+                               get_free_instancenum
+                       fi
+               else
+                       get_free_instancenum
+               fi
+               add_instance $domname $instance
+               if [ "$REASON" == "create" ]; then
+                       vtpm_create $instance
+               elif [ "$REASON" == "hibernate" ]; then
+                       vtpm_resume $instance $domname
+               else
+                       #default case for 'now'
+                       vtpm_create $instance
+               fi
+       fi
+       if [ "$REASON" == "create" ]; then
+               vtpm_reset $instance
+       elif [ "$REASON" == "hibernate" ]; then
+               vtpm_setup $instance
+       else
+               #default case for 'now'
+               vtpm_reset $instance
+       fi
+       xenstore_write $XENBUS_PATH/instance $instance
+       set -e
+}
+
+
+#Remove an instance
+function vtpm_remove_instance () {
+       local domname=$(xenstore_read "$XENBUS_PATH"/domain)
+       set +e
+       find_instance $domname
+       res=$?
+       if [ $res -eq 0 ]; then
+               #Something is really wrong with the DB
+               log err "vTPM DB file $VTPMDB has no entry for '$domname'"
+       else
+               if [ "$REASON" == "hibernate" ]; then
+                       vtpm_suspend $instance
+               fi
+       fi
+       set -e
+}

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] Update vtpm driver following the recent changes to the, Xen patchbot -unstable <=