Skip to contentSkip to conversation

4.4.48-stable review

PATCH In review Greg Kroah-Hartman 4 participants 31 messages Feb 7, 2017 – Feb 8, 2017 1 message not in the archive Stable branch

lore
Share & tools
lore

Greg Kroah-Hartman

author maintainer
#0 lore raw

cover 4.4.48-stable review

This is the start of the stable review cycle for the 4.4.48 release. There are 29 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 Thu Feb 9 12:44:43 UTC 2017. 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.48-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.48-rc1

Toshi Kani <[email protected]>
base/memory, hotplug: fix a kernel oops in show_valid_zones()

Thomas Gleixner <[email protected]>
x86/irq: Make irq activate operations symmetric

Bjørn Mork <[email protected]>
USB: serial: option: add device ID for HP lt2523 (Novatel E371)

Vincent Pelletier <[email protected]>
usb: gadget: f_fs: Assorted buffer overflow checks.

Lukáš Lalinský <[email protected]>
USB: Add quirk for WORLDE easykey.25 MIDI keyboard

Marcel J.E. Mol <[email protected]>
USB: serial: pl2303: add ATEN device ID

Aleksander Morgado <[email protected]>
USB: serial: qcserial: add Dell DW5570 QDL

Radim Krčmář <[email protected]>
KVM: x86: do not save guest-unsupported XSAVE state

Jason Gerecke <[email protected]>
HID: wacom: Fix poor prox handling in 'wacom_pl_irq'

Douglas Miller <[email protected]>
percpu-refcount: fix reference leak during percpu-atomic transition

Gabriel Krisman Bertazi <[email protected]>
mmc: sdhci: Ignore unexpected CARD_INT interrupts

Oliver Hartkopp <[email protected]>
can: bcm: fix hrtimer/tasklet termination in bcm op removal

Michal Hocko <[email protected]>
mm, fs: check for fatal signals in do_generic_file_read()

Toshi Kani <[email protected]>
mm/memory_hotplug.c: check start_pfn in test_pages_in_a_zone()

Rabin Vincent <[email protected]>
cifs: initialize file_info_lock

Dan Streetman <[email protected]>
zswap: disable changing params if init fails

J. Bruce Fields <[email protected]>
svcrpc: fix oops in absence of krb5 module

Kinglong Mee <[email protected]>
NFSD: Fix a null reference case in find_or_create_lock_stateid()

Darren Stevens <[email protected]>
powerpc: Add missing error check to prom_find_boot_cpu()

Gavin Shan <[email protected]>
powerpc/eeh: Fix wrong flag passed to eeh_unfreeze_pe()

Tejun Heo <[email protected]>
libata: apply MAX_SEC_1024 to all CX1-JB*-HP devices

Arvind Yadav <[email protected]>
ata: sata_mv:- Handle return value of devm_ioremap.

Peter Zijlstra <[email protected]>
perf/core: Fix PERF_RECORD_MMAP2 prot/flags for anonymous memory

Ard Biesheuvel <[email protected]>
crypto: arm64/aes-blk - honour iv_out requirement in CBC and CTR modes

Salvatore Benedetto <[email protected]>
crypto: api - Clear CRYPTO_ALG_DEAD bit before registering an alg

Ilia Mirkin <[email protected]>
drm/nouveau/nv1a,nv1f/disp: fix memory clock rate retrieval

Alastair Bridgewater <[email protected]>
drm/nouveau/disp/gt215: Fix HDA ELD handling (thus, HDMI audio) on gt215

Eryu Guan <[email protected]>
ext4: validate s_first_meta_bg at mount time

Bjorn Helgaas <[email protected]>
PCI/ASPM: Handle PCI-to-PCIe bridges as roots of PCIe hierarchies

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

Diffstat:

 Makefile                                           |  4 +-
 arch/arm64/crypto/aes-modes.S                      | 88 +++++++++++-----------
 arch/powerpc/kernel/eeh_driver.c                   |  2 +-
 arch/powerpc/kernel/prom_init.c                    |  3 +
 arch/x86/kernel/apic/io_apic.c                     |  2 +
 arch/x86/kernel/hpet.c                             |  1 +
 arch/x86/kvm/x86.c                                 |  1 +
 crypto/algapi.c                                    |  1 +
 drivers/ata/libata-core.c                          |  4 +-
 drivers/ata/sata_mv.c                              |  3 +
 drivers/base/memory.c                              | 11 ++-
 drivers/gpu/drm/nouveau/dispnv04/hw.c              |  3 +-
 .../gpu/drm/nouveau/nvkm/engine/disp/hdagt215.c    |  2 +-
 drivers/hid/wacom_wac.c                            | 28 +++----
 drivers/mmc/host/sdhci.c                           |  3 +-
 drivers/pci/pcie/aspm.c                            | 19 +++--
 drivers/usb/core/quirks.c                          |  4 +
 drivers/usb/gadget/function/f_fs.c                 | 13 +++-
 drivers/usb/serial/option.c                        |  1 +
 drivers/usb/serial/pl2303.c                        |  1 +
 drivers/usb/serial/pl2303.h                        |  1 +
 drivers/usb/serial/qcserial.c                      |  1 +
 fs/cifs/readdir.c                                  |  1 +
 fs/ext4/super.c                                    |  9 +++
 fs/nfsd/nfs4layouts.c                              |  5 +-
 fs/nfsd/nfs4state.c                                | 19 ++---
 fs/nfsd/state.h                                    |  4 +-
 include/linux/memory_hotplug.h                     |  3 +-
 include/linux/percpu-refcount.h                    |  4 +-
 kernel/events/core.c                               | 42 +++++------
 mm/filemap.c                                       |  5 ++
 mm/memory_hotplug.c                                | 28 +++++--
 mm/zswap.c                                         | 30 +++++++-
 net/can/bcm.c                                      | 23 ++++--
 net/sunrpc/auth_gss/gss_rpc_xdr.c                  |  2 +-
 35 files changed, 236 insertions(+), 135 deletions(-)
author maintainer
#1 lore raw

PATCH 1/29 PCI/ASPM: Handle PCI-to-PCIe bridges as roots of PCIe hierarchies

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

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

From: Bjorn Helgaas <[email protected]>

commit 030305d69fc6963c16003f50d7e8d74b02d0a143 upstream.

In a struct pcie_link_state, link->root points to the pcie_link_state of the root of the PCIe hierarchy. For the topmost link, this points to itself (link->root = link). For others, we copy the pointer from the parent (link->root = link->parent->root).

Previously we recognized that Root Ports originated PCIe hierarchies, but we treated PCI/PCI-X to PCIe Bridges as being in the middle of the hierarchy, and when we tried to copy the pointer from link->parent->root, there was no parent, and we dereferenced a NULL pointer:

  BUG: unable to handle kernel NULL pointer dereference at 0000000000000090
  IP: [<ffffffff9e424350>] pcie_aspm_init_link_state+0x170/0x820

Recognize that PCI/PCI-X to PCIe Bridges originate PCIe hierarchies just like Root Ports do, so link->root for these devices should also point to itself.

---
 drivers/pci/pcie/aspm.c |   19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)
drivers/pci/pcie/aspm.c +13 -6
@@ -518,25 +518,32 @@ static struct pcie_link_state *alloc_pci
 	link = kzalloc(sizeof(*link), GFP_KERNEL);
 	if (!link)
 		return NULL;
+
 	INIT_LIST_HEAD(&link->sibling);
 	INIT_LIST_HEAD(&link->children);
 	INIT_LIST_HEAD(&link->link);
 	link->pdev = pdev;
-	if (pci_pcie_type(pdev) != PCI_EXP_TYPE_ROOT_PORT) {
+
+	/*
+	 * Root Ports and PCI/PCI-X to PCIe Bridges are roots of PCIe
+	 * hierarchies.
+	 */
+	if (pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT ||
+	    pci_pcie_type(pdev) == PCI_EXP_TYPE_PCIE_BRIDGE) {
+		link->root = link;
+	} else {
 		struct pcie_link_state *parent;
+
 		parent = pdev->bus->parent->self->link_state;
 		if (!parent) {
 			kfree(link);
 			return NULL;
 		}
+
 		link->parent = parent;
+		link->root = link->parent->root;
 		list_add(&link->link, &parent->children);
 	}
-	/* Setup a pointer to the root port link */
-	if (!link->parent)
-		link->root = link;
-	else
-		link->root = link->parent->root;
 
 	list_add(&link->sibling, &link_list);
 	pdev->link_state = link;
author maintainer
#2 lore raw

PATCH 2/29 ext4: validate s_first_meta_bg at mount time

In reply to Greg Kroah-Hartman

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

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

From: Eryu Guan <[email protected]>

commit 3a4b77cd47bb837b8557595ec7425f281f2ca1fe upstream.

Ralf Spenneberg reported that he hit a kernel crash when mounting a modified ext4 image. And it turns out that kernel crashed when calculating fs overhead (ext4_calculate_overhead()), this is because the image has very large s_first_meta_bg (debug code shows it's 842150400), and ext4 overruns the memory in count_overhead() when setting bitmap buffer, which is PAGE_SIZE.

ext4_calculate_overhead():
buf = get_zeroed_page(GFP_NOFS); <=== PAGE_SIZE buffer blks = count_overhead(sb, i, buf);

count_overhead():
for (j = ext4_bg_num_gdb(sb, grp); j > 0; j--) { <=== j = 842150400

          ext4_set_bit(EXT4_B2C(sbi, s++), buf);   <=== buffer overrun
          count++;

}

This can be reproduced easily for me by this script:

#!/bin/bash
rm -f fs.img
mkdir -p /mnt/ext4
fallocate -l 16M fs.img
mke2fs -t ext4 -O bigalloc,meta_bg,^resize_inode -F fs.img debugfs -w -R "ssv first_meta_bg 842150400" fs.img mount -o loop fs.img /mnt/ext4

Fix it by validating s_first_meta_bg first at mount time, and refusing to mount if its value exceeds the largest possible meta_bg number.

---
 fs/ext4/super.c |    9 +++++++++
 1 file changed, 9 insertions(+)
fs/ext4/super.c +9 -0
@@ -3663,6 +3663,15 @@ static int ext4_fill_super(struct super_
 			(EXT4_MAX_BLOCK_FILE_PHYS / EXT4_BLOCKS_PER_GROUP(sb)));
 	db_count = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - 1) /
 		   EXT4_DESC_PER_BLOCK(sb);
+	if (ext4_has_feature_meta_bg(sb)) {
+		if (le32_to_cpu(es->s_first_meta_bg) >= db_count) {
+			ext4_msg(sb, KERN_WARNING,
+				 "first meta block group too large: %u "
+				 "(group descriptor block count %u)",
+				 le32_to_cpu(es->s_first_meta_bg), db_count);
+			goto failed_mount;
+		}
+	}
 	sbi->s_group_desc = ext4_kvmalloc(db_count *
 					  sizeof(struct buffer_head *),
 					  GFP_KERNEL);
author maintainer
#3 lore raw

PATCH 3/29 drm/nouveau/disp/gt215: Fix HDA ELD handling (thus, HDMI audio) on gt215

In reply to Greg Kroah-Hartman

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

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

From: Alastair Bridgewater <[email protected]>

commit d347583a39e2df609a9e40c835f72d3614665b53 upstream.

Store the ELD correctly, not just enough copies of the first byte to pad out the given ELD size.

Fixes 120b0c39c756 ("drm/nv50-/disp: audit and version SOR_HDA_ELD method")
---
 drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagt215.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagt215.c +1 -1
@@ -59,7 +59,7 @@ gt215_hda_eld(NV50_DISP_MTHD_V1)
 			);
 		}
 		for (i = 0; i < size; i++)
-			nvkm_wr32(device, 0x61c440 + soff, (i << 8) | args->v0.data[0]);
+			nvkm_wr32(device, 0x61c440 + soff, (i << 8) | args->v0.data[i]);
 		for (; i < 0x60; i++)
 			nvkm_wr32(device, 0x61c440 + soff, (i << 8));
 		nvkm_mask(device, 0x61c448 + soff, 0x80000003, 0x80000003);
author maintainer
#4 lore raw

PATCH 4/29 drm/nouveau/nv1a,nv1f/disp: fix memory clock rate retrieval

In reply to Greg Kroah-Hartman

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

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

From: Ilia Mirkin <[email protected]>

commit 24bf7ae359b8cca165bb30742d2b1c03a1eb23af upstream.

Based on the xf86-video-nv code, NFORCE (NV1A) and NFORCE2 (NV1F) have a different way of retrieving clocks. See the nv_hw.c:nForceUpdateArbitrationSettings function in the original code for how these clocks were accessed.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=54587

---
 drivers/gpu/drm/nouveau/dispnv04/hw.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/nouveau/dispnv04/hw.c +2 -1
@@ -222,6 +222,7 @@ nouveau_hw_get_clock(struct drm_device *
 		uint32_t mpllP;
 
 		pci_read_config_dword(pci_get_bus_and_slot(0, 3), 0x6c, &mpllP);
+		mpllP = (mpllP >> 8) & 0xf;
 		if (!mpllP)
 			mpllP = 4;
 
@@ -232,7 +233,7 @@ nouveau_hw_get_clock(struct drm_device *
 		uint32_t clock;
 
 		pci_read_config_dword(pci_get_bus_and_slot(0, 5), 0x4c, &clock);
-		return clock;
+		return clock / 1000;
 	}
 
 	ret = nouveau_hw_get_pllvals(dev, plltype, &pllvals);
author maintainer
#5 lore raw

PATCH 5/29 crypto: api - Clear CRYPTO_ALG_DEAD bit before registering an alg

In reply to Greg Kroah-Hartman

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

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

From: Salvatore Benedetto <[email protected]>

commit d6040764adcb5cb6de1489422411d701c158bb69 upstream.

Make sure CRYPTO_ALG_DEAD bit is cleared before proceeding with the algorithm registration. This fixes qat-dh registration when driver is restarted

---
 crypto/algapi.c |    1 +
 1 file changed, 1 insertion(+)
crypto/algapi.c +1 -0
@@ -357,6 +357,7 @@ int crypto_register_alg(struct crypto_al
 	struct crypto_larval *larval;
 	int err;
 
+	alg->cra_flags &= ~CRYPTO_ALG_DEAD;
 	err = crypto_check_alg(alg);
 	if (err)
 		return err;
author maintainer
#6 lore raw

PATCH 6/29 crypto: arm64/aes-blk - honour iv_out requirement in CBC and CTR modes

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 11e3b725cfc282efe9d4a354153e99d86a16af08 upstream.

Update the ARMv8 Crypto Extensions and the plain NEON AES implementations in CBC and CTR modes to return the next IV back to the skcipher API client. This is necessary for chaining to work correctly.

Note that for CTR, this is only done if the request is a round multiple of the block size, since otherwise, chaining is impossible anyway.

---
 arch/arm64/crypto/aes-modes.S |   88 ++++++++++++++++++++----------------------
 1 file changed, 42 insertions(+), 46 deletions(-)
arch/arm64/crypto/aes-modes.S +42 -46
@@ -193,15 +193,16 @@ AES_ENTRY(aes_cbc_encrypt)
 	cbz		w6, .Lcbcencloop
 
 	ld1		{v0.16b}, [x5]			/* get iv */
-	enc_prepare	w3, x2, x5
+	enc_prepare	w3, x2, x6
 
 .Lcbcencloop:
 	ld1		{v1.16b}, [x1], #16		/* get next pt block */
 	eor		v0.16b, v0.16b, v1.16b		/* ..and xor with iv */
-	encrypt_block	v0, w3, x2, x5, w6
+	encrypt_block	v0, w3, x2, x6, w7
 	st1		{v0.16b}, [x0], #16
 	subs		w4, w4, #1
 	bne		.Lcbcencloop
+	st1		{v0.16b}, [x5]			/* return iv */
 	ret
 AES_ENDPROC(aes_cbc_encrypt)
 
@@ -211,7 +212,7 @@ AES_ENTRY(aes_cbc_decrypt)
 	cbz		w6, .LcbcdecloopNx
 
 	ld1		{v7.16b}, [x5]			/* get iv */
-	dec_prepare	w3, x2, x5
+	dec_prepare	w3, x2, x6
 
 .LcbcdecloopNx:
 #if INTERLEAVE >= 2
@@ -248,7 +249,7 @@ AES_ENTRY(aes_cbc_decrypt)
 .Lcbcdecloop:
 	ld1		{v1.16b}, [x1], #16		/* get next ct block */
 	mov		v0.16b, v1.16b			/* ...and copy to v0 */
-	decrypt_block	v0, w3, x2, x5, w6
+	decrypt_block	v0, w3, x2, x6, w7
 	eor		v0.16b, v0.16b, v7.16b		/* xor with iv => pt */
 	mov		v7.16b, v1.16b			/* ct is next iv */
 	st1		{v0.16b}, [x0], #16
@@ -256,6 +257,7 @@ AES_ENTRY(aes_cbc_decrypt)
 	bne		.Lcbcdecloop
 .Lcbcdecout:
 	FRAME_POP
+	st1		{v7.16b}, [x5]			/* return iv */
 	ret
 AES_ENDPROC(aes_cbc_decrypt)
 
@@ -267,24 +269,15 @@ AES_ENDPROC(aes_cbc_decrypt)
 
 AES_ENTRY(aes_ctr_encrypt)
 	FRAME_PUSH
-	cbnz		w6, .Lctrfirst		/* 1st time around? */
-	umov		x5, v4.d[1]		/* keep swabbed ctr in reg */
-	rev		x5, x5
-#if INTERLEAVE >= 2
-	cmn		w5, w4			/* 32 bit overflow? */
-	bcs		.Lctrinc
-	add		x5, x5, #1		/* increment BE ctr */
-	b		.LctrincNx
-#else
-	b		.Lctrinc
-#endif
-.Lctrfirst:
+	cbz		w6, .Lctrnotfirst	/* 1st time around? */
 	enc_prepare	w3, x2, x6
 	ld1		{v4.16b}, [x5]
-	umov		x5, v4.d[1]		/* keep swabbed ctr in reg */
-	rev		x5, x5
+
+.Lctrnotfirst:
+	umov		x8, v4.d[1]		/* keep swabbed ctr in reg */
+	rev		x8, x8
 #if INTERLEAVE >= 2
-	cmn		w5, w4			/* 32 bit overflow? */
+	cmn		w8, w4			/* 32 bit overflow? */
 	bcs		.Lctrloop
 .LctrloopNx:
 	subs		w4, w4, #INTERLEAVE
@@ -292,11 +285,11 @@ AES_ENTRY(aes_ctr_encrypt)
 #if INTERLEAVE == 2
 	mov		v0.8b, v4.8b
 	mov		v1.8b, v4.8b
-	rev		x7, x5
-	add		x5, x5, #1
+	rev		x7, x8
+	add		x8, x8, #1
 	ins		v0.d[1], x7
-	rev		x7, x5
-	add		x5, x5, #1
+	rev		x7, x8
+	add		x8, x8, #1
 	ins		v1.d[1], x7
 	ld1		{v2.16b-v3.16b}, [x1], #32	/* get 2 input blocks */
 	do_encrypt_block2x
@@ -305,7 +298,7 @@ AES_ENTRY(aes_ctr_encrypt)
 	st1		{v0.16b-v1.16b}, [x0], #32
 #else
 	ldr		q8, =0x30000000200000001	/* addends 1,2,3[,0] */
-	dup		v7.4s, w5
+	dup		v7.4s, w8
 	mov		v0.16b, v4.16b
 	add		v7.4s, v7.4s, v8.4s
 	mov		v1.16b, v4.16b
@@ -323,18 +316,12 @@ AES_ENTRY(aes_ctr_encrypt)
 	eor		v2.16b, v7.16b, v2.16b
 	eor		v3.16b, v5.16b, v3.16b
 	st1		{v0.16b-v3.16b}, [x0], #64
-	add		x5, x5, #INTERLEAVE
+	add		x8, x8, #INTERLEAVE
 #endif
-	cbz		w4, .LctroutNx
-.LctrincNx:
-	rev		x7, x5
+	rev		x7, x8
 	ins		v4.d[1], x7
+	cbz		w4, .Lctrout
 	b		.LctrloopNx
-.LctroutNx:
-	sub		x5, x5, #1
-	rev		x7, x5
-	ins		v4.d[1], x7
-	b		.Lctrout
 .Lctr1x:
 	adds		w4, w4, #INTERLEAVE
 	beq		.Lctrout
@@ -342,30 +329,39 @@ AES_ENTRY(aes_ctr_encrypt)
 .Lctrloop:
 	mov		v0.16b, v4.16b
 	encrypt_block	v0, w3, x2, x6, w7
+
+	adds		x8, x8, #1		/* increment BE ctr */
+	rev		x7, x8
+	ins		v4.d[1], x7
+	bcs		.Lctrcarry		/* overflow? */
+
+.Lctrcarrydone:
 	subs		w4, w4, #1
 	bmi		.Lctrhalfblock		/* blocks < 0 means 1/2 block */
 	ld1		{v3.16b}, [x1], #16
 	eor		v3.16b, v0.16b, v3.16b
 	st1		{v3.16b}, [x0], #16
-	beq		.Lctrout
-.Lctrinc:
-	adds		x5, x5, #1		/* increment BE ctr */
-	rev		x7, x5
-	ins		v4.d[1], x7
-	bcc		.Lctrloop		/* no overflow? */
-	umov		x7, v4.d[0]		/* load upper word of ctr  */
-	rev		x7, x7			/* ... to handle the carry */
-	add		x7, x7, #1
-	rev		x7, x7
-	ins		v4.d[0], x7
-	b		.Lctrloop
+	bne		.Lctrloop
+
+.Lctrout:
+	st1		{v4.16b}, [x5]		/* return next CTR value */
+	FRAME_POP
+	ret
+
 .Lctrhalfblock:
 	ld1		{v3.8b}, [x1]
 	eor		v3.8b, v0.8b, v3.8b
 	st1		{v3.8b}, [x0]
-.Lctrout:
 	FRAME_POP
 	ret
+
+.Lctrcarry:
+	umov		x7, v4.d[0]		/* load upper word of ctr  */
+	rev		x7, x7			/* ... to handle the carry */
+	add		x7, x7, #1
+	rev		x7, x7
+	ins		v4.d[0], x7
+	b		.Lctrcarrydone
 AES_ENDPROC(aes_ctr_encrypt)
 	.ltorg
 
author maintainer
#7 lore raw

PATCH 7/29 perf/core: Fix PERF_RECORD_MMAP2 prot/flags for anonymous memory

In reply to Greg Kroah-Hartman

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

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

From: Peter Zijlstra <[email protected]>

commit 0b3589be9b98994ce3d5aeca52445d1f5627c4ba upstream.

Andres reported that MMAP2 records for anonymous memory always have their protection field 0.

Turns out, someone daft put the prot/flags generation code in the file branch, leaving them unset for anonymous memory.

Cc Alexander Shishkin <[email protected]>
Cc Arnaldo Carvalho de Melo <[email protected]>
Cc Don Zickus <[email protected]
Cc Jiri Olsa <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Stephane Eranian <[email protected]>
Cc Stephane Eranian <[email protected]>
Cc Thomas Gleixner <[email protected]>
Fixes f972eb63b100 ("perf: Pass protection and flags bits through mmap2 interface")
---
 kernel/events/core.c |   42 +++++++++++++++++++++---------------------
 1 file changed, 21 insertions(+), 21 deletions(-)
kernel/events/core.c +21 -21
@@ -6039,6 +6039,27 @@ static void perf_event_mmap_event(struct
 	char *buf = NULL;
 	char *name;
 
+	if (vma->vm_flags & VM_READ)
+		prot |= PROT_READ;
+	if (vma->vm_flags & VM_WRITE)
+		prot |= PROT_WRITE;
+	if (vma->vm_flags & VM_EXEC)
+		prot |= PROT_EXEC;
+
+	if (vma->vm_flags & VM_MAYSHARE)
+		flags = MAP_SHARED;
+	else
+		flags = MAP_PRIVATE;
+
+	if (vma->vm_flags & VM_DENYWRITE)
+		flags |= MAP_DENYWRITE;
+	if (vma->vm_flags & VM_MAYEXEC)
+		flags |= MAP_EXECUTABLE;
+	if (vma->vm_flags & VM_LOCKED)
+		flags |= MAP_LOCKED;
+	if (vma->vm_flags & VM_HUGETLB)
+		flags |= MAP_HUGETLB;
+
 	if (file) {
 		struct inode *inode;
 		dev_t dev;
@@ -6065,27 +6086,6 @@ static void perf_event_mmap_event(struct
 		maj = MAJOR(dev);
 		min = MINOR(dev);
 
-		if (vma->vm_flags & VM_READ)
-			prot |= PROT_READ;
-		if (vma->vm_flags & VM_WRITE)
-			prot |= PROT_WRITE;
-		if (vma->vm_flags & VM_EXEC)
-			prot |= PROT_EXEC;
-
-		if (vma->vm_flags & VM_MAYSHARE)
-			flags = MAP_SHARED;
-		else
-			flags = MAP_PRIVATE;
-
-		if (vma->vm_flags & VM_DENYWRITE)
-			flags |= MAP_DENYWRITE;
-		if (vma->vm_flags & VM_MAYEXEC)
-			flags |= MAP_EXECUTABLE;
-		if (vma->vm_flags & VM_LOCKED)
-			flags |= MAP_LOCKED;
-		if (vma->vm_flags & VM_HUGETLB)
-			flags |= MAP_HUGETLB;
-
 		goto got_name;
 	} else {
 		if (vma->vm_ops && vma->vm_ops->name) {
author maintainer
#8 lore raw

PATCH 8/29 ata: sata_mv:- Handle return value of devm_ioremap.

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 064c3db9c564cc5be514ac21fb4aa26cc33db746 upstream.

Here, If devm_ioremap will fail. It will return NULL. Then hpriv->base = NULL - 0x20000; Kernel can run into a NULL-pointer dereference. This error check will avoid NULL pointer dereference.

---
 drivers/ata/sata_mv.c |    3 +++
 1 file changed, 3 insertions(+)
drivers/ata/sata_mv.c +3 -0
@@ -4121,6 +4121,9 @@ static int mv_platform_probe(struct plat
 	host->iomap = NULL;
 	hpriv->base = devm_ioremap(&pdev->dev, res->start,
 				   resource_size(res));
+	if (!hpriv->base)
+		return -ENOMEM;
+
 	hpriv->base -= SATAHC0_REG_BASE;
 
 	hpriv->clk = clk_get(&pdev->dev, NULL);
author maintainer
#9 lore raw

PATCH 10/29 powerpc/eeh: Fix wrong flag passed to eeh_unfreeze_pe()

In reply to Greg Kroah-Hartman

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

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

From: Gavin Shan <[email protected]>

commit f05fea5b3574a5926c53865eea27139bb40b2f2b upstream.

In __eeh_clear_pe_frozen_state(), we should pass the flag's value instead of its address to eeh_unfreeze_pe(). The isolated flag is cleared if no error returned from __eeh_clear_pe_frozen_state(). We never observed the error from the function. So the isolated flag should have been always cleared, no real issue is caused because of the misused @flag.

This fixes the code by passing the value of @flag to eeh_unfreeze_pe().

Fixes 5cfb20b96f6 ("powerpc/eeh: Emulate EEH recovery for VFIO devices")
---
 arch/powerpc/kernel/eeh_driver.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/kernel/eeh_driver.c +1 -1
@@ -485,7 +485,7 @@ static void *eeh_pe_detach_dev(void *dat
 static void *__eeh_clear_pe_frozen_state(void *data, void *flag)
 {
 	struct eeh_pe *pe = (struct eeh_pe *)data;
-	bool *clear_sw_state = flag;
+	bool clear_sw_state = *(bool *)flag;
 	int i, rc = 1;
 
 	for (i = 0; rc && i < 3; i++)
author maintainer
#10 lore raw

PATCH 11/29 powerpc: Add missing error check to prom_find_boot_cpu()

In reply to Greg Kroah-Hartman

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

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

From: Darren Stevens <[email protected]>

commit af2b7fa17eb92e52b65f96604448ff7a2a89ee99 upstream.

prom_init.c calls 'instance-to-package' twice, but the return is not checked during prom_find_boot_cpu(). The result is then passed to prom_getprop(), which could be PROM_ERROR. Add a return check to prevent this.

This was found on a pasemi system, where CFE doesn't have a working 'instance-to package' prom call.

Before Commit 5c0484e25ec0 ('powerpc: Endian safe trampoline') the area around addr 0 was mostly 0's and this doesn't cause a problem. Once the macro 'FIXUP_ENDIAN' has been added to head_64.S, the low memory area now has non-zero values, which cause the prom_getprop() call to hang.

mpe: Also confirmed that under SLOF if 'instance-to-package' did fail with PROM_ERROR we would crash in SLOF. So the bug is not specific to CFE, it's just that other open firmwares don't trigger it because they have a working 'instance-to-package'.

Fixes 5c0484e25ec0 ("powerpc: Endian safe trampoline")
---
 arch/powerpc/kernel/prom_init.c |    3 +++
 1 file changed, 3 insertions(+)
arch/powerpc/kernel/prom_init.c +3 -0
@@ -2664,6 +2664,9 @@ static void __init prom_find_boot_cpu(vo
 
 	cpu_pkg = call_prom("instance-to-package", 1, 1, prom_cpu);
 
+	if (!PHANDLE_VALID(cpu_pkg))
+		return;
+
 	prom_getprop(cpu_pkg, "reg", &rval, sizeof(rval));
 	prom.cpu = be32_to_cpu(rval);
 
author maintainer
#11 lore raw

PATCH 12/29 NFSD: Fix a null reference case in find_or_create_lock_stateid()

In reply to Greg Kroah-Hartman

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

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

From: Kinglong Mee <[email protected]>

commit d19fb70dd68c4e960e2ac09b0b9c79dfdeefa726 upstream.

nfsd assigns the nfs4_free_lock_stateid to .sc_free in init_lock_stateid().

If nfsd doesn't go through init_lock_stateid() and put stateid at end, there is a NULL reference to .sc_free when calling nfs4_put_stid(ns).

This patch let the nfs4_stid.sc_free assignment to nfs4_alloc_stid().

Fixes 356a95ece7aa "nfsd: clean up races in lock stateid searching..."
---
 fs/nfsd/nfs4layouts.c |    5 +++--
 fs/nfsd/nfs4state.c   |   19 ++++++++-----------
 fs/nfsd/state.h       |    4 ++--
 3 files changed, 13 insertions(+), 15 deletions(-)
fs/nfsd/nfs4layouts.c +3 -2
@@ -189,10 +189,11 @@ nfsd4_alloc_layout_stateid(struct nfsd4_
 	struct nfs4_layout_stateid *ls;
 	struct nfs4_stid *stp;
 
-	stp = nfs4_alloc_stid(cstate->clp, nfs4_layout_stateid_cache);
+	stp = nfs4_alloc_stid(cstate->clp, nfs4_layout_stateid_cache,
+					nfsd4_free_layout_stateid);
 	if (!stp)
 		return NULL;
-	stp->sc_free = nfsd4_free_layout_stateid;
+
 	get_nfs4_file(fp);
 	stp->sc_file = fp;
 
fs/nfsd/nfs4state.c +8 -11
@@ -553,8 +553,8 @@ out:
 	return co;
 }
 
-struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl,
-					 struct kmem_cache *slab)
+struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl, struct kmem_cache *slab,
+				  void (*sc_free)(struct nfs4_stid *))
 {
 	struct nfs4_stid *stid;
 	int new_id;
@@ -570,6 +570,8 @@ struct nfs4_stid *nfs4_alloc_stid(struct
 	idr_preload_end();
 	if (new_id < 0)
 		goto out_free;
+
+	stid->sc_free = sc_free;
 	stid->sc_client = cl;
 	stid->sc_stateid.si_opaque.so_id = new_id;
 	stid->sc_stateid.si_opaque.so_clid = cl->cl_clientid;
@@ -595,15 +597,12 @@ out_free:
 static struct nfs4_ol_stateid * nfs4_alloc_open_stateid(struct nfs4_client *clp)
 {
 	struct nfs4_stid *stid;
-	struct nfs4_ol_stateid *stp;
 
-	stid = nfs4_alloc_stid(clp, stateid_slab);
+	stid = nfs4_alloc_stid(clp, stateid_slab, nfs4_free_ol_stateid);
 	if (!stid)
 		return NULL;
 
-	stp = openlockstateid(stid);
-	stp->st_stid.sc_free = nfs4_free_ol_stateid;
-	return stp;
+	return openlockstateid(stid);
 }
 
 static void nfs4_free_deleg(struct nfs4_stid *stid)
@@ -701,11 +700,10 @@ alloc_init_deleg(struct nfs4_client *clp
 		goto out_dec;
 	if (delegation_blocked(&current_fh->fh_handle))
 		goto out_dec;
-	dp = delegstateid(nfs4_alloc_stid(clp, deleg_slab));
+	dp = delegstateid(nfs4_alloc_stid(clp, deleg_slab, nfs4_free_deleg));
 	if (dp == NULL)
 		goto out_dec;
 
-	dp->dl_stid.sc_free = nfs4_free_deleg;
 	/*
 	 * delegation seqid's are never incremented.  The 4.1 special
 	 * meaning of seqid 0 isn't meaningful, really, but let's avoid
@@ -5396,7 +5394,6 @@ init_lock_stateid(struct nfs4_ol_stateid
 	stp->st_stateowner = nfs4_get_stateowner(&lo->lo_owner);
 	get_nfs4_file(fp);
 	stp->st_stid.sc_file = fp;
-	stp->st_stid.sc_free = nfs4_free_lock_stateid;
 	stp->st_access_bmap = 0;
 	stp->st_deny_bmap = open_stp->st_deny_bmap;
 	stp->st_openstp = open_stp;
@@ -5439,7 +5436,7 @@ find_or_create_lock_stateid(struct nfs4_
 	lst = find_lock_stateid(lo, fi);
 	if (lst == NULL) {
 		spin_unlock(&clp->cl_lock);
-		ns = nfs4_alloc_stid(clp, stateid_slab);
+		ns = nfs4_alloc_stid(clp, stateid_slab, nfs4_free_lock_stateid);
 		if (ns == NULL)
 			return NULL;
 
fs/nfsd/state.h +2 -2
@@ -583,8 +583,8 @@ extern __be32 nfs4_preprocess_stateid_op
 __be32 nfsd4_lookup_stateid(struct nfsd4_compound_state *cstate,
 		     stateid_t *stateid, unsigned char typemask,
 		     struct nfs4_stid **s, struct nfsd_net *nn);
-struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl,
-		struct kmem_cache *slab);
+struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl, struct kmem_cache *slab,
+				  void (*sc_free)(struct nfs4_stid *));
 void nfs4_unhash_stid(struct nfs4_stid *s);
 void nfs4_put_stid(struct nfs4_stid *s);
 void nfs4_inc_and_copy_stateid(stateid_t *dst, struct nfs4_stid *stid);
author maintainer
#12 lore raw

PATCH 13/29 svcrpc: fix oops in absence of krb5 module

In reply to Greg Kroah-Hartman

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

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

From: J. Bruce Fields <[email protected]>

commit 034dd34ff4916ec1f8f74e39ca3efb04eab2f791 upstream.

Olga Kornievskaia says: "I ran into this oops in the nfsd (below) (4.10-rc3 kernel). To trigger this I had a client (unsuccessfully) try to mount the server with krb5 where the server doesn't have the rpcsec_gss_krb5 module built."

The problem is that rsci.cred is copied from a svc_cred structure that gss_proxy didn't properly initialize. Fix that.

[120408.542387] general protection fault: 0000 [#1] SMP
...
[120408.565724] CPU: 0 PID: 3601 Comm: nfsd Not tainted 4.10.0-rc3+ #16
[120408.567037] Hardware name: VMware, Inc. VMware Virtual =
Platform/440BX Desktop Reference Platform, BIOS 6.00 07/02/2015
[120408.569225] task: ffff8800776f95c0 task.stack: ffffc90003d58000
[120408.570483] RIP: 0010:gss_mech_put+0xb/0x20 [auth_rpcgss]
...
[120408.584946]  ? rsc_free+0x55/0x90 [auth_rpcgss]
[120408.585901]  gss_proxy_save_rsc+0xb2/0x2a0 [auth_rpcgss]
[120408.587017]  svcauth_gss_proxy_init+0x3cc/0x520 [auth_rpcgss]
[120408.588257]  ? __enqueue_entity+0x6c/0x70
[120408.589101]  svcauth_gss_accept+0x391/0xb90 [auth_rpcgss]
[120408.590212]  ? try_to_wake_up+0x4a/0x360
[120408.591036]  ? wake_up_process+0x15/0x20
[120408.592093]  ? svc_xprt_do_enqueue+0x12e/0x2d0 [sunrpc]
[120408.593177]  svc_authenticate+0xe1/0x100 [sunrpc]
[120408.594168]  svc_process_common+0x203/0x710 [sunrpc]
[120408.595220]  svc_process+0x105/0x1c0 [sunrpc]
[120408.596278]  nfsd+0xe9/0x160 [nfsd]
[120408.597060]  kthread+0x101/0x140
[120408.597734]  ? nfsd_destroy+0x60/0x60 [nfsd]
[120408.598626]  ? kthread_park+0x90/0x90
[120408.599448]  ret_from_fork+0x22/0x30
Fixes 1d658336b05f "SUNRPC: Add RPC based upcall mechanism for RPCGSS auth"
Cc Simo Sorce <[email protected]>
---
 net/sunrpc/auth_gss/gss_rpc_xdr.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/sunrpc/auth_gss/gss_rpc_xdr.c +1 -1
@@ -260,7 +260,7 @@ static int gssx_dec_option_array(struct
 	if (!oa->data)
 		return -ENOMEM;
 
-	creds = kmalloc(sizeof(struct svc_cred), GFP_KERNEL);
+	creds = kzalloc(sizeof(struct svc_cred), GFP_KERNEL);
 	if (!creds) {
 		kfree(oa->data);
 		return -ENOMEM;
author maintainer
#13 lore raw

PATCH 14/29 zswap: disable changing params if init fails

In reply to Greg Kroah-Hartman

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

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

From: Dan Streetman <[email protected]>

commit d7b028f56a971a2e4d8d7887540a144eeefcd4ab upstream.

Add zswap_init_failed bool that prevents changing any of the module params, if init_zswap() fails, and set zswap_enabled to false. Change 'enabled' param to a callback, and check zswap_init_failed before allowing any change to 'enabled', 'zpool', or 'compressor' params.

Any driver that is built-in to the kernel will not be unloaded if its init function returns error, and its module params remain accessible for users to change via sysfs. Since zswap uses param callbacks, which assume that zswap has been initialized, changing the zswap params after a failed initialization will result in WARNING due to the param callbacks expecting a pool to already exist. This prevents that by immediately exiting any of the param callbacks if initialization failed.

This was reported here:
https://marc.info/?l=linux-mm&m=147004228125528&w=4

And fixes this WARNING:

  [  429.723476] WARNING: CPU: 0 PID: 5140 at mm/zswap.c:503 __zswap_pool_current+0x56/0x60

The warning is just noise, and not serious. However, when init fails, zswap frees all its percpu dstmem pages and its kmem cache. The kmem cache might be serious, if kmem_cache_alloc(NULL, gfp) has problems; but the percpu dstmem pages are definitely a problem, as they're used as temporary buffer for compressed pages before copying into place in the zpool.

If the user does get zswap enabled after an init failure, then zswap will likely Oops on the first page it tries to compress (or worse, start corrupting memory).

Fixes 90b0fc26d5db ("zswap: change zpool/compressor at runtime")
Cc Seth Jennings <[email protected]>
Cc Michal Hocko <[email protected]>
Cc Sergey Senozhatsky <[email protected]>
Cc Minchan Kim <[email protected]>
---
 mm/zswap.c |   30 +++++++++++++++++++++++++++++-
 1 file changed, 29 insertions(+), 1 deletion(-)
mm/zswap.c +29 -1
@@ -78,7 +78,13 @@ static u64 zswap_duplicate_entry;
 
 /* Enable/disable zswap (disabled by default) */
 static bool zswap_enabled;
-module_param_named(enabled, zswap_enabled, bool, 0644);
+static int zswap_enabled_param_set(const char *,
+				   const struct kernel_param *);
+static struct kernel_param_ops zswap_enabled_param_ops = {
+	.set =		zswap_enabled_param_set,
+	.get =		param_get_bool,
+};
+module_param_cb(enabled, &zswap_enabled_param_ops, &zswap_enabled, 0644);
 
 /* Crypto compressor to use */
 #define ZSWAP_COMPRESSOR_DEFAULT "lzo"
@@ -176,6 +182,9 @@ static atomic_t zswap_pools_count = ATOM
 /* used by param callback function */
 static bool zswap_init_started;
 
+/* fatal error during init */
+static bool zswap_init_failed;
+
 /*********************************
 * helpers and fwd declarations
 **********************************/
@@ -702,6 +711,11 @@ static int __zswap_param_set(const char
 	char *s = strstrip((char *)val);
 	int ret;
 
+	if (zswap_init_failed) {
+		pr_err("can't set param, initialization failed\n");
+		return -ENODEV;
+	}
+
 	/* no change required */
 	if (!strcmp(s, *(char **)kp->arg))
 		return 0;
@@ -781,6 +795,17 @@ static int zswap_zpool_param_set(const c
 	return __zswap_param_set(val, kp, NULL, zswap_compressor);
 }
 
+static int zswap_enabled_param_set(const char *val,
+				   const struct kernel_param *kp)
+{
+	if (zswap_init_failed) {
+		pr_err("can't enable, initialization failed\n");
+		return -ENODEV;
+	}
+
+	return param_set_bool(val, kp);
+}
+
 /*********************************
 * writeback code
 **********************************/
@@ -1267,6 +1292,9 @@ pool_fail:
 dstmem_fail:
 	zswap_entry_cache_destroy();
 cache_fail:
+	/* if built-in, we aren't unloaded on failure; don't allow use */
+	zswap_init_failed = true;
+	zswap_enabled = false;
 	return -ENOMEM;
 }
 /* must be late so crypto has time to come up */
author maintainer
#14 lore raw

PATCH 15/29 cifs: initialize file_info_lock

In reply to Greg Kroah-Hartman

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

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

From: Rabin Vincent <[email protected]>

commit 81ddd8c0c5e1cb41184d66567140cb48c53eb3d1 upstream.

file_info_lock is not initalized in initiate_cifs_search(), leading to the following splat after a simple "mount.cifs ... dir && ls dir/":

 BUG: spinlock bad magic on CPU#0, ls/486
  lock: 0xffff880009301110, .magic: 00000000, .owner: <none>/-1, .owner_cpu: 0
 CPU: 0 PID: 486 Comm: ls Not tainted 4.9.0 #27
 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996)
  ffffc900042f3db0 ffffffff81327533 0000000000000000 ffff880009301110
  ffffc900042f3dd0 ffffffff810baf75 ffff880009301110 ffffffff817ae077
  ffffc900042f3df0 ffffffff810baff6 ffff880009301110 ffff880008d69900
 Call Trace:
  [<ffffffff81327533>] dump_stack+0x65/0x92
  [<ffffffff810baf75>] spin_dump+0x85/0xe0
  [<ffffffff810baff6>] spin_bug+0x26/0x30
  [<ffffffff810bb159>] do_raw_spin_lock+0xe9/0x130
  [<ffffffff8159ad2f>] _raw_spin_lock+0x1f/0x30
  [<ffffffff8127e50d>] cifs_closedir+0x4d/0x100
  [<ffffffff81181cfd>] __fput+0x5d/0x160
  [<ffffffff81181e3e>] ____fput+0xe/0x10
  [<ffffffff8109410e>] task_work_run+0x7e/0xa0
  [<ffffffff81002512>] exit_to_usermode_loop+0x92/0xa0
  [<ffffffff810026f9>] syscall_return_slowpath+0x49/0x50
  [<ffffffff8159b484>] entry_SYSCALL_64_fastpath+0xa7/0xa9
Fixes 3afca265b5f53a0 ("Clarify locking of cifs file and tcon structures and make more granular")
---
 fs/cifs/readdir.c |    1 +
 1 file changed, 1 insertion(+)
fs/cifs/readdir.c +1 -0
@@ -282,6 +282,7 @@ initiate_cifs_search(const unsigned int
 			rc = -ENOMEM;
 			goto error_exit;
 		}
+		spin_lock_init(&cifsFile->file_info_lock);
 		file->private_data = cifsFile;
 		cifsFile->tlink = cifs_get_tlink(tlink);
 		tcon = tlink_tcon(tlink);
author maintainer
#15 lore raw

PATCH 16/29 mm/memory_hotplug.c: check start_pfn in test_pages_in_a_zone()

In reply to Greg Kroah-Hartman

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

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

From: Toshi Kani <[email protected]>

commit deb88a2a19e85842d79ba96b05031739ec327ff4 upstream.

Patch series "fix a kernel oops when reading sysfs valid_zones", v2.

A sysfs memory file is created for each 2GiB memory block on x86-64 when the system has 64GiB or more memory. [1] When the start address of a memory block is not backed by struct page, i.e. a memory range is not aligned by 2GiB, reading its 'valid_zones' attribute file leads to a kernel oops. This issue was observed on multiple x86-64 systems with more than 64GiB of memory. This patch-set fixes this issue.

Patch 1 first fixes an issue in test_pages_in_a_zone(), which does not test the start section.

Patch 2 then fixes the kernel oops by extending test_pages_in_a_zone() to return valid [start, end).

Note for stable kernels: The memory block size change was made by commit bdee237c0343 ("x86: mm: Use 2GB memory block size on large-memory x86-64 systems"), which was accepted to 3.9. However, this patch-set depends on (and fixes) the change to test_pages_in_a_zone() made by commit 5f0f2887f4de ("mm/memory_hotplug.c: check for missing sections in test_pages_in_a_zone()"), which was accepted to 4.4.

So, I recommend that we backport it up to 4.4.

[1] 'Commit bdee237c0343 ("x86: mm: Use 2GB memory block size on

    large-memory x86-64 systems")'

This patch (of 2):

test_pages_in_a_zone() does not check 'start_pfn' when it is aligned by section since 'sec_end_pfn' is set equal to 'pfn'. Since this function is called for testing the range of a sysfs memory file, 'start_pfn' is always aligned by section.

Fix it by properly setting 'sec_end_pfn' to the next section pfn.

Also make sure that this function returns 1 only when the range belongs to a zone.

---
 mm/memory_hotplug.c |   12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)
mm/memory_hotplug.c +8 -4
@@ -1371,7 +1371,7 @@ int is_mem_section_removable(unsigned lo
 }
 
 /*
- * Confirm all pages in a range [start, end) is belongs to the same zone.
+ * Confirm all pages in a range [start, end) belong to the same zone.
  */
 int test_pages_in_a_zone(unsigned long start_pfn, unsigned long end_pfn)
 {
@@ -1379,9 +1379,9 @@ int test_pages_in_a_zone(unsigned long s
 	struct zone *zone = NULL;
 	struct page *page;
 	int i;
-	for (pfn = start_pfn, sec_end_pfn = SECTION_ALIGN_UP(start_pfn);
+	for (pfn = start_pfn, sec_end_pfn = SECTION_ALIGN_UP(start_pfn + 1);
 	     pfn < end_pfn;
-	     pfn = sec_end_pfn + 1, sec_end_pfn += PAGES_PER_SECTION) {
+	     pfn = sec_end_pfn, sec_end_pfn += PAGES_PER_SECTION) {
 		/* Make sure the memory section is present first */
 		if (!present_section_nr(pfn_to_section_nr(pfn)))
 			continue;
@@ -1400,7 +1400,11 @@ int test_pages_in_a_zone(unsigned long s
 			zone = page_zone(page);
 		}
 	}
-	return 1;
+
+	if (zone)
+		return 1;
+	else
+		return 0;
 }
 
 /*
author maintainer
#16 lore raw

PATCH 17/29 mm, fs: check for fatal signals in do_generic_file_read()

In reply to Greg Kroah-Hartman

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

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

From: Michal Hocko <[email protected]>

commit 5abf186a30a89d5b9c18a6bf93a2c192c9fd52f6 upstream.

do_generic_file_read() can be told to perform a large request from userspace. If the system is under OOM and the reading task is the OOM victim then it has an access to memory reserves and finishing the full request can lead to the full memory depletion which is dangerous. Make sure we rather go with a short read and allow the killed task to terminate.

---
 mm/filemap.c |    5 +++++
 1 file changed, 5 insertions(+)
mm/filemap.c +5 -0
@@ -1559,6 +1559,11 @@ static ssize_t do_generic_file_read(stru
 
 		cond_resched();
 find_page:
+		if (fatal_signal_pending(current)) {
+			error = -EINTR;
+			goto out;
+		}
+
 		page = find_get_page(mapping, index);
 		if (!page) {
 			page_cache_sync_readahead(mapping,
author maintainer
#17 lore raw

PATCH 18/29 can: bcm: fix hrtimer/tasklet termination in bcm op removal

In reply to Greg Kroah-Hartman

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

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

From: Oliver Hartkopp <[email protected]>

commit a06393ed03167771246c4c43192d9c264bc48412 upstream.

When removing a bcm tx operation either a hrtimer or a tasklet might run. As the hrtimer triggers its associated tasklet and vice versa we need to take care to mutually terminate both handlers.

---
 net/can/bcm.c |   23 ++++++++++++++++-------
 1 file changed, 16 insertions(+), 7 deletions(-)
net/can/bcm.c +16 -7
@@ -710,14 +710,23 @@ static struct bcm_op *bcm_find_op(struct
 
 static void bcm_remove_op(struct bcm_op *op)
 {
-	hrtimer_cancel(&op->timer);
-	hrtimer_cancel(&op->thrtimer);
+	if (op->tsklet.func) {
+		while (test_bit(TASKLET_STATE_SCHED, &op->tsklet.state) ||
+		       test_bit(TASKLET_STATE_RUN, &op->tsklet.state) ||
+		       hrtimer_active(&op->timer)) {
+			hrtimer_cancel(&op->timer);
+			tasklet_kill(&op->tsklet);
+		}
+	}
 
-	if (op->tsklet.func)
-		tasklet_kill(&op->tsklet);
-
-	if (op->thrtsklet.func)
-		tasklet_kill(&op->thrtsklet);
+	if (op->thrtsklet.func) {
+		while (test_bit(TASKLET_STATE_SCHED, &op->thrtsklet.state) ||
+		       test_bit(TASKLET_STATE_RUN, &op->thrtsklet.state) ||
+		       hrtimer_active(&op->thrtimer)) {
+			hrtimer_cancel(&op->thrtimer);
+			tasklet_kill(&op->thrtsklet);
+		}
+	}
 
 	if ((op->frames) && (op->frames != &op->sframe))
 		kfree(op->frames);
author maintainer
#18 lore raw

PATCH 19/29 mmc: sdhci: Ignore unexpected CARD_INT interrupts

In reply to Greg Kroah-Hartman

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

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

From: Gabriel Krisman Bertazi <[email protected]>

commit 161e6d44a5e2d3f85365cb717d60e363171b39e6 upstream.

One of our kernelCI boxes hanged at boot because a faulty eSDHC device was triggering spurious CARD_INT interrupts for SD cards, causing CMD52 reads, which are not allowed for SD devices. This adds a sanity check to the interruption path, preventing that illegal command from getting sent if the CARD_INT interruption should be disabled.

This quirk allows that particular machine to resume boot despite the faulty hardware, instead of getting hung dealing with thousands of mishandled interrupts.

---
 drivers/mmc/host/sdhci.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/mmc/host/sdhci.c +2 -1
@@ -2629,7 +2629,8 @@ static irqreturn_t sdhci_irq(int irq, vo
 			pr_err("%s: Card is consuming too much power!\n",
 				mmc_hostname(host->mmc));
 
-		if (intmask & SDHCI_INT_CARD_INT) {
+		if ((intmask & SDHCI_INT_CARD_INT) &&
+		    (host->ier & SDHCI_INT_CARD_INT)) {
 			sdhci_enable_sdio_irq_nolock(host, false);
 			host->thread_isr |= SDHCI_INT_CARD_INT;
 			result = IRQ_WAKE_THREAD;
author maintainer
#19 lore raw

PATCH 20/29 percpu-refcount: fix reference leak during percpu-atomic transition

In reply to Greg Kroah-Hartman

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

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

From: Douglas Miller <[email protected]>

commit 966d2b04e070bc040319aaebfec09e0144dc3341 upstream.

percpu_ref_tryget() and percpu_ref_tryget_live() should return "true" IFF they acquire a reference. But the return value from atomic_long_inc_not_zero() is a long and may have high bits set, e.g. PERCPU_COUNT_BIAS, and the return value of the tryget routines is bool so the reference may actually be acquired but the routines return "false" which results in a reference leak since the caller assumes it does not need to do a corresponding percpu_ref_put().

This was seen when performing CPU hotplug during I/O, as hangs in blk_mq_freeze_queue_wait where percpu_ref_kill (blk_mq_freeze_queue_start) raced with percpu_ref_tryget (blk_mq_timeout_work).
Sample stack trace:

__switch_to+0x2c0/0x450
__schedule+0x2f8/0x970
schedule+0x48/0xc0
blk_mq_freeze_queue_wait+0x94/0x120
blk_mq_queue_reinit_work+0xb8/0x180
blk_mq_queue_reinit_prepare+0x84/0xa0
cpuhp_invoke_callback+0x17c/0x600
cpuhp_up_callbacks+0x58/0x150
_cpu_up+0xf0/0x1c0
do_cpu_up+0x120/0x150
cpu_subsys_online+0x64/0xe0
device_online+0xb4/0x120
online_store+0xb4/0xc0
dev_attr_store+0x68/0xa0
sysfs_kf_write+0x80/0xb0
kernfs_fop_write+0x17c/0x250
__vfs_write+0x6c/0x1e0
vfs_write+0xd0/0x270
SyS_write+0x6c/0x110
system_call+0x38/0xe0

Examination of the queue showed a single reference (no PERCPU_COUNT_BIAS, and __PERCPU_REF_DEAD, __PERCPU_REF_ATOMIC set) and no requests. However, conditions at the time of the race are count of PERCPU_COUNT_BIAS + 0 and __PERCPU_REF_DEAD and __PERCPU_REF_ATOMIC set.

The fix is to make the tryget routines use an actual boolean internally instead of the atomic long result truncated to a int.

Fixes e625305b3907 percpu-refcount: make percpu_ref based on longs instead of ints
Fixes e625305b3907 ("percpu-refcount: make percpu_ref based on longs instead of ints")
---
 include/linux/percpu-refcount.h |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
include/linux/percpu-refcount.h +2 -2
@@ -206,7 +206,7 @@ static inline void percpu_ref_get(struct
 static inline bool percpu_ref_tryget(struct percpu_ref *ref)
 {
 	unsigned long __percpu *percpu_count;
-	int ret;
+	bool ret;
 
 	rcu_read_lock_sched();
 
@@ -240,7 +240,7 @@ static inline bool percpu_ref_tryget(str
 static inline bool percpu_ref_tryget_live(struct percpu_ref *ref)
 {
 	unsigned long __percpu *percpu_count;
-	int ret = false;
+	bool ret = false;
 
 	rcu_read_lock_sched();
 
author maintainer
#20 lore raw

PATCH 21/29 HID: wacom: Fix poor prox handling in wacom_pl_irq

In reply to Greg Kroah-Hartman

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

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

From: Jason Gerecke <[email protected]>

commit 282e4637bc1c0b338708bcebd09d31c69abec070 upstream.

Commit 025bcc1 performed cleanup work on the 'wacom_pl_irq' function, making it follow the standards used in the rest of the codebase. The change unintiontionally allowed the function to send input events from reports that are not marked as being in prox. This can cause problems as the report values for X, Y, etc. are not guaranteed to be correct. In particular, occasionally the tablet will send a report with these values set to zero. If such a report is received it can caus an unexpected jump in the XY position.

This patch surrounds more of the processing code with a proximity check, preventing these zeroed reports from overwriting the current state. To be safe, only the tool type and ABS_MISC events should be reported when the pen is marked as being out of prox.

Fixes 025bcc1540 ("HID: wacom: Simplify 'wacom_pl_irq'")
---
 drivers/hid/wacom_wac.c |   24 +++++++++++++-----------
 1 file changed, 13 insertions(+), 11 deletions(-)
drivers/hid/wacom_wac.c +13 -11
@@ -148,19 +148,21 @@ static int wacom_pl_irq(struct wacom_wac
 		wacom->id[0] = STYLUS_DEVICE_ID;
 	}
 
-	pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1));
-	if (features->pressure_max > 255)
-		pressure = (pressure << 1) | ((data[4] >> 6) & 1);
-	pressure += (features->pressure_max + 1) / 2;
+	if (prox) {
+		pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1));
+		if (features->pressure_max > 255)
+			pressure = (pressure << 1) | ((data[4] >> 6) & 1);
+		pressure += (features->pressure_max + 1) / 2;
 
-	input_report_abs(input, ABS_X, data[3] | (data[2] << 7) | ((data[1] & 0x03) << 14));
-	input_report_abs(input, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14));
-	input_report_abs(input, ABS_PRESSURE, pressure);
+		input_report_abs(input, ABS_X, data[3] | (data[2] << 7) | ((data[1] & 0x03) << 14));
+		input_report_abs(input, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14));
+		input_report_abs(input, ABS_PRESSURE, pressure);
 
-	input_report_key(input, BTN_TOUCH, data[4] & 0x08);
-	input_report_key(input, BTN_STYLUS, data[4] & 0x10);
-	/* Only allow the stylus2 button to be reported for the pen tool. */
-	input_report_key(input, BTN_STYLUS2, (wacom->tool[0] == BTN_TOOL_PEN) && (data[4] & 0x20));
+		input_report_key(input, BTN_TOUCH, data[4] & 0x08);
+		input_report_key(input, BTN_STYLUS, data[4] & 0x10);
+		/* Only allow the stylus2 button to be reported for the pen tool. */
+		input_report_key(input, BTN_STYLUS2, (wacom->tool[0] == BTN_TOOL_PEN) && (data[4] & 0x20));
+	}
 
 	if (!prox)
 		wacom->id[0] = 0;
author maintainer
#21 lore raw

PATCH 23/29 USB: serial: qcserial: add Dell DW5570 QDL

In reply to Greg Kroah-Hartman

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

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

From: Aleksander Morgado <[email protected]>

commit 24d615a694d649aa2e167c3f97f62bdad07e3f84 upstream.

The Dell DW5570 is a re-branded Sierra Wireless MC8805 which will by default boot with vid 0x413c and pid 0x81a3. When triggered QDL download mode, the device switches to pid 0x81a6 and provides the standard TTY used for firmware upgrade.

---
 drivers/usb/serial/qcserial.c |    1 +
 1 file changed, 1 insertion(+)
drivers/usb/serial/qcserial.c +1 -0
@@ -124,6 +124,7 @@ static const struct usb_device_id id_tab
 	{USB_DEVICE(0x1410, 0xa021)},	/* Novatel Gobi 3000 Composite */
 	{USB_DEVICE(0x413c, 0x8193)},	/* Dell Gobi 3000 QDL */
 	{USB_DEVICE(0x413c, 0x8194)},	/* Dell Gobi 3000 Composite */
+	{USB_DEVICE(0x413c, 0x81a6)},	/* Dell DW5570 QDL (MC8805) */
 	{USB_DEVICE(0x1199, 0x68a4)},	/* Sierra Wireless QDL */
 	{USB_DEVICE(0x1199, 0x68a5)},	/* Sierra Wireless Modem */
 	{USB_DEVICE(0x1199, 0x68a8)},	/* Sierra Wireless QDL */
author maintainer
#22 lore raw

PATCH 24/29 USB: serial: pl2303: add ATEN device ID

In reply to Greg Kroah-Hartman

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

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

From: Marcel J.E. Mol <[email protected]>

commit d07830db1bdb254e4b50d366010b219286b8c937 upstream.

Seems that ATEN serial-to-usb devices using pl2303 exist with different device ids. This patch adds a missing device ID so it is recognised by the driver.

---
 drivers/usb/serial/pl2303.c |    1 +
 drivers/usb/serial/pl2303.h |    1 +
 2 files changed, 2 insertions(+)
drivers/usb/serial/pl2303.c +1 -0
@@ -49,6 +49,7 @@ static const struct usb_device_id id_tab
 	{ USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) },
 	{ USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) },
 	{ USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) },
+	{ USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID2) },
 	{ USB_DEVICE(ATEN_VENDOR_ID2, ATEN_PRODUCT_ID) },
 	{ USB_DEVICE(ELCOM_VENDOR_ID, ELCOM_PRODUCT_ID) },
 	{ USB_DEVICE(ELCOM_VENDOR_ID, ELCOM_PRODUCT_ID_UCSGT) },
drivers/usb/serial/pl2303.h +1 -0
@@ -27,6 +27,7 @@
 #define ATEN_VENDOR_ID		0x0557
 #define ATEN_VENDOR_ID2		0x0547
 #define ATEN_PRODUCT_ID		0x2008
+#define ATEN_PRODUCT_ID2	0x2118
 
 #define IODATA_VENDOR_ID	0x04bb
 #define IODATA_PRODUCT_ID	0x0a03
author maintainer
#23 lore raw

PATCH 26/29 usb: gadget: f_fs: Assorted buffer overflow checks.

In reply to Greg Kroah-Hartman

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

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

From: Vincent Pelletier <[email protected]>

commit 83e526f2a2fa4b2e82b6bd3ddbb26b70acfa8947 upstream.

OS descriptor head, when flagged as provided, is accessed without checking if it fits in provided buffer. Verify length before access. Also, there are other places where buffer length it checked after accessing offsets which are potentially past the end. Check buffer length before as well to fail cleanly.

---
 drivers/usb/gadget/function/f_fs.c |   13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)
drivers/usb/gadget/function/f_fs.c +12 -1
@@ -2079,6 +2079,8 @@ static int __ffs_data_do_os_desc(enum ff
 		if (len < sizeof(*d) || h->interface >= ffs->interfaces_count)
 			return -EINVAL;
 		length = le32_to_cpu(d->dwSize);
+		if (len < length)
+			return -EINVAL;
 		type = le32_to_cpu(d->dwPropertyDataType);
 		if (type < USB_EXT_PROP_UNICODE ||
 		    type > USB_EXT_PROP_UNICODE_MULTI) {
@@ -2087,6 +2089,11 @@ static int __ffs_data_do_os_desc(enum ff
 			return -EINVAL;
 		}
 		pnl = le16_to_cpu(d->wPropertyNameLength);
+		if (length < 14 + pnl) {
+			pr_vdebug("invalid os descriptor length: %d pnl:%d (descriptor %d)\n",
+				  length, pnl, type);
+			return -EINVAL;
+		}
 		pdl = le32_to_cpu(*(u32 *)((u8 *)data + 10 + pnl));
 		if (length != 14 + pnl + pdl) {
 			pr_vdebug("invalid os descriptor length: %d pnl:%d pdl:%d (descriptor %d)\n",
@@ -2171,6 +2178,9 @@ static int __ffs_data_got_descs(struct f
 		}
 	}
 	if (flags & (1 << i)) {
+		if (len < 4) {
+			goto error;
+		}
 		os_descs_count = get_unaligned_le32(data);
 		data += 4;
 		len -= 4;
@@ -2243,7 +2253,8 @@ static int __ffs_data_got_strings(struct
 
 	ENTER();
 
-	if (unlikely(get_unaligned_le32(data) != FUNCTIONFS_STRINGS_MAGIC ||
+	if (unlikely(len < 16 ||
+		     get_unaligned_le32(data) != FUNCTIONFS_STRINGS_MAGIC ||
 		     get_unaligned_le32(data + 4) != len))
 		goto error;
 	str_count  = get_unaligned_le32(data + 8);
author maintainer
#24 lore raw

PATCH 28/29 x86/irq: Make irq activate operations symmetric

In reply to Greg Kroah-Hartman

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

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

From: Thomas Gleixner <[email protected]>

commit aaaec6fc755447a1d056765b11b24d8ff2b81366 upstream.

The recent commit which prevents double activation of interrupts unearthed interesting code in x86. The code (ab)uses irq_domain_activate_irq() to reconfigure an already activated interrupt. That trips over the prevention code now.

Fix it by deactivating the interrupt before activating the new configuration.

Fixes 08d85f3ea99f1 "irqdomain: Avoid activating interrupts more than once"
Cc Andrey Ryabinin <[email protected]>
Cc Marc Zyngier <[email protected]>
---
 arch/x86/kernel/apic/io_apic.c |    2 ++
 arch/x86/kernel/hpet.c         |    1 +
 2 files changed, 3 insertions(+)
arch/x86/kernel/apic/io_apic.c +2 -0
@@ -2117,6 +2117,7 @@ static inline void __init check_timer(vo
 			if (idx != -1 && irq_trigger(idx))
 				unmask_ioapic_irq(irq_get_chip_data(0));
 		}
+		irq_domain_deactivate_irq(irq_data);
 		irq_domain_activate_irq(irq_data);
 		if (timer_irq_works()) {
 			if (disable_timer_pin_1 > 0)
@@ -2138,6 +2139,7 @@ static inline void __init check_timer(vo
 		 * legacy devices should be connected to IO APIC #0
 		 */
 		replace_pin_at_irq_node(data, node, apic1, pin1, apic2, pin2);
+		irq_domain_deactivate_irq(irq_data);
 		irq_domain_activate_irq(irq_data);
 		legacy_pic->unmask(0);
 		if (timer_irq_works()) {
arch/x86/kernel/hpet.c +1 -0
@@ -351,6 +351,7 @@ static int hpet_resume(struct clock_even
 	} else {
 		struct hpet_dev *hdev = EVT_TO_HPET_DEV(evt);
 
+		irq_domain_deactivate_irq(irq_get_irq_data(hdev->irq));
 		irq_domain_activate_irq(irq_get_irq_data(hdev->irq));
 		disable_irq(hdev->irq);
 		irq_set_affinity(hdev->irq, cpumask_of(hdev->cpu));
author maintainer
#25 lore raw

PATCH 29/29 base/memory, hotplug: fix a kernel oops in show_valid_zones()

In reply to Greg Kroah-Hartman

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

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

From: Toshi Kani <[email protected]>

commit a96dfddbcc04336bbed50dc2b24823e45e09e80c upstream.

Reading a sysfs "memoryN/valid_zones" file leads to the following oops when the first page of a range is not backed by struct page. show_valid_zones() assumes that 'start_pfn' is always valid for page_zone().

 BUG: unable to handle kernel paging request at ffffea017a000000
 IP: show_valid_zones+0x6f/0x160

This issue may happen on x86-64 systems with 64GiB or more memory since their memory block size is bumped up to 2GiB. [1] An example of such systems is desribed below. 0x3240000000 is only aligned by 1GiB and this memory block starts from 0x3200000000, which is not backed by struct page.

BIOS-e820: [mem 0x0000003240000000-0x000000603fffffff] usable

Since test_pages_in_a_zone() already checks holes, fix this issue by extending this function to return 'valid_start' and 'valid_end' for a given range. show_valid_zones() then proceeds with the valid range.

[1] 'Commit bdee237c0343 ("x86: mm: Use 2GB memory block size on

    large-memory x86-64 systems")'
---
 drivers/base/memory.c          |   11 +++++------
 include/linux/memory_hotplug.h |    3 ++-
 mm/memory_hotplug.c            |   20 +++++++++++++++-----
 3 files changed, 22 insertions(+), 12 deletions(-)
drivers/base/memory.c +5 -6
@@ -388,30 +388,29 @@ static ssize_t show_valid_zones(struct d
 {
 	struct memory_block *mem = to_memory_block(dev);
 	unsigned long start_pfn, end_pfn;
+	unsigned long valid_start, valid_end;
 	unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block;
-	struct page *first_page;
 	struct zone *zone;
 
 	start_pfn = section_nr_to_pfn(mem->start_section_nr);
 	end_pfn = start_pfn + nr_pages;
-	first_page = pfn_to_page(start_pfn);
 
 	/* The block contains more than one zone can not be offlined. */
-	if (!test_pages_in_a_zone(start_pfn, end_pfn))
+	if (!test_pages_in_a_zone(start_pfn, end_pfn, &valid_start, &valid_end))
 		return sprintf(buf, "none\n");
 
-	zone = page_zone(first_page);
+	zone = page_zone(pfn_to_page(valid_start));
 
 	if (zone_idx(zone) == ZONE_MOVABLE - 1) {
 		/*The mem block is the last memoryblock of this zone.*/
-		if (end_pfn == zone_end_pfn(zone))
+		if (valid_end == zone_end_pfn(zone))
 			return sprintf(buf, "%s %s\n",
 					zone->name, (zone + 1)->name);
 	}
 
 	if (zone_idx(zone) == ZONE_MOVABLE) {
 		/*The mem block is the first memoryblock of ZONE_MOVABLE.*/
-		if (start_pfn == zone->zone_start_pfn)
+		if (valid_start == zone->zone_start_pfn)
 			return sprintf(buf, "%s %s\n",
 					zone->name, (zone - 1)->name);
 	}
include/linux/memory_hotplug.h +2 -1
@@ -85,7 +85,8 @@ extern int zone_grow_waitqueues(struct z
 extern int add_one_highpage(struct page *page, int pfn, int bad_ppro);
 /* VM interface that may be used by firmware interface */
 extern int online_pages(unsigned long, unsigned long, int);
-extern int test_pages_in_a_zone(unsigned long, unsigned long);
+extern int test_pages_in_a_zone(unsigned long start_pfn, unsigned long end_pfn,
+	unsigned long *valid_start, unsigned long *valid_end);
 extern void __offline_isolated_pages(unsigned long, unsigned long);
 
 typedef void (*online_page_callback_t)(struct page *page);
mm/memory_hotplug.c +15 -5
@@ -1372,10 +1372,13 @@ int is_mem_section_removable(unsigned lo
 
 /*
  * Confirm all pages in a range [start, end) belong to the same zone.
+ * When true, return its valid [start, end).
  */
-int test_pages_in_a_zone(unsigned long start_pfn, unsigned long end_pfn)
+int test_pages_in_a_zone(unsigned long start_pfn, unsigned long end_pfn,
+			 unsigned long *valid_start, unsigned long *valid_end)
 {
 	unsigned long pfn, sec_end_pfn;
+	unsigned long start, end;
 	struct zone *zone = NULL;
 	struct page *page;
 	int i;
@@ -1397,14 +1400,20 @@ int test_pages_in_a_zone(unsigned long s
 			page = pfn_to_page(pfn + i);
 			if (zone && page_zone(page) != zone)
 				return 0;
+			if (!zone)
+				start = pfn + i;
 			zone = page_zone(page);
+			end = pfn + MAX_ORDER_NR_PAGES;
 		}
 	}
 
-	if (zone)
+	if (zone) {
+		*valid_start = start;
+		*valid_end = end;
 		return 1;
-	else
+	} else {
 		return 0;
+	}
 }
 
 /*
@@ -1722,6 +1731,7 @@ static int __ref __offline_pages(unsigne
 	long offlined_pages;
 	int ret, drain, retry_max, node;
 	unsigned long flags;
+	unsigned long valid_start, valid_end;
 	struct zone *zone;
 	struct memory_notify arg;
 
@@ -1732,10 +1742,10 @@ static int __ref __offline_pages(unsigne
 		return -EINVAL;
 	/* This makes hotplug much easier...and readable.
 	   we assume this for now. .*/
-	if (!test_pages_in_a_zone(start_pfn, end_pfn))
+	if (!test_pages_in_a_zone(start_pfn, end_pfn, &valid_start, &valid_end))
 		return -EINVAL;
 
-	zone = page_zone(pfn_to_page(start_pfn));
+	zone = page_zone(pfn_to_page(valid_start));
 	node = zone_to_nid(zone);
 	nr_pages = end_pfn - start_pfn;
 
#26 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.48 release. There are 29 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 Thu Feb 9 12:44:43 UTC 2017. 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.48-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

#27 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.48 release. There are 29 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 Thu Feb 9 12:44:43 UTC 2017. Anything received after that time might be too late.

Build results:

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

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

Thanks,
Guenter

A message that is not in the archive (sent off-list or not yet received): [email protected]

author maintainer
#29 lore raw
Quoted 1 line · kernelci.org bot

stable-rc boot: 517 boots: 0 failed, 498 passed with 19 offline (v4.4.47-30-gcd13c41318b2)

Why is there almost double the number of "passed" systems here compared to 4.9?

thanks,

greg k-h

#30 lore raw
Quoted 5 lines · Greg Kroah-Hartman
Quoted 1 line · kernelci.org bot

stable-rc boot: 517 boots: 0 failed, 498 passed with 19 offline (v4.4.47-30-gcd13c41318b2)

Why is there almost double the number of "passed" systems here compared to 4.9?

Mostly because our build systems are backlogged.

We want to reply to your stable review emails within a reasonable amount of time, so we reply with the results that we've received, even though some builds may have been delayed and/or some labs have not reported in their results.

Kevin

author maintainer
#31 lore raw
Quoted 8 lines · Kevin Hilman
Quoted 5 lines · Greg Kroah-Hartman
Quoted 1 line · kernelci.org bot

stable-rc boot: 517 boots: 0 failed, 498 passed with 19 offline (v4.4.47-30-gcd13c41318b2)

Why is there almost double the number of "passed" systems here compared to 4.9?

Quoted 6 lines

Mostly because our build systems are backlogged.

We want to reply to your stable review emails within a reasonable amount of time, so we reply with the results that we've received, even though some builds may have been delayed and/or some labs have not reported in their results.

Ah, that makes sense, thanks for letting me know. And for running this, it's much appreciated.

greg k-h