Commit 6a8a2354 authored by Marc-André Lureau's avatar Marc-André Lureau Committed by Stefan Berger
Browse files

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: default avatarMarc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: default avatarStefan Berger <stefanb@linux.vnet.ibm.com>
Signed-off-by: default avatarStefan Berger <stefanb@linux.vnet.ibm.com>
parent c4fb8561
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -27,7 +27,7 @@ static void tpm_backend_request_completed(void *opaque, int ret)
    TPMBackend *s = TPM_BACKEND(opaque);
    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 */
    s->cmd = NULL;
@@ -38,8 +38,13 @@ static int tpm_backend_worker_thread(gpointer data)
{
    TPMBackend *s = TPM_BACKEND(data);
    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;
}
+6 −15
Original line number Diff line number Diff line
@@ -183,28 +183,19 @@ static int tpm_emulator_set_locality(TPMEmulator *tpm_emu, uint8_t locty_number,
    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);
    Error *err = NULL;

    DPRINTF("processing TPM command");

    if (tpm_emulator_set_locality(tpm_emu, cmd->locty, &err) < 0) {
        goto error;
    }

    if (tpm_emulator_unix_tx_bufs(tpm_emu, cmd->in, cmd->in_len,
    if (tpm_emulator_set_locality(tpm_emu, cmd->locty, errp) < 0 ||
        tpm_emulator_unix_tx_bufs(tpm_emu, cmd->in, cmd->in_len,
                                  cmd->out, cmd->out_len,
                                  &cmd->selftest_done, &err) < 0) {
        goto error;
    }

    return;

error:
                                  &cmd->selftest_done, errp) < 0) {
        tpm_util_write_fatal_error_response(cmd->out, cmd->out_len);
    error_report_err(err);
    }
}

static int tpm_emulator_probe_caps(TPMEmulator *tpm_emu)
+15 −16
Original line number Diff line number Diff line
@@ -80,10 +80,11 @@ static int tpm_passthrough_unix_read(int fd, uint8_t *buf, uint32_t len)
    }
    return ret;
}
static int tpm_passthrough_unix_tx_bufs(TPMPassthruState *tpm_pt,

static void tpm_passthrough_unix_tx_bufs(TPMPassthruState *tpm_pt,
                                         const uint8_t *in, uint32_t in_len,
                                         uint8_t *out, uint32_t out_len,
                                        bool *selftest_done)
                                         bool *selftest_done, Error **errp)
{
    ssize_t ret;
    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);
    if (ret != in_len) {
        if (!tpm_pt->tpm_op_canceled || errno != ECANCELED) {
            error_report("tpm_passthrough: error while transmitting data "
                         "to TPM: %s (%i)",
                         strerror(errno), errno);
            error_setg_errno(errp, errno, "tpm_passthrough: error while "
                             "transmitting data to TPM");
        }
        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);
    if (ret < 0) {
        if (!tpm_pt->tpm_op_canceled || errno != ECANCELED) {
            error_report("tpm_passthrough: error while reading data from "
                         "TPM: %s (%i)",
                         strerror(errno), errno);
            error_setg_errno(errp, errno, "tpm_passthrough: error while "
                             "reading data from TPM");
        }
    } else if (ret < sizeof(struct tpm_resp_hdr) ||
               tpm_cmd_get_size(out) != ret) {
        ret = -1;
        error_report("tpm_passthrough: received invalid response "
                     "packet from TPM");
        error_setg_errno(errp, errno, "tpm_passthrough: received invalid "
                     "response packet from TPM");
    }

    if (is_selftest && (ret >= sizeof(struct tpm_resp_hdr))) {
@@ -131,18 +130,18 @@ err_exit:
    }

    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);

    DPRINTF("tpm_passthrough: processing command %p\n", cmd);

    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)
+2 −1
Original line number Diff line number Diff line
@@ -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.
 */
static void tpm_tis_request_completed(TPMIf *ti)
static void tpm_tis_request_completed(TPMIf *ti, int ret)
{
    TPMState *s = TPM(ti);
    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_VALID | TPM_TIS_STS_DATA_AVAILABLE);
    s->loc[locty].state = TPM_TIS_STATE_COMPLETION;
+1 −1
Original line number Diff line number Diff line
@@ -41,7 +41,7 @@ typedef struct TPMIfClass {
    InterfaceClass parent_class;

    enum TpmModel model;
    void (*request_completed)(TPMIf *obj);
    void (*request_completed)(TPMIf *obj, int ret);
    enum TPMVersion (*get_version)(TPMIf *obj);
} TPMIfClass;

Loading