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