lkml.org 
[lkml]   [2018]   [Apr]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.16 190/196] libnvdimm, dimm: handle EACCES failures from label reads
    Date
    4.16-stable review patch.  If anyone has any objections, please let me know.

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

    From: Dan Williams <dan.j.williams@intel.com>

    commit e7c5a571a8d6a266aee9ca3f3f26e5afe3717eca upstream.

    The new support for the standard _LSR and _LSW methods neglected to also
    update the nvdimm_init_config_data() and nvdimm_set_config_data() to
    return the translated error code from failed commands. This precision is
    necessary because the locked status that was previously returned on
    ND_CMD_GET_CONFIG_SIZE commands is now returned on
    ND_CMD_{GET,SET}_CONFIG_DATA commands.

    If the kernel misses this indication it can inadvertently fall back to
    label-less mode when it should otherwise avoid all access to locked
    regions.

    Cc: <stable@vger.kernel.org>
    Fixes: 4b27db7e26cd ("acpi, nfit: add support for the _LSI, _LSR, and...")
    Signed-off-by: Dan Williams <dan.j.williams@intel.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/nvdimm/dimm_devs.c | 22 ++++++++++++----------
    1 file changed, 12 insertions(+), 10 deletions(-)

    --- a/drivers/nvdimm/dimm_devs.c
    +++ b/drivers/nvdimm/dimm_devs.c
    @@ -88,9 +88,9 @@ int nvdimm_init_nsarea(struct nvdimm_drv
    int nvdimm_init_config_data(struct nvdimm_drvdata *ndd)
    {
    struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(ndd->dev);
    + int rc = validate_dimm(ndd), cmd_rc = 0;
    struct nd_cmd_get_config_data_hdr *cmd;
    struct nvdimm_bus_descriptor *nd_desc;
    - int rc = validate_dimm(ndd);
    u32 max_cmd_size, config_size;
    size_t offset;

    @@ -124,9 +124,11 @@ int nvdimm_init_config_data(struct nvdim
    cmd->in_offset = offset;
    rc = nd_desc->ndctl(nd_desc, to_nvdimm(ndd->dev),
    ND_CMD_GET_CONFIG_DATA, cmd,
    - cmd->in_length + sizeof(*cmd), NULL);
    - if (rc || cmd->status) {
    - rc = -ENXIO;
    + cmd->in_length + sizeof(*cmd), &cmd_rc);
    + if (rc < 0)
    + break;
    + if (cmd_rc < 0) {
    + rc = cmd_rc;
    break;
    }
    memcpy(ndd->data + offset, cmd->out_buf, cmd->in_length);
    @@ -140,9 +142,9 @@ int nvdimm_init_config_data(struct nvdim
    int nvdimm_set_config_data(struct nvdimm_drvdata *ndd, size_t offset,
    void *buf, size_t len)
    {
    - int rc = validate_dimm(ndd);
    size_t max_cmd_size, buf_offset;
    struct nd_cmd_set_config_hdr *cmd;
    + int rc = validate_dimm(ndd), cmd_rc = 0;
    struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(ndd->dev);
    struct nvdimm_bus_descriptor *nd_desc = nvdimm_bus->nd_desc;

    @@ -164,7 +166,6 @@ int nvdimm_set_config_data(struct nvdimm
    for (buf_offset = 0; len; len -= cmd->in_length,
    buf_offset += cmd->in_length) {
    size_t cmd_size;
    - u32 *status;

    cmd->in_offset = offset + buf_offset;
    cmd->in_length = min(max_cmd_size, len);
    @@ -172,12 +173,13 @@ int nvdimm_set_config_data(struct nvdimm

    /* status is output in the last 4-bytes of the command buffer */
    cmd_size = sizeof(*cmd) + cmd->in_length + sizeof(u32);
    - status = ((void *) cmd) + cmd_size - sizeof(u32);

    rc = nd_desc->ndctl(nd_desc, to_nvdimm(ndd->dev),
    - ND_CMD_SET_CONFIG_DATA, cmd, cmd_size, NULL);
    - if (rc || *status) {
    - rc = rc ? rc : -ENXIO;
    + ND_CMD_SET_CONFIG_DATA, cmd, cmd_size, &cmd_rc);
    + if (rc < 0)
    + break;
    + if (cmd_rc < 0) {
    + rc = cmd_rc;
    break;
    }
    }

    \
     
     \ /
      Last update: 2018-04-22 17:44    [W:2.709 / U:1.724 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site