From 404da66ccd3da52ba8f3a6d08ed028d5033e90a3 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 7 Aug 2017 16:22:50 -0700 Subject: [PATCH] 4.12-stable patches added patches: tcmu-fix-flushing-cmd-entry-dcache-page.patch tcmu-fix-possbile-memory-leak-oops-when-recalculating-cmd-base-size.patch --- queue-4.12/series | 2 + ...u-fix-flushing-cmd-entry-dcache-page.patch | 51 +++++++ ...ops-when-recalculating-cmd-base-size.patch | 125 ++++++++++++++++++ 3 files changed, 178 insertions(+) create mode 100644 queue-4.12/tcmu-fix-flushing-cmd-entry-dcache-page.patch create mode 100644 queue-4.12/tcmu-fix-possbile-memory-leak-oops-when-recalculating-cmd-base-size.patch diff --git a/queue-4.12/series b/queue-4.12/series index 943c280955f..cb4bd70945c 100644 --- a/queue-4.12/series +++ b/queue-4.12/series @@ -46,3 +46,5 @@ media-pulse8-cec-persistent_config-should-be-off-by-default.patch media-lirc-lirc_get_rec_resolution-should-return-microseconds.patch media-platform-davinci-return-einval-for-vpfe_cmd_s_ccdc_raw_params-ioctl.patch ir-spi-fix-issues-with-lirc-api.patch +tcmu-fix-flushing-cmd-entry-dcache-page.patch +tcmu-fix-possbile-memory-leak-oops-when-recalculating-cmd-base-size.patch diff --git a/queue-4.12/tcmu-fix-flushing-cmd-entry-dcache-page.patch b/queue-4.12/tcmu-fix-flushing-cmd-entry-dcache-page.patch new file mode 100644 index 00000000000..b5d33ffae57 --- /dev/null +++ b/queue-4.12/tcmu-fix-flushing-cmd-entry-dcache-page.patch @@ -0,0 +1,51 @@ +From 9d62bc0e6d79b11e3298e831358155930fb8f5e3 Mon Sep 17 00:00:00 2001 +From: Xiubo Li +Date: Fri, 30 Jun 2017 16:14:16 +0800 +Subject: tcmu: Fix flushing cmd entry dcache page + +From: Xiubo Li + +commit 9d62bc0e6d79b11e3298e831358155930fb8f5e3 upstream. + +When feeding the tcmu's cmd ring, we need to flush the dcache page +for the cmd entry to make sure these kernel stores are visible to +user space mappings of that page. + +For the none PAD cmd entry, this will be flushed at the end of the +tcmu_queue_cmd_ring(). + +Signed-off-by: Xiubo Li +Reviewed-by: Mike Christie +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_user.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/target/target_core_user.c ++++ b/drivers/target/target_core_user.c +@@ -699,21 +699,21 @@ tcmu_queue_cmd_ring(struct tcmu_cmd *tcm + size_t pad_size = head_to_end(cmd_head, udev->cmdr_size); + + entry = (void *) mb + CMDR_OFF + cmd_head; +- tcmu_flush_dcache_range(entry, sizeof(*entry)); + tcmu_hdr_set_op(&entry->hdr.len_op, TCMU_OP_PAD); + tcmu_hdr_set_len(&entry->hdr.len_op, pad_size); + entry->hdr.cmd_id = 0; /* not used for PAD */ + entry->hdr.kflags = 0; + entry->hdr.uflags = 0; ++ tcmu_flush_dcache_range(entry, sizeof(*entry)); + + UPDATE_HEAD(mb->cmd_head, pad_size, udev->cmdr_size); ++ tcmu_flush_dcache_range(mb, sizeof(*mb)); + + cmd_head = mb->cmd_head % udev->cmdr_size; /* UAM */ + WARN_ON(cmd_head != 0); + } + + entry = (void *) mb + CMDR_OFF + cmd_head; +- tcmu_flush_dcache_range(entry, sizeof(*entry)); + tcmu_hdr_set_op(&entry->hdr.len_op, TCMU_OP_CMD); + entry->hdr.cmd_id = tcmu_cmd->cmd_id; + entry->hdr.kflags = 0; diff --git a/queue-4.12/tcmu-fix-possbile-memory-leak-oops-when-recalculating-cmd-base-size.patch b/queue-4.12/tcmu-fix-possbile-memory-leak-oops-when-recalculating-cmd-base-size.patch new file mode 100644 index 00000000000..48cfdb8a3f5 --- /dev/null +++ b/queue-4.12/tcmu-fix-possbile-memory-leak-oops-when-recalculating-cmd-base-size.patch @@ -0,0 +1,125 @@ +From b3743c71b7c33a126d6d8942bb268775987400ec Mon Sep 17 00:00:00 2001 +From: Xiubo Li +Date: Tue, 11 Jul 2017 17:59:43 +0800 +Subject: tcmu: Fix possbile memory leak / OOPs when recalculating cmd base size + +From: Xiubo Li + +commit b3743c71b7c33a126d6d8942bb268775987400ec upstream. + +For all the entries allocated from the ring cmd area, the memory is +something like the stack memory, which will always reserve the old +data, so the entry->req.iov_bidi_cnt maybe none zero. + +On some environments, the crash could be reproduce very easy and some +not. The following is the crash core trace as reported by Damien: + +[ 240.143969] CPU: 0 PID: 1285 Comm: iscsi_trx Not tainted 4.12.0-rc1+ #3 +[ 240.150607] Hardware name: ASUS All Series/H87-PRO, BIOS 2104 10/28/2014 +[ 240.157331] task: ffff8807de4f5800 task.stack: ffffc900047dc000 +[ 240.163270] RIP: 0010:memcpy_erms+0x6/0x10 +[ 240.167377] RSP: 0018:ffffc900047dfc68 EFLAGS: 00010202 +[ 240.172621] RAX: ffffc9065db85540 RBX: ffff8807f7980000 RCX: 0000000000000010 +[ 240.179771] RDX: 0000000000000010 RSI: ffff8807de574fe0 RDI: ffffc9065db85540 +[ 240.186930] RBP: ffffc900047dfd30 R08: ffff8807de41b000 R09: 0000000000000000 +[ 240.194088] R10: 0000000000000040 R11: ffff8807e9b726f0 R12: 00000006565726b0 +[ 240.201246] R13: ffffc90007612ea0 R14: 000000065657d540 R15: 0000000000000000 +[ 240.208397] FS: 0000000000000000(0000) GS:ffff88081fa00000(0000) knlGS:0000000000000000 +[ 240.216510] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 240.222280] CR2: ffffc9065db85540 CR3: 0000000001c0f000 CR4: 00000000001406f0 +[ 240.229430] Call Trace: +[ 240.231887] ? tcmu_queue_cmd+0x83c/0xa80 +[ 240.235916] ? target_check_reservation+0xcd/0x6f0 +[ 240.240725] __target_execute_cmd+0x27/0xa0 +[ 240.244918] target_execute_cmd+0x232/0x2c0 +[ 240.249124] ? __local_bh_enable_ip+0x64/0xa0 +[ 240.253499] iscsit_execute_cmd+0x20d/0x270 +[ 240.257693] iscsit_sequence_cmd+0x110/0x190 +[ 240.261985] iscsit_get_rx_pdu+0x360/0xc80 +[ 240.267565] ? iscsi_target_rx_thread+0x54/0xd0 +[ 240.273571] iscsi_target_rx_thread+0x9a/0xd0 +[ 240.279413] kthread+0x113/0x150 +[ 240.284120] ? iscsi_target_tx_thread+0x1e0/0x1e0 +[ 240.290297] ? kthread_create_on_node+0x40/0x40 +[ 240.296297] ret_from_fork+0x2e/0x40 +[ 240.301332] Code: 90 90 90 90 90 eb 1e 0f 1f 00 48 89 f8 48 89 d1 48 +c1 e9 03 83 e2 07 f3 48 a5 89 d1 f3 a4 c3 66 0f 1f 44 00 00 48 89 f8 48 +89 d1 a4 c3 0f 1f 80 00 00 00 00 48 89 f8 48 83 fa 20 72 7e 40 38 +[ 240.321751] RIP: memcpy_erms+0x6/0x10 RSP: ffffc900047dfc68 +[ 240.328838] CR2: ffffc9065db85540 +[ 240.333667] ---[ end trace b7e5354cfb54d08b ]--- + +To fix this, just memset all the entry memory before using it, and +also to be more readable we adjust the bidi code. + +Fixed: fe25cc34795(tcmu: Recalculate the tcmu_cmd size to save cmd area + memories) +Reported-by: Bryant G. Ly +Tested-by: Bryant G. Ly +Reported-by: Damien Le Moal +Tested-by: Damien Le Moal +Reviewed-by: Mike Christie +Signed-off-by: Xiubo Li +Cc: # 4.12+ +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_user.c | 12 +++++------- + 1 file changed, 5 insertions(+), 7 deletions(-) + +--- a/drivers/target/target_core_user.c ++++ b/drivers/target/target_core_user.c +@@ -437,7 +437,7 @@ static int scatter_data_area(struct tcmu + to_offset = get_block_offset_user(udev, dbi, + block_remaining); + offset = DATA_BLOCK_SIZE - block_remaining; +- to = (void *)(unsigned long)to + offset; ++ to += offset; + + if (*iov_cnt != 0 && + to_offset == iov_tail(udev, *iov)) { +@@ -510,7 +510,7 @@ static void gather_data_area(struct tcmu + copy_bytes = min_t(size_t, sg_remaining, + block_remaining); + offset = DATA_BLOCK_SIZE - block_remaining; +- from = (void *)(unsigned long)from + offset; ++ from += offset; + tcmu_flush_dcache_range(from, copy_bytes); + memcpy(to + sg->length - sg_remaining, from, + copy_bytes); +@@ -714,10 +714,9 @@ tcmu_queue_cmd_ring(struct tcmu_cmd *tcm + } + + entry = (void *) mb + CMDR_OFF + cmd_head; ++ memset(entry, 0, command_size); + tcmu_hdr_set_op(&entry->hdr.len_op, TCMU_OP_CMD); + entry->hdr.cmd_id = tcmu_cmd->cmd_id; +- entry->hdr.kflags = 0; +- entry->hdr.uflags = 0; + + /* Handle allocating space from the data area */ + tcmu_cmd_reset_dbi_cur(tcmu_cmd); +@@ -736,11 +735,10 @@ tcmu_queue_cmd_ring(struct tcmu_cmd *tcm + return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; + } + entry->req.iov_cnt = iov_cnt; +- entry->req.iov_dif_cnt = 0; + + /* Handle BIDI commands */ ++ iov_cnt = 0; + if (se_cmd->se_cmd_flags & SCF_BIDI) { +- iov_cnt = 0; + iov++; + ret = scatter_data_area(udev, tcmu_cmd, + se_cmd->t_bidi_data_sg, +@@ -753,8 +751,8 @@ tcmu_queue_cmd_ring(struct tcmu_cmd *tcm + pr_err("tcmu: alloc and scatter bidi data failed\n"); + return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; + } +- entry->req.iov_bidi_cnt = iov_cnt; + } ++ entry->req.iov_bidi_cnt = iov_cnt; + + /* + * Recalaulate the command's base size and size according -- 2.47.3