Skip to contentSkip to conversation

4.11.2-stable review

PATCH In review Greg Kroah-Hartman 4 participants 116 messages May 18, 2017 – May 19, 2017

Subsystems (3)
lore
Share & tools
lore

Greg Kroah-Hartman

author maintainer
#0 lore raw

cover 4.11.2-stable review

This is the start of the stable review cycle for the 4.11.2 release. There are 114 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 Sat May 20 10:35:20 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.11.2-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.11.y
and the diffstat can be found below.

thanks,

greg k-h

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

Greg Kroah-Hartman <[email protected]>

    Linux 4.11.2-rc1

Kees Cook <[email protected]>
pstore: Shut down worker when unregistering

Kees Cook <[email protected]>
pstore: Use dynamic spinlock initializer

Ankit Kumar <[email protected]>
pstore: Fix flags to enable dumps on powerpc

Dan Williams <[email protected]>
libnvdimm, pfn: fix 'npfns' vs section alignment

Dan Williams <[email protected]>
libnvdimm: fix nvdimm_bus_lock() vs device_lock() ordering

Toshi Kani <[email protected]>
libnvdimm, pmem: fix a NULL pointer BUG in nd_pmem_notify

Dan Williams <[email protected]>
libnvdimm, region: fix flush hint detection crash

Joeseph Chang <[email protected]>
ipmi: Fix kernel panic at ipmi_ssif_thread()

Christoph Hellwig <[email protected]>
libata: reject passthrough WRITE SAME requests

Tejun Heo <[email protected]>
cgroup: fix spurious warnings on cgroup_is_dead() from cgroup_sk_alloc()

Johan Hovold <[email protected]>
Bluetooth: hci_intel: add missing tty-device sanity check

Johan Hovold <[email protected]>
Bluetooth: hci_bcm: add missing tty-device sanity check

Szymon Janc <[email protected]>
Bluetooth: Fix user channel for 32bit userspace on 64bit kernel

Timur Tabi <[email protected]>

    tty: pl011: use "qdf2400_e44" as the earlycon name for QDF2400 E44

Wang YanQing <[email protected]>
tty: pty: Fix ldisc flush after userspace become aware of the data already

Johan Hovold <[email protected]>
serial: omap: suspend device on probe errors

Johan Hovold <[email protected]>
serial: omap: fix runtime-pm handling on unbind

Marek Szyprowski <[email protected]>
serial: samsung: Add missing checks for dma_map_single failure

Marek Szyprowski <[email protected]>
serial: samsung: Use right device for DMA-mapping calls

Eric Biggers <[email protected]>
fscrypt: avoid collisions when presenting long encrypted filenames

Eric Biggers <[email protected]>
fscrypt: fix context consistency check when key(s) unavailable

Linus Torvalds <[email protected]>
initramfs: avoid "label at end of compound statement" error

Stafford Horne <[email protected]>
initramfs: Always do fput() and load modules after rootfs populate

Jan Kara <[email protected]>
f2fs: Make flush bios explicitely sync

Jaegeuk Kim <[email protected]>
f2fs: check entire encrypted bigname when finding a dentry

Sheng Yong <[email protected]>
f2fs: fix multiple f2fs_add_link() having same name for inline dentry

Jaegeuk Kim <[email protected]>
f2fs: fix fs corruption due to zero inode page

Jaegeuk Kim <[email protected]>
Revert "f2fs: put allocate_segment after refresh_sit_entry"

Jaegeuk Kim <[email protected]>
f2fs: fix wrong max cost initialization

Ross Zwisler <[email protected]>
dax: fix PMD data corruption when fault races with write

Jan Kara <[email protected]>
ext4: return to starting transaction in ext4_dax_huge_fault()

Jan Kara <[email protected]>
mm: fix data corruption due to stale mmap reads

Ross Zwisler <[email protected]>
dax: prevent invalidation of mapped DAX entries

Dan Williams <[email protected]>
device-dax: fix sysfs attribute deadlock

Dan Williams <[email protected]>
device-dax: fix cdev leak

NeilBrown <[email protected]>
md/raid1: avoid reusing a resync bio after error handling.

Jason A. Donenfeld <[email protected]>
padata: free correct variable

Amir Goldstein <[email protected]>
ovl: do not set overlay.opaque on non-dir create

Björn Jacke <[email protected]>
CIFS: add misssing SFM mapping for doublequote

David Disseldorp <[email protected]>
cifs: fix CIFS_IOC_GET_MNT_INFO oops

Rabin Vincent <[email protected]>
CIFS: fix oplock break deadlocks

David Disseldorp <[email protected]>
cifs: fix CIFS_ENUMERATE_SNAPSHOTS oops

David Disseldorp <[email protected]>
cifs: fix leak in FSCTL_ENUM_SNAPS response handling

Björn Jacke <[email protected]>
CIFS: fix mapping of SFM_SPACE and SFM_PERIOD

Steve French <[email protected]>
SMB3: Work around mount failure when using SMB3 dialect to Macs

Steve French <[email protected]>
Set unicode flag on cifs echo request to avoid Mac error

Sachin Prabhu <[email protected]>
Do not return number of bytes written for ioctl CIFS_IOC_COPYCHUNK_FILE

Sachin Prabhu <[email protected]>
Fix match_prepath()

Vlastimil Babka <[email protected]>
mm: prevent potential recursive reclaim due to clearing PF_MEMALLOC

Johannes Weiner <[email protected]>
mm: vmscan: fix IO/refault regression in cache workingset transition

Andrey Ryabinin <[email protected]>
fs/block_dev: always invalidate cleancache in invalidate_bdev()

Andrey Ryabinin <[email protected]>
fs: fix data invalidation in the cleancache during direct IO

Luis Henriques <[email protected]>
ceph: fix memory leak in __ceph_setxattr()

Michal Hocko <[email protected]>
fs/xattr.c: zero out memory copied to userspace in getxattr

Martin Brandenburg <[email protected]>
orangefs: do not check possibly stale size on truncate

Martin Brandenburg <[email protected]>
orangefs: do not set getattr_time on orangefs_lookup

Martin Brandenburg <[email protected]>
orangefs: clean up oversize xattr validation

Martin Brandenburg <[email protected]>
orangefs: fix bounds check for listxattr

Eric Biggers <[email protected]>
ext4: evict inline data when writing to memory map

Jan Kara <[email protected]>
jbd2: fix dbench4 performance regression for 'nobarrier' mounts

Christian Borntraeger <[email protected]>
perf annotate s390: Implement jump types for perf annotate

Christian Borntraeger <[email protected]>
perf annotate s390: Fix perf annotate error -95 (4.10 regression)

Adrian Hunter <[email protected]>
perf auxtrace: Fix no_size logic in addr_filter__resolve_kernel_syms()

Mike Marciniszyn <[email protected]>
IB/hfi1: Prevent kernel QP post send hard lockups

Jack Morgenstein <[email protected]>
IB/mlx4: Reduce SRIOV multicast cleanup warning message to debug level

Jack Morgenstein <[email protected]>
IB/mlx4: Fix ib device initialization error flow

Shamir Rabinovitch <[email protected]>
IB/IPoIB: ibX: failed to create mcg debug file

Michael J. Ruhl <[email protected]>
IB/core: For multicast functions, verify that LIDs are multicast LIDs

Parav Pandit <[email protected]>
IB/core: Fix kernel crash during fail to initialize device

Jack Morgenstein <[email protected]>
IB/core: Fix sysfs registration error flow

Ding Tianhong <[email protected]>
iov_iter: don't revert iov buffer if csum error

Alex Williamson <[email protected]>
vfio/type1: Remove locked page accounting workqueue

Dennis Yang <[email protected]>
dm thin: fix a memory leak when passing discard bio down

Bart Van Assche <[email protected]>
dm rq: check blk_mq_register_dev() return value in dm_mq_init_request_queue()

Somasundaram Krishnasamy <[email protected]>
dm era: save spacemap metadata root after the pre-commit

Ondrej Kozina <[email protected]>
dm crypt: rewrite (wipe) key in crypto layer using random data

Gary R Hook <[email protected]>
crypto: ccp - Change ISR handler method for a v5 CCP

Gary R Hook <[email protected]>
crypto: ccp - Change ISR handler method for a v3 CCP

Gary R Hook <[email protected]>
crypto: ccp - Disable interrupts early on unload

Gary R Hook <[email protected]>
crypto: ccp - Use only the relevant interrupt bits

Stephan Mueller <[email protected]>
crypto: algif_aead - Require setkey before accept(2)

Krzysztof Kozlowski <[email protected]>
crypto: s5p-sss - Close possible race for completed requests

Mike Snitzer <[email protected]>
block: fix blk_integrity_register to use template's interval_exp if not 0

Marc Zyngier <[email protected]>
arm64: KVM: Fix decoding of Rt/Rt2 when trapping AArch32 CP accesses

Andrew Jones <[email protected]>
KVM: arm/arm64: fix races in kvm_psci_vcpu_on

Paolo Bonzini <[email protected]>

    Revert "KVM: Support vCPU-based gfn->hva cache"

David Hildenbrand <[email protected]>
KVM: x86: fix user triggerable warning in kvm_apic_accept_events()

Vince Weaver <[email protected]>
perf/x86: Fix Broadwell-EP DRAM RAPL events

Richard Weinberger <[email protected]>
um: Fix PTRACE_POKEUSER on x86_64

Ben Hutchings <[email protected]>
x86, pmem: Fix cache flushing for iovec write < 8 bytes

Andy Lutomirski <[email protected]>
selftests/x86/ldt_gdt_32: Work around a glibc sigaction() bug

Ashish Kalra <[email protected]>
x86/boot: Fix BSS corruption/overwrite bug in early x86 kernel startup

Maksim Salau <[email protected]>
usb: misc: legousbtower: Fix buffers on stack

Guenter Roeck <[email protected]>
usb: hub: Do not attempt to autosuspend disconnected devices

Guenter Roeck <[email protected]>
usb: hub: Fix error loop seen after hub communication errors

Alexey Brodkin <[email protected]>
usb: Make sure usb/phy/of gets built-in

Romain Izard <[email protected]>
usb: gadget: legacy gadgets are optional

Gustavo A. R. Silva <[email protected]>
usb: misc: add missing continue in switch

Ian Abbott <[email protected]>
staging: comedi: jr3_pci: cope with jiffies wraparound

Ian Abbott <[email protected]>
staging: comedi: jr3_pci: fix possible null pointer dereference

Sean Young <[email protected]>
staging: sir: fill in missing fields and fix probe

Aditya Shankar <[email protected]>
staging: wilc1000: Fix problem with wrong vif index

Johan Hovold <[email protected]>
staging: gdm724x: gdm_mux: fix use-after-free on module unload

Malcolm Priestley <[email protected]>
staging: vt6656: use off stack for out buffer USB transfers.

Malcolm Priestley <[email protected]>
staging: vt6656: use off stack for in buffer USB transfers.

Bjørn Mork <[email protected]>
USB: Revert "cdc-wdm: fix "out-of-sync" due to missing notifications"

Ajay Kaher <[email protected]>
USB: Proper handling of Race Condition when two USB class drivers try to call init_usb_class simultaneously

Marek Vasut <[email protected]>
USB: serial: ftdi_sio: add device ID for Microsemi/Arrow SF2PLUS Dev Kit

Peter Chen <[email protected]>
usb: host: xhci: print correct command ring address

Roger Quadros <[email protected]>
usb: xhci: bInterval quirk for TI TUSB73x0

Nicholas Bellinger <[email protected]>
iscsi-target: Set session_fall_back_to_erl0 when forcing reinstatement

Bart Van Assche <[email protected]>
target/fileio: Fix zero-length READ and WRITE handling

Nicholas Bellinger <[email protected]>
target: Fix compare_and_write_callback handling for non GOOD status

Juergen Gross <[email protected]>
xen: adjust early dom0 p2m handling to xen hypervisor behavior

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

Diffstat:

 Makefile                                     |   4 +-
 arch/arm/kvm/psci.c                          |   8 +-
 arch/arm64/include/asm/kvm_emulate.h         |   6 +
 arch/arm64/kvm/sys_regs.c                    |   8 +-
 arch/powerpc/kernel/nvram_64.c               |   1 +
 arch/x86/boot/boot.h                         |   2 +-
 arch/x86/events/intel/rapl.c                 |   2 +-
 arch/x86/include/asm/pmem.h                  |   2 +-
 arch/x86/kvm/lapic.c                         |  22 ++--
 arch/x86/kvm/x86.c                           |  53 +++++----
 arch/x86/um/ptrace_64.c                      |   2 +-
 arch/x86/xen/mmu.c                           |   7 +-
 block/blk-integrity.c                        |   3 +-
 crypto/algif_aead.c                          | 157 +++++++++++++++++++++++++--
 drivers/Makefile                             |   1 +
 drivers/ata/libata-scsi.c                    |   8 ++
 drivers/bluetooth/hci_bcm.c                  |   5 +-
 drivers/bluetooth/hci_intel.c                |  13 ++-
 drivers/char/ipmi/ipmi_ssif.c                |   4 +-
 drivers/crypto/ccp/ccp-dev-v3.c              | 120 +++++++++++---------
 drivers/crypto/ccp/ccp-dev-v5.c              | 114 +++++++++++--------
 drivers/crypto/ccp/ccp-dev.h                 |   8 +-
 drivers/crypto/ccp/ccp-pci.c                 |   2 +
 drivers/crypto/s5p-sss.c                     |   5 +-
 drivers/dax/dax.c                            |  55 ++++------
 drivers/infiniband/core/device.c             |  33 ++++--
 drivers/infiniband/core/sysfs.c              |   2 +-
 drivers/infiniband/core/verbs.c              |   8 +-
 drivers/infiniband/hw/hfi1/ruc.c             |  26 +++--
 drivers/infiniband/hw/hfi1/verbs.c           |   4 +-
 drivers/infiniband/hw/hfi1/verbs.h           |   6 +-
 drivers/infiniband/hw/mlx4/main.c            |   1 +
 drivers/infiniband/hw/mlx4/mcg.c             |   3 +-
 drivers/infiniband/ulp/ipoib/ipoib_fs.c      |   3 +
 drivers/infiniband/ulp/ipoib/ipoib_main.c    |  44 +++++++-
 drivers/infiniband/ulp/ipoib/ipoib_vlan.c    |   3 -
 drivers/md/dm-crypt.c                        |   8 +-
 drivers/md/dm-era-target.c                   |   8 +-
 drivers/md/dm-rq.c                           |   6 +-
 drivers/md/dm-thin.c                         |   1 +
 drivers/md/raid1.c                           |   2 +
 drivers/nvdimm/btt_devs.c                    |   2 +-
 drivers/nvdimm/claim.c                       |  23 ++--
 drivers/nvdimm/dax_devs.c                    |   2 +-
 drivers/nvdimm/pfn_devs.c                    |   8 +-
 drivers/nvdimm/pmem.c                        |  37 +++++--
 drivers/nvdimm/region_devs.c                 |  11 +-
 drivers/staging/comedi/drivers/jr3_pci.c     |  13 ++-
 drivers/staging/gdm724x/gdm_mux.c            |   3 +-
 drivers/staging/media/lirc/lirc_sir.c        |  20 ++--
 drivers/staging/vt6656/usbpipe.c             |  31 +++++-
 drivers/staging/wilc1000/linux_wlan.c        |   3 +-
 drivers/target/iscsi/iscsi_target.c          |   1 +
 drivers/target/iscsi/iscsi_target_configfs.c |   1 +
 drivers/target/iscsi/iscsi_target_login.c    |   1 +
 drivers/target/target_core_file.c            |   3 +-
 drivers/target/target_core_sbc.c             |   5 +-
 drivers/tty/pty.c                            |   7 +-
 drivers/tty/serial/amba-pl011.c              |  31 ++++--
 drivers/tty/serial/omap-serial.c             |   9 +-
 drivers/tty/serial/samsung.c                 |  40 +++++--
 drivers/usb/class/cdc-wdm.c                  | 103 +-----------------
 drivers/usb/core/driver.c                    |  21 ++++
 drivers/usb/core/file.c                      |   9 +-
 drivers/usb/core/hub.c                       |  11 +-
 drivers/usb/gadget/Kconfig                   |   1 +
 drivers/usb/host/xhci-mem.c                  |  13 ++-
 drivers/usb/host/xhci-pci.c                  |   3 +
 drivers/usb/host/xhci.h                      |   1 +
 drivers/usb/misc/legousbtower.c              |  37 +++++--
 drivers/usb/misc/usbtest.c                   |   1 +
 drivers/usb/serial/ftdi_sio.c                |   1 +
 drivers/usb/serial/ftdi_sio_ids.h            |   6 +
 drivers/vfio/vfio_iommu_type1.c              | 110 +++++++++----------
 fs/block_dev.c                               |  11 +-
 fs/ceph/xattr.c                              |   3 +
 fs/cifs/cifs_unicode.c                       |   6 +
 fs/cifs/cifs_unicode.h                       |   5 +-
 fs/cifs/cifsfs.c                             |  15 ++-
 fs/cifs/cifsglob.h                           |   1 +
 fs/cifs/cifssmb.c                            |   3 +
 fs/cifs/connect.c                            |  14 +--
 fs/cifs/ioctl.c                              |   7 +-
 fs/cifs/misc.c                               |   2 +-
 fs/cifs/smb2misc.c                           |   5 +-
 fs/cifs/smb2ops.c                            |   1 +
 fs/cifs/smb2pdu.c                            |  14 ++-
 fs/crypto/fname.c                            |   2 +-
 fs/crypto/policy.c                           |  87 +++++++++++----
 fs/dax.c                                     |  59 +++-------
 fs/ext4/file.c                               |  21 +++-
 fs/ext4/inode.c                              |   5 +
 fs/ext4/namei.c                              |   4 +-
 fs/f2fs/data.c                               |   2 +-
 fs/f2fs/dir.c                                |  50 +++++----
 fs/f2fs/f2fs.h                               |   3 +-
 fs/f2fs/gc.c                                 |   2 +-
 fs/f2fs/hash.c                               |   7 +-
 fs/f2fs/inline.c                             |   4 +-
 fs/f2fs/inode.c                              |   2 +-
 fs/f2fs/namei.c                              |  20 ++--
 fs/f2fs/segment.c                            |  11 +-
 fs/f2fs/super.c                              |   2 +-
 fs/iomap.c                                   |  18 ++-
 fs/jbd2/journal.c                            |   2 +-
 fs/orangefs/inode.c                          |   3 +-
 fs/orangefs/namei.c                          |   2 -
 fs/orangefs/xattr.c                          |  26 ++---
 fs/overlayfs/dir.c                           |   2 +-
 fs/pstore/platform.c                         |  10 +-
 fs/pstore/ram_core.c                         |   2 +-
 fs/xattr.c                                   |   2 +-
 include/linux/dax.h                          |   1 -
 include/linux/kvm_host.h                     |  16 +--
 include/linux/memcontrol.h                   |  64 ++++++++++-
 include/linux/mmzone.h                       |   2 +
 init/initramfs.c                             |  16 ++-
 kernel/cgroup/cgroup.c                       |  22 +++-
 kernel/padata.c                              |   2 +-
 mm/filemap.c                                 |  26 ++---
 mm/memcontrol.c                              |  24 ++--
 mm/page_alloc.c                              |   3 +-
 mm/truncate.c                                |  20 +++-
 mm/vmscan.c                                  |  94 ++++++++++++----
 mm/workingset.c                              |   7 +-
 net/bluetooth/hci_sock.c                     |   3 +-
 net/core/datagram.c                          |  13 ++-
 tools/perf/arch/s390/annotate/instructions.c |  30 +++++
 tools/perf/util/annotate.c                   |   8 ++
 tools/perf/util/auxtrace.c                   |   4 +-
 tools/testing/selftests/x86/ldt_gdt.c        |  46 ++++++++
 virt/kvm/kvm_main.c                          |  34 +++---
 132 files changed, 1430 insertions(+), 778 deletions(-)
author maintainer
#1 lore raw

PATCH 1/114 xen: adjust early dom0 p2m handling to xen hypervisor behavior

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

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

From: Juergen Gross <[email protected]>

commit 69861e0a52f8733355ce246f0db15e1b240ad667 upstream.

When booted as pv-guest the p2m list presented by the Xen is already mapped to virtual addresses. In dom0 case the hypervisor might make use of 2M- or 1G-pages for this mapping. Unfortunately while being properly aligned in virtual and machine address space, those pages might not be aligned properly in guest physical address space.

So when trying to obtain the guest physical address of such a page pud_pfn() and pmd_pfn() must be avoided as those will mask away guest physical address bits not being zero in this special case.

---
 arch/x86/xen/mmu.c |    7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
arch/x86/xen/mmu.c +4 -3
@@ -2023,7 +2023,8 @@ static unsigned long __init xen_read_phy
 
 /*
  * Translate a virtual address to a physical one without relying on mapped
- * page tables.
+ * page tables. Don't rely on big pages being aligned in (guest) physical
+ * space!
  */
 static phys_addr_t __init xen_early_virt_to_phys(unsigned long vaddr)
 {
@@ -2044,7 +2045,7 @@ static phys_addr_t __init xen_early_virt
 						       sizeof(pud)));
 	if (!pud_present(pud))
 		return 0;
-	pa = pud_pfn(pud) << PAGE_SHIFT;
+	pa = pud_val(pud) & PTE_PFN_MASK;
 	if (pud_large(pud))
 		return pa + (vaddr & ~PUD_MASK);
 
@@ -2052,7 +2053,7 @@ static phys_addr_t __init xen_early_virt
 						       sizeof(pmd)));
 	if (!pmd_present(pmd))
 		return 0;
-	pa = pmd_pfn(pmd) << PAGE_SHIFT;
+	pa = pmd_val(pmd) & PTE_PFN_MASK;
 	if (pmd_large(pmd))
 		return pa + (vaddr & ~PMD_MASK);
 
author maintainer
#2 lore raw

PATCH 2/114 target: Fix compare_and_write_callback handling for non GOOD status

In reply to Greg Kroah-Hartman

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

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

From: Nicholas Bellinger <[email protected]>

commit a71a5dc7f833943998e97ca8fa6a4c708a0ed1a9 upstream.

Following the bugfix for handling non SAM_STAT_GOOD COMPARE_AND_WRITE status during COMMIT phase in commit 9b2792c3da1, the same bug exists for the READ phase as well.

This would manifest first as a lost SCSI response, and eventual hung task during fabric driver logout or re-login, as existing shutdown logic waited for the COMPARE_AND_WRITE se_cmd->cmd_kref to reach zero.

To address this bug, compare_and_write_callback() has been changed to set post_ret = 1 and return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE as necessary to signal failure status.

---
 drivers/target/target_core_sbc.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/target/target_core_sbc.c +4 -1
@@ -507,8 +507,11 @@ static sense_reason_t compare_and_write_
 	 * been failed with a non-zero SCSI status.
 	 */
 	if (cmd->scsi_status) {
-		pr_err("compare_and_write_callback: non zero scsi_status:"
+		pr_debug("compare_and_write_callback: non zero scsi_status:"
 			" 0x%02x\n", cmd->scsi_status);
+		*post_ret = 1;
+		if (cmd->scsi_status == SAM_STAT_CHECK_CONDITION)
+			ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
 		goto out;
 	}
 
author maintainer
#3 lore raw

PATCH 3/114 target/fileio: Fix zero-length READ and WRITE handling

In reply to Greg Kroah-Hartman

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

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

From: Bart Van Assche <[email protected]>

commit 59ac9c078141b8fd0186c0b18660a1b2c24e724e upstream.

This patch fixes zero-length READ and WRITE handling in target/FILEIO, which was broken a long time back by:

Since:

commit d81cb44726f050d7cf1be4afd9cb45d153b52066
Author: Paolo Bonzini <[email protected]>
Date: Mon Sep 17 16:36:11 2012 -0700

target: go through normal processing for all zero-length commands

which moved zero-length READ and WRITE completion out of target-core, to doing submission into backend driver code.

To address this, go ahead and invoke target_complete_cmd() for any non negative return value in fd_do_rw().

---
 drivers/target/target_core_file.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/target/target_core_file.c +1 -2
@@ -595,8 +595,7 @@ fd_execute_rw(struct se_cmd *cmd, struct
 	if (ret < 0)
 		return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
 
-	if (ret)
-		target_complete_cmd(cmd, SAM_STAT_GOOD);
+	target_complete_cmd(cmd, SAM_STAT_GOOD);
 	return 0;
 }
 
author maintainer
#4 lore raw

PATCH 4/114 iscsi-target: Set session_fall_back_to_erl0 when forcing reinstatement

In reply to Greg Kroah-Hartman

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

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

From: Nicholas Bellinger <[email protected]>

commit 197b806ae5db60c6f609d74da04ddb62ea5e1b00 upstream.

While testing modification of per se_node_acl queue_depth forcing session reinstatement via lio_target_nacl_cmdsn_depth_store() -> core_tpg_set_initiator_node_queue_depth(), a hung task bug triggered when changing cmdsn_depth invoked session reinstatement while an iscsi login was already waiting for session reinstatement to complete.

This can happen when an outstanding se_cmd descriptor is taking a long time to complete, and session reinstatement from iscsi login or cmdsn_depth change occurs concurrently.

To address this bug, explicitly set session_fall_back_to_erl0 = 1 when forcing session reinstatement, so session reinstatement is not attempted if an active session is already being shutdown.

This patch has been tested with two scenarios. The first when iscsi login is blocked waiting for iscsi session reinstatement to complete followed by queue_depth change via configfs, and second when queue_depth change via configfs us blocked followed by a iscsi login driven session reinstatement.

Note this patch depends on commit d36ad77f702 to handle multiple sessions per se_node_acl when changing cmdsn_depth, and for pre v4.5 kernels will need to be included for stable as well.

---
 drivers/target/iscsi/iscsi_target.c          |    1 +
 drivers/target/iscsi/iscsi_target_configfs.c |    1 +
 drivers/target/iscsi/iscsi_target_login.c    |    1 +
 3 files changed, 3 insertions(+)
drivers/target/iscsi/iscsi_target.c +1 -0
@@ -4683,6 +4683,7 @@ int iscsit_release_sessions_for_tpg(stru
 			continue;
 		}
 		atomic_set(&sess->session_reinstatement, 1);
+		atomic_set(&sess->session_fall_back_to_erl0, 1);
 		spin_unlock(&sess->conn_lock);
 
 		list_move_tail(&se_sess->sess_list, &free_list);
drivers/target/iscsi/iscsi_target_configfs.c +1 -0
@@ -1528,6 +1528,7 @@ static void lio_tpg_close_session(struct
 		return;
 	}
 	atomic_set(&sess->session_reinstatement, 1);
+	atomic_set(&sess->session_fall_back_to_erl0, 1);
 	spin_unlock(&sess->conn_lock);
 
 	iscsit_stop_time2retain_timer(sess);
drivers/target/iscsi/iscsi_target_login.c +1 -0
@@ -208,6 +208,7 @@ int iscsi_check_for_session_reinstatemen
 			    initiatorname_param->value) &&
 		   (sess_p->sess_ops->SessionType == sessiontype))) {
 			atomic_set(&sess_p->session_reinstatement, 1);
+			atomic_set(&sess_p->session_fall_back_to_erl0, 1);
 			spin_unlock(&sess_p->conn_lock);
 			iscsit_inc_session_usage_count(sess_p);
 			iscsit_stop_time2retain_timer(sess_p);
author maintainer
#5 lore raw

PATCH 5/114 usb: xhci: bInterval quirk for TI TUSB73x0

In reply to Greg Kroah-Hartman

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

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

From: Roger Quadros <[email protected]>

commit 69307ccb9ad7ccb653e332de68effdeaaab6907d upstream.

As per [1] issue #4,
"The periodic EP scheduler always tries to schedule the EPs that have large intervals (interval equal to or greater than 128 microframes) into different microframes. So it maintains an internal counter and increments for each large interval EP added. When the counter is greater than 128, the scheduler rejects the new EP. So when the hub re-enumerated 128 times, it triggers this condition."

This results in Bandwidth error when devices with periodic endpoints (ISO/INT) having bInterval > 7 are plugged and unplugged several times on a TUSB73x0 XHCI host.

Workaround this issue by limiting the bInterval to 7 (i.e. interval to 6) for High-speed or faster periodic endpoints.

[1] - http://www.ti.com/lit/er/sllz076/sllz076.pdf

---
 drivers/usb/host/xhci-mem.c |   11 +++++++++++
 drivers/usb/host/xhci-pci.c |    3 +++
 drivers/usb/host/xhci.h     |    1 +
 3 files changed, 15 insertions(+)
drivers/usb/host/xhci-mem.c +11 -0
@@ -1502,6 +1502,17 @@ int xhci_endpoint_init(struct xhci_hcd *
 	 */
 	max_esit_payload = xhci_get_max_esit_payload(udev, ep);
 	interval = xhci_get_endpoint_interval(udev, ep);
+
+	/* Periodic endpoint bInterval limit quirk */
+	if (usb_endpoint_xfer_int(&ep->desc) ||
+	    usb_endpoint_xfer_isoc(&ep->desc)) {
+		if ((xhci->quirks & XHCI_LIMIT_ENDPOINT_INTERVAL_7) &&
+		    udev->speed >= USB_SPEED_HIGH &&
+		    interval >= 7) {
+			interval = 6;
+		}
+	}
+
 	mult = xhci_get_endpoint_mult(udev, ep);
 	max_packet = usb_endpoint_maxp(&ep->desc);
 	max_burst = xhci_get_endpoint_max_burst(udev, ep);
drivers/usb/host/xhci-pci.c +3 -0
@@ -199,6 +199,9 @@ static void xhci_pci_quirks(struct devic
 			pdev->device == 0x1042)
 		xhci->quirks |= XHCI_BROKEN_STREAMS;
 
+	if (pdev->vendor == PCI_VENDOR_ID_TI && pdev->device == 0x8241)
+		xhci->quirks |= XHCI_LIMIT_ENDPOINT_INTERVAL_7;
+
 	if (xhci->quirks & XHCI_RESET_ON_RESUME)
 		xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
 				"QUIRK: Resetting on resume");
drivers/usb/host/xhci.h +1 -0
@@ -1818,6 +1818,7 @@ struct xhci_hcd {
 #define XHCI_MISSING_CAS	(1 << 24)
 /* For controller with a broken Port Disable implementation */
 #define XHCI_BROKEN_PORT_PED	(1 << 25)
+#define XHCI_LIMIT_ENDPOINT_INTERVAL_7	(1 << 26)
 
 	unsigned int		num_active_eps;
 	unsigned int		limit_active_eps;
author maintainer
#6 lore raw

PATCH 6/114 usb: host: xhci: print correct command ring address

In reply to Greg Kroah-Hartman

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

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

From: Peter Chen <[email protected]>

commit 6fc091fb0459ade939a795bfdcaf645385b951d4 upstream.

Print correct command ring address using 'val_64'.

---
 drivers/usb/host/xhci-mem.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/host/xhci-mem.c +1 -1
@@ -2491,7 +2491,7 @@ int xhci_mem_init(struct xhci_hcd *xhci,
 		(xhci->cmd_ring->first_seg->dma & (u64) ~CMD_RING_RSVD_BITS) |
 		xhci->cmd_ring->cycle_state;
 	xhci_dbg_trace(xhci, trace_xhci_dbg_init,
-			"// Setting command ring address to 0x%x", val);
+			"// Setting command ring address to 0x%016llx", val_64);
 	xhci_write_64(xhci, val_64, &xhci->op_regs->cmd_ring);
 	xhci_dbg_cmd_ptrs(xhci);
 
author maintainer
#7 lore raw

PATCH 7/114 USB: serial: ftdi_sio: add device ID for Microsemi/Arrow SF2PLUS Dev Kit

In reply to Greg Kroah-Hartman

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

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

From: Marek Vasut <[email protected]>

commit 31c5d1922b90ddc1da6a6ddecef7cd31f17aa32b upstream.

This development kit has an FT4232 on it with a custom USB VID/PID. The FT4232 provides four UARTs, but only two are used. The UART 0 is used by the FlashPro5 programmer and UART 2 is connected to the SmartFusion2 CortexM3 SoC UART port.

Note that the USB VID is registered to Actel according to Linux USB VID database, but that was acquired by Microsemi.

---
 drivers/usb/serial/ftdi_sio.c     |    1 +
 drivers/usb/serial/ftdi_sio_ids.h |    6 ++++++
 2 files changed, 7 insertions(+)
drivers/usb/serial/ftdi_sio.c +1 -0
@@ -873,6 +873,7 @@ static const struct usb_device_id id_tab
 	{ USB_DEVICE_AND_INTERFACE_INFO(MICROCHIP_VID, MICROCHIP_USB_BOARD_PID,
 					USB_CLASS_VENDOR_SPEC,
 					USB_SUBCLASS_VENDOR_SPEC, 0x00) },
+	{ USB_DEVICE_INTERFACE_NUMBER(ACTEL_VID, MICROSEMI_ARROW_SF2PLUS_BOARD_PID, 2) },
 	{ USB_DEVICE(JETI_VID, JETI_SPC1201_PID) },
 	{ USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID),
 		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
drivers/usb/serial/ftdi_sio_ids.h +6 -0
@@ -873,6 +873,12 @@
 #define	FIC_VID			0x1457
 #define	FIC_NEO1973_DEBUG_PID	0x5118
 
+/*
+ * Actel / Microsemi
+ */
+#define ACTEL_VID				0x1514
+#define MICROSEMI_ARROW_SF2PLUS_BOARD_PID	0x2008
+
 /* Olimex */
 #define OLIMEX_VID			0x15BA
 #define OLIMEX_ARM_USB_OCD_PID		0x0003
author maintainer
#8 lore raw

PATCH 8/114 USB: Proper handling of Race Condition when two USB class drivers try to call init_usb_class simultaneously

In reply to Greg Kroah-Hartman

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

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

From: Ajay Kaher <[email protected]>

commit 2f86a96be0ccb1302b7eee7855dbee5ce4dc5dfb upstream.

There is race condition when two USB class drivers try to call init_usb_class at the same time and leads to crash. code path: probe->usb_register_dev->init_usb_class

To solve this, mutex locking has been added in init_usb_class() and destroy_usb_class().

As pointed by Alan, removed "if (usb_class)" test from destroy_usb_class() because usb_class can never be NULL there.

---
 drivers/usb/core/file.c |    9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/usb/core/file.c +7 -2
@@ -29,6 +29,7 @@
 #define MAX_USB_MINORS	256
 static const struct file_operations *usb_minors[MAX_USB_MINORS];
 static DECLARE_RWSEM(minor_rwsem);
+static DEFINE_MUTEX(init_usb_class_mutex);
 
 static int usb_open(struct inode *inode, struct file *file)
 {
@@ -111,8 +112,9 @@ static void release_usb_class(struct kre
 
 static void destroy_usb_class(void)
 {
-	if (usb_class)
-		kref_put(&usb_class->kref, release_usb_class);
+	mutex_lock(&init_usb_class_mutex);
+	kref_put(&usb_class->kref, release_usb_class);
+	mutex_unlock(&init_usb_class_mutex);
 }
 
 int usb_major_init(void)
@@ -173,7 +175,10 @@ int usb_register_dev(struct usb_interfac
 	if (intf->minor >= 0)
 		return -EADDRINUSE;
 
+	mutex_lock(&init_usb_class_mutex);
 	retval = init_usb_class();
+	mutex_unlock(&init_usb_class_mutex);
+
 	if (retval)
 		return retval;
 
author maintainer
#9 lore raw

PATCH 10/114 staging: vt6656: use off stack for in buffer USB transfers.

In reply to Greg Kroah-Hartman

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

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

From: Malcolm Priestley <[email protected]>

commit 05c0cf88bec588a7cb34de569acd871ceef26760 upstream.

Since 4.9 mandated USB buffers to be heap allocated. This causes the driver to fail.

Create buffer for USB transfers.

---
 drivers/staging/vt6656/usbpipe.c |   17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)
drivers/staging/vt6656/usbpipe.c +15 -2
@@ -75,15 +75,28 @@ int vnt_control_in(struct vnt_private *p
 		    u16 index, u16 length, u8 *buffer)
 {
 	int status;
+	u8 *usb_buffer;
 
 	if (test_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags))
 		return STATUS_FAILURE;
 
 	mutex_lock(&priv->usb_lock);
 
+	usb_buffer = kmalloc(length, GFP_KERNEL);
+	if (!usb_buffer) {
+		mutex_unlock(&priv->usb_lock);
+		return -ENOMEM;
+	}
+
 	status = usb_control_msg(priv->usb,
-		                usb_rcvctrlpipe(priv->usb, 0), request, 0xc0, value,
-			        index, buffer, length, USB_CTL_WAIT);
+				 usb_rcvctrlpipe(priv->usb, 0),
+				 request, 0xc0, value,
+				 index, usb_buffer, length, USB_CTL_WAIT);
+
+	if (status == length)
+		memcpy(buffer, usb_buffer, length);
+
+	kfree(usb_buffer);
 
 	mutex_unlock(&priv->usb_lock);
 
author maintainer
#10 lore raw

PATCH 11/114 staging: vt6656: use off stack for out buffer USB transfers.

In reply to Greg Kroah-Hartman

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

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

From: Malcolm Priestley <[email protected]>

commit 12ecd24ef93277e4e5feaf27b0b18f2d3828bc5e upstream.

Since 4.9 mandated USB buffers be heap allocated this causes the driver to fail.

Since there is a wide range of buffer sizes use kmemdup to create allocated buffer.

---
 drivers/staging/vt6656/usbpipe.c |   14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)
drivers/staging/vt6656/usbpipe.c +12 -2
@@ -47,15 +47,25 @@ int vnt_control_out(struct vnt_private *
 		     u16 index, u16 length, u8 *buffer)
 {
 	int status = 0;
+	u8 *usb_buffer;
 
 	if (test_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags))
 		return STATUS_FAILURE;
 
 	mutex_lock(&priv->usb_lock);
 
+	usb_buffer = kmemdup(buffer, length, GFP_KERNEL);
+	if (!usb_buffer) {
+		mutex_unlock(&priv->usb_lock);
+		return -ENOMEM;
+	}
+
 	status = usb_control_msg(priv->usb,
-		usb_sndctrlpipe(priv->usb, 0), request, 0x40, value,
-			index, buffer, length, USB_CTL_WAIT);
+				 usb_sndctrlpipe(priv->usb, 0),
+				 request, 0x40, value,
+				 index, usb_buffer, length, USB_CTL_WAIT);
+
+	kfree(usb_buffer);
 
 	mutex_unlock(&priv->usb_lock);
 
author maintainer
#11 lore raw

PATCH 12/114 staging: gdm724x: gdm_mux: fix use-after-free on module unload

In reply to Greg Kroah-Hartman

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

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

From: Johan Hovold <[email protected]>

commit b58f45c8fc301fe83ee28cad3e64686c19e78f1c upstream.

Make sure to deregister the USB driver before releasing the tty driver to avoid use-after-free in the USB disconnect callback where the tty devices are deregistered.

Fixes 61e121047645 ("staging: gdm7240: adding LTE USB driver")
Cc Won Kang <[email protected]>
---
 drivers/staging/gdm724x/gdm_mux.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/staging/gdm724x/gdm_mux.c +1 -2
@@ -664,9 +664,8 @@ static int __init gdm_usb_mux_init(void)
 
 static void __exit gdm_usb_mux_exit(void)
 {
-	unregister_lte_tty_driver();
-
 	usb_deregister(&gdm_mux_driver);
+	unregister_lte_tty_driver();
 }
 
 module_init(gdm_usb_mux_init);
author maintainer
#12 lore raw

PATCH 13/114 staging: wilc1000: Fix problem with wrong vif index

In reply to Greg Kroah-Hartman

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

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

From: Aditya Shankar <[email protected]>

commit 0e490657c7214cce33fbca3d88227298c5c968ae upstream.

The vif->idx value is always 0 for two interfaces.

wl->vif_num = 0;

loop {
     ...

     vif->idx = wl->vif_num;
     ...
     wl->vif_num = i;
      ....
     i++;
     ...
}

At present, vif->idx is assigned the value of wl->vif_num
at the beginning of this block and device is initialized
based on this index value.
In the next iteration, wl->vif_num is still 0 as it is only updated later but gets assigned to vif->idx in the beginning. This causes problems later when we try to reference a particular interface and also while configuring the firmware.

This patch moves the assignment to vif->idx from the beginning of the block to after wl->vif_num is updated with latest value of i.

Fixes commit 735bb39ca3be ("staging: wilc1000: simplify vif[i]->ndev accesses")
---
 drivers/staging/wilc1000/linux_wlan.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/staging/wilc1000/linux_wlan.c +2 -1
@@ -1251,11 +1251,12 @@ int wilc_netdev_init(struct wilc **wilc,
 		else
 			strcpy(ndev->name, "p2p%d");
 
-		vif->idx = wl->vif_num;
 		vif->wilc = *wilc;
 		vif->ndev = ndev;
 		wl->vif[i] = vif;
 		wl->vif_num = i;
+		vif->idx = wl->vif_num;
+
 		ndev->netdev_ops = &wilc_netdev_ops;
 
 		{
author maintainer
#13 lore raw

PATCH 14/114 staging: sir: fill in missing fields and fix probe

In reply to Greg Kroah-Hartman

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

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

From: Sean Young <[email protected]>

commit cf9ed9aa5b0c196b796d2728218e3c06b0f42d90 upstream.

Some fields are left blank.

---
 drivers/staging/media/lirc/lirc_sir.c |   20 +++++++++-----------
 1 file changed, 9 insertions(+), 11 deletions(-)
drivers/staging/media/lirc/lirc_sir.c +9 -11
@@ -227,6 +227,7 @@ static int init_chrdev(void)
 	if (!rcdev)
 		return -ENOMEM;
 
+	rcdev->input_name = "SIR IrDA port";
 	rcdev->input_phys = KBUILD_MODNAME "/input0";
 	rcdev->input_id.bustype = BUS_HOST;
 	rcdev->input_id.vendor = 0x0001;
@@ -234,6 +235,7 @@ static int init_chrdev(void)
 	rcdev->input_id.version = 0x0100;
 	rcdev->tx_ir = sir_tx_ir;
 	rcdev->allowed_protocols = RC_BIT_ALL_IR_DECODER;
+	rcdev->driver_name = KBUILD_MODNAME;
 	rcdev->map_name = RC_MAP_RC6_MCE;
 	rcdev->timeout = IR_DEFAULT_TIMEOUT;
 	rcdev->dev.parent = &sir_ir_dev->dev;
@@ -740,7 +742,13 @@ static int init_sir_ir(void)
 
 static int sir_ir_probe(struct platform_device *dev)
 {
-	return 0;
+	int retval;
+
+	retval = init_chrdev();
+	if (retval < 0)
+		return retval;
+
+	return init_sir_ir();
 }
 
 static int sir_ir_remove(struct platform_device *dev)
@@ -780,18 +788,8 @@ static int __init sir_ir_init(void)
 		goto pdev_add_fail;
 	}
 
-	retval = init_chrdev();
-	if (retval < 0)
-		goto fail;
-
-	retval = init_sir_ir();
-	if (retval)
-		goto fail;
-
 	return 0;
 
-fail:
-	platform_device_del(sir_ir_dev);
 pdev_add_fail:
 	platform_device_put(sir_ir_dev);
 pdev_alloc_fail:
author maintainer
#14 lore raw

PATCH 15/114 staging: comedi: jr3_pci: fix possible null pointer dereference

In reply to Greg Kroah-Hartman

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

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

From: Ian Abbott <[email protected]>

commit 45292be0b3db0b7f8286683b376e2d9f949d11f9 upstream.

For some reason, the driver does not consider allocation of the subdevice private data to be a fatal error when attaching the COMEDI device. It tests the subdevice private data pointer for validity at certain points, but omits some crucial tests. In particular, jr3_pci_auto_attach() calls jr3_pci_alloc_spriv() to allocate and initialize the subdevice private data, but the same function subsequently dereferences the pointer to access the next_time_min and next_time_max members without checking it first. The other missing test is in the timer expiry routine jr3_pci_poll_dev(), but it will crash before it gets that far.

Fix the bug by returning -ENOMEM from jr3_pci_auto_attach() as soon as one of the calls to jr3_pci_alloc_spriv() returns NULL. The COMEDI core will subsequently call jr3_pci_detach() to clean up.

---
 drivers/staging/comedi/drivers/jr3_pci.c |   11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)
drivers/staging/comedi/drivers/jr3_pci.c +6 -5
@@ -727,11 +727,12 @@ static int jr3_pci_auto_attach(struct co
 		s->insn_read	= jr3_pci_ai_insn_read;
 
 		spriv = jr3_pci_alloc_spriv(dev, s);
-		if (spriv) {
-			/* Channel specific range and maxdata */
-			s->range_table_list	= spriv->range_table_list;
-			s->maxdata_list		= spriv->maxdata_list;
-		}
+		if (!spriv)
+			return -ENOMEM;
+
+		/* Channel specific range and maxdata */
+		s->range_table_list	= spriv->range_table_list;
+		s->maxdata_list		= spriv->maxdata_list;
 	}
 
 	/* Reset DSP card */
author maintainer
#15 lore raw

PATCH 16/114 staging: comedi: jr3_pci: cope with jiffies wraparound

In reply to Greg Kroah-Hartman

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

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

From: Ian Abbott <[email protected]>

commit 8ec04a491825e08068e92bed0bba7821893b6433 upstream.

The timer expiry routine jr3_pci_poll_dev() checks for expiry by checking whether the absolute value of jiffies (stored in local variable now) is greater than the expected expiry time in jiffy units. This will fail when jiffies wraps around. Also, it seems to make sense to handle the expiry one jiffy earlier than the current test. Use time_after_eq() to check for expiry.

---
 drivers/staging/comedi/drivers/jr3_pci.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/staging/comedi/drivers/jr3_pci.c +1 -1
@@ -611,7 +611,7 @@ static void jr3_pci_poll_dev(unsigned lo
 		s = &dev->subdevices[i];
 		spriv = s->private;
 
-		if (now > spriv->next_time_min) {
+		if (time_after_eq(now, spriv->next_time_min)) {
 			struct jr3_pci_poll_delay sub_delay;
 
 			sub_delay = jr3_pci_poll_subdevice(s);
author maintainer
#16 lore raw

PATCH 17/114 usb: misc: add missing continue in switch

In reply to Greg Kroah-Hartman

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

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

From: Gustavo A. R. Silva <[email protected]>

commit 2c930e3d0aed1505e86e0928d323df5027817740 upstream.

Add missing continue in switch.

Addresses-Coverity-ID: 1248733

---
 drivers/usb/misc/usbtest.c |    1 +
 1 file changed, 1 insertion(+)
drivers/usb/misc/usbtest.c +1 -0
@@ -159,6 +159,7 @@ get_endpoints(struct usbtest_dev *dev, s
 			case USB_ENDPOINT_XFER_INT:
 				if (dev->info->intr)
 					goto try_intr;
+				continue;
 			case USB_ENDPOINT_XFER_ISOC:
 				if (dev->info->iso)
 					goto try_iso;
author maintainer
#17 lore raw

PATCH 18/114 usb: gadget: legacy gadgets are optional

In reply to Greg Kroah-Hartman

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

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

From: Romain Izard <[email protected]>

commit 6e253d0fbc665b36192b8ed3cecdbb65b413a1eb upstream.

With commit bc49d1d17dcf ("usb: gadget: don't couple configfs to legacy gadgets"),it is possible to build a modular kernel with both built-in configfs support and modular legacy gadget drivers.

But when building a kernel without modules, it is also necessary to be able to build with configfs but without any legacy gadget driver. This was a possible configuration when the USB_CONFIGFS was a part of the choice options, but not anymore.

Mark the choice for legacy gadget drivers as optional restores this.

Fixes bc49d1d17dcf ("usb: gadget: don't couple configfs to legacy gadgets")
---
 drivers/usb/gadget/Kconfig |    1 +
 1 file changed, 1 insertion(+)
drivers/usb/gadget/Kconfig +1 -0
@@ -460,6 +460,7 @@ config USB_CONFIGFS_F_TCM
 choice
 	tristate "USB Gadget Drivers"
 	default USB_ETH
+	optional
 	help
 	  A Linux "Gadget Driver" talks to the USB Peripheral Controller
 	  driver through the abstract "gadget" API.  Some other operating
author maintainer
#18 lore raw

PATCH 19/114 usb: Make sure usb/phy/of gets built-in

In reply to Greg Kroah-Hartman

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

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

From: Alexey Brodkin <[email protected]>

commit 3d6159640da9c9175d1ca42f151fc1a14caded59 upstream.

DWC3 driver uses of_usb_get_phy_mode() which is implemented in drivers/usb/phy/of.c and in bare minimal configuration it might not be pulled in kernel binary.

In case of ARC or ARM this could be easily reproduced with "allnodefconfig" +CONFIG_USB=m +CONFIG_USB_DWC3=m.

On building all ends-up with:
---------------------->8------------------
Kernel: arch/arm/boot/Image is ready
Kernel: arch/arm/boot/zImage is ready
Building modules, stage 2.
MODPOST 5 modules
ERROR: "of_usb_get_phy_mode" [drivers/usb/dwc3/dwc3.ko] undefined! make[1]: *** [__modpost] Error 1
make: *** [modules] Error 2 ---------------------->8------------------

Signed-off-by Alexey Brodkin <abrodkin at synopsys.com>
Cc Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Cc Masahiro Yamada <yamada.masahiro at socionext.com>
Cc Geert Uytterhoeven <geert+renesas at glider.be>
Cc Nicolas Pitre <nicolas.pitre at linaro.org>
Cc Thomas Gleixner <tglx at linutronix.de>
Cc Felipe Balbi <balbi at kernel.org>
Cc Felix Fietkau <nbd at nbd.name>
Cc Jeremy Kerr <jk at ozlabs.org>
Cc linux-snps-arc at lists.infradead.org
Signed-off-by Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 drivers/Makefile |    1 +
 1 file changed, 1 insertion(+)
drivers/Makefile +1 -0
@@ -104,6 +104,7 @@ obj-$(CONFIG_USB_PHY)		+= usb/
 obj-$(CONFIG_USB)		+= usb/
 obj-$(CONFIG_PCI)		+= usb/
 obj-$(CONFIG_USB_GADGET)	+= usb/
+obj-$(CONFIG_OF)		+= usb/
 obj-$(CONFIG_SERIO)		+= input/serio/
 obj-$(CONFIG_GAMEPORT)		+= input/gameport/
 obj-$(CONFIG_INPUT)		+= input/
author maintainer
#19 lore raw

PATCH 20/114 usb: hub: Fix error loop seen after hub communication errors

In reply to Greg Kroah-Hartman

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

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

From: Guenter Roeck <[email protected]>

commit 245b2eecee2aac6fdc77dcafaa73c33f9644c3c7 upstream.

While stress testing a usb controller using a bind/unbind looop, the following error loop was observed.

usb 7-1.2: new low-speed USB device number 3 using xhci-hcd
usb 7-1.2: hub failed to enable device, error -108
usb 7-1-port2: cannot disable (err = -22)
usb 7-1-port2: couldn't allocate usb_device
usb 7-1-port2: cannot disable (err = -22)
hub 7-1:1.0: hub_ext_port_status failed (err = -22)
hub 7-1:1.0: hub_ext_port_status failed (err = -22)
hub 7-1:1.0: activate --> -22
hub 7-1:1.0: hub_ext_port_status failed (err = -22)
hub 7-1:1.0: hub_ext_port_status failed (err = -22)
hub 7-1:1.0: activate --> -22
hub 7-1:1.0: hub_ext_port_status failed (err = -22)
hub 7-1:1.0: hub_ext_port_status failed (err = -22)
hub 7-1:1.0: activate --> -22
hub 7-1:1.0: hub_ext_port_status failed (err = -22)
hub 7-1:1.0: hub_ext_port_status failed (err = -22)
hub 7-1:1.0: activate --> -22
hub 7-1:1.0: hub_ext_port_status failed (err = -22)
hub 7-1:1.0: hub_ext_port_status failed (err = -22)
hub 7-1:1.0: activate --> -22
hub 7-1:1.0: hub_ext_port_status failed (err = -22)
hub 7-1:1.0: hub_ext_port_status failed (err = -22)
hub 7-1:1.0: activate --> -22
hub 7-1:1.0: hub_ext_port_status failed (err = -22)
hub 7-1:1.0: hub_ext_port_status failed (err = -22)
hub 7-1:1.0: activate --> -22
hub 7-1:1.0: hub_ext_port_status failed (err = -22)
hub 7-1:1.0: hub_ext_port_status failed (err = -22)
hub 7-1:1.0: activate --> -22
hub 7-1:1.0: hub_ext_port_status failed (err = -22)
hub 7-1:1.0: hub_ext_port_status failed (err = -22)
** 57 printk messages dropped ** hub 7-1:1.0: activate --> -22
** 82 printk messages dropped ** hub 7-1:1.0: hub_ext_port_status failed (err = -22)

This continues forever. After adding tracebacks into the code, the call sequence leading to this is found to be as follows.

[<ffffffc0007fc8e0>] hub_activate+0x368/0x7b8
[<ffffffc0007fceb4>] hub_resume+0x2c/0x3c
[<ffffffc00080b3b8>] usb_resume_interface.isra.6+0x128/0x158
[<ffffffc00080b5d0>] usb_suspend_both+0x1e8/0x288
[<ffffffc00080c9c4>] usb_runtime_suspend+0x3c/0x98
[<ffffffc0007820a0>] __rpm_callback+0x48/0x7c
[<ffffffc00078217c>] rpm_callback+0xa8/0xd4
[<ffffffc000786234>] rpm_suspend+0x84/0x758
[<ffffffc000786ca4>] rpm_idle+0x2c8/0x498
[<ffffffc000786ed4>] __pm_runtime_idle+0x60/0xac
[<ffffffc00080eba8>] usb_autopm_put_interface+0x6c/0x7c
[<ffffffc000803798>] hub_event+0x10ac/0x12ac
[<ffffffc000249bb8>] process_one_work+0x390/0x6b8
[<ffffffc00024abcc>] worker_thread+0x480/0x610
[<ffffffc000251a80>] kthread+0x164/0x178
[<ffffffc0002045d0>] ret_from_fork+0x10/0x40

kick_hub_wq() is called from hub_activate() even after failures to communicate with the hub. This results in an endless sequence of hub event -> hub activate -> wq trigger -> hub event -> ...

Provide two solutions for the problem.

- Only trigger the hub event queue if communication with the hub is successful.
- After a suspend failure, only resume already suspended interfaces if the communication with the device is still possible.

Each of the changes fixes the observed problem. Use both to improve robustness.

---
 drivers/usb/core/driver.c |   18 ++++++++++++++++++
 drivers/usb/core/hub.c    |    5 ++++-
 2 files changed, 22 insertions(+), 1 deletion(-)
drivers/usb/core/driver.c +18 -0
@@ -1331,6 +1331,24 @@ static int usb_suspend_both(struct usb_d
 		 */
 		if (udev->parent && !PMSG_IS_AUTO(msg))
 			status = 0;
+
+		/*
+		 * If the device is inaccessible, don't try to resume
+		 * suspended interfaces and just return the error.
+		 */
+		if (status && status != -EBUSY) {
+			int err;
+			u16 devstat;
+
+			err = usb_get_status(udev, USB_RECIP_DEVICE, 0,
+					     &devstat);
+			if (err) {
+				dev_err(&udev->dev,
+					"Failed to suspend device, error %d\n",
+					status);
+				goto done;
+			}
+		}
 	}
 
 	/* If the suspend failed, resume interfaces that did get suspended */
drivers/usb/core/hub.c +4 -1
@@ -1066,6 +1066,9 @@ static void hub_activate(struct usb_hub
 
 		portstatus = portchange = 0;
 		status = hub_port_status(hub, port1, &portstatus, &portchange);
+		if (status)
+			goto abort;
+
 		if (udev || (portstatus & USB_PORT_STAT_CONNECTION))
 			dev_dbg(&port_dev->dev, "status %04x change %04x\n",
 					portstatus, portchange);
@@ -1198,7 +1201,7 @@ static void hub_activate(struct usb_hub
 
 	/* Scan all ports that need attention */
 	kick_hub_wq(hub);
-
+ abort:
 	if (type == HUB_INIT2 || type == HUB_INIT3) {
 		/* Allow autosuspend if it was suppressed */
  disconnected:
author maintainer
#20 lore raw

PATCH 21/114 usb: hub: Do not attempt to autosuspend disconnected devices

In reply to Greg Kroah-Hartman

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

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

From: Guenter Roeck <[email protected]>

commit f5cccf49428447dfbc9edb7a04bb8fc316269781 upstream.

While running a bind/unbind stress test with the dwc3 usb driver on rk3399, the following crash was observed.

Unable to handle kernel NULL pointer dereference at virtual address 00000218
pgd = ffffffc00165f000
[00000218] *pgd=000000000174f003, *pud=000000000174f003,
				*pmd=0000000001750003, *pte=00e8000001751713
Internal error: Oops: 96000005 [#1] PREEMPT SMP
Modules linked in: uinput uvcvideo videobuf2_vmalloc cmac

ipt_MASQUERADE nf_nat_masquerade_ipv4 iptable_nat nf_nat_ipv4 nf_nat rfcomm xt_mark fuse bridge stp llc zram btusb btrtl btbcm btintel bluetooth ip6table_filter mwifiex_pcie mwifiex cfg80211 cdc_ether usbnet r8152 mii joydev snd_seq_midi snd_seq_midi_event snd_rawmidi snd_seq snd_seq_device ppp_async ppp_generic slhc tun

CPU: 1 PID: 29814 Comm: kworker/1:1 Not tainted 4.4.52 #507
Hardware name: Google Kevin (DT)
Workqueue: pm pm_runtime_work
task: ffffffc0ac540000 ti: ffffffc0af4d4000 task.ti: ffffffc0af4d4000
PC is at autosuspend_check+0x74/0x174
LR is at autosuspend_check+0x70/0x174
...
Call trace:
[<ffffffc00080dcc0>] autosuspend_check+0x74/0x174
[<ffffffc000810500>] usb_runtime_idle+0x20/0x40
[<ffffffc000785ae0>] __rpm_callback+0x48/0x7c
[<ffffffc000786af0>] rpm_idle+0x1e8/0x498
[<ffffffc000787cdc>] pm_runtime_work+0x88/0xcc
[<ffffffc000249bb8>] process_one_work+0x390/0x6b8
[<ffffffc00024abcc>] worker_thread+0x480/0x610
[<ffffffc000251a80>] kthread+0x164/0x178
[<ffffffc0002045d0>] ret_from_fork+0x10/0x40

Source:

(gdb) l *0xffffffc00080dcc0
0xffffffc00080dcc0 is in autosuspend_check
(drivers/usb/core/driver.c:1778).
1773 /* We don't need to check interfaces that are
1774 * disabled for runtime PM. Either they are unbound
1775 * or else their drivers don't support autosuspend
1776 * and so they are permanently active.
1777 */
1778 if (intf->dev.power.disable_depth)
1779 continue;
1780 if (atomic_read(&intf->dev.power.usage_count) > 0)
1781 return -EBUSY;
1782 w |= intf->needs_remote_wakeup;

Code analysis shows that intf is set to NULL in usb_disable_device() prior to setting actconfig to NULL. At the same time, usb_runtime_idle() does not lock the usb device, and neither does any of the functions in the traceback. This means that there is no protection against a race condition where usb_disable_device() is removing dev->actconfig->interface[] pointers while those are being accessed from autosuspend_check().

To solve the problem, synchronize and validate device state between autosuspend_check() and usb_disconnect().

---
 drivers/usb/core/driver.c |    3 +++
 drivers/usb/core/hub.c    |    6 ++++++
 2 files changed, 9 insertions(+)
drivers/usb/core/driver.c +3 -0
@@ -1781,6 +1781,9 @@ static int autosuspend_check(struct usb_
 	int			w, i;
 	struct usb_interface	*intf;
 
+	if (udev->state == USB_STATE_NOTATTACHED)
+		return -ENODEV;
+
 	/* Fail if autosuspend is disabled, or any interfaces are in use, or
 	 * any interface drivers require remote wakeup but it isn't available.
 	 */
drivers/usb/core/hub.c +6 -0
@@ -2087,6 +2087,12 @@ void usb_disconnect(struct usb_device **
 	dev_info(&udev->dev, "USB disconnect, device number %d\n",
 			udev->devnum);
 
+	/*
+	 * Ensure that the pm runtime code knows that the USB device
+	 * is in the process of being disconnected.
+	 */
+	pm_runtime_barrier(&udev->dev);
+
 	usb_lock_device(udev);
 
 	hub_disconnect_children(udev);
author maintainer
#21 lore raw

PATCH 22/114 usb: misc: legousbtower: Fix buffers on stack

In reply to Greg Kroah-Hartman

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

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

From: Maksim Salau <[email protected]>

commit 942a48730faf149ccbf3e12ac718aee120bb3529 upstream.

Allocate buffers on HEAP instead of STACK for local structures that are to be received using usb_control_msg().

---
 drivers/usb/misc/legousbtower.c |   37 +++++++++++++++++++++++++++----------
 1 file changed, 27 insertions(+), 10 deletions(-)
drivers/usb/misc/legousbtower.c +27 -10
@@ -317,9 +317,16 @@ static int tower_open (struct inode *ino
 	int subminor;
 	int retval = 0;
 	struct usb_interface *interface;
-	struct tower_reset_reply reset_reply;
+	struct tower_reset_reply *reset_reply;
 	int result;
 
+	reset_reply = kmalloc(sizeof(*reset_reply), GFP_KERNEL);
+
+	if (!reset_reply) {
+		retval = -ENOMEM;
+		goto exit;
+	}
+
 	nonseekable_open(inode, file);
 	subminor = iminor(inode);
 
@@ -364,8 +371,8 @@ static int tower_open (struct inode *ino
 				  USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_DEVICE,
 				  0,
 				  0,
-				  &reset_reply,
-				  sizeof(reset_reply),
+				  reset_reply,
+				  sizeof(*reset_reply),
 				  1000);
 	if (result < 0) {
 		dev_err(&dev->udev->dev,
@@ -406,6 +413,7 @@ unlock_exit:
 	mutex_unlock(&dev->lock);
 
 exit:
+	kfree(reset_reply);
 	return retval;
 }
 
@@ -808,7 +816,7 @@ static int tower_probe (struct usb_inter
 	struct lego_usb_tower *dev = NULL;
 	struct usb_host_interface *iface_desc;
 	struct usb_endpoint_descriptor* endpoint;
-	struct tower_get_version_reply get_version_reply;
+	struct tower_get_version_reply *get_version_reply = NULL;
 	int i;
 	int retval = -ENOMEM;
 	int result;
@@ -886,6 +894,13 @@ static int tower_probe (struct usb_inter
 	dev->interrupt_in_interval = interrupt_in_interval ? interrupt_in_interval : dev->interrupt_in_endpoint->bInterval;
 	dev->interrupt_out_interval = interrupt_out_interval ? interrupt_out_interval : dev->interrupt_out_endpoint->bInterval;
 
+	get_version_reply = kmalloc(sizeof(*get_version_reply), GFP_KERNEL);
+
+	if (!get_version_reply) {
+		retval = -ENOMEM;
+		goto error;
+	}
+
 	/* get the firmware version and log it */
 	result = usb_control_msg (udev,
 				  usb_rcvctrlpipe(udev, 0),
@@ -893,18 +908,19 @@ static int tower_probe (struct usb_inter
 				  USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_DEVICE,
 				  0,
 				  0,
-				  &get_version_reply,
-				  sizeof(get_version_reply),
+				  get_version_reply,
+				  sizeof(*get_version_reply),
 				  1000);
 	if (result < 0) {
 		dev_err(idev, "LEGO USB Tower get version control request failed\n");
 		retval = result;
 		goto error;
 	}
-	dev_info(&interface->dev, "LEGO USB Tower firmware version is %d.%d "
-		 "build %d\n", get_version_reply.major,
-		 get_version_reply.minor,
-		 le16_to_cpu(get_version_reply.build_no));
+	dev_info(&interface->dev,
+		 "LEGO USB Tower firmware version is %d.%d build %d\n",
+		 get_version_reply->major,
+		 get_version_reply->minor,
+		 le16_to_cpu(get_version_reply->build_no));
 
 	/* we can register the device now, as it is ready */
 	usb_set_intfdata (interface, dev);
@@ -928,6 +944,7 @@ exit:
 	return retval;
 
 error:
+	kfree(get_version_reply);
 	tower_delete(dev);
 	return retval;
 }
author maintainer
#22 lore raw

PATCH 23/114 x86/boot: Fix BSS corruption/overwrite bug in early x86 kernel startup

In reply to Greg Kroah-Hartman

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

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

From: Ashish Kalra <[email protected]>

commit d594aa0277e541bb997aef0bc0a55172d8138340 upstream.

The minimum size for a new stack (512 bytes) setup for arch/x86/boot components when the bootloader does not setup/provide a stack for the early boot components is not "enough".

The setup code executing as part of early kernel startup code, uses the stack beyond 512 bytes and accidentally overwrites and corrupts part of the BSS section. This is exposed mostly in the early video setup code, where it was corrupting BSS variables like force_x, force_y, which in-turn affected kernel parameters such as screen_info (screen_info.orig_video_cols) and later caused an exception/panic in console_init().

Most recent boot loaders setup the stack for early boot components, so this stack overwriting into BSS section issue has not been exposed.

Cc Andy Lutomirski <[email protected]>
Cc Borislav Petkov <[email protected]>
Cc Brian Gerst <[email protected]>
Cc Denys Vlasenko <[email protected]>
Cc H. Peter Anvin <[email protected]>
Cc Josh Poimboeuf <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
---
 arch/x86/boot/boot.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/boot/boot.h +1 -1
@@ -16,7 +16,7 @@
 #ifndef BOOT_BOOT_H
 #define BOOT_BOOT_H
 
-#define STACK_SIZE	512	/* Minimum number of bytes for stack */
+#define STACK_SIZE	1024	/* Minimum number of bytes for stack */
 
 #ifndef __ASSEMBLY__
 
author maintainer
#23 lore raw

PATCH 24/114 selftests/x86/ldt_gdt_32: Work around a glibc sigaction() bug

In reply to Greg Kroah-Hartman

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

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

From: Andy Lutomirski <[email protected]>

commit 65973dd3fd31151823f4b8c289eebbb3fb7e6bc0 upstream.

i386 glibc is buggy and calls the sigaction syscall incorrectly.

This is asymptomatic for normal programs, but it blows up on programs that do evil things with segmentation. The ldt_gdt self-test is an example of such an evil program.

This doesn't appear to be a regression -- I think I just got lucky with the uninitialized memory that glibc threw at the kernel when I wrote the test.

This hackish fix manually issues sigaction(2) syscalls to undo the damage. Without the fix, ldt_gdt_32 segfaults; with the fix, it passes for me.

See: https://sourceware.org/bugzilla/show_bug.cgi?id=21269

---
 tools/testing/selftests/x86/ldt_gdt.c |   46 ++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)
tools/testing/selftests/x86/ldt_gdt.c +46 -0
@@ -409,6 +409,51 @@ static void *threadproc(void *ctx)
 	}
 }
 
+#ifdef __i386__
+
+#ifndef SA_RESTORE
+#define SA_RESTORER 0x04000000
+#endif
+
+/*
+ * The UAPI header calls this 'struct sigaction', which conflicts with
+ * glibc.  Sigh.
+ */
+struct fake_ksigaction {
+	void *handler;  /* the real type is nasty */
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+	unsigned char sigset[8];
+};
+
+static void fix_sa_restorer(int sig)
+{
+	struct fake_ksigaction ksa;
+
+	if (syscall(SYS_rt_sigaction, sig, NULL, &ksa, 8) == 0) {
+		/*
+		 * glibc has a nasty bug: it sometimes writes garbage to
+		 * sa_restorer.  This interacts quite badly with anything
+		 * that fiddles with SS because it can trigger legacy
+		 * stack switching.  Patch it up.  See:
+		 *
+		 * https://sourceware.org/bugzilla/show_bug.cgi?id=21269
+		 */
+		if (!(ksa.sa_flags & SA_RESTORER) && ksa.sa_restorer) {
+			ksa.sa_restorer = NULL;
+			if (syscall(SYS_rt_sigaction, sig, &ksa, NULL,
+				    sizeof(ksa.sigset)) != 0)
+				err(1, "rt_sigaction");
+		}
+	}
+}
+#else
+static void fix_sa_restorer(int sig)
+{
+	/* 64-bit glibc works fine. */
+}
+#endif
+
 static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *),
 		       int flags)
 {
@@ -420,6 +465,7 @@ static void sethandler(int sig, void (*h
 	if (sigaction(sig, &sa, 0))
 		err(1, "sigaction");
 
+	fix_sa_restorer(sig);
 }
 
 static jmp_buf jmpbuf;
author maintainer
#24 lore raw

PATCH 25/114 x86, pmem: Fix cache flushing for iovec write < 8 bytes

In reply to Greg Kroah-Hartman

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

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

From: Ben Hutchings <[email protected]>

commit 8376efd31d3d7c44bd05be337adde023cc531fa1 upstream.

Commit 11e63f6d920d added cache flushing for unaligned writes from an iovec, covering the first and last cache line of a >= 8 byte write and the first cache line of a < 8 byte write. But an unaligned write of 2-7 bytes can still cover two cache lines, so make sure we flush both in that case.

Fixes 11e63f6d920d ("x86, pmem: fix broken __copy_user_nocache ...")
---
 arch/x86/include/asm/pmem.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/include/asm/pmem.h +1 -1
@@ -103,7 +103,7 @@ static inline size_t arch_copy_from_iter
 
 		if (bytes < 8) {
 			if (!IS_ALIGNED(dest, 4) || (bytes != 4))
-				arch_wb_cache_pmem(addr, 1);
+				arch_wb_cache_pmem(addr, bytes);
 		} else {
 			if (!IS_ALIGNED(dest, 8)) {
 				dest = ALIGN(dest, boot_cpu_data.x86_clflush_size);
author maintainer
#25 lore raw

PATCH 26/114 um: Fix PTRACE_POKEUSER on x86_64

In reply to Greg Kroah-Hartman

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

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

From: Richard Weinberger <[email protected]>

commit 9abc74a22d85ab29cef9896a2582a530da7e79bf upstream.

This is broken since ever but sadly nobody noticed. Recent versions of GDB set DR_CONTROL unconditionally and UML dies due to a heap corruption. It turns out that the PTRACE_POKEUSER was copy&pasted from i386 and assumes that addresses are 4 bytes long.

Fix that by using 8 as address size in the calculation.

---
 arch/x86/um/ptrace_64.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/um/ptrace_64.c +1 -1
@@ -125,7 +125,7 @@ int poke_user(struct task_struct *child,
 	else if ((addr >= offsetof(struct user, u_debugreg[0])) &&
 		(addr <= offsetof(struct user, u_debugreg[7]))) {
 		addr -= offsetof(struct user, u_debugreg[0]);
-		addr = addr >> 2;
+		addr = addr >> 3;
 		if ((addr == 4) || (addr == 5))
 			return -EIO;
 		child->thread.arch.debugregs[addr] = data;
author maintainer
#26 lore raw

PATCH 27/114 perf/x86: Fix Broadwell-EP DRAM RAPL events

In reply to Greg Kroah-Hartman

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

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

From: Vince Weaver <[email protected]>

commit 33b88e708e7dfa58dc896da2a98f5719d2eb315c upstream.

It appears as though the Broadwell-EP DRAM units share the special units quirk with Haswell-EP/KNL.

Without this patch, you get really high results (a single DRAM using 20W of power).

The powercap driver in drivers/powercap/intel_rapl.c already has this change.

Cc Alexander Shishkin <[email protected]>
Cc Arnaldo Carvalho de Melo <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Kan Liang <[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]>
---
 arch/x86/events/intel/rapl.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/events/intel/rapl.c +1 -1
@@ -761,7 +761,7 @@ static const struct x86_cpu_id rapl_cpu_
 
 	X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_CORE,   hsw_rapl_init),
 	X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_GT3E,   hsw_rapl_init),
-	X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_X,	  hsw_rapl_init),
+	X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_X,	  hsx_rapl_init),
 	X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_XEON_D, hsw_rapl_init),
 
 	X86_RAPL_MODEL_MATCH(INTEL_FAM6_XEON_PHI_KNL, knl_rapl_init),
author maintainer
#27 lore raw

PATCH 29/114 Revert "KVM: Support vCPU-based gfn->hva cache"

In reply to Greg Kroah-Hartman

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

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

From: Paolo Bonzini <[email protected]>

commit 4e335d9e7ddbcf83d03e7fbe65797ebed2272c18 upstream.

This reverts commit bbd6411513aa8ef3ea02abab61318daf87c1af1e.

I've been sitting on this revert for too long and it unfortunately missed 4.11. It's also the reason why I haven't merged ring-based dirty tracking for 4.12.

Using kvm_vcpu_memslots in kvm_gfn_to_hva_cache_init and kvm_vcpu_write_guest_offset_cached means that the MSR value can now be used to access SMRAM, simply by making it point to an SMRAM physical address. This is problematic because it lets the guest OS overwrite memory that it shouldn't be able to touch.

Fixes bbd6411513aa8ef3ea02abab61318daf87c1af1e
---
 arch/x86/kvm/lapic.c     |   22 ++++++++++++----------
 arch/x86/kvm/x86.c       |   41 +++++++++++++++++++++--------------------
 include/linux/kvm_host.h |   16 ++++++++--------
 virt/kvm/kvm_main.c      |   34 +++++++++++++++++-----------------
 4 files changed, 58 insertions(+), 55 deletions(-)
arch/x86/kvm/lapic.c +12 -10
@@ -529,14 +529,16 @@ int kvm_apic_set_irq(struct kvm_vcpu *vc
 
 static int pv_eoi_put_user(struct kvm_vcpu *vcpu, u8 val)
 {
-	return kvm_vcpu_write_guest_cached(vcpu, &vcpu->arch.pv_eoi.data, &val,
-					   sizeof(val));
+
+	return kvm_write_guest_cached(vcpu->kvm, &vcpu->arch.pv_eoi.data, &val,
+				      sizeof(val));
 }
 
 static int pv_eoi_get_user(struct kvm_vcpu *vcpu, u8 *val)
 {
-	return kvm_vcpu_read_guest_cached(vcpu, &vcpu->arch.pv_eoi.data, val,
-					  sizeof(*val));
+
+	return kvm_read_guest_cached(vcpu->kvm, &vcpu->arch.pv_eoi.data, val,
+				      sizeof(*val));
 }
 
 static inline bool pv_eoi_enabled(struct kvm_vcpu *vcpu)
@@ -2285,8 +2287,8 @@ void kvm_lapic_sync_from_vapic(struct kv
 	if (!test_bit(KVM_APIC_CHECK_VAPIC, &vcpu->arch.apic_attention))
 		return;
 
-	if (kvm_vcpu_read_guest_cached(vcpu, &vcpu->arch.apic->vapic_cache, &data,
-				       sizeof(u32)))
+	if (kvm_read_guest_cached(vcpu->kvm, &vcpu->arch.apic->vapic_cache, &data,
+				  sizeof(u32)))
 		return;
 
 	apic_set_tpr(vcpu->arch.apic, data & 0xff);
@@ -2338,14 +2340,14 @@ void kvm_lapic_sync_to_vapic(struct kvm_
 		max_isr = 0;
 	data = (tpr & 0xff) | ((max_isr & 0xf0) << 8) | (max_irr << 24);
 
-	kvm_vcpu_write_guest_cached(vcpu, &vcpu->arch.apic->vapic_cache, &data,
-				    sizeof(u32));
+	kvm_write_guest_cached(vcpu->kvm, &vcpu->arch.apic->vapic_cache, &data,
+				sizeof(u32));
 }
 
 int kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr)
 {
 	if (vapic_addr) {
-		if (kvm_vcpu_gfn_to_hva_cache_init(vcpu,
+		if (kvm_gfn_to_hva_cache_init(vcpu->kvm,
 					&vcpu->arch.apic->vapic_cache,
 					vapic_addr, sizeof(u32)))
 			return -EINVAL;
@@ -2439,7 +2441,7 @@ int kvm_lapic_enable_pv_eoi(struct kvm_v
 	vcpu->arch.pv_eoi.msr_val = data;
 	if (!pv_eoi_enabled(vcpu))
 		return 0;
-	return kvm_vcpu_gfn_to_hva_cache_init(vcpu, &vcpu->arch.pv_eoi.data,
+	return kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.pv_eoi.data,
 					 addr, sizeof(u8));
 }
 
arch/x86/kvm/x86.c +21 -20

117 lines not on this page · raw message

include/linux/kvm_host.h +8 -8
@@ -641,18 +641,18 @@ int kvm_read_guest_page(struct kvm *kvm,
 int kvm_read_guest_atomic(struct kvm *kvm, gpa_t gpa, void *data,
 			  unsigned long len);
 int kvm_read_guest(struct kvm *kvm, gpa_t gpa, void *data, unsigned long len);
-int kvm_vcpu_read_guest_cached(struct kvm_vcpu *vcpu, struct gfn_to_hva_cache *ghc,
-			       void *data, unsigned long len);
+int kvm_read_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
+			   void *data, unsigned long len);
 int kvm_write_guest_page(struct kvm *kvm, gfn_t gfn, const void *data,
 			 int offset, int len);
 int kvm_write_guest(struct kvm *kvm, gpa_t gpa, const void *data,
 		    unsigned long len);
-int kvm_vcpu_write_guest_cached(struct kvm_vcpu *v, struct gfn_to_hva_cache *ghc,
-				void *data, unsigned long len);
-int kvm_vcpu_write_guest_offset_cached(struct kvm_vcpu *v, struct gfn_to_hva_cache *ghc,
-				       void *data, int offset, unsigned long len);
-int kvm_vcpu_gfn_to_hva_cache_init(struct kvm_vcpu *v, struct gfn_to_hva_cache *ghc,
-				   gpa_t gpa, unsigned long len);
+int kvm_write_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
+			   void *data, unsigned long len);
+int kvm_write_guest_offset_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
+			   void *data, int offset, unsigned long len);
+int kvm_gfn_to_hva_cache_init(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
+			      gpa_t gpa, unsigned long len);
 int kvm_clear_guest_page(struct kvm *kvm, gfn_t gfn, int offset, int len);
 int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len);
 struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn);
virt/kvm/kvm_main.c +17 -17
@@ -1973,18 +1973,18 @@ static int __kvm_gfn_to_hva_cache_init(s
 	return 0;
 }
 
-int kvm_vcpu_gfn_to_hva_cache_init(struct kvm_vcpu *vcpu, struct gfn_to_hva_cache *ghc,
+int kvm_gfn_to_hva_cache_init(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
 			      gpa_t gpa, unsigned long len)
 {
-	struct kvm_memslots *slots = kvm_vcpu_memslots(vcpu);
+	struct kvm_memslots *slots = kvm_memslots(kvm);
 	return __kvm_gfn_to_hva_cache_init(slots, ghc, gpa, len);
 }
-EXPORT_SYMBOL_GPL(kvm_vcpu_gfn_to_hva_cache_init);
+EXPORT_SYMBOL_GPL(kvm_gfn_to_hva_cache_init);
 
-int kvm_vcpu_write_guest_offset_cached(struct kvm_vcpu *vcpu, struct gfn_to_hva_cache *ghc,
-				       void *data, int offset, unsigned long len)
+int kvm_write_guest_offset_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
+			   void *data, int offset, unsigned long len)
 {
-	struct kvm_memslots *slots = kvm_vcpu_memslots(vcpu);
+	struct kvm_memslots *slots = kvm_memslots(kvm);
 	int r;
 	gpa_t gpa = ghc->gpa + offset;
 
@@ -1994,7 +1994,7 @@ int kvm_vcpu_write_guest_offset_cached(s
 		__kvm_gfn_to_hva_cache_init(slots, ghc, ghc->gpa, ghc->len);
 
 	if (unlikely(!ghc->memslot))
-		return kvm_vcpu_write_guest(vcpu, gpa, data, len);
+		return kvm_write_guest(kvm, gpa, data, len);
 
 	if (kvm_is_error_hva(ghc->hva))
 		return -EFAULT;
@@ -2006,19 +2006,19 @@ int kvm_vcpu_write_guest_offset_cached(s
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(kvm_vcpu_write_guest_offset_cached);
+EXPORT_SYMBOL_GPL(kvm_write_guest_offset_cached);
 
-int kvm_vcpu_write_guest_cached(struct kvm_vcpu *vcpu, struct gfn_to_hva_cache *ghc,
-			       void *data, unsigned long len)
+int kvm_write_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
+			   void *data, unsigned long len)
 {
-	return kvm_vcpu_write_guest_offset_cached(vcpu, ghc, data, 0, len);
+	return kvm_write_guest_offset_cached(kvm, ghc, data, 0, len);
 }
-EXPORT_SYMBOL_GPL(kvm_vcpu_write_guest_cached);
+EXPORT_SYMBOL_GPL(kvm_write_guest_cached);
 
-int kvm_vcpu_read_guest_cached(struct kvm_vcpu *vcpu, struct gfn_to_hva_cache *ghc,
-			       void *data, unsigned long len)
+int kvm_read_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
+			   void *data, unsigned long len)
 {
-	struct kvm_memslots *slots = kvm_vcpu_memslots(vcpu);
+	struct kvm_memslots *slots = kvm_memslots(kvm);
 	int r;
 
 	BUG_ON(len > ghc->len);
@@ -2027,7 +2027,7 @@ int kvm_vcpu_read_guest_cached(struct kv
 		__kvm_gfn_to_hva_cache_init(slots, ghc, ghc->gpa, ghc->len);
 
 	if (unlikely(!ghc->memslot))
-		return kvm_vcpu_read_guest(vcpu, ghc->gpa, data, len);
+		return kvm_read_guest(kvm, ghc->gpa, data, len);
 
 	if (kvm_is_error_hva(ghc->hva))
 		return -EFAULT;
@@ -2038,7 +2038,7 @@ int kvm_vcpu_read_guest_cached(struct kv
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(kvm_vcpu_read_guest_cached);
+EXPORT_SYMBOL_GPL(kvm_read_guest_cached);
 
 int kvm_clear_guest_page(struct kvm *kvm, gfn_t gfn, int offset, int len)
 {
author maintainer
#28 lore raw

PATCH 30/114 KVM: arm/arm64: fix races in kvm_psci_vcpu_on

In reply to Greg Kroah-Hartman

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

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

From: Andrew Jones <[email protected]>

commit 6c7a5dce22b3f3cc44be098e2837fa6797edb8b8 upstream.

Fix potential races in kvm_psci_vcpu_on() by taking the kvm->lock mutex. In general, it's a bad idea to allow more than one PSCI_CPU_ON to process the same target VCPU at the same time. One such problem that may arise is that one PSCI_CPU_ON could be resetting the target vcpu, which fills the entire sys_regs array with a temporary value including the MPIDR register, while another looks up the VCPU based on the MPIDR value, resulting in no target VCPU found. Resolves both races found with the kvm-unit-tests/arm/psci unit test.

---
 arch/arm/kvm/psci.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
arch/arm/kvm/psci.c +7 -1
@@ -208,9 +208,10 @@ int kvm_psci_version(struct kvm_vcpu *vc
 
 static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
 {
-	int ret = 1;
+	struct kvm *kvm = vcpu->kvm;
 	unsigned long psci_fn = vcpu_get_reg(vcpu, 0) & ~((u32) 0);
 	unsigned long val;
+	int ret = 1;
 
 	switch (psci_fn) {
 	case PSCI_0_2_FN_PSCI_VERSION:
@@ -230,7 +231,9 @@ static int kvm_psci_0_2_call(struct kvm_
 		break;
 	case PSCI_0_2_FN_CPU_ON:
 	case PSCI_0_2_FN64_CPU_ON:
+		mutex_lock(&kvm->lock);
 		val = kvm_psci_vcpu_on(vcpu);
+		mutex_unlock(&kvm->lock);
 		break;
 	case PSCI_0_2_FN_AFFINITY_INFO:
 	case PSCI_0_2_FN64_AFFINITY_INFO:
@@ -279,6 +282,7 @@ static int kvm_psci_0_2_call(struct kvm_
 
 static int kvm_psci_0_1_call(struct kvm_vcpu *vcpu)
 {
+	struct kvm *kvm = vcpu->kvm;
 	unsigned long psci_fn = vcpu_get_reg(vcpu, 0) & ~((u32) 0);
 	unsigned long val;
 
@@ -288,7 +292,9 @@ static int kvm_psci_0_1_call(struct kvm_
 		val = PSCI_RET_SUCCESS;
 		break;
 	case KVM_PSCI_FN_CPU_ON:
+		mutex_lock(&kvm->lock);
 		val = kvm_psci_vcpu_on(vcpu);
+		mutex_unlock(&kvm->lock);
 		break;
 	default:
 		val = PSCI_RET_NOT_SUPPORTED;
author maintainer
#29 lore raw

PATCH 31/114 arm64: KVM: Fix decoding of Rt/Rt2 when trapping AArch32 CP accesses

In reply to Greg Kroah-Hartman

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

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

From: Marc Zyngier <[email protected]>

commit c667186f1c01ca8970c785888868b7ffd74e51ee upstream.

Our 32bit CP14/15 handling inherited some of the ARMv7 code for handling the trapped system registers, completely missing the fact that the fields for Rt and Rt2 are now 5 bit wide, and not 4...

Let's fix it, and provide an accessor for the most common Rt case.

---
 arch/arm64/include/asm/kvm_emulate.h |    6 ++++++
 arch/arm64/kvm/sys_regs.c            |    8 ++++----
 2 files changed, 10 insertions(+), 4 deletions(-)
arch/arm64/include/asm/kvm_emulate.h +6 -0
@@ -240,6 +240,12 @@ static inline u8 kvm_vcpu_trap_get_fault
 	return kvm_vcpu_get_hsr(vcpu) & ESR_ELx_FSC_TYPE;
 }
 
+static inline int kvm_vcpu_sys_get_rt(struct kvm_vcpu *vcpu)
+{
+	u32 esr = kvm_vcpu_get_hsr(vcpu);
+	return (esr & ESR_ELx_SYS64_ISS_RT_MASK) >> ESR_ELx_SYS64_ISS_RT_SHIFT;
+}
+
 static inline unsigned long kvm_vcpu_get_mpidr_aff(struct kvm_vcpu *vcpu)
 {
 	return vcpu_sys_reg(vcpu, MPIDR_EL1) & MPIDR_HWID_BITMASK;
arch/arm64/kvm/sys_regs.c +4 -4
@@ -1638,8 +1638,8 @@ static int kvm_handle_cp_64(struct kvm_v
 {
 	struct sys_reg_params params;
 	u32 hsr = kvm_vcpu_get_hsr(vcpu);
-	int Rt = (hsr >> 5) & 0xf;
-	int Rt2 = (hsr >> 10) & 0xf;
+	int Rt = kvm_vcpu_sys_get_rt(vcpu);
+	int Rt2 = (hsr >> 10) & 0x1f;
 
 	params.is_aarch32 = true;
 	params.is_32bit = false;
@@ -1690,7 +1690,7 @@ static int kvm_handle_cp_32(struct kvm_v
 {
 	struct sys_reg_params params;
 	u32 hsr = kvm_vcpu_get_hsr(vcpu);
-	int Rt  = (hsr >> 5) & 0xf;
+	int Rt  = kvm_vcpu_sys_get_rt(vcpu);
 
 	params.is_aarch32 = true;
 	params.is_32bit = true;
@@ -1805,7 +1805,7 @@ int kvm_handle_sys_reg(struct kvm_vcpu *
 {
 	struct sys_reg_params params;
 	unsigned long esr = kvm_vcpu_get_hsr(vcpu);
-	int Rt = (esr >> 5) & 0x1f;
+	int Rt = kvm_vcpu_sys_get_rt(vcpu);
 	int ret;
 
 	trace_kvm_handle_sys_reg(esr);
author maintainer
#30 lore raw

PATCH 32/114 block: fix blk_integrity_register to use templates interval_exp if not 0

In reply to Greg Kroah-Hartman

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

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

From: Mike Snitzer <[email protected]>

commit 2859323e35ab5fc42f351fbda23ab544eaa85945 upstream.

When registering an integrity profile: if the template's interval_exp is not 0 use it, otherwise use the ilog2() of logical block size of the provided gendisk.

This fixes a long-standing DM linear target bug where it cannot pass integrity data to the underlying device if its logical block size conflicts with the underlying device's logical block size.

---
 block/blk-integrity.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
block/blk-integrity.c +2 -1
@@ -412,7 +412,8 @@ void blk_integrity_register(struct gendi
 
 	bi->flags = BLK_INTEGRITY_VERIFY | BLK_INTEGRITY_GENERATE |
 		template->flags;
-	bi->interval_exp = ilog2(queue_logical_block_size(disk->queue));
+	bi->interval_exp = template->interval_exp ? :
+		ilog2(queue_logical_block_size(disk->queue));
 	bi->profile = template->profile ? template->profile : &nop_profile;
 	bi->tuple_size = template->tuple_size;
 	bi->tag_size = template->tag_size;
author maintainer
#31 lore raw

PATCH 33/114 crypto: s5p-sss - Close possible race for completed requests

In reply to Greg Kroah-Hartman

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

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

From: Krzysztof Kozlowski <[email protected]>

commit 42d5c176b76e190a4a3e0dfeffdae661755955b6 upstream.

Driver is capable of handling only one request at a time and it stores it in its state container struct s5p_aes_dev. This stored request must be protected between concurrent invocations (e.g. completing current request and scheduling new one). Combination of lock and "busy" field is used for that purpose.

When "busy" field is true, the driver will not accept new request thus it will not overwrite currently handled data.

However commit 28b62b145868 ("crypto: s5p-sss - Fix spinlock recursion on LRW(AES)") moved some of the write to "busy" field out of a lock protected critical section. This might lead to potential race between completing current request and scheduling a new one. Effectively the request completion might try to operate on new crypto request.

Fixes 28b62b145868 ("crypto: s5p-sss - Fix spinlock recursion on LRW(AES)")
---
 drivers/crypto/s5p-sss.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/crypto/s5p-sss.c +3 -2
@@ -287,7 +287,6 @@ static void s5p_sg_done(struct s5p_aes_d
 static void s5p_aes_complete(struct s5p_aes_dev *dev, int err)
 {
 	dev->req->base.complete(&dev->req->base, err);
-	dev->busy = false;
 }
 
 static void s5p_unset_outdata(struct s5p_aes_dev *dev)
@@ -462,7 +461,7 @@ static irqreturn_t s5p_aes_interrupt(int
 		spin_unlock_irqrestore(&dev->lock, flags);
 
 		s5p_aes_complete(dev, 0);
-		dev->busy = true;
+		/* Device is still busy */
 		tasklet_schedule(&dev->tasklet);
 	} else {
 		/*
@@ -483,6 +482,7 @@ static irqreturn_t s5p_aes_interrupt(int
 
 error:
 	s5p_sg_done(dev);
+	dev->busy = false;
 	spin_unlock_irqrestore(&dev->lock, flags);
 	s5p_aes_complete(dev, err);
 
@@ -634,6 +634,7 @@ outdata_error:
 
 indata_error:
 	s5p_sg_done(dev);
+	dev->busy = false;
 	spin_unlock_irqrestore(&dev->lock, flags);
 	s5p_aes_complete(dev, err);
 }
author maintainer
#32 lore raw

PATCH 34/114 crypto: algif_aead - Require setkey before accept(2)

In reply to Greg Kroah-Hartman

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

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

From: Stephan Mueller <[email protected]>

commit 2a2a251f110576b1d89efbd0662677d7e7db21a8 upstream.

Some cipher implementations will crash if you try to use them without calling setkey first. This patch adds a check so that the accept(2) call will fail with -ENOKEY if setkey hasn't been done on the socket yet.

Fixes 400c40cf78da ("crypto: algif - add AEAD support")
---
 crypto/algif_aead.c |  157 +++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 149 insertions(+), 8 deletions(-)
crypto/algif_aead.c +149 -8
@@ -45,6 +45,11 @@ struct aead_async_req {
 	char iv[];
 };
 
+struct aead_tfm {
+	struct crypto_aead *aead;
+	bool has_key;
+};
+
 struct aead_ctx {
 	struct aead_sg_list tsgl;
 	struct aead_async_rsgl first_rsgl;
@@ -723,24 +728,146 @@ static struct proto_ops algif_aead_ops =
 	.poll		=	aead_poll,
 };
 
+static int aead_check_key(struct socket *sock)
+{
+	int err = 0;
+	struct sock *psk;
+	struct alg_sock *pask;
+	struct aead_tfm *tfm;
+	struct sock *sk = sock->sk;
+	struct alg_sock *ask = alg_sk(sk);
+
+	lock_sock(sk);
+	if (ask->refcnt)
+		goto unlock_child;
+
+	psk = ask->parent;
+	pask = alg_sk(ask->parent);
+	tfm = pask->private;
+
+	err = -ENOKEY;
+	lock_sock_nested(psk, SINGLE_DEPTH_NESTING);
+	if (!tfm->has_key)
+		goto unlock;
+
+	if (!pask->refcnt++)
+		sock_hold(psk);
+
+	ask->refcnt = 1;
+	sock_put(psk);
+
+	err = 0;
+
+unlock:
+	release_sock(psk);
+unlock_child:
+	release_sock(sk);
+
+	return err;
+}
+
+static int aead_sendmsg_nokey(struct socket *sock, struct msghdr *msg,
+				  size_t size)
+{
+	int err;
+
+	err = aead_check_key(sock);
+	if (err)
+		return err;
+
+	return aead_sendmsg(sock, msg, size);
+}
+
+static ssize_t aead_sendpage_nokey(struct socket *sock, struct page *page,
+				       int offset, size_t size, int flags)
+{
+	int err;
+
+	err = aead_check_key(sock);
+	if (err)
+		return err;
+
+	return aead_sendpage(sock, page, offset, size, flags);
+}
+
+static int aead_recvmsg_nokey(struct socket *sock, struct msghdr *msg,
+				  size_t ignored, int flags)
+{
+	int err;
+
+	err = aead_check_key(sock);
+	if (err)
+		return err;
+
+	return aead_recvmsg(sock, msg, ignored, flags);
+}
+
+static struct proto_ops algif_aead_ops_nokey = {
+	.family		=	PF_ALG,
+
+	.connect	=	sock_no_connect,
+	.socketpair	=	sock_no_socketpair,
+	.getname	=	sock_no_getname,
+	.ioctl		=	sock_no_ioctl,
+	.listen		=	sock_no_listen,
+	.shutdown	=	sock_no_shutdown,
+	.getsockopt	=	sock_no_getsockopt,
+	.mmap		=	sock_no_mmap,
+	.bind		=	sock_no_bind,
+	.accept		=	sock_no_accept,
+	.setsockopt	=	sock_no_setsockopt,
+
+	.release	=	af_alg_release,
+	.sendmsg	=	aead_sendmsg_nokey,
+	.sendpage	=	aead_sendpage_nokey,
+	.recvmsg	=	aead_recvmsg_nokey,
+	.poll		=	aead_poll,
+};
+
 static void *aead_bind(const char *name, u32 type, u32 mask)
 {
-	return crypto_alloc_aead(name, type, mask);
+	struct aead_tfm *tfm;
+	struct crypto_aead *aead;
+
+	tfm = kzalloc(sizeof(*tfm), GFP_KERNEL);
+	if (!tfm)
+		return ERR_PTR(-ENOMEM);
+
+	aead = crypto_alloc_aead(name, type, mask);
+	if (IS_ERR(aead)) {
+		kfree(tfm);
+		return ERR_CAST(aead);
+	}
+
+	tfm->aead = aead;
+
+	return tfm;
 }
 
 static void aead_release(void *private)
 {
-	crypto_free_aead(private);
+	struct aead_tfm *tfm = private;
+
+	crypto_free_aead(tfm->aead);
+	kfree(tfm);
 }
 
 static int aead_setauthsize(void *private, unsigned int authsize)
 {
-	return crypto_aead_setauthsize(private, authsize);
+	struct aead_tfm *tfm = private;
+
+	return crypto_aead_setauthsize(tfm->aead, authsize);
 }
 
 static int aead_setkey(void *private, const u8 *key, unsigned int keylen)
 {
-	return crypto_aead_setkey(private, key, keylen);
+	struct aead_tfm *tfm = private;
+	int err;
+
+	err = crypto_aead_setkey(tfm->aead, key, keylen);
+	tfm->has_key = !err;
+
+	return err;
 }
 
 static void aead_sock_destruct(struct sock *sk)
@@ -757,12 +884,14 @@ static void aead_sock_destruct(struct so
 	af_alg_release_parent(sk);
 }
 
-static int aead_accept_parent(void *private, struct sock *sk)
+static int aead_accept_parent_nokey(void *private, struct sock *sk)
 {
 	struct aead_ctx *ctx;
 	struct alg_sock *ask = alg_sk(sk);
-	unsigned int len = sizeof(*ctx) + crypto_aead_reqsize(private);
-	unsigned int ivlen = crypto_aead_ivsize(private);
+	struct aead_tfm *tfm = private;
+	struct crypto_aead *aead = tfm->aead;
+	unsigned int len = sizeof(*ctx) + crypto_aead_reqsize(aead);
+	unsigned int ivlen = crypto_aead_ivsize(aead);
 
 	ctx = sock_kmalloc(sk, len, GFP_KERNEL);
 	if (!ctx)
@@ -789,7 +918,7 @@ static int aead_accept_parent(void *priv
 
 	ask->private = ctx;
 
-	aead_request_set_tfm(&ctx->aead_req, private);
+	aead_request_set_tfm(&ctx->aead_req, aead);
 	aead_request_set_callback(&ctx->aead_req, CRYPTO_TFM_REQ_MAY_BACKLOG,
 				  af_alg_complete, &ctx->completion);
 
@@ -798,13 +927,25 @@ static int aead_accept_parent(void *priv
 	return 0;
 }
 
+static int aead_accept_parent(void *private, struct sock *sk)
+{
+	struct aead_tfm *tfm = private;
+
+	if (!tfm->has_key)
+		return -ENOKEY;
+
+	return aead_accept_parent_nokey(private, sk);
+}
+
 static const struct af_alg_type algif_type_aead = {
 	.bind		=	aead_bind,
 	.release	=	aead_release,
 	.setkey		=	aead_setkey,
 	.setauthsize	=	aead_setauthsize,
 	.accept		=	aead_accept_parent,
+	.accept_nokey	=	aead_accept_parent_nokey,
 	.ops		=	&algif_aead_ops,
+	.ops_nokey	=	&algif_aead_ops_nokey,
 	.name		=	"aead",
 	.owner		=	THIS_MODULE
 };
author maintainer
#33 lore raw

PATCH 35/114 crypto: ccp - Use only the relevant interrupt bits

In reply to Greg Kroah-Hartman

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

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

From: Gary R Hook <[email protected]>

commit 56467cb11cf8ae4db9003f54b3d3425b5f07a10a upstream.

Each CCP queue can product interrupts for 4 conditions:
operation complete, queue empty, error, and queue stopped. This driver only works with completion and error events.

---
 drivers/crypto/ccp/ccp-dev-v5.c |    9 +++++----
 drivers/crypto/ccp/ccp-dev.h    |    5 ++---
 2 files changed, 7 insertions(+), 7 deletions(-)
drivers/crypto/ccp/ccp-dev-v5.c +5 -4
@@ -748,7 +748,7 @@ static int ccp5_init(struct ccp_device *
 		ioread32(cmd_q->reg_status);
 
 		/* Clear the interrupts */
-		iowrite32(ALL_INTERRUPTS, cmd_q->reg_interrupt_status);
+		iowrite32(SUPPORTED_INTERRUPTS, cmd_q->reg_interrupt_status);
 	}
 
 	dev_dbg(dev, "Requesting an IRQ...\n");
@@ -829,7 +829,7 @@ static int ccp5_init(struct ccp_device *
 	/* Enable interrupts */
 	for (i = 0; i < ccp->cmd_q_count; i++) {
 		cmd_q = &ccp->cmd_q[i];
-		iowrite32(ALL_INTERRUPTS, cmd_q->reg_int_enable);
+		iowrite32(SUPPORTED_INTERRUPTS, cmd_q->reg_int_enable);
 	}
 
 	dev_dbg(dev, "Registering device...\n");
@@ -889,7 +889,7 @@ static void ccp5_destroy(struct ccp_devi
 		iowrite32(cmd_q->qcontrol & ~CMD5_Q_RUN, cmd_q->reg_control);
 
 		/* Disable the interrupts */
-		iowrite32(ALL_INTERRUPTS, cmd_q->reg_interrupt_status);
+		iowrite32(SUPPORTED_INTERRUPTS, cmd_q->reg_interrupt_status);
 
 		/* Clear the interrupt status */
 		iowrite32(0x00, cmd_q->reg_int_enable);
@@ -949,7 +949,8 @@ static irqreturn_t ccp5_irq_handler(int
 			cmd_q->int_rcvd = 1;
 
 			/* Acknowledge the interrupt and wake the kthread */
-			iowrite32(ALL_INTERRUPTS, cmd_q->reg_interrupt_status);
+			iowrite32(SUPPORTED_INTERRUPTS,
+				  cmd_q->reg_interrupt_status);
 			wake_up_interruptible(&cmd_q->int_queue);
 		}
 	}
drivers/crypto/ccp/ccp-dev.h +2 -3
@@ -109,9 +109,8 @@
 #define INT_COMPLETION			0x1
 #define INT_ERROR			0x2
 #define INT_QUEUE_STOPPED		0x4
-#define ALL_INTERRUPTS			(INT_COMPLETION| \
-					 INT_ERROR| \
-					 INT_QUEUE_STOPPED)
+#define	INT_EMPTY_QUEUE			0x8
+#define SUPPORTED_INTERRUPTS		(INT_COMPLETION | INT_ERROR)
 
 #define LSB_REGION_WIDTH		5
 #define MAX_LSB_CNT			8
author maintainer
#34 lore raw

PATCH 36/114 crypto: ccp - Disable interrupts early on unload

In reply to Greg Kroah-Hartman

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

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

From: Gary R Hook <[email protected]>

commit 116591fe3eef11c6f06b662c9176385f13891183 upstream.

Ensure that we disable interrupts first when shutting down the driver.

---
 drivers/crypto/ccp/ccp-dev-v5.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/crypto/ccp/ccp-dev-v5.c +2 -2
@@ -889,10 +889,10 @@ static void ccp5_destroy(struct ccp_devi
 		iowrite32(cmd_q->qcontrol & ~CMD5_Q_RUN, cmd_q->reg_control);
 
 		/* Disable the interrupts */
-		iowrite32(SUPPORTED_INTERRUPTS, cmd_q->reg_interrupt_status);
+		iowrite32(0x00, cmd_q->reg_int_enable);
 
 		/* Clear the interrupt status */
-		iowrite32(0x00, cmd_q->reg_int_enable);
+		iowrite32(SUPPORTED_INTERRUPTS, cmd_q->reg_interrupt_status);
 		ioread32(cmd_q->reg_int_status);
 		ioread32(cmd_q->reg_status);
 	}
author maintainer
#35 lore raw

PATCH 37/114 crypto: ccp - Change ISR handler method for a v3 CCP

In reply to Greg Kroah-Hartman

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

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

From: Gary R Hook <[email protected]>

commit 7b537b24e76a1e8e6d7ea91483a45d5b1426809b upstream.

The CCP has the ability to perform several operations simultaneously, but only one interrupt. When implemented as a PCI device and using MSI-X/MSI interrupts, use a tasklet model to service interrupts. By disabling and enabling interrupts from the CCP, coupled with the queuing that tasklets provide, we can ensure that all events (occurring on the device) are recognized and serviced.

This change fixes a problem wherein 2 or more busy queues can cause notification bits to change state while a (CCP) interrupt is being serviced, but after the queue state has been evaluated. This results in the event being 'lost' and the queue hanging, waiting to be serviced. Since the status bits are never fully de-asserted, the CCP never generates another interrupt (all bits zero -> one or more bits one), and no further CCP operations will be executed.

---
 drivers/crypto/ccp/ccp-dev-v3.c |  120 +++++++++++++++++++++++-----------------
 drivers/crypto/ccp/ccp-dev.h    |    3 +
 drivers/crypto/ccp/ccp-pci.c    |    2 
 3 files changed, 75 insertions(+), 50 deletions(-)
drivers/crypto/ccp/ccp-dev-v3.c +70 -50
@@ -315,17 +315,73 @@ static int ccp_perform_ecc(struct ccp_op
 	return ccp_do_cmd(op, cr, ARRAY_SIZE(cr));
 }
 
+static void ccp_disable_queue_interrupts(struct ccp_device *ccp)
+{
+	iowrite32(0x00, ccp->io_regs + IRQ_MASK_REG);
+}
+
+static void ccp_enable_queue_interrupts(struct ccp_device *ccp)
+{
+	iowrite32(ccp->qim, ccp->io_regs + IRQ_MASK_REG);
+}
+
+static void ccp_irq_bh(unsigned long data)
+{
+	struct ccp_device *ccp = (struct ccp_device *)data;
+	struct ccp_cmd_queue *cmd_q;
+	u32 q_int, status;
+	unsigned int i;
+
+	status = ioread32(ccp->io_regs + IRQ_STATUS_REG);
+
+	for (i = 0; i < ccp->cmd_q_count; i++) {
+		cmd_q = &ccp->cmd_q[i];
+
+		q_int = status & (cmd_q->int_ok | cmd_q->int_err);
+		if (q_int) {
+			cmd_q->int_status = status;
+			cmd_q->q_status = ioread32(cmd_q->reg_status);
+			cmd_q->q_int_status = ioread32(cmd_q->reg_int_status);
+
+			/* On error, only save the first error value */
+			if ((q_int & cmd_q->int_err) && !cmd_q->cmd_error)
+				cmd_q->cmd_error = CMD_Q_ERROR(cmd_q->q_status);
+
+			cmd_q->int_rcvd = 1;
+
+			/* Acknowledge the interrupt and wake the kthread */
+			iowrite32(q_int, ccp->io_regs + IRQ_STATUS_REG);
+			wake_up_interruptible(&cmd_q->int_queue);
+		}
+	}
+	ccp_enable_queue_interrupts(ccp);
+}
+
+static irqreturn_t ccp_irq_handler(int irq, void *data)
+{
+	struct device *dev = data;
+	struct ccp_device *ccp = dev_get_drvdata(dev);
+
+	ccp_disable_queue_interrupts(ccp);
+	if (ccp->use_tasklet)
+		tasklet_schedule(&ccp->irq_tasklet);
+	else
+		ccp_irq_bh((unsigned long)ccp);
+
+	return IRQ_HANDLED;
+}
+
 static int ccp_init(struct ccp_device *ccp)
 {
 	struct device *dev = ccp->dev;
 	struct ccp_cmd_queue *cmd_q;
 	struct dma_pool *dma_pool;
 	char dma_pool_name[MAX_DMAPOOL_NAME_LEN];
-	unsigned int qmr, qim, i;
+	unsigned int qmr, i;
 	int ret;
 
 	/* Find available queues */
-	qim = 0;
+	ccp->qim = 0;
 	qmr = ioread32(ccp->io_regs + Q_MASK_REG);
 	for (i = 0; i < MAX_HW_QUEUES; i++) {
 		if (!(qmr & (1 << i)))
@@ -370,7 +426,7 @@ static int ccp_init(struct ccp_device *c
 		init_waitqueue_head(&cmd_q->int_queue);
 
 		/* Build queue interrupt mask (two interrupts per queue) */
-		qim |= cmd_q->int_ok | cmd_q->int_err;
+		ccp->qim |= cmd_q->int_ok | cmd_q->int_err;
 
 #ifdef CONFIG_ARM64
 		/* For arm64 set the recommended queue cache settings */
@@ -388,14 +444,14 @@ static int ccp_init(struct ccp_device *c
 	dev_notice(dev, "%u command queues available\n", ccp->cmd_q_count);
 
 	/* Disable and clear interrupts until ready */
-	iowrite32(0x00, ccp->io_regs + IRQ_MASK_REG);
+	ccp_disable_queue_interrupts(ccp);
 	for (i = 0; i < ccp->cmd_q_count; i++) {
 		cmd_q = &ccp->cmd_q[i];
 
 		ioread32(cmd_q->reg_int_status);
 		ioread32(cmd_q->reg_status);
 	}
-	iowrite32(qim, ccp->io_regs + IRQ_STATUS_REG);
+	iowrite32(ccp->qim, ccp->io_regs + IRQ_STATUS_REG);
 
 	/* Request an irq */
 	ret = ccp->get_irq(ccp);
@@ -404,6 +460,11 @@ static int ccp_init(struct ccp_device *c
 		goto e_pool;
 	}
 
+	/* Initialize the ISR tasklet? */
+	if (ccp->use_tasklet)
+		tasklet_init(&ccp->irq_tasklet, ccp_irq_bh,
+			     (unsigned long)ccp);
+
 	dev_dbg(dev, "Starting threads...\n");
 	/* Create a kthread for each queue */
 	for (i = 0; i < ccp->cmd_q_count; i++) {
@@ -426,7 +487,7 @@ static int ccp_init(struct ccp_device *c
 
 	dev_dbg(dev, "Enabling interrupts...\n");
 	/* Enable interrupts */
-	iowrite32(qim, ccp->io_regs + IRQ_MASK_REG);
+	ccp_enable_queue_interrupts(ccp);
 
 	dev_dbg(dev, "Registering device...\n");
 	ccp_add_device(ccp);
@@ -463,7 +524,7 @@ static void ccp_destroy(struct ccp_devic
 {
 	struct ccp_cmd_queue *cmd_q;
 	struct ccp_cmd *cmd;
-	unsigned int qim, i;
+	unsigned int i;
 
 	/* Unregister the DMA engine */
 	ccp_dmaengine_unregister(ccp);
@@ -474,22 +535,15 @@ static void ccp_destroy(struct ccp_devic
 	/* Remove this device from the list of available units */
 	ccp_del_device(ccp);
 
-	/* Build queue interrupt mask (two interrupt masks per queue) */
-	qim = 0;
-	for (i = 0; i < ccp->cmd_q_count; i++) {
-		cmd_q = &ccp->cmd_q[i];
-		qim |= cmd_q->int_ok | cmd_q->int_err;
-	}
-
 	/* Disable and clear interrupts */
-	iowrite32(0x00, ccp->io_regs + IRQ_MASK_REG);
+	ccp_disable_queue_interrupts(ccp);
 	for (i = 0; i < ccp->cmd_q_count; i++) {
 		cmd_q = &ccp->cmd_q[i];
 
 		ioread32(cmd_q->reg_int_status);
 		ioread32(cmd_q->reg_status);
 	}
-	iowrite32(qim, ccp->io_regs + IRQ_STATUS_REG);
+	iowrite32(ccp->qim, ccp->io_regs + IRQ_STATUS_REG);
 
 	/* Stop the queue kthreads */
 	for (i = 0; i < ccp->cmd_q_count; i++)
@@ -516,40 +570,6 @@ static void ccp_destroy(struct ccp_devic
 	}
 }
 
-static irqreturn_t ccp_irq_handler(int irq, void *data)
-{
-	struct device *dev = data;
-	struct ccp_device *ccp = dev_get_drvdata(dev);
-	struct ccp_cmd_queue *cmd_q;
-	u32 q_int, status;
-	unsigned int i;
-
-	status = ioread32(ccp->io_regs + IRQ_STATUS_REG);
-
-	for (i = 0; i < ccp->cmd_q_count; i++) {
-		cmd_q = &ccp->cmd_q[i];
-
-		q_int = status & (cmd_q->int_ok | cmd_q->int_err);
-		if (q_int) {
-			cmd_q->int_status = status;
-			cmd_q->q_status = ioread32(cmd_q->reg_status);
-			cmd_q->q_int_status = ioread32(cmd_q->reg_int_status);
-
-			/* On error, only save the first error value */
-			if ((q_int & cmd_q->int_err) && !cmd_q->cmd_error)
-				cmd_q->cmd_error = CMD_Q_ERROR(cmd_q->q_status);
-
-			cmd_q->int_rcvd = 1;
-
-			/* Acknowledge the interrupt and wake the kthread */
-			iowrite32(q_int, ccp->io_regs + IRQ_STATUS_REG);
-			wake_up_interruptible(&cmd_q->int_queue);
-		}
-	}
-
-	return IRQ_HANDLED;
-}
-
 static const struct ccp_actions ccp3_actions = {
 	.aes = ccp_perform_aes,
 	.xts_aes = ccp_perform_xts_aes,
drivers/crypto/ccp/ccp-dev.h +3 -0
@@ -336,7 +336,10 @@ struct ccp_device {
 	void *dev_specific;
 	int (*get_irq)(struct ccp_device *ccp);
 	void (*free_irq)(struct ccp_device *ccp);
+	unsigned int qim;
 	unsigned int irq;
+	bool use_tasklet;
+	struct tasklet_struct irq_tasklet;
 
 	/* I/O area used for device communication. The register mapping
 	 * starts at an offset into the mapped bar.
drivers/crypto/ccp/ccp-pci.c +2 -0
@@ -69,6 +69,7 @@ static int ccp_get_msix_irqs(struct ccp_
 			goto e_irq;
 		}
 	}
+	ccp->use_tasklet = true;
 
 	return 0;
 
@@ -100,6 +101,7 @@ static int ccp_get_msi_irq(struct ccp_de
 		dev_notice(dev, "unable to allocate MSI IRQ (%d)\n", ret);
 		goto e_msi;
 	}
+	ccp->use_tasklet = true;
 
 	return 0;
 
author maintainer
#36 lore raw

PATCH 38/114 crypto: ccp - Change ISR handler method for a v5 CCP

In reply to Greg Kroah-Hartman

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

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

From: Gary R Hook <[email protected]>

commit 6263b51eb3190d30351360fd168959af7e3a49a9 upstream.

The CCP has the ability to perform several operations simultaneously, but only one interrupt. When implemented as a PCI device and using MSI-X/MSI interrupts, use a tasklet model to service interrupts. By disabling and enabling interrupts from the CCP, coupled with the queuing that tasklets provide, we can ensure that all events (occurring on the device) are recognized and serviced.

This change fixes a problem wherein 2 or more busy queues can cause notification bits to change state while a (CCP) interrupt is being serviced, but after the queue state has been evaluated. This results in the event being 'lost' and the queue hanging, waiting to be serviced. Since the status bits are never fully de-asserted, the CCP never generates another interrupt (all bits zero -> one or more bits one), and no further CCP operations will be executed.

---
 drivers/crypto/ccp/ccp-dev-v5.c |  111 ++++++++++++++++++++++++----------------
 1 file changed, 67 insertions(+), 44 deletions(-)
drivers/crypto/ccp/ccp-dev-v5.c +67 -44
@@ -653,6 +653,65 @@ static int ccp_assign_lsbs(struct ccp_de
 	return rc;
 }
 
+static void ccp5_disable_queue_interrupts(struct ccp_device *ccp)
+{
+	unsigned int i;
+
+	for (i = 0; i < ccp->cmd_q_count; i++)
+		iowrite32(0x0, ccp->cmd_q[i].reg_int_enable);
+}
+
+static void ccp5_enable_queue_interrupts(struct ccp_device *ccp)
+{
+	unsigned int i;
+
+	for (i = 0; i < ccp->cmd_q_count; i++)
+		iowrite32(SUPPORTED_INTERRUPTS, ccp->cmd_q[i].reg_int_enable);
+}
+
+static void ccp5_irq_bh(unsigned long data)
+{
+	struct ccp_device *ccp = (struct ccp_device *)data;
+	u32 status;
+	unsigned int i;
+
+	for (i = 0; i < ccp->cmd_q_count; i++) {
+		struct ccp_cmd_queue *cmd_q = &ccp->cmd_q[i];
+
+		status = ioread32(cmd_q->reg_interrupt_status);
+
+		if (status) {
+			cmd_q->int_status = status;
+			cmd_q->q_status = ioread32(cmd_q->reg_status);
+			cmd_q->q_int_status = ioread32(cmd_q->reg_int_status);
+
+			/* On error, only save the first error value */
+			if ((status & INT_ERROR) && !cmd_q->cmd_error)
+				cmd_q->cmd_error = CMD_Q_ERROR(cmd_q->q_status);
+
+			cmd_q->int_rcvd = 1;
+
+			/* Acknowledge the interrupt and wake the kthread */
+			iowrite32(status, cmd_q->reg_interrupt_status);
+			wake_up_interruptible(&cmd_q->int_queue);
+		}
+	}
+	ccp5_enable_queue_interrupts(ccp);
+}
+
+static irqreturn_t ccp5_irq_handler(int irq, void *data)
+{
+	struct device *dev = data;
+	struct ccp_device *ccp = dev_get_drvdata(dev);
+
+	ccp5_disable_queue_interrupts(ccp);
+	if (ccp->use_tasklet)
+		tasklet_schedule(&ccp->irq_tasklet);
+	else
+		ccp5_irq_bh((unsigned long)ccp);
+	return IRQ_HANDLED;
+}
+
 static int ccp5_init(struct ccp_device *ccp)
 {
 	struct device *dev = ccp->dev;
@@ -736,18 +795,17 @@ static int ccp5_init(struct ccp_device *
 	}
 
 	/* Turn off the queues and disable interrupts until ready */
+	ccp5_disable_queue_interrupts(ccp);
 	for (i = 0; i < ccp->cmd_q_count; i++) {
 		cmd_q = &ccp->cmd_q[i];
 
 		cmd_q->qcontrol = 0; /* Start with nothing */
 		iowrite32(cmd_q->qcontrol, cmd_q->reg_control);
 
-		/* Disable the interrupts */
-		iowrite32(0x00, cmd_q->reg_int_enable);
 		ioread32(cmd_q->reg_int_status);
 		ioread32(cmd_q->reg_status);
 
-		/* Clear the interrupts */
+		/* Clear the interrupt status */
 		iowrite32(SUPPORTED_INTERRUPTS, cmd_q->reg_interrupt_status);
 	}
 
@@ -758,6 +816,10 @@ static int ccp5_init(struct ccp_device *
 		dev_err(dev, "unable to allocate an IRQ\n");
 		goto e_pool;
 	}
+	/* Initialize the ISR tasklet */
+	if (ccp->use_tasklet)
+		tasklet_init(&ccp->irq_tasklet, ccp5_irq_bh,
+			     (unsigned long)ccp);
 
 	dev_dbg(dev, "Loading LSB map...\n");
 	/* Copy the private LSB mask to the public registers */
@@ -826,11 +888,7 @@ static int ccp5_init(struct ccp_device *
 	}
 
 	dev_dbg(dev, "Enabling interrupts...\n");
-	/* Enable interrupts */
-	for (i = 0; i < ccp->cmd_q_count; i++) {
-		cmd_q = &ccp->cmd_q[i];
-		iowrite32(SUPPORTED_INTERRUPTS, cmd_q->reg_int_enable);
-	}
+	ccp5_enable_queue_interrupts(ccp);
 
 	dev_dbg(dev, "Registering device...\n");
 	/* Put this on the unit list to make it available */
@@ -882,15 +940,13 @@ static void ccp5_destroy(struct ccp_devi
 	ccp_del_device(ccp);
 
 	/* Disable and clear interrupts */
+	ccp5_disable_queue_interrupts(ccp);
 	for (i = 0; i < ccp->cmd_q_count; i++) {
 		cmd_q = &ccp->cmd_q[i];
 
 		/* Turn off the run bit */
 		iowrite32(cmd_q->qcontrol & ~CMD5_Q_RUN, cmd_q->reg_control);
 
-		/* Disable the interrupts */
-		iowrite32(0x00, cmd_q->reg_int_enable);
-
 		/* Clear the interrupt status */
 		iowrite32(SUPPORTED_INTERRUPTS, cmd_q->reg_interrupt_status);
 		ioread32(cmd_q->reg_int_status);
@@ -925,39 +981,6 @@ static void ccp5_destroy(struct ccp_devi
 	}
 }
 
-static irqreturn_t ccp5_irq_handler(int irq, void *data)
-{
-	struct device *dev = data;
-	struct ccp_device *ccp = dev_get_drvdata(dev);
-	u32 status;
-	unsigned int i;
-
-	for (i = 0; i < ccp->cmd_q_count; i++) {
-		struct ccp_cmd_queue *cmd_q = &ccp->cmd_q[i];
-
-		status = ioread32(cmd_q->reg_interrupt_status);
-
-		if (status) {
-			cmd_q->int_status = status;
-			cmd_q->q_status = ioread32(cmd_q->reg_status);
-			cmd_q->q_int_status = ioread32(cmd_q->reg_int_status);
-
-			/* On error, only save the first error value */
-			if ((status & INT_ERROR) && !cmd_q->cmd_error)
-				cmd_q->cmd_error = CMD_Q_ERROR(cmd_q->q_status);
-
-			cmd_q->int_rcvd = 1;
-
-			/* Acknowledge the interrupt and wake the kthread */
-			iowrite32(SUPPORTED_INTERRUPTS,
-				  cmd_q->reg_interrupt_status);
-			wake_up_interruptible(&cmd_q->int_queue);
-		}
-	}
-
-	return IRQ_HANDLED;
-}
-
 static void ccp5_config(struct ccp_device *ccp)
 {
 	/* Public side */
author maintainer
#37 lore raw

PATCH 39/114 dm crypt: rewrite (wipe) key in crypto layer using random data

In reply to Greg Kroah-Hartman

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

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

From: Ondrej Kozina <[email protected]>

commit c82feeec9a014b72c4ffea36648cfb6f81cc1b73 upstream.

The message "key wipe" used to wipe real key stored in crypto layer by rewriting it with zeroes. Since commit 28856a9 ("crypto: xts - consolidate sanity check for keys") this no longer works in FIPS mode for XTS.

While running in FIPS mode the crypto key part has to differ from the tweak key.

Fixes 28856a9 ("crypto: xts - consolidate sanity check for keys")
---
 drivers/md/dm-crypt.c |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/md/dm-crypt.c +6 -2
@@ -1649,12 +1649,16 @@ out:
 
 static int crypt_wipe_key(struct crypt_config *cc)
 {
+	int r;
+
 	clear_bit(DM_CRYPT_KEY_VALID, &cc->flags);
-	memset(&cc->key, 0, cc->key_size * sizeof(u8));
+	get_random_bytes(&cc->key, cc->key_size);
 	kzfree(cc->key_string);
 	cc->key_string = NULL;
+	r = crypt_setkey(cc);
+	memset(&cc->key, 0, cc->key_size * sizeof(u8));
 
-	return crypt_setkey(cc);
+	return r;
 }
 
 static void crypt_dtr(struct dm_target *ti)
author maintainer
#38 lore raw

PATCH 40/114 dm era: save spacemap metadata root after the pre-commit

In reply to Greg Kroah-Hartman

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

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

From: Somasundaram Krishnasamy <[email protected]>

commit 117aceb030307dcd431fdcff87ce988d3016c34a upstream.

When committing era metadata to disk, it doesn't always save the latest spacemap metadata root in superblock. Due to this, metadata is getting corrupted sometimes when reopening the device. The correct order of update should be, pre-commit (shadows spacemap root), save the spacemap root (newly shadowed block) to in-core superblock and then the final commit.

---
 drivers/md/dm-era-target.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/md/dm-era-target.c +4 -4
@@ -961,15 +961,15 @@ static int metadata_commit(struct era_me
 		}
 	}
 
-	r = save_sm_root(md);
+	r = dm_tm_pre_commit(md->tm);
 	if (r) {
-		DMERR("%s: save_sm_root failed", __func__);
+		DMERR("%s: pre commit failed", __func__);
 		return r;
 	}
 
-	r = dm_tm_pre_commit(md->tm);
+	r = save_sm_root(md);
 	if (r) {
-		DMERR("%s: pre commit failed", __func__);
+		DMERR("%s: save_sm_root failed", __func__);
 		return r;
 	}
 
author maintainer
#39 lore raw

PATCH 41/114 dm rq: check blk_mq_register_dev() return value in dm_mq_init_request_queue()

In reply to Greg Kroah-Hartman

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

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

From: Bart Van Assche <[email protected]>

commit 23a601248958fa4142d49294352fe8d1fdf3e509 upstream.

Otherwise the request-based DM blk-mq request_queue will be put into service without being properly exported via sysfs.

---
 drivers/md/dm-rq.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/md/dm-rq.c +5 -1
@@ -810,10 +810,14 @@ int dm_mq_init_request_queue(struct mapp
 	dm_init_md_queue(md);
 
 	/* backfill 'mq' sysfs registration normally done in blk_register_queue */
-	blk_mq_register_dev(disk_to_dev(md->disk), q);
+	err = blk_mq_register_dev(disk_to_dev(md->disk), q);
+	if (err)
+		goto out_cleanup_queue;
 
 	return 0;
 
+out_cleanup_queue:
+	blk_cleanup_queue(q);
 out_tag_set:
 	blk_mq_free_tag_set(md->tag_set);
 out_kfree_tag_set:
author maintainer
#40 lore raw

PATCH 42/114 dm thin: fix a memory leak when passing discard bio down

In reply to Greg Kroah-Hartman

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

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

From: Dennis Yang <[email protected]>

commit 948f581a53b704b984aa20df009f0a2b4cf7f907 upstream.

dm-thin does not free the discard_parent bio after all chained sub bios finished. The following kmemleak report could be observed after pool with discard_passdown option processes discard bios in linux v4.11-rc7. To fix this, we drop the discard_parent bio reference when its endio (passdown_endio) called.

unreferenced object 0xffff8803d6b29700 (size 256):
comm "kworker/u8:0", pid 30349, jiffies 4379504020 (age 143002.776s) hex dump (first 32 bytes):

    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
    01 00 00 00 00 00 00 f0 00 00 00 00 00 00 00 00  ................
  backtrace:
    [<ffffffff81a5efd9>] kmemleak_alloc+0x49/0xa0
    [<ffffffff8114ec34>] kmem_cache_alloc+0xb4/0x100
    [<ffffffff8110eec0>] mempool_alloc_slab+0x10/0x20
    [<ffffffff8110efa5>] mempool_alloc+0x55/0x150
    [<ffffffff81374939>] bio_alloc_bioset+0xb9/0x260
    [<ffffffffa018fd20>] process_prepared_discard_passdown_pt1+0x40/0x1c0 [dm_thin_pool]
    [<ffffffffa018b409>] break_up_discard_bio+0x1a9/0x200 [dm_thin_pool]
    [<ffffffffa018b484>] process_discard_cell_passdown+0x24/0x40 [dm_thin_pool]
    [<ffffffffa018b24d>] process_discard_bio+0xdd/0xf0 [dm_thin_pool]
    [<ffffffffa018ecf6>] do_worker+0xa76/0xd50 [dm_thin_pool]
    [<ffffffff81086239>] process_one_work+0x139/0x370
    [<ffffffff810867b1>] worker_thread+0x61/0x450
    [<ffffffff8108b316>] kthread+0xd6/0xf0
    [<ffffffff81a6cd1f>] ret_from_fork+0x3f/0x70
    [<ffffffffffffffff>] 0xffffffffffffffff
---
 drivers/md/dm-thin.c |    1 +
 1 file changed, 1 insertion(+)
drivers/md/dm-thin.c +1 -0
@@ -1069,6 +1069,7 @@ static void passdown_endio(struct bio *b
 	 * to unmap (we ignore err).
 	 */
 	queue_passdown_pt2(bio->bi_private);
+	bio_put(bio);
 }
 
 static void process_prepared_discard_passdown_pt1(struct dm_thin_new_mapping *m)
author maintainer
#41 lore raw

PATCH 43/114 vfio/type1: Remove locked page accounting workqueue

In reply to Greg Kroah-Hartman

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

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

From: Alex Williamson <[email protected]>

commit 0cfef2b7410b64d7a430947e0b533314c4f97153 upstream.

If the mmap_sem is contented then the vfio type1 IOMMU backend will defer locked page accounting updates to a workqueue task. This has a few problems and depending on which side the user tries to play, they might be over-penalized for unmaps that haven't yet been accounted or race the workqueue to enter more mappings than they're allowed. The original intent of this workqueue mechanism seems to be focused on reducing latency through the ioctl, but we cannot do so at the cost of correctness. Remove this workqueue mechanism and update the callers to allow for failure. We can also now recheck the limit under write lock to make sure we don't exceed it.

vfio_pin_pages_remote() also now necessarily includes an unwind path which we can jump to directly if the consecutive page pinning finds that we're exceeding the user's memory limits. This avoids the current lazy approach which does accounting and mapping up to the fault, only to return an error on the next iteration to unwind the entire vfio_dma.

---
 drivers/vfio/vfio_iommu_type1.c |  110 ++++++++++++++++++----------------------
 1 file changed, 51 insertions(+), 59 deletions(-)
drivers/vfio/vfio_iommu_type1.c +51 -59
@@ -246,69 +246,46 @@ static int vfio_iova_put_vfio_pfn(struct
 	return ret;
 }
 
-struct vwork {
-	struct mm_struct	*mm;
-	long			npage;
-	struct work_struct	work;
-};
-
-/* delayed decrement/increment for locked_vm */
-static void vfio_lock_acct_bg(struct work_struct *work)
-{
-	struct vwork *vwork = container_of(work, struct vwork, work);
-	struct mm_struct *mm;
-
-	mm = vwork->mm;
-	down_write(&mm->mmap_sem);
-	mm->locked_vm += vwork->npage;
-	up_write(&mm->mmap_sem);
-	mmput(mm);
-	kfree(vwork);
-}
-
-static void vfio_lock_acct(struct task_struct *task, long npage)
+static int vfio_lock_acct(struct task_struct *task, long npage, bool *lock_cap)
 {
-	struct vwork *vwork;
 	struct mm_struct *mm;
 	bool is_current;
+	int ret;
 
 	if (!npage)
-		return;
+		return 0;
 
 	is_current = (task->mm == current->mm);
 
 	mm = is_current ? task->mm : get_task_mm(task);
 	if (!mm)
-		return; /* process exited */
+		return -ESRCH; /* process exited */
 
-	if (down_write_trylock(&mm->mmap_sem)) {
-		mm->locked_vm += npage;
-		up_write(&mm->mmap_sem);
-		if (!is_current)
-			mmput(mm);
-		return;
-	}
+	ret = down_write_killable(&mm->mmap_sem);
+	if (!ret) {
+		if (npage > 0) {
+			if (lock_cap ? !*lock_cap :
+			    !has_capability(task, CAP_IPC_LOCK)) {
+				unsigned long limit;
+
+				limit = task_rlimit(task,
+						RLIMIT_MEMLOCK) >> PAGE_SHIFT;
 
-	if (is_current) {
-		mm = get_task_mm(task);
-		if (!mm)
-			return;
+				if (mm->locked_vm + npage > limit)
+					ret = -ENOMEM;
+			}
+		}
+
+		if (!ret)
+			mm->locked_vm += npage;
+
+		up_write(&mm->mmap_sem);
 	}
 
-	/*
-	 * Couldn't get mmap_sem lock, so must setup to update
-	 * mm->locked_vm later. If locked_vm were atomic, we
-	 * wouldn't need this silliness
-	 */
-	vwork = kmalloc(sizeof(struct vwork), GFP_KERNEL);
-	if (WARN_ON(!vwork)) {
+	if (!is_current)
 		mmput(mm);
-		return;
-	}
-	INIT_WORK(&vwork->work, vfio_lock_acct_bg);
-	vwork->mm = mm;
-	vwork->npage = npage;
-	schedule_work(&vwork->work);
+
+	return ret;
 }
 
 /*
@@ -405,7 +382,7 @@ static int vaddr_get_pfn(struct mm_struc
 static long vfio_pin_pages_remote(struct vfio_dma *dma, unsigned long vaddr,
 				  long npage, unsigned long *pfn_base)
 {
-	unsigned long limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
+	unsigned long pfn = 0, limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
 	bool lock_cap = capable(CAP_IPC_LOCK);
 	long ret, pinned = 0, lock_acct = 0;
 	bool rsvd;
@@ -442,8 +419,6 @@ static long vfio_pin_pages_remote(struct
 	/* Lock all the consecutive pages from pfn_base */
 	for (vaddr += PAGE_SIZE, iova += PAGE_SIZE; pinned < npage;
 	     pinned++, vaddr += PAGE_SIZE, iova += PAGE_SIZE) {
-		unsigned long pfn = 0;
-
 		ret = vaddr_get_pfn(current->mm, vaddr, dma->prot, &pfn);
 		if (ret)
 			break;
@@ -460,14 +435,25 @@ static long vfio_pin_pages_remote(struct
 				put_pfn(pfn, dma->prot);
 				pr_warn("%s: RLIMIT_MEMLOCK (%ld) exceeded\n",
 					__func__, limit << PAGE_SHIFT);
-				break;
+				ret = -ENOMEM;
+				goto unpin_out;
 			}
 			lock_acct++;
 		}
 	}
 
 out:
-	vfio_lock_acct(current, lock_acct);
+	ret = vfio_lock_acct(current, lock_acct, &lock_cap);
+
+unpin_out:
+	if (ret) {
+		if (!rsvd) {
+			for (pfn = *pfn_base ; pinned ; pfn++, pinned--)
+				put_pfn(pfn, dma->prot);
+		}
+
+		return ret;
+	}
 
 	return pinned;
 }
@@ -488,7 +474,7 @@ static long vfio_unpin_pages_remote(stru
 	}
 
 	if (do_accounting)
-		vfio_lock_acct(dma->task, locked - unlocked);
+		vfio_lock_acct(dma->task, locked - unlocked, NULL);
 
 	return unlocked;
 }
@@ -522,8 +508,14 @@ static int vfio_pin_page_external(struct
 		goto pin_page_exit;
 	}
 
-	if (!rsvd && do_accounting)
-		vfio_lock_acct(dma->task, 1);
+	if (!rsvd && do_accounting) {
+		ret = vfio_lock_acct(dma->task, 1, &lock_cap);
+		if (ret) {
+			put_pfn(*pfn_base, dma->prot);
+			goto pin_page_exit;
+		}
+	}
+
 	ret = 1;
 
 pin_page_exit:
@@ -543,7 +535,7 @@ static int vfio_unpin_page_external(stru
 	unlocked = vfio_iova_put_vfio_pfn(dma, vpfn);
 
 	if (do_accounting)
-		vfio_lock_acct(dma->task, -unlocked);
+		vfio_lock_acct(dma->task, -unlocked, NULL);
 
 	return unlocked;
 }
@@ -740,7 +732,7 @@ static long vfio_unmap_unpin(struct vfio
 
 	dma->iommu_mapped = false;
 	if (do_accounting) {
-		vfio_lock_acct(dma->task, -unlocked);
+		vfio_lock_acct(dma->task, -unlocked, NULL);
 		return 0;
 	}
 	return unlocked;
@@ -1382,7 +1374,7 @@ static void vfio_iommu_unmap_unpin_reacc
 			if (!is_invalid_reserved_pfn(vpfn->pfn))
 				locked++;
 		}
-		vfio_lock_acct(dma->task, locked - unlocked);
+		vfio_lock_acct(dma->task, locked - unlocked, NULL);
 	}
 }
 
author maintainer
#42 lore raw

PATCH 44/114 iov_iter: dont revert iov buffer if csum error

In reply to Greg Kroah-Hartman

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

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

From: Ding Tianhong <[email protected]>

commit a6a5993243550b09f620941dea741b7421fdf79c upstream.

The patch 327868212381 (make skb_copy_datagram_msg() et.al. preserve ->msg_iter on error) will revert the iov buffer if copy to iter failed, but it didn't copy any datagram if the skb_checksum_complete error, so no need to revert any data at this place.

v2: Sabrina notice that return -EFAULT when checksum error is not correct
here, it would confuse the caller about the return value, so fix it.

Fixes 327868212381 ("make skb_copy_datagram_msg() et.al. preserve->msg_iter on error")
---
 net/core/datagram.c |   13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)
net/core/datagram.c +7 -6
@@ -760,7 +760,7 @@ int skb_copy_and_csum_datagram_msg(struc
 
 	if (msg_data_left(msg) < chunk) {
 		if (__skb_checksum_complete(skb))
-			goto csum_error;
+			return -EINVAL;
 		if (skb_copy_datagram_msg(skb, hlen, msg, chunk))
 			goto fault;
 	} else {
@@ -768,15 +768,16 @@ int skb_copy_and_csum_datagram_msg(struc
 		if (skb_copy_and_csum_datagram(skb, hlen, &msg->msg_iter,
 					       chunk, &csum))
 			goto fault;
-		if (csum_fold(csum))
-			goto csum_error;
+
+		if (csum_fold(csum)) {
+			iov_iter_revert(&msg->msg_iter, chunk);
+			return -EINVAL;
+		}
+
 		if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE))
 			netdev_rx_csum_fault(skb->dev);
 	}
 	return 0;
-csum_error:
-	iov_iter_revert(&msg->msg_iter, chunk);
-	return -EINVAL;
 fault:
 	return -EFAULT;
 }
author maintainer
#43 lore raw

PATCH 45/114 IB/core: Fix sysfs registration error flow

In reply to Greg Kroah-Hartman

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

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

From: Jack Morgenstein <[email protected]>

commit b312be3d87e4c80872cbea869e569175c5eb0f9a upstream.

The kernel commit cited below restructured ib device management so that the device kobject is initialized in ib_alloc_device.

As part of the restructuring, the kobject is now initialized in procedure ib_alloc_device, and is later added to the device hierarchy in the ib_register_device call stack, in procedure ib_device_register_sysfs (which calls device_add).

However, in the ib_device_register_sysfs error flow, if an error occurs following the call to device_add, the cleanup procedure device_unregister is called. This call results in the device object being deleted -- which results in various use-after-free crashes.

The correct cleanup call is device_del -- which undoes device_add without deleting the device object.

The device object will then (correctly) be deleted in the ib_register_device caller's error cleanup flow, when the caller invokes ib_dealloc_device.

Fixes 55aeed06544f6 ("IB/core: Make ib_alloc_device init the kobject")
---
 drivers/infiniband/core/sysfs.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/core/sysfs.c +1 -1
@@ -1301,7 +1301,7 @@ err_put:
 	free_port_list_attributes(device);
 
 err_unregister:
-	device_unregister(class_dev);
+	device_del(class_dev);
 
 err:
 	return ret;
author maintainer
#44 lore raw

PATCH 46/114 IB/core: Fix kernel crash during fail to initialize device

In reply to Greg Kroah-Hartman

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

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

From: Parav Pandit <[email protected]>

commit 4be3a4fa51f432ef045546d16f25c68a1ab525b9 upstream.

This patch fixes the kernel crash that occurs during ib_dealloc_device() called due to provider driver fails with an error after ib_alloc_device() and before it can register using ib_register_device().

This crashed seen in tha lab as below which can occur with any IB device which fails to perform its device initialization before invoking ib_register_device().

This patch avoids touching cache and port immutable structures if device is not yet initialized.
It also releases related memory when cache and port immutable data structure initialization fails during register_device() state.

[81416.561946] BUG: unable to handle kernel NULL pointer dereference at (null)
[81416.570340] IP: ib_cache_release_one+0x29/0x80 [ib_core]
[81416.576222] PGD 78da66067
[81416.576223] PUD 7f2d7c067
[81416.579484] PMD 0
[81416.582720]
[81416.587242] Oops: 0000 [#1] SMP
[81416.722395] task: ffff8807887515c0 task.stack: ffffc900062c0000
[81416.729148] RIP: 0010:ib_cache_release_one+0x29/0x80 [ib_core]
[81416.735793] RSP: 0018:ffffc900062c3a90 EFLAGS: 00010202
[81416.741823] RAX: 0000000000000000 RBX: 0000000000000001 RCX: 0000000000000000
[81416.749785] RDX: 0000000000000000 RSI: 0000000000000282 RDI: ffff880859fec000
[81416.757757] RBP: ffffc900062c3aa0 R08: ffff8808536e5ac0 R09: ffff880859fec5b0
[81416.765708] R10: 00000000536e5c01 R11: ffff8808536e5ac0 R12: ffff880859fec000
[81416.773672] R13: 0000000000000000 R14: ffff8808536e5ac0 R15: ffff88084ebc0060
[81416.781621] FS:  00007fd879fab740(0000) GS:ffff88085fac0000(0000) knlGS:0000000000000000
[81416.790522] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[81416.797094] CR2: 0000000000000000 CR3: 00000007eb215000 CR4: 00000000003406e0
[81416.805051] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[81416.812997] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[81416.820950] Call Trace:
[81416.824226]  ib_device_release+0x1e/0x40 [ib_core]
[81416.829858]  device_release+0x32/0xa0
[81416.834370]  kobject_cleanup+0x63/0x170
[81416.839058]  kobject_put+0x25/0x50
[81416.843319]  ib_dealloc_device+0x25/0x40 [ib_core]
[81416.848986]  mlx5_ib_add+0x163/0x1990 [mlx5_ib]
[81416.854414]  mlx5_add_device+0x5a/0x160 [mlx5_core]
[81416.860191]  mlx5_register_interface+0x8d/0xc0 [mlx5_core]
[81416.866587]  ? 0xffffffffa09e9000
[81416.870816]  mlx5_ib_init+0x15/0x17 [mlx5_ib]
[81416.876094]  do_one_initcall+0x51/0x1b0
[81416.880861]  ? __vunmap+0x85/0xd0
[81416.885113]  ? kmem_cache_alloc_trace+0x14b/0x1b0
[81416.890768]  ? vfree+0x2e/0x70
[81416.894762]  do_init_module+0x60/0x1fa
[81416.899441]  load_module+0x15f6/0x1af0
[81416.904114]  ? __symbol_put+0x60/0x60
[81416.908709]  ? ima_post_read_file+0x3d/0x80
[81416.913828]  ? security_kernel_post_read_file+0x6b/0x80
[81416.920006]  SYSC_finit_module+0xa6/0xf0
[81416.924888]  SyS_finit_module+0xe/0x10
[81416.929568]  entry_SYSCALL_64_fastpath+0x1a/0xa9
[81416.935089] RIP: 0033:0x7fd879494949
[81416.939543] RSP: 002b:00007ffdbc1b4e58 EFLAGS: 00000202 ORIG_RAX: 0000000000000139
[81416.947982] RAX: ffffffffffffffda RBX: 0000000001b66f00 RCX: 00007fd879494949
[81416.955965] RDX: 0000000000000000 RSI: 000000000041a13c RDI: 0000000000000003
[81416.963926] RBP: 0000000000000003 R08: 0000000000000000 R09: 0000000001b652a0
[81416.971861] R10: 0000000000000003 R11: 0000000000000202 R12: 00007ffdbc1b3e70
[81416.979763] R13: 00007ffdbc1b3e50 R14: 0000000000000005 R15: 0000000000000000
[81417.008005] RIP: ib_cache_release_one+0x29/0x80 [ib_core] RSP: ffffc900062c3a90
[81417.016045] CR2: 0000000000000000
Fixes 55aeed0654 ("IB/core: Make ib_alloc_device init the kobject")
Fixes 7738613e7c ("IB/core: Add per port immutable struct to ib_device")
---
 drivers/infiniband/core/device.c |   33 ++++++++++++++++++++++-----------
 1 file changed, 22 insertions(+), 11 deletions(-)
drivers/infiniband/core/device.c +22 -11
@@ -172,8 +172,16 @@ static void ib_device_release(struct dev
 {
 	struct ib_device *dev = container_of(device, struct ib_device, dev);
 
-	ib_cache_release_one(dev);
-	kfree(dev->port_immutable);
+	WARN_ON(dev->reg_state == IB_DEV_REGISTERED);
+	if (dev->reg_state == IB_DEV_UNREGISTERED) {
+		/*
+		 * In IB_DEV_UNINITIALIZED state, cache or port table
+		 * is not even created. Free cache and port table only when
+		 * device reaches UNREGISTERED state.
+		 */
+		ib_cache_release_one(dev);
+		kfree(dev->port_immutable);
+	}
 	kfree(dev);
 }
 
@@ -380,32 +388,27 @@ int ib_register_device(struct ib_device
 	ret = ib_cache_setup_one(device);
 	if (ret) {
 		pr_warn("Couldn't set up InfiniBand P_Key/GID cache\n");
-		goto out;
+		goto port_cleanup;
 	}
 
 	ret = ib_device_register_rdmacg(device);
 	if (ret) {
 		pr_warn("Couldn't register device with rdma cgroup\n");
-		ib_cache_cleanup_one(device);
-		goto out;
+		goto cache_cleanup;
 	}
 
 	memset(&device->attrs, 0, sizeof(device->attrs));
 	ret = device->query_device(device, &device->attrs, &uhw);
 	if (ret) {
 		pr_warn("Couldn't query the device attributes\n");
-		ib_device_unregister_rdmacg(device);
-		ib_cache_cleanup_one(device);
-		goto out;
+		goto cache_cleanup;
 	}
 
 	ret = ib_device_register_sysfs(device, port_callback);
 	if (ret) {
 		pr_warn("Couldn't register device %s with driver model\n",
 			device->name);
-		ib_device_unregister_rdmacg(device);
-		ib_cache_cleanup_one(device);
-		goto out;
+		goto cache_cleanup;
 	}
 
 	device->reg_state = IB_DEV_REGISTERED;
@@ -417,6 +420,14 @@ int ib_register_device(struct ib_device
 	down_write(&lists_rwsem);
 	list_add_tail(&device->core_list, &device_list);
 	up_write(&lists_rwsem);
+	mutex_unlock(&device_mutex);
+	return 0;
+
+cache_cleanup:
+	ib_cache_cleanup_one(device);
+	ib_cache_release_one(device);
+port_cleanup:
+	kfree(device->port_immutable);
 out:
 	mutex_unlock(&device_mutex);
 	return ret;
author maintainer
#45 lore raw

PATCH 47/114 IB/core: For multicast functions, verify that LIDs are multicast LIDs

In reply to Greg Kroah-Hartman

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

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

From: Michael J. Ruhl <[email protected]>

commit 8561eae60ff9417a50fa1fb2b83ae950dc5c1e21 upstream.

The Infiniband spec defines "A multicast address is defined by a MGID and a MLID" (section 10.5). Currently the MLID value is not validated.

Add check to verify that the MLID value is in the correct address range.

---
 drivers/infiniband/core/verbs.c |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/infiniband/core/verbs.c +6 -2
@@ -1519,7 +1519,9 @@ int ib_attach_mcast(struct ib_qp *qp, un
 
 	if (!qp->device->attach_mcast)
 		return -ENOSYS;
-	if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD)
+	if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD ||
+	    lid < be16_to_cpu(IB_MULTICAST_LID_BASE) ||
+	    lid == be16_to_cpu(IB_LID_PERMISSIVE))
 		return -EINVAL;
 
 	ret = qp->device->attach_mcast(qp, gid, lid);
@@ -1535,7 +1537,9 @@ int ib_detach_mcast(struct ib_qp *qp, un
 
 	if (!qp->device->detach_mcast)
 		return -ENOSYS;
-	if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD)
+	if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD ||
+	    lid < be16_to_cpu(IB_MULTICAST_LID_BASE) ||
+	    lid == be16_to_cpu(IB_LID_PERMISSIVE))
 		return -EINVAL;
 
 	ret = qp->device->detach_mcast(qp, gid, lid);
author maintainer
#46 lore raw

PATCH 48/114 IB/IPoIB: ibX: failed to create mcg debug file

In reply to Greg Kroah-Hartman

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

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

From: Shamir Rabinovitch <[email protected]>

commit 771a52584096c45e4565e8aabb596eece9d73d61 upstream.

When udev renames the netdev devices, ipoib debugfs entries does not get renamed. As a result, if subsequent probe of ipoib device reuse the name then creating a debugfs entry for the new device would fail.

Also, moved ipoib_create_debug_files and ipoib_delete_debug_files as part of ipoib event handling in order to avoid any race condition between these.

Fixes 1732b0ef3b3a ([IPoIB] add path record information in debugfs)
---
 drivers/infiniband/ulp/ipoib/ipoib_fs.c   |    3 ++
 drivers/infiniband/ulp/ipoib/ipoib_main.c |   44 ++++++++++++++++++++++++++----
 drivers/infiniband/ulp/ipoib/ipoib_vlan.c |    3 --
 3 files changed, 42 insertions(+), 8 deletions(-)
drivers/infiniband/ulp/ipoib/ipoib_fs.c +3 -0
@@ -281,8 +281,11 @@ void ipoib_delete_debug_files(struct net
 {
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
 
+	WARN_ONCE(!priv->mcg_dentry, "null mcg debug file\n");
+	WARN_ONCE(!priv->path_dentry, "null path debug file\n");
 	debugfs_remove(priv->mcg_dentry);
 	debugfs_remove(priv->path_dentry);
+	priv->mcg_dentry = priv->path_dentry = NULL;
 }
 
 int ipoib_register_debugfs(void)
drivers/infiniband/ulp/ipoib/ipoib_main.c +39 -5

86 lines not on this page · raw message

drivers/infiniband/ulp/ipoib/ipoib_vlan.c +0 -3
@@ -86,8 +86,6 @@ int __ipoib_vlan_add(struct ipoib_dev_pr
 		goto register_failed;
 	}
 
-	ipoib_create_debug_files(priv->dev);
-
 	/* RTNL childs don't need proprietary sysfs entries */
 	if (type == IPOIB_LEGACY_CHILD) {
 		if (ipoib_cm_add_mode_attr(priv->dev))
@@ -108,7 +106,6 @@ int __ipoib_vlan_add(struct ipoib_dev_pr
 
 sysfs_failed:
 	result = -ENOMEM;
-	ipoib_delete_debug_files(priv->dev);
 	unregister_netdevice(priv->dev);
 
 register_failed:
author maintainer
#47 lore raw

PATCH 49/114 IB/mlx4: Fix ib device initialization error flow

In reply to Greg Kroah-Hartman

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

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

From: Jack Morgenstein <[email protected]>

commit 99e68909d5aba1861897fe7afc3306c3c81b6de0 upstream.

In mlx4_ib_add, procedure mlx4_ib_alloc_eqs is called to allocate EQs.

However, in the mlx4_ib_add error flow, procedure mlx4_ib_free_eqs is not called to free the allocated EQs.

Fixes e605b743f33d ("IB/mlx4: Increase the number of vectors (EQs) available for ULPs")
---
 drivers/infiniband/hw/mlx4/main.c |    1 +
 1 file changed, 1 insertion(+)
drivers/infiniband/hw/mlx4/main.c +1 -0
@@ -2941,6 +2941,7 @@ err_counter:
 		mlx4_ib_delete_counters_table(ibdev, &ibdev->counters_table[i]);
 
 err_map:
+	mlx4_ib_free_eqs(dev, ibdev);
 	iounmap(ibdev->uar_map);
 
 err_uar:
author maintainer
#48 lore raw

PATCH 50/114 IB/mlx4: Reduce SRIOV multicast cleanup warning message to debug level

In reply to Greg Kroah-Hartman

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

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

From: Jack Morgenstein <[email protected]>

commit fb7a91746af18b2ebf596778b38a709cdbc488d3 upstream.

A warning message during SRIOV multicast cleanup should have actually been a debug level message. The condition generating the warning does no harm and can fill the message log.

In some cases, during testing, some tests were so intense as to swamp the message log with these warning messages, causing a stall in the console message log output task. This stall caused an NMI to be sent to all CPUs (so that they all dumped their stacks into the message log). Aside from the message flood causing an NMI, the tests all passed.

Once the message flood which caused the NMI is removed (by reducing the warning message to debug level), the NMI no longer occurs.

Sample message log (console log) output illustrating the flood and resultant NMI (snippets with comments and modified with ... instead of hex digits, to satisfy checkpatch.pl):

<mlx4_ib> _mlx4_ib_mcg_port_cleanup: ... WARNING: group refcount 1!!!... *** About 4000 almost identical lines in less than one second *** <mlx4_ib> _mlx4_ib_mcg_port_cleanup: ... WARNING: group refcount 1!!!...

 INFO: rcu_sched detected stalls on CPUs/tasks: { 17} (...)
 *** { 17} above indicates that CPU 17 was the one that stalled ***
 sending NMI to all CPUs:
 ...
 NMI backtrace for cpu 17
 CPU: 17 PID: 45909 Comm: kworker/17:2
 Hardware name: HP ProLiant DL360p Gen8, BIOS P71 09/08/2013
 Workqueue: events fb_flashcursor
 task: ffff880478...... ti: ffff88064e...... task.ti: ffff88064e......
 RIP: 0010:[ffffffff81......]  [ffffffff81......] io_serial_in+0x15/0x20
 RSP: 0018:ffff88064e257cb0  EFLAGS: 00000002
 RAX: 0000000000...... RBX: ffffffff81...... RCX: 0000000000......
 RDX: 0000000000...... RSI: 0000000000...... RDI: ffffffff81......
 RBP: ffff88064e...... R08: ffffffff81...... R09: 0000000000......
 R10: 0000000000...... R11: ffff88064e...... R12: 0000000000......
 R13: 0000000000...... R14: ffffffff81...... R15: 0000000000......
 FS:  0000000000......(0000) GS:ffff8804af......(0000) knlGS:000000000000
 CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080......
 CR2: 00007f2a2f...... CR3: 0000000001...... CR4: 0000000000......
 DR0: 0000000000...... DR1: 0000000000...... DR2: 0000000000......
 DR3: 0000000000...... DR6: 00000000ff...... DR7: 0000000000......
 Stack:
 ffff88064e...... ffffffff81...... ffffffff81...... 0000000000......
 ffffffff81...... ffff88064e...... ffffffff81...... ffffffff81......
 ffffffff81...... ffff88064e...... ffffffff81...... 0000000000......
 Call Trace:
[<ffffffff813d099b>] wait_for_xmitr+0x3b/0xa0
[<ffffffff813d0b5c>] serial8250_console_putchar+0x1c/0x30
[<ffffffff813d0b40>] ? serial8250_console_write+0x140/0x140
[<ffffffff813cb5fa>] uart_console_write+0x3a/0x80
[<ffffffff813d0aae>] serial8250_console_write+0xae/0x140
[<ffffffff8107c4d1>] call_console_drivers.constprop.15+0x91/0xf0
[<ffffffff8107d6cf>] console_unlock+0x3bf/0x400
[<ffffffff813503cd>] fb_flashcursor+0x5d/0x140
[<ffffffff81355c30>] ? bit_clear+0x120/0x120
[<ffffffff8109d5fb>] process_one_work+0x17b/0x470
[<ffffffff8109e3cb>] worker_thread+0x11b/0x400
[<ffffffff8109e2b0>] ? rescuer_thread+0x400/0x400
[<ffffffff810a5aef>] kthread+0xcf/0xe0
[<ffffffff810a5a20>] ? kthread_create_on_node+0x140/0x140
[<ffffffff81645858>] ret_from_fork+0x58/0x90
[<ffffffff810a5a20>] ? kthread_create_on_node+0x140/0x140
Code: 48 89 e5 d3 e6 48 63 f6 48 03 77 10 8b 06 5d c3 66 0f 1f 44 00 00 66 66 66 6

As indicated in the stack trace above, the console output task got swamped.

Fixes b9c5d6a64358 ("IB/mlx4: Add multicast group (MCG) paravirtualization for SR-IOV")
---
 drivers/infiniband/hw/mlx4/mcg.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/infiniband/hw/mlx4/mcg.c +2 -1
@@ -1102,7 +1102,8 @@ static void _mlx4_ib_mcg_port_cleanup(st
 	while ((p = rb_first(&ctx->mcg_table)) != NULL) {
 		group = rb_entry(p, struct mcast_group, node);
 		if (atomic_read(&group->refcount))
-			mcg_warn_group(group, "group refcount %d!!! (pointer %p)\n", atomic_read(&group->refcount), group);
+			mcg_debug_group(group, "group refcount %d!!! (pointer %p)\n",
+					atomic_read(&group->refcount), group);
 
 		force_clean_group(group);
 	}
author maintainer
#49 lore raw

PATCH 51/114 IB/hfi1: Prevent kernel QP post send hard lockups

In reply to Greg Kroah-Hartman

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

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

From: Mike Marciniszyn <[email protected]>

commit b6eac931b9bb2bce4db7032c35b41e5e34ec22a5 upstream.

The driver progress routines can call cond_resched() when a timeslice is exhausted and irqs are enabled.

If the ULP had been holding a spin lock without disabling irqs and the post send directly called the progress routine, the cond_resched() could yield allowing another thread from the same ULP to deadlock on that same lock.

Correct by replacing the current hfi1_do_send() calldown with a unique one for post send and adding an argument to hfi1_do_send() to indicate
that the send engine is running in a thread. If the routine is not
running in a thread, avoid calling cond_resched().

Fixes Commit 831464ce4b74 ("IB/hfi1: Don't call cond_resched in atomic mode when sending packets")
---
 drivers/infiniband/hw/hfi1/ruc.c   |   26 ++++++++++++++++----------
 drivers/infiniband/hw/hfi1/verbs.c |    4 ++--
 drivers/infiniband/hw/hfi1/verbs.h |    6 ++++--
 3 files changed, 22 insertions(+), 14 deletions(-)
drivers/infiniband/hw/hfi1/ruc.c +16 -10
@@ -1,5 +1,5 @@
 /*
- * Copyright(c) 2015, 2016 Intel Corporation.
+ * Copyright(c) 2015 - 2017 Intel Corporation.
  *
  * This file is provided under a dual BSD/GPLv2 license.  When using or
  * redistributing this file, you may do so under either license.
@@ -784,23 +784,29 @@ void hfi1_make_ruc_header(struct rvt_qp
 /* when sending, force a reschedule every one of these periods */
 #define SEND_RESCHED_TIMEOUT (5 * HZ)  /* 5s in jiffies */
 
+void hfi1_do_send_from_rvt(struct rvt_qp *qp)
+{
+	hfi1_do_send(qp, false);
+}
+
 void _hfi1_do_send(struct work_struct *work)
 {
 	struct iowait *wait = container_of(work, struct iowait, iowork);
 	struct rvt_qp *qp = iowait_to_qp(wait);
 
-	hfi1_do_send(qp);
+	hfi1_do_send(qp, true);
 }
 
 /**
  * hfi1_do_send - perform a send on a QP
  * @work: contains a pointer to the QP
+ * @in_thread: true if in a workqueue thread
  *
  * Process entries in the send work queue until credit or queue is
  * exhausted.  Only allow one CPU to send a packet per QP.
  * Otherwise, two threads could send packets out of order.
  */
-void hfi1_do_send(struct rvt_qp *qp)
+void hfi1_do_send(struct rvt_qp *qp, bool in_thread)
 {
 	struct hfi1_pkt_state ps;
 	struct hfi1_qp_priv *priv = qp->priv;
@@ -868,8 +874,10 @@ void hfi1_do_send(struct rvt_qp *qp)
 			qp->s_hdrwords = 0;
 			/* allow other tasks to run */
 			if (unlikely(time_after(jiffies, timeout))) {
-				if (workqueue_congested(cpu,
-							ps.ppd->hfi1_wq)) {
+				if (!in_thread ||
+				    workqueue_congested(
+						cpu,
+						ps.ppd->hfi1_wq)) {
 					spin_lock_irqsave(
 						&qp->s_lock,
 						ps.flags);
@@ -882,11 +890,9 @@ void hfi1_do_send(struct rvt_qp *qp)
 						*ps.ppd->dd->send_schedule);
 					return;
 				}
-				if (!irqs_disabled()) {
-					cond_resched();
-					this_cpu_inc(
-					   *ps.ppd->dd->send_schedule);
-				}
+				cond_resched();
+				this_cpu_inc(
+					*ps.ppd->dd->send_schedule);
 				timeout = jiffies + (timeout_int) / 8;
 			}
 			spin_lock_irqsave(&qp->s_lock, ps.flags);
drivers/infiniband/hw/hfi1/verbs.c +2 -2
@@ -1,5 +1,5 @@
 /*
- * Copyright(c) 2015, 2016 Intel Corporation.
+ * Copyright(c) 2015 - 2017 Intel Corporation.
  *
  * This file is provided under a dual BSD/GPLv2 license.  When using or
  * redistributing this file, you may do so under either license.
@@ -1751,7 +1751,7 @@ int hfi1_register_ib_device(struct hfi1_
 	dd->verbs_dev.rdi.driver_f.qp_priv_free = qp_priv_free;
 	dd->verbs_dev.rdi.driver_f.free_all_qps = free_all_qps;
 	dd->verbs_dev.rdi.driver_f.notify_qp_reset = notify_qp_reset;
-	dd->verbs_dev.rdi.driver_f.do_send = hfi1_do_send;
+	dd->verbs_dev.rdi.driver_f.do_send = hfi1_do_send_from_rvt;
 	dd->verbs_dev.rdi.driver_f.schedule_send = hfi1_schedule_send;
 	dd->verbs_dev.rdi.driver_f.schedule_send_no_lock = _hfi1_schedule_send;
 	dd->verbs_dev.rdi.driver_f.get_pmtu_from_attr = get_pmtu_from_attr;
drivers/infiniband/hw/hfi1/verbs.h +4 -2
@@ -1,5 +1,5 @@
 /*
- * Copyright(c) 2015, 2016 Intel Corporation.
+ * Copyright(c) 2015 - 2017 Intel Corporation.
  *
  * This file is provided under a dual BSD/GPLv2 license.  When using or
  * redistributing this file, you may do so under either license.
@@ -350,7 +350,9 @@ void hfi1_make_ruc_header(struct rvt_qp
 
 void _hfi1_do_send(struct work_struct *work);
 
-void hfi1_do_send(struct rvt_qp *qp);
+void hfi1_do_send_from_rvt(struct rvt_qp *qp);
+
+void hfi1_do_send(struct rvt_qp *qp, bool in_thread);
 
 void hfi1_send_complete(struct rvt_qp *qp, struct rvt_swqe *wqe,
 			enum ib_wc_status status);
author maintainer
#50 lore raw

PATCH 52/114 perf auxtrace: Fix no_size logic in addr_filter__resolve_kernel_syms()

In reply to Greg Kroah-Hartman

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

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

From: Adrian Hunter <[email protected]>

commit c3a0bbc7ad7598dec5a204868bdf8a2b1b51df14 upstream.

Address filtering with kernel symbols incorrectly resulted in the error "Cannot determine size of symbol" because the no_size logic was the wrong way around.

---
 tools/perf/util/auxtrace.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
tools/perf/util/auxtrace.c +2 -2
@@ -1826,7 +1826,7 @@ static int addr_filter__resolve_kernel_s
 		filt->addr = start;
 		if (filt->range && !filt->size && !filt->sym_to) {
 			filt->size = size;
-			no_size = !!size;
+			no_size = !size;
 		}
 	}
 
@@ -1840,7 +1840,7 @@ static int addr_filter__resolve_kernel_s
 		if (err)
 			return err;
 		filt->size = start + size - filt->addr;
-		no_size = !!size;
+		no_size = !size;
 	}
 
 	/* The very last symbol in kallsyms does not imply a particular size */
author maintainer
#51 lore raw

PATCH 53/114 perf annotate s390: Fix perf annotate error -95 (4.10 regression)

In reply to Greg Kroah-Hartman

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

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

From: Christian Borntraeger <[email protected]>

commit e77852b32d6d4430c68c38aaf73efe5650fa25af upstream.

since 4.10 perf annotate exits on s390 with an "unknown error -95". Turns out that commit 786c1b51844d ("perf annotate: Start supporting cross arch annotation") added a hard requirement for architecture support when objdump is used but only provided x86 and arm support. Meanwhile power was added so lets add s390 as well.

While at it make sure to implement the branch and jump types.

Cc Andreas Krebbel <[email protected]>
Cc Hendrik Brueckner <[email protected]>
Cc Martin Schwidefsky <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc linux-s390 <[email protected]>
Fixes 786c1b51844 "perf annotate: Start supporting cross arch annotation"
---
 tools/perf/util/annotate.c |    6 ++++++
 1 file changed, 6 insertions(+)
tools/perf/util/annotate.c +6 -0
@@ -136,6 +136,12 @@ static struct arch architectures[] = {
 			.comment_char = '#',
 		},
 	},
+	{
+		.name = "s390",
+		.objdump =  {
+			.comment_char = '#',
+		},
+	},
 };
 
 static void ins__delete(struct ins_operands *ops)
author maintainer
#52 lore raw

PATCH 54/114 perf annotate s390: Implement jump types for perf annotate

In reply to Greg Kroah-Hartman

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

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

From: Christian Borntraeger <[email protected]>

commit d9f8dfa9baf9b6ae1f2f84f887176558ecde5268 upstream.

Implement simple detection for all kind of jumps and branches.

---
 tools/perf/arch/s390/annotate/instructions.c |   30 +++++++++++++++++++++++++++
 tools/perf/util/annotate.c                   |    2 +
 2 files changed, 32 insertions(+)
tools/perf/arch/s390/annotate/instructions.c new file +30 -0
@@ -0,0 +1,30 @@
+static struct ins_ops *s390__associate_ins_ops(struct arch *arch, const char *name)
+{
+	struct ins_ops *ops = NULL;
+
+	/* catch all kind of jumps */
+	if (strchr(name, 'j') ||
+	    !strncmp(name, "bct", 3) ||
+	    !strncmp(name, "br", 2))
+		ops = &jump_ops;
+	/* override call/returns */
+	if (!strcmp(name, "bras") ||
+	    !strcmp(name, "brasl") ||
+	    !strcmp(name, "basr"))
+		ops = &call_ops;
+	if (!strcmp(name, "br"))
+		ops = &ret_ops;
+
+	arch__associate_ins_ops(arch, name, ops);
+	return ops;
+}
+
+static int s390__annotate_init(struct arch *arch)
+{
+	if (!arch->initialized) {
+		arch->initialized = true;
+		arch->associate_instruction_ops = s390__associate_ins_ops;
+	}
+
+	return 0;
+}
tools/perf/util/annotate.c +2 -0
@@ -108,6 +108,7 @@ static int arch__associate_ins_ops(struc
 #include "arch/arm64/annotate/instructions.c"
 #include "arch/x86/annotate/instructions.c"
 #include "arch/powerpc/annotate/instructions.c"
+#include "arch/s390/annotate/instructions.c"
 
 static struct arch architectures[] = {
 	{
@@ -132,6 +133,7 @@ static struct arch architectures[] = {
 	},
 	{
 		.name = "s390",
+		.init = s390__annotate_init,
 		.objdump =  {
 			.comment_char = '#',
 		},
author maintainer
#53 lore raw

PATCH 55/114 jbd2: fix dbench4 performance regression for nobarrier mounts

In reply to Greg Kroah-Hartman

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

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

From: Jan Kara <[email protected]>

commit 5052b069acf73866d00077d8bc49983c3ee903e5 upstream.

Commit b685d3d65ac7 "block: treat REQ_FUA and REQ_PREFLUSH as synchronous" removed REQ_SYNC flag from WRITE_FUA implementation. Since JBD2 strips REQ_FUA and REQ_FLUSH flags from submitted IO when the filesystem is mounted with nobarrier mount option, journal superblock writes ended up being async writes after this patch and that caused heavy performance regression for dbench4 benchmark with high number of processes. In my test setup with HP RAID array with non-volatile write cache and 32 GB ram, dbench4 runs with 8 processes regressed by ~25%.

Fix the problem by making sure journal superblock writes are always treated as synchronous since they generally block progress of the journalling machinery and thus the whole filesystem.

Fixes b685d3d65ac791406e0dfd8779cc9b3707fea5a3
---
 fs/jbd2/journal.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/jbd2/journal.c +1 -1
@@ -1348,7 +1348,7 @@ static int jbd2_write_superblock(journal
 	jbd2_superblock_csum_set(journal, sb);
 	get_bh(bh);
 	bh->b_end_io = end_buffer_write_sync;
-	ret = submit_bh(REQ_OP_WRITE, write_flags, bh);
+	ret = submit_bh(REQ_OP_WRITE, write_flags | REQ_SYNC, bh);
 	wait_on_buffer(bh);
 	if (buffer_write_io_error(bh)) {
 		clear_buffer_write_io_error(bh);
author maintainer
#54 lore raw

PATCH 56/114 ext4: evict inline data when writing to memory map

In reply to Greg Kroah-Hartman

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

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

From: Eric Biggers <[email protected]>

commit 7b4cc9787fe35b3ee2dfb1c35e22eafc32e00c33 upstream.

Currently the case of writing via mmap to a file with inline data is not handled. This is maybe a rare case since it requires a writable memory map of a very small file, but it is trivial to trigger with on inline_data filesystem, and it causes the 'BUG_ON(ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA));' in ext4_writepages() to be hit:

    mkfs.ext4 -O inline_data /dev/vdb
    mount /dev/vdb /mnt
    xfs_io -f /mnt/file \
	-c 'pwrite 0 1' \
	-c 'mmap -w 0 1m' \
	-c 'mwrite 0 1' \
	-c 'fsync'

	kernel BUG at fs/ext4/inode.c:2723!
	invalid opcode: 0000 [#1] SMP
	CPU: 1 PID: 2532 Comm: xfs_io Not tainted 4.11.0-rc1-xfstests-00301-g071d9acf3d1f #633
	Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-20170228_101828-anatol 04/01/2014
	task: ffff88003d3a8040 task.stack: ffffc90000300000
	RIP: 0010:ext4_writepages+0xc89/0xf8a
	RSP: 0018:ffffc90000303ca0 EFLAGS: 00010283
	RAX: 0000028410000000 RBX: ffff8800383fa3b0 RCX: ffffffff812afcdc
	RDX: 00000a9d00000246 RSI: ffffffff81e660e0 RDI: 0000000000000246
	RBP: ffffc90000303dc0 R08: 0000000000000002 R09: 869618e8f99b4fa5
	R10: 00000000852287a2 R11: 00000000a03b49f4 R12: ffff88003808e698
	R13: 0000000000000000 R14: 7fffffffffffffff R15: 7fffffffffffffff
	FS:  00007fd3e53094c0(0000) GS:ffff88003e400000(0000) knlGS:0000000000000000
	CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
	CR2: 00007fd3e4c51000 CR3: 000000003d554000 CR4: 00000000003406e0
	Call Trace:
	 ? _raw_spin_unlock+0x27/0x2a
	 ? kvm_clock_read+0x1e/0x20
	 do_writepages+0x23/0x2c
	 ? do_writepages+0x23/0x2c
	 __filemap_fdatawrite_range+0x80/0x87
	 filemap_write_and_wait_range+0x67/0x8c
	 ext4_sync_file+0x20e/0x472
	 vfs_fsync_range+0x8e/0x9f
	 ? syscall_trace_enter+0x25b/0x2d0
	 vfs_fsync+0x1c/0x1e
	 do_fsync+0x31/0x4a
	 SyS_fsync+0x10/0x14
	 do_syscall_64+0x69/0x131
	 entry_SYSCALL64_slow_path+0x25/0x25

We could try to be smart and keep the inline data in this case, or at least support delayed allocation when allocating the block, but these solutions would be more complicated and don't seem worthwhile given how rare this case seems to be. So just fix the bug by calling ext4_convert_inline_data() when we're asked to make a page writable, so that any inline data gets evicted, with the block allocated immediately.

---
 fs/ext4/inode.c |    5 +++++
 1 file changed, 5 insertions(+)
fs/ext4/inode.c +5 -0
@@ -5874,6 +5874,11 @@ int ext4_page_mkwrite(struct vm_fault *v
 	file_update_time(vma->vm_file);
 
 	down_read(&EXT4_I(inode)->i_mmap_sem);
+
+	ret = ext4_convert_inline_data(inode);
+	if (ret)
+		goto out_ret;
+
 	/* Delalloc case is easy... */
 	if (test_opt(inode->i_sb, DELALLOC) &&
 	    !ext4_should_journal_data(inode) &&
author maintainer
#55 lore raw

PATCH 57/114 orangefs: fix bounds check for listxattr

In reply to Greg Kroah-Hartman

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

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

From: Martin Brandenburg <[email protected]>

commit a956af337b9ff25822d9ce1a59c6ed0c09fc14b9 upstream.

---
 fs/orangefs/xattr.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/orangefs/xattr.c +1 -1
@@ -358,7 +358,7 @@ try_again:
 
 	returned_count = new_op->downcall.resp.listxattr.returned_count;
 	if (returned_count < 0 ||
-	    returned_count >= ORANGEFS_MAX_XATTR_LISTLEN) {
+	    returned_count > ORANGEFS_MAX_XATTR_LISTLEN) {
 		gossip_err("%s: impossible value for returned_count:%d:\n",
 		__func__,
 		returned_count);
author maintainer
#56 lore raw

PATCH 58/114 orangefs: clean up oversize xattr validation

In reply to Greg Kroah-Hartman

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

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

From: Martin Brandenburg <[email protected]>

commit e675c5ec51fe2554719a7b6bcdbef0a770f2c19b upstream.

Also don't check flags as this has been validated by the VFS already.

Fix an off-by-one error in the max size checking.

Stop logging just because userspace wants to write attributes which do not fit.

This and the previous commit fix xfstests generic/020.

---
 fs/orangefs/xattr.c |   24 +++++++-----------------
 1 file changed, 7 insertions(+), 17 deletions(-)
fs/orangefs/xattr.c +7 -17
@@ -76,11 +76,8 @@ ssize_t orangefs_inode_getxattr(struct i
 	if (S_ISLNK(inode->i_mode))
 		return -EOPNOTSUPP;
 
-	if (strlen(name) >= ORANGEFS_MAX_XATTR_NAMELEN) {
-		gossip_err("Invalid key length (%d)\n",
-			   (int)strlen(name));
+	if (strlen(name) > ORANGEFS_MAX_XATTR_NAMELEN)
 		return -EINVAL;
-	}
 
 	fsuid = from_kuid(&init_user_ns, current_fsuid());
 	fsgid = from_kgid(&init_user_ns, current_fsgid());
@@ -172,6 +169,9 @@ static int orangefs_inode_removexattr(st
 	struct orangefs_kernel_op_s *new_op = NULL;
 	int ret = -ENOMEM;
 
+	if (strlen(name) > ORANGEFS_MAX_XATTR_NAMELEN)
+		return -EINVAL;
+
 	down_write(&orangefs_inode->xattr_sem);
 	new_op = op_alloc(ORANGEFS_VFS_OP_REMOVEXATTR);
 	if (!new_op)
@@ -231,23 +231,13 @@ int orangefs_inode_setxattr(struct inode
 		     "%s: name %s, buffer_size %zd\n",
 		     __func__, name, size);
 
-	if (size >= ORANGEFS_MAX_XATTR_VALUELEN ||
-	    flags < 0) {
-		gossip_err("orangefs_inode_setxattr: bogus values of size(%d), flags(%d)\n",
-			   (int)size,
-			   flags);
+	if (size > ORANGEFS_MAX_XATTR_VALUELEN)
+		return -EINVAL;
+	if (strlen(name) > ORANGEFS_MAX_XATTR_NAMELEN)
 		return -EINVAL;
-	}
 
 	internal_flag = convert_to_internal_xattr_flags(flags);
 
-	if (strlen(name) >= ORANGEFS_MAX_XATTR_NAMELEN) {
-		gossip_err
-		    ("orangefs_inode_setxattr: bogus key size (%d)\n",
-		     (int)(strlen(name)));
-		return -EINVAL;
-	}
-
 	/* This is equivalent to a removexattr */
 	if (size == 0 && value == NULL) {
 		gossip_debug(GOSSIP_XATTR_DEBUG,
author maintainer
#57 lore raw

PATCH 59/114 orangefs: do not set getattr_time on orangefs_lookup

In reply to Greg Kroah-Hartman

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

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

From: Martin Brandenburg <[email protected]>

commit 17930b252cd6f31163c259eaa99dd8aa630fb9ba upstream.

Since orangefs_lookup calls orangefs_iget which calls orangefs_inode_getattr, getattr_time will get set.

---
 fs/orangefs/namei.c |    2 --
 1 file changed, 2 deletions(-)
fs/orangefs/namei.c +0 -2
@@ -193,8 +193,6 @@ static struct dentry *orangefs_lookup(st
 		goto out;
 	}
 
-	ORANGEFS_I(inode)->getattr_time = jiffies - 1;
-
 	gossip_debug(GOSSIP_NAME_DEBUG,
 		     "%s:%s:%d "
 		     "Found good inode [%lu] with count [%d]\n",
author maintainer
#58 lore raw

PATCH 60/114 orangefs: do not check possibly stale size on truncate

In reply to Greg Kroah-Hartman

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

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

From: Martin Brandenburg <[email protected]>

commit 53950ef541675df48c219a8d665111a0e68dfc2f upstream.

Let the server figure this out because our size might be out of date or not present.

The bug was that

	xfs_io -f -t -c "pread -v 0 100" /mnt/foo
	echo "Test" > /mnt/foo
	xfs_io -f -t -c "pread -v 0 100" /mnt/foo

fails because the second truncate did not happen if nothing had requested the size after the write in echo. Thus i_size was zero (not present) and the orangefs_setattr though i_size was zero and there was nothing to do.

---
 fs/orangefs/inode.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
fs/orangefs/inode.c +1 -2
@@ -218,8 +218,7 @@ int orangefs_setattr(struct dentry *dent
 	if (ret)
 		goto out;
 
-	if ((iattr->ia_valid & ATTR_SIZE) &&
-	    iattr->ia_size != i_size_read(inode)) {
+	if (iattr->ia_valid & ATTR_SIZE) {
 		ret = orangefs_setattr_size(inode, iattr);
 		if (ret)
 			goto out;
author maintainer
#59 lore raw

PATCH 61/114 fs/xattr.c: zero out memory copied to userspace in getxattr

In reply to Greg Kroah-Hartman

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

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

From: Michal Hocko <[email protected]>

commit 81be3dee96346fbe08c31be5ef74f03f6b63cf68 upstream.

getxattr uses vmalloc to allocate memory if kzalloc fails. This is filled by vfs_getxattr and then copied to the userspace. vmalloc, however, doesn't zero out the memory so if the specific implementation of the xattr handler is sloppy we can theoretically expose a kernel memory. There is no real sign this is really the case but let's make sure this will not happen and use vzalloc instead.

---
 fs/xattr.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/xattr.c +1 -1
@@ -530,7 +530,7 @@ getxattr(struct dentry *d, const char __
 			size = XATTR_SIZE_MAX;
 		kvalue = kzalloc(size, GFP_KERNEL | __GFP_NOWARN);
 		if (!kvalue) {
-			kvalue = vmalloc(size);
+			kvalue = vzalloc(size);
 			if (!kvalue)
 				return -ENOMEM;
 		}
author maintainer
#60 lore raw

PATCH 62/114 ceph: fix memory leak in __ceph_setxattr()

In reply to Greg Kroah-Hartman

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

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

From: Luis Henriques <[email protected]>

commit eeca958dce0a9231d1969f86196653eb50fcc9b3 upstream.

The ceph_inode_xattr needs to be released when removing an xattr. Easily reproducible running the 'generic/020' test from xfstests or simply by doing:

  attr -s attr0 -V 0 /mnt/test && attr -r attr0 /mnt/test

While there, also fix the error path.

Here's the kmemleak splat:

unreferenced object 0xffff88001f86fbc0 (size 64):
comm "attr", pid 244, jiffies 4294904246 (age 98.464s) hex dump (first 32 bytes):

    40 fa 86 1f 00 88 ff ff 80 32 38 1f 00 88 ff ff  @........28.....
    00 01 00 00 00 00 ad de 00 02 00 00 00 00 ad de  ................
  backtrace:
    [<ffffffff81560199>] kmemleak_alloc+0x49/0xa0
    [<ffffffff810f3e5b>] kmem_cache_alloc+0x9b/0xf0
    [<ffffffff812b157e>] __ceph_setxattr+0x17e/0x820
    [<ffffffff812b1c57>] ceph_set_xattr_handler+0x37/0x40
    [<ffffffff8111fb4b>] __vfs_removexattr+0x4b/0x60
    [<ffffffff8111fd37>] vfs_removexattr+0x77/0xd0
    [<ffffffff8111fdd1>] removexattr+0x41/0x60
    [<ffffffff8111fe65>] path_removexattr+0x75/0xa0
    [<ffffffff81120aeb>] SyS_lremovexattr+0xb/0x10
    [<ffffffff81564b20>] entry_SYSCALL_64_fastpath+0x13/0x94
    [<ffffffffffffffff>] 0xffffffffffffffff
---
 fs/ceph/xattr.c |    3 +++
 1 file changed, 3 insertions(+)
fs/ceph/xattr.c +3 -0
@@ -392,6 +392,7 @@ static int __set_xattr(struct ceph_inode
 
 	if (update_xattr) {
 		int err = 0;
+
 		if (xattr && (flags & XATTR_CREATE))
 			err = -EEXIST;
 		else if (!xattr && (flags & XATTR_REPLACE))
@@ -399,12 +400,14 @@ static int __set_xattr(struct ceph_inode
 		if (err) {
 			kfree(name);
 			kfree(val);
+			kfree(*newxattr);
 			return err;
 		}
 		if (update_xattr < 0) {
 			if (xattr)
 				__remove_xattr(ci, xattr);
 			kfree(name);
+			kfree(*newxattr);
 			return 0;
 		}
 	}
author maintainer
#61 lore raw

PATCH 63/114 fs: fix data invalidation in the cleancache during direct IO

In reply to Greg Kroah-Hartman

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

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

From: Andrey Ryabinin <[email protected]>

commit 55635ba76ef91f26b418702ace5e6287eb727f6a upstream.

Patch series "Properly invalidate data in the cleancache", v2.

We've noticed that after direct IO write, buffered read sometimes gets stale data which is coming from the cleancache. The reason for this is that some direct write hooks call call invalidate_inode_pages2[_range]() conditionally iff mapping->nrpages is not zero, so we may not invalidate data in the cleancache.

Another odd thing is that we check only for ->nrpages and don't check for ->nrexceptional, but invalidate_inode_pages2[_range] also invalidates exceptional entries as well. So we invalidate exceptional entries only if ->nrpages != 0? This doesn't feel right.

- Patch 1 fixes direct IO writes by removing ->nrpages check.
- Patch 2 fixes similar case in invalidate_bdev().
Note: I only fixed conditional cleancache_invalidate_inode() here.
Do we also need to add ->nrexceptional check in into invalidate_bdev()?

- Patches 3-4: some optimizations.

This patch (of 4):

Some direct IO write fs hooks call invalidate_inode_pages2[_range]() conditionally iff mapping->nrpages is not zero. This can't be right, because invalidate_inode_pages2[_range]() also invalidate data in the cleancache via cleancache_invalidate_inode() call. So if page cache is empty but there is some data in the cleancache, buffered read after direct IO write would get stale data from the cleancache.

Also it doesn't feel right to check only for ->nrpages because invalidate_inode_pages2[_range] invalidates exceptional entries as well.

Fix this by calling invalidate_inode_pages2[_range]() regardless of nrpages state.

Note: nfs,cifs,9p doesn't need similar fix because the never call cleancache_get_page() (nor directly, nor via mpage_readpage[s]()), so they are not affected by this bug.

Fixes c515e1fd361c ("mm/fs: add hooks to support cleancache")
Cc Alexander Viro <[email protected]>
Cc Ross Zwisler <[email protected]>
Cc Jens Axboe <[email protected]>
Cc Johannes Weiner <[email protected]>
Cc Alexey Kuznetsov <[email protected]>
Cc Christoph Hellwig <[email protected]>
Cc Nikolay Borisov <[email protected]>
---
 fs/iomap.c   |   20 +++++++++-----------
 mm/filemap.c |   26 +++++++++++---------------
 2 files changed, 20 insertions(+), 26 deletions(-)
fs/iomap.c +9 -11
@@ -887,16 +887,14 @@ iomap_dio_rw(struct kiocb *iocb, struct
 		flags |= IOMAP_WRITE;
 	}
 
-	if (mapping->nrpages) {
-		ret = filemap_write_and_wait_range(mapping, start, end);
-		if (ret)
-			goto out_free_dio;
-
-		ret = invalidate_inode_pages2_range(mapping,
-				start >> PAGE_SHIFT, end >> PAGE_SHIFT);
-		WARN_ON_ONCE(ret);
-		ret = 0;
-	}
+	ret = filemap_write_and_wait_range(mapping, start, end);
+	if (ret)
+		goto out_free_dio;
+
+	ret = invalidate_inode_pages2_range(mapping,
+			start >> PAGE_SHIFT, end >> PAGE_SHIFT);
+	WARN_ON_ONCE(ret);
+	ret = 0;
 
 	inode_dio_begin(inode);
 
@@ -951,7 +949,7 @@ iomap_dio_rw(struct kiocb *iocb, struct
 	 * one is a pretty crazy thing to do, so we don't support it 100%.  If
 	 * this invalidation fails, tough, the write still worked...
 	 */
-	if (iov_iter_rw(iter) == WRITE && mapping->nrpages) {
+	if (iov_iter_rw(iter) == WRITE) {
 		int err = invalidate_inode_pages2_range(mapping,
 				start >> PAGE_SHIFT, end >> PAGE_SHIFT);
 		WARN_ON_ONCE(err);
mm/filemap.c +11 -15
@@ -2719,18 +2719,16 @@ generic_file_direct_write(struct kiocb *
 	 * about to write.  We do this *before* the write so that we can return
 	 * without clobbering -EIOCBQUEUED from ->direct_IO().
 	 */
-	if (mapping->nrpages) {
-		written = invalidate_inode_pages2_range(mapping,
+	written = invalidate_inode_pages2_range(mapping,
 					pos >> PAGE_SHIFT, end);
-		/*
-		 * If a page can not be invalidated, return 0 to fall back
-		 * to buffered write.
-		 */
-		if (written) {
-			if (written == -EBUSY)
-				return 0;
-			goto out;
-		}
+	/*
+	 * If a page can not be invalidated, return 0 to fall back
+	 * to buffered write.
+	 */
+	if (written) {
+		if (written == -EBUSY)
+			return 0;
+		goto out;
 	}
 
 	data = *from;
@@ -2744,10 +2742,8 @@ generic_file_direct_write(struct kiocb *
 	 * so we don't support it 100%.  If this invalidation
 	 * fails, tough, the write still worked...
 	 */
-	if (mapping->nrpages) {
-		invalidate_inode_pages2_range(mapping,
-					      pos >> PAGE_SHIFT, end);
-	}
+	invalidate_inode_pages2_range(mapping,
+				pos >> PAGE_SHIFT, end);
 
 	if (written > 0) {
 		pos += written;
author maintainer
#62 lore raw

PATCH 64/114 fs/block_dev: always invalidate cleancache in invalidate_bdev()

In reply to Greg Kroah-Hartman

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

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

From: Andrey Ryabinin <[email protected]>

commit a5f6a6a9c72eac38a7fadd1a038532bc8516337c upstream.

invalidate_bdev() calls cleancache_invalidate_inode() iff ->nrpages != 0 which doen't make any sense.

Make sure that invalidate_bdev() always calls cleancache_invalidate_inode() regardless of mapping->nrpages value.

Fixes c515e1fd361c ("mm/fs: add hooks to support cleancache")
Cc Alexander Viro <[email protected]>
Cc Ross Zwisler <[email protected]>
Cc Jens Axboe <[email protected]>
Cc Johannes Weiner <[email protected]>
Cc Alexey Kuznetsov <[email protected]>
Cc Christoph Hellwig <[email protected]>
Cc Nikolay Borisov <[email protected]>
---
 fs/block_dev.c |   11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)
fs/block_dev.c +5 -6
@@ -103,12 +103,11 @@ void invalidate_bdev(struct block_device
 {
 	struct address_space *mapping = bdev->bd_inode->i_mapping;
 
-	if (mapping->nrpages == 0)
-		return;
-
-	invalidate_bh_lrus();
-	lru_add_drain_all();	/* make sure all lru add caches are flushed */
-	invalidate_mapping_pages(mapping, 0, -1);
+	if (mapping->nrpages) {
+		invalidate_bh_lrus();
+		lru_add_drain_all();	/* make sure all lru add caches are flushed */
+		invalidate_mapping_pages(mapping, 0, -1);
+	}
 	/* 99% of the time, we don't need to flush the cleancache on the bdev.
 	 * But, for the strange corners, lets be cautious
 	 */
author maintainer
#63 lore raw

PATCH 65/114 mm: vmscan: fix IO/refault regression in cache workingset transition

In reply to Greg Kroah-Hartman

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

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

From: Johannes Weiner <[email protected]>

commit 2a2e48854d704214dac7546e87ae0e4daa0e61a0 upstream.

Since commit 59dc76b0d4df ("mm: vmscan: reduce size of inactive file list") we noticed bigger IO spikes during changes in cache access patterns.

The patch in question shrunk the inactive list size to leave more room for the current workingset in the presence of streaming IO. However, workingset transitions that previously happened on the inactive list are now pushed out of memory and incur more refaults to complete.

This patch disables active list protection when refaults are being observed. This accelerates workingset transitions, and allows more of the new set to establish itself from memory, without eating into the ability to protect the established workingset during stable periods.

The workloads that were measurably affected for us were hit pretty bad by it, with refault/majfault rates doubling and tripling during cache transitions, and the machines sustaining half-hour periods of 100% IO utilization, where they'd previously have sub-minute peaks at 60-90%.

Stateful services that handle user data tend to be more conservative with kernel upgrades. As a result we hit most page cache issues with some delay, as was the case here.

The severity seemed to warrant a stable tag.

Fixes 59dc76b0d4df ("mm: vmscan: reduce size of inactive file list")
Cc Rik van Riel <[email protected]>
Cc Mel Gorman <[email protected]>
Cc Michal Hocko <[email protected]>
Cc Vladimir Davydov <[email protected]>
---
 include/linux/memcontrol.h |   64 +++++++++++++++++++++++++++++-
 include/linux/mmzone.h     |    2 
 mm/memcontrol.c            |   24 +++--------
 mm/vmscan.c                |   94 +++++++++++++++++++++++++++++++++++----------
 mm/workingset.c            |    7 ++-
 5 files changed, 150 insertions(+), 41 deletions(-)
include/linux/memcontrol.h +61 -3
@@ -56,6 +56,9 @@ enum mem_cgroup_stat_index {
 	MEMCG_SLAB_RECLAIMABLE,
 	MEMCG_SLAB_UNRECLAIMABLE,
 	MEMCG_SOCK,
+	MEMCG_WORKINGSET_REFAULT,
+	MEMCG_WORKINGSET_ACTIVATE,
+	MEMCG_WORKINGSET_NODERECLAIM,
 	MEMCG_NR_STAT,
 };
 
@@ -494,6 +497,40 @@ extern int do_swap_account;
 void lock_page_memcg(struct page *page);
 void unlock_page_memcg(struct page *page);
 
+static inline unsigned long mem_cgroup_read_stat(struct mem_cgroup *memcg,
+						 enum mem_cgroup_stat_index idx)
+{
+	long val = 0;
+	int cpu;
+
+	for_each_possible_cpu(cpu)
+		val += per_cpu(memcg->stat->count[idx], cpu);
+
+	if (val < 0)
+		val = 0;
+
+	return val;
+}
+
+static inline void mem_cgroup_update_stat(struct mem_cgroup *memcg,
+				   enum mem_cgroup_stat_index idx, int val)
+{
+	if (!mem_cgroup_disabled())
+		this_cpu_add(memcg->stat->count[idx], val);
+}
+
+static inline void mem_cgroup_inc_stat(struct mem_cgroup *memcg,
+				   enum mem_cgroup_stat_index idx)
+{
+	mem_cgroup_update_stat(memcg, idx, 1);
+}
+
+static inline void mem_cgroup_dec_stat(struct mem_cgroup *memcg,
+				   enum mem_cgroup_stat_index idx)
+{
+	mem_cgroup_update_stat(memcg, idx, -1);
+}
+
 /**
  * mem_cgroup_update_page_stat - update page state statistics
  * @page: the page
@@ -508,14 +545,14 @@ void unlock_page_memcg(struct page *page
  *   if (TestClearPageState(page))
  *     mem_cgroup_update_page_stat(page, state, -1);
  *   unlock_page(page) or unlock_page_memcg(page)
+ *
+ * Kernel pages are an exception to this, since they'll never move.
  */
 static inline void mem_cgroup_update_page_stat(struct page *page,
 				 enum mem_cgroup_stat_index idx, int val)
 {
-	VM_BUG_ON(!(rcu_read_lock_held() || PageLocked(page)));
-
 	if (page->mem_cgroup)
-		this_cpu_add(page->mem_cgroup->stat->count[idx], val);
+		mem_cgroup_update_stat(page->mem_cgroup, idx, val);
 }
 
 static inline void mem_cgroup_inc_page_stat(struct page *page,
@@ -740,6 +777,27 @@ static inline bool mem_cgroup_oom_synchr
 	return false;
 }
 
+static inline unsigned long mem_cgroup_read_stat(struct mem_cgroup *memcg,
+						 enum mem_cgroup_stat_index idx)
+{
+	return 0;
+}
+
+static inline void mem_cgroup_update_stat(struct mem_cgroup *memcg,
+				   enum mem_cgroup_stat_index idx, int val)
+{
+}
+
+static inline void mem_cgroup_inc_stat(struct mem_cgroup *memcg,
+				   enum mem_cgroup_stat_index idx)
+{
+}
+
+static inline void mem_cgroup_dec_stat(struct mem_cgroup *memcg,
+				   enum mem_cgroup_stat_index idx)
+{
+}
+
 static inline void mem_cgroup_update_page_stat(struct page *page,
 					       enum mem_cgroup_stat_index idx,
 					       int nr)
include/linux/mmzone.h +2 -0
@@ -226,6 +226,8 @@ struct lruvec {
 	struct zone_reclaim_stat	reclaim_stat;
 	/* Evictions & activations on the inactive file list */
 	atomic_long_t			inactive_age;
+	/* Refaults at the time of last reclaim cycle */
+	unsigned long			refaults;
 #ifdef CONFIG_MEMCG
 	struct pglist_data *pgdat;
 #endif
mm/memcontrol.c +7 -17
@@ -568,23 +568,6 @@ mem_cgroup_largest_soft_limit_node(struc
  * common workload, threshold and synchronization as vmstat[] should be
  * implemented.
  */
-static unsigned long
-mem_cgroup_read_stat(struct mem_cgroup *memcg, enum mem_cgroup_stat_index idx)
-{
-	long val = 0;
-	int cpu;
-
-	/* Per-cpu values can be negative, use a signed accumulator */
-	for_each_possible_cpu(cpu)
-		val += per_cpu(memcg->stat->count[idx], cpu);
-	/*
-	 * Summing races with updates, so val may be negative.  Avoid exposing
-	 * transient negative values.
-	 */
-	if (val < 0)
-		val = 0;
-	return val;
-}
 
 static unsigned long mem_cgroup_read_events(struct mem_cgroup *memcg,
 					    enum mem_cgroup_events_index idx)
@@ -5237,6 +5220,13 @@ static int memory_stat_show(struct seq_f
 	seq_printf(m, "pgmajfault %lu\n",
 		   events[MEM_CGROUP_EVENTS_PGMAJFAULT]);
 
+	seq_printf(m, "workingset_refault %lu\n",
+		   stat[MEMCG_WORKINGSET_REFAULT]);
+	seq_printf(m, "workingset_activate %lu\n",
+		   stat[MEMCG_WORKINGSET_ACTIVATE]);
+	seq_printf(m, "workingset_nodereclaim %lu\n",
+		   stat[MEMCG_WORKINGSET_NODERECLAIM]);
+
 	return 0;
 }
 
mm/vmscan.c +74 -20

171 lines not on this page · raw message

mm/workingset.c +6 -1
@@ -269,7 +269,6 @@ bool workingset_refault(void *shadow)
 	lruvec = mem_cgroup_lruvec(pgdat, memcg);
 	refault = atomic_long_read(&lruvec->inactive_age);
 	active_file = lruvec_lru_size(lruvec, LRU_ACTIVE_FILE, MAX_NR_ZONES);
-	rcu_read_unlock();
 
 	/*
 	 * The unsigned subtraction here gives an accurate distance
@@ -290,11 +289,15 @@ bool workingset_refault(void *shadow)
 	refault_distance = (refault - eviction) & EVICTION_MASK;
 
 	inc_node_state(pgdat, WORKINGSET_REFAULT);
+	mem_cgroup_inc_stat(memcg, MEMCG_WORKINGSET_REFAULT);
 
 	if (refault_distance <= active_file) {
 		inc_node_state(pgdat, WORKINGSET_ACTIVATE);
+		mem_cgroup_inc_stat(memcg, MEMCG_WORKINGSET_ACTIVATE);
+		rcu_read_unlock();
 		return true;
 	}
+	rcu_read_unlock();
 	return false;
 }
 
@@ -472,6 +475,8 @@ static enum lru_status shadow_lru_isolat
 	if (WARN_ON_ONCE(node->exceptional))
 		goto out_invalid;
 	inc_node_state(page_pgdat(virt_to_page(node)), WORKINGSET_NODERECLAIM);
+	mem_cgroup_inc_page_stat(virt_to_page(node),
+				 MEMCG_WORKINGSET_NODERECLAIM);
 	__radix_tree_delete_node(&mapping->page_tree, node,
 				 workingset_update_node, mapping);
 
author maintainer
#64 lore raw

PATCH 66/114 mm: prevent potential recursive reclaim due to clearing PF_MEMALLOC

In reply to Greg Kroah-Hartman

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

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

From: Vlastimil Babka <[email protected]>

commit 62be1511b1db8066220b18b7d4da2e6b9fdc69fb upstream.

Patch series "more robust PF_MEMALLOC handling"

This series aims to unify the setting and clearing of PF_MEMALLOC, which prevents recursive reclaim. There are some places that clear the flag unconditionally from current->flags, which may result in clearing a pre-existing flag. This already resulted in a bug report that Patch 1 fixes (without the new helpers, to make backporting easier). Patch 2 introduces the new helpers, modelled after existing memalloc_noio_* and memalloc_nofs_* helpers, and converts mm core to use them. Patches 3 and 4 convert non-mm code.

This patch (of 4):

__alloc_pages_direct_compact() sets PF_MEMALLOC to prevent deadlock during page migration by lock_page() (see the comment in __unmap_and_move()). Then it unconditionally clears the flag, which can clear a pre-existing PF_MEMALLOC flag and result in recursive reclaim. This was not a problem until commit a8161d1ed609 ("mm, page_alloc:
restructure direct compaction handling in slowpath"), because direct compation was called only after direct reclaim, which was skipped when PF_MEMALLOC flag was set.

Even now it's only a theoretical issue, as the new callsite of __alloc_pages_direct_compact() is reached only for costly orders and when gfp_pfmemalloc_allowed() is true, which means either __GFP_NOMEMALLOC is in gfp_flags or in_interrupt() is true. There is no such known context, but let's play it safe and make __alloc_pages_direct_compact() robust for cases where PF_MEMALLOC is already set.

Fixes a8161d1ed609 ("mm, page_alloc: restructure direct compaction handling in slowpath")
Cc Mel Gorman <[email protected]>
Cc Johannes Weiner <[email protected]>
Cc Boris Brezillon <[email protected]>
Cc Chris Leech <[email protected]>
Cc "David S. Miller" <[email protected]>
Cc Eric Dumazet <[email protected]>
Cc Josef Bacik <[email protected]>
Cc Lee Duncan <[email protected]>
Cc Michal Hocko <[email protected]>
Cc Richard Weinberger <[email protected]>
---
 mm/page_alloc.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
mm/page_alloc.c +2 -1
@@ -3245,6 +3245,7 @@ __alloc_pages_direct_compact(gfp_t gfp_m
 		enum compact_priority prio, enum compact_result *compact_result)
 {
 	struct page *page;
+	unsigned int noreclaim_flag = current->flags & PF_MEMALLOC;
 
 	if (!order)
 		return NULL;
@@ -3252,7 +3253,7 @@ __alloc_pages_direct_compact(gfp_t gfp_m
 	current->flags |= PF_MEMALLOC;
 	*compact_result = try_to_compact_pages(gfp_mask, order, alloc_flags, ac,
 									prio);
-	current->flags &= ~PF_MEMALLOC;
+	current->flags = (current->flags & ~PF_MEMALLOC) | noreclaim_flag;
 
 	if (*compact_result <= COMPACT_INACTIVE)
 		return NULL;
author maintainer
#65 lore raw

PATCH 67/114 Fix match_prepath()

In reply to Greg Kroah-Hartman

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

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

From: Sachin Prabhu <[email protected]>

commit cd8c42968ee651b69e00f8661caff32b0086e82d upstream.

Incorrect return value for shares not using the prefix path means that we will never match superblocks for these shares.

Fixes commit c1d8b24d1819 ("Compare prepaths when comparing superblocks")
---
 fs/cifs/connect.c |   14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)
fs/cifs/connect.c +6 -8
@@ -2912,16 +2912,14 @@ match_prepath(struct super_block *sb, st
 {
 	struct cifs_sb_info *old = CIFS_SB(sb);
 	struct cifs_sb_info *new = mnt_data->cifs_sb;
+	bool old_set = old->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH;
+	bool new_set = new->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH;
 
-	if (old->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) {
-		if (!(new->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH))
-			return 0;
-		/* The prepath should be null terminated strings */
-		if (strcmp(new->prepath, old->prepath))
-			return 0;
-
+	if (old_set && new_set && !strcmp(new->prepath, old->prepath))
+		return 1;
+	else if (!old_set && !new_set)
 		return 1;
-	}
+
 	return 0;
 }
 
author maintainer
#66 lore raw

PATCH 68/114 Do not return number of bytes written for ioctl CIFS_IOC_COPYCHUNK_FILE

In reply to Greg Kroah-Hartman

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

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

From: Sachin Prabhu <[email protected]>

commit 7d0c234fd2e1c9ca3fa032696c0c58b1b74a9e0b upstream.

commit 620d8745b35d ("Introduce cifs_copy_file_range()") changes the behaviour of the cifs ioctl call CIFS_IOC_COPYCHUNK_FILE. In case of successful writes, it now returns the number of bytes written. This return value is treated as an error by the xfstest cifs/001. Depending on the errno set at that time, this may or may not result in the test failing.

The patch fixes this by setting the return value to 0 in case of successful writes.

Fixes commit 620d8745b35d ("Introduce cifs_copy_file_range()")
---
 fs/cifs/ioctl.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
fs/cifs/ioctl.c +2 -1
@@ -74,7 +74,8 @@ static long cifs_ioctl_copychunk(unsigne
 
 	rc = cifs_file_copychunk_range(xid, src_file.file, 0, dst_file, 0,
 					src_inode->i_size, 0);
-
+	if (rc > 0)
+		rc = 0;
 out_fput:
 	fdput(src_file);
 out_drop_write:
author maintainer
#67 lore raw

PATCH 69/114 Set unicode flag on cifs echo request to avoid Mac error

In reply to Greg Kroah-Hartman

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

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

From: Steve French <[email protected]>

commit 26c9cb668c7fbf9830516b75d8bee70b699ed449 upstream.

Mac requires the unicode flag to be set for cifs, even for the smb echo request (which doesn't have strings).

Without this Mac rejects the periodic echo requests (when mounting with cifs) that we use to check if server is down

---
 fs/cifs/cifssmb.c |    3 +++
 1 file changed, 3 insertions(+)
fs/cifs/cifssmb.c +3 -0
@@ -718,6 +718,9 @@ CIFSSMBEcho(struct TCP_Server_Info *serv
 	if (rc)
 		return rc;
 
+	if (server->capabilities & CAP_UNICODE)
+		smb->hdr.Flags2 |= SMBFLG2_UNICODE;
+
 	/* set up echo request */
 	smb->hdr.Tid = 0xffff;
 	smb->hdr.WordCount = 1;
author maintainer
#68 lore raw

PATCH 70/114 SMB3: Work around mount failure when using SMB3 dialect to Macs

In reply to Greg Kroah-Hartman

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

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

From: Steve French <[email protected]>

commit 7db0a6efdc3e990cdfd4b24820d010e9eb7890ad upstream.

Macs send the maximum buffer size in response on ioctl to validate negotiate security information, which causes us to fail the mount as the response buffer is larger than the expected response.

Changed ioctl response processing to allow for padding of validate negotiate ioctl response and limit the maximum response size to maximum buffer size.

---
 fs/cifs/smb2pdu.c |   14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)
fs/cifs/smb2pdu.c +11 -3
@@ -632,8 +632,12 @@ int smb3_validate_negotiate(const unsign
 	}
 
 	if (rsplen != sizeof(struct validate_negotiate_info_rsp)) {
-		cifs_dbg(VFS, "invalid size of protocol negotiate response\n");
-		return -EIO;
+		cifs_dbg(VFS, "invalid protocol negotiate response size: %d\n",
+			 rsplen);
+
+		/* relax check since Mac returns max bufsize allowed on ioctl */
+		if (rsplen > CIFSMaxBufSize)
+			return -EIO;
 	}
 
 	/* check validate negotiate info response matches what we got earlier */
@@ -1853,8 +1857,12 @@ SMB2_ioctl(const unsigned int xid, struc
 	 * than one credit. Windows typically sets this smaller, but for some
 	 * ioctls it may be useful to allow server to send more. No point
 	 * limiting what the server can send as long as fits in one credit
+	 * Unfortunately - we can not handle more than CIFS_MAX_MSG_SIZE
+	 * (by default, note that it can be overridden to make max larger)
+	 * in responses (except for read responses which can be bigger.
+	 * We may want to bump this limit up
 	 */
-	req->MaxOutputResponse = cpu_to_le32(0xFF00); /* < 64K uses 1 credit */
+	req->MaxOutputResponse = cpu_to_le32(CIFSMaxBufSize);
 
 	if (is_fsctl)
 		req->Flags = cpu_to_le32(SMB2_0_IOCTL_IS_FSCTL);
author maintainer
#69 lore raw

PATCH 72/114 cifs: fix leak in FSCTL_ENUM_SNAPS response handling

In reply to Greg Kroah-Hartman

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

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

From: David Disseldorp <[email protected]>

commit 0e5c795592930d51fd30d53a2e7b73cba022a29b upstream.

The server may respond with success, and an output buffer less than sizeof(struct smb_snapshot_array) in length. Do not leak the output buffer in this case.

Fixes 834170c85978 ("Enable previous version support")
---
 fs/cifs/smb2ops.c |    1 +
 1 file changed, 1 insertion(+)
fs/cifs/smb2ops.c +1 -0
@@ -942,6 +942,7 @@ smb3_enum_snapshots(const unsigned int x
 		}
 		if (snapshot_in.snapshot_array_size < sizeof(struct smb_snapshot_array)) {
 			rc = -ERANGE;
+			kfree(retbuf);
 			return rc;
 		}
 
author maintainer
#70 lore raw

PATCH 73/114 cifs: fix CIFS_ENUMERATE_SNAPSHOTS oops

In reply to Greg Kroah-Hartman

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

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

From: David Disseldorp <[email protected]>

commit 6026685de33b0db5b2b6b0e9b41b3a1a3261033c upstream.

As with 618763958b22, an open directory may have a NULL private_data pointer prior to readdir. CIFS_ENUMERATE_SNAPSHOTS must check for this before dereference.

Fixes 834170c85978 ("Enable previous version support")
---
 fs/cifs/ioctl.c |    2 ++
 1 file changed, 2 insertions(+)
fs/cifs/ioctl.c +2 -0
@@ -213,6 +213,8 @@ long cifs_ioctl(struct file *filep, unsi
 			rc = smb_mnt_get_fsinfo(xid, tcon, (void __user *)arg);
 			break;
 		case CIFS_ENUMERATE_SNAPSHOTS:
+			if (pSMBFile == NULL)
+				break;
 			if (arg == 0) {
 				rc = -EINVAL;
 				goto cifs_ioc_exit;
author maintainer
#71 lore raw

PATCH 74/114 CIFS: fix oplock break deadlocks

In reply to Greg Kroah-Hartman

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

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

From: Rabin Vincent <[email protected]>

commit 3998e6b87d4258a70df358296d6f1c7234012bfe upstream.

When the final cifsFileInfo_put() is called from cifsiod and an oplock break work is queued, lockdep complains loudly:

=============================================
[ INFO: possible recursive locking detected ]
4.11.0+ #21 Not tainted
---------------------------------------------
kworker/0:2/78 is trying to acquire lock:
("cifsiod"){++++.+}, at: flush_work+0x215/0x350

but task is already holding lock:
("cifsiod"){++++.+}, at: process_one_work+0x255/0x8e0

other info that might help us debug this:

  Possible unsafe locking scenario:
        CPU0
        ----

lock("cifsiod");
lock("cifsiod");

*** DEADLOCK ***

May be due to missing lock nesting notation

2 locks held by kworker/0:2/78:
#0: ("cifsiod"){++++.+}, at: process_one_work+0x255/0x8e0 #1: ((&wdata->work)){+.+...}, at: process_one_work+0x255/0x8e0

 stack backtrace:
 CPU: 0 PID: 78 Comm: kworker/0:2 Not tainted 4.11.0+ #21
 Workqueue: cifsiod cifs_writev_complete
 Call Trace:
  dump_stack+0x85/0xc2
  __lock_acquire+0x17dd/0x2260
  ? match_held_lock+0x20/0x2b0
  ? trace_hardirqs_off_caller+0x86/0x130
  ? mark_lock+0xa6/0x920
  lock_acquire+0xcc/0x260
  ? lock_acquire+0xcc/0x260
  ? flush_work+0x215/0x350
  flush_work+0x236/0x350
  ? flush_work+0x215/0x350
  ? destroy_worker+0x170/0x170
  __cancel_work_timer+0x17d/0x210
  ? ___preempt_schedule+0x16/0x18
  cancel_work_sync+0x10/0x20
  cifsFileInfo_put+0x338/0x7f0
  cifs_writedata_release+0x2a/0x40
  ? cifs_writedata_release+0x2a/0x40
  cifs_writev_complete+0x29d/0x850
  ? preempt_count_sub+0x18/0xd0
  process_one_work+0x304/0x8e0
  worker_thread+0x9b/0x6a0
  kthread+0x1b2/0x200
  ? process_one_work+0x8e0/0x8e0
  ? kthread_create_on_node+0x40/0x40
  ret_from_fork+0x31/0x40

This is a real warning. Since the oplock is queued on the same workqueue this can deadlock if there is only one worker thread active for the workqueue (which will be the case during memory pressure when the rescuer thread is handling it).

Furthermore, there is at least one other kind of hang possible due to the oplock break handling if there is only worker. (This can be reproduced without introducing memory pressure by having passing 1 for the max_active parameter of cifsiod.) cifs_oplock_break() can wait indefintely in the filemap_fdatawait() while the cifs_writev_complete() work is blocked:

sysrq: SysRq : Show Blocked State
task PC stack pid father
kworker/0:1 D 0 16 2 0x00000000

 Workqueue: cifsiod cifs_oplock_break
 Call Trace:
  __schedule+0x562/0xf40
  ? mark_held_locks+0x4a/0xb0
  schedule+0x57/0xe0
  io_schedule+0x21/0x50
  wait_on_page_bit+0x143/0x190
  ? add_to_page_cache_lru+0x150/0x150
  __filemap_fdatawait_range+0x134/0x190
  ? do_writepages+0x51/0x70
  filemap_fdatawait_range+0x14/0x30
  filemap_fdatawait+0x3b/0x40
  cifs_oplock_break+0x651/0x710
  ? preempt_count_sub+0x18/0xd0
  process_one_work+0x304/0x8e0
  worker_thread+0x9b/0x6a0
  kthread+0x1b2/0x200
  ? process_one_work+0x8e0/0x8e0
  ? kthread_create_on_node+0x40/0x40
  ret_from_fork+0x31/0x40
 dd              D    0   683    171 0x00000000
 Call Trace:
  __schedule+0x562/0xf40
  ? mark_held_locks+0x29/0xb0
  schedule+0x57/0xe0
  io_schedule+0x21/0x50
  wait_on_page_bit+0x143/0x190
  ? add_to_page_cache_lru+0x150/0x150
  __filemap_fdatawait_range+0x134/0x190
  ? do_writepages+0x51/0x70
  filemap_fdatawait_range+0x14/0x30
  filemap_fdatawait+0x3b/0x40
  filemap_write_and_wait+0x4e/0x70
  cifs_flush+0x6a/0xb0
  filp_close+0x52/0xa0
  __close_fd+0xdc/0x150
  SyS_close+0x33/0x60
  entry_SYSCALL_64_fastpath+0x1f/0xbe

 Showing all locks held in the system:
 2 locks held by kworker/0:1/16:
  #0:  ("cifsiod"){.+.+.+}, at: process_one_work+0x255/0x8e0
  #1:  ((&cfile->oplock_break)){+.+.+.}, at: process_one_work+0x255/0x8e0

Showing busy workqueues and worker pools:
workqueue cifsiod: flags=0xc
pwq 0: cpus=0 node=0 flags=0x0 nice=0 active=1/1
in-flight: 16:cifs_oplock_break
delayed: cifs_writev_complete, cifs_echo_request
pool 0: cpus=0 node=0 flags=0x0 nice=0 hung=0s workers=3 idle: 750 3

Fix these problems by creating a a new workqueue (with a rescuer) for the oplock break work.

---
 fs/cifs/cifsfs.c   |   15 +++++++++++++--
 fs/cifs/cifsglob.h |    1 +
 fs/cifs/misc.c     |    2 +-
 fs/cifs/smb2misc.c |    5 +++--
 4 files changed, 18 insertions(+), 5 deletions(-)
fs/cifs/cifsfs.c +13 -2
@@ -87,6 +87,7 @@ extern mempool_t *cifs_req_poolp;
 extern mempool_t *cifs_mid_poolp;
 
 struct workqueue_struct	*cifsiod_wq;
+struct workqueue_struct	*cifsoplockd_wq;
 __u32 cifs_lock_secret;
 
 /*
@@ -1369,9 +1370,16 @@ init_cifs(void)
 		goto out_clean_proc;
 	}
 
+	cifsoplockd_wq = alloc_workqueue("cifsoplockd",
+					 WQ_FREEZABLE|WQ_MEM_RECLAIM, 0);
+	if (!cifsoplockd_wq) {
+		rc = -ENOMEM;
+		goto out_destroy_cifsiod_wq;
+	}
+
 	rc = cifs_fscache_register();
 	if (rc)
-		goto out_destroy_wq;
+		goto out_destroy_cifsoplockd_wq;
 
 	rc = cifs_init_inodecache();
 	if (rc)
@@ -1419,7 +1427,9 @@ out_destroy_inodecache:
 	cifs_destroy_inodecache();
 out_unreg_fscache:
 	cifs_fscache_unregister();
-out_destroy_wq:
+out_destroy_cifsoplockd_wq:
+	destroy_workqueue(cifsoplockd_wq);
+out_destroy_cifsiod_wq:
 	destroy_workqueue(cifsiod_wq);
 out_clean_proc:
 	cifs_proc_clean();
@@ -1442,6 +1452,7 @@ exit_cifs(void)
 	cifs_destroy_mids();
 	cifs_destroy_inodecache();
 	cifs_fscache_unregister();
+	destroy_workqueue(cifsoplockd_wq);
 	destroy_workqueue(cifsiod_wq);
 	cifs_proc_clean();
 }
fs/cifs/cifsglob.h +1 -0
@@ -1683,6 +1683,7 @@ void cifs_oplock_break(struct work_struc
 
 extern const struct slow_work_ops cifs_oplock_break_ops;
 extern struct workqueue_struct *cifsiod_wq;
+extern struct workqueue_struct *cifsoplockd_wq;
 extern __u32 cifs_lock_secret;
 
 extern mempool_t *cifs_mid_poolp;
fs/cifs/misc.c +1 -1
@@ -492,7 +492,7 @@ is_valid_oplock_break(char *buffer, stru
 					   CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2,
 					   &pCifsInode->flags);
 
-				queue_work(cifsiod_wq,
+				queue_work(cifsoplockd_wq,
 					   &netfile->oplock_break);
 				netfile->oplock_break_cancelled = false;
 
fs/cifs/smb2misc.c +3 -2
@@ -499,7 +499,7 @@ smb2_tcon_has_lease(struct cifs_tcon *tc
 		else
 			cfile->oplock_break_cancelled = true;
 
-		queue_work(cifsiod_wq, &cfile->oplock_break);
+		queue_work(cifsoplockd_wq, &cfile->oplock_break);
 		kfree(lw);
 		return true;
 	}
@@ -643,7 +643,8 @@ smb2_is_valid_oplock_break(char *buffer,
 					   CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2,
 					   &cinode->flags);
 				spin_unlock(&cfile->file_info_lock);
-				queue_work(cifsiod_wq, &cfile->oplock_break);
+				queue_work(cifsoplockd_wq,
+					   &cfile->oplock_break);
 
 				spin_unlock(&tcon->open_file_lock);
 				spin_unlock(&cifs_tcp_ses_lock);
author maintainer
#72 lore raw

PATCH 75/114 cifs: fix CIFS_IOC_GET_MNT_INFO oops

In reply to Greg Kroah-Hartman

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

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

From: David Disseldorp <[email protected]>

commit d8a6e505d6bba2250852fbc1c1c86fe68aaf9af3 upstream.

An open directory may have a NULL private_data pointer prior to readdir.

Fixes 0de1f4c6f6c0 ("Add way to query server fs info for smb3")
---
 fs/cifs/ioctl.c |    2 ++
 1 file changed, 2 insertions(+)
fs/cifs/ioctl.c +2 -0
@@ -209,6 +209,8 @@ long cifs_ioctl(struct file *filep, unsi
 				rc = -EOPNOTSUPP;
 			break;
 		case CIFS_IOC_GET_MNT_INFO:
+			if (pSMBFile == NULL)
+				break;
 			tcon = tlink_tcon(pSMBFile->tlink);
 			rc = smb_mnt_get_fsinfo(xid, tcon, (void __user *)arg);
 			break;
author maintainer
#73 lore raw

PATCH 77/114 ovl: do not set overlay.opaque on non-dir create

In reply to Greg Kroah-Hartman

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

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

From: Amir Goldstein <[email protected]>

commit 4a99f3c83dc493c8ea84693d78cd792839c8aa64 upstream.

The optimization for opaque dir create was wrongly being applied also to non-dir create.

Fixes 97c684cc9110 ("ovl: create directories inside merged parent opaque")
---
 fs/overlayfs/dir.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/overlayfs/dir.c +1 -1
@@ -210,7 +210,7 @@ static int ovl_create_upper(struct dentr
 	if (err)
 		goto out_dput;
 
-	if (ovl_type_merge(dentry->d_parent)) {
+	if (ovl_type_merge(dentry->d_parent) && d_is_dir(newdentry)) {
 		/* Setting opaque here is just an optimization, allow to fail */
 		ovl_set_opaque(dentry, newdentry);
 	}
author maintainer
#74 lore raw

PATCH 78/114 padata: free correct variable

In reply to Greg Kroah-Hartman

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

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

From: Jason A. Donenfeld <[email protected]>

commit 07a77929ba672d93642a56dc2255dd21e6e2290b upstream.

The author meant to free the variable that was just allocated, instead of the one that failed to be allocated, but made a simple typo. This patch rectifies that.

---
 kernel/padata.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/padata.c +1 -1
@@ -354,7 +354,7 @@ static int padata_setup_cpumasks(struct
 
 	cpumask_and(pd->cpumask.pcpu, pcpumask, cpu_online_mask);
 	if (!alloc_cpumask_var(&pd->cpumask.cbcpu, GFP_KERNEL)) {
-		free_cpumask_var(pd->cpumask.cbcpu);
+		free_cpumask_var(pd->cpumask.pcpu);
 		return -ENOMEM;
 	}
 
author maintainer
#75 lore raw

PATCH 79/114 md/raid1: avoid reusing a resync bio after error handling.

In reply to Greg Kroah-Hartman

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

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

From: NeilBrown <[email protected]>

commit 0c9d5b127f695818c2c5a3868c1f28ca2969e905 upstream.

fix_sync_read_error() modifies a bio on a newly faulty device by setting bi_end_io to end_sync_write.
This ensure that put_buf() will still call rdev_dec_pending() as required, but makes sure that subsequent code in fix_sync_read_error() doesn't try to read from the device.

Unfortunately this interacts badly with sync_request_write() which assumes that any bio with bi_end_io set to non-NULL other than end_sync_read is safe to write to.

As the device is now faulty it doesn't make sense to write. As the bio was recently used for a read, it is "dirty" and not suitable for immediate submission.
In particular, ->bi_next might be non-NULL, which will cause generic_make_request() to complain.

Break this interaction by refusing to write to devices which are marked as Faulty.

Reported-and-tested-by Michael Wang <[email protected]>
Fixes 2e52d449bcec ("md/raid1: add failfast handling for reads.")
---
 drivers/md/raid1.c |    2 ++
 1 file changed, 2 insertions(+)
drivers/md/raid1.c +2 -0
@@ -2222,6 +2222,8 @@ static void sync_request_write(struct md
 		     (i == r1_bio->read_disk ||
 		      !test_bit(MD_RECOVERY_SYNC, &mddev->recovery))))
 			continue;
+		if (test_bit(Faulty, &conf->mirrors[i].rdev->flags))
+			continue;
 
 		bio_set_op_attrs(wbio, REQ_OP_WRITE, 0);
 		if (test_bit(FailFast, &conf->mirrors[i].rdev->flags))
author maintainer
#76 lore raw

PATCH 80/114 device-dax: fix cdev leak

In reply to Greg Kroah-Hartman

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

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

From: Dan Williams <[email protected]>

commit ed01e50acdd3e4a640cf9ebd28a7e810c3ceca97 upstream.

If device_add() fails, cleanup the cdev. Otherwise, we leak a kobj_map() with a stale device number.

As Jason points out, there is a small possibility that userspace has opened and mapped the device in the time between cdev_add() and the device_add() failure. We need a new kill_dax_dev() helper to invalidate any established mappings.

---
 drivers/dax/dax.c |   15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)
drivers/dax/dax.c +11 -4
@@ -703,13 +703,10 @@ static void dax_dev_release(struct devic
 	kfree(dax_dev);
 }
 
-static void unregister_dax_dev(void *dev)
+static void kill_dax_dev(struct dax_dev *dax_dev)
 {
-	struct dax_dev *dax_dev = to_dax_dev(dev);
 	struct cdev *cdev = &dax_dev->cdev;
 
-	dev_dbg(dev, "%s\n", __func__);
-
 	/*
 	 * Note, rcu is not protecting the liveness of dax_dev, rcu is
 	 * ensuring that any fault handlers that might have seen
@@ -721,6 +718,15 @@ static void unregister_dax_dev(void *dev
 	synchronize_srcu(&dax_srcu);
 	unmap_mapping_range(dax_dev->inode->i_mapping, 0, 0, 1);
 	cdev_del(cdev);
+}
+
+static void unregister_dax_dev(void *dev)
+{
+	struct dax_dev *dax_dev = to_dax_dev(dev);
+
+	dev_dbg(dev, "%s\n", __func__);
+
+	kill_dax_dev(dax_dev);
 	device_unregister(dev);
 }
 
@@ -797,6 +803,7 @@ struct dax_dev *devm_create_dax_dev(stru
 	dev_set_name(dev, "dax%d.%d", dax_region->id, dax_dev->id);
 	rc = device_add(dev);
 	if (rc) {
+		kill_dax_dev(dax_dev);
 		put_device(dev);
 		return ERR_PTR(rc);
 	}
author maintainer
#77 lore raw

PATCH 81/114 device-dax: fix sysfs attribute deadlock

In reply to Greg Kroah-Hartman

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

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

From: Dan Williams <[email protected]>

commit 565851c972b50612f3a4542e26879ffb3e906fc2 upstream.

Usage of device_lock() for dax_region attributes is unnecessary and deadlock prone. It's unnecessary because the order of registration / un-registration guarantees that drvdata is always valid. It's deadlock prone because it sets up this situation:

ndctl D 0 2170 2082 0x00000000

 Call Trace:
  __schedule+0x31f/0x980
  schedule+0x3d/0x90
  schedule_preempt_disabled+0x15/0x20
  __mutex_lock+0x402/0x980
  ? __mutex_lock+0x158/0x980
  ? align_show+0x2b/0x80 [dax]
  ? kernfs_seq_start+0x2f/0x90
  mutex_lock_nested+0x1b/0x20
  align_show+0x2b/0x80 [dax]
  dev_attr_show+0x20/0x50

ndctl D 0 2186 2079 0x00000000

 Call Trace:
  __schedule+0x31f/0x980
  schedule+0x3d/0x90
  __kernfs_remove+0x1f6/0x340
  ? kernfs_remove_by_name_ns+0x45/0xa0
  ? remove_wait_queue+0x70/0x70
  kernfs_remove_by_name_ns+0x45/0xa0
  remove_files.isra.1+0x35/0x70
  sysfs_remove_group+0x44/0x90
  sysfs_remove_groups+0x2e/0x50
  dax_region_unregister+0x25/0x40 [dax]
  devm_action_release+0xf/0x20
  release_nodes+0x16d/0x2b0
  devres_release_all+0x3c/0x60
  device_release_driver_internal+0x17d/0x220
  device_release_driver+0x12/0x20
  unbind_store+0x112/0x160

ndctl/2170 is trying to acquire the device_lock() to read an attribute, and ndctl/2186 is holding the device_lock() while trying to drain all active attribute readers.

Thanks to Yi Zhang for the reproduction script.

Fixes d7fe1a67f658 ("dax: add region 'id', 'size', and 'align' attributes")
---
 drivers/dax/dax.c |   40 ++++++++++++----------------------------
 1 file changed, 12 insertions(+), 28 deletions(-)
drivers/dax/dax.c +12 -28
@@ -77,36 +77,27 @@ struct dax_dev {
 	struct resource res[0];
 };
 
+/*
+ * Rely on the fact that drvdata is set before the attributes are
+ * registered, and that the attributes are unregistered before drvdata
+ * is cleared to assume that drvdata is always valid.
+ */
 static ssize_t id_show(struct device *dev,
 		struct device_attribute *attr, char *buf)
 {
-	struct dax_region *dax_region;
-	ssize_t rc = -ENXIO;
+	struct dax_region *dax_region = dev_get_drvdata(dev);
 
-	device_lock(dev);
-	dax_region = dev_get_drvdata(dev);
-	if (dax_region)
-		rc = sprintf(buf, "%d\n", dax_region->id);
-	device_unlock(dev);
-
-	return rc;
+	return sprintf(buf, "%d\n", dax_region->id);
 }
 static DEVICE_ATTR_RO(id);
 
 static ssize_t region_size_show(struct device *dev,
 		struct device_attribute *attr, char *buf)
 {
-	struct dax_region *dax_region;
-	ssize_t rc = -ENXIO;
-
-	device_lock(dev);
-	dax_region = dev_get_drvdata(dev);
-	if (dax_region)
-		rc = sprintf(buf, "%llu\n", (unsigned long long)
-				resource_size(&dax_region->res));
-	device_unlock(dev);
+	struct dax_region *dax_region = dev_get_drvdata(dev);
 
-	return rc;
+	return sprintf(buf, "%llu\n", (unsigned long long)
+			resource_size(&dax_region->res));
 }
 static struct device_attribute dev_attr_region_size = __ATTR(size, 0444,
 		region_size_show, NULL);
@@ -114,16 +105,9 @@ static struct device_attribute dev_attr_
 static ssize_t align_show(struct device *dev,
 		struct device_attribute *attr, char *buf)
 {
-	struct dax_region *dax_region;
-	ssize_t rc = -ENXIO;
-
-	device_lock(dev);
-	dax_region = dev_get_drvdata(dev);
-	if (dax_region)
-		rc = sprintf(buf, "%u\n", dax_region->align);
-	device_unlock(dev);
+	struct dax_region *dax_region = dev_get_drvdata(dev);
 
-	return rc;
+	return sprintf(buf, "%u\n", dax_region->align);
 }
 static DEVICE_ATTR_RO(align);
 
author maintainer
#78 lore raw

PATCH 82/114 dax: prevent invalidation of mapped DAX entries

In reply to Greg Kroah-Hartman

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

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

From: Ross Zwisler <[email protected]>

commit 4636e70bb0a8b871998b6841a2e4b205cf2bc863 upstream.

Patch series "mm,dax: Fix data corruption due to mmap inconsistency", v4.

This series fixes data corruption that can happen for DAX mounts when page faults race with write(2) and as a result page tables get out of sync with block mappings in the filesystem and thus data seen through mmap is different from data seen through read(2).

The series passes testing with t_mmap_stale test program from Ross and also other mmap related tests on DAX filesystem.

This patch (of 4):

dax_invalidate_mapping_entry() currently removes DAX exceptional entries only if they are clean and unlocked. This is done via:

invalidate_mapping_pages()
invalidate_exceptional_entry()
dax_invalidate_mapping_entry()

However, for page cache pages removed in invalidate_mapping_pages() there is an additional criteria which is that the page must not be mapped. This is noted in the comments above invalidate_mapping_pages() and is checked in invalidate_inode_page().

For DAX entries this means that we can can end up in a situation where a DAX exceptional entry, either a huge zero page or a regular DAX entry, could end up mapped but without an associated radix tree entry. This is inconsistent with the rest of the DAX code and with what happens in the page cache case.

We aren't able to unmap the DAX exceptional entry because according to its comments invalidate_mapping_pages() isn't allowed to block, and unmap_mapping_range() takes a write lock on the mapping->i_mmap_rwsem.

Since we essentially never have unmapped DAX entries to evict from the radix tree, just remove dax_invalidate_mapping_entry().

Fixes c6dcf52c23d2 ("mm: Invalidate DAX radix tree entries only if appropriate")
Cc Dan Williams <[email protected]>
---
 fs/dax.c            |   29 -----------------------------
 include/linux/dax.h |    1 -
 mm/truncate.c       |    9 +++------
 3 files changed, 3 insertions(+), 36 deletions(-)
fs/dax.c +0 -29
@@ -507,35 +507,6 @@ int dax_delete_mapping_entry(struct addr
 }
 
 /*
- * Invalidate exceptional DAX entry if easily possible. This handles DAX
- * entries for invalidate_inode_pages() so we evict the entry only if we can
- * do so without blocking.
- */
-int dax_invalidate_mapping_entry(struct address_space *mapping, pgoff_t index)
-{
-	int ret = 0;
-	void *entry, **slot;
-	struct radix_tree_root *page_tree = &mapping->page_tree;
-
-	spin_lock_irq(&mapping->tree_lock);
-	entry = __radix_tree_lookup(page_tree, index, NULL, &slot);
-	if (!entry || !radix_tree_exceptional_entry(entry) ||
-	    slot_locked(mapping, slot))
-		goto out;
-	if (radix_tree_tag_get(page_tree, index, PAGECACHE_TAG_DIRTY) ||
-	    radix_tree_tag_get(page_tree, index, PAGECACHE_TAG_TOWRITE))
-		goto out;
-	radix_tree_delete(page_tree, index);
-	mapping->nrexceptional--;
-	ret = 1;
-out:
-	spin_unlock_irq(&mapping->tree_lock);
-	if (ret)
-		dax_wake_mapping_entry_waiter(mapping, index, entry, true);
-	return ret;
-}
-
-/*
  * Invalidate exceptional DAX entry if it is clean.
  */
 int dax_invalidate_mapping_entry_sync(struct address_space *mapping,
include/linux/dax.h +0 -1
@@ -41,7 +41,6 @@ ssize_t dax_iomap_rw(struct kiocb *iocb,
 int dax_iomap_fault(struct vm_fault *vmf, enum page_entry_size pe_size,
 		    const struct iomap_ops *ops);
 int dax_delete_mapping_entry(struct address_space *mapping, pgoff_t index);
-int dax_invalidate_mapping_entry(struct address_space *mapping, pgoff_t index);
 int dax_invalidate_mapping_entry_sync(struct address_space *mapping,
 				      pgoff_t index);
 void dax_wake_mapping_entry_waiter(struct address_space *mapping,
mm/truncate.c +3 -6
@@ -67,17 +67,14 @@ static void truncate_exceptional_entry(s
 
 /*
  * Invalidate exceptional entry if easily possible. This handles exceptional
- * entries for invalidate_inode_pages() so for DAX it evicts only unlocked and
- * clean entries.
+ * entries for invalidate_inode_pages().
  */
 static int invalidate_exceptional_entry(struct address_space *mapping,
 					pgoff_t index, void *entry)
 {
-	/* Handled by shmem itself */
-	if (shmem_mapping(mapping))
+	/* Handled by shmem itself, or for DAX we do nothing. */
+	if (shmem_mapping(mapping) || dax_mapping(mapping))
 		return 1;
-	if (dax_mapping(mapping))
-		return dax_invalidate_mapping_entry(mapping, index);
 	clear_shadow_entry(mapping, index, entry);
 	return 1;
 }
author maintainer
#79 lore raw

PATCH 83/114 mm: fix data corruption due to stale mmap reads

In reply to Greg Kroah-Hartman

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

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

From: Jan Kara <[email protected]>

commit cd656375f94632d7b5af57bf67b7b5c0270c591c upstream.

Currently, we didn't invalidate page tables during invalidate_inode_pages2() for DAX. That could result in e.g. 2MiB zero page being mapped into page tables while there were already underlying blocks allocated and thus data seen through mmap were different from data seen by read(2). The following sequence reproduces the problem:

- open an mmap over a 2MiB hole

- read from a 2MiB hole, faulting in a 2MiB zero page

- write to the hole with write(3p). The write succeeds but we incorrectly leave the 2MiB zero page mapping intact.

- via the mmap, read the data that was just written. Since the zero page mapping is still intact we read back zeroes instead of the new data.

Fix the problem by unconditionally calling invalidate_inode_pages2_range() in dax_iomap_actor() for new block allocations and by properly invalidating page tables in invalidate_inode_pages2_range() for DAX mappings.

---
 fs/dax.c      |    2 +-
 mm/truncate.c |   11 +++++++++++
 2 files changed, 12 insertions(+), 1 deletion(-)
fs/dax.c +1 -1
@@ -1003,7 +1003,7 @@ dax_iomap_actor(struct inode *inode, lof
 	 * into page tables. We have to tear down these mappings so that data
 	 * written by write(2) is visible in mmap.
 	 */
-	if ((iomap->flags & IOMAP_F_NEW) && inode->i_mapping->nrpages) {
+	if (iomap->flags & IOMAP_F_NEW) {
 		invalidate_inode_pages2_range(inode->i_mapping,
 					      pos >> PAGE_SHIFT,
 					      (end - 1) >> PAGE_SHIFT);
mm/truncate.c +11 -0
@@ -683,6 +683,17 @@ int invalidate_inode_pages2_range(struct
 		cond_resched();
 		index++;
 	}
+	/*
+	 * For DAX we invalidate page tables after invalidating radix tree.  We
+	 * could invalidate page tables while invalidating each entry however
+	 * that would be expensive. And doing range unmapping before doesn't
+	 * work as we have no cheap way to find whether radix tree entry didn't
+	 * get remapped later.
+	 */
+	if (dax_mapping(mapping)) {
+		unmap_mapping_range(mapping, (loff_t)start << PAGE_SHIFT,
+				    (loff_t)(end - start + 1) << PAGE_SHIFT, 0);
+	}
 	cleancache_invalidate_inode(mapping);
 	return ret;
 }
author maintainer
#80 lore raw

PATCH 84/114 ext4: return to starting transaction in ext4_dax_huge_fault()

In reply to Greg Kroah-Hartman

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

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

From: Jan Kara <[email protected]>

commit fb26a1cbed8c90025572d48bc9eabe59f7571e88 upstream.

DAX will return to locking exceptional entry before mapping blocks for a page fault to fix possible races with concurrent writes. To avoid lock inversion between exceptional entry lock and transaction start, start the transaction already in ext4_dax_huge_fault().

---
 fs/ext4/file.c |   21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)
fs/ext4/file.c +17 -4
@@ -257,6 +257,7 @@ static int ext4_dax_huge_fault(struct vm
 		enum page_entry_size pe_size)
 {
 	int result;
+	handle_t *handle = NULL;
 	struct inode *inode = file_inode(vmf->vma->vm_file);
 	struct super_block *sb = inode->i_sb;
 	bool write = vmf->flags & FAULT_FLAG_WRITE;
@@ -264,12 +265,24 @@ static int ext4_dax_huge_fault(struct vm
 	if (write) {
 		sb_start_pagefault(sb);
 		file_update_time(vmf->vma->vm_file);
+		down_read(&EXT4_I(inode)->i_mmap_sem);
+		handle = ext4_journal_start_sb(sb, EXT4_HT_WRITE_PAGE,
+					       EXT4_DATA_TRANS_BLOCKS(sb));
+	} else {
+		down_read(&EXT4_I(inode)->i_mmap_sem);
 	}
-	down_read(&EXT4_I(inode)->i_mmap_sem);
-	result = dax_iomap_fault(vmf, pe_size, &ext4_iomap_ops);
-	up_read(&EXT4_I(inode)->i_mmap_sem);
-	if (write)
+	if (!IS_ERR(handle))
+		result = dax_iomap_fault(vmf, pe_size, &ext4_iomap_ops);
+	else
+		result = VM_FAULT_SIGBUS;
+	if (write) {
+		if (!IS_ERR(handle))
+			ext4_journal_stop(handle);
+		up_read(&EXT4_I(inode)->i_mmap_sem);
 		sb_end_pagefault(sb);
+	} else {
+		up_read(&EXT4_I(inode)->i_mmap_sem);
+	}
 
 	return result;
 }
author maintainer
#81 lore raw

PATCH 85/114 dax: fix PMD data corruption when fault races with write

In reply to Greg Kroah-Hartman

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

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

From: Ross Zwisler <[email protected]>

commit 876f29460cbd4086b43475890c1bf2488fa11d40 upstream.

This is based on a patch from Jan Kara that fixed the equivalent race in the DAX PTE fault path.

Currently DAX PMD read fault can race with write(2) in the following way:

CPU1 - write(2) CPU2 - read fault

                                dax_iomap_pmd_fault()
                                  ->iomap_begin() - sees hole

dax_iomap_rw()
iomap_apply()
->iomap_begin - allocates blocks
dax_iomap_actor()
invalidate_inode_pages2_range()
- there's nothing to invalidate

grab_mapping_entry()
- we add huge zero page to the radix tree and map it to page tables

The result is that hole page is mapped into page tables (and thus zeros are seen in mmap) while file has data written in that place.

Fix the problem by locking exception entry before mapping blocks for the fault. That way we are sure invalidate_inode_pages2_range() call for racing write will either block on entry lock waiting for the fault to finish (and unmap stale page tables after that) or read fault will see already allocated blocks by write(2).

Fixes 9f141d6ef6258 ("dax: Call ->iomap_begin without entry lock during dax fault")
Cc Dan Williams <[email protected]>
---
 fs/dax.c |   28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)
fs/dax.c +14 -14
@@ -1353,6 +1353,16 @@ static int dax_iomap_pmd_fault(struct vm
 		goto fallback;
 
 	/*
+	 * grab_mapping_entry() will make sure we get a 2M empty entry, a DAX
+	 * PMD or a HZP entry.  If it can't (because a 4k page is already in
+	 * the tree, for instance), it will return -EEXIST and we just fall
+	 * back to 4k entries.
+	 */
+	entry = grab_mapping_entry(mapping, pgoff, RADIX_DAX_PMD);
+	if (IS_ERR(entry))
+		goto fallback;
+
+	/*
 	 * Note that we don't use iomap_apply here.  We aren't doing I/O, only
 	 * setting up a mapping, so really we're using iomap_begin() as a way
 	 * to look up our filesystem block.
@@ -1360,21 +1370,11 @@ static int dax_iomap_pmd_fault(struct vm
 	pos = (loff_t)pgoff << PAGE_SHIFT;
 	error = ops->iomap_begin(inode, pos, PMD_SIZE, iomap_flags, &iomap);
 	if (error)
-		goto fallback;
+		goto unlock_entry;
 
 	if (iomap.offset + iomap.length < pos + PMD_SIZE)
 		goto finish_iomap;
 
-	/*
-	 * grab_mapping_entry() will make sure we get a 2M empty entry, a DAX
-	 * PMD or a HZP entry.  If it can't (because a 4k page is already in
-	 * the tree, for instance), it will return -EEXIST and we just fall
-	 * back to 4k entries.
-	 */
-	entry = grab_mapping_entry(mapping, pgoff, RADIX_DAX_PMD);
-	if (IS_ERR(entry))
-		goto finish_iomap;
-
 	switch (iomap.type) {
 	case IOMAP_MAPPED:
 		result = dax_pmd_insert_mapping(vmf, &iomap, pos, &entry);
@@ -1382,7 +1382,7 @@ static int dax_iomap_pmd_fault(struct vm
 	case IOMAP_UNWRITTEN:
 	case IOMAP_HOLE:
 		if (WARN_ON_ONCE(write))
-			goto unlock_entry;
+			break;
 		result = dax_pmd_load_hole(vmf, &iomap, &entry);
 		break;
 	default:
@@ -1390,8 +1390,6 @@ static int dax_iomap_pmd_fault(struct vm
 		break;
 	}
 
- unlock_entry:
-	put_locked_mapping_entry(mapping, pgoff, entry);
  finish_iomap:
 	if (ops->iomap_end) {
 		int copied = PMD_SIZE;
@@ -1407,6 +1405,8 @@ static int dax_iomap_pmd_fault(struct vm
 		ops->iomap_end(inode, pos, PMD_SIZE, copied, iomap_flags,
 				&iomap);
 	}
+ unlock_entry:
+	put_locked_mapping_entry(mapping, pgoff, entry);
  fallback:
 	if (result == VM_FAULT_FALLBACK) {
 		split_huge_pmd(vma, vmf->pmd, vmf->address);
author maintainer
#82 lore raw

PATCH 86/114 f2fs: fix wrong max cost initialization

In reply to Greg Kroah-Hartman

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

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

From: Jaegeuk Kim <[email protected]>

commit c541a51b8ce81d003b02ed67ad3604a2e6220e3e upstream.

This patch fixes missing increased max cost caused by a patch that we increased cose of data segments in greedy algorithm.

Fixes b9cd20619 "f2fs: node segment is prior to data segment selected victim"
---
 fs/f2fs/gc.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/f2fs/gc.c +1 -1
@@ -182,7 +182,7 @@ static unsigned int get_max_cost(struct
 	if (p->alloc_mode == SSR)
 		return sbi->blocks_per_seg;
 	if (p->gc_mode == GC_GREEDY)
-		return sbi->blocks_per_seg * p->ofs_unit;
+		return 2 * sbi->blocks_per_seg * p->ofs_unit;
 	else if (p->gc_mode == GC_CB)
 		return UINT_MAX;
 	else /* No other gc_mode */
author maintainer
#83 lore raw

PATCH 87/114 Revert "f2fs: put allocate_segment after refresh_sit_entry"

In reply to Greg Kroah-Hartman

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

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

From: Jaegeuk Kim <[email protected]>

commit c6f82fe90d7458e5fa190a6820bfc24f96b0de4e upstream.

This reverts commit 3436c4bdb30de421d46f58c9174669fbcfd40ce0.

This makes a leak to register dirty segments. I reproduced the issue by modified postmark which injects a lot of file create/delete/update and finally triggers huge number of SSR allocations.

[Jaegeuk Kim: Change missing incorrect comment]
---
 fs/f2fs/segment.c |    9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)
fs/f2fs/segment.c +4 -5
@@ -1788,15 +1788,14 @@ void allocate_data_block(struct f2fs_sb_
 
 	stat_inc_block_count(sbi, curseg);
 
+	if (!__has_curseg_space(sbi, type))
+		sit_i->s_ops->allocate_segment(sbi, type, false);
 	/*
-	 * SIT information should be updated before segment allocation,
-	 * since SSR needs latest valid block information.
+	 * SIT information should be updated after segment allocation,
+	 * since we need to keep dirty segments precisely under SSR.
 	 */
 	refresh_sit_entry(sbi, old_blkaddr, *new_blkaddr);
 
-	if (!__has_curseg_space(sbi, type))
-		sit_i->s_ops->allocate_segment(sbi, type, false);
-
 	mutex_unlock(&sit_i->sentry_lock);
 
 	if (page && IS_NODESEG(type))
author maintainer
#84 lore raw

PATCH 88/114 f2fs: fix fs corruption due to zero inode page

In reply to Greg Kroah-Hartman

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

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

From: Jaegeuk Kim <[email protected]>

commit 9bb02c3627f46e50246bf7ab957b56ffbef623cb upstream.

This patch fixes the following scenario.

- f2fs_create/f2fs_mkdir - write_checkpoint
- f2fs_mark_inode_dirty_sync - block_operations
- f2fs_lock_all
- f2fs_sync_inode_meta
- f2fs_unlock_all
- sync_inode_metadata
- f2fs_lock_op
- f2fs_write_inode
- update_inode_page
- get_node_page return -ENOENT
- new_inode_page
- fill_node_footer
- f2fs_mark_inode_dirty_sync
- ...
- f2fs_unlock_op
- f2fs_inode_synced
- f2fs_lock_all
- do_checkpoint

In this checkpoint, we can get an inode page which contains zeros having valid node footer only.

---
 fs/f2fs/inode.c |    2 +-
 fs/f2fs/namei.c |   20 ++++++++++----------
 2 files changed, 11 insertions(+), 11 deletions(-)
fs/f2fs/inode.c +1 -1
@@ -316,7 +316,6 @@ retry:
 		} else if (err != -ENOENT) {
 			f2fs_stop_checkpoint(sbi, false);
 		}
-		f2fs_inode_synced(inode);
 		return 0;
 	}
 	ret = update_inode(inode, node_page);
@@ -448,6 +447,7 @@ void handle_failed_inode(struct inode *i
 	 * in a panic when flushing dirty inodes in gdirty_list.
 	 */
 	update_inode_page(inode);
+	f2fs_inode_synced(inode);
 
 	/* don't make bad inode, since it becomes a regular file. */
 	unlock_new_inode(inode);
fs/f2fs/namei.c +10 -10
@@ -148,8 +148,6 @@ static int f2fs_create(struct inode *dir
 	inode->i_mapping->a_ops = &f2fs_dblock_aops;
 	ino = inode->i_ino;
 
-	f2fs_balance_fs(sbi, true);
-
 	f2fs_lock_op(sbi);
 	err = f2fs_add_link(dentry, inode);
 	if (err)
@@ -163,6 +161,8 @@ static int f2fs_create(struct inode *dir
 
 	if (IS_DIRSYNC(dir))
 		f2fs_sync_fs(sbi->sb, 1);
+
+	f2fs_balance_fs(sbi, true);
 	return 0;
 out:
 	handle_failed_inode(inode);
@@ -423,8 +423,6 @@ static int f2fs_symlink(struct inode *di
 	inode_nohighmem(inode);
 	inode->i_mapping->a_ops = &f2fs_dblock_aops;
 
-	f2fs_balance_fs(sbi, true);
-
 	f2fs_lock_op(sbi);
 	err = f2fs_add_link(dentry, inode);
 	if (err)
@@ -487,6 +485,8 @@ err_out:
 	}
 
 	kfree(sd);
+
+	f2fs_balance_fs(sbi, true);
 	return err;
 out:
 	handle_failed_inode(inode);
@@ -508,8 +508,6 @@ static int f2fs_mkdir(struct inode *dir,
 	inode->i_mapping->a_ops = &f2fs_dblock_aops;
 	mapping_set_gfp_mask(inode->i_mapping, GFP_F2FS_HIGH_ZERO);
 
-	f2fs_balance_fs(sbi, true);
-
 	set_inode_flag(inode, FI_INC_LINK);
 	f2fs_lock_op(sbi);
 	err = f2fs_add_link(dentry, inode);
@@ -524,6 +522,8 @@ static int f2fs_mkdir(struct inode *dir,
 
 	if (IS_DIRSYNC(dir))
 		f2fs_sync_fs(sbi->sb, 1);
+
+	f2fs_balance_fs(sbi, true);
 	return 0;
 
 out_fail:
@@ -554,8 +554,6 @@ static int f2fs_mknod(struct inode *dir,
 	init_special_inode(inode, inode->i_mode, rdev);
 	inode->i_op = &f2fs_special_inode_operations;
 
-	f2fs_balance_fs(sbi, true);
-
 	f2fs_lock_op(sbi);
 	err = f2fs_add_link(dentry, inode);
 	if (err)
@@ -569,6 +567,8 @@ static int f2fs_mknod(struct inode *dir,
 
 	if (IS_DIRSYNC(dir))
 		f2fs_sync_fs(sbi->sb, 1);
+
+	f2fs_balance_fs(sbi, true);
 	return 0;
 out:
 	handle_failed_inode(inode);
@@ -595,8 +595,6 @@ static int __f2fs_tmpfile(struct inode *
 		inode->i_mapping->a_ops = &f2fs_dblock_aops;
 	}
 
-	f2fs_balance_fs(sbi, true);
-
 	f2fs_lock_op(sbi);
 	err = acquire_orphan_inode(sbi);
 	if (err)
@@ -622,6 +620,8 @@ static int __f2fs_tmpfile(struct inode *
 	/* link_count was changed by d_tmpfile as well. */
 	f2fs_unlock_op(sbi);
 	unlock_new_inode(inode);
+
+	f2fs_balance_fs(sbi, true);
 	return 0;
 
 release_out:
author maintainer
#85 lore raw

PATCH 89/114 f2fs: fix multiple f2fs_add_link() having same name for inline dentry

In reply to Greg Kroah-Hartman

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

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

From: Sheng Yong <[email protected]>

commit d3bb910c15d75ee3340311c64a1c05985bb663a3 upstream.

Commit 88c5c13a5027 (f2fs: fix multiple f2fs_add_link() calls having same name) does not cover the scenario where inline dentry is enabled. In that case, F2FS_I(dir)->task will be NULL, and __f2fs_add_link will lookup dentries one more time.

This patch fixes it by moving the assigment of current task to a upper level to cover both normal and inline dentry.

Fixes 88c5c13a5027 (f2fs: fix multiple f2fs_add_link() calls having same name)
---
 fs/f2fs/dir.c |   13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)
fs/f2fs/dir.c +6 -7
@@ -207,13 +207,9 @@ static struct f2fs_dir_entry *find_in_le
 		f2fs_put_page(dentry_page, 0);
 	}
 
-	/* This is to increase the speed of f2fs_create */
-	if (!de && room) {
-		F2FS_I(dir)->task = current;
-		if (F2FS_I(dir)->chash != namehash) {
-			F2FS_I(dir)->chash = namehash;
-			F2FS_I(dir)->clevel = level;
-		}
+	if (!de && room && F2FS_I(dir)->chash != namehash) {
+		F2FS_I(dir)->chash = namehash;
+		F2FS_I(dir)->clevel = level;
 	}
 
 	return de;
@@ -254,6 +250,9 @@ struct f2fs_dir_entry *__f2fs_find_entry
 			break;
 	}
 out:
+	/* This is to increase the speed of f2fs_create */
+	if (!de)
+		F2FS_I(dir)->task = current;
 	return de;
 }
 
author maintainer
#86 lore raw

PATCH 90/114 f2fs: check entire encrypted bigname when finding a dentry

In reply to Greg Kroah-Hartman

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

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

From: Jaegeuk Kim <[email protected]>

commit 6332cd32c8290a80e929fc044dc5bdba77396e33 upstream.

If user has no key under an encrypted dir, fscrypt gives digested dentries. Previously, when looking up a dentry, f2fs only checks its hash value with first 4 bytes of the digested dentry, which didn't handle hash collisions fully. This patch enhances to check entire dentry bytes likewise ext4.

Eric reported how to reproduce this issue by:

 # seq -f "edir/abcdefghijklmnopqrstuvwxyz012345%.0f" 100000 | xargs touch
 # find edir -type f | xargs stat -c %i | sort | uniq | wc -l
100000
 # sync
 # echo 3 > /proc/sys/vm/drop_caches
 # keyctl new_session
 # find edir -type f | xargs stat -c %i | sort | uniq | wc -l
99999

(fixed f2fs_dentry_hash() to work even when the hash is 0)

---
 fs/f2fs/dir.c    |   37 +++++++++++++++++++++----------------
 fs/f2fs/f2fs.h   |    3 ++-
 fs/f2fs/hash.c   |    7 ++++++-
 fs/f2fs/inline.c |    4 ++--
 4 files changed, 31 insertions(+), 20 deletions(-)
fs/f2fs/dir.c +21 -16
@@ -130,19 +130,29 @@ struct f2fs_dir_entry *find_target_dentr
 			continue;
 		}
 
-		/* encrypted case */
+		if (de->hash_code != namehash)
+			goto not_match;
+
 		de_name.name = d->filename[bit_pos];
 		de_name.len = le16_to_cpu(de->name_len);
 
-		/* show encrypted name */
-		if (fname->hash) {
-			if (de->hash_code == cpu_to_le32(fname->hash))
-				goto found;
-		} else if (de_name.len == name->len &&
-			de->hash_code == namehash &&
-			!memcmp(de_name.name, name->name, name->len))
+#ifdef CONFIG_F2FS_FS_ENCRYPTION
+		if (unlikely(!name->name)) {
+			if (fname->usr_fname->name[0] == '_') {
+				if (de_name.len >= 16 &&
+					!memcmp(de_name.name + de_name.len - 16,
+						fname->crypto_buf.name + 8, 16))
+					goto found;
+				goto not_match;
+			}
+			name->name = fname->crypto_buf.name;
+			name->len = fname->crypto_buf.len;
+		}
+#endif
+		if (de_name.len == name->len &&
+				!memcmp(de_name.name, name->name, name->len))
 			goto found;
-
+not_match:
 		if (max_slots && max_len > *max_slots)
 			*max_slots = max_len;
 		max_len = 0;
@@ -170,12 +180,7 @@ static struct f2fs_dir_entry *find_in_le
 	struct f2fs_dir_entry *de = NULL;
 	bool room = false;
 	int max_slots;
-	f2fs_hash_t namehash;
-
-	if(fname->hash)
-		namehash = cpu_to_le32(fname->hash);
-	else
-		namehash = f2fs_dentry_hash(&name);
+	f2fs_hash_t namehash = f2fs_dentry_hash(&name, fname);
 
 	nbucket = dir_buckets(level, F2FS_I(dir)->i_dir_level);
 	nblock = bucket_blocks(level);
@@ -541,7 +546,7 @@ int f2fs_add_regular_entry(struct inode
 
 	level = 0;
 	slots = GET_DENTRY_SLOTS(new_name->len);
-	dentry_hash = f2fs_dentry_hash(new_name);
+	dentry_hash = f2fs_dentry_hash(new_name, NULL);
 
 	current_depth = F2FS_I(dir)->i_current_depth;
 	if (F2FS_I(dir)->chash == dentry_hash) {
fs/f2fs/f2fs.h +2 -1
@@ -2133,7 +2133,8 @@ int sanity_check_ckpt(struct f2fs_sb_inf
 /*
  * hash.c
  */
-f2fs_hash_t f2fs_dentry_hash(const struct qstr *name_info);
+f2fs_hash_t f2fs_dentry_hash(const struct qstr *name_info,
+				struct fscrypt_name *fname);
 
 /*
  * node.c
fs/f2fs/hash.c +6 -1
@@ -70,7 +70,8 @@ static void str2hashbuf(const unsigned c
 		*buf++ = pad;
 }
 
-f2fs_hash_t f2fs_dentry_hash(const struct qstr *name_info)
+f2fs_hash_t f2fs_dentry_hash(const struct qstr *name_info,
+				struct fscrypt_name *fname)
 {
 	__u32 hash;
 	f2fs_hash_t f2fs_hash;
@@ -79,6 +80,10 @@ f2fs_hash_t f2fs_dentry_hash(const struc
 	const unsigned char *name = name_info->name;
 	size_t len = name_info->len;
 
+	/* encrypted bigname case */
+	if (fname && !fname->disk_name.name)
+		return cpu_to_le32(fname->hash);
+
 	if (is_dot_dotdot(name_info))
 		return 0;
 
fs/f2fs/inline.c +2 -2
@@ -296,7 +296,7 @@ struct f2fs_dir_entry *find_in_inline_di
 		return NULL;
 	}
 
-	namehash = f2fs_dentry_hash(&name);
+	namehash = f2fs_dentry_hash(&name, fname);
 
 	inline_dentry = inline_data_addr(ipage);
 
@@ -533,7 +533,7 @@ int f2fs_add_inline_entry(struct inode *
 
 	f2fs_wait_on_page_writeback(ipage, NODE, true);
 
-	name_hash = f2fs_dentry_hash(new_name);
+	name_hash = f2fs_dentry_hash(new_name, NULL);
 	make_dentry_ptr(NULL, &d, (void *)dentry_blk, 2);
 	f2fs_update_dentry(ino, mode, &d, new_name, name_hash, bit_pos);
 
author maintainer
#87 lore raw

PATCH 91/114 f2fs: Make flush bios explicitely sync

In reply to Greg Kroah-Hartman

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

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

From: Jan Kara <[email protected]>

commit 3adc5fcb7edf5f8dfe8d37dcb50ba6b30077c905 upstream.

Commit b685d3d65ac7 "block: treat REQ_FUA and REQ_PREFLUSH as synchronous" removed REQ_SYNC flag from WRITE_{FUA|PREFLUSH|...} definitions. generic_make_request_checks() however strips REQ_FUA and REQ_PREFLUSH flags from a bio when the storage doesn't report volatile write cache and thus write effectively becomes asynchronous which can lead to performance regressions.

Fix the problem by making sure all bios which are synchronous are properly marked with REQ_SYNC.

Fixes b685d3d65ac791406e0dfd8779cc9b3707fea5a3
CC Jaegeuk Kim <[email protected]>
---
 fs/f2fs/data.c    |    2 +-
 fs/f2fs/segment.c |    2 +-
 fs/f2fs/super.c   |    2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)
fs/f2fs/data.c +1 -1
@@ -309,7 +309,7 @@ static void __f2fs_submit_merged_bio(str
 	if (type >= META_FLUSH) {
 		io->fio.type = META_FLUSH;
 		io->fio.op = REQ_OP_WRITE;
-		io->fio.op_flags = REQ_META | REQ_PRIO;
+		io->fio.op_flags = REQ_META | REQ_PRIO | REQ_SYNC;
 		if (!test_opt(sbi, NOBARRIER))
 			io->fio.op_flags |= REQ_PREFLUSH | REQ_FUA;
 	}
fs/f2fs/segment.c +1 -1
@@ -416,7 +416,7 @@ static int __submit_flush_wait(struct bl
 	struct bio *bio = f2fs_bio_alloc(0);
 	int ret;
 
-	bio->bi_opf = REQ_OP_WRITE | REQ_PREFLUSH;
+	bio->bi_opf = REQ_OP_WRITE | REQ_SYNC | REQ_PREFLUSH;
 	bio->bi_bdev = bdev;
 	ret = submit_bio_wait(bio);
 	bio_put(bio);
fs/f2fs/super.c +1 -1
@@ -1307,7 +1307,7 @@ static int __f2fs_commit_super(struct bu
 	unlock_buffer(bh);
 
 	/* it's rare case, we can do fua all the time */
-	return __sync_dirty_buffer(bh, REQ_PREFLUSH | REQ_FUA);
+	return __sync_dirty_buffer(bh, REQ_SYNC | REQ_PREFLUSH | REQ_FUA);
 }
 
 static inline bool sanity_check_area_boundary(struct f2fs_sb_info *sbi,
author maintainer
#88 lore raw

PATCH 92/114 initramfs: Always do fput() and load modules after rootfs populate

In reply to Greg Kroah-Hartman

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

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

From: Stafford Horne <[email protected]>

commit 17a9be31747535184f2af156b1f080ec4c92a952 upstream.

In OpenRISC we do not have a bootloader passed initrd, but the built in initramfs does contain the /init and other binaries, including modules. The previous commit 08865514805d2 ("initramfs: finish fput() before accessing any binary from initramfs") made a change to only call fput() if the bootloader initrd was available, this caused intermittent crashes for OpenRISC.

This patch changes the fput() to happen unconditionally if any rootfs is loaded. Also, I added some comments to make it a bit more clear why we call unpack_to_rootfs() multiple times.

Fixes 08865514805d2 ("initramfs: finish fput() before accessing any binary from initramfs")
Cc Lokesh Vutla <[email protected]>
Cc Al Viro <[email protected]>
---
 init/initramfs.c |   15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)
init/initramfs.c +9 -6
@@ -608,9 +608,11 @@ static void __init clean_rootfs(void)
 
 static int __init populate_rootfs(void)
 {
+	/* Load the built in initramfs */
 	char *err = unpack_to_rootfs(__initramfs_start, __initramfs_size);
 	if (err)
 		panic("%s", err); /* Failed to decompress INTERNAL initramfs */
+	/* If available load the bootloader supplied initrd */
 	if (initrd_start) {
 #ifdef CONFIG_BLK_DEV_RAM
 		int fd;
@@ -648,13 +650,14 @@ static int __init populate_rootfs(void)
 			printk(KERN_EMERG "Initramfs unpacking failed: %s\n", err);
 		free_initrd();
 #endif
-		flush_delayed_fput();
-		/*
-		 * Try loading default modules from initramfs.  This gives
-		 * us a chance to load before device_initcalls.
-		 */
-		load_default_modules();
 	}
+	flush_delayed_fput();
+	/*
+	 * Try loading default modules from initramfs.  This gives
+	 * us a chance to load before device_initcalls.
+	 */
+	load_default_modules();
+
 	return 0;
 }
 rootfs_initcall(populate_rootfs);
author maintainer
#89 lore raw

PATCH 94/114 fscrypt: fix context consistency check when key(s) unavailable

In reply to Greg Kroah-Hartman

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

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

From: Eric Biggers <[email protected]>

commit 272f98f6846277378e1758a49a49d7bf39343c02 upstream.

To mitigate some types of offline attacks, filesystem encryption is designed to enforce that all files in an encrypted directory tree use the same encryption policy (i.e. the same encryption context excluding the nonce). However, the fscrypt_has_permitted_context() function which enforces this relies on comparing struct fscrypt_info's, which are only available when we have the encryption keys. This can cause two incorrect behaviors:

1. If we have the parent directory's key but not the child's key, or vice versa, then fscrypt_has_permitted_context() returned false, causing applications to see EPERM or ENOKEY. This is incorrect if the encryption contexts are in fact consistent. Although we'd normally have either both keys or neither key in that case since the master_key_descriptors would be the same, this is not guaranteed because keys can be added or removed from keyrings at any time.

2. If we have neither the parent's key nor the child's key, then fscrypt_has_permitted_context() returned true, causing applications to see no error (or else an error for some other reason). This is incorrect if the encryption contexts are in fact inconsistent, since in that case we should deny access.

To fix this, retrieve and compare the fscrypt_contexts if we are unable to set up both fscrypt_infos.

While this slightly hurts performance when accessing an encrypted directory tree without the key, this isn't a case we really need to be optimizing for; access *with* the key is much more important. Furthermore, the performance hit is barely noticeable given that we are already retrieving the fscrypt_context and doing two keyring searches in fscrypt_get_encryption_info(). If we ever actually wanted to optimize this case we might start by caching the fscrypt_contexts.

---
 fs/crypto/policy.c |   87 +++++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 68 insertions(+), 19 deletions(-)
fs/crypto/policy.c +68 -19
@@ -143,27 +143,61 @@ int fscrypt_ioctl_get_policy(struct file
 }
 EXPORT_SYMBOL(fscrypt_ioctl_get_policy);
 
+/**
+ * fscrypt_has_permitted_context() - is a file's encryption policy permitted
+ *				     within its directory?
+ *
+ * @parent: inode for parent directory
+ * @child: inode for file being looked up, opened, or linked into @parent
+ *
+ * Filesystems must call this before permitting access to an inode in a
+ * situation where the parent directory is encrypted (either before allowing
+ * ->lookup() to succeed, or for a regular file before allowing it to be opened)
+ * and before any operation that involves linking an inode into an encrypted
+ * directory, including link, rename, and cross rename.  It enforces the
+ * constraint that within a given encrypted directory tree, all files use the
+ * same encryption policy.  The pre-access check is needed to detect potentially
+ * malicious offline violations of this constraint, while the link and rename
+ * checks are needed to prevent online violations of this constraint.
+ *
+ * Return: 1 if permitted, 0 if forbidden.  If forbidden, the caller must fail
+ * the filesystem operation with EPERM.
+ */
 int fscrypt_has_permitted_context(struct inode *parent, struct inode *child)
 {
-	struct fscrypt_info *parent_ci, *child_ci;
+	const struct fscrypt_operations *cops = parent->i_sb->s_cop;
+	const struct fscrypt_info *parent_ci, *child_ci;
+	struct fscrypt_context parent_ctx, child_ctx;
 	int res;
 
-	if ((parent == NULL) || (child == NULL)) {
-		printk(KERN_ERR	"parent %p child %p\n", parent, child);
-		BUG_ON(1);
-	}
-
 	/* No restrictions on file types which are never encrypted */
 	if (!S_ISREG(child->i_mode) && !S_ISDIR(child->i_mode) &&
 	    !S_ISLNK(child->i_mode))
 		return 1;
 
-	/* no restrictions if the parent directory is not encrypted */
-	if (!parent->i_sb->s_cop->is_encrypted(parent))
+	/* No restrictions if the parent directory is unencrypted */
+	if (!cops->is_encrypted(parent))
 		return 1;
-	/* if the child directory is not encrypted, this is always a problem */
-	if (!parent->i_sb->s_cop->is_encrypted(child))
+
+	/* Encrypted directories must not contain unencrypted files */
+	if (!cops->is_encrypted(child))
 		return 0;
+
+	/*
+	 * Both parent and child are encrypted, so verify they use the same
+	 * encryption policy.  Compare the fscrypt_info structs if the keys are
+	 * available, otherwise retrieve and compare the fscrypt_contexts.
+	 *
+	 * Note that the fscrypt_context retrieval will be required frequently
+	 * when accessing an encrypted directory tree without the key.
+	 * Performance-wise this is not a big deal because we already don't
+	 * really optimize for file access without the key (to the extent that
+	 * such access is even possible), given that any attempted access
+	 * already causes a fscrypt_context retrieval and keyring search.
+	 *
+	 * In any case, if an unexpected error occurs, fall back to "forbidden".
+	 */
+
 	res = fscrypt_get_encryption_info(parent);
 	if (res)
 		return 0;
@@ -172,17 +206,32 @@ int fscrypt_has_permitted_context(struct
 		return 0;
 	parent_ci = parent->i_crypt_info;
 	child_ci = child->i_crypt_info;
-	if (!parent_ci && !child_ci)
-		return 1;
-	if (!parent_ci || !child_ci)
+
+	if (parent_ci && child_ci) {
+		return memcmp(parent_ci->ci_master_key, child_ci->ci_master_key,
+			      FS_KEY_DESCRIPTOR_SIZE) == 0 &&
+			(parent_ci->ci_data_mode == child_ci->ci_data_mode) &&
+			(parent_ci->ci_filename_mode ==
+			 child_ci->ci_filename_mode) &&
+			(parent_ci->ci_flags == child_ci->ci_flags);
+	}
+
+	res = cops->get_context(parent, &parent_ctx, sizeof(parent_ctx));
+	if (res != sizeof(parent_ctx))
+		return 0;
+
+	res = cops->get_context(child, &child_ctx, sizeof(child_ctx));
+	if (res != sizeof(child_ctx))
 		return 0;
 
-	return (memcmp(parent_ci->ci_master_key,
-			child_ci->ci_master_key,
-			FS_KEY_DESCRIPTOR_SIZE) == 0 &&
-		(parent_ci->ci_data_mode == child_ci->ci_data_mode) &&
-		(parent_ci->ci_filename_mode == child_ci->ci_filename_mode) &&
-		(parent_ci->ci_flags == child_ci->ci_flags));
+	return memcmp(parent_ctx.master_key_descriptor,
+		      child_ctx.master_key_descriptor,
+		      FS_KEY_DESCRIPTOR_SIZE) == 0 &&
+		(parent_ctx.contents_encryption_mode ==
+		 child_ctx.contents_encryption_mode) &&
+		(parent_ctx.filenames_encryption_mode ==
+		 child_ctx.filenames_encryption_mode) &&
+		(parent_ctx.flags == child_ctx.flags);
 }
 EXPORT_SYMBOL(fscrypt_has_permitted_context);
 
author maintainer
#90 lore raw

PATCH 95/114 fscrypt: avoid collisions when presenting long encrypted filenames

In reply to Greg Kroah-Hartman

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

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

From: Eric Biggers <[email protected]>

commit 6b06cdee81d68a8a829ad8e8d0f31d6836744af9 upstream.

When accessing an encrypted directory without the key, userspace must operate on filenames derived from the ciphertext names, which contain arbitrary bytes. Since we must support filenames as long as NAME_MAX, we can't always just base64-encode the ciphertext, since that may make it too long. Currently, this is solved by presenting long names in an abbreviated form containing any needed filesystem-specific hashes (e.g. to identify a directory block), then the last 16 bytes of ciphertext. This needs to be sufficient to identify the actual name on lookup.

However, there is a bug. It seems to have been assumed that due to the use of a CBC (ciphertext block chaining)-based encryption mode, the last 16 bytes (i.e. the AES block size) of ciphertext would depend on the full plaintext, preventing collisions. However, we actually use CBC with ciphertext stealing (CTS), which handles the last two blocks specially, causing them to appear "flipped". Thus, it's actually the second-to-last block which depends on the full plaintext.

This caused long filenames that differ only near the end of their plaintexts to, when observed without the key, point to the wrong inode and be undeletable. For example, with ext4:

    # echo pass | e4crypt add_key -p 16 edir/
    # seq -f "edir/abcdefghijklmnopqrstuvwxyz012345%.0f" 100000 | xargs touch
    # find edir/ -type f | xargs stat -c %i | sort | uniq | wc -l
    100000
    # sync
    # echo 3 > /proc/sys/vm/drop_caches
    # keyctl new_session
    # find edir/ -type f | xargs stat -c %i | sort | uniq | wc -l
    2004
    # rm -rf edir/
    rm: cannot remove 'edir/_A7nNFi3rhkEQlJ6P,hdzluhODKOeWx5V': Structure needs cleaning
    ...

To fix this, when presenting long encrypted filenames, encode the second-to-last block of ciphertext rather than the last 16 bytes.

Although it would be nice to solve this without depending on a specific encryption mode, that would mean doing a cryptographic hash like SHA-256 which would be much less efficient. This way is sufficient for now, and it's still compatible with encryption modes like HEH which are strong pseudorandom permutations. Also, changing the presented names is still allowed at any time because they are only provided to allow applications to do things like delete encrypted directories. They're not designed to be used to persistently identify files --- which would be hard to do anyway, given that they're encrypted after all.

For ease of backports, this patch only makes the minimal fix to both ext4 and f2fs. It leaves ubifs as-is, since ubifs doesn't compare the ciphertext block yet. Follow-on patches will clean things up properly and make the filesystems use a shared helper function.

Fixes 5de0b4d0cd15 ("ext4 crypto: simplify and speed up filename encryption")
---
 fs/crypto/fname.c |    2 +-
 fs/ext4/namei.c   |    4 ++--
 fs/f2fs/dir.c     |    4 ++--
 3 files changed, 5 insertions(+), 5 deletions(-)
fs/crypto/fname.c +1 -1
@@ -300,7 +300,7 @@ int fscrypt_fname_disk_to_usr(struct ino
 	} else {
 		memset(buf, 0, 8);
 	}
-	memcpy(buf + 8, iname->name + iname->len - 16, 16);
+	memcpy(buf + 8, iname->name + ((iname->len - 17) & ~15), 16);
 	oname->name[0] = '_';
 	oname->len = 1 + digest_encode(buf, 24, oname->name + 1);
 	return 0;
fs/ext4/namei.c +2 -2
@@ -1255,9 +1255,9 @@ static inline int ext4_match(struct ext4
 	if (unlikely(!name)) {
 		if (fname->usr_fname->name[0] == '_') {
 			int ret;
-			if (de->name_len < 16)
+			if (de->name_len <= 32)
 				return 0;
-			ret = memcmp(de->name + de->name_len - 16,
+			ret = memcmp(de->name + ((de->name_len - 17) & ~15),
 				     fname->crypto_buf.name + 8, 16);
 			return (ret == 0) ? 1 : 0;
 		}
fs/f2fs/dir.c +2 -2
@@ -139,8 +139,8 @@ struct f2fs_dir_entry *find_target_dentr
 #ifdef CONFIG_F2FS_FS_ENCRYPTION
 		if (unlikely(!name->name)) {
 			if (fname->usr_fname->name[0] == '_') {
-				if (de_name.len >= 16 &&
-					!memcmp(de_name.name + de_name.len - 16,
+				if (de_name.len > 32 &&
+					!memcmp(de_name.name + ((de_name.len - 17) & ~15),
 						fname->crypto_buf.name + 8, 16))
 					goto found;
 				goto not_match;
author maintainer
#91 lore raw

PATCH 96/114 serial: samsung: Use right device for DMA-mapping calls

In reply to Greg Kroah-Hartman

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

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

From: Marek Szyprowski <[email protected]>

commit 768d64f491a530062ddad50e016fb27125f8bd7c upstream.

Driver should provide its own struct device for all DMA-mapping calls instead of extracting device pointer from DMA engine channel. Although this is harmless from the driver operation perspective on ARM architecture, it is always good to use the DMA mapping API in a proper way. This patch fixes following DMA API debug warning:

WARNING: CPU: 0 PID: 0 at lib/dma-debug.c:1241 check_sync+0x520/0x9f4
samsung-uart 12c20000.serial: DMA-API: device driver tries to sync DMA memory it has not allocated [device address=0x000000006df0f580] [size=64 bytes]
Modules linked in:
CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.11.0-rc1-00137-g07ca963 #51
Hardware name: SAMSUNG EXYNOS (Flattened Device Tree)
[<c011aaa4>] (unwind_backtrace) from [<c01127c0>] (show_stack+0x20/0x24)
[<c01127c0>] (show_stack) from [<c06ba5d8>] (dump_stack+0x84/0xa0)
[<c06ba5d8>] (dump_stack) from [<c0139528>] (__warn+0x14c/0x180)
[<c0139528>] (__warn) from [<c01395a4>] (warn_slowpath_fmt+0x48/0x50)
[<c01395a4>] (warn_slowpath_fmt) from [<c0729058>] (check_sync+0x520/0x9f4)
[<c0729058>] (check_sync) from [<c072967c>] (debug_dma_sync_single_for_device+0x88/0xc8)
[<c072967c>] (debug_dma_sync_single_for_device) from [<c0803c10>] (s3c24xx_serial_start_tx_dma+0x100/0x2f8)
[<c0803c10>] (s3c24xx_serial_start_tx_dma) from [<c0804338>] (s3c24xx_serial_tx_chars+0x198/0x33c)
---
 drivers/tty/serial/samsung.c |    9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)
drivers/tty/serial/samsung.c +4 -5
@@ -901,14 +901,13 @@ static int s3c24xx_serial_request_dma(st
 		return -ENOMEM;
 	}
 
-	dma->rx_addr = dma_map_single(dma->rx_chan->device->dev, dma->rx_buf,
+	dma->rx_addr = dma_map_single(p->port.dev, dma->rx_buf,
 				dma->rx_size, DMA_FROM_DEVICE);
 
 	spin_lock_irqsave(&p->port.lock, flags);
 
 	/* TX buffer */
-	dma->tx_addr = dma_map_single(dma->tx_chan->device->dev,
-				p->port.state->xmit.buf,
+	dma->tx_addr = dma_map_single(p->port.dev, p->port.state->xmit.buf,
 				UART_XMIT_SIZE, DMA_TO_DEVICE);
 
 	spin_unlock_irqrestore(&p->port.lock, flags);
@@ -922,7 +921,7 @@ static void s3c24xx_serial_release_dma(s
 
 	if (dma->rx_chan) {
 		dmaengine_terminate_all(dma->rx_chan);
-		dma_unmap_single(dma->rx_chan->device->dev, dma->rx_addr,
+		dma_unmap_single(p->port.dev, dma->rx_addr,
 				dma->rx_size, DMA_FROM_DEVICE);
 		kfree(dma->rx_buf);
 		dma_release_channel(dma->rx_chan);
@@ -931,7 +930,7 @@ static void s3c24xx_serial_release_dma(s
 
 	if (dma->tx_chan) {
 		dmaengine_terminate_all(dma->tx_chan);
-		dma_unmap_single(dma->tx_chan->device->dev, dma->tx_addr,
+		dma_unmap_single(p->port.dev, dma->tx_addr,
 				UART_XMIT_SIZE, DMA_TO_DEVICE);
 		dma_release_channel(dma->tx_chan);
 		dma->tx_chan = NULL;
author maintainer
#92 lore raw

PATCH 97/114 serial: samsung: Add missing checks for dma_map_single failure

In reply to Greg Kroah-Hartman

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

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

From: Marek Szyprowski <[email protected]>

commit 500fcc08a32bfd54f11951ba81530775df15c474 upstream.

This patch adds missing checks for dma_map_single() failure and proper error reporting. Although this issue was harmless on ARM architecture, it is always good to use the DMA mapping API in a proper way. This patch fixes the following DMA API debug warning:

WARNING: CPU: 1 PID: 3785 at lib/dma-debug.c:1171 check_unmap+0x8a0/0xf28
dma-pl330 121a0000.pdma: DMA-API: device driver failed to check map error[device address=0x000000006e0f9000] [size=4096 bytes] [mapped as single]
Modules linked in:
CPU: 1 PID: 3785 Comm: (agetty) Tainted: G        W       4.11.0-rc1-00137-g07ca963-dirty #59
Hardware name: SAMSUNG EXYNOS (Flattened Device Tree)
[<c011aaa4>] (unwind_backtrace) from [<c01127c0>] (show_stack+0x20/0x24)
[<c01127c0>] (show_stack) from [<c06ba5d8>] (dump_stack+0x84/0xa0)
[<c06ba5d8>] (dump_stack) from [<c0139528>] (__warn+0x14c/0x180)
[<c0139528>] (__warn) from [<c01395a4>] (warn_slowpath_fmt+0x48/0x50)
[<c01395a4>] (warn_slowpath_fmt) from [<c072a114>] (check_unmap+0x8a0/0xf28)
[<c072a114>] (check_unmap) from [<c072a834>] (debug_dma_unmap_page+0x98/0xc8)
[<c072a834>] (debug_dma_unmap_page) from [<c0803874>] (s3c24xx_serial_shutdown+0x314/0x52c)
[<c0803874>] (s3c24xx_serial_shutdown) from [<c07f5124>] (uart_port_shutdown+0x54/0x88)
[<c07f5124>] (uart_port_shutdown) from [<c07f522c>] (uart_shutdown+0xd4/0x110)
[<c07f522c>] (uart_shutdown) from [<c07f6a8c>] (uart_hangup+0x9c/0x208)
[<c07f6a8c>] (uart_hangup) from [<c07c426c>] (__tty_hangup+0x49c/0x634)
[<c07c426c>] (__tty_hangup) from [<c07c78ac>] (tty_ioctl+0xc88/0x16e4)
[<c07c78ac>] (tty_ioctl) from [<c03b5f2c>] (do_vfs_ioctl+0xc4/0xd10)
[<c03b5f2c>] (do_vfs_ioctl) from [<c03b6bf4>] (SyS_ioctl+0x7c/0x8c)
[<c03b6bf4>] (SyS_ioctl) from [<c010b4a0>] (ret_fast_syscall+0x0/0x3c)
Fixes 62c37eedb74c8 ("serial: samsung: add dma reqest/release functions")
---
 drivers/tty/serial/samsung.c |   31 ++++++++++++++++++++++++-------
 1 file changed, 24 insertions(+), 7 deletions(-)
drivers/tty/serial/samsung.c +24 -7
@@ -859,7 +859,7 @@ static void s3c24xx_serial_break_ctl(str
 static int s3c24xx_serial_request_dma(struct s3c24xx_uart_port *p)
 {
 	struct s3c24xx_uart_dma	*dma = p->dma;
-	unsigned long flags;
+	int ret;
 
 	/* Default slave configuration parameters */
 	dma->rx_conf.direction		= DMA_DEV_TO_MEM;
@@ -884,8 +884,8 @@ static int s3c24xx_serial_request_dma(st
 
 	dma->tx_chan = dma_request_chan(p->port.dev, "tx");
 	if (IS_ERR(dma->tx_chan)) {
-		dma_release_channel(dma->rx_chan);
-		return PTR_ERR(dma->tx_chan);
+		ret = PTR_ERR(dma->tx_chan);
+		goto err_release_rx;
 	}
 
 	dmaengine_slave_config(dma->tx_chan, &dma->tx_conf);
@@ -894,15 +894,17 @@ static int s3c24xx_serial_request_dma(st
 	dma->rx_size = PAGE_SIZE;
 
 	dma->rx_buf = kmalloc(dma->rx_size, GFP_KERNEL);
-
 	if (!dma->rx_buf) {
-		dma_release_channel(dma->rx_chan);
-		dma_release_channel(dma->tx_chan);
-		return -ENOMEM;
+		ret = -ENOMEM;
+		goto err_release_tx;
 	}
 
 	dma->rx_addr = dma_map_single(p->port.dev, dma->rx_buf,
 				dma->rx_size, DMA_FROM_DEVICE);
+	if (dma_mapping_error(p->port.dev, dma->rx_addr)) {
+		ret = -EIO;
+		goto err_free_rx;
+	}
 
 	spin_lock_irqsave(&p->port.lock, flags);
 
@@ -911,8 +913,23 @@ static int s3c24xx_serial_request_dma(st
 				UART_XMIT_SIZE, DMA_TO_DEVICE);
 
 	spin_unlock_irqrestore(&p->port.lock, flags);
+	if (dma_mapping_error(p->port.dev, dma->tx_addr)) {
+		ret = -EIO;
+		goto err_unmap_rx;
+	}
 
 	return 0;
+
+err_unmap_rx:
+	dma_unmap_single(p->port.dev, dma->rx_addr, dma->rx_size,
+			 DMA_FROM_DEVICE);
+err_free_rx:
+	kfree(dma->rx_buf);
+err_release_tx:
+	dma_release_channel(dma->tx_chan);
+err_release_rx:
+	dma_release_channel(dma->rx_chan);
+	return ret;
 }
 
 static void s3c24xx_serial_release_dma(struct s3c24xx_uart_port *p)
#93 lore raw

Re: [PATCH 4.11 097/114] serial: samsung: Add missing checks for dma_map_single failure

Quoted 48 lines · Greg Kroah-Hartman

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

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

From: Marek Szyprowski <[email protected]>

commit 500fcc08a32bfd54f11951ba81530775df15c474 upstream.

This patch adds missing checks for dma_map_single() failure and proper error reporting. Although this issue was harmless on ARM architecture, it is always good to use the DMA mapping API in a proper way. This patch fixes the following DMA API debug warning:

WARNING: CPU: 1 PID: 3785 at lib/dma-debug.c:1171 check_unmap+0x8a0/0xf28
dma-pl330 121a0000.pdma: DMA-API: device driver failed to check map error[device address=0x000000006e0f9000] [size=4096 bytes] [mapped as single]
Modules linked in:
CPU: 1 PID: 3785 Comm: (agetty) Tainted: G        W       4.11.0-rc1-00137-g07ca963-dirty #59
Hardware name: SAMSUNG EXYNOS (Flattened Device Tree)
[<c011aaa4>] (unwind_backtrace) from [<c01127c0>] (show_stack+0x20/0x24)
[<c01127c0>] (show_stack) from [<c06ba5d8>] (dump_stack+0x84/0xa0)
[<c06ba5d8>] (dump_stack) from [<c0139528>] (__warn+0x14c/0x180)
[<c0139528>] (__warn) from [<c01395a4>] (warn_slowpath_fmt+0x48/0x50)
[<c01395a4>] (warn_slowpath_fmt) from [<c072a114>] (check_unmap+0x8a0/0xf28)
[<c072a114>] (check_unmap) from [<c072a834>] (debug_dma_unmap_page+0x98/0xc8)
[<c072a834>] (debug_dma_unmap_page) from [<c0803874>] (s3c24xx_serial_shutdown+0x314/0x52c)
[<c0803874>] (s3c24xx_serial_shutdown) from [<c07f5124>] (uart_port_shutdown+0x54/0x88)
[<c07f5124>] (uart_port_shutdown) from [<c07f522c>] (uart_shutdown+0xd4/0x110)
[<c07f522c>] (uart_shutdown) from [<c07f6a8c>] (uart_hangup+0x9c/0x208)
[<c07f6a8c>] (uart_hangup) from [<c07c426c>] (__tty_hangup+0x49c/0x634)
[<c07c426c>] (__tty_hangup) from [<c07c78ac>] (tty_ioctl+0xc88/0x16e4)
[<c07c78ac>] (tty_ioctl) from [<c03b5f2c>] (do_vfs_ioctl+0xc4/0xd10)
[<c03b5f2c>] (do_vfs_ioctl) from [<c03b6bf4>] (SyS_ioctl+0x7c/0x8c)
[<c03b6bf4>] (SyS_ioctl) from [<c010b4a0>] (ret_fast_syscall+0x0/0x3c)
Fixes 62c37eedb74c8 ("serial: samsung: add dma reqest/release functions")
---
 drivers/tty/serial/samsung.c |   31 ++++++++++++++++++++++++-------
 1 file changed, 24 insertions(+), 7 deletions(-)

drivers/tty/serial/samsung.c static void s3c24xx_serial_break_ctl(str · line 862

Quoted 5 lines
drivers/tty/serial/samsung.c +1 -1
@@ -859,7 +859,7 @@ static void s3c24xx_serial_break_ctl(str
 static int s3c24xx_serial_request_dma(struct s3c24xx_uart_port *p)
 {
        struct s3c24xx_uart_dma *dma = p->dma;
-       unsigned long flags;
+       int ret;

This does not compile:
http://www.krzk.eu/#/builders/5/builds/225
It works fine in mainline because the patch 3/3 of the set was removing the user of the flags.

I'll send a fixup for stable.

BR,
Krzysztof

author maintainer
#94 lore raw

Re: [PATCH 4.11 097/114] serial: samsung: Add missing checks for dma_map_single failure

Quoted 61 lines · Krzysztof Kozlowski
Quoted 48 lines · Greg Kroah-Hartman

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

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

From: Marek Szyprowski <[email protected]>

commit 500fcc08a32bfd54f11951ba81530775df15c474 upstream.

This patch adds missing checks for dma_map_single() failure and proper error reporting. Although this issue was harmless on ARM architecture, it is always good to use the DMA mapping API in a proper way. This patch fixes the following DMA API debug warning:

WARNING: CPU: 1 PID: 3785 at lib/dma-debug.c:1171 check_unmap+0x8a0/0xf28
dma-pl330 121a0000.pdma: DMA-API: device driver failed to check map error[device address=0x000000006e0f9000] [size=4096 bytes] [mapped as single]
Modules linked in:
CPU: 1 PID: 3785 Comm: (agetty) Tainted: G        W       4.11.0-rc1-00137-g07ca963-dirty #59
Hardware name: SAMSUNG EXYNOS (Flattened Device Tree)
[<c011aaa4>] (unwind_backtrace) from [<c01127c0>] (show_stack+0x20/0x24)
[<c01127c0>] (show_stack) from [<c06ba5d8>] (dump_stack+0x84/0xa0)
[<c06ba5d8>] (dump_stack) from [<c0139528>] (__warn+0x14c/0x180)
[<c0139528>] (__warn) from [<c01395a4>] (warn_slowpath_fmt+0x48/0x50)
[<c01395a4>] (warn_slowpath_fmt) from [<c072a114>] (check_unmap+0x8a0/0xf28)
[<c072a114>] (check_unmap) from [<c072a834>] (debug_dma_unmap_page+0x98/0xc8)
[<c072a834>] (debug_dma_unmap_page) from [<c0803874>] (s3c24xx_serial_shutdown+0x314/0x52c)
[<c0803874>] (s3c24xx_serial_shutdown) from [<c07f5124>] (uart_port_shutdown+0x54/0x88)
[<c07f5124>] (uart_port_shutdown) from [<c07f522c>] (uart_shutdown+0xd4/0x110)
[<c07f522c>] (uart_shutdown) from [<c07f6a8c>] (uart_hangup+0x9c/0x208)
[<c07f6a8c>] (uart_hangup) from [<c07c426c>] (__tty_hangup+0x49c/0x634)
[<c07c426c>] (__tty_hangup) from [<c07c78ac>] (tty_ioctl+0xc88/0x16e4)
[<c07c78ac>] (tty_ioctl) from [<c03b5f2c>] (do_vfs_ioctl+0xc4/0xd10)
[<c03b5f2c>] (do_vfs_ioctl) from [<c03b6bf4>] (SyS_ioctl+0x7c/0x8c)
[<c03b6bf4>] (SyS_ioctl) from [<c010b4a0>] (ret_fast_syscall+0x0/0x3c)
Fixes 62c37eedb74c8 ("serial: samsung: add dma reqest/release functions")
---
 drivers/tty/serial/samsung.c |   31 ++++++++++++++++++++++++-------
 1 file changed, 24 insertions(+), 7 deletions(-)

drivers/tty/serial/samsung.c static void s3c24xx_serial_break_ctl(str · line 862

Quoted 5 lines
drivers/tty/serial/samsung.c +1 -1
@@ -859,7 +859,7 @@ static void s3c24xx_serial_break_ctl(str
 static int s3c24xx_serial_request_dma(struct s3c24xx_uart_port *p)
 {
        struct s3c24xx_uart_dma *dma = p->dma;
-       unsigned long flags;
+       int ret;

This does not compile:
http://www.krzk.eu/#/builders/5/builds/225
It works fine in mainline because the patch 3/3 of the set was removing the user of the flags.

Quoted 1 line

I'll send a fixup for stable.

Ah, thanks, I didn't notice that on my test builds here :(

greg k-h

author maintainer
#95 lore raw

PATCH 98/114 serial: omap: fix runtime-pm handling on unbind

In reply to Greg Kroah-Hartman

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

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

From: Johan Hovold <[email protected]>

commit 099bd73dc17ed77aa8c98323e043613b6e8f54fc upstream.

An unbalanced and misplaced synchronous put was used to suspend the device on driver unbind, something which with a likewise misplaced pm_runtime_disable leads to external aborts when an open port is being removed.

Unhandled fault: external abort on non-linefetch (0x1028) at 0xfa024010
...
[<c046e760>] (serial_omap_set_mctrl) from [<c046a064>] (uart_update_mctrl+0x50/0x60) [<c046a064>] (uart_update_mctrl) from [<c046a400>] (uart_shutdown+0xbc/0x138) [<c046a400>] (uart_shutdown) from [<c046bd2c>] (uart_hangup+0x94/0x190) [<c046bd2c>] (uart_hangup) from [<c045b760>] (__tty_hangup+0x404/0x41c) [<c045b760>] (__tty_hangup) from [<c045b794>] (tty_vhangup+0x1c/0x20) [<c045b794>] (tty_vhangup) from [<c046ccc8>] (uart_remove_one_port+0xec/0x260) [<c046ccc8>] (uart_remove_one_port) from [<c046ef4c>] (serial_omap_remove+0x40/0x60) [<c046ef4c>] (serial_omap_remove) from [<c04845e8>] (platform_drv_remove+0x34/0x4c)

Fix this up by resuming the device before deregistering the port and by suspending and disabling runtime pm only after the port has been removed.

Also make sure to disable autosuspend before disabling runtime pm so that the usage count is balanced and device actually suspended before returning.

Note that due to a negative autosuspend delay being set in probe, the unbalanced put would actually suspend the device on first driver unbind, while rebinding and again unbinding would result in a negative power.usage_count.

Fixes 7e9c8e7dbf3b ("serial: omap: make sure to suspend device before remove")
Cc Felipe Balbi <[email protected]>
Cc Santosh Shilimkar <[email protected]>
---
 drivers/tty/serial/omap-serial.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/tty/serial/omap-serial.c +5 -1
@@ -1780,9 +1780,13 @@ static int serial_omap_remove(struct pla
 {
 	struct uart_omap_port *up = platform_get_drvdata(dev);
 
+	pm_runtime_get_sync(up->dev);
+
+	uart_remove_one_port(&serial_omap_reg, &up->port);
+
+	pm_runtime_dont_use_autosuspend(up->dev);
 	pm_runtime_put_sync(up->dev);
 	pm_runtime_disable(up->dev);
-	uart_remove_one_port(&serial_omap_reg, &up->port);
 	pm_qos_remove_request(&up->pm_qos_request);
 	device_init_wakeup(&dev->dev, false);
 
author maintainer
#96 lore raw

PATCH 99/114 serial: omap: suspend device on probe errors

In reply to Greg Kroah-Hartman

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

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

From: Johan Hovold <[email protected]>

commit 77e6fe7fd2b7cba0bf2f2dc8cde51d7b9a35bf74 upstream.

Make sure to actually suspend the device before returning after a failed (or deferred) probe.

Note that autosuspend must be disabled before runtime pm is disabled in order to balance the usage count due to a negative autosuspend delay as well as to make the final put suspend the device synchronously.

Fixes 388bc2622680 ("omap-serial: Fix the error handling in the omap_serial probe")
Cc Shubhrajyoti D <[email protected]>
---
 drivers/tty/serial/omap-serial.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/tty/serial/omap-serial.c +2 -1
@@ -1767,7 +1767,8 @@ static int serial_omap_probe(struct plat
 	return 0;
 
 err_add_port:
-	pm_runtime_put(&pdev->dev);
+	pm_runtime_dont_use_autosuspend(&pdev->dev);
+	pm_runtime_put_sync(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 	pm_qos_remove_request(&up->pm_qos_request);
 	device_init_wakeup(up->dev, false);
author maintainer
#97 lore raw

PATCH 100/114 tty: pty: Fix ldisc flush after userspace become aware of the data already

In reply to Greg Kroah-Hartman

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

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

From: Wang YanQing <[email protected]>

commit 77dae6134440420bac334581a3ccee94cee1c054 upstream.

While using emacs, cat or others' commands in konsole with recent kernels, I have met many times that CTRL-C freeze konsole. After konsole freeze I can't type anything, then I have to open a new one, it is very annoying.

See bug report:
https://bugs.kde.org/show_bug.cgi?id=175283

The platform in that bug report is Solaris, but now the pty in linux has the same problem or the same behavior as Solaris :)

It has high possibility to trigger the problem follow steps below:
Note: In my test, BigFile is a text file whose size is bigger than 1G 1:open konsole
1:cat BigFile
2:CTRL-C

After some digging, I find out the reason is that commit 1d1d14da12e7 ("pty: Fix buffer flush deadlock") changes the behavior of pty_flush_buffer.

Thread A Thread B
-------- --------
1:n_tty_poll return POLLIN
2:CTRL-C trigger pty_flush_buffer
tty_buffer_flush
n_tty_flush_buffer
3:attempt to check count of chars:
ioctl(fd, TIOCINQ, &available)
available is equal to 0

4:read(fd, buffer, avaiable)
return 0

5:konsole close fd

Yes, I know we could use the same patch included in the BUG report as a workaround for linux platform too. But I think the data in ldisc is belong to application of another side, we shouldn't clear it when we want to flush write buffer of this side in pty_flush_buffer. So I think it is better to disable ldisc flush in pty_flush_buffer, because its new hehavior bring no benefit except that it mess up the behavior between POLLIN, and TIOCINQ or FIONREAD.

Also I find no flush_buffer function in others' tty driver has the same behavior as current pty_flush_buffer.

Fixes 1d1d14da12e7 ("pty: Fix buffer flush deadlock")
---
 drivers/tty/pty.c |    7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)
drivers/tty/pty.c +1 -6
@@ -216,16 +216,11 @@ static int pty_signal(struct tty_struct
 static void pty_flush_buffer(struct tty_struct *tty)
 {
 	struct tty_struct *to = tty->link;
-	struct tty_ldisc *ld;
 
 	if (!to)
 		return;
 
-	ld = tty_ldisc_ref(to);
-	tty_buffer_flush(to, ld);
-	if (ld)
-		tty_ldisc_deref(ld);
-
+	tty_buffer_flush(to, NULL);
 	if (to->packet) {
 		spin_lock_irq(&tty->ctrl_lock);
 		tty->ctrl_status |= TIOCPKT_FLUSHWRITE;
author maintainer
#98 lore raw

PATCH 101/114 tty: pl011: use "qdf2400_e44" as the earlycon name for QDF2400 E44

In reply to Greg Kroah-Hartman

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

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

From: Timur Tabi <[email protected]>

commit 5a0722b898f851b9ef108ea7babc529e4efc773d upstream.

Define a new early console name for Qualcomm Datacenter Technologies QDF2400 SOCs affected by erratum 44, instead of piggy-backing on "pl011". Previously, to enable traditional (non-SPCR) earlycon, the documentation said to specify "earlycon=pl011,<address>,qdf2400_e44", but the code was broken and this didn't actually work.

So instead, the method for specifying the E44 work-around with traditional earlycon is "earlycon=qdf2400_e44,<address>". Both methods of earlycon are now enabled with the same function.

Fixes e53e597fd4c4 ("tty: pl011: fix earlycon work-around for QDF2400 erratum 44")
---
 drivers/tty/serial/amba-pl011.c |   31 +++++++++++++++++++++++--------
 1 file changed, 23 insertions(+), 8 deletions(-)
drivers/tty/serial/amba-pl011.c +23 -8
@@ -2470,19 +2470,34 @@ static int __init pl011_early_console_se
 	if (!device->port.membase)
 		return -ENODEV;
 
-	/* On QDF2400 SOCs affected by Erratum 44, the "qdf2400_e44" must
-	 * also be specified, e.g. "earlycon=pl011,<address>,qdf2400_e44".
-	 */
-	if (!strcmp(device->options, "qdf2400_e44"))
-		device->con->write = qdf2400_e44_early_write;
-	else
-		device->con->write = pl011_early_write;
+	device->con->write = pl011_early_write;
 
 	return 0;
 }
 OF_EARLYCON_DECLARE(pl011, "arm,pl011", pl011_early_console_setup);
 OF_EARLYCON_DECLARE(pl011, "arm,sbsa-uart", pl011_early_console_setup);
-EARLYCON_DECLARE(qdf2400_e44, pl011_early_console_setup);
+
+/*
+ * On Qualcomm Datacenter Technologies QDF2400 SOCs affected by
+ * Erratum 44, traditional earlycon can be enabled by specifying
+ * "earlycon=qdf2400_e44,<address>".  Any options are ignored.
+ *
+ * Alternatively, you can just specify "earlycon", and the early console
+ * will be enabled with the information from the SPCR table.  In this
+ * case, the SPCR code will detect the need for the E44 work-around,
+ * and set the console name to "qdf2400_e44".
+ */
+static int __init
+qdf2400_e44_early_console_setup(struct earlycon_device *device,
+				const char *opt)
+{
+	if (!device->port.membase)
+		return -ENODEV;
+
+	device->con->write = qdf2400_e44_early_write;
+	return 0;
+}
+EARLYCON_DECLARE(qdf2400_e44, qdf2400_e44_early_console_setup);
 
 #else
 #define AMBA_CONSOLE	NULL
author maintainer
#99 lore raw

PATCH 102/114 Bluetooth: Fix user channel for 32bit userspace on 64bit kernel

In reply to Greg Kroah-Hartman

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

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

From: Szymon Janc <[email protected]>

commit ab89f0bdd63a3721f7cd3f064f39fc4ac7ca14d4 upstream.

Running 32bit userspace on 64bit kernel results in MSG_CMSG_COMPAT being defined as 0x80000000. This results in sendmsg failure if used from 32bit userspace running on 64bit kernel. Fix this by accounting for MSG_CMSG_COMPAT in flags check in hci_sock_sendmsg.

---
 net/bluetooth/hci_sock.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
net/bluetooth/hci_sock.c +2 -1
@@ -1680,7 +1680,8 @@ static int hci_sock_sendmsg(struct socke
 	if (msg->msg_flags & MSG_OOB)
 		return -EOPNOTSUPP;
 
-	if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE))
+	if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE|
+			       MSG_CMSG_COMPAT))
 		return -EINVAL;
 
 	if (len < 4 || len > HCI_MAX_FRAME_SIZE)
author maintainer
#100 lore raw

PATCH 103/114 Bluetooth: hci_bcm: add missing tty-device sanity check

In reply to Greg Kroah-Hartman

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

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

From: Johan Hovold <[email protected]>

commit 95065a61e9bf25fb85295127fba893200c2bbbd8 upstream.

Make sure to check the tty-device pointer before looking up the sibling platform device to avoid dereferencing a NULL-pointer when the tty is one end of a Unix98 pty.

Fixes 0395ffc1ee05 ("Bluetooth: hci_bcm: Add PM for BCM devices")
Cc Frederic Danis <[email protected]>
---
 drivers/bluetooth/hci_bcm.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/bluetooth/hci_bcm.c +4 -1
@@ -287,6 +287,9 @@ static int bcm_open(struct hci_uart *hu)
 
 	hu->priv = bcm;
 
+	if (!hu->tty->dev)
+		goto out;
+
 	mutex_lock(&bcm_device_lock);
 	list_for_each(p, &bcm_device_list) {
 		struct bcm_device *dev = list_entry(p, struct bcm_device, list);
@@ -307,7 +310,7 @@ static int bcm_open(struct hci_uart *hu)
 	}
 
 	mutex_unlock(&bcm_device_lock);
-
+out:
 	return 0;
 }
 
author maintainer
#101 lore raw

PATCH 104/114 Bluetooth: hci_intel: add missing tty-device sanity check

In reply to Greg Kroah-Hartman

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

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

From: Johan Hovold <[email protected]>

commit dcb9cfaa5ea9aa0ec08aeb92582ccfe3e4c719a9 upstream.

Make sure to check the tty-device pointer before looking up the sibling platform device to avoid dereferencing a NULL-pointer when the tty is one end of a Unix98 pty.

Fixes 74cdad37cd24 ("Bluetooth: hci_intel: Add runtime PM support")
Fixes 1ab1f239bf17 ("Bluetooth: hci_intel: Add support for platform driver")
Cc Loic Poulain <[email protected]>
---
 drivers/bluetooth/hci_intel.c |   13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)
drivers/bluetooth/hci_intel.c +12 -1
@@ -307,6 +307,9 @@ static int intel_set_power(struct hci_ua
 	struct list_head *p;
 	int err = -ENODEV;
 
+	if (!hu->tty->dev)
+		return err;
+
 	mutex_lock(&intel_device_list_lock);
 
 	list_for_each(p, &intel_device_list) {
@@ -379,6 +382,9 @@ static void intel_busy_work(struct work_
 	struct intel_data *intel = container_of(work, struct intel_data,
 						busy_work);
 
+	if (!intel->hu->tty->dev)
+		return;
+
 	/* Link is busy, delay the suspend */
 	mutex_lock(&intel_device_list_lock);
 	list_for_each(p, &intel_device_list) {
@@ -889,6 +895,8 @@ done:
 	list_for_each(p, &intel_device_list) {
 		struct intel_device *dev = list_entry(p, struct intel_device,
 						      list);
+		if (!hu->tty->dev)
+			break;
 		if (hu->tty->dev->parent == dev->pdev->dev.parent) {
 			if (device_may_wakeup(&dev->pdev->dev)) {
 				set_bit(STATE_LPM_ENABLED, &intel->flags);
@@ -1056,6 +1064,9 @@ static int intel_enqueue(struct hci_uart
 
 	BT_DBG("hu %p skb %p", hu, skb);
 
+	if (!hu->tty->dev)
+		goto out_enqueue;
+
 	/* Be sure our controller is resumed and potential LPM transaction
 	 * completed before enqueuing any packet.
 	 */
@@ -1072,7 +1083,7 @@ static int intel_enqueue(struct hci_uart
 		}
 	}
 	mutex_unlock(&intel_device_list_lock);
-
+out_enqueue:
 	skb_queue_tail(&intel->txq, skb);
 
 	return 0;
author maintainer
#102 lore raw

PATCH 105/114 cgroup: fix spurious warnings on cgroup_is_dead() from cgroup_sk_alloc()

In reply to Greg Kroah-Hartman

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

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

From: Tejun Heo <[email protected]>

commit a590b90d472f2c176c140576ee3ab44df7f67839 upstream.

cgroup_get() expected to be called only on live cgroups and triggers warning on a dead cgroup; however, cgroup_sk_alloc() may be called while cloning a socket which is left in an empty and removed cgroup and thus may legitimately duplicate its reference on a dead cgroup. This currently triggers the following warning spuriously.

 WARNING: CPU: 14 PID: 0 at kernel/cgroup.c:490 cgroup_get+0x55/0x60
 ...
  [<ffffffff8107e123>] __warn+0xd3/0xf0
  [<ffffffff8107e20e>] warn_slowpath_null+0x1e/0x20
  [<ffffffff810ff465>] cgroup_get+0x55/0x60
  [<ffffffff81106061>] cgroup_sk_alloc+0x51/0xe0
  [<ffffffff81761beb>] sk_clone_lock+0x2db/0x390
  [<ffffffff817cce06>] inet_csk_clone_lock+0x16/0xc0
  [<ffffffff817e8173>] tcp_create_openreq_child+0x23/0x4b0
  [<ffffffff818601a1>] tcp_v6_syn_recv_sock+0x91/0x670
  [<ffffffff817e8b16>] tcp_check_req+0x3a6/0x4e0
  [<ffffffff81861ba3>] tcp_v6_rcv+0x693/0xa00
  [<ffffffff81837429>] ip6_input_finish+0x59/0x3e0
  [<ffffffff81837cb2>] ip6_input+0x32/0xb0
  [<ffffffff81837387>] ip6_rcv_finish+0x57/0xa0
  [<ffffffff81837ac8>] ipv6_rcv+0x318/0x4d0
  [<ffffffff817778c7>] __netif_receive_skb_core+0x2d7/0x9a0
  [<ffffffff81777fa6>] __netif_receive_skb+0x16/0x70
  [<ffffffff81778023>] netif_receive_skb_internal+0x23/0x80
  [<ffffffff817787d8>] napi_gro_frags+0x208/0x270
  [<ffffffff8168a9ec>] mlx4_en_process_rx_cq+0x74c/0xf40
  [<ffffffff8168b270>] mlx4_en_poll_rx_cq+0x30/0x90
  [<ffffffff81778b30>] net_rx_action+0x210/0x350
  [<ffffffff8188c426>] __do_softirq+0x106/0x2c7
  [<ffffffff81082bad>] irq_exit+0x9d/0xa0 [<ffffffff8188c0e4>] do_IRQ+0x54/0xd0
  [<ffffffff8188a63f>] common_interrupt+0x7f/0x7f <EOI>
  [<ffffffff8173d7e7>] cpuidle_enter+0x17/0x20
  [<ffffffff810bdfd9>] cpu_startup_entry+0x2a9/0x2f0
  [<ffffffff8103edd1>] start_secondary+0xf1/0x100

This patch renames the existing cgroup_get() with the dead cgroup warning to cgroup_get_live() after cgroup_kn_lock_live() and introduces the new cgroup_get() which doesn't check whether the cgroup is live or dead.

All existing cgroup_get() users except for cgroup_sk_alloc() are converted to use cgroup_get_live().

Fixes d979a39d7242 ("cgroup: duplicate cgroup reference when cloning sockets")
Cc Johannes Weiner <[email protected]>
---
 kernel/cgroup/cgroup.c |   22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)
kernel/cgroup/cgroup.c +16 -6
@@ -438,6 +438,11 @@ out_unlock:
 
 static void cgroup_get(struct cgroup *cgrp)
 {
+	css_get(&cgrp->self);
+}
+
+static void cgroup_get_live(struct cgroup *cgrp)
+{
 	WARN_ON_ONCE(cgroup_is_dead(cgrp));
 	css_get(&cgrp->self);
 }
@@ -932,7 +937,7 @@ static void link_css_set(struct list_hea
 	list_add_tail(&link->cgrp_link, &cset->cgrp_links);
 
 	if (cgroup_parent(cgrp))
-		cgroup_get(cgrp);
+		cgroup_get_live(cgrp);
 }
 
 /**
@@ -1802,7 +1807,7 @@ static struct dentry *cgroup_mount(struc
 			return ERR_PTR(-EINVAL);
 		}
 		cgrp_dfl_visible = true;
-		cgroup_get(&cgrp_dfl_root.cgrp);
+		cgroup_get_live(&cgrp_dfl_root.cgrp);
 
 		dentry = cgroup_do_mount(&cgroup2_fs_type, flags, &cgrp_dfl_root,
 					 CGROUP2_SUPER_MAGIC, ns);
@@ -2576,7 +2581,7 @@ restart:
 			if (!css || !percpu_ref_is_dying(&css->refcnt))
 				continue;
 
-			cgroup_get(dsct);
+			cgroup_get_live(dsct);
 			prepare_to_wait(&dsct->offline_waitq, &wait,
 					TASK_UNINTERRUPTIBLE);
 
@@ -3947,7 +3952,7 @@ static void init_and_link_css(struct cgr
 {
 	lockdep_assert_held(&cgroup_mutex);
 
-	cgroup_get(cgrp);
+	cgroup_get_live(cgrp);
 
 	memset(css, 0, sizeof(*css));
 	css->cgroup = cgrp;
@@ -4123,7 +4128,7 @@ static struct cgroup *cgroup_create(stru
 	/* allocation complete, commit to creation */
 	list_add_tail_rcu(&cgrp->self.sibling, &cgroup_parent(cgrp)->self.children);
 	atomic_inc(&root->nr_cgrps);
-	cgroup_get(parent);
+	cgroup_get_live(parent);
 
 	/*
 	 * @cgrp is now fully operational.  If something fails after this
@@ -4947,7 +4952,7 @@ struct cgroup *cgroup_get_from_path(cons
 	if (kn) {
 		if (kernfs_type(kn) == KERNFS_DIR) {
 			cgrp = kn->priv;
-			cgroup_get(cgrp);
+			cgroup_get_live(cgrp);
 		} else {
 			cgrp = ERR_PTR(-ENOTDIR);
 		}
@@ -5027,6 +5032,11 @@ void cgroup_sk_alloc(struct sock_cgroup_
 
 	/* Socket clone path */
 	if (skcd->val) {
+		/*
+		 * We might be cloning a socket which is left in an empty
+		 * cgroup and the cgroup might have already been rmdir'd.
+		 * Don't use cgroup_get_live().
+		 */
 		cgroup_get(sock_cgroup_ptr(skcd));
 		return;
 	}
author maintainer
#103 lore raw

PATCH 106/114 libata: reject passthrough WRITE SAME requests

In reply to Greg Kroah-Hartman

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

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

From: Christoph Hellwig <[email protected]>

commit c6ade20f5e50e188d20b711a618b20dd1d50457e upstream.

The WRITE SAME to TRIM translation rewrites the DATA OUT buffer. While the SCSI code accomodates for this by passing a read-writable buffer userspace applications don't cater for this behavior. In fact it can be used to rewrite e.g. a readonly file through mmap and should be considered as a security fix.

---
 drivers/ata/libata-scsi.c |    8 ++++++++
 1 file changed, 8 insertions(+)
drivers/ata/libata-scsi.c +8 -0
@@ -3462,6 +3462,14 @@ static unsigned int ata_scsi_write_same_
 	if (unlikely(!dev->dma_mode))
 		goto invalid_opcode;
 
+	/*
+	 * We only allow sending this command through the block layer,
+	 * as it modifies the DATA OUT buffer, which would corrupt user
+	 * memory for SG_IO commands.
+	 */
+	if (unlikely(blk_rq_is_passthrough(scmd->request)))
+		goto invalid_opcode;
+
 	if (unlikely(scmd->cmd_len < 16)) {
 		fp = 15;
 		goto invalid_fld;
author maintainer
#104 lore raw

PATCH 107/114 ipmi: Fix kernel panic at ipmi_ssif_thread()

In reply to Greg Kroah-Hartman

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

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

From: Joeseph Chang <[email protected]>

commit 6de65fcfdb51835789b245203d1bfc8d14cb1e06 upstream.

msg_written_handler() may set ssif_info->multi_data to NULL when using ipmitool to write fru.

Before setting ssif_info->multi_data to NULL, add new local pointer "data_to_send" and store correct i2c data pointer to it to fix NULL pointer kernel panic and incorrect ssif_info->multi_pos.

---
 drivers/char/ipmi/ipmi_ssif.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/char/ipmi/ipmi_ssif.c +3 -1
@@ -891,6 +891,7 @@ static void msg_written_handler(struct s
 		 * for details on the intricacies of this.
 		 */
 		int left;
+		unsigned char *data_to_send;
 
 		ssif_inc_stat(ssif_info, sent_messages_parts);
 
@@ -899,6 +900,7 @@ static void msg_written_handler(struct s
 			left = 32;
 		/* Length byte. */
 		ssif_info->multi_data[ssif_info->multi_pos] = left;
+		data_to_send = ssif_info->multi_data + ssif_info->multi_pos;
 		ssif_info->multi_pos += left;
 		if (left < 32)
 			/*
@@ -912,7 +914,7 @@ static void msg_written_handler(struct s
 		rv = ssif_i2c_send(ssif_info, msg_written_handler,
 				  I2C_SMBUS_WRITE,
 				  SSIF_IPMI_MULTI_PART_REQUEST_MIDDLE,
-				  ssif_info->multi_data + ssif_info->multi_pos,
+				  data_to_send,
 				  I2C_SMBUS_BLOCK_DATA);
 		if (rv < 0) {
 			/* request failed, just return the error. */
author maintainer
#105 lore raw

PATCH 108/114 libnvdimm, region: fix flush hint detection crash

In reply to Greg Kroah-Hartman

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

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

From: Dan Williams <[email protected]>

commit bc042fdfbb92b5b13421316b4548e2d6e98eed37 upstream.

In the case where a dimm does not have any associated flush hints the ndrd->flush_wpq array may be uninitialized leading to crashes with the following signature:

 BUG: unable to handle kernel NULL pointer dereference at 0000000000000010
 IP: region_visible+0x10f/0x160 [libnvdimm]

 Call Trace:
  internal_create_group+0xbe/0x2f0
  sysfs_create_groups+0x40/0x80
  device_add+0x2d8/0x650
  nd_async_device_register+0x12/0x40 [libnvdimm]
  async_run_entry_fn+0x39/0x170
  process_one_work+0x212/0x6c0
  ? process_one_work+0x197/0x6c0
  worker_thread+0x4e/0x4a0
  kthread+0x10c/0x140
  ? process_one_work+0x6c0/0x6c0
  ? kthread_create_on_node+0x60/0x60
  ret_from_fork+0x31/0x40
Fixes f284a4f23752 ("libnvdimm: introduce nvdimm_flush() and nvdimm_has_flush()")
---
 drivers/nvdimm/region_devs.c |   11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)
drivers/nvdimm/region_devs.c +7 -4
@@ -968,17 +968,20 @@ EXPORT_SYMBOL_GPL(nvdimm_flush);
  */
 int nvdimm_has_flush(struct nd_region *nd_region)
 {
-	struct nd_region_data *ndrd = dev_get_drvdata(&nd_region->dev);
 	int i;
 
 	/* no nvdimm == flushing capability unknown */
 	if (nd_region->ndr_mappings == 0)
 		return -ENXIO;
 
-	for (i = 0; i < nd_region->ndr_mappings; i++)
-		/* flush hints present, flushing required */
-		if (ndrd_get_flush_wpq(ndrd, i, 0))
+	for (i = 0; i < nd_region->ndr_mappings; i++) {
+		struct nd_mapping *nd_mapping = &nd_region->mapping[i];
+		struct nvdimm *nvdimm = nd_mapping->nvdimm;
+
+		/* flush hints present / available */
+		if (nvdimm->num_flush)
 			return 1;
+	}
 
 	/*
 	 * The platform defines dimm devices without hints, assume
author maintainer
#106 lore raw

PATCH 109/114 libnvdimm, pmem: fix a NULL pointer BUG in nd_pmem_notify

In reply to Greg Kroah-Hartman

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

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

From: Toshi Kani <[email protected]>

commit b2518c78ce76896f0f8f7940bf02104b227e1709 upstream.

The following BUG was observed when nd_pmem_notify() was called for a BTT device. The use of a pmem_device pointer is not valid with BTT.

 BUG: unable to handle kernel NULL pointer dereference at 0000000000000030
 IP: nd_pmem_notify+0x30/0xf0 [nd_pmem]
 Call Trace:
  nd_device_notify+0x40/0x50
  child_notify+0x10/0x20
  device_for_each_child+0x50/0x90
  nd_region_notify+0x20/0x30
  nd_device_notify+0x40/0x50
  nvdimm_region_notify+0x27/0x30
  acpi_nfit_scrub+0x341/0x590 [nfit]
  process_one_work+0x197/0x450
  worker_thread+0x4e/0x4a0
  kthread+0x109/0x140

Fix nd_pmem_notify() by setting nd_region and badblocks pointers properly for BTT.

Cc Vishal Verma <[email protected]>
Fixes 719994660c24 ("libnvdimm: async notification support")
---
 drivers/nvdimm/pmem.c |   39 ++++++++++++++++++++++++++-------------
 1 file changed, 26 insertions(+), 13 deletions(-)
drivers/nvdimm/pmem.c +26 -13
@@ -388,12 +388,12 @@ static void nd_pmem_shutdown(struct devi
 
 static void nd_pmem_notify(struct device *dev, enum nvdimm_event event)
 {
-	struct pmem_device *pmem = dev_get_drvdata(dev);
-	struct nd_region *nd_region = to_region(pmem);
+	struct nd_region *nd_region;
 	resource_size_t offset = 0, end_trunc = 0;
 	struct nd_namespace_common *ndns;
 	struct nd_namespace_io *nsio;
 	struct resource res;
+	struct badblocks *bb;
 
 	if (event != NVDIMM_REVALIDATE_POISON)
 		return;
@@ -402,20 +402,33 @@ static void nd_pmem_notify(struct device
 		struct nd_btt *nd_btt = to_nd_btt(dev);
 
 		ndns = nd_btt->ndns;
-	} else if (is_nd_pfn(dev)) {
-		struct nd_pfn *nd_pfn = to_nd_pfn(dev);
-		struct nd_pfn_sb *pfn_sb = nd_pfn->pfn_sb;
-
-		ndns = nd_pfn->ndns;
-		offset = pmem->data_offset + __le32_to_cpu(pfn_sb->start_pad);
-		end_trunc = __le32_to_cpu(pfn_sb->end_trunc);
-	} else
-		ndns = to_ndns(dev);
+		nd_region = to_nd_region(ndns->dev.parent);
+		nsio = to_nd_namespace_io(&ndns->dev);
+		bb = &nsio->bb;
+	} else {
+		struct pmem_device *pmem = dev_get_drvdata(dev);
+
+		nd_region = to_region(pmem);
+		bb = &pmem->bb;
+
+		if (is_nd_pfn(dev)) {
+			struct nd_pfn *nd_pfn = to_nd_pfn(dev);
+			struct nd_pfn_sb *pfn_sb = nd_pfn->pfn_sb;
+
+			ndns = nd_pfn->ndns;
+			offset = pmem->data_offset +
+					__le32_to_cpu(pfn_sb->start_pad);
+			end_trunc = __le32_to_cpu(pfn_sb->end_trunc);
+		} else {
+			ndns = to_ndns(dev);
+		}
+
+		nsio = to_nd_namespace_io(&ndns->dev);
+	}
 
-	nsio = to_nd_namespace_io(&ndns->dev);
 	res.start = nsio->res.start + offset;
 	res.end = nsio->res.end - end_trunc;
-	nvdimm_badblocks_populate(nd_region, &pmem->bb, &res);
+	nvdimm_badblocks_populate(nd_region, bb, &res);
 }
 
 MODULE_ALIAS("pmem");
author maintainer
#107 lore raw

PATCH 110/114 libnvdimm: fix nvdimm_bus_lock() vs device_lock() ordering

In reply to Greg Kroah-Hartman

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

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

From: Dan Williams <[email protected]>

commit 452bae0aede774f87bf56c28b6dd50b72c78986c upstream.

A debug patch to turn the standard device_lock() into something that lockdep can analyze yielded the following:

======================================================
[ INFO: possible circular locking dependency detected ]
4.11.0-rc4+ #106 Tainted: G O
-------------------------------------------------------
lt-libndctl/1898 is trying to acquire lock:
(&dev->nvdimm_mutex/3){+.+.+.}, at: [<ffffffffc023c948>] nd_attach_ndns+0x178/0x1b0 [libnvdimm]

but task is already holding lock:
(&nvdimm_bus->reconfig_mutex){+.+.+.}, at: [<ffffffffc022e0b1>] nvdimm_bus_lock+0x21/0x30 [libnvdimm]

which lock already depends on the new lock.

the existing dependency chain (in reverse order) is:

-> #1 (&nvdimm_bus->reconfig_mutex){+.+.+.}:

        lock_acquire+0xf6/0x1f0
        __mutex_lock+0x88/0x980
        mutex_lock_nested+0x1b/0x20
        nvdimm_bus_lock+0x21/0x30 [libnvdimm]
        nvdimm_namespace_capacity+0x1b/0x40 [libnvdimm]
        nvdimm_namespace_common_probe+0x230/0x510 [libnvdimm]
        nd_pmem_probe+0x14/0x180 [nd_pmem]
        nvdimm_bus_probe+0xa9/0x260 [libnvdimm]

-> #0 (&dev->nvdimm_mutex/3){+.+.+.}:

        __lock_acquire+0x1107/0x1280
        lock_acquire+0xf6/0x1f0
        __mutex_lock+0x88/0x980
        mutex_lock_nested+0x1b/0x20
        nd_attach_ndns+0x178/0x1b0 [libnvdimm]
        nd_namespace_store+0x308/0x3c0 [libnvdimm]
        namespace_store+0x87/0x220 [libnvdimm]

In this case '&dev->nvdimm_mutex/3' mirrors '&dev->mutex'.

Fix this by replacing the use of device_lock() with nvdimm_bus_lock() to protect nd_{attach,detach}_ndns() operations.

Fixes 8c2f7e8658df ("libnvdimm: infrastructure for btt devices")
---
 drivers/nvdimm/btt_devs.c |    2 +-
 drivers/nvdimm/claim.c    |   23 +++++++++++++++--------
 drivers/nvdimm/dax_devs.c |    2 +-
 drivers/nvdimm/pfn_devs.c |    2 +-
 4 files changed, 18 insertions(+), 11 deletions(-)
drivers/nvdimm/btt_devs.c +1 -1
@@ -314,7 +314,7 @@ int nd_btt_probe(struct device *dev, str
 	if (rc < 0) {
 		struct nd_btt *nd_btt = to_nd_btt(btt_dev);
 
-		__nd_detach_ndns(btt_dev, &nd_btt->ndns);
+		nd_detach_ndns(btt_dev, &nd_btt->ndns);
 		put_device(btt_dev);
 	}
 
drivers/nvdimm/claim.c +15 -8
@@ -21,8 +21,13 @@
 void __nd_detach_ndns(struct device *dev, struct nd_namespace_common **_ndns)
 {
 	struct nd_namespace_common *ndns = *_ndns;
+	struct nvdimm_bus *nvdimm_bus;
 
-	lockdep_assert_held(&ndns->dev.mutex);
+	if (!ndns)
+		return;
+
+	nvdimm_bus = walk_to_nvdimm_bus(&ndns->dev);
+	lockdep_assert_held(&nvdimm_bus->reconfig_mutex);
 	dev_WARN_ONCE(dev, ndns->claim != dev, "%s: invalid claim\n", __func__);
 	ndns->claim = NULL;
 	*_ndns = NULL;
@@ -37,18 +42,20 @@ void nd_detach_ndns(struct device *dev,
 	if (!ndns)
 		return;
 	get_device(&ndns->dev);
-	device_lock(&ndns->dev);
+	nvdimm_bus_lock(&ndns->dev);
 	__nd_detach_ndns(dev, _ndns);
-	device_unlock(&ndns->dev);
+	nvdimm_bus_unlock(&ndns->dev);
 	put_device(&ndns->dev);
 }
 
 bool __nd_attach_ndns(struct device *dev, struct nd_namespace_common *attach,
 		struct nd_namespace_common **_ndns)
 {
+	struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(&attach->dev);
+
 	if (attach->claim)
 		return false;
-	lockdep_assert_held(&attach->dev.mutex);
+	lockdep_assert_held(&nvdimm_bus->reconfig_mutex);
 	dev_WARN_ONCE(dev, *_ndns, "%s: invalid claim\n", __func__);
 	attach->claim = dev;
 	*_ndns = attach;
@@ -61,9 +68,9 @@ bool nd_attach_ndns(struct device *dev,
 {
 	bool claimed;
 
-	device_lock(&attach->dev);
+	nvdimm_bus_lock(&attach->dev);
 	claimed = __nd_attach_ndns(dev, attach, _ndns);
-	device_unlock(&attach->dev);
+	nvdimm_bus_unlock(&attach->dev);
 	return claimed;
 }
 
@@ -114,7 +121,7 @@ static void nd_detach_and_reset(struct d
 		struct nd_namespace_common **_ndns)
 {
 	/* detach the namespace and destroy / reset the device */
-	nd_detach_ndns(dev, _ndns);
+	__nd_detach_ndns(dev, _ndns);
 	if (is_idle(dev, *_ndns)) {
 		nd_device_unregister(dev, ND_ASYNC);
 	} else if (is_nd_btt(dev)) {
@@ -184,7 +191,7 @@ ssize_t nd_namespace_store(struct device
 	}
 
 	WARN_ON_ONCE(!is_nvdimm_bus_locked(dev));
-	if (!nd_attach_ndns(dev, ndns, _ndns)) {
+	if (!__nd_attach_ndns(dev, ndns, _ndns)) {
 		dev_dbg(dev, "%s already claimed\n",
 				dev_name(&ndns->dev));
 		len = -EBUSY;
drivers/nvdimm/dax_devs.c +1 -1
@@ -124,7 +124,7 @@ int nd_dax_probe(struct device *dev, str
 	dev_dbg(dev, "%s: dax: %s\n", __func__,
 			rc == 0 ? dev_name(dax_dev) : "<none>");
 	if (rc < 0) {
-		__nd_detach_ndns(dax_dev, &nd_pfn->ndns);
+		nd_detach_ndns(dax_dev, &nd_pfn->ndns);
 		put_device(dax_dev);
 	} else
 		__nd_device_register(dax_dev);
drivers/nvdimm/pfn_devs.c +1 -1
@@ -484,7 +484,7 @@ int nd_pfn_probe(struct device *dev, str
 	dev_dbg(dev, "%s: pfn: %s\n", __func__,
 			rc == 0 ? dev_name(pfn_dev) : "<none>");
 	if (rc < 0) {
-		__nd_detach_ndns(pfn_dev, &nd_pfn->ndns);
+		nd_detach_ndns(pfn_dev, &nd_pfn->ndns);
 		put_device(pfn_dev);
 	} else
 		__nd_device_register(pfn_dev);
author maintainer
#108 lore raw

PATCH 111/114 libnvdimm, pfn: fix npfns vs section alignment

In reply to Greg Kroah-Hartman

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

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

From: Dan Williams <[email protected]>

commit d5483feda85a8f39ee2e940e279547c686aac30c upstream.

Fix failures to create namespaces due to the vmem_altmap not advertising enough free space to store the memmap.

 WARNING: CPU: 15 PID: 8022 at arch/x86/mm/init_64.c:656 arch_add_memory+0xde/0xf0
 [..]
 Call Trace:
  dump_stack+0x63/0x83
  __warn+0xcb/0xf0
  warn_slowpath_null+0x1d/0x20
  arch_add_memory+0xde/0xf0
  devm_memremap_pages+0x244/0x440
  pmem_attach_disk+0x37e/0x490 [nd_pmem]
  nd_pmem_probe+0x7e/0xa0 [nd_pmem]
  nvdimm_bus_probe+0x71/0x120 [libnvdimm]
  driver_probe_device+0x2bb/0x460
  bind_store+0x114/0x160
  drv_attr_store+0x25/0x30

In commit 658922e57b84 "libnvdimm, pfn: fix memmap reservation sizing" we arranged for the capacity to be allocated, but failed to also update the 'npfns' parameter. This leads to cases where there is enough capacity reserved to hold all the allocated sections, but vmemmap_populate_hugepages() still encounters -ENOMEM from altmap_alloc_block_buf().

This fix is a stop-gap until we can teach the core memory hotplug implementation to permit sub-section hotplug.

Fixes 658922e57b84 ("libnvdimm, pfn: fix memmap reservation sizing")
---
 drivers/nvdimm/pfn_devs.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/nvdimm/pfn_devs.c +4 -2
@@ -538,7 +538,8 @@ static struct vmem_altmap *__nvdimm_setu
 		nd_pfn->npfns = le64_to_cpu(pfn_sb->npfns);
 		altmap = NULL;
 	} else if (nd_pfn->mode == PFN_MODE_PMEM) {
-		nd_pfn->npfns = (resource_size(res) - offset) / PAGE_SIZE;
+		nd_pfn->npfns = PFN_SECTION_ALIGN_UP((resource_size(res)
+					- offset) / PAGE_SIZE);
 		if (le64_to_cpu(nd_pfn->pfn_sb->npfns) > nd_pfn->npfns)
 			dev_info(&nd_pfn->dev,
 					"number of pfns truncated from %lld to %ld\n",
@@ -625,7 +626,8 @@ static int nd_pfn_init(struct nd_pfn *nd
 	 */
 	start += start_pad;
 	size = resource_size(&nsio->res);
-	npfns = (size - start_pad - end_trunc - SZ_8K) / SZ_4K;
+	npfns = PFN_SECTION_ALIGN_UP((size - start_pad - end_trunc - SZ_8K)
+			/ PAGE_SIZE);
 	if (nd_pfn->mode == PFN_MODE_PMEM) {
 		/*
 		 * vmemmap_populate_hugepages() allocates the memmap array in
author maintainer
#109 lore raw

PATCH 112/114 pstore: Fix flags to enable dumps on powerpc

In reply to Greg Kroah-Hartman

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

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

From: Ankit Kumar <[email protected]>

commit 041939c1ec54208b42f5cd819209173d52a29d34 upstream.

After commit c950fd6f201a kernel registers pstore write based on flag set. Pstore write for powerpc is broken as flags(PSTORE_FLAGS_DMESG) is not set for powerpc architecture. On panic, kernel doesn't write message to /fs/pstore/dmesg*(Entry doesn't gets created at all).

This patch enables pstore write for powerpc architecture by setting PSTORE_FLAGS_DMESG flag.

Fixes c950fd6f201a ("pstore: Split pstore fragile flags")
---
 arch/powerpc/kernel/nvram_64.c |    1 +
 1 file changed, 1 insertion(+)
arch/powerpc/kernel/nvram_64.c +1 -0
@@ -561,6 +561,7 @@ static ssize_t nvram_pstore_read(u64 *id
 static struct pstore_info nvram_pstore_info = {
 	.owner = THIS_MODULE,
 	.name = "nvram",
+	.flags = PSTORE_FLAGS_DMESG,
 	.open = nvram_pstore_open,
 	.read = nvram_pstore_read,
 	.write = nvram_pstore_write,
author maintainer
#110 lore raw

PATCH 113/114 pstore: Use dynamic spinlock initializer

In reply to Greg Kroah-Hartman

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

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

From: Kees Cook <[email protected]>

commit e9a330c4289f2ba1ca4bf98c2b430ab165a8931b upstream.

The per-prz spinlock should be using the dynamic initializer so that lockdep can correctly track it. Without this, under lockdep, we get a warning at boot that the lock is in non-static memory.

Fixes 109704492ef6 ("pstore: Make spinlock per zone instead of global")
Fixes 76d5692a5803 ("pstore: Correctly initialize spinlock and flags")
---
 fs/pstore/ram_core.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/pstore/ram_core.c +1 -1
@@ -532,7 +532,7 @@ struct persistent_ram_zone *persistent_r
 	}
 
 	/* Initialize general buffer state. */
-	prz->buffer_lock = __RAW_SPIN_LOCK_UNLOCKED(buffer_lock);
+	raw_spin_lock_init(&prz->buffer_lock);
 	prz->flags = flags;
 
 	ret = persistent_ram_buffer_map(start, size, prz, memtype);
author maintainer
#111 lore raw

PATCH 114/114 pstore: Shut down worker when unregistering

In reply to Greg Kroah-Hartman

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

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

From: Kees Cook <[email protected]>

commit 6330d5534786d5315d56d558aa6d20740f97d80a upstream.

When built as a module and running with update_ms >= 0, pstore will Oops during module unload since the work timer is still running. This makes sure the worker is stopped before unloading.

---
 fs/pstore/platform.c |   10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)
fs/pstore/platform.c +9 -1
@@ -709,6 +709,7 @@ int pstore_register(struct pstore_info *
 	if (psi->flags & PSTORE_FLAGS_PMSG)
 		pstore_register_pmsg();
 
+	/* Start watching for new records, if desired. */
 	if (pstore_update_ms >= 0) {
 		pstore_timer.expires = jiffies +
 			msecs_to_jiffies(pstore_update_ms);
@@ -731,6 +732,11 @@ EXPORT_SYMBOL_GPL(pstore_register);
 
 void pstore_unregister(struct pstore_info *psi)
 {
+	/* Stop timer and make sure all work has finished. */
+	pstore_update_ms = -1;
+	del_timer_sync(&pstore_timer);
+	flush_work(&pstore_work);
+
 	if (psi->flags & PSTORE_FLAGS_PMSG)
 		pstore_unregister_pmsg();
 	if (psi->flags & PSTORE_FLAGS_FTRACE)
@@ -830,7 +836,9 @@ static void pstore_timefunc(unsigned lon
 		schedule_work(&pstore_work);
 	}
 
-	mod_timer(&pstore_timer, jiffies + msecs_to_jiffies(pstore_update_ms));
+	if (pstore_update_ms >= 0)
+		mod_timer(&pstore_timer,
+			  jiffies + msecs_to_jiffies(pstore_update_ms));
 }
 
 module_param(backend, charp, 0444);
#112 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.11.2 release. There are 114 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 Sat May 20 10:35:20 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.11.2-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.11.y
and the diffstat can be found below.

thanks,

greg k-h

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

thanks,
-- Shuah

author maintainer
#113 lore raw
Quoted 15 lines · Shuah Khan
Quoted 14 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 4.11.2 release. There are 114 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 Sat May 20 10:35:20 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.11.2-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.11.y
and the diffstat can be found below.

Quoted 6 lines
Quoted 4 lines

thanks,

greg k-h

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

That was fast! Thanks for testing all of these and letting me know.

greg k-h

#114 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.11.2 release. There are 114 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 Sat May 20 10:35:20 UTC 2017. Anything received after that time might be too late.

Build results:

	total: 145 pass: 145 fail: 0
Qemu test results:
	total: 122 pass: 122 fail: 0

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

Guenter

author maintainer
#115 lore raw
Quoted 10 lines · Guenter Roeck
Quoted 8 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 4.11.2 release. There are 114 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 Sat May 20 10:35:20 UTC 2017. Anything received after that time might be too late.

Quoted 6 lines

Build results:

	total: 145 pass: 145 fail: 0
Qemu test results:
	total: 122 pass: 122 fail: 0

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

Great, thanks for testing all of these and letting me know.

greg k-h