Skip to contentSkip to conversation

4.13.4-stable review

PATCH In review Greg Kroah-Hartman 6 participants 117 messages Sep 24, 2017 – Sep 27, 2017

Subsystems (4)
lore
Share & tools
lore

Greg Kroah-Hartman

author maintainer
#0 lore raw

cover 4.13.4-stable review

This is the start of the stable review cycle for the 4.13.4 release. There are 109 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 Tue Sep 26 20:33:30 UTC 2017. Anything received after that time might be too late.

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

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

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

thanks,

greg k-h

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

Greg Kroah-Hartman <[email protected]>

    Linux 4.13.4-rc1

Thomas Gleixner <[email protected]>
genirq: Fix cpumask check in __irq_startup_managed()

John Keeping <[email protected]>
genirq/msi: Fix populating multiple interrupts

Thomas Gleixner <[email protected]>
genirq: Make sparse_irq_lock protect what it should protect

Johannes Berg <[email protected]>
mac80211: fix deadlock in driver-managed RX BA session start

Avraham Stern <[email protected]>
mac80211: flush hw_roc_start work before cancelling the ROC

Beni Lev <[email protected]>
mac80211_hwsim: Use proper TX power

Johannes Berg <[email protected]>
mac80211: fix VLAN handling with TXQs

Luca Coelho <[email protected]>
iwlwifi: add workaround to disable wide channels in 5GHz

Peter Zijlstra <[email protected]>
sched/cpuset/pm: Fix cpuset vs. suspend-resume bugs

Michael Lyle <[email protected]>
bcache: fix bch_hprint crash and improve output

Tang Junhui <[email protected]>
bcache: fix for gc and write-back race

Tang Junhui <[email protected]>
bcache: fix sequential large write IO bypass

Tony Asleson <[email protected]>
bcache: Correct return value for sysfs attach errors

Tang Junhui <[email protected]>
bcache: correct cache_dirty_target in __update_writeback_rate()

Tang Junhui <[email protected]>
bcache: do not subtract sectors_to_gc for bypassed IO

Jan Kara <[email protected]>
bcache: Fix leak of bdev reference

Tang Junhui <[email protected]>
bcache: initialize dirty stripes in flash_dev_run()

Takashi Iwai <[email protected]>
ALSA: seq: Cancel pending autoload work at unbinding device

Chanwoo Choi <[email protected]>
PM / devfreq: Fix memory leak when fail to register device

Ulrich Hecht <[email protected]>

    media: adv7180: add missing adv7180cp, adv7180st i2c device IDs

Guenter Roeck <[email protected]>
media: uvcvideo: Prevent heap overflow when accessing mapped controls

Gustavo A. R. Silva <[email protected]>
media: venus: fix copy/paste error in return_buf_error

Sean Young <[email protected]>
media: Revert "[media] lirc_dev: remove superfluous get/put_device() calls"

Daniel Mentz <[email protected]>
media: v4l2-compat-ioctl32: Fix timespec conversion

Martin Schwidefsky <[email protected]>

    s390/mm: fix race on mm->context.flush_mm

Martin Schwidefsky <[email protected]>
s390/mm: fix local TLB flushing vs. detach of an mm address space

Manfred Spraul <[email protected]>
net/netfilter/nf_conntrack_core: Fix net_conntrack_lock()

Keith Busch <[email protected]>
PCI: pciehp: Report power fault only once until we clear it

Aleksandr Bezzubikov <[email protected]>
PCI: shpchp: Enable bridge bus mastering if MSI is enabled

Jose Abreu <[email protected]>
ARC: Re-enable MMU upon Machine Check exception

Baohong Liu <[email protected]>
tracing: Apply trace_clock changes to instance max buffer

Chunyu Hu <[email protected]>
tracing: Fix clear of RECORDED_TGID flag when disabling trace event

Steven Rostedt (VMware) <[email protected]>
tracing: Add barrier to trace_printk() buffer nesting modification

Steven Rostedt (VMware) <[email protected]>
ftrace: Fix memleak when unregistering dynamic ops when tracing disabled

Steven Rostedt (VMware) <[email protected]>
ftrace: Fix selftest goto location on error

Zev Weiss <[email protected]>
ftrace: Fix debug preempt config name in stack_tracer_{en,dis}able

Anup Patel <[email protected]>
mailbox: bcm-flexrm-mailbox: Fix mask used in CMPL_START_ADDR_VALUE()

Dan Carpenter <[email protected]>
scsi: qla2xxx: Fix an integer overflow in sysfs code

Quinn Tran <[email protected]>
scsi: qla2xxx: Use fabric name for Get Port Speed command

Sawan Chandak <[email protected]>
scsi: qla2xxx: Use BIT_6 to acquire FAWWPN from switch

Michael Hernandez <[email protected]>
scsi: qla2xxx: Fix target multiqueue configuration

Joe Carnuccio <[email protected]>

    scsi: qla2xxx: Correction to vha->vref_count timeout

[email protected] <[email protected]>
scsi: qla2xxx: Update fw_started flags at qpair creation.

Hannes Reinecke <[email protected]>
scsi: sg: fixup infoleak when using SG_GET_REQUEST_TABLE

Hannes Reinecke <[email protected]>
scsi: sg: factor out sg_fill_request_table()

Long Li <[email protected]>
scsi: storvsc: fix memory leak on ring buffer busy

Shivasharan S <[email protected]>
scsi: megaraid_sas: Return pended IOCTLs with cmd_status MFI_STAT_WRONG_STATE in case adapter is dead

Shivasharan S <[email protected]>
scsi: megaraid_sas: Check valid aen class range to avoid kernel panic

Shivasharan S <[email protected]>
scsi: megaraid_sas: set minimum value of resetwaittime to be 1 secs

Shivasharan S <[email protected]>
scsi: megaraid_sas: mismatch of allocated MFI frame size and length exposed in MFI MPT pass through command

Brian King <[email protected]>
scsi: aacraid: Fix command send race condition

Dan Carpenter <[email protected]>
scsi: qedi: off by one in qedi_get_cmd_from_tid()

Steffen Maier <[email protected]>
scsi: zfcp: trace high part of "new" 64 bit SCSI LUN

Steffen Maier <[email protected]>
scsi: zfcp: trace HBA FSF response by default on dismiss or timedout late response

Steffen Maier <[email protected]>
scsi: zfcp: fix payload with full FCP_RSP IU in SCSI trace records

Steffen Maier <[email protected]>
scsi: zfcp: fix missing trace records for early returns in TMF eh handlers

Steffen Maier <[email protected]>
scsi: zfcp: fix passing fsf_req to SCSI trace on TMF to correlate with HBA

Steffen Maier <[email protected]>
scsi: zfcp: fix capping of unsuccessful GPN_FT SAN response trace records

Benjamin Block <[email protected]>
scsi: zfcp: add handling for FCP_RESID_OVER to the fcp ingress path

Steffen Maier <[email protected]>
scsi: zfcp: fix queuecommand for scsi_eh commands when DIX enabled

Bart Van Assche <[email protected]>
skd: Submit requests to firmware before triggering the doorbell

Bart Van Assche <[email protected]>
skd: Avoid that module unloading triggers a use-after-free

NeilBrown <[email protected]>
md/bitmap: disable bitmap_resize for file-backed bitmaps.

Shaohua Li <[email protected]>
md/bitmap: copy correct data for bitmap super

Jens Axboe <[email protected]>
block: directly insert blk-mq request from blk_insert_cloned_request()

Bart Van Assche <[email protected]>
block: Relax a check in blk_start_queue()

Michael Ellerman <[email protected]>
powerpc: Fix DAR reporting when alignment handler faults

John Allen <[email protected]>
powerpc/pseries: Don't attempt to acquire drc during memory hot add for assigned lmbs

Alistair Popple <[email protected]>
powerpc/powernv/npu: Move tlb flush before launching ATSD

Frederic Barrat <[email protected]>
cxl: Fix driver use count

zhangyi (F) <[email protected]>
ext4: fix quota inconsistency during orphan cleanup for read-only mounts

zhangyi (F) <[email protected]>
ext4: fix incorrect quotaoff if the quota feature is enabled

Darrick J. Wong <[email protected]>
ext4: in ext4_seek_{hole,data}, return -ENXIO for negative offsets

Bjorn Andersson <[email protected]>
wcn36xx: Introduce mutual exclusion of fw configuration

Sebastian Reichel <[email protected]>
regulator: cpcap: Fix standby mode

Stephan Mueller <[email protected]>
crypto: AF_ALG - remove SGL terminator indicator when chaining

Horia Geantă <[email protected]>
crypto: caam/qi - properly set IV after {en,de}crypt

Horia Geantă <[email protected]>
crypto: caam/qi - fix typo in authenc alg driver name

Ard Biesheuvel <[email protected]>
crypto: scompress - don't sleep with preemption disabled

Gary R Hook <[email protected]>
crypto: ccp - Fix XTS-AES-128 support on v5 CCPs

Zhouyi Zhou <[email protected]>
docs: disable KASLR when debugging kernel

Douglas Leung <[email protected]>
MIPS: math-emu: <MADDF|MSUBF>.D: Fix accuracy (64-bit case)

Douglas Leung <[email protected]>
MIPS: math-emu: <MADDF|MSUBF>.S: Fix accuracy (32-bit case)

Aleksandar Markovic <[email protected]>
MIPS: math-emu: <MADDF|MSUBF>.<D|S>: Clean up "maddf_flags" enumeration

Aleksandar Markovic <[email protected]>
MIPS: math-emu: <MADDF|MSUBF>.<D|S>: Fix some cases of zero inputs

Aleksandar Markovic <[email protected]>
MIPS: math-emu: <MADDF|MSUBF>.<D|S>: Fix some cases of infinite inputs

Aleksandar Markovic <[email protected]>
MIPS: math-emu: <MADDF|MSUBF>.<D|S>: Fix NaN propagation

Aleksandar Markovic <[email protected]>
MIPS: math-emu: MINA.<D|S>: Fix some cases of infinity and zero inputs

Aleksandar Markovic <[email protected]>
MIPS: math-emu: <MAXA|MINA>.<D|S>: Fix cases of both infinite inputs

Aleksandar Markovic <[email protected]>
MIPS: math-emu: <MAXA|MINA>.<D|S>: Fix cases of input values with opposite signs

Aleksandar Markovic <[email protected]>
MIPS: math-emu: <MAX|MIN>.<D|S>: Fix cases of both inputs negative

Aleksandar Markovic <[email protected]>
MIPS: math-emu: <MAX|MAXA|MIN|MINA>.<D|S>: Fix cases of both inputs zero

Aleksandar Markovic <[email protected]>
MIPS: math-emu: <MAX|MAXA|MIN|MINA>.<D|S>: Fix quiet NaN propagation

Kai-Heng Feng <[email protected]>
Input: i8042 - add Gigabyte P57 to the keyboard reset table

Daniel Drake <[email protected]>
pinctrl/amd: save pin registers over suspend/resume

Krzysztof Kozlowski <[email protected]>
pinctrl: samsung: Fix NULL pointer exception on external interrupts on S3C24xx

Krzysztof Kozlowski <[email protected]>
pinctrl: samsung: Fix invalid register offset used for Exynos5433 external interrupts

Arnd Bergmann <[email protected]>
tty: fix __tty_insert_flip_char regression

Arnd Bergmann <[email protected]>
tty: improve tty_insert_flip_char() slow path

Arnd Bergmann <[email protected]>
tty: improve tty_insert_flip_char() fast path

Zhang, Jerry <[email protected]>
drm/amdgpu: read reg in each iterator of psp_wait_for loop

Cameron Gutman <[email protected]>
Input: xpad - validate USB endpoint type during probe

Ethan Barnes <[email protected]>
smp/hotplug: Handle removal correctly in cpuhp_store_callbacks()

Paul E. McKenney <[email protected]>
srcu: Provide ordering for CPU not involved in grace period

Majd Dibbiny <[email protected]>
IB/mlx5: Fix cached MR allocation flow

Mike Marciniszyn <[email protected]>
IB/{qib, hfi1}: Avoid flow control testing for RDMA write operation

Alex Estrin <[email protected]>
IB/hfi1: Revert egress pkey check enforcement

Bart Van Assche <[email protected]>
<linux/uaccess.h>: Fix copy_in_user() declaration

Jan Kara <[email protected]>
orangefs: Don't clear SGID when inheriting ACLs

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

Diffstat:

 Documentation/dev-tools/gdb-kernel-debugging.rst   |   6 +-
 Makefile                                           |   4 +-
 arch/arc/kernel/entry.S                            |   6 +
 arch/arc/mm/tlb.c                                  |   3 -
 arch/mips/math-emu/dp_fmax.c                       |  84 +++++--
 arch/mips/math-emu/dp_fmin.c                       |  86 +++++--
 arch/mips/math-emu/dp_maddf.c                      | 246 +++++++++++++--------
 arch/mips/math-emu/ieee754int.h                    |   4 +
 arch/mips/math-emu/ieee754sp.h                     |   4 +
 arch/mips/math-emu/sp_fmax.c                       |  84 +++++--
 arch/mips/math-emu/sp_fmin.c                       |  86 +++++--
 arch/mips/math-emu/sp_maddf.c                      | 229 +++++++++----------
 arch/powerpc/kernel/align.c                        | 119 ++++++----
 arch/powerpc/platforms/powernv/npu-dma.c           |  12 +-
 arch/powerpc/platforms/pseries/hotplug-memory.c    |   4 +
 arch/s390/include/asm/mmu.h                        |   2 +
 arch/s390/include/asm/mmu_context.h                |   8 +-
 arch/s390/include/asm/tlbflush.h                   |  30 +--
 block/blk-core.c                                   |   9 +-
 block/blk-mq.c                                     |  16 ++
 block/blk-mq.h                                     |   1 +
 crypto/algif_skcipher.c                            |   4 +-
 crypto/scompress.c                                 |   4 +-
 drivers/block/skd_main.c                           |  21 +-
 drivers/crypto/caam/caamalg_qi.c                   |  11 +-
 drivers/crypto/ccp/ccp-crypto-aes-xts.c            |   4 +-
 drivers/crypto/ccp/ccp-dev-v5.c                    |   2 +
 drivers/crypto/ccp/ccp-dev.h                       |   2 +
 drivers/crypto/ccp/ccp-ops.c                       |  43 +++-
 drivers/devfreq/devfreq.c                          |   5 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c            |   3 +-
 drivers/gpu/drm/amd/amdgpu/psp_v3_1.c              |   2 -
 drivers/infiniband/hw/hfi1/init.c                  |   1 -
 drivers/infiniband/hw/hfi1/rc.c                    |   3 +-
 drivers/infiniband/hw/mlx5/mr.c                    |  18 +-
 drivers/infiniband/hw/qib/qib_rc.c                 |   4 +-
 drivers/input/joystick/xpad.c                      |  10 +-
 drivers/input/serio/i8042-x86ia64io.h              |   7 +
 drivers/mailbox/bcm-flexrm-mailbox.c               |   2 +-
 drivers/md/bcache/bcache.h                         |   1 +
 drivers/md/bcache/request.c                        |  12 +-
 drivers/md/bcache/super.c                          |   7 +-
 drivers/md/bcache/sysfs.c                          |   4 +-
 drivers/md/bcache/util.c                           |  50 +++--
 drivers/md/bcache/writeback.c                      |  20 +-
 drivers/md/bcache/writeback.h                      |  21 +-
 drivers/md/bitmap.c                                |   9 +-
 drivers/media/i2c/adv7180.c                        |   2 +
 drivers/media/platform/qcom/venus/helpers.c        |   2 +-
 drivers/media/rc/lirc_dev.c                        |   4 +
 drivers/media/usb/uvc/uvc_ctrl.c                   |   7 +
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c      |   3 +-
 drivers/misc/cxl/api.c                             |   4 +
 drivers/misc/cxl/file.c                            |   8 +-
 drivers/net/wireless/ath/wcn36xx/main.c            |  52 ++++-
 drivers/net/wireless/ath/wcn36xx/wcn36xx.h         |   3 +
 drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c |  62 +++++-
 drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h |   3 +-
 drivers/net/wireless/intel/iwlwifi/mvm/nvm.c       |   3 +-
 drivers/net/wireless/mac80211_hwsim.c              |   2 -
 drivers/pci/hotplug/pciehp_hpc.c                   |   8 +
 drivers/pci/hotplug/shpchp_hpc.c                   |   2 +
 drivers/pinctrl/pinctrl-amd.c                      |  75 +++++++
 drivers/pinctrl/pinctrl-amd.h                      |   1 +
 drivers/pinctrl/samsung/pinctrl-exynos.c           |   8 +-
 drivers/pinctrl/samsung/pinctrl-s3c24xx.c          |  37 ++--
 drivers/pinctrl/samsung/pinctrl-s3c64xx.c          |  40 ++--
 drivers/pinctrl/samsung/pinctrl-samsung.c          |   6 +
 drivers/pinctrl/samsung/pinctrl-samsung.h          |   5 +
 drivers/regulator/cpcap-regulator.c                |   8 +-
 drivers/s390/scsi/zfcp_dbf.c                       |  33 ++-
 drivers/s390/scsi/zfcp_dbf.h                       |  17 +-
 drivers/s390/scsi/zfcp_fc.h                        |   6 +-
 drivers/s390/scsi/zfcp_fsf.c                       |   7 +-
 drivers/s390/scsi/zfcp_scsi.c                      |  16 +-
 drivers/scsi/aacraid/aachba.c                      |  54 ++---
 drivers/scsi/megaraid/megaraid_sas_base.c          |  16 +-
 drivers/scsi/megaraid/megaraid_sas_fusion.c        |   2 +-
 drivers/scsi/qedi/qedi_main.c                      |   2 +-
 drivers/scsi/qla2xxx/qla_attr.c                    |   8 +-
 drivers/scsi/qla2xxx/qla_gs.c                      |   2 +-
 drivers/scsi/qla2xxx/qla_init.c                    |   1 +
 drivers/scsi/qla2xxx/qla_isr.c                     |   2 +-
 drivers/scsi/qla2xxx/qla_mbx.c                     |   3 +-
 drivers/scsi/qla2xxx/qla_mid.c                     |   2 +-
 drivers/scsi/qla2xxx/qla_target.c                  |   2 +-
 drivers/scsi/sg.c                                  |  64 +++---
 drivers/scsi/storvsc_drv.c                         |   2 +
 drivers/tty/tty_buffer.c                           |  26 +++
 fs/ext4/file.c                                     |   4 +-
 fs/ext4/super.c                                    |  38 +++-
 fs/orangefs/acl.c                                  |  48 ++--
 include/linux/ccp.h                                |   3 +-
 include/linux/cpuset.h                             |   6 +
 include/linux/ftrace.h                             |   4 +-
 include/linux/tty_flip.h                           |   3 +-
 include/linux/uaccess.h                            |   2 +-
 include/net/mac80211.h                             |  15 +-
 kernel/cgroup/cpuset.c                             |  16 +-
 kernel/cpu.c                                       |  12 +-
 kernel/irq/chip.c                                  |   2 +-
 kernel/irq/irqdesc.c                               |  24 +-
 kernel/irq/msi.c                                   |   5 +-
 kernel/power/process.c                             |   5 +-
 kernel/rcu/srcutree.c                              |   9 +
 kernel/sched/core.c                                |   7 +-
 kernel/trace/ftrace.c                              |  10 +-
 kernel/trace/trace.c                               |  10 +-
 kernel/trace/trace_events.c                        |   2 +-
 kernel/trace/trace_selftest.c                      |   2 +-
 net/mac80211/agg-rx.c                              |  32 ++-
 net/mac80211/ht.c                                  |   6 +-
 net/mac80211/ieee80211_i.h                         |   4 +
 net/mac80211/iface.c                               |  17 +-
 net/mac80211/offchannel.c                          |   2 +
 net/mac80211/tx.c                                  |  36 ++-
 net/netfilter/nf_conntrack_core.c                  |  52 +++--
 sound/core/seq_device.c                            |   3 +
 118 files changed, 1550 insertions(+), 752 deletions(-)
author maintainer
#3 lore raw

PATCH 2/109 <linux/uaccess.h>: Fix copy_in_user() declaration

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

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

From: Bart Van Assche <[email protected]>

commit f58e76c1c551c7577b25a6fe493d82f5214331b7 upstream.

copy_in_user() copies data from user-space address @from to user- space address @to. Hence declare both @from and @to as user-space pointers.

Fixes commit d597580d3737 ("generic ...copy_..._user primitives")
---
 include/linux/uaccess.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/uaccess.h +1 -1
@@ -156,7 +156,7 @@ copy_to_user(void __user *to, const void
 }
 #ifdef CONFIG_COMPAT
 static __always_inline unsigned long __must_check
-copy_in_user(void __user *to, const void *from, unsigned long n)
+copy_in_user(void __user *to, const void __user *from, unsigned long n)
 {
 	might_fault();
 	if (access_ok(VERIFY_WRITE, to, n) && access_ok(VERIFY_READ, from, n))
author maintainer
#4 lore raw

PATCH 3/109 IB/hfi1: Revert egress pkey check enforcement

In reply to Greg Kroah-Hartman

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

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

From: Alex Estrin <[email protected]>

commit ecdb19f4b513033e6f2c4326cd5b81e04393e5e1 upstream.

Current code has some serious flaws. Disarm the flag pending an appropriate patch.

Fixes 53526500f301 ("IB/hfi1: Permanently enable P_Key checking in HFI")
---
 drivers/infiniband/hw/hfi1/init.c |    1 -
 1 file changed, 1 deletion(-)
drivers/infiniband/hw/hfi1/init.c +0 -1
@@ -483,7 +483,6 @@ void hfi1_init_pportdata(struct pci_dev
 
 	ppd->pkeys[default_pkey_idx] = DEFAULT_P_KEY;
 	ppd->part_enforce |= HFI1_PART_ENFORCE_IN;
-	ppd->part_enforce |= HFI1_PART_ENFORCE_OUT;
 
 	if (loopback) {
 		hfi1_early_err(&pdev->dev,
author maintainer
#23 lore raw

PATCH 17/109 MIPS: math-emu: <MAX|MAXA|MIN|MINA>.<D|S>: Fix quiet NaN propagation

In reply to Greg Kroah-Hartman

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

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

From: Aleksandar Markovic <[email protected]>

commit e78bf0dc4789bdea1453595ae89e8db65918e22e upstream.

Fix the value returned by <MAX|MAXA|MIN|MINA>.<D|S> fd,fs,ft, if both inputs are quiet NaNs. The <MAX|MAXA|MIN|MINA>.<D|S> specifications state that the returned value in such cases should be the quiet NaN contained in register fs.

A relevant example:

MAX.S fd,fs,ft:
If fs contains qNaN1, and ft contains qNaN2, fd is going to contain qNaN1 (without this patch, it used to contain qNaN2).

Fixes a79f5f9ba508 ("MIPS: math-emu: Add support for the MIPS R6 MAX{, A} FPU instruction")
Fixes 4e9561b20e2f ("MIPS: math-emu: Add support for the MIPS R6 MIN{, A} FPU instruction")

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

---
 arch/mips/math-emu/dp_fmax.c |   32 ++++++++++++++++++++++++++++----
 arch/mips/math-emu/dp_fmin.c |   32 ++++++++++++++++++++++++++++----
 arch/mips/math-emu/sp_fmax.c |   32 ++++++++++++++++++++++++++++----
 arch/mips/math-emu/sp_fmin.c |   32 ++++++++++++++++++++++++++++----
 4 files changed, 112 insertions(+), 16 deletions(-)
arch/mips/math-emu/dp_fmax.c +28 -4
@@ -47,14 +47,26 @@ union ieee754dp ieee754dp_fmax(union iee
 	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
 		return ieee754dp_nanxcpt(x);
 
-	/* numbers are preferred to NaNs */
+	/*
+	 * Quiet NaN handling
+	 */
+
+	/*
+	 *    The case of both inputs quiet NaNs
+	 */
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
+		return x;
+
+	/*
+	 *    The cases of exactly one input quiet NaN (numbers
+	 *    are here preferred as returned values to NaNs)
+	 */
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
 		return x;
 
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
@@ -147,14 +159,26 @@ union ieee754dp ieee754dp_fmaxa(union ie
 	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
 		return ieee754dp_nanxcpt(x);
 
-	/* numbers are preferred to NaNs */
+	/*
+	 * Quiet NaN handling
+	 */
+
+	/*
+	 *    The case of both inputs quiet NaNs
+	 */
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
+		return x;
+
+	/*
+	 *    The cases of exactly one input quiet NaN (numbers
+	 *    are here preferred as returned values to NaNs)
+	 */
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
 		return x;
 
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
arch/mips/math-emu/dp_fmin.c +28 -4
@@ -47,14 +47,26 @@ union ieee754dp ieee754dp_fmin(union iee
 	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
 		return ieee754dp_nanxcpt(x);
 
-	/* numbers are preferred to NaNs */
+	/*
+	 * Quiet NaN handling
+	 */
+
+	/*
+	 *    The case of both inputs quiet NaNs
+	 */
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
+		return x;
+
+	/*
+	 *    The cases of exactly one input quiet NaN (numbers
+	 *    are here preferred as returned values to NaNs)
+	 */
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
 		return x;
 
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
@@ -147,14 +159,26 @@ union ieee754dp ieee754dp_fmina(union ie
 	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
 		return ieee754dp_nanxcpt(x);
 
-	/* numbers are preferred to NaNs */
+	/*
+	 * Quiet NaN handling
+	 */
+
+	/*
+	 *    The case of both inputs quiet NaNs
+	 */
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
+		return x;
+
+	/*
+	 *    The cases of exactly one input quiet NaN (numbers
+	 *    are here preferred as returned values to NaNs)
+	 */
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
 		return x;
 
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
arch/mips/math-emu/sp_fmax.c +28 -4
@@ -47,14 +47,26 @@ union ieee754sp ieee754sp_fmax(union iee
 	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
 		return ieee754sp_nanxcpt(x);
 
-	/* numbers are preferred to NaNs */
+	/*
+	 * Quiet NaN handling
+	 */
+
+	/*
+	 *    The case of both inputs quiet NaNs
+	 */
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
+		return x;
+
+	/*
+	 *    The cases of exactly one input quiet NaN (numbers
+	 *    are here preferred as returned values to NaNs)
+	 */
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
 		return x;
 
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
@@ -147,14 +159,26 @@ union ieee754sp ieee754sp_fmaxa(union ie
 	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
 		return ieee754sp_nanxcpt(x);
 
-	/* numbers are preferred to NaNs */
+	/*
+	 * Quiet NaN handling
+	 */
+
+	/*
+	 *    The case of both inputs quiet NaNs
+	 */
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
+		return x;
+
+	/*
+	 *    The cases of exactly one input quiet NaN (numbers
+	 *    are here preferred as returned values to NaNs)
+	 */
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
 		return x;
 
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
arch/mips/math-emu/sp_fmin.c +28 -4
@@ -47,14 +47,26 @@ union ieee754sp ieee754sp_fmin(union iee
 	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
 		return ieee754sp_nanxcpt(x);
 
-	/* numbers are preferred to NaNs */
+	/*
+	 * Quiet NaN handling
+	 */
+
+	/*
+	 *    The case of both inputs quiet NaNs
+	 */
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
+		return x;
+
+	/*
+	 *    The cases of exactly one input quiet NaN (numbers
+	 *    are here preferred as returned values to NaNs)
+	 */
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
 		return x;
 
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
@@ -147,14 +159,26 @@ union ieee754sp ieee754sp_fmina(union ie
 	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
 		return ieee754sp_nanxcpt(x);
 
-	/* numbers are preferred to NaNs */
+	/*
+	 * Quiet NaN handling
+	 */
+
+	/*
+	 *    The case of both inputs quiet NaNs
+	 */
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
+		return x;
+
+	/*
+	 *    The cases of exactly one input quiet NaN (numbers
+	 *    are here preferred as returned values to NaNs)
+	 */
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
 		return x;
 
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
 	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
author maintainer
#38 lore raw

PATCH RESEND 34/109 crypto: AF_ALG - remove SGL terminator indicator when chaining

In reply to Greg Kroah-Hartman

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

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

From: Stephan Mueller <[email protected]>

Fixed differently upstream as commit 2d97591ef43d ("crypto: af_alg - consolidation of duplicate code")

The SGL is MAX_SGL_ENTS + 1 in size. The last SG entry is used for the chaining and is properly updated with the sg_chain invocation. During the filling-in of the initial SG entries, sg_mark_end is called for each SG entry. This is appropriate as long as no additional SGL is chained with the current SGL. However, when a new SGL is chained and the last SG entry is updated with sg_chain, the last but one entry still contains the end marker from the sg_mark_end. This end marker must be removed as otherwise a walk of the chained SGLs will cause a NULL pointer dereference at the last but one SG entry, because sg_next will return NULL.

The patch only applies to all kernels up to and including 4.13. The patch 2d97591ef43d0587be22ad1b0d758d6df4999a0b added to 4.14-rc1 introduced a complete new code base which addresses this bug in a different way. Yet, that patch is too invasive for stable kernels and was therefore not marked for stable.

Fixes 8ff590903d5fc ("crypto: algif_skcipher - User-space interface for skcipher operations")
---
 crypto/algif_skcipher.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
crypto/algif_skcipher.c +3 -1
@@ -144,8 +144,10 @@ static int skcipher_alloc_sgl(struct soc
 		sg_init_table(sgl->sg, MAX_SGL_ENTS + 1);
 		sgl->cur = 0;
 
-		if (sg)
+		if (sg) {
 			sg_chain(sg, MAX_SGL_ENTS + 1, sgl->sg);
+			sg_unmark_end(sg + (MAX_SGL_ENTS - 1));
+		}
 
 		list_add_tail(&sgl->list, &ctx->tsgl);
 	}
author maintainer
#56 lore raw

PATCH 52/109 scsi: zfcp: fix capping of unsuccessful GPN_FT SAN response trace records

In reply to Greg Kroah-Hartman

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

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

From: Steffen Maier <[email protected]>

commit 975171b4461be296a35e83ebd748946b81cf0635 upstream.

v4.9 commit aceeffbb59bb ("zfcp: trace full payload of all SAN records (req,resp,iels)") fixed trace data loss of 2.6.38 commit 2c55b750a884 ("[SCSI] zfcp: Redesign of the debug tracing for SAN records.") necessary for problem determination, e.g. to see the currently active zone set during automatic port scan.

While it already saves space by not dumping any empty residual entries of the large successful GPN_FT response (4 pages), there are seldom cases where the GPN_FT response is unsuccessful and likely does not have FC_NS_FID_LAST set in fp_flags so we did not cap the trace record. We typically see such case for an initiator WWPN, which is not in any zone.

Cap unsuccessful responses to at least the actual basic CT_IU response plus whatever fits the SAN trace record built-in "payload" buffer just in case there's trailing information
of which we would at least see the existence and its beginning.

In order not to erroneously cap successful responses, we need to swap calling the trace function and setting the CT / ELS status to success (0).

Example trace record pair formatted with zfcpdbf:

Timestamp : ...
Area : SAN
Subarea : 00
Level : 1
Exception : -
CPU ID : ..
Caller : 0x...
Record ID : 1
Tag : fssct_1
Request ID : 0x<request_id>
Destination ID : 0x00fffffc
SAN req short : 01000000 fc020000 01720ffc 00000000

                 00000008

SAN req length : 20
|
Timestamp : ...
Area : SAN
Subarea : 00
Level : 1
Exception : -
CPU ID : ..
Caller : 0x...
Record ID : 2
Tag : fsscth2
Request ID : 0x<request_id>
Destination ID : 0x00fffffc
SAN resp short : 01000000 fc020000 80010000 00090700

                 00000000 00000000 00000000 00000000 [trailing info]
                 00000000 00000000 00000000 00000000 [trailing info]
SAN resp length: 16384
San resp info  : 01000000 fc020000 80010000 00090700
                 00000000 00000000 00000000 00000000 [trailing info]
                 00000000 00000000 00000000 00000000 [trailing info]
                 00000000 00000000 00000000 00000000 [trailing info]
                 00000000 00000000 00000000 00000000 [trailing info]
                 00000000 00000000 00000000 00000000 [trailing info]
                 00000000 00000000 00000000 00000000 [trailing info]
                 00000000 00000000 00000000 00000000 [trailing info]
                 00000000 00000000 00000000 00000000 [trailing info]
                 00000000 00000000 00000000 00000000 [trailing info]
                 00000000 00000000 00000000 00000000 [trailing info]
                 00000000 00000000 00000000 00000000 [trailing info]
                 00000000 00000000 00000000 00000000 [trailing info]
                 00000000 00000000 00000000 00000000 [trailing info]
                 00000000 00000000 00000000 00000000 [trailing info]
                 00000000 00000000 00000000 00000000 [trailing info]

The fix saves all but one of the previously associated 64 PAYload trace record chunks of size 256 bytes each.

Fixes aceeffbb59bb ("zfcp: trace full payload of all SAN records (req,resp,iels)")
Fixes 2c55b750a884 ("[SCSI] zfcp: Redesign of the debug tracing for SAN records.")
---
 drivers/s390/scsi/zfcp_dbf.c |   10 +++++++++-
 drivers/s390/scsi/zfcp_fsf.c |    4 ++--
 2 files changed, 11 insertions(+), 3 deletions(-)
drivers/s390/scsi/zfcp_dbf.c +9 -1
@@ -3,7 +3,7 @@
  *
  * Debug traces for zfcp.
  *
- * Copyright IBM Corp. 2002, 2016
+ * Copyright IBM Corp. 2002, 2017
  */
 
 #define KMSG_COMPONENT "zfcp"
@@ -447,6 +447,7 @@ static u16 zfcp_dbf_san_res_cap_len_if_g
 	struct fc_ct_hdr *reqh = sg_virt(ct_els->req);
 	struct fc_ns_gid_ft *reqn = (struct fc_ns_gid_ft *)(reqh + 1);
 	struct scatterlist *resp_entry = ct_els->resp;
+	struct fc_ct_hdr *resph;
 	struct fc_gpn_ft_resp *acc;
 	int max_entries, x, last = 0;
 
@@ -473,6 +474,13 @@ static u16 zfcp_dbf_san_res_cap_len_if_g
 		return len; /* not GPN_FT response so do not cap */
 
 	acc = sg_virt(resp_entry);
+
+	/* cap all but accept CT responses to at least the CT header */
+	resph = (struct fc_ct_hdr *)acc;
+	if ((ct_els->status) ||
+	    (resph->ct_cmd != cpu_to_be16(FC_FS_ACC)))
+		return max(FC_CT_HDR_LEN, ZFCP_DBF_SAN_MAX_PAYLOAD);
+
 	max_entries = (reqh->ct_mr_size * 4 / sizeof(struct fc_gpn_ft_resp))
 		+ 1 /* zfcp_fc_scan_ports: bytes correct, entries off-by-one
 		     * to account for header as 1st pseudo "entry" */;
drivers/s390/scsi/zfcp_fsf.c +2 -2
@@ -928,8 +928,8 @@ static void zfcp_fsf_send_ct_handler(str
 
 	switch (header->fsf_status) {
         case FSF_GOOD:
-		zfcp_dbf_san_res("fsscth2", req);
 		ct->status = 0;
+		zfcp_dbf_san_res("fsscth2", req);
 		break;
         case FSF_SERVICE_CLASS_NOT_SUPPORTED:
 		zfcp_fsf_class_not_supp(req);
@@ -1109,8 +1109,8 @@ static void zfcp_fsf_send_els_handler(st
 
 	switch (header->fsf_status) {
 	case FSF_GOOD:
-		zfcp_dbf_san_res("fsselh1", req);
 		send_els->status = 0;
+		zfcp_dbf_san_res("fsselh1", req);
 		break;
 	case FSF_SERVICE_CLASS_NOT_SUPPORTED:
 		zfcp_fsf_class_not_supp(req);
author maintainer
#61 lore raw

PATCH 57/109 scsi: zfcp: trace high part of "new" 64 bit SCSI LUN

In reply to Greg Kroah-Hartman

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

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

From: Steffen Maier <[email protected]>

commit 5d4a3d0a2ff23799b956e5962b886287614e7fad upstream.

Complements debugging aspects of the otherwise functionally complete v3.17 commit 9cb78c16f5da ("scsi: use 64-bit LUNs").

While I don't have access to a target exporting 3 or 4 level LUNs, I did test it by explicitly attaching a non-existent fake 4 level LUN by means of zfcp sysfs attribute "unit_add".
In order to see corresponding trace records of otherwise successful events, we had to increase the trace level of area SCSI and HBA to 6.

$ echo 6 > /sys/kernel/debug/s390dbf/zfcp_0.0.1880_scsi/level
$ echo 6 > /sys/kernel/debug/s390dbf/zfcp_0.0.1880_hba/level
$ echo 0x4011402240334044 > \
  /sys/bus/ccw/drivers/zfcp/0.0.1880/0x50050763031bd327/unit_add

Example output formatted by an updated zfcpdbf from the s390-tools package interspersed with kernel messages at scsi_logging_level=4605:

Timestamp : ...
Area : REC
Subarea : 00
Level : 1
Exception : -
CPU ID : ..
Caller : 0x...
Record ID : 1
Tag : scsla_1
LUN : 0x4011402240334044
WWPN : 0x50050763031bd327
D_ID : 0x00......
Adapter status : 0x5400050b
Port status : 0x54000001
LUN status : 0x41000000
Ready count : 0x00000001
Running count : 0x00000000
ERP want : 0x01
ERP need : 0x01

scsi 2:0:0:4630896905707208721: scsi scan: INQUIRY pass 1 length 36 scsi 2:0:0:4630896905707208721: scsi scan: INQUIRY successful with code 0x0

Timestamp : ...
Area : HBA
Subarea : 00
Level : 6
Exception : -
CPU ID : ..
Caller : 0x...
Record ID : 1
Tag : fs_norm
Request ID : 0x<inquiry2-req-id>
Request status : 0x00000010
FSF cmnd : 0x00000001
FSF sequence no: 0x...
FSF issued : ...
FSF stat : 0x00000000
FSF stat qual : 00000000 00000000 00000000 00000000
Prot stat : 0x00000001
Prot stat qual : ........ ........ 00000000 00000000
Port handle : 0x...
LUN handle : 0x...
|
Timestamp : ...
Area : SCSI
Subarea : 00
Level : 6
Exception : -
CPU ID : ..
Caller : 0x...
Record ID : 1
Tag : rsl_nor
Request ID : 0x<inquiry2-req-id>
SCSI ID : 0x00000000
SCSI LUN : 0x40224011
SCSI LUN high : 0x40444033 <=======================
SCSI result : 0x00000000
SCSI retries : 0x00
SCSI allowed : 0x03
SCSI scribble : 0x<inquiry2-req-id>
SCSI opcode : 12000000 a4000000 00000000 00000000
FCP rsp inf cod: 0x00
FCP rsp IU : 00000000 00000000 00000000 00000000

                 00000000 00000000

scsi 2:0:0:4630896905707208721: scsi scan: INQUIRY pass 2 length 164 scsi 2:0:0:4630896905707208721: scsi scan: INQUIRY successful with code 0x0 scsi 2:0:0:4630896905707208721: scsi scan: peripheral device type of 31, \
no device added

---
 drivers/s390/scsi/zfcp_dbf.c |    2 +-
 drivers/s390/scsi/zfcp_dbf.h |    4 +++-
 2 files changed, 4 insertions(+), 2 deletions(-)
drivers/s390/scsi/zfcp_dbf.c +1 -1
@@ -563,8 +563,8 @@ void zfcp_dbf_scsi(char *tag, int level,
 	rec->scsi_retries = sc->retries;
 	rec->scsi_allowed = sc->allowed;
 	rec->scsi_id = sc->device->id;
-	/* struct zfcp_dbf_scsi needs to be updated to handle 64bit LUNs */
 	rec->scsi_lun = (u32)sc->device->lun;
+	rec->scsi_lun_64_hi = (u32)(sc->device->lun >> 32);
 	rec->host_scribble = (unsigned long)sc->host_scribble;
 
 	memcpy(rec->scsi_opcode, sc->cmnd,
drivers/s390/scsi/zfcp_dbf.h +3 -1
@@ -204,7 +204,7 @@ enum zfcp_dbf_scsi_id {
  * @id: unique number of recovery record type
  * @tag: identifier string specifying the location of initiation
  * @scsi_id: scsi device id
- * @scsi_lun: scsi device logical unit number
+ * @scsi_lun: scsi device logical unit number, low part of 64 bit, old 32 bit
  * @scsi_result: scsi result
  * @scsi_retries: current retry number of scsi request
  * @scsi_allowed: allowed retries
@@ -214,6 +214,7 @@ enum zfcp_dbf_scsi_id {
  * @host_scribble: LLD specific data attached to SCSI request
  * @pl_len: length of paload stored as zfcp_dbf_pay
  * @fsf_rsp: response for fsf request
+ * @scsi_lun_64_hi: scsi device logical unit number, high part of 64 bit
  */
 struct zfcp_dbf_scsi {
 	u8 id;
@@ -230,6 +231,7 @@ struct zfcp_dbf_scsi {
 	u64 host_scribble;
 	u16 pl_len;
 	struct fcp_resp_with_ext fcp_rsp;
+	u32 scsi_lun_64_hi;
 } __packed;
 
 /**
author maintainer
#62 lore raw

PATCH 58/109 scsi: qedi: off by one in qedi_get_cmd_from_tid()

In reply to Greg Kroah-Hartman

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

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

From: Dan Carpenter <[email protected]>

commit fa2d9d6e894e096678a50ef0f65f7a8c3d8a40b8 upstream.

The > here should be >= or we end up reading one element beyond the end of the qedi->itt_map[] array. The qedi->itt_map[] array is allocated in qedi_alloc_itt().

Fixes ace7f46ba5fd ("scsi: qedi: Add QLogic FastLinQ offload iSCSI driver framework.")
---
 drivers/scsi/qedi/qedi_main.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/qedi/qedi_main.c +1 -1
@@ -1575,7 +1575,7 @@ struct qedi_cmd *qedi_get_cmd_from_tid(s
 {
 	struct qedi_cmd *cmd = NULL;
 
-	if (tid > MAX_ISCSI_TASK_ENTRIES)
+	if (tid >= MAX_ISCSI_TASK_ENTRIES)
 		return NULL;
 
 	cmd = qedi->itt_map[tid].p_cmd;
author maintainer
#70 lore raw

PATCH 66/109 scsi: sg: fixup infoleak when using SG_GET_REQUEST_TABLE

In reply to Greg Kroah-Hartman

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

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

From: Hannes Reinecke <[email protected]>

commit 3e0097499839e0fe3af380410eababe5a47c4cf9 upstream.

When calling SG_GET_REQUEST_TABLE ioctl only a half-filled table is returned; the remaining part will then contain stale kernel memory information. This patch zeroes out the entire table to avoid this issue.

---
 drivers/scsi/sg.c |    5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/scsi/sg.c +2 -3
@@ -839,7 +839,6 @@ sg_fill_request_table(Sg_fd *sfp, sg_req
 	list_for_each_entry(srp, &sfp->rq_list, entry) {
 		if (val > SG_MAX_QUEUE)
 			break;
-		memset(&rinfo[val], 0, SZ_SG_REQ_INFO);
 		rinfo[val].req_state = srp->done + 1;
 		rinfo[val].problem =
 			srp->header.masked_status &
@@ -1047,8 +1046,8 @@ sg_ioctl(struct file *filp, unsigned int
 		else {
 			sg_req_info_t *rinfo;
 
-			rinfo = kmalloc(SZ_SG_REQ_INFO * SG_MAX_QUEUE,
-								GFP_KERNEL);
+			rinfo = kzalloc(SZ_SG_REQ_INFO * SG_MAX_QUEUE,
+					GFP_KERNEL);
 			if (!rinfo)
 				return -ENOMEM;
 			read_lock_irqsave(&sfp->rq_list_lock, iflags);
author maintainer
#71 lore raw

PATCH 67/109 scsi: qla2xxx: Update fw_started flags at qpair creation.

In reply to Greg Kroah-Hartman

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

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

From: [email protected] <[email protected]>

commit e6373f33a6bba0de9f543f4a7faeaaa536c62997 upstream.

Fixes 4b60c82736d0 ("scsi: qla2xxx: Add fw_started flags to qpair")
---
 drivers/scsi/qla2xxx/qla_init.c |    1 +
 1 file changed, 1 insertion(+)
drivers/scsi/qla2xxx/qla_init.c +1 -0
@@ -7804,6 +7804,7 @@ struct qla_qpair *qla2xxx_create_qpair(s
 		ha->queue_pair_map[qpair_id] = qpair;
 		qpair->id = qpair_id;
 		qpair->vp_idx = vp_idx;
+		qpair->fw_started = ha->flags.fw_started;
 		INIT_LIST_HEAD(&qpair->hints_list);
 		qpair->chip_reset = ha->base_qpair->chip_reset;
 		qpair->enable_class_2 = ha->base_qpair->enable_class_2;
author maintainer
#87 lore raw

PATCH 83/109 net/netfilter/nf_conntrack_core: Fix net_conntrack_lock()

In reply to Greg Kroah-Hartman

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

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

From: Manfred Spraul <[email protected]>

commit 3ef0c7a730de0bae03d86c19570af764fa3c4445 upstream.

As we want to remove spin_unlock_wait() and replace it with explicit spin_lock()/spin_unlock() calls, we can use this to simplify the locking.

In addition:
- Reading nf_conntrack_locks_all needs ACQUIRE memory ordering.
- The new code avoids the backwards loop.

Only slightly tested, I did not manage to trigger calls to nf_conntrack_all_lock().

V2: With improved comments, to clearly show how the barriers
pair.

Fixes b16c29191dc8 ("netfilter: nf_conntrack: use safer way to lock all buckets")
Cc Alan Stern <[email protected]>
Cc Sasha Levin <[email protected]>
Cc Pablo Neira Ayuso <[email protected]>
---
 net/netfilter/nf_conntrack_core.c |   52 +++++++++++++++++++++-----------------
 1 file changed, 29 insertions(+), 23 deletions(-)
net/netfilter/nf_conntrack_core.c +29 -23
@@ -96,19 +96,26 @@ static struct conntrack_gc_work conntrac
 
 void nf_conntrack_lock(spinlock_t *lock) __acquires(lock)
 {
+	/* 1) Acquire the lock */
 	spin_lock(lock);
-	while (unlikely(nf_conntrack_locks_all)) {
-		spin_unlock(lock);
 
-		/*
-		 * Order the 'nf_conntrack_locks_all' load vs. the
-		 * spin_unlock_wait() loads below, to ensure
-		 * that 'nf_conntrack_locks_all_lock' is indeed held:
-		 */
-		smp_rmb(); /* spin_lock(&nf_conntrack_locks_all_lock) */
-		spin_unlock_wait(&nf_conntrack_locks_all_lock);
-		spin_lock(lock);
-	}
+	/* 2) read nf_conntrack_locks_all, with ACQUIRE semantics
+	 * It pairs with the smp_store_release() in nf_conntrack_all_unlock()
+	 */
+	if (likely(smp_load_acquire(&nf_conntrack_locks_all) == false))
+		return;
+
+	/* fast path failed, unlock */
+	spin_unlock(lock);
+
+	/* Slow path 1) get global lock */
+	spin_lock(&nf_conntrack_locks_all_lock);
+
+	/* Slow path 2) get the lock we want */
+	spin_lock(lock);
+
+	/* Slow path 3) release the global lock */
+	spin_unlock(&nf_conntrack_locks_all_lock);
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_lock);
 
@@ -149,28 +156,27 @@ static void nf_conntrack_all_lock(void)
 	int i;
 
 	spin_lock(&nf_conntrack_locks_all_lock);
-	nf_conntrack_locks_all = true;
 
-	/*
-	 * Order the above store of 'nf_conntrack_locks_all' against
-	 * the spin_unlock_wait() loads below, such that if
-	 * nf_conntrack_lock() observes 'nf_conntrack_locks_all'
-	 * we must observe nf_conntrack_locks[] held:
-	 */
-	smp_mb(); /* spin_lock(&nf_conntrack_locks_all_lock) */
+	nf_conntrack_locks_all = true;
 
 	for (i = 0; i < CONNTRACK_LOCKS; i++) {
-		spin_unlock_wait(&nf_conntrack_locks[i]);
+		spin_lock(&nf_conntrack_locks[i]);
+
+		/* This spin_unlock provides the "release" to ensure that
+		 * nf_conntrack_locks_all==true is visible to everyone that
+		 * acquired spin_lock(&nf_conntrack_locks[]).
+		 */
+		spin_unlock(&nf_conntrack_locks[i]);
 	}
 }
 
 static void nf_conntrack_all_unlock(void)
 {
-	/*
-	 * All prior stores must be complete before we clear
+	/* All prior stores must be complete before we clear
 	 * 'nf_conntrack_locks_all'. Otherwise nf_conntrack_lock()
 	 * might observe the false value but not the entire
-	 * critical section:
+	 * critical section.
+	 * It pairs with the smp_load_acquire() in nf_conntrack_lock()
 	 */
 	smp_store_release(&nf_conntrack_locks_all, false);
 	spin_unlock(&nf_conntrack_locks_all_lock);
author maintainer
#93 lore raw

PATCH 89/109 media: uvcvideo: Prevent heap overflow when accessing mapped controls

In reply to Greg Kroah-Hartman

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

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

From: Guenter Roeck <[email protected]>

commit 7e09f7d5c790278ab98e5f2c22307ebe8ad6e8ba upstream.

The size of uvc_control_mapping is user controlled leading to a potential heap overflow in the uvc driver. This adds a check to verify the user provided size fits within the bounds of the defined buffer size.

Originally-from: Richard Simmons <[email protected]>

---
 drivers/media/usb/uvc/uvc_ctrl.c |    7 +++++++
 1 file changed, 7 insertions(+)
drivers/media/usb/uvc/uvc_ctrl.c +7 -0
@@ -2002,6 +2002,13 @@ int uvc_ctrl_add_mapping(struct uvc_vide
 		goto done;
 	}
 
+	/* Validate the user-provided bit-size and offset */
+	if (mapping->size > 32 ||
+	    mapping->offset + mapping->size > ctrl->info.size * 8) {
+		ret = -EINVAL;
+		goto done;
+	}
+
 	list_for_each_entry(map, &ctrl->info.mappings, list) {
 		if (mapping->id == map->id) {
 			uvc_trace(UVC_TRACE_CONTROL, "Can't add mapping '%s', "
author maintainer
#106 lore raw

PATCH 103/109 mac80211: fix VLAN handling with TXQs

In reply to Greg Kroah-Hartman

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

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

From: Johannes Berg <[email protected]>

commit 53168215909281a09d3afc6fb51a9d4f81f74d39 upstream.

With TXQs, the AP_VLAN interfaces are resolved to their owner AP interface when enqueuing the frame, which makes sense since the frame really goes out on that as far as the driver is concerned.

However, this introduces a problem: frames to be encrypted with a VLAN-specific GTK will now be encrypted with the AP GTK, since the information about which virtual interface to use to select the key is taken from the TXQ.

Fix this by preserving info->control.vif and using that in the dequeue function. This now requires doing the driver-mapping in the dequeue as well.

Since there's no way to filter the frames that are sitting on a TXQ, drop all frames, which may affect other interfaces, when an AP_VLAN is removed.

---
 include/net/mac80211.h |   15 ++-------------
 net/mac80211/iface.c   |   17 +++++++++++++++--
 net/mac80211/tx.c      |   36 +++++++++++++++++++++++++++++-------
 3 files changed, 46 insertions(+), 22 deletions(-)
include/net/mac80211.h +2 -13
@@ -919,21 +919,10 @@ struct ieee80211_tx_info {
 				unsigned long jiffies;
 			};
 			/* NB: vif can be NULL for injected frames */
-			union {
-				/* NB: vif can be NULL for injected frames */
-				struct ieee80211_vif *vif;
-
-				/* When packets are enqueued on txq it's easy
-				 * to re-construct the vif pointer. There's no
-				 * more space in tx_info so it can be used to
-				 * store the necessary enqueue time for packet
-				 * sojourn time computation.
-				 */
-				codel_time_t enqueue_time;
-			};
+			struct ieee80211_vif *vif;
 			struct ieee80211_key_conf *hw_key;
 			u32 flags;
-			/* 4 bytes free */
+			codel_time_t enqueue_time;
 		} control;
 		struct {
 			u64 cookie;
net/mac80211/iface.c +15 -2
@@ -792,6 +792,7 @@ static int ieee80211_open(struct net_dev
 static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
 			      bool going_down)
 {
+	struct ieee80211_sub_if_data *txq_sdata = sdata;
 	struct ieee80211_local *local = sdata->local;
 	struct fq *fq = &local->fq;
 	unsigned long flags;
@@ -937,6 +938,9 @@ static void ieee80211_do_stop(struct iee
 
 	switch (sdata->vif.type) {
 	case NL80211_IFTYPE_AP_VLAN:
+		txq_sdata = container_of(sdata->bss,
+					 struct ieee80211_sub_if_data, u.ap);
+
 		mutex_lock(&local->mtx);
 		list_del(&sdata->u.vlan.list);
 		mutex_unlock(&local->mtx);
@@ -1007,8 +1011,17 @@ static void ieee80211_do_stop(struct iee
 	}
 	spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
 
-	if (sdata->vif.txq) {
-		struct txq_info *txqi = to_txq_info(sdata->vif.txq);
+	if (txq_sdata->vif.txq) {
+		struct txq_info *txqi = to_txq_info(txq_sdata->vif.txq);
+
+		/*
+		 * FIXME FIXME
+		 *
+		 * We really shouldn't purge the *entire* txqi since that
+		 * contains frames for the other AP_VLANs (and possibly
+		 * the AP itself) as well, but there's no API in FQ now
+		 * to be able to filter.
+		 */
 
 		spin_lock_bh(&fq->lock);
 		ieee80211_txq_purge(local, txqi);
net/mac80211/tx.c +29 -7
@@ -1276,11 +1276,6 @@ static void ieee80211_set_skb_enqueue_ti
 	IEEE80211_SKB_CB(skb)->control.enqueue_time = codel_get_time();
 }
 
-static void ieee80211_set_skb_vif(struct sk_buff *skb, struct txq_info *txqi)
-{
-	IEEE80211_SKB_CB(skb)->control.vif = txqi->txq.vif;
-}
-
 static u32 codel_skb_len_func(const struct sk_buff *skb)
 {
 	return skb->len;
@@ -3414,6 +3409,7 @@ struct sk_buff *ieee80211_tx_dequeue(str
 	struct ieee80211_tx_info *info;
 	struct ieee80211_tx_data tx;
 	ieee80211_tx_result r;
+	struct ieee80211_vif *vif;
 
 	spin_lock_bh(&fq->lock);
 
@@ -3430,8 +3426,6 @@ begin:
 	if (!skb)
 		goto out;
 
-	ieee80211_set_skb_vif(skb, txqi);
-
 	hdr = (struct ieee80211_hdr *)skb->data;
 	info = IEEE80211_SKB_CB(skb);
 
@@ -3488,6 +3482,34 @@ begin:
 		}
 	}
 
+	switch (tx.sdata->vif.type) {
+	case NL80211_IFTYPE_MONITOR:
+		if (tx.sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) {
+			vif = &tx.sdata->vif;
+			break;
+		}
+		tx.sdata = rcu_dereference(local->monitor_sdata);
+		if (tx.sdata) {
+			vif = &tx.sdata->vif;
+			info->hw_queue =
+				vif->hw_queue[skb_get_queue_mapping(skb)];
+		} else if (ieee80211_hw_check(&local->hw, QUEUE_CONTROL)) {
+			ieee80211_free_txskb(&local->hw, skb);
+			goto begin;
+		} else {
+			vif = NULL;
+		}
+		break;
+	case NL80211_IFTYPE_AP_VLAN:
+		tx.sdata = container_of(tx.sdata->bss,
+					struct ieee80211_sub_if_data, u.ap);
+		/* fall through */
+	default:
+		vif = &tx.sdata->vif;
+		break;
+	}
+
+	IEEE80211_SKB_CB(skb)->control.vif = vif;
 out:
 	spin_unlock_bh(&fq->lock);
 
author maintainer
#107 lore raw

PATCH 104/109 mac80211_hwsim: Use proper TX power

In reply to Greg Kroah-Hartman

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

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

From: Beni Lev <[email protected]>

commit 9de981f507474f326e42117858dc9a9321331ae5 upstream.

In struct ieee80211_tx_info, control.vif pointer and rate_driver_data[0] falls on the same place, depending on the union usage.
During the whole TX process, the union is referred to as a control struct, which holds the vif that is later used in the tx flow, especially in order to derive the used tx power.
Referring direcly to rate_driver_data[0] and assigning a value to it, overwrites the vif pointer, hence making all later references irrelevant. Moreover, rate_driver_data[0] isn't used later in the flow in order to retrieve the channel that it is pointing to.

---
 drivers/net/wireless/mac80211_hwsim.c |    2 --
 1 file changed, 2 deletions(-)
drivers/net/wireless/mac80211_hwsim.c +0 -2
@@ -1362,8 +1362,6 @@ static void mac80211_hwsim_tx(struct iee
 				       txi->control.rates,
 				       ARRAY_SIZE(txi->control.rates));
 
-	txi->rate_driver_data[0] = channel;
-
 	if (skb->len >= 24 + 8 &&
 	    ieee80211_is_probe_resp(hdr->frame_control)) {
 		/* fake header transmission time */
author maintainer
#109 lore raw

PATCH 106/109 mac80211: fix deadlock in driver-managed RX BA session start

In reply to Greg Kroah-Hartman

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

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

From: Johannes Berg <[email protected]>

commit bde59c475e0883e4c4294bcd9b9c7e08ae18c828 upstream.

When an RX BA session is started by the driver, and it has to tell mac80211 about it, the corresponding bit in tid_rx_manage_offl gets set and the BA session work is scheduled. Upon testing this bit, it will call __ieee80211_start_rx_ba_session(), thus deadlocking as it already holds the ampdu_mlme.mtx, which that acquires again.

Fix this by adding ___ieee80211_start_rx_ba_session(), a version of the function that requires the mutex already held.

Fixes 699cb58c8a52 ("mac80211: manage RX BA session offload without SKB queue")
---
 net/mac80211/agg-rx.c      |   32 +++++++++++++++++++++-----------
 net/mac80211/ht.c          |    6 +++---
 net/mac80211/ieee80211_i.h |    4 ++++
 3 files changed, 28 insertions(+), 14 deletions(-)
net/mac80211/agg-rx.c +21 -11
@@ -245,10 +245,10 @@ static void ieee80211_send_addba_resp(st
 	ieee80211_tx_skb(sdata, skb);
 }
 
-void __ieee80211_start_rx_ba_session(struct sta_info *sta,
-				     u8 dialog_token, u16 timeout,
-				     u16 start_seq_num, u16 ba_policy, u16 tid,
-				     u16 buf_size, bool tx, bool auto_seq)
+void ___ieee80211_start_rx_ba_session(struct sta_info *sta,
+				      u8 dialog_token, u16 timeout,
+				      u16 start_seq_num, u16 ba_policy, u16 tid,
+				      u16 buf_size, bool tx, bool auto_seq)
 {
 	struct ieee80211_local *local = sta->sdata->local;
 	struct tid_ampdu_rx *tid_agg_rx;
@@ -267,7 +267,7 @@ void __ieee80211_start_rx_ba_session(str
 		ht_dbg(sta->sdata,
 		       "STA %pM requests BA session on unsupported tid %d\n",
 		       sta->sta.addr, tid);
-		goto end_no_lock;
+		goto end;
 	}
 
 	if (!sta->sta.ht_cap.ht_supported) {
@@ -275,14 +275,14 @@ void __ieee80211_start_rx_ba_session(str
 		       "STA %pM erroneously requests BA session on tid %d w/o QoS\n",
 		       sta->sta.addr, tid);
 		/* send a response anyway, it's an error case if we get here */
-		goto end_no_lock;
+		goto end;
 	}
 
 	if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) {
 		ht_dbg(sta->sdata,
 		       "Suspend in progress - Denying ADDBA request (%pM tid %d)\n",
 		       sta->sta.addr, tid);
-		goto end_no_lock;
+		goto end;
 	}
 
 	/* sanity check for incoming parameters:
@@ -296,7 +296,7 @@ void __ieee80211_start_rx_ba_session(str
 		ht_dbg_ratelimited(sta->sdata,
 				   "AddBA Req with bad params from %pM on tid %u. policy %d, buffer size %d\n",
 				   sta->sta.addr, tid, ba_policy, buf_size);
-		goto end_no_lock;
+		goto end;
 	}
 	/* determine default buffer size */
 	if (buf_size == 0)
@@ -311,7 +311,7 @@ void __ieee80211_start_rx_ba_session(str
 	       buf_size, sta->sta.addr);
 
 	/* examine state machine */
-	mutex_lock(&sta->ampdu_mlme.mtx);
+	lockdep_assert_held(&sta->ampdu_mlme.mtx);
 
 	if (test_bit(tid, sta->ampdu_mlme.agg_session_valid)) {
 		if (sta->ampdu_mlme.tid_rx_token[tid] == dialog_token) {
@@ -415,15 +415,25 @@ end:
 		__clear_bit(tid, sta->ampdu_mlme.unexpected_agg);
 		sta->ampdu_mlme.tid_rx_token[tid] = dialog_token;
 	}
-	mutex_unlock(&sta->ampdu_mlme.mtx);
 
-end_no_lock:
 	if (tx)
 		ieee80211_send_addba_resp(sta->sdata, sta->sta.addr, tid,
 					  dialog_token, status, 1, buf_size,
 					  timeout);
 }
 
+void __ieee80211_start_rx_ba_session(struct sta_info *sta,
+				     u8 dialog_token, u16 timeout,
+				     u16 start_seq_num, u16 ba_policy, u16 tid,
+				     u16 buf_size, bool tx, bool auto_seq)
+{
+	mutex_lock(&sta->ampdu_mlme.mtx);
+	___ieee80211_start_rx_ba_session(sta, dialog_token, timeout,
+					 start_seq_num, ba_policy, tid,
+					 buf_size, tx, auto_seq);
+	mutex_unlock(&sta->ampdu_mlme.mtx);
+}
+
 void ieee80211_process_addba_request(struct ieee80211_local *local,
 				     struct sta_info *sta,
 				     struct ieee80211_mgmt *mgmt,
net/mac80211/ht.c +3 -3
@@ -333,9 +333,9 @@ void ieee80211_ba_session_work(struct wo
 
 		if (test_and_clear_bit(tid,
 				       sta->ampdu_mlme.tid_rx_manage_offl))
-			__ieee80211_start_rx_ba_session(sta, 0, 0, 0, 1, tid,
-							IEEE80211_MAX_AMPDU_BUF,
-							false, true);
+			___ieee80211_start_rx_ba_session(sta, 0, 0, 0, 1, tid,
+							 IEEE80211_MAX_AMPDU_BUF,
+							 false, true);
 
 		if (test_and_clear_bit(tid + IEEE80211_NUM_TIDS,
 				       sta->ampdu_mlme.tid_rx_manage_offl))
net/mac80211/ieee80211_i.h +4 -0
@@ -1760,6 +1760,10 @@ void __ieee80211_start_rx_ba_session(str
 				     u8 dialog_token, u16 timeout,
 				     u16 start_seq_num, u16 ba_policy, u16 tid,
 				     u16 buf_size, bool tx, bool auto_seq);
+void ___ieee80211_start_rx_ba_session(struct sta_info *sta,
+				      u8 dialog_token, u16 timeout,
+				      u16 start_seq_num, u16 ba_policy, u16 tid,
+				      u16 buf_size, bool tx, bool auto_seq);
 void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta,
 					 enum ieee80211_agg_stop_reason reason);
 void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
author maintainer
#1 lore raw

PATCH 1/109 orangefs: Dont clear SGID when inheriting ACLs

In reply to Greg Kroah-Hartman

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

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

From: Jan Kara <[email protected]>

commit b5accbb0dfae36d8d36cd882096943c98d5ede15 upstream.

When new directory 'DIR1' is created in a directory 'DIR0' with SGID bit set, DIR1 is expected to have SGID bit set (and owning group equal to the owning group of 'DIR0'). However when 'DIR0' also has some default ACLs that 'DIR1' inherits, setting these ACLs will result in SGID bit on 'DIR1' to get cleared if user is not member of the owning group.

Fix the problem by creating __orangefs_set_acl() function that does not call posix_acl_update_mode() and use it when inheriting ACLs. That prevents SGID bit clearing and the mode has been properly set by posix_acl_create() anyway.

Fixes 073931017b49d9458aa351605b43a7e34598caef
CC Mike Marshall <[email protected]>
---
 fs/orangefs/acl.c |   48 ++++++++++++++++++++++++++++--------------------
 1 file changed, 28 insertions(+), 20 deletions(-)
fs/orangefs/acl.c +28 -20
@@ -61,9 +61,9 @@ struct posix_acl *orangefs_get_acl(struc
 	return acl;
 }
 
-int orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
+static int __orangefs_set_acl(struct inode *inode, struct posix_acl *acl,
+			      int type)
 {
-	struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
 	int error = 0;
 	void *value = NULL;
 	size_t size = 0;
@@ -72,22 +72,6 @@ int orangefs_set_acl(struct inode *inode
 	switch (type) {
 	case ACL_TYPE_ACCESS:
 		name = XATTR_NAME_POSIX_ACL_ACCESS;
-		if (acl) {
-			umode_t mode;
-
-			error = posix_acl_update_mode(inode, &mode, &acl);
-			if (error) {
-				gossip_err("%s: posix_acl_update_mode err: %d\n",
-					   __func__,
-					   error);
-				return error;
-			}
-
-			if (inode->i_mode != mode)
-				SetModeFlag(orangefs_inode);
-			inode->i_mode = mode;
-			mark_inode_dirty_sync(inode);
-		}
 		break;
 	case ACL_TYPE_DEFAULT:
 		name = XATTR_NAME_POSIX_ACL_DEFAULT;
@@ -132,6 +116,29 @@ out:
 	return error;
 }
 
+int orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
+{
+	int error;
+
+	if (type == ACL_TYPE_ACCESS && acl) {
+		umode_t mode;
+
+		error = posix_acl_update_mode(inode, &mode, &acl);
+		if (error) {
+			gossip_err("%s: posix_acl_update_mode err: %d\n",
+				   __func__,
+				   error);
+			return error;
+		}
+
+		if (inode->i_mode != mode)
+			SetModeFlag(ORANGEFS_I(inode));
+		inode->i_mode = mode;
+		mark_inode_dirty_sync(inode);
+	}
+	return __orangefs_set_acl(inode, acl, type);
+}
+
 int orangefs_init_acl(struct inode *inode, struct inode *dir)
 {
 	struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
@@ -146,13 +153,14 @@ int orangefs_init_acl(struct inode *inod
 		return error;
 
 	if (default_acl) {
-		error = orangefs_set_acl(inode, default_acl, ACL_TYPE_DEFAULT);
+		error = __orangefs_set_acl(inode, default_acl,
+					   ACL_TYPE_DEFAULT);
 		posix_acl_release(default_acl);
 	}
 
 	if (acl) {
 		if (!error)
-			error = orangefs_set_acl(inode, acl, ACL_TYPE_ACCESS);
+			error = __orangefs_set_acl(inode, acl, ACL_TYPE_ACCESS);
 		posix_acl_release(acl);
 	}
 
author maintainer
#11 lore raw

PATCH 10/109 tty: improve tty_insert_flip_char() fast path

In reply to Greg Kroah-Hartman

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

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

From: Arnd Bergmann <[email protected]>

commit 979990c6284814617d8f2179d197f72ff62b5d85 upstream.

kernelci.org reports a crazy stack usage for the VT code when CONFIG_KASAN is enabled:

drivers/tty/vt/keyboard.c: In function 'kbd_keycode':
drivers/tty/vt/keyboard.c:1452:1: error: the frame size of 2240 bytes is larger than 2048 bytes [-Werror=frame-larger-than=]

The problem is that tty_insert_flip_char() gets inlined many times into kbd_keycode(), and also into other functions, and each copy requires 128 bytes for stack redzone to check for a possible out-of-bounds access on the 'ch' and 'flags' arguments that are passed into tty_insert_flip_string_flags as a variable-length string.

This introduces a new __tty_insert_flip_char() function for the slow path, which receives the two arguments by value. This completely avoids the problem and the stack usage goes back down to around 100 bytes.

Without KASAN, this is also slightly better, as we don't have to spill the arguments to the stack but can simply pass 'ch' and 'flag' in registers, saving a few bytes in .text for each call site.

This should be backported to linux-4.0 or later, which first introduced the stack sanitizer in the kernel.

Fixes c420f167db8c ("kasan: enable stack instrumentation")
---
 drivers/tty/tty_buffer.c |   24 ++++++++++++++++++++++++
 include/linux/tty_flip.h |    3 ++-
 2 files changed, 26 insertions(+), 1 deletion(-)
drivers/tty/tty_buffer.c +24 -0
@@ -362,6 +362,30 @@ int tty_insert_flip_string_flags(struct
 EXPORT_SYMBOL(tty_insert_flip_string_flags);
 
 /**
+ *	__tty_insert_flip_char   -	Add one character to the tty buffer
+ *	@port: tty port
+ *	@ch: character
+ *	@flag: flag byte
+ *
+ *	Queue a single byte to the tty buffering, with an optional flag.
+ *	This is the slow path of tty_insert_flip_char.
+ */
+int __tty_insert_flip_char(struct tty_port *port, unsigned char ch, char flag)
+{
+	struct tty_buffer *tb = port->buf.tail;
+	int flags = (flag == TTY_NORMAL) ? TTYB_NORMAL : 0;
+
+	if (!tty_buffer_request_room(port, 1))
+		return 0;
+
+	*flag_buf_ptr(tb, tb->used) = flag;
+	*char_buf_ptr(tb, tb->used++) = ch;
+
+	return 1;
+}
+EXPORT_SYMBOL(__tty_insert_flip_char);
+
+/**
  *	tty_schedule_flip	-	push characters to ldisc
  *	@port: tty port to push from
  *
include/linux/tty_flip.h +2 -1
@@ -12,6 +12,7 @@ extern int tty_prepare_flip_string(struc
 		unsigned char **chars, size_t size);
 extern void tty_flip_buffer_push(struct tty_port *port);
 void tty_schedule_flip(struct tty_port *port);
+int __tty_insert_flip_char(struct tty_port *port, unsigned char ch, char flag);
 
 static inline int tty_insert_flip_char(struct tty_port *port,
 					unsigned char ch, char flag)
@@ -26,7 +27,7 @@ static inline int tty_insert_flip_char(s
 		*char_buf_ptr(tb, tb->used++) = ch;
 		return 1;
 	}
-	return tty_insert_flip_string_flags(port, &ch, &flag, 1);
+	return __tty_insert_flip_char(port, ch, flag);
 }
 
 static inline int tty_insert_flip_string(struct tty_port *port,
author maintainer
#12 lore raw

PATCH 11/109 tty: improve tty_insert_flip_char() slow path

In reply to Greg Kroah-Hartman

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

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

From: Arnd Bergmann <[email protected]>

commit 065ea0a7afd64d6cf3464bdd1d8cd227527e2045 upstream.

While working on improving the fast path of tty_insert_flip_char(), I noticed that by calling tty_buffer_request_room(), we needlessly move to the separate flag buffer mode for the tty, even when all characters use TTY_NORMAL as the flag.

This changes the code to call __tty_buffer_request_room() with the correct flag, which will then allocate a regular buffer when it rounds out of space but no special flags have been used. I'm guessing that this is the behavior that Peter Hurley intended when he introduced the compacted flip buffers.

Fixes acc0f67f307f ("tty: Halve flip buffer GFP_ATOMIC memory consumption")
Cc Peter Hurley <[email protected]>
---
 drivers/tty/tty_buffer.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/tty/tty_buffer.c +3 -2
@@ -375,10 +375,11 @@ int __tty_insert_flip_char(struct tty_po
 	struct tty_buffer *tb = port->buf.tail;
 	int flags = (flag == TTY_NORMAL) ? TTYB_NORMAL : 0;
 
-	if (!tty_buffer_request_room(port, 1))
+	if (!__tty_buffer_request_room(port, 1, flags))
 		return 0;
 
-	*flag_buf_ptr(tb, tb->used) = flag;
+	if (~tb->flags & TTYB_NORMAL)
+		*flag_buf_ptr(tb, tb->used) = flag;
 	*char_buf_ptr(tb, tb->used++) = ch;
 
 	return 1;
author maintainer
#13 lore raw

PATCH 12/109 tty: fix __tty_insert_flip_char regression

In reply to Greg Kroah-Hartman

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

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

From: Arnd Bergmann <[email protected]>

commit 8a5a90a2a477b86a3dc2eaa5a706db9bfdd647ca upstream.

Sergey noticed a small but fatal mistake in __tty_insert_flip_char, leading to an oops in an interrupt handler when using any serial port.

The problem is that I accidentally took the tty_buffer pointer before calling __tty_buffer_request_room(), which replaces the buffer. This moves the pointer lookup to the right place after allocating the new buffer space.

Fixes 979990c62848 ("tty: improve tty_insert_flip_char() fast path")
---
 drivers/tty/tty_buffer.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/tty/tty_buffer.c +2 -1
@@ -372,12 +372,13 @@ EXPORT_SYMBOL(tty_insert_flip_string_fla
  */
 int __tty_insert_flip_char(struct tty_port *port, unsigned char ch, char flag)
 {
-	struct tty_buffer *tb = port->buf.tail;
+	struct tty_buffer *tb;
 	int flags = (flag == TTY_NORMAL) ? TTYB_NORMAL : 0;
 
 	if (!__tty_buffer_request_room(port, 1, flags))
 		return 0;
 
+	tb = port->buf.tail;
 	if (~tb->flags & TTYB_NORMAL)
 		*flag_buf_ptr(tb, tb->used) = flag;
 	*char_buf_ptr(tb, tb->used++) = ch;
author maintainer
#14 lore raw

PATCH 13/109 pinctrl: samsung: Fix invalid register offset used for Exynos5433 external interrupts

In reply to Greg Kroah-Hartman

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

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

From: Krzysztof Kozlowski <[email protected]>

commit af0b0baa89953aed07034725023371b2fa50a1e6 upstream.

When setting the pin function for external interrupts, the driver used wrong IO memory address base. The pin function register is always under pctl_base, not the eint_base.

By updating wrong register, the external interrupts for chosen GPIO would not work at all and some other GPIO might be configured to wrong value. For example on Exynos5433-based boards, the external interrupts for gpf{1-5}-X GPIOs should not work at all (driver toggled reserved registers from ALIVE bank instead).

Platforms other than Exynos5433 should not be affected as eint_base equals pctl_base in such case.

Fixes 8b1bd11c1f8f ("pinctrl: samsung: Add the support the multiple IORESOURCE_MEM for one pin-bank")
---
 drivers/pinctrl/samsung/pinctrl-exynos.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/pinctrl/samsung/pinctrl-exynos.c +4 -4
@@ -174,10 +174,10 @@ static int exynos_irq_request_resources(
 
 	spin_lock_irqsave(&bank->slock, flags);
 
-	con = readl(bank->eint_base + reg_con);
+	con = readl(bank->pctl_base + reg_con);
 	con &= ~(mask << shift);
 	con |= EXYNOS_EINT_FUNC << shift;
-	writel(con, bank->eint_base + reg_con);
+	writel(con, bank->pctl_base + reg_con);
 
 	spin_unlock_irqrestore(&bank->slock, flags);
 
@@ -202,10 +202,10 @@ static void exynos_irq_release_resources
 
 	spin_lock_irqsave(&bank->slock, flags);
 
-	con = readl(bank->eint_base + reg_con);
+	con = readl(bank->pctl_base + reg_con);
 	con &= ~(mask << shift);
 	con |= FUNC_INPUT << shift;
-	writel(con, bank->eint_base + reg_con);
+	writel(con, bank->pctl_base + reg_con);
 
 	spin_unlock_irqrestore(&bank->slock, flags);
 
author maintainer
#15 lore raw

PATCH 14/109 pinctrl: samsung: Fix NULL pointer exception on external interrupts on S3C24xx

In reply to Greg Kroah-Hartman

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

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

From: Krzysztof Kozlowski <[email protected]>

commit cee7413d84044a0c1919a7c70a2d761ae24390de upstream.

After commit 8b1bd11c1f8f ("pinctrl: samsung: Add the support the multiple IORESOURCE_MEM for one pin-bank"), the S3C24xx (and probably S3C64xx as well) fails:

	Unable to handle kernel NULL pointer dereference at virtual address 000000a8
	...
	(s3c24xx_demux_eint4_7) from [<c004469c>] (__handle_domain_irq+0x6c/0xcc)
	(__handle_domain_irq) from [<c0009444>] (s3c24xx_handle_irq+0x6c/0x12c)
	(s3c24xx_handle_irq) from [<c000e5fc>] (__irq_svc+0x5c/0x78)

Mentioned commit moved the pointer to controller's base IO memory address from each controller's driver data (samsung_pinctrl_drv_data) to per-bank structure (samsung_pin_bank). The external interrupt demux handlers (s3c24xx_demux_eint()) tried to get this base address from opaque pointer stored under irq_chip data:

	struct irq_data *irqd = irq_desc_get_irq_data(desc);
	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
	...
	pend = readl(bank->eint_base + EINTPEND_REG);

which is wrong because this is hardware irq and it bank was never set for this irq_chip.

For S3C24xx and S3C64xx, this partially reverts mentioned commit by bringing back the virt_base stored under each controller's driver data (samsung_pinctrl_drv_data). This virt_base address will be now duplicated:
- samsung_pinctrl_drv_data->virt_base: used on S3C24xx and S3C64xx,
- samsung_pin_bank->pctl_base: used on Exynos.

Fixes 8b1bd11c1f8f ("pinctrl: samsung: Add the support the multiple IORESOURCE_MEM for one pin-bank")
Cc Sergio Prado <[email protected]>
---
 drivers/pinctrl/samsung/pinctrl-s3c24xx.c |   37 +++++++++++++++------------
 drivers/pinctrl/samsung/pinctrl-s3c64xx.c |   40 +++++++++++++-----------------
 drivers/pinctrl/samsung/pinctrl-samsung.c |    6 ++++
 drivers/pinctrl/samsung/pinctrl-samsung.h |    5 +++
 4 files changed, 50 insertions(+), 38 deletions(-)
drivers/pinctrl/samsung/pinctrl-s3c24xx.c +21 -16
@@ -151,7 +151,7 @@ static void s3c24xx_eint_set_function(st
 	u32 val;
 
 	/* Make sure that pin is configured as interrupt */
-	reg = bank->pctl_base + bank->pctl_offset;
+	reg = d->virt_base + bank->pctl_offset;
 	shift = pin * bank_type->fld_width[PINCFG_TYPE_FUNC];
 	mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1;
 
@@ -184,7 +184,7 @@ static int s3c24xx_eint_type(struct irq_
 	s3c24xx_eint_set_handler(data, type);
 
 	/* Set up interrupt trigger */
-	reg = bank->eint_base + EINT_REG(index);
+	reg = d->virt_base + EINT_REG(index);
 	shift = EINT_OFFS(index);
 
 	val = readl(reg);
@@ -259,29 +259,32 @@ static void s3c2410_demux_eint0_3(struct
 static void s3c2412_eint0_3_ack(struct irq_data *data)
 {
 	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
+	struct samsung_pinctrl_drv_data *d = bank->drvdata;
 
 	unsigned long bitval = 1UL << data->hwirq;
-	writel(bitval, bank->eint_base + EINTPEND_REG);
+	writel(bitval, d->virt_base + EINTPEND_REG);
 }
 
 static void s3c2412_eint0_3_mask(struct irq_data *data)
 {
 	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
+	struct samsung_pinctrl_drv_data *d = bank->drvdata;
 	unsigned long mask;
 
-	mask = readl(bank->eint_base + EINTMASK_REG);
+	mask = readl(d->virt_base + EINTMASK_REG);
 	mask |= (1UL << data->hwirq);
-	writel(mask, bank->eint_base + EINTMASK_REG);
+	writel(mask, d->virt_base + EINTMASK_REG);
 }
 
 static void s3c2412_eint0_3_unmask(struct irq_data *data)
 {
 	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
+	struct samsung_pinctrl_drv_data *d = bank->drvdata;
 	unsigned long mask;
 
-	mask = readl(bank->eint_base + EINTMASK_REG);
+	mask = readl(d->virt_base + EINTMASK_REG);
 	mask &= ~(1UL << data->hwirq);
-	writel(mask, bank->eint_base + EINTMASK_REG);
+	writel(mask, d->virt_base + EINTMASK_REG);
 }
 
 static struct irq_chip s3c2412_eint0_3_chip = {
@@ -316,31 +319,34 @@ static void s3c2412_demux_eint0_3(struct
 static void s3c24xx_eint_ack(struct irq_data *data)
 {
 	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
+	struct samsung_pinctrl_drv_data *d = bank->drvdata;
 	unsigned char index = bank->eint_offset + data->hwirq;
 
-	writel(1UL << index, bank->eint_base + EINTPEND_REG);
+	writel(1UL << index, d->virt_base + EINTPEND_REG);
 }
 
 static void s3c24xx_eint_mask(struct irq_data *data)
 {
 	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
+	struct samsung_pinctrl_drv_data *d = bank->drvdata;
 	unsigned char index = bank->eint_offset + data->hwirq;
 	unsigned long mask;
 
-	mask = readl(bank->eint_base + EINTMASK_REG);
+	mask = readl(d->virt_base + EINTMASK_REG);
 	mask |= (1UL << index);
-	writel(mask, bank->eint_base + EINTMASK_REG);
+	writel(mask, d->virt_base + EINTMASK_REG);
 }
 
 static void s3c24xx_eint_unmask(struct irq_data *data)
 {
 	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
+	struct samsung_pinctrl_drv_data *d = bank->drvdata;
 	unsigned char index = bank->eint_offset + data->hwirq;
 	unsigned long mask;
 
-	mask = readl(bank->eint_base + EINTMASK_REG);
+	mask = readl(d->virt_base + EINTMASK_REG);
 	mask &= ~(1UL << index);
-	writel(mask, bank->eint_base + EINTMASK_REG);
+	writel(mask, d->virt_base + EINTMASK_REG);
 }
 
 static struct irq_chip s3c24xx_eint_chip = {
@@ -356,14 +362,13 @@ static inline void s3c24xx_demux_eint(st
 {
 	struct s3c24xx_eint_data *data = irq_desc_get_handler_data(desc);
 	struct irq_chip *chip = irq_desc_get_chip(desc);
-	struct irq_data *irqd = irq_desc_get_irq_data(desc);
-	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
+	struct samsung_pinctrl_drv_data *d = data->drvdata;
 	unsigned int pend, mask;
 
 	chained_irq_enter(chip, desc);
 
-	pend = readl(bank->eint_base + EINTPEND_REG);
-	mask = readl(bank->eint_base + EINTMASK_REG);
+	pend = readl(d->virt_base + EINTPEND_REG);
+	mask = readl(d->virt_base + EINTMASK_REG);
 
 	pend &= ~mask;
 	pend &= range;
drivers/pinctrl/samsung/pinctrl-s3c64xx.c +18 -22
@@ -280,7 +280,7 @@ static void s3c64xx_irq_set_function(str
 	u32 val;
 
 	/* Make sure that pin is configured as interrupt */
-	reg = bank->pctl_base + bank->pctl_offset;
+	reg = d->virt_base + bank->pctl_offset;
 	shift = pin;
 	if (bank_type->fld_width[PINCFG_TYPE_FUNC] * shift >= 32) {
 		/* 4-bit bank type with 2 con regs */
@@ -308,8 +308,9 @@ static void s3c64xx_irq_set_function(str
 static inline void s3c64xx_gpio_irq_set_mask(struct irq_data *irqd, bool mask)
 {
 	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
+	struct samsung_pinctrl_drv_data *d = bank->drvdata;
 	unsigned char index = EINT_OFFS(bank->eint_offset) + irqd->hwirq;
-	void __iomem *reg = bank->eint_base + EINTMASK_REG(bank->eint_offset);
+	void __iomem *reg = d->virt_base + EINTMASK_REG(bank->eint_offset);
 	u32 val;
 
 	val = readl(reg);
@@ -333,8 +334,9 @@ static void s3c64xx_gpio_irq_mask(struct
 static void s3c64xx_gpio_irq_ack(struct irq_data *irqd)
 {
 	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
+	struct samsung_pinctrl_drv_data *d = bank->drvdata;
 	unsigned char index = EINT_OFFS(bank->eint_offset) + irqd->hwirq;
-	void __iomem *reg = bank->eint_base + EINTPEND_REG(bank->eint_offset);
+	void __iomem *reg = d->virt_base + EINTPEND_REG(bank->eint_offset);
 
 	writel(1 << index, reg);
 }
@@ -357,7 +359,7 @@ static int s3c64xx_gpio_irq_set_type(str
 	s3c64xx_irq_set_handler(irqd, type);
 
 	/* Set up interrupt trigger */
-	reg = bank->eint_base + EINTCON_REG(bank->eint_offset);
+	reg = d->virt_base + EINTCON_REG(bank->eint_offset);
 	shift = EINT_OFFS(bank->eint_offset) + irqd->hwirq;
 	shift = 4 * (shift / 4); /* 4 EINTs per trigger selector */
 
@@ -409,8 +411,7 @@ static void s3c64xx_eint_gpio_irq(struct
 {
 	struct irq_chip *chip = irq_desc_get_chip(desc);
 	struct s3c64xx_eint_gpio_data *data = irq_desc_get_handler_data(desc);
-	struct irq_data *irqd = irq_desc_get_irq_data(desc);
-	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
+	struct samsung_pinctrl_drv_data *drvdata = data->drvdata;
 
 	chained_irq_enter(chip, desc);
 
@@ -420,7 +421,7 @@ static void s3c64xx_eint_gpio_irq(struct
 		unsigned int pin;
 		unsigned int virq;
 
-		svc = readl(bank->eint_base + SERVICE_REG);
+		svc = readl(drvdata->virt_base + SERVICE_REG);
 		group = SVC_GROUP(svc);
 		pin = svc & SVC_NUM_MASK;
 
@@ -515,15 +516,15 @@ static inline void s3c64xx_eint0_irq_set
 {
 	struct s3c64xx_eint0_domain_data *ddata =
 					irq_data_get_irq_chip_data(irqd);
-	struct samsung_pin_bank *bank = ddata->bank;
+	struct samsung_pinctrl_drv_data *d = ddata->bank->drvdata;
 	u32 val;
 
-	val = readl(bank->eint_base + EINT0MASK_REG);
+	val = readl(d->virt_base + EINT0MASK_REG);
 	if (mask)
 		val |= 1 << ddata->eints[irqd->hwirq];
 	else
 		val &= ~(1 << ddata->eints[irqd->hwirq]);
-	writel(val, bank->eint_base + EINT0MASK_REG);
+	writel(val, d->virt_base + EINT0MASK_REG);
 }
 
 static void s3c64xx_eint0_irq_unmask(struct irq_data *irqd)
@@ -540,10 +541,10 @@ static void s3c64xx_eint0_irq_ack(struct
 {
 	struct s3c64xx_eint0_domain_data *ddata =
 					irq_data_get_irq_chip_data(irqd);
-	struct samsung_pin_bank *bank = ddata->bank;
+	struct samsung_pinctrl_drv_data *d = ddata->bank->drvdata;
 
 	writel(1 << ddata->eints[irqd->hwirq],
-					bank->eint_base + EINT0PEND_REG);
+					d->virt_base + EINT0PEND_REG);
 }
 
 static int s3c64xx_eint0_irq_set_type(struct irq_data *irqd, unsigned int type)
@@ -551,7 +552,7 @@ static int s3c64xx_eint0_irq_set_type(st
 	struct s3c64xx_eint0_domain_data *ddata =
 					irq_data_get_irq_chip_data(irqd);
 	struct samsung_pin_bank *bank = ddata->bank;
-	struct samsung_pinctrl_drv_data *d = ddata->bank->drvdata;
+	struct samsung_pinctrl_drv_data *d = bank->drvdata;
 	void __iomem *reg;
 	int trigger;
 	u8 shift;
@@ -566,7 +567,7 @@ static int s3c64xx_eint0_irq_set_type(st
 	s3c64xx_irq_set_handler(irqd, type);
 
 	/* Set up interrupt trigger */
-	reg = bank->eint_base + EINT0CON0_REG;
+	reg = d->virt_base + EINT0CON0_REG;
 	shift = ddata->eints[irqd->hwirq];
 	if (shift >= EINT_MAX_PER_REG) {
 		reg += 4;
@@ -598,19 +599,14 @@ static struct irq_chip s3c64xx_eint0_irq
 static inline void s3c64xx_irq_demux_eint(struct irq_desc *desc, u32 range)
 {
 	struct irq_chip *chip = irq_desc_get_chip(desc);
-	struct irq_data *irqd = irq_desc_get_irq_data(desc);
-	struct s3c64xx_eint0_domain_data *ddata =
-					irq_data_get_irq_chip_data(irqd);
-	struct samsung_pin_bank *bank = ddata->bank;
-
 	struct s3c64xx_eint0_data *data = irq_desc_get_handler_data(desc);
-
+	struct samsung_pinctrl_drv_data *drvdata = data->drvdata;
 	unsigned int pend, mask;
 
 	chained_irq_enter(chip, desc);
 
-	pend = readl(bank->eint_base + EINT0PEND_REG);
-	mask = readl(bank->eint_base + EINT0MASK_REG);
+	pend = readl(drvdata->virt_base + EINT0PEND_REG);
+	mask = readl(drvdata->virt_base + EINT0MASK_REG);
 
 	pend = pend & range & ~mask;
 	pend &= range;
drivers/pinctrl/samsung/pinctrl-samsung.c +6 -0
@@ -1013,6 +1013,12 @@ samsung_pinctrl_get_soc_data(struct sams
 		bank->eint_base = virt_base[0];
 		bank->pctl_base = virt_base[bdata->pctl_res_idx];
 	}
+	/*
+	 * Legacy platforms should provide only one resource with IO memory.
+	 * Store it as virt_base because legacy driver needs to access it
+	 * through samsung_pinctrl_drv_data.
+	 */
+	d->virt_base = virt_base[0];
 
 	for_each_child_of_node(node, np) {
 		if (!of_find_property(np, "gpio-controller", NULL))
drivers/pinctrl/samsung/pinctrl-samsung.h +5 -0
@@ -247,6 +247,10 @@ struct samsung_pin_ctrl {
 /**
  * struct samsung_pinctrl_drv_data: wrapper for holding driver data together.
  * @node: global list node
+ * @virt_base: register base address of the controller; this will be equal
+ *             to each bank samsung_pin_bank->pctl_base and used on legacy
+ *             platforms (like S3C24XX or S3C64XX) which has to access the base
+ *             through samsung_pinctrl_drv_data, not samsung_pin_bank).
  * @dev: device instance representing the controller.
  * @irq: interrpt number used by the controller to notify gpio interrupts.
  * @ctrl: pin controller instance managed by the driver.
@@ -262,6 +266,7 @@ struct samsung_pin_ctrl {
  */
 struct samsung_pinctrl_drv_data {
 	struct list_head		node;
+	void __iomem			*virt_base;
 	struct device			*dev;
 	int				irq;
 
author maintainer
#16 lore raw

PATCH 15/109 pinctrl/amd: save pin registers over suspend/resume

In reply to Greg Kroah-Hartman

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

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

From: Daniel Drake <[email protected]>

commit 79d2c8bede2c93f9432d7da0bc2f76a195c90fc0 upstream.

The touchpad in the Asus laptop models X505BA/BP and X542BA/BP is unresponsive after suspend/resume. The following error appears during resume:

i2c_hid i2c-ELAN1300:00: failed to reset device.

The problem here is that i2c_hid does not notice the interrupt being generated at this point, because the GPIO is no longer configured for interrupts.

Fix this by saving pinctrl-amd pin registers during suspend and restoring them at resume time.

Based on code from pinctrl-intel.

---
 drivers/pinctrl/pinctrl-amd.c |   75 ++++++++++++++++++++++++++++++++++++++++++
 drivers/pinctrl/pinctrl-amd.h |    1 
 2 files changed, 76 insertions(+)
drivers/pinctrl/pinctrl-amd.c +75 -0
@@ -36,6 +36,7 @@
 #include <linux/pinctrl/pinconf.h>
 #include <linux/pinctrl/pinconf-generic.h>
 
+#include "core.h"
 #include "pinctrl-utils.h"
 #include "pinctrl-amd.h"
 
@@ -725,6 +726,69 @@ static const struct pinconf_ops amd_pinc
 	.pin_config_group_set = amd_pinconf_group_set,
 };
 
+#ifdef CONFIG_PM_SLEEP
+static bool amd_gpio_should_save(struct amd_gpio *gpio_dev, unsigned int pin)
+{
+	const struct pin_desc *pd = pin_desc_get(gpio_dev->pctrl, pin);
+
+	if (!pd)
+		return false;
+
+	/*
+	 * Only restore the pin if it is actually in use by the kernel (or
+	 * by userspace).
+	 */
+	if (pd->mux_owner || pd->gpio_owner ||
+	    gpiochip_line_is_irq(&gpio_dev->gc, pin))
+		return true;
+
+	return false;
+}
+
+int amd_gpio_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct amd_gpio *gpio_dev = platform_get_drvdata(pdev);
+	struct pinctrl_desc *desc = gpio_dev->pctrl->desc;
+	int i;
+
+	for (i = 0; i < desc->npins; i++) {
+		int pin = desc->pins[i].number;
+
+		if (!amd_gpio_should_save(gpio_dev, pin))
+			continue;
+
+		gpio_dev->saved_regs[i] = readl(gpio_dev->base + pin*4);
+	}
+
+	return 0;
+}
+
+int amd_gpio_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct amd_gpio *gpio_dev = platform_get_drvdata(pdev);
+	struct pinctrl_desc *desc = gpio_dev->pctrl->desc;
+	int i;
+
+	for (i = 0; i < desc->npins; i++) {
+		int pin = desc->pins[i].number;
+
+		if (!amd_gpio_should_save(gpio_dev, pin))
+			continue;
+
+		writel(gpio_dev->saved_regs[i], gpio_dev->base + pin*4);
+	}
+
+	return 0;
+}
+
+static const struct dev_pm_ops amd_gpio_pm_ops = {
+	SET_LATE_SYSTEM_SLEEP_PM_OPS(amd_gpio_suspend,
+				     amd_gpio_resume)
+};
+#endif
+
 static struct pinctrl_desc amd_pinctrl_desc = {
 	.pins	= kerncz_pins,
 	.npins = ARRAY_SIZE(kerncz_pins),
@@ -764,6 +828,14 @@ static int amd_gpio_probe(struct platfor
 		return -EINVAL;
 	}
 
+#ifdef CONFIG_PM_SLEEP
+	gpio_dev->saved_regs = devm_kcalloc(&pdev->dev, amd_pinctrl_desc.npins,
+					    sizeof(*gpio_dev->saved_regs),
+					    GFP_KERNEL);
+	if (!gpio_dev->saved_regs)
+		return -ENOMEM;
+#endif
+
 	gpio_dev->pdev = pdev;
 	gpio_dev->gc.direction_input	= amd_gpio_direction_input;
 	gpio_dev->gc.direction_output	= amd_gpio_direction_output;
@@ -853,6 +925,9 @@ static struct platform_driver amd_gpio_d
 	.driver		= {
 		.name	= "amd_gpio",
 		.acpi_match_table = ACPI_PTR(amd_gpio_acpi_match),
+#ifdef CONFIG_PM_SLEEP
+		.pm	= &amd_gpio_pm_ops,
+#endif
 	},
 	.probe		= amd_gpio_probe,
 	.remove		= amd_gpio_remove,
drivers/pinctrl/pinctrl-amd.h +1 -0
@@ -97,6 +97,7 @@ struct amd_gpio {
 	unsigned int            hwbank_num;
 	struct resource         *res;
 	struct platform_device  *pdev;
+	u32			*saved_regs;
 };
 
 /*  KERNCZ configuration*/
author maintainer
#22 lore raw

PATCH 16/109 Input: i8042 - add Gigabyte P57 to the keyboard reset table

In reply to Greg Kroah-Hartman

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

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

From: Kai-Heng Feng <[email protected]>

commit 697c5d8a36768b36729533fb44622b35d56d6ad0 upstream.

Similar to other Gigabyte laptops, the touchpad on P57 requires a keyboard reset to detect Elantech touchpad correctly.

---
 drivers/input/serio/i8042-x86ia64io.h |    7 +++++++
 1 file changed, 7 insertions(+)
drivers/input/serio/i8042-x86ia64io.h +7 -0
@@ -840,6 +840,13 @@ static const struct dmi_system_id __init
 		},
 	},
 	{
+		/* Gigabyte P57 - Elantech touchpad */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "P57"),
+		},
+	},
+	{
 		/* Schenker XMG C504 - Elantech touchpad */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "XMG"),
author maintainer
#24 lore raw

PATCH 18/109 MIPS: math-emu: <MAX|MAXA|MIN|MINA>.<D|S>: Fix cases of both inputs zero

In reply to Greg Kroah-Hartman

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

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

From: Aleksandar Markovic <[email protected]>

commit 15560a58bfd4ff82cdd16b2270d4ef9b06d2cc4d upstream.

Fix the value returned by <MAX|MAXA|MIN|MINA>.<D|S>, if both inputs are zeros. The right behavior in such cases is stated in instruction reference manual and is as follows:

fs ft MAX MIN MAXA MINA
---------------------------------------------

    0   0        0       0         0       0
    0  -0        0      -0         0      -0
   -0   0        0      -0         0      -0

-0 -0 -0 -0 -0 -0

Prior to this patch, some of the above cases were yielding correct results. However, for the sake of code consistency, all such cases are rewritten in this patch.

A relevant example:

MAX.S fd,fs,ft:
If fs contains +0.0, and ft contains -0.0, fd is going to contain +0.0 (without this patch, it used to contain -0.0).

Fixes a79f5f9ba508 ("MIPS: math-emu: Add support for the MIPS R6 MAX{, A} FPU instruction")
Fixes 4e9561b20e2f ("MIPS: math-emu: Add support for the MIPS R6 MIN{, A} FPU instruction")

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

---
 arch/mips/math-emu/dp_fmax.c |    8 ++------
 arch/mips/math-emu/dp_fmin.c |    8 ++------
 arch/mips/math-emu/sp_fmax.c |    8 ++------
 arch/mips/math-emu/sp_fmin.c |    8 ++------
 4 files changed, 8 insertions(+), 24 deletions(-)
arch/mips/math-emu/dp_fmax.c +2 -6
@@ -92,9 +92,7 @@ union ieee754dp ieee754dp_fmax(union iee
 		return ys ? x : y;
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
-		if (xs == ys)
-			return x;
-		return ieee754dp_zero(1);
+		return ieee754dp_zero(xs & ys);
 
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
 		DPDNORMX;
@@ -204,9 +202,7 @@ union ieee754dp ieee754dp_fmaxa(union ie
 		return y;
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
-		if (xs == ys)
-			return x;
-		return ieee754dp_zero(1);
+		return ieee754dp_zero(xs & ys);
 
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
 		DPDNORMX;
arch/mips/math-emu/dp_fmin.c +2 -6
@@ -92,9 +92,7 @@ union ieee754dp ieee754dp_fmin(union iee
 		return ys ? y : x;
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
-		if (xs == ys)
-			return x;
-		return ieee754dp_zero(1);
+		return ieee754dp_zero(xs | ys);
 
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
 		DPDNORMX;
@@ -204,9 +202,7 @@ union ieee754dp ieee754dp_fmina(union ie
 		return y;
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
-		if (xs == ys)
-			return x;
-		return ieee754dp_zero(1);
+		return ieee754dp_zero(xs | ys);
 
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
 		DPDNORMX;
arch/mips/math-emu/sp_fmax.c +2 -6
@@ -92,9 +92,7 @@ union ieee754sp ieee754sp_fmax(union iee
 		return ys ? x : y;
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
-		if (xs == ys)
-			return x;
-		return ieee754sp_zero(1);
+		return ieee754sp_zero(xs & ys);
 
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
 		SPDNORMX;
@@ -204,9 +202,7 @@ union ieee754sp ieee754sp_fmaxa(union ie
 		return y;
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
-		if (xs == ys)
-			return x;
-		return ieee754sp_zero(1);
+		return ieee754sp_zero(xs & ys);
 
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
 		SPDNORMX;
arch/mips/math-emu/sp_fmin.c +2 -6
@@ -92,9 +92,7 @@ union ieee754sp ieee754sp_fmin(union iee
 		return ys ? y : x;
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
-		if (xs == ys)
-			return x;
-		return ieee754sp_zero(1);
+		return ieee754sp_zero(xs | ys);
 
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
 		SPDNORMX;
@@ -204,9 +202,7 @@ union ieee754sp ieee754sp_fmina(union ie
 		return y;
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
-		if (xs == ys)
-			return x;
-		return ieee754sp_zero(1);
+		return ieee754sp_zero(xs | ys);
 
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
 		SPDNORMX;
author maintainer
#25 lore raw

PATCH 19/109 MIPS: math-emu: <MAX|MIN>.<D|S>: Fix cases of both inputs negative

In reply to Greg Kroah-Hartman

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

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

From: Aleksandar Markovic <[email protected]>

commit aabf5cf02e22ebc4e541adf835910f388b6c3e65 upstream.

Fix the value returned by <MAX|MIN>.<D|S>, if both inputs are negative normal fp numbers. The previous logic did not take into account that if both inputs have the same sign, there should be separate treatment of the cases when both inputs are negative and when both inputs are positive.

A relevant example:

MAX.S fd,fs,ft:
If fs contains -5.0, and ft contains -7.0, fd is going to contain -5.0 (without this patch, it used to contain -7.0).

Fixes a79f5f9ba508 ("MIPS: math-emu: Add support for the MIPS R6 MAX{, A} FPU instruction")
Fixes 4e9561b20e2f ("MIPS: math-emu: Add support for the MIPS R6 MIN{, A} FPU instruction")

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

---
 arch/mips/math-emu/dp_fmax.c |   32 ++++++++++++++++++++++++--------
 arch/mips/math-emu/dp_fmin.c |   32 ++++++++++++++++++++++++--------
 arch/mips/math-emu/sp_fmax.c |   32 ++++++++++++++++++++++++--------
 arch/mips/math-emu/sp_fmin.c |   32 ++++++++++++++++++++++++--------
 4 files changed, 96 insertions(+), 32 deletions(-)
arch/mips/math-emu/dp_fmax.c +24 -8
@@ -116,16 +116,32 @@ union ieee754dp ieee754dp_fmax(union iee
 	else if (xs < ys)
 		return x;
 
-	/* Compare exponent */
-	if (xe > ye)
-		return x;
-	else if (xe < ye)
-		return y;
+	/* Signs of inputs are equal, let's compare exponents */
+	if (xs == 0) {
+		/* Inputs are both positive */
+		if (xe > ye)
+			return x;
+		else if (xe < ye)
+			return y;
+	} else {
+		/* Inputs are both negative */
+		if (xe > ye)
+			return y;
+		else if (xe < ye)
+			return x;
+	}
 
-	/* Compare mantissa */
+	/* Signs and exponents of inputs are equal, let's compare mantissas */
+	if (xs == 0) {
+		/* Inputs are both positive, with equal signs and exponents */
+		if (xm <= ym)
+			return y;
+		return x;
+	}
+	/* Inputs are both negative, with equal signs and exponents */
 	if (xm <= ym)
-		return y;
-	return x;
+		return x;
+	return y;
 }
 
 union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y)
arch/mips/math-emu/dp_fmin.c +24 -8
@@ -116,16 +116,32 @@ union ieee754dp ieee754dp_fmin(union iee
 	else if (xs < ys)
 		return y;
 
-	/* Compare exponent */
-	if (xe > ye)
-		return y;
-	else if (xe < ye)
-		return x;
+	/* Signs of inputs are the same, let's compare exponents */
+	if (xs == 0) {
+		/* Inputs are both positive */
+		if (xe > ye)
+			return y;
+		else if (xe < ye)
+			return x;
+	} else {
+		/* Inputs are both negative */
+		if (xe > ye)
+			return x;
+		else if (xe < ye)
+			return y;
+	}
 
-	/* Compare mantissa */
+	/* Signs and exponents of inputs are equal, let's compare mantissas */
+	if (xs == 0) {
+		/* Inputs are both positive, with equal signs and exponents */
+		if (xm <= ym)
+			return x;
+		return y;
+	}
+	/* Inputs are both negative, with equal signs and exponents */
 	if (xm <= ym)
-		return x;
-	return y;
+		return y;
+	return x;
 }
 
 union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y)
arch/mips/math-emu/sp_fmax.c +24 -8
@@ -116,16 +116,32 @@ union ieee754sp ieee754sp_fmax(union iee
 	else if (xs < ys)
 		return x;
 
-	/* Compare exponent */
-	if (xe > ye)
-		return x;
-	else if (xe < ye)
-		return y;
+	/* Signs of inputs are equal, let's compare exponents */
+	if (xs == 0) {
+		/* Inputs are both positive */
+		if (xe > ye)
+			return x;
+		else if (xe < ye)
+			return y;
+	} else {
+		/* Inputs are both negative */
+		if (xe > ye)
+			return y;
+		else if (xe < ye)
+			return x;
+	}
 
-	/* Compare mantissa */
+	/* Signs and exponents of inputs are equal, let's compare mantissas */
+	if (xs == 0) {
+		/* Inputs are both positive, with equal signs and exponents */
+		if (xm <= ym)
+			return y;
+		return x;
+	}
+	/* Inputs are both negative, with equal signs and exponents */
 	if (xm <= ym)
-		return y;
-	return x;
+		return x;
+	return y;
 }
 
 union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y)
arch/mips/math-emu/sp_fmin.c +24 -8
@@ -116,16 +116,32 @@ union ieee754sp ieee754sp_fmin(union iee
 	else if (xs < ys)
 		return y;
 
-	/* Compare exponent */
-	if (xe > ye)
-		return y;
-	else if (xe < ye)
-		return x;
+	/* Signs of inputs are the same, let's compare exponents */
+	if (xs == 0) {
+		/* Inputs are both positive */
+		if (xe > ye)
+			return y;
+		else if (xe < ye)
+			return x;
+	} else {
+		/* Inputs are both negative */
+		if (xe > ye)
+			return x;
+		else if (xe < ye)
+			return y;
+	}
 
-	/* Compare mantissa */
+	/* Signs and exponents of inputs are equal, let's compare mantissas */
+	if (xs == 0) {
+		/* Inputs are both positive, with equal signs and exponents */
+		if (xm <= ym)
+			return x;
+		return y;
+	}
+	/* Inputs are both negative, with equal signs and exponents */
 	if (xm <= ym)
-		return x;
-	return y;
+		return y;
+	return x;
 }
 
 union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y)
author maintainer
#26 lore raw

PATCH 20/109 MIPS: math-emu: <MAXA|MINA>.<D|S>: Fix cases of input values with opposite signs

In reply to Greg Kroah-Hartman

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

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

From: Aleksandar Markovic <[email protected]>

commit 1a41b3b441508ae63b1a9ec699ec94065739eb60 upstream.

Fix the value returned by <MAXA|MINA>.<D|S>, if the inputs are normal fp numbers of the same absolute value, but opposite signs.

A relevant example:

MAXA.S fd,fs,ft:
If fs contains -3.0, and ft contains +3.0, fd is going to contain +3.0 (without this patch, it used to contain -3.0).

Fixes a79f5f9ba508 ("MIPS: math-emu: Add support for the MIPS R6 MAX{, A} FPU instruction")
Fixes 4e9561b20e2f ("MIPS: math-emu: Add support for the MIPS R6 MIN{, A} FPU instruction")

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

---
 arch/mips/math-emu/dp_fmax.c |    8 ++++++--
 arch/mips/math-emu/dp_fmin.c |    6 +++++-
 arch/mips/math-emu/sp_fmax.c |    8 ++++++--
 arch/mips/math-emu/sp_fmin.c |    6 +++++-
 4 files changed, 22 insertions(+), 6 deletions(-)
arch/mips/math-emu/dp_fmax.c +6 -2
@@ -243,7 +243,11 @@ union ieee754dp ieee754dp_fmaxa(union ie
 		return y;
 
 	/* Compare mantissa */
-	if (xm <= ym)
+	if (xm < ym)
 		return y;
-	return x;
+	else if (xm > ym)
+		return x;
+	else if (xs == 0)
+		return x;
+	return y;
 }
arch/mips/math-emu/dp_fmin.c +5 -1
@@ -243,7 +243,11 @@ union ieee754dp ieee754dp_fmina(union ie
 		return x;
 
 	/* Compare mantissa */
-	if (xm <= ym)
+	if (xm < ym)
+		return x;
+	else if (xm > ym)
+		return y;
+	else if (xs == 1)
 		return x;
 	return y;
 }
arch/mips/math-emu/sp_fmax.c +6 -2
@@ -243,7 +243,11 @@ union ieee754sp ieee754sp_fmaxa(union ie
 		return y;
 
 	/* Compare mantissa */
-	if (xm <= ym)
+	if (xm < ym)
 		return y;
-	return x;
+	else if (xm > ym)
+		return x;
+	else if (xs == 0)
+		return x;
+	return y;
 }
arch/mips/math-emu/sp_fmin.c +5 -1
@@ -243,7 +243,11 @@ union ieee754sp ieee754sp_fmina(union ie
 		return x;
 
 	/* Compare mantissa */
-	if (xm <= ym)
+	if (xm < ym)
+		return x;
+	else if (xm > ym)
+		return y;
+	else if (xs == 1)
 		return x;
 	return y;
 }
author maintainer
#27 lore raw

PATCH 21/109 MIPS: math-emu: <MAXA|MINA>.<D|S>: Fix cases of both infinite inputs

In reply to Greg Kroah-Hartman

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

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

From: Aleksandar Markovic <[email protected]>

commit 3444c4eb534c20e44f0d6670b34263efaf8b531f upstream.

Fix the value returned by <MAXA|MINA>.<D|S> fd,fs,ft, if both inputs are infinite. The previous implementation returned always the value contained in ft in such cases. The correct behavior is specified in Mips instruction set manual and is as follows:

fs ft MAXA MINA
---------------------------------

    inf   inf        inf      inf
    inf  -inf        inf     -inf
   -inf   inf        inf     -inf

-inf -inf -inf -inf

A relevant example:

MAXA.S fd,fs,ft:
If fs contains +inf, and ft contains -inf, fd is going to contain +inf (without this patch, it used to contain -inf).

Fixes a79f5f9ba508 ("MIPS: math-emu: Add support for the MIPS R6 MAX{, A} FPU instruction")
Fixes 4e9561b20e2f ("MIPS: math-emu: Add support for the MIPS R6 MIN{, A} FPU instruction")

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

---
 arch/mips/math-emu/dp_fmax.c |    4 +++-
 arch/mips/math-emu/dp_fmin.c |    4 +++-
 arch/mips/math-emu/sp_fmax.c |    4 +++-
 arch/mips/math-emu/sp_fmin.c |    4 +++-
 4 files changed, 12 insertions(+), 4 deletions(-)
arch/mips/math-emu/dp_fmax.c +3 -1
@@ -202,6 +202,9 @@ union ieee754dp ieee754dp_fmaxa(union ie
 	/*
 	 * Infinity and zero handling
 	 */
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
+		return ieee754dp_inf(xs & ys);
+
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
@@ -209,7 +212,6 @@ union ieee754dp ieee754dp_fmaxa(union ie
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
 		return x;
 
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
arch/mips/math-emu/dp_fmin.c +3 -1
@@ -202,6 +202,9 @@ union ieee754dp ieee754dp_fmina(union ie
 	/*
 	 * Infinity and zero handling
 	 */
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
+		return ieee754dp_inf(xs | ys);
+
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
@@ -209,7 +212,6 @@ union ieee754dp ieee754dp_fmina(union ie
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
 		return x;
 
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
arch/mips/math-emu/sp_fmax.c +3 -1
@@ -202,6 +202,9 @@ union ieee754sp ieee754sp_fmaxa(union ie
 	/*
 	 * Infinity and zero handling
 	 */
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
+		return ieee754sp_inf(xs & ys);
+
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
@@ -209,7 +212,6 @@ union ieee754sp ieee754sp_fmaxa(union ie
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
 		return x;
 
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
arch/mips/math-emu/sp_fmin.c +3 -1
@@ -202,6 +202,9 @@ union ieee754sp ieee754sp_fmina(union ie
 	/*
 	 * Infinity and zero handling
 	 */
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
+		return ieee754sp_inf(xs | ys);
+
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
@@ -209,7 +212,6 @@ union ieee754sp ieee754sp_fmina(union ie
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
 		return x;
 
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
author maintainer
#28 lore raw

PATCH 22/109 MIPS: math-emu: MINA.<D|S>: Fix some cases of infinity and zero inputs

In reply to Greg Kroah-Hartman

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

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

From: Aleksandar Markovic <[email protected]>

commit 304bfe473e70523e591fb1c9223289d355e0bdcb upstream.

Fix following special cases for MINA>.<D|S>:

- if one of the inputs is zero, and the other is subnormal, normal, or infinity, the value of the former should be returned (that is, a zero).
- if one of the inputs is infinity, and the other input is normal, or subnormal, the value of the latter should be returned.

The previous implementation's logic for such cases was incorrect - it appears as if it implements MAXA, and not MINA instruction.

A relevant example:

MINA.S fd,fs,ft:
If fs contains 100.0, and ft contains 0.0, fd is going to contain 0.0 (without this patch, it used to contain 100.0).

Fixes a79f5f9ba508 ("MIPS: math-emu: Add support for the MIPS R6 MAX{, A} FPU instruction")
Fixes 4e9561b20e2f ("MIPS: math-emu: Add support for the MIPS R6 MIN{, A} FPU instruction")

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

---
 arch/mips/math-emu/dp_fmin.c |    4 ++--
 arch/mips/math-emu/sp_fmin.c |    4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)
arch/mips/math-emu/dp_fmin.c +2 -2
@@ -210,14 +210,14 @@ union ieee754dp ieee754dp_fmina(union ie
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
-		return x;
+		return y;
 
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
-		return y;
+		return x;
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
 		return ieee754dp_zero(xs | ys);
arch/mips/math-emu/sp_fmin.c +2 -2
@@ -210,14 +210,14 @@ union ieee754sp ieee754sp_fmina(union ie
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
-		return x;
+		return y;
 
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
-		return y;
+		return x;
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
 		return ieee754sp_zero(xs | ys);
author maintainer
#29 lore raw

PATCH 23/109 MIPS: math-emu: <MADDF|MSUBF>.<D|S>: Fix NaN propagation

In reply to Greg Kroah-Hartman

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

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

From: Aleksandar Markovic <[email protected]>

commit e840be6e7057757befc3581e1699e30fe7f0dd51 upstream.

Fix the cases of <MADDF|MSUBF>.<D|S> when any of three inputs is any NaN. Correct behavior of <MADDF|MSUBF>.<D|S> fd, fs, ft is following:

- if any of inputs is sNaN, return a sNaN using following rules: if only one input is sNaN, return that one; if more than one input is sNaN, order of precedence for return value is fd, fs, ft
- if no input is sNaN, but at least one of inputs is qNaN, return a qNaN using following rules: if only one input is qNaN, return that one; if more than one input is qNaN, order of precedence for return value is fd, fs, ft

The previous code contained correct handling of some above cases, but not all. Also, such handling was scattered into various cases of "switch (CLPAIR(xc, yc))" statement, and elsewhere. With this patch, this logic is placed in one place, and "switch (CLPAIR(xc, yc))" is significantly simplified.

A relevant example:

MADDF.S fd,fs,ft:
If fs contains qNaN1, ft contains qNaN2, and fd contains qNaN3, fd is going to contain qNaN3 (without this patch, it used to contain qNaN1).

Fixes e24c3bec3e8e ("MIPS: math-emu: Add support for the MIPS R6 MADDF FPU instruction")
Fixes 83d43305a1df ("MIPS: math-emu: Add support for the MIPS R6 MSUBF FPU instruction")

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

---
 arch/mips/math-emu/dp_maddf.c |   66 ++++++++++++------------------------------
 arch/mips/math-emu/sp_maddf.c |   66 +++++++++++++-----------------------------
 2 files changed, 41 insertions(+), 91 deletions(-)
arch/mips/math-emu/dp_maddf.c +20 -46
@@ -48,52 +48,34 @@ static union ieee754dp _dp_maddf(union i
 
 	ieee754_clearcx();
 
-	switch (zc) {
-	case IEEE754_CLASS_SNAN:
-		ieee754_setcx(IEEE754_INVALID_OPERATION);
+	/*
+	 * Handle the cases when at least one of x, y or z is a NaN.
+	 * Order of precedence is sNaN, qNaN and z, x, y.
+	 */
+	if (zc == IEEE754_CLASS_SNAN)
 		return ieee754dp_nanxcpt(z);
-	case IEEE754_CLASS_DNORM:
-		DPDNORMZ;
-	/* QNAN and ZERO cases are handled separately below */
-	}
-
-	switch (CLPAIR(xc, yc)) {
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
-		return ieee754dp_nanxcpt(y);
-
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
+	if (xc == IEEE754_CLASS_SNAN)
 		return ieee754dp_nanxcpt(x);
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
+	if (yc == IEEE754_CLASS_SNAN)
+		return ieee754dp_nanxcpt(y);
+	if (zc == IEEE754_CLASS_QNAN)
+		return z;
+	if (xc == IEEE754_CLASS_QNAN)
+		return x;
+	if (yc == IEEE754_CLASS_QNAN)
 		return y;
 
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
-		return x;
+	if (zc == IEEE754_CLASS_DNORM)
+		DPDNORMZ;
+	/* ZERO z cases are handled separately below */
 
+	switch (CLPAIR(xc, yc)) {
 
 	/*
 	 * Infinity handling
 	 */
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
-		if (zc == IEEE754_CLASS_QNAN)
-			return z;
 		ieee754_setcx(IEEE754_INVALID_OPERATION);
 		return ieee754dp_indef();
 
@@ -102,8 +84,6 @@ static union ieee754dp _dp_maddf(union i
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
-		if (zc == IEEE754_CLASS_QNAN)
-			return z;
 		return ieee754dp_inf(xs ^ ys);
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
@@ -120,25 +100,19 @@ static union ieee754dp _dp_maddf(union i
 		DPDNORMX;
 
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
-		if (zc == IEEE754_CLASS_QNAN)
-			return z;
-		else if (zc == IEEE754_CLASS_INF)
+		if (zc == IEEE754_CLASS_INF)
 			return ieee754dp_inf(zs);
 		DPDNORMY;
 		break;
 
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
-		if (zc == IEEE754_CLASS_QNAN)
-			return z;
-		else if (zc == IEEE754_CLASS_INF)
+		if (zc == IEEE754_CLASS_INF)
 			return ieee754dp_inf(zs);
 		DPDNORMX;
 		break;
 
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
-		if (zc == IEEE754_CLASS_QNAN)
-			return z;
-		else if (zc == IEEE754_CLASS_INF)
+		if (zc == IEEE754_CLASS_INF)
 			return ieee754dp_inf(zs);
 		/* fall through to real computations */
 	}
arch/mips/math-emu/sp_maddf.c +21 -45

105 lines not on this page · raw message

author maintainer
#30 lore raw

PATCH 24/109 MIPS: math-emu: <MADDF|MSUBF>.<D|S>: Fix some cases of infinite inputs

In reply to Greg Kroah-Hartman

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

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

From: Aleksandar Markovic <[email protected]>

commit 0c64fe6348687f0e1cea9a608eae9d351124a73a upstream.

Fix the cases of <MADDF|MSUBF>.<D|S> when any of two multiplicands is infinity. The correct behavior in such cases is affected by the nature of third input. Cases of addition of infinities with opposite signs and subtraction of infinities with same signs may arise and must be handles separately. Also, the value od flags argument (that determines whether the instruction is MADDF or MSUBF) affects the outcome.

Relevant examples:

MADDF.S fd,fs,ft:
If fs contains +inf, ft contains +inf, and fd contains -inf, fd is going to contain indef (without this patch, it used to contain -inf).

MSUBF.S fd,fs,ft:
If fs contains +inf, ft contains 1.0, and fd contains +0.0, fd is going to contain -inf (without this patch, it used to contain +inf).

Fixes e24c3bec3e8e ("MIPS: math-emu: Add support for the MIPS R6 MADDF FPU instruction")
Fixes 83d43305a1df ("MIPS: math-emu: Add support for the MIPS R6 MSUBF FPU instruction")

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

---
 arch/mips/math-emu/dp_maddf.c |   22 +++++++++++++++++++++-
 arch/mips/math-emu/sp_maddf.c |   22 +++++++++++++++++++++-
 2 files changed, 42 insertions(+), 2 deletions(-)
arch/mips/math-emu/dp_maddf.c +21 -1
@@ -84,7 +84,27 @@ static union ieee754dp _dp_maddf(union i
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
-		return ieee754dp_inf(xs ^ ys);
+		if ((zc == IEEE754_CLASS_INF) &&
+		    ((!(flags & maddf_negate_product) && (zs != (xs ^ ys))) ||
+		     ((flags & maddf_negate_product) && (zs == (xs ^ ys))))) {
+			/*
+			 * Cases of addition of infinities with opposite signs
+			 * or subtraction of infinities with same signs.
+			 */
+			ieee754_setcx(IEEE754_INVALID_OPERATION);
+			return ieee754dp_indef();
+		}
+		/*
+		 * z is here either not an infinity, or an infinity having the
+		 * same sign as product (x*y) (in case of MADDF.D instruction)
+		 * or product -(x*y) (in MSUBF.D case). The result must be an
+		 * infinity, and its sign is determined only by the value of
+		 * (flags & maddf_negate_product) and the signs of x and y.
+		 */
+		if (flags & maddf_negate_product)
+			return ieee754dp_inf(1 ^ (xs ^ ys));
+		else
+			return ieee754dp_inf(xs ^ ys);
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
arch/mips/math-emu/sp_maddf.c +21 -1
@@ -85,7 +85,27 @@ static union ieee754sp _sp_maddf(union i
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
-		return ieee754sp_inf(xs ^ ys);
+		if ((zc == IEEE754_CLASS_INF) &&
+		    ((!(flags & maddf_negate_product) && (zs != (xs ^ ys))) ||
+		     ((flags & maddf_negate_product) && (zs == (xs ^ ys))))) {
+			/*
+			 * Cases of addition of infinities with opposite signs
+			 * or subtraction of infinities with same signs.
+			 */
+			ieee754_setcx(IEEE754_INVALID_OPERATION);
+			return ieee754sp_indef();
+		}
+		/*
+		 * z is here either not an infinity, or an infinity having the
+		 * same sign as product (x*y) (in case of MADDF.D instruction)
+		 * or product -(x*y) (in MSUBF.D case). The result must be an
+		 * infinity, and its sign is determined only by the value of
+		 * (flags & maddf_negate_product) and the signs of x and y.
+		 */
+		if (flags & maddf_negate_product)
+			return ieee754sp_inf(1 ^ (xs ^ ys));
+		else
+			return ieee754sp_inf(xs ^ ys);
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
author maintainer
#5 lore raw

PATCH 4/109 IB/{qib, hfi1}: Avoid flow control testing for RDMA write operation

In reply to Greg Kroah-Hartman

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

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

From: Mike Marciniszyn <[email protected]>

commit 5b0ef650bd0f820e922fcc42f1985d4621ae19cf upstream.

Section 9.7.7.2.5 of the 1.3 IBTA spec clearly says that receive credits should never apply to RDMA write.

qib and hfi1 were doing that. The following situation will result in a QP hang:
- A prior SEND or RDMA_WRITE with immmediate consumed the last credit for a QP using RC receive buffer credits
- The prior op is acked so there are no more acks
- The peer ULP fails to post receive for some reason
- An RDMA write sees that the credits are exhausted and waits
- The peer ULP posts receive buffers
- The ULP posts a send or RDMA write that will be hung

The fix is to avoid the credit test for the RDMA write operation.

---
 drivers/infiniband/hw/hfi1/rc.c    |    3 ++-
 drivers/infiniband/hw/qib/qib_rc.c |    4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)
drivers/infiniband/hw/hfi1/rc.c +2 -1
@@ -425,7 +425,7 @@ int hfi1_make_rc_req(struct rvt_qp *qp,
 		case IB_WR_RDMA_WRITE:
 			if (newreq && !(qp->s_flags & RVT_S_UNLIMITED_CREDIT))
 				qp->s_lsn++;
-			/* FALLTHROUGH */
+			goto no_flow_control;
 		case IB_WR_RDMA_WRITE_WITH_IMM:
 			/* If no credit, return. */
 			if (!(qp->s_flags & RVT_S_UNLIMITED_CREDIT) &&
@@ -433,6 +433,7 @@ int hfi1_make_rc_req(struct rvt_qp *qp,
 				qp->s_flags |= RVT_S_WAIT_SSN_CREDIT;
 				goto bail;
 			}
+no_flow_control:
 			put_ib_reth_vaddr(
 				wqe->rdma_wr.remote_addr,
 				&ohdr->u.rc.reth);
drivers/infiniband/hw/qib/qib_rc.c +2 -2
@@ -348,7 +348,7 @@ int qib_make_rc_req(struct rvt_qp *qp, u
 		case IB_WR_RDMA_WRITE:
 			if (newreq && !(qp->s_flags & RVT_S_UNLIMITED_CREDIT))
 				qp->s_lsn++;
-			/* FALLTHROUGH */
+			goto no_flow_control;
 		case IB_WR_RDMA_WRITE_WITH_IMM:
 			/* If no credit, return. */
 			if (!(qp->s_flags & RVT_S_UNLIMITED_CREDIT) &&
@@ -356,7 +356,7 @@ int qib_make_rc_req(struct rvt_qp *qp, u
 				qp->s_flags |= RVT_S_WAIT_SSN_CREDIT;
 				goto bail;
 			}
-
+no_flow_control:
 			ohdr->u.rc.reth.vaddr =
 				cpu_to_be64(wqe->rdma_wr.remote_addr);
 			ohdr->u.rc.reth.rkey =
author maintainer
#6 lore raw

PATCH 5/109 IB/mlx5: Fix cached MR allocation flow

In reply to Greg Kroah-Hartman

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

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

From: Majd Dibbiny <[email protected]>

commit 4c25b7a39005c9243a492b577c3e940eeac36a25 upstream.

When we have a miss in one order of the mkey cache, we try to get an mkey from a higher order.

We still need to check that the higher order can be used with UMR before using it. Otherwise, we will get an mkey with 0 entries and the post send operation that is used to fill it will complete with the following error:

mlx5_0:dump_cqe:275:(pid 0): dump error cqe
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 0f007806 25000025 49ce59d2

Fixes 49780d42dfc9 ("IB/mlx5: Expose MR cache for mlx5_ib")
---
 drivers/infiniband/hw/mlx5/mr.c |   18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)
drivers/infiniband/hw/mlx5/mr.c +13 -5
@@ -48,6 +48,7 @@ enum {
 #define MLX5_UMR_ALIGN 2048
 
 static int clean_mr(struct mlx5_ib_mr *mr);
+static int max_umr_order(struct mlx5_ib_dev *dev);
 static int use_umr(struct mlx5_ib_dev *dev, int order);
 static int unreg_umr(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr);
 
@@ -491,16 +492,18 @@ static struct mlx5_ib_mr *alloc_cached_m
 	struct mlx5_mr_cache *cache = &dev->cache;
 	struct mlx5_ib_mr *mr = NULL;
 	struct mlx5_cache_ent *ent;
+	int last_umr_cache_entry;
 	int c;
 	int i;
 
 	c = order2idx(dev, order);
-	if (c < 0 || c > MAX_UMR_CACHE_ENTRY) {
+	last_umr_cache_entry = order2idx(dev, max_umr_order(dev));
+	if (c < 0 || c > last_umr_cache_entry) {
 		mlx5_ib_warn(dev, "order %d, cache index %d\n", order, c);
 		return NULL;
 	}
 
-	for (i = c; i < MAX_UMR_CACHE_ENTRY; i++) {
+	for (i = c; i <= last_umr_cache_entry; i++) {
 		ent = &cache->ent[i];
 
 		mlx5_ib_dbg(dev, "order %d, cache index %d\n", ent->order, i);
@@ -816,11 +819,16 @@ static int get_octo_len(u64 addr, u64 le
 	return (npages + 1) / 2;
 }
 
-static int use_umr(struct mlx5_ib_dev *dev, int order)
+static int max_umr_order(struct mlx5_ib_dev *dev)
 {
 	if (MLX5_CAP_GEN(dev->mdev, umr_extended_translation_offset))
-		return order <= MAX_UMR_CACHE_ENTRY + 2;
-	return order <= MLX5_MAX_UMR_SHIFT;
+		return MAX_UMR_CACHE_ENTRY + 2;
+	return MLX5_MAX_UMR_SHIFT;
+}
+
+static int use_umr(struct mlx5_ib_dev *dev, int order)
+{
+	return order <= max_umr_order(dev);
 }
 
 static int mr_umem_get(struct ib_pd *pd, u64 start, u64 length,
author maintainer
#7 lore raw

PATCH 6/109 srcu: Provide ordering for CPU not involved in grace period

In reply to Greg Kroah-Hartman

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

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

From: Paul E. McKenney <[email protected]>

commit 35732cf9dd38b1efb0f2f22c91c61b51337d1ac3 upstream.

Tree RCU guarantees that every online CPU has a memory barrier between any given grace period and any of that CPU's RCU read-side sections that must be ordered against that grace period. Since RCU doesn't always know where read-side critical sections are, the actual implementation guarantees order against prior and subsequent non-idle non-offline code, whether in an RCU read-side critical section or not. As a result, there does not need to be a memory barrier at the end of synchronize_rcu() and friends because the ordering internal to the grace period has ordered every CPU's post-grace-period execution against each CPU's pre-grace-period execution, again for all non-idle online CPUs.

In contrast, SRCU can have non-idle online CPUs that are completely uninvolved in a given SRCU grace period, for example, a CPU that never runs any SRCU read-side critical sections and took no part in the grace-period processing. It is in theory possible for a given synchronize_srcu()'s wakeup to be delivered to a CPU that was completely uninvolved in the prior SRCU grace period, which could mean that the code following that synchronize_srcu() would end up being unordered with respect to both the grace period and any pre-existing SRCU read-side critical sections.

This commit therefore adds an smp_mb() to the end of __synchronize_srcu(), which prevents this scenario from occurring.

---
 kernel/rcu/srcutree.c |    9 +++++++++
 1 file changed, 9 insertions(+)
kernel/rcu/srcutree.c +9 -0
@@ -896,6 +896,15 @@ static void __synchronize_srcu(struct sr
 	__call_srcu(sp, &rcu.head, wakeme_after_rcu, do_norm);
 	wait_for_completion(&rcu.completion);
 	destroy_rcu_head_on_stack(&rcu.head);
+
+	/*
+	 * Make sure that later code is ordered after the SRCU grace
+	 * period.  This pairs with the raw_spin_lock_irq_rcu_node()
+	 * in srcu_invoke_callbacks().  Unlike Tree RCU, this is needed
+	 * because the current CPU might have been totally uninvolved with
+	 * (and thus unordered against) that grace period.
+	 */
+	smp_mb();
 }
 
 /**
author maintainer
#8 lore raw

PATCH 7/109 smp/hotplug: Handle removal correctly in cpuhp_store_callbacks()

In reply to Greg Kroah-Hartman

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

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

From: Ethan Barnes <[email protected]>

commit 0c96b27305faf06c068b45e07d28336c80dac286 upstream.

If cpuhp_store_callbacks() is called for CPUHP_AP_ONLINE_DYN or CPUHP_BP_PREPARE_DYN, which are the indicators for dynamically allocated states, then cpuhp_store_callbacks() allocates a new dynamic state. The first allocation in each range returns CPUHP_AP_ONLINE_DYN or CPUHP_BP_PREPARE_DYN.

If cpuhp_remove_state() is invoked for one of these states, then there is no protection against the allocation mechanism. So the removal, which should clear the callbacks and the name, gets a new state assigned and clears that one.

As a consequence the state which should be cleared stays initialized. A consecutive CPU hotplug operation dereferences the state callbacks and accesses either freed or reused memory, resulting in crashes.

Add a protection against this by checking the name argument for NULL. If it's NULL it's a removal. If not, it's an allocation.

[ tglx: Added a comment and massaged changelog ]

Fixes 5b7aa87e0482 ("cpu/hotplug: Implement setup/removal interface")
Cc Ingo Molnar <[email protected]>
Cc "Srivatsa S. Bhat" <[email protected]>
Cc Sebastian Siewior <[email protected]>
Cc Paul McKenney <[email protected]>
---
 kernel/cpu.c |   12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)
kernel/cpu.c +11 -1
@@ -1252,7 +1252,17 @@ static int cpuhp_store_callbacks(enum cp
 	struct cpuhp_step *sp;
 	int ret = 0;
 
-	if (state == CPUHP_AP_ONLINE_DYN || state == CPUHP_BP_PREPARE_DYN) {
+	/*
+	 * If name is NULL, then the state gets removed.
+	 *
+	 * CPUHP_AP_ONLINE_DYN and CPUHP_BP_PREPARE_DYN are handed out on
+	 * the first allocation from these dynamic ranges, so the removal
+	 * would trigger a new allocation and clear the wrong (already
+	 * empty) state, leaving the callbacks of the to be cleared state
+	 * dangling, which causes wreckage on the next hotplug operation.
+	 */
+	if (name && (state == CPUHP_AP_ONLINE_DYN ||
+		     state == CPUHP_BP_PREPARE_DYN)) {
 		ret = cpuhp_reserve_state(state);
 		if (ret < 0)
 			return ret;
author maintainer
#9 lore raw

PATCH 8/109 Input: xpad - validate USB endpoint type during probe

In reply to Greg Kroah-Hartman

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

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

From: Cameron Gutman <[email protected]>

commit 122d6a347329818419b032c5a1776e6b3866d9b9 upstream.

We should only see devices with interrupt endpoints. Ignore any other endpoints that we find, so we don't send try to send them interrupt URBs and trigger a WARN down in the USB stack.

---
 drivers/input/joystick/xpad.c |   10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/input/joystick/xpad.c +6 -4
@@ -1764,10 +1764,12 @@ static int xpad_probe(struct usb_interfa
 		struct usb_endpoint_descriptor *ep =
 				&intf->cur_altsetting->endpoint[i].desc;
 
-		if (usb_endpoint_dir_in(ep))
-			ep_irq_in = ep;
-		else
-			ep_irq_out = ep;
+		if (usb_endpoint_xfer_int(ep)) {
+			if (usb_endpoint_dir_in(ep))
+				ep_irq_in = ep;
+			else
+				ep_irq_out = ep;
+		}
 	}
 
 	if (!ep_irq_in || !ep_irq_out) {
author maintainer
#10 lore raw

PATCH 9/109 drm/amdgpu: read reg in each iterator of psp_wait_for loop

In reply to Greg Kroah-Hartman

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

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

From: Zhang, Jerry <[email protected]>

commit 2890decfd9969cac21067ca0c734fbccaf74d634 upstream.

v2: fix the SOS loading failure for PSP v3.1

---
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c |    3 +--
 drivers/gpu/drm/amd/amdgpu/psp_v3_1.c   |    2 --
 2 files changed, 1 insertion(+), 4 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +1 -2
@@ -95,9 +95,8 @@ int psp_wait_for(struct psp_context *psp
 	int i;
 	struct amdgpu_device *adev = psp->adev;
 
-	val = RREG32(reg_index);
-
 	for (i = 0; i < adev->usec_timeout; i++) {
+		val = RREG32(reg_index);
 		if (check_changed) {
 			if (val != reg_val)
 				return 0;
drivers/gpu/drm/amd/amdgpu/psp_v3_1.c +0 -2
@@ -237,11 +237,9 @@ int psp_v3_1_bootloader_load_sos(struct
 
 	/* there might be handshake issue with hardware which needs delay */
 	mdelay(20);
-#if 0
 	ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_81),
 			   RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81),
 			   0, true);
-#endif
 
 	return ret;
 }
author maintainer
#32 lore raw

PATCH 26/109 MIPS: math-emu: <MADDF|MSUBF>.<D|S>: Clean up "maddf_flags" enumeration

In reply to Greg Kroah-Hartman

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

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

From: Aleksandar Markovic <[email protected]>

commit ae11c0619973ffd73a496308d8a1cb5e1a353737 upstream.

Fix definition and usage of "maddf_flags" enumeration. Avoid duplicate definition and apply more common capitalization.

This patch does not change any scenario. It just makes MADDF and MSUBF emulation code more readable and easier to maintain, and hopefully prevents future bugs as well.

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

---
 arch/mips/math-emu/dp_maddf.c   |   19 ++++++++-----------
 arch/mips/math-emu/ieee754int.h |    4 ++++
 arch/mips/math-emu/sp_maddf.c   |   19 ++++++++-----------
 3 files changed, 20 insertions(+), 22 deletions(-)
arch/mips/math-emu/dp_maddf.c +8 -11
@@ -14,9 +14,6 @@
 
 #include "ieee754dp.h"
 
-enum maddf_flags {
-	maddf_negate_product	= 1 << 0,
-};
 
 static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x,
 				 union ieee754dp y, enum maddf_flags flags)
@@ -85,8 +82,8 @@ static union ieee754dp _dp_maddf(union i
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
 		if ((zc == IEEE754_CLASS_INF) &&
-		    ((!(flags & maddf_negate_product) && (zs != (xs ^ ys))) ||
-		     ((flags & maddf_negate_product) && (zs == (xs ^ ys))))) {
+		    ((!(flags & MADDF_NEGATE_PRODUCT) && (zs != (xs ^ ys))) ||
+		     ((flags & MADDF_NEGATE_PRODUCT) && (zs == (xs ^ ys))))) {
 			/*
 			 * Cases of addition of infinities with opposite signs
 			 * or subtraction of infinities with same signs.
@@ -99,9 +96,9 @@ static union ieee754dp _dp_maddf(union i
 		 * same sign as product (x*y) (in case of MADDF.D instruction)
 		 * or product -(x*y) (in MSUBF.D case). The result must be an
 		 * infinity, and its sign is determined only by the value of
-		 * (flags & maddf_negate_product) and the signs of x and y.
+		 * (flags & MADDF_NEGATE_PRODUCT) and the signs of x and y.
 		 */
-		if (flags & maddf_negate_product)
+		if (flags & MADDF_NEGATE_PRODUCT)
 			return ieee754dp_inf(1 ^ (xs ^ ys));
 		else
 			return ieee754dp_inf(xs ^ ys);
@@ -115,9 +112,9 @@ static union ieee754dp _dp_maddf(union i
 			return ieee754dp_inf(zs);
 		if (zc == IEEE754_CLASS_ZERO) {
 			/* Handle cases +0 + (-0) and similar ones. */
-			if ((!(flags & maddf_negate_product)
+			if ((!(flags & MADDF_NEGATE_PRODUCT)
 					&& (zs == (xs ^ ys))) ||
-			    ((flags & maddf_negate_product)
+			    ((flags & MADDF_NEGATE_PRODUCT)
 					&& (zs != (xs ^ ys))))
 				/*
 				 * Cases of addition of zeros of equal signs
@@ -167,7 +164,7 @@ static union ieee754dp _dp_maddf(union i
 
 	re = xe + ye;
 	rs = xs ^ ys;
-	if (flags & maddf_negate_product)
+	if (flags & MADDF_NEGATE_PRODUCT)
 		rs ^= 1;
 
 	/* shunt to top of word */
@@ -291,5 +288,5 @@ union ieee754dp ieee754dp_maddf(union ie
 union ieee754dp ieee754dp_msubf(union ieee754dp z, union ieee754dp x,
 				union ieee754dp y)
 {
-	return _dp_maddf(z, x, y, maddf_negate_product);
+	return _dp_maddf(z, x, y, MADDF_NEGATE_PRODUCT);
 }
arch/mips/math-emu/ieee754int.h +4 -0
@@ -26,6 +26,10 @@
 
 #define CLPAIR(x, y)	((x)*6+(y))
 
+enum maddf_flags {
+	MADDF_NEGATE_PRODUCT	= 1 << 0,
+};
+
 static inline void ieee754_clearcx(void)
 {
 	ieee754_csr.cx = 0;
arch/mips/math-emu/sp_maddf.c +8 -11
@@ -14,9 +14,6 @@
 
 #include "ieee754sp.h"
 
-enum maddf_flags {
-	maddf_negate_product	= 1 << 0,
-};
 
 static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x,
 				 union ieee754sp y, enum maddf_flags flags)
@@ -86,8 +83,8 @@ static union ieee754sp _sp_maddf(union i
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
 		if ((zc == IEEE754_CLASS_INF) &&
-		    ((!(flags & maddf_negate_product) && (zs != (xs ^ ys))) ||
-		     ((flags & maddf_negate_product) && (zs == (xs ^ ys))))) {
+		    ((!(flags & MADDF_NEGATE_PRODUCT) && (zs != (xs ^ ys))) ||
+		     ((flags & MADDF_NEGATE_PRODUCT) && (zs == (xs ^ ys))))) {
 			/*
 			 * Cases of addition of infinities with opposite signs
 			 * or subtraction of infinities with same signs.
@@ -100,9 +97,9 @@ static union ieee754sp _sp_maddf(union i
 		 * same sign as product (x*y) (in case of MADDF.D instruction)
 		 * or product -(x*y) (in MSUBF.D case). The result must be an
 		 * infinity, and its sign is determined only by the value of
-		 * (flags & maddf_negate_product) and the signs of x and y.
+		 * (flags & MADDF_NEGATE_PRODUCT) and the signs of x and y.
 		 */
-		if (flags & maddf_negate_product)
+		if (flags & MADDF_NEGATE_PRODUCT)
 			return ieee754sp_inf(1 ^ (xs ^ ys));
 		else
 			return ieee754sp_inf(xs ^ ys);
@@ -116,9 +113,9 @@ static union ieee754sp _sp_maddf(union i
 			return ieee754sp_inf(zs);
 		if (zc == IEEE754_CLASS_ZERO) {
 			/* Handle cases +0 + (-0) and similar ones. */
-			if ((!(flags & maddf_negate_product)
+			if ((!(flags & MADDF_NEGATE_PRODUCT)
 					&& (zs == (xs ^ ys))) ||
-			    ((flags & maddf_negate_product)
+			    ((flags & MADDF_NEGATE_PRODUCT)
 					&& (zs != (xs ^ ys))))
 				/*
 				 * Cases of addition of zeros of equal signs
@@ -170,7 +167,7 @@ static union ieee754sp _sp_maddf(union i
 
 	re = xe + ye;
 	rs = xs ^ ys;
-	if (flags & maddf_negate_product)
+	if (flags & MADDF_NEGATE_PRODUCT)
 		rs ^= 1;
 
 	/* shunt to top of word */
@@ -287,5 +284,5 @@ union ieee754sp ieee754sp_maddf(union ie
 union ieee754sp ieee754sp_msubf(union ieee754sp z, union ieee754sp x,
 				union ieee754sp y)
 {
-	return _sp_maddf(z, x, y, maddf_negate_product);
+	return _sp_maddf(z, x, y, MADDF_NEGATE_PRODUCT);
 }
author maintainer
#39 lore raw

PATCH 35/109 regulator: cpcap: Fix standby mode

In reply to Greg Kroah-Hartman

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

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

From: Sebastian Reichel <[email protected]>

commit 91a024e80336528d12b67b5a2e636b9e4467d3ec upstream.

The original patch from Tony uses standby mode bit inverted, which is not correct. This fixes all instances in the driver code for get & set mode. This did not yet make problems, since mode has not been changed by any mainline driver so far.

Fixes 0ad4c07edd41 ("regulator: cpcap: Add basic regulator support")
---
 drivers/regulator/cpcap-regulator.c |    8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/regulator/cpcap-regulator.c +5 -3
@@ -77,6 +77,8 @@
 #define CPCAP_BIT_VAUDIO_MODE0		BIT(1)
 #define CPCAP_BIT_V_AUDIO_EN		BIT(0)
 
+#define CPCAP_BIT_AUDIO_NORMAL_MODE	0x00
+
 /*
  * Off mode configuration bit. Used currently only by SW5 on omap4. There's
  * the following comment in Motorola Linux kernel tree for it:
@@ -217,7 +219,7 @@ static unsigned int cpcap_regulator_get_
 
 	regmap_read(rdev->regmap, rdev->desc->enable_reg, &value);
 
-	if (!(value & CPCAP_BIT_AUDIO_LOW_PWR))
+	if (value & CPCAP_BIT_AUDIO_LOW_PWR)
 		return REGULATOR_MODE_STANDBY;
 
 	return REGULATOR_MODE_NORMAL;
@@ -230,10 +232,10 @@ static int cpcap_regulator_set_mode(stru
 
 	switch (mode) {
 	case REGULATOR_MODE_NORMAL:
-		value = CPCAP_BIT_AUDIO_LOW_PWR;
+		value = CPCAP_BIT_AUDIO_NORMAL_MODE;
 		break;
 	case REGULATOR_MODE_STANDBY:
-		value = 0;
+		value = CPCAP_BIT_AUDIO_LOW_PWR;
 		break;
 	default:
 		return -EINVAL;
author maintainer
#40 lore raw

PATCH 36/109 wcn36xx: Introduce mutual exclusion of fw configuration

In reply to Greg Kroah-Hartman

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

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

From: Bjorn Andersson <[email protected]>

commit 39efc7cc7ccf82d1cd946580cdb70760f347305a upstream.

As the association status changes the driver needs to configure the hardware. This is done based on information in the "sta" acquired by ieee80211_find_sta(), which requires the caller to ensure that the "sta" is valid while its being used; generally by entering an rcu read section.

But the operations acting on the "sta" has to communicate with the firmware and may therefor sleep, resulting in the following report:

[   31.418190] BUG: sleeping function called from invalid context at
kernel/locking/mutex.c:238
[   31.425919] in_atomic(): 0, irqs_disabled(): 0, pid: 34, name:
kworker/u8:1
[   31.434609] CPU: 0 PID: 34 Comm: kworker/u8:1 Tainted: G        W
4.12.0-rc4-next-20170607+ #993
[   31.441002] Hardware name: Qualcomm Technologies, Inc. APQ 8016 SBC
(DT)
[   31.450380] Workqueue: phy0 ieee80211_iface_work
[   31.457226] Call trace:
[   31.461830] [<ffffff8008088c58>] dump_backtrace+0x0/0x260
[   31.464004] [<ffffff8008088f7c>] show_stack+0x14/0x20
[   31.469557] [<ffffff8008392e70>] dump_stack+0x98/0xb8
[   31.474592] [<ffffff80080e4330>] ___might_sleep+0xf0/0x118
[   31.479626] [<ffffff80080e43a8>] __might_sleep+0x50/0x88
[   31.485010] [<ffffff80088ff9a4>] mutex_lock+0x24/0x60
[   31.490479] [<ffffff8008595c38>] wcn36xx_smd_set_link_st+0x30/0x130
[   31.495428] [<ffffff8008591ed8>] wcn36xx_bss_info_changed+0x148/0x448
[   31.501504] [<ffffff80088ab3c4>]
ieee80211_bss_info_change_notify+0xbc/0x118
[   31.508102] [<ffffff80088f841c>] ieee80211_assoc_success+0x664/0x7f8
[   31.515220] [<ffffff80088e13d4>]
ieee80211_rx_mgmt_assoc_resp+0x144/0x2d8
[   31.521555] [<ffffff80088e1e20>]
ieee80211_sta_rx_queued_mgmt+0x190/0x698
[   31.528239] [<ffffff80088bc44c>] ieee80211_iface_work+0x234/0x368
[   31.535011] [<ffffff80080d81ac>] process_one_work+0x1cc/0x340
[   31.541086] [<ffffff80080d8368>] worker_thread+0x48/0x430
[   31.546814] [<ffffff80080de448>] kthread+0x108/0x138
[   31.552195] [<ffffff8008082ec0>] ret_from_fork+0x10/0x50

In order to ensure that the "sta" remains alive (and consistent) for the duration of bss_info_changed() mutual exclusion has to be ensured with sta_remove().

This is done by introducing a mutex to cover firmware configuration changes, which is made to also ensure mutual exclusion between other operations changing the state or configuration of the firmware. With this we can drop the rcu read lock.

---
 drivers/net/wireless/ath/wcn36xx/main.c    |   52 +++++++++++++++++++++++++++--
 drivers/net/wireless/ath/wcn36xx/wcn36xx.h |    3 +
 2 files changed, 53 insertions(+), 2 deletions(-)
drivers/net/wireless/ath/wcn36xx/main.c +50 -2
@@ -372,6 +372,8 @@ static int wcn36xx_config(struct ieee802
 
 	wcn36xx_dbg(WCN36XX_DBG_MAC, "mac config changed 0x%08x\n", changed);
 
+	mutex_lock(&wcn->conf_mutex);
+
 	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
 		int ch = WCN36XX_HW_CHANNEL(wcn);
 		wcn36xx_dbg(WCN36XX_DBG_MAC, "wcn36xx_config channel switch=%d\n",
@@ -382,6 +384,8 @@ static int wcn36xx_config(struct ieee802
 		}
 	}
 
+	mutex_unlock(&wcn->conf_mutex);
+
 	return 0;
 }
 
@@ -396,6 +400,8 @@ static void wcn36xx_configure_filter(str
 
 	wcn36xx_dbg(WCN36XX_DBG_MAC, "mac configure filter\n");
 
+	mutex_lock(&wcn->conf_mutex);
+
 	*total &= FIF_ALLMULTI;
 
 	fp = (void *)(unsigned long)multicast;
@@ -408,6 +414,8 @@ static void wcn36xx_configure_filter(str
 		else if (NL80211_IFTYPE_STATION == vif->type && tmp->sta_assoc)
 			wcn36xx_smd_set_mc_list(wcn, vif, fp);
 	}
+
+	mutex_unlock(&wcn->conf_mutex);
 	kfree(fp);
 }
 
@@ -471,6 +479,8 @@ static int wcn36xx_set_key(struct ieee80
 			 key_conf->key,
 			 key_conf->keylen);
 
+	mutex_lock(&wcn->conf_mutex);
+
 	switch (key_conf->cipher) {
 	case WLAN_CIPHER_SUITE_WEP40:
 		vif_priv->encrypt_type = WCN36XX_HAL_ED_WEP40;
@@ -565,6 +575,8 @@ static int wcn36xx_set_key(struct ieee80
 	}
 
 out:
+	mutex_unlock(&wcn->conf_mutex);
+
 	return ret;
 }
 
@@ -725,6 +737,8 @@ static void wcn36xx_bss_info_changed(str
 	wcn36xx_dbg(WCN36XX_DBG_MAC, "mac bss info changed vif %p changed 0x%08x\n",
 		    vif, changed);
 
+	mutex_lock(&wcn->conf_mutex);
+
 	if (changed & BSS_CHANGED_BEACON_INFO) {
 		wcn36xx_dbg(WCN36XX_DBG_MAC,
 			    "mac bss changed dtim period %d\n",
@@ -787,7 +801,13 @@ static void wcn36xx_bss_info_changed(str
 				     bss_conf->aid);
 
 			vif_priv->sta_assoc = true;
-			rcu_read_lock();
+
+			/*
+			 * Holding conf_mutex ensures mutal exclusion with
+			 * wcn36xx_sta_remove() and as such ensures that sta
+			 * won't be freed while we're operating on it. As such
+			 * we do not need to hold the rcu_read_lock().
+			 */
 			sta = ieee80211_find_sta(vif, bss_conf->bssid);
 			if (!sta) {
 				wcn36xx_err("sta %pM is not found\n",
@@ -811,7 +831,6 @@ static void wcn36xx_bss_info_changed(str
 			 * place where AID is available.
 			 */
 			wcn36xx_smd_config_sta(wcn, vif, sta);
-			rcu_read_unlock();
 		} else {
 			wcn36xx_dbg(WCN36XX_DBG_MAC,
 				    "disassociated bss %pM vif %pM AID=%d\n",
@@ -873,6 +892,9 @@ static void wcn36xx_bss_info_changed(str
 		}
 	}
 out:
+
+	mutex_unlock(&wcn->conf_mutex);
+
 	return;
 }
 
@@ -882,7 +904,10 @@ static int wcn36xx_set_rts_threshold(str
 	struct wcn36xx *wcn = hw->priv;
 	wcn36xx_dbg(WCN36XX_DBG_MAC, "mac set RTS threshold %d\n", value);
 
+	mutex_lock(&wcn->conf_mutex);
 	wcn36xx_smd_update_cfg(wcn, WCN36XX_HAL_CFG_RTS_THRESHOLD, value);
+	mutex_unlock(&wcn->conf_mutex);
+
 	return 0;
 }
 
@@ -893,8 +918,12 @@ static void wcn36xx_remove_interface(str
 	struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif);
 	wcn36xx_dbg(WCN36XX_DBG_MAC, "mac remove interface vif %p\n", vif);
 
+	mutex_lock(&wcn->conf_mutex);
+
 	list_del(&vif_priv->list);
 	wcn36xx_smd_delete_sta_self(wcn, vif->addr);
+
+	mutex_unlock(&wcn->conf_mutex);
 }
 
 static int wcn36xx_add_interface(struct ieee80211_hw *hw,
@@ -915,9 +944,13 @@ static int wcn36xx_add_interface(struct
 		return -EOPNOTSUPP;
 	}
 
+	mutex_lock(&wcn->conf_mutex);
+
 	list_add(&vif_priv->list, &wcn->vif_list);
 	wcn36xx_smd_add_sta_self(wcn, vif);
 
+	mutex_unlock(&wcn->conf_mutex);
+
 	return 0;
 }
 
@@ -930,6 +963,8 @@ static int wcn36xx_sta_add(struct ieee80
 	wcn36xx_dbg(WCN36XX_DBG_MAC, "mac sta add vif %p sta %pM\n",
 		    vif, sta->addr);
 
+	mutex_lock(&wcn->conf_mutex);
+
 	spin_lock_init(&sta_priv->ampdu_lock);
 	sta_priv->vif = vif_priv;
 	/*
@@ -941,6 +976,9 @@ static int wcn36xx_sta_add(struct ieee80
 		sta_priv->aid = sta->aid;
 		wcn36xx_smd_config_sta(wcn, vif, sta);
 	}
+
+	mutex_unlock(&wcn->conf_mutex);
+
 	return 0;
 }
 
@@ -954,8 +992,13 @@ static int wcn36xx_sta_remove(struct iee
 	wcn36xx_dbg(WCN36XX_DBG_MAC, "mac sta remove vif %p sta %pM index %d\n",
 		    vif, sta->addr, sta_priv->sta_index);
 
+	mutex_lock(&wcn->conf_mutex);
+
 	wcn36xx_smd_delete_sta(wcn, sta_priv->sta_index);
 	sta_priv->vif = NULL;
+
+	mutex_unlock(&wcn->conf_mutex);
+
 	return 0;
 }
 
@@ -999,6 +1042,8 @@ static int wcn36xx_ampdu_action(struct i
 	wcn36xx_dbg(WCN36XX_DBG_MAC, "mac ampdu action action %d tid %d\n",
 		    action, tid);
 
+	mutex_lock(&wcn->conf_mutex);
+
 	switch (action) {
 	case IEEE80211_AMPDU_RX_START:
 		sta_priv->tid = tid;
@@ -1038,6 +1083,8 @@ static int wcn36xx_ampdu_action(struct i
 		wcn36xx_err("Unknown AMPDU action\n");
 	}
 
+	mutex_unlock(&wcn->conf_mutex);
+
 	return 0;
 }
 
@@ -1216,6 +1263,7 @@ static int wcn36xx_probe(struct platform
 	wcn = hw->priv;
 	wcn->hw = hw;
 	wcn->dev = &pdev->dev;
+	mutex_init(&wcn->conf_mutex);
 	mutex_init(&wcn->hal_mutex);
 	mutex_init(&wcn->scan_lock);
 
drivers/net/wireless/ath/wcn36xx/wcn36xx.h +3 -0
@@ -202,6 +202,9 @@ struct wcn36xx {
 	struct qcom_smem_state	*tx_rings_empty_state;
 	unsigned		tx_rings_empty_state_bit;
 
+	/* prevents concurrent FW reconfiguration */
+	struct mutex		conf_mutex;
+
 	/*
 	 * smd_buf must be protected with smd_mutex to garantee
 	 * that all messages are sent one after another
author maintainer
#41 lore raw

PATCH 37/109 ext4: in ext4_seek_{hole,data}, return -ENXIO for negative offsets

In reply to Greg Kroah-Hartman

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

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

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

commit 1bd8d6cd3e413d64e543ec3e69ff43e75a1cf1ea upstream.

In the ext4 implementations of SEEK_HOLE and SEEK_DATA, make sure we return -ENXIO for negative offsets instead of banging around inside the extent code and returning -EFSCORRUPTED.

---
 fs/ext4/file.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
fs/ext4/file.c +2 -2
@@ -595,7 +595,7 @@ static loff_t ext4_seek_data(struct file
 	inode_lock(inode);
 
 	isize = i_size_read(inode);
-	if (offset >= isize) {
+	if (offset < 0 || offset >= isize) {
 		inode_unlock(inode);
 		return -ENXIO;
 	}
@@ -658,7 +658,7 @@ static loff_t ext4_seek_hole(struct file
 	inode_lock(inode);
 
 	isize = i_size_read(inode);
-	if (offset >= isize) {
+	if (offset < 0 || offset >= isize) {
 		inode_unlock(inode);
 		return -ENXIO;
 	}
author maintainer
#42 lore raw

PATCH 38/109 ext4: fix incorrect quotaoff if the quota feature is enabled

In reply to Greg Kroah-Hartman

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

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

From: zhangyi (F) <[email protected]>

commit b0a5a9589decd07db755d6a8d9c0910d96ff7992 upstream.

Current ext4 quota should always "usage enabled" if the quota feautre is enabled. But in ext4_orphan_cleanup(), it turn quotas off directly (used for the older journaled quota), so we cannot turn it on again via "quotaon" unless umount and remount ext4.

Simple reproduce:

mkfs.ext4 -O project,quota /dev/vdb1
mount -o prjquota /dev/vdb1 /mnt
chattr -p 123 /mnt
chattr +P /mnt
touch /mnt/aa /mnt/bb
exec 100<>/mnt/aa
rm -f /mnt/aa
sync
echo c > /proc/sysrq-trigger

#reboot and mount
mount -o prjquota /dev/vdb1 /mnt
#query status
quotaon -Ppv /dev/vdb1
#output
quotaon: Cannot find mountpoint for device /dev/vdb1
quotaon: No correct mountpoint specified.

This patch add check for journaled quotas to avoid incorrect quotaoff when ext4 has quota feautre.

---
 fs/ext4/super.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
fs/ext4/super.c +3 -3
@@ -2442,7 +2442,7 @@ static void ext4_orphan_cleanup(struct s
 #ifdef CONFIG_QUOTA
 	/* Needed for iput() to work correctly and not trash data */
 	sb->s_flags |= MS_ACTIVE;
-	/* Turn on quotas so that they are updated correctly */
+	/* Turn on journaled quotas so that they are updated correctly */
 	for (i = 0; i < EXT4_MAXQUOTAS; i++) {
 		if (EXT4_SB(sb)->s_qf_names[i]) {
 			int ret = ext4_quota_on_mount(sb, i);
@@ -2510,9 +2510,9 @@ static void ext4_orphan_cleanup(struct s
 		ext4_msg(sb, KERN_INFO, "%d truncate%s cleaned up",
 		       PLURAL(nr_truncates));
 #ifdef CONFIG_QUOTA
-	/* Turn quotas off */
+	/* Turn off journaled quotas if they were enabled for orphan cleanup */
 	for (i = 0; i < EXT4_MAXQUOTAS; i++) {
-		if (sb_dqopt(sb)->files[i])
+		if (EXT4_SB(sb)->s_qf_names[i] && sb_dqopt(sb)->files[i])
 			dquot_quota_off(sb, i);
 	}
 #endif
author maintainer
#43 lore raw

PATCH 39/109 ext4: fix quota inconsistency during orphan cleanup for read-only mounts

In reply to Greg Kroah-Hartman

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

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

From: zhangyi (F) <[email protected]>

commit 95f1fda47c9d8738f858c3861add7bf0a36a7c0b upstream.

Quota does not get enabled for read-only mounts if filesystem has quota feature, so that quotas cannot updated during orphan cleanup, which will lead to quota inconsistency.

This patch turn on quotas during orphan cleanup for this case, make sure quotas can be updated correctly.

---
 fs/ext4/super.c |   38 +++++++++++++++++++++++++++++++-------
 1 file changed, 31 insertions(+), 7 deletions(-)
fs/ext4/super.c +31 -7
@@ -2404,6 +2404,7 @@ static void ext4_orphan_cleanup(struct s
 	unsigned int s_flags = sb->s_flags;
 	int ret, nr_orphans = 0, nr_truncates = 0;
 #ifdef CONFIG_QUOTA
+	int quota_update = 0;
 	int i;
 #endif
 	if (!es->s_last_orphan) {
@@ -2442,14 +2443,32 @@ static void ext4_orphan_cleanup(struct s
 #ifdef CONFIG_QUOTA
 	/* Needed for iput() to work correctly and not trash data */
 	sb->s_flags |= MS_ACTIVE;
-	/* Turn on journaled quotas so that they are updated correctly */
+
+	/*
+	 * Turn on quotas which were not enabled for read-only mounts if
+	 * filesystem has quota feature, so that they are updated correctly.
+	 */
+	if (ext4_has_feature_quota(sb) && (s_flags & MS_RDONLY)) {
+		int ret = ext4_enable_quotas(sb);
+
+		if (!ret)
+			quota_update = 1;
+		else
+			ext4_msg(sb, KERN_ERR,
+				"Cannot turn on quotas: error %d", ret);
+	}
+
+	/* Turn on journaled quotas used for old sytle */
 	for (i = 0; i < EXT4_MAXQUOTAS; i++) {
 		if (EXT4_SB(sb)->s_qf_names[i]) {
 			int ret = ext4_quota_on_mount(sb, i);
-			if (ret < 0)
+
+			if (!ret)
+				quota_update = 1;
+			else
 				ext4_msg(sb, KERN_ERR,
 					"Cannot turn on journaled "
-					"quota: error %d", ret);
+					"quota: type %d: error %d", i, ret);
 		}
 	}
 #endif
@@ -2510,10 +2529,12 @@ static void ext4_orphan_cleanup(struct s
 		ext4_msg(sb, KERN_INFO, "%d truncate%s cleaned up",
 		       PLURAL(nr_truncates));
 #ifdef CONFIG_QUOTA
-	/* Turn off journaled quotas if they were enabled for orphan cleanup */
-	for (i = 0; i < EXT4_MAXQUOTAS; i++) {
-		if (EXT4_SB(sb)->s_qf_names[i] && sb_dqopt(sb)->files[i])
-			dquot_quota_off(sb, i);
+	/* Turn off quotas if they were enabled for orphan cleanup */
+	if (quota_update) {
+		for (i = 0; i < EXT4_MAXQUOTAS; i++) {
+			if (sb_dqopt(sb)->files[i])
+				dquot_quota_off(sb, i);
+		}
 	}
 #endif
 	sb->s_flags = s_flags; /* Restore MS_RDONLY status */
@@ -5512,6 +5533,9 @@ static int ext4_enable_quotas(struct sup
 				DQUOT_USAGE_ENABLED |
 				(quota_mopt[type] ? DQUOT_LIMITS_ENABLED : 0));
 			if (err) {
+				for (type--; type >= 0; type--)
+					dquot_quota_off(sb, type);
+
 				ext4_warning(sb,
 					"Failed to enable quota tracking "
 					"(type=%d, err=%d). Please run "
author maintainer
#44 lore raw

PATCH 40/109 cxl: Fix driver use count

In reply to Greg Kroah-Hartman

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

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

From: Frederic Barrat <[email protected]>

commit 197267d0356004a31c4d6b6336598f5dff3301e1 upstream.

cxl keeps a driver use count, which is used with the hash memory model on p8 to know when to upgrade local TLBIs to global and to trigger callbacks to manage the MMU for PSL8.

If a process opens a context and closes without attaching or fails the attachment, the driver use count is never decremented. As a consequence, TLB invalidations remain global, even if there are no active cxl contexts.

We should increment the driver use count when the process is attaching to the cxl adapter, and not on open. It's not needed before the adapter starts using the context and the use count is decremented on the detach path, so it makes more sense.

It affects only the user api. The kernel api is already doing The Right Thing.

Fixes 7bb5d91a4dda ("cxl: Rework context lifetimes")
---
 drivers/misc/cxl/api.c  |    4 ++++
 drivers/misc/cxl/file.c |    8 +++++++-
 2 files changed, 11 insertions(+), 1 deletion(-)
drivers/misc/cxl/api.c +4 -0
@@ -336,6 +336,10 @@ int cxl_start_context(struct cxl_context
 			mmput(ctx->mm);
 	}
 
+	/*
+	 * Increment driver use count. Enables global TLBIs for hash
+	 * and callbacks to handle the segment table
+	 */
 	cxl_ctx_get();
 
 	if ((rc = cxl_ops->attach_process(ctx, kernel, wed, 0))) {
drivers/misc/cxl/file.c +7 -1
@@ -95,7 +95,6 @@ static int __afu_open(struct inode *inod
 
 	pr_devel("afu_open pe: %i\n", ctx->pe);
 	file->private_data = ctx;
-	cxl_ctx_get();
 
 	/* indicate success */
 	rc = 0;
@@ -225,6 +224,12 @@ static long afu_ioctl_start_work(struct
 	if (ctx->mm)
 		mmput(ctx->mm);
 
+	/*
+	 * Increment driver use count. Enables global TLBIs for hash
+	 * and callbacks to handle the segment table
+	 */
+	cxl_ctx_get();
+
 	trace_cxl_attach(ctx, work.work_element_descriptor, work.num_interrupts, amr);
 
 	if ((rc = cxl_ops->attach_process(ctx, false, work.work_element_descriptor,
@@ -233,6 +238,7 @@ static long afu_ioctl_start_work(struct
 		cxl_adapter_context_put(ctx->afu->adapter);
 		put_pid(ctx->pid);
 		ctx->pid = NULL;
+		cxl_ctx_put();
 		cxl_context_mm_count_put(ctx);
 		goto out;
 	}
author maintainer
#45 lore raw

PATCH 41/109 powerpc/powernv/npu: Move tlb flush before launching ATSD

In reply to Greg Kroah-Hartman

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

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

From: Alistair Popple <[email protected]>

commit bab9f954aaf352127725a9b7920226abdb65b604 upstream.

The nest MMU tlb flush needs to happen before the GPU translation shootdown is launched to avoid the GPU refilling its tlb with stale nmmu translations prior to the nmmu flush completing.

Fixes 1ab66d1fbada ("powerpc/powernv: Introduce address translation services for Nvlink2")
---
 arch/powerpc/platforms/powernv/npu-dma.c |   12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)
arch/powerpc/platforms/powernv/npu-dma.c +6 -6
@@ -546,6 +546,12 @@ static void mmio_invalidate(struct npu_c
 	unsigned long pid = npu_context->mm->context.id;
 
 	/*
+	 * Unfortunately the nest mmu does not support flushing specific
+	 * addresses so we have to flush the whole mm.
+	 */
+	flush_tlb_mm(npu_context->mm);
+
+	/*
 	 * Loop over all the NPUs this process is active on and launch
 	 * an invalidate.
 	 */
@@ -576,12 +582,6 @@ static void mmio_invalidate(struct npu_c
 		}
 	}
 
-	/*
-	 * Unfortunately the nest mmu does not support flushing specific
-	 * addresses so we have to flush the whole mm.
-	 */
-	flush_tlb_mm(npu_context->mm);
-
 	mmio_invalidate_wait(mmio_atsd_reg, flush);
 	if (flush)
 		/* Wait for the flush to complete */
author maintainer
#46 lore raw

PATCH 42/109 powerpc/pseries: Dont attempt to acquire drc during memory hot add for assigned lmbs

In reply to Greg Kroah-Hartman

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

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

From: John Allen <[email protected]>

commit afb5519fdb346201728040cab4e08ce53e7ff4fd upstream.

Check if an LMB is assigned before attempting to call dlpar_acquire_drc in order to avoid any unnecessary rtas calls. This substantially reduces the running time of memory hot add on lpars with large amounts of memory.

[mpe: We need to explicitly set rc to 0 in the success case, otherwise
the compiler might think we use rc without initialising it.]

Fixes c21f515c7436 ("powerpc/pseries: Make the acquire/release of the drc for memory a seperate step")
---
 arch/powerpc/platforms/pseries/hotplug-memory.c |    4 ++++
 1 file changed, 4 insertions(+)
arch/powerpc/platforms/pseries/hotplug-memory.c +4 -0
@@ -817,6 +817,9 @@ static int dlpar_memory_add_by_count(u32
 		return -EINVAL;
 
 	for (i = 0; i < num_lmbs && lmbs_to_add != lmbs_added; i++) {
+		if (lmbs[i].flags & DRCONF_MEM_ASSIGNED)
+			continue;
+
 		rc = dlpar_acquire_drc(lmbs[i].drc_index);
 		if (rc)
 			continue;
@@ -859,6 +862,7 @@ static int dlpar_memory_add_by_count(u32
 				lmbs[i].base_addr, lmbs[i].drc_index);
 			lmbs[i].reserved = 0;
 		}
+		rc = 0;
 	}
 
 	return rc;
author maintainer
#47 lore raw

PATCH 43/109 powerpc: Fix DAR reporting when alignment handler faults

In reply to Greg Kroah-Hartman

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

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

From: Michael Ellerman <[email protected]>

commit f9effe925039cf54489b5c04e0d40073bb3a123d upstream.

Anton noticed that if we fault part way through emulating an unaligned instruction, we don't update the DAR to reflect that.

The DAR value is eventually reported back to userspace as the address in the SEGV signal, and if userspace is using that value to demand fault then it can be confused by us not setting the value correctly.

This patch is ugly as hell, but is intended to be the minimal fix and back ports easily.

---
 arch/powerpc/kernel/align.c |  119 +++++++++++++++++++++++++++-----------------
 1 file changed, 74 insertions(+), 45 deletions(-)
arch/powerpc/kernel/align.c +74 -45
@@ -235,6 +235,28 @@ static int emulate_dcbz(struct pt_regs *
 
 #define SWIZ_PTR(p)		((unsigned char __user *)((p) ^ swiz))
 
+#define __get_user_or_set_dar(_regs, _dest, _addr)		\
+	({							\
+		int rc = 0;					\
+		typeof(_addr) __addr = (_addr);			\
+		if (__get_user_inatomic(_dest, __addr)) {	\
+			_regs->dar = (unsigned long)__addr;	\
+			rc = -EFAULT;				\
+		}						\
+		rc;						\
+	})
+
+#define __put_user_or_set_dar(_regs, _src, _addr)		\
+	({							\
+		int rc = 0;					\
+		typeof(_addr) __addr = (_addr);			\
+		if (__put_user_inatomic(_src, __addr)) {	\
+			_regs->dar = (unsigned long)__addr;	\
+			rc = -EFAULT;				\
+		}						\
+		rc;						\
+	})
+
 static int emulate_multiple(struct pt_regs *regs, unsigned char __user *addr,
 			    unsigned int reg, unsigned int nb,
 			    unsigned int flags, unsigned int instr,
@@ -263,9 +285,10 @@ static int emulate_multiple(struct pt_re
 		} else {
 			unsigned long pc = regs->nip ^ (swiz & 4);
 
-			if (__get_user_inatomic(instr,
-						(unsigned int __user *)pc))
+			if (__get_user_or_set_dar(regs, instr,
+						  (unsigned int __user *)pc))
 				return -EFAULT;
+
 			if (swiz == 0 && (flags & SW))
 				instr = cpu_to_le32(instr);
 			nb = (instr >> 11) & 0x1f;
@@ -309,31 +332,31 @@ static int emulate_multiple(struct pt_re
 			       ((nb0 + 3) / 4) * sizeof(unsigned long));
 
 		for (i = 0; i < nb; ++i, ++p)
-			if (__get_user_inatomic(REG_BYTE(rptr, i ^ bswiz),
-						SWIZ_PTR(p)))
+			if (__get_user_or_set_dar(regs, REG_BYTE(rptr, i ^ bswiz),
+						  SWIZ_PTR(p)))
 				return -EFAULT;
 		if (nb0 > 0) {
 			rptr = &regs->gpr[0];
 			addr += nb;
 			for (i = 0; i < nb0; ++i, ++p)
-				if (__get_user_inatomic(REG_BYTE(rptr,
-								 i ^ bswiz),
-							SWIZ_PTR(p)))
+				if (__get_user_or_set_dar(regs,
+							  REG_BYTE(rptr, i ^ bswiz),
+							  SWIZ_PTR(p)))
 					return -EFAULT;
 		}
 
 	} else {
 		for (i = 0; i < nb; ++i, ++p)
-			if (__put_user_inatomic(REG_BYTE(rptr, i ^ bswiz),
-						SWIZ_PTR(p)))
+			if (__put_user_or_set_dar(regs, REG_BYTE(rptr, i ^ bswiz),
+						  SWIZ_PTR(p)))
 				return -EFAULT;
 		if (nb0 > 0) {
 			rptr = &regs->gpr[0];
 			addr += nb;
 			for (i = 0; i < nb0; ++i, ++p)
-				if (__put_user_inatomic(REG_BYTE(rptr,
-								 i ^ bswiz),
-							SWIZ_PTR(p)))
+				if (__put_user_or_set_dar(regs,
+							  REG_BYTE(rptr, i ^ bswiz),
+							  SWIZ_PTR(p)))
 					return -EFAULT;
 		}
 	}
@@ -345,29 +368,32 @@ static int emulate_multiple(struct pt_re
  * Only POWER6 has these instructions, and it does true little-endian,
  * so we don't need the address swizzling.
  */
-static int emulate_fp_pair(unsigned char __user *addr, unsigned int reg,
-			   unsigned int flags)
+static int emulate_fp_pair(struct pt_regs *regs, unsigned char __user *addr,
+			   unsigned int reg, unsigned int flags)
 {
 	char *ptr0 = (char *) &current->thread.TS_FPR(reg);
 	char *ptr1 = (char *) &current->thread.TS_FPR(reg+1);
-	int i, ret, sw = 0;
+	int i, sw = 0;
 
 	if (reg & 1)
 		return 0;	/* invalid form: FRS/FRT must be even */
 	if (flags & SW)
 		sw = 7;
-	ret = 0;
+
 	for (i = 0; i < 8; ++i) {
 		if (!(flags & ST)) {
-			ret |= __get_user(ptr0[i^sw], addr + i);
-			ret |= __get_user(ptr1[i^sw], addr + i + 8);
+			if (__get_user_or_set_dar(regs, ptr0[i^sw], addr + i))
+				return -EFAULT;
+			if (__get_user_or_set_dar(regs, ptr1[i^sw], addr + i + 8))
+				return -EFAULT;
 		} else {
-			ret |= __put_user(ptr0[i^sw], addr + i);
-			ret |= __put_user(ptr1[i^sw], addr + i + 8);
+			if (__put_user_or_set_dar(regs, ptr0[i^sw], addr + i))
+				return -EFAULT;
+			if (__put_user_or_set_dar(regs, ptr1[i^sw], addr + i + 8))
+				return -EFAULT;
 		}
 	}
-	if (ret)
-		return -EFAULT;
+
 	return 1;	/* exception handled and fixed up */
 }
 
@@ -377,24 +403,27 @@ static int emulate_lq_stq(struct pt_regs
 {
 	char *ptr0 = (char *)&regs->gpr[reg];
 	char *ptr1 = (char *)&regs->gpr[reg+1];
-	int i, ret, sw = 0;
+	int i, sw = 0;
 
 	if (reg & 1)
 		return 0;	/* invalid form: GPR must be even */
 	if (flags & SW)
 		sw = 7;
-	ret = 0;
+
 	for (i = 0; i < 8; ++i) {
 		if (!(flags & ST)) {
-			ret |= __get_user(ptr0[i^sw], addr + i);
-			ret |= __get_user(ptr1[i^sw], addr + i + 8);
+			if (__get_user_or_set_dar(regs, ptr0[i^sw], addr + i))
+				return -EFAULT;
+			if (__get_user_or_set_dar(regs, ptr1[i^sw], addr + i + 8))
+				return -EFAULT;
 		} else {
-			ret |= __put_user(ptr0[i^sw], addr + i);
-			ret |= __put_user(ptr1[i^sw], addr + i + 8);
+			if (__put_user_or_set_dar(regs, ptr0[i^sw], addr + i))
+				return -EFAULT;
+			if (__put_user_or_set_dar(regs, ptr1[i^sw], addr + i + 8))
+				return -EFAULT;
 		}
 	}
-	if (ret)
-		return -EFAULT;
+
 	return 1;	/* exception handled and fixed up */
 }
 #endif /* CONFIG_PPC64 */
@@ -687,9 +716,14 @@ static int emulate_vsx(unsigned char __u
 	for (j = 0; j < length; j += elsize) {
 		for (i = 0; i < elsize; ++i) {
 			if (flags & ST)
-				ret |= __put_user(ptr[i^sw], addr + i);
+				ret = __put_user_or_set_dar(regs, ptr[i^sw],
+							    addr + i);
 			else
-				ret |= __get_user(ptr[i^sw], addr + i);
+				ret = __get_user_or_set_dar(regs, ptr[i^sw],
+							    addr + i);
+
+			if (ret)
+				return ret;
 		}
 		ptr  += elsize;
 #ifdef __LITTLE_ENDIAN__
@@ -739,7 +773,7 @@ int fix_alignment(struct pt_regs *regs)
 	unsigned int dsisr;
 	unsigned char __user *addr;
 	unsigned long p, swiz;
-	int ret, i;
+	int i;
 	union data {
 		u64 ll;
 		double dd;
@@ -936,7 +970,7 @@ int fix_alignment(struct pt_regs *regs)
 		if (flags & F) {
 			/* Special case for 16-byte FP loads and stores */
 			PPC_WARN_ALIGNMENT(fp_pair, regs);
-			return emulate_fp_pair(addr, reg, flags);
+			return emulate_fp_pair(regs, addr, reg, flags);
 		} else {
 #ifdef CONFIG_PPC64
 			/* Special case for 16-byte loads and stores */
@@ -966,15 +1000,12 @@ int fix_alignment(struct pt_regs *regs)
 		}
 
 		data.ll = 0;
-		ret = 0;
 		p = (unsigned long)addr;
 
 		for (i = 0; i < nb; i++)
-			ret |= __get_user_inatomic(data.v[start + i],
-						   SWIZ_PTR(p++));
-
-		if (unlikely(ret))
-			return -EFAULT;
+			if (__get_user_or_set_dar(regs, data.v[start + i],
+						  SWIZ_PTR(p++)))
+				return -EFAULT;
 
 	} else if (flags & F) {
 		data.ll = current->thread.TS_FPR(reg);
@@ -1046,15 +1077,13 @@ int fix_alignment(struct pt_regs *regs)
 			break;
 		}
 
-		ret = 0;
 		p = (unsigned long)addr;
 
 		for (i = 0; i < nb; i++)
-			ret |= __put_user_inatomic(data.v[start + i],
-						   SWIZ_PTR(p++));
+			if (__put_user_or_set_dar(regs, data.v[start + i],
+						  SWIZ_PTR(p++)))
+				return -EFAULT;
 
-		if (unlikely(ret))
-			return -EFAULT;
 	} else if (flags & F)
 		current->thread.TS_FPR(reg) = data.ll;
 	else
author maintainer
#48 lore raw

PATCH 44/109 block: Relax a check in blk_start_queue()

In reply to Greg Kroah-Hartman

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

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

From: Bart Van Assche <[email protected]>

commit 4ddd56b003f251091a67c15ae3fe4a5c5c5e390a upstream.

Calling blk_start_queue() from interrupt context with the queue lock held and without disabling IRQs, as the skd driver does, is safe. This patch avoids that loading the skd driver triggers the following warning:

WARNING: CPU: 11 PID: 1348 at block/blk-core.c:283 blk_start_queue+0x84/0xa0
RIP: 0010:blk_start_queue+0x84/0xa0
Call Trace:
 skd_unquiesce_dev+0x12a/0x1d0 [skd]
 skd_complete_internal+0x1e7/0x5a0 [skd]
 skd_complete_other+0xc2/0xd0 [skd]
 skd_isr_completion_posted.isra.30+0x2a5/0x470 [skd]
 skd_isr+0x14f/0x180 [skd]
 irq_forced_thread_fn+0x2a/0x70
 irq_thread+0x144/0x1a0
 kthread+0x125/0x140
 ret_from_fork+0x2a/0x40
Fixes commit a038e2536472 ("[PATCH] blk_start_queue() must be called with irq disabled - add warning")
Cc Paolo 'Blaisorblade' Giarrusso <[email protected]>
Cc Andrew Morton <[email protected]>
Cc Christoph Hellwig <[email protected]>
Cc Hannes Reinecke <[email protected]>
Cc Johannes Thumshirn <[email protected]>
---
 block/blk-core.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
block/blk-core.c +1 -1
@@ -280,7 +280,7 @@ EXPORT_SYMBOL(blk_start_queue_async);
 void blk_start_queue(struct request_queue *q)
 {
 	lockdep_assert_held(q->queue_lock);
-	WARN_ON(!irqs_disabled());
+	WARN_ON(!in_interrupt() && !irqs_disabled());
 	WARN_ON_ONCE(q->mq_ops);
 
 	queue_flag_clear(QUEUE_FLAG_STOPPED, q);
author maintainer
#33 lore raw

PATCH 27/109 MIPS: math-emu: <MADDF|MSUBF>.S: Fix accuracy (32-bit case)

In reply to Greg Kroah-Hartman

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

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

From: Douglas Leung <[email protected]>

commit b3b8e1eb27c523e32b6a8aa7ec8ac4754456af57 upstream.

Implement fused multiply-add with correct accuracy.

Fused multiply-add operation has better accuracy than respective sequential execution of multiply and add operations applied on the same inputs. This is because accuracy errors accumulate in latter case.

This patch implements fused multiply-add with the same accuracy as it is implemented in hardware, using 64-bit intermediate calculations.

One test case example (raw bits) that this patch fixes:

MADDF.S fd,fs,ft:
fd = 0x22575225
fs = ft = 0x3727c5ac

Fixes e24c3bec3e8e ("MIPS: math-emu: Add support for the MIPS R6 MADDF FPU instruction")
Fixes 83d43305a1df ("MIPS: math-emu: Add support for the MIPS R6 MSUBF FPU instruction")

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

---
 arch/mips/math-emu/ieee754sp.h |    4 +
 arch/mips/math-emu/sp_maddf.c  |  116 ++++++++++++++++-------------------------
 2 files changed, 50 insertions(+), 70 deletions(-)
arch/mips/math-emu/ieee754sp.h +4 -0
@@ -45,6 +45,10 @@ static inline int ieee754sp_finite(union
 	return SPBEXP(x) != SP_EMAX + 1 + SP_EBIAS;
 }
 
+/* 64 bit right shift with rounding */
+#define XSPSRS64(v, rs)						\
+	(((rs) >= 64) ? ((v) != 0) : ((v) >> (rs)) | ((v) << (64-(rs)) != 0))
+
 /* 3bit extended single precision sticky right shift */
 #define XSPSRS(v, rs)						\
 	((rs > (SP_FBITS+3))?1:((v) >> (rs)) | ((v) << (32-(rs)) != 0))
arch/mips/math-emu/sp_maddf.c +46 -70

168 lines not on this page · raw message

author maintainer
#49 lore raw

PATCH 45/109 block: directly insert blk-mq request from blk_insert_cloned_request()

In reply to Greg Kroah-Hartman

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

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

From: Jens Axboe <[email protected]>

commit 157f377beb710e84bd8bc7a3c4475c0674ebebd7 upstream.

A NULL pointer crash was reported for the case of having the BFQ IO scheduler attached to the underlying blk-mq paths of a DM multipath device. The crash occured in blk_mq_sched_insert_request()'s call to e->type->ops.mq.insert_requests().

Paolo Valente correctly summarized why the crash occured with:
"the call chain (dm_mq_queue_rq -> map_request -> setup_clone -> blk_rq_prep_clone) creates a cloned request without invoking e->type->ops.mq.prepare_request for the target elevator e. The cloned request is therefore not initialized for the scheduler, but it is however inserted into the scheduler by blk_mq_sched_insert_request."

All said, a request-based DM multipath device's IO scheduler should be the only one used -- when the original requests are issued to the underlying paths as cloned requests they are inserted directly in the underlying dispatch queue(s) rather than through an additional elevator.

But commit bd166ef18 ("blk-mq-sched: add framework for MQ capable IO schedulers") switched blk_insert_cloned_request() from using blk_mq_insert_request() to blk_mq_sched_insert_request(). Which incorrectly added elevator machinery into a call chain that isn't supposed to have any.

To fix this introduce a blk-mq private blk_mq_request_bypass_insert() that blk_insert_cloned_request() calls to insert the request without involving any elevator that may be attached to the cloned request's request_queue.

Fixes bd166ef183c2 ("blk-mq-sched: add framework for MQ capable IO schedulers")
---
 block/blk-core.c |    7 ++++++-
 block/blk-mq.c   |   16 ++++++++++++++++
 block/blk-mq.h   |    1 +
 3 files changed, 23 insertions(+), 1 deletion(-)
block/blk-core.c +6 -1
@@ -2330,7 +2330,12 @@ blk_status_t blk_insert_cloned_request(s
 	if (q->mq_ops) {
 		if (blk_queue_io_stat(q))
 			blk_account_io_start(rq, true);
-		blk_mq_sched_insert_request(rq, false, true, false, false);
+		/*
+		 * Since we have a scheduler attached on the top device,
+		 * bypass a potential scheduler on the bottom device for
+		 * insert.
+		 */
+		blk_mq_request_bypass_insert(rq);
 		return BLK_STS_OK;
 	}
 
block/blk-mq.c +16 -0
@@ -1357,6 +1357,22 @@ void __blk_mq_insert_request(struct blk_
 	blk_mq_hctx_mark_pending(hctx, ctx);
 }
 
+/*
+ * Should only be used carefully, when the caller knows we want to
+ * bypass a potential IO scheduler on the target device.
+ */
+void blk_mq_request_bypass_insert(struct request *rq)
+{
+	struct blk_mq_ctx *ctx = rq->mq_ctx;
+	struct blk_mq_hw_ctx *hctx = blk_mq_map_queue(rq->q, ctx->cpu);
+
+	spin_lock(&hctx->lock);
+	list_add_tail(&rq->queuelist, &hctx->dispatch);
+	spin_unlock(&hctx->lock);
+
+	blk_mq_run_hw_queue(hctx, false);
+}
+
 void blk_mq_insert_requests(struct blk_mq_hw_ctx *hctx, struct blk_mq_ctx *ctx,
 			    struct list_head *list)
 
block/blk-mq.h +1 -0
@@ -54,6 +54,7 @@ int blk_mq_alloc_rqs(struct blk_mq_tag_s
  */
 void __blk_mq_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq,
 				bool at_head);
+void blk_mq_request_bypass_insert(struct request *rq);
 void blk_mq_insert_requests(struct blk_mq_hw_ctx *hctx, struct blk_mq_ctx *ctx,
 				struct list_head *list);
 
author maintainer
#50 lore raw

PATCH 46/109 md/bitmap: copy correct data for bitmap super

In reply to Greg Kroah-Hartman

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

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

From: Shaohua Li <[email protected]>

commit 8031c3ddc70ab93099e7d1814382dba39f57b43e upstream.

raid5 cache could write bitmap superblock before bitmap superblock is initialized. The bitmap superblock is less than 512B. The current code will only copy the superblock to a new page and write the whole 512B, which will zero the the data after the superblock. Unfortunately the data could include bitmap, which we should preserve. The patch will make superblock read do 4k chunk and we always copy the 4k data to new page, so the superblock write will old data to disk and we don't change the bitmap.

---
 drivers/md/bitmap.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/md/bitmap.c +2 -2
@@ -625,7 +625,7 @@ re_read:
 		err = read_sb_page(bitmap->mddev,
 				   offset,
 				   sb_page,
-				   0, sizeof(bitmap_super_t));
+				   0, PAGE_SIZE);
 	}
 	if (err)
 		return err;
@@ -2118,7 +2118,7 @@ int bitmap_resize(struct bitmap *bitmap,
 	if (store.sb_page && bitmap->storage.sb_page)
 		memcpy(page_address(store.sb_page),
 		       page_address(bitmap->storage.sb_page),
-		       sizeof(bitmap_super_t));
+		       PAGE_SIZE);
 	bitmap_file_unmap(&bitmap->storage);
 	bitmap->storage = store;
 
author maintainer
#51 lore raw

PATCH 47/109 md/bitmap: disable bitmap_resize for file-backed bitmaps.

In reply to Greg Kroah-Hartman

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

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

From: NeilBrown <[email protected]>

commit e8a27f836f165c26f867ece7f31eb5c811692319 upstream.

bitmap_resize() does not work for file-backed bitmaps. The buffer_heads are allocated and initialized when the bitmap is read from the file, but resize doesn't read from the file, it loads from the internal bitmap. When it comes time to write the new bitmap, the bh is non-existent and we crash.

The common case when growing an array involves making the array larger, and that normally means making the bitmap larger. Doing that inside the kernel is possible, but would need more code. It is probably easier to require people who use file-backed bitmaps to remove them and re-add after a reshape.

So this patch disables the resizing of arrays which have file-backed bitmaps. This is better than crashing.

Fixes d60b479d177a ("md/bitmap: add bitmap_resize function to allow bitmap resizing.")
---
 drivers/md/bitmap.c |    5 +++++
 1 file changed, 5 insertions(+)
drivers/md/bitmap.c +5 -0
@@ -2058,6 +2058,11 @@ int bitmap_resize(struct bitmap *bitmap,
 	long pages;
 	struct bitmap_page *new_bp;
 
+	if (bitmap->storage.file && !init) {
+		pr_info("md: cannot resize file-based bitmap\n");
+		return -EINVAL;
+	}
+
 	if (chunksize == 0) {
 		/* If there is enough space, leave the chunk size unchanged,
 		 * else increase by factor of two until there is enough space.
author maintainer
#52 lore raw

PATCH 48/109 skd: Avoid that module unloading triggers a use-after-free

In reply to Greg Kroah-Hartman

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

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

From: Bart Van Assche <[email protected]>

commit 7277cc67b3916eed47558c64f9c9c0de00a35cda upstream.

Since put_disk() triggers a disk_release() call and since that last function calls blk_put_queue() if disk->queue != NULL, clear the disk->queue pointer before calling put_disk(). This avoids that unloading the skd kernel module triggers the following use-after-free:

WARNING: CPU: 8 PID: 297 at lib/refcount.c:128 refcount_sub_and_test+0x70/0x80
refcount_t: underflow; use-after-free.
CPU: 8 PID: 297 Comm: kworker/8:1 Not tainted 4.11.10-300.fc26.x86_64 #1
Workqueue: events work_for_cpu_fn
Call Trace:
 dump_stack+0x63/0x84
 __warn+0xcb/0xf0
 warn_slowpath_fmt+0x5a/0x80
 refcount_sub_and_test+0x70/0x80
 refcount_dec_and_test+0x11/0x20
 kobject_put+0x1f/0x50
 blk_put_queue+0x15/0x20
 disk_release+0xae/0xf0
 device_release+0x32/0x90
 kobject_release+0x67/0x170
 kobject_put+0x2b/0x50
 put_disk+0x17/0x20
 skd_destruct+0x5c/0x890 [skd]
 skd_pci_probe+0x124d/0x13a0 [skd]
 local_pci_probe+0x42/0xa0
 work_for_cpu_fn+0x14/0x20
 process_one_work+0x19e/0x470
 worker_thread+0x1dc/0x4a0
 kthread+0x125/0x140
 ret_from_fork+0x25/0x30
Cc Christoph Hellwig <[email protected]>
Cc Hannes Reinecke <[email protected]>
Cc Johannes Thumshirn <[email protected]>
---
 drivers/block/skd_main.c |   15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)
drivers/block/skd_main.c +8 -7
@@ -4539,15 +4539,16 @@ static void skd_free_disk(struct skd_dev
 {
 	struct gendisk *disk = skdev->disk;
 
-	if (disk != NULL) {
-		struct request_queue *q = disk->queue;
+	if (disk && (disk->flags & GENHD_FL_UP))
+		del_gendisk(disk);
 
-		if (disk->flags & GENHD_FL_UP)
-			del_gendisk(disk);
-		if (q)
-			blk_cleanup_queue(q);
-		put_disk(disk);
+	if (skdev->queue) {
+		blk_cleanup_queue(skdev->queue);
+		skdev->queue = NULL;
+		disk->queue = NULL;
 	}
+
+	put_disk(disk);
 	skdev->disk = NULL;
 }
 
author maintainer
#53 lore raw

PATCH 49/109 skd: Submit requests to firmware before triggering the doorbell

In reply to Greg Kroah-Hartman

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

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

From: Bart Van Assche <[email protected]>

commit 5fbd545cd3fd311ea1d6e8be4cedddd0ee5684c7 upstream.

Ensure that the members of struct skd_msg_buf have been transferred to the PCIe adapter before the doorbell is triggered. This patch avoids that I/O fails sporadically and that the following error message is reported:

(skd0:STM000196603:[0000:00:09.0]): Completion mismatch comp_id=0x0000 skreq=0x0400 new=0x0000

Cc Christoph Hellwig <[email protected]>
Cc Hannes Reinecke <[email protected]>
Cc Johannes Thumshirn <[email protected]>
---
 drivers/block/skd_main.c |    6 ++++++
 1 file changed, 6 insertions(+)
drivers/block/skd_main.c +6 -0
@@ -2160,6 +2160,9 @@ static void skd_send_fitmsg(struct skd_d
 		 */
 		qcmd |= FIT_QCMD_MSGSIZE_64;
 
+	/* Make sure skd_msg_buf is written before the doorbell is triggered. */
+	smp_wmb();
+
 	SKD_WRITEQ(skdev, qcmd, FIT_Q_COMMAND);
 }
 
@@ -2202,6 +2205,9 @@ static void skd_send_special_fitmsg(stru
 	qcmd = skspcl->mb_dma_address;
 	qcmd |= FIT_QCMD_QID_NORMAL + FIT_QCMD_MSGSIZE_128;
 
+	/* Make sure skd_msg_buf is written before the doorbell is triggered. */
+	smp_wmb();
+
 	SKD_WRITEQ(skdev, qcmd, FIT_Q_COMMAND);
 }
 
author maintainer
#54 lore raw

PATCH 50/109 scsi: zfcp: fix queuecommand for scsi_eh commands when DIX enabled

In reply to Greg Kroah-Hartman

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

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

From: Steffen Maier <[email protected]>

commit 71b8e45da51a7b64a23378221c0a5868bd79da4f upstream.

Since commit db007fc5e20c ("[SCSI] Command protection operation"), scsi_eh_prep_cmnd() saves scmd->prot_op and temporarily resets it to SCSI_PROT_NORMAL.
Other FCP LLDDs such as qla2xxx and lpfc shield their queuecommand() to only access any of scsi_prot_sg...() if (scsi_get_prot_op(cmd) != SCSI_PROT_NORMAL).

Do the same thing for zfcp, which introduced DIX support with commit ef3eb71d8ba4 ("[SCSI] zfcp: Introduce experimental support for DIF/DIX").

Otherwise, TUR SCSI commands as part of scsi_eh likely fail in zfcp, because the regular SCSI command with DIX protection data, that scsi_eh re-uses in scsi_send_eh_cmnd(), of course still has (scsi_prot_sg_count() != 0) and so zfcp sends down bogus requests to the FCP channel hardware.

This causes scsi_eh_test_devices() to have (finish_cmds == 0) [not SCSI device is online or not scsi_eh_tur() failed]
so regular SCSI commands, that caused / were affected by scsi_eh, are moved to work_q and scsi_eh_test_devices() itself returns false. In turn, it unnecessarily escalates in our case in scsi_eh_ready_devs() beyond host reset to finally scsi_eh_offline_sdevs()
which sets affected SCSI devices offline with the following kernel message:

"kernel: sd H:0:T:L: Device offlined - not ready after error recovery"

Fixes ef3eb71d8ba4 ("[SCSI] zfcp: Introduce experimental support for DIF/DIX")
---
 drivers/s390/scsi/zfcp_fsf.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/s390/scsi/zfcp_fsf.c +2 -1
@@ -2258,7 +2258,8 @@ int zfcp_fsf_fcp_cmnd(struct scsi_cmnd *
 	fcp_cmnd = (struct fcp_cmnd *) &req->qtcb->bottom.io.fcp_cmnd;
 	zfcp_fc_scsi_to_fcp(fcp_cmnd, scsi_cmnd, 0);
 
-	if (scsi_prot_sg_count(scsi_cmnd)) {
+	if ((scsi_get_prot_op(scsi_cmnd) != SCSI_PROT_NORMAL) &&
+	    scsi_prot_sg_count(scsi_cmnd)) {
 		zfcp_qdio_set_data_div(qdio, &req->qdio_req,
 				       scsi_prot_sg_count(scsi_cmnd));
 		retval = zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req,
author maintainer
#55 lore raw

PATCH 51/109 scsi: zfcp: add handling for FCP_RESID_OVER to the fcp ingress path

In reply to Greg Kroah-Hartman

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

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

From: Benjamin Block <[email protected]>

commit a099b7b1fc1f0418ab8d79ecf98153e1e134656e upstream.

Up until now zfcp would just ignore the FCP_RESID_OVER flag in the FCP response IU. When this flag is set, it is possible, in regards to the FCP standard, that the storage-server processes the command normally, up to the point where data is missing and simply ignores those.

In this case no CHECK CONDITION would be set, and because we ignored the FCP_RESID_OVER flag we resulted in at least a data loss or even -corruption as a follow-up error, depending on how the applications/layers on top behave. To prevent this, we now set the host-byte of the corresponding scsi_cmnd to DID_ERROR.

Other storage-behaviors, where the same condition results in a CHECK CONDITION set in the answer, don't need to be changed as they are handled in the mid-layer already.

Following is an example trace record decoded with zfcpdbf from the s390-tools package. We forcefully injected a fc_dl which is one byte too small:

Timestamp : ...
Area : SCSI
Subarea : 00
Level : 3
Exception : -
CPU ID : ..
Caller : 0x...
Record ID : 1
Tag : rsl_err
Request ID : 0x...
SCSI ID : 0x...
SCSI LUN : 0x...
SCSI result : 0x00070000

                     ^^DID_ERROR

SCSI retries : 0x..
SCSI allowed : 0x..
SCSI scribble : 0x...
SCSI opcode : 2a000000 00000000 08000000 00000000
FCP rsp inf cod: 0x00
FCP rsp IU : 00000000 00000000 00000400 00000001

                                       ^^fr_flags==FCP_RESID_OVER
                                         ^^fr_status==SAM_STAT_GOOD
                                            ^^^^^^^^fr_resid
                 00000000 00000000

As of now, we don't actively handle to possibility that a response IU has both flags - FCP_RESID_OVER and FCP_RESID_UNDER - set at once.

Fixes 553448f6c483 ("[SCSI] zfcp: Message cleanup")
Fixes ea127f975424 ("[PATCH] s390 (7/7): zfcp host adapter.") (tglx/history.git)
---
 drivers/s390/scsi/zfcp_fc.h |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/s390/scsi/zfcp_fc.h +5 -1
@@ -4,7 +4,7 @@
  * Fibre Channel related definitions and inline functions for the zfcp
  * device driver
  *
- * Copyright IBM Corp. 2009
+ * Copyright IBM Corp. 2009, 2017
  */
 
 #ifndef ZFCP_FC_H
@@ -279,6 +279,10 @@ void zfcp_fc_eval_fcp_rsp(struct fcp_res
 		     !(rsp_flags & FCP_SNS_LEN_VAL) &&
 		     fcp_rsp->resp.fr_status == SAM_STAT_GOOD)
 			set_host_byte(scsi, DID_ERROR);
+	} else if (unlikely(rsp_flags & FCP_RESID_OVER)) {
+		/* FCP_DL was not sufficient for SCSI data length */
+		if (fcp_rsp->resp.fr_status == SAM_STAT_GOOD)
+			set_host_byte(scsi, DID_ERROR);
 	}
 }
 
author maintainer
#57 lore raw

PATCH 53/109 scsi: zfcp: fix passing fsf_req to SCSI trace on TMF to correlate with HBA

In reply to Greg Kroah-Hartman

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

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

From: Steffen Maier <[email protected]>

commit 9fe5d2b2fd30aa8c7827ec62cbbe6d30df4fe3e3 upstream.

Without this fix we get SCSI trace records on task management functions which cannot be correlated to HBA trace records because all fields related to the FSF request are empty (zero).
Also, the FCP_RSP_IU is missing as well as any sense data if available.

This was caused by v2.6.14 commit 8a36e4532ea1 ("[SCSI] zfcp: enhancement of zfcp debug features") introducing trace records for TMFs but hard coding NULL for a possibly existing TMF FSF request.
The scsi_cmnd scribble is also zero or unrelated for the TMF request so it also could not lookup a suitable FSF request from there.

A broken example trace record formatted with zfcpdbf from the s390-tools package:

Timestamp : ...
Area : SCSI
Subarea : 00
Level : 1
Exception : -
CPU ID : ..
Caller : 0x...
Record ID : 1
Tag : lr_fail
Request ID : 0x0000000000000000

                   ^^^^^^^^^^^^^^^^ no correlation to HBA record

SCSI ID : 0x<scsitarget>
SCSI LUN : 0x<scsilun>
SCSI result : 0x000e0000
SCSI retries : 0x00
SCSI allowed : 0x05
SCSI scribble : 0x0000000000000000
SCSI opcode : 2a000017 3bb80000 08000000 00000000
FCP rsp inf cod: 0x00
^^ no TMF response
FCP rsp IU : 00000000 00000000 00000000 00000000

                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                 00000000 00000000
                 ^^^^^^^^^^^^^^^^^ no interesting FCP_RSP_IU

Sense len : ...
^^^^^^^^^^^^^^^^^^^^ no sense data length
Sense info : ...
^^^^^^^^^^^^^^^^^^^^ no sense data content, even if present

There are some true cases where we really do not have an FSF request:
"rsl_fai" from zfcp_dbf_scsi_fail_send() called for early returns / completions in zfcp_scsi_queuecommand(),
"abrt_or", "abrt_bl", "abrt_ru", "abrt_ar" from zfcp_scsi_eh_abort_handler() where we did not get as far, "lr_nres", "tr_nres" from zfcp_task_mgmt_function() where we're successful and do not need to do anything because adapter stopped. For these cases it's correct to pass NULL for fsf_req to _zfcp_dbf_scsi().

Fixes 8a36e4532ea1 ("[SCSI] zfcp: enhancement of zfcp debug features")
---
 drivers/s390/scsi/zfcp_dbf.h  |    7 ++++---
 drivers/s390/scsi/zfcp_scsi.c |    8 ++++----
 2 files changed, 8 insertions(+), 7 deletions(-)
drivers/s390/scsi/zfcp_dbf.h +4 -3
@@ -2,7 +2,7 @@
  * zfcp device driver
  * debug feature declarations
  *
- * Copyright IBM Corp. 2008, 2016
+ * Copyright IBM Corp. 2008, 2017
  */
 
 #ifndef ZFCP_DBF_H
@@ -401,7 +401,8 @@ void zfcp_dbf_scsi_abort(char *tag, stru
  * @flag: indicates type of reset (Target Reset, Logical Unit Reset)
  */
 static inline
-void zfcp_dbf_scsi_devreset(char *tag, struct scsi_cmnd *scmnd, u8 flag)
+void zfcp_dbf_scsi_devreset(char *tag, struct scsi_cmnd *scmnd, u8 flag,
+			    struct zfcp_fsf_req *fsf_req)
 {
 	char tmp_tag[ZFCP_DBF_TAG_LEN];
 
@@ -411,7 +412,7 @@ void zfcp_dbf_scsi_devreset(char *tag, s
 		memcpy(tmp_tag, "lr_", 3);
 
 	memcpy(&tmp_tag[3], tag, 4);
-	_zfcp_dbf_scsi(tmp_tag, 1, scmnd, NULL);
+	_zfcp_dbf_scsi(tmp_tag, 1, scmnd, fsf_req);
 }
 
 /**
drivers/s390/scsi/zfcp_scsi.c +4 -4
@@ -3,7 +3,7 @@
  *
  * Interface to Linux SCSI midlayer.
  *
- * Copyright IBM Corp. 2002, 2016
+ * Copyright IBM Corp. 2002, 2017
  */
 
 #define KMSG_COMPONENT "zfcp"
@@ -278,7 +278,7 @@ static int zfcp_task_mgmt_function(struc
 
 		if (!(atomic_read(&adapter->status) &
 		      ZFCP_STATUS_COMMON_RUNNING)) {
-			zfcp_dbf_scsi_devreset("nres", scpnt, tm_flags);
+			zfcp_dbf_scsi_devreset("nres", scpnt, tm_flags, NULL);
 			return SUCCESS;
 		}
 	}
@@ -288,10 +288,10 @@ static int zfcp_task_mgmt_function(struc
 	wait_for_completion(&fsf_req->completion);
 
 	if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCFAILED) {
-		zfcp_dbf_scsi_devreset("fail", scpnt, tm_flags);
+		zfcp_dbf_scsi_devreset("fail", scpnt, tm_flags, fsf_req);
 		retval = FAILED;
 	} else {
-		zfcp_dbf_scsi_devreset("okay", scpnt, tm_flags);
+		zfcp_dbf_scsi_devreset("okay", scpnt, tm_flags, fsf_req);
 		zfcp_scsi_forget_cmnds(zfcp_sdev, tm_flags);
 	}
 
author maintainer
#58 lore raw

PATCH 54/109 scsi: zfcp: fix missing trace records for early returns in TMF eh handlers

In reply to Greg Kroah-Hartman

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

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

From: Steffen Maier <[email protected]>

commit 1a5d999ebfc7bfe28deb48931bb57faa8e4102b6 upstream.

For problem determination we need to see that we were in scsi_eh as well as whether and why we were successful or not.

The following commits introduced new early returns without adding a trace record:

v2.6.35 commit a1dbfddd02d2
("[SCSI] zfcp: Pass return code from fc_block_scsi_eh to scsi eh") on fc_block_scsi_eh() returning != 0 which is FAST_IO_FAIL,

v2.6.30 commit 63caf367e1c9
("[SCSI] zfcp: Improve reliability of SCSI eh handlers in zfcp") on not having gotten an FSF request after the maximum number of retry attempts and thus could not issue a TMF and has to return FAILED.

Fixes a1dbfddd02d2 ("[SCSI] zfcp: Pass return code from fc_block_scsi_eh to scsi eh")
Fixes 63caf367e1c9 ("[SCSI] zfcp: Improve reliability of SCSI eh handlers in zfcp")
---
 drivers/s390/scsi/zfcp_scsi.c |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/s390/scsi/zfcp_scsi.c +6 -2
@@ -273,8 +273,10 @@ static int zfcp_task_mgmt_function(struc
 
 		zfcp_erp_wait(adapter);
 		ret = fc_block_scsi_eh(scpnt);
-		if (ret)
+		if (ret) {
+			zfcp_dbf_scsi_devreset("fiof", scpnt, tm_flags, NULL);
 			return ret;
+		}
 
 		if (!(atomic_read(&adapter->status) &
 		      ZFCP_STATUS_COMMON_RUNNING)) {
@@ -282,8 +284,10 @@ static int zfcp_task_mgmt_function(struc
 			return SUCCESS;
 		}
 	}
-	if (!fsf_req)
+	if (!fsf_req) {
+		zfcp_dbf_scsi_devreset("reqf", scpnt, tm_flags, NULL);
 		return FAILED;
+	}
 
 	wait_for_completion(&fsf_req->completion);
 
author maintainer
#34 lore raw

PATCH 28/109 MIPS: math-emu: <MADDF|MSUBF>.D: Fix accuracy (64-bit case)

In reply to Greg Kroah-Hartman

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

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

From: Douglas Leung <[email protected]>

commit 2cfa58259f4b65b33ebe8f167019a1f89c6c3289 upstream.

Implement fused multiply-add with correct accuracy.

Fused multiply-add operation has better accuracy than respective sequential execution of multiply and add operations applied on the same inputs. This is because accuracy errors accumulate in latter case.

This patch implements fused multiply-add with the same accuracy as it is implemented in hardware, using 128-bit intermediate calculations.

One test case example (raw bits) that this patch fixes:

MADDF.D fd,fs,ft:
fd = 0x00000ca000000000
fs = ft = 0x3f40624dd2f1a9fc

Fixes e24c3bec3e8e ("MIPS: math-emu: Add support for the MIPS R6 MADDF FPU instruction")
Fixes 83d43305a1df ("MIPS: math-emu: Add support for the MIPS R6 MSUBF FPU instruction")

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

---
 arch/mips/math-emu/dp_maddf.c |  133 +++++++++++++++++++++++++++++-------------
 1 file changed, 94 insertions(+), 39 deletions(-)
arch/mips/math-emu/dp_maddf.c +94 -39
@@ -15,18 +15,44 @@
 #include "ieee754dp.h"
 
 
+/* 128 bits shift right logical with rounding. */
+void srl128(u64 *hptr, u64 *lptr, int count)
+{
+	u64 low;
+
+	if (count >= 128) {
+		*lptr = *hptr != 0 || *lptr != 0;
+		*hptr = 0;
+	} else if (count >= 64) {
+		if (count == 64) {
+			*lptr = *hptr | (*lptr != 0);
+		} else {
+			low = *lptr;
+			*lptr = *hptr >> (count - 64);
+			*lptr |= (*hptr << (128 - count)) != 0 || low != 0;
+		}
+		*hptr = 0;
+	} else {
+		low = *lptr;
+		*lptr = low >> count | *hptr << (64 - count);
+		*lptr |= (low << (64 - count)) != 0;
+		*hptr = *hptr >> count;
+	}
+}
+
 static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x,
 				 union ieee754dp y, enum maddf_flags flags)
 {
 	int re;
 	int rs;
-	u64 rm;
 	unsigned lxm;
 	unsigned hxm;
 	unsigned lym;
 	unsigned hym;
 	u64 lrm;
 	u64 hrm;
+	u64 lzm;
+	u64 hzm;
 	u64 t;
 	u64 at;
 	int s;
@@ -172,7 +198,7 @@ static union ieee754dp _dp_maddf(union i
 	ym <<= 64 - (DP_FBITS + 1);
 
 	/*
-	 * Multiply 64 bits xm, ym to give high 64 bits rm with stickness.
+	 * Multiply 64 bits xm and ym to give 128 bits result in hrm:lrm.
 	 */
 
 	/* 32 * 32 => 64 */
@@ -202,81 +228,110 @@ static union ieee754dp _dp_maddf(union i
 
 	hrm = hrm + (t >> 32);
 
-	rm = hrm | (lrm != 0);
-
-	/*
-	 * Sticky shift down to normal rounding precision.
-	 */
-	if ((s64) rm < 0) {
-		rm = (rm >> (64 - (DP_FBITS + 1 + 3))) |
-		     ((rm << (DP_FBITS + 1 + 3)) != 0);
+	/* Put explicit bit at bit 126 if necessary */
+	if ((int64_t)hrm < 0) {
+		lrm = (hrm << 63) | (lrm >> 1);
+		hrm = hrm >> 1;
 		re++;
-	} else {
-		rm = (rm >> (64 - (DP_FBITS + 1 + 3 + 1))) |
-		     ((rm << (DP_FBITS + 1 + 3 + 1)) != 0);
 	}
-	assert(rm & (DP_HIDDEN_BIT << 3));
 
-	if (zc == IEEE754_CLASS_ZERO)
-		return ieee754dp_format(rs, re, rm);
+	assert(hrm & (1 << 62));
 
-	/* And now the addition */
-	assert(zm & DP_HIDDEN_BIT);
+	if (zc == IEEE754_CLASS_ZERO) {
+		/*
+		 * Move explicit bit from bit 126 to bit 55 since the
+		 * ieee754dp_format code expects the mantissa to be
+		 * 56 bits wide (53 + 3 rounding bits).
+		 */
+		srl128(&hrm, &lrm, (126 - 55));
+		return ieee754dp_format(rs, re, lrm);
+	}
 
-	/*
-	 * Provide guard,round and stick bit space.
-	 */
-	zm <<= 3;
+	/* Move explicit bit from bit 52 to bit 126 */
+	lzm = 0;
+	hzm = zm << 10;
+	assert(hzm & (1 << 62));
 
+	/* Make the exponents the same */
 	if (ze > re) {
 		/*
 		 * Have to shift y fraction right to align.
 		 */
 		s = ze - re;
-		rm = XDPSRS(rm, s);
+		srl128(&hrm, &lrm, s);
 		re += s;
 	} else if (re > ze) {
 		/*
 		 * Have to shift x fraction right to align.
 		 */
 		s = re - ze;
-		zm = XDPSRS(zm, s);
+		srl128(&hzm, &lzm, s);
 		ze += s;
 	}
 	assert(ze == re);
 	assert(ze <= DP_EMAX);
 
+	/* Do the addition */
 	if (zs == rs) {
 		/*
-		 * Generate 28 bit result of adding two 27 bit numbers
-		 * leaving result in xm, xs and xe.
+		 * Generate 128 bit result by adding two 127 bit numbers
+		 * leaving result in hzm:lzm, zs and ze.
 		 */
-		zm = zm + rm;
-
-		if (zm >> (DP_FBITS + 1 + 3)) { /* carry out */
-			zm = XDPSRS1(zm);
+		hzm = hzm + hrm + (lzm > (lzm + lrm));
+		lzm = lzm + lrm;
+		if ((int64_t)hzm < 0) {        /* carry out */
+			srl128(&hzm, &lzm, 1);
 			ze++;
 		}
 	} else {
-		if (zm >= rm) {
-			zm = zm - rm;
+		if (hzm > hrm || (hzm == hrm && lzm >= lrm)) {
+			hzm = hzm - hrm - (lzm < lrm);
+			lzm = lzm - lrm;
 		} else {
-			zm = rm - zm;
+			hzm = hrm - hzm - (lrm < lzm);
+			lzm = lrm - lzm;
 			zs = rs;
 		}
-		if (zm == 0)
+		if (lzm == 0 && hzm == 0)
 			return ieee754dp_zero(ieee754_csr.rm == FPU_CSR_RD);
 
 		/*
-		 * Normalize to rounding precision.
+		 * Put explicit bit at bit 126 if necessary.
 		 */
-		while ((zm >> (DP_FBITS + 3)) == 0) {
-			zm <<= 1;
-			ze--;
+		if (hzm == 0) {
+			/* left shift by 63 or 64 bits */
+			if ((int64_t)lzm < 0) {
+				/* MSB of lzm is the explicit bit */
+				hzm = lzm >> 1;
+				lzm = lzm << 63;
+				ze -= 63;
+			} else {
+				hzm = lzm;
+				lzm = 0;
+				ze -= 64;
+			}
+		}
+
+		t = 0;
+		while ((hzm >> (62 - t)) == 0)
+			t++;
+
+		assert(t <= 62);
+		if (t) {
+			hzm = hzm << t | lzm >> (64 - t);
+			lzm = lzm << t;
+			ze -= t;
 		}
 	}
 
-	return ieee754dp_format(zs, ze, zm);
+	/*
+	 * Move explicit bit from bit 126 to bit 55 since the
+	 * ieee754dp_format code expects the mantissa to be
+	 * 56 bits wide (53 + 3 rounding bits).
+	 */
+	srl128(&hzm, &lzm, (126 - 55));
+
+	return ieee754dp_format(zs, ze, lzm);
 }
 
 union ieee754dp ieee754dp_maddf(union ieee754dp z, union ieee754dp x,
author maintainer
#59 lore raw

PATCH 55/109 scsi: zfcp: fix payload with full FCP_RSP IU in SCSI trace records

In reply to Greg Kroah-Hartman

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

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

From: Steffen Maier <[email protected]>

commit 12c3e5754c8022a4f2fd1e9f00d19e99ee0d3cc1 upstream.

If the FCP_RSP UI has optional parts (FCP_SNS_INFO or FCP_RSP_INFO) and thus does not fit into the fsp_rsp field built into a SCSI trace record, trace the full FCP_RSP UI with all optional parts as payload record instead of just FCP_SNS_INFO as payload and
a 1 byte RSP_INFO_CODE part of FCP_RSP_INFO built into the SCSI record.

That way we would also get the full FCP_SNS_INFO in case a target would ever send more than min(SCSI_SENSE_BUFFERSIZE==96, ZFCP_DBF_PAY_MAX_REC==256)==96.

The mandatory part of FCP_RSP IU is only 24 bytes.
PAYload costs at least one full PAY record of 256 bytes anyway. We cap to the hardware response size which is only FSF_FCP_RSP_SIZE==128. So we can just put the whole FCP_RSP IU with any optional parts into PAYload similarly as we do for SAN PAY since v4.9 commit aceeffbb59bb ("zfcp: trace full payload of all SAN records (req,resp,iels)"). This does not cause any additional trace records wasting memory.

Decoded trace records were confusing because they showed a hard-coded sense data length of 96 even if the FCP_RSP_IU field FCP_SNS_LEN showed actually less.

Since the same commit, we set pl_len for SAN traces to the full length of a request/response even if we cap the corresponding trace.
In contrast, here for SCSI traces we set pl_len to the pre-computed length of FCP_RSP IU considering SNS_LEN or RSP_LEN if valid. Nonetheless we trace a hardcoded payload of length FSF_FCP_RSP_SIZE==128 if there were optional parts.
This makes it easier for the zfcpdbf tool to format only the relevant part of the long FCP_RSP UI buffer. And any trailing information is still available in the payload trace record just in case.

Rename the payload record tag from "fcp_sns" to "fcp_riu" to make the new content explicit to zfcpdbf which can then pick a suitable field name such as "FCP rsp IU all:" instead of "Sense info :"
Also, the same zfcpdbf can still be backwards compatible with "fcp_sns".

Old example trace record before this fix, formatted with the tool zfcpdbf from s390-tools:

Timestamp : ...
Area : SCSI
Subarea : 00
Level : 3
Exception : -
CPU id : ..
Caller : 0x...
Record id : 1
Tag : rsl_err
Request id : 0x<request_id>
SCSI ID : 0x...
SCSI LUN : 0x...
SCSI result : 0x00000002
SCSI retries : 0x00
SCSI allowed : 0x05
SCSI scribble : 0x<request_id>
SCSI opcode : 00000000 00000000 00000000 00000000
FCP rsp inf cod: 0x00
FCP rsp IU : 00000000 00000000 00000202 00000000

                                       ^^==FCP_SNS_LEN_VALID
                 00000020 00000000
                 ^^^^^^^^==FCP_SNS_LEN==32
Sense len      : 96 <==min(SCSI_SENSE_BUFFERSIZE,ZFCP_DBF_PAY_MAX_REC)
Sense info     : 70000600 00000018 00000000 29000000
                 00000400 00000000 00000000 00000000
                 00000000 00000000 00000000 00000000<==superfluous
                 00000000 00000000 00000000 00000000<==superfluous
                 00000000 00000000 00000000 00000000<==superfluous
                 00000000 00000000 00000000 00000000<==superfluous

New example trace records with this fix:

Timestamp : ...
Area : SCSI
Subarea : 00
Level : 3
Exception : -
CPU ID : ..
Caller : 0x...
Record ID : 1
Tag : rsl_err
Request ID : 0x<request_id>
SCSI ID : 0x...
SCSI LUN : 0x...
SCSI result : 0x00000002
SCSI retries : 0x00
SCSI allowed : 0x03
SCSI scribble : 0x<request_id>
SCSI opcode : a30c0112 00000000 02000000 00000000
FCP rsp inf cod: 0x00
FCP rsp IU : 00000000 00000000 00000a02 00000200

                 00000020 00000000
FCP rsp IU len : 56
FCP rsp IU all : 00000000 00000000 00000a02 00000200
                                       ^^=FCP_RESID_UNDER|FCP_SNS_LEN_VALID
                 00000020 00000000 70000500 00000018
                 ^^^^^^^^==FCP_SNS_LEN
                                   ^^^^^^^^^^^^^^^^^
                 00000000 240000cb 00011100 00000000
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                 00000000 00000000
                 ^^^^^^^^^^^^^^^^^==FCP_SNS_INFO

Timestamp : ...
Area : SCSI
Subarea : 00
Level : 1
Exception : -
CPU ID : ..
Caller : 0x...
Record ID : 1
Tag : lr_okay
Request ID : 0x<request_id>
SCSI ID : 0x...
SCSI LUN : 0x...
SCSI result : 0x00000000
SCSI retries : 0x00
SCSI allowed : 0x05
SCSI scribble : 0x<request_id>
SCSI opcode : <CDB of unrelated SCSI command passed to eh handler>
FCP rsp inf cod: 0x00
FCP rsp IU : 00000000 00000000 00000100 00000000

                 00000000 00000008
FCP rsp IU len : 32
FCP rsp IU all : 00000000 00000000 00000100 00000000
                                       ^^==FCP_RSP_LEN_VALID
                 00000000 00000008 00000000 00000000
                          ^^^^^^^^==FCP_RSP_LEN
                                   ^^^^^^^^^^^^^^^^^==FCP_RSP_INFO
Fixes 250a1352b95e ("[SCSI] zfcp: Redesign of the debug tracing for SCSI records.")
---
 drivers/s390/scsi/zfcp_dbf.c |   21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)
drivers/s390/scsi/zfcp_dbf.c +17 -4
@@ -572,19 +572,32 @@ void zfcp_dbf_scsi(char *tag, int level,
 
 	if (fsf) {
 		rec->fsf_req_id = fsf->req_id;
+		rec->pl_len = FCP_RESP_WITH_EXT;
 		fcp_rsp = (struct fcp_resp_with_ext *)
 				&(fsf->qtcb->bottom.io.fcp_rsp);
+		/* mandatory parts of FCP_RSP IU in this SCSI record */
 		memcpy(&rec->fcp_rsp, fcp_rsp, FCP_RESP_WITH_EXT);
 		if (fcp_rsp->resp.fr_flags & FCP_RSP_LEN_VAL) {
 			fcp_rsp_info = (struct fcp_resp_rsp_info *) &fcp_rsp[1];
 			rec->fcp_rsp_info = fcp_rsp_info->rsp_code;
+			rec->pl_len += be32_to_cpu(fcp_rsp->ext.fr_rsp_len);
 		}
 		if (fcp_rsp->resp.fr_flags & FCP_SNS_LEN_VAL) {
-			rec->pl_len = min((u16)SCSI_SENSE_BUFFERSIZE,
-					  (u16)ZFCP_DBF_PAY_MAX_REC);
-			zfcp_dbf_pl_write(dbf, sc->sense_buffer, rec->pl_len,
-					  "fcp_sns", fsf->req_id);
+			rec->pl_len += be32_to_cpu(fcp_rsp->ext.fr_sns_len);
 		}
+		/* complete FCP_RSP IU in associated PAYload record
+		 * but only if there are optional parts
+		 */
+		if (fcp_rsp->resp.fr_flags != 0)
+			zfcp_dbf_pl_write(
+				dbf, fcp_rsp,
+				/* at least one full PAY record
+				 * but not beyond hardware response field
+				 */
+				min_t(u16, max_t(u16, rec->pl_len,
+						 ZFCP_DBF_PAY_MAX_REC),
+				      FSF_FCP_RSP_SIZE),
+				"fcp_riu", fsf->req_id);
 	}
 
 	debug_event(dbf->scsi, level, rec, sizeof(*rec));
author maintainer
#60 lore raw

PATCH 56/109 scsi: zfcp: trace HBA FSF response by default on dismiss or timedout late response

In reply to Greg Kroah-Hartman

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

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

From: Steffen Maier <[email protected]>

commit fdb7cee3b9e3c561502e58137a837341f10cbf8b upstream.

At the default trace level, we only trace unsuccessful events including FSF responses.

zfcp_dbf_hba_fsf_response() only used protocol status and FSF status to decide on an unsuccessful response. However, this is only one of multiple possible sources determining a failed struct zfcp_fsf_req.

An FSF request can also "fail" if its response runs into an ERP timeout or if it gets dismissed because a higher level recovery was triggered [trace tags "erscf_1" or "erscf_2" in zfcp_erp_strategy_check_fsfreq()]. FSF requests with ERP timeout are:
FSF_QTCB_EXCHANGE_CONFIG_DATA, FSF_QTCB_EXCHANGE_PORT_DATA, FSF_QTCB_OPEN_PORT_WITH_DID or FSF_QTCB_CLOSE_PORT or FSF_QTCB_CLOSE_PHYSICAL_PORT for target ports, FSF_QTCB_OPEN_LUN, FSF_QTCB_CLOSE_LUN.
One example is slow queue processing which can cause follow-on errors, e.g. FSF_PORT_ALREADY_OPEN after FSF_QTCB_OPEN_PORT_WITH_DID timed out. In order to see the root cause, we need to see late responses even if the channel presented them successfully with FSF_PROT_GOOD and FSF_GOOD. Example trace records formatted with zfcpdbf from the s390-tools package:

Timestamp : ...
Area : REC
Subarea : 00
Level : 1
Exception : -
CPU ID : ..
Caller : ...
Record ID : 1
Tag : fcegpf1
LUN : 0xffffffffffffffff
WWPN : 0x<WWPN>
D_ID : 0x00<D_ID>
Adapter status : 0x5400050b
Port status : 0x41200000
LUN status : 0x00000000
Ready count : 0x00000001
Running count : 0x...
ERP want : 0x02 ZFCP_ERP_ACTION_REOPEN_PORT
ERP need : 0x02 ZFCP_ERP_ACTION_REOPEN_PORT
|
Timestamp : ... 30 seconds later
Area : REC
Subarea : 00
Level : 1
Exception : -
CPU ID : ..
Caller : ...
Record ID : 2
Tag : erscf_2
LUN : 0xffffffffffffffff
WWPN : 0x<WWPN>
D_ID : 0x00<D_ID>
Adapter status : 0x5400050b
Port status : 0x41200000
LUN status : 0x00000000
Request ID : 0x<request_ID>
ERP status : 0x10000000 ZFCP_STATUS_ERP_TIMEDOUT
ERP step : 0x0800 ZFCP_ERP_STEP_PORT_OPENING
ERP action : 0x02 ZFCP_ERP_ACTION_REOPEN_PORT
ERP count : 0x00
|
Timestamp : ... later than previous record
Area : HBA
Subarea : 00
Level : 5 > default level => 3 <= default level
Exception : -
CPU ID : 00
Caller : ...
Record ID : 1
Tag : fs_qtcb => fs_rerr
Request ID : 0x<request_ID>
Request status : 0x00001010 ZFCP_STATUS_FSFREQ_DISMISSED
| ZFCP_STATUS_FSFREQ_CLEANUP
FSF cmnd : 0x00000005
FSF sequence no: 0x...
FSF issued : ... > 30 seconds ago
FSF stat : 0x00000000 FSF_GOOD
FSF stat qual : 00000000 00000000 00000000 00000000
Prot stat : 0x00000001 FSF_PROT_GOOD
Prot stat qual : 00000000 00000000 00000000 00000000
Port handle : 0x...
LUN handle : 0x00000000
QTCB log length: ...
QTCB log info : ...

In case of problems detecting that new responses are waiting on the input queue, we sooner or later trigger adapter recovery due to an FSF request timeout (trace tag "fsrth_1").
FSF requests with FSF request timeout are:
typically FSF_QTCB_ABORT_FCP_CMND; but theoretically also FSF_QTCB_EXCHANGE_CONFIG_DATA or FSF_QTCB_EXCHANGE_PORT_DATA via sysfs, FSF_QTCB_OPEN_PORT_WITH_DID or FSF_QTCB_CLOSE_PORT for WKA ports, FSF_QTCB_FCP_CMND for task management function (LUN / target reset). One or more pending requests can meanwhile have FSF_PROT_GOOD and FSF_GOOD because the channel filled in the response via DMA into the request's QTCB.

In a theroretical case, inject code can create an erroneous FSF request on purpose. If data router is enabled, it uses deferred error reporting. A READ SCSI command can succeed with FSF_PROT_GOOD, FSF_GOOD, and SAM_STAT_GOOD. But on writing the read data to host memory via DMA, it can still fail, e.g. if an intentionally wrong scatter list does not provide enough space. Rather than getting an unsuccessful response, we get a QDIO activate check which in turn triggers adapter recovery. One or more pending requests can meanwhile have FSF_PROT_GOOD and FSF_GOOD because the channel filled in the response via DMA into the request's QTCB. Example trace records formatted with zfcpdbf from the s390-tools package:

Timestamp : ...
Area : HBA
Subarea : 00
Level : 6 > default level => 3 <= default level
Exception : -
CPU ID : ..
Caller : ...
Record ID : 1
Tag : fs_norm => fs_rerr
Request ID : 0x<request_ID2>
Request status : 0x00001010 ZFCP_STATUS_FSFREQ_DISMISSED
| ZFCP_STATUS_FSFREQ_CLEANUP
FSF cmnd : 0x00000001
FSF sequence no: 0x...
FSF issued : ...
FSF stat : 0x00000000 FSF_GOOD
FSF stat qual : 00000000 00000000 00000000 00000000
Prot stat : 0x00000001 FSF_PROT_GOOD
Prot stat qual : ........ ........ 00000000 00000000
Port handle : 0x...
LUN handle : 0x...
|
Timestamp : ...
Area : SCSI
Subarea : 00
Level : 3
Exception : -
CPU ID : ..
Caller : ...
Record ID : 1
Tag : rsl_err
Request ID : 0x<request_ID2>
SCSI ID : 0x...
SCSI LUN : 0x...
SCSI result : 0x000e0000 DID_TRANSPORT_DISRUPTED
SCSI retries : 0x00
SCSI allowed : 0x05
SCSI scribble : 0x<request_ID2>
SCSI opcode : 28... Read(10)
FCP rsp inf cod: 0x00
FCP rsp IU : 00000000 00000000 00000000 00000000

                                         ^^	SAM_STAT_GOOD
                 00000000 00000000

Only with luck in both above cases, we could see a follow-on trace record of an unsuccesful event following a successful but late FSF response with FSF_PROT_GOOD and FSF_GOOD. Typically this was the case for I/O requests resulting in a SCSI trace record "rsl_err" with DID_TRANSPORT_DISRUPTED [On ZFCP_STATUS_FSFREQ_DISMISSED, zfcp_fsf_protstatus_eval() sets ZFCP_STATUS_FSFREQ_ERROR seen by the request handler functions as failure]. However, the reason for this follow-on trace was invisible because the corresponding HBA trace record was missing at the default trace level (by default hidden records with tags "fs_norm", "fs_qtcb", or "fs_open").

On adapter recovery, after we had shut down the QDIO queues, we perform unsuccessful pseudo completions with flag ZFCP_STATUS_FSFREQ_DISMISSED for each pending FSF request in zfcp_fsf_req_dismiss_all().
In order to find the root cause, we need to see all pseudo responses even if the channel presented them successfully with FSF_PROT_GOOD and FSF_GOOD.

Therefore, check zfcp_fsf_req.status for ZFCP_STATUS_FSFREQ_DISMISSED or ZFCP_STATUS_FSFREQ_ERROR and trace with a new tag "fs_rerr".

It does not matter that there are numerous places which set ZFCP_STATUS_FSFREQ_ERROR after the location where we trace an FSF response early. These cases are based on protocol status != FSF_PROT_GOOD or == FSF_PROT_FSF_STATUS_PRESENTED and are thus already traced by default as trace tag "fs_perr" or "fs_ferr" respectively.

NB: The trace record with tag "fssrh_1" for status read buffers on dismiss all remains. zfcp_fsf_req_complete() handles this and returns early. All other FSF request types are handled separately and as described above.

Fixes 8a36e4532ea1 ("[SCSI] zfcp: enhancement of zfcp debug features")
Fixes 2e261af84cdb ("[SCSI] zfcp: Only collect FSF/HBA debug data for matching trace levels")
---
 drivers/s390/scsi/zfcp_dbf.h |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/s390/scsi/zfcp_dbf.h +5 -1
@@ -323,7 +323,11 @@ void zfcp_dbf_hba_fsf_response(struct zf
 {
 	struct fsf_qtcb *qtcb = req->qtcb;
 
-	if ((qtcb->prefix.prot_status != FSF_PROT_GOOD) &&
+	if (unlikely(req->status & (ZFCP_STATUS_FSFREQ_DISMISSED |
+				    ZFCP_STATUS_FSFREQ_ERROR))) {
+		zfcp_dbf_hba_fsf_resp("fs_rerr", 3, req);
+
+	} else if ((qtcb->prefix.prot_status != FSF_PROT_GOOD) &&
 	    (qtcb->prefix.prot_status != FSF_PROT_FSF_STATUS_PRESENTED)) {
 		zfcp_dbf_hba_fsf_resp("fs_perr", 1, req);
 
author maintainer
#63 lore raw

PATCH 59/109 scsi: aacraid: Fix command send race condition

In reply to Greg Kroah-Hartman

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

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

From: Brian King <[email protected]>

commit 1ae948fa4f00f3a2823e7cb19a3049ef27dd6947 upstream.

This fixes a potential race condition observed on Power systems.

Several places throughout the aacraid driver call aac_fib_send or similar to send a command to the aacraid adapter, then check the return code to determine if the command was actually sent to the adapter, then update the phase field in the scsi command scratch pad area to track that the firmware now owns this command. However, there is nothing that ensures that by the time the aac_fib_send function returns and we go to write to the scsi command, that the command hasn't already completed and the scsi command has been freed. This was causing random crashes in the TCP stack which was tracked down to be caused by memory that had been a struct request + scsi_cmnd being now used for an skbuff. Memory poisoning was enabled in the kernel to debug this which showed that the last owner of the memory that had been freed was aacraid and that it was a struct request. The memory that was corrupted was the exact data pattern of AAC_OWNER_FIRMWARE and it was at the same offset that aacraid writes, which is scsicmd->SCp.phase. The patch below resolves this issue.

---
 drivers/scsi/aacraid/aachba.c |   54 ++++++++++++++++--------------------------
 1 file changed, 21 insertions(+), 33 deletions(-)
drivers/scsi/aacraid/aachba.c +21 -33
@@ -594,6 +594,7 @@ static int aac_get_container_name(struct
 
 	aac_fib_init(cmd_fibcontext);
 	dinfo = (struct aac_get_name *) fib_data(cmd_fibcontext);
+	scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
 
 	dinfo->command = cpu_to_le32(VM_ContainerConfig);
 	dinfo->type = cpu_to_le32(CT_READ_NAME);
@@ -611,10 +612,8 @@ static int aac_get_container_name(struct
 	/*
 	 *	Check that the command queued to the controller
 	 */
-	if (status == -EINPROGRESS) {
-		scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
+	if (status == -EINPROGRESS)
 		return 0;
-	}
 
 	printk(KERN_WARNING "aac_get_container_name: aac_fib_send failed with status: %d.\n", status);
 	aac_fib_complete(cmd_fibcontext);
@@ -725,6 +724,7 @@ static void _aac_probe_container1(void *
 
 	dinfo->count = cpu_to_le32(scmd_id(scsicmd));
 	dinfo->type = cpu_to_le32(FT_FILESYS);
+	scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
 
 	status = aac_fib_send(ContainerCommand,
 			  fibptr,
@@ -736,9 +736,7 @@ static void _aac_probe_container1(void *
 	/*
 	 *	Check that the command queued to the controller
 	 */
-	if (status == -EINPROGRESS)
-		scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
-	else if (status < 0) {
+	if (status < 0 && status != -EINPROGRESS) {
 		/* Inherit results from VM_NameServe, if any */
 		dresp->status = cpu_to_le32(ST_OK);
 		_aac_probe_container2(context, fibptr);
@@ -766,6 +764,7 @@ static int _aac_probe_container(struct s
 		dinfo->count = cpu_to_le32(scmd_id(scsicmd));
 		dinfo->type = cpu_to_le32(FT_FILESYS);
 		scsicmd->SCp.ptr = (char *)callback;
+		scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
 
 		status = aac_fib_send(ContainerCommand,
 			  fibptr,
@@ -777,10 +776,9 @@ static int _aac_probe_container(struct s
 		/*
 		 *	Check that the command queued to the controller
 		 */
-		if (status == -EINPROGRESS) {
-			scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
+		if (status == -EINPROGRESS)
 			return 0;
-		}
+
 		if (status < 0) {
 			scsicmd->SCp.ptr = NULL;
 			aac_fib_complete(fibptr);
@@ -1126,6 +1124,7 @@ static int aac_get_container_serial(stru
 	dinfo->command = cpu_to_le32(VM_ContainerConfig);
 	dinfo->type = cpu_to_le32(CT_CID_TO_32BITS_UID);
 	dinfo->cid = cpu_to_le32(scmd_id(scsicmd));
+	scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
 
 	status = aac_fib_send(ContainerCommand,
 		  cmd_fibcontext,
@@ -1138,10 +1137,8 @@ static int aac_get_container_serial(stru
 	/*
 	 *	Check that the command queued to the controller
 	 */
-	if (status == -EINPROGRESS) {
-		scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
+	if (status == -EINPROGRESS)
 		return 0;
-	}
 
 	printk(KERN_WARNING "aac_get_container_serial: aac_fib_send failed with status: %d.\n", status);
 	aac_fib_complete(cmd_fibcontext);
@@ -2335,16 +2332,14 @@ static int aac_read(struct scsi_cmnd * s
 	 *	Alocate and initialize a Fib
 	 */
 	cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);
-
+	scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
 	status = aac_adapter_read(cmd_fibcontext, scsicmd, lba, count);
 
 	/*
 	 *	Check that the command queued to the controller
 	 */
-	if (status == -EINPROGRESS) {
-		scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
+	if (status == -EINPROGRESS)
 		return 0;
-	}
 
 	printk(KERN_WARNING "aac_read: aac_fib_send failed with status: %d.\n", status);
 	/*
@@ -2429,16 +2424,14 @@ static int aac_write(struct scsi_cmnd *
 	 *	Allocate and initialize a Fib then setup a BlockWrite command
 	 */
 	cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);
-
+	scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
 	status = aac_adapter_write(cmd_fibcontext, scsicmd, lba, count, fua);
 
 	/*
 	 *	Check that the command queued to the controller
 	 */
-	if (status == -EINPROGRESS) {
-		scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
+	if (status == -EINPROGRESS)
 		return 0;
-	}
 
 	printk(KERN_WARNING "aac_write: aac_fib_send failed with status: %d\n", status);
 	/*
@@ -2588,6 +2581,7 @@ static int aac_synchronize(struct scsi_c
 	synchronizecmd->cid = cpu_to_le32(scmd_id(scsicmd));
 	synchronizecmd->count =
 	     cpu_to_le32(sizeof(((struct aac_synchronize_reply *)NULL)->data));
+	scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
 
 	/*
 	 *	Now send the Fib to the adapter
@@ -2603,10 +2597,8 @@ static int aac_synchronize(struct scsi_c
 	/*
 	 *	Check that the command queued to the controller
 	 */
-	if (status == -EINPROGRESS) {
-		scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
+	if (status == -EINPROGRESS)
 		return 0;
-	}
 
 	printk(KERN_WARNING
 		"aac_synchronize: aac_fib_send failed with status: %d.\n", status);
@@ -2666,6 +2658,7 @@ static int aac_start_stop(struct scsi_cm
 	pmcmd->cid = cpu_to_le32(sdev_id(sdev));
 	pmcmd->parm = (scsicmd->cmnd[1] & 1) ?
 		cpu_to_le32(CT_PM_UNIT_IMMEDIATE) : 0;
+	scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
 
 	/*
 	 *	Now send the Fib to the adapter
@@ -2681,10 +2674,8 @@ static int aac_start_stop(struct scsi_cm
 	/*
 	 *	Check that the command queued to the controller
 	 */
-	if (status == -EINPROGRESS) {
-		scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
+	if (status == -EINPROGRESS)
 		return 0;
-	}
 
 	aac_fib_complete(cmd_fibcontext);
 	aac_fib_free(cmd_fibcontext);
@@ -3692,16 +3683,14 @@ static int aac_send_srb_fib(struct scsi_
 	 *	Allocate and initialize a Fib then setup a BlockWrite command
 	 */
 	cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);
-
+	scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
 	status = aac_adapter_scsi(cmd_fibcontext, scsicmd);
 
 	/*
 	 *	Check that the command queued to the controller
 	 */
-	if (status == -EINPROGRESS) {
-		scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
+	if (status == -EINPROGRESS)
 		return 0;
-	}
 
 	printk(KERN_WARNING "aac_srb: aac_fib_send failed with status: %d\n", status);
 	aac_fib_complete(cmd_fibcontext);
@@ -3739,15 +3728,14 @@ static int aac_send_hba_fib(struct scsi_
 	if (!cmd_fibcontext)
 		return -1;
 
+	scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
 	status = aac_adapter_hba(cmd_fibcontext, scsicmd);
 
 	/*
 	 *	Check that the command queued to the controller
 	 */
-	if (status == -EINPROGRESS) {
-		scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
+	if (status == -EINPROGRESS)
 		return 0;
-	}
 
 	pr_warn("aac_hba_cmd_req: aac_fib_send failed with status: %d\n",
 		status);
author maintainer
#64 lore raw

PATCH 60/109 scsi: megaraid_sas: mismatch of allocated MFI frame size and length exposed in MFI MPT pass through command

In reply to Greg Kroah-Hartman

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

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

From: Shivasharan S <[email protected]>

commit ed2983f458bed9dc827ec60c8486253b1669bb52 upstream.

Driver allocated 256 byte MFI frames bytes but while sending MFI frame (embedded inside chain frame of MPT frame) to firmware, driver sets the length as 4k. This results in DMA read error messages during boot.

---
 drivers/scsi/megaraid/megaraid_sas_fusion.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/megaraid/megaraid_sas_fusion.c +1 -1
@@ -3287,7 +3287,7 @@ build_mpt_mfi_pass_thru(struct megasas_i
 	mpi25_ieee_chain->Flags = IEEE_SGE_FLAGS_CHAIN_ELEMENT |
 		MPI2_IEEE_SGE_FLAGS_IOCPLBNTA_ADDR;
 
-	mpi25_ieee_chain->Length = cpu_to_le32(instance->max_chain_frame_sz);
+	mpi25_ieee_chain->Length = cpu_to_le32(instance->mfi_frame_size);
 }
 
 /**
author maintainer
#65 lore raw

PATCH 61/109 scsi: megaraid_sas: set minimum value of resetwaittime to be 1 secs

In reply to Greg Kroah-Hartman

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

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

From: Shivasharan S <[email protected]>

commit e636a7a430f41efb0ff2727960ce61ef9f8f6769 upstream.

Setting resetwaittime to 0 during a FW fault will result in driver not calling the OCR.

---
 drivers/scsi/megaraid/megaraid_sas_base.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/scsi/megaraid/megaraid_sas_base.c +2 -1
@@ -5478,7 +5478,8 @@ static int megasas_init_fw(struct megasa
 		instance->throttlequeuedepth =
 				MEGASAS_THROTTLE_QUEUE_DEPTH;
 
-	if (resetwaittime > MEGASAS_RESET_WAIT_TIME)
+	if ((resetwaittime < 1) ||
+	    (resetwaittime > MEGASAS_RESET_WAIT_TIME))
 		resetwaittime = MEGASAS_RESET_WAIT_TIME;
 
 	if ((scmd_timeout < 10) || (scmd_timeout > MEGASAS_DEFAULT_CMD_TIMEOUT))
author maintainer
#66 lore raw

PATCH 62/109 scsi: megaraid_sas: Check valid aen class range to avoid kernel panic

In reply to Greg Kroah-Hartman

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

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

From: Shivasharan S <[email protected]>

commit 91b3d9f0069c8307d0b3a4c6843b65a439183318 upstream.

---
 drivers/scsi/megaraid/megaraid_sas_base.c |    8 ++++++++
 1 file changed, 8 insertions(+)
drivers/scsi/megaraid/megaraid_sas_base.c +8 -0
@@ -5650,6 +5650,14 @@ megasas_register_aen(struct megasas_inst
 		prev_aen.word =
 			le32_to_cpu(instance->aen_cmd->frame->dcmd.mbox.w[1]);
 
+		if ((curr_aen.members.class < MFI_EVT_CLASS_DEBUG) ||
+		    (curr_aen.members.class > MFI_EVT_CLASS_DEAD)) {
+			dev_info(&instance->pdev->dev,
+				 "%s %d out of range class %d send by application\n",
+				 __func__, __LINE__, curr_aen.members.class);
+			return 0;
+		}
+
 		/*
 		 * A class whose enum value is smaller is inclusive of all
 		 * higher values. If a PROGRESS (= -1) was previously
author maintainer
#67 lore raw

PATCH 63/109 scsi: megaraid_sas: Return pended IOCTLs with cmd_status MFI_STAT_WRONG_STATE in case adapter is dead

In reply to Greg Kroah-Hartman

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

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

From: Shivasharan S <[email protected]>

commit eb3fe263a48b0d27b229c213929c4cb3b1b39a0f upstream.

After a kill adapter, since the cmd_status is not set, the IOCTLs will be hung in driver resulting in application hang. Set cmd_status MFI_STAT_WRONG_STATE when completing pended IOCTLs.

---
 drivers/scsi/megaraid/megaraid_sas_base.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/scsi/megaraid/megaraid_sas_base.c +4 -1
@@ -1995,9 +1995,12 @@ static void megasas_complete_outstanding
 			if (cmd_fusion->sync_cmd_idx != (u32)ULONG_MAX) {
 				cmd_mfi = instance->cmd_list[cmd_fusion->sync_cmd_idx];
 				if (cmd_mfi->sync_cmd &&
-					cmd_mfi->frame->hdr.cmd != MFI_CMD_ABORT)
+				    (cmd_mfi->frame->hdr.cmd != MFI_CMD_ABORT)) {
+					cmd_mfi->frame->hdr.cmd_status =
+							MFI_STAT_WRONG_STATE;
 					megasas_complete_cmd(instance,
 							     cmd_mfi, DID_OK);
+				}
 			}
 		}
 	} else {
author maintainer
#68 lore raw

PATCH 64/109 scsi: storvsc: fix memory leak on ring buffer busy

In reply to Greg Kroah-Hartman

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

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

From: Long Li <[email protected]>

commit 0208eeaa650c5c866a3242201678a19e6dc4a14e upstream.

When storvsc is sending I/O to Hyper-v, it may allocate a bigger buffer descriptor for large data payload that can't fit into a pre-allocated buffer descriptor. This bigger buffer is freed on return path.

If I/O request to Hyper-v fails due to ring buffer busy, the storvsc allocated buffer descriptor should also be freed.

[mkp: applied by hand]

Fixes be0cf6ca301c ("scsi: storvsc: Set the tablesize based on the information given by the host")
---
 drivers/scsi/storvsc_drv.c |    2 ++
 1 file changed, 2 insertions(+)
drivers/scsi/storvsc_drv.c +2 -0
@@ -1640,6 +1640,8 @@ static int storvsc_queuecommand(struct S
 	put_cpu();
 
 	if (ret == -EAGAIN) {
+		if (payload_sz > sizeof(cmd_request->mpb))
+			kfree(payload);
 		/* no more space */
 		return SCSI_MLQUEUE_DEVICE_BUSY;
 	}
author maintainer
#35 lore raw

PATCH 29/109 docs: disable KASLR when debugging kernel

In reply to Greg Kroah-Hartman

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

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

From: Zhouyi Zhou <[email protected]>

commit e604f1cb85367d2e5fd4cf253296d190996da81a upstream.

commit 6807c84652b0 ("x86: Enable KASLR by default") enables KASLR by default on x86. While KASLR will confuse gdb which resolve kernel symbol address from symbol table of vmlinux. We should turn off KASLR for kernel debugging.

---
 Documentation/dev-tools/gdb-kernel-debugging.rst |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
Documentation/dev-tools/gdb-kernel-debugging.rst +4 -2
@@ -31,11 +31,13 @@ Setup
   CONFIG_DEBUG_INFO_REDUCED off. If your architecture supports
   CONFIG_FRAME_POINTER, keep it enabled.
 
-- Install that kernel on the guest.
+- Install that kernel on the guest, turn off KASLR if necessary by adding
+  "nokaslr" to the kernel command line.
   Alternatively, QEMU allows to boot the kernel directly using -kernel,
   -append, -initrd command line switches. This is generally only useful if
   you do not depend on modules. See QEMU documentation for more details on
-  this mode.
+  this mode. In this case, you should build the kernel with
+  CONFIG_RANDOMIZE_BASE disabled if the architecture supports KASLR.
 
 - Enable the gdb stub of QEMU/KVM, either
 
author maintainer
#36 lore raw

PATCH 30/109 crypto: ccp - Fix XTS-AES-128 support on v5 CCPs

In reply to Greg Kroah-Hartman

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

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

From: Gary R Hook <[email protected]>

commit e652399edba99a5497f0d80f240c9075d3b43493 upstream.

Version 5 CCPs have some new requirements for XTS-AES: the type field must be specified, and the key requires 512 bits, with each part occupying 256 bits and padded with zeroes.

---
 drivers/crypto/ccp/ccp-crypto-aes-xts.c |    4 ++
 drivers/crypto/ccp/ccp-dev-v5.c         |    2 +
 drivers/crypto/ccp/ccp-dev.h            |    2 +
 drivers/crypto/ccp/ccp-ops.c            |   43 +++++++++++++++++++++++++-------
 include/linux/ccp.h                     |    3 +-
 5 files changed, 43 insertions(+), 11 deletions(-)
drivers/crypto/ccp/ccp-crypto-aes-xts.c +3 -1
@@ -1,8 +1,9 @@
 /*
  * AMD Cryptographic Coprocessor (CCP) AES XTS crypto API support
  *
- * Copyright (C) 2013 Advanced Micro Devices, Inc.
+ * Copyright (C) 2013,2017 Advanced Micro Devices, Inc.
  *
+ * Author: Gary R Hook <[email protected]>
  * Author: Tom Lendacky <[email protected]>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -164,6 +165,7 @@ static int ccp_aes_xts_crypt(struct ablk
 	memset(&rctx->cmd, 0, sizeof(rctx->cmd));
 	INIT_LIST_HEAD(&rctx->cmd.entry);
 	rctx->cmd.engine = CCP_ENGINE_XTS_AES_128;
+	rctx->cmd.u.xts.type = CCP_AES_TYPE_128;
 	rctx->cmd.u.xts.action = (encrypt) ? CCP_AES_ACTION_ENCRYPT
 					   : CCP_AES_ACTION_DECRYPT;
 	rctx->cmd.u.xts.unit_size = unit_size;
drivers/crypto/ccp/ccp-dev-v5.c +2 -0
@@ -145,6 +145,7 @@ union ccp_function {
 #define	CCP_AES_MODE(p)		((p)->aes.mode)
 #define	CCP_AES_TYPE(p)		((p)->aes.type)
 #define	CCP_XTS_SIZE(p)		((p)->aes_xts.size)
+#define	CCP_XTS_TYPE(p)		((p)->aes_xts.type)
 #define	CCP_XTS_ENCRYPT(p)	((p)->aes_xts.encrypt)
 #define	CCP_DES3_SIZE(p)	((p)->des3.size)
 #define	CCP_DES3_ENCRYPT(p)	((p)->des3.encrypt)
@@ -344,6 +345,7 @@ static int ccp5_perform_xts_aes(struct c
 	CCP5_CMD_PROT(&desc) = 0;
 
 	function.raw = 0;
+	CCP_XTS_TYPE(&function) = op->u.xts.type;
 	CCP_XTS_ENCRYPT(&function) = op->u.xts.action;
 	CCP_XTS_SIZE(&function) = op->u.xts.unit_size;
 	CCP5_CMD_FUNCTION(&desc) = function.raw;
drivers/crypto/ccp/ccp-dev.h +2 -0
@@ -192,6 +192,7 @@
 #define CCP_AES_CTX_SB_COUNT		1
 
 #define CCP_XTS_AES_KEY_SB_COUNT	1
+#define CCP5_XTS_AES_KEY_SB_COUNT	2
 #define CCP_XTS_AES_CTX_SB_COUNT	1
 
 #define CCP_DES3_KEY_SB_COUNT		1
@@ -497,6 +498,7 @@ struct ccp_aes_op {
 };
 
 struct ccp_xts_aes_op {
+	enum ccp_aes_type type;
 	enum ccp_aes_action action;
 	enum ccp_xts_aes_unit_size unit_size;
 };
drivers/crypto/ccp/ccp-ops.c +34 -9

70 lines not on this page · raw message

include/linux/ccp.h +2 -1
@@ -1,7 +1,7 @@
 /*
  * AMD Cryptographic Coprocessor (CCP) driver
  *
- * Copyright (C) 2013,2016 Advanced Micro Devices, Inc.
+ * Copyright (C) 2013,2017 Advanced Micro Devices, Inc.
  *
  * Author: Tom Lendacky <[email protected]>
  * Author: Gary R Hook <[email protected]>
@@ -231,6 +231,7 @@ enum ccp_xts_aes_unit_size {
  * AES operation the new IV overwrites the old IV.
  */
 struct ccp_xts_aes_engine {
+	enum ccp_aes_type type;
 	enum ccp_aes_action action;
 	enum ccp_xts_aes_unit_size unit_size;
 
author maintainer
#37 lore raw

PATCH 31/109 crypto: scompress - dont sleep with preemption disabled

In reply to Greg Kroah-Hartman

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

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

From: Ard Biesheuvel <[email protected]>

commit 3c08377262880afc1621ab9cb6dbe7df47a6033d upstream.

Due to the use of per-CPU buffers, scomp_acomp_comp_decomp() executes with preemption disabled, and so whether the CRYPTO_TFM_REQ_MAY_SLEEP flag is set is irrelevant, since we cannot sleep anyway. So disregard the flag, and use GFP_ATOMIC unconditionally.

---
 crypto/scompress.c |    4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)
crypto/scompress.c +1 -3
@@ -211,9 +211,7 @@ static int scomp_acomp_comp_decomp(struc
 					      scratch_dst, &req->dlen, *ctx);
 	if (!ret) {
 		if (!req->dst) {
-			req->dst = crypto_scomp_sg_alloc(req->dlen,
-				   req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ?
-				   GFP_KERNEL : GFP_ATOMIC);
+			req->dst = crypto_scomp_sg_alloc(req->dlen, GFP_ATOMIC);
 			if (!req->dst)
 				goto out;
 		}
author maintainer
#31 lore raw

PATCH 25/109 MIPS: math-emu: <MADDF|MSUBF>.<D|S>: Fix some cases of zero inputs

In reply to Greg Kroah-Hartman

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

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

From: Aleksandar Markovic <[email protected]>

commit 7cf64ce4d37f1b4f44365fcf77f565d523819dcd upstream.

Fix the cases of <MADDF|MSUBF>.<D|S> when any of two multiplicands is +0 or -0, and the third input is also +0 or -0. Depending on the signs of inputs, certain special cases must be handled.

A relevant example:

MADDF.S fd,fs,ft:
If fs contains +0.0, ft contains -0.0, and fd contains 0.0, fd is going to contain +0.0 (without this patch, it used to contain -0.0).

Fixes e24c3bec3e8e ("MIPS: math-emu: Add support for the MIPS R6 MADDF FPU instruction")
Fixes 83d43305a1df ("MIPS: math-emu: Add support for the MIPS R6 MSUBF FPU instruction")

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

---
 arch/mips/math-emu/dp_maddf.c |   18 +++++++++++++++++-
 arch/mips/math-emu/sp_maddf.c |   18 +++++++++++++++++-
 2 files changed, 34 insertions(+), 2 deletions(-)
arch/mips/math-emu/dp_maddf.c +17 -1
@@ -113,7 +113,23 @@ static union ieee754dp _dp_maddf(union i
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
 		if (zc == IEEE754_CLASS_INF)
 			return ieee754dp_inf(zs);
-		/* Multiplication is 0 so just return z */
+		if (zc == IEEE754_CLASS_ZERO) {
+			/* Handle cases +0 + (-0) and similar ones. */
+			if ((!(flags & maddf_negate_product)
+					&& (zs == (xs ^ ys))) ||
+			    ((flags & maddf_negate_product)
+					&& (zs != (xs ^ ys))))
+				/*
+				 * Cases of addition of zeros of equal signs
+				 * or subtraction of zeroes of opposite signs.
+				 * The sign of the resulting zero is in any
+				 * such case determined only by the sign of z.
+				 */
+				return z;
+
+			return ieee754dp_zero(ieee754_csr.rm == FPU_CSR_RD);
+		}
+		/* x*y is here 0, and z is not 0, so just return z */
 		return z;
 
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
arch/mips/math-emu/sp_maddf.c +17 -1
@@ -114,7 +114,23 @@ static union ieee754sp _sp_maddf(union i
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
 		if (zc == IEEE754_CLASS_INF)
 			return ieee754sp_inf(zs);
-		/* Multiplication is 0 so just return z */
+		if (zc == IEEE754_CLASS_ZERO) {
+			/* Handle cases +0 + (-0) and similar ones. */
+			if ((!(flags & maddf_negate_product)
+					&& (zs == (xs ^ ys))) ||
+			    ((flags & maddf_negate_product)
+					&& (zs != (xs ^ ys))))
+				/*
+				 * Cases of addition of zeros of equal signs
+				 * or subtraction of zeroes of opposite signs.
+				 * The sign of the resulting zero is in any
+				 * such case determined only by the sign of z.
+				 */
+				return z;
+
+			return ieee754sp_zero(ieee754_csr.rm == FPU_CSR_RD);
+		}
+		/* x*y is here 0, and z is not 0, so just return z */
 		return z;
 
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
author maintainer
#79 lore raw

PATCH 75/109 ftrace: Fix selftest goto location on error

In reply to Greg Kroah-Hartman

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

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

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

commit 46320a6acc4fb58f04bcf78c4c942cc43b20f986 upstream.

In the second iteration of trace_selftest_ops(), the error goto label is wrong in the case where trace_selftest_test_global_cnt is off. In the case of error, it leaks the dynamic ops that was allocated.

Fixes 95950c2e ("ftrace: Add self-tests for multiple function trace users")
---
 kernel/trace/trace_selftest.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/trace/trace_selftest.c +1 -1
@@ -273,7 +273,7 @@ static int trace_selftest_ops(struct tra
 		goto out_free;
 	if (cnt > 1) {
 		if (trace_selftest_test_global_cnt == 0)
-			goto out;
+			goto out_free;
 	}
 	if (trace_selftest_test_dyn_cnt == 0)
 		goto out_free;
author maintainer
#80 lore raw

PATCH 76/109 ftrace: Fix memleak when unregistering dynamic ops when tracing disabled

In reply to Greg Kroah-Hartman

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

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

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

commit edb096e00724f02db5f6ec7900f3bbd465c6c76f upstream.

If function tracing is disabled by the user via the function-trace option or the proc sysctl file, and a ftrace_ops that was allocated on the heap is unregistered, then the shutdown code exits out without doing the proper clean up. This was found via kmemleak and running the ftrace selftests, as one of the tests unregisters with function tracing disabled.

 # cat kmemleak
unreferenced object 0xffffffffa0020000 (size 4096):
  comm "swapper/0", pid 1, jiffies 4294668889 (age 569.209s)
  hex dump (first 32 bytes):
    55 ff 74 24 10 55 48 89 e5 ff 74 24 18 55 48 89  U.t$.UH...t$.UH.
    e5 48 81 ec a8 00 00 00 48 89 44 24 50 48 89 4c  .H......H.D$PH.L
  backtrace:
    [<ffffffff81d64665>] kmemleak_vmalloc+0x85/0xf0
    [<ffffffff81355631>] __vmalloc_node_range+0x281/0x3e0
    [<ffffffff8109697f>] module_alloc+0x4f/0x90
    [<ffffffff81091170>] arch_ftrace_update_trampoline+0x160/0x420
    [<ffffffff81249947>] ftrace_startup+0xe7/0x300
    [<ffffffff81249bd2>] register_ftrace_function+0x72/0x90
    [<ffffffff81263786>] trace_selftest_ops+0x204/0x397
    [<ffffffff82bb8971>] trace_selftest_startup_function+0x394/0x624
    [<ffffffff81263a75>] run_tracer_selftest+0x15c/0x1d7
    [<ffffffff82bb83f1>] init_trace_selftests+0x75/0x192
    [<ffffffff81002230>] do_one_initcall+0x90/0x1e2
    [<ffffffff82b7d620>] kernel_init_freeable+0x350/0x3fe
    [<ffffffff81d61ec3>] kernel_init+0x13/0x122
    [<ffffffff81d72c6a>] ret_from_fork+0x2a/0x40
    [<ffffffffffffffff>] 0xffffffffffffffff
Fixes 12cce594fa ("ftrace/x86: Allow !CONFIG_PREEMPT dynamic ops to use allocated trampolines")
---
 kernel/trace/ftrace.c |   10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)
kernel/trace/ftrace.c +6 -4
@@ -2828,13 +2828,14 @@ static int ftrace_shutdown(struct ftrace
 
 	if (!command || !ftrace_enabled) {
 		/*
-		 * If these are per_cpu ops, they still need their
-		 * per_cpu field freed. Since, function tracing is
+		 * If these are dynamic or per_cpu ops, they still
+		 * need their data freed. Since, function tracing is
 		 * not currently active, we can just free them
 		 * without synchronizing all CPUs.
 		 */
-		if (ops->flags & FTRACE_OPS_FL_PER_CPU)
-			per_cpu_ops_free(ops);
+		if (ops->flags & (FTRACE_OPS_FL_DYNAMIC | FTRACE_OPS_FL_PER_CPU))
+			goto free_ops;
+
 		return 0;
 	}
 
@@ -2900,6 +2901,7 @@ static int ftrace_shutdown(struct ftrace
 		if (IS_ENABLED(CONFIG_PREEMPT))
 			synchronize_rcu_tasks();
 
+ free_ops:
 		arch_ftrace_trampoline_free(ops);
 
 		if (ops->flags & FTRACE_OPS_FL_PER_CPU)
author maintainer
#81 lore raw

PATCH 77/109 tracing: Add barrier to trace_printk() buffer nesting modification

In reply to Greg Kroah-Hartman

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

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

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

commit 3d9622c12c8873911f4cc0ccdabd0362c2fca06b upstream.

trace_printk() uses 4 buffers, one for each context (normal, softirq, irq and NMI), such that it does not need to worry about one context preempting the other. There's a nesting counter that gets incremented to figure out which buffer to use. If the context gets preempted by another context which calls trace_printk() it will increment the counter and use the next buffer, and restore the counter when it is finished.

The problem is that gcc may optimize the modification of the buffer nesting counter and it may not be incremented in memory before the buffer is used. If this happens, and the context gets interrupted by another context, it could pick the same buffer and corrupt the one that is being used.

Compiler barriers need to be added after the nesting variable is incremented and before it is decremented to prevent usage of the context buffers by more than one context at the same time.

Cc Andy Lutomirski <[email protected]>
Fixes e2ace00117 ("tracing: Choose static tp_printk buffer by explicit nesting count")

Hat-tip-to: Peter Zijlstra <[email protected]>

---
 kernel/trace/trace.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
kernel/trace/trace.c +7 -1
@@ -2799,11 +2799,17 @@ static char *get_trace_buf(void)
 	if (!buffer || buffer->nesting >= 4)
 		return NULL;
 
-	return &buffer->buffer[buffer->nesting++][0];
+	buffer->nesting++;
+
+	/* Interrupts must see nesting incremented before we use the buffer */
+	barrier();
+	return &buffer->buffer[buffer->nesting][0];
 }
 
 static void put_trace_buf(void)
 {
+	/* Don't let the decrement of nesting leak before this */
+	barrier();
 	this_cpu_dec(trace_percpu_buffer->nesting);
 }
 
author maintainer
#82 lore raw

PATCH 78/109 tracing: Fix clear of RECORDED_TGID flag when disabling trace event

In reply to Greg Kroah-Hartman

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

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

From: Chunyu Hu <[email protected]>

commit 7685ab6c58557c6234f3540260195ecbee7fc4b3 upstream.

When disabling one trace event, the RECORDED_TGID flag in the event file is not correctly cleared. It's clearing RECORDED_CMD flag when it should clear RECORDED_TGID flag.

Cc Joel Fernandes <[email protected]>
Fixes d914ba37d7 ("tracing: Add support for recording tgid of tasks")
---
 kernel/trace/trace_events.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/trace/trace_events.c +1 -1
@@ -406,7 +406,7 @@ static int __ftrace_event_enable_disable
 
 			if (file->flags & EVENT_FILE_FL_RECORDED_TGID) {
 				tracing_stop_tgid_record();
-				clear_bit(EVENT_FILE_FL_RECORDED_CMD_BIT, &file->flags);
+				clear_bit(EVENT_FILE_FL_RECORDED_TGID_BIT, &file->flags);
 			}
 
 			call->class->reg(call, TRACE_REG_UNREGISTER, file);
author maintainer
#83 lore raw

PATCH 79/109 tracing: Apply trace_clock changes to instance max buffer

In reply to Greg Kroah-Hartman

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

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

From: Baohong Liu <[email protected]>

commit 170b3b1050e28d1ba0700e262f0899ffa4fccc52 upstream.

Currently trace_clock timestamps are applied to both regular and max buffers only for global trace. For instance trace, trace_clock timestamps are applied only to regular buffer. But, regular and max buffers can be swapped, for example, following a snapshot. So, for instance trace, bad timestamps can be seen following a snapshot. Let's apply trace_clock timestamps to instance max buffer as well.

Fixes 277ba0446 ("tracing: Add interface to allow multiple trace buffers")
---
 kernel/trace/trace.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/trace/trace.c +1 -1
@@ -6226,7 +6226,7 @@ static int tracing_set_clock(struct trac
 	tracing_reset_online_cpus(&tr->trace_buffer);
 
 #ifdef CONFIG_TRACER_MAX_TRACE
-	if (tr->flags & TRACE_ARRAY_FL_GLOBAL && tr->max_buffer.buffer)
+	if (tr->max_buffer.buffer)
 		ring_buffer_set_clock(tr->max_buffer.buffer, trace_clocks[i].func);
 	tracing_reset_online_cpus(&tr->max_buffer);
 #endif
author maintainer
#84 lore raw

PATCH 80/109 ARC: Re-enable MMU upon Machine Check exception

In reply to Greg Kroah-Hartman

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

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

From: Jose Abreu <[email protected]>

commit 1ee55a8f7f6b7ca4c0c59e0b4b4e3584a085c2d3 upstream.

I recently came upon a scenario where I would get a double fault machine check exception tiriggered by a kernel module. However the ensuing crash stacktrace (ksym lookup) was not working correctly.

Turns out that machine check auto-disables MMU while modules are allocated in kernel vaddr spapce.

This patch re-enables the MMU before start printing the stacktrace making stacktracing of modules work upon a fatal exception.

[vgupta: moved code into low level handler to avoid in 2 places]
---
 arch/arc/kernel/entry.S |    6 ++++++
 arch/arc/mm/tlb.c       |    3 ---
 2 files changed, 6 insertions(+), 3 deletions(-)
arch/arc/kernel/entry.S +6 -0
@@ -92,6 +92,12 @@ ENTRY(EV_MachineCheck)
 	lr  r0, [efa]
 	mov r1, sp
 
+	; hardware auto-disables MMU, re-enable it to allow kernel vaddr
+	; access for say stack unwinding of modules for crash dumps
+	lr	r3, [ARC_REG_PID]
+	or	r3, r3, MMU_ENABLE
+	sr	r3, [ARC_REG_PID]
+
 	lsr  	r3, r2, 8
 	bmsk 	r3, r3, 7
 	brne    r3, ECR_C_MCHK_DUP_TLB, 1f
arch/arc/mm/tlb.c +0 -3
@@ -908,9 +908,6 @@ void do_tlb_overlap_fault(unsigned long
 
 	local_irq_save(flags);
 
-	/* re-enable the MMU */
-	write_aux_reg(ARC_REG_PID, MMU_ENABLE | read_aux_reg(ARC_REG_PID));
-
 	/* loop thru all sets of TLB */
 	for (set = 0; set < mmu->sets; set++) {
 
author maintainer
#85 lore raw

PATCH 81/109 PCI: shpchp: Enable bridge bus mastering if MSI is enabled

In reply to Greg Kroah-Hartman

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

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

From: Aleksandr Bezzubikov <[email protected]>

commit 48b79a14505349a29b3e20f03619ada9b33c4b17 upstream.

An SHPC may generate MSIs to notify software about slot or controller events (SHPC spec r1.0, sec 4.7). A PCI device can only generate an MSI if it has bus mastering enabled.

Enable bus mastering if the bridge contains an SHPC that uses MSI for event notifications.

---
 drivers/pci/hotplug/shpchp_hpc.c |    2 ++
 1 file changed, 2 insertions(+)
drivers/pci/hotplug/shpchp_hpc.c +2 -0
@@ -1062,6 +1062,8 @@ int shpc_init(struct controller *ctrl, s
 		if (rc) {
 			ctrl_info(ctrl, "Can't get msi for the hotplug controller\n");
 			ctrl_info(ctrl, "Use INTx for the hotplug controller\n");
+		} else {
+			pci_set_master(pdev);
 		}
 
 		rc = request_irq(ctrl->pci_dev->irq, shpc_isr, IRQF_SHARED,
author maintainer
#86 lore raw

PATCH 82/109 PCI: pciehp: Report power fault only once until we clear it

In reply to Greg Kroah-Hartman

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

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

From: Keith Busch <[email protected]>

commit 7612b3b28c0b900dcbcdf5e9b9747cc20a1e2455 upstream.

When a power fault occurs, the power controller sets Power Fault Detected in the Slot Status register, and pciehp_isr() queues an INT_POWER_FAULT event to handle it.

It also clears Power Fault Detected, but since nothing has yet changed to correct the power fault, the power controller will likely set it again immediately, which may cause an infinite loop when pcie_isr() rechecks Slot Status.

Fix that by masking off Power Fault Detected from new events if the driver hasn't seen the power fault clear from the previous handling attempt.

Fixes fad214b0aa72 ("PCI: pciehp: Process all hotplug events before looking for new ones")
[bhelgaas: changelog, pull test out and add comment]
Cc Mayurkumar Patel <[email protected]>
---
 drivers/pci/hotplug/pciehp_hpc.c |    8 ++++++++
 1 file changed, 8 insertions(+)
drivers/pci/hotplug/pciehp_hpc.c +8 -0
@@ -586,6 +586,14 @@ static irqreturn_t pciehp_isr(int irq, v
 	events = status & (PCI_EXP_SLTSTA_ABP | PCI_EXP_SLTSTA_PFD |
 			   PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_CC |
 			   PCI_EXP_SLTSTA_DLLSC);
+
+	/*
+	 * If we've already reported a power fault, don't report it again
+	 * until we've done something to handle it.
+	 */
+	if (ctrl->power_fault_detected)
+		events &= ~PCI_EXP_SLTSTA_PFD;
+
 	if (!events)
 		return IRQ_NONE;
 
author maintainer
#88 lore raw

PATCH 84/109 s390/mm: fix local TLB flushing vs. detach of an mm address space

In reply to Greg Kroah-Hartman

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

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

From: Martin Schwidefsky <[email protected]>

commit b3e5dc45fd1ec2aa1de6b80008f9295eb17e0659 upstream.

The local TLB flushing code keeps an additional mask in the mm.context, the cpu_attach_mask. At the time a global flush of an address space is done the cpu_attach_mask is copied to the mm_cpumask in order to avoid future global flushes in case the mm is used by a single CPU only after the flush.

Trouble is that the reset of the mm_cpumask is racy against the detach of an mm address space by switch_mm. The current order is first the global TLB flush and then the copy of the cpu_attach_mask to the mm_cpumask. The order needs to be the other way around.

---
 arch/s390/include/asm/mmu_context.h |    4 ++--
 arch/s390/include/asm/tlbflush.h    |   26 +++++---------------------
 2 files changed, 7 insertions(+), 23 deletions(-)
arch/s390/include/asm/mmu_context.h +2 -2
@@ -102,7 +102,6 @@ static inline void switch_mm(struct mm_s
 	if (prev == next)
 		return;
 	cpumask_set_cpu(cpu, &next->context.cpu_attach_mask);
-	cpumask_set_cpu(cpu, mm_cpumask(next));
 	/* Clear old ASCE by loading the kernel ASCE. */
 	__ctl_load(S390_lowcore.kernel_asce, 1, 1);
 	__ctl_load(S390_lowcore.kernel_asce, 7, 7);
@@ -120,7 +119,7 @@ static inline void finish_arch_post_lock
 		preempt_disable();
 		while (atomic_read(&mm->context.flush_count))
 			cpu_relax();
-
+		cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm));
 		if (mm->context.flush_mm)
 			__tlb_flush_mm(mm);
 		preempt_enable();
@@ -135,6 +134,7 @@ static inline void activate_mm(struct mm
                                struct mm_struct *next)
 {
 	switch_mm(prev, next, current);
+	cpumask_set_cpu(smp_processor_id(), mm_cpumask(next));
 	set_user_asce(next);
 }
 
arch/s390/include/asm/tlbflush.h +5 -21
@@ -43,23 +43,6 @@ static inline void __tlb_flush_global(vo
  * Flush TLB entries for a specific mm on all CPUs (in case gmap is used
  * this implicates multiple ASCEs!).
  */
-static inline void __tlb_flush_full(struct mm_struct *mm)
-{
-	preempt_disable();
-	atomic_inc(&mm->context.flush_count);
-	if (cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) {
-		/* Local TLB flush */
-		__tlb_flush_local();
-	} else {
-		/* Global TLB flush */
-		__tlb_flush_global();
-		/* Reset TLB flush mask */
-		cpumask_copy(mm_cpumask(mm), &mm->context.cpu_attach_mask);
-	}
-	atomic_dec(&mm->context.flush_count);
-	preempt_enable();
-}
-
 static inline void __tlb_flush_mm(struct mm_struct *mm)
 {
 	unsigned long gmap_asce;
@@ -71,16 +54,18 @@ static inline void __tlb_flush_mm(struct
 	 */
 	preempt_disable();
 	atomic_inc(&mm->context.flush_count);
+	/* Reset TLB flush mask */
+	cpumask_copy(mm_cpumask(mm), &mm->context.cpu_attach_mask);
+	barrier();
 	gmap_asce = READ_ONCE(mm->context.gmap_asce);
 	if (MACHINE_HAS_IDTE && gmap_asce != -1UL) {
 		if (gmap_asce)
 			__tlb_flush_idte(gmap_asce);
 		__tlb_flush_idte(mm->context.asce);
 	} else {
-		__tlb_flush_full(mm);
+		/* Global TLB flush */
+		__tlb_flush_global();
 	}
-	/* Reset TLB flush mask */
-	cpumask_copy(mm_cpumask(mm), &mm->context.cpu_attach_mask);
 	atomic_dec(&mm->context.flush_count);
 	preempt_enable();
 }
@@ -94,7 +79,6 @@ static inline void __tlb_flush_kernel(vo
 }
 #else
 #define __tlb_flush_global()	__tlb_flush_local()
-#define __tlb_flush_full(mm)	__tlb_flush_local()
 
 /*
  * Flush TLB entries for a specific ASCE on all CPUs.
author maintainer
#89 lore raw

PATCH 85/109 s390/mm: fix race on mm->context.flush_mm

In reply to Greg Kroah-Hartman

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

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

From: Martin Schwidefsky <[email protected]>

commit 60f07c8ec5fae06c23e9fd7bab67dabce92b3414 upstream.

The order in __tlb_flush_mm_lazy is to flush TLB first and then clear the mm->context.flush_mm bit. This can lead to missed flushes as the bit can be set anytime, the order needs to be the other way aronud.

But this leads to a different race, __tlb_flush_mm_lazy may be called on two CPUs concurrently. If mm->context.flush_mm is cleared first then another CPU can bypass __tlb_flush_mm_lazy although the first CPU has not done the flush yet. In a virtualized environment the time until the flush is finally completed can be arbitrarily long.

Add a spinlock to serialize __tlb_flush_mm_lazy and use the function in finish_arch_post_lock_switch as well.

---
 arch/s390/include/asm/mmu.h         |    2 ++
 arch/s390/include/asm/mmu_context.h |    4 ++--
 arch/s390/include/asm/tlbflush.h    |    4 +++-
 3 files changed, 7 insertions(+), 3 deletions(-)
arch/s390/include/asm/mmu.h +2 -0
@@ -5,6 +5,7 @@
 #include <linux/errno.h>
 
 typedef struct {
+	spinlock_t lock;
 	cpumask_t cpu_attach_mask;
 	atomic_t flush_count;
 	unsigned int flush_mm;
@@ -27,6 +28,7 @@ typedef struct {
 } mm_context_t;
 
 #define INIT_MM_CONTEXT(name)						   \
+	.context.lock =	__SPIN_LOCK_UNLOCKED(name.context.lock),	   \
 	.context.pgtable_lock =						   \
 			__SPIN_LOCK_UNLOCKED(name.context.pgtable_lock),   \
 	.context.pgtable_list = LIST_HEAD_INIT(name.context.pgtable_list), \
arch/s390/include/asm/mmu_context.h +2 -2
@@ -16,6 +16,7 @@
 static inline int init_new_context(struct task_struct *tsk,
 				   struct mm_struct *mm)
 {
+	spin_lock_init(&mm->context.lock);
 	spin_lock_init(&mm->context.pgtable_lock);
 	INIT_LIST_HEAD(&mm->context.pgtable_list);
 	spin_lock_init(&mm->context.gmap_lock);
@@ -120,8 +121,7 @@ static inline void finish_arch_post_lock
 		while (atomic_read(&mm->context.flush_count))
 			cpu_relax();
 		cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm));
-		if (mm->context.flush_mm)
-			__tlb_flush_mm(mm);
+		__tlb_flush_mm_lazy(mm);
 		preempt_enable();
 	}
 	set_fs(current->thread.mm_segment);
arch/s390/include/asm/tlbflush.h +3 -1
@@ -96,10 +96,12 @@ static inline void __tlb_flush_kernel(vo
 
 static inline void __tlb_flush_mm_lazy(struct mm_struct * mm)
 {
+	spin_lock(&mm->context.lock);
 	if (mm->context.flush_mm) {
-		__tlb_flush_mm(mm);
 		mm->context.flush_mm = 0;
+		__tlb_flush_mm(mm);
 	}
+	spin_unlock(&mm->context.lock);
 }
 
 /*
author maintainer
#90 lore raw

PATCH 86/109 media: v4l2-compat-ioctl32: Fix timespec conversion

In reply to Greg Kroah-Hartman

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

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

From: Daniel Mentz <[email protected]>

commit 9c7ba1d7634cef490b85bc64c4091ff004821bfd upstream.

Certain syscalls like recvmmsg support 64 bit timespec values for the X32 ABI. The helper function compat_put_timespec converts a timespec value to a 32 bit or 64 bit value depending on what ABI is used. The v4l2 compat layer, however, is not designed to support 64 bit timespec values and always uses 32 bit values. Hence, compat_put_timespec must not be used.

Without this patch, user space will be provided with bad timestamp values from the VIDIOC_DQEVENT ioctl. Also, fields of the struct v4l2_event32 that come immediately after timestamp get overwritten, namely the field named id.

Fixes 81993e81a994 ("compat: Get rid of (get|put)_compat_time(val|spec)")
Cc H. Peter Anvin <[email protected]>
Cc Laurent Pinchart <[email protected]>
Cc Tiffany Lin <[email protected]>
Cc Ricardo Ribalda Delgado <[email protected]>
Cc Sakari Ailus <[email protected]>
---
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/media/v4l2-core/v4l2-compat-ioctl32.c +2 -1
@@ -796,7 +796,8 @@ static int put_v4l2_event32(struct v4l2_
 		copy_to_user(&up->u, &kp->u, sizeof(kp->u)) ||
 		put_user(kp->pending, &up->pending) ||
 		put_user(kp->sequence, &up->sequence) ||
-		compat_put_timespec(&kp->timestamp, &up->timestamp) ||
+		put_user(kp->timestamp.tv_sec, &up->timestamp.tv_sec) ||
+		put_user(kp->timestamp.tv_nsec, &up->timestamp.tv_nsec) ||
 		put_user(kp->id, &up->id) ||
 		copy_to_user(up->reserved, kp->reserved, 8 * sizeof(__u32)))
 			return -EFAULT;
author maintainer
#91 lore raw

PATCH 87/109 media: Revert "[media] lirc_dev: remove superfluous get/put_device() calls"

In reply to Greg Kroah-Hartman

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

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

From: Sean Young <[email protected]>

commit a607f51e5a4c421e2097077db88105402099c528 upstream.

This reverts commit 5be2b76a9ca4ea5fd3e221114d62eeb0d78267ca.

Only when the lirc device is freed, should we drop our reference to rc_dev, else we the rc_dev is freed to early. If userspace has a file descriptor open during unplug, it goes bang.

==================================================================

BUG: KASAN: use-after-free in __lock_acquire+0x7bb/0x1e10
Read of size 8 at addr ffff8801d7d61ed0 by task ir-rec/2609

-snip-

 mutex_lock_nested+0x1b/0x20
 ? mutex_lock_nested+0x1b/0x20
 rc_close.part.6+0x20/0x60 [rc_core]
 rc_close+0x13/0x20 [rc_core]
 lirc_dev_fop_close+0x62/0xd0 [lirc_dev]
 __fput+0x236/0x410
 ? fput+0xb0/0xb0
 ? do_raw_spin_trylock+0x110/0x110
 ? set_rq_offline.part.70+0xa0/0xa0
 ____fput+0xe/0x10
 task_work_run+0x116/0x180
 ? task_work_cancel+0x170/0x170
 ? _raw_spin_unlock+0x27/0x40
 ? switch_task_namespaces+0x5f/0x90
 do_exit+0x68b/0xe80
Fixes 5be2b76a9ca4 ("[media] lirc_dev: remove superfluous get/put_device() calls")
---
 drivers/media/rc/lirc_dev.c |    4 ++++
 1 file changed, 4 insertions(+)
drivers/media/rc/lirc_dev.c +4 -0
@@ -59,6 +59,8 @@ static void lirc_release(struct device *
 {
 	struct irctl *ir = container_of(ld, struct irctl, dev);
 
+	put_device(ir->dev.parent);
+
 	if (ir->buf_internal) {
 		lirc_buffer_free(ir->buf);
 		kfree(ir->buf);
@@ -218,6 +220,8 @@ int lirc_register_driver(struct lirc_dri
 
 	mutex_unlock(&lirc_dev_lock);
 
+	get_device(ir->dev.parent);
+
 	dev_info(ir->d.dev, "lirc_dev: driver %s registered at minor = %d\n",
 		 ir->d.name, ir->d.minor);
 
author maintainer
#92 lore raw

PATCH 88/109 media: venus: fix copy/paste error in return_buf_error

In reply to Greg Kroah-Hartman

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

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

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

commit 0de0ef6c3f2dd7e9965270683445917e10384ab0 upstream.

Call function v4l2_m2m_dst_buf_remove_by_buf() instead of v4l2_m2m_src_buf_remove_by_buf()

Addresses-Coverity-ID: 1415317

---
 drivers/media/platform/qcom/venus/helpers.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/platform/qcom/venus/helpers.c +1 -1
@@ -243,7 +243,7 @@ static void return_buf_error(struct venu
 	if (vbuf->vb2_buf.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
 		v4l2_m2m_src_buf_remove_by_buf(m2m_ctx, vbuf);
 	else
-		v4l2_m2m_src_buf_remove_by_buf(m2m_ctx, vbuf);
+		v4l2_m2m_dst_buf_remove_by_buf(m2m_ctx, vbuf);
 
 	v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
 }
author maintainer
#94 lore raw

PATCH 90/109 media: adv7180: add missing adv7180cp, adv7180st i2c device IDs

In reply to Greg Kroah-Hartman

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

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

From: Ulrich Hecht <[email protected]>

commit 281ddc3cdc10413b98531d701ab5323c4f3ff1f4 upstream.

Fixes a crash on Renesas R8A7793 Gose board that uses these "compatible" entries.

---
 drivers/media/i2c/adv7180.c |    2 ++
 1 file changed, 2 insertions(+)
drivers/media/i2c/adv7180.c +2 -0
@@ -1402,6 +1402,8 @@ static int adv7180_remove(struct i2c_cli
 
 static const struct i2c_device_id adv7180_id[] = {
 	{ "adv7180", (kernel_ulong_t)&adv7180_info },
+	{ "adv7180cp", (kernel_ulong_t)&adv7180_info },
+	{ "adv7180st", (kernel_ulong_t)&adv7180_info },
 	{ "adv7182", (kernel_ulong_t)&adv7182_info },
 	{ "adv7280", (kernel_ulong_t)&adv7280_info },
 	{ "adv7280-m", (kernel_ulong_t)&adv7280_m_info },
author maintainer
#95 lore raw

PATCH 91/109 PM / devfreq: Fix memory leak when fail to register device

In reply to Greg Kroah-Hartman

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

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

From: Chanwoo Choi <[email protected]>

commit 9e14de1077e9c34f141cf98bdba60cdd5193d962 upstream.

When the devfreq_add_device fails to register deivce, the memory leak of devfreq instance happen. So, this patch fix the memory leak issue. Before freeing the devfreq instance checks whether devfreq instance is NULL or not because the device_unregister() frees the devfreq instance when jumping to the 'err_init'. It is to prevent the duplicate the kfee(devfreq).

Fixes ac4b281176a5 ("PM / devfreq: fix duplicated kfree on devfreq pointer")
---
 drivers/devfreq/devfreq.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/devfreq/devfreq.c +4 -1
@@ -564,7 +564,7 @@ struct devfreq *devfreq_add_device(struc
 	err = device_register(&devfreq->dev);
 	if (err) {
 		mutex_unlock(&devfreq->lock);
-		goto err_out;
+		goto err_dev;
 	}
 
 	devfreq->trans_table =	devm_kzalloc(&devfreq->dev,
@@ -610,6 +610,9 @@ err_init:
 	mutex_unlock(&devfreq_list_lock);
 
 	device_unregister(&devfreq->dev);
+err_dev:
+	if (devfreq)
+		kfree(devfreq);
 err_out:
 	return ERR_PTR(err);
 }
author maintainer
#96 lore raw

PATCH 92/109 ALSA: seq: Cancel pending autoload work at unbinding device

In reply to Greg Kroah-Hartman

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

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

From: Takashi Iwai <[email protected]>

commit fc27fe7e8deef2f37cba3f2be2d52b6ca5eb9d57 upstream.

ALSA sequencer core has a mechanism to load the enumerated devices automatically, and it's performed in an off-load work. This seems causing some race when a sequencer is removed while the pending autoload work is running. As syzkaller spotted, it may lead to some use-after-free:

  BUG: KASAN: use-after-free in snd_rawmidi_dev_seq_free+0x69/0x70
  sound/core/rawmidi.c:1617
  Write of size 8 at addr ffff88006c611d90 by task kworker/2:1/567

  CPU: 2 PID: 567 Comm: kworker/2:1 Not tainted 4.13.0+ #29
  Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
  Workqueue: events autoload_drivers
  Call Trace:
   __dump_stack lib/dump_stack.c:16 [inline]
   dump_stack+0x192/0x22c lib/dump_stack.c:52
   print_address_description+0x78/0x280 mm/kasan/report.c:252
   kasan_report_error mm/kasan/report.c:351 [inline]
   kasan_report+0x230/0x340 mm/kasan/report.c:409
   __asan_report_store8_noabort+0x1c/0x20 mm/kasan/report.c:435
   snd_rawmidi_dev_seq_free+0x69/0x70 sound/core/rawmidi.c:1617
   snd_seq_dev_release+0x4f/0x70 sound/core/seq_device.c:192
   device_release+0x13f/0x210 drivers/base/core.c:814
   kobject_cleanup lib/kobject.c:648 [inline]
   kobject_release lib/kobject.c:677 [inline]
   kref_put include/linux/kref.h:70 [inline]
   kobject_put+0x145/0x240 lib/kobject.c:694
   put_device+0x25/0x30 drivers/base/core.c:1799
   klist_devices_put+0x36/0x40 drivers/base/bus.c:827
   klist_next+0x264/0x4a0 lib/klist.c:403
   next_device drivers/base/bus.c:270 [inline]
   bus_for_each_dev+0x17e/0x210 drivers/base/bus.c:312
   autoload_drivers+0x3b/0x50 sound/core/seq_device.c:117
   process_one_work+0x9fb/0x1570 kernel/workqueue.c:2097
   worker_thread+0x1e4/0x1350 kernel/workqueue.c:2231
   kthread+0x324/0x3f0 kernel/kthread.c:231
   ret_from_fork+0x25/0x30 arch/x86/entry/entry_64.S:425

The fix is simply to assure canceling the autoload work at removing the device.

---
 sound/core/seq_device.c |    3 +++
 1 file changed, 3 insertions(+)
sound/core/seq_device.c +3 -0
@@ -148,8 +148,10 @@ void snd_seq_device_load_drivers(void)
 	flush_work(&autoload_work);
 }
 EXPORT_SYMBOL(snd_seq_device_load_drivers);
+#define cancel_autoload_drivers()	cancel_work_sync(&autoload_work)
 #else
 #define queue_autoload_drivers() /* NOP */
+#define cancel_autoload_drivers() /* NOP */
 #endif
 
 /*
@@ -159,6 +161,7 @@ static int snd_seq_device_dev_free(struc
 {
 	struct snd_seq_device *dev = device->device_data;
 
+	cancel_autoload_drivers();
 	put_device(&dev->dev);
 	return 0;
 }
author maintainer
#97 lore raw

PATCH 93/109 bcache: initialize dirty stripes in flash_dev_run()

In reply to Greg Kroah-Hartman

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

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

From: Tang Junhui <[email protected]>

commit 175206cf9ab63161dec74d9cd7f9992e062491f5 upstream.

bcache uses a Proportion-Differentiation Controller algorithm to control writeback rate to cached devices. In the PD controller algorithm, dirty stripes of thin flash device should not be counted in, because flash only volumes never write back dirty data.

Currently dirty stripe counter for thin flash device is not initialized when the thin flash device starts. Which means the following calculation in PD controller will reference an undefined dirty stripes number, and all cached devices attached to the same cache set where the thin flash device lies on may have an inaccurate writeback rate.

This patch calles bch_sectors_dirty_init() in flash_dev_run(), to correctly initialize dirty stripe counter when the thin flash device starts to run. This patch also does following parameter data type change,
-void bch_sectors_dirty_init(struct cached_dev *dc);
+void bch_sectors_dirty_init(struct bcache_device *);
to call this function conveniently in flash_dev_run().

(Commit log is composed by Coly Li)

---
 drivers/md/bcache/super.c     |    3 ++-
 drivers/md/bcache/writeback.c |    8 ++++----
 drivers/md/bcache/writeback.h |    2 +-
 3 files changed, 7 insertions(+), 6 deletions(-)
drivers/md/bcache/super.c +2 -1
@@ -1026,7 +1026,7 @@ int bch_cached_dev_attach(struct cached_
 	}
 
 	if (BDEV_STATE(&dc->sb) == BDEV_STATE_DIRTY) {
-		bch_sectors_dirty_init(dc);
+		bch_sectors_dirty_init(&dc->disk);
 		atomic_set(&dc->has_dirty, 1);
 		atomic_inc(&dc->count);
 		bch_writeback_queue(dc);
@@ -1228,6 +1228,7 @@ static int flash_dev_run(struct cache_se
 		goto err;
 
 	bcache_device_attach(d, c, u - c->uuids);
+	bch_sectors_dirty_init(d);
 	bch_flash_dev_request_init(d);
 	add_disk(d->disk);
 
drivers/md/bcache/writeback.c +4 -4
@@ -482,17 +482,17 @@ static int sectors_dirty_init_fn(struct
 	return MAP_CONTINUE;
 }
 
-void bch_sectors_dirty_init(struct cached_dev *dc)
+void bch_sectors_dirty_init(struct bcache_device *d)
 {
 	struct sectors_dirty_init op;
 
 	bch_btree_op_init(&op.op, -1);
-	op.inode = dc->disk.id;
+	op.inode = d->id;
 
-	bch_btree_map_keys(&op.op, dc->disk.c, &KEY(op.inode, 0, 0),
+	bch_btree_map_keys(&op.op, d->c, &KEY(op.inode, 0, 0),
 			   sectors_dirty_init_fn, 0);
 
-	dc->disk.sectors_dirty_last = bcache_dev_sectors_dirty(&dc->disk);
+	d->sectors_dirty_last = bcache_dev_sectors_dirty(d);
 }
 
 void bch_cached_dev_writeback_init(struct cached_dev *dc)
drivers/md/bcache/writeback.h +1 -1
@@ -84,7 +84,7 @@ static inline void bch_writeback_add(str
 
 void bcache_dev_sectors_dirty_add(struct cache_set *, unsigned, uint64_t, int);
 
-void bch_sectors_dirty_init(struct cached_dev *dc);
+void bch_sectors_dirty_init(struct bcache_device *);
 void bch_cached_dev_writeback_init(struct cached_dev *);
 int bch_cached_dev_writeback_start(struct cached_dev *);
 
author maintainer
#98 lore raw

PATCH 94/109 bcache: Fix leak of bdev reference

In reply to Greg Kroah-Hartman

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

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

From: Jan Kara <[email protected]>

commit 4b758df21ee7081ab41448d21d60367efaa625b3 upstream.

If blkdev_get_by_path() in register_bcache() fails, we try to lookup the block device using lookup_bdev() to detect which situation we are in to properly report error. However we never drop the reference returned to us from lookup_bdev(). Fix that.

---
 drivers/md/bcache/super.c |    2 ++
 1 file changed, 2 insertions(+)
drivers/md/bcache/super.c +2 -0
@@ -1965,6 +1965,8 @@ static ssize_t register_bcache(struct ko
 			else
 				err = "device busy";
 			mutex_unlock(&bch_register_lock);
+			if (!IS_ERR(bdev))
+				bdput(bdev);
 			if (attr == &ksysfs_register_quiet)
 				goto out;
 		}
author maintainer
#72 lore raw

PATCH 68/109 scsi: qla2xxx: Correction to vha->vref_count timeout

In reply to Greg Kroah-Hartman

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

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

From: Joe Carnuccio <[email protected]>

commit 6e98095f8fb6d98da34c4e6c34e69e7c638d79c0 upstream.

Fix incorrect second argument for wait_event_timeout()

Fixes c4a9b538ab2a ("qla2xxx: Allow vref count to timeout on vport delete.")
---
 drivers/scsi/qla2xxx/qla_mid.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/qla2xxx/qla_mid.c +1 -1
@@ -74,7 +74,7 @@ qla24xx_deallocate_vp_id(scsi_qla_host_t
 	 * ensures no active vp_list traversal while the vport is removed
 	 * from the queue)
 	 */
-	wait_event_timeout(vha->vref_waitq, atomic_read(&vha->vref_count),
+	wait_event_timeout(vha->vref_waitq, !atomic_read(&vha->vref_count),
 	    10*HZ);
 
 	spin_lock_irqsave(&ha->vport_slock, flags);
author maintainer
#99 lore raw

PATCH 95/109 bcache: do not subtract sectors_to_gc for bypassed IO

In reply to Greg Kroah-Hartman

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

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

From: Tang Junhui <[email protected]>

commit 69daf03adef5f7bc13e0ac86b4b8007df1767aab upstream.

Since bypassed IOs use no bucket, so do not subtract sectors_to_gc to trigger gc thread.

---
 drivers/md/bcache/request.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/md/bcache/request.c +3 -3
@@ -196,12 +196,12 @@ static void bch_data_insert_start(struct
 	struct data_insert_op *op = container_of(cl, struct data_insert_op, cl);
 	struct bio *bio = op->bio, *n;
 
-	if (atomic_sub_return(bio_sectors(bio), &op->c->sectors_to_gc) < 0)
-		wake_up_gc(op->c);
-
 	if (op->bypass)
 		return bch_data_invalidate(cl);
 
+	if (atomic_sub_return(bio_sectors(bio), &op->c->sectors_to_gc) < 0)
+		wake_up_gc(op->c);
+
 	/*
 	 * Journal writes are marked REQ_PREFLUSH; if the original write was a
 	 * flush, it'll wait on the journal write.
author maintainer
#100 lore raw

PATCH 96/109 bcache: correct cache_dirty_target in __update_writeback_rate()

In reply to Greg Kroah-Hartman

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

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

From: Tang Junhui <[email protected]>

commit a8394090a9129b40f9d90dcb7f4a49d60c727ca6 upstream.

__update_write_rate() uses a Proportion-Differentiation Controller algorithm to control writeback rate. A dirty target number is used in this PD controller to control writeback rate. A larger target number will make the writeback rate smaller, on the versus, a smaller target number will make the writeback rate larger.

bcache uses the following steps to calculate the target number,
1) cache_sectors = all-buckets-of-cache-set * buckets-size
2) cache_dirty_target = cache_sectors * cached-device-writeback_percent
3) target = cache_dirty_target * (sectors-of-cached-device/sectors-of-all-cached-devices-of-this-cache-set)

The calculation at step 1) for cache_sectors is incorrect, which does not consider dirty blocks occupied by flash only volume.

A flash only volume can be took as a bcache device without cached device. All data sectors allocated for it are persistent on cache device and marked dirty, they are not touched by bcache writeback and garbage collection code. So data blocks of flash only volume should be ignore when calculating cache_sectors of cache set.

Current code does not subtract dirty sectors of flash only volume, which results a larger target number from the above 3 steps. And in sequence the cache device's writeback rate is smaller then a correct value, writeback speed is slower on all cached devices.

This patch fixes the incorrect slower writeback rate by subtracting dirty sectors of flash only volumes in __update_writeback_rate().

(Commit log composed by Coly Li to pass checkpatch.pl checking)

---
 drivers/md/bcache/writeback.c |    3 ++-
 drivers/md/bcache/writeback.h |   19 +++++++++++++++++++
 2 files changed, 21 insertions(+), 1 deletion(-)
drivers/md/bcache/writeback.c +2 -1
@@ -21,7 +21,8 @@
 static void __update_writeback_rate(struct cached_dev *dc)
 {
 	struct cache_set *c = dc->disk.c;
-	uint64_t cache_sectors = c->nbuckets * c->sb.bucket_size;
+	uint64_t cache_sectors = c->nbuckets * c->sb.bucket_size -
+				bcache_flash_devs_sectors_dirty(c);
 	uint64_t cache_dirty_target =
 		div_u64(cache_sectors * dc->writeback_percent, 100);
 
drivers/md/bcache/writeback.h +19 -0
@@ -14,6 +14,25 @@ static inline uint64_t bcache_dev_sector
 	return ret;
 }
 
+static inline uint64_t  bcache_flash_devs_sectors_dirty(struct cache_set *c)
+{
+	uint64_t i, ret = 0;
+
+	mutex_lock(&bch_register_lock);
+
+	for (i = 0; i < c->nr_uuids; i++) {
+		struct bcache_device *d = c->devices[i];
+
+		if (!d || !UUID_FLASH_ONLY(&c->uuids[i]))
+			continue;
+	   ret += bcache_dev_sectors_dirty(d);
+	}
+
+	mutex_unlock(&bch_register_lock);
+
+	return ret;
+}
+
 static inline unsigned offset_to_stripe(struct bcache_device *d,
 					uint64_t offset)
 {
author maintainer
#101 lore raw

PATCH 97/109 bcache: Correct return value for sysfs attach errors

In reply to Greg Kroah-Hartman

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

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

From: Tony Asleson <[email protected]>

commit 77fa100f27475d08a569b9d51c17722130f089e7 upstream.

If you encounter any errors in bch_cached_dev_attach it will return a negative error code. The variable 'v' which stores the result is unsigned, thus user space sees a very large value returned for bytes written which can cause incorrect user space behavior. Utilize 1 signed variable to use throughout the function to preserve error return capability.

---
 drivers/md/bcache/sysfs.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/md/bcache/sysfs.c +2 -2
@@ -192,7 +192,7 @@ STORE(__cached_dev)
 {
 	struct cached_dev *dc = container_of(kobj, struct cached_dev,
 					     disk.kobj);
-	unsigned v = size;
+	ssize_t v = size;
 	struct cache_set *c;
 	struct kobj_uevent_env *env;
 
@@ -227,7 +227,7 @@ STORE(__cached_dev)
 		bch_cached_dev_run(dc);
 
 	if (attr == &sysfs_cache_mode) {
-		ssize_t v = bch_read_string_list(buf, bch_cache_modes + 1);
+		v = bch_read_string_list(buf, bch_cache_modes + 1);
 
 		if (v < 0)
 			return v;
author maintainer
#102 lore raw

PATCH 99/109 bcache: fix for gc and write-back race

In reply to Greg Kroah-Hartman

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

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

From: Tang Junhui <[email protected]>

commit 9baf30972b5568d8b5bc8b3c46a6ec5b58100463 upstream.

gc and write-back get raced (see the email "bcache get stucked" I sended before):

gc thread                               write-back thread
|                                       |bch_writeback_thread()
|bch_gc_thread()                        |
|                                       |==>read_dirty()
|==>bch_btree_gc()                      |
|==>btree_root() //get btree root       |
|                //node write locker    |
|==>bch_btree_gc_root()                 |
|                                       |==>read_dirty_submit()
|                                       |==>write_dirty()
|                                       |==>continue_at(cl,
|                                       |               write_dirty_finish,
|                                       |               system_wq);
|                                       |==>write_dirty_finish()//excute
|                                       |               //in system_wq
|                                       |==>bch_btree_insert()
|                                       |==>bch_btree_map_leaf_nodes()
|                                       |==>__bch_btree_map_nodes()
|                                       |==>btree_root //try to get btree
|                                       |              //root node read
|                                       |              //lock
|                                       |-----stuck here
|==>bch_btree_set_root()
|==>bch_journal_meta()
|==>bch_journal()
|==>journal_try_write()
|==>journal_write_unlocked() //journal_full(&c->journal)
|                            //condition satisfied
|==>continue_at(cl, journal_write, system_wq); //try to excute
|                               //journal_write in system_wq
|                               //but work queue is excuting
|                               //write_dirty_finish()
|==>closure_sync(); //wait journal_write execute
|                   //over and wake up gc,
|-------------stuck here
|==>release root node write locker

This patch alloc a separate work-queue for write-back thread to avoid such race.

(Commit log re-organized by Coly Li to pass checkpatch.pl checking)

---
 drivers/md/bcache/bcache.h    |    1 +
 drivers/md/bcache/super.c     |    2 ++
 drivers/md/bcache/writeback.c |    9 +++++++--
 3 files changed, 10 insertions(+), 2 deletions(-)
drivers/md/bcache/bcache.h +1 -0
@@ -333,6 +333,7 @@ struct cached_dev {
 	/* Limit number of writeback bios in flight */
 	struct semaphore	in_flight;
 	struct task_struct	*writeback_thread;
+	struct workqueue_struct	*writeback_write_wq;
 
 	struct keybuf		writeback_keys;
 
drivers/md/bcache/super.c +2 -0
@@ -1059,6 +1059,8 @@ static void cached_dev_free(struct closu
 	cancel_delayed_work_sync(&dc->writeback_rate_update);
 	if (!IS_ERR_OR_NULL(dc->writeback_thread))
 		kthread_stop(dc->writeback_thread);
+	if (dc->writeback_write_wq)
+		destroy_workqueue(dc->writeback_write_wq);
 
 	mutex_lock(&bch_register_lock);
 
drivers/md/bcache/writeback.c +7 -2
@@ -187,7 +187,7 @@ static void write_dirty(struct closure *
 
 	closure_bio_submit(&io->bio, cl);
 
-	continue_at(cl, write_dirty_finish, system_wq);
+	continue_at(cl, write_dirty_finish, io->dc->writeback_write_wq);
 }
 
 static void read_dirty_endio(struct bio *bio)
@@ -207,7 +207,7 @@ static void read_dirty_submit(struct clo
 
 	closure_bio_submit(&io->bio, cl);
 
-	continue_at(cl, write_dirty, system_wq);
+	continue_at(cl, write_dirty, io->dc->writeback_write_wq);
 }
 
 static void read_dirty(struct cached_dev *dc)
@@ -517,6 +517,11 @@ void bch_cached_dev_writeback_init(struc
 
 int bch_cached_dev_writeback_start(struct cached_dev *dc)
 {
+	dc->writeback_write_wq = alloc_workqueue("bcache_writeback_wq",
+						WQ_MEM_RECLAIM, 0);
+	if (!dc->writeback_write_wq)
+		return -ENOMEM;
+
 	dc->writeback_thread = kthread_create(bch_writeback_thread, dc,
 					      "bcache_writeback");
 	if (IS_ERR(dc->writeback_thread))
author maintainer
#103 lore raw

PATCH 100/109 bcache: fix bch_hprint crash and improve output

In reply to Greg Kroah-Hartman

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

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

From: Michael Lyle <[email protected]>

commit 9276717b9e297a62d1151a43d1cd286213f68eb7 upstream.

Most importantly, solve a crash where %llu was used to format signed numbers. This would cause a buffer overflow when reading sysfs writeback_rate_debug, as only 20 bytes were allocated for this and %llu writes 20 characters plus a null.

Always use the units mechanism rather than having different output paths for simplicity.

Also, correct problems with display output where 1.10 was a larger number than 1.09, by multiplying by 10 and then dividing by 1024 instead of dividing by 100. (Remainders of >= 1000 would print as .10).

Minor changes: Always display the decimal point instead of trying to omit it based on number of digits shown. Decide what units to use based on 1000 as a threshold, not 1024 (in other words, always print at most 3 digits before the decimal point).

---
 drivers/md/bcache/util.c |   46 +++++++++++++++++++++++++++++++++-------------
 1 file changed, 33 insertions(+), 13 deletions(-)
drivers/md/bcache/util.c +33 -13
@@ -74,24 +74,44 @@ STRTO_H(strtouint, unsigned int)
 STRTO_H(strtoll, long long)
 STRTO_H(strtoull, unsigned long long)
 
+/**
+ * bch_hprint() - formats @v to human readable string for sysfs.
+ *
+ * @v - signed 64 bit integer
+ * @buf - the (at least 8 byte) buffer to format the result into.
+ *
+ * Returns the number of bytes used by format.
+ */
 ssize_t bch_hprint(char *buf, int64_t v)
 {
 	static const char units[] = "?kMGTPEZY";
-	char dec[4] = "";
-	int u, t = 0;
+	int u = 0, t;
 
-	for (u = 0; v >= 1024 || v <= -1024; u++) {
-		t = v & ~(~0 << 10);
-		v >>= 10;
-	}
+	uint64_t q;
 
-	if (!u)
-		return sprintf(buf, "%llu", v);
-
-	if (v < 100 && v > -100)
-		snprintf(dec, sizeof(dec), ".%i", t / 100);
-
-	return sprintf(buf, "%lli%s%c", v, dec, units[u]);
+	if (v < 0)
+		q = -v;
+	else
+		q = v;
+
+	/* For as long as the number is more than 3 digits, but at least
+	 * once, shift right / divide by 1024.  Keep the remainder for
+	 * a digit after the decimal point.
+	 */
+	do {
+		u++;
+
+		t = q & ~(~0 << 10);
+		q >>= 10;
+	} while (q >= 1000);
+
+	if (v < 0)
+		/* '-', up to 3 digits, '.', 1 digit, 1 character, null;
+		 * yields 8 bytes.
+		 */
+		return sprintf(buf, "-%llu.%i%c", q, t * 10 / 1024, units[u]);
+	else
+		return sprintf(buf, "%llu.%i%c", q, t * 10 / 1024, units[u]);
 }
 
 ssize_t bch_snprint_string_list(char *buf, size_t size, const char * const list[],
author maintainer
#104 lore raw

PATCH 101/109 sched/cpuset/pm: Fix cpuset vs. suspend-resume bugs

In reply to Greg Kroah-Hartman

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

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

From: Peter Zijlstra <[email protected]>

commit 50e76632339d4655859523a39249dd95ee5e93e7 upstream.

Cpusets vs. suspend-resume is _completely_ broken. And it got noticed because it now resulted in non-cpuset usage breaking too.

On suspend cpuset_cpu_inactive() doesn't call into cpuset_update_active_cpus() because it doesn't want to move tasks about, there is no need, all tasks are frozen and won't run again until after we've resumed everything.

But this means that when we finally do call into cpuset_update_active_cpus() after resuming the last frozen cpu in cpuset_cpu_active(), the top_cpuset will not have any difference with the cpu_active_mask and this it will not in fact do _anything_.

So the cpuset configuration will not be restored. This was largely hidden because we would unconditionally create identity domains and mobile users would not in fact use cpusets much. And servers what do use cpusets tend to not suspend-resume much.

An addition problem is that we'd not in fact wait for the cpuset work to finish before resuming the tasks, allowing spurious migrations outside of the specified domains.

Fix the rebuild by introducing cpuset_force_rebuild() and fix the ordering with cpuset_wait_for_hotplug().

Cc Andy Lutomirski <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Mike Galbraith <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Rafael J. Wysocki <[email protected]>
Cc Tejun Heo <[email protected]>
Cc Thomas Gleixner <[email protected]>
Fixes deb7aa308ea2 ("cpuset: reorganize CPU / memory hotplug handling")
---
 include/linux/cpuset.h |    6 ++++++
 kernel/cgroup/cpuset.c |   16 +++++++++++++++-
 kernel/power/process.c |    5 ++++-
 kernel/sched/core.c    |    7 +++----
 4 files changed, 28 insertions(+), 6 deletions(-)
include/linux/cpuset.h +6 -0
@@ -57,7 +57,9 @@ static inline void cpuset_dec(void)
 
 extern int cpuset_init(void);
 extern void cpuset_init_smp(void);
+extern void cpuset_force_rebuild(void);
 extern void cpuset_update_active_cpus(void);
+extern void cpuset_wait_for_hotplug(void);
 extern void cpuset_cpus_allowed(struct task_struct *p, struct cpumask *mask);
 extern void cpuset_cpus_allowed_fallback(struct task_struct *p);
 extern nodemask_t cpuset_mems_allowed(struct task_struct *p);
@@ -170,11 +172,15 @@ static inline bool cpusets_enabled(void)
 static inline int cpuset_init(void) { return 0; }
 static inline void cpuset_init_smp(void) {}
 
+static inline void cpuset_force_rebuild(void) { }
+
 static inline void cpuset_update_active_cpus(void)
 {
 	partition_sched_domains(1, NULL, NULL);
 }
 
+static inline void cpuset_wait_for_hotplug(void) { }
+
 static inline void cpuset_cpus_allowed(struct task_struct *p,
 				       struct cpumask *mask)
 {
kernel/cgroup/cpuset.c +15 -1
@@ -2260,6 +2260,13 @@ retry:
 	mutex_unlock(&cpuset_mutex);
 }
 
+static bool force_rebuild;
+
+void cpuset_force_rebuild(void)
+{
+	force_rebuild = true;
+}
+
 /**
  * cpuset_hotplug_workfn - handle CPU/memory hotunplug for a cpuset
  *
@@ -2334,8 +2341,10 @@ static void cpuset_hotplug_workfn(struct
 	}
 
 	/* rebuild sched domains if cpus_allowed has changed */
-	if (cpus_updated)
+	if (cpus_updated || force_rebuild) {
+		force_rebuild = false;
 		rebuild_sched_domains();
+	}
 }
 
 void cpuset_update_active_cpus(void)
@@ -2354,6 +2363,11 @@ void cpuset_update_active_cpus(void)
 	schedule_work(&cpuset_hotplug_work);
 }
 
+void cpuset_wait_for_hotplug(void)
+{
+	flush_work(&cpuset_hotplug_work);
+}
+
 /*
  * Keep top_cpuset.mems_allowed tracking node_states[N_MEMORY].
  * Call this routine anytime after node_states[N_MEMORY] changes.
kernel/power/process.c +4 -1
@@ -20,8 +20,9 @@
 #include <linux/workqueue.h>
 #include <linux/kmod.h>
 #include <trace/events/power.h>
+#include <linux/cpuset.h>
 
-/* 
+/*
  * Timeout for stopping processes
  */
 unsigned int __read_mostly freeze_timeout_msecs = 20 * MSEC_PER_SEC;
@@ -202,6 +203,8 @@ void thaw_processes(void)
 	__usermodehelper_set_disable_depth(UMH_FREEZING);
 	thaw_workqueues();
 
+	cpuset_wait_for_hotplug();
+
 	read_lock(&tasklist_lock);
 	for_each_process_thread(g, p) {
 		/* No other threads should have PF_SUSPEND_TASK set */
kernel/sched/core.c +3 -4
@@ -5538,16 +5538,15 @@ static void cpuset_cpu_active(void)
 		 * operation in the resume sequence, just build a single sched
 		 * domain, ignoring cpusets.
 		 */
-		num_cpus_frozen--;
-		if (likely(num_cpus_frozen)) {
-			partition_sched_domains(1, NULL, NULL);
+		partition_sched_domains(1, NULL, NULL);
+		if (--num_cpus_frozen)
 			return;
-		}
 		/*
 		 * This is the last CPU online operation. So fall through and
 		 * restore the original sched domains by considering the
 		 * cpuset configurations.
 		 */
+		cpuset_force_rebuild();
 	}
 	cpuset_update_active_cpus();
 }
author maintainer
#105 lore raw

PATCH 102/109 iwlwifi: add workaround to disable wide channels in 5GHz

In reply to Greg Kroah-Hartman

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

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

From: Luca Coelho <[email protected]>

commit 01a9c948a09348950515bf2abb6113ed83e696d8 upstream.

The OTP in some SKUs have erroneously allowed 40MHz and 80MHz channels in the 5.2GHz band. The firmware has been modified to not allow this in those SKUs, so the driver needs to do the same otherwise the firmware will assert when we try to use it.

---
 drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c |   62 +++++++++++++++++----
 drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h |    3 -
 drivers/net/wireless/intel/iwlwifi/mvm/nvm.c       |    3 -
 3 files changed, 56 insertions(+), 12 deletions(-)
drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c +52 -10
@@ -79,6 +79,7 @@
 /* NVM offsets (in words) definitions */
 enum wkp_nvm_offsets {
 	/* NVM HW-Section offset (in words) definitions */
+	SUBSYSTEM_ID = 0x0A,
 	HW_ADDR = 0x15,
 
 	/* NVM SW-Section offset (in words) definitions */
@@ -254,13 +255,12 @@ static u32 iwl_get_channel_flags(u8 ch_n
 static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
 				struct iwl_nvm_data *data,
 				const __le16 * const nvm_ch_flags,
-				bool lar_supported)
+				bool lar_supported, bool no_wide_in_5ghz)
 {
 	int ch_idx;
 	int n_channels = 0;
 	struct ieee80211_channel *channel;
 	u16 ch_flags;
-	bool is_5ghz;
 	int num_of_ch, num_2ghz_channels;
 	const u8 *nvm_chan;
 
@@ -275,12 +275,20 @@ static int iwl_init_channel_map(struct d
 	}
 
 	for (ch_idx = 0; ch_idx < num_of_ch; ch_idx++) {
+		bool is_5ghz = (ch_idx >= num_2ghz_channels);
+
 		ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx);
 
-		if (ch_idx >= num_2ghz_channels &&
-		    !data->sku_cap_band_52GHz_enable)
+		if (is_5ghz && !data->sku_cap_band_52GHz_enable)
 			continue;
 
+		/* workaround to disable wide channels in 5GHz */
+		if (no_wide_in_5ghz && is_5ghz) {
+			ch_flags &= ~(NVM_CHANNEL_40MHZ |
+				     NVM_CHANNEL_80MHZ |
+				     NVM_CHANNEL_160MHZ);
+		}
+
 		if (ch_flags & NVM_CHANNEL_160MHZ)
 			data->vht160_supported = true;
 
@@ -303,8 +311,8 @@ static int iwl_init_channel_map(struct d
 		n_channels++;
 
 		channel->hw_value = nvm_chan[ch_idx];
-		channel->band = (ch_idx < num_2ghz_channels) ?
-				NL80211_BAND_2GHZ : NL80211_BAND_5GHZ;
+		channel->band = is_5ghz ?
+				NL80211_BAND_5GHZ : NL80211_BAND_2GHZ;
 		channel->center_freq =
 			ieee80211_channel_to_frequency(
 				channel->hw_value, channel->band);
@@ -316,7 +324,6 @@ static int iwl_init_channel_map(struct d
 		 * is not used in mvm, and is used for backwards compatibility
 		 */
 		channel->max_power = IWL_DEFAULT_MAX_TX_POWER;
-		is_5ghz = channel->band == NL80211_BAND_5GHZ;
 
 		/* don't put limitations in case we're using LAR */
 		if (!lar_supported)
@@ -432,14 +439,15 @@ static void iwl_init_vht_hw_capab(const
 
 void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
 		     struct iwl_nvm_data *data, const __le16 *nvm_ch_flags,
-		     u8 tx_chains, u8 rx_chains, bool lar_supported)
+		     u8 tx_chains, u8 rx_chains, bool lar_supported,
+		     bool no_wide_in_5ghz)
 {
 	int n_channels;
 	int n_used = 0;
 	struct ieee80211_supported_band *sband;
 
 	n_channels = iwl_init_channel_map(dev, cfg, data, nvm_ch_flags,
-					  lar_supported);
+					  lar_supported, no_wide_in_5ghz);
 	sband = &data->bands[NL80211_BAND_2GHZ];
 	sband->band = NL80211_BAND_2GHZ;
 	sband->bitrates = &iwl_cfg80211_rates[RATES_24_OFFS];
@@ -645,6 +653,39 @@ static int iwl_set_hw_address(struct iwl
 	return 0;
 }
 
+static bool
+iwl_nvm_no_wide_in_5ghz(struct device *dev, const struct iwl_cfg *cfg,
+			const __le16 *nvm_hw)
+{
+	/*
+	 * Workaround a bug in Indonesia SKUs where the regulatory in
+	 * some 7000-family OTPs erroneously allow wide channels in
+	 * 5GHz.  To check for Indonesia, we take the SKU value from
+	 * bits 1-4 in the subsystem ID and check if it is either 5 or
+	 * 9.  In those cases, we need to force-disable wide channels
+	 * in 5GHz otherwise the FW will throw a sysassert when we try
+	 * to use them.
+	 */
+	if (cfg->device_family == IWL_DEVICE_FAMILY_7000) {
+		/*
+		 * Unlike the other sections in the NVM, the hw
+		 * section uses big-endian.
+		 */
+		u16 subsystem_id = be16_to_cpup((const __be16 *)nvm_hw
+						+ SUBSYSTEM_ID);
+		u8 sku = (subsystem_id & 0x1e) >> 1;
+
+		if (sku == 5 || sku == 9) {
+			IWL_DEBUG_EEPROM(dev,
+					 "disabling wide channels in 5GHz (0x%0x %d)\n",
+					 subsystem_id, sku);
+			return true;
+		}
+	}
+
+	return false;
+}
+
 struct iwl_nvm_data *
 iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
 		   const __le16 *nvm_hw, const __le16 *nvm_sw,
@@ -655,6 +696,7 @@ iwl_parse_nvm_data(struct iwl_trans *tra
 	struct device *dev = trans->dev;
 	struct iwl_nvm_data *data;
 	bool lar_enabled;
+	bool no_wide_in_5ghz = iwl_nvm_no_wide_in_5ghz(dev, cfg, nvm_hw);
 	u32 sku, radio_cfg;
 	u16 lar_config;
 	const __le16 *ch_section;
@@ -725,7 +767,7 @@ iwl_parse_nvm_data(struct iwl_trans *tra
 	}
 
 	iwl_init_sbands(dev, cfg, data, ch_section, tx_chains, rx_chains,
-			lar_fw_supported && lar_enabled);
+			lar_fw_supported && lar_enabled, no_wide_in_5ghz);
 	data->calib_version = 255;
 
 	return data;
drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h +2 -1
@@ -93,7 +93,8 @@ void iwl_set_hw_address_from_csr(struct
  */
 void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
 		     struct iwl_nvm_data *data, const __le16 *nvm_ch_flags,
-		     u8 tx_chains, u8 rx_chains, bool lar_supported);
+		     u8 tx_chains, u8 rx_chains, bool lar_supported,
+		     bool no_wide_in_5ghz);
 
 /**
  * iwl_parse_mcc_info - parse MCC (mobile country code) info coming from FW
drivers/net/wireless/intel/iwlwifi/mvm/nvm.c +2 -1
@@ -628,7 +628,8 @@ int iwl_mvm_nvm_get_from_fw(struct iwl_m
 			rsp->regulatory.channel_profile,
 			mvm->nvm_data->valid_tx_ant & mvm->fw->valid_tx_ant,
 			mvm->nvm_data->valid_rx_ant & mvm->fw->valid_rx_ant,
-			rsp->regulatory.lar_enabled && lar_fw_supported);
+			rsp->regulatory.lar_enabled && lar_fw_supported,
+			false);
 
 	iwl_free_resp(&hcmd);
 	return 0;
author maintainer
#73 lore raw

PATCH 69/109 scsi: qla2xxx: Fix target multiqueue configuration

In reply to Greg Kroah-Hartman

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

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

From: Michael Hernandez <[email protected]>

commit b7edfa235effb4b4a9816c2345620b11609c123e upstream.

Following error will be logged in to message file while trying to configure target with multiqueue.

"Cmd 0x1f aborted with timeout since ISP Abort is pending" "qla25xx_init_queues Rsp que: 1 init failed."

Fixes 82de802ad46e ("scsi: qla2xxx: Preparation for Target MQ.")
---
 drivers/scsi/qla2xxx/qla_isr.c    |    2 +-
 drivers/scsi/qla2xxx/qla_mbx.c    |    1 +
 drivers/scsi/qla2xxx/qla_target.c |    2 +-
 3 files changed, 3 insertions(+), 2 deletions(-)
drivers/scsi/qla2xxx/qla_isr.c +1 -1
@@ -3429,7 +3429,7 @@ msix_register_fail:
 	}
 
 	/* Enable MSI-X vector for response queue update for queue 0 */
-	if (IS_QLA25XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
+	if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
 		if (ha->msixbase && ha->mqiobase &&
 		    (ha->max_rsp_queues > 1 || ha->max_req_queues > 1 ||
 		     ql2xmqsupport))
drivers/scsi/qla2xxx/qla_mbx.c +1 -0
@@ -54,6 +54,7 @@ static struct rom_cmd {
 	{ MBC_GET_MEM_OFFLOAD_CNTRL_STAT },
 	{ MBC_GET_RETRY_COUNT },
 	{ MBC_TRACE_CONTROL },
+	{ MBC_INITIALIZE_MULTIQ },
 };
 
 static int is_rom_cmd(uint16_t cmd)
drivers/scsi/qla2xxx/qla_target.c +1 -1
@@ -6796,7 +6796,7 @@ qlt_probe_one_stage1(struct scsi_qla_hos
 	if (!QLA_TGT_MODE_ENABLED())
 		return;
 
-	if  (ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
+	if  (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
 		ISP_ATIO_Q_IN(base_vha) = &ha->mqiobase->isp25mq.atio_q_in;
 		ISP_ATIO_Q_OUT(base_vha) = &ha->mqiobase->isp25mq.atio_q_out;
 	} else {
author maintainer
#108 lore raw

PATCH 105/109 mac80211: flush hw_roc_start work before cancelling the ROC

In reply to Greg Kroah-Hartman

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

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

From: Avraham Stern <[email protected]>

commit 6e46d8ce894374fc135c96a8d1057c6af1fef237 upstream.

When HW ROC is supported it is possible that after the HW notified that the ROC has started, the ROC was cancelled and another ROC was added while the hw_roc_start worker is waiting on the mutex (since cancelling the ROC and adding another one also holds the same mutex). As a result, the hw_roc_start worker will continue to run after the new ROC is added but before it is actually started by the HW. This may result in notifying userspace that the ROC has started before it actually does, or in case of management tx ROC, in an attempt to tx while not on the right channel.

In addition, when the driver will notify mac80211 that the second ROC has started, mac80211 will warn that this ROC has already been notified.

Fix this by flushing the hw_roc_start work before cancelling an ROC.

---
 net/mac80211/offchannel.c |    2 ++
 1 file changed, 2 insertions(+)
net/mac80211/offchannel.c +2 -0
@@ -707,6 +707,8 @@ static int ieee80211_cancel_roc(struct i
 	if (!cookie)
 		return -ENOENT;
 
+	flush_work(&local->hw_roc_start);
+
 	mutex_lock(&local->mtx);
 	list_for_each_entry_safe(roc, tmp, &local->roc_list, list) {
 		if (!mgmt_tx && roc->cookie != cookie)
author maintainer
#74 lore raw

PATCH 70/109 scsi: qla2xxx: Use BIT_6 to acquire FAWWPN from switch

In reply to Greg Kroah-Hartman

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

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

From: Sawan Chandak <[email protected]>

commit fcc5b5cd726c0779cd689362aea82cc9d5a61346 upstream.

If FA-WWPN feature disabled on the switch side and enabled for the adapter, then driver would update the port name with switch port name.

This patch fixes issue by checking correct BIT flag to validate.

Fixes 41dc529a4602 ("qla2xxx: Improve RSCN handling in driver")
---
 drivers/scsi/qla2xxx/qla_mbx.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/qla2xxx/qla_mbx.c +1 -1
@@ -3690,7 +3690,7 @@ qla24xx_report_id_acquisition(scsi_qla_h
 				if (qla_ini_mode_enabled(vha) &&
 				    ha->flags.fawwpn_enabled &&
 				    (rptid_entry->u.f1.flags &
-				     VP_FLAGS_NAME_VALID)) {
+				     BIT_6)) {
 					memcpy(vha->port_name,
 					    rptid_entry->u.f1.port_name,
 					    WWN_SIZE);
author maintainer
#75 lore raw

PATCH 71/109 scsi: qla2xxx: Use fabric name for Get Port Speed command

In reply to Greg Kroah-Hartman

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

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

From: Quinn Tran <[email protected]>

commit b2e8ae3f0e342a3308b4573790bd42528e51885a upstream.

The Get Port Speed switch command needs the fabric port name of the remote device. Current code uses the registered WWPN.

Fixes 726b85487067d ("qla2xxx: Add framework for async fabric discovery")
Cc <[email protected]> # 4.10+
---
 drivers/scsi/qla2xxx/qla_gs.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/qla2xxx/qla_gs.c +1 -1
@@ -3080,7 +3080,7 @@ int qla24xx_async_gpsc(scsi_qla_host_t *
 		GPSC_RSP_SIZE);
 
 	/* GPSC req */
-	memcpy(ct_req->req.gpsc.port_name, fcport->port_name,
+	memcpy(ct_req->req.gpsc.port_name, fcport->fabric_port_name,
 		WWN_SIZE);
 
 	sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns;
author maintainer
#76 lore raw

PATCH 72/109 scsi: qla2xxx: Fix an integer overflow in sysfs code

In reply to Greg Kroah-Hartman

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

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

From: Dan Carpenter <[email protected]>

commit e6f77540c067b48dee10f1e33678415bfcc89017 upstream.

The value of "size" comes from the user. When we add "start + size" it could lead to an integer overflow bug.

It means we vmalloc() a lot more memory than we had intended. I believe that on 64 bit systems vmalloc() can succeed even if we ask it to allocate huge 4GB buffers. So we would get memory corruption and likely a crash when we call ha->isp_ops->write_optrom() and ->read_optrom().

Only root can trigger this bug.

Fixes b7cc176c9eb3 ("[SCSI] qla2xxx: Allow region-based flash-part accesses.")
---
 drivers/scsi/qla2xxx/qla_attr.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/scsi/qla2xxx/qla_attr.c +4 -4
@@ -318,6 +318,8 @@ qla2x00_sysfs_write_optrom_ctl(struct fi
 		return -EINVAL;
 	if (start > ha->optrom_size)
 		return -EINVAL;
+	if (size > ha->optrom_size - start)
+		size = ha->optrom_size - start;
 
 	mutex_lock(&ha->optrom_mutex);
 	switch (val) {
@@ -343,8 +345,7 @@ qla2x00_sysfs_write_optrom_ctl(struct fi
 		}
 
 		ha->optrom_region_start = start;
-		ha->optrom_region_size = start + size > ha->optrom_size ?
-		    ha->optrom_size - start : size;
+		ha->optrom_region_size = start + size;
 
 		ha->optrom_state = QLA_SREADING;
 		ha->optrom_buffer = vmalloc(ha->optrom_region_size);
@@ -417,8 +418,7 @@ qla2x00_sysfs_write_optrom_ctl(struct fi
 		}
 
 		ha->optrom_region_start = start;
-		ha->optrom_region_size = start + size > ha->optrom_size ?
-		    ha->optrom_size - start : size;
+		ha->optrom_region_size = start + size;
 
 		ha->optrom_state = QLA_SWRITING;
 		ha->optrom_buffer = vmalloc(ha->optrom_region_size);
author maintainer
#77 lore raw

PATCH 73/109 mailbox: bcm-flexrm-mailbox: Fix mask used in CMPL_START_ADDR_VALUE()

In reply to Greg Kroah-Hartman

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

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

From: Anup Patel <[email protected]>

commit 6d2061b981af165d3e45462e0804b5a1f2f4c7bc upstream.

The mask used in CMPL_START_ADDR_VALUE() should be 27bits instead of 26bits. This incorrect mask was causing completion writes to 40bits physical address fail.

This patch fixes mask used in CMPL_START_ADDR_VALUE() macro.

Fixes dbc049eee730 ("mailbox: Add driver for Broadcom FlexRM

ring manager")

---
 drivers/mailbox/bcm-flexrm-mailbox.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mailbox/bcm-flexrm-mailbox.c +1 -1
@@ -95,7 +95,7 @@
 
 /* Register RING_CMPL_START_ADDR fields */
 #define CMPL_START_ADDR_VALUE(pa)			\
-	((u32)((((u64)(pa)) >> RING_CMPL_ALIGN_ORDER) & 0x03ffffff))
+	((u32)((((u64)(pa)) >> RING_CMPL_ALIGN_ORDER) & 0x07ffffff))
 
 /* Register RING_CONTROL fields */
 #define CONTROL_MASK_DISABLE_CONTROL			12
author maintainer
#78 lore raw

PATCH 74/109 ftrace: Fix debug preempt config name in stack_tracer_{en,dis}able

In reply to Greg Kroah-Hartman

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

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

From: Zev Weiss <[email protected]>

commit 60361e12d01676e23a8de89a5ef4a349ae97f616 upstream.

stack_tracer_disable()/stack_tracer_enable() had been using the wrong name for the config symbol to enable their preempt-debugging checks -- fix with a word swap.

Fixes 8aaf1ee70e ("tracing: Rename trace_active to disable_stack_tracer and inline its modification")
include/linux/ftrace.h +2 -2
index 6383115e9d2c..2e028854bac7 100644
@@ -307,7 +307,7 @@ DECLARE_PER_CPU(int, disable_stack_tracer);
 static inline void stack_tracer_disable(void)
 {
 	/* Preemption or interupts must be disabled */
-	if (IS_ENABLED(CONFIG_PREEMPT_DEBUG))
+	if (IS_ENABLED(CONFIG_DEBUG_PREEMPT))
 		WARN_ON_ONCE(!preempt_count() || !irqs_disabled());
 	this_cpu_inc(disable_stack_tracer);
 }
@@ -320,7 +320,7 @@ static inline void stack_tracer_disable(void)
  */
 static inline void stack_tracer_enable(void)
 {
-	if (IS_ENABLED(CONFIG_PREEMPT_DEBUG))
+	if (IS_ENABLED(CONFIG_DEBUG_PREEMPT))
 		WARN_ON_ONCE(!preempt_count() || !irqs_disabled());
 	this_cpu_dec(disable_stack_tracer);
 }
author maintainer
#69 lore raw

PATCH 65/109 scsi: sg: factor out sg_fill_request_table()

In reply to Greg Kroah-Hartman

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

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

From: Hannes Reinecke <[email protected]>

commit 4759df905a474d245752c9dc94288e779b8734dd upstream.

Factor out sg_fill_request_table() for better readability.

[mkp: typos, applied by hand]

---
 drivers/scsi/sg.c |   61 ++++++++++++++++++++++++++++++------------------------
 1 file changed, 35 insertions(+), 26 deletions(-)
drivers/scsi/sg.c +35 -26
@@ -828,6 +828,40 @@ static int max_sectors_bytes(struct requ
 	return max_sectors << 9;
 }
 
+static void
+sg_fill_request_table(Sg_fd *sfp, sg_req_info_t *rinfo)
+{
+	Sg_request *srp;
+	int val;
+	unsigned int ms;
+
+	val = 0;
+	list_for_each_entry(srp, &sfp->rq_list, entry) {
+		if (val > SG_MAX_QUEUE)
+			break;
+		memset(&rinfo[val], 0, SZ_SG_REQ_INFO);
+		rinfo[val].req_state = srp->done + 1;
+		rinfo[val].problem =
+			srp->header.masked_status &
+			srp->header.host_status &
+			srp->header.driver_status;
+		if (srp->done)
+			rinfo[val].duration =
+				srp->header.duration;
+		else {
+			ms = jiffies_to_msecs(jiffies);
+			rinfo[val].duration =
+				(ms > srp->header.duration) ?
+				(ms - srp->header.duration) : 0;
+		}
+		rinfo[val].orphan = srp->orphan;
+		rinfo[val].sg_io_owned = srp->sg_io_owned;
+		rinfo[val].pack_id = srp->header.pack_id;
+		rinfo[val].usr_ptr = srp->header.usr_ptr;
+		val++;
+	}
+}
+
 static long
 sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
 {
@@ -1012,38 +1046,13 @@ sg_ioctl(struct file *filp, unsigned int
 			return -EFAULT;
 		else {
 			sg_req_info_t *rinfo;
-			unsigned int ms;
 
 			rinfo = kmalloc(SZ_SG_REQ_INFO * SG_MAX_QUEUE,
 								GFP_KERNEL);
 			if (!rinfo)
 				return -ENOMEM;
 			read_lock_irqsave(&sfp->rq_list_lock, iflags);
-			val = 0;
-			list_for_each_entry(srp, &sfp->rq_list, entry) {
-				if (val >= SG_MAX_QUEUE)
-					break;
-				memset(&rinfo[val], 0, SZ_SG_REQ_INFO);
-				rinfo[val].req_state = srp->done + 1;
-				rinfo[val].problem =
-					srp->header.masked_status &
-					srp->header.host_status &
-					srp->header.driver_status;
-				if (srp->done)
-					rinfo[val].duration =
-						srp->header.duration;
-				else {
-					ms = jiffies_to_msecs(jiffies);
-					rinfo[val].duration =
-						(ms > srp->header.duration) ?
-						(ms - srp->header.duration) : 0;
-				}
-				rinfo[val].orphan = srp->orphan;
-				rinfo[val].sg_io_owned = srp->sg_io_owned;
-				rinfo[val].pack_id = srp->header.pack_id;
-				rinfo[val].usr_ptr = srp->header.usr_ptr;
-				val++;
-			}
+			sg_fill_request_table(sfp, rinfo);
 			read_unlock_irqrestore(&sfp->rq_list_lock, iflags);
 			result = __copy_to_user(p, rinfo,
 						SZ_SG_REQ_INFO * SG_MAX_QUEUE);
author maintainer
#110 lore raw

PATCH 107/109 genirq: Make sparse_irq_lock protect what it should protect

In reply to Greg Kroah-Hartman

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

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

From: Thomas Gleixner <[email protected]>

commit 12ac1d0f6c3e95732d144ffa65c8b20fbd9aa462 upstream.

for_each_active_irq() iterates the sparse irq allocation bitmap. The caller must hold sparse_irq_lock. Several code pathes expect that an active bit in the sparse bitmap also has a valid interrupt descriptor.

Unfortunately that's not true. The (de)allocation is a two step process, which holds the sparse_irq_lock only across the queue/remove from the radix tree and the set/clear in the allocation bitmap.

If a iteration locks sparse_irq_lock between the two steps, then it might see an active bit but the corresponding irq descriptor is NULL. If that is dereferenced unconditionally, then the kernel oopses. Of course, all iterator sites could be audited and fixed, but....

There is no reason why the sparse_irq_lock needs to be dropped between the two steps, in fact the code becomes simpler when the mutex is held across both and the semantics become more straight forward, so future problems of missing NULL pointer checks in the iteration are avoided and all existing sites are fixed in one go.

Expand the lock held sections so both operations are covered and the bitmap and the radixtree are in sync.

Fixes a05a900a51c7 ("genirq: Make sparse_lock a mutex")
Reported-and-tested-by Huang Ying <[email protected]>
---
 kernel/irq/irqdesc.c |   24 +++++++-----------------
 1 file changed, 7 insertions(+), 17 deletions(-)
kernel/irq/irqdesc.c +7 -17
@@ -421,10 +421,8 @@ static void free_desc(unsigned int irq)
 	 * The sysfs entry must be serialized against a concurrent
 	 * irq_sysfs_init() as well.
 	 */
-	mutex_lock(&sparse_irq_lock);
 	kobject_del(&desc->kobj);
 	delete_irq_desc(irq);
-	mutex_unlock(&sparse_irq_lock);
 
 	/*
 	 * We free the descriptor, masks and stat fields via RCU. That
@@ -462,20 +460,15 @@ static int alloc_descs(unsigned int star
 		desc = alloc_desc(start + i, node, flags, mask, owner);
 		if (!desc)
 			goto err;
-		mutex_lock(&sparse_irq_lock);
 		irq_insert_desc(start + i, desc);
 		irq_sysfs_add(start + i, desc);
-		mutex_unlock(&sparse_irq_lock);
 	}
+	bitmap_set(allocated_irqs, start, cnt);
 	return start;
 
 err:
 	for (i--; i >= 0; i--)
 		free_desc(start + i);
-
-	mutex_lock(&sparse_irq_lock);
-	bitmap_clear(allocated_irqs, start, cnt);
-	mutex_unlock(&sparse_irq_lock);
 	return -ENOMEM;
 }
 
@@ -575,6 +568,7 @@ static inline int alloc_descs(unsigned i
 
 		desc->owner = owner;
 	}
+	bitmap_set(allocated_irqs, start, cnt);
 	return start;
 }
 
@@ -670,10 +664,10 @@ void irq_free_descs(unsigned int from, u
 	if (from >= nr_irqs || (from + cnt) > nr_irqs)
 		return;
 
+	mutex_lock(&sparse_irq_lock);
 	for (i = 0; i < cnt; i++)
 		free_desc(from + i);
 
-	mutex_lock(&sparse_irq_lock);
 	bitmap_clear(allocated_irqs, from, cnt);
 	mutex_unlock(&sparse_irq_lock);
 }
@@ -720,19 +714,15 @@ __irq_alloc_descs(int irq, unsigned int
 					   from, cnt, 0);
 	ret = -EEXIST;
 	if (irq >=0 && start != irq)
-		goto err;
+		goto unlock;
 
 	if (start + cnt > nr_irqs) {
 		ret = irq_expand_nr_irqs(start + cnt);
 		if (ret)
-			goto err;
+			goto unlock;
 	}
-
-	bitmap_set(allocated_irqs, start, cnt);
-	mutex_unlock(&sparse_irq_lock);
-	return alloc_descs(start, cnt, node, affinity, owner);
-
-err:
+	ret = alloc_descs(start, cnt, node, affinity, owner);
+unlock:
 	mutex_unlock(&sparse_irq_lock);
 	return ret;
 }
author maintainer
#111 lore raw

PATCH 108/109 genirq/msi: Fix populating multiple interrupts

In reply to Greg Kroah-Hartman

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

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

From: John Keeping <[email protected]>

commit 596a7a1d0989c621c3ae49be73a1d1f9de22eb5a upstream.

On allocating the interrupts routed via a wire-to-MSI bridge, the allocator iterates over the MSI descriptors to build the hierarchy, but fails to use the descriptor interrupt number, and instead uses the base number, generating the wrong IRQ domain mappings.

The fix is to use the MSI descriptor interrupt number when setting up the interrupt instead of the base interrupt for the allocation range.

The only saving grace is that although the MSI descriptors are allocated in bulk, the wired interrupts are only allocated one by one (so desc->irq == virq) and the bug went unnoticed so far.

---
 kernel/irq/msi.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
kernel/irq/msi.c +3 -2
@@ -315,11 +315,12 @@ int msi_domain_populate_irqs(struct irq_
 
 		ops->set_desc(arg, desc);
 		/* Assumes the domain mutex is held! */
-		ret = irq_domain_alloc_irqs_hierarchy(domain, virq, 1, arg);
+		ret = irq_domain_alloc_irqs_hierarchy(domain, desc->irq, 1,
+						      arg);
 		if (ret)
 			break;
 
-		irq_set_msi_desc_off(virq, 0, desc);
+		irq_set_msi_desc_off(desc->irq, 0, desc);
 	}
 
 	if (ret) {
author maintainer
#112 lore raw

PATCH 109/109 genirq: Fix cpumask check in __irq_startup_managed()

In reply to Greg Kroah-Hartman

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

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

From: Thomas Gleixner <[email protected]>

commit 9cb067ef8a10bb13112e4d1c0ea996ec96527422 upstream.

The result of cpumask_any_and() is invalid when result greater or equal nr_cpu_ids. The current check is checking for greater only. Fix it.

Fixes 761ea388e8c4 ("genirq: Handle managed irqs gracefully in irq_startup()")
Cc Boris Ostrovsky <[email protected]>
Cc Juergen Gross <[email protected]>
Cc Tony Luck <[email protected]>
Cc Chen Yu <[email protected]>
Cc Marc Zyngier <[email protected]>
Cc Alok Kataria <[email protected]>
Cc Joerg Roedel <[email protected]>
Cc "Rafael J. Wysocki" <[email protected]>
Cc Steven Rostedt <[email protected]>
Cc Christoph Hellwig <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Borislav Petkov <[email protected]>
Cc Paolo Bonzini <[email protected]>
Cc Rui Zhang <[email protected]>
Cc "K. Y. Srinivasan" <[email protected]>
Cc Arjan van de Ven <[email protected]>
Cc Dan Williams <[email protected]>
Cc Len Brown <[email protected]>
---
 kernel/irq/chip.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/irq/chip.c +1 -1
@@ -202,7 +202,7 @@ __irq_startup_managed(struct irq_desc *d
 
 	irqd_clr_managed_shutdown(d);
 
-	if (cpumask_any_and(aff, cpu_online_mask) > nr_cpu_ids) {
+	if (cpumask_any_and(aff, cpu_online_mask) >= nr_cpu_ids) {
 		/*
 		 * Catch code which fiddles with enable_irq() on a managed
 		 * and potentially shutdown IRQ. Chained interrupt
#113 lore raw
In reply to Greg Kroah-Hartman
Quoted 8 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 4.13.4 release. There are 109 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 Tue Sep 26 20:33:30 UTC 2017. Anything received after that time might be too late.

Build results:

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

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

Guenter

author maintainer
#114 lore raw
Quoted 10 lines · Guenter Roeck
Quoted 8 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 4.13.4 release. There are 109 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 Tue Sep 26 20:33:30 UTC 2017. Anything received after that time might be too late.

Quoted 6 lines

Build results:

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

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

Thanks for testing all of these and letting me know.

greg k-h

#115 lore raw
In reply to Greg Kroah-Hartman
Quoted 9 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 4.13.4 release. There are 109 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 Tue Sep 26 20:33:30 UTC 2017. Anything received after that time might be too late.

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

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

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

thanks,

greg k-h

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

thanks,
-- Shuah

#2 lore raw

Re: [PATCH 4.13 001/109] orangefs: Dont clear SGID when inheriting ACLs

In reply to Greg Kroah-Hartman

That's a good patch Greg... I have another ACL patch that got pulled in 4.14 and there's some ACL patches in the server part of Orangefs too... Reviewing Jan's patch is what made me realize that Orangefs ACLs were busted. Anywho... we're moving offices so it will be a few days before I can try to get the other patch submitted to stable...

-Mike

Quoted 117 lines · Greg Kroah-Hartman

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

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

From: Jan Kara <[email protected]>

commit b5accbb0dfae36d8d36cd882096943c98d5ede15 upstream.

When new directory 'DIR1' is created in a directory 'DIR0' with SGID bit set, DIR1 is expected to have SGID bit set (and owning group equal to the owning group of 'DIR0'). However when 'DIR0' also has some default ACLs that 'DIR1' inherits, setting these ACLs will result in SGID bit on 'DIR1' to get cleared if user is not member of the owning group.

Fix the problem by creating __orangefs_set_acl() function that does not call posix_acl_update_mode() and use it when inheriting ACLs. That prevents SGID bit clearing and the mode has been properly set by posix_acl_create() anyway.

Fixes 073931017b49d9458aa351605b43a7e34598caef
CC Mike Marshall <[email protected]>
---
 fs/orangefs/acl.c |   48 ++++++++++++++++++++++++++++--------------------
 1 file changed, 28 insertions(+), 20 deletions(-)
fs/orangefs/acl.c +28 -20
@@ -61,9 +61,9 @@ struct posix_acl *orangefs_get_acl(struc
        return acl;
 }
 
-int orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
+static int __orangefs_set_acl(struct inode *inode, struct posix_acl *acl,
+                             int type)
 {
-       struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
        int error = 0;
        void *value = NULL;
        size_t size = 0;
@@ -72,22 +72,6 @@ int orangefs_set_acl(struct inode *inode
        switch (type) {
        case ACL_TYPE_ACCESS:
                name = XATTR_NAME_POSIX_ACL_ACCESS;
-               if (acl) {
-                       umode_t mode;
-
-                       error = posix_acl_update_mode(inode, &mode, &acl);
-                       if (error) {
-                               gossip_err("%s: posix_acl_update_mode err: %d\n",
-                                          __func__,
-                                          error);
-                               return error;
-                       }
-
-                       if (inode->i_mode != mode)
-                               SetModeFlag(orangefs_inode);
-                       inode->i_mode = mode;
-                       mark_inode_dirty_sync(inode);
-               }
                break;
        case ACL_TYPE_DEFAULT:
                name = XATTR_NAME_POSIX_ACL_DEFAULT;
@@ -132,6 +116,29 @@ out:
        return error;
 }
 
+int orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
+{
+       int error;
+
+       if (type == ACL_TYPE_ACCESS && acl) {
+               umode_t mode;
+
+               error = posix_acl_update_mode(inode, &mode, &acl);
+               if (error) {
+                       gossip_err("%s: posix_acl_update_mode err: %d\n",
+                                  __func__,
+                                  error);
+                       return error;
+               }
+
+               if (inode->i_mode != mode)
+                       SetModeFlag(ORANGEFS_I(inode));
+               inode->i_mode = mode;
+               mark_inode_dirty_sync(inode);
+       }
+       return __orangefs_set_acl(inode, acl, type);
+}
+
 int orangefs_init_acl(struct inode *inode, struct inode *dir)
 {
        struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
@@ -146,13 +153,14 @@ int orangefs_init_acl(struct inode *inod
                return error;
 
        if (default_acl) {
-               error = orangefs_set_acl(inode, default_acl, ACL_TYPE_DEFAULT);
+               error = __orangefs_set_acl(inode, default_acl,
+                                          ACL_TYPE_DEFAULT);
                posix_acl_release(default_acl);
        }
 
        if (acl) {
                if (!error)
-                       error = orangefs_set_acl(inode, acl, ACL_TYPE_ACCESS);
+                       error = __orangefs_set_acl(inode, acl, ACL_TYPE_ACCESS);
                posix_acl_release(acl);
        }
 
author maintainer
#116 lore raw
In reply to Shuah Khan
Quoted 15 lines · Shuah Khan
Quoted 14 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 4.13.4 release. There are 109 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 Tue Sep 26 20:33:30 UTC 2017. Anything received after that time might be too late.

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

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

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

Quoted 6 lines
Quoted 4 lines

thanks,

greg k-h

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

Thanks for testing all of these and letting me know.

greg k-h

#17 lore raw

Re: [PATCH 4.13 015/109] pinctrl/amd: save pin registers over suspend/resume

In reply to Greg Kroah-Hartman
Quoted 36 lines · Greg Kroah-Hartman

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

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

From: Daniel Drake <[email protected]>

commit 79d2c8bede2c93f9432d7da0bc2f76a195c90fc0 upstream.

The touchpad in the Asus laptop models X505BA/BP and X542BA/BP is unresponsive after suspend/resume. The following error appears during resume:

i2c_hid i2c-ELAN1300:00: failed to reset device.

The problem here is that i2c_hid does not notice the interrupt being generated at this point, because the GPIO is no longer configured for interrupts.

Fix this by saving pinctrl-amd pin registers during suspend and restoring them at resume time.

Based on code from pinctrl-intel.

drivers/pinctrl/pinctrl-amd.c +3 -0
@@ -725,6 +726,69 @@ static const struct pinconf_ops amd_pinc
 	.pin_config_group_set = amd_pinconf_group_set,
 };
 
+#ifdef CONFIG_PM_SLEEP
+static bool amd_gpio_should_save(struct amd_gpio *gpio_dev, unsigned int pin)
+{

drivers/pinctrl/pinctrl-amd.c static const struct pinconf_ops amd_pinc · line 741

Quoted 10 lines
drivers/pinctrl/pinctrl-amd.c +10 -0
+	const struct pin_desc *pd = pin_desc_get(gpio_dev->pctrl, pin);
+
+	if (!pd)
+		return false;
+
+	/*
+	 * Only restore the pin if it is actually in use by the kernel (or
+	 * by userspace).
+	 */
+	if (pd->mux_owner || pd->gpio_owner ||

This code causes a compilation error in the current Linus' tree (4.14-rc2+). I guess that the same problem will be also in older trees.

IMHO, we need to select CONFIG_PINMUX for when CONFIG_PINCTRL_AMD is selected. The following patch helped here:

Quoted 1 line

From f83130d3b5c147b4d400922847ca2751d8020ab5 Mon Sep 17 00:00:00 2001

From: Petr Mladek <[email protected]>
Date: Tue, 26 Sep 2017 15:51:28 +0200
Subject: [PATCH] pinctrl/amd: Fix build dependency on pinmux code
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The commit 79d2c8bede2c93f943 ("pinctrl/amd: save pin registers over suspend/resume") caused the following compilation errors:

drivers/pinctrl/pinctrl-amd.c: In function ‘amd_gpio_should_save’:
drivers/pinctrl/pinctrl-amd.c:741:8: error: ‘const struct pin_desc’ has no member named ‘mux_owner’
if (pd->mux_owner || pd->gpio_owner ||

        ^

drivers/pinctrl/pinctrl-amd.c:741:25: error: ‘const struct pin_desc’ has no member named ‘gpio_owner’
if (pd->mux_owner || pd->gpio_owner ||

We need to enable CONFIG_PINMUX for this driver as well.

Fixes 79d2c8bede2c93f943 ("pinctrl/amd: save pin registers over suspend/resume")
---
 drivers/pinctrl/Kconfig | 1 +
 1 file changed, 1 insertion(+)
drivers/pinctrl/Kconfig +1 -0
index 1778cf4f81c7..82cd8b08d71f 100644
@@ -100,6 +100,7 @@ config PINCTRL_AMD
 	tristate "AMD GPIO pin control"
 	depends on GPIOLIB
 	select GPIOLIB_IRQCHIP
+	select PINMUX
 	select PINCONF
 	select GENERIC_PINCONF
 	help
Signature · 1 line
1.8.5.6
author maintainer
#18 lore raw

Re: [PATCH 4.13 015/109] pinctrl/amd: save pin registers over suspend/resume

Quoted 95 lines · Petr Mladek
Quoted 36 lines · Greg Kroah-Hartman

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

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

From: Daniel Drake <[email protected]>

commit 79d2c8bede2c93f9432d7da0bc2f76a195c90fc0 upstream.

The touchpad in the Asus laptop models X505BA/BP and X542BA/BP is unresponsive after suspend/resume. The following error appears during resume:

i2c_hid i2c-ELAN1300:00: failed to reset device.

The problem here is that i2c_hid does not notice the interrupt being generated at this point, because the GPIO is no longer configured for interrupts.

Fix this by saving pinctrl-amd pin registers during suspend and restoring them at resume time.

Based on code from pinctrl-intel.

drivers/pinctrl/pinctrl-amd.c +3 -0
@@ -725,6 +726,69 @@ static const struct pinconf_ops amd_pinc
 	.pin_config_group_set = amd_pinconf_group_set,
 };
 
+#ifdef CONFIG_PM_SLEEP
+static bool amd_gpio_should_save(struct amd_gpio *gpio_dev, unsigned int pin)
+{

drivers/pinctrl/pinctrl-amd.c static const struct pinconf_ops amd_pinc · line 741

Quoted 10 lines
drivers/pinctrl/pinctrl-amd.c +10 -0
+	const struct pin_desc *pd = pin_desc_get(gpio_dev->pctrl, pin);
+
+	if (!pd)
+		return false;
+
+	/*
+	 * Only restore the pin if it is actually in use by the kernel (or
+	 * by userspace).
+	 */
+	if (pd->mux_owner || pd->gpio_owner ||

This code causes a compilation error in the current Linus' tree (4.14-rc2+). I guess that the same problem will be also in older trees.

IMHO, we need to select CONFIG_PINMUX for when CONFIG_PINCTRL_AMD is selected. The following patch helped here:

Quoted 1 line

From f83130d3b5c147b4d400922847ca2751d8020ab5 Mon Sep 17 00:00:00 2001

From: Petr Mladek <[email protected]>
Date: Tue, 26 Sep 2017 15:51:28 +0200
Subject: [PATCH] pinctrl/amd: Fix build dependency on pinmux code
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The commit 79d2c8bede2c93f943 ("pinctrl/amd: save pin registers over suspend/resume") caused the following compilation errors:

drivers/pinctrl/pinctrl-amd.c: In function ‘amd_gpio_should_save’:
drivers/pinctrl/pinctrl-amd.c:741:8: error: ‘const struct pin_desc’ has no member named ‘mux_owner’
if (pd->mux_owner || pd->gpio_owner ||

        ^

drivers/pinctrl/pinctrl-amd.c:741:25: error: ‘const struct pin_desc’ has no member named ‘gpio_owner’
if (pd->mux_owner || pd->gpio_owner ||

We need to enable CONFIG_PINMUX for this driver as well.

Fixes 79d2c8bede2c93f943 ("pinctrl/amd: save pin registers over suspend/resume")
---
 drivers/pinctrl/Kconfig | 1 +
 1 file changed, 1 insertion(+)
drivers/pinctrl/Kconfig +1 -0
index 1778cf4f81c7..82cd8b08d71f 100644
@@ -100,6 +100,7 @@ config PINCTRL_AMD
 	tristate "AMD GPIO pin control"
 	depends on GPIOLIB
 	select GPIOLIB_IRQCHIP
+	select PINMUX
 	select PINCONF
 	select GENERIC_PINCONF
 	help
Signature · 1 line
1.8.5.6

What is the commit id for this patch in Linus's tree? I don't see it there...

thanks,

greg k-h

#19 lore raw

Re: [PATCH 4.13 015/109] pinctrl/amd: save pin registers over suspend/resume

Quoted 91 lines · Greg Kroah-Hartman
Quoted 90 lines · Petr Mladek
Quoted 36 lines · Greg Kroah-Hartman

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

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

From: Daniel Drake <[email protected]>

commit 79d2c8bede2c93f9432d7da0bc2f76a195c90fc0 upstream.

The touchpad in the Asus laptop models X505BA/BP and X542BA/BP is unresponsive after suspend/resume. The following error appears during resume:

i2c_hid i2c-ELAN1300:00: failed to reset device.

The problem here is that i2c_hid does not notice the interrupt being generated at this point, because the GPIO is no longer configured for interrupts.

Fix this by saving pinctrl-amd pin registers during suspend and restoring them at resume time.

Based on code from pinctrl-intel.

drivers/pinctrl/pinctrl-amd.c +3 -0
@@ -725,6 +726,69 @@ static const struct pinconf_ops amd_pinc
 	.pin_config_group_set = amd_pinconf_group_set,
 };
 
+#ifdef CONFIG_PM_SLEEP
+static bool amd_gpio_should_save(struct amd_gpio *gpio_dev, unsigned int pin)
+{

drivers/pinctrl/pinctrl-amd.c static const struct pinconf_ops amd_pinc · line 741

Quoted 10 lines
drivers/pinctrl/pinctrl-amd.c +10 -0
+	const struct pin_desc *pd = pin_desc_get(gpio_dev->pctrl, pin);
+
+	if (!pd)
+		return false;
+
+	/*
+	 * Only restore the pin if it is actually in use by the kernel (or
+	 * by userspace).
+	 */
+	if (pd->mux_owner || pd->gpio_owner ||

This code causes a compilation error in the current Linus' tree (4.14-rc2+). I guess that the same problem will be also in older trees.

IMHO, we need to select CONFIG_PINMUX for when CONFIG_PINCTRL_AMD is selected. The following patch helped here:

Quoted 1 line

From f83130d3b5c147b4d400922847ca2751d8020ab5 Mon Sep 17 00:00:00 2001

From: Petr Mladek <[email protected]>
Date: Tue, 26 Sep 2017 15:51:28 +0200
Subject: [PATCH] pinctrl/amd: Fix build dependency on pinmux code
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The commit 79d2c8bede2c93f943 ("pinctrl/amd: save pin registers over suspend/resume") caused the following compilation errors:

drivers/pinctrl/pinctrl-amd.c: In function ‘amd_gpio_should_save’:
drivers/pinctrl/pinctrl-amd.c:741:8: error: ‘const struct pin_desc’ has no member named ‘mux_owner’
if (pd->mux_owner || pd->gpio_owner ||

        ^

drivers/pinctrl/pinctrl-amd.c:741:25: error: ‘const struct pin_desc’ has no member named ‘gpio_owner’
if (pd->mux_owner || pd->gpio_owner ||

We need to enable CONFIG_PINMUX for this driver as well.

Fixes 79d2c8bede2c93f943 ("pinctrl/amd: save pin registers over suspend/resume")
---
 drivers/pinctrl/Kconfig | 1 +
 1 file changed, 1 insertion(+)
drivers/pinctrl/Kconfig +1 -0
index 1778cf4f81c7..82cd8b08d71f 100644
@@ -100,6 +100,7 @@ config PINCTRL_AMD
 	tristate "AMD GPIO pin control"
 	depends on GPIOLIB
 	select GPIOLIB_IRQCHIP
+	select PINMUX
Quoted 8 lines
Quoted 5 lines
drivers/pinctrl/Kconfig +0 -0
 	select PINCONF
 	select GENERIC_PINCONF
 	help
Signature · 1 line
1.8.5.6

What is the commit id for this patch in Linus's tree? I don't see it there...

This extra patch has not been pushed to the Linus' tree yet. It was only my proposal to fix the problem. I did not find the original patch discussed on the kernel mailing list. Therefore I sent this follow up fix as a reply to the 4.13-stable review mail.

I hope that Linus Walleij would notice, review, and push it into Linus' tree.

Best Regards,
Petr

#20 lore raw

Re: [PATCH 4.13 015/109] pinctrl/amd: save pin registers over suspend/resume

Quoted 101 lines · Petr Mladek
Quoted 91 lines · Greg Kroah-Hartman
Quoted 90 lines · Petr Mladek
Quoted 36 lines · Greg Kroah-Hartman

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

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

From: Daniel Drake <[email protected]>

commit 79d2c8bede2c93f9432d7da0bc2f76a195c90fc0 upstream.

The touchpad in the Asus laptop models X505BA/BP and X542BA/BP is unresponsive after suspend/resume. The following error appears during resume:

i2c_hid i2c-ELAN1300:00: failed to reset device.

The problem here is that i2c_hid does not notice the interrupt being generated at this point, because the GPIO is no longer configured for interrupts.

Fix this by saving pinctrl-amd pin registers during suspend and restoring them at resume time.

Based on code from pinctrl-intel.

drivers/pinctrl/pinctrl-amd.c +3 -0
@@ -725,6 +726,69 @@ static const struct pinconf_ops amd_pinc
  .pin_config_group_set = amd_pinconf_group_set,
 };
 
+#ifdef CONFIG_PM_SLEEP
+static bool amd_gpio_should_save(struct amd_gpio *gpio_dev, unsigned int pin)
+{

drivers/pinctrl/pinctrl-amd.c static const struct pinconf_ops amd_pinc · line 741

Quoted 10 lines
drivers/pinctrl/pinctrl-amd.c +10 -0
+ const struct pin_desc *pd = pin_desc_get(gpio_dev->pctrl, pin);
+
+ if (!pd)
+         return false;
+
+ /*
+  * Only restore the pin if it is actually in use by the kernel (or
+  * by userspace).
+  */
+ if (pd->mux_owner || pd->gpio_owner ||

This code causes a compilation error in the current Linus' tree (4.14-rc2+). I guess that the same problem will be also in older trees.

IMHO, we need to select CONFIG_PINMUX for when CONFIG_PINCTRL_AMD is selected. The following patch helped here:

Quoted 1 line

From f83130d3b5c147b4d400922847ca2751d8020ab5 Mon Sep 17 00:00:00 2001

From: Petr Mladek <[email protected]>
Date: Tue, 26 Sep 2017 15:51:28 +0200
Subject: [PATCH] pinctrl/amd: Fix build dependency on pinmux code
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The commit 79d2c8bede2c93f943 ("pinctrl/amd: save pin registers over suspend/resume") caused the following compilation errors:

drivers/pinctrl/pinctrl-amd.c: In function ‘amd_gpio_should_save’:
drivers/pinctrl/pinctrl-amd.c:741:8: error: ‘const struct pin_desc’ has no member named ‘mux_owner’
if (pd->mux_owner || pd->gpio_owner ||

        ^

drivers/pinctrl/pinctrl-amd.c:741:25: error: ‘const struct pin_desc’ has no member named ‘gpio_owner’
if (pd->mux_owner || pd->gpio_owner ||

We need to enable CONFIG_PINMUX for this driver as well.

Fixes 79d2c8bede2c93f943 ("pinctrl/amd: save pin registers over suspend/resume")
---
 drivers/pinctrl/Kconfig | 1 +
 1 file changed, 1 insertion(+)
drivers/pinctrl/Kconfig +1 -0
index 1778cf4f81c7..82cd8b08d71f 100644
@@ -100,6 +100,7 @@ config PINCTRL_AMD
    tristate "AMD GPIO pin control"
    depends on GPIOLIB
    select GPIOLIB_IRQCHIP
+   select PINMUX
Quoted 8 lines
Quoted 5 lines
drivers/pinctrl/Kconfig +0 -1
    select PINCONF
    select GENERIC_PINCONF
    help
--

1.8.5.6

What is the commit id for this patch in Linus's tree? I don't see it there...

Quoted 8 lines

This extra patch has not been pushed to the Linus' tree yet. It was only my proposal to fix the problem. I did not find the original patch discussed on the kernel mailing list. Therefore I sent this follow up fix as a reply to the 4.13-stable review mail.

I hope that Linus Walleij would notice, review, and push it into Linus' tree.

I missed it. OK looking for it so I can apply it.

Yours,
Linus Walleij

#21 lore raw

Re: [PATCH 4.13 015/109] pinctrl/amd: save pin registers over suspend/resume

In reply to Petr Mladek
Quoted 2 lines · Petr Mladek

IMHO, we need to select CONFIG_PINMUX for when CONFIG_PINCTRL_AMD is selected. The following patch helped here:

Took the patch out of this mail, applied it to fixes and tagged it for stable.

Will send it to Torvals ASAP.

Yours,
Linus Walleij