All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Marc-André Lureau" <marcandre.lureau@gmail.com>
To: Stefan Berger <stefanb@linux.vnet.ibm.com>
Cc: amarnath valluri <amarnath.valluri@intel.com>,
	QEMU <qemu-devel@nongnu.org>
Subject: Re: [Qemu-devel] [PATCH v2 25/28] tpm-emulator: protect concurrent ctrl_chr access
Date: Tue, 7 Nov 2017 12:08:18 +0100	[thread overview]
Message-ID: <CAJ+F1CLiyKOt5-oT8YShQjhH2OpUHeuYGy_bmO0ZcCxaiWJoLg@mail.gmail.com> (raw)
In-Reply-To: <7aa51688-2a80-b934-2b21-4673f4a600cc@linux.vnet.ibm.com>

Hi

On Tue, Nov 7, 2017 at 2:11 AM, Stefan Berger
<stefanb@linux.vnet.ibm.com> wrote:
> On 11/06/2017 05:11 PM, Marc-André Lureau wrote:
>>
>> Hi
>>
>> ----- Original Message -----
>>>
>>> On 11/06/2017 01:39 PM, Marc-André Lureau wrote:
>>>>
>>>> The control chardev is being used from the data thread to set the
>>>> locality of the next request. Altough the chr has a write mutex, we
>>>> may potentially read the reply from another thread request.
>>>
>>> Right, so there may be concurrency with the CMD_RESET/GET_TPMESTABLISHED
>>> commands. All the other ones shouldn't be affected. It sound like a bug
>>> in existing code.
>>>
>> I think so too, I'll rebase on master for 2.11, unless you can trivially
>> cherry-pick it.
>
>
> I could trivially cherry-pick it. Now can I send it as a pull request ?
>

Sure, thanks!


>    Stefan
>
>
>>
>>>> Add a mutex to protect from concurrent control commands.
>>>>
>>>> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>>>
>>> Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
>>>
>>>
>> thanks
>>
>>>> ---
>>>>    hw/tpm/tpm_emulator.c | 44
>>>> ++++++++++++++++++++++++++++----------------
>>>>    1 file changed, 28 insertions(+), 16 deletions(-)
>>>>
>>>> diff --git a/hw/tpm/tpm_emulator.c b/hw/tpm/tpm_emulator.c
>>>> index b77c0238c7..24cb61162f 100644
>>>> --- a/hw/tpm/tpm_emulator.c
>>>> +++ b/hw/tpm/tpm_emulator.c
>>>> @@ -71,15 +71,21 @@ typedef struct TPMEmulator {
>>>>        ptm_cap caps; /* capabilities of the TPM */
>>>>        uint8_t cur_locty_number; /* last set locality */
>>>>        Error *migration_blocker;
>>>> +
>>>> +    QemuMutex mutex;
>>>>    } TPMEmulator;
>>>>
>>>>
>>>> -static int tpm_emulator_ctrlcmd(CharBackend *dev, unsigned long cmd,
>>>> void
>>>> *msg,
>>>> +static int tpm_emulator_ctrlcmd(TPMEmulator *tpm, unsigned long cmd,
>>>> void
>>>> *msg,
>>>>                                    size_t msg_len_in, size_t
>>>> msg_len_out)
>>>>    {
>>>> +    CharBackend *dev = &tpm->ctrl_chr;
>>>>        uint32_t cmd_no = cpu_to_be32(cmd);
>>>>        ssize_t n = sizeof(uint32_t) + msg_len_in;
>>>>        uint8_t *buf = NULL;
>>>> +    int ret = -1;
>>>> +
>>>> +    qemu_mutex_lock(&tpm->mutex);
>>>>
>>>>        buf = g_alloca(n);
>>>>        memcpy(buf, &cmd_no, sizeof(cmd_no));
>>>> @@ -87,17 +93,21 @@ static int tpm_emulator_ctrlcmd(CharBackend *dev,
>>>> unsigned long cmd, void *msg,
>>>>
>>>>        n = qemu_chr_fe_write_all(dev, buf, n);
>>>>        if (n <= 0) {
>>>> -        return -1;
>>>> +        goto end;
>>>>        }
>>>>
>>>>        if (msg_len_out != 0) {
>>>>            n = qemu_chr_fe_read_all(dev, msg, msg_len_out);
>>>>            if (n <= 0) {
>>>> -            return -1;
>>>> +            goto end;
>>>>            }
>>>>        }
>>>>
>>>> -    return 0;
>>>> +    ret = 0;
>>>> +
>>>> +end:
>>>> +    qemu_mutex_unlock(&tpm->mutex);
>>>> +    return ret;
>>>>    }
>>>>
>>>>    static int tpm_emulator_unix_tx_bufs(TPMEmulator *tpm_emu,
>>>> @@ -154,7 +164,7 @@ static int tpm_emulator_set_locality(TPMEmulator
>>>> *tpm_emu, uint8_t locty_number,
>>>>
>>>>        DPRINTF("setting locality : 0x%x", locty_number);
>>>>        loc.u.req.loc = locty_number;
>>>> -    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_SET_LOCALITY,
>>>> &loc,
>>>> +    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SET_LOCALITY, &loc,
>>>>                                 sizeof(loc), sizeof(loc)) < 0) {
>>>>            error_setg(errp, "tpm-emulator: could not set locality : %s",
>>>>                       strerror(errno));
>>>> @@ -200,8 +210,8 @@ error:
>>>>    static int tpm_emulator_probe_caps(TPMEmulator *tpm_emu)
>>>>    {
>>>>        DPRINTF("%s", __func__);
>>>> -    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_GET_CAPABILITY,
>>>> -                         &tpm_emu->caps, 0, sizeof(tpm_emu->caps)) < 0)
>>>> {
>>>> +    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_GET_CAPABILITY,
>>>> +                             &tpm_emu->caps, 0, sizeof(tpm_emu->caps))
>>>> <
>>>> 0) {
>>>>            error_report("tpm-emulator: probing failed : %s",
>>>>            strerror(errno));
>>>>            return -1;
>>>>        }
>>>> @@ -252,8 +262,8 @@ static int tpm_emulator_startup_tpm(TPMBackend *tb)
>>>>        ptm_res res;
>>>>
>>>>        DPRINTF("%s", __func__);
>>>> -    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_INIT, &init,
>>>> sizeof(init),
>>>> -                         sizeof(init)) < 0) {
>>>> +    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_INIT, &init, sizeof(init),
>>>> +                             sizeof(init)) < 0) {
>>>>            error_report("tpm-emulator: could not send INIT: %s",
>>>>                         strerror(errno));
>>>>            goto err_exit;
>>>> @@ -276,7 +286,7 @@ static bool
>>>> tpm_emulator_get_tpm_established_flag(TPMBackend *tb)
>>>>        ptm_est est;
>>>>
>>>>        DPRINTF("%s", __func__);
>>>> -    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr,
>>>> CMD_GET_TPMESTABLISHED,
>>>> &est,
>>>> +    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_GET_TPMESTABLISHED, &est,
>>>>                                 0, sizeof(est)) < 0) {
>>>>            error_report("tpm-emulator: Could not get the TPM established
>>>>            flag: %s",
>>>>                         strerror(errno));
>>>> @@ -300,7 +310,7 @@ static int
>>>> tpm_emulator_reset_tpm_established_flag(TPMBackend *tb,
>>>>        }
>>>>
>>>>        reset_est.u.req.loc = tpm_emu->cur_locty_number;
>>>> -    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr,
>>>> CMD_RESET_TPMESTABLISHED,
>>>> +    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_RESET_TPMESTABLISHED,
>>>>                                 &reset_est, sizeof(reset_est),
>>>>                                 sizeof(reset_est)) < 0) {
>>>>            error_report("tpm-emulator: Could not reset the establishment
>>>>            bit: %s",
>>>> @@ -329,7 +339,7 @@ static void tpm_emulator_cancel_cmd(TPMBackend *tb)
>>>>        }
>>>>
>>>>        /* FIXME: make the function non-blocking, or it may block a VCPU
>>>> */
>>>> -    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_CANCEL_TPM_CMD,
>>>> &res,
>>>> 0,
>>>> +    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_CANCEL_TPM_CMD, &res, 0,
>>>>                                 sizeof(res)) < 0) {
>>>>            error_report("tpm-emulator: Could not cancel command: %s",
>>>>                         strerror(errno));
>>>> @@ -377,8 +387,8 @@ static int tpm_emulator_prepare_data_fd(TPMEmulator
>>>> *tpm_emu)
>>>>
>>>>        qemu_chr_fe_set_msgfds(&tpm_emu->ctrl_chr, fds + 1, 1);
>>>>
>>>> -    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_SET_DATAFD, &res,
>>>> 0,
>>>> -                    sizeof(res)) || res != 0) {
>>>> +    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SET_DATAFD, &res, 0,
>>>> +                             sizeof(res)) < 0 || res != 0) {
>>>>            error_report("tpm-emulator: Failed to send CMD_SET_DATAFD:
>>>> %s",
>>>>                         strerror(errno));
>>>>            goto err_exit;
>>>> @@ -494,6 +504,7 @@ static void tpm_emulator_inst_init(Object *obj)
>>>>        DPRINTF("%s", __func__);
>>>>        tpm_emu->options = g_new0(TPMEmulatorOptions, 1);
>>>>        tpm_emu->cur_locty_number = ~0;
>>>> +    qemu_mutex_init(&tpm_emu->mutex);
>>>>    }
>>>>
>>>>    /*
>>>> @@ -503,8 +514,7 @@ static void tpm_emulator_shutdown(TPMEmulator
>>>> *tpm_emu)
>>>>    {
>>>>        ptm_res res;
>>>>
>>>> -    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_SHUTDOWN, &res, 0,
>>>> -                             sizeof(res)) < 0) {
>>>> +    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SHUTDOWN, &res, 0,
>>>> sizeof(res))
>>>> < 0) {
>>>>            error_report("tpm-emulator: Could not cleanly shutdown the
>>>> TPM:
>>>>            %s",
>>>>                         strerror(errno));
>>>>        } else if (res != 0) {
>>>> @@ -529,6 +539,8 @@ static void tpm_emulator_inst_finalize(Object *obj)
>>>>            migrate_del_blocker(tpm_emu->migration_blocker);
>>>>            error_free(tpm_emu->migration_blocker);
>>>>        }
>>>> +
>>>> +    qemu_mutex_destroy(&tpm_emu->mutex);
>>>>    }
>>>>
>>>>    static void tpm_emulator_class_init(ObjectClass *klass, void *data)
>>>
>>>
>>>
>
>



-- 
Marc-André Lureau

  reply	other threads:[~2017-11-07 11:08 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-06 18:38 [Qemu-devel] [PATCH v2 00/28] TPM: code cleanup (not 2.11) Marc-André Lureau
2017-11-06 18:38 ` [Qemu-devel] [PATCH v2 01/28] tpm-tis: remove unused locty_number Marc-André Lureau
2017-11-06 18:57   ` Stefan Berger
2017-11-06 18:38 ` [Qemu-devel] [PATCH v2 02/28] tpm: move TpmIf in include/sysemu/tpm.h Marc-André Lureau
2017-11-06 18:58   ` Stefan Berger
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 03/28] tpm-backend: store TPMIf interface, improve backend_init() Marc-André Lureau
2017-11-06 19:02   ` Stefan Berger
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 04/28] tpm-tis: no longer expose TPMState Marc-André Lureau
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 05/28] tpm-be: call request_completed() out of thread Marc-André Lureau
2017-11-06 19:22   ` Stefan Berger
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 06/28] tpm-be: report error instead of front-end Marc-André Lureau
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 07/28] tpm-be: ask model to the TPM interface Marc-André Lureau
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 08/28] tpm: remove unused opened code Marc-André Lureau
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 09/28] tpm-passthrough: don't save guessed cancel_path in options Marc-André Lureau
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 10/28] tpm-be: update optional function pointers Marc-André Lureau
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 11/28] tpm-passthrough: pass TPMPassthruState to handle_device_opts Marc-André Lureau
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 12/28] tpm-backend: move set 'id' to common code Marc-André Lureau
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 13/28] tpm-passthrough: make it safer to destroy after creation Marc-André Lureau
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 14/28] tpm-passthrough: simplify create() Marc-André Lureau
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 15/28] tpm-passthrough: workaround a possible race Marc-André Lureau
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 16/28] tpm-tis: simplify header inclusion Marc-André Lureau
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 17/28] tpm: rename qemu_find_tpm() -> qemu_find_tpm_be() Marc-André Lureau
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 18/28] tpm: lookup the the TPM interface instead of TIS device Marc-André Lureau
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 19/28] tpm: add TPM interface to lookup TPM version Marc-André Lureau
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 20/28] tpm: add tpm_cmd_get_size() to tpm_util Marc-André Lureau
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 21/28] acpi: change TPM TIS data conditions Marc-André Lureau
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 22/28] tpm-emulator: add a FIXME comment about blocking cancel Marc-André Lureau
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 23/28] tpm-tis: remove redundant 'tpm_tis:' in error messages Marc-André Lureau
2017-11-06 19:24   ` Stefan Berger
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 24/28] tpm-tis: check that at most one TPM device exists Marc-André Lureau
2017-11-06 19:25   ` Stefan Berger
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 25/28] tpm-emulator: protect concurrent ctrl_chr access Marc-André Lureau
2017-11-06 19:32   ` Stefan Berger
2017-11-06 22:11     ` Marc-André Lureau
2017-11-07  1:11       ` Stefan Berger
2017-11-07 11:08         ` Marc-André Lureau [this message]
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 26/28] qdev: add DEFINE_PROP_TPMBE Marc-André Lureau
2017-11-06 20:31   ` Stefan Berger
2017-11-07 10:58     ` Marc-André Lureau
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 27/28] tpm-tis: use DEFINE_PROP_TPMBE Marc-André Lureau
2017-11-06 20:31   ` Stefan Berger
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 28/28] tpm: remove tpm_register_model() Marc-André Lureau
2017-11-06 20:33   ` Stefan Berger
2017-11-07  1:05 ` [Qemu-devel] [PATCH v2 00/28] TPM: code cleanup (not 2.11) Stefan Berger

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAJ+F1CLiyKOt5-oT8YShQjhH2OpUHeuYGy_bmO0ZcCxaiWJoLg@mail.gmail.com \
    --to=marcandre.lureau@gmail.com \
    --cc=amarnath.valluri@intel.com \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanb@linux.vnet.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.