[TPM] Fix an occasional problem when doing local migration due to the xenstore's
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Tue, 27 Jun 2006 10:29:29 +0000 (11:29 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Tue, 27 Jun 2006 10:29:29 +0000 (11:29 +0100)
'instance' variable not being initialized at the time when it's driver
counterpart is accessed. That variable's content was used to initialize the
tpmif structure. Instead, now a pointer to the structure is passed whose
'instance' variable will be initialized before the domain is resumed.

Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
linux-2.6-xen-sparse/drivers/xen/tpmback/common.h
linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c
linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c
linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c

index fba08d1c915afbad3a33b3c8e3f5f8a9ea5c7d28..27b8fd283ad9c61dc4e11fd87e70e922cb85e354 100644 (file)
@@ -21,6 +21,8 @@
        pr_debug("(file=%s, line=%d) " _f,      \
                 __FILE__ , __LINE__ , ## _a )
 
+struct backend_info;
+
 typedef struct tpmif_st {
        struct list_head tpmif_list;
        /* Unique identifier for this interface. */
@@ -43,7 +45,7 @@ typedef struct tpmif_st {
        struct list_head list;  /* scheduling list */
        atomic_t refcnt;
 
-       long int tpm_instance;
+       struct backend_info *bi;
        unsigned long mmap_vstart;
 
        grant_handle_t shmem_handle;
@@ -54,7 +56,7 @@ typedef struct tpmif_st {
 } tpmif_t;
 
 void tpmif_disconnect_complete(tpmif_t * tpmif);
-tpmif_t *tpmif_find(domid_t domid, long int instance);
+tpmif_t *tpmif_find(domid_t domid, struct backend_info *bi);
 void tpmif_interface_init(void);
 void tpmif_interface_exit(void);
 void tpmif_schedule_work(tpmif_t * tpmif);
@@ -64,8 +66,11 @@ void tpmif_xenbus_exit(void);
 int tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn);
 irqreturn_t tpmif_be_int(int irq, void *dev_id, struct pt_regs *regs);
 
+long int tpmback_get_instance(struct backend_info *bi);
+
 int vtpm_release_packets(tpmif_t * tpmif, int send_msgs);
 
+
 #define tpmif_get(_b) (atomic_inc(&(_b)->refcnt))
 #define tpmif_put(_b)                                  \
        do {                                            \
index 50fb3e5d75f67ba03f58bd51ebe1faf741b611d8..0105bd93bfb90d150b710cd7fd136cfbdb782d2c 100644 (file)
@@ -20,7 +20,7 @@ int num_frontends = 0;
 
 LIST_HEAD(tpmif_list);
 
-static tpmif_t *alloc_tpmif(domid_t domid, long int instance)
+static tpmif_t *alloc_tpmif(domid_t domid, struct backend_info *bi)
 {
        tpmif_t *tpmif;
 
@@ -31,7 +31,7 @@ static tpmif_t *alloc_tpmif(domid_t domid, long int instance)
        memset(tpmif, 0, sizeof (*tpmif));
        tpmif->domid = domid;
        tpmif->status = DISCONNECTED;
-       tpmif->tpm_instance = instance;
+       tpmif->bi = bi;
        snprintf(tpmif->devname, sizeof(tpmif->devname), "tpmif%d", domid);
        atomic_set(&tpmif->refcnt, 1);
 
@@ -54,12 +54,12 @@ static void free_tpmif(tpmif_t * tpmif)
        kmem_cache_free(tpmif_cachep, tpmif);
 }
 
-tpmif_t *tpmif_find(domid_t domid, long int instance)
+tpmif_t *tpmif_find(domid_t domid, struct backend_info *bi)
 {
        tpmif_t *tpmif;
 
        list_for_each_entry(tpmif, &tpmif_list, tpmif_list) {
-               if (tpmif->tpm_instance == instance) {
+               if (tpmif->bi == bi) {
                        if (tpmif->domid == domid) {
                                tpmif_get(tpmif);
                                return tpmif;
@@ -69,7 +69,7 @@ tpmif_t *tpmif_find(domid_t domid, long int instance)
                }
        }
 
-       return alloc_tpmif(domid, instance);
+       return alloc_tpmif(domid, bi);
 }
 
 static int map_frontend_page(tpmif_t *tpmif, unsigned long shared_page)
index 066bcf33aa9e6f08d1a004f05c411ffe878ea61a..3e2d5087a7790168d22c7b23812c3c0426a8b64e 100644 (file)
@@ -161,7 +161,7 @@ static struct packet *packet_alloc(tpmif_t * tpmif,
        if (NULL != pak) {
                if (tpmif) {
                        pak->tpmif = tpmif;
-                       pak->tpm_instance = tpmif->tpm_instance;
+                       pak->tpm_instance = tpmback_get_instance(tpmif->bi);
                        tpmif_get(tpmif);
                }
                pak->data_len = size;
index e98072e29bbff2953007749201ebc0336e6fbf43..cb72a2ec364788b0bd30414ba15efa648c9f96a5 100644 (file)
@@ -45,6 +45,14 @@ static void backend_changed(struct xenbus_watch *watch,
 static void frontend_changed(struct xenbus_device *dev,
                             enum xenbus_state frontend_state);
 
+long int tpmback_get_instance(struct backend_info *bi)
+{
+       long int res = -1;
+       if (bi && bi->is_instance_set)
+               res = bi->instance;
+       return res;
+}
+
 static int tpmback_remove(struct xenbus_device *dev)
 {
        struct backend_info *be = dev->dev.driver_data;
@@ -57,6 +65,7 @@ static int tpmback_remove(struct xenbus_device *dev)
                be->backend_watch.node = NULL;
        }
        if (be->tpmif) {
+               be->tpmif->bi = NULL;
                vtpm_release_packets(be->tpmif, 0);
                tpmif_put(be->tpmif);
                be->tpmif = NULL;
@@ -150,7 +159,7 @@ static void frontend_changed(struct xenbus_device *dev,
                break;
 
        case XenbusStateClosing:
-               be->tpmif->tpm_instance = -1;
+               be->instance = -1;
                break;
 
        case XenbusStateClosed:
@@ -233,8 +242,7 @@ static int connect_ring(struct backend_info *be)
        }
 
        if (!be->tpmif) {
-               be->tpmif = tpmif_find(dev->otherend_id,
-                                      be->instance);
+               be->tpmif = tpmif_find(dev->otherend_id, be);
                if (IS_ERR(be->tpmif)) {
                        err = PTR_ERR(be->tpmif);
                        be->tpmif = NULL;