- Use the post_load_with_error() hook to propagate TPM
errors.
- The error object is set if the loading of state fails.
It can then be retrieved using QMP command:
{"execute" : "query-migrate"}
Buglink: https://issues.redhat.com/browse/RHEL-82826
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Arun Menon <armenon@redhat.com>
---
backends/tpm/tpm_emulator.c | 39 ++++++++++++++++++++-------------------
1 file changed, 20 insertions(+), 19 deletions(-)
diff --git a/backends/tpm/tpm_emulator.c b/backends/tpm/tpm_emulator.c
index 4a234ab2c0b19b2604bf0dd8cb5f4540c72a9438..816134d7b4de00a75a3d0b928d160595b17be810 100644
--- a/backends/tpm/tpm_emulator.c
+++ b/backends/tpm/tpm_emulator.c
@@ -819,7 +819,8 @@ static int tpm_emulator_get_state_blobs(TPMEmulator *tpm_emu)
static int tpm_emulator_set_state_blob(TPMEmulator *tpm_emu,
uint32_t type,
TPMSizedBuffer *tsb,
- uint32_t flags)
+ uint32_t flags,
+ Error **errp)
{
ssize_t n;
ptm_setstate pss;
@@ -838,17 +839,17 @@ static int tpm_emulator_set_state_blob(TPMEmulator *tpm_emu,
/* write the header only */
if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SET_STATEBLOB, &pss,
offsetof(ptm_setstate, u.req.data), 0, 0) < 0) {
- error_report("tpm-emulator: could not set state blob type %d : %s",
- type, strerror(errno));
+ error_setg(errp, "tpm-emulator: could not set state blob type %d : %s",
+ type, strerror(errno));
return -1;
}
/* now the body */
n = qemu_chr_fe_write_all(&tpm_emu->ctrl_chr, tsb->buffer, tsb->size);
if (n != tsb->size) {
- error_report("tpm-emulator: Writing the stateblob (type %d) "
- "failed; could not write %u bytes, but only %zd",
- type, tsb->size, n);
+ error_setg(errp, "tpm-emulator: Writing the stateblob (type %d) "
+ "failed; could not write %u bytes, but only %zd",
+ type, tsb->size, n);
return -1;
}
@@ -856,17 +857,17 @@ static int tpm_emulator_set_state_blob(TPMEmulator *tpm_emu,
n = qemu_chr_fe_read_all(&tpm_emu->ctrl_chr,
(uint8_t *)&pss, sizeof(pss.u.resp));
if (n != sizeof(pss.u.resp)) {
- error_report("tpm-emulator: Reading response from writing stateblob "
- "(type %d) failed; expected %zu bytes, got %zd", type,
- sizeof(pss.u.resp), n);
+ error_setg(errp, "tpm-emulator: Reading response from writing "
+ "stateblob (type %d) failed; expected %zu bytes, "
+ "got %zd", type, sizeof(pss.u.resp), n);
return -1;
}
tpm_result = be32_to_cpu(pss.u.resp.tpm_result);
if (tpm_result != 0) {
- error_report("tpm-emulator: Setting the stateblob (type %d) failed "
- "with a TPM error 0x%x %s", type, tpm_result,
- tpm_emulator_strerror(tpm_result));
+ error_setg(errp, "tpm-emulator: Setting the stateblob (type %d) "
+ "failed with a TPM error 0x%x %s", type, tpm_result,
+ tpm_emulator_strerror(tpm_result));
return -1;
}
@@ -880,7 +881,7 @@ static int tpm_emulator_set_state_blob(TPMEmulator *tpm_emu,
*
* Returns a negative errno code in case of error.
*/
-static int tpm_emulator_set_state_blobs(TPMBackend *tb)
+static int tpm_emulator_set_state_blobs(TPMBackend *tb, Error **errp)
{
TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
TPMBlobBuffers *state_blobs = &tpm_emu->state_blobs;
@@ -894,13 +895,13 @@ static int tpm_emulator_set_state_blobs(TPMBackend *tb)
if (tpm_emulator_set_state_blob(tpm_emu, PTM_BLOB_TYPE_PERMANENT,
&state_blobs->permanent,
- state_blobs->permanent_flags) < 0 ||
+ state_blobs->permanent_flags, errp) < 0 ||
tpm_emulator_set_state_blob(tpm_emu, PTM_BLOB_TYPE_VOLATILE,
&state_blobs->volatil,
- state_blobs->volatil_flags) < 0 ||
+ state_blobs->volatil_flags, errp) < 0 ||
tpm_emulator_set_state_blob(tpm_emu, PTM_BLOB_TYPE_SAVESTATE,
&state_blobs->savestate,
- state_blobs->savestate_flags) < 0) {
+ state_blobs->savestate_flags, errp) < 0) {
return -EIO;
}
@@ -948,12 +949,12 @@ static void tpm_emulator_vm_state_change(void *opaque, bool running,
*
* Returns negative errno codes in case of error.
*/
-static int tpm_emulator_post_load(void *opaque, int version_id)
+static int tpm_emulator_post_load(void *opaque, int version_id, Error **errp)
{
TPMBackend *tb = opaque;
int ret;
- ret = tpm_emulator_set_state_blobs(tb);
+ ret = tpm_emulator_set_state_blobs(tb, errp);
if (ret < 0) {
return ret;
}
@@ -969,7 +970,7 @@ static const VMStateDescription vmstate_tpm_emulator = {
.name = "tpm-emulator",
.version_id = 0,
.pre_save = tpm_emulator_pre_save,
- .post_load = tpm_emulator_post_load,
+ .post_load_with_error = tpm_emulator_post_load,
.fields = (const VMStateField[]) {
VMSTATE_UINT32(state_blobs.permanent_flags, TPMEmulator),
VMSTATE_UINT32(state_blobs.permanent.size, TPMEmulator),
--
2.49.0
On Wed, Jul 02, 2025 at 05:06:52PM +0530, Arun Menon wrote:
> - Use the post_load_with_error() hook to propagate TPM
> errors.
> - The error object is set if the loading of state fails.
> It can then be retrieved using QMP command:
> {"execute" : "query-migrate"}
This is only describing what has been done - good commit messages
should primarily describe why it is being done.
> Buglink: https://issues.redhat.com/browse/RHEL-82826
We shouldn't rely on people reading through the buglink to
learn the 'why' - please summarize the important contextual
info and problem scenario here.
>
> Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
> Signed-off-by: Arun Menon <armenon@redhat.com>
> ---
> backends/tpm/tpm_emulator.c | 39 ++++++++++++++++++++-------------------
> 1 file changed, 20 insertions(+), 19 deletions(-)
>
> diff --git a/backends/tpm/tpm_emulator.c b/backends/tpm/tpm_emulator.c
> index 4a234ab2c0b19b2604bf0dd8cb5f4540c72a9438..816134d7b4de00a75a3d0b928d160595b17be810 100644
> --- a/backends/tpm/tpm_emulator.c
> +++ b/backends/tpm/tpm_emulator.c
> @@ -819,7 +819,8 @@ static int tpm_emulator_get_state_blobs(TPMEmulator *tpm_emu)
> static int tpm_emulator_set_state_blob(TPMEmulator *tpm_emu,
> uint32_t type,
> TPMSizedBuffer *tsb,
> - uint32_t flags)
> + uint32_t flags,
> + Error **errp)
> {
> ssize_t n;
> ptm_setstate pss;
> @@ -838,17 +839,17 @@ static int tpm_emulator_set_state_blob(TPMEmulator *tpm_emu,
> /* write the header only */
> if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SET_STATEBLOB, &pss,
> offsetof(ptm_setstate, u.req.data), 0, 0) < 0) {
> - error_report("tpm-emulator: could not set state blob type %d : %s",
> - type, strerror(errno));
> + error_setg(errp, "tpm-emulator: could not set state blob type %d : %s",
> + type, strerror(errno));
> return -1;
> }
>
> /* now the body */
> n = qemu_chr_fe_write_all(&tpm_emu->ctrl_chr, tsb->buffer, tsb->size);
> if (n != tsb->size) {
> - error_report("tpm-emulator: Writing the stateblob (type %d) "
> - "failed; could not write %u bytes, but only %zd",
> - type, tsb->size, n);
> + error_setg(errp, "tpm-emulator: Writing the stateblob (type %d) "
> + "failed; could not write %u bytes, but only %zd",
> + type, tsb->size, n);
> return -1;
> }
>
> @@ -856,17 +857,17 @@ static int tpm_emulator_set_state_blob(TPMEmulator *tpm_emu,
> n = qemu_chr_fe_read_all(&tpm_emu->ctrl_chr,
> (uint8_t *)&pss, sizeof(pss.u.resp));
> if (n != sizeof(pss.u.resp)) {
> - error_report("tpm-emulator: Reading response from writing stateblob "
> - "(type %d) failed; expected %zu bytes, got %zd", type,
> - sizeof(pss.u.resp), n);
> + error_setg(errp, "tpm-emulator: Reading response from writing "
> + "stateblob (type %d) failed; expected %zu bytes, "
> + "got %zd", type, sizeof(pss.u.resp), n);
> return -1;
> }
>
> tpm_result = be32_to_cpu(pss.u.resp.tpm_result);
> if (tpm_result != 0) {
> - error_report("tpm-emulator: Setting the stateblob (type %d) failed "
> - "with a TPM error 0x%x %s", type, tpm_result,
> - tpm_emulator_strerror(tpm_result));
> + error_setg(errp, "tpm-emulator: Setting the stateblob (type %d) "
> + "failed with a TPM error 0x%x %s", type, tpm_result,
> + tpm_emulator_strerror(tpm_result));
> return -1;
> }
>
> @@ -880,7 +881,7 @@ static int tpm_emulator_set_state_blob(TPMEmulator *tpm_emu,
> *
> * Returns a negative errno code in case of error.
> */
> -static int tpm_emulator_set_state_blobs(TPMBackend *tb)
> +static int tpm_emulator_set_state_blobs(TPMBackend *tb, Error **errp)
> {
> TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
> TPMBlobBuffers *state_blobs = &tpm_emu->state_blobs;
> @@ -894,13 +895,13 @@ static int tpm_emulator_set_state_blobs(TPMBackend *tb)
>
> if (tpm_emulator_set_state_blob(tpm_emu, PTM_BLOB_TYPE_PERMANENT,
> &state_blobs->permanent,
> - state_blobs->permanent_flags) < 0 ||
> + state_blobs->permanent_flags, errp) < 0 ||
> tpm_emulator_set_state_blob(tpm_emu, PTM_BLOB_TYPE_VOLATILE,
> &state_blobs->volatil,
> - state_blobs->volatil_flags) < 0 ||
> + state_blobs->volatil_flags, errp) < 0 ||
> tpm_emulator_set_state_blob(tpm_emu, PTM_BLOB_TYPE_SAVESTATE,
> &state_blobs->savestate,
> - state_blobs->savestate_flags) < 0) {
> + state_blobs->savestate_flags, errp) < 0) {
> return -EIO;
> }
>
> @@ -948,12 +949,12 @@ static void tpm_emulator_vm_state_change(void *opaque, bool running,
> *
> * Returns negative errno codes in case of error.
> */
> -static int tpm_emulator_post_load(void *opaque, int version_id)
> +static int tpm_emulator_post_load(void *opaque, int version_id, Error **errp)
> {
> TPMBackend *tb = opaque;
> int ret;
>
> - ret = tpm_emulator_set_state_blobs(tb);
> + ret = tpm_emulator_set_state_blobs(tb, errp);
> if (ret < 0) {
> return ret;
> }
> @@ -969,7 +970,7 @@ static const VMStateDescription vmstate_tpm_emulator = {
> .name = "tpm-emulator",
> .version_id = 0,
> .pre_save = tpm_emulator_pre_save,
> - .post_load = tpm_emulator_post_load,
> + .post_load_with_error = tpm_emulator_post_load,
> .fields = (const VMStateField[]) {
> VMSTATE_UINT32(state_blobs.permanent_flags, TPMEmulator),
> VMSTATE_UINT32(state_blobs.permanent.size, TPMEmulator),
>
> --
> 2.49.0
>
>
With regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
© 2016 - 2025 Red Hat, Inc.