From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755887AbdBOXnc (ORCPT ); Wed, 15 Feb 2017 18:43:32 -0500 Received: from shadbolt.e.decadent.org.uk ([88.96.1.126]:54468 "EHLO shadbolt.e.decadent.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755873AbdBOXn2 (ORCPT ); Wed, 15 Feb 2017 18:43:28 -0500 Content-Type: text/plain; charset="UTF-8" Content-Disposition: inline Content-Transfer-Encoding: 8bit MIME-Version: 1.0 From: Ben Hutchings To: linux-kernel@vger.kernel.org, stable@vger.kernel.org CC: akpm@linux-foundation.org, "Doug Ledford" , "Alex Estrin" , "Bart Van Assche" Date: Wed, 15 Feb 2017 22:41:40 +0000 Message-ID: X-Mailer: LinuxStableQueue (scripts by bwh) Subject: [PATCH 3.16 101/306] IB/srp: Fix infinite loop when FMR sg[0].offset != 0 In-Reply-To: X-SA-Exim-Connect-IP: 2a02:8011:400e:2:6f00:88c8:c921:d332 X-SA-Exim-Mail-From: ben@decadent.org.uk X-SA-Exim-Scanned: No (on shadbolt.decadent.org.uk); SAEximRunCond expanded to false Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 3.16.40-rc1 review patch. If anyone has any objections, please let me know. ------------------ From: Bart Van Assche commit 681cc3608355737c1effebc8145f95c8c3344bc3 upstream. Avoid that mapping an sg-list in which the first element has a non-zero offset triggers an infinite loop when using FMR. This patch makes the FMR mapping code similar to that of ib_sg_to_pages(). Note: older Mellanox HCAs do not support non-zero offsets for FMR. See also commit 8c4037b501ac ("IB/srp: always avoid non-zero offsets into an FMR"). Reported-by: Alex Estrin Signed-off-by: Bart Van Assche Signed-off-by: Doug Ledford [bwh: Backported to 3.16: adjust context] Signed-off-by: Ben Hutchings --- drivers/infiniband/ulp/srp/ib_srp.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -1310,7 +1310,9 @@ static int srp_map_sg_entry(struct srp_m while (dma_len) { unsigned offset = dma_addr & ~dev->mr_page_mask; - if (state->npages == dev->max_pages_per_mr || offset != 0) { + + if (state->npages == dev->max_pages_per_mr || + (state->npages > 0 && offset != 0)) { ret = srp_finish_mapping(state, target); if (ret) return ret; @@ -1329,12 +1331,12 @@ static int srp_map_sg_entry(struct srp_m } /* - * If the last entry of the MR wasn't a full page, then we need to + * If the end of the MR is not on a page boundary then we need to * close it out and start a new one -- we can only merge at page * boundries. */ ret = 0; - if (len != dev->mr_page_size) { + if ((dma_addr & ~dev->mr_page_mask) != 0) { ret = srp_finish_mapping(state, target); if (!ret) srp_map_update_start(state, NULL, 0, 0);