Messages in this thread Patch in this message | | | From | Greg Kroah-Hartman <> | Subject | [PATCH 4.4 53/97] staging: unisys: visorhba: fix s-Par to boot with option CONFIG_VMAP_STACK set to y | Date | Fri, 23 Mar 2018 10:54:40 +0100 |
| |
4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sameer Wadgaonkar <sameer.wadgaonkar@unisys.com>
[ Upstream commit 3c2bf0bd08123f3497bd3e84bd9088c937b0cb40 ]
The root issue is that we are not allowed to have items on the stack being passed to "DMA" like operations. In this case we have a vmcall and an inline completion of scsi command.
This patch fixes the issue by moving the variables on stack in do_scsi_nolinuxstat() to heap memory.
Signed-off-by: Sameer Wadgaonkar <sameer.wadgaonkar@unisys.com> Signed-off-by: David Kershner <david.kershner@unisys.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> --- drivers/staging/unisys/visorhba/visorhba_main.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
--- a/drivers/staging/unisys/visorhba/visorhba_main.c +++ b/drivers/staging/unisys/visorhba/visorhba_main.c @@ -792,7 +792,7 @@ static void do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) { struct scsi_device *scsidev; - unsigned char buf[36]; + unsigned char *buf; struct scatterlist *sg; unsigned int i; char *this_page; @@ -807,6 +807,10 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cm if (cmdrsp->scsi.no_disk_result == 0) return; + buf = kzalloc(sizeof(char) * 36, GFP_KERNEL); + if (!buf) + return; + /* Linux scsi code wants a device at Lun 0 * to issue report luns, but we don't want * a disk there so we'll present a processor @@ -820,6 +824,7 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cm if (scsi_sg_count(scsicmd) == 0) { memcpy(scsi_sglist(scsicmd), buf, cmdrsp->scsi.bufflen); + kfree(buf); return; } @@ -831,6 +836,7 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cm memcpy(this_page, buf + bufind, sg[i].length); kunmap_atomic(this_page_orig); } + kfree(buf); } else { devdata = (struct visorhba_devdata *)scsidev->host->hostdata; for_each_vdisk_match(vdisk, devdata, scsidev) {
| |