From: James Bottomley <James.Bottomley@HansenPartnership.com>
Instead of processing the tpmdev options using the old qemu options,
convert to the new visitor format which also allows the passing of
json on the command line.
Signed-off-by: James Bottomley <jejb@linux.ibm.com>
---
v4: add TpmConfiOptions
v5: exit(0) for help
---
backends/tpm/tpm_emulator.c | 24 ++++-----
backends/tpm/tpm_passthrough.c | 22 +++------
include/sysemu/tpm.h | 4 +-
include/sysemu/tpm_backend.h | 2 +-
qapi/tpm.json | 19 +++++++
softmmu/tpm.c | 90 ++++++++++++++--------------------
softmmu/vl.c | 19 +------
7 files changed, 75 insertions(+), 105 deletions(-)
diff --git a/backends/tpm/tpm_emulator.c b/backends/tpm/tpm_emulator.c
index 49cc3d749d..cb6bf9d7c2 100644
--- a/backends/tpm/tpm_emulator.c
+++ b/backends/tpm/tpm_emulator.c
@@ -584,33 +584,28 @@ err_exit:
return -1;
}
-static int tpm_emulator_handle_device_opts(TPMEmulator *tpm_emu, QemuOpts *opts)
+static int tpm_emulator_handle_device_opts(TPMEmulator *tpm_emu, TpmCreateOptions *opts)
{
- const char *value;
Error *err = NULL;
Chardev *dev;
- value = qemu_opt_get(opts, "chardev");
- if (!value) {
- error_report("tpm-emulator: parameter 'chardev' is missing");
- goto err;
- }
+ tpm_emu->options = QAPI_CLONE(TPMEmulatorOptions, &opts->u.emulator);
+ tpm_emu->data_ioc = NULL;
- dev = qemu_chr_find(value);
+ dev = qemu_chr_find(opts->u.emulator.chardev);
if (!dev) {
- error_report("tpm-emulator: tpm chardev '%s' not found", value);
+ error_report("tpm-emulator: tpm chardev '%s' not found",
+ opts->u.emulator.chardev);
goto err;
}
if (!qemu_chr_fe_init(&tpm_emu->ctrl_chr, dev, &err)) {
error_prepend(&err, "tpm-emulator: No valid chardev found at '%s':",
- value);
+ opts->u.emulator.chardev);
error_report_err(err);
goto err;
}
- tpm_emu->options->chardev = g_strdup(value);
-
if (tpm_emulator_prepare_data_fd(tpm_emu) < 0) {
goto err;
}
@@ -649,7 +644,7 @@ err:
return -1;
}
-static TPMBackend *tpm_emulator_create(QemuOpts *opts)
+static TPMBackend *tpm_emulator_create(TpmCreateOptions *opts)
{
TPMBackend *tb = TPM_BACKEND(object_new(TYPE_TPM_EMULATOR));
@@ -972,7 +967,6 @@ static void tpm_emulator_inst_init(Object *obj)
trace_tpm_emulator_inst_init();
- tpm_emu->options = g_new0(TPMEmulatorOptions, 1);
tpm_emu->cur_locty_number = ~0;
qemu_mutex_init(&tpm_emu->mutex);
tpm_emu->vmstate =
@@ -990,7 +984,7 @@ static void tpm_emulator_shutdown(TPMEmulator *tpm_emu)
{
ptm_res res;
- if (!tpm_emu->options->chardev) {
+ if (!tpm_emu->data_ioc) {
/* was never properly initialized */
return;
}
diff --git a/backends/tpm/tpm_passthrough.c b/backends/tpm/tpm_passthrough.c
index 179697a3a9..3da467ef01 100644
--- a/backends/tpm/tpm_passthrough.c
+++ b/backends/tpm/tpm_passthrough.c
@@ -252,21 +252,12 @@ static int tpm_passthrough_open_sysfs_cancel(TPMPassthruState *tpm_pt)
}
static int
-tpm_passthrough_handle_device_opts(TPMPassthruState *tpm_pt, QemuOpts *opts)
+tpm_passthrough_handle_device_opts(TPMPassthruState *tpm_pt, TpmCreateOptions *opts)
{
- const char *value;
+ tpm_pt->options = QAPI_CLONE(TPMPassthroughOptions, &opts->u.passthrough);
- value = qemu_opt_get(opts, "cancel-path");
- if (value) {
- tpm_pt->options->cancel_path = g_strdup(value);
- }
-
- value = qemu_opt_get(opts, "path");
- if (value) {
- tpm_pt->options->path = g_strdup(value);
- }
-
- tpm_pt->tpm_dev = value ? value : TPM_PASSTHROUGH_DEFAULT_DEVICE;
+ tpm_pt->tpm_dev = opts->u.passthrough.path ? opts->u.passthrough.path :
+ TPM_PASSTHROUGH_DEFAULT_DEVICE;
tpm_pt->tpm_fd = qemu_open_old(tpm_pt->tpm_dev, O_RDWR);
if (tpm_pt->tpm_fd < 0) {
error_report("Cannot access TPM device using '%s': %s",
@@ -288,11 +279,11 @@ tpm_passthrough_handle_device_opts(TPMPassthruState *tpm_pt, QemuOpts *opts)
return 0;
}
-static TPMBackend *tpm_passthrough_create(QemuOpts *opts)
+static TPMBackend *tpm_passthrough_create(TpmCreateOptions *tco)
{
Object *obj = object_new(TYPE_TPM_PASSTHROUGH);
- if (tpm_passthrough_handle_device_opts(TPM_PASSTHROUGH(obj), opts)) {
+ if (tpm_passthrough_handle_device_opts(TPM_PASSTHROUGH(obj), tco)) {
object_unref(obj);
return NULL;
}
@@ -344,7 +335,6 @@ static void tpm_passthrough_inst_init(Object *obj)
{
TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(obj);
- tpm_pt->options = g_new0(TPMPassthroughOptions, 1);
tpm_pt->tpm_fd = -1;
tpm_pt->cancel_fd = -1;
}
diff --git a/include/sysemu/tpm.h b/include/sysemu/tpm.h
index fb40e30ff6..d00a833a21 100644
--- a/include/sysemu/tpm.h
+++ b/include/sysemu/tpm.h
@@ -17,8 +17,8 @@
#ifdef CONFIG_TPM
-int tpm_config_parse(QemuOptsList *opts_list, const char *optarg);
-int tpm_init(void);
+void tpm_config_parse(const char *optarg);
+void tpm_init(void);
void tpm_cleanup(void);
typedef enum TPMVersion {
diff --git a/include/sysemu/tpm_backend.h b/include/sysemu/tpm_backend.h
index 8fd3269c11..846a9e39fa 100644
--- a/include/sysemu/tpm_backend.h
+++ b/include/sysemu/tpm_backend.h
@@ -57,7 +57,7 @@ struct TPMBackendClass {
/* get a descriptive text of the backend to display to the user */
const char *desc;
- TPMBackend *(*create)(QemuOpts *opts);
+ TPMBackend *(*create)(TpmCreateOptions *tco);
/* start up the TPM on the backend - optional */
int (*startup_tpm)(TPMBackend *t, size_t buffersize);
diff --git a/qapi/tpm.json b/qapi/tpm.json
index 4e2ea9756a..2b491c28b4 100644
--- a/qapi/tpm.json
+++ b/qapi/tpm.json
@@ -134,6 +134,25 @@
'emulator': 'TPMEmulatorOptionsWrapper' },
'if': 'CONFIG_TPM' }
+##
+# @TpmCreateOptions:
+#
+# A union referencing different TPM backend types' configuration options
+# without the wrapper to be usable by visitors.
+#
+# @type: - 'passthrough' The configuration options for the TPM passthrough type
+# - 'emulator' The configuration options for TPM emulator backend type
+#
+# Since: 7.2
+##
+{ 'union': 'TpmCreateOptions',
+ 'base': { 'type': 'TpmType',
+ 'id' : 'str' },
+ 'discriminator': 'type',
+ 'data': { 'passthrough' : 'TPMPassthroughOptions',
+ 'emulator': 'TPMEmulatorOptions' },
+ 'if': 'CONFIG_TPM' }
+
##
# @TPMInfo:
#
diff --git a/softmmu/tpm.c b/softmmu/tpm.c
index 578563f05a..fa84a53b96 100644
--- a/softmmu/tpm.c
+++ b/softmmu/tpm.c
@@ -17,14 +17,26 @@
#include "qapi/error.h"
#include "qapi/qapi-commands-tpm.h"
#include "qapi/qmp/qerror.h"
+#include "qapi/qobject-input-visitor.h"
+#include "qapi/qapi-visit-tpm.h"
#include "sysemu/tpm_backend.h"
#include "sysemu/tpm.h"
#include "qemu/config-file.h"
#include "qemu/error-report.h"
+#include "qemu/help_option.h"
static QLIST_HEAD(, TPMBackend) tpm_backends =
QLIST_HEAD_INITIALIZER(tpm_backends);
+typedef struct TpmCreateOptionsQueueEntry {
+ TpmCreateOptions *tco;
+ QSIMPLEQ_ENTRY(TpmCreateOptionsQueueEntry) entry;
+} TpmCreateOptionsQueueEntry;
+
+typedef QSIMPLEQ_HEAD(, TpmCreateOptionsQueueEntry) TpmCreateOptionsQueue;
+
+static TpmCreateOptionsQueue tco_queue = QSIMPLEQ_HEAD_INITIALIZER(tco_queue);
+
static const TPMBackendClass *
tpm_be_find_by_type(enum TpmType type)
{
@@ -84,63 +96,31 @@ TPMBackend *qemu_find_tpm_be(const char *id)
return NULL;
}
-static int tpm_init_tpmdev(void *dummy, QemuOpts *opts, Error **errp)
+static void tpm_init_tpmdev(TpmCreateOptions *tco)
{
- /*
- * Use of error_report() in a function with an Error ** parameter
- * is suspicious. It is okay here. The parameter only exists to
- * make the function usable with qemu_opts_foreach(). It is not
- * actually used.
- */
- const char *value;
- const char *id;
const TPMBackendClass *be;
TPMBackend *drv;
- Error *local_err = NULL;
- int i;
if (!QLIST_EMPTY(&tpm_backends)) {
error_report("Only one TPM is allowed.");
- return 1;
+ exit(1);
}
- id = qemu_opts_id(opts);
- if (id == NULL) {
- error_report(QERR_MISSING_PARAMETER, "id");
- return 1;
- }
-
- value = qemu_opt_get(opts, "type");
- if (!value) {
- error_report(QERR_MISSING_PARAMETER, "type");
- tpm_display_backend_drivers();
- return 1;
- }
-
- i = qapi_enum_parse(&TpmType_lookup, value, -1, NULL);
- be = i >= 0 ? tpm_be_find_by_type(i) : NULL;
+ be = tco->type >= 0 ? tpm_be_find_by_type(tco->type) : NULL;
if (be == NULL) {
error_report(QERR_INVALID_PARAMETER_VALUE,
"type", "a TPM backend type");
tpm_display_backend_drivers();
- return 1;
- }
-
- /* validate backend specific opts */
- if (!qemu_opts_validate(opts, be->opts, &local_err)) {
- error_report_err(local_err);
- return 1;
+ exit(1);
}
- drv = be->create(opts);
+ drv = be->create(tco);
if (!drv) {
- return 1;
+ exit(1);
}
- drv->id = g_strdup(id);
+ drv->id = g_strdup(tco->id);
QLIST_INSERT_HEAD(&tpm_backends, drv, list);
-
- return 0;
}
/*
@@ -161,33 +141,35 @@ void tpm_cleanup(void)
* Initialize the TPM. Process the tpmdev command line options describing the
* TPM backend.
*/
-int tpm_init(void)
+void tpm_init(void)
{
- if (qemu_opts_foreach(qemu_find_opts("tpmdev"),
- tpm_init_tpmdev, NULL, NULL)) {
- return -1;
- }
+ while (!QSIMPLEQ_EMPTY(&tco_queue)) {
+ TpmCreateOptionsQueueEntry *tcoqe = QSIMPLEQ_FIRST(&tco_queue);
- return 0;
+ QSIMPLEQ_REMOVE_HEAD(&tco_queue, entry);
+ tpm_init_tpmdev(tcoqe->tco);
+ g_free(tcoqe);
+ }
}
/*
* Parse the TPM configuration options.
* To display all available TPM backends the user may use '-tpmdev help'
*/
-int tpm_config_parse(QemuOptsList *opts_list, const char *optarg)
+void tpm_config_parse(const char *optarg)
{
- QemuOpts *opts;
+ Visitor *v;
+ TpmCreateOptionsQueueEntry *tcqe;
- if (!strcmp(optarg, "help")) {
+ if (is_help_option(optarg)) {
tpm_display_backend_drivers();
- return -1;
- }
- opts = qemu_opts_parse_noisily(opts_list, optarg, true);
- if (!opts) {
- return -1;
+ exit(0);
}
- return 0;
+ v = qobject_input_visitor_new_str(optarg, "type", &error_fatal);
+ tcqe = g_new(TpmCreateOptionsQueueEntry, 1);
+ visit_type_TpmCreateOptions(v, NULL, &tcqe->tco, &error_fatal);
+ visit_free(v);
+ QSIMPLEQ_INSERT_TAIL(&tco_queue, tcqe, entry);
}
/*
diff --git a/softmmu/vl.c b/softmmu/vl.c
index 798e1dc933..8c2655dbc2 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -328,16 +328,6 @@ static QemuOptsList qemu_object_opts = {
},
};
-static QemuOptsList qemu_tpmdev_opts = {
- .name = "tpmdev",
- .implied_opt_name = "type",
- .head = QTAILQ_HEAD_INITIALIZER(qemu_tpmdev_opts.head),
- .desc = {
- /* options are defined in the TPM backends */
- { /* end of list */ }
- },
-};
-
static QemuOptsList qemu_overcommit_opts = {
.name = "overcommit",
.head = QTAILQ_HEAD_INITIALIZER(qemu_overcommit_opts.head),
@@ -1934,9 +1924,7 @@ static void qemu_create_late_backends(void)
object_option_foreach_add(object_create_late);
- if (tpm_init() < 0) {
- exit(1);
- }
+ tpm_init();
qemu_opts_foreach(qemu_find_opts("mon"),
mon_init_func, NULL, &error_fatal);
@@ -2658,7 +2646,6 @@ void qemu_init(int argc, char **argv)
qemu_add_opts(&qemu_boot_opts);
qemu_add_opts(&qemu_add_fd_opts);
qemu_add_opts(&qemu_object_opts);
- qemu_add_opts(&qemu_tpmdev_opts);
qemu_add_opts(&qemu_overcommit_opts);
qemu_add_opts(&qemu_msg_opts);
qemu_add_opts(&qemu_name_opts);
@@ -2906,9 +2893,7 @@ void qemu_init(int argc, char **argv)
break;
#ifdef CONFIG_TPM
case QEMU_OPTION_tpmdev:
- if (tpm_config_parse(qemu_find_opts("tpmdev"), optarg) < 0) {
- exit(1);
- }
+ tpm_config_parse(optarg);
break;
#endif
case QEMU_OPTION_mempath:
--
2.35.3
On 1/9/23 11:15, James Bottomley wrote:
> From: James Bottomley <James.Bottomley@HansenPartnership.com>
>
> Instead of processing the tpmdev options using the old qemu options,
> convert to the new visitor format which also allows the passing of
> json on the command line.
>
> Signed-off-by: James Bottomley <jejb@linux.ibm.com>
$ ./scripts/checkpatch.pl
0001-tpm-convert-tpmdev-options-processing-to-new-visitor.patch
WARNING: line over 80 characters
#30: FILE: backends/tpm/tpm_emulator.c:586:
+static int tpm_emulator_handle_device_opts(TPMEmulator *tpm_emu,
TpmCreateOptions *opts)
WARNING: line over 80 characters
#101: FILE: backends/tpm/tpm_passthrough.c:255:
+tpm_passthrough_handle_device_opts(TPMPassthruState *tpm_pt,
TpmCreateOptions *opts)
total: 0 errors, 2 warnings, 340 lines checked
> ---
> v4: add TpmConfiOptions
> v5: exit(0) for help
> ---
> backends/tpm/tpm_emulator.c | 24 ++++-----
> backends/tpm/tpm_passthrough.c | 22 +++------
> include/sysemu/tpm.h | 4 +-
> include/sysemu/tpm_backend.h | 2 +-
> qapi/tpm.json | 19 +++++++
> softmmu/tpm.c | 90 ++++++++++++++--------------------
> softmmu/vl.c | 19 +------
> 7 files changed, 75 insertions(+), 105 deletions(-)
>
> diff --git a/backends/tpm/tpm_emulator.c b/backends/tpm/tpm_emulator.c
> index 49cc3d749d..cb6bf9d7c2 100644
> --- a/backends/tpm/tpm_emulator.c
> +++ b/backends/tpm/tpm_emulator.c
> @@ -584,33 +584,28 @@ err_exit:
> return -1;
> }
>
> -static int tpm_emulator_handle_device_opts(TPMEmulator *tpm_emu, QemuOpts *opts)
> +static int tpm_emulator_handle_device_opts(TPMEmulator *tpm_emu, TpmCreateOptions *opts)
> {
> - const char *value;
> Error *err = NULL;
> Chardev *dev;
>
> - value = qemu_opt_get(opts, "chardev");
> - if (!value) {
> - error_report("tpm-emulator: parameter 'chardev' is missing");
> - goto err;
> - }
> + tpm_emu->options = QAPI_CLONE(TPMEmulatorOptions, &opts->u.emulator);
> + tpm_emu->data_ioc = NULL;
>
> - dev = qemu_chr_find(value);
> + dev = qemu_chr_find(opts->u.emulator.chardev);
> if (!dev) {
> - error_report("tpm-emulator: tpm chardev '%s' not found", value);
> + error_report("tpm-emulator: tpm chardev '%s' not found",
> + opts->u.emulator.chardev);
indentation
> goto err;
> }
>
> if (!qemu_chr_fe_init(&tpm_emu->ctrl_chr, dev, &err)) {
> error_prepend(&err, "tpm-emulator: No valid chardev found at '%s':",
> - value);
> + opts->u.emulator.chardev);
> error_report_err(err);
> goto err;
> }
>
> - tpm_emu->options->chardev = g_strdup(value);
> -
> if (tpm_emulator_prepare_data_fd(tpm_emu) < 0) {
> goto err;
> }
> @@ -649,7 +644,7 @@ err:
> return -1;
> }
>
> -static TPMBackend *tpm_emulator_create(QemuOpts *opts)
> +static TPMBackend *tpm_emulator_create(TpmCreateOptions *opts)
> {
> TPMBackend *tb = TPM_BACKEND(object_new(TYPE_TPM_EMULATOR));
>
> @@ -972,7 +967,6 @@ static void tpm_emulator_inst_init(Object *obj)
>
> trace_tpm_emulator_inst_init();
>
> - tpm_emu->options = g_new0(TPMEmulatorOptions, 1);
> tpm_emu->cur_locty_number = ~0;
> qemu_mutex_init(&tpm_emu->mutex);
> tpm_emu->vmstate =
> @@ -990,7 +984,7 @@ static void tpm_emulator_shutdown(TPMEmulator *tpm_emu)
> {
> ptm_res res;
>
> - if (!tpm_emu->options->chardev) {
> + if (!tpm_emu->data_ioc) {
> /* was never properly initialized */
> return;
> }
> diff --git a/backends/tpm/tpm_passthrough.c b/backends/tpm/tpm_passthrough.c
> index 179697a3a9..3da467ef01 100644
> --- a/backends/tpm/tpm_passthrough.c
> +++ b/backends/tpm/tpm_passthrough.c
> @@ -252,21 +252,12 @@ static int tpm_passthrough_open_sysfs_cancel(TPMPassthruState *tpm_pt)
> }
>
> static int
> -tpm_passthrough_handle_device_opts(TPMPassthruState *tpm_pt, QemuOpts *opts)
> +tpm_passthrough_handle_device_opts(TPMPassthruState *tpm_pt, TpmCreateOptions *opts)
> {
> - const char *value;
> + tpm_pt->options = QAPI_CLONE(TPMPassthroughOptions, &opts->u.passthrough);
>
> - value = qemu_opt_get(opts, "cancel-path");
> - if (value) {
> - tpm_pt->options->cancel_path = g_strdup(value);
> - }
> -
> - value = qemu_opt_get(opts, "path");
> - if (value) {
> - tpm_pt->options->path = g_strdup(value);
> - }
> -
> - tpm_pt->tpm_dev = value ? value : TPM_PASSTHROUGH_DEFAULT_DEVICE;
> + tpm_pt->tpm_dev = opts->u.passthrough.path ? opts->u.passthrough.path :
> + TPM_PASSTHROUGH_DEFAULT_DEVICE;
> tpm_pt->tpm_fd = qemu_open_old(tpm_pt->tpm_dev, O_RDWR);
> if (tpm_pt->tpm_fd < 0) {
> error_report("Cannot access TPM device using '%s': %s",
> @@ -288,11 +279,11 @@ tpm_passthrough_handle_device_opts(TPMPassthruState *tpm_pt, QemuOpts *opts)
> return 0;
> }
>
> -static TPMBackend *tpm_passthrough_create(QemuOpts *opts)
> +static TPMBackend *tpm_passthrough_create(TpmCreateOptions *tco)
> {
> Object *obj = object_new(TYPE_TPM_PASSTHROUGH);
>
> - if (tpm_passthrough_handle_device_opts(TPM_PASSTHROUGH(obj), opts)) {
> + if (tpm_passthrough_handle_device_opts(TPM_PASSTHROUGH(obj), tco)) {
> object_unref(obj);
> return NULL;
> }
> @@ -344,7 +335,6 @@ static void tpm_passthrough_inst_init(Object *obj)
> {
> TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(obj);
>
> - tpm_pt->options = g_new0(TPMPassthroughOptions, 1);
> tpm_pt->tpm_fd = -1;
> tpm_pt->cancel_fd = -1;
> }
> diff --git a/include/sysemu/tpm.h b/include/sysemu/tpm.h
> index fb40e30ff6..d00a833a21 100644
> --- a/include/sysemu/tpm.h
> +++ b/include/sysemu/tpm.h
> @@ -17,8 +17,8 @@
>
> #ifdef CONFIG_TPM
>
> -int tpm_config_parse(QemuOptsList *opts_list, const char *optarg);
> -int tpm_init(void);
> +void tpm_config_parse(const char *optarg);
> +void tpm_init(void);
> void tpm_cleanup(void);
>
> typedef enum TPMVersion {
> diff --git a/include/sysemu/tpm_backend.h b/include/sysemu/tpm_backend.h
> index 8fd3269c11..846a9e39fa 100644
> --- a/include/sysemu/tpm_backend.h
> +++ b/include/sysemu/tpm_backend.h
> @@ -57,7 +57,7 @@ struct TPMBackendClass {
> /* get a descriptive text of the backend to display to the user */
> const char *desc;
>
> - TPMBackend *(*create)(QemuOpts *opts);
> + TPMBackend *(*create)(TpmCreateOptions *tco);
>
> /* start up the TPM on the backend - optional */
> int (*startup_tpm)(TPMBackend *t, size_t buffersize);
> diff --git a/qapi/tpm.json b/qapi/tpm.json
> index 4e2ea9756a..2b491c28b4 100644
> --- a/qapi/tpm.json
> +++ b/qapi/tpm.json
> @@ -134,6 +134,25 @@
> 'emulator': 'TPMEmulatorOptionsWrapper' },
> 'if': 'CONFIG_TPM' }
>
> +##
> +# @TpmCreateOptions:
> +#
> +# A union referencing different TPM backend types' configuration options
> +# without the wrapper to be usable by visitors.
> +#
> +# @type: - 'passthrough' The configuration options for the TPM passthrough type
> +# - 'emulator' The configuration options for TPM emulator backend type
> +#
> +# Since: 7.2
> +##
> +{ 'union': 'TpmCreateOptions',
> + 'base': { 'type': 'TpmType',
> + 'id' : 'str' },
> + 'discriminator': 'type',
> + 'data': { 'passthrough' : 'TPMPassthroughOptions',
> + 'emulator': 'TPMEmulatorOptions' },
> + 'if': 'CONFIG_TPM' }
> +
> ##
> # @TPMInfo:
> #
> diff --git a/softmmu/tpm.c b/softmmu/tpm.c
> index 578563f05a..fa84a53b96 100644
> --- a/softmmu/tpm.c
> +++ b/softmmu/tpm.c
> @@ -17,14 +17,26 @@
> #include "qapi/error.h"
> #include "qapi/qapi-commands-tpm.h"
> #include "qapi/qmp/qerror.h"
> +#include "qapi/qobject-input-visitor.h"
> +#include "qapi/qapi-visit-tpm.h"
> #include "sysemu/tpm_backend.h"
> #include "sysemu/tpm.h"
> #include "qemu/config-file.h"
> #include "qemu/error-report.h"
> +#include "qemu/help_option.h"
>
> static QLIST_HEAD(, TPMBackend) tpm_backends =
> QLIST_HEAD_INITIALIZER(tpm_backends);
>
> +typedef struct TpmCreateOptionsQueueEntry {
> + TpmCreateOptions *tco;
> + QSIMPLEQ_ENTRY(TpmCreateOptionsQueueEntry) entry;
> +} TpmCreateOptionsQueueEntry;
> +
> +typedef QSIMPLEQ_HEAD(, TpmCreateOptionsQueueEntry) TpmCreateOptionsQueue;
> +
> +static TpmCreateOptionsQueue tco_queue = QSIMPLEQ_HEAD_INITIALIZER(tco_queue);
> +
> static const TPMBackendClass *
> tpm_be_find_by_type(enum TpmType type)
> {
> @@ -84,63 +96,31 @@ TPMBackend *qemu_find_tpm_be(const char *id)
> return NULL;
> }
>
> -static int tpm_init_tpmdev(void *dummy, QemuOpts *opts, Error **errp)
> +static void tpm_init_tpmdev(TpmCreateOptions *tco)
> {
> - /*
> - * Use of error_report() in a function with an Error ** parameter
> - * is suspicious. It is okay here. The parameter only exists to
> - * make the function usable with qemu_opts_foreach(). It is not
> - * actually used.
> - */
> - const char *value;
> - const char *id;
> const TPMBackendClass *be;
> TPMBackend *drv;
> - Error *local_err = NULL;
> - int i;
>
> if (!QLIST_EMPTY(&tpm_backends)) {
> error_report("Only one TPM is allowed.");
> - return 1;
> + exit(1);
> }
>
> - id = qemu_opts_id(opts);
> - if (id == NULL) {
> - error_report(QERR_MISSING_PARAMETER, "id");
> - return 1;
> - }
> -
> - value = qemu_opt_get(opts, "type");
> - if (!value) {
> - error_report(QERR_MISSING_PARAMETER, "type");
> - tpm_display_backend_drivers();
> - return 1;
> - }
> -
> - i = qapi_enum_parse(&TpmType_lookup, value, -1, NULL);
> - be = i >= 0 ? tpm_be_find_by_type(i) : NULL;
> + be = tco->type >= 0 ? tpm_be_find_by_type(tco->type) : NULL;
> if (be == NULL) {
> error_report(QERR_INVALID_PARAMETER_VALUE,
> "type", "a TPM backend type");
> tpm_display_backend_drivers();
> - return 1;
> - }
> -
> - /* validate backend specific opts */
> - if (!qemu_opts_validate(opts, be->opts, &local_err)) {
> - error_report_err(local_err);
> - return 1;
> + exit(1);
> }
>
> - drv = be->create(opts);
> + drv = be->create(tco);
> if (!drv) {
> - return 1;
> + exit(1);
> }
>
> - drv->id = g_strdup(id);
> + drv->id = g_strdup(tco->id);
> QLIST_INSERT_HEAD(&tpm_backends, drv, list);
> -
> - return 0;
> }
>
> /*
> @@ -161,33 +141,35 @@ void tpm_cleanup(void)
> * Initialize the TPM. Process the tpmdev command line options describing the
> * TPM backend.
> */
> -int tpm_init(void)
> +void tpm_init(void)
> {
> - if (qemu_opts_foreach(qemu_find_opts("tpmdev"),
> - tpm_init_tpmdev, NULL, NULL)) {
> - return -1;
> - }
> + while (!QSIMPLEQ_EMPTY(&tco_queue)) {
> + TpmCreateOptionsQueueEntry *tcoqe = QSIMPLEQ_FIRST(&tco_queue);
>
> - return 0;
> + QSIMPLEQ_REMOVE_HEAD(&tco_queue, entry);
> + tpm_init_tpmdev(tcoqe->tco);
tcoqe->tco and the possible emulator or passthrough specific allocations
should probably be also free'ed here.
> + g_free(tcoqe);
> + }
> }
>
> /*
> * Parse the TPM configuration options.
> * To display all available TPM backends the user may use '-tpmdev help'
> */
> -int tpm_config_parse(QemuOptsList *opts_list, const char *optarg)
> +void tpm_config_parse(const char *optarg)
> {
> - QemuOpts *opts;
> + Visitor *v;
> + TpmCreateOptionsQueueEntry *tcqe;
>
> - if (!strcmp(optarg, "help")) {
> + if (is_help_option(optarg)) {
> tpm_display_backend_drivers();
> - return -1;
> - }
> - opts = qemu_opts_parse_noisily(opts_list, optarg, true);
> - if (!opts) {
> - return -1;
> + exit(0);
> }
> - return 0;
> + v = qobject_input_visitor_new_str(optarg, "type", &error_fatal);
> + tcqe = g_new(TpmCreateOptionsQueueEntry, 1);
> + visit_type_TpmCreateOptions(v, NULL, &tcqe->tco, &error_fatal);
> + visit_free(v);
> + QSIMPLEQ_INSERT_TAIL(&tco_queue, tcqe, entry);
> }
>
> /*
> diff --git a/softmmu/vl.c b/softmmu/vl.c
> index 798e1dc933..8c2655dbc2 100644
> --- a/softmmu/vl.c
> +++ b/softmmu/vl.c
> @@ -328,16 +328,6 @@ static QemuOptsList qemu_object_opts = {
> },
> };
>
> -static QemuOptsList qemu_tpmdev_opts = {
> - .name = "tpmdev",
> - .implied_opt_name = "type",
> - .head = QTAILQ_HEAD_INITIALIZER(qemu_tpmdev_opts.head),
> - .desc = {
> - /* options are defined in the TPM backends */
> - { /* end of list */ }
> - },
> -};
> -
> static QemuOptsList qemu_overcommit_opts = {
> .name = "overcommit",
> .head = QTAILQ_HEAD_INITIALIZER(qemu_overcommit_opts.head),
> @@ -1934,9 +1924,7 @@ static void qemu_create_late_backends(void)
>
> object_option_foreach_add(object_create_late);
>
> - if (tpm_init() < 0) {
> - exit(1);
> - }
> + tpm_init();
>
> qemu_opts_foreach(qemu_find_opts("mon"),
> mon_init_func, NULL, &error_fatal);
> @@ -2658,7 +2646,6 @@ void qemu_init(int argc, char **argv)
> qemu_add_opts(&qemu_boot_opts);
> qemu_add_opts(&qemu_add_fd_opts);
> qemu_add_opts(&qemu_object_opts);
> - qemu_add_opts(&qemu_tpmdev_opts);
> qemu_add_opts(&qemu_overcommit_opts);
> qemu_add_opts(&qemu_msg_opts);
> qemu_add_opts(&qemu_name_opts);
> @@ -2906,9 +2893,7 @@ void qemu_init(int argc, char **argv)
> break;
> #ifdef CONFIG_TPM
> case QEMU_OPTION_tpmdev:
> - if (tpm_config_parse(qemu_find_opts("tpmdev"), optarg) < 0) {
> - exit(1);
> - }
> + tpm_config_parse(optarg);
> break;
> #endif
> case QEMU_OPTION_mempath:
On 9/26/23 11:20, Stefan Berger wrote:
>
> On 1/9/23 11:15, James Bottomley wrote:
>> From: James Bottomley <James.Bottomley@HansenPartnership.com>
>>
>> Instead of processing the tpmdev options using the old qemu options,
>> convert to the new visitor format which also allows the passing of
>> json on the command line.
>>
>> Signed-off-by: James Bottomley <jejb@linux.ibm.com>
>
>> + while (!QSIMPLEQ_EMPTY(&tco_queue)) {
>> + TpmCreateOptionsQueueEntry *tcoqe = QSIMPLEQ_FIRST(&tco_queue);
>> - return 0;
>> + QSIMPLEQ_REMOVE_HEAD(&tco_queue, entry);
>> + tpm_init_tpmdev(tcoqe->tco);
>
> tcoqe->tco and the possible emulator or passthrough specific
> allocations should probably be also free'ed here.
Use: qapi_free_TpmCreateOptions(tcoqe->tco);
© 2016 - 2025 Red Hat, Inc.