s390/dasd: fix read device characteristic with CONFIG_VMAP_STACK=y
The dasd_eckd_restore_device() function calls dasd_generic_read_dev_chars with a temporary buffer on the stack. With CONFIG_VMAP_STACK=y this is a vmalloc address but dasd_generic_restore_device() uses the address of the buffer as I/O address. Circumvent this by using the already allocated cqr->data buffer for the RDC data. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
Родитель
c8e8ed386a
Коммит
9fe567d09f
|
@ -3965,13 +3965,11 @@ int dasd_generic_restore_device(struct ccw_device *cdev)
|
|||
EXPORT_SYMBOL_GPL(dasd_generic_restore_device);
|
||||
|
||||
static struct dasd_ccw_req *dasd_generic_build_rdc(struct dasd_device *device,
|
||||
void *rdc_buffer,
|
||||
int rdc_buffer_size,
|
||||
int magic)
|
||||
{
|
||||
struct dasd_ccw_req *cqr;
|
||||
struct ccw1 *ccw;
|
||||
unsigned long *idaw;
|
||||
|
||||
cqr = dasd_smalloc_request(magic, 1 /* RDC */, rdc_buffer_size, device,
|
||||
NULL);
|
||||
|
@ -3986,16 +3984,8 @@ static struct dasd_ccw_req *dasd_generic_build_rdc(struct dasd_device *device,
|
|||
|
||||
ccw = cqr->cpaddr;
|
||||
ccw->cmd_code = CCW_CMD_RDC;
|
||||
if (idal_is_needed(rdc_buffer, rdc_buffer_size)) {
|
||||
idaw = (unsigned long *) (cqr->data);
|
||||
ccw->cda = (__u32)(addr_t) idaw;
|
||||
ccw->flags = CCW_FLAG_IDA;
|
||||
idaw = idal_create_words(idaw, rdc_buffer, rdc_buffer_size);
|
||||
} else {
|
||||
ccw->cda = (__u32)(addr_t) rdc_buffer;
|
||||
ccw->flags = 0;
|
||||
}
|
||||
|
||||
ccw->cda = (__u32)(addr_t) cqr->data;
|
||||
ccw->flags = 0;
|
||||
ccw->count = rdc_buffer_size;
|
||||
cqr->startdev = device;
|
||||
cqr->memdev = device;
|
||||
|
@ -4013,12 +4003,13 @@ int dasd_generic_read_dev_chars(struct dasd_device *device, int magic,
|
|||
int ret;
|
||||
struct dasd_ccw_req *cqr;
|
||||
|
||||
cqr = dasd_generic_build_rdc(device, rdc_buffer, rdc_buffer_size,
|
||||
magic);
|
||||
cqr = dasd_generic_build_rdc(device, rdc_buffer_size, magic);
|
||||
if (IS_ERR(cqr))
|
||||
return PTR_ERR(cqr);
|
||||
|
||||
ret = dasd_sleep_on(cqr);
|
||||
if (ret == 0)
|
||||
memcpy(rdc_buffer, cqr->data, rdc_buffer_size);
|
||||
dasd_sfree_request(cqr, cqr->memdev);
|
||||
return ret;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче