lkml.org 
[lkml]   [2014]   [Jun]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.4 142/214] efi_pstore: Check remaining space with QueryVariableInfo() before writing data
    Date
    3.4-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Seiji Aguchi <seiji.aguchi@hds.com>

    commit d80a361d779a9f19498943d1ca84243209cd5647 upstream.

    [Issue]

    As discussed in a thread below, Running out of space in EFI isn't a well-tested scenario.
    And we wouldn't expect all firmware to handle it gracefully.
    http://marc.info/?l=linux-kernel&m=134305325801789&w=2

    On the other hand, current efi_pstore doesn't check a remaining space of storage at writing time.
    Therefore, efi_pstore may not work if it tries to write a large amount of data.

    [Patch Description]

    To avoid handling the situation above, this patch checks if there is a space enough to log with
    QueryVariableInfo() before writing data.

    Signed-off-by: Seiji Aguchi <seiji.aguchi@hds.com>
    Acked-by: Mike Waychison <mikew@google.com>
    Signed-off-by: Tony Luck <tony.luck@intel.com>
    Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
    Cc: Rui Xiang <rui.xiang@huawei.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/firmware/efivars.c | 18 ++++++++++++++++++
    include/linux/efi.h | 1 +
    2 files changed, 19 insertions(+)

    --- a/drivers/firmware/efivars.c
    +++ b/drivers/firmware/efivars.c
    @@ -710,12 +710,29 @@ static int efi_pstore_write(enum pstore_
    struct efivars *efivars = psi->data;
    struct efivar_entry *entry, *found = NULL;
    int i, ret = 0;
    + u64 storage_space, remaining_space, max_variable_size;
    + efi_status_t status = EFI_NOT_FOUND;

    sprintf(stub_name, "dump-type%u-%u-", type, part);
    sprintf(name, "%s%lu", stub_name, get_seconds());

    spin_lock(&efivars->lock);

    + /*
    + * Check if there is a space enough to log.
    + * size: a size of logging data
    + * DUMP_NAME_LEN * 2: a maximum size of variable name
    + */
    + status = efivars->ops->query_variable_info(PSTORE_EFI_ATTRIBUTES,
    + &storage_space,
    + &remaining_space,
    + &max_variable_size);
    + if (status || remaining_space < size + DUMP_NAME_LEN * 2) {
    + spin_unlock(&efivars->lock);
    + *id = part;
    + return -ENOSPC;
    + }
    +
    for (i = 0; i < DUMP_NAME_LEN; i++)
    efi_name[i] = stub_name[i];

    @@ -1324,6 +1341,7 @@ efivars_init(void)
    ops.get_variable = efi.get_variable;
    ops.set_variable = efi.set_variable;
    ops.get_next_variable = efi.get_next_variable;
    + ops.query_variable_info = efi.query_variable_info;
    error = register_efivars(&__efivars, &ops, efi_kobj);
    if (error)
    goto err_put;
    --- a/include/linux/efi.h
    +++ b/include/linux/efi.h
    @@ -652,6 +652,7 @@ struct efivar_operations {
    efi_get_variable_t *get_variable;
    efi_get_next_variable_t *get_next_variable;
    efi_set_variable_t *set_variable;
    + efi_query_variable_info_t *query_variable_info;
    };

    struct efivars {



    \
     
     \ /
      Last update: 2014-06-05 23:01    [W:3.626 / U:0.052 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site