1
From: James Bottomley <James.Bottomley@HansenPartnership.com>
2
3
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
4
based, which requires rethreading all the backends. The good news is
2
based, which requires rethreading all the backends. The good news is
5
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
6
error_fatal handling as well, which removes the return status
4
error_fatal handling as well, which removes the return status
7
threading). The bad news is I can't test any of the conversions.
5
threading).
8
swtpm still isn't building on opensuse and, apparently, passthrough
6
9
doesn't like my native TPM because it doesn't allow cancellation.
7
v3 pulls out more unneeded code in the visitor conversion, makes
8
migration work on external state preservation of the simulator and
9
adds documentation
10
11
v4 puts back the wrapper options (but doesn't add any for mssim since
12
it post dates the necessity)
13
14
v5 rebases to the latest master branch and adjusts for removed use_FOO ptrs
15
16
v5 updates help to exit zero; does some checkpatch tidying
17
18
v7 merge review feedback and add acks.
19
20
v8 adds better error handling, more code tidies and adds command
21
socket disconnection/reconnection (instead of trying to keep the
22
socket open the whole time). This adds overhead, but makes
23
debugging guest kernel TPM issues much easier.
24
25
v9 Fix merge conflict with optarg->optstr conversion
26
27
v10 Fix more merge conflicts and update API versions
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).
10
31
11
James
32
James
12
33
13
---
34
---
14
35
15
James Bottomley (2):
36
James Bottomley (2):
16
tpm: convert tpmdev options processing to new visitor format
37
tpm: convert tpmdev options processing to new visitor format
17
tpm: add backend for mssim
38
tpm: add backend for mssim
18
39
19
MAINTAINERS | 5 +
40
MAINTAINERS | 6 +
20
backends/tpm/Kconfig | 5 +
41
backends/tpm/Kconfig | 5 +
21
backends/tpm/meson.build | 1 +
42
backends/tpm/meson.build | 1 +
22
backends/tpm/tpm_emulator.c | 35 ++---
43
backends/tpm/tpm_emulator.c | 25 +--
23
backends/tpm/tpm_mssim.c | 251 +++++++++++++++++++++++++++++++++
44
backends/tpm/tpm_mssim.c | 335 +++++++++++++++++++++++++++++++++
24
backends/tpm/tpm_mssim.h | 43 ++++++
45
backends/tpm/tpm_mssim.h | 44 +++++
25
backends/tpm/tpm_passthrough.c | 37 ++---
46
backends/tpm/tpm_passthrough.c | 23 +--
26
include/sysemu/tpm.h | 2 +-
47
docs/specs/tpm.rst | 39 ++++
48
include/sysemu/tpm.h | 5 +-
27
include/sysemu/tpm_backend.h | 2 +-
49
include/sysemu/tpm_backend.h | 2 +-
28
monitor/hmp-cmds.c | 11 +-
50
qapi/tpm.json | 50 ++++-
29
qapi/tpm.json | 37 ++---
51
system/tpm-hmp-cmds.c | 9 +
30
softmmu/tpm.c | 84 +++++------
52
system/tpm.c | 91 ++++-----
31
softmmu/vl.c | 4 +-
53
system/vl.c | 19 +-
32
13 files changed, 398 insertions(+), 119 deletions(-)
54
14 files changed, 546 insertions(+), 108 deletions(-)
33
create mode 100644 backends/tpm/tpm_mssim.c
55
create mode 100644 backends/tpm/tpm_mssim.c
34
create mode 100644 backends/tpm/tpm_mssim.h
56
create mode 100644 backends/tpm/tpm_mssim.h
35
57
36
--
58
--
37
2.35.3
59
2.35.3
diff view generated by jsdifflib
1
From: James Bottomley <James.Bottomley@HansenPartnership.com>
2
3
Instead of processing the tpmdev options using the old qemu options,
1
Instead of processing the tpmdev options using the old qemu options,
4
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
5
json on the command line.
3
json on the command line.
6
4
7
Signed-off-by: James Bottomley <jejb@linux.ibm.com>
5
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
6
Tested-by: Stefan Berger <stefanb@linux.ibm.com>
7
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
8
8
---
9
---
9
backends/tpm/tpm_emulator.c | 35 ++++++--------
10
v4: add TpmConfiOptions
10
backends/tpm/tpm_passthrough.c | 37 +++++----------
11
v5: exit(0) for help
11
include/sysemu/tpm.h | 2 +-
12
v7: adjust line lengths, free options
13
v8: minor updates; add tested/reviewed-by
14
v9: optarg->optstr
15
---
16
backends/tpm/tpm_emulator.c | 25 ++++------
17
backends/tpm/tpm_passthrough.c | 23 +++------
18
include/sysemu/tpm.h | 5 +-
12
include/sysemu/tpm_backend.h | 2 +-
19
include/sysemu/tpm_backend.h | 2 +-
13
monitor/hmp-cmds.c | 4 +-
20
qapi/tpm.json | 21 ++++++++
14
qapi/tpm.json | 26 ++---------
21
system/tpm.c | 91 ++++++++++++++--------------------
15
softmmu/tpm.c | 84 +++++++++++++++-------------------
22
system/vl.c | 19 +------
16
softmmu/vl.c | 4 +-
23
7 files changed, 81 insertions(+), 105 deletions(-)
17
8 files changed, 71 insertions(+), 123 deletions(-)
18
24
19
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
20
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
21
--- a/backends/tpm/tpm_emulator.c
27
--- a/backends/tpm/tpm_emulator.c
22
+++ b/backends/tpm/tpm_emulator.c
28
+++ b/backends/tpm/tpm_emulator.c
23
@@ -XXX,XX +XXX,XX @@ typedef struct TPMBlobBuffers {
24
struct TPMEmulator {
25
TPMBackend parent;
26
27
- TPMEmulatorOptions *options;
28
+ TpmTypeOptions *options;
29
CharBackend ctrl_chr;
30
QIOChannel *data_ioc;
31
TPMVersion tpm_version;
32
@@ -XXX,XX +XXX,XX @@ err_exit:
29
@@ -XXX,XX +XXX,XX @@ err_exit:
33
return -1;
30
return -1;
34
}
31
}
35
32
36
-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)
37
+static int tpm_emulator_handle_device_opts(TPMEmulator *tpm_emu, TpmTypeOptions *opts)
34
+static int tpm_emulator_handle_device_opts(TPMEmulator *tpm_emu,
35
+ TpmCreateOptions *opts)
38
{
36
{
39
- const char *value;
37
- const char *value;
40
Error *err = NULL;
38
Error *err = NULL;
41
Chardev *dev;
39
Chardev *dev;
42
40
43
- value = qemu_opt_get(opts, "chardev");
41
- value = qemu_opt_get(opts, "chardev");
44
- if (!value) {
42
- if (!value) {
45
- error_report("tpm-emulator: parameter 'chardev' is missing");
43
- error_report("tpm-emulator: parameter 'chardev' is missing");
46
- goto err;
44
- goto err;
47
- }
45
- }
48
+ tpm_emu->options = opts;
46
+ tpm_emu->options = QAPI_CLONE(TPMEmulatorOptions, &opts->u.emulator);
49
+ tpm_emu->data_ioc = NULL;
47
+ tpm_emu->data_ioc = NULL;
50
48
51
- dev = qemu_chr_find(value);
49
- dev = qemu_chr_find(value);
52
+ dev = qemu_chr_find(opts->u.emulator.chardev);
50
+ dev = qemu_chr_find(opts->u.emulator.chardev);
53
if (!dev) {
51
if (!dev) {
54
- error_report("tpm-emulator: tpm chardev '%s' not found", value);
52
- error_report("tpm-emulator: tpm chardev '%s' not found", value);
55
+ error_report("tpm-emulator: tpm chardev '%s' not found",
53
+ error_report("tpm-emulator: tpm chardev '%s' not found",
56
+ opts->u.emulator.chardev);
54
+ opts->u.emulator.chardev);
57
goto err;
55
goto err;
58
}
56
}
59
57
60
if (!qemu_chr_fe_init(&tpm_emu->ctrl_chr, dev, &err)) {
58
if (!qemu_chr_fe_init(&tpm_emu->ctrl_chr, dev, &err)) {
61
error_prepend(&err, "tpm-emulator: No valid chardev found at '%s':",
59
error_prepend(&err, "tpm-emulator: No valid chardev found at '%s':",
...
...
68
- tpm_emu->options->chardev = g_strdup(value);
66
- tpm_emu->options->chardev = g_strdup(value);
69
-
67
-
70
if (tpm_emulator_prepare_data_fd(tpm_emu) < 0) {
68
if (tpm_emulator_prepare_data_fd(tpm_emu) < 0) {
71
goto err;
69
goto err;
72
}
70
}
73
@@ -XXX,XX +XXX,XX @@ static int tpm_emulator_handle_device_opts(TPMEmulator *tpm_emu, QemuOpts *opts)
74
if (tpm_util_test_tpmdev(QIO_CHANNEL_SOCKET(tpm_emu->data_ioc)->fd,
75
&tpm_emu->tpm_version)) {
76
error_report("'%s' is not emulating TPM device. Error: %s",
77
- tpm_emu->options->chardev, strerror(errno));
78
+ tpm_emu->options->u.emulator.chardev, strerror(errno));
79
goto err;
80
}
81
82
@@ -XXX,XX +XXX,XX @@ err:
71
@@ -XXX,XX +XXX,XX @@ err:
83
return -1;
72
return -1;
84
}
73
}
85
74
86
-static TPMBackend *tpm_emulator_create(QemuOpts *opts)
75
-static TPMBackend *tpm_emulator_create(QemuOpts *opts)
87
+static TPMBackend *tpm_emulator_create(TpmTypeOptions *opts)
76
+static TPMBackend *tpm_emulator_create(TpmCreateOptions *opts)
88
{
77
{
89
TPMBackend *tb = TPM_BACKEND(object_new(TYPE_TPM_EMULATOR));
78
TPMBackend *tb = TPM_BACKEND(object_new(TYPE_TPM_EMULATOR));
90
79
91
@@ -XXX,XX +XXX,XX @@ static TPMBackend *tpm_emulator_create(QemuOpts *opts)
92
static TpmTypeOptions *tpm_emulator_get_tpm_options(TPMBackend *tb)
93
{
94
TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
95
- TpmTypeOptions *options = g_new0(TpmTypeOptions, 1);
96
+ TpmTypeOptions *options;
97
98
- options->type = TPM_TYPE_EMULATOR;
99
- options->u.emulator.data = QAPI_CLONE(TPMEmulatorOptions, tpm_emu->options);
100
+ options = QAPI_CLONE(TpmTypeOptions, tpm_emu->options);
101
102
return options;
103
}
104
@@ -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)
105
81
106
trace_tpm_emulator_inst_init();
82
trace_tpm_emulator_inst_init();
107
83
108
- tpm_emu->options = g_new0(TPMEmulatorOptions, 1);
84
- tpm_emu->options = g_new0(TPMEmulatorOptions, 1);
...
...
116
- if (!tpm_emu->options->chardev) {
92
- if (!tpm_emu->options->chardev) {
117
+ if (!tpm_emu->data_ioc) {
93
+ if (!tpm_emu->data_ioc) {
118
/* was never properly initialized */
94
/* was never properly initialized */
119
return;
95
return;
120
}
96
}
121
@@ -XXX,XX +XXX,XX @@ static void tpm_emulator_inst_finalize(Object *obj)
122
123
qemu_chr_fe_deinit(&tpm_emu->ctrl_chr, false);
124
125
- qapi_free_TPMEmulatorOptions(tpm_emu->options);
126
+ qapi_free_TpmTypeOptions(tpm_emu->options);
127
128
if (tpm_emu->migration_blocker) {
129
migrate_del_blocker(tpm_emu->migration_blocker);
130
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
131
index XXXXXXX..XXXXXXX 100644
98
index XXXXXXX..XXXXXXX 100644
132
--- a/backends/tpm/tpm_passthrough.c
99
--- a/backends/tpm/tpm_passthrough.c
133
+++ b/backends/tpm/tpm_passthrough.c
100
+++ b/backends/tpm/tpm_passthrough.c
134
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(TPMPassthruState, TPM_PASSTHROUGH)
135
struct TPMPassthruState {
136
TPMBackend parent;
137
138
- TPMPassthroughOptions *options;
139
+ TpmTypeOptions *options;
140
const char *tpm_dev;
141
int tpm_fd;
142
bool tpm_executing;
143
@@ -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)
144
char *dev;
102
}
145
char path[PATH_MAX];
146
147
- if (tpm_pt->options->cancel_path) {
148
- fd = qemu_open_old(tpm_pt->options->cancel_path, O_WRONLY);
149
+ if (tpm_pt->options->u.passthrough.cancel_path) {
150
+ fd = qemu_open_old(tpm_pt->options->u.passthrough.cancel_path, O_WRONLY);
151
if (fd < 0) {
152
error_report("tpm_passthrough: Could not open TPM cancel path: %s",
153
strerror(errno));
154
@@ -XXX,XX +XXX,XX @@ static int tpm_passthrough_open_sysfs_cancel(TPMPassthruState *tpm_pt)
155
if (fd < 0) {
156
error_report("tpm_passthrough: Could not guess TPM cancel path");
157
} else {
158
- tpm_pt->options->cancel_path = g_strdup(path);
159
+ tpm_pt->options->u.passthrough.cancel_path = g_strdup(path);
160
}
161
162
return fd;
163
}
164
103
165
static int
104
static int
166
-tpm_passthrough_handle_device_opts(TPMPassthruState *tpm_pt, QemuOpts *opts)
105
-tpm_passthrough_handle_device_opts(TPMPassthruState *tpm_pt, QemuOpts *opts)
167
+tpm_passthrough_handle_device_opts(TPMPassthruState *tpm_pt, TpmTypeOptions *opts)
106
+tpm_passthrough_handle_device_opts(TPMPassthruState *tpm_pt,
107
+ TpmCreateOptions *opts)
168
{
108
{
169
- const char *value;
109
- const char *value;
170
+ tpm_pt->options = opts;
110
+ tpm_pt->options = QAPI_CLONE(TPMPassthroughOptions, &opts->u.passthrough);
171
111
172
- value = qemu_opt_get(opts, "cancel-path");
112
- value = qemu_opt_get(opts, "cancel-path");
173
- if (value) {
113
- if (value) {
174
- tpm_pt->options->cancel_path = g_strdup(value);
114
- tpm_pt->options->cancel_path = g_strdup(value);
175
- tpm_pt->options->has_cancel_path = true;
176
- }
115
- }
177
-
116
-
178
- value = qemu_opt_get(opts, "path");
117
- value = qemu_opt_get(opts, "path");
179
- if (value) {
118
- if (value) {
180
- tpm_pt->options->has_path = true;
181
- tpm_pt->options->path = g_strdup(value);
119
- tpm_pt->options->path = g_strdup(value);
182
- }
120
- }
183
-
121
-
184
- tpm_pt->tpm_dev = value ? value : TPM_PASSTHROUGH_DEFAULT_DEVICE;
122
- tpm_pt->tpm_dev = value ? value : TPM_PASSTHROUGH_DEFAULT_DEVICE;
185
+ tpm_pt->tpm_dev = opts->u.passthrough.has_path ? opts->u.passthrough.path : TPM_PASSTHROUGH_DEFAULT_DEVICE;
123
+ tpm_pt->tpm_dev = opts->u.passthrough.path ? opts->u.passthrough.path :
124
+ TPM_PASSTHROUGH_DEFAULT_DEVICE;
186
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);
187
if (tpm_pt->tpm_fd < 0) {
126
if (tpm_pt->tpm_fd < 0) {
188
error_report("Cannot access TPM device using '%s': %s",
127
error_report("Cannot access TPM device using '%s': %s",
189
@@ -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)
190
return 0;
129
return 0;
191
}
130
}
192
131
193
-static TPMBackend *tpm_passthrough_create(QemuOpts *opts)
132
-static TPMBackend *tpm_passthrough_create(QemuOpts *opts)
194
+static TPMBackend *tpm_passthrough_create(TpmTypeOptions *tto)
133
+static TPMBackend *tpm_passthrough_create(TpmCreateOptions *tco)
195
{
134
{
196
Object *obj = object_new(TYPE_TPM_PASSTHROUGH);
135
Object *obj = object_new(TYPE_TPM_PASSTHROUGH);
197
136
198
- if (tpm_passthrough_handle_device_opts(TPM_PASSTHROUGH(obj), opts)) {
137
- if (tpm_passthrough_handle_device_opts(TPM_PASSTHROUGH(obj), opts)) {
199
+ if (tpm_passthrough_handle_device_opts(TPM_PASSTHROUGH(obj), tto)) {
138
+ if (tpm_passthrough_handle_device_opts(TPM_PASSTHROUGH(obj), tco)) {
200
object_unref(obj);
139
object_unref(obj);
201
return NULL;
140
return NULL;
202
}
141
}
203
@@ -XXX,XX +XXX,XX @@ static TpmTypeOptions *tpm_passthrough_get_tpm_options(TPMBackend *tb)
204
{
205
TpmTypeOptions *options = g_new0(TpmTypeOptions, 1);
206
207
- options->type = TPM_TYPE_PASSTHROUGH;
208
- options->u.passthrough.data = QAPI_CLONE(TPMPassthroughOptions,
209
- TPM_PASSTHROUGH(tb)->options);
210
+ options = QAPI_CLONE(TpmTypeOptions, TPM_PASSTHROUGH(tb)->options);
211
212
return options;
213
}
214
@@ -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)
215
{
143
{
216
TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(obj);
144
TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(obj);
217
145
218
- tpm_pt->options = g_new0(TPMPassthroughOptions, 1);
146
- tpm_pt->options = g_new0(TPMPassthroughOptions, 1);
219
tpm_pt->tpm_fd = -1;
147
tpm_pt->tpm_fd = -1;
220
tpm_pt->cancel_fd = -1;
148
tpm_pt->cancel_fd = -1;
221
}
149
}
222
@@ -XXX,XX +XXX,XX @@ static void tpm_passthrough_inst_finalize(Object *obj)
223
if (tpm_pt->cancel_fd >= 0) {
224
qemu_close(tpm_pt->cancel_fd);
225
}
226
- qapi_free_TPMPassthroughOptions(tpm_pt->options);
227
+ qapi_free_TpmTypeOptions(tpm_pt->options);
228
}
229
230
static void tpm_passthrough_class_init(ObjectClass *klass, void *data)
231
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
232
index XXXXXXX..XXXXXXX 100644
151
index XXXXXXX..XXXXXXX 100644
233
--- a/include/sysemu/tpm.h
152
--- a/include/sysemu/tpm.h
234
+++ b/include/sysemu/tpm.h
153
+++ b/include/sysemu/tpm.h
235
@@ -XXX,XX +XXX,XX @@
154
@@ -XXX,XX +XXX,XX @@
155
236
#ifdef CONFIG_TPM
156
#ifdef CONFIG_TPM
237
157
238
int tpm_config_parse(QemuOptsList *opts_list, const char *optarg);
158
-int tpm_config_parse(QemuOptsList *opts_list, const char *optstr);
239
-int tpm_init(void);
159
-int tpm_init(void);
160
+void tpm_config_parse(const char *optstr);
240
+void tpm_init(void);
161
+void tpm_init(void);
162
+
241
void tpm_cleanup(void);
163
void tpm_cleanup(void);
242
164
243
typedef enum TPMVersion {
165
typedef enum TPMVersion {
244
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
245
index XXXXXXX..XXXXXXX 100644
167
index XXXXXXX..XXXXXXX 100644
...
...
248
@@ -XXX,XX +XXX,XX @@ struct TPMBackendClass {
170
@@ -XXX,XX +XXX,XX @@ struct TPMBackendClass {
249
/* 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 */
250
const char *desc;
172
const char *desc;
251
173
252
- TPMBackend *(*create)(QemuOpts *opts);
174
- TPMBackend *(*create)(QemuOpts *opts);
253
+ TPMBackend *(*create)(TpmTypeOptions *tto);
175
+ TPMBackend *(*create)(TpmCreateOptions *tco);
254
176
255
/* start up the TPM on the backend - optional */
177
/* start up the TPM on the backend - optional */
256
int (*startup_tpm)(TPMBackend *t, size_t buffersize);
178
int (*startup_tpm)(TPMBackend *t, size_t buffersize);
257
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
258
index XXXXXXX..XXXXXXX 100644
259
--- a/monitor/hmp-cmds.c
260
+++ b/monitor/hmp-cmds.c
261
@@ -XXX,XX +XXX,XX @@ void hmp_info_tpm(Monitor *mon, const QDict *qdict)
262
263
switch (ti->options->type) {
264
case TPM_TYPE_PASSTHROUGH:
265
- tpo = ti->options->u.passthrough.data;
266
+ tpo = &ti->options->u.passthrough;
267
monitor_printf(mon, "%s%s%s%s",
268
tpo->has_path ? ",path=" : "",
269
tpo->has_path ? tpo->path : "",
270
@@ -XXX,XX +XXX,XX @@ void hmp_info_tpm(Monitor *mon, const QDict *qdict)
271
tpo->has_cancel_path ? tpo->cancel_path : "");
272
break;
273
case TPM_TYPE_EMULATOR:
274
- teo = ti->options->u.emulator.data;
275
+ teo = &ti->options->u.emulator;
276
monitor_printf(mon, ",chardev=%s", teo->chardev);
277
break;
278
case TPM_TYPE__MAX:
279
diff --git a/qapi/tpm.json b/qapi/tpm.json
179
diff --git a/qapi/tpm.json b/qapi/tpm.json
280
index XXXXXXX..XXXXXXX 100644
180
index XXXXXXX..XXXXXXX 100644
281
--- a/qapi/tpm.json
181
--- a/qapi/tpm.json
282
+++ b/qapi/tpm.json
182
+++ b/qapi/tpm.json
283
@@ -XXX,XX +XXX,XX @@
183
@@ -XXX,XX +XXX,XX @@
284
{ 'struct': 'TPMEmulatorOptions', 'data': { 'chardev' : 'str' },
184
'emulator': 'TPMEmulatorOptionsWrapper' },
285
'if': 'CONFIG_TPM' }
185
'if': 'CONFIG_TPM' }
286
186
287
-##
187
+##
288
-# @TPMPassthroughOptionsWrapper:
188
+# @TpmCreateOptions:
289
-#
189
+#
290
-# Since: 1.5
190
+# A union referencing different TPM backend types' configuration options
291
-##
191
+# without the wrapper to be usable by visitors.
292
-{ 'struct': 'TPMPassthroughOptionsWrapper',
192
+#
293
- 'data': { 'data': 'TPMPassthroughOptions' },
193
+# @type: - 'passthrough' The configuration options for the TPM passthrough type
294
- 'if': 'CONFIG_TPM' }
194
+# - 'emulator' The configuration options for TPM emulator backend type
295
-
195
+#
296
-##
196
+# @id: The Id of the TPM
297
-# @TPMEmulatorOptionsWrapper:
197
+#
298
-#
198
+# Since: 9.0
299
-# Since: 2.11
199
+##
300
-##
200
+{ 'union': 'TpmCreateOptions',
301
-{ 'struct': 'TPMEmulatorOptionsWrapper',
302
- 'data': { 'data': 'TPMEmulatorOptions' },
303
- 'if': 'CONFIG_TPM' }
304
-
305
##
306
# @TpmTypeOptions:
307
#
308
# A union referencing different TPM backend types' configuration options
309
#
310
+# @id: identifier of the backend
311
# @type: - 'passthrough' The configuration options for the TPM passthrough type
312
# - 'emulator' The configuration options for TPM emulator backend type
313
#
314
# Since: 1.5
315
##
316
{ 'union': 'TpmTypeOptions',
317
- 'base': { 'type': 'TpmType' },
318
+ 'base': { 'type': 'TpmType',
201
+ 'base': { 'type': 'TpmType',
319
+ 'id': 'str' },
202
+ 'id' : 'str' },
320
'discriminator': 'type',
203
+ 'discriminator': 'type',
321
- 'data': { 'passthrough' : 'TPMPassthroughOptionsWrapper',
322
- 'emulator': 'TPMEmulatorOptionsWrapper' },
323
+ 'data': { 'passthrough' : 'TPMPassthroughOptions',
204
+ 'data': { 'passthrough' : 'TPMPassthroughOptions',
324
+ 'emulator': 'TPMEmulatorOptions' },
205
+ 'emulator': 'TPMEmulatorOptions' },
325
'if': 'CONFIG_TPM' }
206
+ 'if': 'CONFIG_TPM' }
326
207
+
327
##
208
##
328
diff --git a/softmmu/tpm.c b/softmmu/tpm.c
209
# @TPMInfo:
329
index XXXXXXX..XXXXXXX 100644
210
#
330
--- a/softmmu/tpm.c
211
diff --git a/system/tpm.c b/system/tpm.c
331
+++ b/softmmu/tpm.c
212
index XXXXXXX..XXXXXXX 100644
213
--- a/system/tpm.c
214
+++ b/system/tpm.c
332
@@ -XXX,XX +XXX,XX @@
215
@@ -XXX,XX +XXX,XX @@
333
#include "qapi/error.h"
216
#include "qapi/error.h"
334
#include "qapi/qapi-commands-tpm.h"
217
#include "qapi/qapi-commands-tpm.h"
335
#include "qapi/qmp/qerror.h"
218
#include "qapi/qmp/qerror.h"
336
+#include "qapi/qobject-input-visitor.h"
219
+#include "qapi/qobject-input-visitor.h"
...
...
342
+#include "qemu/help_option.h"
225
+#include "qemu/help_option.h"
343
226
344
static QLIST_HEAD(, TPMBackend) tpm_backends =
227
static QLIST_HEAD(, TPMBackend) tpm_backends =
345
QLIST_HEAD_INITIALIZER(tpm_backends);
228
QLIST_HEAD_INITIALIZER(tpm_backends);
346
229
347
+typedef struct TpmTypeOptionsQueueEntry {
230
+typedef struct TpmCreateOptionsQueueEntry {
348
+ TpmTypeOptions *tto;
231
+ TpmCreateOptions *tco;
349
+ QSIMPLEQ_ENTRY(TpmTypeOptionsQueueEntry) entry;
232
+ QSIMPLEQ_ENTRY(TpmCreateOptionsQueueEntry) entry;
350
+} TpmTypeOptionsQueueEntry;
233
+} TpmCreateOptionsQueueEntry;
351
+
234
+
352
+typedef QSIMPLEQ_HEAD(, TpmTypeOptionsQueueEntry) TpmTypeOptionsQueue;
235
+typedef QSIMPLEQ_HEAD(, TpmCreateOptionsQueueEntry) TpmCreateOptionsQueue;
353
+
236
+
354
+static TpmTypeOptionsQueue tto_queue = QSIMPLEQ_HEAD_INITIALIZER(tto_queue);
237
+static TpmCreateOptionsQueue tco_queue = QSIMPLEQ_HEAD_INITIALIZER(tco_queue);
355
+
238
+
356
static const TPMBackendClass *
239
static const TPMBackendClass *
357
tpm_be_find_by_type(enum TpmType type)
240
tpm_be_find_by_type(enum TpmType type)
358
{
241
{
359
@@ -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)
360
return NULL;
243
return NULL;
361
}
244
}
362
245
363
-static int tpm_init_tpmdev(void *dummy, QemuOpts *opts, Error **errp)
246
-static int tpm_init_tpmdev(void *dummy, QemuOpts *opts, Error **errp)
364
+static void tpm_init_tpmdev(TpmTypeOptions *tto)
247
+static void tpm_init_tpmdev(TpmCreateOptions *tco)
365
{
248
{
366
- /*
249
- /*
367
- * Use of error_report() in a function with an Error ** parameter
250
- * Use of error_report() in a function with an Error ** parameter
368
- * is suspicious. It is okay here. The parameter only exists to
251
- * is suspicious. It is okay here. The parameter only exists to
369
- * make the function usable with qemu_opts_foreach(). It is not
252
- * make the function usable with qemu_opts_foreach(). It is not
...
...
382
+ exit(1);
265
+ exit(1);
383
}
266
}
384
267
385
- id = qemu_opts_id(opts);
268
- id = qemu_opts_id(opts);
386
- if (id == NULL) {
269
- if (id == NULL) {
387
+ if (!tto->id) {
270
- error_report(QERR_MISSING_PARAMETER, "id");
388
error_report(QERR_MISSING_PARAMETER, "id");
271
- return 1;
389
- return 1;
272
- }
390
+ exit(1);
273
-
391
}
392
393
- value = qemu_opt_get(opts, "type");
274
- value = qemu_opt_get(opts, "type");
394
- if (!value) {
275
- if (!value) {
395
- error_report(QERR_MISSING_PARAMETER, "type");
276
- error_report(QERR_MISSING_PARAMETER, "type");
396
- tpm_display_backend_drivers();
277
- tpm_display_backend_drivers();
397
- return 1;
278
- return 1;
398
- }
279
- }
399
-
280
-
400
- i = qapi_enum_parse(&TpmType_lookup, value, -1, NULL);
281
- i = qapi_enum_parse(&TpmType_lookup, value, -1, NULL);
401
- be = i >= 0 ? tpm_be_find_by_type(i) : NULL;
282
- be = i >= 0 ? tpm_be_find_by_type(i) : NULL;
402
+ be = tto->type >= 0 ? tpm_be_find_by_type(tto->type) : NULL;
283
+ be = tco->type >= 0 ? tpm_be_find_by_type(tco->type) : NULL;
403
if (be == NULL) {
284
if (be == NULL) {
404
error_report(QERR_INVALID_PARAMETER_VALUE,
285
error_report(QERR_INVALID_PARAMETER_VALUE,
405
"type", "a TPM backend type");
286
"type", "a TPM backend type");
406
tpm_display_backend_drivers();
287
tpm_display_backend_drivers();
407
- return 1;
288
- return 1;
...
...
413
- return 1;
294
- return 1;
414
+ exit(1);
295
+ exit(1);
415
}
296
}
416
297
417
- drv = be->create(opts);
298
- drv = be->create(opts);
418
+ drv = be->create(tto);
299
+ drv = be->create(tco);
419
if (!drv) {
300
if (!drv) {
420
- return 1;
301
- return 1;
421
+ exit(1);
302
+ exit(1);
422
}
303
}
423
304
424
- drv->id = g_strdup(id);
305
- drv->id = g_strdup(id);
425
+ drv->id = g_strdup(tto->id);
306
+ drv->id = g_strdup(tco->id);
426
QLIST_INSERT_HEAD(&tpm_backends, drv, list);
307
QLIST_INSERT_HEAD(&tpm_backends, drv, list);
427
-
308
-
428
- return 0;
309
- return 0;
429
}
310
}
430
311
...
...
438
{
319
{
439
- if (qemu_opts_foreach(qemu_find_opts("tpmdev"),
320
- if (qemu_opts_foreach(qemu_find_opts("tpmdev"),
440
- tpm_init_tpmdev, NULL, NULL)) {
321
- tpm_init_tpmdev, NULL, NULL)) {
441
- return -1;
322
- return -1;
442
- }
323
- }
443
+ while (!QSIMPLEQ_EMPTY(&tto_queue)) {
324
+ while (!QSIMPLEQ_EMPTY(&tco_queue)) {
444
+ TpmTypeOptionsQueueEntry *ttoqe = QSIMPLEQ_FIRST(&tto_queue);
325
+ TpmCreateOptionsQueueEntry *tcoqe = QSIMPLEQ_FIRST(&tco_queue);
445
326
446
- return 0;
327
- return 0;
447
+ QSIMPLEQ_REMOVE_HEAD(&tto_queue, entry);
328
+ QSIMPLEQ_REMOVE_HEAD(&tco_queue, entry);
448
+ tpm_init_tpmdev(ttoqe->tto);
329
+ tpm_init_tpmdev(tcoqe->tco);
449
+ g_free(ttoqe);
330
+ qapi_free_TpmCreateOptions(tcoqe->tco);
331
+ g_free(tcoqe);
450
+ }
332
+ }
451
}
333
}
452
334
453
/*
335
/*
454
@@ -XXX,XX +XXX,XX @@ int tpm_init(void)
336
* Parse the TPM configuration options.
337
* To display all available TPM backends the user may use '-tpmdev help'
455
*/
338
*/
456
int tpm_config_parse(QemuOptsList *opts_list, const char *optarg)
339
-int tpm_config_parse(QemuOptsList *opts_list, const char *optstr)
340
+void tpm_config_parse(const char *optstr)
457
{
341
{
458
- QemuOpts *opts;
342
- QemuOpts *opts;
459
+ Visitor *v;
343
+ Visitor *v;
460
+ TpmTypeOptionsQueueEntry *toqe;
344
+ TpmCreateOptionsQueueEntry *tcqe;
461
345
462
- if (!strcmp(optarg, "help")) {
346
- if (!strcmp(optstr, "help")) {
463
+ if (is_help_option(optarg)) {
347
+ if (is_help_option(optstr)) {
464
tpm_display_backend_drivers();
348
tpm_display_backend_drivers();
465
return -1;
349
- return -1;
466
}
350
- }
467
- opts = qemu_opts_parse_noisily(opts_list, optarg, true);
351
- opts = qemu_opts_parse_noisily(opts_list, optstr, true);
468
- if (!opts) {
352
- if (!opts) {
469
- return -1;
353
- return -1;
470
- }
354
+ exit(0);
471
+ v = qobject_input_visitor_new_str(optarg, "type", &error_fatal);
355
}
472
+ toqe = g_new(TpmTypeOptionsQueueEntry, 1);
356
- return 0;
473
+ visit_type_TpmTypeOptions(v, NULL, &toqe->tto, &error_fatal);
357
+ v = qobject_input_visitor_new_str(optstr, "type", &error_fatal);
358
+ tcqe = g_new(TpmCreateOptionsQueueEntry, 1);
359
+ visit_type_TpmCreateOptions(v, NULL, &tcqe->tco, &error_fatal);
474
+ visit_free(v);
360
+ visit_free(v);
475
+ QSIMPLEQ_INSERT_TAIL(&tto_queue, toqe, entry);
361
+ QSIMPLEQ_INSERT_TAIL(&tco_queue, tcqe, entry);
476
return 0;
362
}
477
}
363
478
364
/*
479
diff --git a/softmmu/vl.c b/softmmu/vl.c
365
diff --git a/system/vl.c b/system/vl.c
480
index XXXXXXX..XXXXXXX 100644
366
index XXXXXXX..XXXXXXX 100644
481
--- a/softmmu/vl.c
367
--- a/system/vl.c
482
+++ b/softmmu/vl.c
368
+++ b/system/vl.c
369
@@ -XXX,XX +XXX,XX @@ static QemuOptsList qemu_object_opts = {
370
},
371
};
372
373
-static QemuOptsList qemu_tpmdev_opts = {
374
- .name = "tpmdev",
375
- .implied_opt_name = "type",
376
- .head = QTAILQ_HEAD_INITIALIZER(qemu_tpmdev_opts.head),
377
- .desc = {
378
- /* options are defined in the TPM backends */
379
- { /* end of list */ }
380
- },
381
-};
382
-
383
static QemuOptsList qemu_overcommit_opts = {
384
.name = "overcommit",
385
.head = QTAILQ_HEAD_INITIALIZER(qemu_overcommit_opts.head),
483
@@ -XXX,XX +XXX,XX @@ static void qemu_create_late_backends(void)
386
@@ -XXX,XX +XXX,XX @@ static void qemu_create_late_backends(void)
484
387
exit(1);
485
object_option_foreach_add(object_create_late);
388
}
486
389
487
- if (tpm_init() < 0) {
390
- if (tpm_init() < 0) {
488
- exit(1);
391
- exit(1);
489
- }
392
- }
490
+ tpm_init();
393
+ tpm_init();
491
394
492
qemu_opts_foreach(qemu_find_opts("mon"),
395
qemu_opts_foreach(qemu_find_opts("mon"),
493
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)
398
qemu_add_opts(&qemu_boot_opts);
399
qemu_add_opts(&qemu_add_fd_opts);
400
qemu_add_opts(&qemu_object_opts);
401
- qemu_add_opts(&qemu_tpmdev_opts);
402
qemu_add_opts(&qemu_overcommit_opts);
403
qemu_add_opts(&qemu_msg_opts);
404
qemu_add_opts(&qemu_name_opts);
405
@@ -XXX,XX +XXX,XX @@ void qemu_init(int argc, char **argv)
406
break;
407
#ifdef CONFIG_TPM
408
case QEMU_OPTION_tpmdev:
409
- if (tpm_config_parse(qemu_find_opts("tpmdev"), optarg) < 0) {
410
- exit(1);
411
- }
412
+ tpm_config_parse(optarg);
413
break;
414
#endif
415
case QEMU_OPTION_mempath:
494
--
416
--
495
2.35.3
417
2.35.3
diff view generated by jsdifflib
1
From: James Bottomley <James.Bottomley@HansenPartnership.com>
2
3
The Microsoft Simulator (mssim) is the reference emulation platform
1
The Microsoft Simulator (mssim) is the reference emulation platform
4
for the TCG TPM 2.0 specification.
2
for the TCG TPM 2.0 specification.
5
3
6
https://github.com/Microsoft/ms-tpm-20-ref.git
4
https://github.com/Microsoft/ms-tpm-20-ref.git
7
5
8
It exports a fairly simple network socket baset protocol on two
6
It exports a fairly simple network socket based protocol on two
9
sockets, one for command (default 2321) and one for control (default
7
sockets, one for command (default 2321) and one for control (default
10
2322). This patch adds a simple backend that can speak the mssim
8
2322). This patch adds a simple backend that can speak the mssim
11
protocol over the network. It also allows the host, and two ports to
9
protocol over the network. It also allows the two sockets to be
12
be specified on the qemu command line. The benefits are twofold:
10
specified on the command line. The benefits are twofold: firstly it
13
firstly it gives us a backend that actually speaks a standard TPM
11
gives us a backend that actually speaks a standard TPM emulation
14
emulation protocol instead of the linux specific TPM driver format of
12
protocol instead of the linux specific TPM driver format of the
15
the current emulated TPM backend and secondly, using the microsoft
13
current emulated TPM backend and secondly, using the microsoft
16
protocol, the end point of the emulator can be anywhere on the
14
protocol, the end point of the emulator can be anywhere on the
17
network, facilitating the cloud use case where a central TPM service
15
network, facilitating the cloud use case where a central TPM service
18
can be used over a control network.
16
can be used over a control network.
19
17
20
The implementation does basic control commands like power off/on, but
18
The implementation does basic control commands like power off/on, but
...
...
34
32
35
-tpmdev "{'type':'mssim','id':'tpm0','command':{'type':inet,'host':'remote','port':'2321'}}"
33
-tpmdev "{'type':'mssim','id':'tpm0','command':{'type':inet,'host':'remote','port':'2321'}}"
36
34
37
tpm-tis also works as the backend.
35
tpm-tis also works as the backend.
38
36
39
Signed-off-by: James Bottomley <jejb@linux.ibm.com>
37
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
38
Acked-by: Markus Armbruster <armbru@redhat.com>
40
39
41
---
40
---
42
41
43
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
44
to test outside influence and add docs.
45
v7: TPMmssim -> TPMMssim; doc and json fixes
46
Make command socket open each time (makes OS debugging easier)
47
v11: add startup method to make sure TPM is reset on reboot
44
---
48
---
45
MAINTAINERS | 5 +
49
MAINTAINERS | 6 +
46
backends/tpm/Kconfig | 5 +
50
backends/tpm/Kconfig | 5 +
47
backends/tpm/meson.build | 1 +
51
backends/tpm/meson.build | 1 +
48
backends/tpm/tpm_mssim.c | 251 +++++++++++++++++++++++++++++++++++++++
52
backends/tpm/tpm_mssim.c | 335 +++++++++++++++++++++++++++++++++++++++
49
backends/tpm/tpm_mssim.h | 43 +++++++
53
backends/tpm/tpm_mssim.h | 44 +++++
50
monitor/hmp-cmds.c | 7 ++
54
docs/specs/tpm.rst | 39 +++++
51
qapi/tpm.json | 25 +++-
55
qapi/tpm.json | 31 +++-
52
7 files changed, 334 insertions(+), 3 deletions(-)
56
system/tpm-hmp-cmds.c | 9 ++
57
8 files changed, 466 insertions(+), 4 deletions(-)
53
create mode 100644 backends/tpm/tpm_mssim.c
58
create mode 100644 backends/tpm/tpm_mssim.c
54
create mode 100644 backends/tpm/tpm_mssim.h
59
create mode 100644 backends/tpm/tpm_mssim.h
55
60
56
diff --git a/MAINTAINERS b/MAINTAINERS
61
diff --git a/MAINTAINERS b/MAINTAINERS
57
index XXXXXXX..XXXXXXX 100644
62
index XXXXXXX..XXXXXXX 100644
58
--- a/MAINTAINERS
63
--- a/MAINTAINERS
59
+++ b/MAINTAINERS
64
+++ b/MAINTAINERS
60
@@ -XXX,XX +XXX,XX @@ F: backends/tpm/
65
@@ -XXX,XX +XXX,XX @@ F: include/hw/acpi/tpm.h
66
F: include/sysemu/tpm*
67
F: qapi/tpm.json
68
F: backends/tpm/
69
+X: backends/tpm/tpm_mssim.*
61
F: tests/qtest/*tpm*
70
F: tests/qtest/*tpm*
71
F: docs/specs/tpm.rst
62
T: git https://github.com/stefanberger/qemu-tpm.git tpm-next
72
T: git https://github.com/stefanberger/qemu-tpm.git tpm-next
63
73
64
+MSSIM TPM Backend
74
+MSSIM TPM Backend
65
+M: James Bottomley <jejb@linux.ibm.com>
75
+M: James Bottomley <jejb@linux.ibm.com>
66
+S: Maintained
76
+S: Maintained
67
+F: backends/tpm/tpm_mssim.*
77
+F: backends/tpm/tpm_mssim.*
68
+
78
+
69
Checkpatch
79
SPDM
70
S: Odd Fixes
80
M: Alistair Francis <alistair.francis@wdc.com>
71
F: scripts/checkpatch.pl
81
S: Maintained
72
diff --git a/backends/tpm/Kconfig b/backends/tpm/Kconfig
82
diff --git a/backends/tpm/Kconfig b/backends/tpm/Kconfig
73
index XXXXXXX..XXXXXXX 100644
83
index XXXXXXX..XXXXXXX 100644
74
--- a/backends/tpm/Kconfig
84
--- a/backends/tpm/Kconfig
75
+++ b/backends/tpm/Kconfig
85
+++ b/backends/tpm/Kconfig
76
@@ -XXX,XX +XXX,XX @@ config TPM_EMULATOR
86
@@ -XXX,XX +XXX,XX @@ config TPM_EMULATOR
...
...
85
diff --git a/backends/tpm/meson.build b/backends/tpm/meson.build
95
diff --git a/backends/tpm/meson.build b/backends/tpm/meson.build
86
index XXXXXXX..XXXXXXX 100644
96
index XXXXXXX..XXXXXXX 100644
87
--- a/backends/tpm/meson.build
97
--- a/backends/tpm/meson.build
88
+++ b/backends/tpm/meson.build
98
+++ b/backends/tpm/meson.build
89
@@ -XXX,XX +XXX,XX @@ if have_tpm
99
@@ -XXX,XX +XXX,XX @@ if have_tpm
90
softmmu_ss.add(files('tpm_util.c'))
100
system_ss.add(files('tpm_util.c'))
91
softmmu_ss.add(when: 'CONFIG_TPM_PASSTHROUGH', if_true: files('tpm_passthrough.c'))
101
system_ss.add(when: 'CONFIG_TPM_PASSTHROUGH', if_true: files('tpm_passthrough.c'))
92
softmmu_ss.add(when: 'CONFIG_TPM_EMULATOR', if_true: files('tpm_emulator.c'))
102
system_ss.add(when: 'CONFIG_TPM_EMULATOR', if_true: files('tpm_emulator.c'))
93
+ softmmu_ss.add(when: 'CONFIG_TPM_MSSIM', if_true: files('tpm_mssim.c'))
103
+ system_ss.add(when: 'CONFIG_TPM_MSSIM', if_true: files('tpm_mssim.c'))
94
endif
104
endif
95
diff --git a/backends/tpm/tpm_mssim.c b/backends/tpm/tpm_mssim.c
105
diff --git a/backends/tpm/tpm_mssim.c b/backends/tpm/tpm_mssim.c
96
new file mode 100644
106
new file mode 100644
97
index XXXXXXX..XXXXXXX
107
index XXXXXXX..XXXXXXX
98
--- /dev/null
108
--- /dev/null
...
...
113
+#include "qapi/clone-visitor.h"
123
+#include "qapi/clone-visitor.h"
114
+#include "qapi/qapi-visit-tpm.h"
124
+#include "qapi/qapi-visit-tpm.h"
115
+
125
+
116
+#include "io/channel-socket.h"
126
+#include "io/channel-socket.h"
117
+
127
+
128
+#include "sysemu/runstate.h"
118
+#include "sysemu/tpm_backend.h"
129
+#include "sysemu/tpm_backend.h"
119
+#include "sysemu/tpm_util.h"
130
+#include "sysemu/tpm_util.h"
120
+
131
+
121
+#include "qom/object.h"
132
+#include "qom/object.h"
122
+
133
+
123
+#include "tpm_int.h"
134
+#include "tpm_int.h"
124
+#include "tpm_mssim.h"
135
+#include "tpm_mssim.h"
125
+
136
+
126
+#define ERROR_PREFIX "TPM mssim Emulator: "
137
+#define ERROR_PREFIX "TPM mssim Emulator: "
127
+
138
+
128
+#define TYPE_TPM_MSSIM "tpm-mssim"
139
+#define TYPE_TPM_MSSIM "tpm-mssim"
129
+OBJECT_DECLARE_SIMPLE_TYPE(TPMmssim, TPM_MSSIM)
140
+OBJECT_DECLARE_SIMPLE_TYPE(TPMMssim, TPM_MSSIM)
130
+
141
+
131
+struct TPMmssim {
142
+struct TPMMssim {
132
+ TPMBackend parent;
143
+ TPMBackend parent;
133
+
144
+
134
+ TpmTypeOptions *opts;
145
+ TPMMssimOptions opts;
135
+
146
+
136
+ QIOChannelSocket *cmd_qc, *ctrl_qc;
147
+ QIOChannelSocket *cmd_qc, *ctrl_qc;
137
+};
148
+};
138
+
149
+
139
+static int tpm_send_ctrl(TPMmssim *t, uint32_t cmd, Error **errp)
150
+static int tpm_send_ctrl(TPMMssim *t, uint32_t cmd, Error **errp)
140
+{
151
+{
141
+ int ret;
152
+ int ret, retc;
142
+
153
+ Error *local_err = NULL;
154
+
155
+ ret = qio_channel_socket_connect_sync(t->ctrl_qc, t->opts.control, errp);
156
+ if (ret != 0) {
157
+ return ret;
158
+ }
143
+ cmd = htonl(cmd);
159
+ cmd = htonl(cmd);
144
+ ret = qio_channel_write_all(QIO_CHANNEL(t->ctrl_qc), (char *)&cmd, sizeof(cmd), errp);
160
+ ret = qio_channel_write_all(QIO_CHANNEL(t->ctrl_qc),
145
+ if (ret != 0)
161
+ (char *)&cmd, sizeof(cmd), errp);
146
+ return ret;
162
+ if (ret != 0) {
147
+ ret = qio_channel_read_all(QIO_CHANNEL(t->ctrl_qc), (char *)&cmd, sizeof(cmd), errp);
163
+ goto out;
148
+ if (ret != 0)
164
+ }
149
+ return ret;
165
+
166
+ ret = qio_channel_read_all(QIO_CHANNEL(t->ctrl_qc),
167
+ (char *)&cmd, sizeof(cmd), errp);
168
+ if (ret != 0) {
169
+ goto out;
170
+ }
150
+ if (cmd != 0) {
171
+ if (cmd != 0) {
151
+ error_setg(errp, ERROR_PREFIX "Incorrect ACK recieved on control channel 0x%x\n", cmd);
172
+ error_setg(errp, ERROR_PREFIX
152
+ return -1;
173
+ "Incorrect ACK recieved on control channel 0x%x", cmd);
153
+ }
174
+ ret = -1;
154
+ return 0;
175
+ }
176
+ out:
177
+ /*
178
+ * need to close the channel here, but if that fails report it
179
+ * while not letting a prior failure get overwritten
180
+ */
181
+ retc = qio_channel_close(QIO_CHANNEL(t->ctrl_qc), &local_err);
182
+ error_propagate(errp, local_err);
183
+ return retc ? retc : ret;
155
+}
184
+}
156
+
185
+
157
+static void tpm_mssim_instance_init(Object *obj)
186
+static void tpm_mssim_instance_init(Object *obj)
158
+{
187
+{
159
+}
188
+}
160
+
189
+
161
+static void tpm_mssim_instance_finalize(Object *obj)
190
+static void tpm_mssim_instance_finalize(Object *obj)
162
+{
191
+{
163
+ TPMmssim *t = TPM_MSSIM(obj);
192
+ TPMMssim *t = TPM_MSSIM(obj);
164
+
193
+
165
+ if (t->ctrl_qc)
194
+ if (t->cmd_qc && !runstate_check(RUN_STATE_POSTMIGRATE)) {
166
+ tpm_send_ctrl(t, TPM_SIGNAL_POWER_OFF, NULL);
195
+ Error *errp = NULL;
196
+ int ret;
197
+
198
+ ret = tpm_send_ctrl(t, TPM_SIGNAL_POWER_OFF, &errp);
199
+ if (ret != 0) {
200
+ error_report_err(errp);
201
+ }
202
+ }
167
+
203
+
168
+ object_unref(OBJECT(t->ctrl_qc));
204
+ object_unref(OBJECT(t->ctrl_qc));
169
+ object_unref(OBJECT(t->cmd_qc));
205
+ object_unref(OBJECT(t->cmd_qc));
170
+}
206
+}
171
+
207
+
...
...
185
+ return 4096;
221
+ return 4096;
186
+}
222
+}
187
+
223
+
188
+static TpmTypeOptions *tpm_mssim_get_opts(TPMBackend *tb)
224
+static TpmTypeOptions *tpm_mssim_get_opts(TPMBackend *tb)
189
+{
225
+{
190
+ TPMmssim *t = TPM_MSSIM(tb);
226
+ TPMMssim *t = TPM_MSSIM(tb);
191
+ TpmTypeOptions *opts;
227
+ TpmTypeOptions *opts = g_new0(TpmTypeOptions, 1);
192
+
228
+
193
+ opts = QAPI_CLONE(TpmTypeOptions, t->opts);
229
+ opts->type = TPM_TYPE_MSSIM;
230
+ QAPI_CLONE_MEMBERS(TPMMssimOptions, &opts->u.mssim, &t->opts);
194
+
231
+
195
+ return opts;
232
+ return opts;
196
+}
233
+}
197
+
234
+
198
+static void tpm_mssim_handle_request(TPMBackend *tb, TPMBackendCmd *cmd,
235
+static void tpm_mssim_handle_request(TPMBackend *tb, TPMBackendCmd *cmd,
199
+ Error **errp)
236
+ Error **errp)
200
+{
237
+{
201
+ TPMmssim *t = TPM_MSSIM(tb);
238
+ TPMMssim *t = TPM_MSSIM(tb);
202
+ uint32_t header, len;
239
+ uint32_t header, len;
203
+ uint8_t locality = cmd->locty;
240
+ uint8_t locality = cmd->locty;
204
+ struct iovec iov[4];
241
+ struct iovec iov[4];
205
+ int ret;
242
+ int ret;
243
+
244
+ ret = qio_channel_socket_connect_sync(t->cmd_qc, t->opts.command, errp);
245
+ if (ret != 0) {
246
+ goto fail_msg;
247
+ }
206
+
248
+
207
+ header = htonl(TPM_SEND_COMMAND);
249
+ header = htonl(TPM_SEND_COMMAND);
208
+ len = htonl(cmd->in_len);
250
+ len = htonl(cmd->in_len);
209
+
251
+
210
+ iov[0].iov_base = &header;
252
+ iov[0].iov_base = &header;
...
...
215
+ iov[2].iov_len = sizeof(len);
257
+ iov[2].iov_len = sizeof(len);
216
+ iov[3].iov_base = (void *)cmd->in;
258
+ iov[3].iov_base = (void *)cmd->in;
217
+ iov[3].iov_len = cmd->in_len;
259
+ iov[3].iov_len = cmd->in_len;
218
+
260
+
219
+ ret = qio_channel_writev_all(QIO_CHANNEL(t->cmd_qc), iov, 4, errp);
261
+ ret = qio_channel_writev_all(QIO_CHANNEL(t->cmd_qc), iov, 4, errp);
220
+ if (ret != 0)
262
+ if (ret != 0) {
221
+ goto fail;
263
+ goto fail;
222
+
264
+ }
223
+ ret = qio_channel_read_all(QIO_CHANNEL(t->cmd_qc), (char *)&len, sizeof(len), errp);
265
+
224
+ if (ret != 0)
266
+ ret = qio_channel_read_all(QIO_CHANNEL(t->cmd_qc),
225
+ goto fail;
267
+ (char *)&len, sizeof(len), errp);
268
+ if (ret != 0) {
269
+ goto fail;
270
+ }
271
+
226
+ len = ntohl(len);
272
+ len = ntohl(len);
227
+ if (len > cmd->out_len) {
273
+ if (len > cmd->out_len) {
228
+ error_setg(errp, "receive size is too large");
274
+ error_setg(errp, "receive size is too large");
229
+ goto fail;
275
+ goto fail;
230
+ }
276
+ }
231
+ ret = qio_channel_read_all(QIO_CHANNEL(t->cmd_qc), (char *)cmd->out, len, errp);
277
+ ret = qio_channel_read_all(QIO_CHANNEL(t->cmd_qc),
232
+ if (ret != 0)
278
+ (char *)cmd->out, len, errp);
233
+ goto fail;
279
+ if (ret != 0) {
280
+ goto fail;
281
+ }
282
+
234
+ /* ACK packet */
283
+ /* ACK packet */
235
+ ret = qio_channel_read_all(QIO_CHANNEL(t->cmd_qc), (char *)&header, sizeof(header), errp);
284
+ ret = qio_channel_read_all(QIO_CHANNEL(t->cmd_qc),
236
+ if (ret != 0)
285
+ (char *)&header, sizeof(header), errp);
237
+ goto fail;
286
+ if (ret != 0) {
287
+ goto fail;
288
+ }
238
+ if (header != 0) {
289
+ if (header != 0) {
239
+ error_setg(errp, "incorrect ACK received on command channel 0x%x", len);
290
+ error_setg(errp, "incorrect ACK received on command channel 0x%x", len);
240
+ goto fail;
291
+ goto fail;
241
+ }
292
+ }
242
+
293
+
294
+ ret = qio_channel_close(QIO_CHANNEL(t->cmd_qc), errp);
295
+ if (ret != 0) {
296
+ goto fail_msg;
297
+ }
298
+
243
+ return;
299
+ return;
244
+
300
+
245
+ fail:
301
+ fail:
302
+ /* we're already failing, so don't worry if this fails too */
303
+ qio_channel_close(QIO_CHANNEL(t->cmd_qc), NULL);
304
+ fail_msg:
246
+ error_prepend(errp, ERROR_PREFIX);
305
+ error_prepend(errp, ERROR_PREFIX);
247
+ tpm_util_write_fatal_error_response(cmd->out, cmd->out_len);
306
+ tpm_util_write_fatal_error_response(cmd->out, cmd->out_len);
248
+}
307
+}
249
+
308
+
250
+static TPMBackend *tpm_mssim_create(TpmTypeOptions *opts)
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
+
345
+static TPMBackend *tpm_mssim_create(TpmCreateOptions *opts)
251
+{
346
+{
252
+ TPMBackend *be = TPM_BACKEND(object_new(TYPE_TPM_MSSIM));
347
+ TPMBackend *be = TPM_BACKEND(object_new(TYPE_TPM_MSSIM));
253
+ TPMmssim *t = TPM_MSSIM(be);
348
+ TPMMssim *t = TPM_MSSIM(be);
254
+ int sock;
255
+ Error *errp = NULL;
349
+ Error *errp = NULL;
256
+ TPMmssimOptions *mo = &opts->u.mssim;
350
+ TPMMssimOptions *mo = &opts->u.mssim;
257
+
351
+
258
+ t->opts = opts;
352
+ if (!mo->command) {
259
+ if (!mo->has_command) {
260
+ mo->has_command = true;
261
+ mo->command = g_new0(SocketAddress, 1);
353
+ mo->command = g_new0(SocketAddress, 1);
262
+ mo->command->type = SOCKET_ADDRESS_TYPE_INET;
354
+ mo->command->type = SOCKET_ADDRESS_TYPE_INET;
263
+ mo->command->u.inet.host = g_strdup("localhost");
355
+ mo->command->u.inet.host = g_strdup("localhost");
264
+ mo->command->u.inet.port = g_strdup("2321");
356
+ mo->command->u.inet.port = g_strdup("2321");
265
+ }
357
+ }
266
+ if (!mo->has_control) {
358
+ if (!mo->control) {
267
+ mo->has_control = true;
359
+ int port;
360
+
268
+ mo->control = g_new0(SocketAddress, 1);
361
+ mo->control = g_new0(SocketAddress, 1);
269
+ mo->control->type = SOCKET_ADDRESS_TYPE_INET;
362
+ mo->control->type = SOCKET_ADDRESS_TYPE_INET;
270
+ mo->control->u.inet.host = g_strdup(mo->command->u.inet.host);
363
+ mo->control->u.inet.host = g_strdup(mo->command->u.inet.host);
271
+ mo->control->u.inet.port = g_strdup("2322");
364
+ /*
272
+ }
365
+ * in the reference implementation, the control port is
273
+
366
+ * always one above the command port
367
+ */
368
+ port = atoi(mo->command->u.inet.port) + 1;
369
+ mo->control->u.inet.port = g_strdup_printf("%d", port);
370
+ }
371
+
372
+ QAPI_CLONE_MEMBERS(TPMMssimOptions, &t->opts, &opts->u.mssim);
274
+ t->cmd_qc = qio_channel_socket_new();
373
+ t->cmd_qc = qio_channel_socket_new();
275
+ t->ctrl_qc = qio_channel_socket_new();
374
+ t->ctrl_qc = qio_channel_socket_new();
276
+
375
+
277
+ if (qio_channel_socket_connect_sync(t->cmd_qc, mo->command, &errp) < 0)
376
+ if (qio_channel_socket_connect_sync(t->cmd_qc, mo->command, &errp) < 0) {
278
+ goto fail;
377
+ goto fail;
279
+
378
+ }
280
+ if (qio_channel_socket_connect_sync(t->ctrl_qc, mo->control, &errp) < 0)
379
+
281
+ goto fail;
380
+ if (qio_channel_socket_connect_sync(t->ctrl_qc, mo->control, &errp) < 0) {
282
+
381
+ goto fail;
283
+ /* reset the TPM using a power cycle sequence, in case someone
382
+ }
284
+ * has previously powered it up */
383
+ qio_channel_close(QIO_CHANNEL(t->ctrl_qc), NULL);
285
+ sock = tpm_send_ctrl(t, TPM_SIGNAL_POWER_OFF, &errp);
384
+ qio_channel_close(QIO_CHANNEL(t->cmd_qc), NULL);
286
+ if (sock != 0)
385
+
287
+ goto fail;
288
+ sock = tpm_send_ctrl(t, TPM_SIGNAL_POWER_ON, &errp);
289
+ if (sock != 0)
290
+ goto fail;
291
+ sock = tpm_send_ctrl(t, TPM_SIGNAL_NV_ON, &errp);
292
+ if (sock != 0)
293
+ goto fail;
294
+
386
+
295
+ return be;
387
+ return be;
296
+
388
+
297
+ fail:
389
+ fail:
298
+ object_unref(OBJECT(t->ctrl_qc));
390
+ object_unref(OBJECT(t->ctrl_qc));
299
+ object_unref(OBJECT(t->cmd_qc));
391
+ object_unref(OBJECT(t->cmd_qc));
300
+ t->ctrl_qc = NULL;
392
+ t->ctrl_qc = NULL;
393
+ t->cmd_qc = NULL;
301
+ error_prepend(&errp, ERROR_PREFIX);
394
+ error_prepend(&errp, ERROR_PREFIX);
302
+ error_report_err(errp);
395
+ error_report_err(errp);
303
+ object_unref(OBJECT(be));
396
+ object_unref(OBJECT(be));
304
+
397
+
305
+ return NULL;
398
+ return NULL;
...
...
326
+ cl->type = TPM_TYPE_MSSIM;
419
+ cl->type = TPM_TYPE_MSSIM;
327
+ cl->opts = tpm_mssim_cmdline_opts;
420
+ cl->opts = tpm_mssim_cmdline_opts;
328
+ cl->desc = "TPM mssim emulator backend driver";
421
+ cl->desc = "TPM mssim emulator backend driver";
329
+ cl->create = tpm_mssim_create;
422
+ cl->create = tpm_mssim_create;
330
+ cl->cancel_cmd = tpm_mssim_cancel_cmd;
423
+ cl->cancel_cmd = tpm_mssim_cancel_cmd;
424
+ cl->startup_tpm = tpm_mssim_startup;
331
+ cl->get_tpm_version = tpm_mssim_get_version;
425
+ cl->get_tpm_version = tpm_mssim_get_version;
332
+ cl->get_buffer_size = tpm_mssim_get_buffer_size;
426
+ cl->get_buffer_size = tpm_mssim_get_buffer_size;
333
+ cl->get_tpm_options = tpm_mssim_get_opts;
427
+ cl->get_tpm_options = tpm_mssim_get_opts;
334
+ cl->handle_request = tpm_mssim_handle_request;
428
+ cl->handle_request = tpm_mssim_handle_request;
335
+}
429
+}
336
+
430
+
337
+static const TypeInfo tpm_mssim_info = {
431
+static const TypeInfo tpm_mssim_info = {
338
+ .name = TYPE_TPM_MSSIM,
432
+ .name = TYPE_TPM_MSSIM,
339
+ .parent = TYPE_TPM_BACKEND,
433
+ .parent = TYPE_TPM_BACKEND,
340
+ .instance_size = sizeof(TPMmssim),
434
+ .instance_size = sizeof(TPMMssim),
341
+ .class_init = tpm_mssim_class_init,
435
+ .class_init = tpm_mssim_class_init,
342
+ .instance_init = tpm_mssim_instance_init,
436
+ .instance_init = tpm_mssim_instance_init,
343
+ .instance_finalize = tpm_mssim_instance_finalize,
437
+ .instance_finalize = tpm_mssim_instance_finalize,
344
+};
438
+};
345
+
439
+
...
...
369
+#define TPM_SIGNAL_POWER_OFF 2
463
+#define TPM_SIGNAL_POWER_OFF 2
370
+#define TPM_SIGNAL_PHYS_PRES_ON 3
464
+#define TPM_SIGNAL_PHYS_PRES_ON 3
371
+#define TPM_SIGNAL_PHYS_PRES_OFF 4
465
+#define TPM_SIGNAL_PHYS_PRES_OFF 4
372
+#define TPM_SIGNAL_HASH_START 5
466
+#define TPM_SIGNAL_HASH_START 5
373
+#define TPM_SIGNAL_HASH_DATA 6
467
+#define TPM_SIGNAL_HASH_DATA 6
374
+ // {uint32_t BufferSize, uint8_t[BufferSize] Buffer}
468
+/* {uint32_t BufferSize, uint8_t[BufferSize] Buffer} */
375
+#define TPM_SIGNAL_HASH_END 7
469
+#define TPM_SIGNAL_HASH_END 7
376
+#define TPM_SEND_COMMAND 8
470
+#define TPM_SEND_COMMAND 8
377
+ // {uint8_t Locality, uint32_t InBufferSize, uint8_t[InBufferSize] InBuffer} ->
471
+/*
378
+ // {uint32_t OutBufferSize, uint8_t[OutBufferSize] OutBuffer}
472
+ * {uint8_t Locality, uint32_t InBufferSize, uint8_t[InBufferSize] InBuffer} ->
379
+
473
+ * {uint32_t OutBufferSize, uint8_t[OutBufferSize] OutBuffer}
474
+ */
380
+#define TPM_SIGNAL_CANCEL_ON 9
475
+#define TPM_SIGNAL_CANCEL_ON 9
381
+#define TPM_SIGNAL_CANCEL_OFF 10
476
+#define TPM_SIGNAL_CANCEL_OFF 10
382
+#define TPM_SIGNAL_NV_ON 11
477
+#define TPM_SIGNAL_NV_ON 11
383
+#define TPM_SIGNAL_NV_OFF 12
478
+#define TPM_SIGNAL_NV_OFF 12
384
+#define TPM_SIGNAL_KEY_CACHE_ON 13
479
+#define TPM_SIGNAL_KEY_CACHE_ON 13
...
...
396
+#define TPM_GET_COMMAND_RESPONSE_SIZES 25
491
+#define TPM_GET_COMMAND_RESPONSE_SIZES 25
397
+
492
+
398
+#define TPM_ACT_GET_SIGNALED 26
493
+#define TPM_ACT_GET_SIGNALED 26
399
+
494
+
400
+#define TPM_TEST_FAILURE_MODE 30
495
+#define TPM_TEST_FAILURE_MODE 30
401
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
496
diff --git a/docs/specs/tpm.rst b/docs/specs/tpm.rst
402
index XXXXXXX..XXXXXXX 100644
497
index XXXXXXX..XXXXXXX 100644
403
--- a/monitor/hmp-cmds.c
498
--- a/docs/specs/tpm.rst
404
+++ b/monitor/hmp-cmds.c
499
+++ b/docs/specs/tpm.rst
500
@@ -XXX,XX +XXX,XX @@ available as a module (assuming a TPM 2 is passed through):
501
/sys/devices/LNXSYSTEM:00/LNXSYBUS:00/MSFT0101:00/tpm/tpm0/pcr-sha256/9
502
...
503
504
+The QEMU TPM Microsoft Simulator Device
505
+---------------------------------------
506
+
507
+The Microsoft Simulator (mssim) is the reference emulation platform
508
+for the TCG TPM 2.0 specification. It provides a reference
509
+implementation for the TPM 2.0 written by Microsoft (See
510
+`ms-tpm-20-ref`_ on github). The reference implementation starts a
511
+network server and listens for TPM commands on port 2321 and TPM
512
+Platform control commands on port 2322, although these can be altered.
513
+The QEMU mssim TPM backend talks to this implementation. By default
514
+it connects to the default ports on localhost:
515
+
516
+.. code-block:: console
517
+
518
+ qemu-system-x86_64 <qemu-options> \
519
+ -tpmdev mssim,id=tpm0 \
520
+ -device tpm-crb,tpmdev=tpm0
521
+
522
+
523
+Although it can also communicate with a remote host, which must be
524
+specified as a SocketAddress via json or dotted keys on the command
525
+line for each of the command and control ports:
526
+
527
+.. code-block:: console
528
+
529
+ qemu-system-x86_64 <qemu-options> \
530
+ -tpmdev "{'type':'mssim','id':'tpm0','command':{'type':'inet','host':'remote','port':'2321'},'control':{'type':'inet','host':'remote','port':'2322'}}" \
531
+ -device tpm-crb,tpmdev=tpm0
532
+
533
+
534
+The mssim backend supports snapshotting and migration by not resetting
535
+the TPM on start up and not powering it down on halt if the VM is in
536
+migration, but the state of the Microsoft Simulator server must be
537
+preserved (or the server kept running) outside of QEMU for restore to
538
+be successful.
539
+
540
The QEMU TPM emulator device
541
----------------------------
542
543
@@ -XXX,XX +XXX,XX @@ the following:
544
545
.. _SWTPM protocol:
546
https://github.com/stefanberger/swtpm/blob/master/man/man3/swtpm_ioctls.pod
547
+
548
+.. _ms-tpm-20-ref:
549
+ https://github.com/microsoft/ms-tpm-20-ref
550
diff --git a/qapi/tpm.json b/qapi/tpm.json
551
index XXXXXXX..XXXXXXX 100644
552
--- a/qapi/tpm.json
553
+++ b/qapi/tpm.json
554
@@ -XXX,XX +XXX,XX @@
555
# = TPM (trusted platform module) devices
556
##
557
558
+{ 'include': 'sockets.json' }
559
+
560
##
561
# @TpmModel:
562
#
563
@@ -XXX,XX +XXX,XX @@
564
#
565
# @emulator: Software Emulator TPM type (since 2.11)
566
#
567
+# @mssim: Microsoft TPM Emulator (since 9.0)
568
+#
569
# Since: 1.5
570
##
571
-{ 'enum': 'TpmType', 'data': [ 'passthrough', 'emulator' ],
572
+{ 'enum': 'TpmType', 'data': [ 'passthrough', 'emulator', 'mssim' ],
573
'if': 'CONFIG_TPM' }
574
575
##
576
@@ -XXX,XX +XXX,XX @@
577
# .. qmp-example::
578
#
579
# -> { "execute": "query-tpm-types" }
580
-# <- { "return": [ "passthrough", "emulator" ] }
581
+# <- { "return": [ "passthrough", "emulator", "mssim" ] }
582
##
583
{ 'command': 'query-tpm-types', 'returns': ['TpmType'],
584
'if': 'CONFIG_TPM' }
585
@@ -XXX,XX +XXX,XX @@
586
'data': { 'data': 'TPMEmulatorOptions' },
587
'if': 'CONFIG_TPM' }
588
589
+##
590
+# @TPMMssimOptions:
591
+#
592
+# Information for the mssim emulator connection
593
+#
594
+# @command: command socket for the TPM emulator
595
+#
596
+# @control: control socket for the TPM emulator
597
+#
598
+# Since: 9.0
599
+##
600
+{ 'struct': 'TPMMssimOptions',
601
+ 'data': { '*command': 'SocketAddress',
602
+ '*control': 'SocketAddress' },
603
+ 'if': 'CONFIG_TPM' }
604
+
605
##
606
# @TpmTypeOptions:
607
#
608
@@ -XXX,XX +XXX,XX @@
609
# passthrough type
610
# - 'emulator' The configuration options for TPM emulator backend
611
# type
612
+# - 'mssim' The configuration options for TPM emulator mssim type
613
#
614
# Since: 1.5
615
##
616
@@ -XXX,XX +XXX,XX @@
617
'base': { 'type': 'TpmType' },
618
'discriminator': 'type',
619
'data': { 'passthrough' : 'TPMPassthroughOptionsWrapper',
620
- 'emulator': 'TPMEmulatorOptionsWrapper' },
621
+ 'emulator': 'TPMEmulatorOptionsWrapper',
622
+ 'mssim' : 'TPMMssimOptions' },
623
'if': 'CONFIG_TPM' }
624
625
##
626
@@ -XXX,XX +XXX,XX @@
627
'id' : 'str' },
628
'discriminator': 'type',
629
'data': { 'passthrough' : 'TPMPassthroughOptions',
630
- 'emulator': 'TPMEmulatorOptions' },
631
+ 'emulator': 'TPMEmulatorOptions',
632
+ 'mssim': 'TPMMssimOptions' },
633
'if': 'CONFIG_TPM' }
634
635
##
636
diff --git a/system/tpm-hmp-cmds.c b/system/tpm-hmp-cmds.c
637
index XXXXXXX..XXXXXXX 100644
638
--- a/system/tpm-hmp-cmds.c
639
+++ b/system/tpm-hmp-cmds.c
405
@@ -XXX,XX +XXX,XX @@ void hmp_info_tpm(Monitor *mon, const QDict *qdict)
640
@@ -XXX,XX +XXX,XX @@ void hmp_info_tpm(Monitor *mon, const QDict *qdict)
406
unsigned int c = 0;
641
unsigned int c = 0;
407
TPMPassthroughOptions *tpo;
642
TPMPassthroughOptions *tpo;
408
TPMEmulatorOptions *teo;
643
TPMEmulatorOptions *teo;
409
+ TPMmssimOptions *tmo;
644
+ TPMMssimOptions *tmo;
410
645
411
info_list = qmp_query_tpm(&err);
646
info_list = qmp_query_tpm(&err);
412
if (err) {
647
if (err) {
413
@@ -XXX,XX +XXX,XX @@ void hmp_info_tpm(Monitor *mon, const QDict *qdict)
648
@@ -XXX,XX +XXX,XX @@ void hmp_info_tpm(Monitor *mon, const QDict *qdict)
414
teo = &ti->options->u.emulator;
649
teo = ti->options->u.emulator.data;
415
monitor_printf(mon, ",chardev=%s", teo->chardev);
650
monitor_printf(mon, ",chardev=%s", teo->chardev);
416
break;
651
break;
417
+ case TPM_TYPE_MSSIM:
652
+ case TPM_TYPE_MSSIM:
418
+ tmo = &ti->options->u.mssim;
653
+ tmo = &ti->options->u.mssim;
419
+ monitor_printf(mon, ",command=%s:%s,control=%s:%s",
654
+ monitor_printf(mon, ",command=%s:%s,control=%s:%s",
420
+ tmo->command->u.inet.host, tmo->command->u.inet.port,
655
+ tmo->command->u.inet.host,
421
+ tmo->control->u.inet.host, tmo->control->u.inet.port);
656
+ tmo->command->u.inet.port,
657
+ tmo->control->u.inet.host,
658
+ tmo->control->u.inet.port);
422
+ break;
659
+ break;
423
case TPM_TYPE__MAX:
660
case TPM_TYPE__MAX:
424
break;
661
break;
425
}
662
}
426
diff --git a/qapi/tpm.json b/qapi/tpm.json
427
index XXXXXXX..XXXXXXX 100644
428
--- a/qapi/tpm.json
429
+++ b/qapi/tpm.json
430
@@ -XXX,XX +XXX,XX @@
431
##
432
# = TPM (trusted platform module) devices
433
##
434
+{ 'include': 'sockets.json' }
435
436
##
437
# @TpmModel:
438
@@ -XXX,XX +XXX,XX @@
439
#
440
# Since: 1.5
441
##
442
-{ 'enum': 'TpmType', 'data': [ 'passthrough', 'emulator' ],
443
+{ 'enum': 'TpmType', 'data': [ 'passthrough', 'emulator', 'mssim' ],
444
'if': 'CONFIG_TPM' }
445
446
##
447
@@ -XXX,XX +XXX,XX @@
448
# Example:
449
#
450
# -> { "execute": "query-tpm-types" }
451
-# <- { "return": [ "passthrough", "emulator" ] }
452
+# <- { "return": [ "passthrough", "emulator", "mssim" ] }
453
#
454
##
455
{ 'command': 'query-tpm-types', 'returns': ['TpmType'],
456
@@ -XXX,XX +XXX,XX @@
457
{ 'struct': 'TPMEmulatorOptions', 'data': { 'chardev' : 'str' },
458
'if': 'CONFIG_TPM' }
459
460
+##
461
+# @TPMmssimOptions:
462
+#
463
+# Information for the mssim emulator connection
464
+#
465
+# @command: command socket for the TPM emulator
466
+# @control: control socket for the TPM emulator
467
+#
468
+# Since: 7.2.0
469
+##
470
+{ 'struct': 'TPMmssimOptions',
471
+ 'data': {
472
+ '*command': 'SocketAddress',
473
+ '*control': 'SocketAddress' },
474
+ 'if': 'CONFIG_TPM' }
475
+
476
##
477
# @TpmTypeOptions:
478
#
479
@@ -XXX,XX +XXX,XX @@
480
# @id: identifier of the backend
481
# @type: - 'passthrough' The configuration options for the TPM passthrough type
482
# - 'emulator' The configuration options for TPM emulator backend type
483
+# - 'mssim' The configuration options for TPM emulator mssim type
484
#
485
# Since: 1.5
486
##
487
@@ -XXX,XX +XXX,XX @@
488
'id': 'str' },
489
'discriminator': 'type',
490
'data': { 'passthrough' : 'TPMPassthroughOptions',
491
- 'emulator': 'TPMEmulatorOptions' },
492
+ 'emulator': 'TPMEmulatorOptions',
493
+ 'mssim': 'TPMmssimOptions' },
494
'if': 'CONFIG_TPM' }
495
496
##
497
--
663
--
498
2.35.3
664
2.35.3
diff view generated by jsdifflib