lkml.org 
[lkml]   [2020]   [Aug]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.4 268/270] s390/dasd: fix inability to use DASD with DIAG driver
    Date
    From: Stefan Haberland <sth@linux.ibm.com>

    commit 9f4aa52387c68049403b59939df5c0dd8e3872cc upstream.

    During initialization of the DASD DIAG driver a request is issued
    that has a bio structure that resides on the stack. With virtually
    mapped kernel stacks this bio address might be in virtual storage
    which is unsuitable for usage with the diag250 call.
    In this case the device can not be set online using the DIAG
    discipline and fails with -EOPNOTSUP.
    In the system journal the following error message is presented:

    dasd: X.X.XXXX Setting the DASD online with discipline DIAG failed
    with rc=-95

    Fix by allocating the bio structure instead of having it on the stack.

    Fixes: ce3dc447493f ("s390: add support for virtually mapped kernel stacks")
    Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
    Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
    Cc: stable@vger.kernel.org #4.20
    Signed-off-by: Jens Axboe <axboe@kernel.dk>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/s390/block/dasd_diag.c | 25 +++++++++++++++++--------
    1 file changed, 17 insertions(+), 8 deletions(-)

    --- a/drivers/s390/block/dasd_diag.c
    +++ b/drivers/s390/block/dasd_diag.c
    @@ -319,7 +319,7 @@ dasd_diag_check_device(struct dasd_devic
    struct dasd_diag_characteristics *rdc_data;
    struct vtoc_cms_label *label;
    struct dasd_block *block;
    - struct dasd_diag_bio bio;
    + struct dasd_diag_bio *bio;
    unsigned int sb, bsize;
    blocknum_t end_block;
    int rc;
    @@ -395,29 +395,36 @@ dasd_diag_check_device(struct dasd_devic
    rc = -ENOMEM;
    goto out;
    }
    + bio = kzalloc(sizeof(*bio), GFP_KERNEL);
    + if (bio == NULL) {
    + DBF_DEV_EVENT(DBF_WARNING, device, "%s",
    + "No memory to allocate initialization bio");
    + rc = -ENOMEM;
    + goto out_label;
    + }
    rc = 0;
    end_block = 0;
    /* try all sizes - needed for ECKD devices */
    for (bsize = 512; bsize <= PAGE_SIZE; bsize <<= 1) {
    mdsk_init_io(device, bsize, 0, &end_block);
    - memset(&bio, 0, sizeof (struct dasd_diag_bio));
    - bio.type = MDSK_READ_REQ;
    - bio.block_number = private->pt_block + 1;
    - bio.buffer = label;
    + memset(bio, 0, sizeof(*bio));
    + bio->type = MDSK_READ_REQ;
    + bio->block_number = private->pt_block + 1;
    + bio->buffer = label;
    memset(&private->iob, 0, sizeof (struct dasd_diag_rw_io));
    private->iob.dev_nr = rdc_data->dev_nr;
    private->iob.key = 0;
    private->iob.flags = 0; /* do synchronous io */
    private->iob.block_count = 1;
    private->iob.interrupt_params = 0;
    - private->iob.bio_list = &bio;
    + private->iob.bio_list = bio;
    private->iob.flaga = DASD_DIAG_FLAGA_DEFAULT;
    rc = dia250(&private->iob, RW_BIO);
    if (rc == 3) {
    pr_warn("%s: A 64-bit DIAG call failed\n",
    dev_name(&device->cdev->dev));
    rc = -EOPNOTSUPP;
    - goto out_label;
    + goto out_bio;
    }
    mdsk_term_io(device);
    if (rc == 0)
    @@ -427,7 +434,7 @@ dasd_diag_check_device(struct dasd_devic
    pr_warn("%s: Accessing the DASD failed because of an incorrect format (rc=%d)\n",
    dev_name(&device->cdev->dev), rc);
    rc = -EIO;
    - goto out_label;
    + goto out_bio;
    }
    /* check for label block */
    if (memcmp(label->label_id, DASD_DIAG_CMS1,
    @@ -457,6 +464,8 @@ dasd_diag_check_device(struct dasd_devic
    (rc == 4) ? ", read-only device" : "");
    rc = 0;
    }
    +out_bio:
    + kfree(bio);
    out_label:
    free_page((long) label);
    out:

    \
     
     \ /
      Last update: 2020-08-17 19:56    [W:4.444 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site