Extend the TPM TIS interface with state migration support.
We need to synchronize with the backend thread to make sure that a command
being processed by the external TPM emulator has completed and its
response been received.
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
---
hw/tpm/tpm_tis.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 53 insertions(+), 1 deletion(-)
diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
index 834eef7..5016d28 100644
--- a/hw/tpm/tpm_tis.c
+++ b/hw/tpm/tpm_tis.c
@@ -902,9 +902,61 @@ static void tpm_tis_reset(DeviceState *dev)
tpm_backend_startup_tpm(s->be_driver, s->be_buffer_size);
}
+/* persistent state handling */
+
+static int tpm_tis_pre_save(void *opaque)
+{
+ TPMState *s = opaque;
+ uint8_t locty = s->active_locty;
+
+ DPRINTF("tpm_tis: suspend: locty = %d : rw_offset = %u\n",
+ locty, s->rw_offset);
+#ifdef DEBUG_TIS
+ tpm_tis_dump_state(opaque, 0);
+#endif
+
+ /*
+ * Synchronize with backend completion.
+ */
+ tpm_backend_finish_sync(s->be_driver);
+
+ return 0;
+}
+
+static const VMStateDescription vmstate_locty = {
+ .name = "loc",
+ .version_id = 1,
+ .minimum_version_id = 0,
+ .minimum_version_id_old = 0,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(state, TPMLocality),
+ VMSTATE_UINT32(inte, TPMLocality),
+ VMSTATE_UINT32(ints, TPMLocality),
+ VMSTATE_UINT8(access, TPMLocality),
+ VMSTATE_UINT32(sts, TPMLocality),
+ VMSTATE_UINT32(iface_id, TPMLocality),
+ VMSTATE_END_OF_LIST(),
+ }
+};
+
static const VMStateDescription vmstate_tpm_tis = {
.name = "tpm",
- .unmigratable = 1,
+ .version_id = 1,
+ .minimum_version_id = 0,
+ .minimum_version_id_old = 0,
+ .pre_save = tpm_tis_pre_save,
+ .fields = (VMStateField[]) {
+ VMSTATE_BUFFER(buffer, TPMState),
+ VMSTATE_UINT16(rw_offset, TPMState),
+ VMSTATE_UINT8(active_locty, TPMState),
+ VMSTATE_UINT8(aborting_locty, TPMState),
+ VMSTATE_UINT8(next_locty, TPMState),
+
+ VMSTATE_STRUCT_ARRAY(loc, TPMState, TPM_TIS_NUM_LOCALITIES, 1,
+ vmstate_locty, TPMLocality),
+
+ VMSTATE_END_OF_LIST()
+ }
};
static Property tpm_tis_properties[] = {
--
2.5.5
Hi
On Thu, Mar 1, 2018 at 8:59 PM, Stefan Berger
<stefanb@linux.vnet.ibm.com> wrote:
> Extend the TPM TIS interface with state migration support.
>
> We need to synchronize with the backend thread to make sure that a command
> being processed by the external TPM emulator has completed and its
> response been received.
>
> Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
> ---
> hw/tpm/tpm_tis.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 53 insertions(+), 1 deletion(-)
>
> diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
> index 834eef7..5016d28 100644
> --- a/hw/tpm/tpm_tis.c
> +++ b/hw/tpm/tpm_tis.c
> @@ -902,9 +902,61 @@ static void tpm_tis_reset(DeviceState *dev)
> tpm_backend_startup_tpm(s->be_driver, s->be_buffer_size);
> }
>
> +/* persistent state handling */
> +
> +static int tpm_tis_pre_save(void *opaque)
> +{
> + TPMState *s = opaque;
> + uint8_t locty = s->active_locty;
> +
> + DPRINTF("tpm_tis: suspend: locty = %d : rw_offset = %u\n",
suspend -> pre_save ?
> + locty, s->rw_offset);
> +#ifdef DEBUG_TIS
> + tpm_tis_dump_state(opaque, 0);
> +#endif
To avoid dead code, you could write:
if (DEBUG_TIS) {
...
}
> +
> + /*
> + * Synchronize with backend completion.
> + */
> + tpm_backend_finish_sync(s->be_driver);
> +
> + return 0;
> +}
> +
> +static const VMStateDescription vmstate_locty = {
> + .name = "loc",
I would use a more descriptive name, such as "tpm-tis/locty"
> + .version_id = 1,
> + .minimum_version_id = 0,
It's the first version, make it all 0.
> + .minimum_version_id_old = 0,
not needed
> + .fields = (VMStateField[]) {
> + VMSTATE_UINT32(state, TPMLocality),
> + VMSTATE_UINT32(inte, TPMLocality),
> + VMSTATE_UINT32(ints, TPMLocality),
> + VMSTATE_UINT8(access, TPMLocality),
> + VMSTATE_UINT32(sts, TPMLocality),
> + VMSTATE_UINT32(iface_id, TPMLocality),
> + VMSTATE_END_OF_LIST(),
> + }
> +};
> +
> static const VMStateDescription vmstate_tpm_tis = {
> .name = "tpm",
It's time to use a more specific name "tpm-tis" ?
> - .unmigratable = 1,
> + .version_id = 1,
> + .minimum_version_id = 0,
It's the first version, make it all 0.
> + .minimum_version_id_old = 0,
not needed
> + .pre_save = tpm_tis_pre_save,
> + .fields = (VMStateField[]) {
> + VMSTATE_BUFFER(buffer, TPMState),
> + VMSTATE_UINT16(rw_offset, TPMState),
> + VMSTATE_UINT8(active_locty, TPMState),
> + VMSTATE_UINT8(aborting_locty, TPMState),
> + VMSTATE_UINT8(next_locty, TPMState),
> +
> + VMSTATE_STRUCT_ARRAY(loc, TPMState, TPM_TIS_NUM_LOCALITIES, 1,
> + vmstate_locty, TPMLocality),
> +
> + VMSTATE_END_OF_LIST()
> + }
> };
>
> static Property tpm_tis_properties[] = {
> --
> 2.5.5
>
>
looks good otherwise
--
Marc-André Lureau
Hi
On Thu, Mar 1, 2018 at 8:59 PM, Stefan Berger
<stefanb@linux.vnet.ibm.com> wrote:
> Extend the TPM TIS interface with state migration support.
>
> We need to synchronize with the backend thread to make sure that a command
> being processed by the external TPM emulator has completed and its
> response been received.
>
> Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
> ---
> hw/tpm/tpm_tis.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 53 insertions(+), 1 deletion(-)
>
> diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
> index 834eef7..5016d28 100644
> --- a/hw/tpm/tpm_tis.c
> +++ b/hw/tpm/tpm_tis.c
> @@ -902,9 +902,61 @@ static void tpm_tis_reset(DeviceState *dev)
> tpm_backend_startup_tpm(s->be_driver, s->be_buffer_size);
> }
>
> +/* persistent state handling */
> +
> +static int tpm_tis_pre_save(void *opaque)
> +{
> + TPMState *s = opaque;
> + uint8_t locty = s->active_locty;
> +
> + DPRINTF("tpm_tis: suspend: locty = %d : rw_offset = %u\n",
> + locty, s->rw_offset);
> +#ifdef DEBUG_TIS
> + tpm_tis_dump_state(opaque, 0);
> +#endif
> +
> + /*
> + * Synchronize with backend completion.
> + */
> + tpm_backend_finish_sync(s->be_driver);
> +
> + return 0;
> +}
> +
> +static const VMStateDescription vmstate_locty = {
> + .name = "loc",
> + .version_id = 1,
> + .minimum_version_id = 0,
> + .minimum_version_id_old = 0,
I don't understand the problem there is leaving all the version fields
to 0, just like CRB.
> + .fields = (VMStateField[]) {
> + VMSTATE_UINT32(state, TPMLocality),
> + VMSTATE_UINT32(inte, TPMLocality),
> + VMSTATE_UINT32(ints, TPMLocality),
> + VMSTATE_UINT8(access, TPMLocality),
> + VMSTATE_UINT32(sts, TPMLocality),
> + VMSTATE_UINT32(iface_id, TPMLocality),
> + VMSTATE_END_OF_LIST(),
> + }
> +};
> +
> static const VMStateDescription vmstate_tpm_tis = {
> .name = "tpm",
> - .unmigratable = 1,
> + .version_id = 1,
> + .minimum_version_id = 0,
> + .minimum_version_id_old = 0,
same
If you remove the version fields: Reviewed-by: Marc-André Lureau
<marcandre.lureau@redhat.com>
> + .pre_save = tpm_tis_pre_save,
> + .fields = (VMStateField[]) {
> + VMSTATE_BUFFER(buffer, TPMState),
> + VMSTATE_UINT16(rw_offset, TPMState),
> + VMSTATE_UINT8(active_locty, TPMState),
> + VMSTATE_UINT8(aborting_locty, TPMState),
> + VMSTATE_UINT8(next_locty, TPMState),
> +
> + VMSTATE_STRUCT_ARRAY(loc, TPMState, TPM_TIS_NUM_LOCALITIES, 1,
> + vmstate_locty, TPMLocality),
> +
> + VMSTATE_END_OF_LIST()
> + }
> };
>
> static Property tpm_tis_properties[] = {
> --
> 2.5.5
>
On 03/28/2018 11:41 AM, Marc-André Lureau wrote:
> Hi
>
> On Thu, Mar 1, 2018 at 8:59 PM, Stefan Berger
> <stefanb@linux.vnet.ibm.com> wrote:
>> +
>> +static const VMStateDescription vmstate_locty = {
>> + .name = "loc",
>> + .version_id = 1,
>> + .minimum_version_id = 0,
>> + .minimum_version_id_old = 0,
> I don't understand the problem there is leaving all the version fields
> to 0, just like CRB.
>
>> + .fields = (VMStateField[]) {
>> + VMSTATE_UINT32(state, TPMLocality),
>> + VMSTATE_UINT32(inte, TPMLocality),
>> + VMSTATE_UINT32(ints, TPMLocality),
>> + VMSTATE_UINT8(access, TPMLocality),
>> + VMSTATE_UINT32(sts, TPMLocality),
>> + VMSTATE_UINT32(iface_id, TPMLocality),
>> + VMSTATE_END_OF_LIST(),
>> + }
>> +};
>> +
>> static const VMStateDescription vmstate_tpm_tis = {
>> .name = "tpm",
>> - .unmigratable = 1,
>> + .version_id = 1,
>> + .minimum_version_id = 0,
>> + .minimum_version_id_old = 0,
> same
>
> If you remove the version fields: Reviewed-by: Marc-André Lureau
> <marcandre.lureau@redhat.com>
This is the error I got when setting .version_id = 0 (on both) and doing
a localhost migration
qemu-system-x86_64: Missing section footer for tpm-tis
qemu-system-x86_64: load of migration failed: Invalid argument
It must have something to do with the nesting invoked by
VMSTATE_STRUCT_ARRAY(loc,...) below.
>
>
>
>> + .pre_save = tpm_tis_pre_save,
>> + .fields = (VMStateField[]) {
>> + VMSTATE_BUFFER(buffer, TPMState),
>> + VMSTATE_UINT16(rw_offset, TPMState),
>> + VMSTATE_UINT8(active_locty, TPMState),
>> + VMSTATE_UINT8(aborting_locty, TPMState),
>> + VMSTATE_UINT8(next_locty, TPMState),
>> +
>> + VMSTATE_STRUCT_ARRAY(loc, TPMState, TPM_TIS_NUM_LOCALITIES, 1,
>> + vmstate_locty, TPMLocality),
>> +
>> + VMSTATE_END_OF_LIST()
>> + }
>> };
>>
>> static Property tpm_tis_properties[] = {
>> --
>> 2.5.5
>>
Hi
On Thu, Mar 29, 2018 at 1:56 AM, Stefan Berger
<stefanb@linux.vnet.ibm.com> wrote:
> On 03/28/2018 11:41 AM, Marc-André Lureau wrote:
>>
>> Hi
>>
>> On Thu, Mar 1, 2018 at 8:59 PM, Stefan Berger
>> <stefanb@linux.vnet.ibm.com> wrote:
>>>
>>> +
>>> +static const VMStateDescription vmstate_locty = {
>>> + .name = "loc",
>>> + .version_id = 1,
>>> + .minimum_version_id = 0,
>>> + .minimum_version_id_old = 0,
>>
>> I don't understand the problem there is leaving all the version fields
>> to 0, just like CRB.
>>
>>> + .fields = (VMStateField[]) {
>>> + VMSTATE_UINT32(state, TPMLocality),
>>> + VMSTATE_UINT32(inte, TPMLocality),
>>> + VMSTATE_UINT32(ints, TPMLocality),
>>> + VMSTATE_UINT8(access, TPMLocality),
>>> + VMSTATE_UINT32(sts, TPMLocality),
>>> + VMSTATE_UINT32(iface_id, TPMLocality),
>>> + VMSTATE_END_OF_LIST(),
>>> + }
>>> +};
>>> +
>>> static const VMStateDescription vmstate_tpm_tis = {
>>> .name = "tpm",
>>> - .unmigratable = 1,
>>> + .version_id = 1,
>>> + .minimum_version_id = 0,
>>> + .minimum_version_id_old = 0,
>>
>> same
>>
>> If you remove the version fields: Reviewed-by: Marc-André Lureau
>> <marcandre.lureau@redhat.com>
>
>
> This is the error I got when setting .version_id = 0 (on both) and doing a
> localhost migration
>
> qemu-system-x86_64: Missing section footer for tpm-tis
> qemu-system-x86_64: load of migration failed: Invalid argument
It's clearly not the most friendly error message, but I debugged it,
you just have to specify the right version for VMSTATE_STRUCT_ARRAY:
0.
VMSTATE_STRUCT_ARRAY(loc, TPMState, TPM_TIS_NUM_LOCALITIES, 0,
vmstate_locty, TPMLocality),
Then it all works with version 0 (or default value)
thanks
>
> It must have something to do with the nesting invoked by
> VMSTATE_STRUCT_ARRAY(loc,...) below.
>
>
>
>
>>
>>
>>
>>> + .pre_save = tpm_tis_pre_save,
>>> + .fields = (VMStateField[]) {
>>> + VMSTATE_BUFFER(buffer, TPMState),
>>> + VMSTATE_UINT16(rw_offset, TPMState),
>>> + VMSTATE_UINT8(active_locty, TPMState),
>>> + VMSTATE_UINT8(aborting_locty, TPMState),
>>> + VMSTATE_UINT8(next_locty, TPMState),
>>> +
>>> + VMSTATE_STRUCT_ARRAY(loc, TPMState, TPM_TIS_NUM_LOCALITIES, 1,
>>> + vmstate_locty, TPMLocality),
>>> +
>>> + VMSTATE_END_OF_LIST()
>>> + }
>>> };
>>>
>>> static Property tpm_tis_properties[] = {
>>> --
>>> 2.5.5
>>>
>
>
--
Marc-André Lureau
On 03/29/2018 01:07 PM, Marc-André Lureau wrote:
> Hi
>
> On Thu, Mar 29, 2018 at 1:56 AM, Stefan Berger
> <stefanb@linux.vnet.ibm.com> wrote:
>> On 03/28/2018 11:41 AM, Marc-André Lureau wrote:
>>> Hi
>>>
>>> On Thu, Mar 1, 2018 at 8:59 PM, Stefan Berger
>>> <stefanb@linux.vnet.ibm.com> wrote:
>>>> +
>>>> +static const VMStateDescription vmstate_locty = {
>>>> + .name = "loc",
>>>> + .version_id = 1,
>>>> + .minimum_version_id = 0,
>>>> + .minimum_version_id_old = 0,
>>> I don't understand the problem there is leaving all the version fields
>>> to 0, just like CRB.
>>>
>>>> + .fields = (VMStateField[]) {
>>>> + VMSTATE_UINT32(state, TPMLocality),
>>>> + VMSTATE_UINT32(inte, TPMLocality),
>>>> + VMSTATE_UINT32(ints, TPMLocality),
>>>> + VMSTATE_UINT8(access, TPMLocality),
>>>> + VMSTATE_UINT32(sts, TPMLocality),
>>>> + VMSTATE_UINT32(iface_id, TPMLocality),
>>>> + VMSTATE_END_OF_LIST(),
>>>> + }
>>>> +};
>>>> +
>>>> static const VMStateDescription vmstate_tpm_tis = {
>>>> .name = "tpm",
>>>> - .unmigratable = 1,
>>>> + .version_id = 1,
>>>> + .minimum_version_id = 0,
>>>> + .minimum_version_id_old = 0,
>>> same
>>>
>>> If you remove the version fields: Reviewed-by: Marc-André Lureau
>>> <marcandre.lureau@redhat.com>
>>
>> This is the error I got when setting .version_id = 0 (on both) and doing a
>> localhost migration
>>
>> qemu-system-x86_64: Missing section footer for tpm-tis
>> qemu-system-x86_64: load of migration failed: Invalid argument
> It's clearly not the most friendly error message, but I debugged it,
> you just have to specify the right version for VMSTATE_STRUCT_ARRAY:
> 0.
> VMSTATE_STRUCT_ARRAY(loc, TPMState, TPM_TIS_NUM_LOCALITIES, 0,
> vmstate_locty, TPMLocality),
>
> Then it all works with version 0 (or default value)
>
> thanks
Thanks.
© 2016 - 2026 Red Hat, Inc.