Skip to contentSkip to conversation

4.9.59-stable review

PATCH In review Greg Kroah-Hartman 3 participants 49 messages Oct 24, 2017 – Oct 25, 2017 Stable branch

lore
Share & tools
lore

Greg Kroah-Hartman

author maintainer
#0 lore raw

cover 4.9.59-stable review

This is the start of the stable review cycle for the 4.9.59 release. There are 48 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:57:14 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.9.59-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.9.y
and the diffstat can be found below.

thanks,

greg k-h

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

Greg Kroah-Hartman <[email protected]>

    Linux 4.9.59-rc1

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

Dexuan Cui <[email protected]>
vmbus: fix missing signaling in hv_signal_on_read()

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]>
lib/digsig: fix dereference of NULL user_key_payload

Eric Biggers <[email protected]>
KEYS: encrypted: 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

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

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

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

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

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

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

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

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

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

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"

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

Diffstat:

 Makefile                                           |   4 +-
 arch/parisc/kernel/syscall.S                       |   6 +-
 arch/x86/kernel/cpu/microcode/intel.c              |  19 ++
 crypto/asymmetric_keys/pkcs7_parser.c              |   3 +
 drivers/bus/mvebu-mbus.c                           |   2 +-
 drivers/clocksource/cs5535-clockevt.c              |   3 +-
 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/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/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.c                            |   3 +-
 drivers/usb/musb/musb_core.c                       |   6 +-
 drivers/usb/musb/sunxi.c                           |   2 +
 drivers/usb/serial/metro-usb.c                     |   1 +
 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                                  |  72 +++++---
 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                                  |   2 +-
 fs/xfs/xfs_inode.c                                 |   8 +-
 fs/xfs/xfs_inode_item.c                            |  86 ++++-----
 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/hyperv.h                             |   4 +-
 include/linux/mbus.h                               |   4 +-
 lib/digsig.c                                       |   6 +
 security/keys/encrypted-keys/encrypted.c           |   7 +
 security/keys/key.c                                |  10 ++
 sound/core/seq/seq_lock.c                          |   4 -
 sound/core/seq/seq_lock.h                          |  12 --
 sound/hda/hdac_controller.c                        |   5 +
 sound/pci/hda/hda_codec.c                          |   2 +-
 sound/usb/quirks.c                                 |   1 +
 54 files changed, 451 insertions(+), 265 deletions(-)
author maintainer
#1 lore raw

PATCH 1/48 USB: devio: Revert "USB: devio: Dont corrupt user memory"

4.9-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
@@ -1577,11 +1577,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
#2 lore raw

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

In reply to Greg Kroah-Hartman

4.9-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
@@ -955,10 +955,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
#3 lore raw

PATCH 3/48 USB: serial: metro-usb: add MS7820 device id

In reply to Greg Kroah-Hartman

4.9-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
#4 lore raw

PATCH 4/48 usb: cdc_acm: Add quirk for Elatec TWN3

In reply to Greg Kroah-Hartman

4.9-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
@@ -1773,6 +1773,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
#5 lore raw

PATCH 6/48 usb: hub: Allow reset retry for USB2 devices on connect bounce

In reply to Greg Kroah-Hartman

4.9-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
@@ -2704,13 +2704,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
#6 lore raw

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

In reply to Greg Kroah-Hartman

4.9-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
#7 lore raw

PATCH 8/48 can: gs_usb: fix busy loop if no more TX context is available

In reply to Greg Kroah-Hartman

4.9-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
#8 lore raw

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

In reply to Greg Kroah-Hartman

4.9-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
#9 lore raw

PATCH 10/48 iio: dummy: events: Add missing break

In reply to Greg Kroah-Hartman

4.9-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
#10 lore raw

PATCH 11/48 usb: musb: sunxi: Explicitly release USB PHY on exit

In reply to Greg Kroah-Hartman

4.9-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
@@ -313,6 +313,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
#11 lore raw

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

In reply to Greg Kroah-Hartman

4.9-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
@@ -890,7 +890,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
@@ -900,9 +900,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
#12 lore raw

PATCH 13/48 xhci: Identify USB 3.1 capable hosts by their port protocol capability

In reply to Greg Kroah-Hartman

4.9-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
@@ -4855,7 +4855,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
#13 lore raw

PATCH 15/48 drm/nouveau/bsp/g92: disable by default

In reply to Greg Kroah-Hartman

4.9-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
#14 lore raw

PATCH 16/48 drm/nouveau/mmu: flush tlbs before deleting page tables

In reply to Greg Kroah-Hartman

4.9-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
@@ -240,6 +240,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
#15 lore raw

PATCH 17/48 ALSA: seq: Enable use locking in all configurations

In reply to Greg Kroah-Hartman

4.9-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)
 {
@@ -42,5 +40,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
#16 lore raw

PATCH 18/48 ALSA: hda: Remove superfluous - added by printk conversion

In reply to Greg Kroah-Hartman

4.9-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
@@ -1755,7 +1755,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
#17 lore raw

PATCH 19/48 ALSA: hda: Abort capability probe at invalid register read

In reply to Greg Kroah-Hartman

4.9-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
#18 lore raw

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

In reply to Greg Kroah-Hartman

4.9-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
#19 lore raw

PATCH 22/48 brcmfmac: Add check for short event packets

In reply to Greg Kroah-Hartman

4.9-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
#20 lore raw

PATCH 23/48 brcmsmac: make some local variables static const to reduce stack size

In reply to Greg Kroah-Hartman

4.9-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
#21 lore raw

PATCH 24/48 bus: mbus: fix window size calculation for 4GB windows

In reply to Greg Kroah-Hartman

4.9-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
#22 lore raw

PATCH 25/48 clockevents/drivers/cs5535: Improve resilience to spurious interrupts

In reply to Greg Kroah-Hartman

4.9-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
#23 lore raw

PATCH 26/48 rtlwifi: rtl8821ae: Fix connection lost problem

In reply to Greg Kroah-Hartman

4.9-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
@@ -1128,7 +1128,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
#24 lore raw

PATCH 27/48 x86/microcode/intel: Disable late loading on model 79

In reply to Greg Kroah-Hartman

4.9-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>
@@ -1046,6 +1047,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)
 {
@@ -1054,6 +1067,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);
 
@@ -1078,6 +1094,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
#25 lore raw

PATCH 28/48 KEYS: encrypted: fix dereference of NULL user_key_payload

In reply to Greg Kroah-Hartman

4.9-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
@@ -315,6 +315,13 @@ static struct key *request_user_key(cons
 
 	down_read(&ukey->sem);
 	upayload = user_key_payload(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
#26 lore raw

PATCH 29/48 lib/digsig: fix dereference of NULL user_key_payload

In reply to Greg Kroah-Hartman

4.9-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(key);
 
+	if (!ukp) {
+		/* key was revoked before we acquired its semaphore */
+		err = -EKEYREVOKED;
+		goto err1;
+	}
+
 	if (ukp->datalen < sizeof(*pkh))
 		goto err1;
 
author maintainer
#27 lore raw

PATCH 30/48 KEYS: dont let add_key() update an uninstantiated key

In reply to Greg Kroah-Hartman

4.9-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
@@ -935,6 +935,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
#28 lore raw

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

In reply to Greg Kroah-Hartman

4.9-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
#29 lore raw

PATCH 32/48 vmbus: fix missing signaling in hv_signal_on_read()

In reply to Greg Kroah-Hartman

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

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

From: Dexuan Cui <[email protected]>

[Fixes upstream in a much larger set of patches that are not worth backporting to 4.9 - gregkh]

When the space available before start of reading (cached_write_sz) is the same as the host required space (pending_sz), we need to still signal host.

Fixes 433e19cf33d3 ("Drivers: hv: vmbus: finally fix hv_need_to_signal_on_read()")

---

Hi Greg, as we discussed, I'm resending this patch, and please only apply it to linux-4.9.y (i.e. v4.9.57 as of today).

 include/linux/hyperv.h |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
include/linux/hyperv.h +2 -2
@@ -1521,11 +1521,11 @@ static inline  void hv_signal_on_read(st
 
 	cur_write_sz = hv_get_bytes_to_write(rbi);
 
-	if (cur_write_sz < pending_sz)
+	if (cur_write_sz <= pending_sz)
 		return;
 
 	cached_write_sz = hv_get_cached_bytes_to_write(rbi);
-	if (cached_write_sz < pending_sz)
+	if (cached_write_sz <= pending_sz)
 		vmbus_setevent(channel);
 
 	return;
author maintainer
#30 lore raw

PATCH 33/48 xfs: dont unconditionally clear the reflink flag on zero-block files

In reply to Greg Kroah-Hartman

4.9-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
@@ -1632,10 +1632,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
#31 lore raw

PATCH 34/48 xfs: evict CoW fork extents when performing finsert/fcollapse

In reply to Greg Kroah-Hartman

4.9-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
@@ -1445,7 +1445,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
#32 lore raw

PATCH 35/48 fs/xfs: Use %pS printk format for direct addresses

In reply to Greg Kroah-Hartman

4.9-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
@@ -167,7 +167,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
#33 lore raw

PATCH 36/48 xfs: report zeroed or not correctly in xfs_zero_range()

In reply to Greg Kroah-Hartman

4.9-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
@@ -92,7 +92,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
#34 lore raw

PATCH 37/48 xfs: update i_size after unwritten conversion in dio completion

In reply to Greg Kroah-Hartman

4.9-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  |   25 +++++++++++++++++--------
 fs/xfs/xfs_iomap.c |    7 +++++--
 fs/xfs/xfs_iomap.h |    2 +-
 fs/xfs/xfs_pnfs.c  |    2 +-
 4 files changed, 24 insertions(+), 12 deletions(-)
fs/xfs/xfs_aops.c +17 -8
@@ -335,7 +335,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);
@@ -1532,6 +1533,21 @@ xfs_end_io_direct_write(
 		return 0;
 	}
 
+	if (flags & XFS_DIO_FLAG_COW)
+		error = xfs_reflink_end_cow(ip, offset, size);
+
+	/*
+	 * 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 & XFS_DIO_FLAG_UNWRITTEN) {
+		trace_xfs_end_io_direct_write_unwritten(ip, offset, size);
+
+		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
@@ -1548,13 +1564,6 @@ xfs_end_io_direct_write(
 		i_size_write(inode, offset + size);
 	spin_unlock(&ip->i_flags_lock);
 
-	if (flags & XFS_DIO_FLAG_COW)
-		error = xfs_reflink_end_cow(ip, offset, size);
-	if (flags & XFS_DIO_FLAG_UNWRITTEN) {
-		trace_xfs_end_io_direct_write_unwritten(ip, offset, size);
-
-		error = xfs_iomap_write_unwritten(ip, offset, size);
-	}
 	if (flags & XFS_DIO_FLAG_APPEND) {
 		trace_xfs_end_io_direct_write_append(ip, offset, size);
 
fs/xfs/xfs_iomap.c +5 -2
@@ -836,7 +836,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;
@@ -847,6 +848,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;
@@ -906,7 +908,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
@@ -279,7 +279,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
#35 lore raw

PATCH 38/48 xfs: perag initialization should only touch m_ag_max_usable for AG 0

In reply to Greg Kroah-Hartman

4.9-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
@@ -157,7 +157,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.
@@ -217,7 +218,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
#36 lore raw

PATCH 39/48 xfs: Capture state of the right inode in xfs_iflush_done

In reply to Greg Kroah-Hartman

4.9-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
#37 lore raw

PATCH 40/48 xfs: always swap the cow forks when swapping extents

In reply to Greg Kroah-Hartman

4.9-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
@@ -2106,11 +2106,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
#38 lore raw

PATCH 41/48 xfs: handle racy AIO in xfs_reflink_end_cow

In reply to Greg Kroah-Hartman

4.9-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
@@ -767,7 +767,13 @@ xfs_reflink_end_cow(
 
 	/* If there is a hole at end_fsb - 1 go to the previous extent */
 	if (eof || 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_bmbt_get_all(xfs_iext_get_ext(ifp, --idx), &got);
 	}
 
@@ -841,6 +847,7 @@ next_extent:
 
 out_defer:
 	xfs_defer_cancel(&dfops);
+out_cancel:
 	xfs_trans_cancel(tp);
 	xfs_iunlock(ip, XFS_ILOCK_EXCL);
 out:
author maintainer
#39 lore raw

PATCH 42/48 xfs: Dont log uninitialised fields in inode structures

In reply to Greg Kroah-Hartman

4.9-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        |   82 ++++++++++++++++++++---------------------
 fs/xfs/xfs_ondisk.h            |    2 -
 3 files changed, 50 insertions(+), 61 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 +41 -41

116 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
#40 lore raw

PATCH 43/48 xfs: move more RT specific code under CONFIG_XFS_RT

In reply to Greg Kroah-Hartman

4.9-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 +++++++++++++
 2 files changed, 15 insertions(+)
fs/xfs/xfs_bmap_util.c +2 -0
@@ -84,6 +84,7 @@ xfs_zero_extent(
 		GFP_NOFS, true);
 }
 
+#ifdef CONFIG_XFS_RT
 int
 xfs_bmap_rtalloc(
 	struct xfs_bmalloca	*ap)	/* bmap alloc argument struct */
@@ -195,6 +196,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,
author maintainer
#41 lore raw

PATCH 44/48 xfs: dont change inode mode if ACL update fails

In reply to Greg Kroah-Hartman

4.9-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
#42 lore raw

PATCH 45/48 xfs: reinit btree pointer on attr tree inactivation walk

In reply to Greg Kroah-Hartman

4.9-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
#43 lore raw

PATCH 46/48 xfs: handle error if xfs_btree_get_bufs fails

In reply to Greg Kroah-Hartman

4.9-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
@@ -1579,6 +1579,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;
@@ -2136,6 +2140,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
#44 lore raw

PATCH 47/48 xfs: cancel dirty pages on invalidation

In reply to Greg Kroah-Hartman

4.9-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
@@ -726,6 +726,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);
 }
 
@@ -1181,25 +1189,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
#45 lore raw

PATCH 48/48 xfs: trim writepage mapping to within eof

In reply to Greg Kroah-Hartman

4.9-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
@@ -4057,6 +4057,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
@@ -196,6 +196,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
@@ -438,6 +438,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;
 }
#46 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.9.59 release. There are 48 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:57:14 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

#47 lore raw
In reply to Greg Kroah-Hartman
Quoted 17 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 4.9.59 release. There are 48 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:57:14 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.9.59-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.9.y
and the diffstat can be found below.

Quoted 5 lines

thanks,

greg k-h

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

Results from the Linaro test farm. No regressions observed.

Summary
------------------------------------------------------------------------

kernel: 4.9.59-rc1
git repo: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
git branch: linux-4.9.y
git commit: 54651838029d43fc051ee147b35e769fe662d28f
git describe: v4.9.58-49-g54651838029d
Test details: https://qa-reports.linaro.org/lkft/linux-stable-rc-4.9-oe/build/v4.9.58-49-g54651838029d

No regressions (compared to build v4.9.58)

Boards, architectures and test suites:
-------------------------------------

hi6220-hikey - arm64
* boot - pass: 20
* kselftest - skip: 8, fail: 7, pass: 38 (known failures)
* libhugetlbfs - skip: 1, pass: 90
* ltp-cap_bounds-tests - pass: 2
* ltp-containers-tests - pass: 76
* ltp-fcntl-locktests-tests - pass: 2
* ltp-filecaps-tests - pass: 2
* ltp-fs-tests - fail: 2, pass: 59
* ltp-fs_bind-tests - pass: 2
* ltp-fs_perms_simple-tests - pass: 19
* ltp-fsx-tests - pass: 2
* ltp-hugetlb-tests - skip: 1, pass: 21
* ltp-io-tests - pass: 3
* ltp-ipc-tests - pass: 9
* ltp-math-tests - pass: 11
* ltp-nptl-tests - pass: 2
* ltp-pty-tests - pass: 4
* ltp-sched-tests - pass: 14
* ltp-securebits-tests - pass: 4
* ltp-syscalls-tests - skip: 122, pass: 986
* ltp-timers-tests - pass: 13

juno-r2 - arm64
* boot - pass: 20
* kselftest - skip: 6, fail: 7, pass: 38 (known failures)
* libhugetlbfs - skip: 1, pass: 90
* ltp-cap_bounds-tests - pass: 2
* ltp-containers-tests - pass: 76
* ltp-fcntl-locktests-tests - pass: 2
* ltp-filecaps-tests - pass: 2
* ltp-fs-tests - fail: 2, pass: 59 (known failures)
* ltp-fs_bind-tests - pass: 2
* ltp-fs_perms_simple-tests - pass: 19
* ltp-fsx-tests - pass: 2
* ltp-hugetlb-tests - pass: 22
* ltp-io-tests - pass: 3
* ltp-ipc-tests - pass: 9
* ltp-math-tests - pass: 11
* ltp-nptl-tests - pass: 2
* ltp-pty-tests - pass: 4
* ltp-sched-tests - pass: 10
* ltp-securebits-tests - pass: 4
* ltp-syscalls-tests - skip: 156, fail: 2, pass: 943 (known failures)
* ltp-timers-tests - pass: 13

x15 - arm
* boot - pass: 20
* kselftest - skip: 8, fail: 8, pass: 36 (known)
* ltp-cap_bounds-tests - pass: 2
* ltp-containers-tests - pass: 64
* ltp-fcntl-locktests-tests - pass: 2
* ltp-filecaps-tests - pass: 2
* ltp-fs-tests - pass: 60
* ltp-fs_bind-tests - pass: 2
* ltp-fs_perms_simple-tests - pass: 19
* ltp-fsx-tests - pass: 2
* ltp-io-tests - pass: 3
* ltp-ipc-tests - pass: 9
* ltp-math-tests - pass: 11
* ltp-nptl-tests - pass: 2
* ltp-pty-tests - pass: 4
* ltp-sched-tests - skip: 1, pass: 13
* ltp-securebits-tests - pass: 4
* ltp-syscalls-tests - skip: 67, fail: 2, pass: 1039 (known and being worked on)
* ltp-timers-tests - pass: 13

dell-poweredge-r200 - x86_64
* boot - pass: 20
* kselftest - fail: 15, pass: 53 (known failures)
* libhugetlbfs - skip: 1, pass: 76
* ltp-cap_bounds-tests - pass: 2
* ltp-containers-tests - pass: 64
* ltp-fcntl-locktests-tests - pass: 2
* ltp-filecaps-tests - pass: 2
* ltp-fs-tests - skip: 1, pass: 61
* ltp-fs_bind-tests - pass: 1
* ltp-fs_perms_simple-tests - pass: 19
* ltp-fsx-tests - pass: 2
* ltp-hugetlb-tests - pass: 22
* ltp-io-tests - pass: 2
* ltp-ipc-tests - pass: 8
* ltp-math-tests - pass: 11
* ltp-nptl-tests - pass: 2
* ltp-pty-tests - pass: 4
* ltp-sched-tests - pass: 9
* ltp-securebits-tests - pass: 4
* ltp-syscalls-tests - skip: 163, pass: 964
* ltp-timers-tests - pass: 13

Documentation - https://collaborate.linaro.org/display/LKFT/Email+Reports

author maintainer
#48 lore raw
Quoted 17 lines · Tom Gall
Quoted 17 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 4.9.59 release. There are 48 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:57:14 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.9.59-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.9.y
and the diffstat can be found below.

Quoted 7 lines
Quoted 5 lines

thanks,

greg k-h

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

Results from the Linaro test farm. No regressions observed.

Thanks for the report, but it would still be good to fix those known failures... :)

thanks,

greg k-h