Skip to contentSkip to conversation

4.4.23-stable review

PATCH In review Greg Kroah-Hartman 3 participants 69 messages Sep 28, 2016 – Sep 29, 2016 1 message not in the archive

Subsystems (3)
lore
Share & tools
lore
author maintainer
#6 lore raw

PATCH 11/73 crypto: skcipher - Fix blkcipher walk OOM crash

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Herbert Xu <[email protected]>

commit acdb04d0b36769b3e05990c488dc74d8b7ac8060 upstream.

When we need to allocate a temporary blkcipher_walk_next and it fails, the code is supposed to take the slow path of processing the data block by block. However, due to an unrelated change we instead end up dereferencing the NULL pointer.

This patch fixes it by moving the unrelated bsize setting out of the way so that we enter the slow path as inteded.

Fixes 7607bd8ff03b ("[CRYPTO] blkcipher: Added blkcipher_walk_virt_block")
---
 crypto/blkcipher.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
crypto/blkcipher.c +2 -1
@@ -234,6 +234,8 @@ static int blkcipher_walk_next(struct bl
 		return blkcipher_walk_done(desc, walk, -EINVAL);
 	}
 
+	bsize = min(walk->walk_blocksize, n);
+
 	walk->flags &= ~(BLKCIPHER_WALK_SLOW | BLKCIPHER_WALK_COPY |
 			 BLKCIPHER_WALK_DIFF);
 	if (!scatterwalk_aligned(&walk->in, walk->alignmask) ||
@@ -246,7 +248,6 @@ static int blkcipher_walk_next(struct bl
 		}
 	}
 
-	bsize = min(walk->walk_blocksize, n);
 	n = scatterwalk_clamp(&walk->in, n);
 	n = scatterwalk_clamp(&walk->out, n);
 
author maintainer
#8 lore raw

PATCH 13/73 ocfs2/dlm: fix race between convert and migration

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Joseph Qi <[email protected]>

commit e6f0c6e6170fec175fe676495f29029aecdf486c upstream.

Commit ac7cf246dfdb ("ocfs2/dlm: fix race between convert and recovery") checks if lockres master has changed to identify whether new master has finished recovery or not. This will introduce a race that right after old master does umount ( means master will change), a new convert request comes.

In this case, it will reset lockres state to DLM_RECOVERING and then retry convert, and then fail with lockres->l_action being set to OCFS2_AST_INVALID, which will cause inconsistent lock level between ocfs2 and dlm, and then finally BUG.

Since dlm recovery will clear lock->convert_pending in dlm_move_lockres_to_recovery_list, we can use it to correctly identify the race case between convert and recovery. So fix it.

Fixes ac7cf246dfdb ("ocfs2/dlm: fix race between convert and recovery")
Cc Mark Fasheh <[email protected]>
Cc Joel Becker <[email protected]>
Cc Junxiao Bi <[email protected]>
---
 fs/ocfs2/dlm/dlmconvert.c |   12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)
fs/ocfs2/dlm/dlmconvert.c +6 -6
@@ -262,7 +262,6 @@ enum dlm_status dlmconvert_remote(struct
 				  struct dlm_lock *lock, int flags, int type)
 {
 	enum dlm_status status;
-	u8 old_owner = res->owner;
 
 	mlog(0, "type=%d, convert_type=%d, busy=%d\n", lock->ml.type,
 	     lock->ml.convert_type, res->state & DLM_LOCK_RES_IN_PROGRESS);
@@ -329,7 +328,6 @@ enum dlm_status dlmconvert_remote(struct
 
 	spin_lock(&res->spinlock);
 	res->state &= ~DLM_LOCK_RES_IN_PROGRESS;
-	lock->convert_pending = 0;
 	/* if it failed, move it back to granted queue.
 	 * if master returns DLM_NORMAL and then down before sending ast,
 	 * it may have already been moved to granted queue, reset to
@@ -338,12 +336,14 @@ enum dlm_status dlmconvert_remote(struct
 		if (status != DLM_NOTQUEUED)
 			dlm_error(status);
 		dlm_revert_pending_convert(res, lock);
-	} else if ((res->state & DLM_LOCK_RES_RECOVERING) ||
-			(old_owner != res->owner)) {
-		mlog(0, "res %.*s is in recovering or has been recovered.\n",
-				res->lockname.len, res->lockname.name);
+	} else if (!lock->convert_pending) {
+		mlog(0, "%s: res %.*s, owner died and lock has been moved back "
+				"to granted list, retry convert.\n",
+				dlm->name, res->lockname.len, res->lockname.name);
 		status = DLM_RECOVERING;
 	}
+
+	lock->convert_pending = 0;
 bail:
 	spin_unlock(&res->spinlock);
 
author maintainer
#16 lore raw

PATCH 21/73 Disable "maybe-uninitialized" warning globally

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Linus Torvalds <[email protected]>

commit 6e8d666e925333c55378e8d5540a8a9ee0eea9c5 upstream.

Several build configurations had already disabled this warning because it generates a lot of false positives. But some had not, and it was still enabled for "allmodconfig" builds, for example.

Looking at the warnings produced, every single one I looked at was a false positive, and the warnings are frequent enough (and big enough) that they can easily hide real problems that you don't notice in the noise generated by -Wmaybe-uninitialized.

The warning is good in theory, but this is a classic case of a warning that causes more problems than the warning can solve.

If gcc gets better at avoiding false positives, we may be able to re-enable this warning. But as is, we're better off without it, and I want to be able to see the *real* warnings.

---
 Makefile |    7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
Makefile +4 -3
@@ -368,7 +368,7 @@ AFLAGS_MODULE   =
 LDFLAGS_MODULE  =
 CFLAGS_KERNEL	=
 AFLAGS_KERNEL	=
-CFLAGS_GCOV	= -fprofile-arcs -ftest-coverage -fno-tree-loop-im -Wno-maybe-uninitialized
+CFLAGS_GCOV	= -fprofile-arcs -ftest-coverage -fno-tree-loop-im
 
 
 # Use USERINCLUDE when you must reference the UAPI directories only.
@@ -616,12 +616,13 @@ ARCH_CFLAGS :=
 include arch/$(SRCARCH)/Makefile
 
 KBUILD_CFLAGS	+= $(call cc-option,-fno-delete-null-pointer-checks,)
+KBUILD_CFLAGS	+= $(call cc-disable-warning,maybe-uninitialized,)
 
 ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
-KBUILD_CFLAGS	+= -Os $(call cc-disable-warning,maybe-uninitialized,)
+KBUILD_CFLAGS	+= -Os
 else
 ifdef CONFIG_PROFILE_ALL_BRANCHES
-KBUILD_CFLAGS	+= -O2 $(call cc-disable-warning,maybe-uninitialized,)
+KBUILD_CFLAGS	+= -O2
 else
 KBUILD_CFLAGS   += -O2
 endif
author maintainer
#18 lore raw

PATCH 24/73 net: caif: fix misleading indentation

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Arnd Bergmann <[email protected]>

commit 8e0cc8c326d99e41468c96fea9785ab78883a281 upstream.

gcc points out code that is not indented the way it is interpreted:

net/caif/cfpkt_skbuff.c: In function 'cfpkt_setlen':
net/caif/cfpkt_skbuff.c:289:4: error: statement is indented as if it were guarded by... [-Werror=misleading-indentation]

    return cfpkt_getlen(pkt);
    ^~~~~~

net/caif/cfpkt_skbuff.c:286:3: note: ...this 'else' clause, but it is not
else
^~~~

It is clear from the context that not returning here would be a bug, as we'd end up passing a negative length into a function that takes a u16 length, so it is not missing curly braces here, and I'm assuming that the indentation is the only part that's wrong about it.

---
 net/caif/cfpkt_skbuff.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/caif/cfpkt_skbuff.c +1 -1
@@ -286,7 +286,7 @@ int cfpkt_setlen(struct cfpkt *pkt, u16
 		else
 			skb_trim(skb, len);
 
-			return cfpkt_getlen(pkt);
+		return cfpkt_getlen(pkt);
 	}
 
 	/* Need to expand SKB */
author maintainer
#19 lore raw

PATCH 26/73 am437x-vfpe: fix typo in vpfe_get_app_input_index

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Arnd Bergmann <[email protected]>

commit 0fb504001192c1df62c847a8bb6558753c36ebef upstream.

gcc-6 points out an obviously silly comparison in vpfe_get_app_input_index():

drivers/media/platform/am437x/am437x-vpfe.c: In function 'vpfe_get_app_input_index':
drivers/media/platform/am437x/am437x-vpfe.c:1709:27: warning: self-comparison always evaluats to true [-Wtautological-compare]

       client->adapter->nr == client->adapter->nr) {
                           ^~

This was introduced in a slighly incorrect conversion, and it's clear that the comparison was meant to compare the iterator to the current subdev instead, as we do in the line above.

Fixes d37232390fd4 ("[media] media: am437x-vpfe: match the OF node/i2c addr instead of name")
---
 drivers/media/platform/am437x/am437x-vpfe.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/platform/am437x/am437x-vpfe.c +1 -1
@@ -1706,7 +1706,7 @@ static int vpfe_get_app_input_index(stru
 		sdinfo = &cfg->sub_devs[i];
 		client = v4l2_get_subdevdata(sdinfo->sd);
 		if (client->addr == curr_client->addr &&
-		    client->adapter->nr == client->adapter->nr) {
+		    client->adapter->nr == curr_client->adapter->nr) {
 			if (vpfe->current_input >= 1)
 				return -1;
 			*app_input_index = j + vpfe->current_input;
author maintainer
#23 lore raw

PATCH 30/73 nouveau: fix nv40_perfctr_next() cleanup regression

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Arnd Bergmann <[email protected]>

commit 86d65b7e7a0c927d07d18605c276d0f142438ead upstream.

gcc-6 warns about code in the nouveau driver that is obviously silly:

drivers/gpu/drm/nouveau/nvkm/engine/pm/nv40.c: In function 'nv40_perfctr_next':
drivers/gpu/drm/nouveau/nvkm/engine/pm/nv40.c:62:19: warning: self-comparison always evaluats to false [-Wtautological-compare]
if (pm->sequence != pm->sequence) {

The behavior was accidentally introduced in a patch described as "This is purely preparation for upcoming commits, there should be no code changes here.". As far as I can tell, that was true for the rest of that patch except for this one function, which has been changed to a NOP.

This patch restores the original behavior.

Fixes 8c1aeaa13954 ("drm/nouveau/pm: cosmetic changes")
---
 drivers/gpu/drm/nouveau/nvkm/engine/pm/nv40.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/gpu/drm/nouveau/nvkm/engine/pm/nv40.c +4 -2
@@ -59,9 +59,11 @@ static void
 nv40_perfctr_next(struct nvkm_pm *pm, struct nvkm_perfdom *dom)
 {
 	struct nvkm_device *device = pm->engine.subdev.device;
-	if (pm->sequence != pm->sequence) {
+	struct nv40_pm *nv40pm = container_of(pm, struct nv40_pm, base);
+
+	if (nv40pm->sequence != pm->sequence) {
 		nvkm_wr32(device, 0x400084, 0x00000020);
-		pm->sequence = pm->sequence;
+		nv40pm->sequence = pm->sequence;
 	}
 }
 
author maintainer
#24 lore raw

PATCH 31/73 megaraid: fix null pointer check in megasas_detach_one().

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Maurizio Lombardi <[email protected]>

commit 546e559c79b1a8d27c23262907a00fc209e392a0 upstream.

The pd_seq_sync pointer can't be NULL, we have to check its entries instead.

---
 drivers/scsi/megaraid/megaraid_sas_base.c |   10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/scsi/megaraid/megaraid_sas_base.c +5 -5
@@ -5941,11 +5941,11 @@ static void megasas_detach_one(struct pc
 			if (fusion->ld_drv_map[i])
 				free_pages((ulong)fusion->ld_drv_map[i],
 					fusion->drv_map_pages);
-				if (fusion->pd_seq_sync)
-					dma_free_coherent(&instance->pdev->dev,
-						pd_seq_map_sz,
-						fusion->pd_seq_sync[i],
-						fusion->pd_seq_phys[i]);
+			if (fusion->pd_seq_sync[i])
+				dma_free_coherent(&instance->pdev->dev,
+					pd_seq_map_sz,
+					fusion->pd_seq_sync[i],
+					fusion->pd_seq_phys[i]);
 		}
 		free_pages((ulong)instance->ctrl_context,
 			instance->ctrl_context_pages);
author maintainer
#25 lore raw

PATCH 32/73 bonding: Fix bonding crash

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Mahesh Bandewar <[email protected]>

[ Upstream commit 24b27fc4cdf9e10c5e79e5923b6b7c2c5c95096c ]

Following few steps will crash kernel -

(a) Create bonding master
> modprobe bonding miimon=50
(b) Create macvlan bridge on eth2

      > ip link add link eth2 dev mvl0 address aa:0:0:0:0:01 \
	   type macvlan

(c) Now try adding eth2 into the bond
> echo +eth2 > /sys/class/net/bond0/bonding/slaves <crash>

Bonding does lots of things before checking if the device enslaved is busy or not.

In this case when the notifier call-chain sends notifications, the bond_netdev_event() assumes that the rx_handler /rx_handler_data is registered while the bond_enslave() hasn't progressed far enough to register rx_handler for the new slave.

This patch adds a rx_handler check that can be performed right at the beginning of the enslave code to avoid getting into this situation.

---
 drivers/net/bonding/bond_main.c |    7 ++++---
 include/linux/netdevice.h       |    1 +
 net/core/dev.c                  |   16 ++++++++++++++++
 3 files changed, 21 insertions(+), 3 deletions(-)
drivers/net/bonding/bond_main.c +4 -3
@@ -1317,9 +1317,10 @@ int bond_enslave(struct net_device *bond
 			    slave_dev->name);
 	}
 
-	/* already enslaved */
-	if (slave_dev->flags & IFF_SLAVE) {
-		netdev_dbg(bond_dev, "Error: Device was already enslaved\n");
+	/* already in-use? */
+	if (netdev_is_rx_handler_busy(slave_dev)) {
+		netdev_err(bond_dev,
+			   "Error: Device is in use and cannot be enslaved\n");
 		return -EBUSY;
 	}
 
include/linux/netdevice.h +1 -0
@@ -3036,6 +3036,7 @@ static inline void napi_free_frags(struc
 	napi->skb = NULL;
 }
 
+bool netdev_is_rx_handler_busy(struct net_device *dev);
 int netdev_rx_handler_register(struct net_device *dev,
 			       rx_handler_func_t *rx_handler,
 			       void *rx_handler_data);
net/core/dev.c +16 -0
@@ -3722,6 +3722,22 @@ static inline struct sk_buff *handle_ing
 }
 
 /**
+ *	netdev_is_rx_handler_busy - check if receive handler is registered
+ *	@dev: device to check
+ *
+ *	Check if a receive handler is already registered for a given device.
+ *	Return true if there one.
+ *
+ *	The caller must hold the rtnl_mutex.
+ */
+bool netdev_is_rx_handler_busy(struct net_device *dev)
+{
+	ASSERT_RTNL();
+	return dev && rtnl_dereference(dev->rx_handler);
+}
+EXPORT_SYMBOL_GPL(netdev_is_rx_handler_busy);
+
+/**
  *	netdev_rx_handler_register - register receive handler
  *	@dev: device to register a handler for
  *	@rx_handler: receive handler to register
author maintainer
#31 lore raw

PATCH 38/73 net/mlx5: Added missing check of msg length in verifying its signature

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Paul Blakey <[email protected]>

[ Upstream commit 2c0f8ce1b584a4d7b8ff53140d21dfed99834940 ]

Set and verify signature calculates the signature for each of the mailbox nodes, even for those that are unused (from cache). Added a missing length check to set and verify only those which are used.

While here, also moved the setting of msg's nodes token to where we already go over them. This saves a pass because checksum is disabled, and the only useful thing remaining that set signature does is setting the token.

Fixes e126ba97dba9 ('mlx5: Add driver for Mellanox Connect-IB

adapters')

---
 drivers/net/ethernet/mellanox/mlx5/core/cmd.c |   83 ++++++++++++++++----------
 1 file changed, 53 insertions(+), 30 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/cmd.c +53 -30
@@ -143,13 +143,14 @@ static struct mlx5_cmd_layout *get_inst(
 	return cmd->cmd_buf + (idx << cmd->log_stride);
 }
 
-static u8 xor8_buf(void *buf, int len)
+static u8 xor8_buf(void *buf, size_t offset, int len)
 {
 	u8 *ptr = buf;
 	u8 sum = 0;
 	int i;
+	int end = len + offset;
 
-	for (i = 0; i < len; i++)
+	for (i = offset; i < end; i++)
 		sum ^= ptr[i];
 
 	return sum;
@@ -157,41 +158,49 @@ static u8 xor8_buf(void *buf, int len)
 
 static int verify_block_sig(struct mlx5_cmd_prot_block *block)
 {
-	if (xor8_buf(block->rsvd0, sizeof(*block) - sizeof(block->data) - 1) != 0xff)
+	size_t rsvd0_off = offsetof(struct mlx5_cmd_prot_block, rsvd0);
+	int xor_len = sizeof(*block) - sizeof(block->data) - 1;
+
+	if (xor8_buf(block, rsvd0_off, xor_len) != 0xff)
 		return -EINVAL;
 
-	if (xor8_buf(block, sizeof(*block)) != 0xff)
+	if (xor8_buf(block, 0, sizeof(*block)) != 0xff)
 		return -EINVAL;
 
 	return 0;
 }
 
-static void calc_block_sig(struct mlx5_cmd_prot_block *block, u8 token,
-			   int csum)
+static void calc_block_sig(struct mlx5_cmd_prot_block *block)
 {
-	block->token = token;
-	if (csum) {
-		block->ctrl_sig = ~xor8_buf(block->rsvd0, sizeof(*block) -
-					    sizeof(block->data) - 2);
-		block->sig = ~xor8_buf(block, sizeof(*block) - 1);
-	}
+	int ctrl_xor_len = sizeof(*block) - sizeof(block->data) - 2;
+	size_t rsvd0_off = offsetof(struct mlx5_cmd_prot_block, rsvd0);
+
+	block->ctrl_sig = ~xor8_buf(block, rsvd0_off, ctrl_xor_len);
+	block->sig = ~xor8_buf(block, 0, sizeof(*block) - 1);
 }
 
-static void calc_chain_sig(struct mlx5_cmd_msg *msg, u8 token, int csum)
+static void calc_chain_sig(struct mlx5_cmd_msg *msg)
 {
 	struct mlx5_cmd_mailbox *next = msg->next;
+	int size = msg->len;
+	int blen = size - min_t(int, sizeof(msg->first.data), size);
+	int n = (blen + MLX5_CMD_DATA_BLOCK_SIZE - 1)
+		/ MLX5_CMD_DATA_BLOCK_SIZE;
+	int i = 0;
 
-	while (next) {
-		calc_block_sig(next->buf, token, csum);
+	for (i = 0; i < n && next; i++)  {
+		calc_block_sig(next->buf);
 		next = next->next;
 	}
 }
 
 static void set_signature(struct mlx5_cmd_work_ent *ent, int csum)
 {
-	ent->lay->sig = ~xor8_buf(ent->lay, sizeof(*ent->lay));
-	calc_chain_sig(ent->in, ent->token, csum);
-	calc_chain_sig(ent->out, ent->token, csum);
+	ent->lay->sig = ~xor8_buf(ent->lay, 0,  sizeof(*ent->lay));
+	if (csum) {
+		calc_chain_sig(ent->in);
+		calc_chain_sig(ent->out);
+	}
 }
 
 static void poll_timeout(struct mlx5_cmd_work_ent *ent)
@@ -222,12 +231,17 @@ static int verify_signature(struct mlx5_
 	struct mlx5_cmd_mailbox *next = ent->out->next;
 	int err;
 	u8 sig;
+	int size = ent->out->len;
+	int blen = size - min_t(int, sizeof(ent->out->first.data), size);
+	int n = (blen + MLX5_CMD_DATA_BLOCK_SIZE - 1)
+		/ MLX5_CMD_DATA_BLOCK_SIZE;
+	int i = 0;
 
-	sig = xor8_buf(ent->lay, sizeof(*ent->lay));
+	sig = xor8_buf(ent->lay, 0, sizeof(*ent->lay));
 	if (sig != 0xff)
 		return -EINVAL;
 
-	while (next) {
+	for (i = 0; i < n && next; i++) {
 		err = verify_block_sig(next->buf);
 		if (err)
 			return err;
@@ -641,7 +655,6 @@ static void cmd_work_handler(struct work
 		spin_unlock_irqrestore(&cmd->alloc_lock, flags);
 	}
 
-	ent->token = alloc_token(cmd);
 	cmd->ent_arr[ent->idx] = ent;
 	lay = get_inst(cmd, ent->idx);
 	ent->lay = lay;
@@ -755,7 +768,8 @@ static u8 *get_status_ptr(struct mlx5_ou
 static int mlx5_cmd_invoke(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *in,
 			   struct mlx5_cmd_msg *out, void *uout, int uout_size,
 			   mlx5_cmd_cbk_t callback,
-			   void *context, int page_queue, u8 *status)
+			   void *context, int page_queue, u8 *status,
+			   u8 token)
 {
 	struct mlx5_cmd *cmd = &dev->cmd;
 	struct mlx5_cmd_work_ent *ent;
@@ -772,6 +786,8 @@ static int mlx5_cmd_invoke(struct mlx5_c
 	if (IS_ERR(ent))
 		return PTR_ERR(ent);
 
+	ent->token = token;
+
 	if (!callback)
 		init_completion(&ent->done);
 
@@ -844,7 +860,8 @@ static const struct file_operations fops
 	.write	= dbg_write,
 };
 
-static int mlx5_copy_to_msg(struct mlx5_cmd_msg *to, void *from, int size)
+static int mlx5_copy_to_msg(struct mlx5_cmd_msg *to, void *from, int size,
+			    u8 token)
 {
 	struct mlx5_cmd_prot_block *block;
 	struct mlx5_cmd_mailbox *next;
@@ -870,6 +887,7 @@ static int mlx5_copy_to_msg(struct mlx5_
 		memcpy(block->data, from, copy);
 		from += copy;
 		size -= copy;
+		block->token = token;
 		next = next->next;
 	}
 
@@ -939,7 +957,8 @@ static void free_cmd_box(struct mlx5_cor
 }
 
 static struct mlx5_cmd_msg *mlx5_alloc_cmd_msg(struct mlx5_core_dev *dev,
-					       gfp_t flags, int size)
+					       gfp_t flags, int size,
+					       u8 token)
 {
 	struct mlx5_cmd_mailbox *tmp, *head = NULL;
 	struct mlx5_cmd_prot_block *block;
@@ -968,6 +987,7 @@ static struct mlx5_cmd_msg *mlx5_alloc_c
 		tmp->next = head;
 		block->next = cpu_to_be64(tmp->next ? tmp->next->dma : 0);
 		block->block_num = cpu_to_be32(n - i - 1);
+		block->token = token;
 		head = tmp;
 	}
 	msg->next = head;
@@ -1351,7 +1371,7 @@ static struct mlx5_cmd_msg *alloc_msg(st
 	}
 
 	if (IS_ERR(msg))
-		msg = mlx5_alloc_cmd_msg(dev, gfp, in_size);
+		msg = mlx5_alloc_cmd_msg(dev, gfp, in_size, 0);
 
 	return msg;
 }
@@ -1376,6 +1396,7 @@ static int cmd_exec(struct mlx5_core_dev
 	int err;
 	u8 status = 0;
 	u32 drv_synd;
+	u8 token;
 
 	if (pci_channel_offline(dev->pdev) ||
 	    dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) {
@@ -1394,20 +1415,22 @@ static int cmd_exec(struct mlx5_core_dev
 		return err;
 	}
 
-	err = mlx5_copy_to_msg(inb, in, in_size);
+	token = alloc_token(&dev->cmd);
+
+	err = mlx5_copy_to_msg(inb, in, in_size, token);
 	if (err) {
 		mlx5_core_warn(dev, "err %d\n", err);
 		goto out_in;
 	}
 
-	outb = mlx5_alloc_cmd_msg(dev, gfp, out_size);
+	outb = mlx5_alloc_cmd_msg(dev, gfp, out_size, token);
 	if (IS_ERR(outb)) {
 		err = PTR_ERR(outb);
 		goto out_in;
 	}
 
 	err = mlx5_cmd_invoke(dev, inb, outb, out, out_size, callback, context,
-			      pages_queue, &status);
+			      pages_queue, &status, token);
 	if (err)
 		goto out_out;
 
@@ -1475,7 +1498,7 @@ static int create_msg_cache(struct mlx5_
 	INIT_LIST_HEAD(&cmd->cache.med.head);
 
 	for (i = 0; i < NUM_LONG_LISTS; i++) {
-		msg = mlx5_alloc_cmd_msg(dev, GFP_KERNEL, LONG_LIST_SIZE);
+		msg = mlx5_alloc_cmd_msg(dev, GFP_KERNEL, LONG_LIST_SIZE, 0);
 		if (IS_ERR(msg)) {
 			err = PTR_ERR(msg);
 			goto ex_err;
@@ -1485,7 +1508,7 @@ static int create_msg_cache(struct mlx5_
 	}
 
 	for (i = 0; i < NUM_MED_LISTS; i++) {
-		msg = mlx5_alloc_cmd_msg(dev, GFP_KERNEL, MED_LIST_SIZE);
+		msg = mlx5_alloc_cmd_msg(dev, GFP_KERNEL, MED_LIST_SIZE, 0);
 		if (IS_ERR(msg)) {
 			err = PTR_ERR(msg);
 			goto ex_err;
author maintainer
#39 lore raw

PATCH 46/73 xfs: prevent dropping ioend completions during buftarg wait

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Brian Foster <[email protected]>

commit 800b2694f890cc35a1bda63501fc71c94389d517 upstream.

xfs_wait_buftarg() waits for all pending I/O, drains the ioend completion workqueue and walks the LRU until all buffers in the cache have been released. This is traditionally an unmount operation` but the mechanism is also reused during filesystem freeze.

xfs_wait_buftarg() invokes drain_workqueue() as part of the quiesce, which is intended more for a shutdown sequence in that it indicates to the queue that new operations are not expected once the drain has begun. New work jobs after this point result in a WARN_ON_ONCE() and are otherwise dropped.

With filesystem freeze, however, read operations are allowed and can proceed during or after the workqueue drain. If such a read occurs during the drain sequence, the workqueue infrastructure complains about the queued ioend completion work item and drops it on the floor. As a result, the buffer remains on the LRU and the freeze never completes.

Despite the fact that the overall buffer cache cleanup is not necessary during freeze, fix up this operation such that it is safe to invoke during non-unmount quiesce operations. Replace the drain_workqueue() call with flush_workqueue(), which runs a similar serialization on pending workqueue jobs without causing new jobs to be dropped. This is safe for unmount as unmount independently locks out new operations by the time xfs_wait_buftarg() is invoked.

---
 fs/xfs/xfs_buf.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/xfs/xfs_buf.c +1 -1
@@ -1535,7 +1535,7 @@ xfs_wait_buftarg(
 	 * ensure here that all reference counts have been dropped before we
 	 * start walking the LRU list.
 	 */
-	drain_workqueue(btp->bt_mount->m_buf_workqueue);
+	flush_workqueue(btp->bt_mount->m_buf_workqueue);
 
 	/* loop until there is nothing left on the lru list. */
 	while (list_lru_count(&btp->bt_lru)) {
author maintainer
#42 lore raw

PATCH 49/73 fix fault_in_multipages_...() on architectures with no-op access_ok()

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Al Viro <[email protected]>

commit e23d4159b109167126e5bcd7f3775c95de7fee47 upstream.

Switching iov_iter fault-in to multipages variants has exposed an old bug in underlying fault_in_multipages_...(); they break if the range passed to them wraps around. Normally access_ok() done by callers will prevent such (and it's a guaranteed EFAULT - ERR_PTR() values fall into such a range and they should not point to any valid objects).

However, on architectures where userland and kernel live in different MMU contexts (e.g. s390) access_ok() is a no-op and on those a range with a wraparound can reach fault_in_multipages_...().

Since any wraparound means EFAULT there, the fix is trivial - turn those

while (uaddr <= end)
...
into

    if (unlikely(uaddr > end))
	    return -EFAULT;
    do
	    ...
    while (uaddr <= end);
---
 include/linux/pagemap.h |   38 +++++++++++++++++++-------------------
 1 file changed, 19 insertions(+), 19 deletions(-)
include/linux/pagemap.h +19 -19
@@ -601,56 +601,56 @@ static inline int fault_in_pages_readabl
  */
 static inline int fault_in_multipages_writeable(char __user *uaddr, int size)
 {
-	int ret = 0;
 	char __user *end = uaddr + size - 1;
 
 	if (unlikely(size == 0))
-		return ret;
+		return 0;
 
+	if (unlikely(uaddr > end))
+		return -EFAULT;
 	/*
 	 * Writing zeroes into userspace here is OK, because we know that if
 	 * the zero gets there, we'll be overwriting it.
 	 */
-	while (uaddr <= end) {
-		ret = __put_user(0, uaddr);
-		if (ret != 0)
-			return ret;
+	do {
+		if (unlikely(__put_user(0, uaddr) != 0))
+			return -EFAULT;
 		uaddr += PAGE_SIZE;
-	}
+	} while (uaddr <= end);
 
 	/* Check whether the range spilled into the next page. */
 	if (((unsigned long)uaddr & PAGE_MASK) ==
 			((unsigned long)end & PAGE_MASK))
-		ret = __put_user(0, end);
+		return __put_user(0, end);
 
-	return ret;
+	return 0;
 }
 
 static inline int fault_in_multipages_readable(const char __user *uaddr,
 					       int size)
 {
 	volatile char c;
-	int ret = 0;
 	const char __user *end = uaddr + size - 1;
 
 	if (unlikely(size == 0))
-		return ret;
+		return 0;
+
+	if (unlikely(uaddr > end))
+		return -EFAULT;
 
-	while (uaddr <= end) {
-		ret = __get_user(c, uaddr);
-		if (ret != 0)
-			return ret;
+	do {
+		if (unlikely(__get_user(c, uaddr) != 0))
+			return -EFAULT;
 		uaddr += PAGE_SIZE;
-	}
+	} while (uaddr <= end);
 
 	/* Check whether the range spilled into the next page. */
 	if (((unsigned long)uaddr & PAGE_MASK) ==
 			((unsigned long)end & PAGE_MASK)) {
-		ret = __get_user(c, end);
-		(void)c;
+		return __get_user(c, end);
 	}
 
-	return ret;
+	return 0;
 }
 
 int add_to_page_cache_locked(struct page *page, struct address_space *mapping,
author maintainer
#46 lore raw

PATCH 53/73 fix memory leaks in tracing_buffers_splice_read()

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Al Viro <[email protected]>

commit 1ae2293dd6d2f5c823cf97e60b70d03631cd622f upstream.

---
 kernel/trace/trace.c |   14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)
kernel/trace/trace.c +8 -6
@@ -5766,9 +5766,6 @@ tracing_buffers_splice_read(struct file
 		return -EBUSY;
 #endif
 
-	if (splice_grow_spd(pipe, &spd))
-		return -ENOMEM;
-
 	if (*ppos & (PAGE_SIZE - 1))
 		return -EINVAL;
 
@@ -5778,6 +5775,9 @@ tracing_buffers_splice_read(struct file
 		len &= PAGE_MASK;
 	}
 
+	if (splice_grow_spd(pipe, &spd))
+		return -ENOMEM;
+
  again:
 	trace_access_lock(iter->cpu_file);
 	entries = ring_buffer_entries_cpu(iter->trace_buffer->buffer, iter->cpu_file);
@@ -5835,19 +5835,21 @@ tracing_buffers_splice_read(struct file
 	/* did we read anything? */
 	if (!spd.nr_pages) {
 		if (ret)
-			return ret;
+			goto out;
 
+		ret = -EAGAIN;
 		if ((file->f_flags & O_NONBLOCK) || (flags & SPLICE_F_NONBLOCK))
-			return -EAGAIN;
+			goto out;
 
 		ret = wait_on_pipe(iter, true);
 		if (ret)
-			return ret;
+			goto out;
 
 		goto again;
 	}
 
 	ret = splice_to_pipe(pipe, &spd);
+out:
 	splice_shrink_spd(&spd);
 
 	return ret;
author maintainer
#48 lore raw

PATCH 55/73 mm: delete unnecessary and unsafe init_tlb_ubc()

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Hugh Dickins <[email protected]>

commit b385d21f27d86426472f6ae92a231095f7de2a8d upstream.

init_tlb_ubc() looked unnecessary to me: tlb_ubc is statically initialized with zeroes in the init_task, and copied from parent to child while it is quiescent in arch_dup_task_struct(); so I went to delete it.

But inserted temporary debug WARN_ONs in place of init_tlb_ubc() to check that it was always empty at that point, and found them firing:
because memcg reclaim can recurse into global reclaim (when allocating biosets for swapout in my case), and arrive back at the init_tlb_ubc() in shrink_node_memcg().

Resetting tlb_ubc.flush_required at that point is wrong: if the upper level needs a deferred TLB flush, but the lower level turns out not to, we miss a TLB flush. But fortunately, that's the only part of the protocol that does not nest: with the initialization removed, cpumask collects bits from upper and lower levels, and flushes TLB when needed.

Fixes 72b252aed506 ("mm: send one IPI per CPU to TLB flush all entries after unmapping pages")
---
 mm/vmscan.c |   19 -------------------
 1 file changed, 19 deletions(-)
mm/vmscan.c +0 -19
@@ -2159,23 +2159,6 @@ out:
 	}
 }
 
-#ifdef CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH
-static void init_tlb_ubc(void)
-{
-	/*
-	 * This deliberately does not clear the cpumask as it's expensive
-	 * and unnecessary. If there happens to be data in there then the
-	 * first SWAP_CLUSTER_MAX pages will send an unnecessary IPI and
-	 * then will be cleared.
-	 */
-	current->tlb_ubc.flush_required = false;
-}
-#else
-static inline void init_tlb_ubc(void)
-{
-}
-#endif /* CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH */
-
 /*
  * This is a basic per-zone page freer.  Used by both kswapd and direct reclaim.
  */
@@ -2210,8 +2193,6 @@ static void shrink_lruvec(struct lruvec
 	scan_adjusted = (global_reclaim(sc) && !current_is_kswapd() &&
 			 sc->priority == DEF_PRIORITY);
 
-	init_tlb_ubc();
-
 	blk_start_plug(&plug);
 	while (nr[LRU_INACTIVE_ANON] || nr[LRU_ACTIVE_FILE] ||
 					nr[LRU_INACTIVE_FILE]) {
author maintainer
#51 lore raw

PATCH 58/73 btrfs: ensure that file descriptor used with subvol ioctls is a dir

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jeff Mahoney <[email protected]>

commit 325c50e3cebb9208009083e841550f98a863bfa0 upstream.

If the subvol/snapshot create/destroy ioctls are passed a regular file with execute permissions set, we'll eventually Oops while trying to do inode->i_op->lookup via lookup_one_len.

This patch ensures that the file descriptor refers to a directory.

Fixes cb8e70901d (Btrfs: Fix subvolume creation locking rules)
Fixes 76dda93c6a (Btrfs: add snapshot/subvolume destroy ioctl)
---
 fs/btrfs/ioctl.c |   12 ++++++++++++
 1 file changed, 12 insertions(+)
fs/btrfs/ioctl.c +12 -0
@@ -1619,6 +1619,9 @@ static noinline int btrfs_ioctl_snap_cre
 	int namelen;
 	int ret = 0;
 
+	if (!S_ISDIR(file_inode(file)->i_mode))
+		return -ENOTDIR;
+
 	ret = mnt_want_write_file(file);
 	if (ret)
 		goto out;
@@ -1676,6 +1679,9 @@ static noinline int btrfs_ioctl_snap_cre
 	struct btrfs_ioctl_vol_args *vol_args;
 	int ret;
 
+	if (!S_ISDIR(file_inode(file)->i_mode))
+		return -ENOTDIR;
+
 	vol_args = memdup_user(arg, sizeof(*vol_args));
 	if (IS_ERR(vol_args))
 		return PTR_ERR(vol_args);
@@ -1699,6 +1705,9 @@ static noinline int btrfs_ioctl_snap_cre
 	bool readonly = false;
 	struct btrfs_qgroup_inherit *inherit = NULL;
 
+	if (!S_ISDIR(file_inode(file)->i_mode))
+		return -ENOTDIR;
+
 	vol_args = memdup_user(arg, sizeof(*vol_args));
 	if (IS_ERR(vol_args))
 		return PTR_ERR(vol_args);
@@ -2345,6 +2354,9 @@ static noinline int btrfs_ioctl_snap_des
 	int ret;
 	int err = 0;
 
+	if (!S_ISDIR(dir->i_mode))
+		return -ENOTDIR;
+
 	vol_args = memdup_user(arg, sizeof(*vol_args));
 	if (IS_ERR(vol_args))
 		return PTR_ERR(vol_args);
author maintainer
#52 lore raw

PATCH 59/73 i2c-eg20t: fix race between i2c init and interrupt enable

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Yadi.hu <[email protected]>

commit 371a015344b6e270e7e3632107d9554ec6d27a6b upstream.

the eg20t driver call request_irq() function before the pch_base_address, base address of i2c controller's register, is assigned an effective value.

there is one possible scenario that an interrupt which isn't inside eg20t arrives immediately after request_irq() is executed when i2c controller shares an interrupt number with others. since the interrupt handler pch_i2c_handler() has already active as shared action, it will be called and read its own register to determine if this interrupt is from itself.

At that moment, since base address of i2c registers is not remapped in kernel space yet,so the INT handler will access an illegal address and then a error occurs.

---
 drivers/i2c/busses/i2c-eg20t.c |   18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)
drivers/i2c/busses/i2c-eg20t.c +11 -7
@@ -773,13 +773,6 @@ static int pch_i2c_probe(struct pci_dev
 	/* Set the number of I2C channel instance */
 	adap_info->ch_num = id->driver_data;
 
-	ret = request_irq(pdev->irq, pch_i2c_handler, IRQF_SHARED,
-		  KBUILD_MODNAME, adap_info);
-	if (ret) {
-		pch_pci_err(pdev, "request_irq FAILED\n");
-		goto err_request_irq;
-	}
-
 	for (i = 0; i < adap_info->ch_num; i++) {
 		pch_adap = &adap_info->pch_data[i].pch_adapter;
 		adap_info->pch_i2c_suspended = false;
@@ -796,6 +789,17 @@ static int pch_i2c_probe(struct pci_dev
 		adap_info->pch_data[i].pch_base_address = base_addr + 0x100 * i;
 
 		pch_adap->dev.parent = &pdev->dev;
+	}
+
+	ret = request_irq(pdev->irq, pch_i2c_handler, IRQF_SHARED,
+		  KBUILD_MODNAME, adap_info);
+	if (ret) {
+		pch_pci_err(pdev, "request_irq FAILED\n");
+		goto err_request_irq;
+	}
+
+	for (i = 0; i < adap_info->ch_num; i++) {
+		pch_adap = &adap_info->pch_data[i].pch_adapter;
 
 		pch_i2c_init(&adap_info->pch_data[i]);
 
author maintainer
#54 lore raw

PATCH 61/73 MIPS: Fix pre-r6 emulation FPU initialisation

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Paul Burton <[email protected]>

commit 7e956304eb8a285304a78582e4537e72c6365f20 upstream.

In the mipsr2_decoder() function, used to emulate pre-MIPSr6 instructions that were removed in MIPSr6, the init_fpu() function is called if a removed pre-MIPSr6 floating point instruction is the first floating point instruction used by the task. However, init_fpu() performs varous actions that rely upon not being migrated. For example in the most basic case it sets the coprocessor 0 Status.CU1 bit to enable the FPU & then loads FP register context into the FPU registers. If the task were to migrate during this time, it may end up attempting to load FP register context on a different CPU where it hasn't set the CU1 bit, leading to errors such as:

    do_cpu invoked from kernel context![#2]:
    CPU: 2 PID: 7338 Comm: fp-prctl Tainted: G      D         4.7.0-00424-g49b0c82 #2
    task: 838e4000 ti: 88d38000 task.ti: 88d38000
    $ 0   : 00000000 00000001 ffffffff 88d3fef8
    $ 4   : 838e4000 88d38004 00000000 00000001
    $ 8   : 3400fc01 801f8020 808e9100 24000000
    $12   : dbffffff 807b69d8 807b0000 00000000
    $16   : 00000000 80786150 00400fc4 809c0398
    $20   : 809c0338 0040273c 88d3ff28 808e9d30
    $24   : 808e9d30 00400fb4
    $28   : 88d38000 88d3fe88 00000000 8011a2ac
    Hi    : 0040273c
    Lo    : 88d3ff28
    epc   : 80114178 _restore_fp+0x10/0xa0
    ra    : 8011a2ac mipsr2_decoder+0xd5c/0x1660
    Status: 1400fc03	KERNEL EXL IE
    Cause : 1080002c (ExcCode 0b)
    PrId  : 0001a920 (MIPS I6400)
    Modules linked in:
    Process fp-prctl (pid: 7338, threadinfo=88d38000, task=838e4000, tls=766527d0)
    Stack : 00000000 00000000 00000000 88d3fe98 00000000 00000000 809c0398 809c0338
    	  808e9100 00000000 88d3ff28 00400fc4 00400fc4 0040273c 7fb69e18 004a0000
    	  004a0000 004a0000 7664add0 8010de18 00000000 00000000 88d3fef8 88d3ff28
    	  808e9100 00000000 766527d0 8010e534 000c0000 85755000 8181d580 00000000
    	  00000000 00000000 004a0000 00000000 766527d0 7fb69e18 004a0000 80105c20
    	  ...
    Call Trace:
    [<80114178>] _restore_fp+0x10/0xa0
    [<8011a2ac>] mipsr2_decoder+0xd5c/0x1660
    [<8010de18>] do_ri+0x90/0x6b8
    [<80105c20>] ret_from_exception+0x0/0x10

Fix this by disabling preemption around the call to init_fpu(), ensuring that it starts & completes on one CPU.

Fixes b0a668fb2038 ("MIPS: kernel: mips-r2-to-r6-emul: Add R2 emulator for MIPS R6")

Patchwork: https://patchwork.linux-mips.org/patch/14305/

---
 arch/mips/kernel/mips-r2-to-r6-emul.c |    2 ++
 1 file changed, 2 insertions(+)
arch/mips/kernel/mips-r2-to-r6-emul.c +2 -0
@@ -1164,7 +1164,9 @@ fpu_emul:
 		regs->regs[31] = r31;
 		regs->cp0_epc = epc;
 		if (!used_math()) {     /* First time FPU user.  */
+			preempt_disable();
 			err = init_fpu();
+			preempt_enable();
 			set_used_math();
 		}
 		lose_fpu(1);    /* Save FPU state for the emulator. */
author maintainer
#61 lore raw

PATCH 69/73 PM / hibernate: Fix rtree_next_node() to avoid walking off list ends

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: James Morse <[email protected]>

commit 924d8696751c4b9e58263bc82efdafcf875596a6 upstream.

rtree_next_node() walks the linked list of leaf nodes to find the next block of pages in the struct memory_bitmap. If it walks off the end of the list of nodes, it walks the list of memory zones to find the next region of memory. If it walks off the end of the list of zones, it returns false.

This leaves the struct bm_position's node and zone pointers pointing at their respective struct list_heads in struct mem_zone_bm_rtree.

memory_bm_find_bit() uses struct bm_position's node and zone pointers to avoid walking lists and trees if the next bit appears in the same node/zone. It handles these values being stale.

Swap rtree_next_node()s 'step then test' to 'test-next then step', this means if we reach the end of memory we return false and leave the node and zone pointers as they were.

This fixes a panic on resume using AMD Seattle with 64K pages:

[    6.868732] Freezing user space processes ... (elapsed 0.000 seconds) done.
[    6.875753] Double checking all user space processes after OOM killer disable... (elapsed 0.000 seconds)
[    6.896453] PM: Using 3 thread(s) for decompression.
[    6.896453] PM: Loading and decompressing image data (5339 pages)...
[    7.318890] PM: Image loading progress:   0%
[    7.323395] Unable to handle kernel paging request at virtual address 00800040
[    7.330611] pgd = ffff000008df0000
[    7.334003] [00800040] *pgd=00000083fffe0003, *pud=00000083fffe0003, *pmd=00000083fffd0003, *pte=0000000000000000
[    7.344266] Internal error: Oops: 96000005 [#1] PREEMPT SMP
[    7.349825] Modules linked in:
[    7.352871] CPU: 2 PID: 1 Comm: swapper/0 Tainted: G        W I     4.8.0-rc1 #4737
[    7.360512] Hardware name: AMD Overdrive/Supercharger/Default string, BIOS ROD1002C 04/08/2016
[    7.369109] task: ffff8003c0220000 task.stack: ffff8003c0280000
[    7.375020] PC is at set_bit+0x18/0x30
[    7.378758] LR is at memory_bm_set_bit+0x24/0x30
[    7.383362] pc : [<ffff00000835bbc8>] lr : [<ffff0000080faf18>] pstate: 60000045
[    7.390743] sp : ffff8003c0283b00
[    7.473551]
[    7.475031] Process swapper/0 (pid: 1, stack limit = 0xffff8003c0280020)
[    7.481718] Stack: (0xffff8003c0283b00 to 0xffff8003c0284000)
[    7.800075] Call trace:
[    7.887097] [<ffff00000835bbc8>] set_bit+0x18/0x30
[    7.891876] [<ffff0000080fb038>] duplicate_memory_bitmap.constprop.38+0x54/0x70
[    7.899172] [<ffff0000080fcc40>] snapshot_write_next+0x22c/0x47c
[    7.905166] [<ffff0000080fe1b4>] load_image_lzo+0x754/0xa88
[    7.910725] [<ffff0000080ff0a8>] swsusp_read+0x144/0x230
[    7.916025] [<ffff0000080fa338>] load_image_and_restore+0x58/0x90
[    7.922105] [<ffff0000080fa660>] software_resume+0x2f0/0x338
[    7.927752] [<ffff000008083350>] do_one_initcall+0x38/0x11c
[    7.933314] [<ffff000008b40cc0>] kernel_init_freeable+0x14c/0x1ec
[    7.939395] [<ffff0000087ce564>] kernel_init+0x10/0xfc
[    7.944520] [<ffff000008082e90>] ret_from_fork+0x10/0x40
[    7.949820] Code: d2800022 8b400c21 f9800031 9ac32043 (c85f7c22)
[    7.955909] ---[ end trace 0024a5986e6ff323 ]---
[    7.960529] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b

Here struct mem_zone_bm_rtree's start_pfn has been returned instead of struct rtree_node's addr as the node/zone pointers are corrupt after we walked off the end of the lists during mark_unsafe_pages().

This behaviour was exposed by commit 6dbecfd345a6 ("PM / hibernate:
Simplify mark_unsafe_pages()"), which caused mark_unsafe_pages() to call duplicate_memory_bitmap(), which uses memory_bm_find_bit() after walking off the end of the memory bitmap.

Fixes 3a20cb177961 (PM / Hibernate: Implement position keeping in radix tree)
[ rjw: Subject ]
---
 kernel/power/snapshot.c |   10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
kernel/power/snapshot.c +5 -5
@@ -765,9 +765,9 @@ static bool memory_bm_pfn_present(struct
  */
 static bool rtree_next_node(struct memory_bitmap *bm)
 {
-	bm->cur.node = list_entry(bm->cur.node->list.next,
-				  struct rtree_node, list);
-	if (&bm->cur.node->list != &bm->cur.zone->leaves) {
+	if (!list_is_last(&bm->cur.node->list, &bm->cur.zone->leaves)) {
+		bm->cur.node = list_entry(bm->cur.node->list.next,
+					  struct rtree_node, list);
 		bm->cur.node_pfn += BM_BITS_PER_BLOCK;
 		bm->cur.node_bit  = 0;
 		touch_softlockup_watchdog();
@@ -775,9 +775,9 @@ static bool rtree_next_node(struct memor
 	}
 
 	/* No more nodes, goto next zone */
-	bm->cur.zone = list_entry(bm->cur.zone->list.next,
+	if (!list_is_last(&bm->cur.zone->list, &bm->zones)) {
+		bm->cur.zone = list_entry(bm->cur.zone->list.next,
 				  struct mem_zone_bm_rtree, list);
-	if (&bm->cur.zone->list != &bm->zones) {
 		bm->cur.node = list_entry(bm->cur.zone->leaves.next,
 					  struct rtree_node, list);
 		bm->cur.node_pfn = 0;
author maintainer
#63 lore raw

PATCH 71/73 power: supply: max17042_battery: fix model download bug.

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Sven Van Asbroeck <[email protected]>

commit 5381cfb6f0422da24cfa9da35b0433c0415830e0 upstream.

The device's model download function returns the model data as an array of u32s, which is later compared to the reference model data. However, since the latter is an array of u16s, the comparison does not happen correctly, and model verification fails. This in turn breaks the POR initialization sequence.

Fixes 39e7213edc4f3 ("max17042_battery: Support regmap to access device's registers")
---
 drivers/power/max17042_battery.c |   15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)
drivers/power/max17042_battery.c +9 -6
@@ -457,13 +457,16 @@ static inline void max17042_write_model_
 }
 
 static inline void max17042_read_model_data(struct max17042_chip *chip,
-					u8 addr, u32 *data, int size)
+					u8 addr, u16 *data, int size)
 {
 	struct regmap *map = chip->regmap;
 	int i;
+	u32 tmp;
 
-	for (i = 0; i < size; i++)
-		regmap_read(map, addr + i, &data[i]);
+	for (i = 0; i < size; i++) {
+		regmap_read(map, addr + i, &tmp);
+		data[i] = (u16)tmp;
+	}
 }
 
 static inline int max17042_model_data_compare(struct max17042_chip *chip,
@@ -486,7 +489,7 @@ static int max17042_init_model(struct ma
 {
 	int ret;
 	int table_size = ARRAY_SIZE(chip->pdata->config_data->cell_char_tbl);
-	u32 *temp_data;
+	u16 *temp_data;
 
 	temp_data = kcalloc(table_size, sizeof(*temp_data), GFP_KERNEL);
 	if (!temp_data)
@@ -501,7 +504,7 @@ static int max17042_init_model(struct ma
 	ret = max17042_model_data_compare(
 		chip,
 		chip->pdata->config_data->cell_char_tbl,
-		(u16 *)temp_data,
+		temp_data,
 		table_size);
 
 	max10742_lock_model(chip);
@@ -514,7 +517,7 @@ static int max17042_verify_model_lock(st
 {
 	int i;
 	int table_size = ARRAY_SIZE(chip->pdata->config_data->cell_char_tbl);
-	u32 *temp_data;
+	u16 *temp_data;
 	int ret = 0;
 
 	temp_data = kcalloc(table_size, sizeof(*temp_data), GFP_KERNEL);
author maintainer
#64 lore raw

PATCH 72/73 qxl: check for kmap failures

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Dan Carpenter <[email protected]>

commit f4cceb2affcd1285d4ce498089e8a79f4cd2fa66 upstream.

If kmap fails, it leads to memory corruption.

---
 drivers/gpu/drm/qxl/qxl_draw.c |    2 ++
 1 file changed, 2 insertions(+)
drivers/gpu/drm/qxl/qxl_draw.c +2 -0
@@ -136,6 +136,8 @@ static int qxl_palette_create_1bit(struc
 				 * correctly globaly, since that would require
 				 * tracking all of our palettes. */
 	ret = qxl_bo_kmap(palette_bo, (void **)&pal);
+	if (ret)
+		return ret;
 	pal->num_ents = 2;
 	pal->unique = unique++;
 	if (visual == FB_VISUAL_TRUECOLOR || visual == FB_VISUAL_DIRECTCOLOR) {

Greg Kroah-Hartman

author maintainer
#0 lore raw

cover 4.4.23-stable review

This is the start of the stable review cycle for the 4.4.23 release. There are 73 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.

Responses should be made by Fri Sep 30 09:04:22 UTC 2016. Anything received after that time might be too late.

The whole patch series can be found in one patch at:

	kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.4.23-rc1.gz

or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.4.y
and the diffstat can be found below.

thanks,

greg k-h

-------------
Pseudo-Shortlog of commits:

Greg Kroah-Hartman <[email protected]>

    Linux 4.4.23-rc1

Dan Carpenter <[email protected]>
hostfs: Freeing an ERR_PTR in hostfs_fill_sb_common()

Dan Carpenter <[email protected]>
qxl: check for kmap failures

Sven Van Asbroeck <[email protected]>
power: supply: max17042_battery: fix model download bug.

Wei Yongjun <[email protected]>
power_supply: tps65217-charger: fix missing platform_set_drvdata()

James Morse <[email protected]>
PM / hibernate: Fix rtree_next_node() to avoid walking off list ends

Thomas Garnier <[email protected]>
PM / hibernate: Restore processor state before using per-CPU variables

Matt Redfearn <[email protected]>
MIPS: paravirt: Fix undefined reference to smp_bootstrap

Huacai Chen <[email protected]>
MIPS: Add a missing ".set pop" in an early commit

Marcin Nowakowski <[email protected]>
MIPS: Avoid a BUG warning during prctl(PR_SET_FP_MODE, ...)

Paul Burton <[email protected]>
MIPS: Remove compact branch policy Kconfig entries

James Hogan <[email protected]>
MIPS: vDSO: Fix Malta EVA mapping to vDSO page structs

Matt Redfearn <[email protected]>
MIPS: SMP: Fix possibility of deadlock when bringing CPUs online

Paul Burton <[email protected]>
MIPS: Fix pre-r6 emulation FPU initialisation

Sudeep Holla <[email protected]>
i2c: qup: skip qup_i2c_suspend if the device is already runtime suspended

Yadi.hu <[email protected]>
i2c-eg20t: fix race between i2c init and interrupt enable

Jeff Mahoney <[email protected]>
btrfs: ensure that file descriptor used with subvol ioctls is a dir

Johannes Berg <[email protected]>
nl80211: validate number of probe response CSA counters

Fabio Estevam <[email protected]>
can: flexcan: fix resume function

Hugh Dickins <[email protected]>
mm: delete unnecessary and unsafe init_tlb_ubc()

Steven Rostedt (Red Hat) <[email protected]>
tracing: Move mutex to protect against resetting of seq data

Al Viro <[email protected]>
fix memory leaks in tracing_buffers_splice_read()

Arvind Yadav <[email protected]>
power: reset: hisi-reboot: Unmap region obtained by of_iomap

Dan Carpenter <[email protected]>
mtd: pmcmsp-flash: Allocating too much in init_msp_flash()

Dan Carpenter <[email protected]>
mtd: maps: sa1100-flash: potential NULL dereference

Al Viro <[email protected]>
fix fault_in_multipages_...() on architectures with no-op access_ok()

Jan Kara <[email protected]>
fanotify: fix list corruption in fanotify_get_response()

Jan Kara <[email protected]>
fsnotify: add a way to stop queueing events on group shutdown

Brian Foster <[email protected]>
xfs: prevent dropping ioend completions during buftarg wait

Ian Kent <[email protected]>
autofs: use dentry flags to block walks during expire

Al Viro <[email protected]>
autofs races

Thierry Reding <[email protected]>
pwm: Mark all devices as "might sleep"

Davide Caratti <[email protected]>
bridge: re-introduce 'fix parsing of MLDv2 reports'

Russell King <[email protected]>
net: smc91x: fix SMC accesses

Xander Huff <[email protected]>
Revert "phy: IRQ cannot be shared"

Florian Fainelli <[email protected]>
net: dsa: bcm_sf2: Fix race condition while unmasking interrupts

Paul Blakey <[email protected]>
net/mlx5: Added missing check of msg length in verifying its signature

Vegard Nossum <[email protected]>
tipc: fix NULL pointer dereference in shutdown()

Vegard Nossum <[email protected]>
net/irda: handle iriap_register_lsap() allocation failure

Lance Richardson <[email protected]>
vti: flush x-netns xfrm cache when vti interface is removed

Linus Torvalds <[email protected]>

    af_unix: split 'u->readlock' into two: 'iolock' and 'bindlock'

Linus Torvalds <[email protected]>
Revert "af_unix: Fix splice-bind deadlock"

Mahesh Bandewar <[email protected]>
bonding: Fix bonding crash

Maurizio Lombardi <[email protected]>
megaraid: fix null pointer check in megasas_detach_one().

Arnd Bergmann <[email protected]>
nouveau: fix nv40_perfctr_next() cleanup regression

Colin Ian King <[email protected]>
Staging: iio: adc: fix indent on break statement

Arnd Bergmann <[email protected]>
iwlegacy: avoid warning about missing braces

Arnd Bergmann <[email protected]>
ath9k: fix misleading indentation

Arnd Bergmann <[email protected]>
am437x-vfpe: fix typo in vpfe_get_app_input_index

Linus Torvalds <[email protected]>
Add braces to avoid "ambiguous ‘else’" compiler warnings

Arnd Bergmann <[email protected]>
net: caif: fix misleading indentation

Steven Rostedt <[email protected]>
Makefile: Mute warning for __builtin_return_address(>0) for tracing only

Linus Torvalds <[email protected]>
Disable "frame-address" warning

Linus Torvalds <[email protected]>
Disable "maybe-uninitialized" warning globally

Arnd Bergmann <[email protected]>
gcov: disable -Wmaybe-uninitialized warning

Arnd Bergmann <[email protected]>
Kbuild: disable 'maybe-uninitialized' warning for CONFIG_PROFILE_ALL_BRANCHES

Robert Jarzmik <[email protected]>
kbuild: forbid kernel directory to contain spaces and colons

Josh Poimboeuf <[email protected]>
tools: Support relative directory path for 'O='

Wang YanQing <[email protected]>
Makefile: revert "Makefile: Document ability to make file.lst and file.S" partially

Michal Marek <[email protected]>
kbuild: Do not run modules_install and install in paralel

Ashish Samant <[email protected]>
ocfs2: fix start offset to ocfs2_zero_range_for_truncate()

Joseph Qi <[email protected]>
ocfs2/dlm: fix race between convert and migration

Herbert Xu <[email protected]>
crypto: echainiv - Replace chaining with multiplication

Herbert Xu <[email protected]>
crypto: skcipher - Fix blkcipher walk OOM crash

Ard Biesheuvel <[email protected]>
crypto: arm/aes-ctr - fix NULL dereference in tail processing

Ard Biesheuvel <[email protected]>
crypto: arm64/aes-ctr - fix NULL dereference in tail processing

Eric Dumazet <[email protected]>
tcp: properly scale window in tcp_v[46]_reqsk_send_ack()

Eric Dumazet <[email protected]>
tcp: fix use after free in tcp_xmit_retransmit_queue()

Artem Germanov <[email protected]>
tcp: cwnd does not increase in TCP YeAH

Dave Jones <[email protected]>
ipv6: release dst in ping_v6_sendmsg

David Forster <[email protected]>
ipv4: panic in leaf_walk_rcu due to stale node pointer

Jeff Mahoney <[email protected]>
reiserfs: fix "new_insert_key may be used uninitialized ..."

Arnd Bergmann <[email protected]>
Fix build warning in kernel/cpuset.c

Michal Nazarewicz <[email protected]>
include/linux/kernel.h: change abs() macro so it uses consistent return type

-------------

Diffstat:

 Makefile                                           |  27 +++--
 arch/arm/crypto/aes-ce-glue.c                      |   2 +-
 arch/arm/mach-pxa/idp.c                            |   3 +-
 arch/arm/mach-pxa/xcep.c                           |   3 +-
 arch/arm/mach-realview/core.c                      |   3 +-
 arch/arm/mach-sa1100/pleb.c                        |   2 +-
 arch/arm64/crypto/aes-glue.c                       |   2 +-
 arch/blackfin/mach-bf561/boards/cm_bf561.c         |   3 +-
 arch/blackfin/mach-bf561/boards/ezkit.c            |   3 +-
 arch/mips/Kconfig.debug                            |  36 -------
 arch/mips/Makefile                                 |   4 -
 arch/mips/include/asm/asmmacro.h                   |   1 +
 .../include/asm/mach-paravirt/kernel-entry-init.h  |   2 +
 arch/mips/kernel/mips-r2-to-r6-emul.c              |   2 +
 arch/mips/kernel/process.c                         |   8 +-
 arch/mips/kernel/smp.c                             |   7 +-
 arch/mips/kernel/vdso.c                            |   8 +-
 crypto/blkcipher.c                                 |   3 +-
 crypto/echainiv.c                                  | 115 +++++----------------
 drivers/gpu/drm/nouveau/nvkm/engine/pm/nv40.c      |   6 +-
 drivers/gpu/drm/qxl/qxl_draw.c                     |   2 +
 drivers/i2c/busses/i2c-eg20t.c                     |  18 ++--
 drivers/i2c/busses/i2c-qup.c                       |   3 +-
 drivers/iio/industrialio-core.c                    |   9 +-
 drivers/iommu/dmar.c                               |   3 +-
 drivers/iommu/intel-iommu.c                        |   3 +-
 drivers/media/platform/am437x/am437x-vpfe.c        |   2 +-
 drivers/mtd/maps/pmcmsp-flash.c                    |   6 +-
 drivers/mtd/maps/sa1100-flash.c                    |   4 +-
 drivers/net/bonding/bond_main.c                    |   7 +-
 drivers/net/can/flexcan.c                          |  13 ++-
 drivers/net/dsa/bcm_sf2.h                          |   2 +-
 drivers/net/ethernet/mellanox/mlx5/core/cmd.c      |  85 +++++++++------
 drivers/net/ethernet/smsc/smc91x.c                 |   7 ++
 drivers/net/ethernet/smsc/smc91x.h                 |  65 ++++++++----
 drivers/net/phy/phy.c                              |   6 +-
 drivers/net/wireless/ath/ath9k/init.c              |   4 +-
 drivers/net/wireless/iwlegacy/3945.c               |   3 +-
 drivers/net/wireless/iwlwifi/dvm/calib.c           |   2 +-
 drivers/power/max17042_battery.c                   |  15 +--
 drivers/power/reset/hisi-reboot.c                  |   5 +-
 drivers/power/tps65217_charger.c                   |   1 +
 drivers/pwm/core.c                                 |   2 +-
 drivers/scsi/megaraid/megaraid_sas_base.c          |  10 +-
 drivers/staging/iio/adc/ad7192.c                   |   2 +-
 fs/autofs4/autofs_i.h                              |   8 +-
 fs/autofs4/expire.c                                |  80 ++++++++------
 fs/autofs4/root.c                                  |   2 +-
 fs/btrfs/ioctl.c                                   |  12 +++
 fs/hostfs/hostfs_kern.c                            |   7 +-
 fs/notify/fanotify/fanotify.c                      |  13 +--
 fs/notify/fanotify/fanotify_user.c                 |  36 ++++---
 fs/notify/group.c                                  |  19 ++++
 fs/notify/notification.c                           |  23 ++---
 fs/ocfs2/dlm/dlmconvert.c                          |  12 +--
 fs/ocfs2/file.c                                    |  34 ++++--
 fs/reiserfs/ibalance.c                             |   3 +-
 fs/xfs/xfs_buf.c                                   |   2 +-
 include/linux/fsnotify_backend.h                   |   6 +-
 include/linux/kernel.h                             |  36 +++----
 include/linux/netdevice.h                          |   1 +
 include/linux/pagemap.h                            |  38 +++----
 include/linux/smc91x.h                             |  10 ++
 include/net/af_unix.h                              |   2 +-
 include/net/tcp.h                                  |   2 +
 kernel/cpuset.c                                    |   2 +-
 kernel/power/hibernate.c                           |   4 +-
 kernel/power/snapshot.c                            |  10 +-
 kernel/trace/Makefile                              |   4 +
 kernel/trace/trace.c                               |  29 +++---
 mm/vmscan.c                                        |  19 ----
 net/bridge/br_multicast.c                          |   2 +-
 net/caif/cfpkt_skbuff.c                            |   2 +-
 net/core/dev.c                                     |  16 +++
 net/ipv4/fib_trie.c                                |   8 +-
 net/ipv4/ip_vti.c                                  |  31 ++++++
 net/ipv4/tcp_ipv4.c                                |   8 +-
 net/ipv4/tcp_yeah.c                                |   2 +-
 net/ipv6/ping.c                                    |   9 +-
 net/ipv6/tcp_ipv6.c                                |   8 +-
 net/irda/iriap.c                                   |   8 +-
 net/tipc/socket.c                                  |   3 +-
 net/unix/af_unix.c                                 | 107 +++++++++----------
 net/wireless/nl80211.c                             |   2 +-
 84 files changed, 626 insertions(+), 513 deletions(-)
author maintainer
#1 lore raw

PATCH 1/73 include/linux/kernel.h: change abs() macro so it uses consistent return type

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Michal Nazarewicz <[email protected]>

commit 8f57e4d930d48217268315898212518d4d3e0773 upstream.

Rewrite abs() so that its return type does not depend on the architecture and no unexpected type conversion happen inside of it. The only conversion is from unsigned to signed type. char is left as a return type but treated as a signed type regradless of it's actual signedness.

With the old version, int arguments were promoted to long and depending on architecture a long argument might result in s64 or long return type (which may or may not be the same).

This came after some back and forth with Nicolas. The current macro has different return type (for the same input type) depending on architecture which might be midly iritating.

An alternative version would promote to int like so:

	#define abs(x)	__abs_choose_expr(x, long long,			\
			__abs_choose_expr(x, long,			\
			__builtin_choose_expr(				\
				sizeof(x) <= sizeof(int),		\
				({ int __x = (x); __x<0?-__x:__x; }),	\
				((void)0))))

I have no preference but imagine Linus might. :] Nicolas argument against is that promoting to int causes iconsistent behaviour:

	int main(void) {
		unsigned short a = 0, b = 1, c = a - b;
		unsigned short d = abs(a - b);
		unsigned short e = abs(c);
		printf("%u %u\n", d, e);  // prints: 1 65535
	}

Then again, no sane person expects consistent behaviour from C integer arithmetic. ;)

Note:

__builtin_types_compatible_p(unsigned char, char) is always false, and __builtin_types_compatible_p(signed char, char) is also always false.

---
 drivers/iio/industrialio-core.c          |    9 +++----
 drivers/net/wireless/iwlwifi/dvm/calib.c |    2 -
 include/linux/kernel.h                   |   36 +++++++++++++++----------------
 3 files changed, 23 insertions(+), 24 deletions(-)
drivers/iio/industrialio-core.c +4 -5
@@ -433,16 +433,15 @@ ssize_t iio_format_value(char *buf, unsi
 		scale_db = true;
 	case IIO_VAL_INT_PLUS_MICRO:
 		if (vals[1] < 0)
-			return sprintf(buf, "-%ld.%06u%s\n", abs(vals[0]),
-					-vals[1],
-				scale_db ? " dB" : "");
+			return sprintf(buf, "-%d.%06u%s\n", abs(vals[0]),
+				       -vals[1], scale_db ? " dB" : "");
 		else
 			return sprintf(buf, "%d.%06u%s\n", vals[0], vals[1],
 				scale_db ? " dB" : "");
 	case IIO_VAL_INT_PLUS_NANO:
 		if (vals[1] < 0)
-			return sprintf(buf, "-%ld.%09u\n", abs(vals[0]),
-					-vals[1]);
+			return sprintf(buf, "-%d.%09u\n", abs(vals[0]),
+				       -vals[1]);
 		else
 			return sprintf(buf, "%d.%09u\n", vals[0], vals[1]);
 	case IIO_VAL_FRACTIONAL:
drivers/net/wireless/iwlwifi/dvm/calib.c +1 -1
@@ -901,7 +901,7 @@ static void iwlagn_gain_computation(stru
 		/* bound gain by 2 bits value max, 3rd bit is sign */
 		data->delta_gain_code[i] =
 			min(abs(delta_g),
-			(long) CHAIN_NOISE_MAX_DELTA_GAIN_CODE);
+			(s32) CHAIN_NOISE_MAX_DELTA_GAIN_CODE);
 
 		if (delta_g < 0)
 			/*
include/linux/kernel.h +18 -18
@@ -202,26 +202,26 @@ extern int _cond_resched(void);
 
 /**
  * abs - return absolute value of an argument
- * @x: the value.  If it is unsigned type, it is converted to signed type first
- *   (s64, long or int depending on its size).
+ * @x: the value.  If it is unsigned type, it is converted to signed type first.
+ *     char is treated as if it was signed (regardless of whether it really is)
+ *     but the macro's return type is preserved as char.
  *
- * Return: an absolute value of x.  If x is 64-bit, macro's return type is s64,
- *   otherwise it is signed long.
+ * Return: an absolute value of x.
  */
-#define abs(x) __builtin_choose_expr(sizeof(x) == sizeof(s64), ({	\
-		s64 __x = (x);						\
-		(__x < 0) ? -__x : __x;					\
-	}), ({								\
-		long ret;						\
-		if (sizeof(x) == sizeof(long)) {			\
-			long __x = (x);					\
-			ret = (__x < 0) ? -__x : __x;			\
-		} else {						\
-			int __x = (x);					\
-			ret = (__x < 0) ? -__x : __x;			\
-		}							\
-		ret;							\
-	}))
+#define abs(x)	__abs_choose_expr(x, long long,				\
+		__abs_choose_expr(x, long,				\
+		__abs_choose_expr(x, int,				\
+		__abs_choose_expr(x, short,				\
+		__abs_choose_expr(x, char,				\
+		__builtin_choose_expr(					\
+			__builtin_types_compatible_p(typeof(x), char),	\
+			(char)({ signed char __x = (x); __x<0?-__x:__x; }), \
+			((void)0)))))))
+
+#define __abs_choose_expr(x, type, other) __builtin_choose_expr(	\
+	__builtin_types_compatible_p(typeof(x),   signed type) ||	\
+	__builtin_types_compatible_p(typeof(x), unsigned type),		\
+	({ signed type __x = (x); __x < 0 ? -__x : __x; }), other)
 
 /**
  * reciprocal_scale - "scale" a value into range [0, ep_ro)
author maintainer
#3 lore raw

PATCH 3/73 reiserfs: fix "new_insert_key may be used uninitialized ..."

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jeff Mahoney <[email protected]>

commit 0a11b9aae49adf1f952427ef1a1d9e793dd6ffb6 upstream.

new_insert_key only makes any sense when it's associated with a new_insert_ptr, which is initialized to NULL and changed to a buffer_head when we also initialize new_insert_key. We can key off of that to avoid the uninitialized warning.

---
 fs/reiserfs/ibalance.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
fs/reiserfs/ibalance.c +2 -1
@@ -1153,8 +1153,9 @@ int balance_internal(struct tree_balance
 				       insert_ptr);
 	}
 
-	memcpy(new_insert_key_addr, &new_insert_key, KEY_SIZE);
 	insert_ptr[0] = new_insert_ptr;
+	if (new_insert_ptr)
+		memcpy(new_insert_key_addr, &new_insert_key, KEY_SIZE);
 
 	return order;
 }
author maintainer
#7 lore raw

PATCH 12/73 crypto: echainiv - Replace chaining with multiplication

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Herbert Xu <[email protected]>

commit 53a5d5ddccf849dbc27a8c1bba0b43c3a45fb792 upstream.

The current implementation uses a global per-cpu array to store data which are used to derive the next IV. This is insecure as the attacker may change the stored data.

This patch removes all traces of chaining and replaces it with multiplication of the salt and the sequence number.

Fixes a10f554fa7e0 ("crypto: echainiv - Add encrypted chain IV...")
---
 crypto/echainiv.c |  115 +++++++++++-------------------------------------------
 1 file changed, 24 insertions(+), 91 deletions(-)
crypto/echainiv.c +24 -91
@@ -1,8 +1,8 @@
 /*
  * echainiv: Encrypted Chain IV Generator
  *
- * This generator generates an IV based on a sequence number by xoring it
- * with a salt and then encrypting it with the same key as used to encrypt
+ * This generator generates an IV based on a sequence number by multiplying
+ * it with a salt and then encrypting it with the same key as used to encrypt
  * the plain text.  This algorithm requires that the block size be equal
  * to the IV size.  It is mainly useful for CBC.
  *
@@ -23,81 +23,17 @@
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
-#include <linux/mm.h>
 #include <linux/module.h>
-#include <linux/percpu.h>
-#include <linux/spinlock.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 
-#define MAX_IV_SIZE 16
-
-static DEFINE_PER_CPU(u32 [MAX_IV_SIZE / sizeof(u32)], echainiv_iv);
-
-/* We don't care if we get preempted and read/write IVs from the next CPU. */
-static void echainiv_read_iv(u8 *dst, unsigned size)
-{
-	u32 *a = (u32 *)dst;
-	u32 __percpu *b = echainiv_iv;
-
-	for (; size >= 4; size -= 4) {
-		*a++ = this_cpu_read(*b);
-		b++;
-	}
-}
-
-static void echainiv_write_iv(const u8 *src, unsigned size)
-{
-	const u32 *a = (const u32 *)src;
-	u32 __percpu *b = echainiv_iv;
-
-	for (; size >= 4; size -= 4) {
-		this_cpu_write(*b, *a);
-		a++;
-		b++;
-	}
-}
-
-static void echainiv_encrypt_complete2(struct aead_request *req, int err)
-{
-	struct aead_request *subreq = aead_request_ctx(req);
-	struct crypto_aead *geniv;
-	unsigned int ivsize;
-
-	if (err == -EINPROGRESS)
-		return;
-
-	if (err)
-		goto out;
-
-	geniv = crypto_aead_reqtfm(req);
-	ivsize = crypto_aead_ivsize(geniv);
-
-	echainiv_write_iv(subreq->iv, ivsize);
-
-	if (req->iv != subreq->iv)
-		memcpy(req->iv, subreq->iv, ivsize);
-
-out:
-	if (req->iv != subreq->iv)
-		kzfree(subreq->iv);
-}
-
-static void echainiv_encrypt_complete(struct crypto_async_request *base,
-					 int err)
-{
-	struct aead_request *req = base->data;
-
-	echainiv_encrypt_complete2(req, err);
-	aead_request_complete(req, err);
-}
-
 static int echainiv_encrypt(struct aead_request *req)
 {
 	struct crypto_aead *geniv = crypto_aead_reqtfm(req);
 	struct aead_geniv_ctx *ctx = crypto_aead_ctx(geniv);
 	struct aead_request *subreq = aead_request_ctx(req);
-	crypto_completion_t compl;
-	void *data;
+	__be64 nseqno;
+	u64 seqno;
 	u8 *info;
 	unsigned int ivsize = crypto_aead_ivsize(geniv);
 	int err;
@@ -107,8 +43,6 @@ static int echainiv_encrypt(struct aead_
 
 	aead_request_set_tfm(subreq, ctx->child);
 
-	compl = echainiv_encrypt_complete;
-	data = req;
 	info = req->iv;
 
 	if (req->src != req->dst) {
@@ -123,29 +57,30 @@ static int echainiv_encrypt(struct aead_
 			return err;
 	}
 
-	if (unlikely(!IS_ALIGNED((unsigned long)info,
-				 crypto_aead_alignmask(geniv) + 1))) {
-		info = kmalloc(ivsize, req->base.flags &
-				       CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL:
-								  GFP_ATOMIC);
-		if (!info)
-			return -ENOMEM;
-
-		memcpy(info, req->iv, ivsize);
-	}
-
-	aead_request_set_callback(subreq, req->base.flags, compl, data);
+	aead_request_set_callback(subreq, req->base.flags,
+				  req->base.complete, req->base.data);
 	aead_request_set_crypt(subreq, req->dst, req->dst,
 			       req->cryptlen, info);
 	aead_request_set_ad(subreq, req->assoclen);
 
-	crypto_xor(info, ctx->salt, ivsize);
+	memcpy(&nseqno, info + ivsize - 8, 8);
+	seqno = be64_to_cpu(nseqno);
+	memset(info, 0, ivsize);
+
 	scatterwalk_map_and_copy(info, req->dst, req->assoclen, ivsize, 1);
-	echainiv_read_iv(info, ivsize);
 
-	err = crypto_aead_encrypt(subreq);
-	echainiv_encrypt_complete2(req, err);
-	return err;
+	do {
+		u64 a;
+
+		memcpy(&a, ctx->salt + ivsize - 8, 8);
+
+		a |= 1;
+		a *= seqno;
+
+		memcpy(info + ivsize - 8, &a, 8);
+	} while ((ivsize -= 8));
+
+	return crypto_aead_encrypt(subreq);
 }
 
 static int echainiv_decrypt(struct aead_request *req)
@@ -192,8 +127,7 @@ static int echainiv_aead_create(struct c
 	alg = crypto_spawn_aead_alg(spawn);
 
 	err = -EINVAL;
-	if (inst->alg.ivsize & (sizeof(u32) - 1) ||
-	    inst->alg.ivsize > MAX_IV_SIZE)
+	if (inst->alg.ivsize & (sizeof(u64) - 1) || !inst->alg.ivsize)
 		goto free_inst;
 
 	inst->alg.encrypt = echainiv_encrypt;
@@ -202,7 +136,6 @@ static int echainiv_aead_create(struct c
 	inst->alg.init = aead_init_geniv;
 	inst->alg.exit = aead_exit_geniv;
 
-	inst->alg.base.cra_alignmask |= __alignof__(u32) - 1;
 	inst->alg.base.cra_ctxsize = sizeof(struct aead_geniv_ctx);
 	inst->alg.base.cra_ctxsize += inst->alg.ivsize;
 
author maintainer
#9 lore raw

PATCH 14/73 ocfs2: fix start offset to ocfs2_zero_range_for_truncate()

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Ashish Samant <[email protected]>

commit d21c353d5e99c56cdd5b5c1183ffbcaf23b8b960 upstream.

If we punch a hole on a reflink such that following conditions are met:

1. start offset is on a cluster boundary
2. end offset is not on a cluster boundary
3. (end offset is somewhere in another extent) or
(hole range > MAX_CONTIG_BYTES(1MB)),

we dont COW the first cluster starting at the start offset. But in this case, we were wrongly passing this cluster to ocfs2_zero_range_for_truncate() to zero out. This will modify the cluster in place and zero it in the source too.

Fix this by skipping this cluster in such a scenario.

To reproduce:

1. Create a random file of say 10 MB

     xfs_io -c 'pwrite -b 4k 0 10M' -f 10MBfile

2. Reflink it
reflink -f 10MBfile reflnktest
3. Punch a hole at starting at cluster boundary with range greater that 1MB. You can also use a range that will put the end offset in another extent.

     fallocate -p -o 0 -l 1048615 reflnktest

4. sync
5. Check the first cluster in the source file. (It will be zeroed out). dd if=10MBfile iflag=direct bs=<cluster size> count=1 | hexdump -C

---
 fs/ocfs2/file.c |   38 ++++++++++++++++++++++++++------------
 1 file changed, 26 insertions(+), 12 deletions(-)
fs/ocfs2/file.c +26 -12
@@ -1536,7 +1536,8 @@ static int ocfs2_zero_partial_clusters(s
 				       u64 start, u64 len)
 {
 	int ret = 0;
-	u64 tmpend, end = start + len;
+	u64 tmpend = 0;
+	u64 end = start + len;
 	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
 	unsigned int csize = osb->s_clustersize;
 	handle_t *handle;
@@ -1568,18 +1569,31 @@ static int ocfs2_zero_partial_clusters(s
 	}
 
 	/*
-	 * We want to get the byte offset of the end of the 1st cluster.
+	 * If start is on a cluster boundary and end is somewhere in another
+	 * cluster, we have not COWed the cluster starting at start, unless
+	 * end is also within the same cluster. So, in this case, we skip this
+	 * first call to ocfs2_zero_range_for_truncate() truncate and move on
+	 * to the next one.
 	 */
-	tmpend = (u64)osb->s_clustersize + (start & ~(osb->s_clustersize - 1));
-	if (tmpend > end)
-		tmpend = end;
-
-	trace_ocfs2_zero_partial_clusters_range1((unsigned long long)start,
-						 (unsigned long long)tmpend);
-
-	ret = ocfs2_zero_range_for_truncate(inode, handle, start, tmpend);
-	if (ret)
-		mlog_errno(ret);
+	if ((start & (csize - 1)) != 0) {
+		/*
+		 * We want to get the byte offset of the end of the 1st
+		 * cluster.
+		 */
+		tmpend = (u64)osb->s_clustersize +
+			(start & ~(osb->s_clustersize - 1));
+		if (tmpend > end)
+			tmpend = end;
+
+		trace_ocfs2_zero_partial_clusters_range1(
+			(unsigned long long)start,
+			(unsigned long long)tmpend);
+
+		ret = ocfs2_zero_range_for_truncate(inode, handle, start,
+						    tmpend);
+		if (ret)
+			mlog_errno(ret);
+	}
 
 	if (tmpend < end) {
 		/*
author maintainer
#10 lore raw

PATCH 15/73 kbuild: Do not run modules_install and install in paralel

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Michal Marek <[email protected]>

commit a85a41ed69f27c4c667d8c418df14b4fb220c4ad upstream.

Based on a x86-only patch by Andy Lutomirski <[email protected]>

With modular kernels, 'make install' is going to need the installed modules at some point to generate the initramfs.

---
 Makefile |    6 ++++++
 1 file changed, 6 insertions(+)
Makefile +6 -0
@@ -495,6 +495,12 @@ ifeq ($(KBUILD_EXTMOD),)
                 endif
         endif
 endif
+# install and module_install need also be processed one by one
+ifneq ($(filter install,$(MAKECMDGOALS)),)
+        ifneq ($(filter modules_install,$(MAKECMDGOALS)),)
+	        mixed-targets := 1
+        endif
+endif
 
 ifeq ($(mixed-targets),1)
 # ===========================================================================
author maintainer
#11 lore raw

PATCH 16/73 Makefile: revert "Makefile: Document ability to make file.lst and file.S" partially

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Wang YanQing <[email protected]>

commit 40ab87a4003c7952976ce901a2b9ece5ed833168 upstream.

Commit 627189797807 ("Makefile: Document ability to make file.lst and file.S") document ability to make file.S, but there isn't such ability in kbuild, so revert it.

---
 Makefile |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
Makefile +1 -1
@@ -1266,7 +1266,7 @@ help:
 	@echo  '  firmware_install- Install all firmware to INSTALL_FW_PATH'
 	@echo  '                    (default: $$(INSTALL_MOD_PATH)/lib/firmware)'
 	@echo  '  dir/            - Build all files in dir and below'
-	@echo  '  dir/file.[oisS] - Build specified target only'
+	@echo  '  dir/file.[ois]  - Build specified target only'
 	@echo  '  dir/file.lst    - Build specified mixed source/assembly target only'
 	@echo  '                    (requires a recent binutils and recent build (System.map))'
 	@echo  '  dir/file.ko     - Build module including final link'
author maintainer
#12 lore raw

PATCH 17/73 tools: Support relative directory path for O=

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Josh Poimboeuf <[email protected]>

commit e17cf3a80d4ba0c4e40bf1a89deb1354c2e10e14 upstream.

Running "make O=foo" (with a relative directory path) fails with:

scripts/Makefile.include:3: *** O=foo does not exist. Stop. /home/jpoimboe/git/linux/Makefile:1547: recipe for target 'tools/objtool' failed

The tools Makefile gets confused by the relative path and tries to build objtool in tools/foo. Convert the output directory to an absolute path before passing it to the tools Makefile.

---
 Makefile |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
Makefile +2 -2
@@ -1506,11 +1506,11 @@ image_name:
 # Clear a bunch of variables before executing the submake
 tools/: FORCE
 	$(Q)mkdir -p $(objtree)/tools
-	$(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(filter --j% -j,$(MAKEFLAGS))" O=$(O) subdir=tools -C $(src)/tools/
+	$(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(filter --j% -j,$(MAKEFLAGS))" O=$(shell cd $(objtree) && /bin/pwd) subdir=tools -C $(src)/tools/
 
 tools/%: FORCE
 	$(Q)mkdir -p $(objtree)/tools
-	$(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(filter --j% -j,$(MAKEFLAGS))" O=$(O) subdir=tools -C $(src)/tools/ $*
+	$(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(filter --j% -j,$(MAKEFLAGS))" O=$(shell cd $(objtree) && /bin/pwd) subdir=tools -C $(src)/tools/ $*
 
 # Single targets
 # ---------------------------------------------------------------------------
author maintainer
#13 lore raw

PATCH 18/73 kbuild: forbid kernel directory to contain spaces and colons

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Robert Jarzmik <[email protected]>

commit 51193b76bfff5027cf96ba63effae808ad67cca7 upstream.

When the kernel path contains a space or a colon somewhere in the path name, the modules_install target doesn't work anymore, as the path names are not enclosed in double quotes. It is also supposed that and O= build will suffer from the same weakness as modules_install.

Instead of checking and improving kbuild to resist to directories including these characters, error out early to prevent any build if the kernel's main directory contains a space.

---
 Makefile |    4 ++++
 1 file changed, 4 insertions(+)
Makefile +4 -0
@@ -128,6 +128,10 @@ _all:
 # Cancel implicit rules on top Makefile
 $(CURDIR)/Makefile Makefile: ;
 
+ifneq ($(words $(subst :, ,$(CURDIR))), 1)
+  $(error main directory cannot contain spaces nor colons)
+endif
+
 ifneq ($(KBUILD_OUTPUT),)
 # Invoke a second make in the output directory, passing relevant variables
 # check that the output directory actually exists
author maintainer
#4 lore raw

PATCH 9/73 crypto: arm64/aes-ctr - fix NULL dereference in tail processing

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Ard Biesheuvel <[email protected]>

commit 2db34e78f126c6001d79d3b66ab1abb482dc7caa upstream.

The AES-CTR glue code avoids calling into the blkcipher API for the tail portion of the walk, by comparing the remainder of walk.nbytes modulo AES_BLOCK_SIZE with the residual nbytes, and jumping straight into the tail processing block if they are equal. This tail processing block checks whether nbytes != 0, and does nothing otherwise.

However, in case of an allocation failure in the blkcipher layer, we may enter this code with walk.nbytes == 0, while nbytes > 0. In this case, we should not dereference the source and destination pointers, since they may be NULL. So instead of checking for nbytes != 0, check for (walk.nbytes % AES_BLOCK_SIZE) != 0, which implies the former in non-error conditions.

Fixes 49788fe2a128 ("arm64/crypto: AES-ECB/CBC/CTR/XTS using ARMv8 NEON and Crypto Extensions")
---
 arch/arm64/crypto/aes-glue.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/crypto/aes-glue.c +1 -1
@@ -211,7 +211,7 @@ static int ctr_encrypt(struct blkcipher_
 		err = blkcipher_walk_done(desc, &walk,
 					  walk.nbytes % AES_BLOCK_SIZE);
 	}
-	if (nbytes) {
+	if (walk.nbytes % AES_BLOCK_SIZE) {
 		u8 *tdst = walk.dst.virt.addr + blocks * AES_BLOCK_SIZE;
 		u8 *tsrc = walk.src.virt.addr + blocks * AES_BLOCK_SIZE;
 		u8 __aligned(8) tail[AES_BLOCK_SIZE];
author maintainer
#2 lore raw

PATCH 2/73 Fix build warning in kernel/cpuset.c

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Arnd Bergmann <[email protected]>

Quoted 3 lines

2 ../kernel/cpuset.c:2101:11: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types] 1 ../kernel/cpuset.c:2101:2: warning: initialization from incompatible pointer type
1 ../kernel/cpuset.c:2101:2: warning: (near initialization for 'cpuset_cgrp_subsys.fork')

This got introduced by 06ec7a1d7646 ("cpuset: make sure new tasks conform to the current config of the cpuset"). In the upstream kernel, the function prototype was changed as of b53202e63089 ("cgroup: kill cgrp_ss_priv[CGROUP_CANFORK_COUNT] and friends").

That patch is not suitable for stable kernels, and fortunately the warning seems harmless as the prototypes only differ in the second argument that is unused. Adding that argument gets rid of the warning:

---
 kernel/cpuset.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/cpuset.c +1 -1
@@ -2079,7 +2079,7 @@ static void cpuset_bind(struct cgroup_su
  * which could have been changed by cpuset just after it inherits the
  * state from the parent and before it sits on the cgroup's task list.
  */
-void cpuset_fork(struct task_struct *task)
+void cpuset_fork(struct task_struct *task, void *priv)
 {
 	if (task_css_is_root(task, cpuset_cgrp_id))
 		return;
author maintainer
#5 lore raw

PATCH 10/73 crypto: arm/aes-ctr - fix NULL dereference in tail processing

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Ard Biesheuvel <[email protected]>

commit f82e90b28654804ab72881d577d87c3d5c65e2bc upstream.

The AES-CTR glue code avoids calling into the blkcipher API for the tail portion of the walk, by comparing the remainder of walk.nbytes modulo AES_BLOCK_SIZE with the residual nbytes, and jumping straight into the tail processing block if they are equal. This tail processing block checks whether nbytes != 0, and does nothing otherwise.

However, in case of an allocation failure in the blkcipher layer, we may enter this code with walk.nbytes == 0, while nbytes > 0. In this case, we should not dereference the source and destination pointers, since they may be NULL. So instead of checking for nbytes != 0, check for (walk.nbytes % AES_BLOCK_SIZE) != 0, which implies the former in non-error conditions.

Fixes 86464859cc77 ("crypto: arm - AES in ECB/CBC/CTR/XTS modes using ARMv8 Crypto Extensions")
---
 arch/arm/crypto/aes-ce-glue.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/crypto/aes-ce-glue.c +1 -1
@@ -279,7 +279,7 @@ static int ctr_encrypt(struct blkcipher_
 		err = blkcipher_walk_done(desc, &walk,
 					  walk.nbytes % AES_BLOCK_SIZE);
 	}
-	if (nbytes) {
+	if (walk.nbytes % AES_BLOCK_SIZE) {
 		u8 *tdst = walk.dst.virt.addr + blocks * AES_BLOCK_SIZE;
 		u8 *tsrc = walk.src.virt.addr + blocks * AES_BLOCK_SIZE;
 		u8 __aligned(8) tail[AES_BLOCK_SIZE];
author maintainer
#15 lore raw

PATCH 20/73 gcov: disable -Wmaybe-uninitialized warning

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Arnd Bergmann <[email protected]>

commit e72e2dfe7c16ffbfbabf9cb24adc6d9f93a4fe37 upstream.

When gcov profiling is enabled, we see a lot of spurious warnings about possibly uninitialized variables being used:

arch/arm/mm/dma-mapping.c: In function 'arm_coherent_iommu_map_page':
arch/arm/mm/dma-mapping.c:1085:16: warning: 'start' may be used uninitialized in this function [-Wmaybe-uninitialized] drivers/clk/st/clk-flexgen.c: In function 'st_of_flexgen_setup':
drivers/clk/st/clk-flexgen.c:323:9: warning: 'num_parents' may be used uninitialized in this function [-Wmaybe-uninitialized] kernel/cgroup.c: In function 'cgroup_mount':
kernel/cgroup.c:2119:11: warning: 'root' may be used uninitialized in this function [-Wmaybe-uninitialized]

All of these are false positives, so it seems better to just disable the warnings whenever GCOV is enabled. Most users don't enable GCOV, and based on a prior patch, it is now also disabled for 'allmodconfig' builds, so there should be no downsides of doing this.

---
 Makefile |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
Makefile +1 -1
@@ -368,7 +368,7 @@ AFLAGS_MODULE   =
 LDFLAGS_MODULE  =
 CFLAGS_KERNEL	=
 AFLAGS_KERNEL	=
-CFLAGS_GCOV	= -fprofile-arcs -ftest-coverage -fno-tree-loop-im
+CFLAGS_GCOV	= -fprofile-arcs -ftest-coverage -fno-tree-loop-im -Wno-maybe-uninitialized
 
 
 # Use USERINCLUDE when you must reference the UAPI directories only.
author maintainer
#22 lore raw

PATCH 29/73 Staging: iio: adc: fix indent on break statement

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Colin Ian King <[email protected]>

commit b6acb0cfc21293a1bfc283e9217f58f7474ef728 upstream.

Fix indent warning when building with gcc 6:
drivers/staging/iio/adc/ad7192.c:239:4: warning: statement is indented
as if it were guarded by... [-Wmisleading-indentation]

---
 drivers/staging/iio/adc/ad7192.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/staging/iio/adc/ad7192.c +1 -1
@@ -236,7 +236,7 @@ static int ad7192_setup(struct ad7192_st
 			st->mclk = pdata->ext_clk_hz;
 		else
 			st->mclk = AD7192_INT_FREQ_MHZ;
-			break;
+		break;
 	default:
 		ret = -EINVAL;
 		goto out;
author maintainer
#26 lore raw

PATCH 33/73 Revert "af_unix: Fix splice-bind deadlock"

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Linus Torvalds <[email protected]>

commit 38f7bd94a97b542de86a2be9229289717e33a7a4 upstream.

This reverts commit c845acb324aa85a39650a14e7696982ceea75dc1.

It turns out that it just replaces one deadlock with another one: we can still get the wrong lock ordering with the readlock due to overlayfs calling back into the filesystem layer and still taking the vfs locks after the readlock.

The proper solution ends up being to just split the readlock into two
pieces: the bind lock (taken *outside* the vfs locks) and the IO lock (taken *inside* the filesystem locks). The two locks are independent anyway.

---
 net/unix/af_unix.c |   68 +++++++++++++++++++++--------------------------------
 1 file changed, 27 insertions(+), 41 deletions(-)
net/unix/af_unix.c +27 -41
@@ -953,20 +953,32 @@ fail:
 	return NULL;
 }
 
-static int unix_mknod(struct dentry *dentry, struct path *path, umode_t mode,
-		      struct path *res)
+static int unix_mknod(const char *sun_path, umode_t mode, struct path *res)
 {
-	int err;
-
-	err = security_path_mknod(path, dentry, mode, 0);
+	struct dentry *dentry;
+	struct path path;
+	int err = 0;
+	/*
+	 * Get the parent directory, calculate the hash for last
+	 * component.
+	 */
+	dentry = kern_path_create(AT_FDCWD, sun_path, &path, 0);
+	err = PTR_ERR(dentry);
+	if (IS_ERR(dentry))
+		return err;
+
+	/*
+	 * All right, let's create it.
+	 */
+	err = security_path_mknod(&path, dentry, mode, 0);
 	if (!err) {
-		err = vfs_mknod(d_inode(path->dentry), dentry, mode, 0);
+		err = vfs_mknod(d_inode(path.dentry), dentry, mode, 0);
 		if (!err) {
-			res->mnt = mntget(path->mnt);
+			res->mnt = mntget(path.mnt);
 			res->dentry = dget(dentry);
 		}
 	}
-
+	done_path_create(&path, dentry);
 	return err;
 }
 
@@ -977,12 +989,10 @@ static int unix_bind(struct socket *sock
 	struct unix_sock *u = unix_sk(sk);
 	struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr;
 	char *sun_path = sunaddr->sun_path;
-	int err, name_err;
+	int err;
 	unsigned int hash;
 	struct unix_address *addr;
 	struct hlist_head *list;
-	struct path path;
-	struct dentry *dentry;
 
 	err = -EINVAL;
 	if (sunaddr->sun_family != AF_UNIX)
@@ -998,34 +1008,14 @@ static int unix_bind(struct socket *sock
 		goto out;
 	addr_len = err;
 
-	name_err = 0;
-	dentry = NULL;
-	if (sun_path[0]) {
-		/* Get the parent directory, calculate the hash for last
-		 * component.
-		 */
-		dentry = kern_path_create(AT_FDCWD, sun_path, &path, 0);
-
-		if (IS_ERR(dentry)) {
-			/* delay report until after 'already bound' check */
-			name_err = PTR_ERR(dentry);
-			dentry = NULL;
-		}
-	}
-
 	err = mutex_lock_interruptible(&u->readlock);
 	if (err)
-		goto out_path;
+		goto out;
 
 	err = -EINVAL;
 	if (u->addr)
 		goto out_up;
 
-	if (name_err) {
-		err = name_err == -EEXIST ? -EADDRINUSE : name_err;
-		goto out_up;
-	}
-
 	err = -ENOMEM;
 	addr = kmalloc(sizeof(*addr)+addr_len, GFP_KERNEL);
 	if (!addr)
@@ -1036,11 +1026,11 @@ static int unix_bind(struct socket *sock
 	addr->hash = hash ^ sk->sk_type;
 	atomic_set(&addr->refcnt, 1);
 
-	if (dentry) {
-		struct path u_path;
+	if (sun_path[0]) {
+		struct path path;
 		umode_t mode = S_IFSOCK |
 		       (SOCK_INODE(sock)->i_mode & ~current_umask());
-		err = unix_mknod(dentry, &path, mode, &u_path);
+		err = unix_mknod(sun_path, mode, &path);
 		if (err) {
 			if (err == -EEXIST)
 				err = -EADDRINUSE;
@@ -1048,9 +1038,9 @@ static int unix_bind(struct socket *sock
 			goto out_up;
 		}
 		addr->hash = UNIX_HASH_SIZE;
-		hash = d_real_inode(dentry)->i_ino & (UNIX_HASH_SIZE - 1);
+		hash = d_real_inode(path.dentry)->i_ino & (UNIX_HASH_SIZE - 1);
 		spin_lock(&unix_table_lock);
-		u->path = u_path;
+		u->path = path;
 		list = &unix_socket_table[hash];
 	} else {
 		spin_lock(&unix_table_lock);
@@ -1073,10 +1063,6 @@ out_unlock:
 	spin_unlock(&unix_table_lock);
 out_up:
 	mutex_unlock(&u->readlock);
-out_path:
-	if (dentry)
-		done_path_create(&path, dentry);
-
 out:
 	return err;
 }
author maintainer
#27 lore raw

PATCH 34/73 af_unix: split u->readlock into two: iolock and bindlock

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Linus Torvalds <[email protected]>

commit 6e1ce3c3451291142a57c4f3f6f999a29fb5b3bc upstream.

Right now we use the 'readlock' both for protecting some of the af_unix IO path and for making the bind be single-threaded.

The two are independent, but using the same lock makes for a nasty deadlock due to ordering with regards to filesystem locking. The bind locking would want to nest outside the VSF pathname locking, but the IO locking wants to nest inside some of those same locks.

We tried to fix this earlier with commit c845acb324aa ("af_unix: Fix splice-bind deadlock") which moved the readlock inside the vfs locks, but that caused problems with overlayfs that will then call back into filesystem routines that take the lock in the wrong order anyway.

Splitting the locks means that we can go back to having the bind lock be the outermost lock, and we don't have any deadlocks with lock ordering.

---
 include/net/af_unix.h |    2 +-
 net/unix/af_unix.c    |   41 +++++++++++++++++++++--------------------
 2 files changed, 22 insertions(+), 21 deletions(-)
include/net/af_unix.h +1 -1
@@ -52,7 +52,7 @@ struct unix_sock {
 	struct sock		sk;
 	struct unix_address     *addr;
 	struct path		path;
-	struct mutex		readlock;
+	struct mutex		iolock, bindlock;
 	struct sock		*peer;
 	struct list_head	link;
 	atomic_long_t		inflight;
net/unix/af_unix.c +21 -20

149 lines not on this page · raw message

author maintainer
#28 lore raw

PATCH 35/73 vti: flush x-netns xfrm cache when vti interface is removed

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Lance Richardson <[email protected]>

[ Upstream commit a5d0dc810abf3d6b241777467ee1d6efb02575fc ]

When executing the script included below, the netns delete operation hangs with the following message (repeated at 10 second intervals):

kernel:unregister_netdevice: waiting for lo to become free. Usage count = 1

This occurs because a reference to the lo interface in the "secure" netns is still held by a dst entry in the xfrm bundle cache in the init netns.

Address this problem by garbage collecting the tunnel netns flow cache when a cross-namespace vti interface receives a NETDEV_DOWN notification.

A more detailed description of the problem scenario (referencing commands in the script below):

(1) ip link add vti_test type vti local 1.1.1.1 remote 1.1.1.2 key 1

The vti_test interface is created in the init namespace. vti_tunnel_init() attaches a struct ip_tunnel to the vti interface's netdev_priv(dev), setting the tunnel net to &init_net.

(2) ip link set vti_test netns secure

The vti_test interface is moved to the "secure" netns. Note that the associated struct ip_tunnel still has tunnel->net set to &init_net.

(3) ip netns exec secure ping -c 4 -i 0.02 -I 192.168.100.1 192.168.200.1

The first packet sent using the vti device causes xfrm_lookup() to be called as follows:

      dst = xfrm_lookup(tunnel->net, skb_dst(skb), fl, NULL, 0);

Note that tunnel->net is the init namespace, while skb_dst(skb) references the vti_test interface in the "secure" namespace. The returned dst references an interface in the init namespace.

Also note that the first parameter to xfrm_lookup() determines which flow cache is used to store the computed xfrm bundle, so after xfrm_lookup() returns there will be a cached bundle in the init namespace flow cache with a dst referencing a device in the "secure" namespace.

(4) ip netns del secure

Kernel begins to delete the "secure" namespace. At some point the vti_test interface is deleted, at which point dst_ifdown() changes the dst->dev in the cached xfrm bundle flow from vti_test to lo (still in the "secure" namespace however).
Since nothing has happened to cause the init namespace's flow cache to be garbage collected, this dst remains attached to the flow cache, so the kernel loops waiting for the last reference to lo to go away.

<Begin script>
ip link add br1 type bridge
ip link set dev br1 up
ip addr add dev br1 1.1.1.1/8

ip netns add secure
ip link add vti_test type vti local 1.1.1.1 remote 1.1.1.2 key 1 ip link set vti_test netns secure
ip netns exec secure ip link set vti_test up
ip netns exec secure ip link s lo up
ip netns exec secure ip addr add dev lo 192.168.100.1/24
ip netns exec secure ip route add 192.168.200.0/24 dev vti_test ip xfrm policy flush
ip xfrm state flush
ip xfrm policy add dir out tmpl src 1.1.1.1 dst 1.1.1.2 \
proto esp mode tunnel mark 1
ip xfrm policy add dir in tmpl src 1.1.1.2 dst 1.1.1.1 \
proto esp mode tunnel mark 1
ip xfrm state add src 1.1.1.1 dst 1.1.1.2 proto esp spi 1 \
mode tunnel enc des3_ede 0x112233445566778811223344556677881122334455667788
ip xfrm state add src 1.1.1.2 dst 1.1.1.1 proto esp spi 1 \
mode tunnel enc des3_ede 0x112233445566778811223344556677881122334455667788

ip netns exec secure ping -c 4 -i 0.02 -I 192.168.100.1 192.168.200.1

ip netns del secure
<End script>

---
 net/ipv4/ip_vti.c |   31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)
net/ipv4/ip_vti.c +31 -0
@@ -540,6 +540,33 @@ static struct rtnl_link_ops vti_link_ops
 	.get_link_net	= ip_tunnel_get_link_net,
 };
 
+static bool is_vti_tunnel(const struct net_device *dev)
+{
+	return dev->netdev_ops == &vti_netdev_ops;
+}
+
+static int vti_device_event(struct notifier_block *unused,
+			    unsigned long event, void *ptr)
+{
+	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
+	struct ip_tunnel *tunnel = netdev_priv(dev);
+
+	if (!is_vti_tunnel(dev))
+		return NOTIFY_DONE;
+
+	switch (event) {
+	case NETDEV_DOWN:
+		if (!net_eq(tunnel->net, dev_net(dev)))
+			xfrm_garbage_collect(tunnel->net);
+		break;
+	}
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block vti_notifier_block __read_mostly = {
+	.notifier_call = vti_device_event,
+};
+
 static int __init vti_init(void)
 {
 	const char *msg;
@@ -547,6 +574,8 @@ static int __init vti_init(void)
 
 	pr_info("IPv4 over IPsec tunneling driver\n");
 
+	register_netdevice_notifier(&vti_notifier_block);
+
 	msg = "tunnel device";
 	err = register_pernet_device(&vti_net_ops);
 	if (err < 0)
@@ -579,6 +608,7 @@ xfrm_proto_ah_failed:
 xfrm_proto_esp_failed:
 	unregister_pernet_device(&vti_net_ops);
 pernet_dev_failed:
+	unregister_netdevice_notifier(&vti_notifier_block);
 	pr_err("vti init: failed to register %s\n", msg);
 	return err;
 }
@@ -590,6 +620,7 @@ static void __exit vti_fini(void)
 	xfrm4_protocol_deregister(&vti_ah4_protocol, IPPROTO_AH);
 	xfrm4_protocol_deregister(&vti_esp4_protocol, IPPROTO_ESP);
 	unregister_pernet_device(&vti_net_ops);
+	unregister_netdevice_notifier(&vti_notifier_block);
 }
 
 module_init(vti_init);
author maintainer
#29 lore raw

PATCH 36/73 net/irda: handle iriap_register_lsap() allocation failure

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Vegard Nossum <[email protected]>

[ Upstream commit 5ba092efc7ddff040777ae7162f1d195f513571b ]

If iriap_register_lsap() fails to allocate memory, self->lsap is set to NULL. However, none of the callers handle the failure and irlmp_connect_request() will happily dereference it:

    iriap_register_lsap: Unable to allocated LSAP!
    ================================================================================
    UBSAN: Undefined behaviour in net/irda/irlmp.c:378:2
    member access within null pointer of type 'struct lsap_cb'
    CPU: 1 PID: 15403 Comm: trinity-c0 Not tainted 4.8.0-rc1+ #81
    Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.9.3-0-ge2fc41e-prebuilt.qemu-project.org
    04/01/2014
     0000000000000000 ffff88010c7e78a8 ffffffff82344f40 0000000041b58ab3
     ffffffff84f98000 ffffffff82344e94 ffff88010c7e78d0 ffff88010c7e7880
     ffff88010630ad00 ffffffff84a5fae0 ffffffff84d3f5c0 000000000000017a
    Call Trace:
     [<ffffffff82344f40>] dump_stack+0xac/0xfc
     [<ffffffff8242f5a8>] ubsan_epilogue+0xd/0x8a
     [<ffffffff824302bf>] __ubsan_handle_type_mismatch+0x157/0x411
     [<ffffffff83b7bdbc>] irlmp_connect_request+0x7ac/0x970
     [<ffffffff83b77cc0>] iriap_connect_request+0xa0/0x160
     [<ffffffff83b77f48>] state_s_disconnect+0x88/0xd0
     [<ffffffff83b78904>] iriap_do_client_event+0x94/0x120
     [<ffffffff83b77710>] iriap_getvaluebyclass_request+0x3e0/0x6d0
     [<ffffffff83ba6ebb>] irda_find_lsap_sel+0x1eb/0x630
     [<ffffffff83ba90c8>] irda_connect+0x828/0x12d0
     [<ffffffff833c0dfb>] SYSC_connect+0x22b/0x340
     [<ffffffff833c7e09>] SyS_connect+0x9/0x10
     [<ffffffff81007bd3>] do_syscall_64+0x1b3/0x4b0
     [<ffffffff845f946a>] entry_SYSCALL64_slow_path+0x25/0x25
    ================================================================================

The bug seems to have been around since forever.

There's more problems with missing error checks in iriap_init() (and indeed all of irda_init()), but that's a bigger problem that needs very careful review and testing. This patch will fix the most serious bug (as it's easily reached from unprivileged userspace).

I have tested my patch with a reproducer.

---
 net/irda/iriap.c |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
net/irda/iriap.c +6 -2
@@ -185,8 +185,12 @@ struct iriap_cb *iriap_open(__u8 slsap_s
 
 	self->magic = IAS_MAGIC;
 	self->mode = mode;
-	if (mode == IAS_CLIENT)
-		iriap_register_lsap(self, slsap_sel, mode);
+	if (mode == IAS_CLIENT) {
+		if (iriap_register_lsap(self, slsap_sel, mode)) {
+			kfree(self);
+			return NULL;
+		}
+	}
 
 	self->confirm = callback;
 	self->priv = priv;
author maintainer
#30 lore raw

PATCH 37/73 tipc: fix NULL pointer dereference in shutdown()

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Vegard Nossum <[email protected]>

[ Upstream commit d2fbdf76b85bcdfe57b8ef2ba09d20e8ada79abd ]

tipc_msg_create() can return a NULL skb and if so, we shouldn't try to call tipc_node_xmit_skb() on it.

    general protection fault: 0000 [#1] PREEMPT SMP KASAN
    CPU: 3 PID: 30298 Comm: trinity-c0 Not tainted 4.7.0-rc7+ #19
    Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014
    task: ffff8800baf09980 ti: ffff8800595b8000 task.ti: ffff8800595b8000
    RIP: 0010:[<ffffffff830bb46b>]  [<ffffffff830bb46b>] tipc_node_xmit_skb+0x6b/0x140
    RSP: 0018:ffff8800595bfce8  EFLAGS: 00010246
    RAX: 0000000000000000 RBX: 0000000000000000 RCX: 000000003023b0e0
    RDX: 0000000000000000 RSI: dffffc0000000000 RDI: ffffffff83d12580
    RBP: ffff8800595bfd78 R08: ffffed000b2b7f32 R09: 0000000000000000
    R10: fffffbfff0759725 R11: 0000000000000000 R12: 1ffff1000b2b7f9f
    R13: ffff8800595bfd58 R14: ffffffff83d12580 R15: dffffc0000000000
    FS:  00007fcdde242700(0000) GS:ffff88011af80000(0000) knlGS:0000000000000000
    CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    CR2: 00007fcddde1db10 CR3: 000000006874b000 CR4: 00000000000006e0
    DR0: 00007fcdde248000 DR1: 00007fcddd73d000 DR2: 00007fcdde248000
    DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000090602
    Stack:
     0000000000000018 0000000000000018 0000000041b58ab3 ffffffff83954208
     ffffffff830bb400 ffff8800595bfd30 ffffffff8309d767 0000000000000018
     0000000000000018 ffff8800595bfd78 ffffffff8309da1a 00000000810ee611
    Call Trace:
     [<ffffffff830c84a3>] tipc_shutdown+0x553/0x880
     [<ffffffff825b4a3b>] SyS_shutdown+0x14b/0x170
     [<ffffffff8100334c>] do_syscall_64+0x19c/0x410
     [<ffffffff83295ca5>] entry_SYSCALL64_slow_path+0x25/0x25
    Code: 90 00 b4 0b 83 c7 00 f1 f1 f1 f1 4c 8d 6d e0 c7 40 04 00 00 00 f4 c7 40 08 f3 f3 f3 f3 48 89 d8 48 c1 e8 03 c7 45 b4 00 00 00 00 <80> 3c 30 00 75 78 48 8d 7b 08 49 8d 75 c0 48 b8 00 00 00 00 00
    RIP  [<ffffffff830bb46b>] tipc_node_xmit_skb+0x6b/0x140
     RSP <ffff8800595bfce8>
    ---[ end trace 57b0484e351e71f1 ]---

I feel like we should maybe return -ENOMEM or -ENOBUFS, but I'm not sure userspace is equipped to handle that. Anyway, this is better than a GPF and looks somewhat consistent with other tipc_msg_create() callers.

---
 net/tipc/socket.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
net/tipc/socket.c +2 -1
@@ -2111,7 +2111,8 @@ restart:
 					      TIPC_CONN_MSG, SHORT_H_SIZE,
 					      0, dnode, onode, dport, oport,
 					      TIPC_CONN_SHUTDOWN);
-			tipc_node_xmit_skb(net, skb, dnode, tsk->portid);
+			if (skb)
+				tipc_node_xmit_skb(net, skb, dnode, tsk->portid);
 		}
 		tsk->connected = 0;
 		sock->state = SS_DISCONNECTING;
author maintainer
#32 lore raw

PATCH 39/73 net: dsa: bcm_sf2: Fix race condition while unmasking interrupts

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Florian Fainelli <[email protected]>

[ Upstream commit 4f101c47791cdcb831b3ef1f831b1cc51e4fe03c ]

We kept shadow copies of which interrupt sources we have enabled and disabled, but due to an order bug in how intrl2_mask_clear was defined, we could run into the following scenario:

CPU0 CPU1
intrl2_1_mask_clear(..)
sets INTRL2_CPU_MASK_CLEAR

					bcm_sf2_switch_1_isr
					read INTRL2_CPU_STATUS and masks with stale
					irq1_mask value

updates irq1_mask value

Which would make us loop again and again trying to process and interrupt we are not clearing since our copy of whether it was enabled before still indicates it was not. Fix this by updating the shadow copy first, and then unasking at the HW level.

Fixes 246d7f773c13 ("net: dsa: add Broadcom SF2 switch driver")
---
 drivers/net/dsa/bcm_sf2.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/dsa/bcm_sf2.h +1 -1
@@ -187,8 +187,8 @@ static inline void name##_writeq(struct
 static inline void intrl2_##which##_mask_clear(struct bcm_sf2_priv *priv, \
 						u32 mask)		\
 {									\
-	intrl2_##which##_writel(priv, mask, INTRL2_CPU_MASK_CLEAR);	\
 	priv->irq##which##_mask &= ~(mask);				\
+	intrl2_##which##_writel(priv, mask, INTRL2_CPU_MASK_CLEAR);	\
 }									\
 static inline void intrl2_##which##_mask_set(struct bcm_sf2_priv *priv, \
 						u32 mask)		\
author maintainer
#33 lore raw

PATCH 40/73 Revert "phy: IRQ cannot be shared"

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Xander Huff <[email protected]>

[ Upstream commit c3e70edd7c2eed6acd234627a6007627f5c76e8e ]

This reverts:
commit 33c133cc7598 ("phy: IRQ cannot be shared")

On hardware with multiple PHY devices hooked up to the same IRQ line, allow them to share it.

Sergei Shtylyov says:
"I'm not sure now what was the reason I concluded that the IRQ sharing was impossible... most probably I thought that the kernel IRQ handling code exited the loop over the IRQ actions once IRQ_HANDLED was returned -- which is obviously not so in reality..."

---
 drivers/net/phy/phy.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/net/phy/phy.c +4 -2
@@ -640,8 +640,10 @@ phy_err:
 int phy_start_interrupts(struct phy_device *phydev)
 {
 	atomic_set(&phydev->irq_disable, 0);
-	if (request_irq(phydev->irq, phy_interrupt, 0, "phy_interrupt",
-			phydev) < 0) {
+	if (request_irq(phydev->irq, phy_interrupt,
+				IRQF_SHARED,
+				"phy_interrupt",
+				phydev) < 0) {
 		pr_warn("%s: Can't get IRQ %d (PHY)\n",
 			phydev->bus->name, phydev->irq);
 		phydev->irq = PHY_POLL;
author maintainer
#34 lore raw

PATCH 41/73 net: smc91x: fix SMC accesses

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Russell King <[email protected]>

[ Upstream commit 2fb04fdf30192ff1e2b5834e9b7745889ea8bbcb ]

Commit b70661c70830 ("net: smc91x: use run-time configuration on all ARM machines") broke some ARM platforms through several mistakes. Firstly, the access size must correspond to the following rule:

(a) at least one of 16-bit or 8-bit access size must be supported
(b) 32-bit accesses are optional, and may be enabled in addition to the above.

Secondly, it provides no emulation of 16-bit accesses, instead blindly making 16-bit accesses even when the platform specifies that only 8-bit is supported.

Reorganise smc91x.h so we can make use of the existing 16-bit access emulation already provided - if 16-bit accesses are supported, use 16-bit accesses directly, otherwise if 8-bit accesses are supported, use the provided 16-bit access emulation. If neither, BUG(). This exactly reflects the driver behaviour prior to the commit being fixed.

Since the conversion incorrectly cut down the available access sizes on several platforms, we also need to go through every platform and fix up the overly-restrictive access size: Arnd assumed that if a platform can perform 32-bit, 16-bit and 8-bit accesses, then only a 32-bit access size needed to be specified - not so, all available access sizes must be specified.

This likely fixes some performance regressions in doing this: if a platform does not support 8-bit accesses, 8-bit accesses have been emulated by performing a 16-bit read-modify-write access.

Tested on the Intel Assabet/Neponset platform, which supports only 8-bit accesses, which was broken by the original commit.

Fixes b70661c70830 ("net: smc91x: use run-time configuration on all ARM machines")
---
 arch/arm/mach-pxa/idp.c                    |    3 -
 arch/arm/mach-pxa/xcep.c                   |    3 -
 arch/arm/mach-realview/core.c              |    3 -
 arch/arm/mach-sa1100/pleb.c                |    2 
 arch/blackfin/mach-bf561/boards/cm_bf561.c |    3 -
 arch/blackfin/mach-bf561/boards/ezkit.c    |    3 -
 drivers/net/ethernet/smsc/smc91x.c         |    7 +++
 drivers/net/ethernet/smsc/smc91x.h         |   65 ++++++++++++++++++++---------
 include/linux/smc91x.h                     |   10 ++++
 9 files changed, 73 insertions(+), 26 deletions(-)
arch/arm/mach-pxa/idp.c +2 -1
@@ -83,7 +83,8 @@ static struct resource smc91x_resources[
 };
 
 static struct smc91x_platdata smc91x_platdata = {
-	.flags = SMC91X_USE_32BIT | SMC91X_USE_DMA | SMC91X_NOWAIT,
+	.flags = SMC91X_USE_8BIT | SMC91X_USE_16BIT | SMC91X_USE_32BIT |
+		 SMC91X_USE_DMA | SMC91X_NOWAIT,
 };
 
 static struct platform_device smc91x_device = {
arch/arm/mach-pxa/xcep.c +2 -1
@@ -120,7 +120,8 @@ static struct resource smc91x_resources[
 };
 
 static struct smc91x_platdata xcep_smc91x_info = {
-	.flags	= SMC91X_USE_32BIT | SMC91X_NOWAIT | SMC91X_USE_DMA,
+	.flags	= SMC91X_USE_8BIT | SMC91X_USE_16BIT | SMC91X_USE_32BIT |
+		  SMC91X_NOWAIT | SMC91X_USE_DMA,
 };
 
 static struct platform_device smc91x_device = {
arch/arm/mach-realview/core.c +2 -1
@@ -95,7 +95,8 @@ static struct smsc911x_platform_config s
 };
 
 static struct smc91x_platdata smc91x_platdata = {
-	.flags = SMC91X_USE_32BIT | SMC91X_NOWAIT,
+	.flags = SMC91X_USE_8BIT | SMC91X_USE_16BIT | SMC91X_USE_32BIT |
+		 SMC91X_NOWAIT,
 };
 
 static struct platform_device realview_eth_device = {
arch/arm/mach-sa1100/pleb.c +1 -1
@@ -45,7 +45,7 @@ static struct resource smc91x_resources[
 };
 
 static struct smc91x_platdata smc91x_platdata = {
-	.flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+	.flags = SMC91X_USE_16BIT | SMC91X_USE_8BIT | SMC91X_NOWAIT,
 };
 
 static struct platform_device smc91x_device = {
arch/blackfin/mach-bf561/boards/cm_bf561.c +2 -1
@@ -146,7 +146,8 @@ static struct platform_device hitachi_fb
 #include <linux/smc91x.h>
 
 static struct smc91x_platdata smc91x_info = {
-	.flags = SMC91X_USE_32BIT | SMC91X_NOWAIT,
+	.flags = SMC91X_USE_8BIT | SMC91X_USE_16BIT | SMC91X_USE_32BIT |
+		 SMC91X_NOWAIT,
 	.leda = RPC_LED_100_10,
 	.ledb = RPC_LED_TX_RX,
 };
arch/blackfin/mach-bf561/boards/ezkit.c +2 -1
@@ -134,7 +134,8 @@ static struct platform_device net2272_bf
 #include <linux/smc91x.h>
 
 static struct smc91x_platdata smc91x_info = {
-	.flags = SMC91X_USE_32BIT | SMC91X_NOWAIT,
+	.flags = SMC91X_USE_8BIT | SMC91X_USE_16BIT | SMC91X_USE_32BIT |
+		 SMC91X_NOWAIT,
 	.leda = RPC_LED_100_10,
 	.ledb = RPC_LED_TX_RX,
 };
drivers/net/ethernet/smsc/smc91x.c +7 -0
@@ -2269,6 +2269,13 @@ static int smc_drv_probe(struct platform
 	if (pd) {
 		memcpy(&lp->cfg, pd, sizeof(lp->cfg));
 		lp->io_shift = SMC91X_IO_SHIFT(lp->cfg.flags);
+
+		if (!SMC_8BIT(lp) && !SMC_16BIT(lp)) {
+			dev_err(&pdev->dev,
+				"at least one of 8-bit or 16-bit access support is required.\n");
+			ret = -ENXIO;
+			goto out_free_netdev;
+		}
 	}
 
 #if IS_BUILTIN(CONFIG_OF)
drivers/net/ethernet/smsc/smc91x.h +45 -20

92 lines not on this page · raw message

include/linux/smc91x.h +10 -0
@@ -1,6 +1,16 @@
 #ifndef __SMC91X_H__
 #define __SMC91X_H__
 
+/*
+ * These bits define which access sizes a platform can support, rather
+ * than the maximal access size.  So, if your platform can do 16-bit
+ * and 32-bit accesses to the SMC91x device, but not 8-bit, set both
+ * SMC91X_USE_16BIT and SMC91X_USE_32BIT.
+ *
+ * The SMC91x driver requires at least one of SMC91X_USE_8BIT or
+ * SMC91X_USE_16BIT to be supported - just setting SMC91X_USE_32BIT is
+ * an invalid configuration.
+ */
 #define SMC91X_USE_8BIT (1 << 0)
 #define SMC91X_USE_16BIT (1 << 1)
 #define SMC91X_USE_32BIT (1 << 2)
author maintainer
#35 lore raw

PATCH 42/73 bridge: re-introduce fix parsing of MLDv2 reports

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Davide Caratti <[email protected]>

[ Upstream commit 9264251ee2a55bce8fb93826b3f581fb9eb7e2c2 ]

commit bc8c20acaea1 ("bridge: multicast: treat igmpv3 report with INCLUDE and no sources as a leave") seems to have accidentally reverted commit 47cc84ce0c2f ("bridge: fix parsing of MLDv2 reports"). This commit brings back a change to br_ip6_multicast_mld2_report() where parsing of MLDv2 reports stops when the first group is successfully added to the MDB cache.

Fixes bc8c20acaea1 ("bridge: multicast: treat igmpv3 report with INCLUDE and no sources as a leave")
---
 net/bridge/br_multicast.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/bridge/br_multicast.c +1 -1
@@ -1113,7 +1113,7 @@ static int br_ip6_multicast_mld2_report(
 		} else {
 			err = br_ip6_multicast_add_group(br, port,
 							 &grec->grec_mca, vid);
-			if (!err)
+			if (err)
 				break;
 		}
 	}
author maintainer
#37 lore raw

PATCH 44/73 autofs races

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Al Viro <[email protected]>

commit ea01a18494b3d7a91b2f1f2a6a5aaef4741bc294 upstream.

* make autofs4_expire_indirect() skip the dentries being in process of expiry
* do *not* mess with list_move(); making sure that dentry with AUTOFS_INF_EXPIRING are not picked for expiry is enough.
* do not remove NO_RCU when we set EXPIRING, don't bother with smp_mb() there. Clear it at the same time we clear EXPIRING. Makes a bunch of tests simpler.
* rename NO_RCU to WANT_EXPIRE, which is what it really is.

---
 fs/autofs4/autofs_i.h |    8 ++++++--
 fs/autofs4/expire.c   |   27 ++++++++-------------------
 fs/autofs4/root.c     |    2 +-
 3 files changed, 15 insertions(+), 22 deletions(-)
fs/autofs4/autofs_i.h +6 -2
@@ -79,9 +79,13 @@ struct autofs_info {
 };
 
 #define AUTOFS_INF_EXPIRING	(1<<0) /* dentry is in the process of expiring */
-#define AUTOFS_INF_NO_RCU	(1<<1) /* the dentry is being considered
+#define AUTOFS_INF_WANT_EXPIRE	(1<<1) /* the dentry is being considered
 					* for expiry, so RCU_walk is
-					* not permitted
+					* not permitted.  If it progresses to
+					* actual expiry attempt, the flag is
+					* not cleared when EXPIRING is set -
+					* in that case it gets cleared only
+					* when it comes to clearing EXPIRING.
 					*/
 #define AUTOFS_INF_PENDING	(1<<2) /* dentry pending mount */
 
fs/autofs4/expire.c +8 -19
@@ -315,19 +315,17 @@ struct dentry *autofs4_expire_direct(str
 	if (ino->flags & AUTOFS_INF_PENDING)
 		goto out;
 	if (!autofs4_direct_busy(mnt, root, timeout, do_now)) {
-		ino->flags |= AUTOFS_INF_NO_RCU;
+		ino->flags |= AUTOFS_INF_WANT_EXPIRE;
 		spin_unlock(&sbi->fs_lock);
 		synchronize_rcu();
 		spin_lock(&sbi->fs_lock);
 		if (!autofs4_direct_busy(mnt, root, timeout, do_now)) {
 			ino->flags |= AUTOFS_INF_EXPIRING;
-			smp_mb();
-			ino->flags &= ~AUTOFS_INF_NO_RCU;
 			init_completion(&ino->expire_complete);
 			spin_unlock(&sbi->fs_lock);
 			return root;
 		}
-		ino->flags &= ~AUTOFS_INF_NO_RCU;
+		ino->flags &= ~AUTOFS_INF_WANT_EXPIRE;
 	}
 out:
 	spin_unlock(&sbi->fs_lock);
@@ -444,7 +442,7 @@ struct dentry *autofs4_expire_indirect(s
 	while ((dentry = get_next_positive_subdir(dentry, root))) {
 		spin_lock(&sbi->fs_lock);
 		ino = autofs4_dentry_ino(dentry);
-		if (ino->flags & AUTOFS_INF_NO_RCU)
+		if (ino->flags & AUTOFS_INF_WANT_EXPIRE)
 			expired = NULL;
 		else
 			expired = should_expire(dentry, mnt, timeout, how);
@@ -453,7 +451,7 @@ struct dentry *autofs4_expire_indirect(s
 			continue;
 		}
 		ino = autofs4_dentry_ino(expired);
-		ino->flags |= AUTOFS_INF_NO_RCU;
+		ino->flags |= AUTOFS_INF_WANT_EXPIRE;
 		spin_unlock(&sbi->fs_lock);
 		synchronize_rcu();
 		spin_lock(&sbi->fs_lock);
@@ -463,7 +461,7 @@ struct dentry *autofs4_expire_indirect(s
 			goto found;
 		}
 
-		ino->flags &= ~AUTOFS_INF_NO_RCU;
+		ino->flags &= ~AUTOFS_INF_WANT_EXPIRE;
 		if (expired != dentry)
 			dput(expired);
 		spin_unlock(&sbi->fs_lock);
@@ -473,17 +471,8 @@ struct dentry *autofs4_expire_indirect(s
 found:
 	DPRINTK("returning %p %pd", expired, expired);
 	ino->flags |= AUTOFS_INF_EXPIRING;
-	smp_mb();
-	ino->flags &= ~AUTOFS_INF_NO_RCU;
 	init_completion(&ino->expire_complete);
 	spin_unlock(&sbi->fs_lock);
-	spin_lock(&sbi->lookup_lock);
-	spin_lock(&expired->d_parent->d_lock);
-	spin_lock_nested(&expired->d_lock, DENTRY_D_LOCK_NESTED);
-	list_move(&expired->d_parent->d_subdirs, &expired->d_child);
-	spin_unlock(&expired->d_lock);
-	spin_unlock(&expired->d_parent->d_lock);
-	spin_unlock(&sbi->lookup_lock);
 	return expired;
 }
 
@@ -494,7 +483,7 @@ int autofs4_expire_wait(struct dentry *d
 	int status;
 
 	/* Block on any pending expire */
-	if (!(ino->flags & (AUTOFS_INF_EXPIRING | AUTOFS_INF_NO_RCU)))
+	if (!(ino->flags & AUTOFS_INF_WANT_EXPIRE))
 		return 0;
 	if (rcu_walk)
 		return -ECHILD;
@@ -551,7 +540,7 @@ int autofs4_expire_run(struct super_bloc
 	ino = autofs4_dentry_ino(dentry);
 	/* avoid rapid-fire expire attempts if expiry fails */
 	ino->last_used = now;
-	ino->flags &= ~AUTOFS_INF_EXPIRING;
+	ino->flags &= ~(AUTOFS_INF_EXPIRING|AUTOFS_INF_WANT_EXPIRE);
 	complete_all(&ino->expire_complete);
 	spin_unlock(&sbi->fs_lock);
 
@@ -579,7 +568,7 @@ int autofs4_do_expire_multi(struct super
 		spin_lock(&sbi->fs_lock);
 		/* avoid rapid-fire expire attempts if expiry fails */
 		ino->last_used = now;
-		ino->flags &= ~AUTOFS_INF_EXPIRING;
+		ino->flags &= ~(AUTOFS_INF_EXPIRING|AUTOFS_INF_WANT_EXPIRE);
 		complete_all(&ino->expire_complete);
 		spin_unlock(&sbi->fs_lock);
 		dput(dentry);
fs/autofs4/root.c +1 -1
@@ -455,7 +455,7 @@ static int autofs4_d_manage(struct dentr
 		 * a mount-trap.
 		 */
 		struct inode *inode;
-		if (ino->flags & (AUTOFS_INF_EXPIRING | AUTOFS_INF_NO_RCU))
+		if (ino->flags & AUTOFS_INF_WANT_EXPIRE)
 			return 0;
 		if (d_mountpoint(dentry))
 			return 0;
author maintainer
#36 lore raw

PATCH 43/73 pwm: Mark all devices as "might sleep"

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Thierry Reding <[email protected]>

commit ff01c944cfa939f3474c28d88223213494aedf0b upstream.

Commit d1cd21427747 ("pwm: Set enable state properly on failed call to enable") introduced a mutex that is needed to protect internal state of PWM devices. Since that mutex is acquired in pwm_set_polarity() and in pwm_enable() and might potentially block, all PWM devices effectively become "might sleep".

It's rather pointless to keep the .can_sleep field around, but given that there are external users let's postpone the removal for the next release cycle.

Fixes d1cd21427747 ("pwm: Set enable state properly on failed call to enable")
---
 drivers/pwm/core.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pwm/core.c +1 -1
@@ -889,7 +889,7 @@ EXPORT_SYMBOL_GPL(devm_pwm_put);
   */
 bool pwm_can_sleep(struct pwm_device *pwm)
 {
-	return pwm->chip->can_sleep;
+	return true;
 }
 EXPORT_SYMBOL_GPL(pwm_can_sleep);
 
author maintainer
#38 lore raw

PATCH 45/73 autofs: use dentry flags to block walks during expire

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Ian Kent <[email protected]>

commit 7cbdb4a286a60c5d519cb9223fe2134d26870d39 upstream.

Somewhere along the way the autofs expire operation has changed to hold a spin lock over expired dentry selection. The autofs indirect mount expired dentry selection is complicated and quite lengthy so it isn't appropriate to hold a spin lock over the operation.

Commit 47be61845c77 ("fs/dcache.c: avoid soft-lockup in dput()") added a might_sleep() to dput() causing a WARN_ONCE() about this usage to be issued.

But the spin lock doesn't need to be held over this check, the autofs dentry info. flags are enough to block walks into dentrys during the expire.

I've left the direct mount expire as it is (for now) because it is much simpler and quicker than the indirect mount expire and adding spin lock release and re-aquires would do nothing more than add overhead.

---
 fs/autofs4/expire.c |   55 +++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 42 insertions(+), 13 deletions(-)
fs/autofs4/expire.c +42 -13
@@ -415,6 +415,7 @@ static struct dentry *should_expire(stru
 	}
 	return NULL;
 }
+
 /*
  * Find an eligible tree to time-out
  * A tree is eligible if :-
@@ -430,6 +431,7 @@ struct dentry *autofs4_expire_indirect(s
 	struct dentry *root = sb->s_root;
 	struct dentry *dentry;
 	struct dentry *expired;
+	struct dentry *found;
 	struct autofs_info *ino;
 
 	if (!root)
@@ -440,31 +442,46 @@ struct dentry *autofs4_expire_indirect(s
 
 	dentry = NULL;
 	while ((dentry = get_next_positive_subdir(dentry, root))) {
+		int flags = how;
+
 		spin_lock(&sbi->fs_lock);
 		ino = autofs4_dentry_ino(dentry);
-		if (ino->flags & AUTOFS_INF_WANT_EXPIRE)
-			expired = NULL;
-		else
-			expired = should_expire(dentry, mnt, timeout, how);
-		if (!expired) {
+		if (ino->flags & AUTOFS_INF_WANT_EXPIRE) {
 			spin_unlock(&sbi->fs_lock);
 			continue;
 		}
+		spin_unlock(&sbi->fs_lock);
+
+		expired = should_expire(dentry, mnt, timeout, flags);
+		if (!expired)
+			continue;
+
+		spin_lock(&sbi->fs_lock);
 		ino = autofs4_dentry_ino(expired);
 		ino->flags |= AUTOFS_INF_WANT_EXPIRE;
 		spin_unlock(&sbi->fs_lock);
 		synchronize_rcu();
-		spin_lock(&sbi->fs_lock);
-		if (should_expire(expired, mnt, timeout, how)) {
-			if (expired != dentry)
-				dput(dentry);
-			goto found;
-		}
 
+		/* Make sure a reference is not taken on found if
+		 * things have changed.
+		 */
+		flags &= ~AUTOFS_EXP_LEAVES;
+		found = should_expire(expired, mnt, timeout, how);
+		if (!found || found != expired)
+			/* Something has changed, continue */
+			goto next;
+
+		if (expired != dentry)
+			dput(dentry);
+
+		spin_lock(&sbi->fs_lock);
+		goto found;
+next:
+		spin_lock(&sbi->fs_lock);
 		ino->flags &= ~AUTOFS_INF_WANT_EXPIRE;
+		spin_unlock(&sbi->fs_lock);
 		if (expired != dentry)
 			dput(expired);
-		spin_unlock(&sbi->fs_lock);
 	}
 	return NULL;
 
@@ -481,6 +498,7 @@ int autofs4_expire_wait(struct dentry *d
 	struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
 	struct autofs_info *ino = autofs4_dentry_ino(dentry);
 	int status;
+	int state;
 
 	/* Block on any pending expire */
 	if (!(ino->flags & AUTOFS_INF_WANT_EXPIRE))
@@ -488,8 +506,19 @@ int autofs4_expire_wait(struct dentry *d
 	if (rcu_walk)
 		return -ECHILD;
 
+retry:
 	spin_lock(&sbi->fs_lock);
-	if (ino->flags & AUTOFS_INF_EXPIRING) {
+	state = ino->flags & (AUTOFS_INF_WANT_EXPIRE | AUTOFS_INF_EXPIRING);
+	if (state == AUTOFS_INF_WANT_EXPIRE) {
+		spin_unlock(&sbi->fs_lock);
+		/*
+		 * Possibly being selected for expire, wait until
+		 * it's selected or not.
+		 */
+		schedule_timeout_uninterruptible(HZ/10);
+		goto retry;
+	}
+	if (state & AUTOFS_INF_EXPIRING) {
 		spin_unlock(&sbi->fs_lock);
 
 		DPRINTK("waiting for expire %p name=%pd", dentry, dentry);
author maintainer
#40 lore raw

PATCH 47/73 fsnotify: add a way to stop queueing events on group shutdown

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jan Kara <[email protected]>

commit 12703dbfeb15402260e7554d32a34ac40c233990 upstream.

Implement a function that can be called when a group is being shutdown to stop queueing new events to the group. Fanotify will use this.

Fixes 5838d4442bd5 ("fanotify: fix double free of pending permission events")
---
 fs/notify/group.c                |   19 +++++++++++++++++++
 fs/notify/notification.c         |    8 +++++++-
 include/linux/fsnotify_backend.h |    3 +++
 3 files changed, 29 insertions(+), 1 deletion(-)
fs/notify/group.c +19 -0
@@ -40,6 +40,17 @@ static void fsnotify_final_destroy_group
 }
 
 /*
+ * Stop queueing new events for this group. Once this function returns
+ * fsnotify_add_event() will not add any new events to the group's queue.
+ */
+void fsnotify_group_stop_queueing(struct fsnotify_group *group)
+{
+	mutex_lock(&group->notification_mutex);
+	group->shutdown = true;
+	mutex_unlock(&group->notification_mutex);
+}
+
+/*
  * Trying to get rid of a group. Remove all marks, flush all events and release
  * the group reference.
  * Note that another thread calling fsnotify_clear_marks_by_group() may still
@@ -47,6 +58,14 @@ static void fsnotify_final_destroy_group
  */
 void fsnotify_destroy_group(struct fsnotify_group *group)
 {
+	/*
+	 * Stop queueing new events. The code below is careful enough to not
+	 * require this but fanotify needs to stop queuing events even before
+	 * fsnotify_destroy_group() is called and this makes the other callers
+	 * of fsnotify_destroy_group() to see the same behavior.
+	 */
+	fsnotify_group_stop_queueing(group);
+
 	/* clear all inode marks for this group */
 	fsnotify_clear_marks_by_group(group);
 
fs/notify/notification.c +7 -1
@@ -82,7 +82,8 @@ void fsnotify_destroy_event(struct fsnot
  * Add an event to the group notification queue.  The group can later pull this
  * event off the queue to deal with.  The function returns 0 if the event was
  * added to the queue, 1 if the event was merged with some other queued event,
- * 2 if the queue of events has overflown.
+ * 2 if the event was not queued - either the queue of events has overflown
+ * or the group is shutting down.
  */
 int fsnotify_add_event(struct fsnotify_group *group,
 		       struct fsnotify_event *event,
@@ -96,6 +97,11 @@ int fsnotify_add_event(struct fsnotify_g
 
 	mutex_lock(&group->notification_mutex);
 
+	if (group->shutdown) {
+		mutex_unlock(&group->notification_mutex);
+		return 2;
+	}
+
 	if (group->q_len >= group->max_events) {
 		ret = 2;
 		/* Queue overflow event only if it isn't already queued */
include/linux/fsnotify_backend.h +3 -0
@@ -148,6 +148,7 @@ struct fsnotify_group {
 	#define FS_PRIO_1	1 /* fanotify content based access control */
 	#define FS_PRIO_2	2 /* fanotify pre-content access */
 	unsigned int priority;
+	bool shutdown;		/* group is being shut down, don't queue more events */
 
 	/* stores all fastpath marks assoc with this group so they can be cleaned on unregister */
 	struct mutex mark_mutex;	/* protect marks_list */
@@ -308,6 +309,8 @@ extern struct fsnotify_group *fsnotify_a
 extern void fsnotify_get_group(struct fsnotify_group *group);
 /* drop reference on a group from fsnotify_alloc_group */
 extern void fsnotify_put_group(struct fsnotify_group *group);
+/* group destruction begins, stop queuing new events */
+extern void fsnotify_group_stop_queueing(struct fsnotify_group *group);
 /* destroy group */
 extern void fsnotify_destroy_group(struct fsnotify_group *group);
 /* fasync handler function */
author maintainer
#41 lore raw

PATCH 48/73 fanotify: fix list corruption in fanotify_get_response()

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jan Kara <[email protected]>

commit 96d41019e3ac55f6f0115b0ce97e4f24a3d636d2 upstream.

fanotify_get_response() calls fsnotify_remove_event() when it finds that group is being released from fanotify_release() (bypass_perm is set).

However the event it removes need not be only in the group's notification queue but it can have already moved to access_list (userspace read the event before closing the fanotify instance fd) which is protected by a different lock. Thus when fsnotify_remove_event() races with fanotify_release() operating on access_list, the list can get corrupted.

Fix the problem by moving all the logic removing permission events from the lists to one place - fanotify_release().

---
 fs/notify/fanotify/fanotify.c      |   13 +------------
 fs/notify/fanotify/fanotify_user.c |   36 ++++++++++++++++++++++++------------
 fs/notify/notification.c           |   15 ---------------
 include/linux/fsnotify_backend.h   |    3 ---
 4 files changed, 25 insertions(+), 42 deletions(-)
fs/notify/fanotify/fanotify.c +1 -12
@@ -67,18 +67,7 @@ static int fanotify_get_response(struct
 
 	pr_debug("%s: group=%p event=%p\n", __func__, group, event);
 
-	wait_event(group->fanotify_data.access_waitq, event->response ||
-				atomic_read(&group->fanotify_data.bypass_perm));
-
-	if (!event->response) {	/* bypass_perm set */
-		/*
-		 * Event was canceled because group is being destroyed. Remove
-		 * it from group's event list because we are responsible for
-		 * freeing the permission event.
-		 */
-		fsnotify_remove_event(group, &event->fae.fse);
-		return 0;
-	}
+	wait_event(group->fanotify_data.access_waitq, event->response);
 
 	/* userspace responded, convert to something usable */
 	switch (event->response) {
fs/notify/fanotify/fanotify_user.c +24 -12
@@ -358,16 +358,20 @@ static int fanotify_release(struct inode
 
 #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
 	struct fanotify_perm_event_info *event, *next;
+	struct fsnotify_event *fsn_event;
 
 	/*
-	 * There may be still new events arriving in the notification queue
-	 * but since userspace cannot use fanotify fd anymore, no event can
-	 * enter or leave access_list by now.
+	 * Stop new events from arriving in the notification queue. since
+	 * userspace cannot use fanotify fd anymore, no event can enter or
+	 * leave access_list by now either.
 	 */
-	spin_lock(&group->fanotify_data.access_lock);
-
-	atomic_inc(&group->fanotify_data.bypass_perm);
+	fsnotify_group_stop_queueing(group);
 
+	/*
+	 * Process all permission events on access_list and notification queue
+	 * and simulate reply from userspace.
+	 */
+	spin_lock(&group->fanotify_data.access_lock);
 	list_for_each_entry_safe(event, next, &group->fanotify_data.access_list,
 				 fae.fse.list) {
 		pr_debug("%s: found group=%p event=%p\n", __func__, group,
@@ -379,12 +383,21 @@ static int fanotify_release(struct inode
 	spin_unlock(&group->fanotify_data.access_lock);
 
 	/*
-	 * Since bypass_perm is set, newly queued events will not wait for
-	 * access response. Wake up the already sleeping ones now.
-	 * synchronize_srcu() in fsnotify_destroy_group() will wait for all
-	 * processes sleeping in fanotify_handle_event() waiting for access
-	 * response and thus also for all permission events to be freed.
+	 * Destroy all non-permission events. For permission events just
+	 * dequeue them and set the response. They will be freed once the
+	 * response is consumed and fanotify_get_response() returns.
 	 */
+	mutex_lock(&group->notification_mutex);
+	while (!fsnotify_notify_queue_is_empty(group)) {
+		fsn_event = fsnotify_remove_first_event(group);
+		if (!(fsn_event->mask & FAN_ALL_PERM_EVENTS))
+			fsnotify_destroy_event(group, fsn_event);
+		else
+			FANOTIFY_PE(fsn_event)->response = FAN_ALLOW;
+	}
+	mutex_unlock(&group->notification_mutex);
+
+	/* Response for all permission events it set, wakeup waiters */
 	wake_up(&group->fanotify_data.access_waitq);
 #endif
 
@@ -755,7 +768,6 @@ SYSCALL_DEFINE2(fanotify_init, unsigned
 	spin_lock_init(&group->fanotify_data.access_lock);
 	init_waitqueue_head(&group->fanotify_data.access_waitq);
 	INIT_LIST_HEAD(&group->fanotify_data.access_list);
-	atomic_set(&group->fanotify_data.bypass_perm, 0);
 #endif
 	switch (flags & FAN_ALL_CLASS_BITS) {
 	case FAN_CLASS_NOTIF:
fs/notify/notification.c +0 -15
@@ -132,21 +132,6 @@ queue:
 }
 
 /*
- * Remove @event from group's notification queue. It is the responsibility of
- * the caller to destroy the event.
- */
-void fsnotify_remove_event(struct fsnotify_group *group,
-			   struct fsnotify_event *event)
-{
-	mutex_lock(&group->notification_mutex);
-	if (!list_empty(&event->list)) {
-		list_del_init(&event->list);
-		group->q_len--;
-	}
-	mutex_unlock(&group->notification_mutex);
-}
-
-/*
  * Remove and return the first event from the notification list.  It is the
  * responsibility of the caller to destroy the obtained event
  */
include/linux/fsnotify_backend.h +0 -3
@@ -180,7 +180,6 @@ struct fsnotify_group {
 			spinlock_t access_lock;
 			struct list_head access_list;
 			wait_queue_head_t access_waitq;
-			atomic_t bypass_perm;
 #endif /* CONFIG_FANOTIFY_ACCESS_PERMISSIONS */
 			int f_flags;
 			unsigned int max_marks;
@@ -323,8 +322,6 @@ extern int fsnotify_add_event(struct fsn
 			      struct fsnotify_event *event,
 			      int (*merge)(struct list_head *,
 					   struct fsnotify_event *));
-/* Remove passed event from groups notification queue */
-extern void fsnotify_remove_event(struct fsnotify_group *group, struct fsnotify_event *event);
 /* true if the group notification queue is empty */
 extern bool fsnotify_notify_queue_is_empty(struct fsnotify_group *group);
 /* return, but do not dequeue the first event on the notification queue */
author maintainer
#43 lore raw

PATCH 50/73 mtd: maps: sa1100-flash: potential NULL dereference

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Dan Carpenter <[email protected]>

commit dc01a28d80a42cef08c94dfc595565aaebe46d15 upstream.

We check for NULL but then dereference "info->mtd" on the next line.

Fixes 72169755cf36 ('mtd: maps: sa1100-flash: show parent device in sysfs')
---
 drivers/mtd/maps/sa1100-flash.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/mtd/maps/sa1100-flash.c +3 -1
@@ -230,8 +230,10 @@ static struct sa_info *sa1100_setup_mtd(
 
 		info->mtd = mtd_concat_create(cdev, info->num_subdev,
 					      plat->name);
-		if (info->mtd == NULL)
+		if (info->mtd == NULL) {
 			ret = -ENXIO;
+			goto err;
+		}
 	}
 	info->mtd->dev.parent = &pdev->dev;
 
author maintainer
#44 lore raw

PATCH 51/73 mtd: pmcmsp-flash: Allocating too much in init_msp_flash()

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Dan Carpenter <[email protected]>

commit 79ad07d45743721010e766e65dc004ad249bd429 upstream.

There is a cut and paste issue here. The bug is that we are allocating more memory than necessary for msp_maps. We should be allocating enough space for a map_info struct (144 bytes) but we instead allocate enough for an mtd_info struct (1840 bytes). It's a small waste.

The other part of this is not harmful but when we allocated msp_flash then we allocated enough space fro a map_info pointer instead of an mtd_info pointer. But since pointers are the same size it works out fine.

Anyway, I decided to clean up all three allocations a bit to make them a bit more consistent and clear.

Fixes 68aa0fa87f6d ('[MTD] PMC MSP71xx flash/rootfs mappings')
---
 drivers/mtd/maps/pmcmsp-flash.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/mtd/maps/pmcmsp-flash.c +3 -3
@@ -75,15 +75,15 @@ static int __init init_msp_flash(void)
 
 	printk(KERN_NOTICE "Found %d PMC flash devices\n", fcnt);
 
-	msp_flash = kmalloc(fcnt * sizeof(struct map_info *), GFP_KERNEL);
+	msp_flash = kcalloc(fcnt, sizeof(*msp_flash), GFP_KERNEL);
 	if (!msp_flash)
 		return -ENOMEM;
 
-	msp_parts = kmalloc(fcnt * sizeof(struct mtd_partition *), GFP_KERNEL);
+	msp_parts = kcalloc(fcnt, sizeof(*msp_parts), GFP_KERNEL);
 	if (!msp_parts)
 		goto free_msp_flash;
 
-	msp_maps = kcalloc(fcnt, sizeof(struct mtd_info), GFP_KERNEL);
+	msp_maps = kcalloc(fcnt, sizeof(*msp_maps), GFP_KERNEL);
 	if (!msp_maps)
 		goto free_msp_parts;
 
author maintainer
#45 lore raw

PATCH 52/73 power: reset: hisi-reboot: Unmap region obtained by of_iomap

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Arvind Yadav <[email protected]>

commit bae170efd6c42bf116f513a1dd07639d68fa71b9 upstream.

Free memory mapping, if probe is not successful.

Fixes 4a9b37371822 ("power: reset: move hisilicon reboot code")
---
 drivers/power/reset/hisi-reboot.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/power/reset/hisi-reboot.c +4 -1
@@ -53,13 +53,16 @@ static int hisi_reboot_probe(struct plat
 
 	if (of_property_read_u32(np, "reboot-offset", &reboot_offset) < 0) {
 		pr_err("failed to find reboot-offset property\n");
+		iounmap(base);
 		return -EINVAL;
 	}
 
 	err = register_restart_handler(&hisi_restart_nb);
-	if (err)
+	if (err) {
 		dev_err(&pdev->dev, "cannot register restart handler (err=%d)\n",
 			err);
+		iounmap(base);
+	}
 
 	return err;
 }
author maintainer
#17 lore raw

PATCH 23/73 Makefile: Mute warning for __builtin_return_address(>0) for tracing only

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Steven Rostedt <[email protected]>

commit 377ccbb483738f84400ddf5840c7dd8825716985 upstream.

With the latest gcc compilers, they give a warning if __builtin_return_address() parameter is greater than 0. That is because if it is used by a function called by a top level function (or in the case of the kernel, by assembly), it can try to access stack frames outside the stack and crash the system.

The tracing system uses __builtin_return_address() of up to 2! But it is well aware of the dangers that it may have, and has even added precautions to protect against it (see the thunk code in arch/x86/entry/thunk*.S)

Linus originally added KBUILD_CFLAGS that would suppress the warning for the entire kernel, as simply adding KBUILD_CFLAGS to the tracing directory wouldn't work. The tracing directory plays a bit with the CFLAGS and requires a little more logic.

This adds that special logic to only suppress the warning for the tracing directory. If it is used anywhere else outside of tracing, the warning will still be triggered.

---
 Makefile              |    1 -
 kernel/trace/Makefile |    4 ++++
 2 files changed, 4 insertions(+), 1 deletion(-)
Makefile +0 -1
@@ -617,7 +617,6 @@ include arch/$(SRCARCH)/Makefile
 
 KBUILD_CFLAGS	+= $(call cc-option,-fno-delete-null-pointer-checks,)
 KBUILD_CFLAGS	+= $(call cc-disable-warning,maybe-uninitialized,)
-KBUILD_CFLAGS	+= $(call cc-disable-warning,frame-address,)
 
 ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
 KBUILD_CFLAGS	+= -Os
kernel/trace/Makefile +4 -0
@@ -1,4 +1,8 @@
 
+# We are fully aware of the dangers of __builtin_return_address()
+FRAME_CFLAGS := $(call cc-disable-warning,frame-address)
+KBUILD_CFLAGS += $(FRAME_CFLAGS)
+
 # Do not instrument the tracer itself:
 
 ifdef CONFIG_FUNCTION_TRACER
author maintainer
#47 lore raw

PATCH 54/73 tracing: Move mutex to protect against resetting of seq data

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Steven Rostedt (Red Hat) <[email protected]>

commit 1245800c0f96eb6ebb368593e251d66c01e61022 upstream.

The iter->seq can be reset outside the protection of the mutex. So can reading of user data. Move the mutex up to the beginning of the function.

Fixes d7350c3f45694 ("tracing/core: make the read callbacks reentrants")
---
 kernel/trace/trace.c |   15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)
kernel/trace/trace.c +8 -7
@@ -4727,19 +4727,20 @@ tracing_read_pipe(struct file *filp, cha
 	struct trace_iterator *iter = filp->private_data;
 	ssize_t sret;
 
-	/* return any leftover data */
-	sret = trace_seq_to_user(&iter->seq, ubuf, cnt);
-	if (sret != -EBUSY)
-		return sret;
-
-	trace_seq_init(&iter->seq);
-
 	/*
 	 * Avoid more than one consumer on a single file descriptor
 	 * This is just a matter of traces coherency, the ring buffer itself
 	 * is protected.
 	 */
 	mutex_lock(&iter->mutex);
+
+	/* return any leftover data */
+	sret = trace_seq_to_user(&iter->seq, ubuf, cnt);
+	if (sret != -EBUSY)
+		goto out;
+
+	trace_seq_init(&iter->seq);
+
 	if (iter->trace->read) {
 		sret = iter->trace->read(iter, filp, ubuf, cnt, ppos);
 		if (sret)
author maintainer
#49 lore raw

PATCH 56/73 can: flexcan: fix resume function

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Fabio Estevam <[email protected]>

commit 4de349e786a3a2d51bd02d56f3de151bbc3c3df9 upstream.

On a imx6ul-pico board the following error is seen during system suspend:

dpm_run_callback(): platform_pm_resume+0x0/0x54 returns -110
PM: Device 2090000.flexcan failed to resume: error -110

The reason for this suspend error is because when the CAN interface is not active the clocks are disabled and then flexcan_chip_enable() will always fail due to a timeout error.

In order to fix this issue, only call flexcan_chip_enable/disable() when the CAN interface is active.

Based on a patch from Dong Aisheng in the NXP kernel.

---
 drivers/net/can/flexcan.c |   13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)
drivers/net/can/flexcan.c +8 -5
@@ -1268,11 +1268,10 @@ static int __maybe_unused flexcan_suspen
 	struct flexcan_priv *priv = netdev_priv(dev);
 	int err;
 
-	err = flexcan_chip_disable(priv);
-	if (err)
-		return err;
-
 	if (netif_running(dev)) {
+		err = flexcan_chip_disable(priv);
+		if (err)
+			return err;
 		netif_stop_queue(dev);
 		netif_device_detach(dev);
 	}
@@ -1285,13 +1284,17 @@ static int __maybe_unused flexcan_resume
 {
 	struct net_device *dev = dev_get_drvdata(device);
 	struct flexcan_priv *priv = netdev_priv(dev);
+	int err;
 
 	priv->can.state = CAN_STATE_ERROR_ACTIVE;
 	if (netif_running(dev)) {
 		netif_device_attach(dev);
 		netif_start_queue(dev);
+		err = flexcan_chip_enable(priv);
+		if (err)
+			return err;
 	}
-	return flexcan_chip_enable(priv);
+	return 0;
 }
 
 static SIMPLE_DEV_PM_OPS(flexcan_pm_ops, flexcan_suspend, flexcan_resume);
author maintainer
#20 lore raw

PATCH 27/73 ath9k: fix misleading indentation

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Arnd Bergmann <[email protected]>

commit 362210e0dff4eb7bb36a9b34dbef3b39d779d95e upstream.

A cleanup patch in linux-3.18 moved around some code in the ath9k driver and left some code to be indented in a misleading way, made worse by the addition of some new code for p2p mode, as discovered by a new gcc-6 warning:

drivers/net/wireless/ath/ath9k/init.c: In function 'ath9k_set_hw_capab':
drivers/net/wireless/ath/ath9k/init.c:851:4: warning: statement is indented as if it were guarded by... [-Wmisleading-indentation]

    hw->wiphy->iface_combinations = if_comb;
    ^~

drivers/net/wireless/ath/ath9k/init.c:847:3: note: ...this 'if' clause, but it is not
if (ath9k_is_chanctx_enabled())
^~

The code is in fact correct, but the indentation is not, so I'm reformatting it as it should have been after the original cleanup.

Fixes 499afaccf6f3 ("ath9k: Isolate ath9k_use_chanctx module parameter")
Fixes eb61f9f623f7 ("ath9k: advertise p2p dev support when chanctx")
---
 drivers/net/wireless/ath/ath9k/init.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/wireless/ath/ath9k/init.c +2 -2
@@ -869,8 +869,8 @@ static void ath9k_set_hw_capab(struct at
 			hw->wiphy->interface_modes |=
 					BIT(NL80211_IFTYPE_P2P_DEVICE);
 
-			hw->wiphy->iface_combinations = if_comb;
-			hw->wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
+		hw->wiphy->iface_combinations = if_comb;
+		hw->wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
 	}
 
 	hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
author maintainer
#21 lore raw

PATCH 28/73 iwlegacy: avoid warning about missing braces

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Arnd Bergmann <[email protected]>

commit 2cce76c3fab410520610a7d2f52faebc3cfcf843 upstream.

gcc-6 warns about code in il3945_hw_txq_ctx_free() being somewhat ambiguous:

drivers/net/wireless/intel/iwlegacy/3945.c:1022:5: warning: suggest explicit braces to avoid ambiguous 'else' [-Wparentheses]

This adds a set of curly braces to avoid the warning.

---
 drivers/net/wireless/iwlegacy/3945.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/wireless/iwlegacy/3945.c +2 -1
@@ -1019,12 +1019,13 @@ il3945_hw_txq_ctx_free(struct il_priv *i
 	int txq_id;
 
 	/* Tx queues */
-	if (il->txq)
+	if (il->txq) {
 		for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++)
 			if (txq_id == IL39_CMD_QUEUE_NUM)
 				il_cmd_queue_free(il);
 			else
 				il_tx_queue_free(il, txq_id);
+	}
 
 	/* free tx queue structure */
 	il_free_txq_mem(il);
author maintainer
#14 lore raw

PATCH 19/73 Kbuild: disable maybe-uninitialized warning for CONFIG_PROFILE_ALL_BRANCHES

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Arnd Bergmann <[email protected]>

commit 815eb71e7149ecce40db9dd0ad09c4dd9d33c60f upstream.

CONFIG_PROFILE_ALL_BRANCHES confuses gcc-5.x to the degree that it prints incorrect warnings about a lot of variables that it thinks can be used uninitialized, e.g.:

i2c/busses/i2c-diolan-u2c.c: In function 'diolan_usb_xfer':
i2c/busses/i2c-diolan-u2c.c:391:16: warning: 'byte' may be used uninitialized in this function iio/gyro/itg3200_core.c: In function 'itg3200_probe':
iio/gyro/itg3200_core.c:213:6: warning: 'val' may be used uninitialized in this function leds/leds-lp55xx-common.c: In function 'lp55xx_update_bits':
leds/leds-lp55xx-common.c:350:6: warning: 'tmp' may be used uninitialized in this function misc/bmp085.c: In function 'show_pressure':
misc/bmp085.c:363:10: warning: 'pressure' may be used uninitialized in this function power/ds2782_battery.c: In function 'ds2786_get_capacity':
power/ds2782_battery.c:214:17: warning: 'raw' may be used uninitialized in this function

These are all false positives that either rob someone's time when trying to figure out whether they are real, or they get people to send wrong patches to shut up the warnings.

Nobody normally wants to run a CONFIG_PROFILE_ALL_BRANCHES kernel in production, so disabling the whole class of warnings for this configuration has no serious downsides either.

Acked-by Steven Rostedt <rostedtgoodmis.org>
---
 Makefile |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
Makefile +5 -1
@@ -620,7 +620,11 @@ KBUILD_CFLAGS	+= $(call cc-option,-fno-d
 ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
 KBUILD_CFLAGS	+= -Os $(call cc-disable-warning,maybe-uninitialized,)
 else
-KBUILD_CFLAGS	+= -O2
+ifdef CONFIG_PROFILE_ALL_BRANCHES
+KBUILD_CFLAGS	+= -O2 $(call cc-disable-warning,maybe-uninitialized,)
+else
+KBUILD_CFLAGS   += -O2
+endif
 endif
 
 # Tell gcc to never replace conditional load with a non-conditional one
author maintainer
#56 lore raw

PATCH 64/73 MIPS: Remove compact branch policy Kconfig entries

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Paul Burton <[email protected]>

commit b03c1e3b8eed9026733c473071d1f528358a0e50 upstream.

Commit c1a0e9bc885d ("MIPS: Allow compact branch policy to be changed") added Kconfig entries allowing for the compact branch policy used by the compiler for MIPSr6 kernels to be specified. This can be useful for debugging, particularly in systems where compact branches have recently been introduced.

Unfortunately mainline gcc 5.x supports MIPSr6 but not the -mcompact-branches compiler flag, leading to MIPSr6 kernels failing to build with gcc 5.x with errors such as:

mipsel-linux-gnu-gcc: error: unrecognized command line option '-mcompact-branches=optimal' make[2]: *** [kernel/bounds.s] Error 1

Fixing this by hiding the Kconfig entry behind another seems to be more hassle than it's worth, as MIPSr6 & compact branches have been around for a while now and if policy does need to be set for debug it can be done easily enough with KCFLAGS. Therefore remove the compact branch policy Kconfig entries & their handling in the Makefile.

This reverts commit c1a0e9bc885d ("MIPS: Allow compact branch policy to be changed").

Fixes c1a0e9bc885d ("MIPS: Allow compact branch policy to be changed")

Patchwork: https://patchwork.linux-mips.org/patch/14241/

---
 arch/mips/Kconfig.debug |   36 ------------------------------------
 arch/mips/Makefile      |    4 ----
 2 files changed, 40 deletions(-)
arch/mips/Kconfig.debug +0 -36
@@ -113,42 +113,6 @@ config SPINLOCK_TEST
 	help
 	  Add several files to the debugfs to test spinlock speed.
 
-if CPU_MIPSR6
-
-choice
-	prompt "Compact branch policy"
-	default MIPS_COMPACT_BRANCHES_OPTIMAL
-
-config MIPS_COMPACT_BRANCHES_NEVER
-	bool "Never (force delay slot branches)"
-	help
-	  Pass the -mcompact-branches=never flag to the compiler in order to
-	  force it to always emit branches with delay slots, and make no use
-	  of the compact branch instructions introduced by MIPSr6. This is
-	  useful if you suspect there may be an issue with compact branches in
-	  either the compiler or the CPU.
-
-config MIPS_COMPACT_BRANCHES_OPTIMAL
-	bool "Optimal (use where beneficial)"
-	help
-	  Pass the -mcompact-branches=optimal flag to the compiler in order for
-	  it to make use of compact branch instructions where it deems them
-	  beneficial, and use branches with delay slots elsewhere. This is the
-	  default compiler behaviour, and should be used unless you have a
-	  reason to choose otherwise.
-
-config MIPS_COMPACT_BRANCHES_ALWAYS
-	bool "Always (force compact branches)"
-	help
-	  Pass the -mcompact-branches=always flag to the compiler in order to
-	  force it to always emit compact branches, making no use of branch
-	  instructions with delay slots. This can result in more compact code
-	  which may be beneficial in some scenarios.
-
-endchoice
-
-endif # CPU_MIPSR6
-
 config SCACHE_DEBUGFS
 	bool "L2 cache debugfs entries"
 	depends on DEBUG_FS
arch/mips/Makefile +0 -4
@@ -204,10 +204,6 @@ toolchain-msa				:= $(call cc-option-yn,
 cflags-$(toolchain-msa)			+= -DTOOLCHAIN_SUPPORTS_MSA
 endif
 
-cflags-$(CONFIG_MIPS_COMPACT_BRANCHES_NEVER)	+= -mcompact-branches=never
-cflags-$(CONFIG_MIPS_COMPACT_BRANCHES_OPTIMAL)	+= -mcompact-branches=optimal
-cflags-$(CONFIG_MIPS_COMPACT_BRANCHES_ALWAYS)	+= -mcompact-branches=always
-
 #
 # Firmware support
 #
author maintainer
#57 lore raw

PATCH 65/73 MIPS: Avoid a BUG warning during prctl(PR_SET_FP_MODE, ...)

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Marcin Nowakowski <[email protected]>

commit b244614a60ab7ce54c12a9cbe15cfbf8d79d0967 upstream.

cpu_has_fpu macro uses smp_processor_id() and is currently executed with preemption enabled, that triggers the warning at runtime.

It is assumed throughout the kernel that if any CPU has an FPU, then all CPUs would have an FPU as well, so it is safe to perform the check with preemption enabled - change the code to use raw_ variant of the check to avoid the warning.

Patchwork: https://patchwork.linux-mips.org/patch/14125/

---
 arch/mips/kernel/process.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
arch/mips/kernel/process.c +4 -4
@@ -593,14 +593,14 @@ int mips_set_process_fp_mode(struct task
 		return -EOPNOTSUPP;
 
 	/* Avoid inadvertently triggering emulation */
-	if ((value & PR_FP_MODE_FR) && cpu_has_fpu &&
-	    !(current_cpu_data.fpu_id & MIPS_FPIR_F64))
+	if ((value & PR_FP_MODE_FR) && raw_cpu_has_fpu &&
+	    !(raw_current_cpu_data.fpu_id & MIPS_FPIR_F64))
 		return -EOPNOTSUPP;
-	if ((value & PR_FP_MODE_FRE) && cpu_has_fpu && !cpu_has_fre)
+	if ((value & PR_FP_MODE_FRE) && raw_cpu_has_fpu && !cpu_has_fre)
 		return -EOPNOTSUPP;
 
 	/* FR = 0 not supported in MIPS R6 */
-	if (!(value & PR_FP_MODE_FR) && cpu_has_fpu && cpu_has_mips_r6)
+	if (!(value & PR_FP_MODE_FR) && raw_cpu_has_fpu && cpu_has_mips_r6)
 		return -EOPNOTSUPP;
 
 	/* Proceed with the mode switch */
author maintainer
#59 lore raw

PATCH 67/73 MIPS: paravirt: Fix undefined reference to smp_bootstrap

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Matt Redfearn <[email protected]>

commit 951c39cd3bc0aedf67fbd8fb4b9380287e6205d1 upstream.

If the paravirt machine is compiles without CONFIG_SMP, the following linker error occurs

arch/mips/kernel/head.o: In function `kernel_entry':
(.ref.text+0x10): undefined reference to `smp_bootstrap'

due to the kernel entry macro always including SMP startup code. Wrap this code in CONFIG_SMP to fix the error.

Patchwork: https://patchwork.linux-mips.org/patch/14212/

---
 arch/mips/include/asm/mach-paravirt/kernel-entry-init.h |    2 ++
 1 file changed, 2 insertions(+)
arch/mips/include/asm/mach-paravirt/kernel-entry-init.h +2 -0
@@ -11,11 +11,13 @@
 #define CP0_EBASE $15, 1
 
 	.macro  kernel_entry_setup
+#ifdef CONFIG_SMP
 	mfc0	t0, CP0_EBASE
 	andi	t0, t0, 0x3ff		# CPUNum
 	beqz	t0, 1f
 	# CPUs other than zero goto smp_bootstrap
 	j	smp_bootstrap
+#endif /* CONFIG_SMP */
 
 1:
 	.endm
author maintainer
#60 lore raw

PATCH 68/73 PM / hibernate: Restore processor state before using per-CPU variables

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Thomas Garnier <[email protected]>

commit 62822e2ec4ad091ba31f823f577ef80db52e3c2c upstream.

Restore the processor state before calling any other functions to ensure per-CPU variables can be used with KASLR memory randomization.

Tracing functions use per-CPU variables (GS based on x86) and one was called just before restoring the processor state fully. It resulted in a double fault when both the tracing & the exception handler functions tried to use a per-CPU variable.

---
 kernel/power/hibernate.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/power/hibernate.c +2 -2
@@ -299,12 +299,12 @@ static int create_image(int platform_mod
 	save_processor_state();
 	trace_suspend_resume(TPS("machine_suspend"), PM_EVENT_HIBERNATE, true);
 	error = swsusp_arch_suspend();
+	/* Restore control flow magically appears here */
+	restore_processor_state();
 	trace_suspend_resume(TPS("machine_suspend"), PM_EVENT_HIBERNATE, false);
 	if (error)
 		printk(KERN_ERR "PM: Error %d creating hibernation image\n",
 			error);
-	/* Restore control flow magically appears here */
-	restore_processor_state();
 	if (!in_suspend)
 		events_check_enabled = false;
 
author maintainer
#58 lore raw

PATCH 66/73 MIPS: Add a missing ".set pop" in an early commit

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Huacai Chen <[email protected]>

commit 3cbc6fc9c99f1709203711f125bc3b79487aba06 upstream.

Commit 842dfc11ea9a21 ("MIPS: Fix build with binutils 2.24.51+") missing a ".set pop" in macro fpu_restore_16even, so add it.

Patchwork: https://patchwork.linux-mips.org/patch/14210/

---
 arch/mips/include/asm/asmmacro.h |    1 +
 1 file changed, 1 insertion(+)
arch/mips/include/asm/asmmacro.h +1 -0
@@ -135,6 +135,7 @@
 	ldc1	$f28, THREAD_FPR28(\thread)
 	ldc1	$f30, THREAD_FPR30(\thread)
 	ctc1	\tmp, fcr31
+	.set	pop
 	.endm
 
 	.macro	fpu_restore_16odd thread
author maintainer
#62 lore raw

PATCH 70/73 power_supply: tps65217-charger: fix missing platform_set_drvdata()

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Wei Yongjun <[email protected]>

commit 33e7664a0af6e9a516f01014f39737aaa119b6d9 upstream.

Add missing platform_set_drvdata() in tps65217_charger_probe(), otherwise calling platform_get_drvdata() in remove returns NULL.

This is detected by Coccinelle semantic patch.

Fixes 3636859b280c ("power_supply: Add support for tps65217-charger")
---
 drivers/power/tps65217_charger.c |    1 +
 1 file changed, 1 insertion(+)
drivers/power/tps65217_charger.c +1 -0
@@ -205,6 +205,7 @@ static int tps65217_charger_probe(struct
 	if (!charger)
 		return -ENOMEM;
 
+	platform_set_drvdata(pdev, charger);
 	charger->tps = tps;
 	charger->dev = &pdev->dev;
 
author maintainer
#65 lore raw

PATCH 73/73 hostfs: Freeing an ERR_PTR in hostfs_fill_sb_common()

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Dan Carpenter <[email protected]>

commit 8a545f185145e3c09348cd74326268ecfc6715a3 upstream.

We can't pass error pointers to kfree() or it causes an oops.

Fixes 52b209f7b848 ('get rid of hostfs_read_inode()')
---
 fs/hostfs/hostfs_kern.c |    7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
fs/hostfs/hostfs_kern.c +4 -3
@@ -959,10 +959,11 @@ static int hostfs_fill_sb_common(struct
 
 	if (S_ISLNK(root_inode->i_mode)) {
 		char *name = follow_link(host_root_path);
-		if (IS_ERR(name))
+		if (IS_ERR(name)) {
 			err = PTR_ERR(name);
-		else
-			err = read_name(root_inode, name);
+			goto out_put;
+		}
+		err = read_name(root_inode, name);
 		kfree(name);
 		if (err)
 			goto out_put;
author maintainer
#53 lore raw

PATCH 60/73 i2c: qup: skip qup_i2c_suspend if the device is already runtime suspended

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Sudeep Holla <[email protected]>

commit 331dcf421c34d227784d07943eb01e4023a42b0a upstream.

If the i2c device is already runtime suspended, if qup_i2c_suspend is executed during suspend-to-idle or suspend-to-ram it will result in the following splat:

WARNING: CPU: 3 PID: 1593 at drivers/clk/clk.c:476 clk_core_unprepare+0x80/0x90
Modules linked in:

CPU: 3 PID: 1593 Comm: bash Tainted: G        W       4.8.0-rc3 #14
Hardware name: Qualcomm Technologies, Inc. APQ 8016 SBC (DT)
PC is at clk_core_unprepare+0x80/0x90
LR is at clk_unprepare+0x28/0x40
pc : [<ffff0000086eecf0>] lr : [<ffff0000086f0c58>] pstate: 60000145
Call trace:
 clk_core_unprepare+0x80/0x90
 qup_i2c_disable_clocks+0x2c/0x68
 qup_i2c_suspend+0x10/0x20
 platform_pm_suspend+0x24/0x68
 ...

This patch fixes the issue by executing qup_i2c_pm_suspend_runtime conditionally in qup_i2c_suspend.

---
 drivers/i2c/busses/i2c-qup.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/i2c/busses/i2c-qup.c +2 -1
@@ -727,7 +727,8 @@ static int qup_i2c_pm_resume_runtime(str
 #ifdef CONFIG_PM_SLEEP
 static int qup_i2c_suspend(struct device *device)
 {
-	qup_i2c_pm_suspend_runtime(device);
+	if (!pm_runtime_suspended(device))
+		return qup_i2c_pm_suspend_runtime(device);
 	return 0;
 }
 
author maintainer
#55 lore raw

PATCH 63/73 MIPS: vDSO: Fix Malta EVA mapping to vDSO page structs

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: James Hogan <[email protected]>

commit 554af0c396380baf416f54c439b99b495180b2f4 upstream.

The page structures associated with the vDSO pages in the kernel image are calculated using virt_to_page(), which uses __pa() under the hood to find the pfn associated with the virtual address. The vDSO data pointers however point to kernel symbols, so __pa_symbol() should really be used instead.

Since there is no equivalent to virt_to_page() which uses __pa_symbol(), fix init_vdso_image() to work directly with pfns, calculated with __phys_to_pfn(__pa_symbol(...)).

This issue broke the Malta Enhanced Virtual Addressing (EVA) configuration which has a non-default implementation of __pa_symbol(). This is because it uses a physical alias so that the kernel executes from KSeg0 (VA 0x80000000 -> PA 0x00000000), while RAM is provided to the kernel in the KUSeg range (VA 0x00000000 -> PA 0x80000000) which uses the same underlying RAM.

Since there are no page structures associated with the low physical address region, some arbitrary kernel memory would be interpreted as a page structure for the vDSO pages and badness ensues.

Fixes ebb5e78cc634 ("MIPS: Initial implementation of a VDSO")
Cc Leonid Yegoshin <[email protected]>

Patchwork: https://patchwork.linux-mips.org/patch/14229/

---
 arch/mips/kernel/vdso.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
arch/mips/kernel/vdso.c +4 -4
@@ -39,16 +39,16 @@ static struct vm_special_mapping vdso_vv
 static void __init init_vdso_image(struct mips_vdso_image *image)
 {
 	unsigned long num_pages, i;
+	unsigned long data_pfn;
 
 	BUG_ON(!PAGE_ALIGNED(image->data));
 	BUG_ON(!PAGE_ALIGNED(image->size));
 
 	num_pages = image->size / PAGE_SIZE;
 
-	for (i = 0; i < num_pages; i++) {
-		image->mapping.pages[i] =
-			virt_to_page(image->data + (i * PAGE_SIZE));
-	}
+	data_pfn = __phys_to_pfn(__pa_symbol(image->data));
+	for (i = 0; i < num_pages; i++)
+		image->mapping.pages[i] = pfn_to_page(data_pfn + i);
 }
 
 static int __init init_vdso(void)
author maintainer
#50 lore raw

PATCH 57/73 nl80211: validate number of probe response CSA counters

In reply to Greg Kroah-Hartman

4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johannes Berg <[email protected]>

commit ad5987b47e96a0fb6d13fea250e936aed000093c upstream.

Due to an apparent copy/paste bug, the number of counters for the beacon configuration were checked twice, instead of checking the number of probe response counters. Fix this to check the number of probe response counters before parsing those.

Fixes 9a774c78e211 ("cfg80211: Support multiple CSA counters")
---
 net/wireless/nl80211.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/wireless/nl80211.c +1 -1
@@ -6628,7 +6628,7 @@ static int nl80211_channel_switch(struct
 
 		params.n_counter_offsets_presp = len / sizeof(u16);
 		if (rdev->wiphy.max_num_csa_counters &&
-		    (params.n_counter_offsets_beacon >
+		    (params.n_counter_offsets_presp >
 		     rdev->wiphy.max_num_csa_counters))
 			return -EINVAL;
 
#66 lore raw
In reply to Greg Kroah-Hartman
Quoted 9 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 4.4.23 release. There are 73 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.

Responses should be made by Fri Sep 30 09:04:22 UTC 2016. Anything received after that time might be too late.

The whole patch series can be found in one patch at:

Quoted 9 lines
	kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.4.23-rc1.gz

or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.4.y
and the diffstat can be found below.

thanks,

greg k-h

Compiled and booted on my test system. No dmesg regressions.

thanks,
-- Shuah

Signature · 5 lines
Shuah Khan
Sr. Linux Kernel Developer
Open Source Innovation Group
Samsung Research America(Silicon Valley)
[email protected]
#67 lore raw
In reply to Greg Kroah-Hartman
Quoted 8 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 4.4.23 release. There are 73 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.

Responses should be made by Fri Sep 30 09:04:22 UTC 2016. Anything received after that time might be too late.

Build results:

	total: 149 pass: 149 fail: 0
Qemu test results:
	total: 101 pass: 101 fail: 0

Details are available at http://kerneltests.org/builders.

Guenter

author maintainer
#69 lore raw
In reply to a message not in the archive
Quoted 12 lines · kernelci.org bot

stable-rc boot: 103 boots: 1 failed, 100 passed with 2 offline (v4.4.22-74-g060fb6041a6c)

Full Boot Summary: https://kernelci.org/boot/all/job/stable-rc/kernel/v4.4.22-74-g060fb6041a6c/
Full Build Summary: https://kernelci.org/build/stable-rc/kernel/v4.4.22-74-g060fb6041a6c/

Tree: stable-rc
Branch: local/linux-4.4.y
Git Describe: v4.4.22-74-g060fb6041a6c
Git Commit: 060fb6041a6c284fb7da4a8038d45dd9f1d82e36
Git URL: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
Tested: 29 unique boards, 12 SoC families, 19 builds out of 201

Quoted 6 lines

Boot Failure Detected: https://kernelci.org/boot/?v4.4.22-74-g060fb6041a6c&fail

arm:

multi_v7_defconfig+CONFIG_PROVE_LOCKING=y:
at91-sama5d3_xplained: 1 failed lab

same failure as for 4.7?