Commit 9fe567d0 authored by Martin Schwidefsky's avatar Martin Schwidefsky
Browse files

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: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent c8e8ed38
Loading
Loading
Loading
Loading
+5 −14
Original line number Diff line number Diff line
@@ -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->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;
}