| From 5b77b8bf95f4d154adeb4331ca247ddb1f0e0802 Mon Sep 17 00:00:00 2001 |
| From: raymond pang <raymondpangxd@gmail.com> |
| Date: Thu, 28 Mar 2019 12:19:25 +0000 |
| Subject: libata: fix using DMA buffers on stack |
| |
| [ Upstream commit dd08a8d9a66de4b54575c294a92630299f7e0fe7 ] |
| |
| When CONFIG_VMAP_STACK=y, __pa() returns incorrect physical address for |
| a stack virtual address. Stack DMA buffers must be avoided. |
| |
| Signed-off-by: raymond pang <raymondpangxd@gmail.com> |
| Signed-off-by: Jens Axboe <axboe@kernel.dk> |
| Signed-off-by: Sasha Levin (Microsoft) <sashal@kernel.org> |
| --- |
| drivers/ata/libata-zpodd.c | 34 ++++++++++++++++++++++++---------- |
| 1 file changed, 24 insertions(+), 10 deletions(-) |
| |
| diff --git a/drivers/ata/libata-zpodd.c b/drivers/ata/libata-zpodd.c |
| index b3ed8f9953a8..173e6f2dd9af 100644 |
| --- a/drivers/ata/libata-zpodd.c |
| +++ b/drivers/ata/libata-zpodd.c |
| @@ -52,38 +52,52 @@ static int eject_tray(struct ata_device *dev) |
| /* Per the spec, only slot type and drawer type ODD can be supported */ |
| static enum odd_mech_type zpodd_get_mech_type(struct ata_device *dev) |
| { |
| - char buf[16]; |
| + char *buf; |
| unsigned int ret; |
| - struct rm_feature_desc *desc = (void *)(buf + 8); |
| + struct rm_feature_desc *desc; |
| struct ata_taskfile tf; |
| static const char cdb[] = { GPCMD_GET_CONFIGURATION, |
| 2, /* only 1 feature descriptor requested */ |
| 0, 3, /* 3, removable medium feature */ |
| 0, 0, 0,/* reserved */ |
| - 0, sizeof(buf), |
| + 0, 16, |
| 0, 0, 0, |
| }; |
| |
| + buf = kzalloc(16, GFP_KERNEL); |
| + if (!buf) |
| + return ODD_MECH_TYPE_UNSUPPORTED; |
| + desc = (void *)(buf + 8); |
| + |
| ata_tf_init(dev, &tf); |
| tf.flags = ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; |
| tf.command = ATA_CMD_PACKET; |
| tf.protocol = ATAPI_PROT_PIO; |
| - tf.lbam = sizeof(buf); |
| + tf.lbam = 16; |
| |
| ret = ata_exec_internal(dev, &tf, cdb, DMA_FROM_DEVICE, |
| - buf, sizeof(buf), 0); |
| - if (ret) |
| + buf, 16, 0); |
| + if (ret) { |
| + kfree(buf); |
| return ODD_MECH_TYPE_UNSUPPORTED; |
| + } |
| |
| - if (be16_to_cpu(desc->feature_code) != 3) |
| + if (be16_to_cpu(desc->feature_code) != 3) { |
| + kfree(buf); |
| return ODD_MECH_TYPE_UNSUPPORTED; |
| + } |
| |
| - if (desc->mech_type == 0 && desc->load == 0 && desc->eject == 1) |
| + if (desc->mech_type == 0 && desc->load == 0 && desc->eject == 1) { |
| + kfree(buf); |
| return ODD_MECH_TYPE_SLOT; |
| - else if (desc->mech_type == 1 && desc->load == 0 && desc->eject == 1) |
| + } else if (desc->mech_type == 1 && desc->load == 0 && |
| + desc->eject == 1) { |
| + kfree(buf); |
| return ODD_MECH_TYPE_DRAWER; |
| - else |
| + } else { |
| + kfree(buf); |
| return ODD_MECH_TYPE_UNSUPPORTED; |
| + } |
| } |
| |
| /* Test if ODD is zero power ready by sense code */ |
| -- |
| 2.19.1 |
| |