diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index f736f95..1444b0b 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -1110,6 +1110,76 @@ static void parse_nic_config(XLU_Config **config, const char *buf,
     parse_nic_config_multistring(config, 1, &buf, nic);
 }
 
+static int parse_vtpm_config_token(XLU_Config **config, char *token,
+                                   libxl_device_vtpm *vtpm)
+{
+    char *oparg;
+
+    if (MATCH_OPTION("uuid", token, oparg)) {
+        if(libxl_uuid_from_string(&vtpm->uuid, oparg)) {
+            fprintf(stderr, "Invalid uuid specified (%s)\n", oparg);
+            return 1;
+        }
+    } else if (MATCH_OPTION("backend", token, oparg)) {
+        replace_string(&vtpm->backend_domname, oparg);
+    } else {
+        fprintf(stderr, "unrecognized argument `%s'\n", token);
+        return 1;
+    }
+
+    return 0;
+}
+
+static int parse_vtpm_config_one(XLU_Config **config, const char *config_str,
+                                 libxl_device_vtpm *vtpm)
+{
+    char *buf = xstrdup(config_str);
+    char *p;
+    int ret;
+
+    p = strtok(buf, ",");
+    if (!p) {
+        ret = 0;
+        goto out;
+    }
+
+    do {
+        while (*p == ' ')
+            p++;
+        ret = parse_vtpm_config_token(config, p, vtpm);
+    } while ((p = strtok(NULL, ",")) != NULL && ret == 0);
+
+out:
+    free(buf);
+
+    return ret;
+}
+
+static void parse_vtpm_config_multistring(XLU_Config **config,
+                                          int nspecs, const char *const *specs,
+                                          libxl_device_vtpm *vtpm)
+{
+    int i;
+
+    libxl_device_vtpm_init(vtpm);
+
+    if (!*config) {
+        *config = xlu_cfg_init(stderr, "command line");
+        if (!*config) { perror("xlu_cfg_init"); exit(-1); }
+    }
+
+    for (i = 0; i < nspecs; i++) {
+        if (parse_vtpm_config_one(config, specs[i], vtpm))
+            exit(EXIT_FAILURE);
+    }
+}
+
+static void parse_vtpm_config(XLU_Config **config, const char *buf,
+                              libxl_device_vtpm *vtpm)
+{
+    parse_vtpm_config_multistring(config, 1, &buf, vtpm);
+}
+
 static unsigned long parse_ulong(const char *str)
 {
     char *endptr;
@@ -1858,42 +1928,17 @@ static void parse_config_data(const char *config_source,
         while ((buf = xlu_cfg_get_listitem (vtpms, d_config->num_vtpms))
                != NULL) {
             libxl_device_vtpm *vtpm;
-            char * buf2 = strdup(buf);
-            char *p, *p2;
-            bool got_backend = false;
 
             vtpm = ARRAY_EXTEND_INIT(d_config->vtpms,
                                      d_config->num_vtpms,
                                      libxl_device_vtpm_init);
 
-            p = strtok(buf2, ",");
-            if(p) {
-               do {
-                  while(*p == ' ')
-                     ++p;
-                  if ((p2 = strchr(p, '=')) == NULL)
-                     break;
-                  *p2 = '\0';
-                  if (!strcmp(p, "backend")) {
-                     vtpm->backend_domname = strdup(p2 + 1);
-                     got_backend = true;
-                  } else if(!strcmp(p, "uuid")) {
-                     if( libxl_uuid_from_string(&vtpm->uuid, p2 + 1) ) {
-                        fprintf(stderr,
-                              "Failed to parse vtpm UUID: %s\n", p2 + 1);
-                        exit(1);
-                    }
-                  } else {
-                     fprintf(stderr, "Unknown string `%s' in vtpm spec\n", p);
-                     exit(1);
-                  }
-               } while ((p = strtok(NULL, ",")) != NULL);
-            }
-            if(!got_backend) {
+            parse_vtpm_config(&config, buf, vtpm);
+
+            if(!vtpm->backend_domname) {
                fprintf(stderr, "vtpm spec missing required backend field!\n");
                exit(1);
             }
-            free(buf2);
         }
     }
 
@@ -6812,8 +6857,8 @@ int main_vtpmattach(int argc, char **argv)
 {
     int opt;
     libxl_device_vtpm vtpm;
-    char *oparg;
     uint32_t domid;
+    XLU_Config *config = 0;
 
     SWITCH_FOREACH_OPT(opt, "", NULL, "vtpm-attach", 1) {
         /* No options */
@@ -6825,20 +6870,8 @@ int main_vtpmattach(int argc, char **argv)
     }
     ++optind;
 
-    libxl_device_vtpm_init(&vtpm);
-    for (argv += optind, argc -= optind; argc > 0; ++argv, --argc) {
-        if (MATCH_OPTION("uuid", *argv, oparg)) {
-            if(libxl_uuid_from_string(&(vtpm.uuid), oparg)) {
-                fprintf(stderr, "Invalid uuid specified (%s)\n", oparg);
-                return 1;
-            }
-        } else if (MATCH_OPTION("backend", *argv, oparg)) {
-            replace_string(&vtpm.backend_domname, oparg);
-        } else {
-            fprintf(stderr, "unrecognized argument `%s'\n", *argv);
-            return 1;
-        }
-    }
+    parse_vtpm_config_multistring(&config, argc-optind,
+                                  (const char* const*) argv + optind, &vtpm);
 
     if(dryrun_only) {
        char* json = libxl_device_vtpm_to_json(ctx, &vtpm);
