Skip to contentSkip to conversation

4.13.10-stable review

PATCH In review Greg Kroah-Hartman 4 participants 88 messages Oct 24, 2017 – Oct 30, 2017 Stable branch

lore
Share & tools
lore

Greg Kroah-Hartman

author maintainer
#0 lore raw

cover 4.13.10-stable review

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

Responses should be made by Thu Oct 26 12:56:27 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.13.10-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.13.y
and the diffstat can be found below.

thanks,

greg k-h

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

Greg Kroah-Hartman <[email protected]>

    Linux 4.13.10-rc1

Arnd Bergmann <[email protected]>
xfs: move two more RT specific functions into CONFIG_XFS_RT

Brian Foster <[email protected]>
xfs: trim writepage mapping to within eof

Dave Chinner <[email protected]>
xfs: cancel dirty pages on invalidation

Eric Sandeen <[email protected]>
xfs: handle error if xfs_btree_get_bufs fails

Brian Foster <[email protected]>
xfs: reinit btree pointer on attr tree inactivation walk

Dave Chinner <[email protected]>
xfs: don't change inode mode if ACL update fails

Dave Chinner <[email protected]>
xfs: move more RT specific code under CONFIG_XFS_RT

Dave Chinner <[email protected]>
xfs: Don't log uninitialised fields in inode structures

Christoph Hellwig <[email protected]>
xfs: handle racy AIO in xfs_reflink_end_cow

Darrick J. Wong <[email protected]>
xfs: always swap the cow forks when swapping extents

Carlos Maiolino <[email protected]>
xfs: Capture state of the right inode in xfs_iflush_done

Darrick J. Wong <[email protected]>
xfs: perag initialization should only touch m_ag_max_usable for AG 0

Eryu Guan <[email protected]>
xfs: update i_size after unwritten conversion in dio completion

Eryu Guan <[email protected]>
xfs: report zeroed or not correctly in xfs_zero_range()

Helge Deller <[email protected]>
fs/xfs: Use %pS printk format for direct addresses

Darrick J. Wong <[email protected]>
xfs: evict CoW fork extents when performing finsert/fcollapse

Darrick J. Wong <[email protected]>
xfs: don't unconditionally clear the reflink flag on zero-block files

Chandan Rajendra <[email protected]>
iomap_dio_rw: Allocate AIO completion queue before submitting dio

Takashi Iwai <[email protected]>
ALSA: hda - Fix incorrect TLV callback check introduced during set_fs() removal

Shawn Lin <[email protected]>
arm64: dts: rockchip: correct vqmmc voltage for rk3399 platforms

Eric Sesterhenn <[email protected]>
pkcs7: Prevent NULL pointer dereference, since sinfo is not always set.

David Howells <[email protected]>
KEYS: don't let add_key() update an uninstantiated key

Eric Biggers <[email protected]>
FS-Cache: fix dereference of NULL user_key_payload

David Howells <[email protected]>
KEYS: Fix race between updating and finding a negative key

Eric Biggers <[email protected]>
ecryptfs: fix dereference of NULL user_key_payload

Eric Biggers <[email protected]>
fscrypt: fix dereference of NULL user_key_payload

Eric Biggers <[email protected]>
lib/digsig: fix dereference of NULL user_key_payload

Borislav Petkov <[email protected]>
x86/microcode/intel: Disable late loading on model 79

Larry Finger <[email protected]>
rtlwifi: rtl8821ae: Fix connection lost problem

David Kozub <[email protected]>
clockevents/drivers/cs5535: Improve resilience to spurious interrupts

Jan Luebbe <[email protected]>
bus: mbus: fix window size calculation for 4GB windows

Chen-Yu Tsai <[email protected]>
ARM: dts: sun6i: Fix endpoint IDs in second display pipeline

Arnd Bergmann <[email protected]>
brcmsmac: make some local variables 'static const' to reduce stack size

Kevin Cernekee <[email protected]>
brcmfmac: Add check for short event packets

Chanwoo Choi <[email protected]>
Input: stmfts - fix setting ABS_MT_POSITION_* maximum size

Len Brown <[email protected]>
Revert "tools/power turbostat: stop migrating, unless '-m'"

Guenter Roeck <[email protected]>
i2c: piix4: Fix SMBus port selection for AMD Family 17h chips

Pontus Andersson <[email protected]>
i2c: ismt: Separate I2C block read from SMBus block read

Takashi Iwai <[email protected]>
ALSA: hda: Abort capability probe at invalid register read

Takashi Iwai <[email protected]>
ALSA: hda: Remove superfluous '-' added by printk conversion

Ben Hutchings <[email protected]>
ALSA: seq: Enable 'use' locking in all configurations

Steven Rostedt (VMware) <[email protected]>
tracing/samples: Fix creation and deletion of simple_thread_fn creation

Sean Young <[email protected]>
media: dvb: i2c transfers over usb cannot be done from stack

Jose Abreu <[email protected]>
media: cec: Respond to unregistered initiators, when applicable

Hans Verkuil <[email protected]>
media: s5p-cec: add NACK detection support

Ben Skeggs <[email protected]>
drm/nouveau/mmu: flush tlbs before deleting page tables

Ilia Mirkin <[email protected]>
drm/nouveau/bsp/g92: disable by default

Ben Skeggs <[email protected]>
drm/nouveau/kms/nv50: fix oops during DP IRQ handling on non-MST boards

Chris Wilson <[email protected]>
drm/i915: Use bdw_ddi_translations_fdi for Broadwell

Adrian Hunter <[email protected]>
mmc: sdhci-pci: Fix default d3_retune for Intel host controllers

Eric Biggers <[email protected]>
KEYS: encrypted: fix dereference of NULL user_key_payload

ZHU Yi (ST-FIR/ENG1-Zhu) <[email protected]>
can: flexcan: fix p1010 state transition issue

ZHU Yi (ST-FIR/ENG1-Zhu) <[email protected]>
can: flexcan: fix i.MX28 state transition issue

ZHU Yi (ST-FIR/ENG1-Zhu) <[email protected]>
can: flexcan: fix i.MX6 state transition issue

ZHU Yi (ST-FIR/ENG1-Zhu) <[email protected]>
can: flexcan: implement error passive state quirk

ZHU Yi (ST-FIR/ENG1-Zhu) <[email protected]>
can: flexcan: rename legacy error state quirk

ZHU Yi (ST-FIR/ENG1-Zhu) <[email protected]>
can: flexcan: fix state transition regression

Marc Kleine-Budde <[email protected]>
can: af_can: can_pernet_init(): add missing error handling for kzalloc returning NULL

Stefan Mätje <[email protected]>
can: esd_usb2: Fix can_dlc value for received RTR, frames

Mayank Rana <[email protected]>
usb: xhci: Handle error condition in xhci_stop_device()

Lu Baolu <[email protected]>
usb: xhci: Reset halted endpoint if trb is noop

Jeffy Chen <[email protected]>
xhci: Cleanup current_cmd in xhci_cleanup_command_queue()

Mathias Nyman <[email protected]>
xhci: Identify USB 3.1 capable hosts by their port protocol capability

Jonathan Liu <[email protected]>
usb: musb: Check for host-mode using is_host_active() on reset interrupt

Alexandre Bailon <[email protected]>
usb: musb: musb_cppi41: Configure the number of channels for DA8xx

Alexandre Bailon <[email protected]>
usb: musb: musb_cppi41: Fix cppi41_set_dma_mode() for DA8xx

Alexandre Bailon <[email protected]>
usb: musb: musb_cppi41: Fix the address of teardown and autoreq registers

Johan Hovold <[email protected]>
USB: musb: fix late external abort on suspend

Johan Hovold <[email protected]>
USB: musb: fix session-bit runtime-PM quirk

Jonathan Liu <[email protected]>
usb: musb: sunxi: Explicitly release USB PHY on exit

Lars-Peter Clausen <[email protected]>
iio: dummy: events: Add missing break

Helge Deller <[email protected]>
parisc: Fix detection of nonsynchronous cr16 cycle counters

John David Anglin <[email protected]>
parisc: Fix double-word compare and exchange in LWS code on 32-bit kernels

Christian Borntraeger <[email protected]>
s390/cputime: fix guest/irq/softirq times after CPU hotplug

Josef Bacik <[email protected]>
nbd: don't set the device size until we're connected

Quinn Tran <[email protected]>
scsi: qla2xxx: Fix uninitialized work element

Wolfgang Grandegger <[email protected]>
can: gs_usb: fix busy loop if no more TX context is available

Jussi Laako <[email protected]>
ALSA: usb-audio: Add native DSD support for Pro-Ject Pre Box S2 Digital

Mathias Nyman <[email protected]>
usb: hub: Allow reset retry for USB2 devices on connect bounce

Felipe Balbi <[email protected]>
usb: quirks: add quirk for WORLDE MINI MIDI keyboard

Maksim Salau <[email protected]>
usb: cdc_acm: Add quirk for Elatec TWN3

Johan Hovold <[email protected]>
USB: serial: metro-usb: add MS7820 device id

Alan Stern <[email protected]>
USB: core: fix out-of-bounds access bug in usb_get_bos_descriptor()

Hans de Goede <[email protected]>
USB: devio: Revert "USB: devio: Don't corrupt user memory"

Phil Elwell <[email protected]>
staging: bcm2835-audio: Fix memory corruption

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

Diffstat:

 Makefile                                           |   4 +-
 arch/arm/boot/dts/sun6i-a31.dtsi                   |  16 +-
 arch/arm64/boot/dts/rockchip/rk3399-firefly.dts    |   4 +-
 arch/parisc/kernel/syscall.S                       |   6 +-
 arch/parisc/kernel/time.c                          |   5 +-
 arch/s390/kernel/smp.c                             |   3 +
 arch/x86/kernel/cpu/microcode/intel.c              |  19 ++
 crypto/asymmetric_keys/pkcs7_parser.c              |   3 +
 drivers/block/nbd.c                                |   2 +-
 drivers/bus/mvebu-mbus.c                           |   2 +-
 drivers/clocksource/cs5535-clockevt.c              |   3 +-
 drivers/gpu/drm/i915/intel_ddi.c                   |   4 +-
 drivers/gpu/drm/nouveau/nv50_display.c             |   5 +-
 drivers/gpu/drm/nouveau/nvkm/engine/bsp/g84.c      |   2 +-
 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c     |   2 +
 drivers/i2c/busses/i2c-ismt.c                      |   5 +-
 drivers/i2c/busses/i2c-piix4.c                     |  30 +++-
 drivers/iio/dummy/iio_simple_dummy_events.c        |   1 +
 drivers/input/touchscreen/stmfts.c                 |   6 +-
 drivers/media/cec/cec-adap.c                       |  13 +-
 drivers/media/dvb-frontends/dib3000mc.c            |  50 ++++--
 drivers/media/dvb-frontends/dvb-pll.c              |  22 ++-
 .../media/platform/s5p-cec/exynos_hdmi_cecctrl.c   |   3 +-
 drivers/media/platform/s5p-cec/s5p_cec.c           |  11 +-
 drivers/media/platform/s5p-cec/s5p_cec.h           |   2 +
 drivers/media/tuners/mt2060.c                      |  59 ++++--
 drivers/mmc/host/sdhci-pci-core.c                  |   2 +
 drivers/net/can/flexcan.c                          |  91 ++++++++--
 drivers/net/can/usb/esd_usb2.c                     |   2 +-
 drivers/net/can/usb/gs_usb.c                       |  10 +-
 .../wireless/broadcom/brcm80211/brcmfmac/fweh.c    |   3 +-
 .../broadcom/brcm80211/brcmsmac/phy/phy_n.c        | 197 ++++++++++-----------
 .../net/wireless/realtek/rtlwifi/rtl8821ae/hw.c    |   2 +-
 drivers/scsi/qla2xxx/qla_os.c                      |   3 +-
 .../vc04_services/bcm2835-audio/bcm2835-vchiq.c    |  19 +-
 drivers/usb/class/cdc-acm.c                        |   3 +
 drivers/usb/core/config.c                          |   6 +-
 drivers/usb/core/devio.c                           |   6 +-
 drivers/usb/core/hub.c                             |  11 +-
 drivers/usb/core/quirks.c                          |   4 +
 drivers/usb/host/xhci-hub.c                        |  23 ++-
 drivers/usb/host/xhci-ring.c                       |  21 ++-
 drivers/usb/host/xhci.c                            |   3 +-
 drivers/usb/musb/musb_core.c                       |  21 ++-
 drivers/usb/musb/musb_core.h                       |   2 +
 drivers/usb/musb/musb_cppi41.c                     |  94 ++++++++--
 drivers/usb/musb/sunxi.c                           |   2 +
 drivers/usb/serial/metro-usb.c                     |   1 +
 fs/crypto/keyinfo.c                                |   5 +
 fs/ecryptfs/ecryptfs_kernel.h                      |  24 ++-
 fs/ecryptfs/keystore.c                             |   9 +-
 fs/fscache/object-list.c                           |   7 +
 fs/iomap.c                                         |  14 +-
 fs/xfs/libxfs/xfs_ag_resv.c                        |  12 +-
 fs/xfs/libxfs/xfs_alloc.c                          |   8 +
 fs/xfs/libxfs/xfs_bmap.c                           |  11 ++
 fs/xfs/libxfs/xfs_bmap.h                           |   1 +
 fs/xfs/libxfs/xfs_log_format.h                     |  27 +--
 fs/xfs/xfs_acl.c                                   |  22 ++-
 fs/xfs/xfs_aops.c                                  |  50 ++++--
 fs/xfs/xfs_attr_inactive.c                         |   2 +
 fs/xfs/xfs_bmap_util.c                             |  40 ++++-
 fs/xfs/xfs_bmap_util.h                             |  13 ++
 fs/xfs/xfs_error.c                                 |   2 +-
 fs/xfs/xfs_file.c                                  |  35 ++--
 fs/xfs/xfs_fsmap.c                                 |  58 +++---
 fs/xfs/xfs_inode.c                                 |   8 +-
 fs/xfs/xfs_inode_item.c                            |  81 +++++----
 fs/xfs/xfs_iomap.c                                 |   7 +-
 fs/xfs/xfs_iomap.h                                 |   2 +-
 fs/xfs/xfs_ondisk.h                                |   2 +-
 fs/xfs/xfs_pnfs.c                                  |   2 +-
 fs/xfs/xfs_reflink.c                               |   9 +-
 include/linux/key.h                                |  47 +++--
 include/linux/mbus.h                               |   4 +-
 include/sound/control.h                            |   3 +
 lib/digsig.c                                       |   6 +
 net/can/af_can.c                                   |  14 +-
 net/dns_resolver/dns_key.c                         |   2 +-
 samples/trace_events/trace-events-sample.c         |  14 +-
 security/keys/big_key.c                            |   4 +-
 security/keys/encrypted-keys/encrypted.c           |   9 +-
 security/keys/gc.c                                 |   8 +-
 security/keys/key.c                                |  41 +++--
 security/keys/keyctl.c                             |   9 +-
 security/keys/keyring.c                            |  10 +-
 security/keys/proc.c                               |   7 +-
 security/keys/process_keys.c                       |   2 +-
 security/keys/request_key.c                        |   7 +-
 security/keys/request_key_auth.c                   |   2 +-
 security/keys/trusted.c                            |   2 +-
 security/keys/user_defined.c                       |   4 +-
 sound/core/seq/seq_lock.c                          |   4 -
 sound/core/seq/seq_lock.h                          |  12 --
 sound/core/vmaster.c                               |  31 ++++
 sound/hda/hdac_controller.c                        |   5 +
 sound/pci/hda/hda_codec.c                          |  97 +++++-----
 sound/usb/quirks.c                                 |   1 +
 tools/power/x86/turbostat/turbostat.c              |  10 +-
 99 files changed, 1091 insertions(+), 523 deletions(-)
author maintainer
#1 lore raw

PATCH 1/85 staging: bcm2835-audio: Fix memory corruption

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

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

From: Phil Elwell <[email protected]>

commit c97d96b4e612c7dc1b37d7afc61b598a9a25994d upstream.

The previous commit (0adbfd46) fixed a memory leak but also freed a block in the success case, causing a stale pointer to be used with potentially fatal results. Only free the vchi_instance block in the case that vchi_connect fails; once connected, the instance is retained for subsequent connections.

Simplifying the code by removing a bunch of gotos and returning errors directly.

Fixes 0adbfd4694c2 ("staging: bcm2835-audio: fix memory leak in bcm2835_audio_open_connection()")
---
 drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c |   19 ++++--------
 1 file changed, 7 insertions(+), 12 deletions(-)
drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c +7 -12
@@ -390,8 +390,7 @@ static int bcm2835_audio_open_connection
 			__func__, instance);
 		instance->alsa_stream = alsa_stream;
 		alsa_stream->instance = instance;
-		ret = 0; // xxx todo -1;
-		goto err_free_mem;
+		return 0;
 	}
 
 	/* Initialize and create a VCHI connection */
@@ -401,16 +400,15 @@ static int bcm2835_audio_open_connection
 			LOG_ERR("%s: failed to initialise VCHI instance (ret=%d)\n",
 				__func__, ret);
 
-			ret = -EIO;
-			goto err_free_mem;
+			return -EIO;
 		}
 		ret = vchi_connect(NULL, 0, vchi_instance);
 		if (ret) {
 			LOG_ERR("%s: failed to connect VCHI instance (ret=%d)\n",
 				__func__, ret);
 
-			ret = -EIO;
-			goto err_free_mem;
+			kfree(vchi_instance);
+			return -EIO;
 		}
 		initted = 1;
 	}
@@ -421,19 +419,16 @@ static int bcm2835_audio_open_connection
 	if (IS_ERR(instance)) {
 		LOG_ERR("%s: failed to initialize audio service\n", __func__);
 
-		ret = PTR_ERR(instance);
-		goto err_free_mem;
+		/* vchi_instance is retained for use the next time. */
+		return PTR_ERR(instance);
 	}
 
 	instance->alsa_stream = alsa_stream;
 	alsa_stream->instance = instance;
 
 	LOG_DBG(" success !\n");
-	ret = 0;
-err_free_mem:
-	kfree(vchi_instance);
 
-	return ret;
+	return 0;
 }
 
 int bcm2835_audio_open(struct bcm2835_alsa_stream *alsa_stream)
author maintainer
#2 lore raw

PATCH 2/85 USB: devio: Revert "USB: devio: Dont corrupt user memory"

In reply to Greg Kroah-Hartman

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

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

From: Hans de Goede <[email protected]>

commit 845d584f41eac3475c21e4a7d5e88d0f6e410cf7 upstream.

Taking the uurb->buffer_length userspace passes in as a maximum for the actual urbs transfer_buffer_length causes 2 serious issues:

1) It breaks isochronous support for all userspace apps using libusb, as existing libusb versions pass in 0 for uurb->buffer_length, relying on the kernel using the lenghts of the usbdevfs_iso_packet_desc descriptors passed in added together as buffer length.

This for example causes redirection of USB audio and Webcam's into virtual machines using qemu-kvm to no longer work. This is a userspace ABI break and as such must be reverted.

Note that the original commit does not protect other users / the kernels memory, it only stops the userspace process making the call from shooting itself in the foot.

2) It may cause the kernel to program host controllers to DMA over random memory. Just as the devio code used to only look at the iso_packet_desc lenghts, the host drivers do the same, relying on the submitter of the urbs to make sure the entire buffer is large enough and not checking transfer_buffer_length.

But the "USB: devio: Don't corrupt user memory" commit now takes the userspace provided uurb->buffer_length for the buffer-size while copying over the user-provided iso_packet_desc lengths 1:1, allowing the user to specify a small buffer size while programming the host controller to dma a lot more data.

(Atleast the ohci, uhci, xhci and fhci drivers do not check
transfer_buffer_length for isoc transfers.)

This reverts commit fa1ed74eb1c2 ("USB: devio: Don't corrupt user memory") fixing both these issues.

---
 drivers/usb/core/devio.c |    6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)
drivers/usb/core/devio.c +1 -5
@@ -1576,11 +1576,7 @@ static int proc_do_submiturb(struct usb_
 			totlen += isopkt[u].length;
 		}
 		u *= sizeof(struct usb_iso_packet_descriptor);
-		if (totlen <= uurb->buffer_length)
-			uurb->buffer_length = totlen;
-		else
-			WARN_ONCE(1, "uurb->buffer_length is too short %d vs %d",
-				  totlen, uurb->buffer_length);
+		uurb->buffer_length = totlen;
 		break;
 
 	default:
author maintainer
#3 lore raw

PATCH 3/85 USB: core: fix out-of-bounds access bug in usb_get_bos_descriptor()

In reply to Greg Kroah-Hartman

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

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

From: Alan Stern <[email protected]>

commit 1c0edc3633b56000e18d82fc241e3995ca18a69e upstream.

Andrey used the syzkaller fuzzer to find an out-of-bounds memory access in usb_get_bos_descriptor(). The code wasn't checking that the next usb_dev_cap_header structure could fit into the remaining buffer space.

This patch fixes the error and also reduces the bNumDeviceCaps field in the header to match the actual number of capabilities found, in cases where there are fewer than expected.

---
 drivers/usb/core/config.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/usb/core/config.c +4 -2
@@ -960,10 +960,12 @@ int usb_get_bos_descriptor(struct usb_de
 	for (i = 0; i < num; i++) {
 		buffer += length;
 		cap = (struct usb_dev_cap_header *)buffer;
-		length = cap->bLength;
 
-		if (total_len < length)
+		if (total_len < sizeof(*cap) || total_len < cap->bLength) {
+			dev->bos->desc->bNumDeviceCaps = i;
 			break;
+		}
+		length = cap->bLength;
 		total_len -= length;
 
 		if (cap->bDescriptorType != USB_DT_DEVICE_CAPABILITY) {
author maintainer
#4 lore raw

PATCH 4/85 USB: serial: metro-usb: add MS7820 device id

In reply to Greg Kroah-Hartman

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

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

From: Johan Hovold <[email protected]>

commit 31dc3f819bac28a0990b36510197560258ab7421 upstream.

Add device-id entry for (Honeywell) Metrologic MS7820 bar code scanner.

The device has two interfaces (in this mode?); a vendor-specific interface with two interrupt endpoints and a second HID interface, which we do not bind to.

---
 drivers/usb/serial/metro-usb.c |    1 +
 1 file changed, 1 insertion(+)
drivers/usb/serial/metro-usb.c +1 -0
@@ -45,6 +45,7 @@ struct metrousb_private {
 static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID_BI) },
 	{ USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID_UNI) },
+	{ USB_DEVICE_INTERFACE_CLASS(0x0c2e, 0x0730, 0xff) },	/* MS7820 */
 	{ }, /* Terminating entry. */
 };
 MODULE_DEVICE_TABLE(usb, id_table);
author maintainer
#5 lore raw

PATCH 5/85 usb: cdc_acm: Add quirk for Elatec TWN3

In reply to Greg Kroah-Hartman

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

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

From: Maksim Salau <[email protected]>

commit 765fb2f181cad669f2beb87842a05d8071f2be85 upstream.

Elatec TWN3 has the union descriptor on data interface. This results in failure to bind the device to the driver with the following log:
usb 1-1.2: new full speed USB device using streamplug-ehci and address 4 usb 1-1.2: New USB device found, idVendor=09d8, idProduct=0320 usb 1-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=0 usb 1-1.2: Product: RFID Device (COM)
usb 1-1.2: Manufacturer: OEM
cdc_acm 1-1.2:1.0: Zero length descriptor references
cdc_acm: probe of 1-1.2:1.0 failed with error -22

Adding the NO_UNION_NORMAL quirk for the device fixes the issue.

lsusb -v of the device:

Bus 001 Device 003: ID 09d8:0320
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00

  bDeviceClass            2 Communications
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0        32
  idVendor           0x09d8
  idProduct          0x0320
  bcdDevice            3.00
  iManufacturer           1 OEM
  iProduct                2 RFID Device (COM)
  iSerial                 0
  bNumConfigurations      1

Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 67
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
MaxPower 250mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 2 Communications
bInterfaceSubClass 2 Abstract (modem)
bInterfaceProtocol 1 AT-commands (v.25ter)
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0020 1x 32 bytes
bInterval 2
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 10 CDC Data
bInterfaceSubClass 0 Unused
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0020 1x 32 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0020 1x 32 bytes
bInterval 0
CDC Header:
bcdCDC 1.10
CDC Call Management:
bmCapabilities 0x03
call management
use DataInterface
bDataInterface 1
CDC ACM:
bmCapabilities 0x06
sends break
line coding and serial state
CDC Union:
bMasterInterface 0
bSlaveInterface 1
Device Status: 0x0000
(Bus Powered)

---
 drivers/usb/class/cdc-acm.c |    3 +++
 1 file changed, 3 insertions(+)
drivers/usb/class/cdc-acm.c +3 -0
@@ -1832,6 +1832,9 @@ static const struct usb_device_id acm_id
 	{ USB_DEVICE(0xfff0, 0x0100), /* DATECS FP-2000 */
 	.driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */
 	},
+	{ USB_DEVICE(0x09d8, 0x0320), /* Elatec GmbH TWN3 */
+	.driver_info = NO_UNION_NORMAL, /* has misplaced union descriptor */
+	},
 
 	{ USB_DEVICE(0x2912, 0x0001), /* ATOL FPrint */
 	.driver_info = CLEAR_HALT_CONDITIONS,
author maintainer
#6 lore raw

PATCH 7/85 usb: hub: Allow reset retry for USB2 devices on connect bounce

In reply to Greg Kroah-Hartman

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

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

From: Mathias Nyman <[email protected]>

commit 1ac7db63333db1eeff901bfd6bbcd502b4634fa4 upstream.

If the connect status change is set during reset signaling, but the status remains connected just retry port reset.

This solves an issue with connecting a 90W HP Thunderbolt 3 dock with a Lenovo Carbon x1 (5th generation) which causes a 30min loop of a high speed device being re-discovererd before usb ports starts working.

[...]

[ 389.023845] usb 3-1: new high-speed USB device number 55 using xhci_hcd
[ 389.491841] usb 3-1: new high-speed USB device number 56 using xhci_hcd
[ 389.959928] usb 3-1: new high-speed USB device number 57 using xhci_hcd

[...]

This is caused by a high speed device that doesn't successfully go to the enabled state after the second port reset. Instead the connection bounces (connected, with connect status change), bailing out completely from enumeration just to restart from scratch.

---
 drivers/usb/core/hub.c |   11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)
drivers/usb/core/hub.c +7 -4
@@ -2710,13 +2710,16 @@ static int hub_port_wait_reset(struct us
 	if (!(portstatus & USB_PORT_STAT_CONNECTION))
 		return -ENOTCONN;
 
-	/* bomb out completely if the connection bounced.  A USB 3.0
-	 * connection may bounce if multiple warm resets were issued,
+	/* Retry if connect change is set but status is still connected.
+	 * A USB 3.0 connection may bounce if multiple warm resets were issued,
 	 * but the device may have successfully re-connected. Ignore it.
 	 */
 	if (!hub_is_superspeed(hub->hdev) &&
-			(portchange & USB_PORT_STAT_C_CONNECTION))
-		return -ENOTCONN;
+	    (portchange & USB_PORT_STAT_C_CONNECTION)) {
+		usb_clear_port_feature(hub->hdev, port1,
+				       USB_PORT_FEAT_C_CONNECTION);
+		return -EAGAIN;
+	}
 
 	if (!(portstatus & USB_PORT_STAT_ENABLE))
 		return -EBUSY;
author maintainer
#7 lore raw

PATCH 8/85 ALSA: usb-audio: Add native DSD support for Pro-Ject Pre Box S2 Digital

In reply to Greg Kroah-Hartman

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

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

From: Jussi Laako <[email protected]>

commit 9bb201a5d5acc733943e8af7151cceab9d976a69 upstream.

Add native DSD support quirk for Pro-Ject Pre Box S2 Digital USB id 2772:0230.

---
 sound/usb/quirks.c |    1 +
 1 file changed, 1 insertion(+)
sound/usb/quirks.c +1 -0
@@ -1352,6 +1352,7 @@ u64 snd_usb_interface_dsd_format_quirks(
 	case USB_ID(0x20b1, 0x2008): /* Matrix Audio X-Sabre */
 	case USB_ID(0x20b1, 0x300a): /* Matrix Audio Mini-i Pro */
 	case USB_ID(0x22d9, 0x0416): /* OPPO HA-1 */
+	case USB_ID(0x2772, 0x0230): /* Pro-Ject Pre Box S2 Digital */
 		if (fp->altsetting == 2)
 			return SNDRV_PCM_FMTBIT_DSD_U32_BE;
 		break;
author maintainer
#8 lore raw

PATCH 9/85 can: gs_usb: fix busy loop if no more TX context is available

In reply to Greg Kroah-Hartman

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

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

From: Wolfgang Grandegger <[email protected]>

commit 97819f943063b622eca44d3644067c190dc75039 upstream.

If sending messages with no cable connected, it quickly happens that there is no more TX context available. Then "gs_can_start_xmit()" returns with "NETDEV_TX_BUSY" and the upper layer does retry immediately keeping the CPU busy. To fix that issue, I moved "atomic_dec(&dev->active_tx_urbs)" from "gs_usb_xmit_callback()" to the TX done handling in "gs_usb_receive_bulk_callback()". Renaming "active_tx_urbs" to "active_tx_contexts" and moving it into "gs_[alloc|free]_tx_context()" would also make sense.

---
 drivers/net/can/usb/gs_usb.c |   10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)
drivers/net/can/usb/gs_usb.c +2 -8
@@ -375,6 +375,8 @@ static void gs_usb_receive_bulk_callback
 
 		gs_free_tx_context(txc);
 
+		atomic_dec(&dev->active_tx_urbs);
+
 		netif_wake_queue(netdev);
 	}
 
@@ -463,14 +465,6 @@ static void gs_usb_xmit_callback(struct
 			  urb->transfer_buffer_length,
 			  urb->transfer_buffer,
 			  urb->transfer_dma);
-
-	atomic_dec(&dev->active_tx_urbs);
-
-	if (!netif_device_present(netdev))
-		return;
-
-	if (netif_queue_stopped(netdev))
-		netif_wake_queue(netdev);
 }
 
 static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb,
author maintainer
#9 lore raw

PATCH 10/85 scsi: qla2xxx: Fix uninitialized work element

In reply to Greg Kroah-Hartman

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

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

From: Quinn Tran <[email protected]>

commit a9e170e28636fd577249f39029d59e4e960a42b8 upstream.

Fixes following stack trace

kernel: Call Trace:
kernel: dump_stack+0x63/0x84
kernel: __warn+0xd1/0xf0
kernel: warn_slowpath_null+0x1d/0x20
kernel: __queue_work+0x37a/0x420
kernel: queue_work_on+0x27/0x40
kernel: queue_work+0x14/0x20 [qla2xxx]
kernel: schedule_work+0x13/0x20 [qla2xxx]
kernel: qla2x00_post_work+0xab/0xb0 [qla2xxx]
kernel: qla2x00_post_aen_work+0x3b/0x50 [qla2xxx]
kernel: qla2x00_async_event+0x20d/0x15d0 [qla2xxx]
kernel: ? lock_timer_base+0x7d/0xa0
kernel: qla24xx_intr_handler+0x1da/0x310 [qla2xxx]
kernel: qla2x00_poll+0x36/0x60 [qla2xxx]
kernel: qla2x00_mailbox_command+0x659/0xec0 [qla2xxx]
kernel: ? proc_create_data+0x7a/0xd0
kernel: qla25xx_init_rsp_que+0x15b/0x240 [qla2xxx]
kernel: ? request_irq+0x14/0x20 [qla2xxx]
kernel: qla25xx_create_rsp_que+0x256/0x3c0 [qla2xxx]
kernel: qla2xxx_create_qpair+0x2af/0x5b0 [qla2xxx]
kernel: qla2x00_probe_one+0x1107/0x1c30 [qla2xxx]

Fixes ec7193e26055 ("qla2xxx: Fix delayed response to command for loop mode/direct connect.")
---
 drivers/scsi/qla2xxx/qla_os.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/scsi/qla2xxx/qla_os.c +2 -1
@@ -3165,6 +3165,8 @@ qla2x00_probe_one(struct pci_dev *pdev,
 	    host->can_queue, base_vha->req,
 	    base_vha->mgmt_svr_loop_id, host->sg_tablesize);
 
+	INIT_WORK(&base_vha->iocb_work, qla2x00_iocb_work_fn);
+
 	if (ha->mqenable) {
 		bool mq = false;
 		bool startit = false;
@@ -3213,7 +3215,6 @@ qla2x00_probe_one(struct pci_dev *pdev,
 	 */
 	qla2xxx_wake_dpc(base_vha);
 
-	INIT_WORK(&base_vha->iocb_work, qla2x00_iocb_work_fn);
 	INIT_WORK(&ha->board_disable, qla2x00_disable_board_on_pci_error);
 
 	if (IS_QLA8031(ha) || IS_MCTP_CAPABLE(ha)) {
author maintainer
#10 lore raw

PATCH 11/85 nbd: dont set the device size until were connected

In reply to Greg Kroah-Hartman

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

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

From: Josef Bacik <[email protected]>

commit 639812a1ed9bf49ae2c026086fbf975339cd1eef upstream.

A user reported a regression with using the normal ioctl interface on newer kernels. This happens because I was setting the device size before the device was actually connected, which caused us to error out and close everything down. This didn't happen on netlink because we hold the device lock the whole time we're setting things up, but we don't do that for the ioctl path. This fixes the problem.

Fixes 29eaadc ("nbd: stop using the bdev everywhere")
---
 drivers/block/nbd.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/block/nbd.c +1 -1
@@ -243,7 +243,6 @@ static void nbd_size_set(struct nbd_devi
 	struct nbd_config *config = nbd->config;
 	config->blksize = blocksize;
 	config->bytesize = blocksize * nr_blocks;
-	nbd_size_update(nbd);
 }
 
 static void nbd_complete_rq(struct request *req)
@@ -1090,6 +1089,7 @@ static int nbd_start_device(struct nbd_d
 		args->index = i;
 		queue_work(recv_workqueue, &args->work);
 	}
+	nbd_size_update(nbd);
 	return error;
 }
 
author maintainer
#11 lore raw

PATCH 12/85 s390/cputime: fix guest/irq/softirq times after CPU hotplug

In reply to Greg Kroah-Hartman

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

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

From: Christian Borntraeger <[email protected]>

commit b7662eef14caf4f582d453d45395825b5a8f594c upstream.

On CPU hotplug some cpu stats contain bogus values:

$ cat /proc/stat
cpu 0 0 49 1280 0 0 0 3 0 0
cpu0 0 0 49 618 0 0 0 3 0 0
cpu1 0 0 0 662 0 0 0 0 0 0
[...]
$ echo 0 > /sys/devices/system/cpu/cpu1/online
$ echo 1 > /sys/devices/system/cpu/cpu1/online
$ cat /proc/stat
cpu 0 0 49 3200 0 450359962737 450359962737 3 0 0
cpu0 0 0 49 1956 0 0 0 3 0 0
cpu1 0 0 0 1244 0 450359962737 450359962737 0 0 0
[...]

pcpu_attach_task() needs the same assignments as vtime_task_switch.

Fixes b7394a5f4ce9 ("sched/cputime, s390: Implement delayed accounting of system time")
---
 arch/s390/kernel/smp.c |    3 +++
 1 file changed, 3 insertions(+)
arch/s390/kernel/smp.c +3 -0
@@ -293,7 +293,10 @@ static void pcpu_attach_task(struct pcpu
 	lc->lpp = LPP_MAGIC;
 	lc->current_pid = tsk->pid;
 	lc->user_timer = tsk->thread.user_timer;
+	lc->guest_timer = tsk->thread.guest_timer;
 	lc->system_timer = tsk->thread.system_timer;
+	lc->hardirq_timer = tsk->thread.hardirq_timer;
+	lc->softirq_timer = tsk->thread.softirq_timer;
 	lc->steal_timer = 0;
 }
 
author maintainer
#12 lore raw

PATCH 13/85 parisc: Fix double-word compare and exchange in LWS code on 32-bit kernels

In reply to Greg Kroah-Hartman

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

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

From: John David Anglin <[email protected]>

commit 374b3bf8e8b519f61eb9775888074c6e46b3bf0c upstream.

As discussed on the debian-hppa list, double-wordcompare and exchange operations fail on 32-bit kernels. Looking at the code, I realized that the ",ma" completer does the wrong thing in the "ldw,ma 4(%r26), %r29" instruction. This increments %r26 and causes the following store to write to the wrong location.

Note by Helge Deller:
The patch applies cleanly to stable kernel series if this upstream commit is merged in advance:
f4125cfdb300 ("parisc: Avoid trashing sr2 and sr3 in LWS code").

Fixes 89206491201c ("parisc: Implement new LWS CAS supporting 64 bit operations.")
---
 arch/parisc/kernel/syscall.S |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
arch/parisc/kernel/syscall.S +3 -3
@@ -742,7 +742,7 @@ lws_compare_and_swap_2:
 10:	ldd	0(%r25), %r25
 11:	ldd	0(%r24), %r24
 #else
-	/* Load new value into r22/r23 - high/low */
+	/* Load old value into r22/r23 - high/low */
 10:	ldw	0(%r25), %r22
 11:	ldw	4(%r25), %r23
 	/* Load new value into fr4 for atomic store later */
@@ -834,11 +834,11 @@ cas2_action:
 	copy	%r0, %r28
 #else
 	/* Compare first word */
-19:	ldw,ma	0(%r26), %r29
+19:	ldw	0(%r26), %r29
 	sub,=	%r29, %r22, %r0
 	b,n	cas2_end
 	/* Compare second word */
-20:	ldw,ma	4(%r26), %r29
+20:	ldw	4(%r26), %r29
 	sub,=	%r29, %r23, %r0
 	b,n	cas2_end
 	/* Perform the store */
author maintainer
#13 lore raw

PATCH 14/85 parisc: Fix detection of nonsynchronous cr16 cycle counters

In reply to Greg Kroah-Hartman

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

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

From: Helge Deller <[email protected]>

commit 8642b31ba9eef8a01845146a26682d4869e62513 upstream.

For CPUs which have an unknown or invalid CPU location (physical location) assume that their cycle counters aren't syncronized across CPUs.

Fixes c8c3735997a3 ("parisc: Enhance detection of synchronous cr16 clocksources")
---
 arch/parisc/kernel/time.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
arch/parisc/kernel/time.c +4 -1
@@ -253,7 +253,10 @@ static int __init init_cr16_clocksource(
 		cpu0_loc = per_cpu(cpu_data, 0).cpu_loc;
 
 		for_each_online_cpu(cpu) {
-			if (cpu0_loc == per_cpu(cpu_data, cpu).cpu_loc)
+			if (cpu == 0)
+				continue;
+			if ((cpu0_loc != 0) &&
+			    (cpu0_loc == per_cpu(cpu_data, cpu).cpu_loc))
 				continue;
 
 			clocksource_cr16.name = "cr16_unstable";
author maintainer
#14 lore raw

PATCH 15/85 iio: dummy: events: Add missing break

In reply to Greg Kroah-Hartman

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

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

From: Lars-Peter Clausen <[email protected]>

commit be94a6f6d488b4767662e8949dc62361bd1d6311 upstream.

Add missing break in iio_simple_dummy_write_event_config() for the voltage threshold event enable attribute. Without this writing to the in_voltage0_thresh_rising_en always returns -EINVAL even though the change was correctly applied.

Fixes 3e34e650db197 ("iio: dummy: Demonstrate the usage of new channel types")
---
 drivers/iio/dummy/iio_simple_dummy_events.c |    1 +
 1 file changed, 1 insertion(+)
drivers/iio/dummy/iio_simple_dummy_events.c +1 -0
@@ -72,6 +72,7 @@ int iio_simple_dummy_write_event_config(
 				st->event_en = state;
 			else
 				return -EINVAL;
+			break;
 		default:
 			return -EINVAL;
 		}
author maintainer
#15 lore raw

PATCH 16/85 usb: musb: sunxi: Explicitly release USB PHY on exit

In reply to Greg Kroah-Hartman

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

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

From: Jonathan Liu <[email protected]>

commit 6ed05c68cbcae42cd52b8e53b66952bfa9c002ce upstream.

This fixes a kernel oops when unloading the driver due to usb_put_phy being called after usb_phy_generic_unregister when the device is detached. Calling usb_phy_generic_unregister causes x->dev->driver to be NULL in usb_put_phy and results in a NULL pointer dereference.

---
 drivers/usb/musb/sunxi.c |    2 ++
 1 file changed, 2 insertions(+)
drivers/usb/musb/sunxi.c +2 -0
@@ -297,6 +297,8 @@ static int sunxi_musb_exit(struct musb *
 	if (test_bit(SUNXI_MUSB_FL_HAS_SRAM, &glue->flags))
 		sunxi_sram_release(musb->controller->parent);
 
+	devm_usb_put_phy(glue->dev, glue->xceiv);
+
 	return 0;
 }
 
author maintainer
#16 lore raw

PATCH 17/85 USB: musb: fix session-bit runtime-PM quirk

In reply to Greg Kroah-Hartman

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

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

From: Johan Hovold <[email protected]>

commit 4f190e0b9de89c4c917c3ffb3799e9d00fc534ac upstream.

The current session-bit quirk implementation does not prevent the retry counter from underflowing, something which could break runtime PM and keep the device active for a very long time (about 2^32 seconds) after a disconnect.

This notably breaks the B-device timeout case, but could potentially cause problems also when the controller is operating as an A-device.

Fixes 2bff3916fda9 ("usb: musb: Fix PM for hub disconnect")
Cc Tony Lindgren <[email protected]>
---
 drivers/usb/musb/musb_core.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/usb/musb/musb_core.c +4 -4
@@ -1861,22 +1861,22 @@ static void musb_pm_runtime_check_sessio
 		MUSB_DEVCTL_HR;
 	switch (devctl & ~s) {
 	case MUSB_QUIRK_B_INVALID_VBUS_91:
-		if (musb->quirk_retries--) {
+		if (musb->quirk_retries) {
 			musb_dbg(musb,
 				 "Poll devctl on invalid vbus, assume no session");
 			schedule_delayed_work(&musb->irq_work,
 					      msecs_to_jiffies(1000));
-
+			musb->quirk_retries--;
 			return;
 		}
 		/* fall through */
 	case MUSB_QUIRK_A_DISCONNECT_19:
-		if (musb->quirk_retries--) {
+		if (musb->quirk_retries) {
 			musb_dbg(musb,
 				 "Poll devctl on possible host mode disconnect");
 			schedule_delayed_work(&musb->irq_work,
 					      msecs_to_jiffies(1000));
-
+			musb->quirk_retries--;
 			return;
 		}
 		if (!musb->session)
author maintainer
#17 lore raw

PATCH 18/85 USB: musb: fix late external abort on suspend

In reply to Greg Kroah-Hartman

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

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

From: Johan Hovold <[email protected]>

commit 0c3aae9bd59978fb8c3557d7883380bef0f2cfa1 upstream.

The musb delayed irq work was never flushed on suspend, something which since 4.9 can lead to an external abort if the work is scheduled after the grandparent's clock has been disabled:

PM: Suspending system (mem)
PM: suspend of devices complete after 125.224 msecs
PM: suspend devices took 0.132 seconds
PM: late suspend of devices complete after 7.423 msecs
PM: noirq suspend of devices complete after 7.083 msecs
suspend debug: Waiting for 5 second(s).
Unhandled fault: external abort on non-linefetch (0x1008) at 0xd0262c60
...
[<c054880c>] (musb_default_readb) from [<c0547b5c>] (musb_irq_work+0x48/0x220) [<c0547b5c>] (musb_irq_work) from [<c014f8a4>] (process_one_work+0x1f4/0x758) [<c014f8a4>] (process_one_work) from [<c014fe5c>] (worker_thread+0x54/0x514) [<c014fe5c>] (worker_thread) from [<c015704c>] (kthread+0x128/0x158) [<c015704c>] (kthread) from [<c0109330>] (ret_from_fork+0x14/0x24)

Commit 2bff3916fda9 ("usb: musb: Fix PM for hub disconnect") started scheduling musb_irq_work with a delay of up to a second and with retries thereby making this easy to trigger, for example, by suspending shortly after a disconnect.

Note that we set a flag to prevent the irq work from rescheduling itself during suspend and instead process a disconnect immediately. This takes care of the case where we are disconnected shortly before suspending.

However, when in host mode, a disconnect while suspended will still go unnoticed and thus prevent the controller from runtime suspending upon resume as the session bit is always set. This will need to be addressed separately.

Fixes 550a7375fe72 ("USB: Add MUSB and TUSB support")
Fixes 467d5c980709 ("usb: musb: Implement session bit based runtime PM for musb-core")
Fixes 2bff3916fda9 ("usb: musb: Fix PM for hub disconnect")
Cc Felipe Balbi <[email protected]>
Cc Tony Lindgren <[email protected]>
---
 drivers/usb/musb/musb_core.c |   11 +++++++++--
 drivers/usb/musb/musb_core.h |    2 ++
 2 files changed, 11 insertions(+), 2 deletions(-)
drivers/usb/musb/musb_core.c +9 -2
@@ -1861,7 +1861,7 @@ static void musb_pm_runtime_check_sessio
 		MUSB_DEVCTL_HR;
 	switch (devctl & ~s) {
 	case MUSB_QUIRK_B_INVALID_VBUS_91:
-		if (musb->quirk_retries) {
+		if (musb->quirk_retries && !musb->flush_irq_work) {
 			musb_dbg(musb,
 				 "Poll devctl on invalid vbus, assume no session");
 			schedule_delayed_work(&musb->irq_work,
@@ -1871,7 +1871,7 @@ static void musb_pm_runtime_check_sessio
 		}
 		/* fall through */
 	case MUSB_QUIRK_A_DISCONNECT_19:
-		if (musb->quirk_retries) {
+		if (musb->quirk_retries && !musb->flush_irq_work) {
 			musb_dbg(musb,
 				 "Poll devctl on possible host mode disconnect");
 			schedule_delayed_work(&musb->irq_work,
@@ -2681,8 +2681,15 @@ static int musb_suspend(struct device *d
 
 	musb_platform_disable(musb);
 	musb_disable_interrupts(musb);
+
+	musb->flush_irq_work = true;
+	while (flush_delayed_work(&musb->irq_work))
+		;
+	musb->flush_irq_work = false;
+
 	if (!(musb->io.quirks & MUSB_PRESERVE_SESSION))
 		musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
+
 	WARN_ON(!list_empty(&musb->pending_list));
 
 	spin_lock_irqsave(&musb->lock, flags);
drivers/usb/musb/musb_core.h +2 -0
@@ -428,6 +428,8 @@ struct musb {
 	unsigned		test_mode:1;
 	unsigned		softconnect:1;
 
+	unsigned		flush_irq_work:1;
+
 	u8			address;
 	u8			test_mode_nr;
 	u16			ackpend;		/* ep0 */
author maintainer
#18 lore raw

PATCH 19/85 usb: musb: musb_cppi41: Fix the address of teardown and autoreq registers

In reply to Greg Kroah-Hartman

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

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

From: Alexandre Bailon <[email protected]>

commit bfa53e0e366b98185fadb03f7916d1538cb90ebd upstream.

The DA8xx and DSPS platforms don't use the same address for few registers. On Da8xx, this is causing some issues (e.g. teardown that doesn't work). Configure the address of the register during the init and use them instead of constants.

---
 drivers/usb/musb/musb_cppi41.c |   23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)
drivers/usb/musb/musb_cppi41.c +19 -4
@@ -26,6 +26,9 @@
 
 #define MUSB_DMA_NUM_CHANNELS 15
 
+#define DA8XX_USB_AUTOREQ	0x14
+#define DA8XX_USB_TEARDOWN	0x1c
+
 struct cppi41_dma_controller {
 	struct dma_controller controller;
 	struct cppi41_dma_channel rx_channel[MUSB_DMA_NUM_CHANNELS];
@@ -35,6 +38,9 @@ struct cppi41_dma_controller {
 	u32 rx_mode;
 	u32 tx_mode;
 	u32 auto_req;
+
+	u32 tdown_reg;
+	u32 autoreq_reg;
 };
 
 static void save_rx_toggle(struct cppi41_dma_channel *cppi41_channel)
@@ -364,8 +370,8 @@ static void cppi41_set_autoreq_mode(stru
 	if (new_mode == old_mode)
 		return;
 	controller->auto_req = new_mode;
-	musb_writel(controller->controller.musb->ctrl_base, USB_CTRL_AUTOREQ,
-		    new_mode);
+	musb_writel(controller->controller.musb->ctrl_base,
+		    controller->autoreq_reg, new_mode);
 }
 
 static bool cppi41_configure_channel(struct dma_channel *channel,
@@ -581,12 +587,13 @@ static int cppi41_dma_channel_abort(stru
 
 	do {
 		if (is_tx)
-			musb_writel(musb->ctrl_base, USB_TDOWN, tdbit);
+			musb_writel(musb->ctrl_base, controller->tdown_reg,
+				    tdbit);
 		ret = dmaengine_terminate_all(cppi41_channel->dc);
 	} while (ret == -EAGAIN);
 
 	if (is_tx) {
-		musb_writel(musb->ctrl_base, USB_TDOWN, tdbit);
+		musb_writel(musb->ctrl_base, controller->tdown_reg, tdbit);
 
 		csr = musb_readw(epio, MUSB_TXCSR);
 		if (csr & MUSB_TXCSR_TXPKTRDY) {
@@ -727,6 +734,14 @@ cppi41_dma_controller_create(struct musb
 	controller->controller.is_compatible = cppi41_is_compatible;
 	controller->controller.musb = musb;
 
+	if (musb->io.quirks & MUSB_DA8XX) {
+		controller->tdown_reg = DA8XX_USB_TEARDOWN;
+		controller->autoreq_reg = DA8XX_USB_AUTOREQ;
+	} else {
+		controller->tdown_reg = USB_TDOWN;
+		controller->autoreq_reg = USB_CTRL_AUTOREQ;
+	}
+
 	ret = cppi41_dma_controller_start(controller);
 	if (ret)
 		goto plat_get_fail;
author maintainer
#19 lore raw

PATCH 20/85 usb: musb: musb_cppi41: Fix cppi41_set_dma_mode() for DA8xx

In reply to Greg Kroah-Hartman

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

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

From: Alexandre Bailon <[email protected]>

commit e10c5b0c773efb8643ee89d387d310584ca30830 upstream.

The way to configure the DMA mode on DA8xx is different from DSPS. Add a new function to configure DMA mode on DA8xx and use a callback to call the right function based on the platform.

---
 drivers/usb/musb/musb_cppi41.c |   40 +++++++++++++++++++++++++++++++++++++---
 1 file changed, 37 insertions(+), 3 deletions(-)
drivers/usb/musb/musb_cppi41.c +37 -3
@@ -26,6 +26,7 @@
 
 #define MUSB_DMA_NUM_CHANNELS 15
 
+#define DA8XX_USB_MODE		0x10
 #define DA8XX_USB_AUTOREQ	0x14
 #define DA8XX_USB_TEARDOWN	0x1c
 
@@ -41,6 +42,9 @@ struct cppi41_dma_controller {
 
 	u32 tdown_reg;
 	u32 autoreq_reg;
+
+	void (*set_dma_mode)(struct cppi41_dma_channel *cppi41_channel,
+			     unsigned int mode);
 };
 
 static void save_rx_toggle(struct cppi41_dma_channel *cppi41_channel)
@@ -355,6 +359,32 @@ static void cppi41_set_dma_mode(struct c
 	}
 }
 
+static void da8xx_set_dma_mode(struct cppi41_dma_channel *cppi41_channel,
+		unsigned int mode)
+{
+	struct cppi41_dma_controller *controller = cppi41_channel->controller;
+	struct musb *musb = controller->controller.musb;
+	unsigned int shift;
+	u32 port;
+	u32 new_mode;
+	u32 old_mode;
+
+	old_mode = controller->tx_mode;
+	port = cppi41_channel->port_num;
+
+	shift = (port - 1) * 4;
+	if (!cppi41_channel->is_tx)
+		shift += 16;
+	new_mode = old_mode & ~(3 << shift);
+	new_mode |= mode << shift;
+
+	if (new_mode == old_mode)
+		return;
+	controller->tx_mode = new_mode;
+	musb_writel(musb->ctrl_base, DA8XX_USB_MODE, new_mode);
+}
+
+
 static void cppi41_set_autoreq_mode(struct cppi41_dma_channel *cppi41_channel,
 		unsigned mode)
 {
@@ -379,6 +409,7 @@ static bool cppi41_configure_channel(str
 				dma_addr_t dma_addr, u32 len)
 {
 	struct cppi41_dma_channel *cppi41_channel = channel->private_data;
+	struct cppi41_dma_controller *controller = cppi41_channel->controller;
 	struct dma_chan *dc = cppi41_channel->dc;
 	struct dma_async_tx_descriptor *dma_desc;
 	enum dma_transfer_direction direction;
@@ -404,7 +435,7 @@ static bool cppi41_configure_channel(str
 			musb_writel(musb->ctrl_base,
 				RNDIS_REG(cppi41_channel->port_num), len);
 			/* gen rndis */
-			cppi41_set_dma_mode(cppi41_channel,
+			controller->set_dma_mode(cppi41_channel,
 					EP_MODE_DMA_GEN_RNDIS);
 
 			/* auto req */
@@ -413,14 +444,15 @@ static bool cppi41_configure_channel(str
 		} else {
 			musb_writel(musb->ctrl_base,
 					RNDIS_REG(cppi41_channel->port_num), 0);
-			cppi41_set_dma_mode(cppi41_channel,
+			controller->set_dma_mode(cppi41_channel,
 					EP_MODE_DMA_TRANSPARENT);
 			cppi41_set_autoreq_mode(cppi41_channel,
 					EP_MODE_AUTOREQ_NONE);
 		}
 	} else {
 		/* fallback mode */
-		cppi41_set_dma_mode(cppi41_channel, EP_MODE_DMA_TRANSPARENT);
+		controller->set_dma_mode(cppi41_channel,
+				EP_MODE_DMA_TRANSPARENT);
 		cppi41_set_autoreq_mode(cppi41_channel, EP_MODE_AUTOREQ_NONE);
 		len = min_t(u32, packet_sz, len);
 	}
@@ -737,9 +769,11 @@ cppi41_dma_controller_create(struct musb
 	if (musb->io.quirks & MUSB_DA8XX) {
 		controller->tdown_reg = DA8XX_USB_TEARDOWN;
 		controller->autoreq_reg = DA8XX_USB_AUTOREQ;
+		controller->set_dma_mode = da8xx_set_dma_mode;
 	} else {
 		controller->tdown_reg = USB_TDOWN;
 		controller->autoreq_reg = USB_CTRL_AUTOREQ;
+		controller->set_dma_mode = cppi41_set_dma_mode;
 	}
 
 	ret = cppi41_dma_controller_start(controller);
author maintainer
#20 lore raw

PATCH 21/85 usb: musb: musb_cppi41: Configure the number of channels for DA8xx

In reply to Greg Kroah-Hartman

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

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

From: Alexandre Bailon <[email protected]>

commit 297d7fe9e439473800ab1f2f853b4b5f8c888500 upstream.

Currently, the number of channels is set to 15 but in the case of DA8xx, the number of channels is 4.
Update the driver to configure the number of channels at runtime.

---
 drivers/usb/musb/musb_cppi41.c |   31 ++++++++++++++++++++++++++-----
 1 file changed, 26 insertions(+), 5 deletions(-)
drivers/usb/musb/musb_cppi41.c +26 -5
@@ -30,10 +30,12 @@
 #define DA8XX_USB_AUTOREQ	0x14
 #define DA8XX_USB_TEARDOWN	0x1c
 
+#define DA8XX_DMA_NUM_CHANNELS 4
+
 struct cppi41_dma_controller {
 	struct dma_controller controller;
-	struct cppi41_dma_channel rx_channel[MUSB_DMA_NUM_CHANNELS];
-	struct cppi41_dma_channel tx_channel[MUSB_DMA_NUM_CHANNELS];
+	struct cppi41_dma_channel *rx_channel;
+	struct cppi41_dma_channel *tx_channel;
 	struct hrtimer early_tx;
 	struct list_head early_tx_list;
 	u32 rx_mode;
@@ -45,6 +47,7 @@ struct cppi41_dma_controller {
 
 	void (*set_dma_mode)(struct cppi41_dma_channel *cppi41_channel,
 			     unsigned int mode);
+	u8 num_channels;
 };
 
 static void save_rx_toggle(struct cppi41_dma_channel *cppi41_channel)
@@ -483,7 +486,7 @@ static struct dma_channel *cppi41_dma_ch
 	struct cppi41_dma_channel *cppi41_channel = NULL;
 	u8 ch_num = hw_ep->epnum - 1;
 
-	if (ch_num >= MUSB_DMA_NUM_CHANNELS)
+	if (ch_num >= controller->num_channels)
 		return NULL;
 
 	if (is_tx)
@@ -643,7 +646,7 @@ static void cppi41_release_all_dma_chans
 	struct dma_chan *dc;
 	int i;
 
-	for (i = 0; i < MUSB_DMA_NUM_CHANNELS; i++) {
+	for (i = 0; i < ctrl->num_channels; i++) {
 		dc = ctrl->tx_channel[i].dc;
 		if (dc)
 			dma_release_channel(dc);
@@ -695,7 +698,7 @@ static int cppi41_dma_controller_start(s
 			goto err;
 
 		ret = -EINVAL;
-		if (port > MUSB_DMA_NUM_CHANNELS || !port)
+		if (port > controller->num_channels || !port)
 			goto err;
 		if (is_tx)
 			cppi41_channel = &controller->tx_channel[port - 1];
@@ -736,6 +739,8 @@ void cppi41_dma_controller_destroy(struc
 
 	hrtimer_cancel(&controller->early_tx);
 	cppi41_dma_controller_stop(controller);
+	kfree(controller->rx_channel);
+	kfree(controller->tx_channel);
 	kfree(controller);
 }
 EXPORT_SYMBOL_GPL(cppi41_dma_controller_destroy);
@@ -744,6 +749,7 @@ struct dma_controller *
 cppi41_dma_controller_create(struct musb *musb, void __iomem *base)
 {
 	struct cppi41_dma_controller *controller;
+	int channel_size;
 	int ret = 0;
 
 	if (!musb->controller->parent->of_node) {
@@ -770,18 +776,33 @@ cppi41_dma_controller_create(struct musb
 		controller->tdown_reg = DA8XX_USB_TEARDOWN;
 		controller->autoreq_reg = DA8XX_USB_AUTOREQ;
 		controller->set_dma_mode = da8xx_set_dma_mode;
+		controller->num_channels = DA8XX_DMA_NUM_CHANNELS;
 	} else {
 		controller->tdown_reg = USB_TDOWN;
 		controller->autoreq_reg = USB_CTRL_AUTOREQ;
 		controller->set_dma_mode = cppi41_set_dma_mode;
+		controller->num_channels = MUSB_DMA_NUM_CHANNELS;
 	}
 
+	channel_size = controller->num_channels *
+			sizeof(struct cppi41_dma_channel);
+	controller->rx_channel = kzalloc(channel_size, GFP_KERNEL);
+	if (!controller->rx_channel)
+		goto rx_channel_alloc_fail;
+	controller->tx_channel = kzalloc(channel_size, GFP_KERNEL);
+	if (!controller->tx_channel)
+		goto tx_channel_alloc_fail;
+
 	ret = cppi41_dma_controller_start(controller);
 	if (ret)
 		goto plat_get_fail;
 	return &controller->controller;
 
 plat_get_fail:
+	kfree(controller->tx_channel);
+tx_channel_alloc_fail:
+	kfree(controller->rx_channel);
+rx_channel_alloc_fail:
 	kfree(controller);
 kzalloc_fail:
 	if (ret == -EPROBE_DEFER)
author maintainer
#21 lore raw

PATCH 22/85 usb: musb: Check for host-mode using is_host_active() on reset interrupt

In reply to Greg Kroah-Hartman

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

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

From: Jonathan Liu <[email protected]>

commit 445ef61543da3db5b699f87fb0aa4f227165f6ed upstream.

The sunxi musb has a bug where sometimes it will generate a babble error on device disconnect instead of a disconnect IRQ. When this happens the musb controller switches from host mode to device mode (it clears MUSB_DEVCTL_HM/MUSB_DEVCTL_SESSION and sets MUSB_DEVCTL_BDEVICE) and gets stuck in this state.

The babble error is misdetected as a bus reset because MUSB_DEVCTL_HM was cleared.

To fix this, use is_host_active() rather than (devctl & MUSB_DEVCTL_HM) to detect babble error so that sunxi musb babble recovery can handle it by restoring the mode. This information is provided by the driver logic and does not rely on register contents.

---
 drivers/usb/musb/musb_core.c |    6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/usb/musb/musb_core.c +2 -4
@@ -906,7 +906,7 @@ b_host:
 	 */
 	if (int_usb & MUSB_INTR_RESET) {
 		handled = IRQ_HANDLED;
-		if (devctl & MUSB_DEVCTL_HM) {
+		if (is_host_active(musb)) {
 			/*
 			 * When BABBLE happens what we can depends on which
 			 * platform MUSB is running, because some platforms
@@ -916,9 +916,7 @@ b_host:
 			 * drop the session.
 			 */
 			dev_err(musb->controller, "Babble\n");
-
-			if (is_host_active(musb))
-				musb_recover_from_babble(musb);
+			musb_recover_from_babble(musb);
 		} else {
 			musb_dbg(musb, "BUS RESET as %s",
 				usb_otg_state_string(musb->xceiv->otg->state));
author maintainer
#22 lore raw

PATCH 23/85 xhci: Identify USB 3.1 capable hosts by their port protocol capability

In reply to Greg Kroah-Hartman

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

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

From: Mathias Nyman <[email protected]>

commit ea7d0d69426cab6747ed311c53f4142eb48b9454 upstream.

Many USB 3.1 capable hosts never updated the Serial Bus Release Number (SBRN) register to USB 3.1 from USB 3.0

xhci driver identified USB 3.1 capable hosts based on this SBRN register, which according to specs "contains the release of the Universal Serial Bus Specification with which this Universal Serial Bus Host Controller module is compliant." but still in october 2017 gives USB 3.0 as the only possible option.

Make an additional check for USB 3.1 support and enable it if the xHCI supported protocol capablity lists USB 3.1 capable ports.

---
 drivers/usb/host/xhci.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/usb/host/xhci.c +2 -1
@@ -4805,7 +4805,8 @@ int xhci_gen_setup(struct usb_hcd *hcd,
 		 */
 		hcd->has_tt = 1;
 	} else {
-		if (xhci->sbrn == 0x31) {
+		/* Some 3.1 hosts return sbrn 0x30, can't rely on sbrn alone */
+		if (xhci->sbrn == 0x31 || xhci->usb3_rhub.min_rev >= 1) {
 			xhci_info(xhci, "Host supports USB 3.1 Enhanced SuperSpeed\n");
 			hcd->speed = HCD_USB31;
 			hcd->self.root_hub->speed = USB_SPEED_SUPER_PLUS;
author maintainer
#23 lore raw

PATCH 24/85 xhci: Cleanup current_cmd in xhci_cleanup_command_queue()

In reply to Greg Kroah-Hartman

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

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

From: Jeffy Chen <[email protected]>

commit d1aad52cf8b3f95dfe9b5b64da66343306ddf73b upstream.

KASAN reported use-after-free bug when xhci host controller died:

[  176.952537] BUG: KASAN: use-after-free in xhci_handle_command_timeout+0x68/0x224
[  176.960846] Write of size 4 at addr ffffffc0cbb01608 by task kworker/3:3/1680
...
[  177.180644] Freed by task 0:
[  177.183882]  kasan_slab_free+0x90/0x15c
[  177.188194]  kfree+0x114/0x28c
[  177.191630]  xhci_cleanup_command_queue+0xc8/0xf8
[  177.196916]  xhci_hc_died+0x84/0x358

Problem here is that when the cmd_timer fired, it would try to access current_cmd while the command queue is already freed by xhci_hc_died().

Cleanup current_cmd in xhci_cleanup_command_queue() to avoid that.

Fixes d9f11ba9f107 ("xhci: Rework how we handle unresponsive or hoptlug removed hosts")
---
 drivers/usb/host/xhci-ring.c |    1 +
 1 file changed, 1 insertion(+)
drivers/usb/host/xhci-ring.c +1 -0
@@ -1309,6 +1309,7 @@ static void xhci_complete_del_and_free_c
 void xhci_cleanup_command_queue(struct xhci_hcd *xhci)
 {
 	struct xhci_command *cur_cmd, *tmp_cmd;
+	xhci->current_cmd = NULL;
 	list_for_each_entry_safe(cur_cmd, tmp_cmd, &xhci->cmd_list, cmd_list)
 		xhci_complete_del_and_free_cmd(cur_cmd, COMP_COMMAND_ABORTED);
 }
author maintainer
#24 lore raw

PATCH 25/85 usb: xhci: Reset halted endpoint if trb is noop

In reply to Greg Kroah-Hartman

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

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

From: Lu Baolu <[email protected]>

commit 810a624bd1b64b13ddcc2eb5c1880526a750a870 upstream.

When a URB is cancled, xhci driver turns the untransferred trbs into no-ops. If an endpoint stalls on a no-op trb that belongs to the cancelled URB, the event handler won't reset the endpoint. Hence, it will stay halted.

---
 drivers/usb/host/xhci-ring.c |   20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)
drivers/usb/host/xhci-ring.c +13 -7
@@ -2578,15 +2578,21 @@ static int handle_tx_event(struct xhci_h
 				(struct xhci_generic_trb *) ep_trb);
 
 		/*
-		 * No-op TRB should not trigger interrupts.
-		 * If ep_trb is a no-op TRB, it means the
-		 * corresponding TD has been cancelled. Just ignore
-		 * the TD.
+		 * No-op TRB could trigger interrupts in a case where
+		 * a URB was killed and a STALL_ERROR happens right
+		 * after the endpoint ring stopped. Reset the halted
+		 * endpoint. Otherwise, the endpoint remains stalled
+		 * indefinitely.
 		 */
 		if (trb_is_noop(ep_trb)) {
-			xhci_dbg(xhci,
-				 "ep_trb is a no-op TRB. Skip it for slot %u ep %u\n",
-				 slot_id, ep_index);
+			if (trb_comp_code == COMP_STALL_ERROR ||
+			    xhci_requires_manual_halt_cleanup(xhci, ep_ctx,
+							      trb_comp_code))
+				xhci_cleanup_halted_endpoint(xhci, slot_id,
+							     ep_index,
+							     ep_ring->stream_id,
+							     td, ep_trb,
+							     EP_HARD_RESET);
 			goto cleanup;
 		}
 
author maintainer
#25 lore raw

PATCH 26/85 usb: xhci: Handle error condition in xhci_stop_device()

In reply to Greg Kroah-Hartman

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

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

From: Mayank Rana <[email protected]>

commit b3207c65dfafae27e7c492cb9188c0dc0eeaf3fd upstream.

xhci_stop_device() calls xhci_queue_stop_endpoint() multiple times without checking the return value. xhci_queue_stop_endpoint() can return error if the HC is already halted or unable to queue commands. This can cause a deadlock condition as xhci_stop_device() would end up waiting indefinitely for a completion for the command that didn't get queued. Fix this by checking the return value and bailing out of xhci_stop_device() in case of error. This patch happens to fix potential memory leaks of the allocated command structures as well.

Fixes c311e391a7ef ("xhci: rework command timeout and cancellation,")
---
 drivers/usb/host/xhci-hub.c |   23 ++++++++++++++++++-----
 1 file changed, 18 insertions(+), 5 deletions(-)
drivers/usb/host/xhci-hub.c +18 -5
@@ -420,14 +420,25 @@ static int xhci_stop_device(struct xhci_
 						     GFP_NOWAIT);
 			if (!command) {
 				spin_unlock_irqrestore(&xhci->lock, flags);
-				xhci_free_command(xhci, cmd);
-				return -ENOMEM;
+				ret = -ENOMEM;
+				goto cmd_cleanup;
+			}
+
+			ret = xhci_queue_stop_endpoint(xhci, command, slot_id,
+						       i, suspend);
+			if (ret) {
+				spin_unlock_irqrestore(&xhci->lock, flags);
+				xhci_free_command(xhci, command);
+				goto cmd_cleanup;
 			}
-			xhci_queue_stop_endpoint(xhci, command, slot_id, i,
-						 suspend);
 		}
 	}
-	xhci_queue_stop_endpoint(xhci, cmd, slot_id, 0, suspend);
+	ret = xhci_queue_stop_endpoint(xhci, cmd, slot_id, 0, suspend);
+	if (ret) {
+		spin_unlock_irqrestore(&xhci->lock, flags);
+		goto cmd_cleanup;
+	}
+
 	xhci_ring_cmd_db(xhci);
 	spin_unlock_irqrestore(&xhci->lock, flags);
 
@@ -439,6 +450,8 @@ static int xhci_stop_device(struct xhci_
 		xhci_warn(xhci, "Timeout while waiting for stop endpoint command\n");
 		ret = -ETIME;
 	}
+
+cmd_cleanup:
 	xhci_free_command(xhci, cmd);
 	return ret;
 }
author maintainer
#26 lore raw

PATCH 28/85 can: af_can: can_pernet_init(): add missing error handling for kzalloc returning NULL

In reply to Greg Kroah-Hartman

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

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

From: Marc Kleine-Budde <[email protected]>

commit 5a606223c6b5b7560da253ed52e62c67fa18e29b upstream.

This patch adds the missing check and error handling for out-of-memory situations, when kzalloc cannot allocate memory.

Fixes cb5635a36776 ("can: complete initial namespace support")
---
 net/can/af_can.c |   14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)
net/can/af_can.c +13 -1
@@ -875,9 +875,14 @@ static int can_pernet_init(struct net *n
 	spin_lock_init(&net->can.can_rcvlists_lock);
 	net->can.can_rx_alldev_list =
 		kzalloc(sizeof(struct dev_rcv_lists), GFP_KERNEL);
-
+	if (!net->can.can_rx_alldev_list)
+		goto out;
 	net->can.can_stats = kzalloc(sizeof(struct s_stats), GFP_KERNEL);
+	if (!net->can.can_stats)
+		goto out_free_alldev_list;
 	net->can.can_pstats = kzalloc(sizeof(struct s_pstats), GFP_KERNEL);
+	if (!net->can.can_pstats)
+		goto out_free_can_stats;
 
 	if (IS_ENABLED(CONFIG_PROC_FS)) {
 		/* the statistics are updated every second (timer triggered) */
@@ -892,6 +897,13 @@ static int can_pernet_init(struct net *n
 	}
 
 	return 0;
+
+ out_free_can_stats:
+	kfree(net->can.can_stats);
+ out_free_alldev_list:
+	kfree(net->can.can_rx_alldev_list);
+ out:
+	return -ENOMEM;
 }
 
 static void can_pernet_exit(struct net *net)
author maintainer
#27 lore raw

PATCH 29/85 can: flexcan: fix state transition regression

In reply to Greg Kroah-Hartman

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

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

From: ZHU Yi (ST-FIR/ENG1-Zhu) <[email protected]>

commit ad2302345d59d29232cb668baaae9e840925d153 upstream.

Update state upon any interrupt to report correct state transitions in case the flexcan core enabled the broken error state quirk fix.

---
 drivers/net/can/flexcan.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/net/can/flexcan.c +3 -2
@@ -765,8 +765,9 @@ static irqreturn_t flexcan_irq(int irq,
 		flexcan_write(reg_esr & FLEXCAN_ESR_ALL_INT, &regs->esr);
 	}
 
-	/* state change interrupt */
-	if (reg_esr & FLEXCAN_ESR_ERR_STATE)
+	/* state change interrupt or broken error state quirk fix is enabled */
+	if ((reg_esr & FLEXCAN_ESR_ERR_STATE) ||
+	    (priv->devtype_data->quirks & FLEXCAN_QUIRK_BROKEN_ERR_STATE))
 		flexcan_irq_state(dev, reg_esr);
 
 	/* bus error IRQ - handle if bus error reporting is activated */
author maintainer
#28 lore raw

PATCH 30/85 can: flexcan: rename legacy error state quirk

In reply to Greg Kroah-Hartman

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

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

From: ZHU Yi (ST-FIR/ENG1-Zhu) <[email protected]>

commit 2f8639b24b4f4f9dd6cf7c1f2aea90e2fcbcc451 upstream.

Rename FLEXCAN_QUIRK_BROKEN_ERR_STATE to FLEXCAN_QUIRK_BROKEN_WERR_STATE for better description of the missing [TR]WRN_INT quirk.

---
 drivers/net/can/flexcan.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/net/can/flexcan.c +4 -4
@@ -193,7 +193,7 @@
  *
  * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected.
  */
-#define FLEXCAN_QUIRK_BROKEN_ERR_STATE	BIT(1) /* [TR]WRN_INT not connected */
+#define FLEXCAN_QUIRK_BROKEN_WERR_STATE	BIT(1) /* [TR]WRN_INT not connected */
 #define FLEXCAN_QUIRK_DISABLE_RXFG	BIT(2) /* Disable RX FIFO Global mask */
 #define FLEXCAN_QUIRK_ENABLE_EACEN_RRS	BIT(3) /* Enable EACEN and RRS bit in ctrl2 */
 #define FLEXCAN_QUIRK_DISABLE_MECR	BIT(4) /* Disable Memory error detection */
@@ -281,7 +281,7 @@ struct flexcan_priv {
 };
 
 static const struct flexcan_devtype_data fsl_p1010_devtype_data = {
-	.quirks = FLEXCAN_QUIRK_BROKEN_ERR_STATE,
+	.quirks = FLEXCAN_QUIRK_BROKEN_WERR_STATE,
 };
 
 static const struct flexcan_devtype_data fsl_imx28_devtype_data;
@@ -767,7 +767,7 @@ static irqreturn_t flexcan_irq(int irq,
 
 	/* state change interrupt or broken error state quirk fix is enabled */
 	if ((reg_esr & FLEXCAN_ESR_ERR_STATE) ||
-	    (priv->devtype_data->quirks & FLEXCAN_QUIRK_BROKEN_ERR_STATE))
+	    (priv->devtype_data->quirks & FLEXCAN_QUIRK_BROKEN_WERR_STATE))
 		flexcan_irq_state(dev, reg_esr);
 
 	/* bus error IRQ - handle if bus error reporting is activated */
@@ -888,7 +888,7 @@ static int flexcan_chip_start(struct net
 	 * on most Flexcan cores, too. Otherwise we don't get
 	 * any error warning or passive interrupts.
 	 */
-	if (priv->devtype_data->quirks & FLEXCAN_QUIRK_BROKEN_ERR_STATE ||
+	if (priv->devtype_data->quirks & FLEXCAN_QUIRK_BROKEN_WERR_STATE ||
 	    priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)
 		reg_ctrl |= FLEXCAN_CTRL_ERR_MSK;
 	else
author maintainer
#29 lore raw

PATCH 31/85 can: flexcan: implement error passive state quirk

In reply to Greg Kroah-Hartman

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

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

From: ZHU Yi (ST-FIR/ENG1-Zhu) <[email protected]>

commit da49a8075c00b4d98ef069a0ee201177a8b79ead upstream.

Add FLEXCAN_QUIRK_BROKEN_PERR_STATE for better description of the missing error passive interrupt quirk.

Error interrupt flooding may happen if the broken error state quirk fix is enabled. For example, in case there is singled out node on the bus and the node sends a frame, then error interrupt flooding happens and will not stop because the node cannot go to bus off. The flooding will stop after another node connected to the bus again.

If high bitrate configured on the low end system, then the flooding may causes performance issue, hence, this patch mitigates this by:
1. disable error interrupt upon error passive state transition
2. re-enable error interrupt upon error warning state transition
3. disable/enable error interrupt upon error active state transition depends on FLEXCAN_QUIRK_BROKEN_WERR_STATE

In this way, the driver is still able to report correct state transitions without additional latency. When there are bus problems, flooding of error interrupts is limited to the number of frames required to change state from error warning to error passive if the core has [TR]WRN_INT connected (FLEXCAN_QUIRK_BROKEN_WERR_STATE is not enabled), otherwise, the flooding is limited to the number of frames required to change state from error active to error passive.

---
 drivers/net/can/flexcan.c |   75 ++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 66 insertions(+), 9 deletions(-)
drivers/net/can/flexcan.c +66 -9
@@ -182,14 +182,14 @@
 /* FLEXCAN hardware feature flags
  *
  * Below is some version info we got:
- *    SOC   Version   IP-Version  Glitch- [TR]WRN_INT Memory err RTR re-
- *                                Filter? connected?  detection  ception in MB
- *   MX25  FlexCAN2  03.00.00.00     no        no         no        no
- *   MX28  FlexCAN2  03.00.04.00    yes       yes         no        no
- *   MX35  FlexCAN2  03.00.00.00     no        no         no        no
- *   MX53  FlexCAN2  03.00.00.00    yes        no         no        no
- *   MX6s  FlexCAN3  10.00.12.00    yes       yes         no       yes
- *   VF610 FlexCAN3  ?               no       yes        yes       yes?
+ *    SOC   Version   IP-Version  Glitch- [TR]WRN_INT IRQ Err Memory err RTR re-
+ *                                Filter? connected?  Passive detection  ception in MB
+ *   MX25  FlexCAN2  03.00.00.00     no        no         ?       no        no
+ *   MX28  FlexCAN2  03.00.04.00    yes       yes        no       no        no
+ *   MX35  FlexCAN2  03.00.00.00     no        no         ?       no        no
+ *   MX53  FlexCAN2  03.00.00.00    yes        no        no       no        no
+ *   MX6s  FlexCAN3  10.00.12.00    yes       yes        no       no       yes
+ *   VF610 FlexCAN3  ?               no       yes         ?      yes       yes?
  *
  * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected.
  */
@@ -198,6 +198,7 @@
 #define FLEXCAN_QUIRK_ENABLE_EACEN_RRS	BIT(3) /* Enable EACEN and RRS bit in ctrl2 */
 #define FLEXCAN_QUIRK_DISABLE_MECR	BIT(4) /* Disable Memory error detection */
 #define FLEXCAN_QUIRK_USE_OFF_TIMESTAMP	BIT(5) /* Use timestamp based offloading */
+#define FLEXCAN_QUIRK_BROKEN_PERR_STATE	BIT(6) /* No interrupt for error passive */
 
 /* Structure of the message buffer */
 struct flexcan_mb {
@@ -335,6 +336,22 @@ static inline void flexcan_write(u32 val
 }
 #endif
 
+static inline void flexcan_error_irq_enable(const struct flexcan_priv *priv)
+{
+	struct flexcan_regs __iomem *regs = priv->regs;
+	u32 reg_ctrl = (priv->reg_ctrl_default | FLEXCAN_CTRL_ERR_MSK);
+
+	flexcan_write(reg_ctrl, &regs->ctrl);
+}
+
+static inline void flexcan_error_irq_disable(const struct flexcan_priv *priv)
+{
+	struct flexcan_regs __iomem *regs = priv->regs;
+	u32 reg_ctrl = (priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_MSK);
+
+	flexcan_write(reg_ctrl, &regs->ctrl);
+}
+
 static inline int flexcan_transceiver_enable(const struct flexcan_priv *priv)
 {
 	if (!priv->reg_xceiver)
@@ -713,6 +730,7 @@ static irqreturn_t flexcan_irq(int irq,
 	struct flexcan_regs __iomem *regs = priv->regs;
 	irqreturn_t handled = IRQ_NONE;
 	u32 reg_iflag1, reg_esr;
+	enum can_state last_state = priv->can.state;
 
 	reg_iflag1 = flexcan_read(&regs->iflag1);
 
@@ -767,7 +785,8 @@ static irqreturn_t flexcan_irq(int irq,
 
 	/* state change interrupt or broken error state quirk fix is enabled */
 	if ((reg_esr & FLEXCAN_ESR_ERR_STATE) ||
-	    (priv->devtype_data->quirks & FLEXCAN_QUIRK_BROKEN_WERR_STATE))
+	    (priv->devtype_data->quirks & (FLEXCAN_QUIRK_BROKEN_WERR_STATE |
+	                                   FLEXCAN_QUIRK_BROKEN_PERR_STATE)))
 		flexcan_irq_state(dev, reg_esr);
 
 	/* bus error IRQ - handle if bus error reporting is activated */
@@ -775,6 +794,44 @@ static irqreturn_t flexcan_irq(int irq,
 	    (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING))
 		flexcan_irq_bus_err(dev, reg_esr);
 
+	/* availability of error interrupt among state transitions in case
+	 * bus error reporting is de-activated and
+	 * FLEXCAN_QUIRK_BROKEN_PERR_STATE is enabled:
+	 *  +--------------------------------------------------------------+
+	 *  | +----------------------------------------------+ [stopped /  |
+	 *  | |                                              |  sleeping] -+
+	 *  +-+-> active <-> warning <-> passive -> bus off -+
+	 *        ___________^^^^^^^^^^^^_______________________________
+	 *        disabled(1)  enabled             disabled
+	 *
+	 * (1): enabled if FLEXCAN_QUIRK_BROKEN_WERR_STATE is enabled
+	 */
+	if ((last_state != priv->can.state) &&
+	    (priv->devtype_data->quirks & FLEXCAN_QUIRK_BROKEN_PERR_STATE) &&
+	    !(priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)) {
+		switch (priv->can.state) {
+		case CAN_STATE_ERROR_ACTIVE:
+			if (priv->devtype_data->quirks &
+			    FLEXCAN_QUIRK_BROKEN_WERR_STATE)
+				flexcan_error_irq_enable(priv);
+			else
+				flexcan_error_irq_disable(priv);
+			break;
+
+		case CAN_STATE_ERROR_WARNING:
+			flexcan_error_irq_enable(priv);
+			break;
+
+		case CAN_STATE_ERROR_PASSIVE:
+		case CAN_STATE_BUS_OFF:
+			flexcan_error_irq_disable(priv);
+			break;
+
+		default:
+			break;
+		}
+	}
+
 	return handled;
 }
 
author maintainer
#30 lore raw

PATCH 32/85 can: flexcan: fix i.MX6 state transition issue

In reply to Greg Kroah-Hartman

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

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

From: ZHU Yi (ST-FIR/ENG1-Zhu) <[email protected]>

commit cf9c04677f2bf599b44511963039ec6e25583feb upstream.

Enable FLEXCAN_QUIRK_BROKEN_PERR_STATE for i.MX6 to report correct state transitions.

---
 drivers/net/can/flexcan.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/can/flexcan.c +1 -1
@@ -289,7 +289,7 @@ static const struct flexcan_devtype_data
 
 static const struct flexcan_devtype_data fsl_imx6q_devtype_data = {
 	.quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS |
-		FLEXCAN_QUIRK_USE_OFF_TIMESTAMP,
+		FLEXCAN_QUIRK_USE_OFF_TIMESTAMP | FLEXCAN_QUIRK_BROKEN_PERR_STATE,
 };
 
 static const struct flexcan_devtype_data fsl_vf610_devtype_data = {
author maintainer
#31 lore raw

PATCH 33/85 can: flexcan: fix i.MX28 state transition issue

In reply to Greg Kroah-Hartman

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

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

From: ZHU Yi (ST-FIR/ENG1-Zhu) <[email protected]>

commit 083c5571290a2d4308b75f1a59cf376b6e907808 upstream.

Enable FLEXCAN_QUIRK_BROKEN_PERR_STATE for i.MX28 to report correct state transitions, especially to error passive.

drivers/net/can/flexcan.c +3 -1
index d6ad12744ff1..ed544c44848f 100644
@@ -285,7 +285,9 @@ static const struct flexcan_devtype_data fsl_p1010_devtype_data = {
 	.quirks = FLEXCAN_QUIRK_BROKEN_WERR_STATE,
 };
 
-static const struct flexcan_devtype_data fsl_imx28_devtype_data;
+static const struct flexcan_devtype_data fsl_imx28_devtype_data = {
+	.quirks = FLEXCAN_QUIRK_BROKEN_PERR_STATE,
+};
 
 static const struct flexcan_devtype_data fsl_imx6q_devtype_data = {
 	.quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS |
author maintainer
#32 lore raw

PATCH 34/85 can: flexcan: fix p1010 state transition issue

In reply to Greg Kroah-Hartman

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

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

From: ZHU Yi (ST-FIR/ENG1-Zhu) <[email protected]>

commit fb5b91d61bebc24686ffc379138fd67808b1a1e6 upstream.

Enable FLEXCAN_QUIRK_BROKEN_WERR_STATE and FLEXCAN_QUIRK_BROKEN_PERR_STATE for p1010 to report correct state transitions.

---
 drivers/net/can/flexcan.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/can/flexcan.c +2 -1
@@ -282,7 +282,8 @@ struct flexcan_priv {
 };
 
 static const struct flexcan_devtype_data fsl_p1010_devtype_data = {
-	.quirks = FLEXCAN_QUIRK_BROKEN_WERR_STATE,
+	.quirks = FLEXCAN_QUIRK_BROKEN_WERR_STATE |
+		FLEXCAN_QUIRK_BROKEN_PERR_STATE,
 };
 
 static const struct flexcan_devtype_data fsl_imx28_devtype_data = {
author maintainer
#33 lore raw

PATCH 35/85 KEYS: encrypted: fix dereference of NULL user_key_payload

In reply to Greg Kroah-Hartman

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

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

From: Eric Biggers <[email protected]>

commit 13923d0865ca96312197962522e88bc0aedccd74 upstream.

A key of type "encrypted" references a "master key" which is used to encrypt and decrypt the encrypted key's payload. However, when we accessed the master key's payload, we failed to handle the case where the master key has been revoked, which sets the payload pointer to NULL. Note that request_key() *does* skip revoked keys, but there is still a window where the key can be revoked before we acquire its semaphore.

Fix it by checking for a NULL payload, treating it like a key which was already revoked at the time it was requested.

This was an issue for master keys of type "user" only. Master keys can also be of type "trusted", but those cannot be revoked.

Fixes 7e70cb497850 ("keys: add new key-type encrypted")
Cc Mimi Zohar <[email protected]>
Cc David Safford <[email protected]>
---
 security/keys/encrypted-keys/encrypted.c |    7 +++++++
 1 file changed, 7 insertions(+)
security/keys/encrypted-keys/encrypted.c +7 -0
@@ -309,6 +309,13 @@ static struct key *request_user_key(cons
 
 	down_read(&ukey->sem);
 	upayload = user_key_payload_locked(ukey);
+	if (!upayload) {
+		/* key was revoked before we acquired its semaphore */
+		up_read(&ukey->sem);
+		key_put(ukey);
+		ukey = ERR_PTR(-EKEYREVOKED);
+		goto error;
+	}
 	*master_key = upayload->data;
 	*master_keylen = upayload->datalen;
 error:
author maintainer
#34 lore raw

PATCH 36/85 mmc: sdhci-pci: Fix default d3_retune for Intel host controllers

In reply to Greg Kroah-Hartman

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

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

From: Adrian Hunter <[email protected]>

commit eb701ce16a45ed9880897c48f05ee608d77c72e3 upstream.

The default for d3_retune is true, but that was not being set in all cases, which results in eMMC errors because re-tuning has not been done. Fix by initializing d3_retune to true.

Fixes c959a6b00ff5 ("mmc: sdhci-pci: Don't re-tune with runtime pm for some Intel devices")
Reported-and-tested-by ojab <[email protected]>
---
 drivers/mmc/host/sdhci-pci-core.c |    2 ++
 1 file changed, 2 insertions(+)
drivers/mmc/host/sdhci-pci-core.c +2 -0
@@ -449,6 +449,8 @@ static void intel_dsm_init(struct intel_
 	int err;
 	u32 val;
 
+	intel_host->d3_retune = true;
+
 	err = __intel_dsm(intel_host, dev, INTEL_DSM_FNS, &intel_host->dsm_fns);
 	if (err) {
 		pr_debug("%s: DSM not supported, error %d\n",
author maintainer
#35 lore raw

PATCH 38/85 drm/nouveau/kms/nv50: fix oops during DP IRQ handling on non-MST boards

In reply to Greg Kroah-Hartman

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

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

From: Ben Skeggs <[email protected]>

commit 227f66d2f9954f68375736af62ebcd73c6754d69 upstream.

---
 drivers/gpu/drm/nouveau/nv50_display.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/gpu/drm/nouveau/nv50_display.c +4 -1
@@ -3281,11 +3281,14 @@ nv50_mstm = {
 void
 nv50_mstm_service(struct nv50_mstm *mstm)
 {
-	struct drm_dp_aux *aux = mstm->mgr.aux;
+	struct drm_dp_aux *aux = mstm ? mstm->mgr.aux : NULL;
 	bool handled = true;
 	int ret;
 	u8 esi[8] = {};
 
+	if (!aux)
+		return;
+
 	while (handled) {
 		ret = drm_dp_dpcd_read(aux, DP_SINK_COUNT_ESI, esi, 8);
 		if (ret != 8) {
author maintainer
#36 lore raw

PATCH 39/85 drm/nouveau/bsp/g92: disable by default

In reply to Greg Kroah-Hartman

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

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

From: Ilia Mirkin <[email protected]>

commit 194d68dd051c2dd5ac2b522ae16100e774e8d869 upstream.

G92's seem to require some additional bit of initialization before the BSP engine can work. It feels like clocks are not set up for the underlying VLD engine, which means that all commands submitted to the xtensa chip end up hanging. VP seems to work fine though.

This still allows people to force-enable the bsp engine if they want to play around with it, but makes it harder for the card to hang by default.

---
 drivers/gpu/drm/nouveau/nvkm/engine/bsp/g84.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/nouveau/nvkm/engine/bsp/g84.c +1 -1
@@ -39,5 +39,5 @@ int
 g84_bsp_new(struct nvkm_device *device, int index, struct nvkm_engine **pengine)
 {
 	return nvkm_xtensa_new_(&g84_bsp, device, index,
-				true, 0x103000, pengine);
+				device->chipset != 0x92, 0x103000, pengine);
 }
author maintainer
#37 lore raw

PATCH 40/85 drm/nouveau/mmu: flush tlbs before deleting page tables

In reply to Greg Kroah-Hartman

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

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

From: Ben Skeggs <[email protected]>

commit 77913bbcb43ac9a07a6fe849c2fd3bf85fc8bdd8 upstream.

Even though we've zeroed the PDE, the GPU may have cached the PD, so we need to flush when deleting them.

Noticed while working on replacement MMU code, but a backport might be a good idea, so let's fix it in the current code too.

---
 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c |    2 ++
 1 file changed, 2 insertions(+)
drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c +2 -0
@@ -241,6 +241,8 @@ nvkm_vm_unmap_pgt(struct nvkm_vm *vm, in
 			mmu->func->map_pgt(vpgd->obj, pde, vpgt->mem);
 		}
 
+		mmu->func->flush(vm);
+
 		nvkm_memory_del(&pgt);
 	}
 }
author maintainer
#38 lore raw

PATCH 41/85 media: s5p-cec: add NACK detection support

In reply to Greg Kroah-Hartman

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

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

From: Hans Verkuil <[email protected]>

commit e949f61461ab83b094cad564c89a8d2b078b4508 upstream.

The s5p-cec driver returned CEC_TX_STATUS_ERROR for the NACK condition.

Some digging into the datasheet uncovered the S5P_CEC_TX_STAT1 register where bit 0 indicates if the transmit was nacked or not.

Use this to return the correct CEC_TX_STATUS_NACK status to userspace.

This was the only driver that couldn't tell a NACK from another error, and that was very unusual. And a potential problem for applications as well.

Tested with my Odroid-U3.

---
 drivers/media/platform/s5p-cec/exynos_hdmi_cecctrl.c |    3 ++-
 drivers/media/platform/s5p-cec/s5p_cec.c             |   11 ++++++++++-
 drivers/media/platform/s5p-cec/s5p_cec.h             |    2 ++
 3 files changed, 14 insertions(+), 2 deletions(-)
drivers/media/platform/s5p-cec/exynos_hdmi_cecctrl.c +2 -1
@@ -172,7 +172,8 @@ u32 s5p_cec_get_status(struct s5p_cec_de
 {
 	u32 status = 0;
 
-	status = readb(cec->reg + S5P_CEC_STATUS_0);
+	status = readb(cec->reg + S5P_CEC_STATUS_0) & 0xf;
+	status |= (readb(cec->reg + S5P_CEC_TX_STAT1) & 0xf) << 4;
 	status |= readb(cec->reg + S5P_CEC_STATUS_1) << 8;
 	status |= readb(cec->reg + S5P_CEC_STATUS_2) << 16;
 	status |= readb(cec->reg + S5P_CEC_STATUS_3) << 24;
drivers/media/platform/s5p-cec/s5p_cec.c +10 -1
@@ -92,7 +92,10 @@ static irqreturn_t s5p_cec_irq_handler(i
 	dev_dbg(cec->dev, "irq received\n");
 
 	if (status & CEC_STATUS_TX_DONE) {
-		if (status & CEC_STATUS_TX_ERROR) {
+		if (status & CEC_STATUS_TX_NACK) {
+			dev_dbg(cec->dev, "CEC_STATUS_TX_NACK set\n");
+			cec->tx = STATE_NACK;
+		} else if (status & CEC_STATUS_TX_ERROR) {
 			dev_dbg(cec->dev, "CEC_STATUS_TX_ERROR set\n");
 			cec->tx = STATE_ERROR;
 		} else {
@@ -135,6 +138,12 @@ static irqreturn_t s5p_cec_irq_handler_t
 		cec_transmit_done(cec->adap, CEC_TX_STATUS_OK, 0, 0, 0, 0);
 		cec->tx = STATE_IDLE;
 		break;
+	case STATE_NACK:
+		cec_transmit_done(cec->adap,
+			CEC_TX_STATUS_MAX_RETRIES | CEC_TX_STATUS_NACK,
+			0, 1, 0, 0);
+		cec->tx = STATE_IDLE;
+		break;
 	case STATE_ERROR:
 		cec_transmit_done(cec->adap,
 			CEC_TX_STATUS_MAX_RETRIES | CEC_TX_STATUS_ERROR,
drivers/media/platform/s5p-cec/s5p_cec.h +2 -0
@@ -35,6 +35,7 @@
 #define CEC_STATUS_TX_TRANSFERRING	(1 << 1)
 #define CEC_STATUS_TX_DONE		(1 << 2)
 #define CEC_STATUS_TX_ERROR		(1 << 3)
+#define CEC_STATUS_TX_NACK		(1 << 4)
 #define CEC_STATUS_TX_BYTES		(0xFF << 8)
 #define CEC_STATUS_RX_RUNNING		(1 << 16)
 #define CEC_STATUS_RX_RECEIVING		(1 << 17)
@@ -55,6 +56,7 @@ enum cec_state {
 	STATE_IDLE,
 	STATE_BUSY,
 	STATE_DONE,
+	STATE_NACK,
 	STATE_ERROR
 };
 
author maintainer
#39 lore raw

PATCH 42/85 media: cec: Respond to unregistered initiators, when applicable

In reply to Greg Kroah-Hartman

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

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

From: Jose Abreu <[email protected]>

commit 845d6524d69b40bd6abd61dc1264a8657159aa55 upstream.

Running CEC 1.4 compliance test we get the following error on test 11.1.6.2: "ERROR: The DUT did not broadcast a
<Report Physical Address> message to the unregistered device."

Fix this by letting GIVE_PHYSICAL_ADDR message respond to unregistered device. Also, GIVE_DEVICE_VENDOR_ID and GIVE_FEATURES fall in the same category so, respond also to these messages.

With this fix we pass CEC 1.4 official compliance.

---
 drivers/media/cec/cec-adap.c |   13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)
drivers/media/cec/cec-adap.c +10 -3
@@ -1726,12 +1726,19 @@ static int cec_receive_notify(struct cec
 	 */
 	switch (msg->msg[1]) {
 	case CEC_MSG_GET_CEC_VERSION:
-	case CEC_MSG_GIVE_DEVICE_VENDOR_ID:
 	case CEC_MSG_ABORT:
 	case CEC_MSG_GIVE_DEVICE_POWER_STATUS:
-	case CEC_MSG_GIVE_PHYSICAL_ADDR:
 	case CEC_MSG_GIVE_OSD_NAME:
+		/*
+		 * These messages reply with a directed message, so ignore if
+		 * the initiator is Unregistered.
+		 */
+		if (!adap->passthrough && from_unregistered)
+			return 0;
+		/* Fall through */
+	case CEC_MSG_GIVE_DEVICE_VENDOR_ID:
 	case CEC_MSG_GIVE_FEATURES:
+	case CEC_MSG_GIVE_PHYSICAL_ADDR:
 		/*
 		 * Skip processing these messages if the passthrough mode
 		 * is on.
@@ -1739,7 +1746,7 @@ static int cec_receive_notify(struct cec
 		if (adap->passthrough)
 			goto skip_processing;
 		/* Ignore if addressing is wrong */
-		if (is_broadcast || from_unregistered)
+		if (is_broadcast)
 			return 0;
 		break;
 
author maintainer
#40 lore raw

PATCH 43/85 media: dvb: i2c transfers over usb cannot be done from stack

In reply to Greg Kroah-Hartman

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

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

From: Sean Young <[email protected]>

commit b4756707152700c96acdfe149cb1ca4cec306c7a upstream.

Since commit 29d2fef8be11 ("usb: catch attempts to submit urbs with a vmalloc'd transfer buffer"), the AverMedia AverTV DVB-T USB 2.0 (a800) fails to probe.

---
 drivers/media/dvb-frontends/dib3000mc.c |   50 +++++++++++++++++++++------
 drivers/media/dvb-frontends/dvb-pll.c   |   22 +++++++++--
 drivers/media/tuners/mt2060.c           |   59 +++++++++++++++++++++++++-------
 3 files changed, 103 insertions(+), 28 deletions(-)
drivers/media/dvb-frontends/dib3000mc.c +39 -11
@@ -55,29 +55,57 @@ struct dib3000mc_state {
 
 static u16 dib3000mc_read_word(struct dib3000mc_state *state, u16 reg)
 {
-	u8 wb[2] = { (reg >> 8) | 0x80, reg & 0xff };
-	u8 rb[2];
 	struct i2c_msg msg[2] = {
-		{ .addr = state->i2c_addr >> 1, .flags = 0,        .buf = wb, .len = 2 },
-		{ .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 },
+		{ .addr = state->i2c_addr >> 1, .flags = 0,        .len = 2 },
+		{ .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .len = 2 },
 	};
+	u16 word;
+	u8 *b;
+
+	b = kmalloc(4, GFP_KERNEL);
+	if (!b)
+		return 0;
+
+	b[0] = (reg >> 8) | 0x80;
+	b[1] = reg;
+	b[2] = 0;
+	b[3] = 0;
+
+	msg[0].buf = b;
+	msg[1].buf = b + 2;
 
 	if (i2c_transfer(state->i2c_adap, msg, 2) != 2)
 		dprintk("i2c read error on %d\n",reg);
 
-	return (rb[0] << 8) | rb[1];
+	word = (b[2] << 8) | b[3];
+	kfree(b);
+
+	return word;
 }
 
 static int dib3000mc_write_word(struct dib3000mc_state *state, u16 reg, u16 val)
 {
-	u8 b[4] = {
-		(reg >> 8) & 0xff, reg & 0xff,
-		(val >> 8) & 0xff, val & 0xff,
-	};
 	struct i2c_msg msg = {
-		.addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4
+		.addr = state->i2c_addr >> 1, .flags = 0, .len = 4
 	};
-	return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
+	int rc;
+	u8 *b;
+
+	b = kmalloc(4, GFP_KERNEL);
+	if (!b)
+		return -ENOMEM;
+
+	b[0] = reg >> 8;
+	b[1] = reg;
+	b[2] = val >> 8;
+	b[3] = val;
+
+	msg.buf = b;
+
+	rc = i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
+	kfree(b);
+
+	return rc;
 }
 
 static int dib3000mc_identify(struct dib3000mc_state *state)
drivers/media/dvb-frontends/dvb-pll.c +17 -5
@@ -753,13 +753,19 @@ struct dvb_frontend *dvb_pll_attach(stru
 				    struct i2c_adapter *i2c,
 				    unsigned int pll_desc_id)
 {
-	u8 b1 [] = { 0 };
-	struct i2c_msg msg = { .addr = pll_addr, .flags = I2C_M_RD,
-			       .buf = b1, .len = 1 };
+	u8 *b1;
+	struct i2c_msg msg = { .addr = pll_addr, .flags = I2C_M_RD, .len = 1 };
 	struct dvb_pll_priv *priv = NULL;
 	int ret;
 	const struct dvb_pll_desc *desc;
 
+	b1 = kmalloc(1, GFP_KERNEL);
+	if (!b1)
+		return NULL;
+
+	b1[0] = 0;
+	msg.buf = b1;
+
 	if ((id[dvb_pll_devcount] > DVB_PLL_UNDEFINED) &&
 	    (id[dvb_pll_devcount] < ARRAY_SIZE(pll_list)))
 		pll_desc_id = id[dvb_pll_devcount];
@@ -773,15 +779,19 @@ struct dvb_frontend *dvb_pll_attach(stru
 			fe->ops.i2c_gate_ctrl(fe, 1);
 
 		ret = i2c_transfer (i2c, &msg, 1);
-		if (ret != 1)
+		if (ret != 1) {
+			kfree(b1);
 			return NULL;
+		}
 		if (fe->ops.i2c_gate_ctrl)
 			     fe->ops.i2c_gate_ctrl(fe, 0);
 	}
 
 	priv = kzalloc(sizeof(struct dvb_pll_priv), GFP_KERNEL);
-	if (priv == NULL)
+	if (!priv) {
+		kfree(b1);
 		return NULL;
+	}
 
 	priv->pll_i2c_address = pll_addr;
 	priv->i2c = i2c;
@@ -811,6 +821,8 @@ struct dvb_frontend *dvb_pll_attach(stru
 				"insmod option" : "autodetected");
 	}
 
+	kfree(b1);
+
 	return fe;
 }
 EXPORT_SYMBOL(dvb_pll_attach);
drivers/media/tuners/mt2060.c +47 -12

99 lines not on this page · raw message

author maintainer
#41 lore raw

PATCH 44/85 tracing/samples: Fix creation and deletion of simple_thread_fn creation

In reply to Greg Kroah-Hartman

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

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

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

commit 6575257c60e1a26a5319ccf2b5ce5b6449001017 upstream.

Commit 7496946a8 ("tracing: Add samples of DECLARE_EVENT_CLASS() and DEFINE_EVENT()") added template examples for all the events. It created a DEFINE_EVENT_FN() example which reused the foo_bar_reg and foo_bar_unreg functions.

Enabling both the TRACE_EVENT_FN() and DEFINE_EVENT_FN() example trace events caused the foo_bar_reg to be called twice, creating the test thread twice. The foo_bar_unreg would remove it only once, even if it was called multiple times, leaving a thread existing when the module is unloaded, causing an oops.

Add a ref count and allow foo_bar_reg() and foo_bar_unreg() be called by multiple trace events.

Fixes 7496946a8 ("tracing: Add samples of DECLARE_EVENT_CLASS() and DEFINE_EVENT()")
---
 samples/trace_events/trace-events-sample.c |   14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)
samples/trace_events/trace-events-sample.c +11 -3
@@ -78,29 +78,37 @@ static int simple_thread_fn(void *arg)
 }
 
 static DEFINE_MUTEX(thread_mutex);
+static bool simple_thread_cnt;
 
 int foo_bar_reg(void)
 {
+	mutex_lock(&thread_mutex);
+	if (simple_thread_cnt++)
+		goto out;
+
 	pr_info("Starting thread for foo_bar_fn\n");
 	/*
 	 * We shouldn't be able to start a trace when the module is
 	 * unloading (there's other locks to prevent that). But
 	 * for consistency sake, we still take the thread_mutex.
 	 */
-	mutex_lock(&thread_mutex);
 	simple_tsk_fn = kthread_run(simple_thread_fn, NULL, "event-sample-fn");
+ out:
 	mutex_unlock(&thread_mutex);
 	return 0;
 }
 
 void foo_bar_unreg(void)
 {
-	pr_info("Killing thread for foo_bar_fn\n");
-	/* protect against module unloading */
 	mutex_lock(&thread_mutex);
+	if (--simple_thread_cnt)
+		goto out;
+
+	pr_info("Killing thread for foo_bar_fn\n");
 	if (simple_tsk_fn)
 		kthread_stop(simple_tsk_fn);
 	simple_tsk_fn = NULL;
+ out:
 	mutex_unlock(&thread_mutex);
 }
 
#42 lore raw

Re: [PATCH 4.13 44/85] tracing/samples: Fix creation and deletion of simple_thread_fn creation

Quoted 1 line · On Tue, 24 Oct 2017 15:07:18 +0200 Greg Kroah-Hartman…

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

Just that it needs a fix.

samples/trace_events/trace-events-sample.c static int simple_thread_fn(void *arg) · line 81

Quoted 8 lines
samples/trace_events/trace-events-sample.c +1 -0
@@ -78,29 +78,37 @@ static int simple_thread_fn(void *arg)
 }
 
 static DEFINE_MUTEX(thread_mutex);
+static bool simple_thread_cnt;

This needs to be int not bool, and Linus fixed it in his tree.

commit a0cb2b5c390 ("Fix tracing sample code warning.")

-- Steve

author maintainer
#43 lore raw

Re: [PATCH 4.13 44/85] tracing/samples: Fix creation and deletion of simple_thread_fn creation

Quoted 13 lines · Steven Rostedt
Quoted 1 line · On Tue, 24 Oct 2017 15:07:18 +0200 Greg Kroah-Hartman…

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

Just that it needs a fix.

Quoted 6 lines
samples/trace_events/trace-events-sample.c +0 -0
@@ -78,29 +78,37 @@ static int simple_thread_fn(void *arg)
 }
 
Quoted 6 lines

samples/trace_events/trace-events-sample.c static int simple_thread_fn(void *arg) · line 81

Quoted 2 lines
samples/trace_events/trace-events-sample.c +1 -0
 static DEFINE_MUTEX(thread_mutex);
+static bool simple_thread_cnt;

This needs to be int not bool, and Linus fixed it in his tree.

commit a0cb2b5c390 ("Fix tracing sample code warning.")

I've already queued that up now, right?

thanks,

greg k-h

author maintainer
#44 lore raw

PATCH 45/85 ALSA: seq: Enable use locking in all configurations

In reply to Greg Kroah-Hartman

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

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

From: Ben Hutchings <[email protected]>

commit 8009d506a1dd00cf436b0c4cca0dcec130580a21 upstream.

The 'use' locking macros are no-ops if neither SMP or SND_DEBUG is enabled. This might once have been OK in non-preemptible configurations, but even in that case snd_seq_read() may sleep while relying on a 'use' lock. So always use the proper implementations.

---
 sound/core/seq/seq_lock.c |    4 ----
 sound/core/seq/seq_lock.h |   12 ------------
 2 files changed, 16 deletions(-)
sound/core/seq/seq_lock.c +0 -4
@@ -23,8 +23,6 @@
 #include <sound/core.h>
 #include "seq_lock.h"
 
-#if defined(CONFIG_SMP) || defined(CONFIG_SND_DEBUG)
-
 /* wait until all locks are released */
 void snd_use_lock_sync_helper(snd_use_lock_t *lockp, const char *file, int line)
 {
@@ -41,5 +39,3 @@ void snd_use_lock_sync_helper(snd_use_lo
 	}
 }
 EXPORT_SYMBOL(snd_use_lock_sync_helper);
-
-#endif
sound/core/seq/seq_lock.h +0 -12
@@ -3,8 +3,6 @@
 
 #include <linux/sched.h>
 
-#if defined(CONFIG_SMP) || defined(CONFIG_SND_DEBUG)
-
 typedef atomic_t snd_use_lock_t;
 
 /* initialize lock */
@@ -20,14 +18,4 @@ typedef atomic_t snd_use_lock_t;
 void snd_use_lock_sync_helper(snd_use_lock_t *lock, const char *file, int line);
 #define snd_use_lock_sync(lockp) snd_use_lock_sync_helper(lockp, __BASE_FILE__, __LINE__)
 
-#else /* SMP || CONFIG_SND_DEBUG */
-
-typedef spinlock_t snd_use_lock_t;	/* dummy */
-#define snd_use_lock_init(lockp) /**/
-#define snd_use_lock_use(lockp) /**/
-#define snd_use_lock_free(lockp) /**/
-#define snd_use_lock_sync(lockp) /**/
-
-#endif /* SMP || CONFIG_SND_DEBUG */
-
 #endif /* __SND_SEQ_LOCK_H */
author maintainer
#45 lore raw

PATCH 46/85 ALSA: hda: Remove superfluous - added by printk conversion

In reply to Greg Kroah-Hartman

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

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

From: Takashi Iwai <[email protected]>

commit 6bf88a343db2b3c160edf9b82a74966b31cc80bd upstream.

While converting the error messages to the standard macros in the commit 4e76a8833fac ("ALSA: hda - Replace with standard printk"), a superfluous '-' slipped in the code mistakenly. Its influence is almost negligible, merely shows a dB value as negative integer instead of positive integer (or vice versa) in the rare error message. So let's kill this embarrassing byte to show more correct value.

Fixes 4e76a8833fac ("ALSA: hda - Replace with standard printk")
---
 sound/pci/hda/hda_codec.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
sound/pci/hda/hda_codec.c +1 -1
@@ -1824,7 +1824,7 @@ static int get_kctl_0dB_offset(struct hd
 			return -1;
 		if (*step_to_check && *step_to_check != step) {
 			codec_err(codec, "Mismatching dB step for vmaster slave (%d!=%d)\n",
--				   *step_to_check, step);
+				   *step_to_check, step);
 			return -1;
 		}
 		*step_to_check = step;
author maintainer
#46 lore raw

PATCH 47/85 ALSA: hda: Abort capability probe at invalid register read

In reply to Greg Kroah-Hartman

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

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

From: Takashi Iwai <[email protected]>

commit 098a0a62c1554f5a3813ef1b8539563214ada8f6 upstream.

The loop in snd_hdac_bus_parse_capabilities() may go to nirvana when it hits an invalid register value read:

 BUG: unable to handle kernel paging request at ffffad5dc41f3fff
 IP: pci_azx_readl+0x5/0x10 [snd_hda_intel]
 Call Trace:
  snd_hdac_bus_parse_capabilities+0x3c/0x1f0 [snd_hda_core]
  azx_probe_continue+0x7d5/0x940 [snd_hda_intel]
  .....

This happened on a new Intel machine, and we need to check the value and abort the loop accordingly.

[Note: the fixes tag below indicates only the commit where this patch
can be applied; the original problem was introduced even before that commit]

Fixes 6720b38420a0 ("ALSA: hda - move bus_parse_capabilities to core")
---
 sound/hda/hdac_controller.c |    5 +++++
 1 file changed, 5 insertions(+)
sound/hda/hdac_controller.c +5 -0
@@ -284,6 +284,11 @@ int snd_hdac_bus_parse_capabilities(stru
 		dev_dbg(bus->dev, "HDA capability ID: 0x%x\n",
 			(cur_cap & AZX_CAP_HDR_ID_MASK) >> AZX_CAP_HDR_ID_OFF);
 
+		if (cur_cap == -1) {
+			dev_dbg(bus->dev, "Invalid capability reg read\n");
+			break;
+		}
+
 		switch ((cur_cap & AZX_CAP_HDR_ID_MASK) >> AZX_CAP_HDR_ID_OFF) {
 		case AZX_ML_CAP_ID:
 			dev_dbg(bus->dev, "Found ML capability\n");
author maintainer
#47 lore raw

PATCH 48/85 i2c: ismt: Separate I2C block read from SMBus block read

In reply to Greg Kroah-Hartman

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

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

From: Pontus Andersson <[email protected]>

commit c6ebcedbab7ca78984959386012a17b21183e1a3 upstream.

Commit b6c159a9cb69 ("i2c: ismt: Don't duplicate the receive length for block reads") broke I2C block reads. It aimed to fix normal SMBus block read, but changed the correct behavior of I2C block read in the process.

According to Documentation/i2c/smbus-protocol, one vital difference between normal SMBus block read and I2C block read is that there is no byte count prefixed in the data sent on the wire:

SMBus Block Read: i2c_smbus_read_block_data()
S Addr Wr [A] Comm [A]
S Addr Rd [A] [Count] A [Data] A [Data] A ... A [Data] NA P

I2C Block Read: i2c_smbus_read_i2c_block_data()
S Addr Wr [A] Comm [A]
S Addr Rd [A] [Data] A [Data] A ... A [Data] NA P

Therefore the two transaction types need to be processed differently in the driver by copying of the dma_buffer as done previously for the I2C_SMBUS_I2C_BLOCK_DATA case.

Fixes b6c159a9cb69 ("i2c: ismt: Don't duplicate the receive length for block reads")
---
 drivers/i2c/busses/i2c-ismt.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/i2c/busses/i2c-ismt.c +4 -1
@@ -340,12 +340,15 @@ static int ismt_process_desc(const struc
 			data->word = dma_buffer[0] | (dma_buffer[1] << 8);
 			break;
 		case I2C_SMBUS_BLOCK_DATA:
-		case I2C_SMBUS_I2C_BLOCK_DATA:
 			if (desc->rxbytes != dma_buffer[0] + 1)
 				return -EMSGSIZE;
 
 			memcpy(data->block, dma_buffer, desc->rxbytes);
 			break;
+		case I2C_SMBUS_I2C_BLOCK_DATA:
+			memcpy(&data->block[1], dma_buffer, desc->rxbytes);
+			data->block[0] = desc->rxbytes;
+			break;
 		}
 		return 0;
 	}
author maintainer
#48 lore raw

PATCH 50/85 Revert "tools/power turbostat: stop migrating, unless -m"

In reply to Greg Kroah-Hartman

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

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

From: Len Brown <[email protected]>

commit c97cc7dbce2fe6f46e137f4b040f915a0181ee85 upstream.

This reverts commit c91fc8519d87715a3a173475ea3778794c139996.

That change caused a C6 and PC6 residency regression on large idle systems.

Users also complained about new output indicating jitter:

turbostat: cpu6 jitter 3794 9142

---
 tools/power/x86/turbostat/turbostat.c |   10 +---------
 1 file changed, 1 insertion(+), 9 deletions(-)
tools/power/x86/turbostat/turbostat.c +1 -9
@@ -92,7 +92,6 @@ unsigned int do_ring_perf_limit_reasons;
 unsigned int crystal_hz;
 unsigned long long tsc_hz;
 int base_cpu;
-int do_migrate;
 double discover_bclk(unsigned int family, unsigned int model);
 unsigned int has_hwp;	/* IA32_PM_ENABLE, IA32_HWP_CAPABILITIES */
 			/* IA32_HWP_REQUEST, IA32_HWP_STATUS */
@@ -303,9 +302,6 @@ int for_all_cpus(int (func)(struct threa
 
 int cpu_migrate(int cpu)
 {
-	if (!do_migrate)
-		return 0;
-
 	CPU_ZERO_S(cpu_affinity_setsize, cpu_affinity_set);
 	CPU_SET_S(cpu, cpu_affinity_setsize, cpu_affinity_set);
 	if (sched_setaffinity(0, cpu_affinity_setsize, cpu_affinity_set) == -1)
@@ -5007,7 +5003,6 @@ void cmdline(int argc, char **argv)
 		{"hide",	required_argument,	0, 'H'},	// meh, -h taken by --help
 		{"Joules",	no_argument,		0, 'J'},
 		{"list",	no_argument,		0, 'l'},
-		{"migrate",	no_argument,		0, 'm'},
 		{"out",		required_argument,	0, 'o'},
 		{"quiet",	no_argument,		0, 'q'},
 		{"show",	required_argument,	0, 's'},
@@ -5019,7 +5014,7 @@ void cmdline(int argc, char **argv)
 
 	progname = argv[0];
 
-	while ((opt = getopt_long_only(argc, argv, "+C:c:Ddhi:Jmo:qST:v",
+	while ((opt = getopt_long_only(argc, argv, "+C:c:Ddhi:JM:m:o:qST:v",
 				long_options, &option_index)) != -1) {
 		switch (opt) {
 		case 'a':
@@ -5062,9 +5057,6 @@ void cmdline(int argc, char **argv)
 			list_header_only++;
 			quiet++;
 			break;
-		case 'm':
-			do_migrate = 1;
-			break;
 		case 'o':
 			outf = fopen_or_die(optarg, "w");
 			break;
author maintainer
#49 lore raw

PATCH 51/85 Input: stmfts - fix setting ABS_MT_POSITION_* maximum size

In reply to Greg Kroah-Hartman

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

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

From: Chanwoo Choi <[email protected]>

commit c9bfb2f0031a2de664147ebbfb90f95bb12fdf79 upstream.

The commit 78bcac7b2ae1e ("Input: add support for the STMicroelectronics FingerTip touchscreen) used the 'touchscreen_parse_properties()' helper function in order to get the value of common properties.

But, commit 78bcac7b2ae1e didn't set the capability of ABS_MT_POSITION_* before calling touchscreen_parse_properties(). In result, the max_x and max_y of 'struct touchscreen_properties' were not set.

Fixes 78bcac7b2ae1e ("Input: add support for the STMicroelectronics FingerTip touchscreen")
---
 drivers/input/touchscreen/stmfts.c |    6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/input/touchscreen/stmfts.c +2 -4
@@ -663,12 +663,10 @@ static int stmfts_probe(struct i2c_clien
 	sdata->input->open = stmfts_input_open;
 	sdata->input->close = stmfts_input_close;
 
+	input_set_capability(sdata->input, EV_ABS, ABS_MT_POSITION_X);
+	input_set_capability(sdata->input, EV_ABS, ABS_MT_POSITION_Y);
 	touchscreen_parse_properties(sdata->input, true, &sdata->prop);
 
-	input_set_abs_params(sdata->input, ABS_MT_POSITION_X, 0,
-						sdata->prop.max_x, 0, 0);
-	input_set_abs_params(sdata->input, ABS_MT_POSITION_Y, 0,
-						sdata->prop.max_y, 0, 0);
 	input_set_abs_params(sdata->input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
 	input_set_abs_params(sdata->input, ABS_MT_TOUCH_MINOR, 0, 255, 0, 0);
 	input_set_abs_params(sdata->input, ABS_MT_ORIENTATION, 0, 255, 0, 0);
author maintainer
#50 lore raw

PATCH 52/85 brcmfmac: Add check for short event packets

In reply to Greg Kroah-Hartman

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

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

From: Kevin Cernekee <[email protected]>

commit dd2349121bb1b8ff688c3ca6a2a0bea9d8c142ca upstream.

The length of the data in the received skb is currently passed into brcmf_fweh_process_event() as packet_len, but this value is not checked. event_packet should be followed by DATALEN bytes of additional event data. Ensure that the received packet actually contains at least DATALEN bytes of additional data, to avoid copying uninitialized memory into event->data.

---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c +2 -1
@@ -429,7 +429,8 @@ void brcmf_fweh_process_event(struct brc
 	if (code != BRCMF_E_IF && !fweh->evt_handler[code])
 		return;
 
-	if (datalen > BRCMF_DCMD_MAXLEN)
+	if (datalen > BRCMF_DCMD_MAXLEN ||
+	    datalen + sizeof(*event_packet) > packet_len)
 		return;
 
 	if (in_interrupt())
author maintainer
#51 lore raw

PATCH 53/85 brcmsmac: make some local variables static const to reduce stack size

In reply to Greg Kroah-Hartman

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

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

From: Arnd Bergmann <[email protected]>

commit c503dd38f850be28867ef7a42d9abe5ade81a9bd upstream.

With KASAN and a couple of other patches applied, this driver is one of the few remaining ones that actually use more than 2048 bytes of kernel stack:

broadcom/brcm80211/brcmsmac/phy/phy_n.c: In function 'wlc_phy_workarounds_nphy_gainctrl':
broadcom/brcm80211/brcmsmac/phy/phy_n.c:16065:1: warning: the frame size of 3264 bytes is larger than 2048 bytes [-Wframe-larger-than=] broadcom/brcm80211/brcmsmac/phy/phy_n.c: In function 'wlc_phy_workarounds_nphy':
broadcom/brcm80211/brcmsmac/phy/phy_n.c:17138:1: warning: the frame size of 2864 bytes is larger than 2048 bytes [-Wframe-larger-than=]

Here, I'm reducing the stack size by marking as many local variables as 'static const' as I can without changing the actual code.

This is the first of three patches to improve the stack usage in this driver. It would be good to have this backported to stabl kernels to get all drivers in 'allmodconfig' below the 2048 byte limit so we can turn on the frame warning again globally, but I realize that the patch is larger than the normal limit for stable backports.

The other two patches do not need to be backported.

---
 drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c |  197 +++++------
 1 file changed, 97 insertions(+), 100 deletions(-)
drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c +97 -100
@@ -14764,8 +14764,8 @@ static void wlc_phy_ipa_restore_tx_digi_
 }
 
 static void
-wlc_phy_set_rfseq_nphy(struct brcms_phy *pi, u8 cmd, u8 *events, u8 *dlys,
-		       u8 len)
+wlc_phy_set_rfseq_nphy(struct brcms_phy *pi, u8 cmd, const u8 *events,
+		       const u8 *dlys, u8 len)
 {
 	u32 t1_offset, t2_offset;
 	u8 ctr;
@@ -15240,16 +15240,16 @@ static void wlc_phy_workarounds_nphy_gai
 static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(struct brcms_phy *pi)
 {
 	u16 currband;
-	s8 lna1G_gain_db_rev7[] = { 9, 14, 19, 24 };
-	s8 *lna1_gain_db = NULL;
-	s8 *lna1_gain_db_2 = NULL;
-	s8 *lna2_gain_db = NULL;
-	s8 tiaA_gain_db_rev7[] = { -9, -6, -3, 0, 3, 3, 3, 3, 3, 3 };
-	s8 *tia_gain_db;
-	s8 tiaA_gainbits_rev7[] = { 0, 1, 2, 3, 4, 4, 4, 4, 4, 4 };
-	s8 *tia_gainbits;
-	u16 rfseqA_init_gain_rev7[] = { 0x624f, 0x624f };
-	u16 *rfseq_init_gain;
+	static const s8 lna1G_gain_db_rev7[] = { 9, 14, 19, 24 };
+	const s8 *lna1_gain_db = NULL;
+	const s8 *lna1_gain_db_2 = NULL;
+	const s8 *lna2_gain_db = NULL;
+	static const s8 tiaA_gain_db_rev7[] = { -9, -6, -3, 0, 3, 3, 3, 3, 3, 3 };
+	const s8 *tia_gain_db;
+	static const s8 tiaA_gainbits_rev7[] = { 0, 1, 2, 3, 4, 4, 4, 4, 4, 4 };
+	const s8 *tia_gainbits;
+	static const u16 rfseqA_init_gain_rev7[] = { 0x624f, 0x624f };
+	const u16 *rfseq_init_gain;
 	u16 init_gaincode;
 	u16 clip1hi_gaincode;
 	u16 clip1md_gaincode = 0;
@@ -15310,10 +15310,9 @@ static void wlc_phy_workarounds_nphy_gai
 
 			if ((freq <= 5080) || (freq == 5825)) {
 
-				s8 lna1A_gain_db_rev7[] = { 11, 16, 20, 24 };
-				s8 lna1A_gain_db_2_rev7[] = {
-					11, 17, 22, 25};
-				s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 };
+				static const s8 lna1A_gain_db_rev7[] = { 11, 16, 20, 24 };
+				static const s8 lna1A_gain_db_2_rev7[] = { 11, 17, 22, 25};
+				static const s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 };
 
 				crsminu_th = 0x3e;
 				lna1_gain_db = lna1A_gain_db_rev7;
@@ -15321,10 +15320,9 @@ static void wlc_phy_workarounds_nphy_gai
 				lna2_gain_db = lna2A_gain_db_rev7;
 			} else if ((freq >= 5500) && (freq <= 5700)) {
 
-				s8 lna1A_gain_db_rev7[] = { 11, 17, 21, 25 };
-				s8 lna1A_gain_db_2_rev7[] = {
-					12, 18, 22, 26};
-				s8 lna2A_gain_db_rev7[] = { 1, 8, 12, 16 };
+				static const s8 lna1A_gain_db_rev7[] = { 11, 17, 21, 25 };
+				static const s8 lna1A_gain_db_2_rev7[] = { 12, 18, 22, 26};
+				static const s8 lna2A_gain_db_rev7[] = { 1, 8, 12, 16 };
 
 				crsminu_th = 0x45;
 				clip1md_gaincode_B = 0x14;
@@ -15335,10 +15333,9 @@ static void wlc_phy_workarounds_nphy_gai
 				lna2_gain_db = lna2A_gain_db_rev7;
 			} else {
 
-				s8 lna1A_gain_db_rev7[] = { 12, 18, 22, 26 };
-				s8 lna1A_gain_db_2_rev7[] = {
-					12, 18, 22, 26};
-				s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 };
+				static const s8 lna1A_gain_db_rev7[] = { 12, 18, 22, 26 };
+				static const s8 lna1A_gain_db_2_rev7[] = { 12, 18, 22, 26};
+				static const s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 };
 
 				crsminu_th = 0x41;
 				lna1_gain_db = lna1A_gain_db_rev7;
@@ -15450,65 +15447,65 @@ static void wlc_phy_workarounds_nphy_gai
 		NPHY_RFSEQ_CMD_CLR_HIQ_DIS,
 		NPHY_RFSEQ_CMD_SET_HPF_BW
 	};
-	u8 rfseq_updategainu_dlys[] = { 10, 30, 1 };
-	s8 lna1G_gain_db[] = { 7, 11, 16, 23 };
-	s8 lna1G_gain_db_rev4[] = { 8, 12, 17, 25 };
-	s8 lna1G_gain_db_rev5[] = { 9, 13, 18, 26 };
-	s8 lna1G_gain_db_rev6[] = { 8, 13, 18, 25 };
-	s8 lna1G_gain_db_rev6_224B0[] = { 10, 14, 19, 27 };
-	s8 lna1A_gain_db[] = { 7, 11, 17, 23 };
-	s8 lna1A_gain_db_rev4[] = { 8, 12, 18, 23 };
-	s8 lna1A_gain_db_rev5[] = { 6, 10, 16, 21 };
-	s8 lna1A_gain_db_rev6[] = { 6, 10, 16, 21 };
-	s8 *lna1_gain_db = NULL;
-	s8 lna2G_gain_db[] = { -5, 6, 10, 14 };
-	s8 lna2G_gain_db_rev5[] = { -3, 7, 11, 16 };
-	s8 lna2G_gain_db_rev6[] = { -5, 6, 10, 14 };
-	s8 lna2G_gain_db_rev6_224B0[] = { -5, 6, 10, 15 };
-	s8 lna2A_gain_db[] = { -6, 2, 6, 10 };
-	s8 lna2A_gain_db_rev4[] = { -5, 2, 6, 10 };
-	s8 lna2A_gain_db_rev5[] = { -7, 0, 4, 8 };
-	s8 lna2A_gain_db_rev6[] = { -7, 0, 4, 8 };
-	s8 *lna2_gain_db = NULL;
-	s8 tiaG_gain_db[] = {
+	static const u8 rfseq_updategainu_dlys[] = { 10, 30, 1 };
+	static const s8 lna1G_gain_db[] = { 7, 11, 16, 23 };
+	static const s8 lna1G_gain_db_rev4[] = { 8, 12, 17, 25 };
+	static const s8 lna1G_gain_db_rev5[] = { 9, 13, 18, 26 };
+	static const s8 lna1G_gain_db_rev6[] = { 8, 13, 18, 25 };
+	static const s8 lna1G_gain_db_rev6_224B0[] = { 10, 14, 19, 27 };
+	static const s8 lna1A_gain_db[] = { 7, 11, 17, 23 };
+	static const s8 lna1A_gain_db_rev4[] = { 8, 12, 18, 23 };
+	static const s8 lna1A_gain_db_rev5[] = { 6, 10, 16, 21 };
+	static const s8 lna1A_gain_db_rev6[] = { 6, 10, 16, 21 };
+	const s8 *lna1_gain_db = NULL;
+	static const s8 lna2G_gain_db[] = { -5, 6, 10, 14 };
+	static const s8 lna2G_gain_db_rev5[] = { -3, 7, 11, 16 };
+	static const s8 lna2G_gain_db_rev6[] = { -5, 6, 10, 14 };
+	static const s8 lna2G_gain_db_rev6_224B0[] = { -5, 6, 10, 15 };
+	static const s8 lna2A_gain_db[] = { -6, 2, 6, 10 };
+	static const s8 lna2A_gain_db_rev4[] = { -5, 2, 6, 10 };
+	static const s8 lna2A_gain_db_rev5[] = { -7, 0, 4, 8 };
+	static const s8 lna2A_gain_db_rev6[] = { -7, 0, 4, 8 };
+	const s8 *lna2_gain_db = NULL;
+	static const s8 tiaG_gain_db[] = {
 		0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A };
-	s8 tiaA_gain_db[] = {
+	static const s8 tiaA_gain_db[] = {
 		0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13 };
-	s8 tiaA_gain_db_rev4[] = {
+	static const s8 tiaA_gain_db_rev4[] = {
 		0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d };
-	s8 tiaA_gain_db_rev5[] = {
+	static const s8 tiaA_gain_db_rev5[] = {
 		0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d };
-	s8 tiaA_gain_db_rev6[] = {
+	static const s8 tiaA_gain_db_rev6[] = {
 		0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d };
-	s8 *tia_gain_db;
-	s8 tiaG_gainbits[] = {
+	const s8 *tia_gain_db;
+	static const s8 tiaG_gainbits[] = {
 		0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 };
-	s8 tiaA_gainbits[] = {
+	static const s8 tiaA_gainbits[] = {
 		0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06 };
-	s8 tiaA_gainbits_rev4[] = {
+	static const s8 tiaA_gainbits_rev4[] = {
 		0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 };
-	s8 tiaA_gainbits_rev5[] = {
+	static const s8 tiaA_gainbits_rev5[] = {
 		0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 };
-	s8 tiaA_gainbits_rev6[] = {
+	static const s8 tiaA_gainbits_rev6[] = {
 		0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 };
-	s8 *tia_gainbits;
-	s8 lpf_gain_db[] = { 0x00, 0x06, 0x0c, 0x12, 0x12, 0x12 };
-	s8 lpf_gainbits[] = { 0x00, 0x01, 0x02, 0x03, 0x03, 0x03 };
-	u16 rfseqG_init_gain[] = { 0x613f, 0x613f, 0x613f, 0x613f };
-	u16 rfseqG_init_gain_rev4[] = { 0x513f, 0x513f, 0x513f, 0x513f };
-	u16 rfseqG_init_gain_rev5[] = { 0x413f, 0x413f, 0x413f, 0x413f };
-	u16 rfseqG_init_gain_rev5_elna[] = {
+	const s8 *tia_gainbits;
+	static const s8 lpf_gain_db[] = { 0x00, 0x06, 0x0c, 0x12, 0x12, 0x12 };
+	static const s8 lpf_gainbits[] = { 0x00, 0x01, 0x02, 0x03, 0x03, 0x03 };
+	static const u16 rfseqG_init_gain[] = { 0x613f, 0x613f, 0x613f, 0x613f };
+	static const u16 rfseqG_init_gain_rev4[] = { 0x513f, 0x513f, 0x513f, 0x513f };
+	static const u16 rfseqG_init_gain_rev5[] = { 0x413f, 0x413f, 0x413f, 0x413f };
+	static const u16 rfseqG_init_gain_rev5_elna[] = {
 		0x013f, 0x013f, 0x013f, 0x013f };
-	u16 rfseqG_init_gain_rev6[] = { 0x513f, 0x513f };
-	u16 rfseqG_init_gain_rev6_224B0[] = { 0x413f, 0x413f };
-	u16 rfseqG_init_gain_rev6_elna[] = { 0x113f, 0x113f };
-	u16 rfseqA_init_gain[] = { 0x516f, 0x516f, 0x516f, 0x516f };
-	u16 rfseqA_init_gain_rev4[] = { 0x614f, 0x614f, 0x614f, 0x614f };
-	u16 rfseqA_init_gain_rev4_elna[] = {
+	static const u16 rfseqG_init_gain_rev6[] = { 0x513f, 0x513f };
+	static const u16 rfseqG_init_gain_rev6_224B0[] = { 0x413f, 0x413f };
+	static const u16 rfseqG_init_gain_rev6_elna[] = { 0x113f, 0x113f };
+	static const u16 rfseqA_init_gain[] = { 0x516f, 0x516f, 0x516f, 0x516f };
+	static const u16 rfseqA_init_gain_rev4[] = { 0x614f, 0x614f, 0x614f, 0x614f };
+	static const u16 rfseqA_init_gain_rev4_elna[] = {
 		0x314f, 0x314f, 0x314f, 0x314f };
-	u16 rfseqA_init_gain_rev5[] = { 0x714f, 0x714f, 0x714f, 0x714f };
-	u16 rfseqA_init_gain_rev6[] = { 0x714f, 0x714f };
-	u16 *rfseq_init_gain;
+	static const u16 rfseqA_init_gain_rev5[] = { 0x714f, 0x714f, 0x714f, 0x714f };
+	static const u16 rfseqA_init_gain_rev6[] = { 0x714f, 0x714f };
+	const u16 *rfseq_init_gain;
 	u16 initG_gaincode = 0x627e;
 	u16 initG_gaincode_rev4 = 0x527e;
 	u16 initG_gaincode_rev5 = 0x427e;
@@ -15538,10 +15535,10 @@ static void wlc_phy_workarounds_nphy_gai
 	u16 clip1mdA_gaincode_rev6 = 0x2084;
 	u16 clip1md_gaincode = 0;
 	u16 clip1loG_gaincode = 0x0074;
-	u16 clip1loG_gaincode_rev5[] = {
+	static const u16 clip1loG_gaincode_rev5[] = {
 		0x0062, 0x0064, 0x006a, 0x106a, 0x106c, 0x1074, 0x107c, 0x207c
 	};
-	u16 clip1loG_gaincode_rev6[] = {
+	static const u16 clip1loG_gaincode_rev6[] = {
 		0x106a, 0x106c, 0x1074, 0x107c, 0x007e, 0x107e, 0x207e, 0x307e
 	};
 	u16 clip1loG_gaincode_rev6_224B0 = 0x1074;
@@ -16066,7 +16063,7 @@ static void wlc_phy_workarounds_nphy_gai
 
 static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
 {
-	u8 rfseq_rx2tx_events[] = {
+	static const u8 rfseq_rx2tx_events[] = {
 		NPHY_RFSEQ_CMD_NOP,
 		NPHY_RFSEQ_CMD_RXG_FBW,
 		NPHY_RFSEQ_CMD_TR_SWITCH,
@@ -16076,7 +16073,7 @@ static void wlc_phy_workarounds_nphy(str
 		NPHY_RFSEQ_CMD_EXT_PA
 	};
 	u8 rfseq_rx2tx_dlys[] = { 8, 6, 6, 2, 4, 60, 1 };
-	u8 rfseq_tx2rx_events[] = {
+	static const u8 rfseq_tx2rx_events[] = {
 		NPHY_RFSEQ_CMD_NOP,
 		NPHY_RFSEQ_CMD_EXT_PA,
 		NPHY_RFSEQ_CMD_TX_GAIN,
@@ -16085,8 +16082,8 @@ static void wlc_phy_workarounds_nphy(str
 		NPHY_RFSEQ_CMD_RXG_FBW,
 		NPHY_RFSEQ_CMD_CLR_HIQ_DIS
 	};
-	u8 rfseq_tx2rx_dlys[] = { 8, 6, 2, 4, 4, 6, 1 };
-	u8 rfseq_tx2rx_events_rev3[] = {
+	static const u8 rfseq_tx2rx_dlys[] = { 8, 6, 2, 4, 4, 6, 1 };
+	static const u8 rfseq_tx2rx_events_rev3[] = {
 		NPHY_REV3_RFSEQ_CMD_EXT_PA,
 		NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
 		NPHY_REV3_RFSEQ_CMD_TX_GAIN,
@@ -16096,7 +16093,7 @@ static void wlc_phy_workarounds_nphy(str
 		NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS,
 		NPHY_REV3_RFSEQ_CMD_END
 	};
-	u8 rfseq_tx2rx_dlys_rev3[] = { 8, 4, 2, 2, 4, 4, 6, 1 };
+	static const u8 rfseq_tx2rx_dlys_rev3[] = { 8, 4, 2, 2, 4, 4, 6, 1 };
 	u8 rfseq_rx2tx_events_rev3[] = {
 		NPHY_REV3_RFSEQ_CMD_NOP,
 		NPHY_REV3_RFSEQ_CMD_RXG_FBW,
@@ -16110,7 +16107,7 @@ static void wlc_phy_workarounds_nphy(str
 	};
 	u8 rfseq_rx2tx_dlys_rev3[] = { 8, 6, 6, 4, 4, 18, 42, 1, 1 };
 
-	u8 rfseq_rx2tx_events_rev3_ipa[] = {
+	static const u8 rfseq_rx2tx_events_rev3_ipa[] = {
 		NPHY_REV3_RFSEQ_CMD_NOP,
 		NPHY_REV3_RFSEQ_CMD_RXG_FBW,
 		NPHY_REV3_RFSEQ_CMD_TR_SWITCH,
@@ -16121,15 +16118,15 @@ static void wlc_phy_workarounds_nphy(str
 		NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
 		NPHY_REV3_RFSEQ_CMD_END
 	};
-	u8 rfseq_rx2tx_dlys_rev3_ipa[] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 };
-	u16 rfseq_rx2tx_dacbufpu_rev7[] = { 0x10f, 0x10f };
+	static const u8 rfseq_rx2tx_dlys_rev3_ipa[] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 };
+	static const u16 rfseq_rx2tx_dacbufpu_rev7[] = { 0x10f, 0x10f };
 
 	s16 alpha0, alpha1, alpha2;
 	s16 beta0, beta1, beta2;
 	u32 leg_data_weights, ht_data_weights, nss1_data_weights,
 	    stbc_data_weights;
 	u8 chan_freq_range = 0;
-	u16 dac_control = 0x0002;
+	static const u16 dac_control = 0x0002;
 	u16 aux_adc_vmid_rev7_core0[] = { 0x8e, 0x96, 0x96, 0x96 };
 	u16 aux_adc_vmid_rev7_core1[] = { 0x8f, 0x9f, 0x9f, 0x96 };
 	u16 aux_adc_vmid_rev4[] = { 0xa2, 0xb4, 0xb4, 0x89 };
@@ -16139,8 +16136,8 @@ static void wlc_phy_workarounds_nphy(str
 	u16 aux_adc_gain_rev4[] = { 0x02, 0x02, 0x02, 0x00 };
 	u16 aux_adc_gain_rev3[] = { 0x02, 0x02, 0x02, 0x00 };
 	u16 *aux_adc_gain;
-	u16 sk_adc_vmid[] = { 0xb4, 0xb4, 0xb4, 0x24 };
-	u16 sk_adc_gain[] = { 0x02, 0x02, 0x02, 0x02 };
+	static const u16 sk_adc_vmid[] = { 0xb4, 0xb4, 0xb4, 0x24 };
+	static const u16 sk_adc_gain[] = { 0x02, 0x02, 0x02, 0x02 };
 	s32 min_nvar_val = 0x18d;
 	s32 min_nvar_offset_6mbps = 20;
 	u8 pdetrange;
@@ -16151,9 +16148,9 @@ static void wlc_phy_workarounds_nphy(str
 	u16 rfseq_rx2tx_lpf_h_hpc_rev7 = 0x77;
 	u16 rfseq_tx2rx_lpf_h_hpc_rev7 = 0x77;
 	u16 rfseq_pktgn_lpf_h_hpc_rev7 = 0x77;
-	u16 rfseq_htpktgn_lpf_hpc_rev7[] = { 0x77, 0x11, 0x11 };
-	u16 rfseq_pktgn_lpf_hpc_rev7[] = { 0x11, 0x11 };
-	u16 rfseq_cckpktgn_lpf_hpc_rev7[] = { 0x11, 0x11 };
+	static const u16 rfseq_htpktgn_lpf_hpc_rev7[] = { 0x77, 0x11, 0x11 };
+	static const u16 rfseq_pktgn_lpf_hpc_rev7[] = { 0x11, 0x11 };
+	static const u16 rfseq_cckpktgn_lpf_hpc_rev7[] = { 0x11, 0x11 };
 	u16 ipalvlshift_3p3_war_en = 0;
 	u16 rccal_bcap_val, rccal_scap_val;
 	u16 rccal_tx20_11b_bcap = 0;
@@ -24291,13 +24288,13 @@ static void wlc_phy_update_txcal_ladder_
 	u16 bbmult;
 	u16 tblentry;
 
-	struct nphy_txiqcal_ladder ladder_lo[] = {
+	static const struct nphy_txiqcal_ladder ladder_lo[] = {
 		{3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0},
 		{25, 0}, {25, 1}, {25, 2}, {25, 3}, {25, 4}, {25, 5},
 		{25, 6}, {25, 7}, {35, 7}, {50, 7}, {71, 7}, {100, 7}
 	};
 
-	struct nphy_txiqcal_ladder ladder_iq[] = {
+	static const struct nphy_txiqcal_ladder ladder_iq[] = {
 		{3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0},
 		{25, 0}, {35, 0}, {50, 0}, {71, 0}, {100, 0}, {100, 1},
 		{100, 2}, {100, 3}, {100, 4}, {100, 5}, {100, 6}, {100, 7}
@@ -25773,67 +25770,67 @@ wlc_phy_cal_txiqlo_nphy(struct brcms_phy
 	u16 cal_gain[2];
 	struct nphy_iqcal_params cal_params[2];
 	u32 tbl_len;
-	void *tbl_ptr;
+	const void *tbl_ptr;
 	bool ladder_updated[2];
 	u8 mphase_cal_lastphase = 0;
 	int bcmerror = 0;
 	bool phyhang_avoid_state = false;
 
-	u16 tbl_tx_iqlo_cal_loft_ladder_20[] = {
+	static const u16 tbl_tx_iqlo_cal_loft_ladder_20[] = {
 		0x0300, 0x0500, 0x0700, 0x0900, 0x0d00, 0x1100, 0x1900, 0x1901,
 		0x1902,
 		0x1903, 0x1904, 0x1905, 0x1906, 0x1907, 0x2407, 0x3207, 0x4607,
 		0x6407
 	};
 
-	u16 tbl_tx_iqlo_cal_iqimb_ladder_20[] = {
+	static const u16 tbl_tx_iqlo_cal_iqimb_ladder_20[] = {
 		0x0200, 0x0300, 0x0600, 0x0900, 0x0d00, 0x1100, 0x1900, 0x2400,
 		0x3200,
 		0x4600, 0x6400, 0x6401, 0x6402, 0x6403, 0x6404, 0x6405, 0x6406,
 		0x6407
 	};
 
-	u16 tbl_tx_iqlo_cal_loft_ladder_40[] = {
+	static const u16 tbl_tx_iqlo_cal_loft_ladder_40[] = {
 		0x0200, 0x0300, 0x0400, 0x0700, 0x0900, 0x0c00, 0x1200, 0x1201,
 		0x1202,
 		0x1203, 0x1204, 0x1205, 0x1206, 0x1207, 0x1907, 0x2307, 0x3207,
 		0x4707
 	};
 
-	u16 tbl_tx_iqlo_cal_iqimb_ladder_40[] = {
+	static const u16 tbl_tx_iqlo_cal_iqimb_ladder_40[] = {
 		0x0100, 0x0200, 0x0400, 0x0700, 0x0900, 0x0c00, 0x1200, 0x1900,
 		0x2300,
 		0x3200, 0x4700, 0x4701, 0x4702, 0x4703, 0x4704, 0x4705, 0x4706,
 		0x4707
 	};
 
-	u16 tbl_tx_iqlo_cal_startcoefs[] = {
+	static const u16 tbl_tx_iqlo_cal_startcoefs[] = {
 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
 		0x0000
 	};
 
-	u16 tbl_tx_iqlo_cal_cmds_fullcal[] = {
+	static const u16 tbl_tx_iqlo_cal_cmds_fullcal[] = {
 		0x8123, 0x8264, 0x8086, 0x8245, 0x8056,
 		0x9123, 0x9264, 0x9086, 0x9245, 0x9056
 	};
 
-	u16 tbl_tx_iqlo_cal_cmds_recal[] = {
+	static const u16 tbl_tx_iqlo_cal_cmds_recal[] = {
 		0x8101, 0x8253, 0x8053, 0x8234, 0x8034,
 		0x9101, 0x9253, 0x9053, 0x9234, 0x9034
 	};
 
-	u16 tbl_tx_iqlo_cal_startcoefs_nphyrev3[] = {
+	static const u16 tbl_tx_iqlo_cal_startcoefs_nphyrev3[] = {
 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
 		0x0000
 	};
 
-	u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[] = {
+	static const u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[] = {
 		0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234,
 		0x9434, 0x9334, 0x9084, 0x9267, 0x9056, 0x9234
 	};
 
-	u16 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[] = {
+	static const u16 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[] = {
 		0x8423, 0x8323, 0x8073, 0x8256, 0x8045, 0x8223,
 		0x9423, 0x9323, 0x9073, 0x9256, 0x9045, 0x9223
 	};
author maintainer
#52 lore raw

PATCH 54/85 ARM: dts: sun6i: Fix endpoint IDs in second display pipeline

In reply to Greg Kroah-Hartman

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

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

From: Chen-Yu Tsai <[email protected]>

commit a231d2783c332ef3e3ba238e82dbe599ff41ba14 upstream.

When the second display pipeline device nodes for the A31/A31s were added, it was not known that the TCONs could (through either DRCs) select either backend as their input. Thus in the endpoints connecting these components together, the endpoint IDs were set to 0, while in fact they should have been set to 1.

Fixes 9a26882a7378 ("ARM: dts: sun6i: Add second display pipeline device
		      nodes")
---
 arch/arm/boot/dts/sun6i-a31.dtsi |   16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)
arch/arm/boot/dts/sun6i-a31.dtsi +8 -8
@@ -311,8 +311,8 @@
 					#size-cells = <0>;
 					reg = <0>;
 
-					tcon1_in_drc1: endpoint@0 {
-						reg = <0>;
+					tcon1_in_drc1: endpoint@1 {
+						reg = <1>;
 						remote-endpoint = <&drc1_out_tcon1>;
 					};
 				};
@@ -1012,8 +1012,8 @@
 					#size-cells = <0>;
 					reg = <1>;
 
-					be1_out_drc1: endpoint@0 {
-						reg = <0>;
+					be1_out_drc1: endpoint@1 {
+						reg = <1>;
 						remote-endpoint = <&drc1_in_be1>;
 					};
 				};
@@ -1042,8 +1042,8 @@
 					#size-cells = <0>;
 					reg = <0>;
 
-					drc1_in_be1: endpoint@0 {
-						reg = <0>;
+					drc1_in_be1: endpoint@1 {
+						reg = <1>;
 						remote-endpoint = <&be1_out_drc1>;
 					};
 				};
@@ -1053,8 +1053,8 @@
 					#size-cells = <0>;
 					reg = <1>;
 
-					drc1_out_tcon1: endpoint@0 {
-						reg = <0>;
+					drc1_out_tcon1: endpoint@1 {
+						reg = <1>;
 						remote-endpoint = <&tcon1_in_drc1>;
 					};
 				};
author maintainer
#53 lore raw

PATCH 55/85 bus: mbus: fix window size calculation for 4GB windows

In reply to Greg Kroah-Hartman

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

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

From: Jan Luebbe <[email protected]>

commit 2bbbd96357ce76cc45ec722c00f654aa7b189112 upstream.

At least the Armada XP SoC supports 4GB on a single DRAM window. Because the size register values contain the actual size - 1, the MSB is set in that case. For example, the SDRAM window's control register's value is 0xffffffe1 for 4GB (bits 31 to 24 contain the size).

The MBUS driver reads back each window's size from registers and calculates the actual size as (control_reg | ~DDR_SIZE_MASK) + 1, which overflows for 32 bit values, resulting in other miscalculations further on (a bad RAM window for the CESA crypto engine calculated by mvebu_mbus_setup_cpu_target_nooverlap() in my case).

This patch changes the type in 'struct mbus_dram_window' from u32 to u64, which allows us to keep using the same register calculation code in most MBUS-using drivers (which calculate ->size - 1 again).

Fixes fddddb52a6c4 ("bus: introduce an Marvell EBU MBus driver")
---
 drivers/bus/mvebu-mbus.c |    2 +-
 include/linux/mbus.h     |    4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)
drivers/bus/mvebu-mbus.c +1 -1
@@ -720,7 +720,7 @@ mvebu_mbus_default_setup_cpu_target(stru
 			if (mbus->hw_io_coherency)
 				w->mbus_attr |= ATTR_HW_COHERENCY;
 			w->base = base & DDR_BASE_CS_LOW_MASK;
-			w->size = (size | ~DDR_SIZE_MASK) + 1;
+			w->size = (u64)(size | ~DDR_SIZE_MASK) + 1;
 		}
 	}
 	mvebu_mbus_dram_info.num_cs = cs;
include/linux/mbus.h +2 -2
@@ -31,8 +31,8 @@ struct mbus_dram_target_info
 	struct mbus_dram_window {
 		u8	cs_index;
 		u8	mbus_attr;
-		u32	base;
-		u32	size;
+		u64	base;
+		u64	size;
 	} cs[4];
 };
 
author maintainer
#54 lore raw

PATCH 56/85 clockevents/drivers/cs5535: Improve resilience to spurious interrupts

In reply to Greg Kroah-Hartman

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

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

From: David Kozub <[email protected]>

commit eb39a7c0355393c5a8d930f342ad7a6231b552c4 upstream.

The interrupt handler mfgpt_tick() is not robust versus spurious interrupts which happen before the clock event device is registered and fully initialized.

The reason is that the safe guard against spurious interrupts solely checks for the clockevents shutdown state, but lacks a check for detached state. If the interrupt hits while the device is in detached state it passes the safe guard and dereferences the event handler call back which is NULL.

Add the missing state check.

Fixes 8f9327cbb6e8 ("clockevents/drivers/cs5535: Migrate to new 'set-state' interface")
Cc Daniel Lezcano <[email protected]>
---
 drivers/clocksource/cs5535-clockevt.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/clocksource/cs5535-clockevt.c +2 -1
@@ -117,7 +117,8 @@ static irqreturn_t mfgpt_tick(int irq, v
 	/* Turn off the clock (and clear the event) */
 	disable_timer(cs5535_event_clock);
 
-	if (clockevent_state_shutdown(&cs5535_clockevent))
+	if (clockevent_state_detached(&cs5535_clockevent) ||
+	    clockevent_state_shutdown(&cs5535_clockevent))
 		return IRQ_HANDLED;
 
 	/* Clear the counter */
author maintainer
#55 lore raw

PATCH 57/85 rtlwifi: rtl8821ae: Fix connection lost problem

In reply to Greg Kroah-Hartman

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

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

From: Larry Finger <[email protected]>

commit b8b8b16352cd90c6083033fd4487f04fae935c18 upstream.

In commit 40b368af4b75 ("rtlwifi: Fix alignment issues"), the read of REG_DBI_READ was changed from 16 to 8 bits. For unknown reasonsi this change results in reduced stability for the wireless connection. This regression was located using bisection.

Fixes 40b368af4b75 ("rtlwifi: Fix alignment issues")
Reported-and-tested-by James Cameron <[email protected]>
Cc Ping-Ke Shih <[email protected]>
---
 drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c +1 -1
@@ -1122,7 +1122,7 @@ static u8 _rtl8821ae_dbi_read(struct rtl
 	}
 	if (0 == tmp) {
 		read_addr = REG_DBI_RDATA + addr % 4;
-		ret = rtl_read_byte(rtlpriv, read_addr);
+		ret = rtl_read_word(rtlpriv, read_addr);
 	}
 	return ret;
 }
author maintainer
#56 lore raw

PATCH 58/85 x86/microcode/intel: Disable late loading on model 79

In reply to Greg Kroah-Hartman

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

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

From: Borislav Petkov <[email protected]>

commit 723f2828a98c8ca19842042f418fb30dd8cfc0f7 upstream.

Blacklist Broadwell X model 79 for late loading due to an erratum.

---
 arch/x86/kernel/cpu/microcode/intel.c |   19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
arch/x86/kernel/cpu/microcode/intel.c +19 -0
@@ -34,6 +34,7 @@
 #include <linux/mm.h>
 
 #include <asm/microcode_intel.h>
+#include <asm/intel-family.h>
 #include <asm/processor.h>
 #include <asm/tlbflush.h>
 #include <asm/setup.h>
@@ -917,6 +918,18 @@ static int get_ucode_fw(void *to, const
 	return 0;
 }
 
+static bool is_blacklisted(unsigned int cpu)
+{
+	struct cpuinfo_x86 *c = &cpu_data(cpu);
+
+	if (c->x86 == 6 && c->x86_model == INTEL_FAM6_BROADWELL_X) {
+		pr_err_once("late loading on model 79 is disabled.\n");
+		return true;
+	}
+
+	return false;
+}
+
 static enum ucode_state request_microcode_fw(int cpu, struct device *device,
 					     bool refresh_fw)
 {
@@ -925,6 +938,9 @@ static enum ucode_state request_microcod
 	const struct firmware *firmware;
 	enum ucode_state ret;
 
+	if (is_blacklisted(cpu))
+		return UCODE_NFOUND;
+
 	sprintf(name, "intel-ucode/%02x-%02x-%02x",
 		c->x86, c->x86_model, c->x86_mask);
 
@@ -949,6 +965,9 @@ static int get_ucode_user(void *to, cons
 static enum ucode_state
 request_microcode_user(int cpu, const void __user *buf, size_t size)
 {
+	if (is_blacklisted(cpu))
+		return UCODE_NFOUND;
+
 	return generic_load_microcode(cpu, (void *)buf, size, &get_ucode_user);
 }
 
author maintainer
#57 lore raw

PATCH 59/85 lib/digsig: fix dereference of NULL user_key_payload

In reply to Greg Kroah-Hartman

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

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

From: Eric Biggers <[email protected]>

commit 192cabd6a296cbc57b3d8c05c4c89d87fc102506 upstream.

digsig_verify() requests a user key, then accesses its payload. However, a revoked key has a NULL payload, and we failed to check for this. request_key() *does* skip revoked keys, but there is still a window where the key can be revoked before we acquire its semaphore.

Fix it by checking for a NULL payload, treating it like a key which was already revoked at the time it was requested.

Fixes 051dbb918c7f ("crypto: digital signature verification support")
Cc Dmitry Kasatkin <[email protected]>
---
 lib/digsig.c |    6 ++++++
 1 file changed, 6 insertions(+)
lib/digsig.c +6 -0
@@ -87,6 +87,12 @@ static int digsig_verify_rsa(struct key
 	down_read(&key->sem);
 	ukp = user_key_payload_locked(key);
 
+	if (!ukp) {
+		/* key was revoked before we acquired its semaphore */
+		err = -EKEYREVOKED;
+		goto err1;
+	}
+
 	if (ukp->datalen < sizeof(*pkh))
 		goto err1;
 
author maintainer
#58 lore raw

PATCH 60/85 fscrypt: fix dereference of NULL user_key_payload

In reply to Greg Kroah-Hartman

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

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

From: Eric Biggers <[email protected]>

commit d60b5b7854c3d135b869f74fb93eaf63cbb1991a upstream.

When an fscrypt-encrypted file is opened, we request the file's master key from the keyrings service as a logon key, then access its payload. However, a revoked key has a NULL payload, and we failed to check for this. request_key() *does* skip revoked keys, but there is still a window where the key can be revoked before we acquire its semaphore.

Fix it by checking for a NULL payload, treating it like a key which was already revoked at the time it was requested.

Fixes 88bd6ccdcdd6 ("ext4 crypto: add encryption key management facilities")
---
 fs/crypto/keyinfo.c |    5 +++++
 1 file changed, 5 insertions(+)
fs/crypto/keyinfo.c +5 -0
@@ -109,6 +109,11 @@ static int validate_user_key(struct fscr
 		goto out;
 	}
 	ukp = user_key_payload_locked(keyring_key);
+	if (!ukp) {
+		/* key was revoked before we acquired its semaphore */
+		res = -EKEYREVOKED;
+		goto out;
+	}
 	if (ukp->datalen != sizeof(struct fscrypt_key)) {
 		res = -EINVAL;
 		goto out;
author maintainer
#59 lore raw

PATCH 61/85 ecryptfs: fix dereference of NULL user_key_payload

In reply to Greg Kroah-Hartman

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

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

From: Eric Biggers <[email protected]>

commit f66665c09ab489a11ca490d6a82df57cfc1bea3e upstream.

In eCryptfs, we failed to verify that the authentication token keys are not revoked before dereferencing their payloads, which is problematic because the payload of a revoked key is NULL. request_key() *does* skip revoked keys, but there is still a window where the key can be revoked before we acquire the key semaphore.

Fix it by updating ecryptfs_get_key_payload_data() to return -EKEYREVOKED if the key payload is NULL. For completeness we check this for "encrypted" keys as well as "user" keys, although encrypted keys cannot be revoked currently.

Alternatively we could use key_validate(), but since we'll also need to fix ecryptfs_get_key_payload_data() to validate the payload length, it seems appropriate to just check the payload pointer.

Fixes 237fead61998 ("[PATCH] ecryptfs: fs/Makefile and fs/Kconfig")
Cc Michael Halcrow <[email protected]>
---
 fs/ecryptfs/ecryptfs_kernel.h |   24 +++++++++++++++++-------
 fs/ecryptfs/keystore.c        |    9 ++++++++-
 2 files changed, 25 insertions(+), 8 deletions(-)
fs/ecryptfs/ecryptfs_kernel.h +17 -7
@@ -84,11 +84,16 @@ struct ecryptfs_page_crypt_context {
 static inline struct ecryptfs_auth_tok *
 ecryptfs_get_encrypted_key_payload_data(struct key *key)
 {
-	if (key->type == &key_type_encrypted)
-		return (struct ecryptfs_auth_tok *)
-			(&((struct encrypted_key_payload *)key->payload.data[0])->payload_data);
-	else
+	struct encrypted_key_payload *payload;
+
+	if (key->type != &key_type_encrypted)
 		return NULL;
+
+	payload = key->payload.data[0];
+	if (!payload)
+		return ERR_PTR(-EKEYREVOKED);
+
+	return (struct ecryptfs_auth_tok *)payload->payload_data;
 }
 
 static inline struct key *ecryptfs_get_encrypted_key(char *sig)
@@ -114,12 +119,17 @@ static inline struct ecryptfs_auth_tok *
 ecryptfs_get_key_payload_data(struct key *key)
 {
 	struct ecryptfs_auth_tok *auth_tok;
+	struct user_key_payload *ukp;
 
 	auth_tok = ecryptfs_get_encrypted_key_payload_data(key);
-	if (!auth_tok)
-		return (struct ecryptfs_auth_tok *)user_key_payload_locked(key)->data;
-	else
+	if (auth_tok)
 		return auth_tok;
+
+	ukp = user_key_payload_locked(key);
+	if (!ukp)
+		return ERR_PTR(-EKEYREVOKED);
+
+	return (struct ecryptfs_auth_tok *)ukp->data;
 }
 
 #define ECRYPTFS_MAX_KEYSET_SIZE 1024
fs/ecryptfs/keystore.c +8 -1
@@ -459,7 +459,8 @@ out:
  * @auth_tok_key: key containing the authentication token
  * @auth_tok: authentication token
  *
- * Returns zero on valid auth tok; -EINVAL otherwise
+ * Returns zero on valid auth tok; -EINVAL if the payload is invalid; or
+ * -EKEYREVOKED if the key was revoked before we acquired its semaphore.
  */
 static int
 ecryptfs_verify_auth_tok_from_key(struct key *auth_tok_key,
@@ -468,6 +469,12 @@ ecryptfs_verify_auth_tok_from_key(struct
 	int rc = 0;
 
 	(*auth_tok) = ecryptfs_get_key_payload_data(auth_tok_key);
+	if (IS_ERR(*auth_tok)) {
+		rc = PTR_ERR(*auth_tok);
+		*auth_tok = NULL;
+		goto out;
+	}
+
 	if (ecryptfs_verify_version((*auth_tok)->version)) {
 		printk(KERN_ERR "Data structure version mismatch. Userspace "
 		       "tools must match eCryptfs kernel module with major "
author maintainer
#60 lore raw

PATCH 62/85 KEYS: Fix race between updating and finding a negative key

In reply to Greg Kroah-Hartman

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

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

From: David Howells <[email protected]>

commit 363b02dab09b3226f3bd1420dad9c72b79a42a76 upstream.

Consolidate KEY_FLAG_INSTANTIATED, KEY_FLAG_NEGATIVE and the rejection error into one field such that:

(1) The instantiation state can be modified/read atomically.

(2) The error can be accessed atomically with the state.

(3) The error isn't stored unioned with the payload pointers.

This deals with the problem that the state is spread over three different objects (two bits and a separate variable) and reading or updating them atomically isn't practical, given that not only can uninstantiated keys change into instantiated or rejected keys, but rejected keys can also turn into instantiated keys - and someone accessing the key might not be using any locking.

The main side effect of this problem is that what was held in the payload may change, depending on the state. For instance, you might observe the key to be in the rejected state. You then read the cached error, but if the key semaphore wasn't locked, the key might've become instantiated between the two reads - and you might now have something in hand that isn't actually an error code.

The state is now KEY_IS_UNINSTANTIATED, KEY_IS_POSITIVE or a negative error code if the key is negatively instantiated. The key_is_instantiated() function is replaced with key_is_positive() to avoid confusion as negative keys are also 'instantiated'.

Additionally, barriering is included:

(1) Order payload-set before state-set during instantiation.

(2) Order state-read before payload-read when using the key.

Further separate barriering is necessary if RCU is being used to access the payload content after reading the payload pointers.

Fixes 146aa8b1453b ("KEYS: Merge the type-specific data with the payload data")
---
 include/linux/key.h                      |   47 +++++++++++++++++++------------
 net/dns_resolver/dns_key.c               |    2 -
 security/keys/big_key.c                  |    4 +-
 security/keys/encrypted-keys/encrypted.c |    2 -
 security/keys/gc.c                       |    8 ++---
 security/keys/key.c                      |   31 +++++++++++++-------
 security/keys/keyctl.c                   |    9 ++---
 security/keys/keyring.c                  |   10 +++---
 security/keys/proc.c                     |    7 +++-
 security/keys/process_keys.c             |    2 -
 security/keys/request_key.c              |    7 +---
 security/keys/request_key_auth.c         |    2 -
 security/keys/trusted.c                  |    2 -
 security/keys/user_defined.c             |    4 +-
 14 files changed, 80 insertions(+), 57 deletions(-)
include/linux/key.h +30 -17
@@ -138,6 +138,11 @@ struct key_restriction {
 	struct key_type *keytype;
 };
 
+enum key_state {
+	KEY_IS_UNINSTANTIATED,
+	KEY_IS_POSITIVE,		/* Positively instantiated */
+};
+
 /*****************************************************************************/
 /*
  * authentication token / access credential / keyring
@@ -169,6 +174,7 @@ struct key {
 						 * - may not match RCU dereferenced payload
 						 * - payload should contain own length
 						 */
+	short			state;		/* Key state (+) or rejection error (-) */
 
 #ifdef KEY_DEBUGGING
 	unsigned		magic;
@@ -176,18 +182,16 @@ struct key {
 #endif
 
 	unsigned long		flags;		/* status flags (change with bitops) */
-#define KEY_FLAG_INSTANTIATED	0	/* set if key has been instantiated */
-#define KEY_FLAG_DEAD		1	/* set if key type has been deleted */
-#define KEY_FLAG_REVOKED	2	/* set if key had been revoked */
-#define KEY_FLAG_IN_QUOTA	3	/* set if key consumes quota */
-#define KEY_FLAG_USER_CONSTRUCT	4	/* set if key is being constructed in userspace */
-#define KEY_FLAG_NEGATIVE	5	/* set if key is negative */
-#define KEY_FLAG_ROOT_CAN_CLEAR	6	/* set if key can be cleared by root without permission */
-#define KEY_FLAG_INVALIDATED	7	/* set if key has been invalidated */
-#define KEY_FLAG_BUILTIN	8	/* set if key is built in to the kernel */
-#define KEY_FLAG_ROOT_CAN_INVAL	9	/* set if key can be invalidated by root without permission */
-#define KEY_FLAG_KEEP		10	/* set if key should not be removed */
-#define KEY_FLAG_UID_KEYRING	11	/* set if key is a user or user session keyring */
+#define KEY_FLAG_DEAD		0	/* set if key type has been deleted */
+#define KEY_FLAG_REVOKED	1	/* set if key had been revoked */
+#define KEY_FLAG_IN_QUOTA	2	/* set if key consumes quota */
+#define KEY_FLAG_USER_CONSTRUCT	3	/* set if key is being constructed in userspace */
+#define KEY_FLAG_ROOT_CAN_CLEAR	4	/* set if key can be cleared by root without permission */
+#define KEY_FLAG_INVALIDATED	5	/* set if key has been invalidated */
+#define KEY_FLAG_BUILTIN	6	/* set if key is built in to the kernel */
+#define KEY_FLAG_ROOT_CAN_INVAL	7	/* set if key can be invalidated by root without permission */
+#define KEY_FLAG_KEEP		8	/* set if key should not be removed */
+#define KEY_FLAG_UID_KEYRING	9	/* set if key is a user or user session keyring */
 
 	/* the key type and key description string
 	 * - the desc is used to match a key against search criteria
@@ -213,7 +217,6 @@ struct key {
 			struct list_head name_link;
 			struct assoc_array keys;
 		};
-		int reject_error;
 	};
 
 	/* This is set on a keyring to restrict the addition of a link to a key
@@ -353,17 +356,27 @@ extern void key_set_timeout(struct key *
 #define	KEY_NEED_SETATTR 0x20	/* Require permission to change attributes */
 #define	KEY_NEED_ALL	0x3f	/* All the above permissions */
 
+static inline short key_read_state(const struct key *key)
+{
+	/* Barrier versus mark_key_instantiated(). */
+	return smp_load_acquire(&key->state);
+}
+
 /**
- * key_is_instantiated - Determine if a key has been positively instantiated
+ * key_is_positive - Determine if a key has been positively instantiated
  * @key: The key to check.
  *
  * Return true if the specified key has been positively instantiated, false
  * otherwise.
  */
-static inline bool key_is_instantiated(const struct key *key)
+static inline bool key_is_positive(const struct key *key)
+{
+	return key_read_state(key) == KEY_IS_POSITIVE;
+}
+
+static inline bool key_is_negative(const struct key *key)
 {
-	return test_bit(KEY_FLAG_INSTANTIATED, &key->flags) &&
-		!test_bit(KEY_FLAG_NEGATIVE, &key->flags);
+	return key_read_state(key) < 0;
 }
 
 #define dereference_key_rcu(KEY)					\
net/dns_resolver/dns_key.c +1 -1
@@ -224,7 +224,7 @@ static int dns_resolver_match_preparse(s
 static void dns_resolver_describe(const struct key *key, struct seq_file *m)
 {
 	seq_puts(m, key->description);
-	if (key_is_instantiated(key)) {
+	if (key_is_positive(key)) {
 		int err = PTR_ERR(key->payload.data[dns_key_error]);
 
 		if (err)
security/keys/big_key.c +2 -2
@@ -247,7 +247,7 @@ void big_key_revoke(struct key *key)
 
 	/* clear the quota */
 	key_payload_reserve(key, 0);
-	if (key_is_instantiated(key) &&
+	if (key_is_positive(key) &&
 	    (size_t)key->payload.data[big_key_len] > BIG_KEY_FILE_THRESHOLD)
 		vfs_truncate(path, 0);
 }
@@ -279,7 +279,7 @@ void big_key_describe(const struct key *
 
 	seq_puts(m, key->description);
 
-	if (key_is_instantiated(key))
+	if (key_is_positive(key))
 		seq_printf(m, ": %zu [%s]",
 			   datalen,
 			   datalen > BIG_KEY_FILE_THRESHOLD ? "file" : "buff");
security/keys/encrypted-keys/encrypted.c +1 -1
@@ -854,7 +854,7 @@ static int encrypted_update(struct key *
 	size_t datalen = prep->datalen;
 	int ret = 0;
 
-	if (test_bit(KEY_FLAG_NEGATIVE, &key->flags))
+	if (key_is_negative(key))
 		return -ENOKEY;
 	if (datalen <= 0 || datalen > 32767 || !prep->data)
 		return -EINVAL;
security/keys/gc.c +4 -4
@@ -129,15 +129,15 @@ static noinline void key_gc_unused_keys(
 	while (!list_empty(keys)) {
 		struct key *key =
 			list_entry(keys->next, struct key, graveyard_link);
+		short state = key->state;
+
 		list_del(&key->graveyard_link);
 
 		kdebug("- %u", key->serial);
 		key_check(key);
 
 		/* Throw away the key data if the key is instantiated */
-		if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags) &&
-		    !test_bit(KEY_FLAG_NEGATIVE, &key->flags) &&
-		    key->type->destroy)
+		if (state == KEY_IS_POSITIVE && key->type->destroy)
 			key->type->destroy(key);
 
 		security_key_free(key);
@@ -151,7 +151,7 @@ static noinline void key_gc_unused_keys(
 		}
 
 		atomic_dec(&key->user->nkeys);
-		if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
+		if (state != KEY_IS_UNINSTANTIATED)
 			atomic_dec(&key->user->nikeys);
 
 		key_user_put(key->user);
security/keys/key.c +20 -11
@@ -402,6 +402,18 @@ int key_payload_reserve(struct key *key,
 EXPORT_SYMBOL(key_payload_reserve);
 
 /*
+ * Change the key state to being instantiated.
+ */
+static void mark_key_instantiated(struct key *key, int reject_error)
+{
+	/* Commit the payload before setting the state; barrier versus
+	 * key_read_state().
+	 */
+	smp_store_release(&key->state,
+			  (reject_error < 0) ? reject_error : KEY_IS_POSITIVE);
+}
+
+/*
  * Instantiate a key and link it into the target keyring atomically.  Must be
  * called with the target keyring's semaphore writelocked.  The target key's
  * semaphore need not be locked as instantiation is serialised by
@@ -424,14 +436,14 @@ static int __key_instantiate_and_link(st
 	mutex_lock(&key_construction_mutex);
 
 	/* can't instantiate twice */
-	if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) {
+	if (key->state == KEY_IS_UNINSTANTIATED) {
 		/* instantiate the key */
 		ret = key->type->instantiate(key, prep);
 
 		if (ret == 0) {
 			/* mark the key as being instantiated */
 			atomic_inc(&key->user->nikeys);
-			set_bit(KEY_FLAG_INSTANTIATED, &key->flags);
+			mark_key_instantiated(key, 0);
 
 			if (test_and_clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags))
 				awaken = 1;
@@ -577,13 +589,10 @@ int key_reject_and_link(struct key *key,
 	mutex_lock(&key_construction_mutex);
 
 	/* can't instantiate twice */
-	if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) {
+	if (key->state == KEY_IS_UNINSTANTIATED) {
 		/* mark the key as being negatively instantiated */
 		atomic_inc(&key->user->nikeys);
-		key->reject_error = -error;
-		smp_wmb();
-		set_bit(KEY_FLAG_NEGATIVE, &key->flags);
-		set_bit(KEY_FLAG_INSTANTIATED, &key->flags);
+		mark_key_instantiated(key, -error);
 		now = current_kernel_time();
 		key->expiry = now.tv_sec + timeout;
 		key_schedule_gc(key->expiry + key_gc_delay);
@@ -752,8 +761,8 @@ static inline key_ref_t __key_update(key
 
 	ret = key->type->update(key, prep);
 	if (ret == 0)
-		/* updating a negative key instantiates it */
-		clear_bit(KEY_FLAG_NEGATIVE, &key->flags);
+		/* Updating a negative key positively instantiates it */
+		mark_key_instantiated(key, 0);
 
 	up_write(&key->sem);
 
@@ -986,8 +995,8 @@ int key_update(key_ref_t key_ref, const
 
 	ret = key->type->update(key, &prep);
 	if (ret == 0)
-		/* updating a negative key instantiates it */
-		clear_bit(KEY_FLAG_NEGATIVE, &key->flags);
+		/* Updating a negative key positively instantiates it */
+		mark_key_instantiated(key, 0);
 
 	up_write(&key->sem);
 
security/keys/keyctl.c +4 -5
@@ -766,10 +766,9 @@ long keyctl_read_key(key_serial_t keyid,
 
 	key = key_ref_to_ptr(key_ref);
 
-	if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) {
-		ret = -ENOKEY;
-		goto error2;
-	}
+	ret = key_read_state(key);
+	if (ret < 0)
+		goto error2; /* Negatively instantiated */
 
 	/* see if we can read it directly */
 	ret = key_permission(key_ref, KEY_NEED_READ);
@@ -901,7 +900,7 @@ long keyctl_chown_key(key_serial_t id, u
 		atomic_dec(&key->user->nkeys);
 		atomic_inc(&newowner->nkeys);
 
-		if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) {
+		if (key->state != KEY_IS_UNINSTANTIATED) {
 			atomic_dec(&key->user->nikeys);
 			atomic_inc(&newowner->nikeys);
 		}
security/keys/keyring.c +5 -5
@@ -414,7 +414,7 @@ static void keyring_describe(const struc
 	else
 		seq_puts(m, "[anon]");
 
-	if (key_is_instantiated(keyring)) {
+	if (key_is_positive(keyring)) {
 		if (keyring->keys.nr_leaves_on_tree != 0)
 			seq_printf(m, ": %lu", keyring->keys.nr_leaves_on_tree);
 		else
@@ -553,7 +553,8 @@ static int keyring_search_iterator(const
 {
 	struct keyring_search_context *ctx = iterator_data;
 	const struct key *key = keyring_ptr_to_key(object);
-	unsigned long kflags = key->flags;
+	unsigned long kflags = READ_ONCE(key->flags);
+	short state = READ_ONCE(key->state);
 
 	kenter("{%d}", key->serial);
 
@@ -597,9 +598,8 @@ static int keyring_search_iterator(const
 
 	if (ctx->flags & KEYRING_SEARCH_DO_STATE_CHECK) {
 		/* we set a different error code if we pass a negative key */
-		if (kflags & (1 << KEY_FLAG_NEGATIVE)) {
-			smp_rmb();
-			ctx->result = ERR_PTR(key->reject_error);
+		if (state < 0) {
+			ctx->result = ERR_PTR(state);
 			kleave(" = %d [neg]", ctx->skipped_ret);
 			goto skipped;
 		}
security/keys/proc.c +5 -2
@@ -182,6 +182,7 @@ static int proc_keys_show(struct seq_fil
 	unsigned long timo;
 	key_ref_t key_ref, skey_ref;
 	char xbuf[16];
+	short state;
 	int rc;
 
 	struct keyring_search_context ctx = {
@@ -240,17 +241,19 @@ static int proc_keys_show(struct seq_fil
 			sprintf(xbuf, "%luw", timo / (60*60*24*7));
 	}
 
+	state = key_read_state(key);
+
 #define showflag(KEY, LETTER, FLAG) \
 	(test_bit(FLAG,	&(KEY)->flags) ? LETTER : '-')
 
 	seq_printf(m, "%08x %c%c%c%c%c%c%c %5d %4s %08x %5d %5d %-9.9s ",
 		   key->serial,
-		   showflag(key, 'I', KEY_FLAG_INSTANTIATED),
+		   state != KEY_IS_UNINSTANTIATED ? 'I' : '-',
 		   showflag(key, 'R', KEY_FLAG_REVOKED),
 		   showflag(key, 'D', KEY_FLAG_DEAD),
 		   showflag(key, 'Q', KEY_FLAG_IN_QUOTA),
 		   showflag(key, 'U', KEY_FLAG_USER_CONSTRUCT),
-		   showflag(key, 'N', KEY_FLAG_NEGATIVE),
+		   state < 0 ? 'N' : '-',
 		   showflag(key, 'i', KEY_FLAG_INVALIDATED),
 		   refcount_read(&key->usage),
 		   xbuf,
security/keys/process_keys.c +1 -1
@@ -730,7 +730,7 @@ try_again:
 
 	ret = -EIO;
 	if (!(lflags & KEY_LOOKUP_PARTIAL) &&
-	    !test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
+	    key_read_state(key) == KEY_IS_UNINSTANTIATED)
 		goto invalid_key;
 
 	/* check the permissions */
security/keys/request_key.c +3 -4
@@ -595,10 +595,9 @@ int wait_for_key_construction(struct key
 			  intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
 	if (ret)
 		return -ERESTARTSYS;
-	if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) {
-		smp_rmb();
-		return key->reject_error;
-	}
+	ret = key_read_state(key);
+	if (ret < 0)
+		return ret;
 	return key_validate(key);
 }
 EXPORT_SYMBOL(wait_for_key_construction);
security/keys/request_key_auth.c +1 -1
@@ -73,7 +73,7 @@ static void request_key_auth_describe(co
 
 	seq_puts(m, "key:");
 	seq_puts(m, key->description);
-	if (key_is_instantiated(key))
+	if (key_is_positive(key))
 		seq_printf(m, " pid:%d ci:%zu", rka->pid, rka->callout_len);
 }
 
security/keys/trusted.c +1 -1
@@ -1066,7 +1066,7 @@ static int trusted_update(struct key *ke
 	char *datablob;
 	int ret = 0;
 
-	if (test_bit(KEY_FLAG_NEGATIVE, &key->flags))
+	if (key_is_negative(key))
 		return -ENOKEY;
 	p = key->payload.data[0];
 	if (!p->migratable)
security/keys/user_defined.c +2 -2
@@ -114,7 +114,7 @@ int user_update(struct key *key, struct
 
 	/* attach the new data, displacing the old */
 	key->expiry = prep->expiry;
-	if (!test_bit(KEY_FLAG_NEGATIVE, &key->flags))
+	if (key_is_positive(key))
 		zap = dereference_key_locked(key);
 	rcu_assign_keypointer(key, prep->payload.data[0]);
 	prep->payload.data[0] = NULL;
@@ -162,7 +162,7 @@ EXPORT_SYMBOL_GPL(user_destroy);
 void user_describe(const struct key *key, struct seq_file *m)
 {
 	seq_puts(m, key->description);
-	if (key_is_instantiated(key))
+	if (key_is_positive(key))
 		seq_printf(m, ": %u", key->datalen);
 }
 
author maintainer
#61 lore raw

PATCH 63/85 FS-Cache: fix dereference of NULL user_key_payload

In reply to Greg Kroah-Hartman

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

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

From: Eric Biggers <[email protected]>

commit d124b2c53c7bee6569d2a2d0b18b4a1afde00134 upstream.

When the file /proc/fs/fscache/objects (available with CONFIG_FSCACHE_OBJECT_LIST=y) is opened, we request a user key with description "fscache:objlist", then access its payload. However, a revoked key has a NULL payload, and we failed to check for this. request_key() *does* skip revoked keys, but there is still a window where the key can be revoked before we access its payload.

Fix it by checking for a NULL payload, treating it like a key which was already revoked at the time it was requested.

Fixes 4fbf4291aa15 ("FS-Cache: Allow the current state of all objects to be dumped")
---
 fs/fscache/object-list.c |    7 +++++++
 1 file changed, 7 insertions(+)
fs/fscache/object-list.c +7 -0
@@ -330,6 +330,13 @@ static void fscache_objlist_config(struc
 	rcu_read_lock();
 
 	confkey = user_key_payload_rcu(key);
+	if (!confkey) {
+		/* key was revoked */
+		rcu_read_unlock();
+		key_put(key);
+		goto no_config;
+	}
+
 	buf = confkey->data;
 
 	for (len = confkey->datalen - 1; len >= 0; len--) {
author maintainer
#62 lore raw

PATCH 64/85 KEYS: dont let add_key() update an uninstantiated key

In reply to Greg Kroah-Hartman

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

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

From: David Howells <[email protected]>

commit 60ff5b2f547af3828aebafd54daded44cfb0807a upstream.

Currently, when passed a key that already exists, add_key() will call the key's ->update() method if such exists. But this is heavily broken in the case where the key is uninstantiated because it doesn't call __key_instantiate_and_link(). Consequently, it doesn't do most of the things that are supposed to happen when the key is instantiated, such as setting the instantiation state, clearing KEY_FLAG_USER_CONSTRUCT and awakening tasks waiting on it, and incrementing key->user->nikeys.

It also never takes key_construction_mutex, which means that ->instantiate() can run concurrently with ->update() on the same key. In the case of the "user" and "logon" key types this causes a memory leak, at best. Maybe even worse, the ->update() methods of the "encrypted" and "trusted" key types actually just dereference a NULL pointer when passed an uninstantiated key.

Change key_create_or_update() to wait interruptibly for the key to finish construction before continuing.

This patch only affects *uninstantiated* keys. For now we still allow a negatively instantiated key to be updated (thereby positively instantiating it), although that's broken too (the next patch fixes it) and I'm not sure that anyone actually uses that functionality either.

Here is a simple reproducer for the bug using the "encrypted" key type (requires CONFIG_ENCRYPTED_KEYS=y), though as noted above the bug pertained to more than just the "encrypted" key type:

    #include <stdlib.h>
    #include <unistd.h>
    #include <keyutils.h>

    int main(void)
    {
        int ringid = keyctl_join_session_keyring(NULL);

        if (fork()) {
            for (;;) {
                const char payload[] = "update user:foo 32";

                usleep(rand() % 10000);
                add_key("encrypted", "desc", payload, sizeof(payload), ringid);
                keyctl_clear(ringid);
            }
        } else {
            for (;;)
                request_key("encrypted", "desc", "callout_info", ringid);
        }
    }

It causes:

    BUG: unable to handle kernel NULL pointer dereference at 0000000000000018
    IP: encrypted_update+0xb0/0x170
    PGD 7a178067 P4D 7a178067 PUD 77269067 PMD 0
    PREEMPT SMP
    CPU: 0 PID: 340 Comm: reproduce Tainted: G      D         4.14.0-rc1-00025-g428490e38b2e #796
    Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
    task: ffff8a467a39a340 task.stack: ffffb15c40770000
    RIP: 0010:encrypted_update+0xb0/0x170
    RSP: 0018:ffffb15c40773de8 EFLAGS: 00010246
    RAX: 0000000000000000 RBX: ffff8a467a275b00 RCX: 0000000000000000
    RDX: 0000000000000005 RSI: ffff8a467a275b14 RDI: ffffffffb742f303
    RBP: ffffb15c40773e20 R08: 0000000000000000 R09: ffff8a467a275b17
    R10: 0000000000000020 R11: 0000000000000000 R12: 0000000000000000
    R13: 0000000000000000 R14: ffff8a4677057180 R15: ffff8a467a275b0f
    FS:  00007f5d7fb08700(0000) GS:ffff8a467f200000(0000) knlGS:0000000000000000
    CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    CR2: 0000000000000018 CR3: 0000000077262005 CR4: 00000000001606f0
    Call Trace:
     key_create_or_update+0x2bc/0x460
     SyS_add_key+0x10c/0x1d0
     entry_SYSCALL_64_fastpath+0x1f/0xbe
    RIP: 0033:0x7f5d7f211259
    RSP: 002b:00007ffed03904c8 EFLAGS: 00000246 ORIG_RAX: 00000000000000f8
    RAX: ffffffffffffffda RBX: 000000003b2a7955 RCX: 00007f5d7f211259
    RDX: 00000000004009e4 RSI: 00000000004009ff RDI: 0000000000400a04
    RBP: 0000000068db8bad R08: 000000003b2a7955 R09: 0000000000000004
    R10: 000000000000001a R11: 0000000000000246 R12: 0000000000400868
    R13: 00007ffed03905d0 R14: 0000000000000000 R15: 0000000000000000
    Code: 77 28 e8 64 34 1f 00 45 31 c0 31 c9 48 8d 55 c8 48 89 df 48 8d 75 d0 e8 ff f9 ff ff 85 c0 41 89 c4 0f 88 84 00 00 00 4c 8b 7d c8 <49> 8b 75 18 4c 89 ff e8 24 f8 ff ff 85 c0 41 89 c4 78 6d 49 8b
    RIP: encrypted_update+0xb0/0x170 RSP: ffffb15c40773de8
    CR2: 0000000000000018
---
 security/keys/key.c |   10 ++++++++++
 1 file changed, 10 insertions(+)
security/keys/key.c +10 -0
@@ -945,6 +945,16 @@ error:
 	 */
 	__key_link_end(keyring, &index_key, edit);
 
+	key = key_ref_to_ptr(key_ref);
+	if (test_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags)) {
+		ret = wait_for_key_construction(key, true);
+		if (ret < 0) {
+			key_ref_put(key_ref);
+			key_ref = ERR_PTR(ret);
+			goto error_free_prep;
+		}
+	}
+
 	key_ref = __key_update(key_ref, &prep);
 	goto error_free_prep;
 }
author maintainer
#63 lore raw

PATCH 65/85 pkcs7: Prevent NULL pointer dereference, since sinfo is not always set.

In reply to Greg Kroah-Hartman

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

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

From: Eric Sesterhenn <[email protected]>

commit 68a1fdbbf8bd3378325e45c19e167a165f9ffc3a upstream.

The ASN.1 parser does not necessarily set the sinfo field, this patch prevents a NULL pointer dereference on broken input.

Fixes 99db44350672 ("PKCS#7: Appropriately restrict authenticated attributes and content type")
---
 crypto/asymmetric_keys/pkcs7_parser.c |    3 +++
 1 file changed, 3 insertions(+)
crypto/asymmetric_keys/pkcs7_parser.c +3 -0
@@ -88,6 +88,9 @@ static int pkcs7_check_authattrs(struct
 	bool want = false;
 
 	sinfo = msg->signed_infos;
+	if (!sinfo)
+		goto inconsistent;
+
 	if (sinfo->authattrs) {
 		want = true;
 		msg->have_authattrs = true;
author maintainer
#64 lore raw

PATCH 66/85 arm64: dts: rockchip: correct vqmmc voltage for rk3399 platforms

In reply to Greg Kroah-Hartman

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

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

From: Shawn Lin <[email protected]>

commit b31ce3041787b61f2dad39d2dcda5c4a81d10e2b upstream.

The vcc_sd or vcc_sdio used for IO voltage for sdmmc and sdio interface on rk3399 platform have a limitation that it can't be larger than 3.0v, otherwise it has a potential risk for the chip. Correct all of them.

Fixes 171582e00db1 ("arm64: dts: rockchip: add support for firefly-rk3399 board")
Fixes 2c66fc34e945 ("arm64: dts: rockchip: add RK3399-Q7 (Puma) SoM")
Fixes 8164a84cca12 ("arm64: dts: rockchip: Add support for rk3399 sapphire SOM")
---
 arch/arm64/boot/dts/rockchip/rk3399-firefly.dts |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/rockchip/rk3399-firefly.dts +2 -2
@@ -370,10 +370,10 @@
 				regulator-always-on;
 				regulator-boot-on;
 				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <3300000>;
+				regulator-max-microvolt = <3000000>;
 				regulator-state-mem {
 					regulator-on-in-suspend;
-					regulator-suspend-microvolt = <3300000>;
+					regulator-suspend-microvolt = <3000000>;
 				};
 			};
 
author maintainer
#65 lore raw

PATCH 67/85 ALSA: hda - Fix incorrect TLV callback check introduced during set_fs() removal

In reply to Greg Kroah-Hartman

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

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

From: Takashi Iwai <[email protected]>

commit a91d66129fb9bcead12af3ed2008d6ddbf179509 upstream.

The commit 99b5c5bb9a54 ("ALSA: hda - Remove the use of set_fs()") converted the get_kctl_0dB_offset() call for killing set_fs() usage in HD-audio codec code. The conversion assumed that the TLV callback used in HD-audio code is only snd_hda_mixer_amp() and applies the TLV calculation locally.

Although this assumption is correct, and all slave kctls are actually with that callback, the current code is still utterly buggy; it doesn't hit this condition and falls back to the next check. It's because the function gets called after adding slave kctls to vmaster. By assigning a slave kctl, the slave kctl object is faked inside vmaster code, and the whole kctl ops are overridden. Thus the callback op points to a different value from what we've assumed.

More badly, as reported by the KERNEXEC and UDEREF features of PaX, the code flow turns into the unexpected pitfall. The next fallback check is SNDRV_CTL_ELEM_ACCESS_TLV_READ access bit, and this always hits for each kctl with TLV. Then it evaluates the callback function pointer wrongly as if it were a TLV array. Although currently its side-effect is fairly limited, this incorrect reference may lead to an unpleasant result.

For addressing the regression, this patch introduces a new helper to vmaster code, snd_ctl_apply_vmaster_slaves(). This works similarly like the existing map_slaves() in hda_codec.c: it loops over the slave list of the given master, and applies the given function to each slave. Then the initializer function receives the right kctl object and we can compare the correct pointer instead of the faked one.

Also, for catching the similar breakage in future, give an error message when the unexpected TLV callback is found and bail out immediately.

Fixes 99b5c5bb9a54 ("ALSA: hda - Remove the use of set_fs()")
---
 include/sound/control.h   |    3 +
 sound/core/vmaster.c      |   31 ++++++++++++++
 sound/pci/hda/hda_codec.c |   97 ++++++++++++++++++++++++++--------------------
 3 files changed, 89 insertions(+), 42 deletions(-)
include/sound/control.h +3 -0
@@ -248,6 +248,9 @@ int snd_ctl_add_vmaster_hook(struct snd_
 			     void *private_data);
 void snd_ctl_sync_vmaster(struct snd_kcontrol *kctl, bool hook_only);
 #define snd_ctl_sync_vmaster_hook(kctl)	snd_ctl_sync_vmaster(kctl, true)
+int snd_ctl_apply_vmaster_slaves(struct snd_kcontrol *kctl,
+				 int (*func)(struct snd_kcontrol *, void *),
+				 void *arg);
 
 /*
  * Helper functions for jack-detection controls
sound/core/vmaster.c +31 -0
@@ -484,3 +484,34 @@ void snd_ctl_sync_vmaster(struct snd_kco
 		master->hook(master->hook_private_data, master->val);
 }
 EXPORT_SYMBOL_GPL(snd_ctl_sync_vmaster);
+
+/**
+ * snd_ctl_apply_vmaster_slaves - Apply function to each vmaster slave
+ * @kctl: vmaster kctl element
+ * @func: function to apply
+ * @arg: optional function argument
+ *
+ * Apply the function @func to each slave kctl of the given vmaster kctl.
+ * Returns 0 if successful, or a negative error code.
+ */
+int snd_ctl_apply_vmaster_slaves(struct snd_kcontrol *kctl,
+				 int (*func)(struct snd_kcontrol *, void *),
+				 void *arg)
+{
+	struct link_master *master;
+	struct link_slave *slave;
+	int err;
+
+	master = snd_kcontrol_chip(kctl);
+	err = master_init(master);
+	if (err < 0)
+		return err;
+	list_for_each_entry(slave, &master->slaves, list) {
+		err = func(&slave->slave, arg);
+		if (err < 0)
+			return err;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(snd_ctl_apply_vmaster_slaves);
sound/pci/hda/hda_codec.c +55 -42

119 lines not on this page · raw message

author maintainer
#66 lore raw

PATCH 68/85 iomap_dio_rw: Allocate AIO completion queue before submitting dio

In reply to Greg Kroah-Hartman

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

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

From: Chandan Rajendra <[email protected]>

commit 546e7be8244dc050effef0555df5b8d94d10dafc upstream.

Executing xfs/104 test in a loop on Linux-v4.13 kernel on a ppc64 machine can cause the following NULL pointer dereference,

.queue_work_on+0x4c/0x80
.iomap_dio_bio_end_io+0xbc/0x1f0
.bio_endio+0x118/0x1f0
.blk_update_request+0xd0/0x470
.blk_mq_end_request+0x24/0xc0
.lo_complete_rq+0x40/0xe0
.__blk_mq_complete_request_remote+0x28/0x40
.flush_smp_call_function_queue+0xc4/0x1e0
.smp_ipi_demux_relaxed+0x8c/0x100
.icp_hv_ipi_action+0x54/0xa0
.__handle_irq_event_percpu+0x84/0x2c0
.handle_irq_event_percpu+0x28/0x80
.handle_percpu_irq+0x78/0xc0
.generic_handle_irq+0x40/0x70
.__do_irq+0x88/0x200
.call_do_irq+0x14/0x24
.do_IRQ+0x84/0x130

This occurs due to the following sequence of events,

1. Allocate dio for Direct I/O write.
2. Invoke iomap_apply() until iov_iter_count() bytes have been submitted.
- Assume that we have submitted atleast one bio. Hence iomap_dio->ref value

     will be >= 2.

- If during the second iteration, iomap_apply() ends up returning -ENOSPC, we would break out of the loop and since the 'ret' value is a negative number we end up not allocating memory for super_block->s_dio_done_wq.
3. Meanwhile, iomap_dio_bio_end_io() is invoked for bios that have been submitted and here the code ends up dereferencing the NULL pointer stored at super_block->s_dio_done_wq.

This commit fixes the bug by allocating memory for super_block->s_dio_done_wq before iomap_apply() is invoked.

---
 fs/iomap.c |   14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)
fs/iomap.c +7 -7
@@ -993,6 +993,13 @@ iomap_dio_rw(struct kiocb *iocb, struct
 	WARN_ON_ONCE(ret);
 	ret = 0;
 
+	if (iov_iter_rw(iter) == WRITE && !is_sync_kiocb(iocb) &&
+	    !inode->i_sb->s_dio_done_wq) {
+		ret = sb_init_dio_done_wq(inode->i_sb);
+		if (ret < 0)
+			goto out_free_dio;
+	}
+
 	inode_dio_begin(inode);
 
 	blk_start_plug(&plug);
@@ -1015,13 +1022,6 @@ iomap_dio_rw(struct kiocb *iocb, struct
 	if (ret < 0)
 		iomap_dio_set_error(dio, ret);
 
-	if (ret >= 0 && iov_iter_rw(iter) == WRITE && !is_sync_kiocb(iocb) &&
-			!inode->i_sb->s_dio_done_wq) {
-		ret = sb_init_dio_done_wq(inode->i_sb);
-		if (ret < 0)
-			iomap_dio_set_error(dio, ret);
-	}
-
 	if (!atomic_dec_and_test(&dio->ref)) {
 		if (!is_sync_kiocb(iocb))
 			return -EIOCBQUEUED;
author maintainer
#67 lore raw

PATCH 69/85 xfs: dont unconditionally clear the reflink flag on zero-block files

In reply to Greg Kroah-Hartman

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

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

From: Darrick J. Wong <[email protected]>

commit cc6f77710a6de6210f9feda7cd53e2f5ee7a7e69 upstream.

If we have speculative cow preallocations hanging around in the cow fork, don't let a truncate operation clear the reflink flag because if we do then there's a chance we'll forget to free those extents when we destroy the incore inode.

---
 fs/xfs/xfs_inode.c |    8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
fs/xfs/xfs_inode.c +5 -3
@@ -1623,10 +1623,12 @@ xfs_itruncate_extents(
 		goto out;
 
 	/*
-	 * Clear the reflink flag if we truncated everything.
+	 * Clear the reflink flag if there are no data fork blocks and
+	 * there are no extents staged in the cow fork.
 	 */
-	if (ip->i_d.di_nblocks == 0 && xfs_is_reflink_inode(ip)) {
-		ip->i_d.di_flags2 &= ~XFS_DIFLAG2_REFLINK;
+	if (xfs_is_reflink_inode(ip) && ip->i_cnextents == 0) {
+		if (ip->i_d.di_nblocks == 0)
+			ip->i_d.di_flags2 &= ~XFS_DIFLAG2_REFLINK;
 		xfs_inode_clear_cowblocks_tag(ip);
 	}
 
author maintainer
#68 lore raw

PATCH 70/85 xfs: evict CoW fork extents when performing finsert/fcollapse

In reply to Greg Kroah-Hartman

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

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

From: Darrick J. Wong <[email protected]>

commit 3af423b03435c81036fa710623d3ae92fbe346a3 upstream.

When we perform an finsert/fcollapse operation, cancel all the CoW extents for the affected file offset range so that they don't end up pointing to the wrong blocks.

---
 fs/xfs/xfs_bmap_util.c |   14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)
fs/xfs/xfs_bmap_util.c +13 -1
@@ -1459,7 +1459,19 @@ xfs_shift_file_space(
 		return error;
 
 	/*
-	 * The extent shiting code works on extent granularity. So, if
+	 * Clean out anything hanging around in the cow fork now that
+	 * we've flushed all the dirty data out to disk to avoid having
+	 * CoW extents at the wrong offsets.
+	 */
+	if (xfs_is_reflink_inode(ip)) {
+		error = xfs_reflink_cancel_cow_range(ip, offset, NULLFILEOFF,
+				true);
+		if (error)
+			return error;
+	}
+
+	/*
+	 * The extent shifting code works on extent granularity. So, if
 	 * stop_fsb is not the starting block of extent, we need to split
 	 * the extent at stop_fsb.
 	 */
author maintainer
#69 lore raw

PATCH 71/85 fs/xfs: Use %pS printk format for direct addresses

In reply to Greg Kroah-Hartman

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

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

From: Helge Deller <[email protected]>

commit e150dcd459e1b441eaf08f341a986f04e61bf3b8 upstream.

Use the %pS instead of the %pF printk format specifier for printing symbols from direct addresses. This is needed for the ia64, ppc64 and parisc64 architectures.

---
 fs/xfs/xfs_error.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/xfs/xfs_error.c +1 -1
@@ -344,7 +344,7 @@ xfs_verifier_error(
 {
 	struct xfs_mount *mp = bp->b_target->bt_mount;
 
-	xfs_alert(mp, "Metadata %s detected at %pF, %s block 0x%llx",
+	xfs_alert(mp, "Metadata %s detected at %pS, %s block 0x%llx",
 		  bp->b_error == -EFSBADCRC ? "CRC error" : "corruption",
 		  __return_address, bp->b_ops->name, bp->b_bn);
 
author maintainer
#70 lore raw

PATCH 72/85 xfs: report zeroed or not correctly in xfs_zero_range()

In reply to Greg Kroah-Hartman

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

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

From: Eryu Guan <[email protected]>

commit d20a5e3851969fa685f118a80e4df670255a4e8d upstream.

The 'did_zero' param of xfs_zero_range() was not passed to iomap_zero_range() correctly. This was introduced by commit 7bb41db3ea16 ("xfs: handle 64-bit length in xfs_iozero"), and found by code inspection.

---
 fs/xfs/xfs_file.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/xfs/xfs_file.c +1 -1
@@ -58,7 +58,7 @@ xfs_zero_range(
 	xfs_off_t		count,
 	bool			*did_zero)
 {
-	return iomap_zero_range(VFS_I(ip), pos, count, NULL, &xfs_iomap_ops);
+	return iomap_zero_range(VFS_I(ip), pos, count, did_zero, &xfs_iomap_ops);
 }
 
 int
author maintainer
#71 lore raw

PATCH 73/85 xfs: update i_size after unwritten conversion in dio completion

In reply to Greg Kroah-Hartman

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

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

From: Eryu Guan <[email protected]>

commit ee70daaba82d70766d0723b743d9fdeb3b06102a upstream.

Since commit d531d91d6990 ("xfs: always use unwritten extents for direct I/O writes"), we start allocating unwritten extents for all direct writes to allow appending aio in XFS.

But for dio writes that could extend file size we update the in-core inode size first, then convert the unwritten extents to real allocations at dio completion time in xfs_dio_write_end_io(). Thus a racing direct read could see the new i_size and find the unwritten extents first and read zeros instead of actual data, if the direct writer also takes a shared iolock.

Fix it by updating the in-core inode size after the unwritten extent conversion. To do this, introduce a new boolean argument to xfs_iomap_write_unwritten() to tell if we want to update in-core i_size or not.

---
 fs/xfs/xfs_aops.c  |    3 ++-
 fs/xfs/xfs_file.c  |   33 +++++++++++++++++++--------------
 fs/xfs/xfs_iomap.c |    7 +++++--
 fs/xfs/xfs_iomap.h |    2 +-
 fs/xfs/xfs_pnfs.c  |    2 +-
 5 files changed, 28 insertions(+), 19 deletions(-)
fs/xfs/xfs_aops.c +2 -1
@@ -330,7 +330,8 @@ xfs_end_io(
 		error = xfs_reflink_end_cow(ip, offset, size);
 		break;
 	case XFS_IO_UNWRITTEN:
-		error = xfs_iomap_write_unwritten(ip, offset, size);
+		/* writeback should never update isize */
+		error = xfs_iomap_write_unwritten(ip, offset, size, false);
 		break;
 	default:
 		ASSERT(!xfs_ioend_is_append(ioend) || ioend->io_append_trans);
fs/xfs/xfs_file.c +19 -14
@@ -432,7 +432,6 @@ xfs_dio_write_end_io(
 	struct inode		*inode = file_inode(iocb->ki_filp);
 	struct xfs_inode	*ip = XFS_I(inode);
 	loff_t			offset = iocb->ki_pos;
-	bool			update_size = false;
 	int			error = 0;
 
 	trace_xfs_end_io_direct_write(ip, offset, size);
@@ -443,6 +442,21 @@ xfs_dio_write_end_io(
 	if (size <= 0)
 		return size;
 
+	if (flags & IOMAP_DIO_COW) {
+		error = xfs_reflink_end_cow(ip, offset, size);
+		if (error)
+			return error;
+	}
+
+	/*
+	 * Unwritten conversion updates the in-core isize after extent
+	 * conversion but before updating the on-disk size. Updating isize any
+	 * earlier allows a racing dio read to find unwritten extents before
+	 * they are converted.
+	 */
+	if (flags & IOMAP_DIO_UNWRITTEN)
+		return xfs_iomap_write_unwritten(ip, offset, size, true);
+
 	/*
 	 * We need to update the in-core inode size here so that we don't end up
 	 * with the on-disk inode size being outside the in-core inode size. We
@@ -457,20 +471,11 @@ xfs_dio_write_end_io(
 	spin_lock(&ip->i_flags_lock);
 	if (offset + size > i_size_read(inode)) {
 		i_size_write(inode, offset + size);
-		update_size = true;
-	}
-	spin_unlock(&ip->i_flags_lock);
-
-	if (flags & IOMAP_DIO_COW) {
-		error = xfs_reflink_end_cow(ip, offset, size);
-		if (error)
-			return error;
-	}
-
-	if (flags & IOMAP_DIO_UNWRITTEN)
-		error = xfs_iomap_write_unwritten(ip, offset, size);
-	else if (update_size)
+		spin_unlock(&ip->i_flags_lock);
 		error = xfs_setfilesize(ip, offset, size);
+	} else {
+		spin_unlock(&ip->i_flags_lock);
+	}
 
 	return error;
 }
fs/xfs/xfs_iomap.c +5 -2
@@ -829,7 +829,8 @@ int
 xfs_iomap_write_unwritten(
 	xfs_inode_t	*ip,
 	xfs_off_t	offset,
-	xfs_off_t	count)
+	xfs_off_t	count,
+	bool		update_isize)
 {
 	xfs_mount_t	*mp = ip->i_mount;
 	xfs_fileoff_t	offset_fsb;
@@ -840,6 +841,7 @@ xfs_iomap_write_unwritten(
 	xfs_trans_t	*tp;
 	xfs_bmbt_irec_t imap;
 	struct xfs_defer_ops dfops;
+	struct inode	*inode = VFS_I(ip);
 	xfs_fsize_t	i_size;
 	uint		resblks;
 	int		error;
@@ -899,7 +901,8 @@ xfs_iomap_write_unwritten(
 		i_size = XFS_FSB_TO_B(mp, offset_fsb + count_fsb);
 		if (i_size > offset + count)
 			i_size = offset + count;
-
+		if (update_isize && i_size > i_size_read(inode))
+			i_size_write(inode, i_size);
 		i_size = xfs_new_eof(ip, i_size);
 		if (i_size) {
 			ip->i_d.di_size = i_size;
fs/xfs/xfs_iomap.h +1 -1
@@ -27,7 +27,7 @@ int xfs_iomap_write_direct(struct xfs_in
 			struct xfs_bmbt_irec *, int);
 int xfs_iomap_write_allocate(struct xfs_inode *, int, xfs_off_t,
 			struct xfs_bmbt_irec *);
-int xfs_iomap_write_unwritten(struct xfs_inode *, xfs_off_t, xfs_off_t);
+int xfs_iomap_write_unwritten(struct xfs_inode *, xfs_off_t, xfs_off_t, bool);
 
 void xfs_bmbt_to_iomap(struct xfs_inode *, struct iomap *,
 		struct xfs_bmbt_irec *);
fs/xfs/xfs_pnfs.c +1 -1
@@ -274,7 +274,7 @@ xfs_fs_commit_blocks(
 					(end - 1) >> PAGE_SHIFT);
 		WARN_ON_ONCE(error);
 
-		error = xfs_iomap_write_unwritten(ip, start, length);
+		error = xfs_iomap_write_unwritten(ip, start, length, false);
 		if (error)
 			goto out_drop_iolock;
 	}
author maintainer
#72 lore raw

PATCH 74/85 xfs: perag initialization should only touch m_ag_max_usable for AG 0

In reply to Greg Kroah-Hartman

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

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

From: Darrick J. Wong <[email protected]>

commit 9789dd9e1d939232e8ff4c50ef8e75aa6781b3fb upstream.

We call __xfs_ag_resv_init to make a per-AG reservation for each AG. This makes the reservation per-AG, not per-filesystem. Therefore, it is incorrect to adjust m_ag_max_usable for each AG. Adjust it only when we're reserving AG 0's blocks so that we only do it once per fs.

---
 fs/xfs/libxfs/xfs_ag_resv.c |   12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)
fs/xfs/libxfs/xfs_ag_resv.c +10 -2
@@ -156,7 +156,8 @@ __xfs_ag_resv_free(
 	trace_xfs_ag_resv_free(pag, type, 0);
 
 	resv = xfs_perag_resv(pag, type);
-	pag->pag_mount->m_ag_max_usable += resv->ar_asked;
+	if (pag->pag_agno == 0)
+		pag->pag_mount->m_ag_max_usable += resv->ar_asked;
 	/*
 	 * AGFL blocks are always considered "free", so whatever
 	 * was reserved at mount time must be given back at umount.
@@ -216,7 +217,14 @@ __xfs_ag_resv_init(
 		return error;
 	}
 
-	mp->m_ag_max_usable -= ask;
+	/*
+	 * Reduce the maximum per-AG allocation length by however much we're
+	 * trying to reserve for an AG.  Since this is a filesystem-wide
+	 * counter, we only make the adjustment for AG 0.  This assumes that
+	 * there aren't any AGs hungrier for per-AG reservation than AG 0.
+	 */
+	if (pag->pag_agno == 0)
+		mp->m_ag_max_usable -= ask;
 
 	resv = xfs_perag_resv(pag, type);
 	resv->ar_asked = ask;
author maintainer
#73 lore raw

PATCH 75/85 xfs: Capture state of the right inode in xfs_iflush_done

In reply to Greg Kroah-Hartman

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

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

From: Carlos Maiolino <[email protected]>

commit 842f6e9f786226c58fcbd5ef80eadca72fdfe652 upstream.

My previous patch: d3a304b6292168b83b45d624784f973fdc1ca674 check for XFS_LI_FAILED flag xfs_iflush done, so the failed item can be properly resubmitted.

In the loop scanning other inodes being completed, it should check the current item for the XFS_LI_FAILED, and not the initial one.

The state of the initial inode is checked after the loop ends

Kudos to Eric for catching this.

---
 fs/xfs/xfs_inode_item.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/xfs/xfs_inode_item.c +1 -1
@@ -745,7 +745,7 @@ xfs_iflush_done(
 		 */
 		iip = INODE_ITEM(blip);
 		if ((iip->ili_logged && blip->li_lsn == iip->ili_flush_lsn) ||
-		    lip->li_flags & XFS_LI_FAILED)
+		    (blip->li_flags & XFS_LI_FAILED))
 			need_ail++;
 
 		blip = next;
author maintainer
#74 lore raw

PATCH 76/85 xfs: always swap the cow forks when swapping extents

In reply to Greg Kroah-Hartman

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

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

From: Darrick J. Wong <[email protected]>

commit 52bfcdd7adbc26639bc7b2356ab9a3f5dad68ad6 upstream.

Since the CoW fork exists as a secondary data structure to the data fork, we must always swap cow forks during swapext. We also need to swap the extent counts and reset the cowblocks tags.

---
 fs/xfs/xfs_bmap_util.c |   24 ++++++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)
fs/xfs/xfs_bmap_util.c +22 -2
@@ -2121,11 +2121,31 @@ xfs_swap_extents(
 		ip->i_d.di_flags2 |= tip->i_d.di_flags2 & XFS_DIFLAG2_REFLINK;
 		tip->i_d.di_flags2 &= ~XFS_DIFLAG2_REFLINK;
 		tip->i_d.di_flags2 |= f & XFS_DIFLAG2_REFLINK;
+	}
+
+	/* Swap the cow forks. */
+	if (xfs_sb_version_hasreflink(&mp->m_sb)) {
+		xfs_extnum_t	extnum;
+
+		ASSERT(ip->i_cformat == XFS_DINODE_FMT_EXTENTS);
+		ASSERT(tip->i_cformat == XFS_DINODE_FMT_EXTENTS);
+
+		extnum = ip->i_cnextents;
+		ip->i_cnextents = tip->i_cnextents;
+		tip->i_cnextents = extnum;
+
 		cowfp = ip->i_cowfp;
 		ip->i_cowfp = tip->i_cowfp;
 		tip->i_cowfp = cowfp;
-		xfs_inode_set_cowblocks_tag(ip);
-		xfs_inode_set_cowblocks_tag(tip);
+
+		if (ip->i_cowfp && ip->i_cnextents)
+			xfs_inode_set_cowblocks_tag(ip);
+		else
+			xfs_inode_clear_cowblocks_tag(ip);
+		if (tip->i_cowfp && tip->i_cnextents)
+			xfs_inode_set_cowblocks_tag(tip);
+		else
+			xfs_inode_clear_cowblocks_tag(tip);
 	}
 
 	xfs_trans_log_inode(tp, ip,  src_log_flags);
author maintainer
#75 lore raw

PATCH 77/85 xfs: handle racy AIO in xfs_reflink_end_cow

In reply to Greg Kroah-Hartman

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

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

From: Christoph Hellwig <[email protected]>

commit e12199f85d0ad1b04ce6c425ad93cd847fe930bb upstream.

If we got two AIO writes into a COW area the second one might not have any COW extents left to convert. Handle that case gracefully instead of triggering an assert or accessing beyond the bounds of the extent list.

---
 fs/xfs/xfs_reflink.c |    9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)
fs/xfs/xfs_reflink.c +8 -1
@@ -735,7 +735,13 @@ xfs_reflink_end_cow(
 	/* If there is a hole at end_fsb - 1 go to the previous extent */
 	if (!xfs_iext_lookup_extent(ip, ifp, end_fsb - 1, &idx, &got) ||
 	    got.br_startoff > end_fsb) {
-		ASSERT(idx > 0);
+		/*
+		 * In case of racing, overlapping AIO writes no COW extents
+		 * might be left by the time I/O completes for the loser of
+		 * the race.  In that case we are done.
+		 */
+		if (idx <= 0)
+			goto out_cancel;
 		xfs_iext_get_extent(ifp, --idx, &got);
 	}
 
@@ -807,6 +813,7 @@ next_extent:
 
 out_defer:
 	xfs_defer_cancel(&dfops);
+out_cancel:
 	xfs_trans_cancel(tp);
 	xfs_iunlock(ip, XFS_ILOCK_EXCL);
 out:
author maintainer
#76 lore raw

PATCH 78/85 xfs: Dont log uninitialised fields in inode structures

In reply to Greg Kroah-Hartman

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

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

From: Dave Chinner <[email protected]>

commit 20413e37d71befd02b5846acdaf5e2564dd1c38e upstream.

Prevent kmemcheck from throwing warnings about reading uninitialised memory when formatting inodes into the incore log buffer. There are several issues here - we don't always log all the fields in the inode log format item, and we never log the inode the di_next_unlinked field.

In the case of the inode log format item, this is exacerbated by the old xfs_inode_log_format structure padding issue. Hence make the padded, 64 bit aligned version of the structure the one we always use for formatting the log and get rid of the 64 bit variant. This means we'll always log the 64-bit version and so recovery only needs to convert from the unpadded 32 bit version from older 32 bit kernels.

---
 fs/xfs/libxfs/xfs_log_format.h |   27 ++++----------
 fs/xfs/xfs_inode_item.c        |   77 +++++++++++++++++++++--------------------
 fs/xfs/xfs_ondisk.h            |    2 -
 3 files changed, 49 insertions(+), 57 deletions(-)
fs/xfs/libxfs/xfs_log_format.h +8 -19
@@ -270,6 +270,7 @@ typedef struct xfs_inode_log_format {
 	uint32_t		ilf_fields;	/* flags for fields logged */
 	uint16_t		ilf_asize;	/* size of attr d/ext/root */
 	uint16_t		ilf_dsize;	/* size of data/ext/root */
+	uint32_t		ilf_pad;	/* pad for 64 bit boundary */
 	uint64_t		ilf_ino;	/* inode number */
 	union {
 		uint32_t	ilfu_rdev;	/* rdev value for dev inode*/
@@ -280,29 +281,17 @@ typedef struct xfs_inode_log_format {
 	int32_t			ilf_boffset;	/* off of inode in buffer */
 } xfs_inode_log_format_t;
 
-typedef struct xfs_inode_log_format_32 {
-	uint16_t		ilf_type;	/* inode log item type */
-	uint16_t		ilf_size;	/* size of this item */
-	uint32_t		ilf_fields;	/* flags for fields logged */
-	uint16_t		ilf_asize;	/* size of attr d/ext/root */
-	uint16_t		ilf_dsize;	/* size of data/ext/root */
-	uint64_t		ilf_ino;	/* inode number */
-	union {
-		uint32_t	ilfu_rdev;	/* rdev value for dev inode*/
-		uuid_t		ilfu_uuid;	/* mount point value */
-	} ilf_u;
-	int64_t			ilf_blkno;	/* blkno of inode buffer */
-	int32_t			ilf_len;	/* len of inode buffer */
-	int32_t			ilf_boffset;	/* off of inode in buffer */
-} __attribute__((packed)) xfs_inode_log_format_32_t;
-
-typedef struct xfs_inode_log_format_64 {
+/*
+ * Old 32 bit systems will log in this format without the 64 bit
+ * alignment padding. Recovery will detect this and convert it to the
+ * correct format.
+ */
+struct xfs_inode_log_format_32 {
 	uint16_t		ilf_type;	/* inode log item type */
 	uint16_t		ilf_size;	/* size of this item */
 	uint32_t		ilf_fields;	/* flags for fields logged */
 	uint16_t		ilf_asize;	/* size of attr d/ext/root */
 	uint16_t		ilf_dsize;	/* size of data/ext/root */
-	uint32_t		ilf_pad;	/* pad for 64 bit boundary */
 	uint64_t		ilf_ino;	/* inode number */
 	union {
 		uint32_t	ilfu_rdev;	/* rdev value for dev inode*/
@@ -311,7 +300,7 @@ typedef struct xfs_inode_log_format_64 {
 	int64_t			ilf_blkno;	/* blkno of inode buffer */
 	int32_t			ilf_len;	/* len of inode buffer */
 	int32_t			ilf_boffset;	/* off of inode in buffer */
-} xfs_inode_log_format_64_t;
+} __attribute__((packed));
 
 
 /*
fs/xfs/xfs_inode_item.c +40 -37

111 lines not on this page · raw message

fs/xfs/xfs_ondisk.h +1 -1
@@ -134,7 +134,7 @@ xfs_check_ondisk_structs(void)
 	XFS_CHECK_STRUCT_SIZE(struct xfs_icreate_log,		28);
 	XFS_CHECK_STRUCT_SIZE(struct xfs_ictimestamp,		8);
 	XFS_CHECK_STRUCT_SIZE(struct xfs_inode_log_format_32,	52);
-	XFS_CHECK_STRUCT_SIZE(struct xfs_inode_log_format_64,	56);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_inode_log_format,	56);
 	XFS_CHECK_STRUCT_SIZE(struct xfs_qoff_logformat,	20);
 	XFS_CHECK_STRUCT_SIZE(struct xfs_trans_header,		16);
 }
author maintainer
#77 lore raw

PATCH 79/85 xfs: move more RT specific code under CONFIG_XFS_RT

In reply to Greg Kroah-Hartman

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

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

From: Dave Chinner <[email protected]>

commit bb9c2e5433250f5b477035dc478314f8e6dd5e36 upstream.

Various utility functions and interfaces that iterate internal devices try to reference the realtime device even when RT support is not compiled into the kernel.

Make sure this code is excluded from the CONFIG_XFS_RT=n build, and where appropriate stub functions to return fatal errors if they ever get called when RT support is not present.

---
 fs/xfs/xfs_bmap_util.c |    2 ++
 fs/xfs/xfs_bmap_util.h |   13 +++++++++++++
 fs/xfs/xfs_fsmap.c     |   12 ++++++++++++
 3 files changed, 27 insertions(+)
fs/xfs/xfs_bmap_util.c +2 -0
@@ -84,6 +84,7 @@ xfs_zero_extent(
 		GFP_NOFS, 0);
 }
 
+#ifdef CONFIG_XFS_RT
 int
 xfs_bmap_rtalloc(
 	struct xfs_bmalloca	*ap)	/* bmap alloc argument struct */
@@ -190,6 +191,7 @@ xfs_bmap_rtalloc(
 	}
 	return 0;
 }
+#endif /* CONFIG_XFS_RT */
 
 /*
  * Check if the endoff is outside the last extent. If so the caller will grow
fs/xfs/xfs_bmap_util.h +13 -0
@@ -28,7 +28,20 @@ struct xfs_mount;
 struct xfs_trans;
 struct xfs_bmalloca;
 
+#ifdef CONFIG_XFS_RT
 int	xfs_bmap_rtalloc(struct xfs_bmalloca *ap);
+#else /* !CONFIG_XFS_RT */
+/*
+ * Attempts to allocate RT extents when RT is disable indicates corruption and
+ * should trigger a shutdown.
+ */
+static inline int
+xfs_bmap_rtalloc(struct xfs_bmalloca *ap)
+{
+	return -EFSCORRUPTED;
+}
+#endif /* CONFIG_XFS_RT */
+
 int	xfs_bmap_eof(struct xfs_inode *ip, xfs_fileoff_t endoff,
 		     int whichfork, int *eof);
 int	xfs_bmap_punch_delalloc_range(struct xfs_inode *ip,
fs/xfs/xfs_fsmap.c +12 -0
@@ -521,6 +521,7 @@ __xfs_getfsmap_rtdev(
 	return query_fn(tp, info);
 }
 
+#ifdef CONFIG_XFS_RT
 /* Actually query the realtime bitmap. */
 STATIC int
 xfs_getfsmap_rtdev_rtbitmap_query(
@@ -561,6 +562,7 @@ xfs_getfsmap_rtdev_rtbitmap(
 	return __xfs_getfsmap_rtdev(tp, keys, xfs_getfsmap_rtdev_rtbitmap_query,
 			info);
 }
+#endif /* CONFIG_XFS_RT */
 
 /* Execute a getfsmap query against the regular data device. */
 STATIC int
@@ -795,7 +797,15 @@ xfs_getfsmap_check_keys(
 	return false;
 }
 
+/*
+ * There are only two devices if we didn't configure RT devices at build time.
+ */
+#ifdef CONFIG_XFS_RT
 #define XFS_GETFSMAP_DEVS	3
+#else
+#define XFS_GETFSMAP_DEVS	2
+#endif /* CONFIG_XFS_RT */
+
 /*
  * Get filesystem's extents as described in head, and format for
  * output.  Calls formatter to fill the user's buffer until all
@@ -853,10 +863,12 @@ xfs_getfsmap(
 		handlers[1].dev = new_encode_dev(mp->m_logdev_targp->bt_dev);
 		handlers[1].fn = xfs_getfsmap_logdev;
 	}
+#ifdef CONFIG_XFS_RT
 	if (mp->m_rtdev_targp) {
 		handlers[2].dev = new_encode_dev(mp->m_rtdev_targp->bt_dev);
 		handlers[2].fn = xfs_getfsmap_rtdev_rtbitmap;
 	}
+#endif /* CONFIG_XFS_RT */
 
 	xfs_sort(handlers, XFS_GETFSMAP_DEVS, sizeof(struct xfs_getfsmap_dev),
 			xfs_getfsmap_dev_compare);
author maintainer
#78 lore raw

PATCH 80/85 xfs: dont change inode mode if ACL update fails

In reply to Greg Kroah-Hartman

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

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

From: Dave Chinner <[email protected]>

commit 67f2ffe31d1a683170c2ba0ecc643e42a5fdd397 upstream.

If we get ENOSPC half way through setting the ACL, the inode mode can still be changed even though the ACL does not exist. Reorder the operation to only change the mode of the inode if the ACL is set correctly.

Whilst this does not fix the problem with crash consistency (that requires attribute addition to be a deferred op) it does prevent ENOSPC and other non-fatal errors setting an xattr to be handled sanely.

This fixes xfstests generic/449.

---
 fs/xfs/xfs_acl.c |   22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)
fs/xfs/xfs_acl.c +16 -6
@@ -247,6 +247,8 @@ xfs_set_mode(struct inode *inode, umode_
 int
 xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
 {
+	umode_t mode;
+	bool set_mode = false;
 	int error = 0;
 
 	if (!acl)
@@ -257,16 +259,24 @@ xfs_set_acl(struct inode *inode, struct
 		return error;
 
 	if (type == ACL_TYPE_ACCESS) {
-		umode_t mode;
-
 		error = posix_acl_update_mode(inode, &mode, &acl);
 		if (error)
 			return error;
-		error = xfs_set_mode(inode, mode);
-		if (error)
-			return error;
+		set_mode = true;
 	}
 
  set_acl:
-	return __xfs_set_acl(inode, acl, type);
+	error =  __xfs_set_acl(inode, acl, type);
+	if (error)
+		return error;
+
+	/*
+	 * We set the mode after successfully updating the ACL xattr because the
+	 * xattr update can fail at ENOSPC and we don't want to change the mode
+	 * if the ACL update hasn't been applied.
+	 */
+	if (set_mode)
+		error = xfs_set_mode(inode, mode);
+
+	return error;
 }
author maintainer
#79 lore raw

PATCH 81/85 xfs: reinit btree pointer on attr tree inactivation walk

In reply to Greg Kroah-Hartman

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

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

From: Brian Foster <[email protected]>

commit f35c5e10c6ed6ba52a8dd8573924a80b6a02f03f upstream.

xfs_attr3_root_inactive() walks the attr fork tree to invalidate the associated blocks. xfs_attr3_node_inactive() recursively descends from internal blocks to leaf blocks, caching block address values along the way to revisit parent blocks, locate the next entry and descend down that branch of the tree.

The code that attempts to reread the parent block is unsafe because it assumes that the local xfs_da_node_entry pointer remains valid after an xfs_trans_brelse() and re-read of the parent buffer. Under heavy memory pressure, it is possible that the buffer has been reclaimed and reallocated by the time the parent block is reread. This means that 'btree' can point to an invalid memory address, lead to a random/garbage value for child_fsb and cause the subsequent read of the attr fork to go off the rails and return a NULL buffer for an attr fork offset that is most likely not allocated.

Note that this problem can be manufactured by setting XFS_ATTR_BTREE_REF to 0 to prevent LRU caching of attr buffers, creating a file with a multi-level attr fork and removing it to trigger inactivation.

To address this problem, reinit the node/btree pointers to the parent buffer after it has been re-read. This ensures btree points to a valid record and allows the walk to proceed.

---
 fs/xfs/xfs_attr_inactive.c |    2 ++
 1 file changed, 2 insertions(+)
fs/xfs/xfs_attr_inactive.c +2 -0
@@ -302,6 +302,8 @@ xfs_attr3_node_inactive(
 						 &bp, XFS_ATTR_FORK);
 			if (error)
 				return error;
+			node = bp->b_addr;
+			btree = dp->d_ops->node_tree_p(node);
 			child_fsb = be32_to_cpu(btree[i + 1].before);
 			xfs_trans_brelse(*trans, bp);
 		}
author maintainer
#80 lore raw

PATCH 82/85 xfs: handle error if xfs_btree_get_bufs fails

In reply to Greg Kroah-Hartman

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

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

From: Eric Sandeen <[email protected]>

commit 93e8befc17f6d6ea92b0aee3741ceac8bca4590f upstream.

Jason reported that a corrupted filesystem failed to replay the log with a metadata block out of bounds warning:

XFS (dm-2): _xfs_buf_find: Block out of range: block 0x80270fff8, EOFS 0x9c40000

_xfs_buf_find() and xfs_btree_get_bufs() return NULL if that happens, and then when xfs_alloc_fix_freelist() calls xfs_trans_binval() on that NULL bp, we oops with:

BUG: unable to handle kernel NULL pointer dereference at 00000000000000f8

We don't handle _xfs_buf_find errors very well, every caller higher up the stack gets to guess at why it failed. But we should at least handle it somehow, so return EFSCORRUPTED here.

---
 fs/xfs/libxfs/xfs_alloc.c |    8 ++++++++
 1 file changed, 8 insertions(+)
fs/xfs/libxfs/xfs_alloc.c +8 -0
@@ -1584,6 +1584,10 @@ xfs_alloc_ag_vextent_small(
 
 				bp = xfs_btree_get_bufs(args->mp, args->tp,
 					args->agno, fbno, 0);
+				if (!bp) {
+					error = -EFSCORRUPTED;
+					goto error0;
+				}
 				xfs_trans_binval(args->tp, bp);
 			}
 			args->len = 1;
@@ -2141,6 +2145,10 @@ xfs_alloc_fix_freelist(
 		if (error)
 			goto out_agbp_relse;
 		bp = xfs_btree_get_bufs(mp, tp, args->agno, bno, 0);
+		if (!bp) {
+			error = -EFSCORRUPTED;
+			goto out_agbp_relse;
+		}
 		xfs_trans_binval(tp, bp);
 	}
 
author maintainer
#81 lore raw

PATCH 83/85 xfs: cancel dirty pages on invalidation

In reply to Greg Kroah-Hartman

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

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

From: Dave Chinner <[email protected]>

commit 793d7dbe6d82a50b9d14bf992b9eaacb70a11ce6 upstream.

Recently we've had warnings arise from the vm handing us pages without bufferheads attached to them. This should not ever occur in XFS, but we don't defend against it properly if it does. The only place where we remove bufferheads from a page is in xfs_vm_releasepage(), but we can't tell the difference here between "page is dirty so don't release" and "page is dirty but is being invalidated so release it".

In some places that are invalidating pages ask for pages to be released and follow up afterward calling ->releasepage by checking whether the page was dirty and then aborting the invalidation. This is a possible vector for releasing buffers from a page but then leaving it in the mapping, so we really do need to avoid dirty pages in xfs_vm_releasepage().

To differentiate between invalidated pages and normal pages, we need to clear the page dirty flag when invalidating the pages. This can be done through xfs_vm_invalidatepage(), and will result xfs_vm_releasepage() seeing the page as clean which matches the bufferhead state on the page after calling block_invalidatepage().

Hence we can re-add the page dirty check in xfs_vm_releasepage to catch the case where we might be releasing a page that is actually dirty and so should not have the bufferheads on it removed. This will remove one possible vector of "dirty page with no bufferheads" and so help narrow down the search for the root cause of that problem.

---
 fs/xfs/xfs_aops.c |   34 ++++++++++++++++++++++------------
 1 file changed, 22 insertions(+), 12 deletions(-)
fs/xfs/xfs_aops.c +22 -12
@@ -722,6 +722,14 @@ xfs_vm_invalidatepage(
 {
 	trace_xfs_invalidatepage(page->mapping->host, page, offset,
 				 length);
+
+	/*
+	 * If we are invalidating the entire page, clear the dirty state from it
+	 * so that we can check for attempts to release dirty cached pages in
+	 * xfs_vm_releasepage().
+	 */
+	if (offset == 0 && length >= PAGE_SIZE)
+		cancel_dirty_page(page);
 	block_invalidatepage(page, offset, length);
 }
 
@@ -1177,25 +1185,27 @@ xfs_vm_releasepage(
 	 * mm accommodates an old ext3 case where clean pages might not have had
 	 * the dirty bit cleared. Thus, it can send actual dirty pages to
 	 * ->releasepage() via shrink_active_list(). Conversely,
-	 * block_invalidatepage() can send pages that are still marked dirty
-	 * but otherwise have invalidated buffers.
+	 * block_invalidatepage() can send pages that are still marked dirty but
+	 * otherwise have invalidated buffers.
 	 *
 	 * We want to release the latter to avoid unnecessary buildup of the
-	 * LRU, skip the former and warn if we've left any lingering
-	 * delalloc/unwritten buffers on clean pages. Skip pages with delalloc
-	 * or unwritten buffers and warn if the page is not dirty. Otherwise
-	 * try to release the buffers.
+	 * LRU, so xfs_vm_invalidatepage() clears the page dirty flag on pages
+	 * that are entirely invalidated and need to be released.  Hence the
+	 * only time we should get dirty pages here is through
+	 * shrink_active_list() and so we can simply skip those now.
+	 *
+	 * warn if we've left any lingering delalloc/unwritten buffers on clean
+	 * or invalidated pages we are about to release.
 	 */
+	if (PageDirty(page))
+		return 0;
+
 	xfs_count_page_state(page, &delalloc, &unwritten);
 
-	if (delalloc) {
-		WARN_ON_ONCE(!PageDirty(page));
+	if (WARN_ON_ONCE(delalloc))
 		return 0;
-	}
-	if (unwritten) {
-		WARN_ON_ONCE(!PageDirty(page));
+	if (WARN_ON_ONCE(unwritten))
 		return 0;
-	}
 
 	return try_to_free_buffers(page);
 }
author maintainer
#82 lore raw

PATCH 84/85 xfs: trim writepage mapping to within eof

In reply to Greg Kroah-Hartman

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

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

From: Brian Foster <[email protected]>

commit 40214d128e07dd21bb07a8ed6a7fe2f911281ab2 upstream.

The writeback rework in commit fbcc02561359 ("xfs: Introduce writeback context for writepages") introduced a subtle change in behavior with regard to the block mapping used across the ->writepages() sequence. The previous xfs_cluster_write() code would only flush pages up to EOF at the time of the writepage, thus ensuring that any pages due to file-extending writes would be handled on a separate cycle and with a new, updated block mapping.

The updated code establishes a block mapping in xfs_writepage_map() that could extend beyond EOF if the file has post-eof preallocation. Because we now use the generic writeback infrastructure and pass the cached mapping to each writepage call, there is no implicit EOF limit in place. If eofblocks trimming occurs during ->writepages(), any post-eof portion of the cached mapping becomes invalid. The eofblocks code has no means to serialize against writeback because there are no pages associated with post-eof blocks. Therefore if an eofblocks trim occurs and is followed by a file-extending buffered write, not only has the mapping become invalid, but we could end up writing a page to disk based on the invalid mapping.

Consider the following sequence of events:

- A buffered write creates a delalloc extent and post-eof speculative preallocation.
- Writeback starts and on the first writepage cycle, the delalloc extent is converted to real blocks (including the post-eof blocks) and the mapping is cached.
- The file is closed and xfs_release() trims post-eof blocks. The cached writeback mapping is now invalid.
- Another buffered write appends the file with a delalloc extent.
- The concurrent writeback cycle picks up the just written page because the writeback range end is LLONG_MAX. xfs_writepage_map() attributes it to the (now invalid) cached mapping and writes the data to an incorrect location on disk (and where the file offset is still backed by a delalloc extent).

This problem is reproduced by xfstests test generic/464, which triggers racing writes, appends, open/closes and writeback requests.

To address this problem, trim the mapping used during writeback to within EOF when the mapping is validated. This ensures the mapping is revalidated for any pages encountered beyond EOF as of the time the current mapping was cached or last validated.

---
 fs/xfs/libxfs/xfs_bmap.c |   11 +++++++++++
 fs/xfs/libxfs/xfs_bmap.h |    1 +
 fs/xfs/xfs_aops.c        |   13 +++++++++++++
 3 files changed, 25 insertions(+)
fs/xfs/libxfs/xfs_bmap.c +11 -0
@@ -3860,6 +3860,17 @@ xfs_trim_extent(
 	}
 }
 
+/* trim extent to within eof */
+void
+xfs_trim_extent_eof(
+	struct xfs_bmbt_irec	*irec,
+	struct xfs_inode	*ip)
+
+{
+	xfs_trim_extent(irec, 0, XFS_B_TO_FSB(ip->i_mount,
+					      i_size_read(VFS_I(ip))));
+}
+
 /*
  * Trim the returned map to the required bounds
  */
fs/xfs/libxfs/xfs_bmap.h +1 -0
@@ -208,6 +208,7 @@ void	xfs_bmap_trace_exlist(struct xfs_in
 
 void	xfs_trim_extent(struct xfs_bmbt_irec *irec, xfs_fileoff_t bno,
 		xfs_filblks_t len);
+void	xfs_trim_extent_eof(struct xfs_bmbt_irec *, struct xfs_inode *);
 int	xfs_bmap_add_attrfork(struct xfs_inode *ip, int size, int rsvd);
 void	xfs_bmap_local_to_extents_empty(struct xfs_inode *ip, int whichfork);
 void	xfs_bmap_add_free(struct xfs_mount *mp, struct xfs_defer_ops *dfops,
fs/xfs/xfs_aops.c +13 -0
@@ -433,6 +433,19 @@ xfs_imap_valid(
 {
 	offset >>= inode->i_blkbits;
 
+	/*
+	 * We have to make sure the cached mapping is within EOF to protect
+	 * against eofblocks trimming on file release leaving us with a stale
+	 * mapping. Otherwise, a page for a subsequent file extending buffered
+	 * write could get picked up by this writeback cycle and written to the
+	 * wrong blocks.
+	 *
+	 * Note that what we really want here is a generic mapping invalidation
+	 * mechanism to protect us from arbitrary extent modifying contexts, not
+	 * just eofblocks.
+	 */
+	xfs_trim_extent_eof(imap, XFS_I(inode));
+
 	return offset >= imap->br_startoff &&
 		offset < imap->br_startoff + imap->br_blockcount;
 }
author maintainer
#83 lore raw

PATCH 85/85 xfs: move two more RT specific functions into CONFIG_XFS_RT

In reply to Greg Kroah-Hartman

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

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

From: Arnd Bergmann <[email protected]>

commit 785545c8982604fe3ba79d16409e83993be77d5e upstream.

The last cleanup introduced two harmless warnings:

fs/xfs/xfs_fsmap.c:480:1: warning: '__xfs_getfsmap_rtdev' defined but not used fs/xfs/xfs_fsmap.c:372:1: warning: 'xfs_getfsmap_rtdev_rtbitmap_helper' defined but not used

This moves those two functions as well.

Fixes bb9c2e543325 ("xfs: move more RT specific code under CONFIG_XFS_RT")
---
 fs/xfs/xfs_fsmap.c |   48 ++++++++++++++++++++++++------------------------
 1 file changed, 24 insertions(+), 24 deletions(-)
fs/xfs/xfs_fsmap.c +24 -24
@@ -367,29 +367,6 @@ xfs_getfsmap_datadev_helper(
 	return xfs_getfsmap_helper(cur->bc_tp, info, rec, rec_daddr);
 }
 
-/* Transform a rtbitmap "record" into a fsmap */
-STATIC int
-xfs_getfsmap_rtdev_rtbitmap_helper(
-	struct xfs_trans		*tp,
-	struct xfs_rtalloc_rec		*rec,
-	void				*priv)
-{
-	struct xfs_mount		*mp = tp->t_mountp;
-	struct xfs_getfsmap_info	*info = priv;
-	struct xfs_rmap_irec		irec;
-	xfs_daddr_t			rec_daddr;
-
-	rec_daddr = XFS_FSB_TO_BB(mp, rec->ar_startblock);
-
-	irec.rm_startblock = rec->ar_startblock;
-	irec.rm_blockcount = rec->ar_blockcount;
-	irec.rm_owner = XFS_RMAP_OWN_NULL;	/* "free" */
-	irec.rm_offset = 0;
-	irec.rm_flags = 0;
-
-	return xfs_getfsmap_helper(tp, info, &irec, rec_daddr);
-}
-
 /* Transform a bnobt irec into a fsmap */
 STATIC int
 xfs_getfsmap_datadev_bnobt_helper(
@@ -475,6 +452,30 @@ xfs_getfsmap_logdev(
 	return xfs_getfsmap_helper(tp, info, &rmap, 0);
 }
 
+#ifdef CONFIG_XFS_RT
+/* Transform a rtbitmap "record" into a fsmap */
+STATIC int
+xfs_getfsmap_rtdev_rtbitmap_helper(
+	struct xfs_trans		*tp,
+	struct xfs_rtalloc_rec		*rec,
+	void				*priv)
+{
+	struct xfs_mount		*mp = tp->t_mountp;
+	struct xfs_getfsmap_info	*info = priv;
+	struct xfs_rmap_irec		irec;
+	xfs_daddr_t			rec_daddr;
+
+	rec_daddr = XFS_FSB_TO_BB(mp, rec->ar_startblock);
+
+	irec.rm_startblock = rec->ar_startblock;
+	irec.rm_blockcount = rec->ar_blockcount;
+	irec.rm_owner = XFS_RMAP_OWN_NULL;	/* "free" */
+	irec.rm_offset = 0;
+	irec.rm_flags = 0;
+
+	return xfs_getfsmap_helper(tp, info, &irec, rec_daddr);
+}
+
 /* Execute a getfsmap query against the realtime device. */
 STATIC int
 __xfs_getfsmap_rtdev(
@@ -521,7 +522,6 @@ __xfs_getfsmap_rtdev(
 	return query_fn(tp, info);
 }
 
-#ifdef CONFIG_XFS_RT
 /* Actually query the realtime bitmap. */
 STATIC int
 xfs_getfsmap_rtdev_rtbitmap_query(
#84 lore raw

Re: [PATCH 4.13 85/85] xfs: move two more RT specific functions into CONFIG_XFS_RT

Quoted 8 lines · Greg Kroah-Hartman

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

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

From: Arnd Bergmann <[email protected]>

commit 785545c8982604fe3ba79d16409e83993be77d5e upstream.

Quoted 8 lines

The last cleanup introduced two harmless warnings:

fs/xfs/xfs_fsmap.c:480:1: warning: '__xfs_getfsmap_rtdev' defined but not used fs/xfs/xfs_fsmap.c:372:1: warning: 'xfs_getfsmap_rtdev_rtbitmap_helper' defined but not used

This moves those two functions as well.

Fixes bb9c2e543325 ("xfs: move more RT specific code under CONFIG_XFS_RT")

I haven't checked what kernel contains bb9c2e543325, but if I remember correctly the warning only showed up during the 4.14-rc cycle, so unless you backported bb9c2e543325 or I misremembered it, backporting my fix would be wrong.

I lost remote access to my build box, so I can't verify at the moment. Can you double-check that we want this backport?

Arnd

author maintainer
#85 lore raw

Re: [PATCH 4.13 85/85] xfs: move two more RT specific functions into CONFIG_XFS_RT

Quoted 17 lines · Arnd Bergmann
Quoted 15 lines · Greg Kroah-Hartman

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

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

From: Arnd Bergmann <[email protected]>

commit 785545c8982604fe3ba79d16409e83993be77d5e upstream.

The last cleanup introduced two harmless warnings:

fs/xfs/xfs_fsmap.c:480:1: warning: '__xfs_getfsmap_rtdev' defined but not used fs/xfs/xfs_fsmap.c:372:1: warning: 'xfs_getfsmap_rtdev_rtbitmap_helper' defined but not used

This moves those two functions as well.

Quoted 8 lines
Quoted 1 line
Fixes bb9c2e543325 ("xfs: move more RT specific code under CONFIG_XFS_RT")

I haven't checked what kernel contains bb9c2e543325, but if I remember correctly the warning only showed up during the 4.14-rc cycle, so unless you backported bb9c2e543325 or I misremembered it, backporting my fix would be wrong.

I lost remote access to my build box, so I can't verify at the moment. Can you double-check that we want this backport?

Yes, that patch is part of the xfs patch series that is in this -rc release before your fixup patch here. So all should be good, thanks for checking.

greg k-h

#86 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.13.10 release. There are 85 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.

Responses should be made by Thu Oct 26 12:56:27 UTC 2017. Anything received after that time might be too late.

Build results:

	total: 145 pass: 145 fail: 0
Qemu test results:
	total: 123 pass: 123 fail: 0

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

Guenter

author maintainer
#87 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.13.10 release. There are 85 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.

Responses should be made by Thu Oct 26 12:56:27 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: 123 pass: 123 fail: 0

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

THanks for the testing and letting me know.

greg k-h