1
The requested feedback was to convert the tpmdev handler to being json
1
The requested feedback was to convert the tpmdev handler to being json
2
based, which requires rethreading all the backends. The good news is
2
based, which requires rethreading all the backends. The good news is
3
this reduced quite a bit of code (especially as I converted it to
3
this reduced quite a bit of code (especially as I converted it to
4
error_fatal handling as well, which removes the return status
4
error_fatal handling as well, which removes the return status
5
threading). The bad news is I can't test any of the conversions.
5
threading).
6
swtpm still isn't building on opensuse and, apparently, passthrough
7
doesn't like my native TPM because it doesn't allow cancellation.
8
6
9
v3 pulls out more unneeded code in the visitor conversion, makes
7
v3 pulls out more unneeded code in the visitor conversion, makes
10
migration work on external state preservation of the simulator and
8
migration work on external state preservation of the simulator and
11
adds documentation
9
adds documentation
12
10
...
...
26
24
27
v9 Fix merge conflict with optarg->optstr conversion
25
v9 Fix merge conflict with optarg->optstr conversion
28
26
29
v10 Fix more merge conflicts and update API versions
27
v10 Fix more merge conflicts and update API versions
30
28
29
v11 Fix another merge conflict and correct a warm reboot problem where
30
the TPM isn't getting reset (meaning the PCR values are wrong).
31
31
James
32
James
32
33
33
---
34
---
34
35
35
James Bottomley (2):
36
James Bottomley (2):
36
tpm: convert tpmdev options processing to new visitor format
37
tpm: convert tpmdev options processing to new visitor format
37
tpm: add backend for mssim
38
tpm: add backend for mssim
38
39
39
MAINTAINERS | 6 +
40
MAINTAINERS | 6 +
40
backends/tpm/Kconfig | 5 +
41
backends/tpm/Kconfig | 5 +
41
backends/tpm/meson.build | 1 +
42
backends/tpm/meson.build | 1 +
42
backends/tpm/tpm_emulator.c | 25 ++-
43
backends/tpm/tpm_emulator.c | 25 +--
43
backends/tpm/tpm_mssim.c | 319 +++++++++++++++++++++++++++++++++
44
backends/tpm/tpm_mssim.c | 335 +++++++++++++++++++++++++++++++++
44
backends/tpm/tpm_mssim.h | 44 +++++
45
backends/tpm/tpm_mssim.h | 44 +++++
45
backends/tpm/tpm_passthrough.c | 23 +--
46
backends/tpm/tpm_passthrough.c | 23 +--
46
docs/specs/tpm.rst | 39 ++++
47
docs/specs/tpm.rst | 39 ++++
47
include/sysemu/tpm.h | 5 +-
48
include/sysemu/tpm.h | 5 +-
48
include/sysemu/tpm_backend.h | 2 +-
49
include/sysemu/tpm_backend.h | 2 +-
49
qapi/tpm.json | 50 +++++-
50
qapi/tpm.json | 50 ++++-
50
system/tpm-hmp-cmds.c | 9 +
51
system/tpm-hmp-cmds.c | 9 +
51
system/tpm.c | 91 ++++------
52
system/tpm.c | 91 ++++-----
52
system/vl.c | 19 +-
53
system/vl.c | 19 +-
53
14 files changed, 530 insertions(+), 108 deletions(-)
54
14 files changed, 546 insertions(+), 108 deletions(-)
54
create mode 100644 backends/tpm/tpm_mssim.c
55
create mode 100644 backends/tpm/tpm_mssim.c
55
create mode 100644 backends/tpm/tpm_mssim.h
56
create mode 100644 backends/tpm/tpm_mssim.h
56
57
57
--
58
--
58
2.35.3
59
2.35.3
diff view generated by jsdifflib
1
Instead of processing the tpmdev options using the old qemu options,
1
Instead of processing the tpmdev options using the old qemu options,
2
convert to the new visitor format which also allows the passing of
2
convert to the new visitor format which also allows the passing of
3
json on the command line.
3
json on the command line.
4
4
5
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
5
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
6
Tested-by: Stefan Berger <stefanb@linux.ibm.com>
6
Tested-by: Stefan Berger <stefanb@linux.ibm.com>
7
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
7
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
8
8
9
---
9
---
10
v4: add TpmConfiOptions
10
v4: add TpmConfiOptions
11
v5: exit(0) for help
11
v5: exit(0) for help
12
v7: adjust line lengths, free options
12
v7: adjust line lengths, free options
13
v8: minor updates; add tested/reviewed-by
13
v8: minor updates; add tested/reviewed-by
14
v9: optarg->optstr
14
v9: optarg->optstr
15
---
15
---
16
backends/tpm/tpm_emulator.c | 25 ++++------
16
backends/tpm/tpm_emulator.c | 25 ++++------
17
backends/tpm/tpm_passthrough.c | 23 +++------
17
backends/tpm/tpm_passthrough.c | 23 +++------
18
include/sysemu/tpm.h | 5 +-
18
include/sysemu/tpm.h | 5 +-
19
include/sysemu/tpm_backend.h | 2 +-
19
include/sysemu/tpm_backend.h | 2 +-
20
qapi/tpm.json | 21 ++++++++
20
qapi/tpm.json | 21 ++++++++
21
system/tpm.c | 91 ++++++++++++++--------------------
21
system/tpm.c | 91 ++++++++++++++--------------------
22
system/vl.c | 19 +------
22
system/vl.c | 19 +------
23
7 files changed, 81 insertions(+), 105 deletions(-)
23
7 files changed, 81 insertions(+), 105 deletions(-)
24
24
25
diff --git a/backends/tpm/tpm_emulator.c b/backends/tpm/tpm_emulator.c
25
diff --git a/backends/tpm/tpm_emulator.c b/backends/tpm/tpm_emulator.c
26
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
27
--- a/backends/tpm/tpm_emulator.c
27
--- a/backends/tpm/tpm_emulator.c
28
+++ b/backends/tpm/tpm_emulator.c
28
+++ b/backends/tpm/tpm_emulator.c
29
@@ -XXX,XX +XXX,XX @@ err_exit:
29
@@ -XXX,XX +XXX,XX @@ err_exit:
30
return -1;
30
return -1;
31
}
31
}
32
32
33
-static int tpm_emulator_handle_device_opts(TPMEmulator *tpm_emu, QemuOpts *opts)
33
-static int tpm_emulator_handle_device_opts(TPMEmulator *tpm_emu, QemuOpts *opts)
34
+static int tpm_emulator_handle_device_opts(TPMEmulator *tpm_emu,
34
+static int tpm_emulator_handle_device_opts(TPMEmulator *tpm_emu,
35
+ TpmCreateOptions *opts)
35
+ TpmCreateOptions *opts)
36
{
36
{
37
- const char *value;
37
- const char *value;
38
Error *err = NULL;
38
Error *err = NULL;
39
Chardev *dev;
39
Chardev *dev;
40
40
41
- value = qemu_opt_get(opts, "chardev");
41
- value = qemu_opt_get(opts, "chardev");
42
- if (!value) {
42
- if (!value) {
43
- error_report("tpm-emulator: parameter 'chardev' is missing");
43
- error_report("tpm-emulator: parameter 'chardev' is missing");
44
- goto err;
44
- goto err;
45
- }
45
- }
46
+ tpm_emu->options = QAPI_CLONE(TPMEmulatorOptions, &opts->u.emulator);
46
+ tpm_emu->options = QAPI_CLONE(TPMEmulatorOptions, &opts->u.emulator);
47
+ tpm_emu->data_ioc = NULL;
47
+ tpm_emu->data_ioc = NULL;
48
48
49
- dev = qemu_chr_find(value);
49
- dev = qemu_chr_find(value);
50
+ dev = qemu_chr_find(opts->u.emulator.chardev);
50
+ dev = qemu_chr_find(opts->u.emulator.chardev);
51
if (!dev) {
51
if (!dev) {
52
- error_report("tpm-emulator: tpm chardev '%s' not found", value);
52
- error_report("tpm-emulator: tpm chardev '%s' not found", value);
53
+ error_report("tpm-emulator: tpm chardev '%s' not found",
53
+ error_report("tpm-emulator: tpm chardev '%s' not found",
54
+ opts->u.emulator.chardev);
54
+ opts->u.emulator.chardev);
55
goto err;
55
goto err;
56
}
56
}
57
57
58
if (!qemu_chr_fe_init(&tpm_emu->ctrl_chr, dev, &err)) {
58
if (!qemu_chr_fe_init(&tpm_emu->ctrl_chr, dev, &err)) {
59
error_prepend(&err, "tpm-emulator: No valid chardev found at '%s':",
59
error_prepend(&err, "tpm-emulator: No valid chardev found at '%s':",
60
- value);
60
- value);
61
+ opts->u.emulator.chardev);
61
+ opts->u.emulator.chardev);
62
error_report_err(err);
62
error_report_err(err);
63
goto err;
63
goto err;
64
}
64
}
65
65
66
- tpm_emu->options->chardev = g_strdup(value);
66
- tpm_emu->options->chardev = g_strdup(value);
67
-
67
-
68
if (tpm_emulator_prepare_data_fd(tpm_emu) < 0) {
68
if (tpm_emulator_prepare_data_fd(tpm_emu) < 0) {
69
goto err;
69
goto err;
70
}
70
}
71
@@ -XXX,XX +XXX,XX @@ err:
71
@@ -XXX,XX +XXX,XX @@ err:
72
return -1;
72
return -1;
73
}
73
}
74
74
75
-static TPMBackend *tpm_emulator_create(QemuOpts *opts)
75
-static TPMBackend *tpm_emulator_create(QemuOpts *opts)
76
+static TPMBackend *tpm_emulator_create(TpmCreateOptions *opts)
76
+static TPMBackend *tpm_emulator_create(TpmCreateOptions *opts)
77
{
77
{
78
TPMBackend *tb = TPM_BACKEND(object_new(TYPE_TPM_EMULATOR));
78
TPMBackend *tb = TPM_BACKEND(object_new(TYPE_TPM_EMULATOR));
79
79
80
@@ -XXX,XX +XXX,XX @@ static void tpm_emulator_inst_init(Object *obj)
80
@@ -XXX,XX +XXX,XX @@ static void tpm_emulator_inst_init(Object *obj)
81
81
82
trace_tpm_emulator_inst_init();
82
trace_tpm_emulator_inst_init();
83
83
84
- tpm_emu->options = g_new0(TPMEmulatorOptions, 1);
84
- tpm_emu->options = g_new0(TPMEmulatorOptions, 1);
85
tpm_emu->cur_locty_number = ~0;
85
tpm_emu->cur_locty_number = ~0;
86
qemu_mutex_init(&tpm_emu->mutex);
86
qemu_mutex_init(&tpm_emu->mutex);
87
tpm_emu->vmstate =
87
tpm_emu->vmstate =
88
@@ -XXX,XX +XXX,XX @@ static void tpm_emulator_shutdown(TPMEmulator *tpm_emu)
88
@@ -XXX,XX +XXX,XX @@ static void tpm_emulator_shutdown(TPMEmulator *tpm_emu)
89
{
89
{
90
ptm_res res;
90
ptm_res res;
91
91
92
- if (!tpm_emu->options->chardev) {
92
- if (!tpm_emu->options->chardev) {
93
+ if (!tpm_emu->data_ioc) {
93
+ if (!tpm_emu->data_ioc) {
94
/* was never properly initialized */
94
/* was never properly initialized */
95
return;
95
return;
96
}
96
}
97
diff --git a/backends/tpm/tpm_passthrough.c b/backends/tpm/tpm_passthrough.c
97
diff --git a/backends/tpm/tpm_passthrough.c b/backends/tpm/tpm_passthrough.c
98
index XXXXXXX..XXXXXXX 100644
98
index XXXXXXX..XXXXXXX 100644
99
--- a/backends/tpm/tpm_passthrough.c
99
--- a/backends/tpm/tpm_passthrough.c
100
+++ b/backends/tpm/tpm_passthrough.c
100
+++ b/backends/tpm/tpm_passthrough.c
101
@@ -XXX,XX +XXX,XX @@ static int tpm_passthrough_open_sysfs_cancel(TPMPassthruState *tpm_pt)
101
@@ -XXX,XX +XXX,XX @@ static int tpm_passthrough_open_sysfs_cancel(TPMPassthruState *tpm_pt)
102
}
102
}
103
103
104
static int
104
static int
105
-tpm_passthrough_handle_device_opts(TPMPassthruState *tpm_pt, QemuOpts *opts)
105
-tpm_passthrough_handle_device_opts(TPMPassthruState *tpm_pt, QemuOpts *opts)
106
+tpm_passthrough_handle_device_opts(TPMPassthruState *tpm_pt,
106
+tpm_passthrough_handle_device_opts(TPMPassthruState *tpm_pt,
107
+ TpmCreateOptions *opts)
107
+ TpmCreateOptions *opts)
108
{
108
{
109
- const char *value;
109
- const char *value;
110
+ tpm_pt->options = QAPI_CLONE(TPMPassthroughOptions, &opts->u.passthrough);
110
+ tpm_pt->options = QAPI_CLONE(TPMPassthroughOptions, &opts->u.passthrough);
111
111
112
- value = qemu_opt_get(opts, "cancel-path");
112
- value = qemu_opt_get(opts, "cancel-path");
113
- if (value) {
113
- if (value) {
114
- tpm_pt->options->cancel_path = g_strdup(value);
114
- tpm_pt->options->cancel_path = g_strdup(value);
115
- }
115
- }
116
-
116
-
117
- value = qemu_opt_get(opts, "path");
117
- value = qemu_opt_get(opts, "path");
118
- if (value) {
118
- if (value) {
119
- tpm_pt->options->path = g_strdup(value);
119
- tpm_pt->options->path = g_strdup(value);
120
- }
120
- }
121
-
121
-
122
- tpm_pt->tpm_dev = value ? value : TPM_PASSTHROUGH_DEFAULT_DEVICE;
122
- tpm_pt->tpm_dev = value ? value : TPM_PASSTHROUGH_DEFAULT_DEVICE;
123
+ tpm_pt->tpm_dev = opts->u.passthrough.path ? opts->u.passthrough.path :
123
+ tpm_pt->tpm_dev = opts->u.passthrough.path ? opts->u.passthrough.path :
124
+ TPM_PASSTHROUGH_DEFAULT_DEVICE;
124
+ TPM_PASSTHROUGH_DEFAULT_DEVICE;
125
tpm_pt->tpm_fd = qemu_open_old(tpm_pt->tpm_dev, O_RDWR);
125
tpm_pt->tpm_fd = qemu_open_old(tpm_pt->tpm_dev, O_RDWR);
126
if (tpm_pt->tpm_fd < 0) {
126
if (tpm_pt->tpm_fd < 0) {
127
error_report("Cannot access TPM device using '%s': %s",
127
error_report("Cannot access TPM device using '%s': %s",
128
@@ -XXX,XX +XXX,XX @@ tpm_passthrough_handle_device_opts(TPMPassthruState *tpm_pt, QemuOpts *opts)
128
@@ -XXX,XX +XXX,XX @@ tpm_passthrough_handle_device_opts(TPMPassthruState *tpm_pt, QemuOpts *opts)
129
return 0;
129
return 0;
130
}
130
}
131
131
132
-static TPMBackend *tpm_passthrough_create(QemuOpts *opts)
132
-static TPMBackend *tpm_passthrough_create(QemuOpts *opts)
133
+static TPMBackend *tpm_passthrough_create(TpmCreateOptions *tco)
133
+static TPMBackend *tpm_passthrough_create(TpmCreateOptions *tco)
134
{
134
{
135
Object *obj = object_new(TYPE_TPM_PASSTHROUGH);
135
Object *obj = object_new(TYPE_TPM_PASSTHROUGH);
136
136
137
- if (tpm_passthrough_handle_device_opts(TPM_PASSTHROUGH(obj), opts)) {
137
- if (tpm_passthrough_handle_device_opts(TPM_PASSTHROUGH(obj), opts)) {
138
+ if (tpm_passthrough_handle_device_opts(TPM_PASSTHROUGH(obj), tco)) {
138
+ if (tpm_passthrough_handle_device_opts(TPM_PASSTHROUGH(obj), tco)) {
139
object_unref(obj);
139
object_unref(obj);
140
return NULL;
140
return NULL;
141
}
141
}
142
@@ -XXX,XX +XXX,XX @@ static void tpm_passthrough_inst_init(Object *obj)
142
@@ -XXX,XX +XXX,XX @@ static void tpm_passthrough_inst_init(Object *obj)
143
{
143
{
144
TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(obj);
144
TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(obj);
145
145
146
- tpm_pt->options = g_new0(TPMPassthroughOptions, 1);
146
- tpm_pt->options = g_new0(TPMPassthroughOptions, 1);
147
tpm_pt->tpm_fd = -1;
147
tpm_pt->tpm_fd = -1;
148
tpm_pt->cancel_fd = -1;
148
tpm_pt->cancel_fd = -1;
149
}
149
}
150
diff --git a/include/sysemu/tpm.h b/include/sysemu/tpm.h
150
diff --git a/include/sysemu/tpm.h b/include/sysemu/tpm.h
151
index XXXXXXX..XXXXXXX 100644
151
index XXXXXXX..XXXXXXX 100644
152
--- a/include/sysemu/tpm.h
152
--- a/include/sysemu/tpm.h
153
+++ b/include/sysemu/tpm.h
153
+++ b/include/sysemu/tpm.h
154
@@ -XXX,XX +XXX,XX @@
154
@@ -XXX,XX +XXX,XX @@
155
155
156
#ifdef CONFIG_TPM
156
#ifdef CONFIG_TPM
157
157
158
-int tpm_config_parse(QemuOptsList *opts_list, const char *optstr);
158
-int tpm_config_parse(QemuOptsList *opts_list, const char *optstr);
159
-int tpm_init(void);
159
-int tpm_init(void);
160
+void tpm_config_parse(const char *optstr);
160
+void tpm_config_parse(const char *optstr);
161
+void tpm_init(void);
161
+void tpm_init(void);
162
+
162
+
163
void tpm_cleanup(void);
163
void tpm_cleanup(void);
164
164
165
typedef enum TPMVersion {
165
typedef enum TPMVersion {
166
diff --git a/include/sysemu/tpm_backend.h b/include/sysemu/tpm_backend.h
166
diff --git a/include/sysemu/tpm_backend.h b/include/sysemu/tpm_backend.h
167
index XXXXXXX..XXXXXXX 100644
167
index XXXXXXX..XXXXXXX 100644
168
--- a/include/sysemu/tpm_backend.h
168
--- a/include/sysemu/tpm_backend.h
169
+++ b/include/sysemu/tpm_backend.h
169
+++ b/include/sysemu/tpm_backend.h
170
@@ -XXX,XX +XXX,XX @@ struct TPMBackendClass {
170
@@ -XXX,XX +XXX,XX @@ struct TPMBackendClass {
171
/* get a descriptive text of the backend to display to the user */
171
/* get a descriptive text of the backend to display to the user */
172
const char *desc;
172
const char *desc;
173
173
174
- TPMBackend *(*create)(QemuOpts *opts);
174
- TPMBackend *(*create)(QemuOpts *opts);
175
+ TPMBackend *(*create)(TpmCreateOptions *tco);
175
+ TPMBackend *(*create)(TpmCreateOptions *tco);
176
176
177
/* start up the TPM on the backend - optional */
177
/* start up the TPM on the backend - optional */
178
int (*startup_tpm)(TPMBackend *t, size_t buffersize);
178
int (*startup_tpm)(TPMBackend *t, size_t buffersize);
179
diff --git a/qapi/tpm.json b/qapi/tpm.json
179
diff --git a/qapi/tpm.json b/qapi/tpm.json
180
index XXXXXXX..XXXXXXX 100644
180
index XXXXXXX..XXXXXXX 100644
181
--- a/qapi/tpm.json
181
--- a/qapi/tpm.json
182
+++ b/qapi/tpm.json
182
+++ b/qapi/tpm.json
183
@@ -XXX,XX +XXX,XX @@
183
@@ -XXX,XX +XXX,XX @@
184
'emulator': 'TPMEmulatorOptionsWrapper' },
184
'emulator': 'TPMEmulatorOptionsWrapper' },
185
'if': 'CONFIG_TPM' }
185
'if': 'CONFIG_TPM' }
186
186
187
+##
187
+##
188
+# @TpmCreateOptions:
188
+# @TpmCreateOptions:
189
+#
189
+#
190
+# A union referencing different TPM backend types' configuration options
190
+# A union referencing different TPM backend types' configuration options
191
+# without the wrapper to be usable by visitors.
191
+# without the wrapper to be usable by visitors.
192
+#
192
+#
193
+# @type: - 'passthrough' The configuration options for the TPM passthrough type
193
+# @type: - 'passthrough' The configuration options for the TPM passthrough type
194
+# - 'emulator' The configuration options for TPM emulator backend type
194
+# - 'emulator' The configuration options for TPM emulator backend type
195
+#
195
+#
196
+# @id: The Id of the TPM
196
+# @id: The Id of the TPM
197
+#
197
+#
198
+# Since: 9.0
198
+# Since: 9.0
199
+##
199
+##
200
+{ 'union': 'TpmCreateOptions',
200
+{ 'union': 'TpmCreateOptions',
201
+ 'base': { 'type': 'TpmType',
201
+ 'base': { 'type': 'TpmType',
202
+ 'id' : 'str' },
202
+ 'id' : 'str' },
203
+ 'discriminator': 'type',
203
+ 'discriminator': 'type',
204
+ 'data': { 'passthrough' : 'TPMPassthroughOptions',
204
+ 'data': { 'passthrough' : 'TPMPassthroughOptions',
205
+ 'emulator': 'TPMEmulatorOptions' },
205
+ 'emulator': 'TPMEmulatorOptions' },
206
+ 'if': 'CONFIG_TPM' }
206
+ 'if': 'CONFIG_TPM' }
207
+
207
+
208
##
208
##
209
# @TPMInfo:
209
# @TPMInfo:
210
#
210
#
211
diff --git a/system/tpm.c b/system/tpm.c
211
diff --git a/system/tpm.c b/system/tpm.c
212
index XXXXXXX..XXXXXXX 100644
212
index XXXXXXX..XXXXXXX 100644
213
--- a/system/tpm.c
213
--- a/system/tpm.c
214
+++ b/system/tpm.c
214
+++ b/system/tpm.c
215
@@ -XXX,XX +XXX,XX @@
215
@@ -XXX,XX +XXX,XX @@
216
#include "qapi/error.h"
216
#include "qapi/error.h"
217
#include "qapi/qapi-commands-tpm.h"
217
#include "qapi/qapi-commands-tpm.h"
218
#include "qapi/qmp/qerror.h"
218
#include "qapi/qmp/qerror.h"
219
+#include "qapi/qobject-input-visitor.h"
219
+#include "qapi/qobject-input-visitor.h"
220
+#include "qapi/qapi-visit-tpm.h"
220
+#include "qapi/qapi-visit-tpm.h"
221
#include "sysemu/tpm_backend.h"
221
#include "sysemu/tpm_backend.h"
222
#include "sysemu/tpm.h"
222
#include "sysemu/tpm.h"
223
#include "qemu/config-file.h"
223
#include "qemu/config-file.h"
224
#include "qemu/error-report.h"
224
#include "qemu/error-report.h"
225
+#include "qemu/help_option.h"
225
+#include "qemu/help_option.h"
226
226
227
static QLIST_HEAD(, TPMBackend) tpm_backends =
227
static QLIST_HEAD(, TPMBackend) tpm_backends =
228
QLIST_HEAD_INITIALIZER(tpm_backends);
228
QLIST_HEAD_INITIALIZER(tpm_backends);
229
229
230
+typedef struct TpmCreateOptionsQueueEntry {
230
+typedef struct TpmCreateOptionsQueueEntry {
231
+ TpmCreateOptions *tco;
231
+ TpmCreateOptions *tco;
232
+ QSIMPLEQ_ENTRY(TpmCreateOptionsQueueEntry) entry;
232
+ QSIMPLEQ_ENTRY(TpmCreateOptionsQueueEntry) entry;
233
+} TpmCreateOptionsQueueEntry;
233
+} TpmCreateOptionsQueueEntry;
234
+
234
+
235
+typedef QSIMPLEQ_HEAD(, TpmCreateOptionsQueueEntry) TpmCreateOptionsQueue;
235
+typedef QSIMPLEQ_HEAD(, TpmCreateOptionsQueueEntry) TpmCreateOptionsQueue;
236
+
236
+
237
+static TpmCreateOptionsQueue tco_queue = QSIMPLEQ_HEAD_INITIALIZER(tco_queue);
237
+static TpmCreateOptionsQueue tco_queue = QSIMPLEQ_HEAD_INITIALIZER(tco_queue);
238
+
238
+
239
static const TPMBackendClass *
239
static const TPMBackendClass *
240
tpm_be_find_by_type(enum TpmType type)
240
tpm_be_find_by_type(enum TpmType type)
241
{
241
{
242
@@ -XXX,XX +XXX,XX @@ TPMBackend *qemu_find_tpm_be(const char *id)
242
@@ -XXX,XX +XXX,XX @@ TPMBackend *qemu_find_tpm_be(const char *id)
243
return NULL;
243
return NULL;
244
}
244
}
245
245
246
-static int tpm_init_tpmdev(void *dummy, QemuOpts *opts, Error **errp)
246
-static int tpm_init_tpmdev(void *dummy, QemuOpts *opts, Error **errp)
247
+static void tpm_init_tpmdev(TpmCreateOptions *tco)
247
+static void tpm_init_tpmdev(TpmCreateOptions *tco)
248
{
248
{
249
- /*
249
- /*
250
- * Use of error_report() in a function with an Error ** parameter
250
- * Use of error_report() in a function with an Error ** parameter
251
- * is suspicious. It is okay here. The parameter only exists to
251
- * is suspicious. It is okay here. The parameter only exists to
252
- * make the function usable with qemu_opts_foreach(). It is not
252
- * make the function usable with qemu_opts_foreach(). It is not
253
- * actually used.
253
- * actually used.
254
- */
254
- */
255
- const char *value;
255
- const char *value;
256
- const char *id;
256
- const char *id;
257
const TPMBackendClass *be;
257
const TPMBackendClass *be;
258
TPMBackend *drv;
258
TPMBackend *drv;
259
- Error *local_err = NULL;
259
- Error *local_err = NULL;
260
- int i;
260
- int i;
261
261
262
if (!QLIST_EMPTY(&tpm_backends)) {
262
if (!QLIST_EMPTY(&tpm_backends)) {
263
error_report("Only one TPM is allowed.");
263
error_report("Only one TPM is allowed.");
264
- return 1;
264
- return 1;
265
+ exit(1);
265
+ exit(1);
266
}
266
}
267
267
268
- id = qemu_opts_id(opts);
268
- id = qemu_opts_id(opts);
269
- if (id == NULL) {
269
- if (id == NULL) {
270
- error_report(QERR_MISSING_PARAMETER, "id");
270
- error_report(QERR_MISSING_PARAMETER, "id");
271
- return 1;
271
- return 1;
272
- }
272
- }
273
-
273
-
274
- value = qemu_opt_get(opts, "type");
274
- value = qemu_opt_get(opts, "type");
275
- if (!value) {
275
- if (!value) {
276
- error_report(QERR_MISSING_PARAMETER, "type");
276
- error_report(QERR_MISSING_PARAMETER, "type");
277
- tpm_display_backend_drivers();
277
- tpm_display_backend_drivers();
278
- return 1;
278
- return 1;
279
- }
279
- }
280
-
280
-
281
- i = qapi_enum_parse(&TpmType_lookup, value, -1, NULL);
281
- i = qapi_enum_parse(&TpmType_lookup, value, -1, NULL);
282
- be = i >= 0 ? tpm_be_find_by_type(i) : NULL;
282
- be = i >= 0 ? tpm_be_find_by_type(i) : NULL;
283
+ be = tco->type >= 0 ? tpm_be_find_by_type(tco->type) : NULL;
283
+ be = tco->type >= 0 ? tpm_be_find_by_type(tco->type) : NULL;
284
if (be == NULL) {
284
if (be == NULL) {
285
error_report(QERR_INVALID_PARAMETER_VALUE,
285
error_report(QERR_INVALID_PARAMETER_VALUE,
286
"type", "a TPM backend type");
286
"type", "a TPM backend type");
287
tpm_display_backend_drivers();
287
tpm_display_backend_drivers();
288
- return 1;
288
- return 1;
289
- }
289
- }
290
-
290
-
291
- /* validate backend specific opts */
291
- /* validate backend specific opts */
292
- if (!qemu_opts_validate(opts, be->opts, &local_err)) {
292
- if (!qemu_opts_validate(opts, be->opts, &local_err)) {
293
- error_report_err(local_err);
293
- error_report_err(local_err);
294
- return 1;
294
- return 1;
295
+ exit(1);
295
+ exit(1);
296
}
296
}
297
297
298
- drv = be->create(opts);
298
- drv = be->create(opts);
299
+ drv = be->create(tco);
299
+ drv = be->create(tco);
300
if (!drv) {
300
if (!drv) {
301
- return 1;
301
- return 1;
302
+ exit(1);
302
+ exit(1);
303
}
303
}
304
304
305
- drv->id = g_strdup(id);
305
- drv->id = g_strdup(id);
306
+ drv->id = g_strdup(tco->id);
306
+ drv->id = g_strdup(tco->id);
307
QLIST_INSERT_HEAD(&tpm_backends, drv, list);
307
QLIST_INSERT_HEAD(&tpm_backends, drv, list);
308
-
308
-
309
- return 0;
309
- return 0;
310
}
310
}
311
311
312
/*
312
/*
313
@@ -XXX,XX +XXX,XX @@ void tpm_cleanup(void)
313
@@ -XXX,XX +XXX,XX @@ void tpm_cleanup(void)
314
* Initialize the TPM. Process the tpmdev command line options describing the
314
* Initialize the TPM. Process the tpmdev command line options describing the
315
* TPM backend.
315
* TPM backend.
316
*/
316
*/
317
-int tpm_init(void)
317
-int tpm_init(void)
318
+void tpm_init(void)
318
+void tpm_init(void)
319
{
319
{
320
- if (qemu_opts_foreach(qemu_find_opts("tpmdev"),
320
- if (qemu_opts_foreach(qemu_find_opts("tpmdev"),
321
- tpm_init_tpmdev, NULL, NULL)) {
321
- tpm_init_tpmdev, NULL, NULL)) {
322
- return -1;
322
- return -1;
323
- }
323
- }
324
+ while (!QSIMPLEQ_EMPTY(&tco_queue)) {
324
+ while (!QSIMPLEQ_EMPTY(&tco_queue)) {
325
+ TpmCreateOptionsQueueEntry *tcoqe = QSIMPLEQ_FIRST(&tco_queue);
325
+ TpmCreateOptionsQueueEntry *tcoqe = QSIMPLEQ_FIRST(&tco_queue);
326
326
327
- return 0;
327
- return 0;
328
+ QSIMPLEQ_REMOVE_HEAD(&tco_queue, entry);
328
+ QSIMPLEQ_REMOVE_HEAD(&tco_queue, entry);
329
+ tpm_init_tpmdev(tcoqe->tco);
329
+ tpm_init_tpmdev(tcoqe->tco);
330
+ qapi_free_TpmCreateOptions(tcoqe->tco);
330
+ qapi_free_TpmCreateOptions(tcoqe->tco);
331
+ g_free(tcoqe);
331
+ g_free(tcoqe);
332
+ }
332
+ }
333
}
333
}
334
334
335
/*
335
/*
336
* Parse the TPM configuration options.
336
* Parse the TPM configuration options.
337
* To display all available TPM backends the user may use '-tpmdev help'
337
* To display all available TPM backends the user may use '-tpmdev help'
338
*/
338
*/
339
-int tpm_config_parse(QemuOptsList *opts_list, const char *optstr)
339
-int tpm_config_parse(QemuOptsList *opts_list, const char *optstr)
340
+void tpm_config_parse(const char *optstr)
340
+void tpm_config_parse(const char *optstr)
341
{
341
{
342
- QemuOpts *opts;
342
- QemuOpts *opts;
343
+ Visitor *v;
343
+ Visitor *v;
344
+ TpmCreateOptionsQueueEntry *tcqe;
344
+ TpmCreateOptionsQueueEntry *tcqe;
345
345
346
- if (!strcmp(optstr, "help")) {
346
- if (!strcmp(optstr, "help")) {
347
+ if (is_help_option(optstr)) {
347
+ if (is_help_option(optstr)) {
348
tpm_display_backend_drivers();
348
tpm_display_backend_drivers();
349
- return -1;
349
- return -1;
350
- }
350
- }
351
- opts = qemu_opts_parse_noisily(opts_list, optstr, true);
351
- opts = qemu_opts_parse_noisily(opts_list, optstr, true);
352
- if (!opts) {
352
- if (!opts) {
353
- return -1;
353
- return -1;
354
+ exit(0);
354
+ exit(0);
355
}
355
}
356
- return 0;
356
- return 0;
357
+ v = qobject_input_visitor_new_str(optstr, "type", &error_fatal);
357
+ v = qobject_input_visitor_new_str(optstr, "type", &error_fatal);
358
+ tcqe = g_new(TpmCreateOptionsQueueEntry, 1);
358
+ tcqe = g_new(TpmCreateOptionsQueueEntry, 1);
359
+ visit_type_TpmCreateOptions(v, NULL, &tcqe->tco, &error_fatal);
359
+ visit_type_TpmCreateOptions(v, NULL, &tcqe->tco, &error_fatal);
360
+ visit_free(v);
360
+ visit_free(v);
361
+ QSIMPLEQ_INSERT_TAIL(&tco_queue, tcqe, entry);
361
+ QSIMPLEQ_INSERT_TAIL(&tco_queue, tcqe, entry);
362
}
362
}
363
363
364
/*
364
/*
365
diff --git a/system/vl.c b/system/vl.c
365
diff --git a/system/vl.c b/system/vl.c
366
index XXXXXXX..XXXXXXX 100644
366
index XXXXXXX..XXXXXXX 100644
367
--- a/system/vl.c
367
--- a/system/vl.c
368
+++ b/system/vl.c
368
+++ b/system/vl.c
369
@@ -XXX,XX +XXX,XX @@ static QemuOptsList qemu_object_opts = {
369
@@ -XXX,XX +XXX,XX @@ static QemuOptsList qemu_object_opts = {
370
},
370
},
371
};
371
};
372
372
373
-static QemuOptsList qemu_tpmdev_opts = {
373
-static QemuOptsList qemu_tpmdev_opts = {
374
- .name = "tpmdev",
374
- .name = "tpmdev",
375
- .implied_opt_name = "type",
375
- .implied_opt_name = "type",
376
- .head = QTAILQ_HEAD_INITIALIZER(qemu_tpmdev_opts.head),
376
- .head = QTAILQ_HEAD_INITIALIZER(qemu_tpmdev_opts.head),
377
- .desc = {
377
- .desc = {
378
- /* options are defined in the TPM backends */
378
- /* options are defined in the TPM backends */
379
- { /* end of list */ }
379
- { /* end of list */ }
380
- },
380
- },
381
-};
381
-};
382
-
382
-
383
static QemuOptsList qemu_overcommit_opts = {
383
static QemuOptsList qemu_overcommit_opts = {
384
.name = "overcommit",
384
.name = "overcommit",
385
.head = QTAILQ_HEAD_INITIALIZER(qemu_overcommit_opts.head),
385
.head = QTAILQ_HEAD_INITIALIZER(qemu_overcommit_opts.head),
386
@@ -XXX,XX +XXX,XX @@ static void qemu_create_late_backends(void)
386
@@ -XXX,XX +XXX,XX @@ static void qemu_create_late_backends(void)
387
exit(1);
387
exit(1);
388
}
388
}
389
389
390
- if (tpm_init() < 0) {
390
- if (tpm_init() < 0) {
391
- exit(1);
391
- exit(1);
392
- }
392
- }
393
+ tpm_init();
393
+ tpm_init();
394
394
395
qemu_opts_foreach(qemu_find_opts("mon"),
395
qemu_opts_foreach(qemu_find_opts("mon"),
396
mon_init_func, NULL, &error_fatal);
396
mon_init_func, NULL, &error_fatal);
397
@@ -XXX,XX +XXX,XX @@ void qemu_init(int argc, char **argv)
397
@@ -XXX,XX +XXX,XX @@ void qemu_init(int argc, char **argv)
398
qemu_add_opts(&qemu_boot_opts);
398
qemu_add_opts(&qemu_boot_opts);
399
qemu_add_opts(&qemu_add_fd_opts);
399
qemu_add_opts(&qemu_add_fd_opts);
400
qemu_add_opts(&qemu_object_opts);
400
qemu_add_opts(&qemu_object_opts);
401
- qemu_add_opts(&qemu_tpmdev_opts);
401
- qemu_add_opts(&qemu_tpmdev_opts);
402
qemu_add_opts(&qemu_overcommit_opts);
402
qemu_add_opts(&qemu_overcommit_opts);
403
qemu_add_opts(&qemu_msg_opts);
403
qemu_add_opts(&qemu_msg_opts);
404
qemu_add_opts(&qemu_name_opts);
404
qemu_add_opts(&qemu_name_opts);
405
@@ -XXX,XX +XXX,XX @@ void qemu_init(int argc, char **argv)
405
@@ -XXX,XX +XXX,XX @@ void qemu_init(int argc, char **argv)
406
break;
406
break;
407
#ifdef CONFIG_TPM
407
#ifdef CONFIG_TPM
408
case QEMU_OPTION_tpmdev:
408
case QEMU_OPTION_tpmdev:
409
- if (tpm_config_parse(qemu_find_opts("tpmdev"), optarg) < 0) {
409
- if (tpm_config_parse(qemu_find_opts("tpmdev"), optarg) < 0) {
410
- exit(1);
410
- exit(1);
411
- }
411
- }
412
+ tpm_config_parse(optarg);
412
+ tpm_config_parse(optarg);
413
break;
413
break;
414
#endif
414
#endif
415
case QEMU_OPTION_mempath:
415
case QEMU_OPTION_mempath:
416
--
416
--
417
2.35.3
417
2.35.3
diff view generated by jsdifflib
...
...
42
v2: convert to SocketAddr json and use qio_channel_socket_connect_sync()
42
v2: convert to SocketAddr json and use qio_channel_socket_connect_sync()
43
v3: gate control power off by migration state keep control socket disconnected
43
v3: gate control power off by migration state keep control socket disconnected
44
to test outside influence and add docs.
44
to test outside influence and add docs.
45
v7: TPMmssim -> TPMMssim; doc and json fixes
45
v7: TPMmssim -> TPMMssim; doc and json fixes
46
Make command socket open each time (makes OS debugging easier)
46
Make command socket open each time (makes OS debugging easier)
47
v11: add startup method to make sure TPM is reset on reboot
47
---
48
---
48
MAINTAINERS | 6 +
49
MAINTAINERS | 6 +
49
backends/tpm/Kconfig | 5 +
50
backends/tpm/Kconfig | 5 +
50
backends/tpm/meson.build | 1 +
51
backends/tpm/meson.build | 1 +
51
backends/tpm/tpm_mssim.c | 319 +++++++++++++++++++++++++++++++++++++++
52
backends/tpm/tpm_mssim.c | 335 +++++++++++++++++++++++++++++++++++++++
52
backends/tpm/tpm_mssim.h | 44 ++++++
53
backends/tpm/tpm_mssim.h | 44 +++++
53
docs/specs/tpm.rst | 39 +++++
54
docs/specs/tpm.rst | 39 +++++
54
qapi/tpm.json | 31 +++-
55
qapi/tpm.json | 31 +++-
55
system/tpm-hmp-cmds.c | 9 ++
56
system/tpm-hmp-cmds.c | 9 ++
56
8 files changed, 450 insertions(+), 4 deletions(-)
57
8 files changed, 466 insertions(+), 4 deletions(-)
57
create mode 100644 backends/tpm/tpm_mssim.c
58
create mode 100644 backends/tpm/tpm_mssim.c
58
create mode 100644 backends/tpm/tpm_mssim.h
59
create mode 100644 backends/tpm/tpm_mssim.h
59
60
60
diff --git a/MAINTAINERS b/MAINTAINERS
61
diff --git a/MAINTAINERS b/MAINTAINERS
61
index XXXXXXX..XXXXXXX 100644
62
index XXXXXXX..XXXXXXX 100644
...
...
73
+MSSIM TPM Backend
74
+MSSIM TPM Backend
74
+M: James Bottomley <jejb@linux.ibm.com>
75
+M: James Bottomley <jejb@linux.ibm.com>
75
+S: Maintained
76
+S: Maintained
76
+F: backends/tpm/tpm_mssim.*
77
+F: backends/tpm/tpm_mssim.*
77
+
78
+
78
Checkpatch
79
SPDM
79
S: Odd Fixes
80
M: Alistair Francis <alistair.francis@wdc.com>
80
F: scripts/checkpatch.pl
81
S: Maintained
81
diff --git a/backends/tpm/Kconfig b/backends/tpm/Kconfig
82
diff --git a/backends/tpm/Kconfig b/backends/tpm/Kconfig
82
index XXXXXXX..XXXXXXX 100644
83
index XXXXXXX..XXXXXXX 100644
83
--- a/backends/tpm/Kconfig
84
--- a/backends/tpm/Kconfig
84
+++ b/backends/tpm/Kconfig
85
+++ b/backends/tpm/Kconfig
85
@@ -XXX,XX +XXX,XX @@ config TPM_EMULATOR
86
@@ -XXX,XX +XXX,XX @@ config TPM_EMULATOR
...
...
303
+ fail_msg:
304
+ fail_msg:
304
+ error_prepend(errp, ERROR_PREFIX);
305
+ error_prepend(errp, ERROR_PREFIX);
305
+ tpm_util_write_fatal_error_response(cmd->out, cmd->out_len);
306
+ tpm_util_write_fatal_error_response(cmd->out, cmd->out_len);
306
+}
307
+}
307
+
308
+
309
+static int tpm_mssim_startup(TPMBackend *tb, size_t buffersize)
310
+{
311
+ TPMMssim *t = TPM_MSSIM(tb);
312
+ Error *errp = NULL;
313
+ int ret;
314
+
315
+ if (runstate_check(RUN_STATE_INMIGRATE)) {
316
+ return 0;
317
+ }
318
+
319
+ /*
320
+ * reset the TPM using a power cycle sequence, in case someone has
321
+ * previously powered it up
322
+ */
323
+ ret = tpm_send_ctrl(t, TPM_SIGNAL_POWER_OFF, &errp);
324
+ if (ret != 0) {
325
+ goto fail;
326
+ }
327
+
328
+ ret = tpm_send_ctrl(t, TPM_SIGNAL_POWER_ON, &errp);
329
+ if (ret != 0) {
330
+ goto fail;
331
+ }
332
+
333
+ ret = tpm_send_ctrl(t, TPM_SIGNAL_NV_ON, &errp);
334
+ if (ret != 0) {
335
+ goto fail;
336
+ }
337
+
338
+ return 0;
339
+
340
+ fail:
341
+ error_report_err(errp);
342
+ return -1;
343
+}
344
+
308
+static TPMBackend *tpm_mssim_create(TpmCreateOptions *opts)
345
+static TPMBackend *tpm_mssim_create(TpmCreateOptions *opts)
309
+{
346
+{
310
+ TPMBackend *be = TPM_BACKEND(object_new(TYPE_TPM_MSSIM));
347
+ TPMBackend *be = TPM_BACKEND(object_new(TYPE_TPM_MSSIM));
311
+ TPMMssim *t = TPM_MSSIM(be);
348
+ TPMMssim *t = TPM_MSSIM(be);
312
+ int ret;
313
+ Error *errp = NULL;
349
+ Error *errp = NULL;
314
+ TPMMssimOptions *mo = &opts->u.mssim;
350
+ TPMMssimOptions *mo = &opts->u.mssim;
315
+
351
+
316
+ if (!mo->command) {
352
+ if (!mo->command) {
317
+ mo->command = g_new0(SocketAddress, 1);
353
+ mo->command = g_new0(SocketAddress, 1);
...
...
345
+ goto fail;
381
+ goto fail;
346
+ }
382
+ }
347
+ qio_channel_close(QIO_CHANNEL(t->ctrl_qc), NULL);
383
+ qio_channel_close(QIO_CHANNEL(t->ctrl_qc), NULL);
348
+ qio_channel_close(QIO_CHANNEL(t->cmd_qc), NULL);
384
+ qio_channel_close(QIO_CHANNEL(t->cmd_qc), NULL);
349
+
385
+
350
+ if (!runstate_check(RUN_STATE_INMIGRATE)) {
351
+ /*
352
+ * reset the TPM using a power cycle sequence, in case someone
353
+ * has previously powered it up
354
+ */
355
+ ret = tpm_send_ctrl(t, TPM_SIGNAL_POWER_OFF, &errp);
356
+ if (ret != 0) {
357
+ goto fail;
358
+ }
359
+
360
+ ret = tpm_send_ctrl(t, TPM_SIGNAL_POWER_ON, &errp);
361
+ if (ret != 0) {
362
+ goto fail;
363
+ }
364
+
365
+ ret = tpm_send_ctrl(t, TPM_SIGNAL_NV_ON, &errp);
366
+ if (ret != 0) {
367
+ goto fail;
368
+ }
369
+ }
370
+
386
+
371
+ return be;
387
+ return be;
372
+
388
+
373
+ fail:
389
+ fail:
374
+ object_unref(OBJECT(t->ctrl_qc));
390
+ object_unref(OBJECT(t->ctrl_qc));
...
...
403
+ cl->type = TPM_TYPE_MSSIM;
419
+ cl->type = TPM_TYPE_MSSIM;
404
+ cl->opts = tpm_mssim_cmdline_opts;
420
+ cl->opts = tpm_mssim_cmdline_opts;
405
+ cl->desc = "TPM mssim emulator backend driver";
421
+ cl->desc = "TPM mssim emulator backend driver";
406
+ cl->create = tpm_mssim_create;
422
+ cl->create = tpm_mssim_create;
407
+ cl->cancel_cmd = tpm_mssim_cancel_cmd;
423
+ cl->cancel_cmd = tpm_mssim_cancel_cmd;
424
+ cl->startup_tpm = tpm_mssim_startup;
408
+ cl->get_tpm_version = tpm_mssim_get_version;
425
+ cl->get_tpm_version = tpm_mssim_get_version;
409
+ cl->get_buffer_size = tpm_mssim_get_buffer_size;
426
+ cl->get_buffer_size = tpm_mssim_get_buffer_size;
410
+ cl->get_tpm_options = tpm_mssim_get_opts;
427
+ cl->get_tpm_options = tpm_mssim_get_opts;
411
+ cl->handle_request = tpm_mssim_handle_request;
428
+ cl->handle_request = tpm_mssim_handle_request;
412
+}
429
+}
...
...
555
+{ 'enum': 'TpmType', 'data': [ 'passthrough', 'emulator', 'mssim' ],
572
+{ 'enum': 'TpmType', 'data': [ 'passthrough', 'emulator', 'mssim' ],
556
'if': 'CONFIG_TPM' }
573
'if': 'CONFIG_TPM' }
557
574
558
##
575
##
559
@@ -XXX,XX +XXX,XX @@
576
@@ -XXX,XX +XXX,XX @@
560
# Example:
577
# .. qmp-example::
561
#
578
#
562
# -> { "execute": "query-tpm-types" }
579
# -> { "execute": "query-tpm-types" }
563
-# <- { "return": [ "passthrough", "emulator" ] }
580
-# <- { "return": [ "passthrough", "emulator" ] }
564
+# <- { "return": [ "passthrough", "emulator", "mssim" ] }
581
+# <- { "return": [ "passthrough", "emulator", "mssim" ] }
565
##
582
##
...
...
diff view generated by jsdifflib