From: Greg Kroah-Hartman Date: Sat, 26 Sep 2015 17:48:40 +0000 (-0700) Subject: 4.2-stable patches X-Git-Tag: v4.1.9~17 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d140789e1211ffa20d6f2f79bc97f66953185c8f;p=thirdparty%2Fkernel%2Fstable-queue.git 4.2-stable patches added patches: ecryptfs-invalidate-dcache-entries-when-lower-i_nlink-is-zero.patch hfs-fix-b-tree-corruption-after-insertion-at-position-0.patch hfs-hfsplus-cache-pages-correctly-between-bnode_create-and-bnode_free.patch i2c-xgene-slimpro-dma_mapping_error-doesn-t-return-an-error-code.patch ib-iser-fix-missing-return-status-check-in-iser_send_data_out.patch ib-iser-fix-possible-bogus-dma-unmapping.patch ib-mlx4-fix-incorrect-cq-flushing-in-error-state.patch ib-mlx4-fix-potential-deadlock-when-sending-mad-to-wire.patch ib-mlx4-forbid-using-sysfs-to-change-roce-pkeys.patch ib-mlx4-use-correct-sl-on-ah-query-under-roce.patch ib-mlx5-avoid-destroying-a-null-mr-in-reg_user_mr-error-flow.patch ib-qib-change-lkey-table-allocation-to-support-more-mrs.patch ib-srp-handle-partial-connection-success-correctly.patch ib-srp-stop-the-scsi_eh_-n-and-scsi_tmf_-n-threads-if-login-fails.patch ib-uverbs-fix-race-between-ib_uverbs_open-and-remove_one.patch ib-uverbs-reject-invalid-or-unknown-opcodes.patch ideapad-laptop-add-lenovo-yoga-3-14-to-no_hw_rfkill-dmi-list.patch lib-decompressors-use-real-out-buf-size-for-gunzip-with-kernel.patch stmmac-fix-check-for-phydev-being-open.patch --- diff --git a/queue-4.2/ecryptfs-invalidate-dcache-entries-when-lower-i_nlink-is-zero.patch b/queue-4.2/ecryptfs-invalidate-dcache-entries-when-lower-i_nlink-is-zero.patch new file mode 100644 index 00000000000..0188ab93541 --- /dev/null +++ b/queue-4.2/ecryptfs-invalidate-dcache-entries-when-lower-i_nlink-is-zero.patch @@ -0,0 +1,55 @@ +From 5556e7e6d30e8e9b5ee51b0e5edd526ee80e5e36 Mon Sep 17 00:00:00 2001 +From: Tyler Hicks +Date: Wed, 5 Aug 2015 11:26:36 -0500 +Subject: eCryptfs: Invalidate dcache entries when lower i_nlink is zero + +From: Tyler Hicks + +commit 5556e7e6d30e8e9b5ee51b0e5edd526ee80e5e36 upstream. + +Consider eCryptfs dcache entries to be stale when the corresponding +lower inode's i_nlink count is zero. This solves a problem caused by the +lower inode being directly modified, without going through the eCryptfs +mount, leaving stale eCryptfs dentries cached and the eCryptfs inode's +i_nlink count not being cleared. + +Signed-off-by: Tyler Hicks +Reported-by: Richard Weinberger +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ecryptfs/dentry.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +--- a/fs/ecryptfs/dentry.c ++++ b/fs/ecryptfs/dentry.c +@@ -45,20 +45,20 @@ + static int ecryptfs_d_revalidate(struct dentry *dentry, unsigned int flags) + { + struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); +- int rc; +- +- if (!(lower_dentry->d_flags & DCACHE_OP_REVALIDATE)) +- return 1; ++ int rc = 1; + + if (flags & LOOKUP_RCU) + return -ECHILD; + +- rc = lower_dentry->d_op->d_revalidate(lower_dentry, flags); ++ if (lower_dentry->d_flags & DCACHE_OP_REVALIDATE) ++ rc = lower_dentry->d_op->d_revalidate(lower_dentry, flags); ++ + if (d_really_is_positive(dentry)) { +- struct inode *lower_inode = +- ecryptfs_inode_to_lower(d_inode(dentry)); ++ struct inode *inode = d_inode(dentry); + +- fsstack_copy_attr_all(d_inode(dentry), lower_inode); ++ fsstack_copy_attr_all(inode, ecryptfs_inode_to_lower(inode)); ++ if (!inode->i_nlink) ++ return 0; + } + return rc; + } diff --git a/queue-4.2/hfs-fix-b-tree-corruption-after-insertion-at-position-0.patch b/queue-4.2/hfs-fix-b-tree-corruption-after-insertion-at-position-0.patch new file mode 100644 index 00000000000..5ced0ddd2c7 --- /dev/null +++ b/queue-4.2/hfs-fix-b-tree-corruption-after-insertion-at-position-0.patch @@ -0,0 +1,77 @@ +From b4cc0efea4f0bfa2477c56af406cfcf3d3e58680 Mon Sep 17 00:00:00 2001 +From: Hin-Tak Leung +Date: Wed, 9 Sep 2015 15:38:07 -0700 +Subject: hfs: fix B-tree corruption after insertion at position 0 + +From: Hin-Tak Leung + +commit b4cc0efea4f0bfa2477c56af406cfcf3d3e58680 upstream. + +Fix B-tree corruption when a new record is inserted at position 0 in the +node in hfs_brec_insert(). + +This is an identical change to the corresponding hfs b-tree code to Sergei +Antonov's "hfsplus: fix B-tree corruption after insertion at position 0", +to keep similar code paths in the hfs and hfsplus drivers in sync, where +appropriate. + +Signed-off-by: Hin-Tak Leung +Cc: Sergei Antonov +Cc: Joe Perches +Reviewed-by: Vyacheslav Dubeyko +Cc: Anton Altaparmakov +Cc: Al Viro +Cc: Christoph Hellwig +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/hfs/brec.c | 20 +++++++++++--------- + 1 file changed, 11 insertions(+), 9 deletions(-) + +--- a/fs/hfs/brec.c ++++ b/fs/hfs/brec.c +@@ -131,13 +131,16 @@ skip: + hfs_bnode_write(node, entry, data_off + key_len, entry_len); + hfs_bnode_dump(node); + +- if (new_node) { +- /* update parent key if we inserted a key +- * at the start of the first node +- */ +- if (!rec && new_node != node) +- hfs_brec_update_parent(fd); ++ /* ++ * update parent key if we inserted a key ++ * at the start of the node and it is not the new node ++ */ ++ if (!rec && new_node != node) { ++ hfs_bnode_read_key(node, fd->search_key, data_off + size); ++ hfs_brec_update_parent(fd); ++ } + ++ if (new_node) { + hfs_bnode_put(fd->bnode); + if (!new_node->parent) { + hfs_btree_inc_height(tree); +@@ -166,9 +169,6 @@ skip: + goto again; + } + +- if (!rec) +- hfs_brec_update_parent(fd); +- + return 0; + } + +@@ -366,6 +366,8 @@ again: + if (IS_ERR(parent)) + return PTR_ERR(parent); + __hfs_brec_find(parent, fd); ++ if (fd->record < 0) ++ return -ENOENT; + hfs_bnode_dump(parent); + rec = fd->record; + diff --git a/queue-4.2/hfs-hfsplus-cache-pages-correctly-between-bnode_create-and-bnode_free.patch b/queue-4.2/hfs-hfsplus-cache-pages-correctly-between-bnode_create-and-bnode_free.patch new file mode 100644 index 00000000000..18ba0d156fb --- /dev/null +++ b/queue-4.2/hfs-hfsplus-cache-pages-correctly-between-bnode_create-and-bnode_free.patch @@ -0,0 +1,180 @@ +From 7cb74be6fd827e314f81df3c5889b87e4c87c569 Mon Sep 17 00:00:00 2001 +From: Hin-Tak Leung +Date: Wed, 9 Sep 2015 15:38:04 -0700 +Subject: hfs,hfsplus: cache pages correctly between bnode_create and bnode_free + +From: Hin-Tak Leung + +commit 7cb74be6fd827e314f81df3c5889b87e4c87c569 upstream. + +Pages looked up by __hfs_bnode_create() (called by hfs_bnode_create() and +hfs_bnode_find() for finding or creating pages corresponding to an inode) +are immediately kmap()'ed and used (both read and write) and kunmap()'ed, +and should not be page_cache_release()'ed until hfs_bnode_free(). + +This patch fixes a problem I first saw in July 2012: merely running "du" +on a large hfsplus-mounted directory a few times on a reasonably loaded +system would get the hfsplus driver all confused and complaining about +B-tree inconsistencies, and generates a "BUG: Bad page state". Most +recently, I can generate this problem on up-to-date Fedora 22 with shipped +kernel 4.0.5, by running "du /" (="/" + "/home" + "/mnt" + other smaller +mounts) and "du /mnt" simultaneously on two windows, where /mnt is a +lightly-used QEMU VM image of the full Mac OS X 10.9: + +$ df -i / /home /mnt +Filesystem Inodes IUsed IFree IUse% Mounted on +/dev/mapper/fedora-root 3276800 551665 2725135 17% / +/dev/mapper/fedora-home 52879360 716221 52163139 2% /home +/dev/nbd0p2 4294967295 1387818 4293579477 1% /mnt + +After applying the patch, I was able to run "du /" (60+ times) and "du +/mnt" (150+ times) continuously and simultaneously for 6+ hours. + +There are many reports of the hfsplus driver getting confused under load +and generating "BUG: Bad page state" or other similar issues over the +years. [1] + +The unpatched code [2] has always been wrong since it entered the kernel +tree. The only reason why it gets away with it is that the +kmap/memcpy/kunmap follow very quickly after the page_cache_release() so +the kernel has not had a chance to reuse the memory for something else, +most of the time. + +The current RW driver appears to have followed the design and development +of the earlier read-only hfsplus driver [3], where-by version 0.1 (Dec +2001) had a B-tree node-centric approach to +read_cache_page()/page_cache_release() per bnode_get()/bnode_put(), +migrating towards version 0.2 (June 2002) of caching and releasing pages +per inode extents. When the current RW code first entered the kernel [2] +in 2005, there was an REF_PAGES conditional (and "//" commented out code) +to switch between B-node centric paging to inode-centric paging. There +was a mistake with the direction of one of the REF_PAGES conditionals in +__hfs_bnode_create(). In a subsequent "remove debug code" commit [4], the +read_cache_page()/page_cache_release() per bnode_get()/bnode_put() were +removed, but a page_cache_release() was mistakenly left in (propagating +the "REF_PAGES <-> !REF_PAGE" mistake), and the commented-out +page_cache_release() in bnode_release() (which should be spanned by +!REF_PAGES) was never enabled. + +References: +[1]: +Michael Fox, Apr 2013 +http://www.spinics.net/lists/linux-fsdevel/msg63807.html +("hfsplus volume suddenly inaccessable after 'hfs: recoff %d too large'") + +Sasha Levin, Feb 2015 +http://lkml.org/lkml/2015/2/20/85 ("use after free") + +https://bugs.launchpad.net/ubuntu/+source/linux/+bug/740814 +https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1027887 +https://bugzilla.kernel.org/show_bug.cgi?id=42342 +https://bugzilla.kernel.org/show_bug.cgi?id=63841 +https://bugzilla.kernel.org/show_bug.cgi?id=78761 + +[2]: +http://git.kernel.org/cgit/linux/kernel/git/tglx/history.git/commit/\ +fs/hfs/bnode.c?id=d1081202f1d0ee35ab0beb490da4b65d4bc763db +commit d1081202f1d0ee35ab0beb490da4b65d4bc763db +Author: Andrew Morton +Date: Wed Feb 25 16:17:36 2004 -0800 + + [PATCH] HFS rewrite + +http://git.kernel.org/cgit/linux/kernel/git/tglx/history.git/commit/\ +fs/hfsplus/bnode.c?id=91556682e0bf004d98a529bf829d339abb98bbbd + +commit 91556682e0bf004d98a529bf829d339abb98bbbd +Author: Andrew Morton +Date: Wed Feb 25 16:17:48 2004 -0800 + + [PATCH] HFS+ support + +[3]: +http://sourceforge.net/projects/linux-hfsplus/ + +http://sourceforge.net/projects/linux-hfsplus/files/Linux%202.4.x%20patch/hfsplus%200.1/ +http://sourceforge.net/projects/linux-hfsplus/files/Linux%202.4.x%20patch/hfsplus%200.2/ + +http://linux-hfsplus.cvs.sourceforge.net/viewvc/linux-hfsplus/linux/\ +fs/hfsplus/bnode.c?r1=1.4&r2=1.5 + +Date: Thu Jun 6 09:45:14 2002 +0000 +Use buffer cache instead of page cache in bnode.c. Cache inode extents. + +[4]: +http://git.kernel.org/cgit/linux/kernel/git/\ +stable/linux-stable.git/commit/?id=a5e3985fa014029eb6795664c704953720cc7f7d + +commit a5e3985fa014029eb6795664c704953720cc7f7d +Author: Roman Zippel +Date: Tue Sep 6 15:18:47 2005 -0700 + +[PATCH] hfs: remove debug code + +Signed-off-by: Hin-Tak Leung +Signed-off-by: Sergei Antonov +Reviewed-by: Anton Altaparmakov +Reported-by: Sasha Levin +Cc: Al Viro +Cc: Christoph Hellwig +Cc: Vyacheslav Dubeyko +Cc: Sougata Santra +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/hfs/bnode.c | 9 ++++----- + fs/hfsplus/bnode.c | 3 --- + 2 files changed, 4 insertions(+), 8 deletions(-) + +--- a/fs/hfs/bnode.c ++++ b/fs/hfs/bnode.c +@@ -288,7 +288,6 @@ static struct hfs_bnode *__hfs_bnode_cre + page_cache_release(page); + goto fail; + } +- page_cache_release(page); + node->page[i] = page; + } + +@@ -398,11 +397,11 @@ node_error: + + void hfs_bnode_free(struct hfs_bnode *node) + { +- //int i; ++ int i; + +- //for (i = 0; i < node->tree->pages_per_bnode; i++) +- // if (node->page[i]) +- // page_cache_release(node->page[i]); ++ for (i = 0; i < node->tree->pages_per_bnode; i++) ++ if (node->page[i]) ++ page_cache_release(node->page[i]); + kfree(node); + } + +--- a/fs/hfsplus/bnode.c ++++ b/fs/hfsplus/bnode.c +@@ -454,7 +454,6 @@ static struct hfs_bnode *__hfs_bnode_cre + page_cache_release(page); + goto fail; + } +- page_cache_release(page); + node->page[i] = page; + } + +@@ -566,13 +565,11 @@ node_error: + + void hfs_bnode_free(struct hfs_bnode *node) + { +-#if 0 + int i; + + for (i = 0; i < node->tree->pages_per_bnode; i++) + if (node->page[i]) + page_cache_release(node->page[i]); +-#endif + kfree(node); + } + diff --git a/queue-4.2/i2c-xgene-slimpro-dma_mapping_error-doesn-t-return-an-error-code.patch b/queue-4.2/i2c-xgene-slimpro-dma_mapping_error-doesn-t-return-an-error-code.patch new file mode 100644 index 00000000000..0fd596ac16b --- /dev/null +++ b/queue-4.2/i2c-xgene-slimpro-dma_mapping_error-doesn-t-return-an-error-code.patch @@ -0,0 +1,49 @@ +From a4a9a8cb3248b3b48a6049acaeaf23d4ad3712b9 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Tue, 18 Aug 2015 12:12:19 +0300 +Subject: i2c: xgene-slimpro: dma_mapping_error() doesn't return an error code + +From: Dan Carpenter + +commit a4a9a8cb3248b3b48a6049acaeaf23d4ad3712b9 upstream. + +The dma_mapping_error() function returns true if there is an error, it +doesn't return an error code. We should return -ENOMEM. + +Signed-off-by: Dan Carpenter +Reviewed-by: Axel Lin +Signed-off-by: Wolfram Sang +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/i2c/busses/i2c-xgene-slimpro.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/i2c/busses/i2c-xgene-slimpro.c ++++ b/drivers/i2c/busses/i2c-xgene-slimpro.c +@@ -198,10 +198,10 @@ static int slimpro_i2c_blkrd(struct slim + int rc; + + paddr = dma_map_single(ctx->dev, ctx->dma_buffer, readlen, DMA_FROM_DEVICE); +- rc = dma_mapping_error(ctx->dev, paddr); +- if (rc) { ++ if (dma_mapping_error(ctx->dev, paddr)) { + dev_err(&ctx->adapter.dev, "Error in mapping dma buffer %p\n", + ctx->dma_buffer); ++ rc = -ENOMEM; + goto err; + } + +@@ -241,10 +241,10 @@ static int slimpro_i2c_blkwr(struct slim + memcpy(ctx->dma_buffer, data, writelen); + paddr = dma_map_single(ctx->dev, ctx->dma_buffer, writelen, + DMA_TO_DEVICE); +- rc = dma_mapping_error(ctx->dev, paddr); +- if (rc) { ++ if (dma_mapping_error(ctx->dev, paddr)) { + dev_err(&ctx->adapter.dev, "Error in mapping dma buffer %p\n", + ctx->dma_buffer); ++ rc = -ENOMEM; + goto err; + } + diff --git a/queue-4.2/ib-iser-fix-missing-return-status-check-in-iser_send_data_out.patch b/queue-4.2/ib-iser-fix-missing-return-status-check-in-iser_send_data_out.patch new file mode 100644 index 00000000000..24eb1a0618a --- /dev/null +++ b/queue-4.2/ib-iser-fix-missing-return-status-check-in-iser_send_data_out.patch @@ -0,0 +1,52 @@ +From d16739055bd1f562ae4d83e69f7f7f1cefcfbe16 Mon Sep 17 00:00:00 2001 +From: Sagi Grimberg +Date: Thu, 6 Aug 2015 18:32:48 +0300 +Subject: IB/iser: Fix missing return status check in iser_send_data_out + +From: Sagi Grimberg + +commit d16739055bd1f562ae4d83e69f7f7f1cefcfbe16 upstream. + +Since commit "IB/iser: Fix race between iser connection teardown..." +iser_initialize_task_headers() might fail, so we need to check that. + +Fixes: 7414dde0a6c3a958e (IB/iser: Fix race between iser connection ...) +Signed-off-by: Sagi Grimberg +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/ulp/iser/iser_initiator.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +--- a/drivers/infiniband/ulp/iser/iser_initiator.c ++++ b/drivers/infiniband/ulp/iser/iser_initiator.c +@@ -454,7 +454,7 @@ int iser_send_data_out(struct iscsi_conn + unsigned long buf_offset; + unsigned long data_seg_len; + uint32_t itt; +- int err = 0; ++ int err; + struct ib_sge *tx_dsg; + + itt = (__force uint32_t)hdr->itt; +@@ -475,7 +475,9 @@ int iser_send_data_out(struct iscsi_conn + memcpy(&tx_desc->iscsi_header, hdr, sizeof(struct iscsi_hdr)); + + /* build the tx desc */ +- iser_initialize_task_headers(task, tx_desc); ++ err = iser_initialize_task_headers(task, tx_desc); ++ if (err) ++ goto send_data_out_error; + + mem_reg = &iser_task->rdma_reg[ISER_DIR_OUT]; + tx_dsg = &tx_desc->tx_sg[1]; +@@ -502,7 +504,7 @@ int iser_send_data_out(struct iscsi_conn + + send_data_out_error: + kmem_cache_free(ig.desc_cache, tx_desc); +- iser_err("conn %p failed err %d\n",conn, err); ++ iser_err("conn %p failed err %d\n", conn, err); + return err; + } + diff --git a/queue-4.2/ib-iser-fix-possible-bogus-dma-unmapping.patch b/queue-4.2/ib-iser-fix-possible-bogus-dma-unmapping.patch new file mode 100644 index 00000000000..f1378b99cbd --- /dev/null +++ b/queue-4.2/ib-iser-fix-possible-bogus-dma-unmapping.patch @@ -0,0 +1,74 @@ +From 8d5944d80359e645feb2ebd069a6f4caf7825e40 Mon Sep 17 00:00:00 2001 +From: Sagi Grimberg +Date: Thu, 6 Aug 2015 18:32:50 +0300 +Subject: IB/iser: Fix possible bogus DMA unmapping + +From: Sagi Grimberg + +commit 8d5944d80359e645feb2ebd069a6f4caf7825e40 upstream. + +If iser_initialize_task_headers() routine failed before +dma mapping, we should not attempt to unmap in cleanup_task(). + +Fixes: 7414dde0a6c3a958e (IB/iser: Fix race between iser connection ...) +Signed-off-by: Sagi Grimberg +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/ulp/iser/iscsi_iser.c | 12 ++++++++---- + drivers/infiniband/ulp/iser/iscsi_iser.h | 2 ++ + 2 files changed, 10 insertions(+), 4 deletions(-) + +--- a/drivers/infiniband/ulp/iser/iscsi_iser.c ++++ b/drivers/infiniband/ulp/iser/iscsi_iser.c +@@ -201,6 +201,7 @@ iser_initialize_task_headers(struct iscs + goto out; + } + ++ tx_desc->mapped = true; + tx_desc->dma_addr = dma_addr; + tx_desc->tx_sg[0].addr = tx_desc->dma_addr; + tx_desc->tx_sg[0].length = ISER_HEADERS_LEN; +@@ -360,16 +361,19 @@ iscsi_iser_task_xmit(struct iscsi_task * + static void iscsi_iser_cleanup_task(struct iscsi_task *task) + { + struct iscsi_iser_task *iser_task = task->dd_data; +- struct iser_tx_desc *tx_desc = &iser_task->desc; +- struct iser_conn *iser_conn = task->conn->dd_data; ++ struct iser_tx_desc *tx_desc = &iser_task->desc; ++ struct iser_conn *iser_conn = task->conn->dd_data; + struct iser_device *device = iser_conn->ib_conn.device; + + /* DEVICE_REMOVAL event might have already released the device */ + if (!device) + return; + +- ib_dma_unmap_single(device->ib_device, +- tx_desc->dma_addr, ISER_HEADERS_LEN, DMA_TO_DEVICE); ++ if (likely(tx_desc->mapped)) { ++ ib_dma_unmap_single(device->ib_device, tx_desc->dma_addr, ++ ISER_HEADERS_LEN, DMA_TO_DEVICE); ++ tx_desc->mapped = false; ++ } + + /* mgmt tasks do not need special cleanup */ + if (!task->sc) +--- a/drivers/infiniband/ulp/iser/iscsi_iser.h ++++ b/drivers/infiniband/ulp/iser/iscsi_iser.h +@@ -270,6 +270,7 @@ enum iser_desc_type { + * sg[1] optionally points to either of immediate data + * unsolicited data-out or control + * @num_sge: number sges used on this TX task ++ * @mapped: Is the task header mapped + */ + struct iser_tx_desc { + struct iser_hdr iser_header; +@@ -278,6 +279,7 @@ struct iser_tx_desc { + u64 dma_addr; + struct ib_sge tx_sg[2]; + int num_sge; ++ bool mapped; + }; + + #define ISER_RX_PAD_SIZE (256 - (ISER_RX_PAYLOAD_SIZE + \ diff --git a/queue-4.2/ib-mlx4-fix-incorrect-cq-flushing-in-error-state.patch b/queue-4.2/ib-mlx4-fix-incorrect-cq-flushing-in-error-state.patch new file mode 100644 index 00000000000..6ed34caae1c --- /dev/null +++ b/queue-4.2/ib-mlx4-fix-incorrect-cq-flushing-in-error-state.patch @@ -0,0 +1,41 @@ +From 799cdaf8a98f13d4fba3162e21e1e63f21045010 Mon Sep 17 00:00:00 2001 +From: Ariel Nahum +Date: Sun, 9 Aug 2015 11:16:27 +0300 +Subject: IB/mlx4: Fix incorrect cq flushing in error state + +From: Ariel Nahum + +commit 799cdaf8a98f13d4fba3162e21e1e63f21045010 upstream. + +When handling a device internal error, the driver is responsible to +drain the completion queue with flush errors. + +In case a completion queue was assigned to multiple send queues, the +driver iterates over the send queues and generates flush errors of +inflight wqes. The driver must correctly pass the wc array with an +offset as a result of the previous send queue iteration. Not doing so +will overwrite previously set completions and return a wrong number +of polled completions which includes ones which were not correctly set. + +Fixes: 35f05dabf95a (IB/mlx4: Reset flow support for IB kernel ULPs) +Signed-off-by: Ariel Nahum +Signed-off-by: Sagi Grimberg +Cc: Yishai Hadas +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/mlx4/cq.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/infiniband/hw/mlx4/cq.c ++++ b/drivers/infiniband/hw/mlx4/cq.c +@@ -638,7 +638,7 @@ static void mlx4_ib_poll_sw_comp(struct + * simulated FLUSH_ERR completions + */ + list_for_each_entry(qp, &cq->send_qp_list, cq_send_list) { +- mlx4_ib_qp_sw_comp(qp, num_entries, wc, npolled, 1); ++ mlx4_ib_qp_sw_comp(qp, num_entries, wc + *npolled, npolled, 1); + if (*npolled >= num_entries) + goto out; + } diff --git a/queue-4.2/ib-mlx4-fix-potential-deadlock-when-sending-mad-to-wire.patch b/queue-4.2/ib-mlx4-fix-potential-deadlock-when-sending-mad-to-wire.patch new file mode 100644 index 00000000000..929a3695901 --- /dev/null +++ b/queue-4.2/ib-mlx4-fix-potential-deadlock-when-sending-mad-to-wire.patch @@ -0,0 +1,44 @@ +From 90c1d8b6350cca9d8a234f03c77a317a7613bcee Mon Sep 17 00:00:00 2001 +From: Jack Morgenstein +Date: Thu, 30 Jul 2015 17:34:21 +0300 +Subject: IB/mlx4: Fix potential deadlock when sending mad to wire + +From: Jack Morgenstein + +commit 90c1d8b6350cca9d8a234f03c77a317a7613bcee upstream. + +send_mad_to_wire takes the same spinlock that is taken in +the interrupt context. Therefore, it needs irqsave/restore. + +Fixes: b9c5d6a64358 ('IB/mlx4: Add multicast group (MCG) paravirtualization for SR-IOV') +Signed-off-by: Jack Morgenstein +Signed-off-by: Or Gerlitz +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/mlx4/mcg.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/drivers/infiniband/hw/mlx4/mcg.c ++++ b/drivers/infiniband/hw/mlx4/mcg.c +@@ -206,15 +206,16 @@ static int send_mad_to_wire(struct mlx4_ + { + struct mlx4_ib_dev *dev = ctx->dev; + struct ib_ah_attr ah_attr; ++ unsigned long flags; + +- spin_lock(&dev->sm_lock); ++ spin_lock_irqsave(&dev->sm_lock, flags); + if (!dev->sm_ah[ctx->port - 1]) { + /* port is not yet Active, sm_ah not ready */ +- spin_unlock(&dev->sm_lock); ++ spin_unlock_irqrestore(&dev->sm_lock, flags); + return -EAGAIN; + } + mlx4_ib_query_ah(dev->sm_ah[ctx->port - 1], &ah_attr); +- spin_unlock(&dev->sm_lock); ++ spin_unlock_irqrestore(&dev->sm_lock, flags); + return mlx4_ib_send_to_wire(dev, mlx4_master_func_num(dev->dev), + ctx->port, IB_QPT_GSI, 0, 1, IB_QP1_QKEY, + &ah_attr, NULL, mad); diff --git a/queue-4.2/ib-mlx4-forbid-using-sysfs-to-change-roce-pkeys.patch b/queue-4.2/ib-mlx4-forbid-using-sysfs-to-change-roce-pkeys.patch new file mode 100644 index 00000000000..d4b0960a7be --- /dev/null +++ b/queue-4.2/ib-mlx4-forbid-using-sysfs-to-change-roce-pkeys.patch @@ -0,0 +1,51 @@ +From 2b135db3e81301d0452e6aa107349abe67b097d6 Mon Sep 17 00:00:00 2001 +From: Jack Morgenstein +Date: Thu, 30 Jul 2015 17:34:23 +0300 +Subject: IB/mlx4: Forbid using sysfs to change RoCE pkeys + +From: Jack Morgenstein + +commit 2b135db3e81301d0452e6aa107349abe67b097d6 upstream. + +The pkey mapping for RoCE must remain the default mapping: +VFs: + virtual index 0 = mapped to real index 0 (0xFFFF) + All others indices: mapped to a real pkey index containing an + invalid pkey. +PF: + virtual index i = real index i. + +Don't allow users to change these mappings using files found in +sysfs. + +Fixes: c1e7e466120b ('IB/mlx4: Add iov directory in sysfs under the ib device') +Signed-off-by: Jack Morgenstein +Signed-off-by: Or Gerlitz +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/mlx4/sysfs.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/infiniband/hw/mlx4/sysfs.c ++++ b/drivers/infiniband/hw/mlx4/sysfs.c +@@ -640,6 +640,8 @@ static int add_port(struct mlx4_ib_dev * + struct mlx4_port *p; + int i; + int ret; ++ int is_eth = rdma_port_get_link_layer(&dev->ib_dev, port_num) == ++ IB_LINK_LAYER_ETHERNET; + + p = kzalloc(sizeof *p, GFP_KERNEL); + if (!p) +@@ -657,7 +659,8 @@ static int add_port(struct mlx4_ib_dev * + + p->pkey_group.name = "pkey_idx"; + p->pkey_group.attrs = +- alloc_group_attrs(show_port_pkey, store_port_pkey, ++ alloc_group_attrs(show_port_pkey, ++ is_eth ? NULL : store_port_pkey, + dev->dev->caps.pkey_table_len[port_num]); + if (!p->pkey_group.attrs) { + ret = -ENOMEM; diff --git a/queue-4.2/ib-mlx4-use-correct-sl-on-ah-query-under-roce.patch b/queue-4.2/ib-mlx4-use-correct-sl-on-ah-query-under-roce.patch new file mode 100644 index 00000000000..494cbe9f579 --- /dev/null +++ b/queue-4.2/ib-mlx4-use-correct-sl-on-ah-query-under-roce.patch @@ -0,0 +1,40 @@ +From 5e99b139f1b68acd65e36515ca347b03856dfb5a Mon Sep 17 00:00:00 2001 +From: Noa Osherovich +Date: Thu, 30 Jul 2015 17:34:24 +0300 +Subject: IB/mlx4: Use correct SL on AH query under RoCE + +From: Noa Osherovich + +commit 5e99b139f1b68acd65e36515ca347b03856dfb5a upstream. + +The mlx4 IB driver implementation for ib_query_ah used a wrong offset +(28 instead of 29) when link type is Ethernet. Fixed to use the correct one. + +Fixes: fa417f7b520e ('IB/mlx4: Add support for IBoE') +Signed-off-by: Shani Michaeli +Signed-off-by: Noa Osherovich +Signed-off-by: Or Gerlitz +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/mlx4/ah.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/infiniband/hw/mlx4/ah.c ++++ b/drivers/infiniband/hw/mlx4/ah.c +@@ -148,9 +148,13 @@ int mlx4_ib_query_ah(struct ib_ah *ibah, + enum rdma_link_layer ll; + + memset(ah_attr, 0, sizeof *ah_attr); +- ah_attr->sl = be32_to_cpu(ah->av.ib.sl_tclass_flowlabel) >> 28; + ah_attr->port_num = be32_to_cpu(ah->av.ib.port_pd) >> 24; + ll = rdma_port_get_link_layer(ibah->device, ah_attr->port_num); ++ if (ll == IB_LINK_LAYER_ETHERNET) ++ ah_attr->sl = be32_to_cpu(ah->av.eth.sl_tclass_flowlabel) >> 29; ++ else ++ ah_attr->sl = be32_to_cpu(ah->av.ib.sl_tclass_flowlabel) >> 28; ++ + ah_attr->dlid = ll == IB_LINK_LAYER_INFINIBAND ? be16_to_cpu(ah->av.ib.dlid) : 0; + if (ah->av.ib.stat_rate) + ah_attr->static_rate = ah->av.ib.stat_rate - MLX4_STAT_RATE_OFFSET; diff --git a/queue-4.2/ib-mlx5-avoid-destroying-a-null-mr-in-reg_user_mr-error-flow.patch b/queue-4.2/ib-mlx5-avoid-destroying-a-null-mr-in-reg_user_mr-error-flow.patch new file mode 100644 index 00000000000..92050161ca5 --- /dev/null +++ b/queue-4.2/ib-mlx5-avoid-destroying-a-null-mr-in-reg_user_mr-error-flow.patch @@ -0,0 +1,49 @@ +From 11d748045c6dadb279d1acdb6d2ea8f3f2ede85b Mon Sep 17 00:00:00 2001 +From: Haggai Eran +Date: Tue, 1 Sep 2015 09:56:56 +0300 +Subject: IB/mlx5: avoid destroying a NULL mr in reg_user_mr error flow + +From: Haggai Eran + +commit 11d748045c6dadb279d1acdb6d2ea8f3f2ede85b upstream. + +The mlx5_ib_reg_user_mr() function will attempt to call clean_mr() in +its error flow even though there is never a case where the error flow +occurs with a valid MR pointer to destroy. + +Remove the clean_mr() call and the incorrect comment above it. + +Fixes: b4cfe447d47b ("IB/mlx5: Implement on demand paging by adding +support for MMU notifiers") +Cc: Eli Cohen +Signed-off-by: Haggai Eran +Reviewed-by: Sagi Grimberg +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/mlx5/mr.c | 12 ------------ + 1 file changed, 12 deletions(-) + +--- a/drivers/infiniband/hw/mlx5/mr.c ++++ b/drivers/infiniband/hw/mlx5/mr.c +@@ -1118,19 +1118,7 @@ struct ib_mr *mlx5_ib_reg_user_mr(struct + return &mr->ibmr; + + error: +- /* +- * Destroy the umem *before* destroying the MR, to ensure we +- * will not have any in-flight notifiers when destroying the +- * MR. +- * +- * As the MR is completely invalid to begin with, and this +- * error path is only taken if we can't push the mr entry into +- * the pagefault tree, this is safe. +- */ +- + ib_umem_release(umem); +- /* Kill the MR, and return an error code. */ +- clean_mr(mr); + return ERR_PTR(err); + } + diff --git a/queue-4.2/ib-qib-change-lkey-table-allocation-to-support-more-mrs.patch b/queue-4.2/ib-qib-change-lkey-table-allocation-to-support-more-mrs.patch new file mode 100644 index 00000000000..ae990a72fd0 --- /dev/null +++ b/queue-4.2/ib-qib-change-lkey-table-allocation-to-support-more-mrs.patch @@ -0,0 +1,104 @@ +From d6f1c17e162b2a11e708f28fa93f2f79c164b442 Mon Sep 17 00:00:00 2001 +From: Mike Marciniszyn +Date: Tue, 21 Jul 2015 08:36:07 -0400 +Subject: IB/qib: Change lkey table allocation to support more MRs + +From: Mike Marciniszyn + +commit d6f1c17e162b2a11e708f28fa93f2f79c164b442 upstream. + +The lkey table is allocated with with a get_user_pages() with an +order based on a number of index bits from a module parameter. + +The underlying kernel code cannot allocate that many contiguous pages. + +There is no reason the underlying memory needs to be physically +contiguous. + +This patch: +- switches the allocation/deallocation to vmalloc/vfree +- caps the number of bits to 23 to insure at least 1 generation bit + o this matches the module parameter description + +Reviewed-by: Vinit Agnihotri +Signed-off-by: Mike Marciniszyn +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/qib/qib_keys.c | 4 ++++ + drivers/infiniband/hw/qib/qib_verbs.c | 14 ++++++++++---- + drivers/infiniband/hw/qib/qib_verbs.h | 2 ++ + 3 files changed, 16 insertions(+), 4 deletions(-) + +--- a/drivers/infiniband/hw/qib/qib_keys.c ++++ b/drivers/infiniband/hw/qib/qib_keys.c +@@ -86,6 +86,10 @@ int qib_alloc_lkey(struct qib_mregion *m + * unrestricted LKEY. + */ + rkt->gen++; ++ /* ++ * bits are capped in qib_verbs.c to insure enough bits ++ * for generation number ++ */ + mr->lkey = (r << (32 - ib_qib_lkey_table_size)) | + ((((1 << (24 - ib_qib_lkey_table_size)) - 1) & rkt->gen) + << 8); +--- a/drivers/infiniband/hw/qib/qib_verbs.c ++++ b/drivers/infiniband/hw/qib/qib_verbs.c +@@ -40,6 +40,7 @@ + #include + #include + #include ++#include + + #include "qib.h" + #include "qib_common.h" +@@ -2109,10 +2110,16 @@ int qib_register_ib_device(struct qib_de + * the LKEY). The remaining bits act as a generation number or tag. + */ + spin_lock_init(&dev->lk_table.lock); ++ /* insure generation is at least 4 bits see keys.c */ ++ if (ib_qib_lkey_table_size > MAX_LKEY_TABLE_BITS) { ++ qib_dev_warn(dd, "lkey bits %u too large, reduced to %u\n", ++ ib_qib_lkey_table_size, MAX_LKEY_TABLE_BITS); ++ ib_qib_lkey_table_size = MAX_LKEY_TABLE_BITS; ++ } + dev->lk_table.max = 1 << ib_qib_lkey_table_size; + lk_tab_size = dev->lk_table.max * sizeof(*dev->lk_table.table); + dev->lk_table.table = (struct qib_mregion __rcu **) +- __get_free_pages(GFP_KERNEL, get_order(lk_tab_size)); ++ vmalloc(lk_tab_size); + if (dev->lk_table.table == NULL) { + ret = -ENOMEM; + goto err_lk; +@@ -2286,7 +2293,7 @@ err_tx: + sizeof(struct qib_pio_header), + dev->pio_hdrs, dev->pio_hdrs_phys); + err_hdrs: +- free_pages((unsigned long) dev->lk_table.table, get_order(lk_tab_size)); ++ vfree(dev->lk_table.table); + err_lk: + kfree(dev->qp_table); + err_qpt: +@@ -2340,8 +2347,7 @@ void qib_unregister_ib_device(struct qib + sizeof(struct qib_pio_header), + dev->pio_hdrs, dev->pio_hdrs_phys); + lk_tab_size = dev->lk_table.max * sizeof(*dev->lk_table.table); +- free_pages((unsigned long) dev->lk_table.table, +- get_order(lk_tab_size)); ++ vfree(dev->lk_table.table); + kfree(dev->qp_table); + } + +--- a/drivers/infiniband/hw/qib/qib_verbs.h ++++ b/drivers/infiniband/hw/qib/qib_verbs.h +@@ -647,6 +647,8 @@ struct qib_qpn_table { + struct qpn_map map[QPNMAP_ENTRIES]; + }; + ++#define MAX_LKEY_TABLE_BITS 23 ++ + struct qib_lkey_table { + spinlock_t lock; /* protect changes in this struct */ + u32 next; /* next unused index (speeds search) */ diff --git a/queue-4.2/ib-srp-handle-partial-connection-success-correctly.patch b/queue-4.2/ib-srp-handle-partial-connection-success-correctly.patch new file mode 100644 index 00000000000..74bbef36cc7 --- /dev/null +++ b/queue-4.2/ib-srp-handle-partial-connection-success-correctly.patch @@ -0,0 +1,56 @@ +From c257ea6f9f9aed0b173e0c2932bb8dac5612cdc6 Mon Sep 17 00:00:00 2001 +From: Bart Van Assche +Date: Fri, 31 Jul 2015 14:13:22 -0700 +Subject: IB/srp: Handle partial connection success correctly + +From: Bart Van Assche + +commit c257ea6f9f9aed0b173e0c2932bb8dac5612cdc6 upstream. + +Avoid that the following kernel warning is reported if the SRP +target system accepts fewer channels per connection than what +was requested by the initiator system: + +WARNING: at drivers/infiniband/ulp/srp/ib_srp.c:617 srp_destroy_qp+0xb1/0x120 [ib_srp]() +Call Trace: +[] warn_slowpath_common+0x7f/0xc0 +[] warn_slowpath_null+0x1a/0x20 +[] srp_destroy_qp+0xb1/0x120 [ib_srp] +[] srp_create_ch_ib+0x19b/0x420 [ib_srp] +[] srp_create_target+0x7d7/0xa94 [ib_srp] +[] dev_attr_store+0x20/0x30 +[] sysfs_write_file+0xef/0x170 +[] vfs_write+0xb4/0x130 +[] sys_write+0x5f/0xa0 +[] system_call_fastpath+0x16/0x1b + +Signed-off-by: Bart Van Assche +Cc: Sagi Grimberg +Cc: Sebastian Parschauer +Cc: Christoph Hellwig +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/ulp/srp/ib_srp.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/infiniband/ulp/srp/ib_srp.c ++++ b/drivers/infiniband/ulp/srp/ib_srp.c +@@ -3262,7 +3262,7 @@ static ssize_t srp_create_target(struct + srp_free_ch_ib(target, ch); + srp_free_req_data(target, ch); + target->ch_count = ch - target->ch; +- break; ++ goto connected; + } + } + +@@ -3272,6 +3272,7 @@ static ssize_t srp_create_target(struct + node_idx++; + } + ++connected: + target->scsi_host->nr_hw_queues = target->ch_count; + + ret = srp_add_target(host, target); diff --git a/queue-4.2/ib-srp-stop-the-scsi_eh_-n-and-scsi_tmf_-n-threads-if-login-fails.patch b/queue-4.2/ib-srp-stop-the-scsi_eh_-n-and-scsi_tmf_-n-threads-if-login-fails.patch new file mode 100644 index 00000000000..e6a8dfbb583 --- /dev/null +++ b/queue-4.2/ib-srp-stop-the-scsi_eh_-n-and-scsi_tmf_-n-threads-if-login-fails.patch @@ -0,0 +1,50 @@ +From bc44bd1d864664f3658352c6aaaa02557d49165d Mon Sep 17 00:00:00 2001 +From: Bart Van Assche +Date: Fri, 14 Aug 2015 11:01:09 -0700 +Subject: IB/srp: Stop the scsi_eh_ and scsi_tmf_ threads if login fails + +From: Bart Van Assche + +commit bc44bd1d864664f3658352c6aaaa02557d49165d upstream. + +scsi_host_alloc() not only allocates memory for a SCSI host but also +creates the scsi_eh_ kernel thread and the scsi_tmf_ workqueue. +Stop these threads if login fails by calling scsi_host_put(). + +Reported-by: Konstantin Krotov +Fixes: fb49c8bbaae7 ("Remove an extraneous scsi_host_put() from an error path") +Signed-off-by: Bart Van Assche +Cc: Sagi Grimberg +Cc: Sebastian Parschauer +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/ulp/srp/ib_srp.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/drivers/infiniband/ulp/srp/ib_srp.c ++++ b/drivers/infiniband/ulp/srp/ib_srp.c +@@ -2757,6 +2757,13 @@ static int srp_sdev_count(struct Scsi_Ho + return c; + } + ++/* ++ * Return values: ++ * < 0 upon failure. Caller is responsible for SRP target port cleanup. ++ * 0 and target->state == SRP_TARGET_REMOVED if asynchronous target port ++ * removal has been scheduled. ++ * 0 and target->state != SRP_TARGET_REMOVED upon success. ++ */ + static int srp_add_target(struct srp_host *host, struct srp_target_port *target) + { + struct srp_rport_identifiers ids; +@@ -3295,6 +3302,8 @@ out: + mutex_unlock(&host->add_target_mutex); + + scsi_host_put(target->scsi_host); ++ if (ret < 0) ++ scsi_host_put(target->scsi_host); + + return ret; + diff --git a/queue-4.2/ib-uverbs-fix-race-between-ib_uverbs_open-and-remove_one.patch b/queue-4.2/ib-uverbs-fix-race-between-ib_uverbs_open-and-remove_one.patch new file mode 100644 index 00000000000..2f9ed06dba4 --- /dev/null +++ b/queue-4.2/ib-uverbs-fix-race-between-ib_uverbs_open-and-remove_one.patch @@ -0,0 +1,201 @@ +From 35d4a0b63dc0c6d1177d4f532a9deae958f0662c Mon Sep 17 00:00:00 2001 +From: Yishai Hadas +Date: Thu, 13 Aug 2015 18:32:03 +0300 +Subject: IB/uverbs: Fix race between ib_uverbs_open and remove_one + +From: Yishai Hadas + +commit 35d4a0b63dc0c6d1177d4f532a9deae958f0662c upstream. + +Fixes: 2a72f212263701b927559f6850446421d5906c41 ("IB/uverbs: Remove dev_table") + +Before this commit there was a device look-up table that was protected +by a spin_lock used by ib_uverbs_open and by ib_uverbs_remove_one. When +it was dropped and container_of was used instead, it enabled the race +with remove_one as dev might be freed just after: +dev = container_of(inode->i_cdev, struct ib_uverbs_device, cdev) but +before the kref_get. + +In addition, this buggy patch added some dead code as +container_of(x,y,z) can never be NULL and so dev can never be NULL. +As a result the comment above ib_uverbs_open saying "the open method +will either immediately run -ENXIO" is wrong as it can never happen. + +The solution follows Jason Gunthorpe suggestion from below URL: +https://www.mail-archive.com/linux-rdma@vger.kernel.org/msg25692.html + +cdev will hold a kref on the parent (the containing structure, +ib_uverbs_device) and only when that kref is released it is +guaranteed that open will never be called again. + +In addition, fixes the active count scheme to use an atomic +not a kref to prevent WARN_ON as pointed by above comment +from Jason. + +Signed-off-by: Yishai Hadas +Signed-off-by: Shachar Raindel +Reviewed-by: Jason Gunthorpe +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/core/uverbs.h | 3 +- + drivers/infiniband/core/uverbs_main.c | 43 +++++++++++++++++++++++----------- + 2 files changed, 32 insertions(+), 14 deletions(-) + +--- a/drivers/infiniband/core/uverbs.h ++++ b/drivers/infiniband/core/uverbs.h +@@ -85,7 +85,7 @@ + */ + + struct ib_uverbs_device { +- struct kref ref; ++ atomic_t refcount; + int num_comp_vectors; + struct completion comp; + struct device *dev; +@@ -94,6 +94,7 @@ struct ib_uverbs_device { + struct cdev cdev; + struct rb_root xrcd_tree; + struct mutex xrcd_tree_mutex; ++ struct kobject kobj; + }; + + struct ib_uverbs_event_file { +--- a/drivers/infiniband/core/uverbs_main.c ++++ b/drivers/infiniband/core/uverbs_main.c +@@ -130,14 +130,18 @@ static int (*uverbs_ex_cmd_table[])(stru + static void ib_uverbs_add_one(struct ib_device *device); + static void ib_uverbs_remove_one(struct ib_device *device); + +-static void ib_uverbs_release_dev(struct kref *ref) ++static void ib_uverbs_release_dev(struct kobject *kobj) + { + struct ib_uverbs_device *dev = +- container_of(ref, struct ib_uverbs_device, ref); ++ container_of(kobj, struct ib_uverbs_device, kobj); + +- complete(&dev->comp); ++ kfree(dev); + } + ++static struct kobj_type ib_uverbs_dev_ktype = { ++ .release = ib_uverbs_release_dev, ++}; ++ + static void ib_uverbs_release_event_file(struct kref *ref) + { + struct ib_uverbs_event_file *file = +@@ -303,13 +307,19 @@ static int ib_uverbs_cleanup_ucontext(st + return context->device->dealloc_ucontext(context); + } + ++static void ib_uverbs_comp_dev(struct ib_uverbs_device *dev) ++{ ++ complete(&dev->comp); ++} ++ + static void ib_uverbs_release_file(struct kref *ref) + { + struct ib_uverbs_file *file = + container_of(ref, struct ib_uverbs_file, ref); + + module_put(file->device->ib_dev->owner); +- kref_put(&file->device->ref, ib_uverbs_release_dev); ++ if (atomic_dec_and_test(&file->device->refcount)) ++ ib_uverbs_comp_dev(file->device); + + kfree(file); + } +@@ -743,9 +753,7 @@ static int ib_uverbs_open(struct inode * + int ret; + + dev = container_of(inode->i_cdev, struct ib_uverbs_device, cdev); +- if (dev) +- kref_get(&dev->ref); +- else ++ if (!atomic_inc_not_zero(&dev->refcount)) + return -ENXIO; + + if (!try_module_get(dev->ib_dev->owner)) { +@@ -766,6 +774,7 @@ static int ib_uverbs_open(struct inode * + mutex_init(&file->mutex); + + filp->private_data = file; ++ kobject_get(&dev->kobj); + + return nonseekable_open(inode, filp); + +@@ -773,13 +782,16 @@ err_module: + module_put(dev->ib_dev->owner); + + err: +- kref_put(&dev->ref, ib_uverbs_release_dev); ++ if (atomic_dec_and_test(&dev->refcount)) ++ ib_uverbs_comp_dev(dev); ++ + return ret; + } + + static int ib_uverbs_close(struct inode *inode, struct file *filp) + { + struct ib_uverbs_file *file = filp->private_data; ++ struct ib_uverbs_device *dev = file->device; + + ib_uverbs_cleanup_ucontext(file, file->ucontext); + +@@ -787,6 +799,7 @@ static int ib_uverbs_close(struct inode + kref_put(&file->async_file->ref, ib_uverbs_release_event_file); + + kref_put(&file->ref, ib_uverbs_release_file); ++ kobject_put(&dev->kobj); + + return 0; + } +@@ -882,10 +895,11 @@ static void ib_uverbs_add_one(struct ib_ + if (!uverbs_dev) + return; + +- kref_init(&uverbs_dev->ref); ++ atomic_set(&uverbs_dev->refcount, 1); + init_completion(&uverbs_dev->comp); + uverbs_dev->xrcd_tree = RB_ROOT; + mutex_init(&uverbs_dev->xrcd_tree_mutex); ++ kobject_init(&uverbs_dev->kobj, &ib_uverbs_dev_ktype); + + spin_lock(&map_lock); + devnum = find_first_zero_bit(dev_map, IB_UVERBS_MAX_DEVICES); +@@ -912,6 +926,7 @@ static void ib_uverbs_add_one(struct ib_ + cdev_init(&uverbs_dev->cdev, NULL); + uverbs_dev->cdev.owner = THIS_MODULE; + uverbs_dev->cdev.ops = device->mmap ? &uverbs_mmap_fops : &uverbs_fops; ++ uverbs_dev->cdev.kobj.parent = &uverbs_dev->kobj; + kobject_set_name(&uverbs_dev->cdev.kobj, "uverbs%d", uverbs_dev->devnum); + if (cdev_add(&uverbs_dev->cdev, base, 1)) + goto err_cdev; +@@ -942,9 +957,10 @@ err_cdev: + clear_bit(devnum, overflow_map); + + err: +- kref_put(&uverbs_dev->ref, ib_uverbs_release_dev); ++ if (atomic_dec_and_test(&uverbs_dev->refcount)) ++ ib_uverbs_comp_dev(uverbs_dev); + wait_for_completion(&uverbs_dev->comp); +- kfree(uverbs_dev); ++ kobject_put(&uverbs_dev->kobj); + return; + } + +@@ -964,9 +980,10 @@ static void ib_uverbs_remove_one(struct + else + clear_bit(uverbs_dev->devnum - IB_UVERBS_MAX_DEVICES, overflow_map); + +- kref_put(&uverbs_dev->ref, ib_uverbs_release_dev); ++ if (atomic_dec_and_test(&uverbs_dev->refcount)) ++ ib_uverbs_comp_dev(uverbs_dev); + wait_for_completion(&uverbs_dev->comp); +- kfree(uverbs_dev); ++ kobject_put(&uverbs_dev->kobj); + } + + static char *uverbs_devnode(struct device *dev, umode_t *mode) diff --git a/queue-4.2/ib-uverbs-reject-invalid-or-unknown-opcodes.patch b/queue-4.2/ib-uverbs-reject-invalid-or-unknown-opcodes.patch new file mode 100644 index 00000000000..f479b6c2a9c --- /dev/null +++ b/queue-4.2/ib-uverbs-reject-invalid-or-unknown-opcodes.patch @@ -0,0 +1,52 @@ +From b632ffa7cee439ba5dce3b3bc4a5cbe2b3e20133 Mon Sep 17 00:00:00 2001 +From: Christoph Hellwig +Date: Wed, 26 Aug 2015 11:00:37 +0200 +Subject: IB/uverbs: reject invalid or unknown opcodes + +From: Christoph Hellwig + +commit b632ffa7cee439ba5dce3b3bc4a5cbe2b3e20133 upstream. + +We have many WR opcodes that are only supported in kernel space +and/or require optional information to be copied into the WR +structure. Reject all those not explicitly handled so that we +can't pass invalid information to drivers. + +Signed-off-by: Christoph Hellwig +Reviewed-by: Jason Gunthorpe +Reviewed-by: Sagi Grimberg +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/core/uverbs_cmd.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +--- a/drivers/infiniband/core/uverbs_cmd.c ++++ b/drivers/infiniband/core/uverbs_cmd.c +@@ -2346,6 +2346,12 @@ ssize_t ib_uverbs_post_send(struct ib_uv + next->send_flags = user_wr->send_flags; + + if (is_ud) { ++ if (next->opcode != IB_WR_SEND && ++ next->opcode != IB_WR_SEND_WITH_IMM) { ++ ret = -EINVAL; ++ goto out_put; ++ } ++ + next->wr.ud.ah = idr_read_ah(user_wr->wr.ud.ah, + file->ucontext); + if (!next->wr.ud.ah) { +@@ -2385,9 +2391,11 @@ ssize_t ib_uverbs_post_send(struct ib_uv + user_wr->wr.atomic.compare_add; + next->wr.atomic.swap = user_wr->wr.atomic.swap; + next->wr.atomic.rkey = user_wr->wr.atomic.rkey; ++ case IB_WR_SEND: + break; + default: +- break; ++ ret = -EINVAL; ++ goto out_put; + } + } + diff --git a/queue-4.2/ideapad-laptop-add-lenovo-yoga-3-14-to-no_hw_rfkill-dmi-list.patch b/queue-4.2/ideapad-laptop-add-lenovo-yoga-3-14-to-no_hw_rfkill-dmi-list.patch new file mode 100644 index 00000000000..a656a67ccfa --- /dev/null +++ b/queue-4.2/ideapad-laptop-add-lenovo-yoga-3-14-to-no_hw_rfkill-dmi-list.patch @@ -0,0 +1,41 @@ +From fa92a31b3335478c545cdc8e79e1e9b788184e6b Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Mon, 10 Aug 2015 10:45:45 +0200 +Subject: ideapad-laptop: Add Lenovo Yoga 3 14 to no_hw_rfkill dmi list + +From: Hans de Goede + +commit fa92a31b3335478c545cdc8e79e1e9b788184e6b upstream. + +Like some of the other Yoga models the Lenovo Yoga 3 14 does not have a +hw rfkill switch, and trying to read the hw rfkill switch through the +ideapad module causes it to always reported blocking breaking wifi. + +This commit adds the Lenovo Yoga 3 14 to the no_hw_rfkill dmi list, fixing +the wifi breakage. + +BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1239050 +Signed-off-by: Hans de Goede +Signed-off-by: Darren Hart +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/platform/x86/ideapad-laptop.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/platform/x86/ideapad-laptop.c ++++ b/drivers/platform/x86/ideapad-laptop.c +@@ -853,6 +853,13 @@ static const struct dmi_system_id no_hw_ + }, + }, + { ++ .ident = "Lenovo Yoga 3 14", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Yoga 3 14"), ++ }, ++ }, ++ { + .ident = "Lenovo Yoga 3 Pro 1370", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), diff --git a/queue-4.2/lib-decompressors-use-real-out-buf-size-for-gunzip-with-kernel.patch b/queue-4.2/lib-decompressors-use-real-out-buf-size-for-gunzip-with-kernel.patch new file mode 100644 index 00000000000..b4697b2fb31 --- /dev/null +++ b/queue-4.2/lib-decompressors-use-real-out-buf-size-for-gunzip-with-kernel.patch @@ -0,0 +1,322 @@ +From 2d3862d26e67a59340ba1cf1748196c76c5787de Mon Sep 17 00:00:00 2001 +From: Yinghai Lu +Date: Wed, 9 Sep 2015 15:39:12 -0700 +Subject: lib/decompressors: use real out buf size for gunzip with kernel + +From: Yinghai Lu + +commit 2d3862d26e67a59340ba1cf1748196c76c5787de upstream. + +When loading x86 64bit kernel above 4GiB with patched grub2, got kernel +gunzip error. + +| early console in decompress_kernel +| decompress_kernel: +| input: [0x807f2143b4-0x807ff61aee] +| output: [0x807cc00000-0x807f3ea29b] 0x027ea29c: output_len +| boot via startup_64 +| KASLR using RDTSC... +| new output: [0x46fe000000-0x470138cfff] 0x0338d000: output_run_size +| decompress: [0x46fe000000-0x47007ea29b] <=== [0x807f2143b4-0x807ff61aee] +| +| Decompressing Linux... gz... +| +| uncompression error +| +| -- System halted + +the new buffer is at 0x46fe000000ULL, decompressor_gzip is using +0xffffffb901ffffff as out_len. gunzip in lib/zlib_inflate/inflate.c cap +that len to 0x01ffffff and decompress fails later. + +We could hit this problem with crashkernel booting that uses kexec loading +kernel above 4GiB. + +We have decompress_* support: + 1. inbuf[]/outbuf[] for kernel preboot. + 2. inbuf[]/flush() for initramfs + 3. fill()/flush() for initrd. +This bug only affect kernel preboot path that use outbuf[]. + +Add __decompress and take real out_buf_len for gunzip instead of guessing +wrong buf size. + +Fixes: 1431574a1c4 (lib/decompressors: fix "no limit" output buffer length) +Signed-off-by: Yinghai Lu +Cc: Alexandre Courbot +Cc: Jon Medhurst +Cc: Stephen Warren +Cc: "H. Peter Anvin" +Cc: Thomas Gleixner +Cc: Ingo Molnar +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/boot/compressed/decompress.c | 2 +- + arch/h8300/boot/compressed/misc.c | 2 +- + arch/m32r/boot/compressed/misc.c | 3 ++- + arch/mips/boot/compressed/decompress.c | 4 ++-- + arch/s390/boot/compressed/misc.c | 2 +- + arch/sh/boot/compressed/misc.c | 2 +- + arch/unicore32/boot/compressed/misc.c | 4 ++-- + arch/x86/boot/compressed/misc.c | 3 ++- + lib/decompress_bunzip2.c | 6 +++--- + lib/decompress_inflate.c | 31 ++++++++++++++++++++++++++----- + lib/decompress_unlz4.c | 6 +++--- + lib/decompress_unlzma.c | 7 +++---- + lib/decompress_unlzo.c | 13 ++++++++++++- + lib/decompress_unxz.c | 12 +++++++++++- + 14 files changed, 70 insertions(+), 27 deletions(-) + +--- a/arch/arm/boot/compressed/decompress.c ++++ b/arch/arm/boot/compressed/decompress.c +@@ -57,5 +57,5 @@ extern char * strstr(const char * s1, co + + int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x)) + { +- return decompress(input, len, NULL, NULL, output, NULL, error); ++ return __decompress(input, len, NULL, NULL, output, 0, NULL, error); + } +--- a/arch/h8300/boot/compressed/misc.c ++++ b/arch/h8300/boot/compressed/misc.c +@@ -70,5 +70,5 @@ void decompress_kernel(void) + free_mem_ptr = (unsigned long)&_end; + free_mem_end_ptr = free_mem_ptr + HEAP_SIZE; + +- decompress(input_data, input_len, NULL, NULL, output, NULL, error); ++ __decompress(input_data, input_len, NULL, NULL, output, 0, NULL, error); + } +--- a/arch/m32r/boot/compressed/misc.c ++++ b/arch/m32r/boot/compressed/misc.c +@@ -86,6 +86,7 @@ decompress_kernel(int mmu_on, unsigned c + free_mem_end_ptr = free_mem_ptr + BOOT_HEAP_SIZE; + + puts("\nDecompressing Linux... "); +- decompress(input_data, input_len, NULL, NULL, output_data, NULL, error); ++ __decompress(input_data, input_len, NULL, NULL, output_data, 0, ++ NULL, error); + puts("done.\nBooting the kernel.\n"); + } +--- a/arch/mips/boot/compressed/decompress.c ++++ b/arch/mips/boot/compressed/decompress.c +@@ -111,8 +111,8 @@ void decompress_kernel(unsigned long boo + puts("\n"); + + /* Decompress the kernel with according algorithm */ +- decompress((char *)zimage_start, zimage_size, 0, 0, +- (void *)VMLINUX_LOAD_ADDRESS_ULL, 0, error); ++ __decompress((char *)zimage_start, zimage_size, 0, 0, ++ (void *)VMLINUX_LOAD_ADDRESS_ULL, 0, 0, error); + + /* FIXME: should we flush cache here? */ + puts("Now, booting the kernel...\n"); +--- a/arch/s390/boot/compressed/misc.c ++++ b/arch/s390/boot/compressed/misc.c +@@ -167,7 +167,7 @@ unsigned long decompress_kernel(void) + #endif + + puts("Uncompressing Linux... "); +- decompress(input_data, input_len, NULL, NULL, output, NULL, error); ++ __decompress(input_data, input_len, NULL, NULL, output, 0, NULL, error); + puts("Ok, booting the kernel.\n"); + return (unsigned long) output; + } +--- a/arch/sh/boot/compressed/misc.c ++++ b/arch/sh/boot/compressed/misc.c +@@ -132,7 +132,7 @@ void decompress_kernel(void) + + puts("Uncompressing Linux... "); + cache_control(CACHE_ENABLE); +- decompress(input_data, input_len, NULL, NULL, output, NULL, error); ++ __decompress(input_data, input_len, NULL, NULL, output, 0, NULL, error); + cache_control(CACHE_DISABLE); + puts("Ok, booting the kernel.\n"); + } +--- a/arch/unicore32/boot/compressed/misc.c ++++ b/arch/unicore32/boot/compressed/misc.c +@@ -119,8 +119,8 @@ unsigned long decompress_kernel(unsigned + output_ptr = get_unaligned_le32(tmp); + + arch_decomp_puts("Uncompressing Linux..."); +- decompress(input_data, input_data_end - input_data, NULL, NULL, +- output_data, NULL, error); ++ __decompress(input_data, input_data_end - input_data, NULL, NULL, ++ output_data, 0, NULL, error); + arch_decomp_puts(" done, booting the kernel.\n"); + return output_ptr; + } +--- a/arch/x86/boot/compressed/misc.c ++++ b/arch/x86/boot/compressed/misc.c +@@ -424,7 +424,8 @@ asmlinkage __visible void *decompress_ke + #endif + + debug_putstr("\nDecompressing Linux... "); +- decompress(input_data, input_len, NULL, NULL, output, NULL, error); ++ __decompress(input_data, input_len, NULL, NULL, output, output_len, ++ NULL, error); + parse_elf(output); + /* + * 32-bit always performs relocations. 64-bit relocations are only +--- a/lib/decompress_bunzip2.c ++++ b/lib/decompress_bunzip2.c +@@ -743,12 +743,12 @@ exit_0: + } + + #ifdef PREBOOT +-STATIC int INIT decompress(unsigned char *buf, long len, ++STATIC int INIT __decompress(unsigned char *buf, long len, + long (*fill)(void*, unsigned long), + long (*flush)(void*, unsigned long), +- unsigned char *outbuf, ++ unsigned char *outbuf, long olen, + long *pos, +- void(*error)(char *x)) ++ void (*error)(char *x)) + { + return bunzip2(buf, len - 4, fill, flush, outbuf, pos, error); + } +--- a/lib/decompress_inflate.c ++++ b/lib/decompress_inflate.c +@@ -1,4 +1,5 @@ + #ifdef STATIC ++#define PREBOOT + /* Pre-boot environment: included */ + + /* prevent inclusion of _LINUX_KERNEL_H in pre-boot environment: lots +@@ -33,23 +34,23 @@ static long INIT nofill(void *buffer, un + } + + /* Included from initramfs et al code */ +-STATIC int INIT gunzip(unsigned char *buf, long len, ++STATIC int INIT __gunzip(unsigned char *buf, long len, + long (*fill)(void*, unsigned long), + long (*flush)(void*, unsigned long), +- unsigned char *out_buf, ++ unsigned char *out_buf, long out_len, + long *pos, + void(*error)(char *x)) { + u8 *zbuf; + struct z_stream_s *strm; + int rc; +- size_t out_len; + + rc = -1; + if (flush) { + out_len = 0x8000; /* 32 K */ + out_buf = malloc(out_len); + } else { +- out_len = ((size_t)~0) - (size_t)out_buf; /* no limit */ ++ if (!out_len) ++ out_len = ((size_t)~0) - (size_t)out_buf; /* no limit */ + } + if (!out_buf) { + error("Out of memory while allocating output buffer"); +@@ -181,4 +182,24 @@ gunzip_nomem1: + return rc; /* returns Z_OK (0) if successful */ + } + +-#define decompress gunzip ++#ifndef PREBOOT ++STATIC int INIT gunzip(unsigned char *buf, long len, ++ long (*fill)(void*, unsigned long), ++ long (*flush)(void*, unsigned long), ++ unsigned char *out_buf, ++ long *pos, ++ void (*error)(char *x)) ++{ ++ return __gunzip(buf, len, fill, flush, out_buf, 0, pos, error); ++} ++#else ++STATIC int INIT __decompress(unsigned char *buf, long len, ++ long (*fill)(void*, unsigned long), ++ long (*flush)(void*, unsigned long), ++ unsigned char *out_buf, long out_len, ++ long *pos, ++ void (*error)(char *x)) ++{ ++ return __gunzip(buf, len, fill, flush, out_buf, out_len, pos, error); ++} ++#endif +--- a/lib/decompress_unlz4.c ++++ b/lib/decompress_unlz4.c +@@ -196,12 +196,12 @@ exit_0: + } + + #ifdef PREBOOT +-STATIC int INIT decompress(unsigned char *buf, long in_len, ++STATIC int INIT __decompress(unsigned char *buf, long in_len, + long (*fill)(void*, unsigned long), + long (*flush)(void*, unsigned long), +- unsigned char *output, ++ unsigned char *output, long out_len, + long *posp, +- void(*error)(char *x) ++ void (*error)(char *x) + ) + { + return unlz4(buf, in_len - 4, fill, flush, output, posp, error); +--- a/lib/decompress_unlzma.c ++++ b/lib/decompress_unlzma.c +@@ -667,13 +667,12 @@ exit_0: + } + + #ifdef PREBOOT +-STATIC int INIT decompress(unsigned char *buf, long in_len, ++STATIC int INIT __decompress(unsigned char *buf, long in_len, + long (*fill)(void*, unsigned long), + long (*flush)(void*, unsigned long), +- unsigned char *output, ++ unsigned char *output, long out_len, + long *posp, +- void(*error)(char *x) +- ) ++ void (*error)(char *x)) + { + return unlzma(buf, in_len - 4, fill, flush, output, posp, error); + } +--- a/lib/decompress_unlzo.c ++++ b/lib/decompress_unlzo.c +@@ -31,6 +31,7 @@ + */ + + #ifdef STATIC ++#define PREBOOT + #include "lzo/lzo1x_decompress_safe.c" + #else + #include +@@ -287,4 +288,14 @@ exit: + return ret; + } + +-#define decompress unlzo ++#ifdef PREBOOT ++STATIC int INIT __decompress(unsigned char *buf, long len, ++ long (*fill)(void*, unsigned long), ++ long (*flush)(void*, unsigned long), ++ unsigned char *out_buf, long olen, ++ long *pos, ++ void (*error)(char *x)) ++{ ++ return unlzo(buf, len, fill, flush, out_buf, pos, error); ++} ++#endif +--- a/lib/decompress_unxz.c ++++ b/lib/decompress_unxz.c +@@ -394,4 +394,14 @@ error_alloc_state: + * This macro is used by architecture-specific files to decompress + * the kernel image. + */ +-#define decompress unxz ++#ifdef XZ_PREBOOT ++STATIC int INIT __decompress(unsigned char *buf, long len, ++ long (*fill)(void*, unsigned long), ++ long (*flush)(void*, unsigned long), ++ unsigned char *out_buf, long olen, ++ long *pos, ++ void (*error)(char *x)) ++{ ++ return unxz(buf, len, fill, flush, out_buf, pos, error); ++} ++#endif diff --git a/queue-4.2/series b/queue-4.2/series index b12552f0f56..68097ff5f9e 100644 --- a/queue-4.2/series +++ b/queue-4.2/series @@ -112,3 +112,22 @@ iommu-fsl-really-fix-init-section-s-content.patch iommu-io-pgtable-arm-unmap-and-free-table-when-overwriting-with-block.patch iommu-tegra-smmu-parameterize-number-of-tlb-lines.patch iommu-vt-d-really-use-upper-context-table-when-necessary.patch +ecryptfs-invalidate-dcache-entries-when-lower-i_nlink-is-zero.patch +hfs-fix-b-tree-corruption-after-insertion-at-position-0.patch +i2c-xgene-slimpro-dma_mapping_error-doesn-t-return-an-error-code.patch +ideapad-laptop-add-lenovo-yoga-3-14-to-no_hw_rfkill-dmi-list.patch +ib-srp-handle-partial-connection-success-correctly.patch +ib-srp-stop-the-scsi_eh_-n-and-scsi_tmf_-n-threads-if-login-fails.patch +ib-qib-change-lkey-table-allocation-to-support-more-mrs.patch +ib-uverbs-reject-invalid-or-unknown-opcodes.patch +ib-uverbs-fix-race-between-ib_uverbs_open-and-remove_one.patch +ib-iser-fix-missing-return-status-check-in-iser_send_data_out.patch +ib-iser-fix-possible-bogus-dma-unmapping.patch +ib-mlx5-avoid-destroying-a-null-mr-in-reg_user_mr-error-flow.patch +ib-mlx4-fix-potential-deadlock-when-sending-mad-to-wire.patch +ib-mlx4-forbid-using-sysfs-to-change-roce-pkeys.patch +ib-mlx4-use-correct-sl-on-ah-query-under-roce.patch +ib-mlx4-fix-incorrect-cq-flushing-in-error-state.patch +stmmac-fix-check-for-phydev-being-open.patch +hfs-hfsplus-cache-pages-correctly-between-bnode_create-and-bnode_free.patch +lib-decompressors-use-real-out-buf-size-for-gunzip-with-kernel.patch diff --git a/queue-4.2/stmmac-fix-check-for-phydev-being-open.patch b/queue-4.2/stmmac-fix-check-for-phydev-being-open.patch new file mode 100644 index 00000000000..33308ad856d --- /dev/null +++ b/queue-4.2/stmmac-fix-check-for-phydev-being-open.patch @@ -0,0 +1,43 @@ +From dfc50fcaad574e5c8c85cbc83eca1426b2413fa4 Mon Sep 17 00:00:00 2001 +From: Alexey Brodkin +Date: Wed, 9 Sep 2015 18:01:08 +0300 +Subject: stmmac: fix check for phydev being open + +From: Alexey Brodkin + +commit dfc50fcaad574e5c8c85cbc83eca1426b2413fa4 upstream. + +Current check of phydev with IS_ERR(phydev) may make not much sense +because of_phy_connect() returns NULL on failure instead of error value. + +Still for checking result of phy_connect() IS_ERR() makes perfect sense. + +So let's use combined check IS_ERR_OR_NULL() that covers both cases. + +Cc: Sergei Shtylyov +Cc: Giuseppe Cavallaro +Cc: linux-kernel@vger.kernel.org +Cc: David Miller +Signed-off-by: Alexey Brodkin +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -837,8 +837,11 @@ static int stmmac_init_phy(struct net_de + interface); + } + +- if (IS_ERR(phydev)) { ++ if (IS_ERR_OR_NULL(phydev)) { + pr_err("%s: Could not attach to PHY\n", dev->name); ++ if (!phydev) ++ return -ENODEV; ++ + return PTR_ERR(phydev); + } +