From patchwork Wed Mar 30 19:42:12 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Berger X-Patchwork-Id: 88957 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) by ozlabs.org (Postfix) with ESMTP id 9C39EB6EF0 for ; Thu, 31 Mar 2011 06:54:03 +1100 (EST) Received: from localhost ([127.0.0.1]:43689 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Q51Mo-0006ot-Nx for incoming@patchwork.ozlabs.org; Wed, 30 Mar 2011 15:47:46 -0400 Received: from [140.186.70.92] (port=34552 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Q51I5-0004wA-5C for qemu-devel@nongnu.org; Wed, 30 Mar 2011 15:42:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Q51I2-0005iF-Cy for qemu-devel@nongnu.org; Wed, 30 Mar 2011 15:42:53 -0400 Received: from e35.co.us.ibm.com ([32.97.110.153]:53678) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Q51I2-0005i2-3j for qemu-devel@nongnu.org; Wed, 30 Mar 2011 15:42:50 -0400 Received: from d03relay03.boulder.ibm.com (d03relay03.boulder.ibm.com [9.17.195.228]) by e35.co.us.ibm.com (8.14.4/8.13.1) with ESMTP id p2UJRClx005624 for ; Wed, 30 Mar 2011 13:27:13 -0600 Received: from d03av02.boulder.ibm.com (d03av02.boulder.ibm.com [9.17.195.168]) by d03relay03.boulder.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id p2UJgmqJ106240 for ; Wed, 30 Mar 2011 13:42:48 -0600 Received: from d03av02.boulder.ibm.com (loopback [127.0.0.1]) by d03av02.boulder.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p2UJgjic021881 for ; Wed, 30 Mar 2011 13:42:47 -0600 Received: from localhost6.localdomain6 (d941e-10.watson.ibm.com [9.59.241.154]) by d03av02.boulder.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id p2UJgaaj020455 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Wed, 30 Mar 2011 13:42:36 -0600 Received: from localhost6.localdomain6 (localhost.localdomain [127.0.0.1]) by localhost6.localdomain6 (8.14.4/8.14.3) with ESMTP id p2UJgaDT016952; Wed, 30 Mar 2011 15:42:36 -0400 Received: (from root@localhost) by localhost6.localdomain6 (8.14.4/8.14.4/Submit) id p2UJgZJ1016951; Wed, 30 Mar 2011 15:42:35 -0400 Message-Id: <20110330194235.935788784@linux.vnet.ibm.com> User-Agent: quilt/0.48-1 Date: Wed, 30 Mar 2011 15:42:12 -0400 From: Stefan Berger To: stefanb@linux.vnet.ibm.com, qemu-devel@nongnu.org References: <20110330194211.732385449@linux.vnet.ibm.com> Content-Disposition: inline; filename=qemu_tpm.diff X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6, seldom 2.4 (older, 4) X-Received-From: 32.97.110.153 Cc: andreas.niederl@iaik.tugraz.at Subject: [Qemu-devel] [PATCH V2 1/9] Support for TPM command line options X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org This patch adds support for TPM command line options. The command line supported here (considering the libtpms based backend) are ./qemu-... -tpm type=,path=, and ./qemu-... -tpm ? where the latter works similar to -soundhw ? and shows a list of available TPM backends (i.e., libtpms-based, Xen). Only the 'type' is interpreted in arch_init.c. Using this 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 'handle_options' and return true if the VM can be started or 'false' if not enough or bad parameters were provided. Signed-off-by: Stefan Berger --- arch_init.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ arch_init.h | 2 + hw/pc.h | 7 +++++ qemu-config.c | 20 ++++++++++++++ qemu-options.hx | 11 ++++++++ vl.c | 11 ++++++++ 6 files changed, 128 insertions(+) Index: qemu-git/hw/pc.h =================================================================== --- qemu-git.orig/hw/pc.h +++ qemu-git/hw/pc.h @@ -6,6 +6,7 @@ #include "isa.h" #include "fdc.h" #include "net.h" +#include "tpm_tis.h" /* PC-style peripherals (also used by other machines). */ @@ -128,6 +129,12 @@ void pc_register_ferr_irq(qemu_irq irq); void pc_cmos_set_s3_resume(void *opaque, int irq, int level); void pc_acpi_smi_interrupt(void *opaque, int irq, int level); +/* tpm_tis.c */ +extern bool has_tpm; +const BackendTPMDriver *tis_set_backend_driver(const char *tpm_type); +void tis_display_backend_drivers(FILE *); + + void pc_cpus_init(const char *cpu_model); void pc_memory_init(ram_addr_t ram_size, const char *kernel_filename, Index: qemu-git/qemu-options.hx =================================================================== --- qemu-git.orig/qemu-options.hx +++ qemu-git/qemu-options.hx @@ -1041,6 +1041,17 @@ Specify SMBIOS type 0 fields Specify SMBIOS type 1 fields ETEXI +#ifndef _WIN32 +# ifdef CONFIG_TPM +DEF("tpm", HAS_ARG, QEMU_OPTION_tpm, \ + "" + "-tpm type=,path=\n" \ + " enable a TPM with state from file in given path\n" + " use -tpm ? to get a list of supported TPM types\n", + QEMU_ARCH_I386) +# endif +#endif + DEFHEADING() STEXI @end table Index: qemu-git/vl.c =================================================================== --- qemu-git.orig/vl.c +++ qemu-git/vl.c @@ -244,6 +244,8 @@ int nb_numa_nodes; uint64_t node_mem[MAX_NODES]; uint64_t node_cpumask[MAX_NODES]; +bool has_tpm = false; + static QEMUTimer *nographic_timer; uint8_t qemu_uuid[16]; @@ -2420,6 +2422,15 @@ int main(int argc, char **argv, char **e ram_size = value; break; } +#ifdef CONFIG_TPM + case QEMU_OPTION_tpm: + if (!(tpm_available())) { + printf("Option %s not supported for this target\n", popt->name); + exit(1); + } + select_tpm(optarg); + break; +#endif case QEMU_OPTION_mempath: mem_path = optarg; break; Index: qemu-git/qemu-config.c =================================================================== --- qemu-git.orig/qemu-config.c +++ qemu-git/qemu-config.c @@ -451,6 +451,25 @@ QemuOptsList qemu_option_rom_opts = { }, }; +static QemuOptsList qemu_tpm_opts = { + .name = "tpm", + .head = QTAILQ_HEAD_INITIALIZER(qemu_tpm_opts.head), + .desc = { + { + .name = "type", + .type = QEMU_OPT_STRING, + .help = "Type of TPM backend", + }, + { + .name = "path", + .type = QEMU_OPT_STRING, + .help = "Persitent storage for TPM state", + }, + { /* end of list */ } + }, +}; + + static QemuOptsList *vm_config_groups[32] = { &qemu_drive_opts, &qemu_chardev_opts, @@ -465,6 +484,7 @@ static QemuOptsList *vm_config_groups[32 &qemu_trace_opts, #endif &qemu_option_rom_opts, + &qemu_tpm_opts, NULL, }; Index: qemu-git/arch_init.c =================================================================== --- qemu-git.orig/arch_init.c +++ qemu-git/arch_init.c @@ -41,6 +41,8 @@ #include "net.h" #include "gdbstub.h" #include "hw/smbios.h" +#include "blockdev.h" +#include "hw/tpm_tis.h" #ifdef TARGET_SPARC int graphic_width = 1024; @@ -726,3 +728,78 @@ int xen_available(void) return 0; #endif } + +int tpm_available(void) { +#ifdef CONFIG_TPM + return 1; +#else + return 0; +#endif +} + +#ifdef CONFIG_TPM + +#if defined (TARGET_I386) || defined (TARGET_X86_64) + + +static int configure_tpm(QemuOpts *opts) +{ + const char *value; + const BackendTPMDriver *be; + + if (has_tpm) { + fprintf(stderr,"Only one TPM is allowed\n"); + return 1; + } + + value = qemu_opt_get(opts, "type"); + if (!value) { + fprintf(stderr, + "Missing TPM backend type."); + tis_display_backend_drivers(stderr); + return 1; + } + + be = tis_set_backend_driver(value); + if (be == NULL) { + fprintf(stderr, + "A TPM backend driver of type %s is not supported.\n", + value); + tis_display_backend_drivers(stderr); + return 1; + } + + has_tpm = be->handle_options(opts); + if (!has_tpm) + return 1; + + return 0; +} + + +void select_tpm(const char *optarg) +{ + QemuOpts *opts; + + if (strcmp("none", optarg) != 0) { + if (*optarg == '?') { + tis_display_backend_drivers(stdout); + exit(0); + } + opts = qemu_opts_parse(qemu_find_opts("tpm"), optarg, 0); + if (!opts) + exit(1); + if (configure_tpm(opts)) + exit(1); + } +} + +# else /* CONFIG_TPM */ + +void select_tpm(const char *optarg) +{ + (void)optarg; +} + +# endif +#endif /* CONFIG_TPM */ Index: qemu-git/arch_init.h =================================================================== --- qemu-git.orig/arch_init.h +++ qemu-git/arch_init.h @@ -31,5 +31,7 @@ int audio_available(void); void audio_init(qemu_irq *isa_pic, PCIBus *pci_bus); int kvm_available(void); int xen_available(void); +int tpm_available(void); +void select_tpm(const char *optarg); #endif