[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH V8 01/14] Support for TPM command line options
From: |
Michael S. Tsirkin |
Subject: |
Re: [Qemu-devel] [PATCH V8 01/14] Support for TPM command line options |
Date: |
Thu, 1 Sep 2011 20:14:32 +0300 |
User-agent: |
Mutt/1.5.21 (2010-09-15) |
On Wed, Aug 31, 2011 at 10:35:52AM -0400, Stefan Berger wrote:
> This patch adds support for TPM command line options.
> The command line supported here (considering the libtpms based
> backend) are
>
> ./qemu-... -tpm builtin,path=<path to blockstorage file>
>
> and
>
> ./qemu-... -tpmdev builtin,path=<path to blockstorage file>,id=<id>
> -device tpm-tis,tpmdev=<id>
do we really need both?
> and
>
> ./qemu-... -tpmdev ?
>
> where the latter works similar to -soundhw ? and shows a list of
> available TPM backends ('builtin').
>
> To show the available TPM models do:
>
> ./qemu-... -tpm model=?
Can we live with -tpmdev for backend and plain device_add for frontend?
Frontend would be connected to backend using a tpmdev matching the id
of the frontend...
> In case of -tpm, 'type' (above 'builtin') and 'model' are interpreted in
> tpm.c.
> In case of -tpmdev 'type' and 'id' are interpreted in tpm.c
> Using the type parameter, the backend is chosen, i.e., 'builtin' for the
> libtpms-based builtin TPM. The interpretation of the other parameters along
> with determining whether enough parameters were provided is pushed into
> the backend driver, which needs to implement the interface function
> 'create' and return a TPMDriver structure if the VM can be started or 'NULL'
> if not enough or bad parameters were provided.
>
> Since SeaBIOS will now use 128kb for ACPI tables the amount of reserved
> memory for ACPI tables needs to be increased -- increasing it to 128kb.
Increasing from which value to which?
> Monitor support for 'info tpm' has been added. It for example prints the
> following:
>
> TPM devices:
> builtin: model=tpm-tis,id=tpm0
This mixes frontend and backend properties.
>
> v8:
> - adjusting formatting of backend drivers output to accomodate better
> formatting of 'passthrough' backend output
>
> v6:
> - use #idef CONFIG_TPM to surround TPM calls
> - use QLIST_FOREACH_SAFE rather than QLIST_FOREACH in tpm_cleanup
> - commented backend ops in tpm.h
> - moving to IRQ 5 (11 collided with network cards)
>
> v5:
> - fixing typo reported by Serge Hallyn
> - Adapting code to split command line parameters supporting
> -tpmdev ... -device tpm-tis,tpmdev=...
> - moved code out of arch_init.c|h into tpm.c|h
> - increasing reserved memory for ACPI tables to 128kb (from 64kb)
> - the backend interface has a create() function for interpreting the command
> line parameters and returning a TPMDevice structure; previoulsy
> this function was called handle_options()
> - the backend interface has a destroy() function for cleaning up after
> the create() function was called
> - added support for 'info tpm' in monitor
>
> v4:
> - coding style fixes
>
> v3:
> - added hw/tpm_tis.h to this patch so Qemu compiles at this stage
>
> Signed-off-by: Stefan Berger <address@hidden>
>
> ---
> Makefile.target | 1
> hmp-commands.hx | 2
> hw/pc.c | 7 +
> hw/tpm_tis.h | 75 +++++++++++++++
> monitor.c | 10 ++
> qemu-config.c | 46 +++++++++
> qemu-options.hx | 80 ++++++++++++++++
> tpm.c | 279
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> tpm.h | 112 ++++++++++++++++++++++
> vl.c | 18 +++
> 10 files changed, 629 insertions(+), 1 deletion(-)
>
> Index: qemu-git/qemu-options.hx
> ===================================================================
> --- qemu-git.orig/qemu-options.hx
> +++ qemu-git/qemu-options.hx
> @@ -1760,6 +1760,86 @@ ETEXI
>
> DEFHEADING()
>
> +DEFHEADING(TPM device options:)
> +
> +#ifndef _WIN32
> +# ifdef CONFIG_TPM
> +DEF("tpm", HAS_ARG, QEMU_OPTION_tpm, \
> + "" \
> + "-tpm builtin,path=<path>[,model=<model>]\n" \
> + " enable a builtin TPM with state in file in path\n" \
> + "-tpm model=? to list available TPM device models\n" \
> + "-tpm ? to list available TPM backend types\n",
> + QEMU_ARCH_I386)
> +DEF("tpmdev", HAS_ARG, QEMU_OPTION_tpmdev, \
> + "-tpmdev [builtin],id=str[,option][,option][,...]\n",
> + QEMU_ARCH_I386)
> +# endif
> +#endif
> +STEXI
> +
> +The general form of a TPM device option is:
> address@hidden @option
> +
> address@hidden -tpmdev @var{backend} ,address@hidden [,@var{options}]
> address@hidden -tpmdev
> +Backend type must be:
> address@hidden
> +
> +The specific backend type will determine the applicable options.
> +The @code{-tpmdev} options requires a @code{-device} option.
> +
> +Options to each backend are described below.
> +
> +Use ? to print all available TPM backend types.
> address@hidden
> +qemu -tpmdev ?
> address@hidden example
> +
> address@hidden -tpmdev builtin ,address@hidden, address@hidden
> +
> +Creates an instance of the built-in TPM.
> +
> address@hidden specifies the path to the QCoW2 image that will store
> +the TPM's persistent data. @option{path} is required.
> +
> +To create a built-in TPM use the following two options:
> address@hidden
> +-tpmdev builtin,id=tpm0,path=<path_to_qcow2> -device tpm-tis,tpmdev=tpm0
> address@hidden example
> +Not that the @code{-tpmdev} id is @code{tpm0} and is referenced by
> address@hidden in the device option.
> +
> address@hidden table
> +
> +The short form of a TPM device option is:
> address@hidden @option
> +
> address@hidden -tpm @var{backend-type}, address@hidden [,address@hidden
> address@hidden -tpm
> +
> address@hidden specifies the device model. The default device model is a
> address@hidden device model. @code{model} is optional.
> +
> +Use ? to print all available TPM models.
> address@hidden
> +qemu -tpm model=?
> address@hidden example
> +
> +The other options have the same meaning as explained above.
> +
> +To create a built-in TPM use the following option:
> address@hidden
> +-tpm builtin, path=<path_to_qcow2>
> address@hidden example
> +
> address@hidden table
> +
> +ETEXI
> +
> +
> +DEFHEADING()
> +
> DEFHEADING(Linux/Multiboot boot specific:)
> STEXI
>
> Index: qemu-git/vl.c
> ===================================================================
> --- qemu-git.orig/vl.c
> +++ qemu-git/vl.c
> @@ -137,6 +137,7 @@ int main(int argc, char **argv)
> #include "block.h"
> #include "blockdev.h"
> #include "block-migration.h"
> +#include "tpm.h"
> #include "dma.h"
> #include "audio/audio.h"
> #include "migration.h"
> @@ -2498,6 +2499,14 @@ int main(int argc, char **argv, char **e
> ram_size = value;
> break;
> }
> +#ifdef CONFIG_TPM
> + case QEMU_OPTION_tpm:
> + tpm_config_parse(qemu_find_opts("tpm"), optarg);
> + break;
> + case QEMU_OPTION_tpmdev:
> + tpm_config_parse(qemu_find_opts("tpmdev"), optarg);
> + break;
> +#endif
> case QEMU_OPTION_mempath:
> mem_path = optarg;
> break;
> @@ -3149,6 +3158,12 @@ int main(int argc, char **argv, char **e
> exit(1);
> }
>
> +#ifdef CONFIG_TPM
> + if (tpm_init() < 0) {
> + exit(1);
> + }
> +#endif
> +
> /* init the bluetooth world */
> if (foreach_device_config(DEV_BT, bt_parse))
> exit(1);
> @@ -3394,6 +3409,9 @@ int main(int argc, char **argv, char **e
> quit_timers();
> net_cleanup();
> res_free();
> +#ifdef CONFIG_TPM
> + tpm_cleanup();
> +#endif
>
> return 0;
> }
> Index: qemu-git/qemu-config.c
> ===================================================================
> --- qemu-git.orig/qemu-config.c
> +++ qemu-git/qemu-config.c
> @@ -507,6 +507,50 @@ QemuOptsList qemu_boot_opts = {
> },
> };
>
> +static QemuOptsList qemu_tpmdev_opts = {
> + .name = "tpmdev",
> + .implied_opt_name = "type",
> + .head = QTAILQ_HEAD_INITIALIZER(qemu_tpmdev_opts.head),
> + .desc = {
> + {
> + .name = "type",
> + .type = QEMU_OPT_STRING,
> + .help = "Type of TPM backend",
> + },
> + {
> + .name = "path",
> + .type = QEMU_OPT_STRING,
> + .help = "Persistent storage for TPM state",
> + },
> + { /* end of list */ }
> + },
> +};
> +
> +static QemuOptsList qemu_tpm_opts = {
> + .name = "tpm",
> + .implied_opt_name = "type",
> + .head = QTAILQ_HEAD_INITIALIZER(qemu_tpm_opts.head),
> + .desc = {
> + {
> + .name = "type",
> + .type = QEMU_OPT_STRING,
> + .help = "Type of TPM backend",
> + },
> + {
> + .name = "model",
> + .type = QEMU_OPT_STRING,
> + .help = "Model of TPM frontend",
> + },
> + {
> + .name = "path",
> + .type = QEMU_OPT_STRING,
> + .help = "Persistent storage for TPM state",
> + },
> + { /* end of list */ }
> + },
> +};
> +
> +
> static QemuOptsList *vm_config_groups[32] = {
> &qemu_drive_opts,
> &qemu_chardev_opts,
> @@ -523,6 +567,8 @@ static QemuOptsList *vm_config_groups[32
> &qemu_option_rom_opts,
> &qemu_machine_opts,
> &qemu_boot_opts,
> + &qemu_tpmdev_opts,
> + &qemu_tpm_opts,
> NULL,
> };
>
> Index: qemu-git/hw/tpm_tis.h
> ===================================================================
> --- /dev/null
> +++ qemu-git/hw/tpm_tis.h
> @@ -0,0 +1,75 @@
> +/*
> + * tpm_tis.h - include file for tpm_tis.c
> + *
> + * Copyright (C) 2006,2010,2011 IBM Corporation
> + *
> + * Author: Stefan Berger <address@hidden>
> + * David Safford <address@hidden>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation, version 2 of the
> + * License.
> + */
> +#ifndef _HW_TPM_TIS_H
> +#define _HW_TPM_TIS_H
> +
> +#include "isa.h"
> +#include "block_int.h"
> +#include "qemu-thread.h"
> +
> +#include <stdint.h>
> +
> +#define TIS_ADDR_BASE 0xFED40000
> +
> +#define NUM_LOCALITIES 5 /* per spec */
> +#define NO_LOCALITY 0xff
Please use consistent prefixes to avoid namespace
pollution. E.g. tpm_tis_ for stuff in tpm_tis.h, etc.
> +
> +#define IS_VALID_LOCTY(x) ((x) < NUM_LOCALITIES)
> +
> +
> +#define TPM_TIS_IRQ 5
> +
> +#define TIS_TPM_BUFFER_MAX 4096
> +
> +
> +typedef struct TPMSizedBuffer {
> + uint32_t size;
> + uint8_t *buffer;
> +} TPMSizedBuffer;
> +
> +
> +enum tis_state {
> + STATE_IDLE = 0,
> + STATE_READY,
> + STATE_COMPLETION,
> + STATE_EXECUTION,
> + STATE_RECEPTION,
> +};
> +
> +
> +void tis_reset_for_snapshot_resume(TPMState *s);
> +
> +
> +/* utility functions */
> +
> +static inline uint16_t tis_get_size_from_buffer(const TPMSizedBuffer *sb)
> +{
> + return (sb->buffer[4] << 8) + sb->buffer[5];
> +}
> +
> +static inline void dumpBuffer(FILE *stream,
> + unsigned char *buffer, unsigned int len)
> +{
> + int i;
> +
> + for (i = 0; i < len; i++) {
> + if (i && !(i % 16)) {
> + fprintf(stream, "\n");
> + }
> + fprintf(stream, "%.2X ", buffer[i]);
> + }
> + fprintf(stream, "\n");
> +}
> +
> +#endif /* _HW_TPM_TIS_H */
> Index: qemu-git/tpm.c
> ===================================================================
> --- /dev/null
> +++ qemu-git/tpm.c
> @@ -0,0 +1,279 @@
> +/*
> + * TPM configuraion
> + *
> + * Copyright (C) 2011 IBM Corporation
> + * Copyright (C) 2011 Stefan Berger
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2. See
> + * the COPYING file in the top-level directory.
> + *
> + * Based on net.c
> + */
> +#include "config.h"
> +
> +#include "tpm.h"
> +#include "monitor.h"
> +#include "qerror.h"
> +
> +
> +#ifdef CONFIG_TPM
> +
> +#if defined(TARGET_I386) || defined(TARGET_X86_64)
> +
> +static const TPMDriverOps *bes[] = {
> + NULL,
> +};
> +
> +
> +static const char *tpm_models[] = {
> + TPM_DEFAULT_DEVICE_MODEL,
> + NULL,
> +};
> +
> +
> +static QLIST_HEAD(, TPMBackend) tpm_backends =
> + QLIST_HEAD_INITIALIZER(tpm_backends);
> +
> +
> +const TPMDriverOps *tpm_get_backend_driver(const char *id)
> +{
> + int i;
> +
> + for (i = 0; bes[i] != NULL; i++) {
> + if (!strcmp(bes[i]->id, id)) {
> + break;
> + }
> + }
> +
> + return bes[i];
> +}
> +
> +
> +static void tpm_display_models(FILE *out)
> +{
> + int i;
> +
> + fprintf(stderr, "qemu: Supported TPM models: ");
> + for (i = 0 ; tpm_models[i]; i++) {
> + fprintf(stderr, "%s%c", tpm_models[i], tpm_models[i+1] ? ',' : '\n');
> + }
> +}
> +
> +
> +static int tpm_check_model(const char *model)
> +{
> + int i;
> +
> + for (i = 0 ; tpm_models[i]; i++) {
> + if (strcmp(tpm_models[i], model) == 0) {
> + return 1;
> + }
> + }
> +
> + return 0;
> +}
> +
> +
> +void tpm_display_backend_drivers(FILE *out)
> +{
> + int i;
> +
> + fprintf(out, "Supported TPM types (choose only one):\n");
> +
> + for (i = 0; bes[i] != NULL; i++) {
> + fprintf(out, "%12s %s",
> + bes[i]->id, bes[i]->desc());
> + fprintf(out, "\n");
> + }
> + fprintf(out, "\n");
> +}
> +
> +
> +TPMBackend *qemu_find_tpm(const char *id)
> +{
> + TPMBackend *drv;
> +
> + QLIST_FOREACH(drv, &tpm_backends, list) {
> + if (!strcmp(drv->id, id)) {
> + return drv;
> + }
> + }
> +
> + return NULL;
> +}
> +
> +
> +void do_info_tpm(Monitor *mon)
> +{
> + TPMBackend *drv;
> + const char *model;
> +
> + monitor_printf(mon, "TPM devices:\n");
> +
> + QLIST_FOREACH(drv, &tpm_backends, list) {
> + model = drv->model ? drv->model : TPM_DEFAULT_DEVICE_MODEL;
> + monitor_printf(mon, " %s: model=%s,id=%s\n",
> + drv->ops->id, model, drv->id);
> + }
> +}
> +
> +/*
> + * Create those TPMs that were created with -tpm rather than -tpmdev.
> + * The ones created with -tpm have a 'model' name.
> + */
> +void qemu_create_tpm(void)
> +{
> + TPMBackend *drv;
> +
> + QLIST_FOREACH(drv, &tpm_backends, list) {
> + if (drv->model) {
> + if (strcmp(drv->model, TPM_DEFAULT_DEVICE_MODEL) == 0) {
> + isa_create_simple(drv->model);
> + }
> + }
> + }
> +}
> +
> +
> +static int configure_tpm(QemuOpts *opts, int is_tpmdev)
> +{
> + const char *value;
> + const char *id = TPM_DEFAULT_DEVICE_ID;
> + const char *model = NULL;
> + const TPMDriverOps *be;
> + TPMBackend *drv;
> +
> + if (!QLIST_EMPTY(&tpm_backends)) {
> + fprintf(stderr, "Only one TPM is allowed.\n");
> + return 1;
> + }
> +
> + if (is_tpmdev) {
> + id = qemu_opts_id(opts);
> + if (id == NULL) {
> + qerror_report(QERR_MISSING_PARAMETER, "id");
> + return 1;
> + }
> + } else {
> + model = qemu_opt_get(opts, "model");
> + if (model) {
> + if (strcmp(model, "?") == 0) {
> + tpm_display_models(stdout);
> + return 1;
> + }
> + if (!tpm_check_model(model)) {
> + qerror_report(QERR_INVALID_PARAMETER_VALUE, "model",
> + "a tpm model");
> + tpm_display_models(stderr);
> + return 1;
> + }
> + } else {
> + model = TPM_DEFAULT_DEVICE_MODEL;
> + }
> + }
> +
> + value = qemu_opt_get(opts, "type");
> + if (!value) {
> + qerror_report(QERR_MISSING_PARAMETER, "type");
> + tpm_display_backend_drivers(stderr);
> + return 1;
> + }
> +
> + be = tpm_get_backend_driver(value);
> + if (be == NULL) {
> + qerror_report(QERR_INVALID_PARAMETER_VALUE, "type",
> + "a tpm backend type");
> + tpm_display_backend_drivers(stderr);
> + return 1;
> + }
> +
> + assert((is_tpmdev && model == NULL) || (!is_tpmdev && model != NULL));
Why isn't this using qdev for parameter passing?
> +
> + drv = be->create(opts, id, model);
> + if (!drv) {
> + return 1;
> + }
> +
> + QLIST_INSERT_HEAD(&tpm_backends, drv, list);
> +
> + return 0;
> +}
> +
> +
> +static int tpm_init_tpmdev(QemuOpts *opts, void *dummy)
> +{
> + return configure_tpm(opts, 1);
> +}
> +
> +
> +static int tpm_init_tpm(QemuOpts *opts, void *dummy)
> +{
> + return configure_tpm(opts, 0);
> +}
> +
> +
> +int tpm_init(void)
> +{
> + if (qemu_opts_foreach(qemu_find_opts("tpmdev"),
> + tpm_init_tpmdev, NULL, 1) != 0) {
> + return -1;
> + }
> +
> + if (qemu_opts_foreach(qemu_find_opts("tpm"),
> + tpm_init_tpm, NULL, 1) != 0) {
> + return -1;
> + }
> +
> + return 0;
> +}
> +
> +
> +void tpm_cleanup(void)
> +{
> + TPMBackend *drv, *next;
> +
> + QLIST_FOREACH_SAFE(drv, &tpm_backends, list, next) {
> + QLIST_REMOVE(drv, list);
> + drv->ops->destroy(drv);
> + }
> +}
> +
> +
> +void tpm_config_parse(QemuOptsList *opts_list, const char *optarg)
> +{
> + QemuOpts *opts;
> +
> + if (strcmp("none", optarg) != 0) {
> + if (*optarg == '?') {
> + tpm_display_backend_drivers(stdout);
> + exit(0);
> + }
> + opts = qemu_opts_parse(opts_list, optarg, 1);
> + if (!opts) {
> + exit(1);
> + }
> + }
> +}
> +
> +# else /* TARGET_I386 || TARGET_X86_64 */
> +
> +void tpm_config_parse(QemuOptsList *opts_list, const char *optarg)
> +{
> +}
> +
> +int tpm_init(void)
> +{
> + return 0;
> +}
> +
> +void tpm_cleanup(void)
> +{
> +}
> +
> +void do_info_tpm(Monitor *mon)
> +{
> + monitor_printf(mon, "TPM support: not compiled\n");
> +}
> +
> +# endif
> +#endif /* CONFIG_TPM */
> Index: qemu-git/tpm.h
> ===================================================================
> --- /dev/null
> +++ qemu-git/tpm.h
> @@ -0,0 +1,112 @@
> +#ifndef _HW_TPM_CONFIG_H
> +#define _HW_TPM_CONFIG_H
> +
> +struct TPMState;
> +typedef struct TPMState TPMState;
> +
> +#include "hw/tpm_tis.h"
> +
> +struct TPMDriverOps;
> +typedef struct TPMDriverOps TPMDriverOps;
> +
> +typedef struct TPMBackend {
> + char *id;
> + char *model;
> + TPMDriverOps *ops;
> +
> + QLIST_ENTRY(TPMBackend) list;
> +} TPMBackend;
> +
> +
> +/* locality data -- all fields are persisted */
> +typedef struct TPMLocality {
> + enum tis_state state;
> + uint8_t access;
> + uint8_t sts;
> + uint32_t inte;
> + uint32_t ints;
> +
> + uint16_t w_offset;
> + uint16_t r_offset;
> + TPMSizedBuffer w_buffer;
> + TPMSizedBuffer r_buffer;
> +} TPMLocality;
> +
> +
> +/* overall state of the TPM interface */
> +struct TPMState {
> + ISADevice busdev;
> +
> + uint32_t offset;
> + uint8_t buf[TIS_TPM_BUFFER_MAX];
> +
> + uint8_t active_locty;
> + uint8_t aborting_locty;
> + uint8_t next_locty;
> +
> + uint8_t command_locty;
> + TPMLocality loc[NUM_LOCALITIES];
> +
> + qemu_irq irq;
> + uint32_t irq_num;
> +
> + QemuMutex state_lock;
> + QemuCond from_tpm_cond;
> + QemuCond to_tpm_cond;
> + bool to_tpm_execute;
> +
> + bool tpm_initialized;
> +
> + char *backend;
> + TPMBackend *be_driver;
> +};
> +
> +
> +typedef void (TPMRecvDataCB)(TPMState *s, uint8_t locty);
> +
> +struct TPMDriverOps {
> + const char *id;
> + /* get a descriptive text of the backend to display to the user */
> + const char *(*desc)(void);
> +
> + void (*job_for_main_thread)(void *);
> +
> + TPMBackend *(*create)(QemuOpts *, const char *id, const char *model);
> + void (*destroy)(TPMBackend *drv);
> +
> + /* initialize the backend */
> + int (*init)(TPMState *s, TPMRecvDataCB *datacb);
> + /* start up the TPM on the backend early if possible */
> + int (*early_startup_tpm)(void);
> + /* start up the TPM on the backend late if necessary */
> + int (*late_startup_tpm)(void);
> + /* returns true if nothing will ever answer TPM requests */
> + bool (*had_startup_error)(void);
> +
> + size_t (*realloc_buffer)(TPMSizedBuffer *sb);
> +
> + void (*reset)(void);
> +
> + /* called to trigger the saving of the volatile data;
> + called before the VM suspends / migrates */
> + int (*save_volatile_data)(void);
> + /* triggers the loading of the volatile data */
> + int (*load_volatile_data)(TPMState *s);
> +
> + bool (*get_tpm_established_flag)(void);
> +};
> +
> +#define TPM_DEFAULT_DEVICE_ID "tpm0"
> +#define TPM_DEFAULT_DEVICE_MODEL "tpm-tis"
> +
> +void tpm_config_parse(QemuOptsList *opts_list, const char *optarg);
> +int tpm_init(void);
> +void tpm_cleanup(void);
> +void qemu_create_tpm(void);
> +TPMBackend *qemu_find_tpm(const char *id);
> +void do_info_tpm(Monitor *mon);
> +void tpm_display_backend_drivers(FILE *out);
> +const TPMDriverOps *tpm_get_backend_driver(const char *id);
> +
> +
> +#endif /* _HW_TPM_CONFIG_H */
> Index: qemu-git/hw/pc.c
> ===================================================================
> --- qemu-git.orig/hw/pc.c
> +++ qemu-git/hw/pc.c
> @@ -43,6 +43,7 @@
> #include "ui/qemu-spice.h"
> #include "memory.h"
> #include "exec-memory.h"
> +#include "tpm.h"
>
> /* output Bochs bios info messages */
> //#define DEBUG_BIOS
> @@ -62,7 +63,7 @@
> #define PC_MAX_BIOS_SIZE (4 * 1024 * 1024)
>
> /* Leave a chunk of memory at the top of RAM for the BIOS ACPI tables. */
> -#define ACPI_DATA_SIZE 0x10000
> +#define ACPI_DATA_SIZE 0x20000
> #define BIOS_CFG_IOPORT 0x510
> #define FW_CFG_ACPI_TABLES (FW_CFG_ARCH_LOCAL + 0)
> #define FW_CFG_SMBIOS_ENTRIES (FW_CFG_ARCH_LOCAL + 1)
> @@ -1183,6 +1184,10 @@ void pc_basic_device_init(qemu_irq *isa_
> fd[i] = drive_get(IF_FLOPPY, 0, i);
> }
> fdctrl_init_isa(fd);
> +
> +#ifdef CONFIG_TPM
> + qemu_create_tpm();
> +#endif
> }
>
> void pc_pci_device_init(PCIBus *pci_bus)
> Index: qemu-git/monitor.c
> ===================================================================
> --- qemu-git.orig/monitor.c
> +++ qemu-git/monitor.c
> @@ -47,6 +47,7 @@
> #include "migration.h"
> #include "kvm.h"
> #include "acl.h"
> +#include "tpm.h"
> #include "qint.h"
> #include "qfloat.h"
> #include "qlist.h"
> @@ -3151,6 +3152,15 @@ static const mon_cmd_t info_cmds[] = {
> .mhandler.info = do_info_trace_events,
> },
> #endif
> +#if defined(CONFIG_TPM)
> + {
> + .name = "tpm",
> + .args_type = "",
> + .params = "",
> + .help = "show the TPM devices",
> + .mhandler.info = do_info_tpm,
> + },
> +#endif
> {
> .name = NULL,
> },
> Index: qemu-git/hmp-commands.hx
> ===================================================================
> --- qemu-git.orig/hmp-commands.hx
> +++ qemu-git/hmp-commands.hx
> @@ -1351,6 +1351,8 @@ show device tree
> show qdev device model list
> @item info roms
> show roms
> address@hidden info tpm
> +show the TPM devices
> @end table
> ETEXI
>
> Index: qemu-git/Makefile.target
> ===================================================================
> --- qemu-git.orig/Makefile.target
> +++ qemu-git/Makefile.target
> @@ -200,6 +200,7 @@ obj-$(CONFIG_KVM) += kvm.o kvm-all.o
> obj-$(CONFIG_NO_KVM) += kvm-stub.o
> obj-y += memory.o
> LIBS+=-lz
> +obj-y += tpm.o
>
> QEMU_CFLAGS += $(VNC_TLS_CFLAGS)
> QEMU_CFLAGS += $(VNC_SASL_CFLAGS)
>
- Re: [Qemu-devel] [PATCH V8 01/14] Support for TPM command line options,
Michael S. Tsirkin <=