tpm: report backend request error
Use an Error** for request to let the caller handle error reporting. This will also allow to inform the frontend of a backend error. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com> Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
This commit is contained in:
parent
c4fb8561bc
commit
6a8a23549a
|
@ -27,7 +27,7 @@ static void tpm_backend_request_completed(void *opaque, int ret)
|
||||||
TPMBackend *s = TPM_BACKEND(opaque);
|
TPMBackend *s = TPM_BACKEND(opaque);
|
||||||
TPMIfClass *tic = TPM_IF_GET_CLASS(s->tpmif);
|
TPMIfClass *tic = TPM_IF_GET_CLASS(s->tpmif);
|
||||||
|
|
||||||
tic->request_completed(s->tpmif);
|
tic->request_completed(s->tpmif, ret);
|
||||||
|
|
||||||
/* no need for atomic, as long the BQL is taken */
|
/* no need for atomic, as long the BQL is taken */
|
||||||
s->cmd = NULL;
|
s->cmd = NULL;
|
||||||
|
@ -38,8 +38,13 @@ static int tpm_backend_worker_thread(gpointer data)
|
||||||
{
|
{
|
||||||
TPMBackend *s = TPM_BACKEND(data);
|
TPMBackend *s = TPM_BACKEND(data);
|
||||||
TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);
|
TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);
|
||||||
|
Error *err = NULL;
|
||||||
|
|
||||||
k->handle_request(s, s->cmd);
|
k->handle_request(s, s->cmd, &err);
|
||||||
|
if (err) {
|
||||||
|
error_report_err(err);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -183,28 +183,19 @@ static int tpm_emulator_set_locality(TPMEmulator *tpm_emu, uint8_t locty_number,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tpm_emulator_handle_request(TPMBackend *tb, TPMBackendCmd *cmd)
|
static void tpm_emulator_handle_request(TPMBackend *tb, TPMBackendCmd *cmd,
|
||||||
|
Error **errp)
|
||||||
{
|
{
|
||||||
TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
|
TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
|
||||||
Error *err = NULL;
|
|
||||||
|
|
||||||
DPRINTF("processing TPM command");
|
DPRINTF("processing TPM command");
|
||||||
|
|
||||||
if (tpm_emulator_set_locality(tpm_emu, cmd->locty, &err) < 0) {
|
if (tpm_emulator_set_locality(tpm_emu, cmd->locty, errp) < 0 ||
|
||||||
goto error;
|
tpm_emulator_unix_tx_bufs(tpm_emu, cmd->in, cmd->in_len,
|
||||||
}
|
|
||||||
|
|
||||||
if (tpm_emulator_unix_tx_bufs(tpm_emu, cmd->in, cmd->in_len,
|
|
||||||
cmd->out, cmd->out_len,
|
cmd->out, cmd->out_len,
|
||||||
&cmd->selftest_done, &err) < 0) {
|
&cmd->selftest_done, errp) < 0) {
|
||||||
goto error;
|
tpm_util_write_fatal_error_response(cmd->out, cmd->out_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
error:
|
|
||||||
tpm_util_write_fatal_error_response(cmd->out, cmd->out_len);
|
|
||||||
error_report_err(err);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tpm_emulator_probe_caps(TPMEmulator *tpm_emu)
|
static int tpm_emulator_probe_caps(TPMEmulator *tpm_emu)
|
||||||
|
|
|
@ -80,10 +80,11 @@ static int tpm_passthrough_unix_read(int fd, uint8_t *buf, uint32_t len)
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
static int tpm_passthrough_unix_tx_bufs(TPMPassthruState *tpm_pt,
|
|
||||||
const uint8_t *in, uint32_t in_len,
|
static void tpm_passthrough_unix_tx_bufs(TPMPassthruState *tpm_pt,
|
||||||
uint8_t *out, uint32_t out_len,
|
const uint8_t *in, uint32_t in_len,
|
||||||
bool *selftest_done)
|
uint8_t *out, uint32_t out_len,
|
||||||
|
bool *selftest_done, Error **errp)
|
||||||
{
|
{
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
bool is_selftest;
|
bool is_selftest;
|
||||||
|
@ -98,9 +99,8 @@ static int tpm_passthrough_unix_tx_bufs(TPMPassthruState *tpm_pt,
|
||||||
ret = qemu_write_full(tpm_pt->tpm_fd, in, in_len);
|
ret = qemu_write_full(tpm_pt->tpm_fd, in, in_len);
|
||||||
if (ret != in_len) {
|
if (ret != in_len) {
|
||||||
if (!tpm_pt->tpm_op_canceled || errno != ECANCELED) {
|
if (!tpm_pt->tpm_op_canceled || errno != ECANCELED) {
|
||||||
error_report("tpm_passthrough: error while transmitting data "
|
error_setg_errno(errp, errno, "tpm_passthrough: error while "
|
||||||
"to TPM: %s (%i)",
|
"transmitting data to TPM");
|
||||||
strerror(errno), errno);
|
|
||||||
}
|
}
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
}
|
}
|
||||||
|
@ -110,15 +110,14 @@ static int tpm_passthrough_unix_tx_bufs(TPMPassthruState *tpm_pt,
|
||||||
ret = tpm_passthrough_unix_read(tpm_pt->tpm_fd, out, out_len);
|
ret = tpm_passthrough_unix_read(tpm_pt->tpm_fd, out, out_len);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if (!tpm_pt->tpm_op_canceled || errno != ECANCELED) {
|
if (!tpm_pt->tpm_op_canceled || errno != ECANCELED) {
|
||||||
error_report("tpm_passthrough: error while reading data from "
|
error_setg_errno(errp, errno, "tpm_passthrough: error while "
|
||||||
"TPM: %s (%i)",
|
"reading data from TPM");
|
||||||
strerror(errno), errno);
|
|
||||||
}
|
}
|
||||||
} else if (ret < sizeof(struct tpm_resp_hdr) ||
|
} else if (ret < sizeof(struct tpm_resp_hdr) ||
|
||||||
tpm_cmd_get_size(out) != ret) {
|
tpm_cmd_get_size(out) != ret) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
error_report("tpm_passthrough: received invalid response "
|
error_setg_errno(errp, errno, "tpm_passthrough: received invalid "
|
||||||
"packet from TPM");
|
"response packet from TPM");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_selftest && (ret >= sizeof(struct tpm_resp_hdr))) {
|
if (is_selftest && (ret >= sizeof(struct tpm_resp_hdr))) {
|
||||||
|
@ -131,18 +130,18 @@ err_exit:
|
||||||
}
|
}
|
||||||
|
|
||||||
tpm_pt->tpm_executing = false;
|
tpm_pt->tpm_executing = false;
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tpm_passthrough_handle_request(TPMBackend *tb, TPMBackendCmd *cmd)
|
static void tpm_passthrough_handle_request(TPMBackend *tb, TPMBackendCmd *cmd,
|
||||||
|
Error **errp)
|
||||||
{
|
{
|
||||||
TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
|
TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
|
||||||
|
|
||||||
DPRINTF("tpm_passthrough: processing command %p\n", cmd);
|
DPRINTF("tpm_passthrough: processing command %p\n", cmd);
|
||||||
|
|
||||||
tpm_passthrough_unix_tx_bufs(tpm_pt, cmd->in, cmd->in_len,
|
tpm_passthrough_unix_tx_bufs(tpm_pt, cmd->in, cmd->in_len,
|
||||||
cmd->out, cmd->out_len, &cmd->selftest_done);
|
cmd->out, cmd->out_len, &cmd->selftest_done,
|
||||||
|
errp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tpm_passthrough_reset(TPMBackend *tb)
|
static void tpm_passthrough_reset(TPMBackend *tb)
|
||||||
|
|
|
@ -393,7 +393,7 @@ static void tpm_tis_prep_abort(TPMState *s, uint8_t locty, uint8_t newlocty)
|
||||||
/*
|
/*
|
||||||
* Callback from the TPM to indicate that the response was received.
|
* Callback from the TPM to indicate that the response was received.
|
||||||
*/
|
*/
|
||||||
static void tpm_tis_request_completed(TPMIf *ti)
|
static void tpm_tis_request_completed(TPMIf *ti, int ret)
|
||||||
{
|
{
|
||||||
TPMState *s = TPM(ti);
|
TPMState *s = TPM(ti);
|
||||||
uint8_t locty = s->cmd.locty;
|
uint8_t locty = s->cmd.locty;
|
||||||
|
@ -405,6 +405,7 @@ static void tpm_tis_request_completed(TPMIf *ti)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME: report error if ret != 0 */
|
||||||
tpm_tis_sts_set(&s->loc[locty],
|
tpm_tis_sts_set(&s->loc[locty],
|
||||||
TPM_TIS_STS_VALID | TPM_TIS_STS_DATA_AVAILABLE);
|
TPM_TIS_STS_VALID | TPM_TIS_STS_DATA_AVAILABLE);
|
||||||
s->loc[locty].state = TPM_TIS_STATE_COMPLETION;
|
s->loc[locty].state = TPM_TIS_STATE_COMPLETION;
|
||||||
|
|
|
@ -41,7 +41,7 @@ typedef struct TPMIfClass {
|
||||||
InterfaceClass parent_class;
|
InterfaceClass parent_class;
|
||||||
|
|
||||||
enum TpmModel model;
|
enum TpmModel model;
|
||||||
void (*request_completed)(TPMIf *obj);
|
void (*request_completed)(TPMIf *obj, int ret);
|
||||||
enum TPMVersion (*get_version)(TPMIf *obj);
|
enum TPMVersion (*get_version)(TPMIf *obj);
|
||||||
} TPMIfClass;
|
} TPMIfClass;
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "qapi-types.h"
|
#include "qapi-types.h"
|
||||||
#include "qemu/option.h"
|
#include "qemu/option.h"
|
||||||
#include "sysemu/tpm.h"
|
#include "sysemu/tpm.h"
|
||||||
|
#include "qapi/error.h"
|
||||||
|
|
||||||
#define TYPE_TPM_BACKEND "tpm-backend"
|
#define TYPE_TPM_BACKEND "tpm-backend"
|
||||||
#define TPM_BACKEND(obj) \
|
#define TPM_BACKEND(obj) \
|
||||||
|
@ -84,7 +85,7 @@ struct TPMBackendClass {
|
||||||
|
|
||||||
TpmTypeOptions *(*get_tpm_options)(TPMBackend *t);
|
TpmTypeOptions *(*get_tpm_options)(TPMBackend *t);
|
||||||
|
|
||||||
void (*handle_request)(TPMBackend *s, TPMBackendCmd *cmd);
|
void (*handle_request)(TPMBackend *s, TPMBackendCmd *cmd, Error **errp);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue