Skip to content

Commit d7776a0

Browse files
Stefan Haberlandgregkh
authored andcommitted
s390/dasd: fix inability to use DASD with DIAG driver
commit 9f4aa52 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: ce3dc44 ("s390: add support for virtually mapped kernel stacks") Signed-off-by: Stefan Haberland <[email protected]> Reviewed-by: Peter Oberparleiter <[email protected]> Cc: [email protected] #4.20 Signed-off-by: Jens Axboe <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 2026a26 commit d7776a0

File tree

1 file changed

+17
-8
lines changed

1 file changed

+17
-8
lines changed

drivers/s390/block/dasd_diag.c

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ dasd_diag_check_device(struct dasd_device *device)
319319
struct dasd_diag_characteristics *rdc_data;
320320
struct vtoc_cms_label *label;
321321
struct dasd_block *block;
322-
struct dasd_diag_bio bio;
322+
struct dasd_diag_bio *bio;
323323
unsigned int sb, bsize;
324324
blocknum_t end_block;
325325
int rc;
@@ -395,29 +395,36 @@ dasd_diag_check_device(struct dasd_device *device)
395395
rc = -ENOMEM;
396396
goto out;
397397
}
398+
bio = kzalloc(sizeof(*bio), GFP_KERNEL);
399+
if (bio == NULL) {
400+
DBF_DEV_EVENT(DBF_WARNING, device, "%s",
401+
"No memory to allocate initialization bio");
402+
rc = -ENOMEM;
403+
goto out_label;
404+
}
398405
rc = 0;
399406
end_block = 0;
400407
/* try all sizes - needed for ECKD devices */
401408
for (bsize = 512; bsize <= PAGE_SIZE; bsize <<= 1) {
402409
mdsk_init_io(device, bsize, 0, &end_block);
403-
memset(&bio, 0, sizeof (struct dasd_diag_bio));
404-
bio.type = MDSK_READ_REQ;
405-
bio.block_number = private->pt_block + 1;
406-
bio.buffer = label;
410+
memset(bio, 0, sizeof(*bio));
411+
bio->type = MDSK_READ_REQ;
412+
bio->block_number = private->pt_block + 1;
413+
bio->buffer = label;
407414
memset(&private->iob, 0, sizeof (struct dasd_diag_rw_io));
408415
private->iob.dev_nr = rdc_data->dev_nr;
409416
private->iob.key = 0;
410417
private->iob.flags = 0; /* do synchronous io */
411418
private->iob.block_count = 1;
412419
private->iob.interrupt_params = 0;
413-
private->iob.bio_list = &bio;
420+
private->iob.bio_list = bio;
414421
private->iob.flaga = DASD_DIAG_FLAGA_DEFAULT;
415422
rc = dia250(&private->iob, RW_BIO);
416423
if (rc == 3) {
417424
pr_warn("%s: A 64-bit DIAG call failed\n",
418425
dev_name(&device->cdev->dev));
419426
rc = -EOPNOTSUPP;
420-
goto out_label;
427+
goto out_bio;
421428
}
422429
mdsk_term_io(device);
423430
if (rc == 0)
@@ -427,7 +434,7 @@ dasd_diag_check_device(struct dasd_device *device)
427434
pr_warn("%s: Accessing the DASD failed because of an incorrect format (rc=%d)\n",
428435
dev_name(&device->cdev->dev), rc);
429436
rc = -EIO;
430-
goto out_label;
437+
goto out_bio;
431438
}
432439
/* check for label block */
433440
if (memcmp(label->label_id, DASD_DIAG_CMS1,
@@ -457,6 +464,8 @@ dasd_diag_check_device(struct dasd_device *device)
457464
(rc == 4) ? ", read-only device" : "");
458465
rc = 0;
459466
}
467+
out_bio:
468+
kfree(bio);
460469
out_label:
461470
free_page((long) label);
462471
out:

0 commit comments

Comments
 (0)