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
9
doesn't like my native TPM because it doesn't allow cancellation.
10
6
11
v3 pulls out more unneeded code in the visitor conversion, makes
7
v3 pulls out more unneeded code in the visitor conversion, makes
12
migration work on external state preservation of the simulator and
8
migration work on external state preservation of the simulator and
13
adds documentation
9
adds documentation
14
10
15
v4 puts back the wrapper options (but doesn't add any for mssim since
11
v4 puts back the wrapper options (but doesn't add any for mssim since
16
it post dates the necessity)
12
it post dates the necessity)
17
13
18
v5 rebases to the latest master branch and adjusts for removed use_FOO ptrs
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).
19
31
20
James
32
James
21
33
22
---
34
---
23
35
...
...
26
tpm: add backend for mssim
38
tpm: add backend for mssim
27
39
28
MAINTAINERS | 6 +
40
MAINTAINERS | 6 +
29
backends/tpm/Kconfig | 5 +
41
backends/tpm/Kconfig | 5 +
30
backends/tpm/meson.build | 1 +
42
backends/tpm/meson.build | 1 +
31
backends/tpm/tpm_emulator.c | 24 ++-
43
backends/tpm/tpm_emulator.c | 25 +--
32
backends/tpm/tpm_mssim.c | 263 +++++++++++++++++++++++++++++++++
44
backends/tpm/tpm_mssim.c | 335 +++++++++++++++++++++++++++++++++
33
backends/tpm/tpm_mssim.h | 43 ++++++
45
backends/tpm/tpm_mssim.h | 44 +++++
34
backends/tpm/tpm_passthrough.c | 25 +---
46
backends/tpm/tpm_passthrough.c | 23 +--
35
docs/specs/tpm.rst | 35 +++++
47
docs/specs/tpm.rst | 39 ++++
36
include/sysemu/tpm.h | 4 +-
48
include/sysemu/tpm.h | 5 +-
37
include/sysemu/tpm_backend.h | 2 +-
49
include/sysemu/tpm_backend.h | 2 +-
38
monitor/hmp-cmds.c | 7 +
50
qapi/tpm.json | 50 ++++-
39
qapi/tpm.json | 45 +++++-
51
system/tpm-hmp-cmds.c | 9 +
40
softmmu/tpm.c | 90 +++++------
52
system/tpm.c | 91 ++++-----
41
softmmu/vl.c | 19 +--
53
system/vl.c | 19 +-
42
14 files changed, 459 insertions(+), 110 deletions(-)
54
14 files changed, 546 insertions(+), 108 deletions(-)
43
create mode 100644 backends/tpm/tpm_mssim.c
55
create mode 100644 backends/tpm/tpm_mssim.c
44
create mode 100644 backends/tpm/tpm_mssim.h
56
create mode 100644 backends/tpm/tpm_mssim.h
45
57
46
--
58
--
47
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
---
10
v4: add TpmConfiOptions
10
v4: add TpmConfiOptions
11
v5: exit(0) for help
12
v7: adjust line lengths, free options
13
v8: minor updates; add tested/reviewed-by
14
v9: optarg->optstr
11
---
15
---
12
backends/tpm/tpm_emulator.c | 24 ++++-----
16
backends/tpm/tpm_emulator.c | 25 ++++------
13
backends/tpm/tpm_passthrough.c | 25 +++-------
17
backends/tpm/tpm_passthrough.c | 23 +++------
14
include/sysemu/tpm.h | 4 +-
18
include/sysemu/tpm.h | 5 +-
15
include/sysemu/tpm_backend.h | 2 +-
19
include/sysemu/tpm_backend.h | 2 +-
16
qapi/tpm.json | 19 +++++++
20
qapi/tpm.json | 21 ++++++++
17
softmmu/tpm.c | 90 ++++++++++++++--------------------
21
system/tpm.c | 91 ++++++++++++++--------------------
18
softmmu/vl.c | 19 +------
22
system/vl.c | 19 +------
19
7 files changed, 76 insertions(+), 107 deletions(-)
23
7 files changed, 81 insertions(+), 105 deletions(-)
20
24
21
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
22
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
23
--- a/backends/tpm/tpm_emulator.c
27
--- a/backends/tpm/tpm_emulator.c
24
+++ b/backends/tpm/tpm_emulator.c
28
+++ b/backends/tpm/tpm_emulator.c
25
@@ -XXX,XX +XXX,XX @@ err_exit:
29
@@ -XXX,XX +XXX,XX @@ err_exit:
26
return -1;
30
return -1;
27
}
31
}
28
32
29
-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)
30
+static int tpm_emulator_handle_device_opts(TPMEmulator *tpm_emu, TpmCreateOptions *opts)
34
+static int tpm_emulator_handle_device_opts(TPMEmulator *tpm_emu,
35
+ TpmCreateOptions *opts)
31
{
36
{
32
- const char *value;
37
- const char *value;
33
Error *err = NULL;
38
Error *err = NULL;
34
Chardev *dev;
39
Chardev *dev;
35
40
...
...
44
- dev = qemu_chr_find(value);
49
- dev = qemu_chr_find(value);
45
+ dev = qemu_chr_find(opts->u.emulator.chardev);
50
+ dev = qemu_chr_find(opts->u.emulator.chardev);
46
if (!dev) {
51
if (!dev) {
47
- error_report("tpm-emulator: tpm chardev '%s' not found", value);
52
- error_report("tpm-emulator: tpm chardev '%s' not found", value);
48
+ error_report("tpm-emulator: tpm chardev '%s' not found",
53
+ error_report("tpm-emulator: tpm chardev '%s' not found",
49
+ opts->u.emulator.chardev);
54
+ opts->u.emulator.chardev);
50
goto err;
55
goto err;
51
}
56
}
52
57
53
if (!qemu_chr_fe_init(&tpm_emu->ctrl_chr, dev, &err)) {
58
if (!qemu_chr_fe_init(&tpm_emu->ctrl_chr, dev, &err)) {
54
error_prepend(&err, "tpm-emulator: No valid chardev found at '%s':",
59
error_prepend(&err, "tpm-emulator: No valid chardev found at '%s':",
...
...
96
@@ -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)
97
}
102
}
98
103
99
static int
104
static int
100
-tpm_passthrough_handle_device_opts(TPMPassthruState *tpm_pt, QemuOpts *opts)
105
-tpm_passthrough_handle_device_opts(TPMPassthruState *tpm_pt, QemuOpts *opts)
101
+tpm_passthrough_handle_device_opts(TPMPassthruState *tpm_pt, TpmCreateOptions *opts)
106
+tpm_passthrough_handle_device_opts(TPMPassthruState *tpm_pt,
107
+ TpmCreateOptions *opts)
102
{
108
{
103
- const char *value;
109
- const char *value;
104
+ tpm_pt->options = QAPI_CLONE(TPMPassthroughOptions, &opts->u.passthrough);
110
+ tpm_pt->options = QAPI_CLONE(TPMPassthroughOptions, &opts->u.passthrough);
105
111
106
- value = qemu_opt_get(opts, "cancel-path");
112
- value = qemu_opt_get(opts, "cancel-path");
...
...
112
- if (value) {
118
- if (value) {
113
- tpm_pt->options->path = g_strdup(value);
119
- tpm_pt->options->path = g_strdup(value);
114
- }
120
- }
115
-
121
-
116
- tpm_pt->tpm_dev = value ? value : TPM_PASSTHROUGH_DEFAULT_DEVICE;
122
- tpm_pt->tpm_dev = value ? value : TPM_PASSTHROUGH_DEFAULT_DEVICE;
117
+ tpm_pt->tpm_dev = opts->u.passthrough.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;
118
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);
119
if (tpm_pt->tpm_fd < 0) {
126
if (tpm_pt->tpm_fd < 0) {
120
error_report("Cannot access TPM device using '%s': %s",
127
error_report("Cannot access TPM device using '%s': %s",
121
@@ -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)
122
return 0;
129
return 0;
...
...
130
- if (tpm_passthrough_handle_device_opts(TPM_PASSTHROUGH(obj), opts)) {
137
- if (tpm_passthrough_handle_device_opts(TPM_PASSTHROUGH(obj), opts)) {
131
+ if (tpm_passthrough_handle_device_opts(TPM_PASSTHROUGH(obj), tco)) {
138
+ if (tpm_passthrough_handle_device_opts(TPM_PASSTHROUGH(obj), tco)) {
132
object_unref(obj);
139
object_unref(obj);
133
return NULL;
140
return NULL;
134
}
141
}
135
@@ -XXX,XX +XXX,XX @@ static TpmTypeOptions *tpm_passthrough_get_tpm_options(TPMBackend *tb)
136
TpmTypeOptions *options = g_new0(TpmTypeOptions, 1);
137
138
options->type = TPM_TYPE_PASSTHROUGH;
139
- options->u.passthrough.data = QAPI_CLONE(TPMPassthroughOptions,
140
- TPM_PASSTHROUGH(tb)->options);
141
+
142
+ options->u.passthrough.data = QAPI_CLONE(TPMPassthroughOptions, TPM_PASSTHROUGH(tb)->options);
143
144
return options;
145
}
146
@@ -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)
147
{
143
{
148
TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(obj);
144
TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(obj);
149
145
150
- tpm_pt->options = g_new0(TPMPassthroughOptions, 1);
146
- tpm_pt->options = g_new0(TPMPassthroughOptions, 1);
...
...
157
+++ b/include/sysemu/tpm.h
153
+++ b/include/sysemu/tpm.h
158
@@ -XXX,XX +XXX,XX @@
154
@@ -XXX,XX +XXX,XX @@
159
155
160
#ifdef CONFIG_TPM
156
#ifdef CONFIG_TPM
161
157
162
-int tpm_config_parse(QemuOptsList *opts_list, const char *optarg);
158
-int tpm_config_parse(QemuOptsList *opts_list, const char *optstr);
163
-int tpm_init(void);
159
-int tpm_init(void);
164
+void tpm_config_parse(const char *optarg);
160
+void tpm_config_parse(const char *optstr);
165
+void tpm_init(void);
161
+void tpm_init(void);
162
+
166
void tpm_cleanup(void);
163
void tpm_cleanup(void);
167
164
168
typedef enum TPMVersion {
165
typedef enum TPMVersion {
169
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
170
index XXXXXXX..XXXXXXX 100644
167
index XXXXXXX..XXXXXXX 100644
...
...
194
+# without the wrapper to be usable by visitors.
191
+# without the wrapper to be usable by visitors.
195
+#
192
+#
196
+# @type: - 'passthrough' The configuration options for the TPM passthrough type
193
+# @type: - 'passthrough' The configuration options for the TPM passthrough type
197
+# - 'emulator' The configuration options for TPM emulator backend type
194
+# - 'emulator' The configuration options for TPM emulator backend type
198
+#
195
+#
199
+# Since: 7.2
196
+# @id: The Id of the TPM
197
+#
198
+# Since: 9.0
200
+##
199
+##
201
+{ 'union': 'TpmCreateOptions',
200
+{ 'union': 'TpmCreateOptions',
202
+ 'base': { 'type': 'TpmType',
201
+ 'base': { 'type': 'TpmType',
203
+ 'id' : 'str' },
202
+ 'id' : 'str' },
204
+ 'discriminator': 'type',
203
+ 'discriminator': 'type',
...
...
207
+ 'if': 'CONFIG_TPM' }
206
+ 'if': 'CONFIG_TPM' }
208
+
207
+
209
##
208
##
210
# @TPMInfo:
209
# @TPMInfo:
211
#
210
#
212
diff --git a/softmmu/tpm.c b/softmmu/tpm.c
211
diff --git a/system/tpm.c b/system/tpm.c
213
index XXXXXXX..XXXXXXX 100644
212
index XXXXXXX..XXXXXXX 100644
214
--- a/softmmu/tpm.c
213
--- a/system/tpm.c
215
+++ b/softmmu/tpm.c
214
+++ b/system/tpm.c
216
@@ -XXX,XX +XXX,XX @@
215
@@ -XXX,XX +XXX,XX @@
217
#include "qapi/error.h"
216
#include "qapi/error.h"
218
#include "qapi/qapi-commands-tpm.h"
217
#include "qapi/qapi-commands-tpm.h"
219
#include "qapi/qmp/qerror.h"
218
#include "qapi/qmp/qerror.h"
220
+#include "qapi/qobject-input-visitor.h"
219
+#include "qapi/qobject-input-visitor.h"
...
...
326
+ TpmCreateOptionsQueueEntry *tcoqe = QSIMPLEQ_FIRST(&tco_queue);
325
+ TpmCreateOptionsQueueEntry *tcoqe = QSIMPLEQ_FIRST(&tco_queue);
327
326
328
- return 0;
327
- return 0;
329
+ QSIMPLEQ_REMOVE_HEAD(&tco_queue, entry);
328
+ QSIMPLEQ_REMOVE_HEAD(&tco_queue, entry);
330
+ tpm_init_tpmdev(tcoqe->tco);
329
+ tpm_init_tpmdev(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 *optarg)
339
-int tpm_config_parse(QemuOptsList *opts_list, const char *optstr)
340
+void tpm_config_parse(const char *optarg)
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(optarg, "help")) {
346
- if (!strcmp(optstr, "help")) {
347
+ if (is_help_option(optarg)) {
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, optarg, true);
351
- opts = qemu_opts_parse_noisily(opts_list, optstr, true);
352
- if (!opts) {
352
- if (!opts) {
353
- return -1;
353
- return -1;
354
+ return;
354
+ exit(0);
355
}
355
}
356
- return 0;
356
- return 0;
357
+ v = qobject_input_visitor_new_str(optarg, "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/softmmu/vl.c b/softmmu/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/softmmu/vl.c
367
--- a/system/vl.c
368
+++ b/softmmu/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 = {
...
...
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
387
exit(1);
388
object_option_foreach_add(object_create_late);
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();
...
...
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
...
...
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()
44
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
45
to test outside influence and add docs.
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
46
---
48
---
47
MAINTAINERS | 6 +
49
MAINTAINERS | 6 +
48
backends/tpm/Kconfig | 5 +
50
backends/tpm/Kconfig | 5 +
49
backends/tpm/meson.build | 1 +
51
backends/tpm/meson.build | 1 +
50
backends/tpm/tpm_mssim.c | 263 +++++++++++++++++++++++++++++++++++++++
52
backends/tpm/tpm_mssim.c | 335 +++++++++++++++++++++++++++++++++++++++
51
backends/tpm/tpm_mssim.h | 43 +++++++
53
backends/tpm/tpm_mssim.h | 44 +++++
52
docs/specs/tpm.rst | 35 ++++++
54
docs/specs/tpm.rst | 39 +++++
53
monitor/hmp-cmds.c | 7 ++
55
qapi/tpm.json | 31 +++-
54
qapi/tpm.json | 28 ++++-
56
system/tpm-hmp-cmds.c | 9 ++
55
8 files changed, 384 insertions(+), 4 deletions(-)
57
8 files changed, 466 insertions(+), 4 deletions(-)
56
create mode 100644 backends/tpm/tpm_mssim.c
58
create mode 100644 backends/tpm/tpm_mssim.c
57
create mode 100644 backends/tpm/tpm_mssim.h
59
create mode 100644 backends/tpm/tpm_mssim.h
58
60
59
diff --git a/MAINTAINERS b/MAINTAINERS
61
diff --git a/MAINTAINERS b/MAINTAINERS
60
index XXXXXXX..XXXXXXX 100644
62
index XXXXXXX..XXXXXXX 100644
...
...
72
+MSSIM TPM Backend
74
+MSSIM TPM Backend
73
+M: James Bottomley <jejb@linux.ibm.com>
75
+M: James Bottomley <jejb@linux.ibm.com>
74
+S: Maintained
76
+S: Maintained
75
+F: backends/tpm/tpm_mssim.*
77
+F: backends/tpm/tpm_mssim.*
76
+
78
+
77
Checkpatch
79
SPDM
78
S: Odd Fixes
80
M: Alistair Francis <alistair.francis@wdc.com>
79
F: scripts/checkpatch.pl
81
S: Maintained
80
diff --git a/backends/tpm/Kconfig b/backends/tpm/Kconfig
82
diff --git a/backends/tpm/Kconfig b/backends/tpm/Kconfig
81
index XXXXXXX..XXXXXXX 100644
83
index XXXXXXX..XXXXXXX 100644
82
--- a/backends/tpm/Kconfig
84
--- a/backends/tpm/Kconfig
83
+++ b/backends/tpm/Kconfig
85
+++ b/backends/tpm/Kconfig
84
@@ -XXX,XX +XXX,XX @@ config TPM_EMULATOR
86
@@ -XXX,XX +XXX,XX @@ config TPM_EMULATOR
...
...
93
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
94
index XXXXXXX..XXXXXXX 100644
96
index XXXXXXX..XXXXXXX 100644
95
--- a/backends/tpm/meson.build
97
--- a/backends/tpm/meson.build
96
+++ b/backends/tpm/meson.build
98
+++ b/backends/tpm/meson.build
97
@@ -XXX,XX +XXX,XX @@ if have_tpm
99
@@ -XXX,XX +XXX,XX @@ if have_tpm
98
softmmu_ss.add(files('tpm_util.c'))
100
system_ss.add(files('tpm_util.c'))
99
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'))
100
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'))
101
+ 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'))
102
endif
104
endif
103
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
104
new file mode 100644
106
new file mode 100644
105
index XXXXXXX..XXXXXXX
107
index XXXXXXX..XXXXXXX
106
--- /dev/null
108
--- /dev/null
...
...
133
+#include "tpm_mssim.h"
135
+#include "tpm_mssim.h"
134
+
136
+
135
+#define ERROR_PREFIX "TPM mssim Emulator: "
137
+#define ERROR_PREFIX "TPM mssim Emulator: "
136
+
138
+
137
+#define TYPE_TPM_MSSIM "tpm-mssim"
139
+#define TYPE_TPM_MSSIM "tpm-mssim"
138
+OBJECT_DECLARE_SIMPLE_TYPE(TPMmssim, TPM_MSSIM)
140
+OBJECT_DECLARE_SIMPLE_TYPE(TPMMssim, TPM_MSSIM)
139
+
141
+
140
+struct TPMmssim {
142
+struct TPMMssim {
141
+ TPMBackend parent;
143
+ TPMBackend parent;
142
+
144
+
143
+ TPMmssimOptions opts;
145
+ TPMMssimOptions opts;
144
+
146
+
145
+ QIOChannelSocket *cmd_qc, *ctrl_qc;
147
+ QIOChannelSocket *cmd_qc, *ctrl_qc;
146
+};
148
+};
147
+
149
+
148
+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)
149
+{
151
+{
150
+ int ret;
152
+ int ret, retc;
151
+
153
+ Error *local_err = NULL;
152
+ qio_channel_socket_connect_sync(t->ctrl_qc, t->opts.control, errp);
154
+
155
+ ret = qio_channel_socket_connect_sync(t->ctrl_qc, t->opts.control, errp);
156
+ if (ret != 0) {
157
+ return ret;
158
+ }
153
+ cmd = htonl(cmd);
159
+ cmd = htonl(cmd);
154
+ 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),
155
+ if (ret != 0)
161
+ (char *)&cmd, sizeof(cmd), errp);
162
+ if (ret != 0) {
156
+ goto out;
163
+ goto out;
157
+ ret = qio_channel_read_all(QIO_CHANNEL(t->ctrl_qc), (char *)&cmd, sizeof(cmd), errp);
164
+ }
158
+ if (ret != 0)
165
+
166
+ ret = qio_channel_read_all(QIO_CHANNEL(t->ctrl_qc),
167
+ (char *)&cmd, sizeof(cmd), errp);
168
+ if (ret != 0) {
159
+ goto out;
169
+ goto out;
170
+ }
160
+ if (cmd != 0) {
171
+ if (cmd != 0) {
161
+ error_setg(errp, ERROR_PREFIX "Incorrect ACK recieved on control channel 0x%x\n", cmd);
172
+ error_setg(errp, ERROR_PREFIX
173
+ "Incorrect ACK recieved on control channel 0x%x", cmd);
162
+ ret = -1;
174
+ ret = -1;
163
+ }
175
+ }
164
+ out:
176
+ out:
165
+ qio_channel_close(QIO_CHANNEL(t->ctrl_qc), errp);
177
+ /*
166
+ return ret;
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;
167
+}
184
+}
168
+
185
+
169
+static void tpm_mssim_instance_init(Object *obj)
186
+static void tpm_mssim_instance_init(Object *obj)
170
+{
187
+{
171
+}
188
+}
172
+
189
+
173
+static void tpm_mssim_instance_finalize(Object *obj)
190
+static void tpm_mssim_instance_finalize(Object *obj)
174
+{
191
+{
175
+ TPMmssim *t = TPM_MSSIM(obj);
192
+ TPMMssim *t = TPM_MSSIM(obj);
176
+
193
+
177
+ if (t->ctrl_qc && !runstate_check(RUN_STATE_INMIGRATE))
194
+ if (t->cmd_qc && !runstate_check(RUN_STATE_POSTMIGRATE)) {
178
+ 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
+ }
179
+
203
+
180
+ object_unref(OBJECT(t->ctrl_qc));
204
+ object_unref(OBJECT(t->ctrl_qc));
181
+ object_unref(OBJECT(t->cmd_qc));
205
+ object_unref(OBJECT(t->cmd_qc));
182
+}
206
+}
183
+
207
+
...
...
197
+ return 4096;
221
+ return 4096;
198
+}
222
+}
199
+
223
+
200
+static TpmTypeOptions *tpm_mssim_get_opts(TPMBackend *tb)
224
+static TpmTypeOptions *tpm_mssim_get_opts(TPMBackend *tb)
201
+{
225
+{
202
+ TPMmssim *t = TPM_MSSIM(tb);
226
+ TPMMssim *t = TPM_MSSIM(tb);
203
+ TpmTypeOptions *opts = g_new0(TpmTypeOptions, 1);
227
+ TpmTypeOptions *opts = g_new0(TpmTypeOptions, 1);
204
+
228
+
205
+ opts->type = TPM_TYPE_MSSIM;
229
+ opts->type = TPM_TYPE_MSSIM;
206
+ opts->u.mssim = t->opts;
230
+ QAPI_CLONE_MEMBERS(TPMMssimOptions, &opts->u.mssim, &t->opts);
207
+
231
+
208
+ return opts;
232
+ return opts;
209
+}
233
+}
210
+
234
+
211
+static void tpm_mssim_handle_request(TPMBackend *tb, TPMBackendCmd *cmd,
235
+static void tpm_mssim_handle_request(TPMBackend *tb, TPMBackendCmd *cmd,
212
+ Error **errp)
236
+ Error **errp)
213
+{
237
+{
214
+ TPMmssim *t = TPM_MSSIM(tb);
238
+ TPMMssim *t = TPM_MSSIM(tb);
215
+ uint32_t header, len;
239
+ uint32_t header, len;
216
+ uint8_t locality = cmd->locty;
240
+ uint8_t locality = cmd->locty;
217
+ struct iovec iov[4];
241
+ struct iovec iov[4];
218
+ 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
+ }
219
+
248
+
220
+ header = htonl(TPM_SEND_COMMAND);
249
+ header = htonl(TPM_SEND_COMMAND);
221
+ len = htonl(cmd->in_len);
250
+ len = htonl(cmd->in_len);
222
+
251
+
223
+ iov[0].iov_base = &header;
252
+ iov[0].iov_base = &header;
...
...
228
+ iov[2].iov_len = sizeof(len);
257
+ iov[2].iov_len = sizeof(len);
229
+ iov[3].iov_base = (void *)cmd->in;
258
+ iov[3].iov_base = (void *)cmd->in;
230
+ iov[3].iov_len = cmd->in_len;
259
+ iov[3].iov_len = cmd->in_len;
231
+
260
+
232
+ 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);
233
+ if (ret != 0)
262
+ if (ret != 0) {
234
+ goto fail;
263
+ goto fail;
235
+
264
+ }
236
+ ret = qio_channel_read_all(QIO_CHANNEL(t->cmd_qc), (char *)&len, sizeof(len), errp);
265
+
237
+ if (ret != 0)
266
+ ret = qio_channel_read_all(QIO_CHANNEL(t->cmd_qc),
238
+ goto fail;
267
+ (char *)&len, sizeof(len), errp);
268
+ if (ret != 0) {
269
+ goto fail;
270
+ }
271
+
239
+ len = ntohl(len);
272
+ len = ntohl(len);
240
+ if (len > cmd->out_len) {
273
+ if (len > cmd->out_len) {
241
+ error_setg(errp, "receive size is too large");
274
+ error_setg(errp, "receive size is too large");
242
+ goto fail;
275
+ goto fail;
243
+ }
276
+ }
244
+ 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),
245
+ if (ret != 0)
278
+ (char *)cmd->out, len, errp);
246
+ goto fail;
279
+ if (ret != 0) {
280
+ goto fail;
281
+ }
282
+
247
+ /* ACK packet */
283
+ /* ACK packet */
248
+ 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),
249
+ if (ret != 0)
285
+ (char *)&header, sizeof(header), errp);
250
+ goto fail;
286
+ if (ret != 0) {
287
+ goto fail;
288
+ }
251
+ if (header != 0) {
289
+ if (header != 0) {
252
+ 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);
253
+ goto fail;
291
+ goto fail;
254
+ }
292
+ }
255
+
293
+
294
+ ret = qio_channel_close(QIO_CHANNEL(t->cmd_qc), errp);
295
+ if (ret != 0) {
296
+ goto fail_msg;
297
+ }
298
+
256
+ return;
299
+ return;
257
+
300
+
258
+ 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:
259
+ error_prepend(errp, ERROR_PREFIX);
305
+ error_prepend(errp, ERROR_PREFIX);
260
+ tpm_util_write_fatal_error_response(cmd->out, cmd->out_len);
306
+ tpm_util_write_fatal_error_response(cmd->out, cmd->out_len);
261
+}
307
+}
262
+
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
+
263
+static TPMBackend *tpm_mssim_create(TpmCreateOptions *opts)
345
+static TPMBackend *tpm_mssim_create(TpmCreateOptions *opts)
264
+{
346
+{
265
+ TPMBackend *be = TPM_BACKEND(object_new(TYPE_TPM_MSSIM));
347
+ TPMBackend *be = TPM_BACKEND(object_new(TYPE_TPM_MSSIM));
266
+ TPMmssim *t = TPM_MSSIM(be);
348
+ TPMMssim *t = TPM_MSSIM(be);
267
+ int sock;
268
+ Error *errp = NULL;
349
+ Error *errp = NULL;
269
+ TPMmssimOptions *mo = &opts->u.mssim;
350
+ TPMMssimOptions *mo = &opts->u.mssim;
270
+
351
+
271
+ if (!mo->command) {
352
+ if (!mo->command) {
272
+ mo->command = g_new0(SocketAddress, 1);
353
+ mo->command = g_new0(SocketAddress, 1);
273
+ mo->command->type = SOCKET_ADDRESS_TYPE_INET;
354
+ mo->command->type = SOCKET_ADDRESS_TYPE_INET;
274
+ mo->command->u.inet.host = g_strdup("localhost");
355
+ mo->command->u.inet.host = g_strdup("localhost");
...
...
278
+ int port;
359
+ int port;
279
+
360
+
280
+ mo->control = g_new0(SocketAddress, 1);
361
+ mo->control = g_new0(SocketAddress, 1);
281
+ mo->control->type = SOCKET_ADDRESS_TYPE_INET;
362
+ mo->control->type = SOCKET_ADDRESS_TYPE_INET;
282
+ 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);
283
+ /* in the reference implementation, the control port is
364
+ /*
284
+ * always one above the command port */
365
+ * in the reference implementation, the control port is
366
+ * always one above the command port
367
+ */
285
+ port = atoi(mo->command->u.inet.port) + 1;
368
+ port = atoi(mo->command->u.inet.port) + 1;
286
+ mo->control->u.inet.port = g_strdup_printf("%d", port);
369
+ mo->control->u.inet.port = g_strdup_printf("%d", port);
287
+ }
370
+ }
288
+
371
+
289
+ t->opts = opts->u.mssim;
372
+ QAPI_CLONE_MEMBERS(TPMMssimOptions, &t->opts, &opts->u.mssim);
290
+ t->cmd_qc = qio_channel_socket_new();
373
+ t->cmd_qc = qio_channel_socket_new();
291
+ t->ctrl_qc = qio_channel_socket_new();
374
+ t->ctrl_qc = qio_channel_socket_new();
292
+
375
+
293
+ 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) {
294
+ goto fail;
377
+ goto fail;
295
+
378
+ }
296
+ if (qio_channel_socket_connect_sync(t->ctrl_qc, mo->control, &errp) < 0)
379
+
297
+ goto fail;
380
+ if (qio_channel_socket_connect_sync(t->ctrl_qc, mo->control, &errp) < 0) {
298
+ qio_channel_close(QIO_CHANNEL(t->ctrl_qc), &errp);
381
+ goto fail;
299
+
382
+ }
300
+ if (!runstate_check(RUN_STATE_INMIGRATE)) {
383
+ qio_channel_close(QIO_CHANNEL(t->ctrl_qc), NULL);
301
+ /* reset the TPM using a power cycle sequence, in case someone
384
+ qio_channel_close(QIO_CHANNEL(t->cmd_qc), NULL);
302
+ * has previously powered it up */
385
+
303
+ sock = tpm_send_ctrl(t, TPM_SIGNAL_POWER_OFF, &errp);
304
+ if (sock != 0)
305
+ goto fail;
306
+ sock = tpm_send_ctrl(t, TPM_SIGNAL_POWER_ON, &errp);
307
+ if (sock != 0)
308
+ goto fail;
309
+ sock = tpm_send_ctrl(t, TPM_SIGNAL_NV_ON, &errp);
310
+ if (sock != 0)
311
+ goto fail;
312
+ }
313
+
386
+
314
+ return be;
387
+ return be;
315
+
388
+
316
+ fail:
389
+ fail:
317
+ object_unref(OBJECT(t->ctrl_qc));
390
+ object_unref(OBJECT(t->ctrl_qc));
...
...
346
+ cl->type = TPM_TYPE_MSSIM;
419
+ cl->type = TPM_TYPE_MSSIM;
347
+ cl->opts = tpm_mssim_cmdline_opts;
420
+ cl->opts = tpm_mssim_cmdline_opts;
348
+ cl->desc = "TPM mssim emulator backend driver";
421
+ cl->desc = "TPM mssim emulator backend driver";
349
+ cl->create = tpm_mssim_create;
422
+ cl->create = tpm_mssim_create;
350
+ cl->cancel_cmd = tpm_mssim_cancel_cmd;
423
+ cl->cancel_cmd = tpm_mssim_cancel_cmd;
424
+ cl->startup_tpm = tpm_mssim_startup;
351
+ cl->get_tpm_version = tpm_mssim_get_version;
425
+ cl->get_tpm_version = tpm_mssim_get_version;
352
+ cl->get_buffer_size = tpm_mssim_get_buffer_size;
426
+ cl->get_buffer_size = tpm_mssim_get_buffer_size;
353
+ cl->get_tpm_options = tpm_mssim_get_opts;
427
+ cl->get_tpm_options = tpm_mssim_get_opts;
354
+ cl->handle_request = tpm_mssim_handle_request;
428
+ cl->handle_request = tpm_mssim_handle_request;
355
+}
429
+}
356
+
430
+
357
+static const TypeInfo tpm_mssim_info = {
431
+static const TypeInfo tpm_mssim_info = {
358
+ .name = TYPE_TPM_MSSIM,
432
+ .name = TYPE_TPM_MSSIM,
359
+ .parent = TYPE_TPM_BACKEND,
433
+ .parent = TYPE_TPM_BACKEND,
360
+ .instance_size = sizeof(TPMmssim),
434
+ .instance_size = sizeof(TPMMssim),
361
+ .class_init = tpm_mssim_class_init,
435
+ .class_init = tpm_mssim_class_init,
362
+ .instance_init = tpm_mssim_instance_init,
436
+ .instance_init = tpm_mssim_instance_init,
363
+ .instance_finalize = tpm_mssim_instance_finalize,
437
+ .instance_finalize = tpm_mssim_instance_finalize,
364
+};
438
+};
365
+
439
+
...
...
389
+#define TPM_SIGNAL_POWER_OFF 2
463
+#define TPM_SIGNAL_POWER_OFF 2
390
+#define TPM_SIGNAL_PHYS_PRES_ON 3
464
+#define TPM_SIGNAL_PHYS_PRES_ON 3
391
+#define TPM_SIGNAL_PHYS_PRES_OFF 4
465
+#define TPM_SIGNAL_PHYS_PRES_OFF 4
392
+#define TPM_SIGNAL_HASH_START 5
466
+#define TPM_SIGNAL_HASH_START 5
393
+#define TPM_SIGNAL_HASH_DATA 6
467
+#define TPM_SIGNAL_HASH_DATA 6
394
+ // {uint32_t BufferSize, uint8_t[BufferSize] Buffer}
468
+/* {uint32_t BufferSize, uint8_t[BufferSize] Buffer} */
395
+#define TPM_SIGNAL_HASH_END 7
469
+#define TPM_SIGNAL_HASH_END 7
396
+#define TPM_SEND_COMMAND 8
470
+#define TPM_SEND_COMMAND 8
397
+ // {uint8_t Locality, uint32_t InBufferSize, uint8_t[InBufferSize] InBuffer} ->
471
+/*
398
+ // {uint32_t OutBufferSize, uint8_t[OutBufferSize] OutBuffer}
472
+ * {uint8_t Locality, uint32_t InBufferSize, uint8_t[InBufferSize] InBuffer} ->
399
+
473
+ * {uint32_t OutBufferSize, uint8_t[OutBufferSize] OutBuffer}
474
+ */
400
+#define TPM_SIGNAL_CANCEL_ON 9
475
+#define TPM_SIGNAL_CANCEL_ON 9
401
+#define TPM_SIGNAL_CANCEL_OFF 10
476
+#define TPM_SIGNAL_CANCEL_OFF 10
402
+#define TPM_SIGNAL_NV_ON 11
477
+#define TPM_SIGNAL_NV_ON 11
403
+#define TPM_SIGNAL_NV_OFF 12
478
+#define TPM_SIGNAL_NV_OFF 12
404
+#define TPM_SIGNAL_KEY_CACHE_ON 13
479
+#define TPM_SIGNAL_KEY_CACHE_ON 13
...
...
427
...
502
...
428
503
429
+The QEMU TPM Microsoft Simulator Device
504
+The QEMU TPM Microsoft Simulator Device
430
+---------------------------------------
505
+---------------------------------------
431
+
506
+
432
+The TCG provides a reference implementation for TPM 2.0 written by
507
+The Microsoft Simulator (mssim) is the reference emulation platform
433
+Microsoft (See `ms-tpm-20-ref`_ on github). The reference implementation
508
+for the TCG TPM 2.0 specification. It provides a reference
434
+starts a network server and listens for TPM commands on port 2321 and
509
+implementation for the TPM 2.0 written by Microsoft (See
435
+TPM Platform control commands on port 2322, although these can be
510
+`ms-tpm-20-ref`_ on github). The reference implementation starts a
436
+altered. The QEMU mssim TPM backend talks to this implementation. By
511
+network server and listens for TPM commands on port 2321 and TPM
437
+default it connects to the default ports on localhost:
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:
438
+
515
+
439
+.. code-block:: console
516
+.. code-block:: console
440
+
517
+
441
+ qemu-system-x86_64 <qemu-options> \
518
+ qemu-system-x86_64 <qemu-options> \
442
+ -tpmdev mssim,id=tpm0 \
519
+ -tpmdev mssim,id=tpm0 \
443
+ -device tpm-crb,tpmdev=tpm0
520
+ -device tpm-crb,tpmdev=tpm0
444
+
521
+
445
+
522
+
446
+Although it can also communicate with a remote host, which must be
523
+Although it can also communicate with a remote host, which must be
447
+specified as a SocketAddress via json on the command line for each of
524
+specified as a SocketAddress via json or dotted keys on the command
448
+the command and control ports:
525
+line for each of the command and control ports:
449
+
526
+
450
+.. code-block:: console
527
+.. code-block:: console
451
+
528
+
452
+ qemu-system-x86_64 <qemu-options> \
529
+ qemu-system-x86_64 <qemu-options> \
453
+ -tpmdev "{'type':'mssim','id':'tpm0','command':{'type':'inet','host':'remote','port':'2321'},'control':{'type':'inet','host':'remote','port':'2322'}}" \
530
+ -tpmdev "{'type':'mssim','id':'tpm0','command':{'type':'inet','host':'remote','port':'2321'},'control':{'type':'inet','host':'remote','port':'2322'}}" \
454
+ -device tpm-crb,tpmdev=tpm0
531
+ -device tpm-crb,tpmdev=tpm0
455
+
532
+
456
+
533
+
457
+The mssim backend supports snapshotting and migration, but the state
534
+The mssim backend supports snapshotting and migration by not resetting
458
+of the Microsoft Simulator server must be preserved (or the server
535
+the TPM on start up and not powering it down on halt if the VM is in
459
+kept running) outside of QEMU for restore to be successful.
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.
460
+
539
+
461
The QEMU TPM emulator device
540
The QEMU TPM emulator device
462
----------------------------
541
----------------------------
463
542
464
@@ -XXX,XX +XXX,XX @@ the following:
543
@@ -XXX,XX +XXX,XX @@ the following:
465
544
466
.. _SWTPM protocol:
545
.. _SWTPM protocol:
467
https://github.com/stefanberger/swtpm/blob/master/man/man3/swtpm_ioctls.pod
546
https://github.com/stefanberger/swtpm/blob/master/man/man3/swtpm_ioctls.pod
468
+
547
+
469
+.. _ms-tpm-20-ref:
548
+.. _ms-tpm-20-ref:
470
+ https://github.com/microsoft/ms-tpm-20-ref
549
+ https://github.com/microsoft/ms-tpm-20-ref
471
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
550
diff --git a/qapi/tpm.json b/qapi/tpm.json
472
index XXXXXXX..XXXXXXX 100644
551
index XXXXXXX..XXXXXXX 100644
473
--- a/monitor/hmp-cmds.c
552
--- a/qapi/tpm.json
474
+++ b/monitor/hmp-cmds.c
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
475
@@ -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)
476
unsigned int c = 0;
641
unsigned int c = 0;
477
TPMPassthroughOptions *tpo;
642
TPMPassthroughOptions *tpo;
478
TPMEmulatorOptions *teo;
643
TPMEmulatorOptions *teo;
479
+ TPMmssimOptions *tmo;
644
+ TPMMssimOptions *tmo;
480
645
481
info_list = qmp_query_tpm(&err);
646
info_list = qmp_query_tpm(&err);
482
if (err) {
647
if (err) {
483
@@ -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)
484
teo = ti->options->u.emulator.data;
649
teo = ti->options->u.emulator.data;
485
monitor_printf(mon, ",chardev=%s", teo->chardev);
650
monitor_printf(mon, ",chardev=%s", teo->chardev);
486
break;
651
break;
487
+ case TPM_TYPE_MSSIM:
652
+ case TPM_TYPE_MSSIM:
488
+ tmo = &ti->options->u.mssim;
653
+ tmo = &ti->options->u.mssim;
489
+ monitor_printf(mon, ",command=%s:%s,control=%s:%s",
654
+ monitor_printf(mon, ",command=%s:%s,control=%s:%s",
490
+ tmo->command->u.inet.host, tmo->command->u.inet.port,
655
+ tmo->command->u.inet.host,
491
+ 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);
492
+ break;
659
+ break;
493
case TPM_TYPE__MAX:
660
case TPM_TYPE__MAX:
494
break;
661
break;
495
}
662
}
496
diff --git a/qapi/tpm.json b/qapi/tpm.json
497
index XXXXXXX..XXXXXXX 100644
498
--- a/qapi/tpm.json
499
+++ b/qapi/tpm.json
500
@@ -XXX,XX +XXX,XX @@
501
##
502
# = TPM (trusted platform module) devices
503
##
504
+{ 'include': 'sockets.json' }
505
506
##
507
# @TpmModel:
508
@@ -XXX,XX +XXX,XX @@
509
#
510
# Since: 1.5
511
##
512
-{ 'enum': 'TpmType', 'data': [ 'passthrough', 'emulator' ],
513
+{ 'enum': 'TpmType', 'data': [ 'passthrough', 'emulator', 'mssim' ],
514
'if': 'CONFIG_TPM' }
515
516
##
517
@@ -XXX,XX +XXX,XX @@
518
# Example:
519
#
520
# -> { "execute": "query-tpm-types" }
521
-# <- { "return": [ "passthrough", "emulator" ] }
522
+# <- { "return": [ "passthrough", "emulator", "mssim" ] }
523
#
524
##
525
{ 'command': 'query-tpm-types', 'returns': ['TpmType'],
526
@@ -XXX,XX +XXX,XX @@
527
'data': { 'data': 'TPMEmulatorOptions' },
528
'if': 'CONFIG_TPM' }
529
530
+##
531
+# @TPMmssimOptions:
532
+#
533
+# Information for the mssim emulator connection
534
+#
535
+# @command: command socket for the TPM emulator
536
+# @control: control socket for the TPM emulator
537
+#
538
+# Since: 7.2.0
539
+##
540
+{ 'struct': 'TPMmssimOptions',
541
+ 'data': {
542
+ '*command': 'SocketAddress',
543
+ '*control': 'SocketAddress' },
544
+ 'if': 'CONFIG_TPM' }
545
+
546
##
547
# @TpmTypeOptions:
548
#
549
@@ -XXX,XX +XXX,XX @@
550
#
551
# @type: - 'passthrough' The configuration options for the TPM passthrough type
552
# - 'emulator' The configuration options for TPM emulator backend type
553
+# - 'mssim' The configuration options for TPM emulator mssim type
554
#
555
# Since: 1.5
556
##
557
@@ -XXX,XX +XXX,XX @@
558
'base': { 'type': 'TpmType' },
559
'discriminator': 'type',
560
'data': { 'passthrough' : 'TPMPassthroughOptionsWrapper',
561
- 'emulator': 'TPMEmulatorOptionsWrapper' },
562
+ 'emulator': 'TPMEmulatorOptionsWrapper',
563
+ 'mssim' : 'TPMmssimOptions' },
564
'if': 'CONFIG_TPM' }
565
566
##
567
@@ -XXX,XX +XXX,XX @@
568
'id' : 'str' },
569
'discriminator': 'type',
570
'data': { 'passthrough' : 'TPMPassthroughOptions',
571
- 'emulator': 'TPMEmulatorOptions' },
572
+ 'emulator': 'TPMEmulatorOptions',
573
+ 'mssim': 'TPMmssimOptions' },
574
'if': 'CONFIG_TPM' }
575
576
##
577
--
663
--
578
2.35.3
664
2.35.3
diff view generated by jsdifflib