ia64/xen-unstable

changeset 13565:a02622437e07

VTPM_TOOLS: Added support for QEMU to communicate with vTPM over UNIX
socket for HVM guests.

Signed-off-by: Vinnie Scarlata <vincent.r.scarlata@intel.com>
author kfraser@localhost.localdomain
date Mon Jan 22 15:59:41 2007 +0000 (2007-01-22)
parents ded2d8dcef52
children b1c03f19a4ef
files tools/examples/vtpm-impl tools/vtpm/vtpm.patch tools/vtpm_manager/Rules.mk tools/vtpm_manager/manager/Makefile tools/vtpm_manager/manager/dmictl.c tools/vtpm_manager/manager/vtpm_manager.h tools/vtpm_manager/manager/vtpm_manager_handler.c tools/vtpm_manager/manager/vtpmd.c tools/vtpm_manager/manager/vtpmpriv.h
line diff
     1.1 --- a/tools/examples/vtpm-impl	Mon Jan 22 15:58:27 2007 +0000
     1.2 +++ b/tools/examples/vtpm-impl	Mon Jan 22 15:59:41 2007 +0000
     1.3 @@ -32,12 +32,15 @@
     1.4  # OF THE POSSIBILITY OF SUCH DAMAGE.
     1.5  # ===================================================================
     1.6  
     1.7 -#            |        SRC        |    TAG  |      CMD SIZE     |        ORD       | type| mode
     1.8 -TPM_CMD_OPEN=\\x00\\x00\\x00\\x00\\x01\\xc1\\x00\\x00\\x00\\x10\\x01\\x00\\x00\\x01\\x01\\x01
     1.9 -TPM_CMD_RESM=\\x00\\x00\\x00\\x00\\x01\\xc1\\x00\\x00\\x00\\x10\\x01\\x00\\x00\\x01\\x01\\x02
    1.10 +#            |        SRC        |    TAG  |      CMD SIZE     |        ORD       |mtype|strt
    1.11 +TPM_CMD_OPEN=\\x00\\x00\\x00\\x00\\x01\\xc1\\x00\\x00\\x00\\x11\\x01\\x00\\x00\\x01\\x01\\x01
    1.12 +TPM_CMD_RESM=\\x00\\x00\\x00\\x00\\x01\\xc1\\x00\\x00\\x00\\x11\\x01\\x00\\x00\\x01\\x01\\x02
    1.13  TPM_CMD_CLOS=\\x00\\x00\\x00\\x00\\x01\\xc1\\x00\\x00\\x00\\x0e\\x01\\x00\\x00\\x02
    1.14  TPM_CMD_DELE=\\x00\\x00\\x00\\x00\\x01\\xc1\\x00\\x00\\x00\\x0e\\x01\\x00\\x00\\x03
    1.15  
    1.16 +TPM_TYPE_PVM=\\x01
    1.17 +TPM_TYPE_HVM=\\x02
    1.18 +
    1.19  TPM_SUCCESS=00000000
    1.20  
    1.21  TX_VTPM_MANAGER=/var/vtpm/fifos/from_console.fifo
    1.22 @@ -80,7 +83,7 @@ function vtpm_manager_cmd() {
    1.23   release_lock vtpm_mgr
    1.24  
    1.25   #return whether the command was successful
    1.26 - if [ $resp_hex != $TPM_SUCCESS ]; then
    1.27 + if [ $resp_hex ne $TPM_SUCCESS ]; then
    1.28     vtpm_fatal_error=1
    1.29     false
    1.30    else
    1.31 @@ -88,6 +91,20 @@ function vtpm_manager_cmd() {
    1.32   fi
    1.33  }
    1.34  
    1.35 +# Helper to get vm type to pass to vtpm_manager open/resume
    1.36 +function vtpm_get_type() {
    1.37 + local inst=$(xenstore_read $XENBUS_PATH/frontend-id)
    1.38 + local vm=$(xenstore_read /local/domain/$inst/vm)
    1.39 + if [ "$vm" != "" ]; then
    1.40 +  local ostype=$(xenstore-read $vm/image/ostype)
    1.41 +  if [ "$ostype" == "hvm" ]; then
    1.42 +   echo $TPM_TYPE_HVM;
    1.43 +  else
    1.44 +   echo $TPM_TYPE_PVM;
    1.45 +  fi
    1.46 + fi
    1.47 +}
    1.48 +
    1.49  # ------------------ Command handlers -----------------
    1.50  
    1.51  # Create new vtpm instance & set it up for use
    1.52 @@ -99,11 +116,13 @@ function vtpm_create () {
    1.53  
    1.54  # Setup vtpm instance for use.
    1.55  function vtpm_start() {
    1.56 - $(vtpm_manager_cmd $TPM_CMD_OPEN $1)
    1.57 + local vmtype=$(vtpm_get_type);
    1.58 + $(vtpm_manager_cmd $TPM_CMD_OPEN$vmtype $1)
    1.59  }
    1.60  
    1.61  function vtpm_resume() {
    1.62 - $(vtpm_manager_cmd $TPM_CMD_RESM $1)
    1.63 + local vmtype=$(vtpm_get_type);
    1.64 + $(vtpm_manager_cmd $TPM_CMD_RESM$vmtype $1)
    1.65  }
    1.66  
    1.67  # Reset the vtpm AKA clear PCRs
     2.1 --- a/tools/vtpm/vtpm.patch	Mon Jan 22 15:58:27 2007 +0000
     2.2 +++ b/tools/vtpm/vtpm.patch	Mon Jan 22 15:59:41 2007 +0000
     2.3 @@ -1,14 +1,14 @@
     2.4  diff -uprN tpm_emulator/AUTHORS vtpm/AUTHORS
     2.5 ---- tpm_emulator/AUTHORS	2006-07-24 14:35:35.000000000 -0700
     2.6 -+++ vtpm/AUTHORS	2006-07-24 14:35:35.000000000 -0700
     2.7 +--- tpm_emulator/AUTHORS	2006-12-08 12:51:29.000000000 -0800
     2.8 ++++ vtpm/AUTHORS	2006-12-13 16:38:52.000000000 -0800
     2.9  @@ -1,3 +1,3 @@
    2.10   Mario Strasser <mast@gmx.net>
    2.11   Heiko Stamer <stamer@gaos.org> [DAA]
    2.12  -INTEL Corp <> [Dropped to Ring3]
    2.13  +INTEL Corp <> [VTPM Extensions]
    2.14  diff -uprN tpm_emulator/ChangeLog vtpm/ChangeLog
    2.15 ---- tpm_emulator/ChangeLog	2006-07-24 14:35:35.000000000 -0700
    2.16 -+++ vtpm/ChangeLog	2006-07-24 14:35:35.000000000 -0700
    2.17 +--- tpm_emulator/ChangeLog	2006-12-08 12:51:29.000000000 -0800
    2.18 ++++ vtpm/ChangeLog	2006-12-13 16:38:52.000000000 -0800
    2.19  @@ -1,5 +1,6 @@
    2.20   ????-??-?? Intel Corp
    2.21   	* Moved module out of kernel to run as a ring 3 app
    2.22 @@ -17,9 +17,9 @@ diff -uprN tpm_emulator/ChangeLog vtpm/C
    2.23   2006-06-23  Mario Strasser <mast@gmx.net>
    2.24   	* tpm_startup.c: behaviour of ST_CLEAR and storage of
    2.25  diff -uprN tpm_emulator/linux_module.h vtpm/linux_module.h
    2.26 ---- tpm_emulator/linux_module.h	2006-07-24 14:35:35.000000000 -0700
    2.27 -+++ vtpm/linux_module.h	2006-07-24 14:35:35.000000000 -0700
    2.28 -@@ -44,18 +44,21 @@
    2.29 +--- tpm_emulator/linux_module.h	2006-12-08 12:51:29.000000000 -0800
    2.30 ++++ vtpm/linux_module.h	2007-01-09 14:49:06.000000000 -0800
    2.31 +@@ -44,18 +44,26 @@
    2.32   #define TPM_DEVICE_NAME   "tpm"
    2.33   #define TPM_MODULE_NAME   "tpm_emulator"
    2.34   
    2.35 @@ -31,8 +31,13 @@ diff -uprN tpm_emulator/linux_module.h v
    2.36  -                        __FILE__, __LINE__, ## __VA_ARGS__)
    2.37  +#define debug(fmt, ...) printf("TPMD[%d]: %s:%d: Debug: " fmt "\n", \
    2.38  +                        dmi_id, __FILE__, __LINE__, ## __VA_ARGS__)
    2.39 ++#define debug_nostop(fmt, ...) printf("TPMD[%d]: %s:%d: Debug: " fmt, \
    2.40 ++                        dmi_id, __FILE__, __LINE__, ## __VA_ARGS__)
    2.41 ++#define debug_more(fmt, ...) printf( fmt, ## __VA_ARGS__ )
    2.42   #else
    2.43   #define debug(fmt, ...) 
    2.44 ++#define debug_nostop(fmt, ...) 
    2.45 ++#define debug_more(fmt, ...)
    2.46   #endif
    2.47  -#define info(fmt, ...)  printf("TPMD: %s:%d: Info: " fmt "\n", \
    2.48  -                        __FILE__, __LINE__, ## __VA_ARGS__)
    2.49 @@ -50,8 +55,8 @@ diff -uprN tpm_emulator/linux_module.h v
    2.50   /* memory allocation */
    2.51   
    2.52  diff -uprN tpm_emulator/Makefile vtpm/Makefile
    2.53 ---- tpm_emulator/Makefile	2006-07-24 14:35:35.000000000 -0700
    2.54 -+++ vtpm/Makefile	2006-07-24 14:35:35.000000000 -0700
    2.55 +--- tpm_emulator/Makefile	2006-12-08 12:51:29.000000000 -0800
    2.56 ++++ vtpm/Makefile	2006-12-13 16:38:52.000000000 -0800
    2.57  @@ -7,7 +7,7 @@
    2.58   COMPILE_ARCH    ?= $(shell uname -m | sed -e s/i.86/x86_32/)
    2.59   
    2.60 @@ -83,9 +88,46 @@ diff -uprN tpm_emulator/Makefile vtpm/Ma
    2.61   
    2.62   .PHONY: all install clean dist gmp version
    2.63  +
    2.64 +diff -uprN tpm_emulator/tpm/tpm_capability.c vtpm/tpm/tpm_capability.c
    2.65 +--- tpm_emulator/tpm/tpm_capability.c	2006-06-23 03:37:07.000000000 -0700
    2.66 ++++ vtpm/tpm/tpm_capability.c	2007-01-10 10:00:49.000000000 -0800
    2.67 +@@ -136,8 +136,18 @@ static TPM_RESULT cap_property(UINT32 su
    2.68 + 
    2.69 +     case TPM_CAP_PROP_TIS_TIMEOUT:
    2.70 +       debug("[TPM_CAP_PROP_TIS_TIMEOUT]");
    2.71 +-      /* TODO: TPM_CAP_PROP_TIS_TIMEOUT */
    2.72 +-      return TPM_FAIL;
    2.73 ++      /* TODO: TPM_CAP_PROP_TIS_TIMEOUT: Measure these values and determine correct ones */
    2.74 ++      UINT32 len = *respSize = 16;
    2.75 ++      BYTE *ptr = *resp = tpm_malloc(*respSize);
    2.76 ++      if (ptr == NULL || 
    2.77 ++          tpm_marshal_UINT32(&ptr, &len, 200000) ||
    2.78 ++          tpm_marshal_UINT32(&ptr, &len, 200000) ||
    2.79 ++          tpm_marshal_UINT32(&ptr, &len, 200000) ||
    2.80 ++          tpm_marshal_UINT32(&ptr, &len, 200000)) {
    2.81 ++        tpm_free(*resp);
    2.82 ++        return TPM_FAIL;
    2.83 ++      }
    2.84 ++      return TPM_SUCCESS;
    2.85 + 
    2.86 +     case TPM_CAP_PROP_STARTUP_EFFECT:
    2.87 +       debug("[TPM_CAP_PROP_STARTUP_EFFECT]");
    2.88 +@@ -190,7 +200,11 @@ static TPM_RESULT cap_property(UINT32 su
    2.89 + 
    2.90 +     case TPM_CAP_PROP_DURATION:
    2.91 +       debug("[TPM_CAP_PROP_DURATION]");
    2.92 +-      /* TODO: TPM_CAP_PROP_DURATION */
    2.93 ++      /* TODO: TPM_CAP_PROP_DURATION: Measure these values and return accurate ones */
    2.94 ++      BYTE dur[]= {0x0,0x0,0x0,0xc,0x0,0x7,0xa1,0x20,0x0,0x1e,0x84,0x80,0x11,0xe1,0xa3,0x0}; 
    2.95 ++      *respSize = 16;
    2.96 ++      *resp = tpm_malloc(*respSize);
    2.97 ++      memcpy(*resp,dur,16); 
    2.98 +       return TPM_FAIL;
    2.99 + 
   2.100 +     case TPM_CAP_PROP_ACTIVE_COUNTER:
   2.101  diff -uprN tpm_emulator/tpm/tpm_data.c vtpm/tpm/tpm_data.c
   2.102 ---- tpm_emulator/tpm/tpm_data.c	2006-07-24 14:35:35.000000000 -0700
   2.103 -+++ vtpm/tpm/tpm_data.c	2006-07-24 14:35:35.000000000 -0700
   2.104 +--- tpm_emulator/tpm/tpm_data.c	2006-12-08 12:51:29.000000000 -0800
   2.105 ++++ vtpm/tpm/tpm_data.c	2006-12-13 16:38:52.000000000 -0800
   2.106  @@ -1,6 +1,7 @@
   2.107   /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   2.108    * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
   2.109 @@ -371,10 +413,15 @@ diff -uprN tpm_emulator/tpm/tpm_data.c v
   2.110   
   2.111   #else
   2.112  diff -uprN tpm_emulator/tpmd.c vtpm/tpmd.c
   2.113 ---- tpm_emulator/tpmd.c	2006-07-24 14:35:35.000000000 -0700
   2.114 -+++ vtpm/tpmd.c	2006-07-24 14:35:35.000000000 -0700
   2.115 -@@ -23,13 +23,27 @@
   2.116 +--- tpm_emulator/tpmd.c	2006-12-08 12:51:29.000000000 -0800
   2.117 ++++ vtpm/tpmd.c	2007-01-09 14:48:56.000000000 -0800
   2.118 +@@ -21,12 +21,24 @@
   2.119 + #include <sys/stat.h>
   2.120 + #include <fcntl.h>
   2.121   #include <sys/time.h>
   2.122 ++#include <sys/socket.h>
   2.123 ++#include <sys/un.h>
   2.124 ++#include <errno.h>
   2.125   
   2.126   #include "tpm_emulator.h"
   2.127  +#include "vtpm_manager.h"
   2.128 @@ -384,61 +431,115 @@ diff -uprN tpm_emulator/tpmd.c vtpm/tpmd
   2.129  +#ifdef VTPM_MULTI_VM
   2.130  + #define DEV_BE "/dev/vtpm"
   2.131  +#else
   2.132 -+ #define GUEST_RX_FIFO_D "/var/vtpm/fifos/tpm_cmd_to_%d.fifo"
   2.133 -+ #define GUEST_TX_FIFO "/var/vtpm/fifos/tpm_rsp_from_all.fifo"
   2.134 ++ #define PVM_RX_FIFO_D "/var/vtpm/fifos/tpm_cmd_to_%d.fifo"
   2.135 ++ #define PVM_TX_FIFO "/var/vtpm/fifos/tpm_rsp_from_all.fifo"
   2.136 + 
   2.137 ++ #define HVM_RX_FIFO_D "/var/vtpm/socks/%d.socket"
   2.138  +#endif
   2.139 - 
   2.140 ++
   2.141  + int dmi_id;
   2.142  +						
   2.143   #define BUFFER_SIZE 2048
   2.144   
   2.145 -+static uint8_t ctrl_msg[] = { 0, 0, 0, 0,   // destination
   2.146 -+                              1, 193,       // VTPM_TAG
   2.147 -+                              0, 0, 0, 10,  // Size
   2.148 -+                              0, 0, 0, 0};  // TPM_SUCCESS
   2.149 -+                            
   2.150 -+
   2.151   static int devurandom=0;
   2.152 -+
   2.153 - 	  
   2.154 - void get_random_bytes(void *buf, int nbytes) {
   2.155 -   
   2.156 -@@ -52,18 +66,26 @@ uint64_t tpm_get_ticks(void)
   2.157 +@@ -38,7 +50,7 @@ void get_random_bytes(void *buf, int nby
   2.158 +   }
   2.159 + 
   2.160 +   if (read(devurandom, buf, nbytes) != nbytes) {
   2.161 +-      printf("Can't get random number.\n");
   2.162 ++      error("Can't get random number.\n");
   2.163 +       exit(-1);
   2.164 +   }
   2.165 + }
   2.166 +@@ -52,105 +64,182 @@ uint64_t tpm_get_ticks(void)
   2.167   
   2.168   int main(int argc, char **argv)
   2.169   {
   2.170  -  uint8_t in[BUFFER_SIZE], *out;
   2.171 -+  uint8_t in[BUFFER_SIZE], *out, *addressed_out;
   2.172 ++  uint8_t type, in[BUFFER_SIZE], *out, *addressed_out;
   2.173 ++  char *vtpm_rx_file=NULL;
   2.174     uint32_t out_size;
   2.175     int in_size, written;
   2.176  -  int i;
   2.177  -  struct stat file_info;
   2.178 --
   2.179 ++  int i, guest_id=-1;
   2.180 + 
   2.181  -  int tpm_tx_fh=-1, tpm_rx_fh=-1;
   2.182 -+  int i, guest_id=-1;
   2.183 ++#ifndef VTPM_MULTI_VM
   2.184 ++  int sockfd = -1;
   2.185 ++  struct sockaddr_un addr;
   2.186 ++  struct sockaddr_un client_addr;
   2.187 ++  unsigned int client_length;
   2.188 ++
   2.189 ++#endif
   2.190  + 
   2.191  +  int vtpm_tx_fh=-1, vtpm_rx_fh=-1;
   2.192  +#ifdef VTPM_MULTI_VM
   2.193     if (argc < 2) {
   2.194 -     printf("Usage: tpmd clear|save|deactivated\n" );
   2.195 +-    printf("Usage: tpmd clear|save|deactivated\n" );
   2.196 ++    error("Usage: tpmd clear|save|deactivated\n" );
   2.197  +#else
   2.198 -+  if (argc < 3) {
   2.199 -+    printf("Usage: tpmd clear|save|deactivated vtpmid\n" );
   2.200 ++  if (argc < 4) {
   2.201 ++    error("Usage: tpmd clear|save|deactivated pvm|hvm vtpmid\n" );
   2.202  +#endif
   2.203   	  return -1;
   2.204     }
   2.205   
   2.206  +#ifndef VTPM_MULTI_VM
   2.207 -+  dmi_id = atoi(argv[2]);
   2.208 ++  /* setup type of vm */
   2.209 ++  if (!strcmp(argv[2], "pvm")) {
   2.210 ++    type = VTPM_TYPE_PVM; // Get commands from vTPM Manager through fifo
   2.211 ++  } else if (!strcmp(argv[2], "hvm")) {
   2.212 ++    type = VTPM_TYPE_HVM; // Get commands from qemu via socket
   2.213 ++  } else {
   2.214 ++    error("invalid vTPM type '%s'.\n", argv[2]);
   2.215 ++  }
   2.216 ++
   2.217 ++  dmi_id = atoi(argv[3]);
   2.218 ++
   2.219 ++  if (type == VTPM_TYPE_PVM) {
   2.220 ++    vtpm_rx_file = malloc(10 + strlen(PVM_RX_FIFO_D));
   2.221 ++    sprintf(vtpm_rx_file, PVM_RX_FIFO_D, (uint32_t) dmi_id);
   2.222 ++  } else {
   2.223 ++    vtpm_rx_file = malloc(10 + strlen(HVM_RX_FIFO_D));
   2.224 ++    sprintf(vtpm_rx_file, HVM_RX_FIFO_D, (uint32_t) dmi_id);
   2.225 ++
   2.226 ++    if ( (sockfd = socket(PF_UNIX,SOCK_STREAM,0)) < 0) {
   2.227 ++          error("Unable to create socket. errno = %d\n", errno);
   2.228 ++      exit (-1);
   2.229 ++    }
   2.230 ++
   2.231 ++    memset(&addr, 0, sizeof(addr));
   2.232 ++    addr.sun_family = AF_UNIX;
   2.233 ++    strcpy(addr.sun_path,vtpm_rx_file );
   2.234 ++    unlink(addr.sun_path);
   2.235 ++  }
   2.236 ++#endif
   2.237 ++
   2.238 ++#ifdef VTPM_MULTI_VM
   2.239 ++  info("Initializing tpm state: %s\n", argv[1]);
   2.240 ++#else
   2.241 ++  info("Initializing tpm state: %s, type: %s, id: %d\n", argv[1], argv[2], dmi_id);
   2.242  +#endif
   2.243  +
   2.244     /* initialize TPM emulator */
   2.245     if (!strcmp(argv[1], "clear")) {
   2.246 -     printf("Initializing tpm: %s\n", argv[1]);
   2.247 -@@ -80,46 +102,30 @@ int main(int argc, char **argv)
   2.248 +-    printf("Initializing tpm: %s\n", argv[1]);
   2.249 +     tpm_emulator_init(1);
   2.250 +-  } else if (!strcmp(argv[1], "save")) { 
   2.251 +-    printf("Initializing tpm: %s\n", argv[1]);
   2.252 ++  } else if (!strcmp(argv[1], "save")) {
   2.253 +     tpm_emulator_init(2);
   2.254 +   } else if (!strcmp(argv[1], "deactivated")) {
   2.255 +-    printf("Initializing tpm: %s\n", argv[1]);
   2.256 +     tpm_emulator_init(3);
   2.257 +   } else {
   2.258 +-    printf("invalid startup mode '%s'; must be 'clear', "
   2.259 ++    error("invalid startup mode '%s'; must be 'clear', "
   2.260 +       "'save' (default) or 'deactivated", argv[1]);
   2.261       return -1;
   2.262     }
   2.263 - 
   2.264 +-
   2.265  -  if ( stat(TPM_RX_FNAME, &file_info) == -1) {
   2.266  -    if ( mkfifo(TPM_RX_FNAME, S_IWUSR | S_IRUSR ) ) {
   2.267  -      printf("Failed to create fifo %s.\n", TPM_RX_FNAME);
   2.268 @@ -453,8 +554,6 @@ diff -uprN tpm_emulator/tpmd.c vtpm/tpmd
   2.269  -    }
   2.270  -  }
   2.271  -
   2.272 -+  char *guest_rx_file = malloc(10 + strlen(GUEST_RX_FIFO_D));
   2.273 -+  sprintf(guest_rx_file, GUEST_RX_FIFO_D, (uint32_t) dmi_id);
   2.274  +  
   2.275     while (1) {
   2.276   abort_command:
   2.277 @@ -462,15 +561,33 @@ diff -uprN tpm_emulator/tpmd.c vtpm/tpmd
   2.278  -      tpm_rx_fh = open(TPM_RX_FNAME, O_RDONLY);
   2.279  +    if (vtpm_rx_fh < 0) {
   2.280  +#ifdef VTPM_MUTLI_VM
   2.281 -+	  vtpm_rx_fh = open(DEV_BE, O_RDWR);
   2.282 ++      vtpm_rx_fh = open(DEV_BE, O_RDWR);
   2.283  +#else
   2.284 -+      vtpm_rx_fh = open(guest_rx_file, O_RDONLY);
   2.285 ++      if (type == VTPM_TYPE_PVM) {
   2.286 ++        vtpm_rx_fh = open(vtpm_rx_file, O_RDONLY);
   2.287 ++      } else {
   2.288 ++        if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
   2.289 ++          error("Unable to bind(). errno = %d\n", errno);
   2.290 ++          exit (-1);
   2.291 ++        }
   2.292 ++
   2.293 ++        if (listen(sockfd, 10) <0) {
   2.294 ++          error("Unable to listen(). errno = %d\n", errno);
   2.295 ++          exit (-1);
   2.296 ++        }
   2.297 ++
   2.298 ++        memset(&client_addr, 0, sizeof(client_addr));
   2.299 ++        client_length = sizeof(client_addr);
   2.300 ++
   2.301 ++        vtpm_rx_fh = vtpm_tx_fh = accept(sockfd, &client_addr, &client_length);
   2.302 ++      }
   2.303  +#endif
   2.304       }
   2.305       
   2.306  -    if (tpm_rx_fh < 0) {
   2.307 +-      printf("ERROR: failed to open devices to listen to guest.\n");
   2.308  +    if (vtpm_rx_fh < 0) {
   2.309 -       printf("ERROR: failed to open devices to listen to guest.\n");
   2.310 ++      error("Failed to open devices to listen to guest.\n");
   2.311         return -1;
   2.312       }
   2.313       
   2.314 @@ -486,7 +603,8 @@ diff -uprN tpm_emulator/tpmd.c vtpm/tpmd
   2.315  -    in_size = read(tpm_rx_fh, in, BUFFER_SIZE);
   2.316  +    in_size = read(vtpm_rx_fh, in, BUFFER_SIZE);
   2.317       if (in_size < 6) { // Magic size of minium TPM command
   2.318 -       printf("Recv[%d] to small: 0x", in_size);
   2.319 +-      printf("Recv[%d] to small: 0x", in_size);
   2.320 ++      info("Recv incomplete command of %d bytes.", in_size);
   2.321         if (in_size <= 0) {
   2.322  -          close(tpm_rx_fh);
   2.323  -          tpm_rx_fh = -1;
   2.324 @@ -495,8 +613,13 @@ diff -uprN tpm_emulator/tpmd.c vtpm/tpmd
   2.325             goto abort_command;
   2.326         }
   2.327       } else { 
   2.328 -@@ -129,28 +135,73 @@ abort_command:
   2.329 -       printf("\n");
   2.330 +-      printf("Recv[%d]: 0x", in_size);
   2.331 ++      debug_nostop("Recv[%d]: 0x", in_size);
   2.332 +       for (i=0; i< in_size; i++) 
   2.333 +-        printf("%x ", in[i]);
   2.334 +-      printf("\n");
   2.335 ++        debug_more("%x ", in[i]);
   2.336 ++      debug_more("\n");
   2.337       }
   2.338   
   2.339  -    
   2.340 @@ -504,71 +627,56 @@ diff -uprN tpm_emulator/tpmd.c vtpm/tpmd
   2.341  -        printf("ERROR: Handler Failed.\n");
   2.342  +    if (guest_id == -1) {
   2.343  +        guest_id = *((uint32_t *) in);
   2.344 -+        *((uint32_t *) ctrl_msg) = *((uint32_t *) in);
   2.345  +    } else {
   2.346  +        if (guest_id != *((uint32_t *) in) ) {
   2.347 -+            printf("WARNING: More than one guest attached\n");
   2.348 ++            error("WARNING: More than one guest attached\n");
   2.349  +        }
   2.350 ++    }
   2.351 ++
   2.352 ++    if (vtpm_tx_fh < 0) {
   2.353 ++#ifdef VTPM_MUTLI_VM
   2.354 ++      vtpm_tx_fh = open(DEV_BE, O_RDWR);
   2.355 ++      vtpm_rx_fh = vtpm_tx_fh;
   2.356 ++#else
   2.357 ++      if (type == VTPM_TYPE_PVM) {
   2.358 ++        vtpm_tx_fh = open(PVM_TX_FIFO, O_WRONLY);
   2.359 ++      } // No need to open the other direction for HVM
   2.360 ++#endif
   2.361 ++    }
   2.362 ++
   2.363 ++    if (vtpm_tx_fh < 0) {
   2.364 ++      error("Failed to open devices to respond to guest.\n");
   2.365 ++      return -1;
   2.366 ++    }
   2.367 ++
   2.368 ++    // Handle the command, but skip the domain id header    
   2.369 ++    if (tpm_handle_command(in + sizeof(uint32_t), in_size - sizeof(uint32_t), &out, &out_size) != 0) { 
   2.370 ++      error("Handler Failed.\n");
   2.371       }
   2.372   
   2.373  -    written = write(tpm_tx_fh, out, out_size);
   2.374 -+    if (vtpm_tx_fh < 0) {
   2.375 -+#ifdef VTPM_MUTLI_VM
   2.376 -+	  vtpm_tx_fh = open(DEV_BE, O_RDWR);
   2.377 -+	  vtpm_rx_fh = vtpm_tx_fh;
   2.378 -+#else
   2.379 -+      vtpm_tx_fh = open(GUEST_TX_FIFO, O_WRONLY);
   2.380 -+#endif
   2.381 -+    }
   2.382 ++    addressed_out = (uint8_t *) tpm_malloc(sizeof(uint32_t) + out_size);
   2.383 ++    *(uint32_t *) addressed_out = *(uint32_t *) in;
   2.384 ++    memcpy(addressed_out + sizeof(uint32_t), out, out_size);
   2.385 ++
   2.386 ++    written = write(vtpm_tx_fh, addressed_out, out_size + sizeof(uint32_t));
   2.387   
   2.388  -    if (written != out_size ) {
   2.389  -      printf("ERROR: Part of response not written %d/%d.\nAttempt: ", written, out_size);
   2.390 --    } else {
   2.391 ++    if (written != out_size + sizeof(uint32_t)) {
   2.392 ++      error("Part of response not written %d/%d.\n", written, out_size);
   2.393 +     } else {
   2.394  -      printf("Sent[%Zu]: ", out_size);
   2.395 -+    if (vtpm_tx_fh < 0) {
   2.396 -+      printf("ERROR: failed to open devices to respond to guest.\n");
   2.397 -+      return -1;
   2.398 -+    }
   2.399 -+    
   2.400 -+    // Handle command, but we need to skip the identifier
   2.401 -+    if (  BE16_TO_CPU( ((uint16_t *) in)[2] ) == VTPM_TAG_REQ ) { // Control message from xend
   2.402 -+      // This DM doesn't really care about ctrl messages. Just ACK the message
   2.403 -+      written = write(vtpm_tx_fh, ctrl_msg, sizeof(ctrl_msg));
   2.404 -+
   2.405 -+      if (written != sizeof(ctrl_msg)) {
   2.406 -+        printf("ERROR: Part of response not written %d/%Zu.\n", written, sizeof(ctrl_msg));
   2.407 -+      } else {
   2.408 -+        printf("Send Ctrl Message confermation\n");
   2.409 -+      }
   2.410 -+    } else { // Message from Guest
   2.411 -+      if (tpm_handle_command(in + sizeof(uint32_t), in_size - sizeof(uint32_t), &out, &out_size) != 0) { 
   2.412 -+        printf("ERROR: Handler Failed.\n");
   2.413 -+      }
   2.414 -+
   2.415 -+      addressed_out = (uint8_t *) tpm_malloc(sizeof(uint32_t) + out_size);
   2.416 -+      *(uint32_t *) addressed_out = *(uint32_t *) in;
   2.417 -+      memcpy(addressed_out + sizeof(uint32_t), out, out_size);
   2.418 -+
   2.419 -+      written = write(vtpm_tx_fh, addressed_out, out_size + sizeof(uint32_t));
   2.420 -+
   2.421 -+      if (written != out_size + sizeof(uint32_t)) {
   2.422 -+        printf("ERROR: Part of response not written %d/%d.\n", written, out_size);
   2.423 -+        for (i=0; i< out_size+ sizeof(uint32_t); i++)
   2.424 -+          printf("%x ", addressed_out[i]);
   2.425 -+        printf("\n");
   2.426 -+      } else {
   2.427 -+        printf("Sent[%Zu]: ", out_size + sizeof(uint32_t));
   2.428 -+        for (i=0; i< out_size+ sizeof(uint32_t); i++)
   2.429 -+          printf("%x ", addressed_out[i]);
   2.430 -+        printf("\n");
   2.431 -+      }
   2.432 -+      tpm_free(out);
   2.433 -+      tpm_free(addressed_out);
   2.434 ++      debug_nostop("Sent[%Zu]: ", out_size + sizeof(uint32_t));
   2.435 ++      for (i=0; i< out_size+ sizeof(uint32_t); i++)
   2.436 ++        debug_more("%x ", addressed_out[i]);
   2.437 ++      debug_more("\n");
   2.438       }
   2.439  -    for (i=0; i< out_size; i++)
   2.440  -      printf("%x ", out[i]);
   2.441  -    printf("\n");
   2.442 --    tpm_free(out);
   2.443 +     tpm_free(out);
   2.444 ++    tpm_free(addressed_out);
   2.445   
   2.446     } // loop
   2.447   
   2.448 @@ -579,19 +687,7 @@ diff -uprN tpm_emulator/tpmd.c vtpm/tpmd
   2.449  +  close(vtpm_tx_fh);
   2.450  +#ifndef VTPM_MUTLI_VM
   2.451  +  close(vtpm_rx_fh);
   2.452 -+  free (guest_rx_file);
   2.453 ++  free (vtpm_rx_file);
   2.454  +#endif
   2.455   
   2.456   }
   2.457 -Binary files tpm_emulator/tpm_emulator and vtpm/tpm_emulator differ
   2.458 -diff -uprN tpm_emulator/tpm_version.h vtpm/tpm_version.h
   2.459 ---- tpm_emulator/tpm_version.h	2006-07-24 14:35:41.000000000 -0700
   2.460 -+++ vtpm/tpm_version.h	2006-07-24 14:35:35.000000000 -0700
   2.461 -@@ -2,5 +2,5 @@
   2.462 - #define _TPM_VERSION_H_
   2.463 - #define VERSION_MAJOR 0
   2.464 - #define VERSION_MINOR 4
   2.465 --#define VERSION_BUILD 1153776940
   2.466 -+#define VERSION_BUILD 1153776935
   2.467 - #endif /* _TPM_VERSION_H_ */
   2.468 -Binary files tpm_emulator/vtpmd and vtpm/vtpmd differ
     3.1 --- a/tools/vtpm_manager/Rules.mk	Mon Jan 22 15:58:27 2007 +0000
     3.2 +++ b/tools/vtpm_manager/Rules.mk	Mon Jan 22 15:59:41 2007 +0000
     3.3 @@ -39,7 +39,7 @@ OBJS	= $(patsubst %.c,%.o,$(SRCS))
     3.4  CFLAGS += -D_GNU_SOURCE
     3.5  
     3.6  # Logging Level. See utils/tools.h for usage
     3.7 -CFLAGS += -DLOGGING_MODULES="(BITMASK(VTPM_LOG_TCS)|BITMASK(VTPM_LOG_VTSP)|BITMASK(VTPM_LOG_VTPM)|BITMASK(VTPM_LOG_VTPM_DEEP))"
     3.8 +CFLAGS += -DLOGGING_MODULES="(BITMASK(VTPM_LOG_TCS)|BITMASK(VTPM_LOG_VTSP)|BITMASK(VTPM_LOG_VTPM))"
     3.9  
    3.10  # Silent Mode
    3.11  #CFLAGS += -DLOGGING_MODULES=0x0
     4.1 --- a/tools/vtpm_manager/manager/Makefile	Mon Jan 22 15:58:27 2007 +0000
     4.2 +++ b/tools/vtpm_manager/manager/Makefile	Mon Jan 22 15:59:41 2007 +0000
     4.3 @@ -14,6 +14,9 @@ install: build
     4.4  	if [ ! -d "$(DESTDIR)/var/vtpm/fifos" ]; \
     4.5  		then mkdir -p $(DESTDIR)/var/vtpm/fifos; \
     4.6  	fi
     4.7 +	if [ ! -d "$(DESTDIR)/var/vtpm/socks" ]; \
     4.8 +		then mkdir -p $(DESTDIR)/var/vtpm/socks; \
     4.9 +	fi
    4.10  	$(INSTALL_PROG) $(BIN) $(TOOLS_INSTALL_DIR)
    4.11  
    4.12  .PHONY: clean
     5.1 --- a/tools/vtpm_manager/manager/dmictl.c	Mon Jan 22 15:58:27 2007 +0000
     5.2 +++ b/tools/vtpm_manager/manager/dmictl.c	Mon Jan 22 15:59:41 2007 +0000
     5.3 @@ -54,7 +54,7 @@
     5.4  // if dmi_res is non-null, then return a pointer to new object.
     5.5  // Also, this does not fill in the measurements. They should be filled by
     5.6  // design dependent code or saveNVM
     5.7 -TPM_RESULT init_dmi(UINT32 dmi_id, BYTE type,  VTPM_DMI_RESOURCE **dmi_res) {
     5.8 +TPM_RESULT init_dmi(UINT32 dmi_id, BYTE dmi_type, VTPM_DMI_RESOURCE **dmi_res) {
     5.9  
    5.10    TPM_RESULT status=TPM_SUCCESS;
    5.11    VTPM_DMI_RESOURCE *new_dmi=NULL;
    5.12 @@ -66,6 +66,7 @@ TPM_RESULT init_dmi(UINT32 dmi_id, BYTE 
    5.13    }
    5.14    memset(new_dmi, 0, sizeof(VTPM_DMI_RESOURCE));
    5.15    new_dmi->dmi_id = dmi_id;
    5.16 +  new_dmi->dmi_type = dmi_type;
    5.17    new_dmi->connected = FALSE;
    5.18    new_dmi->TCSContext = 0;
    5.19  
    5.20 @@ -120,47 +121,46 @@ TPM_RESULT VTPM_Handle_New_DMI(const buf
    5.21    
    5.22    VTPM_DMI_RESOURCE *new_dmi=NULL;
    5.23    TPM_RESULT status=TPM_FAIL;
    5.24 -  BYTE type, startup_mode;
    5.25 +  BYTE dmi_type, vm_type, startup_mode;
    5.26    UINT32 dmi_id; 
    5.27  
    5.28    if (param_buf == NULL) { // Assume creation of Dom 0 control
    5.29 -    type = VTPM_TYPE_NON_MIGRATABLE;
    5.30 +    dmi_type = VTPM_TYPE_NON_MIGRATABLE;
    5.31      dmi_id = VTPM_CTL_DM;
    5.32 -  } else if (buffer_len(param_buf) != sizeof(BYTE) + sizeof(BYTE) + sizeof(UINT32)) {
    5.33 +  } else if (buffer_len(param_buf) != sizeof(BYTE) * 3  + sizeof(UINT32)) {
    5.34      vtpmloginfo(VTPM_LOG_VTPM, "New DMI command wrong length: %d.\n", buffer_len(param_buf));
    5.35      status = TPM_BAD_PARAMETER;
    5.36      goto abort_egress;
    5.37    } else {
    5.38      vtpm_globals->connected_dmis++; // Put this here so we don't count Dom0
    5.39 -    BSG_UnpackList( param_buf->bytes, 3,
    5.40 -		    BSG_TYPE_BYTE, &type,
    5.41 +    BSG_UnpackList( param_buf->bytes, 4,
    5.42 +		    BSG_TYPE_BYTE, &dmi_type,
    5.43  		    BSG_TYPE_BYTE, &startup_mode,
    5.44 +		    BSG_TYPE_BYTE, &vm_type,
    5.45  		    BSG_TYPE_UINT32,  &dmi_id);
    5.46    }
    5.47  
    5.48 +  if ((dmi_type != VTPM_TYPE_NON_MIGRATABLE) && (dmi_type != VTPM_TYPE_MIGRATABLE)) {
    5.49 +    vtpmlogerror(VTPM_LOG_VTPM, "Creation of VTPM with illegal type.\n");
    5.50 +    status = TPM_BAD_PARAMETER;
    5.51 +    goto abort_egress;
    5.52 +  }
    5.53 +
    5.54    new_dmi = (VTPM_DMI_RESOURCE *) hashtable_search(vtpm_globals->dmi_map, &dmi_id);
    5.55    if (new_dmi == NULL) { 
    5.56      vtpmloginfo(VTPM_LOG_VTPM, "Creating new DMI instance %d attached.\n", dmi_id );
    5.57      // Brand New DMI. Initialize the persistent pieces
    5.58 -    TPMTRYRETURN(init_dmi(dmi_id, type, &new_dmi) );  
    5.59 +    TPMTRYRETURN(init_dmi(dmi_id, dmi_type, &new_dmi) );  
    5.60    } else 
    5.61      vtpmloginfo(VTPM_LOG_VTPM, "Re-attaching DMI instance %d.\n", dmi_id);
    5.62  
    5.63 -  if (type != VTPM_TYPE_MIGRATED) {
    5.64 -    new_dmi->dmi_type = type;
    5.65 -  } else {
    5.66 -    vtpmlogerror(VTPM_LOG_VTPM, "Creation of VTPM with illegal type.\n");
    5.67 -    status = TPM_BAD_PARAMETER;
    5.68 -    goto abort_egress;
    5.69 -  }
    5.70 -  
    5.71    if (new_dmi->connected) {
    5.72      vtpmlogerror(VTPM_LOG_VTPM, "Attempt to re-attach, currently attached instance %d. Ignoring\n", dmi_id);
    5.73      status = TPM_BAD_PARAMETER;
    5.74      goto abort_egress;
    5.75    }
    5.76    
    5.77 -  if (type == VTPM_TYPE_MIGRATED) {
    5.78 +  if (new_dmi->dmi_type == VTPM_TYPE_MIGRATED) {
    5.79      vtpmlogerror(VTPM_LOG_VTPM, "Attempt to re-attach previously migrated instance %d without recovering first. Ignoring\n", dmi_id);
    5.80      status = TPM_BAD_PARAMETER;
    5.81      goto abort_egress;
    5.82 @@ -173,7 +173,7 @@ TPM_RESULT VTPM_Handle_New_DMI(const buf
    5.83  
    5.84    // Design specific new DMI code. 
    5.85    // Includes: create IPCs, Measuring DMI, and maybe launching DMI
    5.86 -  status = VTPM_New_DMI_Extra(new_dmi, startup_mode);
    5.87 +  TPMTRYRETURN(VTPM_New_DMI_Extra(new_dmi, vm_type, startup_mode) );
    5.88    goto egress;
    5.89    
    5.90   abort_egress:
     6.1 --- a/tools/vtpm_manager/manager/vtpm_manager.h	Mon Jan 22 15:58:27 2007 +0000
     6.2 +++ b/tools/vtpm_manager/manager/vtpm_manager.h	Mon Jan 22 15:59:41 2007 +0000
     6.3 @@ -70,6 +70,10 @@
     6.4  #define VTPM_ORD_MIGRATE_OUT  (VTPM_PRIV_BASE + 5) // migrate VTPM to dest 
     6.5  
     6.6  //************************ Return Codes ****************************
     6.7 +#define VTPM_TYPE_PVM 1 // Paravirtualized Domain
     6.8 +#define VTPM_TYPE_HVM 2 // HVM Domain
     6.9 +
    6.10 +//************************ Return Codes ****************************
    6.11  #define VTPM_SUCCESS               0
    6.12  #define VTPM_FAIL                  1
    6.13  #define VTPM_UNSUPPORTED           2
    6.14 @@ -104,8 +108,9 @@ VTPM Response Format
    6.15  
    6.16  VTPM_Open:
    6.17    Input Parameters:
    6.18 -    Domain_type: 1 byte 
    6.19 +    mig_type: 1 byte 
    6.20      startup_mode: 1 byte // Cold Boot = 1, resume = 2, deactive = 3
    6.21 +    domain type: 1 byte
    6.22      instance_id: 4 bytes
    6.23    Output Parameters:
    6.24      None
     7.1 --- a/tools/vtpm_manager/manager/vtpm_manager_handler.c	Mon Jan 22 15:58:27 2007 +0000
     7.2 +++ b/tools/vtpm_manager/manager/vtpm_manager_handler.c	Mon Jan 22 15:59:41 2007 +0000
     7.3 @@ -40,6 +40,7 @@
     7.4  #include <stdio.h>
     7.5  #include <unistd.h>
     7.6  #include <string.h>
     7.7 +#include <errno.h>
     7.8  
     7.9  #include "vtpm_manager.h"
    7.10  #include "vtpmpriv.h"
    7.11 @@ -105,7 +106,7 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ip
    7.12        for (i=0; i<size_read; i++) 
    7.13  	vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cmd_header[i]);
    7.14      } else {
    7.15 -      vtpmhandlerlogerror(VTPM_LOG_VTPM, "%s can't read from ipc. Aborting... \n", thread_name);
    7.16 +      vtpmhandlerlogerror(VTPM_LOG_VTPM, "%s can't read from ipc. Errono = %d. Aborting... \n", thread_name, errno);
    7.17        goto abort_command;
    7.18      }
    7.19  
     8.1 --- a/tools/vtpm_manager/manager/vtpmd.c	Mon Jan 22 15:58:27 2007 +0000
     8.2 +++ b/tools/vtpm_manager/manager/vtpmd.c	Mon Jan 22 15:59:41 2007 +0000
     8.3 @@ -63,6 +63,9 @@
     8.4  #define VTPM_TX_HP_FNAME       "/var/vtpm/fifos/to_console.fifo"
     8.5  #define VTPM_RX_HP_FNAME       "/var/vtpm/fifos/from_console.fifo"
     8.6  
     8.7 +#define VTPM_TYPE_PVM_STRING "pvm"
     8.8 +#define VTPM_TYPE_HVM_STRING "hvm"
     8.9 +
    8.10  struct vtpm_thread_params_s {
    8.11    vtpm_ipc_handle_t *tx_ipc_h;
    8.12    vtpm_ipc_handle_t *rx_ipc_h;
    8.13 @@ -104,12 +107,12 @@ void signal_handler(int reason) {
    8.14  
    8.15  struct sigaction ctl_c_handler;
    8.16  
    8.17 -TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res, BYTE startup_mode) {
    8.18 +TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res, BYTE vm_type, BYTE startup_mode) {
    8.19  
    8.20    TPM_RESULT status = TPM_SUCCESS;
    8.21    int fh;
    8.22    char dmi_id_str[11]; // UINT32s are up to 10 digits + NULL
    8.23 -  char *tx_vtpm_name, *tx_tpm_name;
    8.24 +  char *tx_vtpm_name, *tx_tpm_name, *vm_type_string;
    8.25    struct stat file_info;
    8.26  
    8.27    if (dmi_res->dmi_id == VTPM_CTL_DM) {
    8.28 @@ -156,6 +159,10 @@ TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_R
    8.29      */
    8.30      memset(&dmi_res->DMI_measurement, 0xcc, sizeof(TPM_DIGEST));
    8.31  
    8.32 +    if (vm_type == VTPM_TYPE_PVM)
    8.33 +      vm_type_string = (BYTE *)&VTPM_TYPE_PVM_STRING;
    8.34 +    else
    8.35 +      vm_type_string = (BYTE *)&VTPM_TYPE_HVM_STRING;
    8.36  
    8.37      // Launch DMI
    8.38      sprintf(dmi_id_str, "%d", (int) dmi_res->dmi_id);
    8.39 @@ -172,13 +179,13 @@ TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_R
    8.40      } else if (pid == 0) {
    8.41        switch (startup_mode) {
    8.42        case TPM_ST_CLEAR:
    8.43 -        execl (TPM_EMULATOR_PATH, "vtpmd", "clear", dmi_id_str, NULL);
    8.44 +        execl (TPM_EMULATOR_PATH, "vtpmd", "clear", vm_type_string, dmi_id_str, NULL);
    8.45          break;
    8.46        case TPM_ST_STATE:
    8.47 -        execl (TPM_EMULATOR_PATH, "vtpmd", "save", dmi_id_str, NULL);
    8.48 +        execl (TPM_EMULATOR_PATH, "vtpmd", "save", vm_type_string, dmi_id_str, NULL);
    8.49          break;
    8.50        case TPM_ST_DEACTIVATED:
    8.51 -        execl (TPM_EMULATOR_PATH, "vtpmd", "deactivated", dmi_id_str, NULL);
    8.52 +        execl (TPM_EMULATOR_PATH, "vtpmd", "deactivated", vm_type_string, dmi_id_str, NULL);
    8.53          break;
    8.54        default:
    8.55          status = TPM_BAD_PARAMETER;
     9.1 --- a/tools/vtpm_manager/manager/vtpmpriv.h	Mon Jan 22 15:58:27 2007 +0000
     9.2 +++ b/tools/vtpm_manager/manager/vtpmpriv.h	Mon Jan 22 15:59:41 2007 +0000
     9.3 @@ -165,7 +165,7 @@ TPM_RESULT VTPM_Handle_Get_Migration_key
     9.4  TPM_RESULT VTPM_SaveManagerData(void);
     9.5  TPM_RESULT VTPM_LoadManagerData(void);
     9.6  
     9.7 -TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res, BYTE startup_mode);
     9.8 +TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res, BYTE vm_type, BYTE startup_mode);
     9.9  
    9.10  TPM_RESULT VTPM_Close_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res);
    9.11