This is the start of the stable review cycle for the 4.19.90 release. There are 140 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 Wed, 18 Dec 2019 17:41:25 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.19.90-rc1... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.19.y and the diffstat can be found below.
thanks,
greg k-h
------------- Pseudo-Shortlog of commits:
Greg Kroah-Hartman gregkh@linuxfoundation.org Linux 4.19.90-rc1
Heiko Carstens heiko.carstens@de.ibm.com s390/smp,vdso: fix ASCE handling
Thomas Hellstrom thellstrom@vmware.com mm/memory.c: fix a huge pud insertion race during faulting
Michal Hocko mhocko@suse.com mm, thp, proc: report THP eligibility for each vma
Daniel Schultz d.schultz@phytec.de mfd: rk808: Fix RK818 ID template
yangerkun yangerkun@huawei.com ext4: fix a bug in ext4_wait_for_tail_page_commit
Darrick J. Wong darrick.wong@oracle.com splice: only read in as much information as there is pipe buffer space
Alexandre Belloni alexandre.belloni@bootlin.com rtc: disable uie before setting time and enable after
Chen Jun chenjun102@huawei.com mm/shmem.c: cast the type of unmap_start to u64
Will Deacon will@kernel.org firmware: qcom: scm: Ensure 'a0' status code is treated as signed
Theodore Ts'o tytso@mit.edu ext4: work around deleting a file with i_nlink == 0 safely
Vincenzo Frascino vincenzo.frascino@arm.com powerpc: Fix vDSO clock_getres()
Nathan Chancellor natechancellor@gmail.com powerpc: Avoid clang warnings around setjmp and longjmp
Anders Roxell anders.roxell@linaro.org regulator: 88pm800: fix warning same module names
Miaoqing Pan miaoqing@codeaurora.org ath10k: fix fw crash by moving chip reset after napi disabled
Helen Koike helen.koike@collabora.com media: vimc: fix component match compare
Ido Schimmel idosch@mellanox.com mlxsw: spectrum_router: Refresh nexthop neighbour when it becomes dead
Tony Lindgren tony@atomide.com power: supply: cpcap-battery: Fix signed counter sample register
Shirish S Shirish.S@amd.com x86/MCE/AMD: Carve out the MC4_MISC thresholding quirk
Shirish S Shirish.S@amd.com x86/MCE/AMD: Turn off MC4_MISC thresholding on all family 0x15 models
Luo Jiaxing luojiaxing@huawei.com scsi: hisi_sas: Reject setting programmed minimum linkrate > 1.5G
Xiang Chen chenxiang66@hisilicon.com scsi: hisi_sas: send primitive NOTIFY to SSP situation only
Yonglong Liu liuyonglong@huawei.com net: hns3: Check variable is valid before assigning it to another
Huazhong Tan tanhuazhong@huawei.com net: hns3: change hnae3_register_ae_dev() to int
Jian Shen shenjian15@huawei.com net: hns3: clear pci private data when unload hns3 driver
Karsten Graul kgraul@linux.ibm.com net/smc: do not wait under send_lock
Toke Høiland-Jørgensen toke@redhat.com sch_cake: Correctly update parent qlen when splitting GSO packets
Stefano Stabellini sstabellini@kernel.org pvcalls-front: don't return error when the ring is full
YueHaibing yuehaibing@huawei.com e100: Fix passing zero to 'PTR_ERR' warning in e100_load_ucode_wait
Nathan Chancellor natechancellor@gmail.com drbd: Change drbd_request_detach_interruptible's return type to int
James Smart jsmart2021@gmail.com scsi: lpfc: Correct topology type reporting on G7 adapters
James Smart jsmart2021@gmail.com scsi: lpfc: Correct code setting non existent bits in sli4 ABORT WQE
James Smart jsmart2021@gmail.com scsi: lpfc: Cap NPIV vports to 256
H. Nikolaus Schaller hns@goldelico.com omap: pdata-quirks: remove openpandora quirks for mmc3 and wl1251
Wen Yang wenyang@linux.alibaba.com usb: typec: fix use after free in typec_register_port()
Meng Li Meng.Li@windriver.com iio: ad7949: kill pointless "readback"-handling code
Mathias Nyman mathias.nyman@linux.intel.com xhci: make sure interrupts are restored to correct state
Quinn Tran qutran@marvell.com scsi: qla2xxx: Fix SRB leak on switch command timeout
Himanshu Madhani hmadhani@marvell.com scsi: qla2xxx: Fix message indicating vectors used by driver
Bart Van Assche bvanassche@acm.org scsi: qla2xxx: Always check the qla2x00_wait_for_hba_online() return value
Bart Van Assche bvanassche@acm.org scsi: qla2xxx: Fix qla24xx_process_bidir_cmd()
Bart Van Assche bvanassche@acm.org scsi: qla2xxx: Fix session lookup in qlt_abort_work()
Quinn Tran qutran@marvell.com scsi: qla2xxx: Fix hang in fcport delete path
Himanshu Madhani hmadhani@marvell.com scsi: qla2xxx: Fix DMA unmap leak
Steffen Maier maier@linux.ibm.com scsi: zfcp: trace channel log even for FCP command responses
Ming Lei ming.lei@redhat.com block: fix single range discard merge
Jeff Mahoney jeffm@suse.com reiserfs: fix extended attributes on the root directory
Jan Kara jack@suse.cz ext4: Fix credit estimate for final inode freeing
Dmitry Monakhov dmtrmonakhov@yandex-team.ru quota: fix livelock in dquot_writeback_dquots
Chengguang Xu cgxu519@mykernel.net ext2: check err when partial != NULL
Dmitry Monakhov dmtrmonakhov@yandex-team.ru quota: Check that quota is not dirty before release
Ville Syrjälä ville.syrjala@linux.intel.com video/hdmi: Fix AVI bar unpack
Cédric Le Goater clg@kaod.org powerpc/xive: Skip ioremap() of ESB pages for LSI interrupts
Alastair D'Silva alastair@d-silva.org powerpc: Allow flush_icache_range to work across ranges >4GB
Cédric Le Goater clg@kaod.org powerpc/xive: Prevent page fault issues in the machine crash handler
Alastair D'Silva alastair@d-silva.org powerpc: Allow 64bit VDSO __kernel_sync_dicache to work across ranges >4GB
Arnd Bergmann arnd@arndb.de ppdev: fix PPGETTIME/PPSETTIME ioctls
Jarkko Nikula jarkko.nikula@bitmer.com ARM: dts: omap3-tao3530: Fix incorrect MMC card detection GPIO polarity
H. Nikolaus Schaller hns@goldelico.com mmc: host: omap_hsmmc: add code for special init of wl1251 to get rid of pandora_wl1251_init_card
Krzysztof Kozlowski krzk@kernel.org pinctrl: samsung: Fix device node refcount leaks in S3C64xx wakeup controller init
Krzysztof Kozlowski krzk@kernel.org pinctrl: samsung: Fix device node refcount leaks in init code
Krzysztof Kozlowski krzk@kernel.org pinctrl: samsung: Fix device node refcount leaks in S3C24xx wakeup controller init
Krzysztof Kozlowski krzk@kernel.org pinctrl: samsung: Fix device node refcount leaks in Exynos wakeup controller init
Nishka Dasgupta nishkadg.linux@gmail.com pinctrl: samsung: Add of_node_put() before return in error path
Gregory CLEMENT gregory.clement@bootlin.com pinctrl: armada-37xx: Fix irq mask access in armada_37xx_irq_set_type()
Rafael J. Wysocki rafael.j.wysocki@intel.com ACPI: PM: Avoid attaching ACPI PM domain to certain devices
Vamshi K Sthambamkadi vamshi.k.sthambamkadi@gmail.com ACPI: bus: Fix NULL pointer check in acpi_bus_get_private_data()
Francesco Ruggeri fruggeri@arista.com ACPI: OSL: only free map once in osl.c
Mika Westerberg mika.westerberg@linux.intel.com ACPI / hotplug / PCI: Allocate resources directly under the non-hotplug bridge
John Hubbard jhubbard@nvidia.com cpufreq: powernv: fix stack bloat and hard limit on number of CPUs
Leonard Crestez leonard.crestez@nxp.com PM / devfreq: Lock devfreq in trans_stat_show
Alexander Shishkin alexander.shishkin@linux.intel.com intel_th: pci: Add Tiger Lake CPU support
Alexander Shishkin alexander.shishkin@linux.intel.com intel_th: pci: Add Ice Lake CPU support
Alexander Shishkin alexander.shishkin@linux.intel.com intel_th: Fix a double put_device() in error path
Gao Xiang gaoxiang25@huawei.com erofs: zero out when listxattr is called with no xattr
Zhenzhong Duan zhenzhong.duan@oracle.com cpuidle: Do not unset the driver if it is there already
Hans Verkuil hverkuil-cisco@xs4all.nl media: cec.h: CEC_OP_REC_FLAG_ values were swapped
Johan Hovold johan@kernel.org media: radio: wl1273: fix interrupt masking on release
Johan Hovold johan@kernel.org media: bdisp: fix memleak on release
Gerald Schaefer gerald.schaefer@de.ibm.com s390/mm: properly clear _PAGE_NOEXEC bit when it is not supported
Denis Efremov efremov@linux.com ar5523: check NULL before memcpy() in ar5523_cmd()
Aleksa Sarai cyphar@cyphar.com cgroup: pids: use atomic64_t for pids->limit
Ming Lei ming.lei@redhat.com blk-mq: avoid sysfs buffer overflow with too many CPU cores
David Jeffery djeffery@redhat.com md: improve handling of bio with REQ_PREFLUSH in md_flush_request()
Pawel Harlozinski pawel.harlozinski@linux.intel.com ASoC: Jack: Fix NULL pointer dereference in snd_soc_jack_report
Jacob Rasmussen jacobraz@chromium.org ASoC: rt5645: Fixed typo for buddy jack support.
Jacob Rasmussen jacobraz@chromium.org ASoC: rt5645: Fixed buddy jack support.
Tejun Heo tj@kernel.org workqueue: Fix pwq ref leak in rescuer_thread()
Tejun Heo tj@kernel.org workqueue: Fix spurious sanity check failures in destroy_workqueue()
Dmitry Fomichev dmitry.fomichev@wdc.com dm zoned: reduce overhead of backing device checks
Maged Mokhtar mmokhtar@petasan.org dm writecache: handle REQ_FUA
Sumit Garg sumit.garg@linaro.org hwrng: omap - Fix RNG wait loop timeout
Amir Goldstein amir73il@gmail.com ovl: relax WARN_ON() on rename to self
Amir Goldstein amir73il@gmail.com ovl: fix corner case of non-unique st_dev;st_ino
Greg Kroah-Hartman gregkh@linuxfoundation.org lib: raid6: fix awk build warnings
Larry Finger Larry.Finger@lwfinger.net rtlwifi: rtl8192de: Fix missing enable interrupt flag
Larry Finger Larry.Finger@lwfinger.net rtlwifi: rtl8192de: Fix missing callback that tests for hw release of buffer
Larry Finger Larry.Finger@lwfinger.net rtlwifi: rtl8192de: Fix missing code to retrieve RX buffer address
Josef Bacik josef@toxicpanda.com btrfs: record all roots for rename exchange on a subvol
Filipe Manana fdmanana@suse.com Btrfs: send, skip backreference walking for extents with many references
Qu Wenruo wqu@suse.com btrfs: Remove btrfs_bio::flags member
Tejun Heo tj@kernel.org btrfs: Avoid getting stuck during cyclic writebacks
Filipe Manana fdmanana@suse.com Btrfs: fix negative subv_writers counter and data space leak after buffered write
Filipe Manana fdmanana@suse.com Btrfs: fix metadata space leak on fixup worker failure to set range as delalloc
Josef Bacik josef@toxicpanda.com btrfs: use refcount_inc_not_zero in kill_all_nodes
Josef Bacik josef@toxicpanda.com btrfs: check page->mapping when loading free space cache
Yoshihiro Shimoda yoshihiro.shimoda.uh@renesas.com phy: renesas: rcar-gen3-usb2: Fix sysfs interface of "role"
Thinh Nguyen Thinh.Nguyen@synopsys.com usb: dwc3: ep0: Clear started flag on completion
Tejas Joglekar Tejas.Joglekar@synopsys.com usb: dwc3: gadget: Fix logical condition
Heikki Krogerus heikki.krogerus@linux.intel.com usb: dwc3: pci: add ID for the Intel Comet Lake -H variant
David Hildenbrand david@redhat.com virtio-balloon: fix managed page counts when migrating pages between zones
Miquel Raynal miquel.raynal@bootlin.com mtd: spear_smi: Fix Write Burst mode
Tadeusz Struk tadeusz.struk@intel.com tpm: add check after commands attribs tab allocation
Pete Zaitcev zaitcev@redhat.com usb: mon: Fix a deadlock in usbmon between mmap and read
Emiliano Ingrassia ingrassia@epigenesys.com usb: core: urb: fix URB structure initialization function
Johan Hovold johan@kernel.org USB: adutux: fix interface sanity check
Wen Yang wenyang@linux.alibaba.com usb: roles: fix a potential use after free
Johan Hovold johan@kernel.org USB: serial: io_edgeport: fix epic endpoint lookup
Johan Hovold johan@kernel.org USB: idmouse: fix interface sanity checks
Johan Hovold johan@kernel.org USB: atm: ueagle-atm: add missing endpoint check
Jean-Baptiste Maneyrol jmaneyrol@invensense.com iio: imu: inv_mpu6050: fix temperature reporting using bad unit
Chris Lesiak chris.lesiak@licor.com iio: humidity: hdc100x: fix IIO_HUMIDITYRELATIVE channel reporting
Nuno Sá nuno.sa@analog.com iio: adis16480: Add debugfs_reg_access entry
H. Nikolaus Schaller hns@goldelico.com ARM: dts: pandora-common: define wl1251 as child node of mmc3
Mathias Nyman mathias.nyman@linux.intel.com xhci: handle some XHCI_TRUST_TX_LENGTH quirks cases as default behaviour.
Kai-Heng Feng kai.heng.feng@canonical.com xhci: Increase STS_HALT timeout in xhci_suspend()
Mika Westerberg mika.westerberg@linux.intel.com xhci: Fix memory leak in xhci_add_in_port()
Henry Lin henryl@nvidia.com usb: xhci: only set D3hot for pci device
Johan Hovold johan@kernel.org staging: gigaset: add endpoint-type sanity check
Johan Hovold johan@kernel.org staging: gigaset: fix illegal free on probe errors
Johan Hovold johan@kernel.org staging: gigaset: fix general protection fault on probe
Johan Hovold johan@kernel.org staging: rtl8712: fix interface sanity check
Johan Hovold johan@kernel.org staging: rtl8188eu: fix interface sanity check
Kai-Heng Feng kai.heng.feng@canonical.com usb: Allow USB device to be warm reset in suspended state
Oliver Neukum oneukum@suse.com USB: documentation: flags on usb-storage versus UAS
Oliver Neukum oneukum@suse.com USB: uas: heed CAPACITY_HEURISTICS
Oliver Neukum oneukum@suse.com USB: uas: honor flag to avoid CAPACITY16
Arnd Bergmann arnd@arndb.de media: venus: remove invalid compat_ioctl32 handler
Quinn Tran qutran@marvell.com scsi: qla2xxx: Fix driver unload hang
Gustavo A. R. Silva gustavo@embeddedor.com usb: gadget: pch_udc: fix use after free
Wei Yongjun weiyongjun1@huawei.com usb: gadget: configfs: Fix missing spin_lock_init()
-------------
Diffstat:
Documentation/admin-guide/kernel-parameters.txt | 22 ++--- Documentation/filesystems/proc.txt | 3 + Makefile | 4 +- arch/arm/boot/dts/omap3-pandora-common.dtsi | 36 ++++++++- arch/arm/boot/dts/omap3-tao3530.dtsi | 2 +- arch/arm/mach-omap2/pdata-quirks.c | 93 ---------------------- arch/powerpc/include/asm/vdso_datapage.h | 2 + arch/powerpc/kernel/Makefile | 4 +- arch/powerpc/kernel/asm-offsets.c | 2 +- arch/powerpc/kernel/misc_64.S | 4 +- arch/powerpc/kernel/time.c | 1 + arch/powerpc/kernel/vdso32/gettimeofday.S | 7 +- arch/powerpc/kernel/vdso64/cacheflush.S | 4 +- arch/powerpc/kernel/vdso64/gettimeofday.S | 7 +- arch/powerpc/sysdev/xive/common.c | 9 +++ arch/powerpc/sysdev/xive/spapr.c | 12 ++- arch/powerpc/xmon/Makefile | 4 +- arch/s390/include/asm/pgtable.h | 4 +- arch/s390/kernel/smp.c | 5 ++ arch/x86/kernel/cpu/mcheck/mce.c | 30 ------- arch/x86/kernel/cpu/mcheck/mce_amd.c | 36 +++++++++ block/blk-merge.c | 2 +- block/blk-mq-sysfs.c | 15 ++-- drivers/acpi/bus.c | 2 +- drivers/acpi/device_pm.c | 12 ++- drivers/acpi/osl.c | 28 ++++--- drivers/block/drbd/drbd_state.c | 6 +- drivers/block/drbd/drbd_state.h | 3 +- drivers/char/hw_random/omap-rng.c | 9 ++- drivers/char/ppdev.c | 16 +++- drivers/char/tpm/tpm2-cmd.c | 4 + drivers/cpufreq/powernv-cpufreq.c | 17 +++- drivers/cpuidle/driver.c | 15 ++-- drivers/devfreq/devfreq.c | 12 ++- drivers/edac/altera_edac.c | 1 + drivers/firmware/qcom_scm-64.c | 2 +- drivers/hwtracing/intel_th/core.c | 8 +- drivers/hwtracing/intel_th/pci.c | 10 +++ drivers/iio/humidity/hdc100x.c | 2 +- drivers/iio/imu/adis16480.c | 1 + drivers/iio/imu/inv_mpu6050/inv_mpu_core.c | 23 +++--- drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | 16 +++- drivers/isdn/gigaset/usb-gigaset.c | 23 ++++-- drivers/md/dm-writecache.c | 3 +- drivers/md/dm-zoned-metadata.c | 29 ++++--- drivers/md/dm-zoned-reclaim.c | 8 +- drivers/md/dm-zoned-target.c | 54 +++++++++---- drivers/md/dm-zoned.h | 2 + drivers/md/md-linear.c | 5 +- drivers/md/md-multipath.c | 5 +- drivers/md/md.c | 11 ++- drivers/md/md.h | 4 +- drivers/md/raid0.c | 5 +- drivers/md/raid1.c | 5 +- drivers/md/raid10.c | 5 +- drivers/md/raid5.c | 4 +- drivers/media/platform/qcom/venus/vdec.c | 3 - drivers/media/platform/qcom/venus/venc.c | 3 - drivers/media/platform/sti/bdisp/bdisp-v4l2.c | 3 +- drivers/media/platform/vimc/vimc-core.c | 7 +- drivers/media/radio/radio-wl1273.c | 3 +- drivers/mmc/host/omap_hsmmc.c | 30 +++++++ drivers/mtd/devices/spear_smi.c | 38 ++++++++- drivers/net/ethernet/hisilicon/hns3/hnae3.c | 26 ++++-- drivers/net/ethernet/hisilicon/hns3/hnae3.h | 2 +- drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 9 ++- drivers/net/ethernet/intel/e100.c | 4 +- .../net/ethernet/mellanox/mlxsw/spectrum_router.c | 73 ++++++++++++++++- drivers/net/wireless/ath/ar5523/ar5523.c | 3 +- drivers/net/wireless/ath/ath10k/pci.c | 9 ++- .../net/wireless/realtek/rtlwifi/rtl8192de/hw.c | 9 ++- .../net/wireless/realtek/rtlwifi/rtl8192de/sw.c | 1 + .../net/wireless/realtek/rtlwifi/rtl8192de/trx.c | 25 +++++- .../net/wireless/realtek/rtlwifi/rtl8192de/trx.h | 2 + drivers/pci/hotplug/acpiphp_glue.c | 12 ++- drivers/phy/renesas/phy-rcar-gen3-usb2.c | 5 +- drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 6 +- drivers/pinctrl/samsung/pinctrl-exynos.c | 14 +++- drivers/pinctrl/samsung/pinctrl-s3c24xx.c | 6 +- drivers/pinctrl/samsung/pinctrl-s3c64xx.c | 6 +- drivers/pinctrl/samsung/pinctrl-samsung.c | 10 ++- drivers/power/supply/cpcap-battery.c | 11 +-- .../regulator/{88pm800.c => 88pm800-regulator.c} | 0 drivers/regulator/Makefile | 2 +- drivers/rtc/interface.c | 19 ++++- drivers/s390/scsi/zfcp_dbf.c | 8 +- drivers/scsi/hisi_sas/hisi_sas.h | 2 +- drivers/scsi/hisi_sas/hisi_sas_main.c | 15 ++-- drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 4 +- drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 4 +- drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 4 +- drivers/scsi/lpfc/lpfc.h | 3 +- drivers/scsi/lpfc/lpfc_attr.c | 17 +++- drivers/scsi/lpfc/lpfc_init.c | 3 + drivers/scsi/lpfc/lpfc_mbox.c | 6 +- drivers/scsi/lpfc/lpfc_nvme.c | 2 - drivers/scsi/lpfc/lpfc_sli.c | 14 +--- drivers/scsi/qla2xxx/qla_attr.c | 3 +- drivers/scsi/qla2xxx/qla_bsg.c | 15 ++-- drivers/scsi/qla2xxx/qla_gs.c | 2 +- drivers/scsi/qla2xxx/qla_init.c | 16 ++-- drivers/scsi/qla2xxx/qla_isr.c | 6 +- drivers/scsi/qla2xxx/qla_mbx.c | 4 - drivers/scsi/qla2xxx/qla_mid.c | 11 +-- drivers/scsi/qla2xxx/qla_os.c | 7 +- drivers/scsi/qla2xxx/qla_target.c | 11 +-- drivers/staging/erofs/xattr.c | 2 + drivers/staging/rtl8188eu/os_dep/usb_intf.c | 2 +- drivers/staging/rtl8712/usb_intf.c | 2 +- drivers/usb/atm/ueagle-atm.c | 18 +++-- drivers/usb/core/hub.c | 5 +- drivers/usb/core/urb.c | 1 + drivers/usb/dwc3/dwc3-pci.c | 6 +- drivers/usb/dwc3/ep0.c | 8 ++ drivers/usb/dwc3/gadget.c | 2 +- drivers/usb/gadget/configfs.c | 1 + drivers/usb/gadget/udc/pch_udc.c | 1 - drivers/usb/host/xhci-hub.c | 8 +- drivers/usb/host/xhci-mem.c | 4 + drivers/usb/host/xhci-pci.c | 13 +++ drivers/usb/host/xhci-ring.c | 3 +- drivers/usb/host/xhci.c | 9 +-- drivers/usb/host/xhci.h | 1 + drivers/usb/misc/adutux.c | 2 +- drivers/usb/misc/idmouse.c | 2 +- drivers/usb/mon/mon_bin.c | 32 +++++--- drivers/usb/roles/class.c | 2 +- drivers/usb/serial/io_edgeport.c | 10 ++- drivers/usb/storage/uas.c | 10 +++ drivers/usb/typec/class.c | 6 +- drivers/video/hdmi.c | 8 +- drivers/virtio/virtio_balloon.c | 11 +++ drivers/xen/pvcalls-front.c | 4 +- fs/btrfs/delayed-inode.c | 13 ++- fs/btrfs/extent_io.c | 12 +-- fs/btrfs/file.c | 2 +- fs/btrfs/free-space-cache.c | 6 ++ fs/btrfs/inode.c | 9 ++- fs/btrfs/send.c | 25 +++++- fs/btrfs/volumes.h | 1 - fs/ext2/inode.c | 7 +- fs/ext4/inode.c | 25 ++++-- fs/ext4/namei.c | 11 ++- fs/ocfs2/quota_global.c | 2 +- fs/overlayfs/dir.c | 2 +- fs/overlayfs/inode.c | 8 +- fs/proc/task_mmu.c | 2 + fs/quota/dquot.c | 11 +-- fs/reiserfs/inode.c | 12 ++- fs/reiserfs/namei.c | 7 +- fs/reiserfs/reiserfs.h | 2 + fs/reiserfs/super.c | 2 + fs/reiserfs/xattr.c | 19 +++-- fs/reiserfs/xattr_acl.c | 4 +- fs/splice.c | 14 +++- include/asm-generic/pgtable.h | 25 ++++++ include/linux/huge_mm.h | 13 ++- include/linux/mfd/rk808.h | 2 +- include/linux/quotaops.h | 10 +++ include/uapi/linux/cec.h | 4 +- kernel/cgroup/pids.c | 11 +-- kernel/workqueue.c | 37 +++++++-- lib/raid6/unroll.awk | 2 +- mm/huge_memory.c | 12 ++- mm/memory.c | 10 ++- mm/shmem.c | 2 +- net/sched/sch_cake.c | 5 +- net/smc/smc_tx.c | 10 +-- sound/soc/codecs/rt5645.c | 6 +- sound/soc/soc-jack.c | 3 +- 170 files changed, 1112 insertions(+), 565 deletions(-)
From: Wei Yongjun weiyongjun1@huawei.com
commit 093edc2baad2c258b1f55d1ab9c63c2b5ae67e42 upstream.
The driver allocates the spinlock but not initialize it. Use spin_lock_init() on it to initialize it correctly.
This is detected by Coccinelle semantic patch.
Fixes: 1a1c851bbd70 ("usb: gadget: configfs: fix concurrent issue between composite APIs") Signed-off-by: Wei Yongjun weiyongjun1@huawei.com Cc: stable stable@vger.kernel.org Reviewed-by: Peter Chen peter.chen@nxp.com Link: https://lore.kernel.org/r/20191030034046.188808-1-weiyongjun1@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/gadget/configfs.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -1544,6 +1544,7 @@ static struct config_group *gadgets_make gi->composite.resume = NULL; gi->composite.max_speed = USB_SPEED_SUPER;
+ spin_lock_init(&gi->spinlock); mutex_init(&gi->lock); INIT_LIST_HEAD(&gi->string_list); INIT_LIST_HEAD(&gi->available_func);
From: Gustavo A. R. Silva gustavo@embeddedor.com
commit 66d1b0c0580b7f1b1850ee4423f32ac42afa2e92 upstream.
Remove pointer dereference after free.
pci_pool_free doesn't care about contents of td. It's just a void* for it
Addresses-Coverity-ID: 1091173 ("Use after free") Cc: stable@vger.kernel.org Acked-by: Michal Nazarewicz mina86@mina86.com Signed-off-by: Gustavo A. R. Silva gustavo@embeddedor.com Link: https://lore.kernel.org/r/20191106202821.GA20347@embeddedor Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/gadget/udc/pch_udc.c | 1 - 1 file changed, 1 deletion(-)
--- a/drivers/usb/gadget/udc/pch_udc.c +++ b/drivers/usb/gadget/udc/pch_udc.c @@ -1520,7 +1520,6 @@ static void pch_udc_free_dma_chain(struc td = phys_to_virt(addr); addr2 = (dma_addr_t)td->next; dma_pool_free(dev->data_requests, td, addr); - td->next = 0x00; addr = addr2; } req->chain_len = 1;
From: Quinn Tran qutran@marvell.com
commit dd322b7f3efc8cda085bb60eadc4aee6324eadd8 upstream.
This patch fixes driver unload hang by removing msleep()
Fixes: d74595278f4ab ("scsi: qla2xxx: Add multiple queue pair functionality.") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20191105150657.8092-5-hmadhani@marvell.com Reviewed-by: Ewan D. Milne emilne@redhat.com Signed-off-by: Quinn Tran qutran@marvell.com Signed-off-by: Himanshu Madhani hmadhani@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/scsi/qla2xxx/qla_init.c | 2 -- 1 file changed, 2 deletions(-)
--- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -8725,8 +8725,6 @@ int qla2xxx_delete_qpair(struct scsi_qla struct qla_hw_data *ha = qpair->hw;
qpair->delete_in_progress = 1; - while (atomic_read(&qpair->ref_count)) - msleep(500);
ret = qla25xx_delete_req_que(vha, qpair->req); if (ret != QLA_SUCCESS)
From: Arnd Bergmann arnd@arndb.de
commit 4adc0423de92cf850d1ef5c0e7cb28fd7a38219e upstream.
v4l2_compat_ioctl32() is the function that calls into v4l2_file_operations->compat_ioctl32(), so setting that back to the same function leads to a trivial endless loop, followed by a kernel stack overrun.
Remove the incorrect assignment.
Cc: stable@vger.kernel.org Fixes: 7472c1c69138 ("[media] media: venus: vdec: add video decoder files") Fixes: aaaa93eda64b ("[media] media: venus: venc: add video encoder files") Signed-off-by: Arnd Bergmann arnd@arndb.de Acked-by: Stanimir Varbanov stanimir.varbanov@linaro.org Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/media/platform/qcom/venus/vdec.c | 3 --- drivers/media/platform/qcom/venus/venc.c | 3 --- 2 files changed, 6 deletions(-)
--- a/drivers/media/platform/qcom/venus/vdec.c +++ b/drivers/media/platform/qcom/venus/vdec.c @@ -1115,9 +1115,6 @@ static const struct v4l2_file_operations .unlocked_ioctl = video_ioctl2, .poll = v4l2_m2m_fop_poll, .mmap = v4l2_m2m_fop_mmap, -#ifdef CONFIG_COMPAT - .compat_ioctl32 = v4l2_compat_ioctl32, -#endif };
static int vdec_probe(struct platform_device *pdev) --- a/drivers/media/platform/qcom/venus/venc.c +++ b/drivers/media/platform/qcom/venus/venc.c @@ -1220,9 +1220,6 @@ static const struct v4l2_file_operations .unlocked_ioctl = video_ioctl2, .poll = v4l2_m2m_fop_poll, .mmap = v4l2_m2m_fop_mmap, -#ifdef CONFIG_COMPAT - .compat_ioctl32 = v4l2_compat_ioctl32, -#endif };
static int venc_probe(struct platform_device *pdev)
From: Oliver Neukum oneukum@suse.com
commit bff000cae1eec750d62e265c4ba2db9af57b17e1 upstream.
Copy the support over from usb-storage to get feature parity
Signed-off-by: Oliver Neukum oneukum@suse.com Cc: stable stable@vger.kernel.org Link: https://lore.kernel.org/r/20191114112758.32747-2-oneukum@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/storage/uas.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -832,6 +832,10 @@ static int uas_slave_configure(struct sc sdev->wce_default_on = 1; }
+ /* Some disks cannot handle READ_CAPACITY_16 */ + if (devinfo->flags & US_FL_NO_READ_CAPACITY_16) + sdev->no_read_capacity_16 = 1; + /* * Some disks return the total number of blocks in response * to READ CAPACITY rather than the highest block number.
From: Oliver Neukum oneukum@suse.com
commit 335cbbd5762d5e5c67a8ddd6e6362c2aa42a328f upstream.
There is no need to ignore this flag. We should be as close to storage in that regard as makes sense, so honor flags whose cost is tiny.
Signed-off-by: Oliver Neukum oneukum@suse.com Cc: stable stable@vger.kernel.org Link: https://lore.kernel.org/r/20191114112758.32747-3-oneukum@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/storage/uas.c | 6 ++++++ 1 file changed, 6 insertions(+)
--- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -845,6 +845,12 @@ static int uas_slave_configure(struct sc sdev->fix_capacity = 1;
/* + * in some cases we have to guess + */ + if (devinfo->flags & US_FL_CAPACITY_HEURISTICS) + sdev->guess_capacity = 1; + + /* * Some devices don't like MODE SENSE with page=0x3f, * which is the command used for checking if a device * is write-protected. Now that we tell the sd driver
From: Oliver Neukum oneukum@suse.com
commit 65cc8bf99349f651a0a2cee69333525fe581f306 upstream.
Document which flags work storage, UAS or both
Signed-off-by: Oliver Neukum oneukum@suse.com Cc: stable stable@vger.kernel.org Link: https://lore.kernel.org/r/20191114112758.32747-4-oneukum@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- Documentation/admin-guide/kernel-parameters.txt | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-)
--- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -4941,13 +4941,13 @@ Flags is a set of characters, each corresponding to a common usb-storage quirk flag as follows: a = SANE_SENSE (collect more than 18 bytes - of sense data); + of sense data, not on uas); b = BAD_SENSE (don't collect more than 18 - bytes of sense data); + bytes of sense data, not on uas); c = FIX_CAPACITY (decrease the reported device capacity by one sector); d = NO_READ_DISC_INFO (don't use - READ_DISC_INFO command); + READ_DISC_INFO command, not on uas); e = NO_READ_CAPACITY_16 (don't use READ_CAPACITY_16 command); f = NO_REPORT_OPCODES (don't use report opcodes @@ -4962,17 +4962,18 @@ j = NO_REPORT_LUNS (don't use report luns command, uas only); l = NOT_LOCKABLE (don't try to lock and - unlock ejectable media); + unlock ejectable media, not on uas); m = MAX_SECTORS_64 (don't transfer more - than 64 sectors = 32 KB at a time); + than 64 sectors = 32 KB at a time, + not on uas); n = INITIAL_READ10 (force a retry of the - initial READ(10) command); + initial READ(10) command, not on uas); o = CAPACITY_OK (accept the capacity - reported by the device); + reported by the device, not on uas); p = WRITE_CACHE (the device cache is ON - by default); + by default, not on uas); r = IGNORE_RESIDUE (the device reports - bogus residue values); + bogus residue values, not on uas); s = SINGLE_LUN (the device has only one Logical Unit); t = NO_ATA_1X (don't allow ATA(12) and ATA(16) @@ -4981,7 +4982,8 @@ w = NO_WP_DETECT (don't test whether the medium is write-protected). y = ALWAYS_SYNC (issue a SYNCHRONIZE_CACHE - even if the device claims no cache) + even if the device claims no cache, + not on uas) Example: quirks=0419:aaf5:rl,0421:0433:rc
user_debug= [KNL,ARM]
From: Kai-Heng Feng kai.heng.feng@canonical.com
commit e76b3bf7654c3c94554c24ba15a3d105f4006c80 upstream.
On Dell WD15 dock, sometimes USB ethernet cannot be detected after plugging cable to the ethernet port, the hub and roothub get runtime resumed and runtime suspended immediately: ... [ 433.315169] xhci_hcd 0000:3a:00.0: hcd_pci_runtime_resume: 0 [ 433.315204] usb usb4: usb auto-resume [ 433.315226] hub 4-0:1.0: hub_resume [ 433.315239] xhci_hcd 0000:3a:00.0: Get port status 4-1 read: 0x10202e2, return 0x10343 [ 433.315264] usb usb4-port1: status 0343 change 0001 [ 433.315279] xhci_hcd 0000:3a:00.0: clear port1 connect change, portsc: 0x10002e2 [ 433.315293] xhci_hcd 0000:3a:00.0: Get port status 4-2 read: 0x2a0, return 0x2a0 [ 433.317012] xhci_hcd 0000:3a:00.0: xhci_hub_status_data: stopping port polling. [ 433.422282] xhci_hcd 0000:3a:00.0: Get port status 4-1 read: 0x10002e2, return 0x343 [ 433.422307] usb usb4-port1: do warm reset [ 433.422311] usb 4-1: device reset not allowed in state 8 [ 433.422339] hub 4-0:1.0: state 7 ports 2 chg 0002 evt 0000 [ 433.422346] xhci_hcd 0000:3a:00.0: Get port status 4-1 read: 0x10002e2, return 0x343 [ 433.422356] usb usb4-port1: do warm reset [ 433.422358] usb 4-1: device reset not allowed in state 8 [ 433.422428] xhci_hcd 0000:3a:00.0: set port remote wake mask, actual port 0 status = 0xf0002e2 [ 433.422455] xhci_hcd 0000:3a:00.0: set port remote wake mask, actual port 1 status = 0xe0002a0 [ 433.422465] hub 4-0:1.0: hub_suspend [ 433.422475] usb usb4: bus auto-suspend, wakeup 1 [ 433.426161] xhci_hcd 0000:3a:00.0: xhci_hub_status_data: stopping port polling. [ 433.466209] xhci_hcd 0000:3a:00.0: port 0 polling in bus suspend, waiting [ 433.510204] xhci_hcd 0000:3a:00.0: port 0 polling in bus suspend, waiting [ 433.554051] xhci_hcd 0000:3a:00.0: port 0 polling in bus suspend, waiting [ 433.598235] xhci_hcd 0000:3a:00.0: port 0 polling in bus suspend, waiting [ 433.642154] xhci_hcd 0000:3a:00.0: port 0 polling in bus suspend, waiting [ 433.686204] xhci_hcd 0000:3a:00.0: port 0 polling in bus suspend, waiting [ 433.730205] xhci_hcd 0000:3a:00.0: port 0 polling in bus suspend, waiting [ 433.774203] xhci_hcd 0000:3a:00.0: port 0 polling in bus suspend, waiting [ 433.818207] xhci_hcd 0000:3a:00.0: port 0 polling in bus suspend, waiting [ 433.862040] xhci_hcd 0000:3a:00.0: port 0 polling in bus suspend, waiting [ 433.862053] xhci_hcd 0000:3a:00.0: xhci_hub_status_data: stopping port polling. [ 433.862077] xhci_hcd 0000:3a:00.0: xhci_suspend: stopping port polling. [ 433.862096] xhci_hcd 0000:3a:00.0: // Setting command ring address to 0x8578fc001 [ 433.862312] xhci_hcd 0000:3a:00.0: hcd_pci_runtime_suspend: 0 [ 433.862445] xhci_hcd 0000:3a:00.0: PME# enabled [ 433.902376] xhci_hcd 0000:3a:00.0: restoring config space at offset 0xc (was 0x0, writing 0x20) [ 433.902395] xhci_hcd 0000:3a:00.0: restoring config space at offset 0x4 (was 0x100000, writing 0x100403) [ 433.902490] xhci_hcd 0000:3a:00.0: PME# disabled [ 433.902504] xhci_hcd 0000:3a:00.0: enabling bus mastering [ 433.902547] xhci_hcd 0000:3a:00.0: // Setting command ring address to 0x8578fc001 [ 433.902649] pcieport 0000:00:1b.0: PME: Spurious native interrupt! [ 433.902839] xhci_hcd 0000:3a:00.0: Port change event, 4-1, id 3, portsc: 0xb0202e2 [ 433.902842] xhci_hcd 0000:3a:00.0: resume root hub [ 433.902845] xhci_hcd 0000:3a:00.0: handle_port_status: starting port polling. [ 433.902877] xhci_hcd 0000:3a:00.0: xhci_resume: starting port polling. [ 433.902889] xhci_hcd 0000:3a:00.0: xhci_hub_status_data: stopping port polling. [ 433.902891] xhci_hcd 0000:3a:00.0: hcd_pci_runtime_resume: 0 [ 433.902919] usb usb4: usb wakeup-resume [ 433.902942] usb usb4: usb auto-resume [ 433.902966] hub 4-0:1.0: hub_resume ...
As Mathias pointed out, the hub enters Cold Attach Status state and requires a warm reset. However usb_reset_device() bails out early when the device is in suspended state, as its callers port_event() and hub_event() don't always resume the device.
Since there's nothing wrong to reset a suspended device, allow usb_reset_device() to do so to solve the issue.
Signed-off-by: Kai-Heng Feng kai.heng.feng@canonical.com Acked-by: Alan Stern stern@rowland.harvard.edu Cc: stable stable@vger.kernel.org Link: https://lore.kernel.org/r/20191106062710.29880-1-kai.heng.feng@canonical.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/core/hub.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
--- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -5740,7 +5740,7 @@ re_enumerate_no_bos:
/** * usb_reset_device - warn interface drivers and perform a USB port reset - * @udev: device to reset (not in SUSPENDED or NOTATTACHED state) + * @udev: device to reset (not in NOTATTACHED state) * * Warns all drivers bound to registered interfaces (using their pre_reset * method), performs the port reset, and then lets the drivers know that @@ -5768,8 +5768,7 @@ int usb_reset_device(struct usb_device * struct usb_host_config *config = udev->actconfig; struct usb_hub *hub = usb_hub_to_struct_hub(udev->parent);
- if (udev->state == USB_STATE_NOTATTACHED || - udev->state == USB_STATE_SUSPENDED) { + if (udev->state == USB_STATE_NOTATTACHED) { dev_dbg(&udev->dev, "device reset not allowed in state %d\n", udev->state); return -EINVAL;
From: Johan Hovold johan@kernel.org
commit 74ca34118a0e05793935d804ccffcedd6eb56596 upstream.
Make sure to use the current alternate setting when verifying the interface descriptors to avoid binding to an invalid interface.
Failing to do so could cause the driver to misbehave or trigger a WARN() in usb_submit_urb() that kernels with panic_on_warn set would choke on.
Fixes: c2478d39076b ("staging: r8188eu: Add files for new driver - part 20") Cc: stable stable@vger.kernel.org # 3.12 Signed-off-by: Johan Hovold johan@kernel.org Link: https://lore.kernel.org/r/20191210114751.5119-2-johan@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/staging/rtl8188eu/os_dep/usb_intf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/staging/rtl8188eu/os_dep/usb_intf.c +++ b/drivers/staging/rtl8188eu/os_dep/usb_intf.c @@ -70,7 +70,7 @@ static struct dvobj_priv *usb_dvobj_init phost_conf = pusbd->actconfig; pconf_desc = &phost_conf->desc;
- phost_iface = &usb_intf->altsetting[0]; + phost_iface = usb_intf->cur_altsetting; piface_desc = &phost_iface->desc;
pdvobjpriv->NumInterfaces = pconf_desc->bNumInterfaces;
From: Johan Hovold johan@kernel.org
commit c724f776f048538ecfdf53a52b7a522309f5c504 upstream.
Make sure to use the current alternate setting when verifying the interface descriptors to avoid binding to an invalid interface.
Failing to do so could cause the driver to misbehave or trigger a WARN() in usb_submit_urb() that kernels with panic_on_warn set would choke on.
Fixes: 2865d42c78a9 ("staging: r8712u: Add the new driver to the mainline kernel") Cc: stable stable@vger.kernel.org # 2.6.37 Signed-off-by: Johan Hovold johan@kernel.org Link: https://lore.kernel.org/r/20191210114751.5119-3-johan@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/staging/rtl8712/usb_intf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/staging/rtl8712/usb_intf.c +++ b/drivers/staging/rtl8712/usb_intf.c @@ -275,7 +275,7 @@ static uint r8712_usb_dvobj_init(struct
pdvobjpriv->padapter = padapter; padapter->EepromAddressSize = 6; - phost_iface = &pintf->altsetting[0]; + phost_iface = pintf->cur_altsetting; piface_desc = &phost_iface->desc; pdvobjpriv->nr_endpoint = piface_desc->bNumEndpoints; if (pusbd->speed == USB_SPEED_HIGH) {
From: Johan Hovold johan@kernel.org
commit 53f35a39c3860baac1e5ca80bf052751cfb24a99 upstream.
Fix a general protection fault when accessing the endpoint descriptors which could be triggered by a malicious device due to missing sanity checks on the number of endpoints.
Reported-by: syzbot+35b1c403a14f5c89eba7@syzkaller.appspotmail.com Fixes: 07dc1f9f2f80 ("[PATCH] isdn4linux: Siemens Gigaset drivers - M105 USB DECT adapter") Cc: stable stable@vger.kernel.org # 2.6.17 Cc: Hansjoerg Lipp hjlipp@web.de Cc: Tilman Schmidt tilman@imap.cc Signed-off-by: Johan Hovold johan@kernel.org Link: https://lore.kernel.org/r/20191202085610.12719-2-johan@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/isdn/gigaset/usb-gigaset.c | 5 +++++ 1 file changed, 5 insertions(+)
--- a/drivers/isdn/gigaset/usb-gigaset.c +++ b/drivers/isdn/gigaset/usb-gigaset.c @@ -688,6 +688,11 @@ static int gigaset_probe(struct usb_inte return -ENODEV; }
+ if (hostif->desc.bNumEndpoints < 2) { + dev_err(&interface->dev, "missing endpoints\n"); + return -ENODEV; + } + dev_info(&udev->dev, "%s: Device matched ... !\n", __func__);
/* allocate memory for our device state and initialize it */
From: Johan Hovold johan@kernel.org
commit 84f60ca7b326ed8c08582417493982fe2573a9ad upstream.
The driver failed to initialise its receive-buffer pointer, something which could lead to an illegal free on late probe errors.
Fix this by making sure to clear all driver data at allocation.
Fixes: 2032e2c2309d ("usb_gigaset: code cleanup") Cc: stable stable@vger.kernel.org # 2.6.33 Cc: Tilman Schmidt tilman@imap.cc Signed-off-by: Johan Hovold johan@kernel.org Link: https://lore.kernel.org/r/20191202085610.12719-3-johan@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/isdn/gigaset/usb-gigaset.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)
--- a/drivers/isdn/gigaset/usb-gigaset.c +++ b/drivers/isdn/gigaset/usb-gigaset.c @@ -574,8 +574,7 @@ static int gigaset_initcshw(struct cards { struct usb_cardstate *ucs;
- cs->hw.usb = ucs = - kmalloc(sizeof(struct usb_cardstate), GFP_KERNEL); + cs->hw.usb = ucs = kzalloc(sizeof(struct usb_cardstate), GFP_KERNEL); if (!ucs) { pr_err("out of memory\n"); return -ENOMEM; @@ -587,9 +586,6 @@ static int gigaset_initcshw(struct cards ucs->bchars[3] = 0; ucs->bchars[4] = 0x11; ucs->bchars[5] = 0x13; - ucs->bulk_out_buffer = NULL; - ucs->bulk_out_urb = NULL; - ucs->read_urb = NULL; tasklet_init(&cs->write_tasklet, gigaset_modem_fill, (unsigned long) cs);
From: Johan Hovold johan@kernel.org
commit ed9ed5a89acba51b82bdff61144d4e4a4245ec8a upstream.
Add missing endpoint-type sanity checks to probe.
This specifically prevents a warning in USB core on URB submission when fuzzing USB descriptors.
Signed-off-by: Johan Hovold johan@kernel.org Cc: stable stable@vger.kernel.org Link: https://lore.kernel.org/r/20191202085610.12719-4-johan@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/isdn/gigaset/usb-gigaset.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
--- a/drivers/isdn/gigaset/usb-gigaset.c +++ b/drivers/isdn/gigaset/usb-gigaset.c @@ -708,6 +708,12 @@ static int gigaset_probe(struct usb_inte
endpoint = &hostif->endpoint[0].desc;
+ if (!usb_endpoint_is_bulk_out(endpoint)) { + dev_err(&interface->dev, "missing bulk-out endpoint\n"); + retval = -ENODEV; + goto error; + } + buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); ucs->bulk_out_size = buffer_size; ucs->bulk_out_epnum = usb_endpoint_num(endpoint); @@ -727,6 +733,12 @@ static int gigaset_probe(struct usb_inte
endpoint = &hostif->endpoint[1].desc;
+ if (!usb_endpoint_is_int_in(endpoint)) { + dev_err(&interface->dev, "missing int-in endpoint\n"); + retval = -ENODEV; + goto error; + } + ucs->busy = 0;
ucs->read_urb = usb_alloc_urb(0, GFP_KERNEL);
From: Henry Lin henryl@nvidia.com
commit f2c710f7dca8457e88b4ac9de2060f011254f9dd upstream.
Xhci driver cannot call pci_set_power_state() on non-pci xhci host controllers. For example, NVIDIA Tegra XHCI host controller which acts as platform device with XHCI_SPURIOUS_WAKEUP quirk set in some platform hits this issue during shutdown.
Cc: stable@vger.kernel.org Fixes: 638298dc66ea ("xhci: Fix spurious wakeups after S5 on Haswell") Signed-off-by: Henry Lin henryl@nvidia.com Signed-off-by: Mathias Nyman mathias.nyman@linux.intel.com Link: https://lore.kernel.org/r/20191211142007.8847-4-mathias.nyman@linux.intel.co... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/host/xhci-pci.c | 13 +++++++++++++ drivers/usb/host/xhci.c | 7 ++----- drivers/usb/host/xhci.h | 1 + 3 files changed, 16 insertions(+), 5 deletions(-)
--- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -495,6 +495,18 @@ static int xhci_pci_resume(struct usb_hc } #endif /* CONFIG_PM */
+static void xhci_pci_shutdown(struct usb_hcd *hcd) +{ + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + struct pci_dev *pdev = to_pci_dev(hcd->self.controller); + + xhci_shutdown(hcd); + + /* Yet another workaround for spurious wakeups at shutdown with HSW */ + if (xhci->quirks & XHCI_SPURIOUS_WAKEUP) + pci_set_power_state(pdev, PCI_D3hot); +} + /*-------------------------------------------------------------------------*/
/* PCI driver selection metadata; PCI hotplugging uses this */ @@ -530,6 +542,7 @@ static int __init xhci_pci_init(void) #ifdef CONFIG_PM xhci_pci_hc_driver.pci_suspend = xhci_pci_suspend; xhci_pci_hc_driver.pci_resume = xhci_pci_resume; + xhci_pci_hc_driver.shutdown = xhci_pci_shutdown; #endif return pci_register_driver(&xhci_pci_driver); } --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -769,7 +769,7 @@ static void xhci_stop(struct usb_hcd *hc * * This will only ever be called with the main usb_hcd (the USB3 roothub). */ -static void xhci_shutdown(struct usb_hcd *hcd) +void xhci_shutdown(struct usb_hcd *hcd) { struct xhci_hcd *xhci = hcd_to_xhci(hcd);
@@ -788,11 +788,8 @@ static void xhci_shutdown(struct usb_hcd xhci_dbg_trace(xhci, trace_xhci_dbg_init, "xhci_shutdown completed - status = %x", readl(&xhci->op_regs->status)); - - /* Yet another workaround for spurious wakeups at shutdown with HSW */ - if (xhci->quirks & XHCI_SPURIOUS_WAKEUP) - pci_set_power_state(to_pci_dev(hcd->self.sysdev), PCI_D3hot); } +EXPORT_SYMBOL_GPL(xhci_shutdown);
#ifdef CONFIG_PM static void xhci_save_registers(struct xhci_hcd *xhci) --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -2052,6 +2052,7 @@ int xhci_start(struct xhci_hcd *xhci); int xhci_reset(struct xhci_hcd *xhci); int xhci_run(struct usb_hcd *hcd); int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks); +void xhci_shutdown(struct usb_hcd *hcd); void xhci_init_driver(struct hc_driver *drv, const struct xhci_driver_overrides *over); int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id);
From: Mika Westerberg mika.westerberg@linux.intel.com
commit ce91f1a43b37463f517155bdfbd525eb43adbd1a upstream.
When xHCI is part of Alpine or Titan Ridge Thunderbolt controller and the xHCI device is hot-removed as a result of unplugging a dock for example, the driver leaks memory it allocates for xhci->usb3_rhub.psi and xhci->usb2_rhub.psi in xhci_add_in_port() as reported by kmemleak:
unreferenced object 0xffff922c24ef42f0 (size 16): comm "kworker/u16:2", pid 178, jiffies 4294711640 (age 956.620s) hex dump (first 16 bytes): 21 00 0c 00 12 00 dc 05 23 00 e0 01 00 00 00 00 !.......#....... backtrace: [<000000007ac80914>] xhci_mem_init+0xcf8/0xeb7 [<0000000001b6d775>] xhci_init+0x7c/0x160 [<00000000db443fe3>] xhci_gen_setup+0x214/0x340 [<00000000fdffd320>] xhci_pci_setup+0x48/0x110 [<00000000541e1e03>] usb_add_hcd.cold+0x265/0x747 [<00000000ca47a56b>] usb_hcd_pci_probe+0x219/0x3b4 [<0000000021043861>] xhci_pci_probe+0x24/0x1c0 [<00000000b9231f25>] local_pci_probe+0x3d/0x70 [<000000006385c9d7>] pci_device_probe+0xd0/0x150 [<0000000070241068>] really_probe+0xf5/0x3c0 [<0000000061f35c0a>] driver_probe_device+0x58/0x100 [<000000009da11198>] bus_for_each_drv+0x79/0xc0 [<000000009ce45f69>] __device_attach+0xda/0x160 [<00000000df201aaf>] pci_bus_add_device+0x46/0x70 [<0000000088a1bc48>] pci_bus_add_devices+0x27/0x60 [<00000000ad9ee708>] pci_bus_add_devices+0x52/0x60 unreferenced object 0xffff922c24ef3318 (size 8): comm "kworker/u16:2", pid 178, jiffies 4294711640 (age 956.620s) hex dump (first 8 bytes): 34 01 05 00 35 41 0a 00 4...5A.. backtrace: [<000000007ac80914>] xhci_mem_init+0xcf8/0xeb7 [<0000000001b6d775>] xhci_init+0x7c/0x160 [<00000000db443fe3>] xhci_gen_setup+0x214/0x340 [<00000000fdffd320>] xhci_pci_setup+0x48/0x110 [<00000000541e1e03>] usb_add_hcd.cold+0x265/0x747 [<00000000ca47a56b>] usb_hcd_pci_probe+0x219/0x3b4 [<0000000021043861>] xhci_pci_probe+0x24/0x1c0 [<00000000b9231f25>] local_pci_probe+0x3d/0x70 [<000000006385c9d7>] pci_device_probe+0xd0/0x150 [<0000000070241068>] really_probe+0xf5/0x3c0 [<0000000061f35c0a>] driver_probe_device+0x58/0x100 [<000000009da11198>] bus_for_each_drv+0x79/0xc0 [<000000009ce45f69>] __device_attach+0xda/0x160 [<00000000df201aaf>] pci_bus_add_device+0x46/0x70 [<0000000088a1bc48>] pci_bus_add_devices+0x27/0x60 [<00000000ad9ee708>] pci_bus_add_devices+0x52/0x60
Fix this by calling kfree() for the both psi objects in xhci_mem_cleanup().
Cc: stable@vger.kernel.org # 4.4+ Fixes: 47189098f8be ("xhci: parse xhci protocol speed ID list for usb 3.1 usage") Signed-off-by: Mika Westerberg mika.westerberg@linux.intel.com Signed-off-by: Mathias Nyman mathias.nyman@linux.intel.com Link: https://lore.kernel.org/r/20191211142007.8847-2-mathias.nyman@linux.intel.co... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/host/xhci-mem.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -1909,13 +1909,17 @@ no_bw: xhci->usb3_rhub.num_ports = 0; xhci->num_active_eps = 0; kfree(xhci->usb2_rhub.ports); + kfree(xhci->usb2_rhub.psi); kfree(xhci->usb3_rhub.ports); + kfree(xhci->usb3_rhub.psi); kfree(xhci->hw_ports); kfree(xhci->rh_bw); kfree(xhci->ext_caps);
xhci->usb2_rhub.ports = NULL; + xhci->usb2_rhub.psi = NULL; xhci->usb3_rhub.ports = NULL; + xhci->usb3_rhub.psi = NULL; xhci->hw_ports = NULL; xhci->rh_bw = NULL; xhci->ext_caps = NULL;
From: Kai-Heng Feng kai.heng.feng@canonical.com
commit 7c67cf6658cec70d8a43229f2ce74ca1443dc95e upstream.
I've recently observed failed xHCI suspend attempt on AMD Raven Ridge system: kernel: xhci_hcd 0000:04:00.4: WARN: xHC CMD_RUN timeout kernel: PM: suspend_common(): xhci_pci_suspend+0x0/0xd0 returns -110 kernel: PM: pci_pm_suspend(): hcd_pci_suspend+0x0/0x30 returns -110 kernel: PM: dpm_run_callback(): pci_pm_suspend+0x0/0x150 returns -110 kernel: PM: Device 0000:04:00.4 failed to suspend async: error -110
Similar to commit ac343366846a ("xhci: Increase STS_SAVE timeout in xhci_suspend()") we also need to increase the HALT timeout to make it be able to suspend again.
Cc: stable@vger.kernel.org # 5.2+ Fixes: f7fac17ca925 ("xhci: Convert xhci_handshake() to use readl_poll_timeout_atomic()") Signed-off-by: Kai-Heng Feng kai.heng.feng@canonical.com Signed-off-by: Mathias Nyman mathias.nyman@linux.intel.com Link: https://lore.kernel.org/r/20191211142007.8847-5-mathias.nyman@linux.intel.co... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/host/xhci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -960,7 +960,7 @@ static bool xhci_pending_portevent(struc int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup) { int rc = 0; - unsigned int delay = XHCI_MAX_HALT_USEC; + unsigned int delay = XHCI_MAX_HALT_USEC * 2; struct usb_hcd *hcd = xhci_to_hcd(xhci); u32 command; u32 res;
From: Mathias Nyman mathias.nyman@linux.intel.com
commit 7ff11162808cc2ec66353fc012c58bb449c892c3 upstream.
xhci driver claims it needs XHCI_TRUST_TX_LENGTH quirk for both Broadcom/Cavium and a Renesas xHC controllers.
The quirk was inteded for handling false "success" complete event for transfers that had data left untransferred. These transfers should complete with "short packet" events instead.
In these two new cases the false "success" completion is reported after a "short packet" if the TD consists of several TRBs. xHCI specs 4.10.1.1.2 say remaining TRBs should report "short packet" as well after the first short packet in a TD, but this issue seems so common it doesn't make sense to add the quirk for all vendors.
Turn these events into short packets automatically instead.
This gets rid of the "The WARN Successful completion on short TX for slot 1 ep 1: needs XHCI_TRUST_TX_LENGTH quirk" warning in many cases.
Cc: stable@vger.kernel.org Reported-by: Eli Billauer eli.billauer@gmail.com Reported-by: Ard Biesheuvel ardb@kernel.org Tested-by: Eli Billauer eli.billauer@gmail.com Tested-by: Ard Biesheuvel ardb@kernel.org Signed-off-by: Mathias Nyman mathias.nyman@linux.intel.com Link: https://lore.kernel.org/r/20191211142007.8847-6-mathias.nyman@linux.intel.co... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/host/xhci-ring.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2330,7 +2330,8 @@ static int handle_tx_event(struct xhci_h case COMP_SUCCESS: if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) == 0) break; - if (xhci->quirks & XHCI_TRUST_TX_LENGTH) + if (xhci->quirks & XHCI_TRUST_TX_LENGTH || + ep_ring->last_td_was_short) trb_comp_code = COMP_SHORT_PACKET; else xhci_warn_ratelimited(xhci,
From: H. Nikolaus Schaller hns@goldelico.com
commit 4f9007d692017cef38baf2a9b82b7879d5b2407b upstream.
Since v4.7 the dma initialization requires that there is a device tree property for "rx" and "tx" channels which is not provided by the pdata-quirks initialization.
By conversion of the mmc3 setup to device tree this will finally allows to remove the OpenPandora wlan specific omap3 data-quirks.
Fixes: 81eef6ca9201 ("mmc: omap_hsmmc: Use dma_request_chan() for requesting DMA channel") Signed-off-by: H. Nikolaus Schaller hns@goldelico.com Cc: stable@vger.kernel.org # v4.7+ Acked-by: Tony Lindgren tony@atomide.com Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/arm/boot/dts/omap3-pandora-common.dtsi | 36 ++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-)
--- a/arch/arm/boot/dts/omap3-pandora-common.dtsi +++ b/arch/arm/boot/dts/omap3-pandora-common.dtsi @@ -229,6 +229,17 @@ gpio = <&gpio6 4 GPIO_ACTIVE_HIGH>; /* GPIO_164 */ };
+ /* wl1251 wifi+bt module */ + wlan_en: fixed-regulator-wg7210_en { + compatible = "regulator-fixed"; + regulator-name = "vwlan"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + startup-delay-us = <50000>; + enable-active-high; + gpio = <&gpio1 23 GPIO_ACTIVE_HIGH>; + }; + /* wg7210 (wifi+bt module) 32k clock buffer */ wg7210_32k: fixed-regulator-wg7210_32k { compatible = "regulator-fixed"; @@ -525,9 +536,30 @@ /*wp-gpios = <&gpio4 31 GPIO_ACTIVE_HIGH>;*/ /* GPIO_127 */ };
-/* mmc3 is probed using pdata-quirks to pass wl1251 card data */ &mmc3 { - status = "disabled"; + vmmc-supply = <&wlan_en>; + + bus-width = <4>; + non-removable; + ti,non-removable; + cap-power-off-card; + + pinctrl-names = "default"; + pinctrl-0 = <&mmc3_pins>; + + #address-cells = <1>; + #size-cells = <0>; + + wlan: wifi@1 { + compatible = "ti,wl1251"; + + reg = <1>; + + interrupt-parent = <&gpio1>; + interrupts = <21 IRQ_TYPE_LEVEL_HIGH>; /* GPIO_21 */ + + ti,wl1251-has-eeprom; + }; };
/* bluetooth*/
From: Nuno Sá nuno.sa@analog.com
commit 4c35b7a51e2f291471f7221d112c6a45c63e83bc upstream.
The driver is defining debugfs entries by calling `adis16480_debugfs_init()`. However, those entries are attached to the iio_dev debugfs entry which won't exist if no debugfs_reg_access callback is provided.
Fixes: 2f3abe6cbb6c ("iio:imu: Add support for the ADIS16480 and similar IMUs") Signed-off-by: Nuno Sá nuno.sa@analog.com Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/iio/imu/adis16480.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/iio/imu/adis16480.c +++ b/drivers/iio/imu/adis16480.c @@ -727,6 +727,7 @@ static const struct iio_info adis16480_i .read_raw = &adis16480_read_raw, .write_raw = &adis16480_write_raw, .update_scan_mode = adis_update_scan_mode, + .debugfs_reg_access = adis_debugfs_reg_access, };
static int adis16480_stop_device(struct iio_dev *indio_dev)
From: Chris Lesiak chris.lesiak@licor.com
commit 342a6928bd5017edbdae376042d8ad6af3d3b943 upstream.
The IIO_HUMIDITYRELATIVE channel was being incorrectly reported back as percent when it should have been milli percent. This is via an incorrect scale value being returned to userspace.
Signed-off-by: Chris Lesiak chris.lesiak@licor.com Acked-by: Matt Ranostay matt.ranostay@konsulko.com Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/iio/humidity/hdc100x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/iio/humidity/hdc100x.c +++ b/drivers/iio/humidity/hdc100x.c @@ -229,7 +229,7 @@ static int hdc100x_read_raw(struct iio_d *val2 = 65536; return IIO_VAL_FRACTIONAL; } else { - *val = 100; + *val = 100000; *val2 = 65536; return IIO_VAL_FRACTIONAL; }
From: Jean-Baptiste Maneyrol jmaneyrol@invensense.com
commit 53eaa9c27fdc01b4f4d885223e29f97393409e7e upstream.
Temperature should be reported in milli-degrees, not degrees. Fix scale and offset values to use the correct unit.
This is a fix for an issue that has been present for a long time. The fixes tag reflects the point at which the code last changed in a fashion that would make this fix patch no longer apply. Backports will be necessary to fix those elements that predate that patch.
Fixes: 1615fe41a195 ("iio: imu: mpu6050: Fix FIFO layout for ICM20602") Cc: stable@vger.kernel.org Signed-off-by: Jean-Baptiste Maneyrol jmaneyrol@invensense.com Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/iio/imu/inv_mpu6050/inv_mpu_core.c | 23 ++++++++++++----------- drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | 16 ++++++++++++---- 2 files changed, 24 insertions(+), 15 deletions(-)
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c @@ -122,6 +122,7 @@ static const struct inv_mpu6050_hw hw_in .reg = ®_set_6050, .config = &chip_config_6050, .fifo_size = 1024, + .temp = {INV_MPU6050_TEMP_OFFSET, INV_MPU6050_TEMP_SCALE}, }, { .whoami = INV_MPU6500_WHOAMI_VALUE, @@ -129,6 +130,7 @@ static const struct inv_mpu6050_hw hw_in .reg = ®_set_6500, .config = &chip_config_6050, .fifo_size = 512, + .temp = {INV_MPU6500_TEMP_OFFSET, INV_MPU6500_TEMP_SCALE}, }, { .whoami = INV_MPU6515_WHOAMI_VALUE, @@ -136,6 +138,7 @@ static const struct inv_mpu6050_hw hw_in .reg = ®_set_6500, .config = &chip_config_6050, .fifo_size = 512, + .temp = {INV_MPU6500_TEMP_OFFSET, INV_MPU6500_TEMP_SCALE}, }, { .whoami = INV_MPU6000_WHOAMI_VALUE, @@ -143,6 +146,7 @@ static const struct inv_mpu6050_hw hw_in .reg = ®_set_6050, .config = &chip_config_6050, .fifo_size = 1024, + .temp = {INV_MPU6050_TEMP_OFFSET, INV_MPU6050_TEMP_SCALE}, }, { .whoami = INV_MPU9150_WHOAMI_VALUE, @@ -150,6 +154,7 @@ static const struct inv_mpu6050_hw hw_in .reg = ®_set_6050, .config = &chip_config_6050, .fifo_size = 1024, + .temp = {INV_MPU6050_TEMP_OFFSET, INV_MPU6050_TEMP_SCALE}, }, { .whoami = INV_MPU9250_WHOAMI_VALUE, @@ -157,6 +162,7 @@ static const struct inv_mpu6050_hw hw_in .reg = ®_set_6500, .config = &chip_config_6050, .fifo_size = 512, + .temp = {INV_MPU6500_TEMP_OFFSET, INV_MPU6500_TEMP_SCALE}, }, { .whoami = INV_MPU9255_WHOAMI_VALUE, @@ -164,6 +170,7 @@ static const struct inv_mpu6050_hw hw_in .reg = ®_set_6500, .config = &chip_config_6050, .fifo_size = 512, + .temp = {INV_MPU6500_TEMP_OFFSET, INV_MPU6500_TEMP_SCALE}, }, { .whoami = INV_ICM20608_WHOAMI_VALUE, @@ -171,6 +178,7 @@ static const struct inv_mpu6050_hw hw_in .reg = ®_set_6500, .config = &chip_config_6050, .fifo_size = 512, + .temp = {INV_ICM20608_TEMP_OFFSET, INV_ICM20608_TEMP_SCALE}, }, { .whoami = INV_ICM20602_WHOAMI_VALUE, @@ -178,6 +186,7 @@ static const struct inv_mpu6050_hw hw_in .reg = ®_set_icm20602, .config = &chip_config_6050, .fifo_size = 1008, + .temp = {INV_ICM20608_TEMP_OFFSET, INV_ICM20608_TEMP_SCALE}, }, };
@@ -478,12 +487,8 @@ inv_mpu6050_read_raw(struct iio_dev *ind
return IIO_VAL_INT_PLUS_MICRO; case IIO_TEMP: - *val = 0; - if (st->chip_type == INV_ICM20602) - *val2 = INV_ICM20602_TEMP_SCALE; - else - *val2 = INV_MPU6050_TEMP_SCALE; - + *val = st->hw->temp.scale / 1000000; + *val2 = st->hw->temp.scale % 1000000; return IIO_VAL_INT_PLUS_MICRO; default: return -EINVAL; @@ -491,11 +496,7 @@ inv_mpu6050_read_raw(struct iio_dev *ind case IIO_CHAN_INFO_OFFSET: switch (chan->type) { case IIO_TEMP: - if (st->chip_type == INV_ICM20602) - *val = INV_ICM20602_TEMP_OFFSET; - else - *val = INV_MPU6050_TEMP_OFFSET; - + *val = st->hw->temp.offset; return IIO_VAL_INT; default: return -EINVAL; --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h @@ -109,6 +109,7 @@ struct inv_mpu6050_chip_config { * @reg: register map of the chip. * @config: configuration of the chip. * @fifo_size: size of the FIFO in bytes. + * @temp: offset and scale to apply to raw temperature. */ struct inv_mpu6050_hw { u8 whoami; @@ -116,6 +117,10 @@ struct inv_mpu6050_hw { const struct inv_mpu6050_reg_map *reg; const struct inv_mpu6050_chip_config *config; size_t fifo_size; + struct { + int offset; + int scale; + } temp; };
/* @@ -224,16 +229,19 @@ struct inv_mpu6050_state { #define INV_MPU6050_REG_UP_TIME_MIN 5000 #define INV_MPU6050_REG_UP_TIME_MAX 10000
-#define INV_MPU6050_TEMP_OFFSET 12421 -#define INV_MPU6050_TEMP_SCALE 2941 +#define INV_MPU6050_TEMP_OFFSET 12420 +#define INV_MPU6050_TEMP_SCALE 2941176 #define INV_MPU6050_MAX_GYRO_FS_PARAM 3 #define INV_MPU6050_MAX_ACCL_FS_PARAM 3 #define INV_MPU6050_THREE_AXIS 3 #define INV_MPU6050_GYRO_CONFIG_FSR_SHIFT 3 #define INV_MPU6050_ACCL_CONFIG_FSR_SHIFT 3
-#define INV_ICM20602_TEMP_OFFSET 8170 -#define INV_ICM20602_TEMP_SCALE 3060 +#define INV_MPU6500_TEMP_OFFSET 7011 +#define INV_MPU6500_TEMP_SCALE 2995178 + +#define INV_ICM20608_TEMP_OFFSET 8170 +#define INV_ICM20608_TEMP_SCALE 3059976
/* 6 + 6 round up and plus 8 */ #define INV_MPU6050_OUTPUT_DATA_SIZE 24
From: Johan Hovold johan@kernel.org
commit 09068c1ad53fb077bdac288869dec2435420bdc4 upstream.
Make sure that the interrupt interface has an endpoint before trying to access its endpoint descriptors to avoid dereferencing a NULL pointer.
The driver binds to the interrupt interface with interface number 0, but must not assume that this interface or its current alternate setting are the first entries in the corresponding configuration arrays.
Fixes: b72458a80c75 ("[PATCH] USB: Eagle and ADI 930 usb adsl modem driver") Cc: stable stable@vger.kernel.org # 2.6.16 Signed-off-by: Johan Hovold johan@kernel.org Link: https://lore.kernel.org/r/20191210112601.3561-2-johan@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/atm/ueagle-atm.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
--- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c @@ -2168,10 +2168,11 @@ resubmit: /* * Start the modem : init the data and start kernel thread */ -static int uea_boot(struct uea_softc *sc) +static int uea_boot(struct uea_softc *sc, struct usb_interface *intf) { - int ret, size; struct intr_pkt *intr; + int ret = -ENOMEM; + int size;
uea_enters(INS_TO_USBDEV(sc));
@@ -2196,6 +2197,11 @@ static int uea_boot(struct uea_softc *sc if (UEA_CHIP_VERSION(sc) == ADI930) load_XILINX_firmware(sc);
+ if (intf->cur_altsetting->desc.bNumEndpoints < 1) { + ret = -ENODEV; + goto err0; + } + intr = kmalloc(size, GFP_KERNEL); if (!intr) goto err0; @@ -2207,8 +2213,7 @@ static int uea_boot(struct uea_softc *sc usb_fill_int_urb(sc->urb_int, sc->usb_dev, usb_rcvintpipe(sc->usb_dev, UEA_INTR_PIPE), intr, size, uea_intr, sc, - sc->usb_dev->actconfig->interface[0]->altsetting[0]. - endpoint[0].desc.bInterval); + intf->cur_altsetting->endpoint[0].desc.bInterval);
ret = usb_submit_urb(sc->urb_int, GFP_KERNEL); if (ret < 0) { @@ -2223,6 +2228,7 @@ static int uea_boot(struct uea_softc *sc sc->kthread = kthread_create(uea_kthread, sc, "ueagle-atm"); if (IS_ERR(sc->kthread)) { uea_err(INS_TO_USBDEV(sc), "failed to create thread\n"); + ret = PTR_ERR(sc->kthread); goto err2; }
@@ -2237,7 +2243,7 @@ err1: kfree(intr); err0: uea_leaves(INS_TO_USBDEV(sc)); - return -ENOMEM; + return ret; }
/* @@ -2598,7 +2604,7 @@ static int uea_bind(struct usbatm_data * if (ret < 0) goto error;
- ret = uea_boot(sc); + ret = uea_boot(sc, intf); if (ret < 0) goto error_rm_grp;
From: Johan Hovold johan@kernel.org
commit 59920635b89d74b9207ea803d5e91498d39e8b69 upstream.
Make sure to use the current alternate setting when verifying the interface descriptors to avoid binding to an invalid interface.
Failing to do so could cause the driver to misbehave or trigger a WARN() in usb_submit_urb() that kernels with panic_on_warn set would choke on.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable stable@vger.kernel.org Signed-off-by: Johan Hovold johan@kernel.org Link: https://lore.kernel.org/r/20191210112601.3561-4-johan@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/misc/idmouse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/usb/misc/idmouse.c +++ b/drivers/usb/misc/idmouse.c @@ -337,7 +337,7 @@ static int idmouse_probe(struct usb_inte int result;
/* check if we have gotten the data or the hid interface */ - iface_desc = &interface->altsetting[0]; + iface_desc = interface->cur_altsetting; if (iface_desc->desc.bInterfaceClass != 0x0A) return -ENODEV;
From: Johan Hovold johan@kernel.org
commit 7c5a2df3367a2c4984f1300261345817d95b71f8 upstream.
Make sure to use the current alternate setting when looking up the endpoints on epic devices to avoid binding to an invalid interface.
Failing to do so could cause the driver to misbehave or trigger a WARN() in usb_submit_urb() that kernels with panic_on_warn set would choke on.
Fixes: 6e8cf7751f9f ("USB: add EPIC support to the io_edgeport driver") Cc: stable stable@vger.kernel.org # 2.6.21 Signed-off-by: Johan Hovold johan@kernel.org Link: https://lore.kernel.org/r/20191210112601.3561-5-johan@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/serial/io_edgeport.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
--- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c @@ -2919,16 +2919,18 @@ static int edge_startup(struct usb_seria response = 0;
if (edge_serial->is_epic) { + struct usb_host_interface *alt; + + alt = serial->interface->cur_altsetting; + /* EPIC thing, set up our interrupt polling now and our read * urb, so that the device knows it really is connected. */ interrupt_in_found = bulk_in_found = bulk_out_found = false; - for (i = 0; i < serial->interface->altsetting[0] - .desc.bNumEndpoints; ++i) { + for (i = 0; i < alt->desc.bNumEndpoints; ++i) { struct usb_endpoint_descriptor *endpoint; int buffer_size;
- endpoint = &serial->interface->altsetting[0]. - endpoint[i].desc; + endpoint = &alt->endpoint[i].desc; buffer_size = usb_endpoint_maxp(endpoint); if (!interrupt_in_found && (usb_endpoint_is_int_in(endpoint))) {
From: Wen Yang wenyang@linux.alibaba.com
commit 1848a543191ae32e558bb0a5974ae7c38ebd86fc upstream.
Free the sw structure only after we are done using it. This patch just moves the put_device() down a bit to avoid the use after free.
Fixes: 5c54fcac9a9d ("usb: roles: Take care of driver module reference counting") Signed-off-by: Wen Yang wenyang@linux.alibaba.com Reviewed-by: Heikki Krogerus heikki.krogerus@linux.intel.com Reviewed-by: Peter Chen peter.chen@nxp.com Cc: stable stable@vger.kernel.org Cc: Hans de Goede hdegoede@redhat.com Cc: Chunfeng Yun chunfeng.yun@mediatek.com Cc: Suzuki K Poulose suzuki.poulose@arm.com Cc: linux-usb@vger.kernel.org Cc: linux-kernel@vger.kernel.org Link: https://lore.kernel.org/r/20191124142236.25671-1-wenyang@linux.alibaba.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/roles/class.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/usb/roles/class.c +++ b/drivers/usb/roles/class.c @@ -130,8 +130,8 @@ EXPORT_SYMBOL_GPL(usb_role_switch_get); void usb_role_switch_put(struct usb_role_switch *sw) { if (!IS_ERR_OR_NULL(sw)) { - put_device(&sw->dev); module_put(sw->dev.parent->driver->owner); + put_device(&sw->dev); } } EXPORT_SYMBOL_GPL(usb_role_switch_put);
From: Johan Hovold johan@kernel.org
commit 3c11c4bed02b202e278c0f5c319ae435d7fb9815 upstream.
Make sure to use the current alternate setting when verifying the interface descriptors to avoid binding to an invalid interface.
Failing to do so could cause the driver to misbehave or trigger a WARN() in usb_submit_urb() that kernels with panic_on_warn set would choke on.
Fixes: 03270634e242 ("USB: Add ADU support for Ontrak ADU devices") Cc: stable stable@vger.kernel.org # 2.6.19 Signed-off-by: Johan Hovold johan@kernel.org Link: https://lore.kernel.org/r/20191210112601.3561-3-johan@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/misc/adutux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/usb/misc/adutux.c +++ b/drivers/usb/misc/adutux.c @@ -671,7 +671,7 @@ static int adu_probe(struct usb_interfac init_waitqueue_head(&dev->read_wait); init_waitqueue_head(&dev->write_wait);
- res = usb_find_common_endpoints_reverse(&interface->altsetting[0], + res = usb_find_common_endpoints_reverse(interface->cur_altsetting, NULL, NULL, &dev->interrupt_in_endpoint, &dev->interrupt_out_endpoint);
From: Emiliano Ingrassia ingrassia@epigenesys.com
commit 1cd17f7f0def31e3695501c4f86cd3faf8489840 upstream.
Explicitly initialize URB structure urb_list field in usb_init_urb(). This field can be potentially accessed uninitialized and its initialization is coherent with the usage of list_del_init() in usb_hcd_unlink_urb_from_ep() and usb_giveback_urb_bh() and its explicit initialization in usb_hcd_submit_urb() error path.
Signed-off-by: Emiliano Ingrassia ingrassia@epigenesys.com Cc: stable stable@vger.kernel.org Link: https://lore.kernel.org/r/20191127160355.GA27196@ingrassia.epigenesys.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/core/urb.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c @@ -45,6 +45,7 @@ void usb_init_urb(struct urb *urb) if (urb) { memset(urb, 0, sizeof(*urb)); kref_init(&urb->kref); + INIT_LIST_HEAD(&urb->urb_list); INIT_LIST_HEAD(&urb->anchor_list); } }
From: Pete Zaitcev zaitcev@redhat.com
commit 19e6317d24c25ee737c65d1ffb7483bdda4bb54a upstream.
The problem arises because our read() function grabs a lock of the circular buffer, finds something of interest, then invokes copy_to_user() straight from the buffer, which in turn takes mm->mmap_sem. In the same time, the callback mon_bin_vma_fault() is invoked under mm->mmap_sem. It attempts to take the fetch lock and deadlocks.
This patch does away with protecting of our page list with any semaphores, and instead relies on the kernel not close the device while mmap is active in a process.
In addition, we prohibit re-sizing of a buffer while mmap is active. This way, when (now unlocked) fault is processed, it works with the page that is intended to be mapped-in, and not some other random page. Note that this may have an ABI impact, but hopefully no legitimate program is this wrong.
Signed-off-by: Pete Zaitcev zaitcev@redhat.com Reported-by: syzbot+56f9673bb4cdcbeb0e92@syzkaller.appspotmail.com Reviewed-by: Alan Stern stern@rowland.harvard.edu Fixes: 46eb14a6e158 ("USB: fix usbmon BUG trigger") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20191204203941.3503452b@suzdal.zaitcev.lan Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/mon/mon_bin.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-)
--- a/drivers/usb/mon/mon_bin.c +++ b/drivers/usb/mon/mon_bin.c @@ -1039,12 +1039,18 @@ static long mon_bin_ioctl(struct file *f
mutex_lock(&rp->fetch_lock); spin_lock_irqsave(&rp->b_lock, flags); - mon_free_buff(rp->b_vec, rp->b_size/CHUNK_SIZE); - kfree(rp->b_vec); - rp->b_vec = vec; - rp->b_size = size; - rp->b_read = rp->b_in = rp->b_out = rp->b_cnt = 0; - rp->cnt_lost = 0; + if (rp->mmap_active) { + mon_free_buff(vec, size/CHUNK_SIZE); + kfree(vec); + ret = -EBUSY; + } else { + mon_free_buff(rp->b_vec, rp->b_size/CHUNK_SIZE); + kfree(rp->b_vec); + rp->b_vec = vec; + rp->b_size = size; + rp->b_read = rp->b_in = rp->b_out = rp->b_cnt = 0; + rp->cnt_lost = 0; + } spin_unlock_irqrestore(&rp->b_lock, flags); mutex_unlock(&rp->fetch_lock); } @@ -1216,13 +1222,21 @@ mon_bin_poll(struct file *file, struct p static void mon_bin_vma_open(struct vm_area_struct *vma) { struct mon_reader_bin *rp = vma->vm_private_data; + unsigned long flags; + + spin_lock_irqsave(&rp->b_lock, flags); rp->mmap_active++; + spin_unlock_irqrestore(&rp->b_lock, flags); }
static void mon_bin_vma_close(struct vm_area_struct *vma) { + unsigned long flags; + struct mon_reader_bin *rp = vma->vm_private_data; + spin_lock_irqsave(&rp->b_lock, flags); rp->mmap_active--; + spin_unlock_irqrestore(&rp->b_lock, flags); }
/* @@ -1234,16 +1248,12 @@ static vm_fault_t mon_bin_vma_fault(stru unsigned long offset, chunk_idx; struct page *pageptr;
- mutex_lock(&rp->fetch_lock); offset = vmf->pgoff << PAGE_SHIFT; - if (offset >= rp->b_size) { - mutex_unlock(&rp->fetch_lock); + if (offset >= rp->b_size) return VM_FAULT_SIGBUS; - } chunk_idx = offset / CHUNK_SIZE; pageptr = rp->b_vec[chunk_idx].pg; get_page(pageptr); - mutex_unlock(&rp->fetch_lock); vmf->page = pageptr; return 0; }
From: Tadeusz Struk tadeusz.struk@intel.com
commit f1689114acc5e89a196fec6d732dae3e48edb6ad upstream.
devm_kcalloc() can fail and return NULL so we need to check for that.
Cc: stable@vger.kernel.org Fixes: 58472f5cd4f6f ("tpm: validate TPM 2.0 commands") Signed-off-by: Tadeusz Struk tadeusz.struk@intel.com Reviewed-by: Jerry Snitselaar jsnitsel@redhat.com Reviewed-by: Jarkko Sakkinen jarkko.sakkinen@linux.intel.com Tested-by: Jarkko Sakkinen jarkko.sakkinen@linux.intel.com Signed-off-by: Jarkko Sakkinen jarkko.sakkinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/char/tpm/tpm2-cmd.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c @@ -938,6 +938,10 @@ static int tpm2_get_cc_attrs_tbl(struct
chip->cc_attrs_tbl = devm_kcalloc(&chip->dev, 4, nr_commands, GFP_KERNEL); + if (!chip->cc_attrs_tbl) { + rc = -ENOMEM; + goto out; + }
rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_GET_CAPABILITY); if (rc)
From: Miquel Raynal miquel.raynal@bootlin.com
commit 69c7f4618c16b4678f8a4949b6bb5ace259c0033 upstream.
Any write with either dd or flashcp to a device driven by the spear_smi.c driver will pass through the spear_smi_cpy_toio() function. This function will get called for chunks of up to 256 bytes. If the amount of data is smaller, we may have a problem if the data length is not 4-byte aligned. In this situation, the kernel panics during the memcpy:
# dd if=/dev/urandom bs=1001 count=1 of=/dev/mtd6 spear_smi_cpy_toio [620] dest c9070000, src c7be8800, len 256 spear_smi_cpy_toio [620] dest c9070100, src c7be8900, len 256 spear_smi_cpy_toio [620] dest c9070200, src c7be8a00, len 256 spear_smi_cpy_toio [620] dest c9070300, src c7be8b00, len 233 Unhandled fault: external abort on non-linefetch (0x808) at 0xc90703e8 [...] PC is at memcpy+0xcc/0x330
The above error occurs because the implementation of memcpy_toio() tries to optimize the number of I/O by writing 4 bytes at a time as much as possible, until there are less than 4 bytes left and then switches to word or byte writes.
Unfortunately, the specification states about the Write Burst mode:
"the next AHB Write request should point to the next incremented address and should have the same size (byte, half-word or word)"
This means ARM architecture implementation of memcpy_toio() cannot reliably be used blindly here. Workaround this situation by update the write path to stick to byte access when the burst length is not multiple of 4.
Fixes: f18dbbb1bfe0 ("mtd: ST SPEAr: Add SMI driver for serial NOR flash") Cc: Russell King linux@armlinux.org.uk Cc: Boris Brezillon boris.brezillon@collabora.com Cc: stable@vger.kernel.org Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Reviewed-by: Russell King rmk+kernel@armlinux.org.uk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/mtd/devices/spear_smi.c | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-)
--- a/drivers/mtd/devices/spear_smi.c +++ b/drivers/mtd/devices/spear_smi.c @@ -592,6 +592,26 @@ static int spear_mtd_read(struct mtd_inf return 0; }
+/* + * The purpose of this function is to ensure a memcpy_toio() with byte writes + * only. Its structure is inspired from the ARM implementation of _memcpy_toio() + * which also does single byte writes but cannot be used here as this is just an + * implementation detail and not part of the API. Not mentioning the comment + * stating that _memcpy_toio() should be optimized. + */ +static void spear_smi_memcpy_toio_b(volatile void __iomem *dest, + const void *src, size_t len) +{ + const unsigned char *from = src; + + while (len) { + len--; + writeb(*from, dest); + from++; + dest++; + } +} + static inline int spear_smi_cpy_toio(struct spear_smi *dev, u32 bank, void __iomem *dest, const void *src, size_t len) { @@ -614,7 +634,23 @@ static inline int spear_smi_cpy_toio(str ctrlreg1 = readl(dev->io_base + SMI_CR1); writel((ctrlreg1 | WB_MODE) & ~SW_MODE, dev->io_base + SMI_CR1);
- memcpy_toio(dest, src, len); + /* + * In Write Burst mode (WB_MODE), the specs states that writes must be: + * - incremental + * - of the same size + * The ARM implementation of memcpy_toio() will optimize the number of + * I/O by using as much 4-byte writes as possible, surrounded by + * 2-byte/1-byte access if: + * - the destination is not 4-byte aligned + * - the length is not a multiple of 4-byte. + * Avoid this alternance of write access size by using our own 'byte + * access' helper if at least one of the two conditions above is true. + */ + if (IS_ALIGNED(len, sizeof(u32)) && + IS_ALIGNED((uintptr_t)dest, sizeof(u32))) + memcpy_toio(dest, src, len); + else + spear_smi_memcpy_toio_b(dest, src, len);
writel(ctrlreg1, dev->io_base + SMI_CR1);
From: David Hildenbrand david@redhat.com
commit 63341ab03706e11a31e3dd8ccc0fbc9beaf723f0 upstream.
In case we have to migrate a ballon page to a newpage of another zone, the managed page count of both zones is wrong. Paired with memory offlining (which will adjust the managed page count), we can trigger kernel crashes and all kinds of different symptoms.
One way to reproduce: 1. Start a QEMU guest with 4GB, no NUMA 2. Hotplug a 1GB DIMM and online the memory to ZONE_NORMAL 3. Inflate the balloon to 1GB 4. Unplug the DIMM (be quick, otherwise unmovable data ends up on it) 5. Observe /proc/zoneinfo Node 0, zone Normal pages free 16810 min 24848885473806 low 18471592959183339 high 36918337032892872 spanned 262144 present 262144 managed 18446744073709533486 6. Do anything that requires some memory (e.g., inflate the balloon some more). The OOM goes crazy and the system crashes [ 238.324946] Out of memory: Killed process 537 (login) total-vm:27584kB, anon-rss:860kB, file-rss:0kB, shmem-rss:00 [ 238.338585] systemd invoked oom-killer: gfp_mask=0x100cca(GFP_HIGHUSER_MOVABLE), order=0, oom_score_adj=0 [ 238.339420] CPU: 0 PID: 1 Comm: systemd Tainted: G D W 5.4.0-next-20191204+ #75 [ 238.340139] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.0-59-gc9ba5276e321-prebuilt.qemu4 [ 238.341121] Call Trace: [ 238.341337] dump_stack+0x8f/0xd0 [ 238.341630] dump_header+0x61/0x5ea [ 238.341942] oom_kill_process.cold+0xb/0x10 [ 238.342299] out_of_memory+0x24d/0x5a0 [ 238.342625] __alloc_pages_slowpath+0xd12/0x1020 [ 238.343024] __alloc_pages_nodemask+0x391/0x410 [ 238.343407] pagecache_get_page+0xc3/0x3a0 [ 238.343757] filemap_fault+0x804/0xc30 [ 238.344083] ? ext4_filemap_fault+0x28/0x42 [ 238.344444] ext4_filemap_fault+0x30/0x42 [ 238.344789] __do_fault+0x37/0x1a0 [ 238.345087] __handle_mm_fault+0x104d/0x1ab0 [ 238.345450] handle_mm_fault+0x169/0x360 [ 238.345790] do_user_addr_fault+0x20d/0x490 [ 238.346154] do_page_fault+0x31/0x210 [ 238.346468] async_page_fault+0x43/0x50 [ 238.346797] RIP: 0033:0x7f47eba4197e [ 238.347110] Code: Bad RIP value. [ 238.347387] RSP: 002b:00007ffd7c0c1890 EFLAGS: 00010293 [ 238.347834] RAX: 0000000000000002 RBX: 000055d196a20a20 RCX: 00007f47eba4197e [ 238.348437] RDX: 0000000000000033 RSI: 00007ffd7c0c18c0 RDI: 0000000000000004 [ 238.349047] RBP: 00007ffd7c0c1c20 R08: 0000000000000000 R09: 0000000000000033 [ 238.349660] R10: 00000000ffffffff R11: 0000000000000293 R12: 0000000000000001 [ 238.350261] R13: ffffffffffffffff R14: 0000000000000000 R15: 00007ffd7c0c18c0 [ 238.350878] Mem-Info: [ 238.351085] active_anon:3121 inactive_anon:51 isolated_anon:0 [ 238.351085] active_file:12 inactive_file:7 isolated_file:0 [ 238.351085] unevictable:0 dirty:0 writeback:0 unstable:0 [ 238.351085] slab_reclaimable:5565 slab_unreclaimable:10170 [ 238.351085] mapped:3 shmem:111 pagetables:155 bounce:0 [ 238.351085] free:720717 free_pcp:2 free_cma:0 [ 238.353757] Node 0 active_anon:12484kB inactive_anon:204kB active_file:48kB inactive_file:28kB unevictable:0kB iss [ 238.355979] Node 0 DMA free:11556kB min:36kB low:48kB high:60kB reserved_highatomic:0KB active_anon:152kB inactivB [ 238.358345] lowmem_reserve[]: 0 2955 2884 2884 2884 [ 238.358761] Node 0 DMA32 free:2677864kB min:7004kB low:10028kB high:13052kB reserved_highatomic:0KB active_anon:0B [ 238.361202] lowmem_reserve[]: 0 0 72057594037927865 72057594037927865 72057594037927865 [ 238.361888] Node 0 Normal free:193448kB min:99395541895224kB low:73886371836733356kB high:147673348131571488kB reB [ 238.364765] lowmem_reserve[]: 0 0 0 0 0 [ 238.365101] Node 0 DMA: 7*4kB (U) 5*8kB (UE) 6*16kB (UME) 2*32kB (UM) 1*64kB (U) 2*128kB (UE) 3*256kB (UME) 2*512B [ 238.366379] Node 0 DMA32: 0*4kB 1*8kB (U) 2*16kB (UM) 2*32kB (UM) 2*64kB (UM) 1*128kB (U) 1*256kB (U) 1*512kB (U)B [ 238.367654] Node 0 Normal: 1985*4kB (UME) 1321*8kB (UME) 844*16kB (UME) 524*32kB (UME) 300*64kB (UME) 138*128kB (B [ 238.369184] Node 0 hugepages_total=0 hugepages_free=0 hugepages_surp=0 hugepages_size=2048kB [ 238.369915] 130 total pagecache pages [ 238.370241] 0 pages in swap cache [ 238.370533] Swap cache stats: add 0, delete 0, find 0/0 [ 238.370981] Free swap = 0kB [ 238.371239] Total swap = 0kB [ 238.371488] 1048445 pages RAM [ 238.371756] 0 pages HighMem/MovableOnly [ 238.372090] 306992 pages reserved [ 238.372376] 0 pages cma reserved [ 238.372661] 0 pages hwpoisoned
In another instance (older kernel), I was able to observe this (negative page count :/): [ 180.896971] Offlined Pages 32768 [ 182.667462] Offlined Pages 32768 [ 184.408117] Offlined Pages 32768 [ 186.026321] Offlined Pages 32768 [ 187.684861] Offlined Pages 32768 [ 189.227013] Offlined Pages 32768 [ 190.830303] Offlined Pages 32768 [ 190.833071] Built 1 zonelists, mobility grouping on. Total pages: -36920272750453009
In another instance (older kernel), I was no longer able to start any process: [root@vm ~]# [ 214.348068] Offlined Pages 32768 [ 215.973009] Offlined Pages 32768 cat /proc/meminfo -bash: fork: Cannot allocate memory [root@vm ~]# cat /proc/meminfo -bash: fork: Cannot allocate memory
Fix it by properly adjusting the managed page count when migrating if the zone changed. The managed page count of the zones now looks after unplug of the DIMM (and after deflating the balloon) just like before inflating the balloon (and plugging+onlining the DIMM).
We'll temporarily modify the totalram page count. If this ever becomes a problem, we can fine tune by providing helpers that don't touch the totalram pages (e.g., adjust_zone_managed_page_count()).
Please note that fixing up the managed page count is only necessary when we adjusted the managed page count when inflating - only if we don't have VIRTIO_BALLOON_F_DEFLATE_ON_OOM. With that feature, the managed page count is not touched when inflating/deflating.
Reported-by: Yumei Huang yuhuang@redhat.com Fixes: 3dcc0571cd64 ("mm: correctly update zone->managed_pages") Cc: stable@vger.kernel.org # v3.11+ Cc: "Michael S. Tsirkin" mst@redhat.com Cc: Jason Wang jasowang@redhat.com Cc: Jiang Liu liuj97@gmail.com Cc: Andrew Morton akpm@linux-foundation.org Cc: Igor Mammedov imammedo@redhat.com Cc: virtualization@lists.linux-foundation.org Signed-off-by: David Hildenbrand david@redhat.com Signed-off-by: Michael S. Tsirkin mst@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/virtio/virtio_balloon.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
--- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c @@ -468,6 +468,17 @@ static int virtballoon_migratepage(struc
get_page(newpage); /* balloon reference */
+ /* + * When we migrate a page to a different zone and adjusted the + * managed page count when inflating, we have to fixup the count of + * both involved zones. + */ + if (!virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_DEFLATE_ON_OOM) && + page_zone(page) != page_zone(newpage)) { + adjust_managed_page_count(page, 1); + adjust_managed_page_count(newpage, -1); + } + /* balloon's page migration 1st step -- inflate "newpage" */ spin_lock_irqsave(&vb_dev_info->pages_lock, flags); balloon_page_insert(vb_dev_info, newpage);
From: Heikki Krogerus heikki.krogerus@linux.intel.com
commit 3c3caae4cd6e122472efcf64759ff6392fb6bce2 upstream.
The original ID that was added for Comet Lake PCH was actually for the -LP (low power) variant even though the constant for it said CMLH. Changing that while at it.
Signed-off-by: Heikki Krogerus heikki.krogerus@linux.intel.com Acked-by: Felipe Balbi balbi@kernel.org Cc: stable stable@vger.kernel.org Link: https://lore.kernel.org/r/20191212093713.60614-1-heikki.krogerus@linux.intel... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/dwc3/dwc3-pci.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
--- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -29,7 +29,8 @@ #define PCI_DEVICE_ID_INTEL_BXT_M 0x1aaa #define PCI_DEVICE_ID_INTEL_APL 0x5aaa #define PCI_DEVICE_ID_INTEL_KBP 0xa2b0 -#define PCI_DEVICE_ID_INTEL_CMLH 0x02ee +#define PCI_DEVICE_ID_INTEL_CMLLP 0x02ee +#define PCI_DEVICE_ID_INTEL_CMLH 0x06ee #define PCI_DEVICE_ID_INTEL_GLK 0x31aa #define PCI_DEVICE_ID_INTEL_CNPLP 0x9dee #define PCI_DEVICE_ID_INTEL_CNPH 0xa36e @@ -306,6 +307,9 @@ static const struct pci_device_id dwc3_p { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_MRFLD), (kernel_ulong_t) &dwc3_pci_mrfld_properties, },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_CMLLP), + (kernel_ulong_t) &dwc3_pci_intel_properties, }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_CMLH), (kernel_ulong_t) &dwc3_pci_intel_properties, },
From: Tejas Joglekar Tejas.Joglekar@synopsys.com
commit 8c7d4b7b3d43c54c0b8c1e4adb917a151c754196 upstream.
This patch corrects the condition to kick the transfer without giving back the requests when either request has remaining data or when there are pending SGs. The && check was introduced during spliting up the dwc3_gadget_ep_cleanup_completed_requests() function.
Fixes: f38e35dd84e2 ("usb: dwc3: gadget: split dwc3_gadget_ep_cleanup_completed_requests()")
Cc: stable@vger.kernel.org Signed-off-by: Tejas Joglekar joglekar@synopsys.com Signed-off-by: Felipe Balbi balbi@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/dwc3/gadget.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2295,7 +2295,7 @@ static int dwc3_gadget_ep_cleanup_comple
req->request.actual = req->request.length - req->remaining;
- if (!dwc3_gadget_ep_request_completed(req) && + if (!dwc3_gadget_ep_request_completed(req) || req->num_pending_sgs) { __dwc3_gadget_kick_transfer(dep); goto out;
From: Thinh Nguyen Thinh.Nguyen@synopsys.com
commit 2d7b78f59e020b07fc6338eefe286f54ee2d6773 upstream.
Clear ep0's DWC3_EP_TRANSFER_STARTED flag if the END_TRANSFER command is completed. Otherwise, we can't start control transfer again after END_TRANSFER.
Cc: stable@vger.kernel.org Signed-off-by: Thinh Nguyen thinhn@synopsys.com Signed-off-by: Felipe Balbi balbi@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/dwc3/ep0.c | 8 ++++++++ 1 file changed, 8 insertions(+)
--- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -1110,6 +1110,9 @@ static void dwc3_ep0_xfernotready(struct void dwc3_ep0_interrupt(struct dwc3 *dwc, const struct dwc3_event_depevt *event) { + struct dwc3_ep *dep = dwc->eps[event->endpoint_number]; + u8 cmd; + switch (event->endpoint_event) { case DWC3_DEPEVT_XFERCOMPLETE: dwc3_ep0_xfer_complete(dwc, event); @@ -1122,7 +1125,12 @@ void dwc3_ep0_interrupt(struct dwc3 *dwc case DWC3_DEPEVT_XFERINPROGRESS: case DWC3_DEPEVT_RXTXFIFOEVT: case DWC3_DEPEVT_STREAMEVT: + break; case DWC3_DEPEVT_EPCMDCMPLT: + cmd = DEPEVT_PARAMETER_CMD(event->parameters); + + if (cmd == DWC3_DEPCMD_ENDTRANSFER) + dep->flags &= ~DWC3_EP_TRANSFER_STARTED; break; } }
From: Yoshihiro Shimoda yoshihiro.shimoda.uh@renesas.com
commit 4bd5ead82d4b877ebe41daf95f28cda53205b039 upstream.
Since the role_store() uses strncmp(), it's possible to refer out-of-memory if the sysfs data size is smaller than strlen("host"). This patch fixes it by using sysfs_streq() instead of strncmp().
Reported-by: Pavel Machek pavel@denx.de Fixes: 9bb86777fb71 ("phy: rcar-gen3-usb2: add sysfs for usb role swap") Cc: stable@vger.kernel.org # v4.10+ Signed-off-by: Yoshihiro Shimoda yoshihiro.shimoda.uh@renesas.com Reviewed-by: Geert Uytterhoeven geert+renesas@glider.be Acked-by: Pavel Machek pavel@denx.de Signed-off-by: Kishon Vijay Abraham I kishon@ti.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/phy/renesas/phy-rcar-gen3-usb2.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c +++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c @@ -23,6 +23,7 @@ #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/regulator/consumer.h> +#include <linux/string.h> #include <linux/usb/of.h> #include <linux/workqueue.h>
@@ -241,9 +242,9 @@ static ssize_t role_store(struct device if (!ch->has_otg_pins || !ch->phy->init_count) return -EIO;
- if (!strncmp(buf, "host", strlen("host"))) + if (sysfs_streq(buf, "host")) new_mode = PHY_MODE_USB_HOST; - else if (!strncmp(buf, "peripheral", strlen("peripheral"))) + else if (sysfs_streq(buf, "peripheral")) new_mode = PHY_MODE_USB_DEVICE; else return -EINVAL;
From: Josef Bacik josef@toxicpanda.com
commit 3797136b626ad4b6582223660c041efdea8f26b2 upstream.
While testing 5.2 we ran into the following panic
[52238.017028] BUG: kernel NULL pointer dereference, address: 0000000000000001 [52238.105608] RIP: 0010:drop_buffers+0x3d/0x150 [52238.304051] Call Trace: [52238.308958] try_to_free_buffers+0x15b/0x1b0 [52238.317503] shrink_page_list+0x1164/0x1780 [52238.325877] shrink_inactive_list+0x18f/0x3b0 [52238.334596] shrink_node_memcg+0x23e/0x7d0 [52238.342790] ? do_shrink_slab+0x4f/0x290 [52238.350648] shrink_node+0xce/0x4a0 [52238.357628] balance_pgdat+0x2c7/0x510 [52238.365135] kswapd+0x216/0x3e0 [52238.371425] ? wait_woken+0x80/0x80 [52238.378412] ? balance_pgdat+0x510/0x510 [52238.386265] kthread+0x111/0x130 [52238.392727] ? kthread_create_on_node+0x60/0x60 [52238.401782] ret_from_fork+0x1f/0x30
The page we were trying to drop had a page->private, but had no page->mapping and so called drop_buffers, assuming that we had a buffer_head on the page, and then panic'ed trying to deref 1, which is our page->private for data pages.
This is happening because we're truncating the free space cache while we're trying to load the free space cache. This isn't supposed to happen, and I'll fix that in a followup patch. However we still shouldn't allow those sort of mistakes to result in messing with pages that do not belong to us. So add the page->mapping check to verify that we still own this page after dropping and re-acquiring the page lock.
This page being unlocked as: btrfs_readpage extent_read_full_page __extent_read_full_page __do_readpage if (!nr) unlock_page <-- nr can be 0 only if submit_extent_page returns an error
CC: stable@vger.kernel.org # 4.4+ Reviewed-by: Filipe Manana fdmanana@suse.com Reviewed-by: Nikolay Borisov nborisov@suse.com Signed-off-by: Josef Bacik josef@toxicpanda.com [ add callchain ] Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/btrfs/free-space-cache.c | 6 ++++++ 1 file changed, 6 insertions(+)
--- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c @@ -382,6 +382,12 @@ static int io_ctl_prepare_pages(struct b if (uptodate && !PageUptodate(page)) { btrfs_readpage(NULL, page); lock_page(page); + if (page->mapping != inode->i_mapping) { + btrfs_err(BTRFS_I(inode)->root->fs_info, + "free space cache page truncated"); + io_ctl_drop_pages(io_ctl); + return -EIO; + } if (!PageUptodate(page)) { btrfs_err(BTRFS_I(inode)->root->fs_info, "error reading free space cache");
From: Josef Bacik josef@toxicpanda.com
commit baf320b9d531f1cfbf64c60dd155ff80a58b3796 upstream.
We hit the following warning while running down a different problem
[ 6197.175850] ------------[ cut here ]------------ [ 6197.185082] refcount_t: underflow; use-after-free. [ 6197.194704] WARNING: CPU: 47 PID: 966 at lib/refcount.c:190 refcount_sub_and_test_checked+0x53/0x60 [ 6197.521792] Call Trace: [ 6197.526687] __btrfs_release_delayed_node+0x76/0x1c0 [ 6197.536615] btrfs_kill_all_delayed_nodes+0xec/0x130 [ 6197.546532] ? __btrfs_btree_balance_dirty+0x60/0x60 [ 6197.556482] btrfs_clean_one_deleted_snapshot+0x71/0xd0 [ 6197.566910] cleaner_kthread+0xfa/0x120 [ 6197.574573] kthread+0x111/0x130 [ 6197.581022] ? kthread_create_on_node+0x60/0x60 [ 6197.590086] ret_from_fork+0x1f/0x30 [ 6197.597228] ---[ end trace 424bb7ae00509f56 ]---
This is because the free side drops the ref without the lock, and then takes the lock if our refcount is 0. So you can have nodes on the tree that have a refcount of 0. Fix this by zero'ing out that element in our temporary array so we don't try to kill it again.
CC: stable@vger.kernel.org # 4.14+ Reviewed-by: Nikolay Borisov nborisov@suse.com Signed-off-by: Josef Bacik josef@toxicpanda.com Reviewed-by: David Sterba dsterba@suse.com [ add comment ] Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/btrfs/delayed-inode.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
--- a/fs/btrfs/delayed-inode.c +++ b/fs/btrfs/delayed-inode.c @@ -1939,12 +1939,19 @@ void btrfs_kill_all_delayed_nodes(struct }
inode_id = delayed_nodes[n - 1]->inode_id + 1; - - for (i = 0; i < n; i++) - refcount_inc(&delayed_nodes[i]->refs); + for (i = 0; i < n; i++) { + /* + * Don't increase refs in case the node is dead and + * about to be removed from the tree in the loop below + */ + if (!refcount_inc_not_zero(&delayed_nodes[i]->refs)) + delayed_nodes[i] = NULL; + } spin_unlock(&root->inode_lock);
for (i = 0; i < n; i++) { + if (!delayed_nodes[i]) + continue; __btrfs_kill_delayed_node(delayed_nodes[i]); btrfs_release_delayed_node(delayed_nodes[i]); }
From: Filipe Manana fdmanana@suse.com
commit 536870071dbc4278264f59c9a2f5f447e584d139 upstream.
In the fixup worker, if we fail to mark the range as delalloc in the io tree, we must release the previously reserved metadata, as well as update the outstanding extents counter for the inode, otherwise we leak metadata space.
In pratice we can't return an error from btrfs_set_extent_delalloc(), which is just a wrapper around __set_extent_bit(), as for most errors __set_extent_bit() does a BUG_ON() (or panics which hits a BUG_ON() as well) and returning an -EEXIST error doesn't happen in this case since the exclusive bits parameter always has a value of 0 through this code path. Nevertheless, just fix the error handling in the fixup worker, in case one day __set_extent_bit() can return an error to this code path.
Fixes: f3038ee3a3f101 ("btrfs: Handle btrfs_set_extent_delalloc failure in fixup worker") CC: stable@vger.kernel.org # 4.19+ Reviewed-by: Nikolay Borisov nborisov@suse.com Signed-off-by: Filipe Manana fdmanana@suse.com Reviewed-by: David Sterba dsterba@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/btrfs/inode.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
--- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -2161,12 +2161,16 @@ again: mapping_set_error(page->mapping, ret); end_extent_writepage(page, ret, page_start, page_end); ClearPageChecked(page); - goto out; + goto out_reserved; }
ClearPageChecked(page); set_page_dirty(page); +out_reserved: btrfs_delalloc_release_extents(BTRFS_I(inode), PAGE_SIZE); + if (ret) + btrfs_delalloc_release_space(inode, data_reserved, page_start, + PAGE_SIZE, true); out: unlock_extent_cached(&BTRFS_I(inode)->io_tree, page_start, page_end, &cached_state);
From: Filipe Manana fdmanana@suse.com
commit a0e248bb502d5165b3314ac3819e888fdcdf7d9f upstream.
When doing a buffered write it's possible to leave the subv_writers counter of the root, used for synchronization between buffered nocow writers and snapshotting. This happens in an exceptional case like the following:
1) We fail to allocate data space for the write, since there's not enough available data space nor enough unallocated space for allocating a new data block group;
2) Because of that failure, we try to go to NOCOW mode, which succeeds and therefore we set the local variable 'only_release_metadata' to true and set the root's sub_writers counter to 1 through the call to btrfs_start_write_no_snapshotting() made by check_can_nocow();
3) The call to btrfs_copy_from_user() returns zero, which is very unlikely to happen but not impossible;
4) No pages are copied because btrfs_copy_from_user() returned zero;
5) We call btrfs_end_write_no_snapshotting() which decrements the root's subv_writers counter to 0;
6) We don't set 'only_release_metadata' back to 'false' because we do it only if 'copied', the value returned by btrfs_copy_from_user(), is greater than zero;
7) On the next iteration of the while loop, which processes the same page range, we are now able to allocate data space for the write (we got enough data space released in the meanwhile);
8) After this if we fail at btrfs_delalloc_reserve_metadata(), because now there isn't enough free metadata space, or in some other place further below (prepare_pages(), lock_and_cleanup_extent_if_need(), btrfs_dirty_pages()), we break out of the while loop with 'only_release_metadata' having a value of 'true';
9) Because 'only_release_metadata' is 'true' we end up decrementing the root's subv_writers counter to -1 (through a call to btrfs_end_write_no_snapshotting()), and we also end up not releasing the data space previously reserved through btrfs_check_data_free_space(). As a consequence the mechanism for synchronizing NOCOW buffered writes with snapshotting gets broken.
Fix this by always setting 'only_release_metadata' to false at the start of each iteration.
Fixes: 8257b2dc3c1a ("Btrfs: introduce btrfs_{start, end}_nocow_write() for each subvolume") Fixes: 7ee9e4405f26 ("Btrfs: check if we can nocow if we don't have data space") CC: stable@vger.kernel.org # 4.4+ Reviewed-by: Josef Bacik josef@toxicpanda.com Signed-off-by: Filipe Manana fdmanana@suse.com Reviewed-by: David Sterba dsterba@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/btrfs/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1636,6 +1636,7 @@ static noinline ssize_t btrfs_buffered_w break; }
+ only_release_metadata = false; sector_offset = pos & (fs_info->sectorsize - 1); reserve_bytes = round_up(write_bytes + sector_offset, fs_info->sectorsize); @@ -1791,7 +1792,6 @@ again: set_extent_bit(&BTRFS_I(inode)->io_tree, lockstart, lockend, EXTENT_NORESERVE, NULL, NULL, GFP_NOFS); - only_release_metadata = false; }
btrfs_drop_pages(pages, num_pages);
From: Tejun Heo tj@kernel.org
commit f7bddf1e27d18fbc7d3e3056ba449cfbe4e20b0a upstream.
During a cyclic writeback, extent_write_cache_pages() uses done_index to update the writeback_index after the current run is over. However, instead of current index + 1, it gets to to the current index itself.
Unfortunately, this, combined with returning on EOF instead of looping back, can lead to the following pathlogical behavior.
1. There is a single file which has accumulated enough dirty pages to trigger balance_dirty_pages() and the writer appending to the file with a series of short writes.
2. balance_dirty_pages kicks in, wakes up background writeback and sleeps.
3. Writeback kicks in and the cursor is on the last page of the dirty file. Writeback is started or skipped if already in progress. As it's EOF, extent_write_cache_pages() returns and the cursor is set to done_index which is pointing to the last page.
4. Writeback is done. Nothing happens till balance_dirty_pages finishes, at which point we go back to #1.
This can almost completely stall out writing back of the file and keep the system over dirty threshold for a long time which can mess up the whole system. We encountered this issue in production with a package handling application which can reliably reproduce the issue when running under tight memory limits.
Reading the comment in the error handling section, this seems to be to avoid accidentally skipping a page in case the write attempt on the page doesn't succeed. However, this concern seems bogus.
On each page, the code either:
* Skips and moves onto the next page.
* Fails issue and sets done_index to index + 1.
* Successfully issues and continue to the next page if budget allows and not EOF.
IOW, as long as it's not EOF and there's budget, the code never retries writing back the same page. Only when a page happens to be the last page of a particular run, we end up retrying the page, which can't possibly guarantee anything data integrity related. Besides, cyclic writes are only used for non-syncing writebacks meaning that there's no data integrity implication to begin with.
Fix it by always setting done_index past the current page being processed.
Note that this problem exists in other writepages too.
CC: stable@vger.kernel.org # 4.19+ Signed-off-by: Tejun Heo tj@kernel.org Reviewed-by: David Sterba dsterba@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/btrfs/extent_io.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-)
--- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -3956,7 +3956,7 @@ retry: for (i = 0; i < nr_pages; i++) { struct page *page = pvec.pages[i];
- done_index = page->index; + done_index = page->index + 1; /* * At this point we hold neither the i_pages lock nor * the page lock: the page may be truncated or @@ -3993,16 +3993,6 @@ retry: ret = 0; } if (ret < 0) { - /* - * done_index is set past this page, - * so media errors will not choke - * background writeout for the entire - * file. This has consequences for - * range_cyclic semantics (ie. it may - * not be suitable for data integrity - * writeout). - */ - done_index = page->index + 1; done = 1; break; }
From: Qu Wenruo wqu@suse.com
commit 34b127aecd4fe8e6a3903e10f204a7b7ffddca22 upstream.
The last user of btrfs_bio::flags was removed in commit 326e1dbb5736 ("block: remove management of bi_remaining when restoring original bi_end_io"), remove it.
(Tagged for stable as the structure is heavily used and space savings are desirable.)
CC: stable@vger.kernel.org # 4.4+ Signed-off-by: Qu Wenruo wqu@suse.com Reviewed-by: David Sterba dsterba@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/btrfs/volumes.h | 1 - 1 file changed, 1 deletion(-)
--- a/fs/btrfs/volumes.h +++ b/fs/btrfs/volumes.h @@ -304,7 +304,6 @@ struct btrfs_bio { u64 map_type; /* get from map_lookup->type */ bio_end_io_t *end_io; struct bio *orig_bio; - unsigned long flags; void *private; atomic_t error; int max_errors;
From: Filipe Manana fdmanana@suse.com
commit fd0ddbe2509568b00df364156f47561e9f469f15 upstream.
Backreference walking, which is used by send to figure if it can issue clone operations instead of write operations, can be very slow and use too much memory when extents have many references. This change simply skips backreference walking when an extent has more than 64 references, in which case we fallback to a write operation instead of a clone operation. This limit is conservative and in practice I observed no signicant slowdown with up to 100 references and still low memory usage up to that limit.
This is a temporary workaround until there are speedups in the backref walking code, and as such it does not attempt to add extra interfaces or knobs to tweak the threshold.
Reported-by: Atemu atemu.main@gmail.com Link: https://lore.kernel.org/linux-btrfs/CAE4GHgkvqVADtS4AzcQJxo0Q1jKQgKaW3JGp3SG... CC: stable@vger.kernel.org # 4.4+ Reviewed-by: Qu Wenruo wqu@suse.com Signed-off-by: Filipe Manana fdmanana@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/btrfs/send.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-)
--- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c @@ -25,6 +25,14 @@ #include "compression.h"
/* + * Maximum number of references an extent can have in order for us to attempt to + * issue clone operations instead of write operations. This currently exists to + * avoid hitting limitations of the backreference walking code (taking a lot of + * time and using too much memory for extents with large number of references). + */ +#define SEND_MAX_EXTENT_REFS 64 + +/* * A fs_path is a helper to dynamically build path names with unknown size. * It reallocates the internal buffer on demand. * It allows fast adding of path elements on the right side (normal path) and @@ -1303,6 +1311,7 @@ static int find_extent_clone(struct send struct clone_root *cur_clone_root; struct btrfs_key found_key; struct btrfs_path *tmp_path; + struct btrfs_extent_item *ei; int compressed; u32 i;
@@ -1352,7 +1361,6 @@ static int find_extent_clone(struct send ret = extent_from_logical(fs_info, disk_byte, tmp_path, &found_key, &flags); up_read(&fs_info->commit_root_sem); - btrfs_release_path(tmp_path);
if (ret < 0) goto out; @@ -1361,6 +1369,21 @@ static int find_extent_clone(struct send goto out; }
+ ei = btrfs_item_ptr(tmp_path->nodes[0], tmp_path->slots[0], + struct btrfs_extent_item); + /* + * Backreference walking (iterate_extent_inodes() below) is currently + * too expensive when an extent has a large number of references, both + * in time spent and used memory. So for now just fallback to write + * operations instead of clone operations when an extent has more than + * a certain amount of references. + */ + if (btrfs_extent_refs(tmp_path->nodes[0], ei) > SEND_MAX_EXTENT_REFS) { + ret = -ENOENT; + goto out; + } + btrfs_release_path(tmp_path); + /* * Setup the clone roots. */
From: Josef Bacik josef@toxicpanda.com
commit 3e1740993e43116b3bc71b0aad1e6872f6ccf341 upstream.
Testing with the new fsstress support for subvolumes uncovered a pretty bad problem with rename exchange on subvolumes. We're modifying two different subvolumes, but we only start the transaction on one of them, so the other one is not added to the dirty root list. This is caught by btrfs_cow_block() with a warning because the root has not been updated, however if we do not modify this root again we'll end up pointing at an invalid root because the root item is never updated.
Fix this by making sure we add the destination root to the trans list, the same as we do with normal renames. This fixes the corruption.
Fixes: cdd1fedf8261 ("btrfs: add support for RENAME_EXCHANGE and RENAME_WHITEOUT") CC: stable@vger.kernel.org # 4.9+ Reviewed-by: Filipe Manana fdmanana@suse.com Signed-off-by: Josef Bacik josef@toxicpanda.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/btrfs/inode.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -9510,6 +9510,9 @@ static int btrfs_rename_exchange(struct goto out_notrans; }
+ if (dest != root) + btrfs_record_root_in_trans(trans, dest); + /* * We need to find a free sequence number both in the source and * in the destination directory for the exchange.
From: Larry Finger Larry.Finger@lwfinger.net
commit 0e531cc575c4e9e3dd52ad287b49d3c2dc74c810 upstream.
In commit 38506ecefab9 ("rtlwifi: rtl_pci: Start modification for new drivers"), a callback to get the RX buffer address was added to the PCI driver. Unfortunately, driver rtl8192de was not modified appropriately and the code runs into a WARN_ONCE() call. The use of an incorrect array is also fixed.
Fixes: 38506ecefab9 ("rtlwifi: rtl_pci: Start modification for new drivers") Cc: Stable stable@vger.kernel.org # 3.18+ Signed-off-by: Larry Finger Larry.Finger@lwfinger.net Signed-off-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c @@ -840,13 +840,15 @@ u64 rtl92de_get_desc(struct ieee80211_hw break; } } else { - struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc; switch (desc_name) { case HW_DESC_OWN: - ret = GET_RX_DESC_OWN(pdesc); + ret = GET_RX_DESC_OWN(p_desc); break; case HW_DESC_RXPKT_LEN: - ret = GET_RX_DESC_PKT_LEN(pdesc); + ret = GET_RX_DESC_PKT_LEN(p_desc); + break; + case HW_DESC_RXBUFF_ADDR: + ret = GET_RX_DESC_BUFF_ADDR(p_desc); break; default: WARN_ONCE(true, "rtl8192de: ERR rxdesc :%d not processed\n",
From: Larry Finger Larry.Finger@lwfinger.net
commit 3155db7613edea8fb943624062baf1e4f9cfbfd6 upstream.
In commit 38506ecefab9 ("rtlwifi: rtl_pci: Start modification for new drivers"), a callback needed to check if the hardware has released a buffer indicating that a DMA operation is completed was not added.
Fixes: 38506ecefab9 ("rtlwifi: rtl_pci: Start modification for new drivers") Cc: Stable stable@vger.kernel.org # v3.18+ Signed-off-by: Larry Finger Larry.Finger@lwfinger.net Signed-off-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c | 1 + drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c | 17 +++++++++++++++++ drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.h | 2 ++ 3 files changed, 20 insertions(+)
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c @@ -238,6 +238,7 @@ static struct rtl_hal_ops rtl8192de_hal_ .led_control = rtl92de_led_control, .set_desc = rtl92de_set_desc, .get_desc = rtl92de_get_desc, + .is_tx_desc_closed = rtl92de_is_tx_desc_closed, .tx_polling = rtl92de_tx_polling, .enable_hw_sec = rtl92de_enable_hw_security_config, .set_key = rtl92de_set_key, --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c @@ -859,6 +859,23 @@ u64 rtl92de_get_desc(struct ieee80211_hw return ret; }
+bool rtl92de_is_tx_desc_closed(struct ieee80211_hw *hw, + u8 hw_queue, u16 index) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue]; + u8 *entry = (u8 *)(&ring->desc[ring->idx]); + u8 own = (u8)rtl92de_get_desc(hw, entry, true, HW_DESC_OWN); + + /* a beacon packet will only use the first + * descriptor by defaut, and the own bit may not + * be cleared by the hardware + */ + if (own) + return false; + return true; +} + void rtl92de_tx_polling(struct ieee80211_hw *hw, u8 hw_queue) { struct rtl_priv *rtlpriv = rtl_priv(hw); --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.h +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.h @@ -737,6 +737,8 @@ void rtl92de_set_desc(struct ieee80211_h u8 desc_name, u8 *val); u64 rtl92de_get_desc(struct ieee80211_hw *hw, u8 *p_desc, bool istx, u8 desc_name); +bool rtl92de_is_tx_desc_closed(struct ieee80211_hw *hw, + u8 hw_queue, u16 index); void rtl92de_tx_polling(struct ieee80211_hw *hw, u8 hw_queue); void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, bool b_firstseg, bool b_lastseg,
From: Larry Finger Larry.Finger@lwfinger.net
commit 330bb7117101099c687e9c7f13d48068670b9c62 upstream.
In commit 38506ecefab9 ("rtlwifi: rtl_pci: Start modification for new drivers"), the flag that indicates that interrupts are enabled was never set.
In addition, there are several places when enable/disable interrupts were commented out are restored. A sychronize_interrupts() call is removed.
Fixes: 38506ecefab9 ("rtlwifi: rtl_pci: Start modification for new drivers") Cc: Stable stable@vger.kernel.org # v3.18+ Signed-off-by: Larry Finger Larry.Finger@lwfinger.net Signed-off-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.c @@ -1198,6 +1198,7 @@ void rtl92de_enable_interrupt(struct iee
rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF); rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF); + rtlpci->irq_enabled = true; }
void rtl92de_disable_interrupt(struct ieee80211_hw *hw) @@ -1207,7 +1208,7 @@ void rtl92de_disable_interrupt(struct ie
rtl_write_dword(rtlpriv, REG_HIMR, IMR8190_DISABLED); rtl_write_dword(rtlpriv, REG_HIMRE, IMR8190_DISABLED); - synchronize_irq(rtlpci->pdev->irq); + rtlpci->irq_enabled = false; }
static void _rtl92de_poweroff_adapter(struct ieee80211_hw *hw) @@ -1373,7 +1374,7 @@ void rtl92de_set_beacon_related_register
bcn_interval = mac->beacon_interval; atim_window = 2; - /*rtl92de_disable_interrupt(hw); */ + rtl92de_disable_interrupt(hw); rtl_write_word(rtlpriv, REG_ATIMWND, atim_window); rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f); @@ -1393,9 +1394,9 @@ void rtl92de_set_beacon_interval(struct
RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG, "beacon_interval:%d\n", bcn_interval); - /* rtl92de_disable_interrupt(hw); */ + rtl92de_disable_interrupt(hw); rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); - /* rtl92de_enable_interrupt(hw); */ + rtl92de_enable_interrupt(hw); }
void rtl92de_update_interrupt_mask(struct ieee80211_hw *hw,
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
commit 702600eef73033ddd4eafcefcbb6560f3e3a90f7 upstream.
Newer versions of awk spit out these fun warnings: awk: ../lib/raid6/unroll.awk:16: warning: regexp escape sequence `#' is not a known regexp operator
As commit 700c1018b86d ("x86/insn: Fix awk regexp warnings") showed, it turns out that there are a number of awk strings that do not need to be escaped and newer versions of awk now warn about this.
Fix the string up so that no warning is produced. The exact same kernel module gets created before and after this patch, showing that it wasn't needed.
Link: https://lore.kernel.org/r/20191206152600.GA75093@kroah.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- lib/raid6/unroll.awk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/lib/raid6/unroll.awk +++ b/lib/raid6/unroll.awk @@ -13,7 +13,7 @@ BEGIN { for (i = 0; i < rep; ++i) { tmp = $0 gsub(/$$/, i, tmp) - gsub(/$#/, n, tmp) + gsub(/$#/, n, tmp) gsub(/$*/, "$", tmp) print tmp }
From: Amir Goldstein amir73il@gmail.com
commit 9c6d8f13e9da10a26ad7f0a020ef86e8ef142835 upstream.
On non-samefs overlay without xino, non pure upper inodes should use a pseudo_dev assigned to each unique lower fs and pure upper inodes use the real upper st_dev.
It is fine for an overlay pure upper inode to use the same st_dev;st_ino values as the real upper inode, because the content of those two different filesystem objects is always the same.
In this case, however: - two filesystems, A and B - upper layer is on A - lower layer 1 is also on A - lower layer 2 is on B
Non pure upper overlay inode, whose origin is in layer 1 will have the same st_dev;st_ino values as the real lower inode. This may result with a false positive results of 'diff' between the real lower and copied up overlay inode.
Fix this by using the upper st_dev;st_ino values in this case. This breaks the property of constant st_dev;st_ino across copy up of this case. This breakage will be fixed by a later patch.
Fixes: 5148626b806a ("ovl: allocate anon bdev per unique lower fs") Cc: stable@vger.kernel.org # v4.17+ Signed-off-by: Amir Goldstein amir73il@gmail.com Signed-off-by: Miklos Szeredi mszeredi@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/overlayfs/inode.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
--- a/fs/overlayfs/inode.c +++ b/fs/overlayfs/inode.c @@ -203,8 +203,14 @@ int ovl_getattr(const struct path *path, if (ovl_test_flag(OVL_INDEX, d_inode(dentry)) || (!ovl_verify_lower(dentry->d_sb) && (is_dir || lowerstat.nlink == 1))) { - stat->ino = lowerstat.ino; lower_layer = ovl_layer_lower(dentry); + /* + * Cannot use origin st_dev;st_ino because + * origin inode content may differ from overlay + * inode content. + */ + if (samefs || lower_layer->fsid) + stat->ino = lowerstat.ino; }
/*
From: Amir Goldstein amir73il@gmail.com
commit 6889ee5a53b8d969aa542047f5ac8acdc0e79a91 upstream.
In ovl_rename(), if new upper is hardlinked to old upper underneath overlayfs before upper dirs are locked, user will get an ESTALE error and a WARN_ON will be printed.
Changes to underlying layers while overlayfs is mounted may result in unexpected behavior, but it shouldn't crash the kernel and it shouldn't trigger WARN_ON() either, so relax this WARN_ON().
Reported-by: syzbot+bb1836a212e69f8e201a@syzkaller.appspotmail.com Fixes: 804032fabb3b ("ovl: don't check rename to self") Cc: stable@vger.kernel.org # v4.9+ Signed-off-by: Amir Goldstein amir73il@gmail.com Signed-off-by: Miklos Szeredi mszeredi@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/overlayfs/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/overlayfs/dir.c +++ b/fs/overlayfs/dir.c @@ -1174,7 +1174,7 @@ static int ovl_rename(struct inode *oldd if (newdentry == trap) goto out_dput;
- if (WARN_ON(olddentry->d_inode == newdentry->d_inode)) + if (olddentry->d_inode == newdentry->d_inode) goto out_dput;
err = 0;
From: Sumit Garg sumit.garg@linaro.org
commit be867f987a4e1222114dd07a01838a17c26f3fff upstream.
Existing RNG data read timeout is 200us but it doesn't cover EIP76 RNG data rate which takes approx. 700us to produce 16 bytes of output data as per testing results. So configure the timeout as 1000us to also take account of lack of udelay()'s reliability.
Fixes: 383212425c92 ("hwrng: omap - Add device variant for SafeXcel IP-76 found in Armada 8K") Cc: stable@vger.kernel.org Signed-off-by: Sumit Garg sumit.garg@linaro.org Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/char/hw_random/omap-rng.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
--- a/drivers/char/hw_random/omap-rng.c +++ b/drivers/char/hw_random/omap-rng.c @@ -66,6 +66,13 @@ #define OMAP4_RNG_OUTPUT_SIZE 0x8 #define EIP76_RNG_OUTPUT_SIZE 0x10
+/* + * EIP76 RNG takes approx. 700us to produce 16 bytes of output data + * as per testing results. And to account for the lack of udelay()'s + * reliability, we keep the timeout as 1000us. + */ +#define RNG_DATA_FILL_TIMEOUT 100 + enum { RNG_OUTPUT_0_REG = 0, RNG_OUTPUT_1_REG, @@ -176,7 +183,7 @@ static int omap_rng_do_read(struct hwrng if (max < priv->pdata->data_size) return 0;
- for (i = 0; i < 20; i++) { + for (i = 0; i < RNG_DATA_FILL_TIMEOUT; i++) { present = priv->pdata->data_present(priv); if (present || !wait) break;
From: Maged Mokhtar mmokhtar@petasan.org
commit c1005322ff02110a4df7f0033368ea015062b583 upstream.
Call writecache_flush() on REQ_FUA in writecache_map().
Cc: stable@vger.kernel.org # 4.18+ Signed-off-by: Maged Mokhtar mmokhtar@petasan.org Acked-by: Mikulas Patocka mpatocka@redhat.com Signed-off-by: Mike Snitzer snitzer@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/md/dm-writecache.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/md/dm-writecache.c +++ b/drivers/md/dm-writecache.c @@ -1223,7 +1223,8 @@ bio_copy: } } while (bio->bi_iter.bi_size);
- if (unlikely(wc->uncommitted_blocks >= wc->autocommit_blocks)) + if (unlikely(bio->bi_opf & REQ_FUA || + wc->uncommitted_blocks >= wc->autocommit_blocks)) writecache_flush(wc); else writecache_schedule_autocommit(wc);
From: Dmitry Fomichev dmitry.fomichev@wdc.com
commit e7fad909b68aa37470d9f2d2731b5bec355ee5d6 upstream.
Commit 75d66ffb48efb3 added backing device health checks and as a part of these checks, check_events() block ops template call is invoked in dm-zoned mapping path as well as in reclaim and flush path. Calling check_events() with ATA or SCSI backing devices introduces a blocking scsi_test_unit_ready() call being made in sd_check_events(). Even though the overhead of calling scsi_test_unit_ready() is small for ATA zoned devices, it is much larger for SCSI and it affects performance in a very negative way.
Fix this performance regression by executing check_events() only in case of any I/O errors. The function dmz_bdev_is_dying() is modified to call only blk_queue_dying(), while calls to check_events() are made in a new helper function, dmz_check_bdev().
Reported-by: zhangxiaoxu zhangxiaoxu5@huawei.com Fixes: 75d66ffb48efb3 ("dm zoned: properly handle backing device failure") Cc: stable@vger.kernel.org Signed-off-by: Dmitry Fomichev dmitry.fomichev@wdc.com Signed-off-by: Mike Snitzer snitzer@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/md/dm-zoned-metadata.c | 29 ++++++++++++++-------- drivers/md/dm-zoned-reclaim.c | 8 +----- drivers/md/dm-zoned-target.c | 54 ++++++++++++++++++++++++++++------------- drivers/md/dm-zoned.h | 2 + 4 files changed, 61 insertions(+), 32 deletions(-)
--- a/drivers/md/dm-zoned-metadata.c +++ b/drivers/md/dm-zoned-metadata.c @@ -552,6 +552,7 @@ static struct dmz_mblock *dmz_get_mblock TASK_UNINTERRUPTIBLE); if (test_bit(DMZ_META_ERROR, &mblk->state)) { dmz_release_mblock(zmd, mblk); + dmz_check_bdev(zmd->dev); return ERR_PTR(-EIO); }
@@ -623,6 +624,8 @@ static int dmz_rdwr_block(struct dmz_met ret = submit_bio_wait(bio); bio_put(bio);
+ if (ret) + dmz_check_bdev(zmd->dev); return ret; }
@@ -689,6 +692,7 @@ static int dmz_write_dirty_mblocks(struc TASK_UNINTERRUPTIBLE); if (test_bit(DMZ_META_ERROR, &mblk->state)) { clear_bit(DMZ_META_ERROR, &mblk->state); + dmz_check_bdev(zmd->dev); ret = -EIO; } nr_mblks_submitted--; @@ -766,7 +770,7 @@ int dmz_flush_metadata(struct dmz_metada /* If there are no dirty metadata blocks, just flush the device cache */ if (list_empty(&write_list)) { ret = blkdev_issue_flush(zmd->dev->bdev, GFP_NOIO, NULL); - goto out; + goto err; }
/* @@ -776,7 +780,7 @@ int dmz_flush_metadata(struct dmz_metada */ ret = dmz_log_dirty_mblocks(zmd, &write_list); if (ret) - goto out; + goto err;
/* * The log is on disk. It is now safe to update in place @@ -784,11 +788,11 @@ int dmz_flush_metadata(struct dmz_metada */ ret = dmz_write_dirty_mblocks(zmd, &write_list, zmd->mblk_primary); if (ret) - goto out; + goto err;
ret = dmz_write_sb(zmd, zmd->mblk_primary); if (ret) - goto out; + goto err;
while (!list_empty(&write_list)) { mblk = list_first_entry(&write_list, struct dmz_mblock, link); @@ -803,16 +807,20 @@ int dmz_flush_metadata(struct dmz_metada
zmd->sb_gen++; out: - if (ret && !list_empty(&write_list)) { - spin_lock(&zmd->mblk_lock); - list_splice(&write_list, &zmd->mblk_dirty_list); - spin_unlock(&zmd->mblk_lock); - } - dmz_unlock_flush(zmd); up_write(&zmd->mblk_sem);
return ret; + +err: + if (!list_empty(&write_list)) { + spin_lock(&zmd->mblk_lock); + list_splice(&write_list, &zmd->mblk_dirty_list); + spin_unlock(&zmd->mblk_lock); + } + if (!dmz_check_bdev(zmd->dev)) + ret = -EIO; + goto out; }
/* @@ -1235,6 +1243,7 @@ static int dmz_update_zone(struct dmz_me if (ret) { dmz_dev_err(zmd->dev, "Get zone %u report failed", dmz_id(zmd, zone)); + dmz_check_bdev(zmd->dev); return ret; }
--- a/drivers/md/dm-zoned-reclaim.c +++ b/drivers/md/dm-zoned-reclaim.c @@ -81,6 +81,7 @@ static int dmz_reclaim_align_wp(struct d "Align zone %u wp %llu to %llu (wp+%u) blocks failed %d", dmz_id(zmd, zone), (unsigned long long)wp_block, (unsigned long long)block, nr_blocks, ret); + dmz_check_bdev(zrc->dev); return ret; }
@@ -488,12 +489,7 @@ static void dmz_reclaim_work(struct work ret = dmz_do_reclaim(zrc); if (ret) { dmz_dev_debug(zrc->dev, "Reclaim error %d\n", ret); - if (ret == -EIO) - /* - * LLD might be performing some error handling sequence - * at the underlying device. To not interfere, do not - * attempt to schedule the next reclaim run immediately. - */ + if (!dmz_check_bdev(zrc->dev)) return; }
--- a/drivers/md/dm-zoned-target.c +++ b/drivers/md/dm-zoned-target.c @@ -79,6 +79,8 @@ static inline void dmz_bio_endio(struct
if (status != BLK_STS_OK && bio->bi_status == BLK_STS_OK) bio->bi_status = status; + if (bio->bi_status != BLK_STS_OK) + bioctx->target->dev->flags |= DMZ_CHECK_BDEV;
if (atomic_dec_and_test(&bioctx->ref)) { struct dm_zone *zone = bioctx->zone; @@ -564,32 +566,52 @@ out: }
/* - * Check the backing device availability. If it's on the way out, + * Check if the backing device is being removed. If it's on the way out, * start failing I/O. Reclaim and metadata components also call this * function to cleanly abort operation in the event of such failure. */ bool dmz_bdev_is_dying(struct dmz_dev *dmz_dev) { - struct gendisk *disk; + if (dmz_dev->flags & DMZ_BDEV_DYING) + return true;
- if (!(dmz_dev->flags & DMZ_BDEV_DYING)) { - disk = dmz_dev->bdev->bd_disk; - if (blk_queue_dying(bdev_get_queue(dmz_dev->bdev))) { - dmz_dev_warn(dmz_dev, "Backing device queue dying"); - dmz_dev->flags |= DMZ_BDEV_DYING; - } else if (disk->fops->check_events) { - if (disk->fops->check_events(disk, 0) & - DISK_EVENT_MEDIA_CHANGE) { - dmz_dev_warn(dmz_dev, "Backing device offline"); - dmz_dev->flags |= DMZ_BDEV_DYING; - } - } + if (dmz_dev->flags & DMZ_CHECK_BDEV) + return !dmz_check_bdev(dmz_dev); + + if (blk_queue_dying(bdev_get_queue(dmz_dev->bdev))) { + dmz_dev_warn(dmz_dev, "Backing device queue dying"); + dmz_dev->flags |= DMZ_BDEV_DYING; }
return dmz_dev->flags & DMZ_BDEV_DYING; }
/* + * Check the backing device availability. This detects such events as + * backing device going offline due to errors, media removals, etc. + * This check is less efficient than dmz_bdev_is_dying() and should + * only be performed as a part of error handling. + */ +bool dmz_check_bdev(struct dmz_dev *dmz_dev) +{ + struct gendisk *disk; + + dmz_dev->flags &= ~DMZ_CHECK_BDEV; + + if (dmz_bdev_is_dying(dmz_dev)) + return false; + + disk = dmz_dev->bdev->bd_disk; + if (disk->fops->check_events && + disk->fops->check_events(disk, 0) & DISK_EVENT_MEDIA_CHANGE) { + dmz_dev_warn(dmz_dev, "Backing device offline"); + dmz_dev->flags |= DMZ_BDEV_DYING; + } + + return !(dmz_dev->flags & DMZ_BDEV_DYING); +} + +/* * Process a new BIO. */ static int dmz_map(struct dm_target *ti, struct bio *bio) @@ -902,8 +924,8 @@ static int dmz_prepare_ioctl(struct dm_t { struct dmz_target *dmz = ti->private;
- if (dmz_bdev_is_dying(dmz->dev)) - return -ENODEV; + if (!dmz_check_bdev(dmz->dev)) + return -EIO;
*bdev = dmz->dev->bdev;
--- a/drivers/md/dm-zoned.h +++ b/drivers/md/dm-zoned.h @@ -71,6 +71,7 @@ struct dmz_dev {
/* Device flags. */ #define DMZ_BDEV_DYING (1 << 0) +#define DMZ_CHECK_BDEV (2 << 0)
/* * Zone descriptor. @@ -254,5 +255,6 @@ void dmz_schedule_reclaim(struct dmz_rec * Functions defined in dm-zoned-target.c */ bool dmz_bdev_is_dying(struct dmz_dev *dmz_dev); +bool dmz_check_bdev(struct dmz_dev *dmz_dev);
#endif /* DM_ZONED_H */
From: Tejun Heo tj@kernel.org
commit def98c84b6cdf2eeea19ec5736e90e316df5206b upstream.
Before actually destrying a workqueue, destroy_workqueue() checks whether it's actually idle. If it isn't, it prints out a bunch of warning messages and leaves the workqueue dangling. It unfortunately has a couple issues.
* Mayday list queueing increments pwq's refcnts which gets detected as busy and fails the sanity checks. However, because mayday list queueing is asynchronous, this condition can happen without any actual work items left in the workqueue.
* Sanity check failure leaves the sysfs interface behind too which can lead to init failure of newer instances of the workqueue.
This patch fixes the above two by
* If a workqueue has a rescuer, disable and kill the rescuer before sanity checks. Disabling and killing is guaranteed to flush the existing mayday list.
* Remove sysfs interface before sanity checks.
Signed-off-by: Tejun Heo tj@kernel.org Reported-by: Marcin Pawlowski mpawlowski@fb.com Reported-by: "Williams, Gerald S" gerald.s.williams@intel.com Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- kernel/workqueue.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-)
--- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -4154,9 +4154,28 @@ void destroy_workqueue(struct workqueue_ struct pool_workqueue *pwq; int node;
+ /* + * Remove it from sysfs first so that sanity check failure doesn't + * lead to sysfs name conflicts. + */ + workqueue_sysfs_unregister(wq); + /* drain it before proceeding with destruction */ drain_workqueue(wq);
+ /* kill rescuer, if sanity checks fail, leave it w/o rescuer */ + if (wq->rescuer) { + struct worker *rescuer = wq->rescuer; + + /* this prevents new queueing */ + spin_lock_irq(&wq_mayday_lock); + wq->rescuer = NULL; + spin_unlock_irq(&wq_mayday_lock); + + /* rescuer will empty maydays list before exiting */ + kthread_stop(rescuer->task); + } + /* sanity checks */ mutex_lock(&wq->mutex); for_each_pwq(pwq, wq) { @@ -4188,11 +4207,6 @@ void destroy_workqueue(struct workqueue_ list_del_rcu(&wq->list); mutex_unlock(&wq_pool_mutex);
- workqueue_sysfs_unregister(wq); - - if (wq->rescuer) - kthread_stop(wq->rescuer->task); - if (!(wq->flags & WQ_UNBOUND)) { /* * The base ref is never dropped on per-cpu pwqs. Directly
On Mon, Dec 16, 2019 at 06:48:41PM +0100, Greg Kroah-Hartman wrote:
From: Tejun Heo tj@kernel.org
commit def98c84b6cdf2eeea19ec5736e90e316df5206b upstream.
Before actually destrying a workqueue, destroy_workqueue() checks whether it's actually idle. If it isn't, it prints out a bunch of warning messages and leaves the workqueue dangling. It unfortunately has a couple issues.
Mayday list queueing increments pwq's refcnts which gets detected as busy and fails the sanity checks. However, because mayday list queueing is asynchronous, this condition can happen without any actual work items left in the workqueue.
Sanity check failure leaves the sysfs interface behind too which can lead to init failure of newer instances of the workqueue.
This patch fixes the above two by
If a workqueue has a rescuer, disable and kill the rescuer before sanity checks. Disabling and killing is guaranteed to flush the existing mayday list.
Remove sysfs interface before sanity checks.
Signed-off-by: Tejun Heo tj@kernel.org Reported-by: Marcin Pawlowski mpawlowski@fb.com Reported-by: "Williams, Gerald S" gerald.s.williams@intel.com Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
This commit also requires the following commit:
commit 8efe1223d73c218ce7e8b2e0e9aadb974b582d7f Author: Tejun Heo tj@kernel.org Date: Fri Sep 20 13:39:57 2019 -0700
workqueue: Fix missing kfree(rescuer) in destroy_workqueue()
Signed-off-by: Tejun Heo tj@kernel.org Reported-by: Qian Cai cai@lca.pw Fixes: def98c84b6cd ("workqueue: Fix spurious sanity check failures in destroy_workqueue()")
This is also required to 4.4, 4.9, 4.14 and 5.3.
Best regards, Nobuhiro
On Tue, Dec 17, 2019 at 01:38:10PM +0900, Nobuhiro Iwamatsu wrote:
On Mon, Dec 16, 2019 at 06:48:41PM +0100, Greg Kroah-Hartman wrote:
From: Tejun Heo tj@kernel.org
commit def98c84b6cdf2eeea19ec5736e90e316df5206b upstream.
Before actually destrying a workqueue, destroy_workqueue() checks whether it's actually idle. If it isn't, it prints out a bunch of warning messages and leaves the workqueue dangling. It unfortunately has a couple issues.
Mayday list queueing increments pwq's refcnts which gets detected as busy and fails the sanity checks. However, because mayday list queueing is asynchronous, this condition can happen without any actual work items left in the workqueue.
Sanity check failure leaves the sysfs interface behind too which can lead to init failure of newer instances of the workqueue.
This patch fixes the above two by
If a workqueue has a rescuer, disable and kill the rescuer before sanity checks. Disabling and killing is guaranteed to flush the existing mayday list.
Remove sysfs interface before sanity checks.
Signed-off-by: Tejun Heo tj@kernel.org Reported-by: Marcin Pawlowski mpawlowski@fb.com Reported-by: "Williams, Gerald S" gerald.s.williams@intel.com Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
This commit also requires the following commit:
commit 8efe1223d73c218ce7e8b2e0e9aadb974b582d7f Author: Tejun Heo tj@kernel.org Date: Fri Sep 20 13:39:57 2019 -0700
workqueue: Fix missing kfree(rescuer) in destroy_workqueue() Signed-off-by: Tejun Heo <tj@kernel.org> Reported-by: Qian Cai <cai@lca.pw> Fixes: def98c84b6cd ("workqueue: Fix spurious sanity check failures in destroy_workqueue()")
This is also required to 4.4, 4.9, 4.14 and 5.3.
Thank you for this, now queued up everywhere.
greg k-h
From: Tejun Heo tj@kernel.org
commit e66b39af00f426b3356b96433d620cb3367ba1ff upstream.
008847f66c3 ("workqueue: allow rescuer thread to do more work.") made the rescuer worker requeue the pwq immediately if there may be more work items which need rescuing instead of waiting for the next mayday timer expiration. Unfortunately, it doesn't check whether the pwq is already on the mayday list and unconditionally gets the ref and moves it onto the list. This doesn't corrupt the list but creates an additional reference to the pwq. It got queued twice but will only be removed once.
This leak later can trigger pwq refcnt warning on workqueue destruction and prevent freeing of the workqueue.
Signed-off-by: Tejun Heo tj@kernel.org Cc: "Williams, Gerald S" gerald.s.williams@intel.com Cc: NeilBrown neilb@suse.de Cc: stable@vger.kernel.org # v3.19+ Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- kernel/workqueue.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
--- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -2413,8 +2413,14 @@ repeat: */ if (need_to_create_worker(pool)) { spin_lock(&wq_mayday_lock); - get_pwq(pwq); - list_move_tail(&pwq->mayday_node, &wq->maydays); + /* + * Queue iff we aren't racing destruction + * and somebody else hasn't queued it already. + */ + if (wq->rescuer && list_empty(&pwq->mayday_node)) { + get_pwq(pwq); + list_add_tail(&pwq->mayday_node, &wq->maydays); + } spin_unlock(&wq_mayday_lock); } } @@ -4478,7 +4484,8 @@ static void show_pwq(struct pool_workque pr_info(" pwq %d:", pool->id); pr_cont_pool_info(pool);
- pr_cont(" active=%d/%d%s\n", pwq->nr_active, pwq->max_active, + pr_cont(" active=%d/%d refcnt=%d%s\n", + pwq->nr_active, pwq->max_active, pwq->refcnt, !list_empty(&pwq->mayday_node) ? " MAYDAY" : "");
hash_for_each(pool->busy_hash, bkt, worker, hentry) {
From: Jacob Rasmussen jacobraz@chromium.org
commit e7cfd867fd9842f346688f28412eb83dec342900 upstream.
The headphone jack on buddy was broken with the following commit: commit 6b5da66322c5 ("ASoC: rt5645: read jd1_1 status for jd detection"). This changes the jd_mode for buddy to 4 so buddy can read from the same register that was used in the working version of this driver without affecting any other devices that might use this, since no other device uses jd_mode = 4. To test this I plugged and uplugged the headphone jack, verifying audio works.
Signed-off-by: Jacob Rasmussen jacobraz@google.com Reviewed-by: Ross Zwisler zwisler@google.com Link: https://lore.kernel.org/r/20191111185957.217244-1-jacobraz@google.com Signed-off-by: Mark Brown broonie@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- sound/soc/codecs/rt5645.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
--- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -3307,6 +3307,9 @@ static void rt5645_jack_detect_work(stru snd_soc_jack_report(rt5645->mic_jack, report, SND_JACK_MICROPHONE); return; + case 4: + val = snd_soc_component_read32(rt5645->component, RT5645_A_JD_CTRL1) & 0x002; + break; default: /* read rt5645 jd1_1 status */ val = snd_soc_component_read32(rt5645->component, RT5645_INT_IRQ_ST) & 0x1000; break; @@ -3634,7 +3637,7 @@ static const struct rt5645_platform_data static const struct rt5645_platform_data buddy_platform_data = { .dmic1_data_pin = RT5645_DMIC_DATA_GPIO5, .dmic2_data_pin = RT5645_DMIC_DATA_IN2P, - .jd_mode = 3, + .jd_mode = 4, .level_trigger_irq = true, };
@@ -4030,6 +4033,7 @@ static int rt5645_i2c_probe(struct i2c_c RT5645_JD1_MODE_1); break; case 3: + case 4: regmap_update_bits(rt5645->regmap, RT5645_A_JD_CTRL1, RT5645_JD1_MODE_MASK, RT5645_JD1_MODE_2);
From: Jacob Rasmussen jacobraz@chromium.org
commit fe23be2d85b05f561431d75acddec726ea807d2a upstream.
Had a typo in e7cfd867fd98 that resulted in buddy jack support not being fixed.
Fixes: e7cfd867fd98 ("ASoC: rt5645: Fixed buddy jack support.") Signed-off-by: Jacob Rasmussen jacobraz@google.com Reviewed-by: Ross Zwisler zwisler@google.com Cc: jacobraz@google.com CC: stable@vger.kernel.org Link: https://lore.kernel.org/r/20191114232011.165762-1-jacobraz@google.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- sound/soc/codecs/rt5645.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -3308,7 +3308,7 @@ static void rt5645_jack_detect_work(stru report, SND_JACK_MICROPHONE); return; case 4: - val = snd_soc_component_read32(rt5645->component, RT5645_A_JD_CTRL1) & 0x002; + val = snd_soc_component_read32(rt5645->component, RT5645_A_JD_CTRL1) & 0x0020; break; default: /* read rt5645 jd1_1 status */ val = snd_soc_component_read32(rt5645->component, RT5645_INT_IRQ_ST) & 0x1000;
From: Pawel Harlozinski pawel.harlozinski@linux.intel.com
commit 8f157d4ff039e03e2ed4cb602eeed2fd4687a58f upstream.
Check for existance of jack before tracing. NULL pointer dereference has been reported by KASAN while unloading machine driver (snd_soc_cnl_rt274).
Signed-off-by: Pawel Harlozinski pawel.harlozinski@linux.intel.com Link: https://lore.kernel.org/r/20191112130237.10141-1-pawel.harlozinski@linux.int... Signed-off-by: Mark Brown broonie@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- sound/soc/soc-jack.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
--- a/sound/soc/soc-jack.c +++ b/sound/soc/soc-jack.c @@ -100,10 +100,9 @@ void snd_soc_jack_report(struct snd_soc_ unsigned int sync = 0; int enable;
- trace_snd_soc_jack_report(jack, mask, status); - if (!jack) return; + trace_snd_soc_jack_report(jack, mask, status);
dapm = &jack->card->dapm;
From: David Jeffery djeffery@redhat.com
commit 775d78319f1ceb32be8eb3b1202ccdc60e9cb7f1 upstream.
If pers->make_request fails in md_flush_request(), the bio is lost. To fix this, pass back a bool to indicate if the original make_request call should continue to handle the I/O and instead of assuming the flush logic will push it to completion.
Convert md_flush_request to return a bool and no longer calls the raid driver's make_request function. If the return is true, then the md flush logic has or will complete the bio and the md make_request call is done. If false, then the md make_request function needs to keep processing like it is a normal bio. Let the original call to md_handle_request handle any need to retry sending the bio to the raid driver's make_request function should it be needed.
Also mark md_flush_request and the make_request function pointer as __must_check to issue warnings should these critical return values be ignored.
Fixes: 2bc13b83e629 ("md: batch flush requests.") Cc: stable@vger.kernel.org # # v4.19+ Cc: NeilBrown neilb@suse.com Signed-off-by: David Jeffery djeffery@redhat.com Reviewed-by: Xiao Ni xni@redhat.com Signed-off-by: Song Liu songliubraving@fb.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/md/md-linear.c | 5 ++--- drivers/md/md-multipath.c | 5 ++--- drivers/md/md.c | 11 +++++++++-- drivers/md/md.h | 4 ++-- drivers/md/raid0.c | 5 ++--- drivers/md/raid1.c | 5 ++--- drivers/md/raid10.c | 5 ++--- drivers/md/raid5.c | 4 ++-- 8 files changed, 23 insertions(+), 21 deletions(-)
--- a/drivers/md/md-linear.c +++ b/drivers/md/md-linear.c @@ -252,10 +252,9 @@ static bool linear_make_request(struct m sector_t start_sector, end_sector, data_offset; sector_t bio_sector = bio->bi_iter.bi_sector;
- if (unlikely(bio->bi_opf & REQ_PREFLUSH)) { - md_flush_request(mddev, bio); + if (unlikely(bio->bi_opf & REQ_PREFLUSH) + && md_flush_request(mddev, bio)) return true; - }
tmp_dev = which_dev(mddev, bio_sector); start_sector = tmp_dev->end_sector - tmp_dev->rdev->sectors; --- a/drivers/md/md-multipath.c +++ b/drivers/md/md-multipath.c @@ -112,10 +112,9 @@ static bool multipath_make_request(struc struct multipath_bh * mp_bh; struct multipath_info *multipath;
- if (unlikely(bio->bi_opf & REQ_PREFLUSH)) { - md_flush_request(mddev, bio); + if (unlikely(bio->bi_opf & REQ_PREFLUSH) + && md_flush_request(mddev, bio)) return true; - }
mp_bh = mempool_alloc(&conf->pool, GFP_NOIO);
--- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -487,7 +487,13 @@ static void md_submit_flush_data(struct } }
-void md_flush_request(struct mddev *mddev, struct bio *bio) +/* + * Manages consolidation of flushes and submitting any flushes needed for + * a bio with REQ_PREFLUSH. Returns true if the bio is finished or is + * being finished in another context. Returns false if the flushing is + * complete but still needs the I/O portion of the bio to be processed. + */ +bool md_flush_request(struct mddev *mddev, struct bio *bio) { ktime_t start = ktime_get_boottime(); spin_lock_irq(&mddev->lock); @@ -512,9 +518,10 @@ void md_flush_request(struct mddev *mdde bio_endio(bio); else { bio->bi_opf &= ~REQ_PREFLUSH; - mddev->pers->make_request(mddev, bio); + return false; } } + return true; } EXPORT_SYMBOL(md_flush_request);
--- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -532,7 +532,7 @@ struct md_personality int level; struct list_head list; struct module *owner; - bool (*make_request)(struct mddev *mddev, struct bio *bio); + bool __must_check (*make_request)(struct mddev *mddev, struct bio *bio); /* * start up works that do NOT require md_thread. tasks that * requires md_thread should go into start() @@ -684,7 +684,7 @@ extern void md_error(struct mddev *mddev extern void md_finish_reshape(struct mddev *mddev);
extern int mddev_congested(struct mddev *mddev, int bits); -extern void md_flush_request(struct mddev *mddev, struct bio *bio); +extern bool __must_check md_flush_request(struct mddev *mddev, struct bio *bio); extern void md_super_write(struct mddev *mddev, struct md_rdev *rdev, sector_t sector, int size, struct page *page); extern int md_super_wait(struct mddev *mddev); --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -580,10 +580,9 @@ static bool raid0_make_request(struct md unsigned chunk_sects; unsigned sectors;
- if (unlikely(bio->bi_opf & REQ_PREFLUSH)) { - md_flush_request(mddev, bio); + if (unlikely(bio->bi_opf & REQ_PREFLUSH) + && md_flush_request(mddev, bio)) return true; - }
if (unlikely((bio_op(bio) == REQ_OP_DISCARD))) { raid0_handle_discard(mddev, bio); --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1537,10 +1537,9 @@ static bool raid1_make_request(struct md { sector_t sectors;
- if (unlikely(bio->bi_opf & REQ_PREFLUSH)) { - md_flush_request(mddev, bio); + if (unlikely(bio->bi_opf & REQ_PREFLUSH) + && md_flush_request(mddev, bio)) return true; - }
/* * There is a limit to the maximum size, but --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -1562,10 +1562,9 @@ static bool raid10_make_request(struct m int chunk_sects = chunk_mask + 1; int sectors = bio_sectors(bio);
- if (unlikely(bio->bi_opf & REQ_PREFLUSH)) { - md_flush_request(mddev, bio); + if (unlikely(bio->bi_opf & REQ_PREFLUSH) + && md_flush_request(mddev, bio)) return true; - }
if (!md_write_start(mddev, bio)) return false; --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -5590,8 +5590,8 @@ static bool raid5_make_request(struct md if (ret == 0) return true; if (ret == -ENODEV) { - md_flush_request(mddev, bi); - return true; + if (md_flush_request(mddev, bi)) + return true; } /* ret == -EAGAIN, fallback */ /*
From: Ming Lei ming.lei@redhat.com
commit 8962842ca5abdcf98e22ab3b2b45a103f0408b95 upstream.
It is reported that sysfs buffer overflow can be triggered if the system has too many CPU cores(>841 on 4K PAGE_SIZE) when showing CPUs of hctx via /sys/block/$DEV/mq/$N/cpu_list.
Use snprintf to avoid the potential buffer overflow.
This version doesn't change the attribute format, and simply stops showing CPU numbers if the buffer is going to overflow.
Cc: stable@vger.kernel.org Fixes: 676141e48af7("blk-mq: don't dump CPU -> hw queue map on driver load") Signed-off-by: Ming Lei ming.lei@redhat.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- block/blk-mq-sysfs.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
--- a/block/blk-mq-sysfs.c +++ b/block/blk-mq-sysfs.c @@ -151,20 +151,25 @@ static ssize_t blk_mq_hw_sysfs_nr_reserv
static ssize_t blk_mq_hw_sysfs_cpus_show(struct blk_mq_hw_ctx *hctx, char *page) { + const size_t size = PAGE_SIZE - 1; unsigned int i, first = 1; - ssize_t ret = 0; + int ret = 0, pos = 0;
for_each_cpu(i, hctx->cpumask) { if (first) - ret += sprintf(ret + page, "%u", i); + ret = snprintf(pos + page, size - pos, "%u", i); else - ret += sprintf(ret + page, ", %u", i); + ret = snprintf(pos + page, size - pos, ", %u", i); + + if (ret >= size - pos) + break;
first = 0; + pos += ret; }
- ret += sprintf(ret + page, "\n"); - return ret; + ret = snprintf(pos + page, size - pos, "\n"); + return pos + ret; }
static struct attribute *default_ctx_attrs[] = {
From: Aleksa Sarai cyphar@cyphar.com
commit a713af394cf382a30dd28a1015cbe572f1b9ca75 upstream.
Because pids->limit can be changed concurrently (but we don't want to take a lock because it would be needlessly expensive), use atomic64_ts instead.
Fixes: commit 49b786ea146f ("cgroup: implement the PIDs subsystem") Cc: stable@vger.kernel.org # v4.3+ Signed-off-by: Aleksa Sarai cyphar@cyphar.com Signed-off-by: Tejun Heo tj@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- kernel/cgroup/pids.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
--- a/kernel/cgroup/pids.c +++ b/kernel/cgroup/pids.c @@ -48,7 +48,7 @@ struct pids_cgroup { * %PIDS_MAX = (%PID_MAX_LIMIT + 1). */ atomic64_t counter; - int64_t limit; + atomic64_t limit;
/* Handle for "pids.events" */ struct cgroup_file events_file; @@ -76,8 +76,8 @@ pids_css_alloc(struct cgroup_subsys_stat if (!pids) return ERR_PTR(-ENOMEM);
- pids->limit = PIDS_MAX; atomic64_set(&pids->counter, 0); + atomic64_set(&pids->limit, PIDS_MAX); atomic64_set(&pids->events_limit, 0); return &pids->css; } @@ -149,13 +149,14 @@ static int pids_try_charge(struct pids_c
for (p = pids; parent_pids(p); p = parent_pids(p)) { int64_t new = atomic64_add_return(num, &p->counter); + int64_t limit = atomic64_read(&p->limit);
/* * Since new is capped to the maximum number of pid_t, if * p->limit is %PIDS_MAX then we know that this test will never * fail. */ - if (new > p->limit) + if (new > limit) goto revert; }
@@ -280,7 +281,7 @@ set_limit: * Limit updates don't need to be mutex'd, since it isn't * critical that any racing fork()s follow the new limit. */ - pids->limit = limit; + atomic64_set(&pids->limit, limit); return nbytes; }
@@ -288,7 +289,7 @@ static int pids_max_show(struct seq_file { struct cgroup_subsys_state *css = seq_css(sf); struct pids_cgroup *pids = css_pids(css); - int64_t limit = pids->limit; + int64_t limit = atomic64_read(&pids->limit);
if (limit >= PIDS_MAX) seq_printf(sf, "%s\n", PIDS_MAX_STR);
From: Denis Efremov efremov@linux.com
commit 315cee426f87658a6799815845788fde965ddaad upstream.
memcpy() call with "idata == NULL && ilen == 0" results in undefined behavior in ar5523_cmd(). For example, NULL is passed in callchain "ar5523_stat_work() -> ar5523_cmd_write() -> ar5523_cmd()". This patch adds ilen check before memcpy() call in ar5523_cmd() to prevent an undefined behavior.
Cc: Pontus Fuchs pontus.fuchs@gmail.com Cc: Kalle Valo kvalo@codeaurora.org Cc: "David S. Miller" davem@davemloft.net Cc: David Laight David.Laight@ACULAB.COM Cc: stable@vger.kernel.org Signed-off-by: Denis Efremov efremov@linux.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/net/wireless/ath/ar5523/ar5523.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/net/wireless/ath/ar5523/ar5523.c +++ b/drivers/net/wireless/ath/ar5523/ar5523.c @@ -255,7 +255,8 @@ static int ar5523_cmd(struct ar5523 *ar,
if (flags & AR5523_CMD_FLAG_MAGIC) hdr->magic = cpu_to_be32(1 << 24); - memcpy(hdr + 1, idata, ilen); + if (ilen) + memcpy(hdr + 1, idata, ilen);
cmd->odata = odata; cmd->olen = olen;
From: Gerald Schaefer gerald.schaefer@de.ibm.com
commit ab874f22d35a8058d8fdee5f13eb69d8867efeae upstream.
On older HW or under a hypervisor, w/o the instruction-execution- protection (IEP) facility, and also w/o EDAT-1, a translation-specification exception may be recognized when bit 55 of a pte is one (_PAGE_NOEXEC).
The current code tries to prevent setting _PAGE_NOEXEC in such cases, by removing it within set_pte_at(). However, ptep_set_access_flags() will modify a pte directly, w/o using set_pte_at(). There is at least one scenario where this can result in an active pte with _PAGE_NOEXEC set, which would then lead to a panic due to a translation-specification exception (write to swapped out page):
do_swap_page pte = mk_pte (with _PAGE_NOEXEC bit) set_pte_at (will remove _PAGE_NOEXEC bit in page table, but keep it in local variable pte) vmf->orig_pte = pte (pte still contains _PAGE_NOEXEC bit) do_wp_page wp_page_reuse entry = vmf->orig_pte (still with _PAGE_NOEXEC bit) ptep_set_access_flags (writes entry with _PAGE_NOEXEC bit)
Fix this by clearing _PAGE_NOEXEC already in mk_pte_phys(), where the pgprot value is applied, so that no pte with _PAGE_NOEXEC will ever be visible, if it is not supported. The check in set_pte_at() can then also be removed.
Cc: stable@vger.kernel.org # 4.11+ Fixes: 57d7f939e7bd ("s390: add no-execute support") Signed-off-by: Gerald Schaefer gerald.schaefer@de.ibm.com Signed-off-by: Vasily Gorbik gor@linux.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/s390/include/asm/pgtable.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -1150,8 +1150,6 @@ void gmap_pmdp_idte_global(struct mm_str static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t entry) { - if (!MACHINE_HAS_NX) - pte_val(entry) &= ~_PAGE_NOEXEC; if (pte_present(entry)) pte_val(entry) &= ~_PAGE_UNUSED; if (mm_has_pgste(mm)) @@ -1168,6 +1166,8 @@ static inline pte_t mk_pte_phys(unsigned { pte_t __pte; pte_val(__pte) = physpage + pgprot_val(pgprot); + if (!MACHINE_HAS_NX) + pte_val(__pte) &= ~_PAGE_NOEXEC; return pte_mkyoung(__pte); }
From: Johan Hovold johan@kernel.org
commit 11609a7e21f8cea42630350aa57662928fa4dc63 upstream.
If a process is interrupted while accessing the video device and the device lock is contended, release() could return early and fail to free related resources.
Note that the return value of the v4l2 release file operation is ignored.
Fixes: 28ffeebbb7bd ("[media] bdisp: 2D blitter driver using v4l2 mem2mem framework") Cc: stable stable@vger.kernel.org # 4.2 Signed-off-by: Johan Hovold johan@kernel.org Reviewed-by: Fabien Dessenne fabien.dessenne@st.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/media/platform/sti/bdisp/bdisp-v4l2.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
--- a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c +++ b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c @@ -651,8 +651,7 @@ static int bdisp_release(struct file *fi
dev_dbg(bdisp->dev, "%s\n", __func__);
- if (mutex_lock_interruptible(&bdisp->lock)) - return -ERESTARTSYS; + mutex_lock(&bdisp->lock);
v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
From: Johan Hovold johan@kernel.org
commit 1091eb830627625dcf79958d99353c2391f41708 upstream.
If a process is interrupted while accessing the radio device and the core lock is contended, release() could return early and fail to update the interrupt mask.
Note that the return value of the v4l2 release file operation is ignored.
Fixes: 87d1a50ce451 ("[media] V4L2: WL1273 FM Radio: TI WL1273 FM radio driver") Cc: stable stable@vger.kernel.org # 2.6.38 Cc: Matti Aaltonen matti.j.aaltonen@nokia.com Signed-off-by: Johan Hovold johan@kernel.org Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/media/radio/radio-wl1273.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
--- a/drivers/media/radio/radio-wl1273.c +++ b/drivers/media/radio/radio-wl1273.c @@ -1156,8 +1156,7 @@ static int wl1273_fm_fops_release(struct if (radio->rds_users > 0) { radio->rds_users--; if (radio->rds_users == 0) { - if (mutex_lock_interruptible(&core->lock)) - return -EINTR; + mutex_lock(&core->lock);
radio->irq_flags &= ~WL1273_RDS_EVENT;
From: Hans Verkuil hverkuil-cisco@xs4all.nl
commit 806e0cdfee0b99efbb450f9f6e69deb7118602fc upstream.
CEC_OP_REC_FLAG_NOT_USED is 0 and CEC_OP_REC_FLAG_USED is 1, not the other way around.
Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Reported-by: Jiunn Chang c0d1n61at3@gmail.com Cc: stable@vger.kernel.org # for v4.10 and up Signed-off-by: Mauro Carvalho Chehab mchehab+samsung@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- include/uapi/linux/cec.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/include/uapi/linux/cec.h +++ b/include/uapi/linux/cec.h @@ -767,8 +767,8 @@ struct cec_event { #define CEC_MSG_SELECT_DIGITAL_SERVICE 0x93 #define CEC_MSG_TUNER_DEVICE_STATUS 0x07 /* Recording Flag Operand (rec_flag) */ -#define CEC_OP_REC_FLAG_USED 0 -#define CEC_OP_REC_FLAG_NOT_USED 1 +#define CEC_OP_REC_FLAG_NOT_USED 0 +#define CEC_OP_REC_FLAG_USED 1 /* Tuner Display Info Operand (tuner_display_info) */ #define CEC_OP_TUNER_DISPLAY_INFO_DIGITAL 0 #define CEC_OP_TUNER_DISPLAY_INFO_NONE 1
From: Zhenzhong Duan zhenzhong.duan@oracle.com
commit 918c1fe9fbbe46fcf56837ff21f0ef96424e8b29 upstream.
Fix __cpuidle_set_driver() to check if any of the CPUs in the mask has a driver different from drv already and, if so, return -EBUSY before updating any cpuidle_drivers per-CPU pointers.
Fixes: 82467a5a885d ("cpuidle: simplify multiple driver support") Cc: 3.11+ stable@vger.kernel.org # 3.11+ Signed-off-by: Zhenzhong Duan zhenzhong.duan@oracle.com [ rjw: Subject & changelog ] Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/cpuidle/driver.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-)
--- a/drivers/cpuidle/driver.c +++ b/drivers/cpuidle/driver.c @@ -62,24 +62,23 @@ static inline void __cpuidle_unset_drive * __cpuidle_set_driver - set per CPU driver variables for the given driver. * @drv: a valid pointer to a struct cpuidle_driver * - * For each CPU in the driver's cpumask, unset the registered driver per CPU - * to @drv. - * - * Returns 0 on success, -EBUSY if the CPUs have driver(s) already. + * Returns 0 on success, -EBUSY if any CPU in the cpumask have a driver + * different from drv already. */ static inline int __cpuidle_set_driver(struct cpuidle_driver *drv) { int cpu;
for_each_cpu(cpu, drv->cpumask) { + struct cpuidle_driver *old_drv;
- if (__cpuidle_get_cpu_driver(cpu)) { - __cpuidle_unset_driver(drv); + old_drv = __cpuidle_get_cpu_driver(cpu); + if (old_drv && old_drv != drv) return -EBUSY; - } + }
+ for_each_cpu(cpu, drv->cpumask) per_cpu(cpuidle_drivers, cpu) = drv; - }
return 0; }
From: Gao Xiang gaoxiang25@huawei.com
commit 926d1650176448d7684b991fbe1a5b1a8289e97c upstream.
As David reported [1], ENODATA returns when attempting to modify files by using EROFS as an overlayfs lower layer.
The root cause is that listxattr could return unexpected -ENODATA by mistake for inodes without xattr. That breaks listxattr return value convention and it can cause copy up failure when used with overlayfs.
Resolve by zeroing out if no xattr is found for listxattr.
[1] https://lore.kernel.org/r/CAEvUa7nxnby+rxK-KRMA46=exeOMApkDMAV08AjMkkPnTPV4C... Link: https://lore.kernel.org/r/20191201084040.29275-1-hsiangkao@aol.com Fixes: cadf1ccf1b00 ("staging: erofs: add error handling for xattr submodule") Cc: stable@vger.kernel.org # 4.19+ Reviewed-by: Chao Yu yuchao0@huawei.com Signed-off-by: Gao Xiang gaoxiang25@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/staging/erofs/xattr.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/staging/erofs/xattr.c +++ b/drivers/staging/erofs/xattr.c @@ -638,6 +638,8 @@ ssize_t erofs_listxattr(struct dentry *d struct listxattr_iter it;
ret = init_inode_xattrs(d_inode(dentry)); + if (ret == -ENOATTR) + return 0; if (ret) return ret;
From: Alexander Shishkin alexander.shishkin@linux.intel.com
commit 512592779a337feb5905d8fcf9498dbf33672d4a upstream.
Commit a753bfcfdb1f ("intel_th: Make the switch allocate its subdevices") factored out intel_th_subdevice_alloc() from intel_th_populate(), but got the error path wrong, resulting in two instances of a double put_device() on a freshly initialized, but not 'added' device.
Fix this by only doing one put_device() in the error path.
Signed-off-by: Alexander Shishkin alexander.shishkin@linux.intel.com Fixes: a753bfcfdb1f ("intel_th: Make the switch allocate its subdevices") Reported-by: Wen Yang wenyang@linux.alibaba.com Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Cc: stable@vger.kernel.org # v4.14+ Link: https://lore.kernel.org/r/20191120130806.44028-2-alexander.shishkin@linux.in... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/hwtracing/intel_th/core.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-)
--- a/drivers/hwtracing/intel_th/core.c +++ b/drivers/hwtracing/intel_th/core.c @@ -629,10 +629,8 @@ intel_th_subdevice_alloc(struct intel_th }
err = intel_th_device_add_resources(thdev, res, subdev->nres); - if (err) { - put_device(&thdev->dev); + if (err) goto fail_put_device; - }
if (subdev->type == INTEL_TH_OUTPUT) { thdev->dev.devt = MKDEV(th->major, th->num_thdevs); @@ -646,10 +644,8 @@ intel_th_subdevice_alloc(struct intel_th }
err = device_add(&thdev->dev); - if (err) { - put_device(&thdev->dev); + if (err) goto fail_free_res; - }
/* need switch driver to be loaded to enumerate the rest */ if (subdev->type == INTEL_TH_SWITCH && !req) {
From: Alexander Shishkin alexander.shishkin@linux.intel.com
commit 6a1743422a7c0fda26764a544136cac13e5ae486 upstream.
This adds support for the Trace Hub in Ice Lake CPU.
Signed-off-by: Alexander Shishkin alexander.shishkin@linux.intel.com Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20191120130806.44028-3-alexander.shishkin@linux.in... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/hwtracing/intel_th/pci.c | 5 +++++ 1 file changed, 5 insertions(+)
--- a/drivers/hwtracing/intel_th/pci.c +++ b/drivers/hwtracing/intel_th/pci.c @@ -186,6 +186,11 @@ static const struct pci_device_id intel_ .driver_data = (kernel_ulong_t)&intel_th_2x, }, { + /* Ice Lake CPU */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8a29), + .driver_data = (kernel_ulong_t)&intel_th_2x, + }, + { /* Tiger Lake PCH */ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa0a6), .driver_data = (kernel_ulong_t)&intel_th_2x,
From: Alexander Shishkin alexander.shishkin@linux.intel.com
commit 6e6c18bcb78c0dc0601ebe216bed12c844492d0c upstream.
This adds support for the Trace Hub in Tiger Lake CPU.
Signed-off-by: Alexander Shishkin alexander.shishkin@linux.intel.com Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20191120130806.44028-4-alexander.shishkin@linux.in... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/hwtracing/intel_th/pci.c | 5 +++++ 1 file changed, 5 insertions(+)
--- a/drivers/hwtracing/intel_th/pci.c +++ b/drivers/hwtracing/intel_th/pci.c @@ -191,6 +191,11 @@ static const struct pci_device_id intel_ .driver_data = (kernel_ulong_t)&intel_th_2x, }, { + /* Tiger Lake CPU */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9a33), + .driver_data = (kernel_ulong_t)&intel_th_2x, + }, + { /* Tiger Lake PCH */ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa0a6), .driver_data = (kernel_ulong_t)&intel_th_2x,
From: Leonard Crestez leonard.crestez@nxp.com
commit 2abb0d5268ae7b5ddf82099b1f8d5aa8414637d4 upstream.
There is no locking in this sysfs show function so stats printing can race with a devfreq_update_status called as part of freq switching or with initialization.
Also add an assert in devfreq_update_status to make it clear that lock must be held by caller.
Fixes: 39688ce6facd ("PM / devfreq: account suspend/resume for stats") Cc: stable@vger.kernel.org Signed-off-by: Leonard Crestez leonard.crestez@nxp.com Reviewed-by: Matthias Kaehlcke mka@chromium.org Reviewed-by: Chanwoo Choi cw00.choi@samsung.com Signed-off-by: Chanwoo Choi cw00.choi@samsung.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/devfreq/devfreq.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
--- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -163,6 +163,7 @@ int devfreq_update_status(struct devfreq int lev, prev_lev, ret = 0; unsigned long cur_time;
+ lockdep_assert_held(&devfreq->lock); cur_time = jiffies;
/* Immediately exit if previous_freq is not initialized yet. */ @@ -1287,12 +1288,17 @@ static ssize_t trans_stat_show(struct de int i, j; unsigned int max_state = devfreq->profile->max_state;
- if (!devfreq->stop_polling && - devfreq_update_status(devfreq, devfreq->previous_freq)) - return 0; if (max_state == 0) return sprintf(buf, "Not Supported.\n");
+ mutex_lock(&devfreq->lock); + if (!devfreq->stop_polling && + devfreq_update_status(devfreq, devfreq->previous_freq)) { + mutex_unlock(&devfreq->lock); + return 0; + } + mutex_unlock(&devfreq->lock); + len = sprintf(buf, " From : To\n"); len += sprintf(buf + len, " :"); for (i = 0; i < max_state; i++)
From: John Hubbard jhubbard@nvidia.com
commit db0d32d84031188443e25edbd50a71a6e7ac5d1d upstream.
The following build warning occurred on powerpc 64-bit builds:
drivers/cpufreq/powernv-cpufreq.c: In function 'init_chip_info': drivers/cpufreq/powernv-cpufreq.c:1070:1: warning: the frame size of 1040 bytes is larger than 1024 bytes [-Wframe-larger-than=]
This is with a cross-compiler based on gcc 8.1.0, which I got from: https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/x86_64/8.1.0/
The warning is due to putting 1024 bytes on the stack:
unsigned int chip[256];
...and it's also undesirable to have a hard limit on the number of CPUs here.
Fix both problems by dynamically allocating based on num_possible_cpus, as recommended by Michael Ellerman.
Fixes: 053819e0bf840 ("cpufreq: powernv: Handle throttling due to Pmax capping at chip level") Signed-off-by: John Hubbard jhubbard@nvidia.com Acked-by: Viresh Kumar viresh.kumar@linaro.org Cc: 4.10+ stable@vger.kernel.org # 4.10+ Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/cpufreq/powernv-cpufreq.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-)
--- a/drivers/cpufreq/powernv-cpufreq.c +++ b/drivers/cpufreq/powernv-cpufreq.c @@ -1042,9 +1042,14 @@ static struct cpufreq_driver powernv_cpu
static int init_chip_info(void) { - unsigned int chip[256]; + unsigned int *chip; unsigned int cpu, i; unsigned int prev_chip_id = UINT_MAX; + int ret = 0; + + chip = kcalloc(num_possible_cpus(), sizeof(*chip), GFP_KERNEL); + if (!chip) + return -ENOMEM;
for_each_possible_cpu(cpu) { unsigned int id = cpu_to_chip_id(cpu); @@ -1056,8 +1061,10 @@ static int init_chip_info(void) }
chips = kcalloc(nr_chips, sizeof(struct chip), GFP_KERNEL); - if (!chips) - return -ENOMEM; + if (!chips) { + ret = -ENOMEM; + goto free_and_return; + }
for (i = 0; i < nr_chips; i++) { chips[i].id = chip[i]; @@ -1067,7 +1074,9 @@ static int init_chip_info(void) per_cpu(chip_info, cpu) = &chips[i]; }
- return 0; +free_and_return: + kfree(chip); + return ret; }
static inline void clean_chip_info(void)
From: Mika Westerberg mika.westerberg@linux.intel.com
commit 77adf9355304f8dcf09054280af5e23fc451ab3d upstream.
Valerio and others reported that commit 84c8b58ed3ad ("ACPI / hotplug / PCI: Don't scan bridges managed by native hotplug") prevents some recent LG and HP laptops from booting with endless loop of:
ACPI Error: No handler or method for GPE 08, disabling event (20190215/evgpe-835) ACPI Error: No handler or method for GPE 09, disabling event (20190215/evgpe-835) ACPI Error: No handler or method for GPE 0A, disabling event (20190215/evgpe-835) ...
What seems to happen is that during boot, after the initial PCI enumeration when EC is enabled the platform triggers ACPI Notify() to one of the root ports. The root port itself looks like this:
pci 0000:00:1b.0: PCI bridge to [bus 02-3a] pci 0000:00:1b.0: bridge window [mem 0xc4000000-0xda0fffff] pci 0000:00:1b.0: bridge window [mem 0x80000000-0xa1ffffff 64bit pref]
The BIOS has configured the root port so that it does not have I/O bridge window.
Now when the ACPI Notify() is triggered ACPI hotplug handler calls acpiphp_native_scan_bridge() for each non-hotplug bridge (as this system is using native PCIe hotplug) and pci_assign_unassigned_bridge_resources() to allocate resources.
The device connected to the root port is a PCIe switch (Thunderbolt controller) with two hotplug downstream ports. Because of the hotplug ports __pci_bus_size_bridges() tries to add "additional I/O" of 256 bytes to each (DEFAULT_HOTPLUG_IO_SIZE). This gets further aligned to 4k as that's the minimum I/O window size so each hotplug port gets 4k I/O window and the same happens for the root port (which is also hotplug port). This means 3 * 4k = 12k I/O window.
Because of this pci_assign_unassigned_bridge_resources() ends up opening a I/O bridge window for the root port at first available I/O address which seems to be in range 0x1000 - 0x3fff. Normally this range is used for ACPI stuff such as GPE bits (below is part of /proc/ioports):
1800-1803 : ACPI PM1a_EVT_BLK 1804-1805 : ACPI PM1a_CNT_BLK 1808-180b : ACPI PM_TMR 1810-1815 : ACPI CPU throttle 1850-1850 : ACPI PM2_CNT_BLK 1854-1857 : pnp 00:05 1860-187f : ACPI GPE0_BLK
However, when the ACPI Notify() happened this range was not yet reserved for ACPI/PNP (that happens later) so PCI gets it. It then starts writing to this range and accidentally stomps over GPE bits among other things causing the endless stream of messages about missing GPE handler.
This problem does not happen if "pci=hpiosize=0" is passed in the kernel command line. The reason is that then the kernel does not try to allocate the additional 256 bytes for each hotplug port.
Fix this by allocating resources directly below the non-hotplug bridges where a new device may appear as a result of ACPI Notify(). This avoids the hotplug bridges and prevents opening the additional I/O window.
Fixes: 84c8b58ed3ad ("ACPI / hotplug / PCI: Don't scan bridges managed by native hotplug") Link: https://bugzilla.kernel.org/show_bug.cgi?id=203617 Link: https://lore.kernel.org/r/20191030150545.19885-1-mika.westerberg@linux.intel... Reported-by: Valerio Passini passini.valerio@gmail.com Signed-off-by: Mika Westerberg mika.westerberg@linux.intel.com Signed-off-by: Bjorn Helgaas bhelgaas@google.com Reviewed-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/pci/hotplug/acpiphp_glue.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
--- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -449,8 +449,15 @@ static void acpiphp_native_scan_bridge(s
/* Scan non-hotplug bridges that need to be reconfigured */ for_each_pci_bridge(dev, bus) { - if (!hotplug_is_native(dev)) - max = pci_scan_bridge(bus, dev, max, 1); + if (hotplug_is_native(dev)) + continue; + + max = pci_scan_bridge(bus, dev, max, 1); + if (dev->subordinate) { + pcibios_resource_survey_bus(dev->subordinate); + pci_bus_size_bridges(dev->subordinate); + pci_bus_assign_resources(dev->subordinate); + } } }
@@ -480,7 +487,6 @@ static void enable_slot(struct acpiphp_s if (PCI_SLOT(dev->devfn) == slot->device) acpiphp_native_scan_bridge(dev); } - pci_assign_unassigned_bridge_resources(bus->self); } else { LIST_HEAD(add_list); int max, pass;
From: Francesco Ruggeri fruggeri@arista.com
commit 833a426cc471b6088011b3d67f1dc4e147614647 upstream.
acpi_os_map_cleanup checks map->refcount outside of acpi_ioremap_lock before freeing the map. This creates a race condition the can result in the map being freed more than once. A panic can be caused by running
for ((i=0; i<10; i++)) do for ((j=0; j<100000; j++)) do cat /sys/firmware/acpi/tables/data/BERT >/dev/null done & done
This patch makes sure that only the process that drops the reference to 0 does the freeing.
Fixes: b7c1fadd6c2e ("ACPI: Do not use krefs under a mutex in osl.c") Signed-off-by: Francesco Ruggeri fruggeri@arista.com Reviewed-by: Dmitry Safonov 0x7f454c46@gmail.com Cc: All applicable stable@vger.kernel.org Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/acpi/osl.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-)
--- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -374,19 +374,21 @@ void *__ref acpi_os_map_memory(acpi_phys } EXPORT_SYMBOL_GPL(acpi_os_map_memory);
-static void acpi_os_drop_map_ref(struct acpi_ioremap *map) +/* Must be called with mutex_lock(&acpi_ioremap_lock) */ +static unsigned long acpi_os_drop_map_ref(struct acpi_ioremap *map) { - if (!--map->refcount) + unsigned long refcount = --map->refcount; + + if (!refcount) list_del_rcu(&map->list); + return refcount; }
static void acpi_os_map_cleanup(struct acpi_ioremap *map) { - if (!map->refcount) { - synchronize_rcu_expedited(); - acpi_unmap(map->phys, map->virt); - kfree(map); - } + synchronize_rcu_expedited(); + acpi_unmap(map->phys, map->virt); + kfree(map); }
/** @@ -406,6 +408,7 @@ static void acpi_os_map_cleanup(struct a void __ref acpi_os_unmap_iomem(void __iomem *virt, acpi_size size) { struct acpi_ioremap *map; + unsigned long refcount;
if (!acpi_permanent_mmap) { __acpi_unmap_table(virt, size); @@ -419,10 +422,11 @@ void __ref acpi_os_unmap_iomem(void __io WARN(true, PREFIX "%s: bad address %p\n", __func__, virt); return; } - acpi_os_drop_map_ref(map); + refcount = acpi_os_drop_map_ref(map); mutex_unlock(&acpi_ioremap_lock);
- acpi_os_map_cleanup(map); + if (!refcount) + acpi_os_map_cleanup(map); } EXPORT_SYMBOL_GPL(acpi_os_unmap_iomem);
@@ -457,6 +461,7 @@ void acpi_os_unmap_generic_address(struc { u64 addr; struct acpi_ioremap *map; + unsigned long refcount;
if (gas->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) return; @@ -472,10 +477,11 @@ void acpi_os_unmap_generic_address(struc mutex_unlock(&acpi_ioremap_lock); return; } - acpi_os_drop_map_ref(map); + refcount = acpi_os_drop_map_ref(map); mutex_unlock(&acpi_ioremap_lock);
- acpi_os_map_cleanup(map); + if (!refcount) + acpi_os_map_cleanup(map); } EXPORT_SYMBOL(acpi_os_unmap_generic_address);
From: Vamshi K Sthambamkadi vamshi.k.sthambamkadi@gmail.com
commit 627ead724eff33673597216f5020b72118827de4 upstream.
kmemleak reported backtrace: [<bbee0454>] kmem_cache_alloc_trace+0x128/0x260 [<6677f215>] i2c_acpi_install_space_handler+0x4b/0xe0 [<1180f4fc>] i2c_register_adapter+0x186/0x400 [<6083baf7>] i2c_add_adapter+0x4e/0x70 [<a3ddf966>] intel_gmbus_setup+0x1a2/0x2c0 [i915] [<84cb69ae>] i915_driver_probe+0x8d8/0x13a0 [i915] [<81911d4b>] i915_pci_probe+0x48/0x160 [i915] [<4b159af1>] pci_device_probe+0xdc/0x160 [<b3c64704>] really_probe+0x1ee/0x450 [<bc029f5a>] driver_probe_device+0x142/0x1b0 [<d8829d20>] device_driver_attach+0x49/0x50 [<de71f045>] __driver_attach+0xc9/0x150 [<df33ac83>] bus_for_each_dev+0x56/0xa0 [<80089bba>] driver_attach+0x19/0x20 [<cc73f583>] bus_add_driver+0x177/0x220 [<7b29d8c7>] driver_register+0x56/0xf0
In i2c_acpi_remove_space_handler(), a leak occurs whenever the "data" parameter is initialized to 0 before being passed to acpi_bus_get_private_data().
This is because the NULL pointer check in acpi_bus_get_private_data() (condition->if(!*data)) returns EINVAL and, in consequence, memory is never freed in i2c_acpi_remove_space_handler().
Fix the NULL pointer check in acpi_bus_get_private_data() to follow the analogous check in acpi_get_data_full().
Signed-off-by: Vamshi K Sthambamkadi vamshi.k.sthambamkadi@gmail.com [ rjw: Subject & changelog ] Cc: All applicable stable@vger.kernel.org Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/acpi/bus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -166,7 +166,7 @@ int acpi_bus_get_private_data(acpi_handl { acpi_status status;
- if (!*data) + if (!data) return -EINVAL;
status = acpi_get_data(handle, acpi_bus_private_data_handler, data);
From: Rafael J. Wysocki rafael.j.wysocki@intel.com
commit b9ea0bae260f6aae546db224daa6ac1bd9d94b91 upstream.
Certain ACPI-enumerated devices represented as platform devices in Linux, like fans, require special low-level power management handling implemented by their drivers that is not in agreement with the ACPI PM domain behavior. That leads to problems with managing ACPI fans during system-wide suspend and resume.
For this reason, make acpi_dev_pm_attach() skip the affected devices by adding a list of device IDs to avoid to it and putting the IDs of the affected devices into that list.
Fixes: e5cc8ef31267 (ACPI / PM: Provide ACPI PM callback routines for subsystems) Reported-by: Zhang Rui rui.zhang@intel.com Tested-by: Todd Brandt todd.e.brandt@linux.intel.com Cc: 3.10+ stable@vger.kernel.org # 3.10+ Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/acpi/device_pm.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
--- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -1254,9 +1254,19 @@ static void acpi_dev_pm_detach(struct de */ int acpi_dev_pm_attach(struct device *dev, bool power_on) { + /* + * Skip devices whose ACPI companions match the device IDs below, + * because they require special power management handling incompatible + * with the generic ACPI PM domain. + */ + static const struct acpi_device_id special_pm_ids[] = { + {"PNP0C0B", }, /* Generic ACPI fan */ + {"INT3404", }, /* Fan */ + {} + }; struct acpi_device *adev = ACPI_COMPANION(dev);
- if (!adev) + if (!adev || !acpi_match_device_ids(adev, special_pm_ids)) return 0;
/*
From: Gregory CLEMENT gregory.clement@bootlin.com
commit 04fb02757ae5188031eb71b2f6f189edb1caf5dc upstream.
As explained in the following commit a9a1a4833613 ("pinctrl: armada-37xx: Fix gpio interrupt setup") the armada_37xx_irq_set_type() function can be called before the initialization of the mask field.
That means that we can't use this field in this function and need to workaround it using hwirq.
Fixes: 30ac0d3b0702 ("pinctrl: armada-37xx: Add edge both type gpio irq support") Cc: stable@vger.kernel.org Reported-by: Russell King rmk+kernel@armlinux.org.uk Signed-off-by: Gregory CLEMENT gregory.clement@bootlin.com Link: https://lore.kernel.org/r/20191115155752.2562-1-gregory.clement@bootlin.com Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c @@ -592,10 +592,10 @@ static int armada_37xx_irq_set_type(stru regmap_read(info->regmap, in_reg, &in_val);
/* Set initial polarity based on current input level. */ - if (in_val & d->mask) - val |= d->mask; /* falling */ + if (in_val & BIT(d->hwirq % GPIO_PER_REG)) + val |= BIT(d->hwirq % GPIO_PER_REG); /* falling */ else - val &= ~d->mask; /* rising */ + val &= ~(BIT(d->hwirq % GPIO_PER_REG)); /* rising */ break; } default:
From: Nishka Dasgupta nishkadg.linux@gmail.com
commit 3d2557ab75d4c568c79eefa2e550e0d80348a6bd upstream.
Each iteration of for_each_child_of_node puts the previous node, but in the case of a return from the middle of the loop, there is no put, thus causing a memory leak. Hence add an of_node_put before the return of exynos_eint_wkup_init() error path. Issue found with Coccinelle.
Signed-off-by: Nishka Dasgupta nishkadg.linux@gmail.com Cc: stable@vger.kernel.org Fixes: 14c255d35b25 ("pinctrl: exynos: Add irq_chip instance for Exynos7 wakeup interrupts") Signed-off-by: Krzysztof Kozlowski krzk@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/pinctrl/samsung/pinctrl-exynos.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/drivers/pinctrl/samsung/pinctrl-exynos.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos.c @@ -494,8 +494,10 @@ int exynos_eint_wkup_init(struct samsung if (match) { irq_chip = kmemdup(match->data, sizeof(*irq_chip), GFP_KERNEL); - if (!irq_chip) + if (!irq_chip) { + of_node_put(np); return -ENOMEM; + } wkup_np = np; break; }
From: Krzysztof Kozlowski krzk@kernel.org
commit 5c7f48dd14e892e3e920dd6bbbd52df79e1b3b41 upstream.
In exynos_eint_wkup_init() the for_each_child_of_node() loop is used with a break to find a matching child node. Although each iteration of for_each_child_of_node puts the previous node, but early exit from loop misses it. This leads to leak of device node.
Cc: stable@vger.kernel.org Fixes: 43b169db1841 ("pinctrl: add exynos4210 specific extensions for samsung pinctrl driver") Signed-off-by: Krzysztof Kozlowski krzk@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/pinctrl/samsung/pinctrl-exynos.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
--- a/drivers/pinctrl/samsung/pinctrl-exynos.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos.c @@ -514,6 +514,7 @@ int exynos_eint_wkup_init(struct samsung bank->nr_pins, &exynos_eint_irqd_ops, bank); if (!bank->irq_domain) { dev_err(dev, "wkup irq domain add failed\n"); + of_node_put(wkup_np); return -ENXIO; }
@@ -528,8 +529,10 @@ int exynos_eint_wkup_init(struct samsung weint_data = devm_kcalloc(dev, bank->nr_pins, sizeof(*weint_data), GFP_KERNEL); - if (!weint_data) + if (!weint_data) { + of_node_put(wkup_np); return -ENOMEM; + }
for (idx = 0; idx < bank->nr_pins; ++idx) { irq = irq_of_parse_and_map(bank->of_node, idx); @@ -546,10 +549,13 @@ int exynos_eint_wkup_init(struct samsung } }
- if (!muxed_banks) + if (!muxed_banks) { + of_node_put(wkup_np); return 0; + }
irq = irq_of_parse_and_map(wkup_np, 0); + of_node_put(wkup_np); if (!irq) { dev_err(dev, "irq number for muxed EINTs not found\n"); return 0;
From: Krzysztof Kozlowski krzk@kernel.org
commit 6fbbcb050802d6ea109f387e961b1dbcc3a80c96 upstream.
In s3c24xx_eint_init() the for_each_child_of_node() loop is used with a break to find a matching child node. Although each iteration of for_each_child_of_node puts the previous node, but early exit from loop misses it. This leads to leak of device node.
Cc: stable@vger.kernel.org Fixes: af99a7507469 ("pinctrl: Add pinctrl-s3c24xx driver") Signed-off-by: Krzysztof Kozlowski krzk@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/pinctrl/samsung/pinctrl-s3c24xx.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
--- a/drivers/pinctrl/samsung/pinctrl-s3c24xx.c +++ b/drivers/pinctrl/samsung/pinctrl-s3c24xx.c @@ -490,8 +490,10 @@ static int s3c24xx_eint_init(struct sams return -ENODEV;
eint_data = devm_kzalloc(dev, sizeof(*eint_data), GFP_KERNEL); - if (!eint_data) + if (!eint_data) { + of_node_put(eint_np); return -ENOMEM; + }
eint_data->drvdata = d;
@@ -503,12 +505,14 @@ static int s3c24xx_eint_init(struct sams irq = irq_of_parse_and_map(eint_np, i); if (!irq) { dev_err(dev, "failed to get wakeup EINT IRQ %d\n", i); + of_node_put(eint_np); return -ENXIO; }
eint_data->parents[i] = irq; irq_set_chained_handler_and_data(irq, handlers[i], eint_data); } + of_node_put(eint_np);
bank = d->pin_banks; for (i = 0; i < d->nr_banks; ++i, ++bank) {
From: Krzysztof Kozlowski krzk@kernel.org
commit a322b3377f4bac32aa25fb1acb9e7afbbbbd0137 upstream.
Several functions use for_each_child_of_node() loop with a break to find a matching child node. Although each iteration of for_each_child_of_node puts the previous node, but early exit from loop misses it. This leads to leak of device node.
Cc: stable@vger.kernel.org Fixes: 9a2c1c3b91aa ("pinctrl: samsung: Allow grouping multiple pinmux/pinconf nodes") Signed-off-by: Krzysztof Kozlowski krzk@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/pinctrl/samsung/pinctrl-samsung.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
--- a/drivers/pinctrl/samsung/pinctrl-samsung.c +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c @@ -272,6 +272,7 @@ static int samsung_dt_node_to_map(struct &reserved_maps, num_maps); if (ret < 0) { samsung_dt_free_map(pctldev, *map, *num_maps); + of_node_put(np); return ret; } } @@ -785,8 +786,10 @@ static struct samsung_pmx_func *samsung_ if (!of_get_child_count(cfg_np)) { ret = samsung_pinctrl_create_function(dev, drvdata, cfg_np, func); - if (ret < 0) + if (ret < 0) { + of_node_put(cfg_np); return ERR_PTR(ret); + } if (ret > 0) { ++func; ++func_cnt; @@ -797,8 +800,11 @@ static struct samsung_pmx_func *samsung_ for_each_child_of_node(cfg_np, func_np) { ret = samsung_pinctrl_create_function(dev, drvdata, func_np, func); - if (ret < 0) + if (ret < 0) { + of_node_put(func_np); + of_node_put(cfg_np); return ERR_PTR(ret); + } if (ret > 0) { ++func; ++func_cnt;
From: Krzysztof Kozlowski krzk@kernel.org
commit 7f028caadf6c37580d0f59c6c094ed09afc04062 upstream.
In s3c64xx_eint_eint0_init() the for_each_child_of_node() loop is used with a break to find a matching child node. Although each iteration of for_each_child_of_node puts the previous node, but early exit from loop misses it. This leads to leak of device node.
Cc: stable@vger.kernel.org Fixes: 61dd72613177 ("pinctrl: Add pinctrl-s3c64xx driver") Signed-off-by: Krzysztof Kozlowski krzk@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/pinctrl/samsung/pinctrl-s3c64xx.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
--- a/drivers/pinctrl/samsung/pinctrl-s3c64xx.c +++ b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c @@ -704,8 +704,10 @@ static int s3c64xx_eint_eint0_init(struc return -ENODEV;
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); - if (!data) + if (!data) { + of_node_put(eint0_np); return -ENOMEM; + } data->drvdata = d;
for (i = 0; i < NUM_EINT0_IRQ; ++i) { @@ -714,6 +716,7 @@ static int s3c64xx_eint_eint0_init(struc irq = irq_of_parse_and_map(eint0_np, i); if (!irq) { dev_err(dev, "failed to get wakeup EINT IRQ %d\n", i); + of_node_put(eint0_np); return -ENXIO; }
@@ -721,6 +724,7 @@ static int s3c64xx_eint_eint0_init(struc s3c64xx_eint0_handlers[i], data); } + of_node_put(eint0_np);
bank = d->pin_banks; for (i = 0; i < d->nr_banks; ++i, ++bank) {
From: H. Nikolaus Schaller hns@goldelico.com
commit f6498b922e57aecbe3b7fa30a308d9d586c0c369 upstream.
Pandora_wl1251_init_card was used to do special pdata based setup of the sdio mmc interface. This does no longer work with v4.7 and later. A fix requires a device tree based mmc3 setup.
Therefore we move the special setup to omap_hsmmc.c instead of calling some pdata supplied init_card function.
The new code checks for a DT child node compatible to wl1251 so it will not affect other MMC3 use cases.
Generally, this code was and still is a hack and should be moved to mmc core to e.g. read such properties from optional DT child nodes.
Fixes: 81eef6ca9201 ("mmc: omap_hsmmc: Use dma_request_chan() for requesting DMA channel") Signed-off-by: H. Nikolaus Schaller hns@goldelico.com Cc: stable@vger.kernel.org # v4.7+ [Ulf: Fixed up some checkpatch complaints] Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/mmc/host/omap_hsmmc.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
--- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -1661,6 +1661,36 @@ static void omap_hsmmc_init_card(struct
if (mmc_pdata(host)->init_card) mmc_pdata(host)->init_card(card); + else if (card->type == MMC_TYPE_SDIO || + card->type == MMC_TYPE_SD_COMBO) { + struct device_node *np = mmc_dev(mmc)->of_node; + + /* + * REVISIT: should be moved to sdio core and made more + * general e.g. by expanding the DT bindings of child nodes + * to provide a mechanism to provide this information: + * Documentation/devicetree/bindings/mmc/mmc-card.txt + */ + + np = of_get_compatible_child(np, "ti,wl1251"); + if (np) { + /* + * We have TI wl1251 attached to MMC3. Pass this + * information to the SDIO core because it can't be + * probed by normal methods. + */ + + dev_info(host->dev, "found wl1251\n"); + card->quirks |= MMC_QUIRK_NONSTD_SDIO; + card->cccr.wide_bus = 1; + card->cis.vendor = 0x104c; + card->cis.device = 0x9066; + card->cis.blksize = 512; + card->cis.max_dtr = 24000000; + card->ocr = 0x80; + of_node_put(np); + } + } }
static void omap_hsmmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
From: Jarkko Nikula jarkko.nikula@bitmer.com
commit 287897f9aaa2ad1c923d9875914f57c4dc9159c8 upstream.
The MMC card detection GPIO polarity is active low on TAO3530, like in many other similar boards. Now the card is not detected and it is unable to mount rootfs from an SD card.
Fix this by using the correct polarity.
This incorrect polarity was defined already in the commit 30d95c6d7092 ("ARM: dts: omap3: Add Technexion TAO3530 SOM omap3-tao3530.dtsi") in v3.18 kernel and later changed to use defined GPIO constants in v4.4 kernel by the commit 3a637e008e54 ("ARM: dts: Use defined GPIO constants in flags cell for OMAP2+ boards").
While the latter commit did not introduce the issue I'm marking it with Fixes tag due the v4.4 kernels still being maintained.
Fixes: 3a637e008e54 ("ARM: dts: Use defined GPIO constants in flags cell for OMAP2+ boards") Cc: linux-stable stable@vger.kernel.org # 4.4+ Signed-off-by: Jarkko Nikula jarkko.nikula@bitmer.com Signed-off-by: Tony Lindgren tony@atomide.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/arm/boot/dts/omap3-tao3530.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/arm/boot/dts/omap3-tao3530.dtsi +++ b/arch/arm/boot/dts/omap3-tao3530.dtsi @@ -225,7 +225,7 @@ pinctrl-0 = <&mmc1_pins>; vmmc-supply = <&vmmc1>; vqmmc-supply = <&vsim>; - cd-gpios = <&twl_gpio 0 GPIO_ACTIVE_HIGH>; + cd-gpios = <&twl_gpio 0 GPIO_ACTIVE_LOW>; bus-width = <8>; };
From: Arnd Bergmann arnd@arndb.de
commit 998174042da229e2cf5841f574aba4a743e69650 upstream.
Going through the uses of timeval in the user space API, I noticed two bugs in ppdev that were introduced in the y2038 conversion:
* The range check was accidentally moved from ppsettime to ppgettime
* On sparc64, the microseconds are in the other half of the 64-bit word.
Fix both, and mark the fix for stable backports.
Cc: stable@vger.kernel.org Fixes: 3b9ab374a1e6 ("ppdev: convert to y2038 safe") Signed-off-by: Arnd Bergmann arnd@arndb.de Link: https://lore.kernel.org/r/20191108203435.112759-8-arnd@arndb.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/char/ppdev.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)
--- a/drivers/char/ppdev.c +++ b/drivers/char/ppdev.c @@ -623,20 +623,27 @@ static int pp_do_ioctl(struct file *file if (copy_from_user(time32, argp, sizeof(time32))) return -EFAULT;
+ if ((time32[0] < 0) || (time32[1] < 0)) + return -EINVAL; + return pp_set_timeout(pp->pdev, time32[0], time32[1]);
case PPSETTIME64: if (copy_from_user(time64, argp, sizeof(time64))) return -EFAULT;
+ if ((time64[0] < 0) || (time64[1] < 0)) + return -EINVAL; + + if (IS_ENABLED(CONFIG_SPARC64) && !in_compat_syscall()) + time64[1] >>= 32; + return pp_set_timeout(pp->pdev, time64[0], time64[1]);
case PPGETTIME32: jiffies_to_timespec64(pp->pdev->timeout, &ts); time32[0] = ts.tv_sec; time32[1] = ts.tv_nsec / NSEC_PER_USEC; - if ((time32[0] < 0) || (time32[1] < 0)) - return -EINVAL;
if (copy_to_user(argp, time32, sizeof(time32))) return -EFAULT; @@ -647,8 +654,9 @@ static int pp_do_ioctl(struct file *file jiffies_to_timespec64(pp->pdev->timeout, &ts); time64[0] = ts.tv_sec; time64[1] = ts.tv_nsec / NSEC_PER_USEC; - if ((time64[0] < 0) || (time64[1] < 0)) - return -EINVAL; + + if (IS_ENABLED(CONFIG_SPARC64) && !in_compat_syscall()) + time64[1] <<= 32;
if (copy_to_user(argp, time64, sizeof(time64))) return -EFAULT;
From: Alastair D'Silva alastair@d-silva.org
commit f9ec11165301982585e5e5f606739b5bae5331f3 upstream.
When calling __kernel_sync_dicache with a size >4GB, we were masking off the upper 32 bits, so we would incorrectly flush a range smaller than intended.
This patch replaces the 32 bit shifts with 64 bit ones, so that the full size is accounted for.
Signed-off-by: Alastair D'Silva alastair@d-silva.org Cc: stable@vger.kernel.org Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20191104023305.9581-3-alastair@au1.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/powerpc/kernel/vdso64/cacheflush.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/arch/powerpc/kernel/vdso64/cacheflush.S +++ b/arch/powerpc/kernel/vdso64/cacheflush.S @@ -39,7 +39,7 @@ V_FUNCTION_BEGIN(__kernel_sync_dicache) subf r8,r6,r4 /* compute length */ add r8,r8,r5 /* ensure we get enough */ lwz r9,CFG_DCACHE_LOGBLOCKSZ(r10) - srw. r8,r8,r9 /* compute line count */ + srd. r8,r8,r9 /* compute line count */ crclr cr0*4+so beqlr /* nothing to do? */ mtctr r8 @@ -56,7 +56,7 @@ V_FUNCTION_BEGIN(__kernel_sync_dicache) subf r8,r6,r4 /* compute length */ add r8,r8,r5 lwz r9,CFG_ICACHE_LOGBLOCKSZ(r10) - srw. r8,r8,r9 /* compute line count */ + srd. r8,r8,r9 /* compute line count */ crclr cr0*4+so beqlr /* nothing to do? */ mtctr r8
From: Cédric Le Goater clg@kaod.org
commit 1ca3dec2b2dff9d286ce6cd64108bda0e98f9710 upstream.
When the machine crash handler is invoked, all interrupts are masked but interrupts which have not been started yet do not have an ESB page mapped in the Linux address space. This crashes the 'crash kexec' sequence on sPAPR guests.
To fix, force the mapping of the ESB page when an interrupt is being mapped in the Linux IRQ number space. This is done by setting the initial state of the interrupt to OFF which is not necessarily the case on PowerNV.
Fixes: 243e25112d06 ("powerpc/xive: Native exploitation of the XIVE interrupt controller") Cc: stable@vger.kernel.org # v4.12+ Signed-off-by: Cédric Le Goater clg@kaod.org Reviewed-by: Greg Kurz groug@kaod.org Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20191031063100.3864-1-clg@kaod.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/powerpc/sysdev/xive/common.c | 9 +++++++++ 1 file changed, 9 insertions(+)
--- a/arch/powerpc/sysdev/xive/common.c +++ b/arch/powerpc/sysdev/xive/common.c @@ -968,6 +968,15 @@ static int xive_irq_alloc_data(unsigned xd->target = XIVE_INVALID_TARGET; irq_set_handler_data(virq, xd);
+ /* + * Turn OFF by default the interrupt being mapped. A side + * effect of this check is the mapping the ESB page of the + * interrupt in the Linux address space. This prevents page + * fault issues in the crash handler which masks all + * interrupts. + */ + xive_esb_read(xd, XIVE_ESB_SET_PQ_01); + return 0; }
From: Alastair D'Silva alastair@d-silva.org
commit 29430fae82073d39b1b881a3cd507416a56a363f upstream.
When calling flush_icache_range with a size >4GB, we were masking off the upper 32 bits, so we would incorrectly flush a range smaller than intended.
This patch replaces the 32 bit shifts with 64 bit ones, so that the full size is accounted for.
Signed-off-by: Alastair D'Silva alastair@d-silva.org Cc: stable@vger.kernel.org Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20191104023305.9581-2-alastair@au1.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/powerpc/kernel/misc_64.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/arch/powerpc/kernel/misc_64.S +++ b/arch/powerpc/kernel/misc_64.S @@ -87,7 +87,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_I subf r8,r6,r4 /* compute length */ add r8,r8,r5 /* ensure we get enough */ lwz r9,DCACHEL1LOGBLOCKSIZE(r10) /* Get log-2 of cache block size */ - srw. r8,r8,r9 /* compute line count */ + srd. r8,r8,r9 /* compute line count */ beqlr /* nothing to do? */ mtctr r8 1: dcbst 0,r6 @@ -103,7 +103,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_I subf r8,r6,r4 /* compute length */ add r8,r8,r5 lwz r9,ICACHEL1LOGBLOCKSIZE(r10) /* Get log-2 of Icache block size */ - srw. r8,r8,r9 /* compute line count */ + srd. r8,r8,r9 /* compute line count */ beqlr /* nothing to do? */ mtctr r8 2: icbi 0,r6
From: Cédric Le Goater clg@kaod.org
commit b67a95f2abff0c34e5667c15ab8900de73d8d087 upstream.
The PCI INTx interrupts and other LSI interrupts are handled differently under a sPAPR platform. When the interrupt source characteristics are queried, the hypervisor returns an H_INT_ESB flag to inform the OS that it should be using the H_INT_ESB hcall for interrupt management and not loads and stores on the interrupt ESB pages.
A default -1 value is returned for the addresses of the ESB pages. The driver ignores this condition today and performs a bogus IO mapping. Recent changes and the DEBUG_VM configuration option make the bug visible with :
kernel BUG at arch/powerpc/include/asm/book3s/64/pgtable.h:612! Oops: Exception in kernel mode, sig: 5 [#1] LE PAGE_SIZE=64K MMU=Radix MMU=Hash SMP NR_CPUS=1024 NUMA pSeries Modules linked in: CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.4.0-0.rc6.git0.1.fc32.ppc64le #1 NIP: c000000000f63294 LR: c000000000f62e44 CTR: 0000000000000000 REGS: c0000000fa45f0d0 TRAP: 0700 Not tainted (5.4.0-0.rc6.git0.1.fc32.ppc64le) ... NIP ioremap_page_range+0x4c4/0x6e0 LR ioremap_page_range+0x74/0x6e0 Call Trace: ioremap_page_range+0x74/0x6e0 (unreliable) do_ioremap+0x8c/0x120 __ioremap_caller+0x128/0x140 ioremap+0x30/0x50 xive_spapr_populate_irq_data+0x170/0x260 xive_irq_domain_map+0x8c/0x170 irq_domain_associate+0xb4/0x2d0 irq_create_mapping+0x1e0/0x3b0 irq_create_fwspec_mapping+0x27c/0x3e0 irq_create_of_mapping+0x98/0xb0 of_irq_parse_and_map_pci+0x168/0x230 pcibios_setup_device+0x88/0x250 pcibios_setup_bus_devices+0x54/0x100 __of_scan_bus+0x160/0x310 pcibios_scan_phb+0x330/0x390 pcibios_init+0x8c/0x128 do_one_initcall+0x60/0x2c0 kernel_init_freeable+0x290/0x378 kernel_init+0x2c/0x148 ret_from_kernel_thread+0x5c/0x80
Fixes: bed81ee181dd ("powerpc/xive: introduce H_INT_ESB hcall") Cc: stable@vger.kernel.org # v4.14+ Signed-off-by: Cédric Le Goater clg@kaod.org Tested-by: Daniel Axtens dja@axtens.net Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20191203163642.2428-1-clg@kaod.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/powerpc/sysdev/xive/spapr.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
--- a/arch/powerpc/sysdev/xive/spapr.c +++ b/arch/powerpc/sysdev/xive/spapr.c @@ -359,20 +359,28 @@ static int xive_spapr_populate_irq_data( data->esb_shift = esb_shift; data->trig_page = trig_page;
+ data->hw_irq = hw_irq; + /* * No chip-id for the sPAPR backend. This has an impact how we * pick a target. See xive_pick_irq_target(). */ data->src_chip = XIVE_INVALID_CHIP_ID;
+ /* + * When the H_INT_ESB flag is set, the H_INT_ESB hcall should + * be used for interrupt management. Skip the remapping of the + * ESB pages which are not available. + */ + if (data->flags & XIVE_IRQ_FLAG_H_INT_ESB) + return 0; + data->eoi_mmio = ioremap(data->eoi_page, 1u << data->esb_shift); if (!data->eoi_mmio) { pr_err("Failed to map EOI page for irq 0x%x\n", hw_irq); return -ENOMEM; }
- data->hw_irq = hw_irq; - /* Full function page supports trigger */ if (flags & XIVE_SRC_TRIGGER) { data->trig_mmio = data->eoi_mmio;
From: Ville Syrjälä ville.syrjala@linux.intel.com
commit 6039f37dd6b76641198e290f26b31c475248f567 upstream.
The bar values are little endian, not big endian. The pack function did it right but the unpack got it wrong. Fix it.
Cc: stable@vger.kernel.org Cc: linux-media@vger.kernel.org Cc: Martin Bugge marbugge@cisco.com Cc: Hans Verkuil hans.verkuil@cisco.com Cc: Thierry Reding treding@nvidia.com Cc: Mauro Carvalho Chehab mchehab@osg.samsung.com Fixes: 2c676f378edb ("[media] hdmi: added unpack and logging functions for InfoFrames") Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20190919132853.30954-1-ville.s... Reviewed-by: Thierry Reding treding@nvidia.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/video/hdmi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
--- a/drivers/video/hdmi.c +++ b/drivers/video/hdmi.c @@ -1039,12 +1039,12 @@ static int hdmi_avi_infoframe_unpack(str if (ptr[0] & 0x10) frame->active_aspect = ptr[1] & 0xf; if (ptr[0] & 0x8) { - frame->top_bar = (ptr[5] << 8) + ptr[6]; - frame->bottom_bar = (ptr[7] << 8) + ptr[8]; + frame->top_bar = (ptr[6] << 8) | ptr[5]; + frame->bottom_bar = (ptr[8] << 8) | ptr[7]; } if (ptr[0] & 0x4) { - frame->left_bar = (ptr[9] << 8) + ptr[10]; - frame->right_bar = (ptr[11] << 8) + ptr[12]; + frame->left_bar = (ptr[10] << 8) | ptr[9]; + frame->right_bar = (ptr[12] << 8) | ptr[11]; } frame->scan_mode = ptr[0] & 0x3;
From: Dmitry Monakhov dmtrmonakhov@yandex-team.ru
commit df4bb5d128e2c44848aeb36b7ceceba3ac85080d upstream.
There is a race window where quota was redirted once we drop dq_list_lock inside dqput(), but before we grab dquot->dq_lock inside dquot_release()
TASK1 TASK2 (chowner) ->dqput() we_slept: spin_lock(&dq_list_lock) if (dquot_dirty(dquot)) { spin_unlock(&dq_list_lock); dquot->dq_sb->dq_op->write_dquot(dquot); goto we_slept if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) { spin_unlock(&dq_list_lock); dquot->dq_sb->dq_op->release_dquot(dquot); dqget() mark_dquot_dirty() dqput() goto we_slept; } So dquot dirty quota will be released by TASK1, but on next we_sleept loop we detect this and call ->write_dquot() for it. XFSTEST: https://github.com/dmonakhov/xfstests/commit/440a80d4cbb39e9234df4d7240aee1d...
Link: https://lore.kernel.org/r/20191031103920.3919-2-dmonakhov@openvz.org CC: stable@vger.kernel.org Signed-off-by: Dmitry Monakhov dmtrmonakhov@yandex-team.ru Signed-off-by: Jan Kara jack@suse.cz Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/ocfs2/quota_global.c | 2 +- fs/quota/dquot.c | 2 +- include/linux/quotaops.h | 10 ++++++++++ 3 files changed, 12 insertions(+), 2 deletions(-)
--- a/fs/ocfs2/quota_global.c +++ b/fs/ocfs2/quota_global.c @@ -728,7 +728,7 @@ static int ocfs2_release_dquot(struct dq
mutex_lock(&dquot->dq_lock); /* Check whether we are not racing with some other dqget() */ - if (atomic_read(&dquot->dq_count) > 1) + if (dquot_is_busy(dquot)) goto out; /* Running from downconvert thread? Postpone quota processing to wq */ if (current == osb->dc_task) { --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -491,7 +491,7 @@ int dquot_release(struct dquot *dquot)
mutex_lock(&dquot->dq_lock); /* Check whether we are not racing with some other dqget() */ - if (atomic_read(&dquot->dq_count) > 1) + if (dquot_is_busy(dquot)) goto out_dqlock; if (dqopt->ops[dquot->dq_id.type]->release_dqblk) { ret = dqopt->ops[dquot->dq_id.type]->release_dqblk(dquot); --- a/include/linux/quotaops.h +++ b/include/linux/quotaops.h @@ -54,6 +54,16 @@ static inline struct dquot *dqgrab(struc atomic_inc(&dquot->dq_count); return dquot; } + +static inline bool dquot_is_busy(struct dquot *dquot) +{ + if (test_bit(DQ_MOD_B, &dquot->dq_flags)) + return true; + if (atomic_read(&dquot->dq_count) > 1) + return true; + return false; +} + void dqput(struct dquot *dquot); int dquot_scan_active(struct super_block *sb, int (*fn)(struct dquot *dquot, unsigned long priv),
From: Chengguang Xu cgxu519@mykernel.net
commit e705f4b8aa27a59f8933e8f384e9752f052c469c upstream.
Check err when partial == NULL is meaningless because partial == NULL means getting branch successfully without error.
CC: stable@vger.kernel.org Link: https://lore.kernel.org/r/20191105045100.7104-1-cgxu519@mykernel.net Signed-off-by: Chengguang Xu cgxu519@mykernel.net Signed-off-by: Jan Kara jack@suse.cz Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/ext2/inode.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
--- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c @@ -699,10 +699,13 @@ static int ext2_get_blocks(struct inode if (!partial) { count++; mutex_unlock(&ei->truncate_mutex); - if (err) - goto cleanup; goto got_it; } + + if (err) { + mutex_unlock(&ei->truncate_mutex); + goto cleanup; + } }
/*
From: Dmitry Monakhov dmtrmonakhov@yandex-team.ru
commit 6ff33d99fc5c96797103b48b7b0902c296f09c05 upstream.
Write only quotas which are dirty at entry.
XFSTEST: https://github.com/dmonakhov/xfstests/commit/b10ad23566a5bf75832a6f500e12360...
Link: https://lore.kernel.org/r/20191031103920.3919-1-dmonakhov@openvz.org CC: stable@vger.kernel.org Signed-off-by: Konstantin Khlebnikov khlebnikov@yandex-team.ru Signed-off-by: Dmitry Monakhov dmtrmonakhov@yandex-team.ru Signed-off-by: Jan Kara jack@suse.cz Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/quota/dquot.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
--- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -617,7 +617,7 @@ EXPORT_SYMBOL(dquot_scan_active); /* Write all dquot structures to quota files */ int dquot_writeback_dquots(struct super_block *sb, int type) { - struct list_head *dirty; + struct list_head dirty; struct dquot *dquot; struct quota_info *dqopt = sb_dqopt(sb); int cnt; @@ -631,9 +631,10 @@ int dquot_writeback_dquots(struct super_ if (!sb_has_quota_active(sb, cnt)) continue; spin_lock(&dq_list_lock); - dirty = &dqopt->info[cnt].dqi_dirty_list; - while (!list_empty(dirty)) { - dquot = list_first_entry(dirty, struct dquot, + /* Move list away to avoid livelock. */ + list_replace_init(&dqopt->info[cnt].dqi_dirty_list, &dirty); + while (!list_empty(&dirty)) { + dquot = list_first_entry(&dirty, struct dquot, dq_dirty);
WARN_ON(!test_bit(DQ_ACTIVE_B, &dquot->dq_flags));
From: Jan Kara jack@suse.cz
commit 65db869c754e7c271691dd5feabf884347e694f5 upstream.
Estimate for the number of credits needed for final freeing of inode in ext4_evict_inode() was to small. We may modify 4 blocks (inode & sb for orphan deletion, bitmap & group descriptor for inode freeing) and not just 3.
[ Fixed minor whitespace nit. -- TYT ]
Fixes: e50e5129f384 ("ext4: xattr-in-inode support") CC: stable@vger.kernel.org Signed-off-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/20191105164437.32602-6-jack@suse.cz Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/ext4/inode.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
--- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -196,7 +196,12 @@ void ext4_evict_inode(struct inode *inod { handle_t *handle; int err; - int extra_credits = 3; + /* + * Credits for final inode cleanup and freeing: + * sb + inode (ext4_orphan_del()), block bitmap, group descriptor + * (xattr block freeing), bitmap, group descriptor (inode freeing) + */ + int extra_credits = 6; struct ext4_xattr_inode_array *ea_inode_array = NULL;
trace_ext4_evict_inode(inode); @@ -252,8 +257,12 @@ void ext4_evict_inode(struct inode *inod if (!IS_NOQUOTA(inode)) extra_credits += EXT4_MAXQUOTAS_DEL_BLOCKS(inode->i_sb);
+ /* + * Block bitmap, group descriptor, and inode are accounted in both + * ext4_blocks_for_truncate() and extra_credits. So subtract 3. + */ handle = ext4_journal_start(inode, EXT4_HT_TRUNCATE, - ext4_blocks_for_truncate(inode)+extra_credits); + ext4_blocks_for_truncate(inode) + extra_credits - 3); if (IS_ERR(handle)) { ext4_std_error(inode->i_sb, PTR_ERR(handle)); /*
From: Jeff Mahoney jeffm@suse.com
commit 60e4cf67a582d64f07713eda5fcc8ccdaf7833e6 upstream.
Since commit d0a5b995a308 (vfs: Add IOP_XATTR inode operations flag) extended attributes haven't worked on the root directory in reiserfs.
This is due to reiserfs conditionally setting the sb->s_xattrs handler array depending on whether it located or create the internal privroot directory. It necessarily does this after the root inode is already read in. The IOP_XATTR flag is set during inode initialization, so it never gets set on the root directory.
This commit unconditionally assigns sb->s_xattrs and clears IOP_XATTR on internal inodes. The old return values due to the conditional assignment are handled via open_xa_root, which now returns EOPNOTSUPP as the VFS would have done.
Link: https://lore.kernel.org/r/20191024143127.17509-1-jeffm@suse.com CC: stable@vger.kernel.org Fixes: d0a5b995a308 ("vfs: Add IOP_XATTR inode operations flag") Signed-off-by: Jeff Mahoney jeffm@suse.com Signed-off-by: Jan Kara jack@suse.cz Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/reiserfs/inode.c | 12 ++++++++++-- fs/reiserfs/namei.c | 7 +++++-- fs/reiserfs/reiserfs.h | 2 ++ fs/reiserfs/super.c | 2 ++ fs/reiserfs/xattr.c | 19 ++++++++++++------- fs/reiserfs/xattr_acl.c | 4 +--- 6 files changed, 32 insertions(+), 14 deletions(-)
--- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -2097,6 +2097,15 @@ int reiserfs_new_inode(struct reiserfs_t goto out_inserted_sd; }
+ /* + * Mark it private if we're creating the privroot + * or something under it. + */ + if (IS_PRIVATE(dir) || dentry == REISERFS_SB(sb)->priv_root) { + inode->i_flags |= S_PRIVATE; + inode->i_opflags &= ~IOP_XATTR; + } + if (reiserfs_posixacl(inode->i_sb)) { reiserfs_write_unlock(inode->i_sb); retval = reiserfs_inherit_default_acl(th, dir, dentry, inode); @@ -2111,8 +2120,7 @@ int reiserfs_new_inode(struct reiserfs_t reiserfs_warning(inode->i_sb, "jdm-13090", "ACLs aren't enabled in the fs, " "but vfs thinks they are!"); - } else if (IS_PRIVATE(dir)) - inode->i_flags |= S_PRIVATE; + }
if (security->name) { reiserfs_write_unlock(inode->i_sb); --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c @@ -377,10 +377,13 @@ static struct dentry *reiserfs_lookup(st
/* * Propagate the private flag so we know we're - * in the priv tree + * in the priv tree. Also clear IOP_XATTR + * since we don't have xattrs on xattr files. */ - if (IS_PRIVATE(dir)) + if (IS_PRIVATE(dir)) { inode->i_flags |= S_PRIVATE; + inode->i_opflags &= ~IOP_XATTR; + } } reiserfs_write_unlock(dir->i_sb); if (retval == IO_ERROR) { --- a/fs/reiserfs/reiserfs.h +++ b/fs/reiserfs/reiserfs.h @@ -1168,6 +1168,8 @@ static inline int bmap_would_wrap(unsign return bmap_nr > ((1LL << 16) - 1); }
+extern const struct xattr_handler *reiserfs_xattr_handlers[]; + /* * this says about version of key of all items (but stat data) the * object consists of --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -2052,6 +2052,8 @@ static int reiserfs_fill_super(struct su if (replay_only(s)) goto error_unlocked;
+ s->s_xattr = reiserfs_xattr_handlers; + if (bdev_read_only(s->s_bdev) && !sb_rdonly(s)) { SWARN(silent, s, "clm-7000", "Detected readonly device, marking FS readonly"); --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -122,13 +122,13 @@ static struct dentry *open_xa_root(struc struct dentry *xaroot;
if (d_really_is_negative(privroot)) - return ERR_PTR(-ENODATA); + return ERR_PTR(-EOPNOTSUPP);
inode_lock_nested(d_inode(privroot), I_MUTEX_XATTR);
xaroot = dget(REISERFS_SB(sb)->xattr_root); if (!xaroot) - xaroot = ERR_PTR(-ENODATA); + xaroot = ERR_PTR(-EOPNOTSUPP); else if (d_really_is_negative(xaroot)) { int err = -ENODATA;
@@ -610,6 +610,10 @@ int reiserfs_xattr_set(struct inode *ino int error, error2; size_t jbegin_count = reiserfs_xattr_nblocks(inode, buffer_size);
+ /* Check before we start a transaction and then do nothing. */ + if (!d_really_is_positive(REISERFS_SB(inode->i_sb)->priv_root)) + return -EOPNOTSUPP; + if (!(flags & XATTR_REPLACE)) jbegin_count += reiserfs_xattr_jcreate_nblocks(inode);
@@ -832,8 +836,7 @@ ssize_t reiserfs_listxattr(struct dentry if (d_really_is_negative(dentry)) return -EINVAL;
- if (!dentry->d_sb->s_xattr || - get_inode_sd_version(d_inode(dentry)) == STAT_DATA_V1) + if (get_inode_sd_version(d_inode(dentry)) == STAT_DATA_V1) return -EOPNOTSUPP;
dir = open_xa_dir(d_inode(dentry), XATTR_REPLACE); @@ -873,6 +876,7 @@ static int create_privroot(struct dentry }
d_inode(dentry)->i_flags |= S_PRIVATE; + d_inode(dentry)->i_opflags &= ~IOP_XATTR; reiserfs_info(dentry->d_sb, "Created %s - reserved for xattr " "storage.\n", PRIVROOT_NAME);
@@ -886,7 +890,7 @@ static int create_privroot(struct dentry #endif
/* Actual operations that are exported to VFS-land */ -static const struct xattr_handler *reiserfs_xattr_handlers[] = { +const struct xattr_handler *reiserfs_xattr_handlers[] = { #ifdef CONFIG_REISERFS_FS_XATTR &reiserfs_xattr_user_handler, &reiserfs_xattr_trusted_handler, @@ -957,8 +961,10 @@ int reiserfs_lookup_privroot(struct supe if (!IS_ERR(dentry)) { REISERFS_SB(s)->priv_root = dentry; d_set_d_op(dentry, &xattr_lookup_poison_ops); - if (d_really_is_positive(dentry)) + if (d_really_is_positive(dentry)) { d_inode(dentry)->i_flags |= S_PRIVATE; + d_inode(dentry)->i_opflags &= ~IOP_XATTR; + } } else err = PTR_ERR(dentry); inode_unlock(d_inode(s->s_root)); @@ -987,7 +993,6 @@ int reiserfs_xattr_init(struct super_blo }
if (d_really_is_positive(privroot)) { - s->s_xattr = reiserfs_xattr_handlers; inode_lock(d_inode(privroot)); if (!REISERFS_SB(s)->xattr_root) { struct dentry *dentry; --- a/fs/reiserfs/xattr_acl.c +++ b/fs/reiserfs/xattr_acl.c @@ -320,10 +320,8 @@ reiserfs_inherit_default_acl(struct reis * would be useless since permissions are ignored, and a pain because * it introduces locking cycles */ - if (IS_PRIVATE(dir)) { - inode->i_flags |= S_PRIVATE; + if (IS_PRIVATE(inode)) goto apply_umask; - }
err = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl); if (err)
From: Ming Lei ming.lei@redhat.com
commit 2a5cf35cd6c56b2924bce103413ad3381bdc31fa upstream.
There are actually two kinds of discard merge:
- one is the normal discard merge, just like normal read/write request, and call it single-range discard
- another is the multi-range discard, queue_max_discard_segments(rq->q) > 1
For the former case, queue_max_discard_segments(rq->q) is 1, and we should handle this kind of discard merge like the normal read/write request.
This patch fixes the following kernel panic issue[1], which is caused by not removing the single-range discard request from elevator queue.
Guangwu has one raid discard test case, in which this issue is a bit easier to trigger, and I verified that this patch can fix the kernel panic issue in Guangwu's test case.
[1] kernel panic log from Jens's report
BUG: unable to handle kernel NULL pointer dereference at 0000000000000148 PGD 0 P4D 0. Oops: 0000 [#1] SMP PTI CPU: 37 PID: 763 Comm: kworker/37:1H Not tainted \ 4.20.0-rc3-00649-ge64d9a554a91-dirty #14 Hardware name: Wiwynn \ Leopard-Orv2/Leopard-DDR BW, BIOS LBM08 03/03/2017 Workqueue: kblockd \ blk_mq_run_work_fn RIP: \ 0010:blk_mq_get_driver_tag+0x81/0x120 Code: 24 \ 10 48 89 7c 24 20 74 21 83 fa ff 0f 95 c0 48 8b 4c 24 28 65 48 33 0c 25 28 00 00 00 \ 0f 85 96 00 00 00 48 83 c4 30 5b 5d c3 <48> 8b 87 48 01 00 00 8b 40 04 39 43 20 72 37 \ f6 87 b0 00 00 00 02 RSP: 0018:ffffc90004aabd30 EFLAGS: 00010246 \ RAX: 0000000000000003 RBX: ffff888465ea1300 RCX: ffffc90004aabde8 RDX: 00000000ffffffff RSI: ffffc90004aabde8 RDI: 0000000000000000 RBP: 0000000000000000 R08: ffff888465ea1348 R09: 0000000000000000 R10: 0000000000001000 R11: 00000000ffffffff R12: ffff888465ea1300 R13: 0000000000000000 R14: ffff888465ea1348 R15: ffff888465d10000 FS: 0000000000000000(0000) GS:ffff88846f9c0000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000148 CR3: 000000000220a003 CR4: 00000000003606e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: blk_mq_dispatch_rq_list+0xec/0x480 ? elv_rb_del+0x11/0x30 blk_mq_do_dispatch_sched+0x6e/0xf0 blk_mq_sched_dispatch_requests+0xfa/0x170 __blk_mq_run_hw_queue+0x5f/0xe0 process_one_work+0x154/0x350 worker_thread+0x46/0x3c0 kthread+0xf5/0x130 ? process_one_work+0x350/0x350 ? kthread_destroy_worker+0x50/0x50 ret_from_fork+0x1f/0x30 Modules linked in: sb_edac x86_pkg_temp_thermal intel_powerclamp coretemp kvm_intel \ kvm switchtec irqbypass iTCO_wdt iTCO_vendor_support efivars cdc_ether usbnet mii \ cdc_acm i2c_i801 lpc_ich mfd_core ipmi_si ipmi_devintf ipmi_msghandler acpi_cpufreq \ button sch_fq_codel nfsd nfs_acl lockd grace auth_rpcgss oid_registry sunrpc nvme \ nvme_core fuse sg loop efivarfs autofs4 CR2: 0000000000000148 \
---[ end trace 340a1fb996df1b9b ]--- RIP: 0010:blk_mq_get_driver_tag+0x81/0x120 Code: 24 10 48 89 7c 24 20 74 21 83 fa ff 0f 95 c0 48 8b 4c 24 28 65 48 33 0c 25 28 \ 00 00 00 0f 85 96 00 00 00 48 83 c4 30 5b 5d c3 <48> 8b 87 48 01 00 00 8b 40 04 39 43 \ 20 72 37 f6 87 b0 00 00 00 02
Fixes: 445251d0f4d329a ("blk-mq: fix discard merge with scheduler attached") Reported-by: Jens Axboe axboe@kernel.dk Cc: Guangwu Zhang guazhang@redhat.com Cc: Christoph Hellwig hch@lst.de Cc: Jianchao Wang jianchao.w.wang@oracle.com Signed-off-by: Ming Lei ming.lei@redhat.com Signed-off-by: Jens Axboe axboe@kernel.dk Cc: Andre Tomt andre@tomt.net Cc: Jack Wang jack.wang.usish@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- block/blk-merge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/block/blk-merge.c +++ b/block/blk-merge.c @@ -774,7 +774,7 @@ static struct request *attempt_merge(str
req->__data_len += blk_rq_bytes(next);
- if (req_op(req) != REQ_OP_DISCARD) + if (!blk_discard_mergable(req)) elv_merge_requests(q, req, next);
/*
From: Steffen Maier maier@linux.ibm.com
[ Upstream commit 100843f176109af94600e500da0428e21030ca7f ]
While v2.6.26 commit b75db73159cc ("[SCSI] zfcp: Add qtcb dump to hba debug trace") is right that we don't want to flood the (payload) trace ring buffer, we don't trace successful FCP command responses by default. So we can include the channel log for problem determination with failed responses of any FSF request type.
Fixes: b75db73159cc ("[SCSI] zfcp: Add qtcb dump to hba debug trace") Fixes: a54ca0f62f95 ("[SCSI] zfcp: Redesign of the debug tracing for HBA records.") Cc: stable@vger.kernel.org #2.6.38+ Link: https://lore.kernel.org/r/e37597b5c4ae123aaa85fd86c23a9f71e994e4a9.157201813... Reviewed-by: Benjamin Block bblock@linux.ibm.com Signed-off-by: Steffen Maier maier@linux.ibm.com Signed-off-by: Benjamin Block bblock@linux.ibm.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/s390/scsi/zfcp_dbf.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c index 3b368fcf13f40..946380f0d7199 100644 --- a/drivers/s390/scsi/zfcp_dbf.c +++ b/drivers/s390/scsi/zfcp_dbf.c @@ -94,11 +94,9 @@ void zfcp_dbf_hba_fsf_res(char *tag, int level, struct zfcp_fsf_req *req) memcpy(rec->u.res.fsf_status_qual, &q_head->fsf_status_qual, FSF_STATUS_QUALIFIER_SIZE);
- if (req->fsf_command != FSF_QTCB_FCP_CMND) { - rec->pl_len = q_head->log_length; - zfcp_dbf_pl_write(dbf, (char *)q_pref + q_head->log_start, - rec->pl_len, "fsf_res", req->req_id); - } + rec->pl_len = q_head->log_length; + zfcp_dbf_pl_write(dbf, (char *)q_pref + q_head->log_start, + rec->pl_len, "fsf_res", req->req_id);
debug_event(dbf->hba, level, rec, sizeof(*rec)); spin_unlock_irqrestore(&dbf->hba_lock, flags);
From: Himanshu Madhani hmadhani@marvell.com
[ Upstream commit 5d328de64d89400dcf9911125844d8adc0db697f ]
With debug kernel we see following wanings indicating memory leak.
[28809.523959] WARNING: CPU: 3 PID: 6790 at lib/dma-debug.c:978 dma_debug_device_change+0x166/0x1d0 [28809.523964] pci 0000:0c:00.6: DMA-API: device driver has pending DMA allocations while released from device [count=5] [28809.523964] One of leaked entries details: [device address=0x00000002aefe4000] [size=8208 bytes] [mapped with DMA_BIDIRECTIONAL] [mapped as coherent]
Fix this by unmapping DMA memory.
Signed-off-by: Quinn Tran qutran@marvell.com Signed-off-by: Himanshu Madhani hmadhani@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla2xxx/qla_bsg.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c index 85b03a7f473c1..b68a708c67251 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c @@ -342,6 +342,8 @@ qla2x00_process_els(struct bsg_job *bsg_job) dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list, bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE); if (!req_sg_cnt) { + dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list, + bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE); rval = -ENOMEM; goto done_free_fcport; } @@ -349,6 +351,8 @@ qla2x00_process_els(struct bsg_job *bsg_job) rsp_sg_cnt = dma_map_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list, bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE); if (!rsp_sg_cnt) { + dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list, + bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE); rval = -ENOMEM; goto done_free_fcport; }
From: Quinn Tran qutran@marvell.com
[ Upstream commit f00b3428a801758243693e046b34226e92bc56b3 ]
A hang was observed in the fcport delete path when the device was responding slow and an issue-lip path (results in session termination) was taken.
Fix this by issuing logo requests unconditionally.
PID: 19491 TASK: ffff8e23e67bb150 CPU: 0 COMMAND: "kworker/0:0" #0 [ffff8e2370297bf8] __schedule at ffffffffb4f7dbb0 #1 [ffff8e2370297c88] schedule at ffffffffb4f7e199 #2 [ffff8e2370297c98] schedule_timeout at ffffffffb4f7ba68 #3 [ffff8e2370297d40] msleep at ffffffffb48ad9ff #4 [ffff8e2370297d58] qlt_free_session_done at ffffffffc0c32052 [qla2xxx] #5 [ffff8e2370297e20] process_one_work at ffffffffb48bcfdf #6 [ffff8e2370297e68] worker_thread at ffffffffb48bdca6 #7 [ffff8e2370297ec8] kthread at ffffffffb48c4f81
Signed-off-by: Quinn Tran qutran@marvell.com Signed-off-by: Himanshu Madhani hmadhani@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla2xxx/qla_init.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index df91847d20cd0..9cb5527d3d8f1 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -291,9 +291,6 @@ qla2x00_async_logout(struct scsi_qla_host *vha, fc_port_t *fcport) struct srb_iocb *lio; int rval = QLA_FUNCTION_FAILED;
- if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT)) - return rval; - fcport->flags |= FCF_ASYNC_SENT; sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); if (!sp)
From: Bart Van Assche bvanassche@acm.org
[ Upstream commit ac452b8e79320c9e90c78edf32ba2d42431e4daf ]
Pass the correct session ID to find_sess_by_s_id() instead of passing an uninitialized variable.
Cc: Himanshu Madhani hmadhani@marvell.com Fixes: 2d70c103fd2a ("[SCSI] qla2xxx: Add LLD target-mode infrastructure for >= 24xx series") # v3.5. Signed-off-by: Bart Van Assche bvanassche@acm.org Tested-by: Himanshu Madhani hmadhani@marvell.com Reviewed-by: Himanshu Madhani hmadhani@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla2xxx/qla_target.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 078d124533247..2a03d097da7b6 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -6062,7 +6062,6 @@ static void qlt_abort_work(struct qla_tgt *tgt, struct qla_hw_data *ha = vha->hw; struct fc_port *sess = NULL; unsigned long flags = 0, flags2 = 0; - uint32_t be_s_id; uint8_t s_id[3]; int rc;
@@ -6075,8 +6074,7 @@ static void qlt_abort_work(struct qla_tgt *tgt, s_id[1] = prm->abts.fcp_hdr_le.s_id[1]; s_id[2] = prm->abts.fcp_hdr_le.s_id[0];
- sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha, - (unsigned char *)&be_s_id); + sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha, s_id); if (!sess) { spin_unlock_irqrestore(&ha->tgt.sess_lock, flags2);
From: Bart Van Assche bvanassche@acm.org
[ Upstream commit c29282c65d1cf54daeea63be46243d7f69d72f4d ]
Set the r??_data_len variables before using these instead of after.
This patch fixes the following Coverity complaint:
const: At condition req_data_len != rsp_data_len, the value of req_data_len must be equal to 0. const: At condition req_data_len != rsp_data_len, the value of rsp_data_len must be equal to 0. dead_error_condition: The condition req_data_len != rsp_data_len cannot be true.
Cc: Himanshu Madhani hmadhani@marvell.com Fixes: a9b6f722f62d ("[SCSI] qla2xxx: Implementation of bidirectional.") # v3.7. Signed-off-by: Bart Van Assche bvanassche@acm.org Tested-by: Himanshu Madhani hmadhani@marvell.com Reviewed-by: Himanshu Madhani hmadhani@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla2xxx/qla_bsg.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c index b68a708c67251..47f062e96e62c 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c @@ -1779,8 +1779,8 @@ qla24xx_process_bidir_cmd(struct bsg_job *bsg_job) uint16_t nextlid = 0; uint32_t tot_dsds; srb_t *sp = NULL; - uint32_t req_data_len = 0; - uint32_t rsp_data_len = 0; + uint32_t req_data_len; + uint32_t rsp_data_len;
/* Check the type of the adapter */ if (!IS_BIDI_CAPABLE(ha)) { @@ -1885,6 +1885,9 @@ qla24xx_process_bidir_cmd(struct bsg_job *bsg_job) goto done_unmap_sg; }
+ req_data_len = bsg_job->request_payload.payload_len; + rsp_data_len = bsg_job->reply_payload.payload_len; + if (req_data_len != rsp_data_len) { rval = EXT_STATUS_BUSY; ql_log(ql_log_warn, vha, 0x70aa, @@ -1892,10 +1895,6 @@ qla24xx_process_bidir_cmd(struct bsg_job *bsg_job) goto done_unmap_sg; }
- req_data_len = bsg_job->request_payload.payload_len; - rsp_data_len = bsg_job->reply_payload.payload_len; - - /* Alloc SRB structure */ sp = qla2x00_get_sp(vha, &(vha->bidir_fcport), GFP_KERNEL); if (!sp) {
From: Bart Van Assche bvanassche@acm.org
[ Upstream commit e6803efae5acd109fad9f2f07dab674563441a53 ]
This patch fixes several Coverity complaints about not always checking the qla2x00_wait_for_hba_online() return value.
Cc: Himanshu Madhani hmadhani@marvell.com Signed-off-by: Bart Van Assche bvanassche@acm.org Tested-by: Himanshu Madhani hmadhani@marvell.com Reviewed-by: Himanshu Madhani hmadhani@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla2xxx/qla_attr.c | 3 ++- drivers/scsi/qla2xxx/qla_target.c | 7 +++++-- 2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 3e9c49b3184f1..b008d583dd6e1 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -655,7 +655,8 @@ qla2x00_sysfs_write_reset(struct file *filp, struct kobject *kobj, break; } else { /* Make sure FC side is not in reset */ - qla2x00_wait_for_hba_online(vha); + WARN_ON_ONCE(qla2x00_wait_for_hba_online(vha) != + QLA_SUCCESS);
/* Issue MPI reset */ scsi_block_requests(vha->host); diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 2a03d097da7b6..210ce294038df 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -6543,7 +6543,8 @@ qlt_enable_vha(struct scsi_qla_host *vha) } else { set_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags); qla2xxx_wake_dpc(base_vha); - qla2x00_wait_for_hba_online(base_vha); + WARN_ON_ONCE(qla2x00_wait_for_hba_online(base_vha) != + QLA_SUCCESS); } } EXPORT_SYMBOL(qlt_enable_vha); @@ -6573,7 +6574,9 @@ static void qlt_disable_vha(struct scsi_qla_host *vha)
set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); qla2xxx_wake_dpc(vha); - qla2x00_wait_for_hba_online(vha); + if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) + ql_dbg(ql_dbg_tgt, vha, 0xe081, + "qla2x00_wait_for_hba_online() failed\n"); }
/*
From: Himanshu Madhani hmadhani@marvell.com
[ Upstream commit da48b82425b8bf999fb9f7c220e967c4d661b5f8 ]
This patch updates log message which indicates number of vectors used by the driver instead of displaying failure to get maximum requested vectors. Driver will always request maximum vectors during initialization. In the event driver is not able to get maximum requested vectors, it will adjust the allocated vectors. This is normal and does not imply failure in driver.
Signed-off-by: Himanshu Madhani hmadhani@marvell.com Reviewed-by: Ewan D. Milne emilne@redhat.com Reviewed-by: Lee Duncan lduncan@suse.com Link: https://lore.kernel.org/r/20190830222402.23688-2-hmadhani@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla2xxx/qla_isr.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 8fa7242dbb437..afe15b3e45fbf 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -3418,10 +3418,8 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp) ha->msix_count, ret); goto msix_out; } else if (ret < ha->msix_count) { - ql_log(ql_log_warn, vha, 0x00c6, - "MSI-X: Failed to enable support " - "with %d vectors, using %d vectors.\n", - ha->msix_count, ret); + ql_log(ql_log_info, vha, 0x00c6, + "MSI-X: Using %d vectors\n", ret); ha->msix_count = ret; /* Recalculate queue values */ if (ha->mqiobase && (ql2xmqsupport || ql2xnvmeenable)) {
From: Quinn Tran qutran@marvell.com
[ Upstream commit af2a0c51b1205327f55a7e82e530403ae1d42cbb ]
when GPSC/GPDB switch command fails, driver just returns without doing a proper cleanup. This patch fixes this memory leak by calling sp->free() in the error path.
Link: https://lore.kernel.org/r/20191105150657.8092-4-hmadhani@marvell.com Reviewed-by: Ewan D. Milne emilne@redhat.com Signed-off-by: Quinn Tran qutran@marvell.com Signed-off-by: Himanshu Madhani hmadhani@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla2xxx/qla_gs.c | 2 +- drivers/scsi/qla2xxx/qla_init.c | 11 +++++------ drivers/scsi/qla2xxx/qla_mbx.c | 4 ---- drivers/scsi/qla2xxx/qla_mid.c | 11 ++++------- drivers/scsi/qla2xxx/qla_os.c | 7 ++++++- 5 files changed, 16 insertions(+), 19 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index b8d3403c3c85a..f621cb55ccfb2 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c @@ -3264,7 +3264,7 @@ static void qla24xx_async_gpsc_sp_done(void *s, int res) fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
if (res == QLA_FUNCTION_TIMEOUT) - return; + goto done;
if (res == (DID_ERROR << 16)) { /* entry status error */ diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 9cb5527d3d8f1..e6f3a0f5188c4 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -982,13 +982,11 @@ void qla24xx_async_gpdb_sp_done(void *s, int res) "Async done-%s res %x, WWPN %8phC mb[1]=%x mb[2]=%x \n", sp->name, res, fcport->port_name, mb[1], mb[2]);
- if (res == QLA_FUNCTION_TIMEOUT) { - dma_pool_free(sp->vha->hw->s_dma_pool, sp->u.iocb_cmd.u.mbx.in, - sp->u.iocb_cmd.u.mbx.in_dma); - return; - } - fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); + + if (res == QLA_FUNCTION_TIMEOUT) + goto done; + memset(&ea, 0, sizeof(ea)); ea.event = FCME_GPDB_DONE; ea.fcport = fcport; @@ -996,6 +994,7 @@ void qla24xx_async_gpdb_sp_done(void *s, int res)
qla2x00_fcport_event_handler(vha, &ea);
+done: dma_pool_free(ha->s_dma_pool, sp->u.iocb_cmd.u.mbx.in, sp->u.iocb_cmd.u.mbx.in_dma);
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 128fcff24f1be..b01f69dd4b283 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -6131,17 +6131,13 @@ int qla24xx_send_mb_cmd(struct scsi_qla_host *vha, mbx_cmd_t *mcp) case QLA_SUCCESS: ql_dbg(ql_dbg_mbx, vha, 0x119d, "%s: %s done.\n", __func__, sp->name); - sp->free(sp); break; default: ql_dbg(ql_dbg_mbx, vha, 0x119e, "%s: %s Failed. %x.\n", __func__, sp->name, rval); - sp->free(sp); break; }
- return rval; - done_free_sp: sp->free(sp); done: diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index d620f4bebcd0d..516fccdbcebd4 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c @@ -931,7 +931,7 @@ int qla24xx_control_vp(scsi_qla_host_t *vha, int cmd)
sp = qla2x00_get_sp(base_vha, NULL, GFP_KERNEL); if (!sp) - goto done; + return rval;
sp->type = SRB_CTRL_VP; sp->name = "ctrl_vp"; @@ -946,7 +946,7 @@ int qla24xx_control_vp(scsi_qla_host_t *vha, int cmd) ql_dbg(ql_dbg_async, vha, 0xffff, "%s: %s Failed submission. %x.\n", __func__, sp->name, rval); - goto done_free_sp; + goto done; }
ql_dbg(ql_dbg_vport, vha, 0x113f, "%s hndl %x submitted\n", @@ -962,16 +962,13 @@ int qla24xx_control_vp(scsi_qla_host_t *vha, int cmd) case QLA_SUCCESS: ql_dbg(ql_dbg_vport, vha, 0xffff, "%s: %s done.\n", __func__, sp->name); - goto done_free_sp; + break; default: ql_dbg(ql_dbg_vport, vha, 0xffff, "%s: %s Failed. %x.\n", __func__, sp->name, rval); - goto done_free_sp; + break; } done: - return rval; - -done_free_sp: sp->free(sp); return rval; } diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 183bfda8f5d11..bb20a4a228cfe 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -1029,7 +1029,7 @@ qla2xxx_mqueuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd, ql_dbg(ql_dbg_io + ql_dbg_verbose, vha, 0x3078, "Start scsi failed rval=%d for cmd=%p.\n", rval, cmd); if (rval == QLA_INTERFACE_ERROR) - goto qc24_fail_command; + goto qc24_free_sp_fail_command; goto qc24_host_busy_free_sp; }
@@ -1044,6 +1044,11 @@ qc24_host_busy: qc24_target_busy: return SCSI_MLQUEUE_TARGET_BUSY;
+qc24_free_sp_fail_command: + sp->free(sp); + CMD_SP(cmd) = NULL; + qla2xxx_rel_qpair_sp(sp->qpair, sp); + qc24_fail_command: cmd->scsi_done(cmd);
From: Mathias Nyman mathias.nyman@linux.intel.com
[ Upstream commit bd82873f23c9a6ad834348f8b83f3b6a5bca2c65 ]
spin_unlock_irqrestore() might be called with stale flags after reading port status, possibly restoring interrupts to a incorrect state.
If a usb2 port just finished resuming while the port status is read the spin lock will be temporary released and re-acquired in a separate function. The flags parameter is passed as value instead of a pointer, not updating flags properly before the final spin_unlock_irqrestore() is called.
Cc: stable@vger.kernel.org # v3.12+ Fixes: 8b3d45705e54 ("usb: Fix xHCI host issues on remote wakeup.") Signed-off-by: Mathias Nyman mathias.nyman@linux.intel.com Link: https://lore.kernel.org/r/20191211142007.8847-7-mathias.nyman@linux.intel.co... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/host/xhci-hub.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 333f9202ec8be..02843c16f9c78 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -831,7 +831,7 @@ static u32 xhci_get_ext_port_status(u32 raw_port_status, u32 port_li) static u32 xhci_get_port_status(struct usb_hcd *hcd, struct xhci_bus_state *bus_state, u16 wIndex, u32 raw_port_status, - unsigned long flags) + unsigned long *flags) __releases(&xhci->lock) __acquires(&xhci->lock) { @@ -917,12 +917,12 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd, xhci_test_and_clear_bit(xhci, port, PORT_PLC); xhci_set_link_state(xhci, port, XDEV_U0);
- spin_unlock_irqrestore(&xhci->lock, flags); + spin_unlock_irqrestore(&xhci->lock, *flags); time_left = wait_for_completion_timeout( &bus_state->rexit_done[wIndex], msecs_to_jiffies( XHCI_MAX_REXIT_TIMEOUT_MS)); - spin_lock_irqsave(&xhci->lock, flags); + spin_lock_irqsave(&xhci->lock, *flags);
if (time_left) { slot_id = xhci_find_slot_id_by_port(hcd, @@ -1076,7 +1076,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, } trace_xhci_get_port_status(wIndex, temp); status = xhci_get_port_status(hcd, bus_state, wIndex, temp, - flags); + &flags); if (status == 0xffffffff) goto error;
From: Meng Li Meng.Li@windriver.com
[ Upstream commit c270bbf7bb9ddc4e2a51b3c56557c377c9ac79bc ]
The device could be configured to spit out also the configuration word while reading the AD result value (in the same SPI xfer) - this is called "readback" in the device datasheet.
The driver checks if readback is enabled and it eventually adjusts the SPI xfer length and it applies proper shifts to still get the data, discarding the configuration word.
The readback option is actually never enabled (the driver disables it), so the said checks do not serve for any purpose.
Since enabling the readback option seems not to provide any advantage (the driver entirely sets the configuration word without relying on any default value), just kill the said, unused, code.
Signed-off-by: Andrea Merello andrea.merello@gmail.com Reviewed-by: Alexandru Ardelean alexandru.ardelean@analog.com Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/edac/altera_edac.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c index 56de378ad13dc..c9108906bcdc0 100644 --- a/drivers/edac/altera_edac.c +++ b/drivers/edac/altera_edac.c @@ -600,6 +600,7 @@ static const struct regmap_config s10_sdram_regmap_cfg = { .reg_read = s10_protected_reg_read, .reg_write = s10_protected_reg_write, .use_single_rw = true, + .fast_io = true, };
static int altr_s10_sdram_probe(struct platform_device *pdev)
Something nasty seems happening here: it looks like the commit message and the actual diff have nothing to do one wrt the other; the commit message is from one of my patches, the diff is against some unrelated file.
Il giorno lun 16 dic 2019 alle ore 19:05 Greg Kroah-Hartman gregkh@linuxfoundation.org ha scritto:
From: Meng Li Meng.Li@windriver.com
[ Upstream commit c270bbf7bb9ddc4e2a51b3c56557c377c9ac79bc ]
The device could be configured to spit out also the configuration word while reading the AD result value (in the same SPI xfer) - this is called "readback" in the device datasheet.
The driver checks if readback is enabled and it eventually adjusts the SPI xfer length and it applies proper shifts to still get the data, discarding the configuration word.
The readback option is actually never enabled (the driver disables it), so the said checks do not serve for any purpose.
Since enabling the readback option seems not to provide any advantage (the driver entirely sets the configuration word without relying on any default value), just kill the said, unused, code.
Signed-off-by: Andrea Merello andrea.merello@gmail.com Reviewed-by: Alexandru Ardelean alexandru.ardelean@analog.com Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org
drivers/edac/altera_edac.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c index 56de378ad13dc..c9108906bcdc0 100644 --- a/drivers/edac/altera_edac.c +++ b/drivers/edac/altera_edac.c @@ -600,6 +600,7 @@ static const struct regmap_config s10_sdram_regmap_cfg = { .reg_read = s10_protected_reg_read, .reg_write = s10_protected_reg_write, .use_single_rw = true,
.fast_io = true,
};
static int altr_s10_sdram_probe(struct platform_device *pdev)
2.20.1
On Mon, Dec 16, 2019 at 07:31:31PM +0100, Andrea Merello wrote:
Something nasty seems happening here: it looks like the commit message and the actual diff have nothing to do one wrt the other; the commit message is from one of my patches, the diff is against some unrelated file.
Il giorno lun 16 dic 2019 alle ore 19:05 Greg Kroah-Hartman gregkh@linuxfoundation.org ha scritto:
From: Meng Li Meng.Li@windriver.com
[ Upstream commit c270bbf7bb9ddc4e2a51b3c56557c377c9ac79bc ]
The device could be configured to spit out also the configuration word while reading the AD result value (in the same SPI xfer) - this is called "readback" in the device datasheet.
The driver checks if readback is enabled and it eventually adjusts the SPI xfer length and it applies proper shifts to still get the data, discarding the configuration word.
The readback option is actually never enabled (the driver disables it), so the said checks do not serve for any purpose.
Since enabling the readback option seems not to provide any advantage (the driver entirely sets the configuration word without relying on any default value), just kill the said, unused, code.
Signed-off-by: Andrea Merello andrea.merello@gmail.com Reviewed-by: Alexandru Ardelean alexandru.ardelean@analog.com Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org
drivers/edac/altera_edac.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c index 56de378ad13dc..c9108906bcdc0 100644 --- a/drivers/edac/altera_edac.c +++ b/drivers/edac/altera_edac.c @@ -600,6 +600,7 @@ static const struct regmap_config s10_sdram_regmap_cfg = { .reg_read = s10_protected_reg_read, .reg_write = s10_protected_reg_write, .use_single_rw = true,
.fast_io = true,
};
static int altr_s10_sdram_probe(struct platform_device *pdev)
2.20.1
Wow, something went wrong.
Sasha, can you look into this?
thanks,
greg k-h
On Mon, Dec 16, 2019 at 07:45:36PM +0100, Greg Kroah-Hartman wrote:
On Mon, Dec 16, 2019 at 07:31:31PM +0100, Andrea Merello wrote:
Something nasty seems happening here: it looks like the commit message and the actual diff have nothing to do one wrt the other; the commit message is from one of my patches, the diff is against some unrelated file.
Il giorno lun 16 dic 2019 alle ore 19:05 Greg Kroah-Hartman gregkh@linuxfoundation.org ha scritto:
From: Meng Li Meng.Li@windriver.com
[ Upstream commit c270bbf7bb9ddc4e2a51b3c56557c377c9ac79bc ]
The device could be configured to spit out also the configuration word while reading the AD result value (in the same SPI xfer) - this is called "readback" in the device datasheet.
The driver checks if readback is enabled and it eventually adjusts the SPI xfer length and it applies proper shifts to still get the data, discarding the configuration word.
The readback option is actually never enabled (the driver disables it), so the said checks do not serve for any purpose.
Since enabling the readback option seems not to provide any advantage (the driver entirely sets the configuration word without relying on any default value), just kill the said, unused, code.
Signed-off-by: Andrea Merello andrea.merello@gmail.com Reviewed-by: Alexandru Ardelean alexandru.ardelean@analog.com Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org
drivers/edac/altera_edac.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c index 56de378ad13dc..c9108906bcdc0 100644 --- a/drivers/edac/altera_edac.c +++ b/drivers/edac/altera_edac.c @@ -600,6 +600,7 @@ static const struct regmap_config s10_sdram_regmap_cfg = { .reg_read = s10_protected_reg_read, .reg_write = s10_protected_reg_write, .use_single_rw = true,
.fast_io = true,
};
static int altr_s10_sdram_probe(struct platform_device *pdev)
2.20.1
Wow, something went wrong.
Sasha, can you look into this?
Yikes, sorry - this is one of the commits that needed to be manually backported, and I must have copy pasted the wrong commit hash to use as the commit message.
This really is 56d9e7bd3fa0 ("EDAC/altera: Use fast register IO for S10 IRQs") which needs to be in the stable tree, I'll go fix up the message.
From: Wen Yang wenyang@linux.alibaba.com
[ Upstream commit 5c388abefda0d92355714010c0199055c57ab6c7 ]
We can't use "port->sw" and/or "port->mux" after it has been freed.
Fixes: 23481121c81d ("usb: typec: class: Don't use port parent for getting mux handles") Signed-off-by: Wen Yang wenyang@linux.alibaba.com Cc: stable stable@vger.kernel.org Cc: linux-usb@vger.kernel.org Cc: linux-kernel@vger.kernel.org Acked-by: Heikki Krogerus heikki.krogerus@linux.intel.com Link: https://lore.kernel.org/r/20191126140452.14048-1-wenyang@linux.alibaba.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/typec/class.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c index 00141e05bc724..1916ee1600b47 100644 --- a/drivers/usb/typec/class.c +++ b/drivers/usb/typec/class.c @@ -1589,14 +1589,16 @@ struct typec_port *typec_register_port(struct device *parent,
port->sw = typec_switch_get(&port->dev); if (IS_ERR(port->sw)) { + ret = PTR_ERR(port->sw); put_device(&port->dev); - return ERR_CAST(port->sw); + return ERR_PTR(ret); }
port->mux = typec_mux_get(&port->dev, "typec-mux"); if (IS_ERR(port->mux)) { + ret = PTR_ERR(port->mux); put_device(&port->dev); - return ERR_CAST(port->mux); + return ERR_PTR(ret); }
ret = device_add(&port->dev);
From: H. Nikolaus Schaller hns@goldelico.com
[ Upstream commit 2398c41d64321e62af54424fd399964f3d48cdc2 ]
With a wl1251 child node of mmc3 in the device tree decoded in omap_hsmmc.c to handle special wl1251 initialization, we do no longer need to instantiate the mmc3 through pdata quirks.
We also can remove the wlan regulator and reset/interrupt definitions and do them through device tree.
Fixes: 81eef6ca9201 ("mmc: omap_hsmmc: Use dma_request_chan() for requesting DMA channel") Signed-off-by: H. Nikolaus Schaller hns@goldelico.com Cc: stable@vger.kernel.org # v4.7+ Acked-by: Tony Lindgren tony@atomide.com Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/mach-omap2/pdata-quirks.c | 93 ------------------------------ 1 file changed, 93 deletions(-)
diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c index 7f02743edbe4c..dae7262287704 100644 --- a/arch/arm/mach-omap2/pdata-quirks.c +++ b/arch/arm/mach-omap2/pdata-quirks.c @@ -305,108 +305,15 @@ static void __init omap3_logicpd_torpedo_init(void) }
/* omap3pandora legacy devices */ -#define PANDORA_WIFI_IRQ_GPIO 21 -#define PANDORA_WIFI_NRESET_GPIO 23
static struct platform_device pandora_backlight = { .name = "pandora-backlight", .id = -1, };
-static struct regulator_consumer_supply pandora_vmmc3_supply[] = { - REGULATOR_SUPPLY("vmmc", "omap_hsmmc.2"), -}; - -static struct regulator_init_data pandora_vmmc3 = { - .constraints = { - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - }, - .num_consumer_supplies = ARRAY_SIZE(pandora_vmmc3_supply), - .consumer_supplies = pandora_vmmc3_supply, -}; - -static struct fixed_voltage_config pandora_vwlan = { - .supply_name = "vwlan", - .microvolts = 1800000, /* 1.8V */ - .gpio = PANDORA_WIFI_NRESET_GPIO, - .startup_delay = 50000, /* 50ms */ - .enable_high = 1, - .init_data = &pandora_vmmc3, -}; - -static struct platform_device pandora_vwlan_device = { - .name = "reg-fixed-voltage", - .id = 1, - .dev = { - .platform_data = &pandora_vwlan, - }, -}; - -static void pandora_wl1251_init_card(struct mmc_card *card) -{ - /* - * We have TI wl1251 attached to MMC3. Pass this information to - * SDIO core because it can't be probed by normal methods. - */ - if (card->type == MMC_TYPE_SDIO || card->type == MMC_TYPE_SD_COMBO) { - card->quirks |= MMC_QUIRK_NONSTD_SDIO; - card->cccr.wide_bus = 1; - card->cis.vendor = 0x104c; - card->cis.device = 0x9066; - card->cis.blksize = 512; - card->cis.max_dtr = 24000000; - card->ocr = 0x80; - } -} - -static struct omap2_hsmmc_info pandora_mmc3[] = { - { - .mmc = 3, - .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD, - .gpio_cd = -EINVAL, - .gpio_wp = -EINVAL, - .init_card = pandora_wl1251_init_card, - }, - {} /* Terminator */ -}; - -static void __init pandora_wl1251_init(void) -{ - struct wl1251_platform_data pandora_wl1251_pdata; - int ret; - - memset(&pandora_wl1251_pdata, 0, sizeof(pandora_wl1251_pdata)); - - pandora_wl1251_pdata.power_gpio = -1; - - ret = gpio_request_one(PANDORA_WIFI_IRQ_GPIO, GPIOF_IN, "wl1251 irq"); - if (ret < 0) - goto fail; - - pandora_wl1251_pdata.irq = gpio_to_irq(PANDORA_WIFI_IRQ_GPIO); - if (pandora_wl1251_pdata.irq < 0) - goto fail_irq; - - pandora_wl1251_pdata.use_eeprom = true; - ret = wl1251_set_platform_data(&pandora_wl1251_pdata); - if (ret < 0) - goto fail_irq; - - return; - -fail_irq: - gpio_free(PANDORA_WIFI_IRQ_GPIO); -fail: - pr_err("wl1251 board initialisation failed\n"); -} - static void __init omap3_pandora_legacy_init(void) { platform_device_register(&pandora_backlight); - platform_device_register(&pandora_vwlan_device); - omap_hsmmc_init(pandora_mmc3); - omap_hsmmc_late_init(pandora_mmc3); - pandora_wl1251_init(); } #endif /* CONFIG_ARCH_OMAP3 */
From: James Smart jsmart2021@gmail.com
[ Upstream commit 8b47ae69e049ae0b3373859d901f0334322f9fe9 ]
Depending on the chipset, the number of NPIV vports may vary and be in excess of what most switches support (256). To avoid confusion with the users, limit the reported NPIV vports to 256.
Additionally correct the 16G adapter which is reporting a bogus NPIV vport number if the link is down.
Signed-off-by: Dick Kennedy dick.kennedy@broadcom.com Signed-off-by: James Smart jsmart2021@gmail.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/lpfc/lpfc.h | 3 ++- drivers/scsi/lpfc/lpfc_attr.c | 12 ++++++++++-- drivers/scsi/lpfc/lpfc_init.c | 3 +++ 3 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index a62e85cb62eb2..706aca3f7c253 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -966,7 +966,8 @@ struct lpfc_hba { struct list_head port_list; struct lpfc_vport *pport; /* physical lpfc_vport pointer */ uint16_t max_vpi; /* Maximum virtual nports */ -#define LPFC_MAX_VPI 0xFFFF /* Max number of VPI supported */ +#define LPFC_MAX_VPI 0xFF /* Max number VPI supported 0 - 0xff */ +#define LPFC_MAX_VPORTS 0x100 /* Max vports per port, with pport */ uint16_t max_vports; /* * For IOV HBAs max_vpi can change * after a reset. max_vports is max diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 3f69a5e4e470a..1e9002138d31c 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -1632,6 +1632,9 @@ lpfc_get_hba_info(struct lpfc_hba *phba, max_vpi = (bf_get(lpfc_mbx_rd_conf_vpi_count, rd_config) > 0) ? (bf_get(lpfc_mbx_rd_conf_vpi_count, rd_config) - 1) : 0;
+ /* Limit the max we support */ + if (max_vpi > LPFC_MAX_VPI) + max_vpi = LPFC_MAX_VPI; if (mvpi) *mvpi = max_vpi; if (avpi) @@ -1647,8 +1650,13 @@ lpfc_get_hba_info(struct lpfc_hba *phba, *axri = pmb->un.varRdConfig.avail_xri; if (mvpi) *mvpi = pmb->un.varRdConfig.max_vpi; - if (avpi) - *avpi = pmb->un.varRdConfig.avail_vpi; + if (avpi) { + /* avail_vpi is only valid if link is up and ready */ + if (phba->link_state == LPFC_HBA_READY) + *avpi = pmb->un.varRdConfig.avail_vpi; + else + *avpi = pmb->un.varRdConfig.max_vpi; + } }
mempool_free(pmboxq, phba->mbox_mem_pool); diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index da63c026ba460..57510a831735b 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -7766,6 +7766,9 @@ lpfc_sli4_read_config(struct lpfc_hba *phba) bf_get(lpfc_mbx_rd_conf_xri_base, rd_config); phba->sli4_hba.max_cfg_param.max_vpi = bf_get(lpfc_mbx_rd_conf_vpi_count, rd_config); + /* Limit the max we support */ + if (phba->sli4_hba.max_cfg_param.max_vpi > LPFC_MAX_VPORTS) + phba->sli4_hba.max_cfg_param.max_vpi = LPFC_MAX_VPORTS; phba->sli4_hba.max_cfg_param.vpi_base = bf_get(lpfc_mbx_rd_conf_vpi_base, rd_config); phba->sli4_hba.max_cfg_param.max_rpi =
From: James Smart jsmart2021@gmail.com
[ Upstream commit 1c36833d82ff24d0d54215fd956e7cc30fffce54 ]
Driver is setting bits in word 10 of the SLI4 ABORT WQE (the wqid). The field was a carry over from a prior SLI revision. The field does not exist in SLI4, and the action may result in an overlap with future definition of the WQE.
Remove the setting of WQID in the ABORT WQE.
Also cleaned up WQE field settings - initialize to zero, don't bother to set fields to zero.
Signed-off-by: Dick Kennedy dick.kennedy@broadcom.com Signed-off-by: James Smart jsmart2021@gmail.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/lpfc/lpfc_nvme.c | 2 -- drivers/scsi/lpfc/lpfc_sli.c | 14 +++----------- 2 files changed, 3 insertions(+), 13 deletions(-)
diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index 8ee585e453dcf..f73726e55e44d 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c @@ -1856,7 +1856,6 @@ lpfc_nvme_fcp_abort(struct nvme_fc_local_port *pnvme_lport, bf_set(abort_cmd_criteria, &abts_wqe->abort_cmd, T_XRI_TAG);
/* word 7 */ - bf_set(wqe_ct, &abts_wqe->abort_cmd.wqe_com, 0); bf_set(wqe_cmnd, &abts_wqe->abort_cmd.wqe_com, CMD_ABORT_XRI_CX); bf_set(wqe_class, &abts_wqe->abort_cmd.wqe_com, nvmereq_wqe->iocb.ulpClass); @@ -1871,7 +1870,6 @@ lpfc_nvme_fcp_abort(struct nvme_fc_local_port *pnvme_lport, abts_buf->iotag);
/* word 10 */ - bf_set(wqe_wqid, &abts_wqe->abort_cmd.wqe_com, nvmereq_wqe->hba_wqidx); bf_set(wqe_qosd, &abts_wqe->abort_cmd.wqe_com, 1); bf_set(wqe_lenloc, &abts_wqe->abort_cmd.wqe_com, LPFC_WQE_LENLOC_NONE);
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 755803ff6cfef..f459fd62e493c 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -10989,19 +10989,12 @@ lpfc_sli4_abort_nvme_io(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
/* Complete prepping the abort wqe and issue to the FW. */ abts_wqe = &abtsiocbp->wqe; - bf_set(abort_cmd_ia, &abts_wqe->abort_cmd, 0); - bf_set(abort_cmd_criteria, &abts_wqe->abort_cmd, T_XRI_TAG); - - /* Explicitly set reserved fields to zero.*/ - abts_wqe->abort_cmd.rsrvd4 = 0; - abts_wqe->abort_cmd.rsrvd5 = 0;
- /* WQE Common - word 6. Context is XRI tag. Set 0. */ - bf_set(wqe_xri_tag, &abts_wqe->abort_cmd.wqe_com, 0); - bf_set(wqe_ctxt_tag, &abts_wqe->abort_cmd.wqe_com, 0); + /* Clear any stale WQE contents */ + memset(abts_wqe, 0, sizeof(union lpfc_wqe)); + bf_set(abort_cmd_criteria, &abts_wqe->abort_cmd, T_XRI_TAG);
/* word 7 */ - bf_set(wqe_ct, &abts_wqe->abort_cmd.wqe_com, 0); bf_set(wqe_cmnd, &abts_wqe->abort_cmd.wqe_com, CMD_ABORT_XRI_CX); bf_set(wqe_class, &abts_wqe->abort_cmd.wqe_com, cmdiocb->iocb.ulpClass); @@ -11016,7 +11009,6 @@ lpfc_sli4_abort_nvme_io(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, abtsiocbp->iotag);
/* word 10 */ - bf_set(wqe_wqid, &abts_wqe->abort_cmd.wqe_com, cmdiocb->hba_wqidx); bf_set(wqe_qosd, &abts_wqe->abort_cmd.wqe_com, 1); bf_set(wqe_lenloc, &abts_wqe->abort_cmd.wqe_com, LPFC_WQE_LENLOC_NONE);
From: James Smart jsmart2021@gmail.com
[ Upstream commit 76558b25733140a0c6bd53ea8af04b2811c92ec3 ]
Driver missed classifying the chip type for G7 when reporting supported topologies. This resulted in loop being shown as supported on FC links that are not supported per the standard.
Add the chip classifications to the topology checks in the driver.
Signed-off-by: Dick Kennedy dick.kennedy@broadcom.com Signed-off-by: James Smart jsmart2021@gmail.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/lpfc/lpfc_attr.c | 5 +++-- drivers/scsi/lpfc/lpfc_mbox.c | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 1e9002138d31c..fe084d47ed9e5 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -3849,8 +3849,9 @@ lpfc_topology_store(struct device *dev, struct device_attribute *attr, val); return -EINVAL; } - if (phba->pcidev->device == PCI_DEVICE_ID_LANCER_G6_FC && - val == 4) { + if ((phba->pcidev->device == PCI_DEVICE_ID_LANCER_G6_FC || + phba->pcidev->device == PCI_DEVICE_ID_LANCER_G7_FC) && + val == 4) { lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, "3114 Loop mode not supported\n"); return -EINVAL; diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c index deb094fdbb793..e6bf5e8bc7670 100644 --- a/drivers/scsi/lpfc/lpfc_mbox.c +++ b/drivers/scsi/lpfc/lpfc_mbox.c @@ -513,9 +513,9 @@ lpfc_init_link(struct lpfc_hba * phba, break; }
- if (phba->pcidev->device == PCI_DEVICE_ID_LANCER_G6_FC && - mb->un.varInitLnk.link_flags & FLAGS_TOPOLOGY_MODE_LOOP) { - /* Failover is not tried for Lancer G6 */ + if ((phba->pcidev->device == PCI_DEVICE_ID_LANCER_G6_FC || + phba->pcidev->device == PCI_DEVICE_ID_LANCER_G7_FC) && + mb->un.varInitLnk.link_flags & FLAGS_TOPOLOGY_MODE_LOOP) { mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_PT_PT; phba->cfg_topology = FLAGS_TOPOLOGY_MODE_PT_PT; }
From: Nathan Chancellor natechancellor@gmail.com
[ Upstream commit 5816a0932b4fd74257b8cc5785bc8067186a8723 ]
Clang warns when an implicit conversion is done between enumerated types:
drivers/block/drbd/drbd_state.c:708:8: warning: implicit conversion from enumeration type 'enum drbd_ret_code' to different enumeration type 'enum drbd_state_rv' [-Wenum-conversion] rv = ERR_INTR; ~ ^~~~~~~~
drbd_request_detach_interruptible's only call site is in the return statement of adm_detach, which returns an int. Change the return type of drbd_request_detach_interruptible to match, silencing Clang's warning.
Reported-by: Nick Desaulniers ndesaulniers@google.com Reviewed-by: Nick Desaulniers ndesaulniers@google.com Signed-off-by: Nathan Chancellor natechancellor@gmail.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/drbd/drbd_state.c | 6 ++---- drivers/block/drbd/drbd_state.h | 3 +-- 2 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c index 0813c654c8938..b452359b6aae8 100644 --- a/drivers/block/drbd/drbd_state.c +++ b/drivers/block/drbd/drbd_state.c @@ -688,11 +688,9 @@ request_detach(struct drbd_device *device) CS_VERBOSE | CS_ORDERED | CS_INHIBIT_MD_IO); }
-enum drbd_state_rv -drbd_request_detach_interruptible(struct drbd_device *device) +int drbd_request_detach_interruptible(struct drbd_device *device) { - enum drbd_state_rv rv; - int ret; + int ret, rv;
drbd_suspend_io(device); /* so no-one is stuck in drbd_al_begin_io */ wait_event_interruptible(device->state_wait, diff --git a/drivers/block/drbd/drbd_state.h b/drivers/block/drbd/drbd_state.h index b2a390ba73a05..f87371e55e682 100644 --- a/drivers/block/drbd/drbd_state.h +++ b/drivers/block/drbd/drbd_state.h @@ -162,8 +162,7 @@ static inline int drbd_request_state(struct drbd_device *device, }
/* for use in adm_detach() (drbd_adm_detach(), drbd_adm_down()) */ -enum drbd_state_rv -drbd_request_detach_interruptible(struct drbd_device *device); +int drbd_request_detach_interruptible(struct drbd_device *device);
enum drbd_role conn_highest_role(struct drbd_connection *connection); enum drbd_role conn_highest_peer(struct drbd_connection *connection);
From: YueHaibing yuehaibing@huawei.com
[ Upstream commit cd0d465bb697a9c7bf66a9fe940f7981232f1676 ]
Fix a static code checker warning: drivers/net/ethernet/intel/e100.c:1349 e100_load_ucode_wait() warn: passing zero to 'PTR_ERR'
Signed-off-by: YueHaibing yuehaibing@huawei.com Tested-by: Aaron Brown aaron.f.brown@intel.com Signed-off-by: Jeff Kirsher jeffrey.t.kirsher@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/e100.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/intel/e100.c b/drivers/net/ethernet/intel/e100.c index 27d5f27163d2c..78b44d7876386 100644 --- a/drivers/net/ethernet/intel/e100.c +++ b/drivers/net/ethernet/intel/e100.c @@ -1345,8 +1345,8 @@ static inline int e100_load_ucode_wait(struct nic *nic)
fw = e100_request_firmware(nic); /* If it's NULL, then no ucode is required */ - if (!fw || IS_ERR(fw)) - return PTR_ERR(fw); + if (IS_ERR_OR_NULL(fw)) + return PTR_ERR_OR_ZERO(fw);
if ((err = e100_exec_cb(nic, (void *)fw, e100_setup_ucode))) netif_err(nic, probe, nic->netdev,
From: Stefano Stabellini sstabellini@kernel.org
[ Upstream commit d90a1ca60a1eccb4383fe203c76223ab4c0799ed ]
When the ring is full, size == array_size. It is not an error condition, so simply return 0 instead of an error.
Signed-off-by: Stefano Stabellini stefanos@xilinx.com Reviewed-by: Boris Ostrovsky boris.ostrovsky@oracle.com Signed-off-by: Boris Ostrovsky boris.ostrovsky@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/xen/pvcalls-front.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c index 3a144eecb6a72..d7438fdc57061 100644 --- a/drivers/xen/pvcalls-front.c +++ b/drivers/xen/pvcalls-front.c @@ -504,8 +504,10 @@ static int __write_ring(struct pvcalls_data_intf *intf, virt_mb();
size = pvcalls_queued(prod, cons, array_size); - if (size >= array_size) + if (size > array_size) return -EINVAL; + if (size == array_size) + return 0; if (len > array_size - size) len = array_size - size;
From: Toke Høiland-Jørgensen toke@redhat.com
[ Upstream commit 8c6c37fdc20ec9ffaa342f827a8e20afe736fb0c ]
To ensure parent qdiscs have the same notion of the number of enqueued packets even after splitting a GSO packet, update the qdisc tree with the number of packets that was added due to the split.
Reported-by: Pete Heist pete@heistp.net Tested-by: Pete Heist pete@heistp.net Signed-off-by: Toke Høiland-Jørgensen toke@redhat.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/sched/sch_cake.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/net/sched/sch_cake.c b/net/sched/sch_cake.c index 9fd37d91b5ed0..e4cf72b0675e1 100644 --- a/net/sched/sch_cake.c +++ b/net/sched/sch_cake.c @@ -1666,7 +1666,7 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, if (skb_is_gso(skb) && q->rate_flags & CAKE_FLAG_SPLIT_GSO) { struct sk_buff *segs, *nskb; netdev_features_t features = netif_skb_features(skb); - unsigned int slen = 0; + unsigned int slen = 0, numsegs = 0;
segs = skb_gso_segment(skb, features & ~NETIF_F_GSO_MASK); if (IS_ERR_OR_NULL(segs)) @@ -1682,6 +1682,7 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, flow_queue_add(flow, segs);
sch->q.qlen++; + numsegs++; slen += segs->len; q->buffer_used += segs->truesize; b->packets++; @@ -1695,7 +1696,7 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, sch->qstats.backlog += slen; q->avg_window_bytes += slen;
- qdisc_tree_reduce_backlog(sch, 1, len); + qdisc_tree_reduce_backlog(sch, 1-numsegs, len-slen); consume_skb(skb); } else { /* not splitting */
From: Karsten Graul kgraul@linux.ibm.com
[ Upstream commit 33f3fcc290671590821ff3c0c9396db1ec9b7d4c ]
smc_cdc_get_free_slot() might wait for free transfer buffers when using SMC-R. This wait should not be done under the send_lock, which is a spin_lock. This fixes a cpu loop in parallel threads waiting for the send_lock.
Signed-off-by: Karsten Graul kgraul@linux.ibm.com Signed-off-by: Ursula Braun ubraun@linux.ibm.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/smc/smc_tx.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/net/smc/smc_tx.c b/net/smc/smc_tx.c index 0ecbbdc337b82..62885a2781c9a 100644 --- a/net/smc/smc_tx.c +++ b/net/smc/smc_tx.c @@ -486,25 +486,23 @@ static int smcr_tx_sndbuf_nonempty(struct smc_connection *conn) struct smc_wr_buf *wr_buf; int rc;
- spin_lock_bh(&conn->send_lock); rc = smc_cdc_get_free_slot(conn, &wr_buf, &pend); if (rc < 0) { if (rc == -EBUSY) { struct smc_sock *smc = container_of(conn, struct smc_sock, conn);
- if (smc->sk.sk_err == ECONNABORTED) { - rc = sock_error(&smc->sk); - goto out_unlock; - } + if (smc->sk.sk_err == ECONNABORTED) + return sock_error(&smc->sk); rc = 0; if (conn->alert_token_local) /* connection healthy */ mod_delayed_work(system_wq, &conn->tx_work, SMC_TX_WORK_DELAY); } - goto out_unlock; + return rc; }
+ spin_lock_bh(&conn->send_lock); if (!conn->local_tx_ctrl.prod_flags.urg_data_present) { rc = smc_tx_rdma_writes(conn); if (rc) {
From: Jian Shen shenjian15@huawei.com
[ Upstream commit ac864c2346d087dd3739435af1b8d36be5f60c75 ]
When unload hns3 driver, we should clear the pci private data.
Signed-off-by: Jian Shen shenjian15@huawei.com Signed-off-by: Peng Li lipeng321@huawei.com Signed-off-by: Huazhong Tan tanhuazhong@huawei.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c index b2860087a7dc7..4b4d9de0a6bb5 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c @@ -1620,6 +1620,7 @@ static void hns3_remove(struct pci_dev *pdev) hns3_disable_sriov(pdev);
hnae3_unregister_ae_dev(ae_dev); + pci_set_drvdata(pdev, NULL); }
/**
From: Huazhong Tan tanhuazhong@huawei.com
[ Upstream commit 74354140a579008fd164241e3697d9c37e5b8989 ]
hnae3_register_ae_dev() may fail, and it should return a error code to its caller, so change hnae3_register_ae_dev() return type to int.
Also, when hnae3_register_ae_dev() return error, hns3_probe() should do some error handling and return the error code.
Signed-off-by: Huazhong Tan tanhuazhong@huawei.com Signed-off-by: Peng Li lipeng321@huawei.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/hisilicon/hns3/hnae3.c | 10 +++++++++- drivers/net/ethernet/hisilicon/hns3/hnae3.h | 2 +- drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 8 ++++++-- 3 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.c b/drivers/net/ethernet/hisilicon/hns3/hnae3.c index 2097f92e14c5c..f98bff60bec37 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.c +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.c @@ -239,7 +239,7 @@ EXPORT_SYMBOL(hnae3_unregister_ae_algo); * @ae_dev: the AE device * NOTE: the duplicated name will not be checked */ -void hnae3_register_ae_dev(struct hnae3_ae_dev *ae_dev) +int hnae3_register_ae_dev(struct hnae3_ae_dev *ae_dev) { const struct pci_device_id *id; struct hnae3_ae_algo *ae_algo; @@ -260,6 +260,7 @@ void hnae3_register_ae_dev(struct hnae3_ae_dev *ae_dev)
if (!ae_dev->ops) { dev_err(&ae_dev->pdev->dev, "ae_dev ops are null\n"); + ret = -EOPNOTSUPP; goto out_err; }
@@ -286,8 +287,15 @@ void hnae3_register_ae_dev(struct hnae3_ae_dev *ae_dev) ret); }
+ mutex_unlock(&hnae3_common_lock); + + return 0; + out_err: + list_del(&ae_dev->node); mutex_unlock(&hnae3_common_lock); + + return ret; } EXPORT_SYMBOL(hnae3_register_ae_dev);
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h index f5c7fc9c5e5cc..5e1a7ab06c63b 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h @@ -513,7 +513,7 @@ struct hnae3_handle { #define hnae3_get_bit(origin, shift) \ hnae3_get_field((origin), (0x1 << (shift)), (shift))
-void hnae3_register_ae_dev(struct hnae3_ae_dev *ae_dev); +int hnae3_register_ae_dev(struct hnae3_ae_dev *ae_dev); void hnae3_unregister_ae_dev(struct hnae3_ae_dev *ae_dev);
void hnae3_unregister_ae_algo(struct hnae3_ae_algo *ae_algo); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c index 4b4d9de0a6bb5..0788e78747d94 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c @@ -1604,9 +1604,13 @@ static int hns3_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ae_dev->dev_type = HNAE3_DEV_KNIC; pci_set_drvdata(pdev, ae_dev);
- hnae3_register_ae_dev(ae_dev); + ret = hnae3_register_ae_dev(ae_dev); + if (ret) { + devm_kfree(&pdev->dev, ae_dev); + pci_set_drvdata(pdev, NULL); + }
- return 0; + return ret; }
/* hns3_remove - Device removal routine
From: Yonglong Liu liuyonglong@huawei.com
[ Upstream commit 676131f7c53ecdd79e29fc8cfcdefe6f9f2485e8 ]
In hnae3_register_ae_dev(), ae_algo->ops is assigned to ae_dev->ops before check that ae_algo->ops is valid.
And in hnae3_register_ae_algo(), missing check for ae_algo->ops.
This patch fixes them.
Signed-off-by: Yonglong Liu liuyonglong@huawei.com Signed-off-by: Peng Li lipeng321@huawei.com Signed-off-by: Huazhong Tan tanhuazhong@huawei.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/hisilicon/hns3/hnae3.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.c b/drivers/net/ethernet/hisilicon/hns3/hnae3.c index f98bff60bec37..f9259e568fa05 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.c +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.c @@ -173,8 +173,12 @@ void hnae3_register_ae_algo(struct hnae3_ae_algo *ae_algo) if (!id) continue;
- /* ae_dev init should set flag */ + if (!ae_algo->ops) { + dev_err(&ae_dev->pdev->dev, "ae_algo ops are null\n"); + continue; + } ae_dev->ops = ae_algo->ops; + ret = ae_algo->ops->init_ae_dev(ae_dev); if (ret) { dev_err(&ae_dev->pdev->dev, @@ -182,6 +186,7 @@ void hnae3_register_ae_algo(struct hnae3_ae_algo *ae_algo) continue; }
+ /* ae_dev init should set flag */ hnae3_set_bit(ae_dev->flag, HNAE3_DEV_INITED_B, 1);
/* check the client list for the match with this ae_dev type and @@ -256,15 +261,13 @@ int hnae3_register_ae_dev(struct hnae3_ae_dev *ae_dev) if (!id) continue;
- ae_dev->ops = ae_algo->ops; - - if (!ae_dev->ops) { - dev_err(&ae_dev->pdev->dev, "ae_dev ops are null\n"); + if (!ae_algo->ops) { + dev_err(&ae_dev->pdev->dev, "ae_algo ops are null\n"); ret = -EOPNOTSUPP; goto out_err; } + ae_dev->ops = ae_algo->ops;
- /* ae_dev init should set flag */ ret = ae_dev->ops->init_ae_dev(ae_dev); if (ret) { dev_err(&ae_dev->pdev->dev, @@ -272,6 +275,7 @@ int hnae3_register_ae_dev(struct hnae3_ae_dev *ae_dev) goto out_err; }
+ /* ae_dev init should set flag */ hnae3_set_bit(ae_dev->flag, HNAE3_DEV_INITED_B, 1); break; }
From: Xiang Chen chenxiang66@hisilicon.com
[ Upstream commit 569eddcf3a0f4efff4ef96a7012010e0f7daa8b4 ]
Send primitive NOTIFY to SSP situation only, or it causes underflow issue when sending IO. Also rename hisi_sas_hw.sl_notify() to hisi_sas_hw. sl_notify_ssp().
Signed-off-by: Xiang Chen chenxiang66@hisilicon.com Signed-off-by: John Garry john.garry@huawei.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/hisi_sas/hisi_sas.h | 2 +- drivers/scsi/hisi_sas/hisi_sas_main.c | 3 ++- drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 4 ++-- drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 4 ++-- drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 4 ++-- 5 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 6c7d2e201abed..d499c44661661 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -220,7 +220,7 @@ struct hisi_sas_hw { int (*slot_index_alloc)(struct hisi_hba *hisi_hba, int *slot_idx, struct domain_device *device); struct hisi_sas_device *(*alloc_dev)(struct domain_device *device); - void (*sl_notify)(struct hisi_hba *hisi_hba, int phy_no); + void (*sl_notify_ssp)(struct hisi_hba *hisi_hba, int phy_no); int (*get_free_slot)(struct hisi_hba *hisi_hba, struct hisi_sas_dq *dq); void (*start_delivery)(struct hisi_sas_dq *dq); void (*prep_ssp)(struct hisi_hba *hisi_hba, diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index f478d1f50dfc0..0ad8875c30e8e 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -716,7 +716,8 @@ static void hisi_sas_phyup_work(struct work_struct *work) struct asd_sas_phy *sas_phy = &phy->sas_phy; int phy_no = sas_phy->id;
- hisi_hba->hw->sl_notify(hisi_hba, phy_no); /* This requires a sleep */ + if (phy->identify.target_port_protocols == SAS_PROTOCOL_SSP) + hisi_hba->hw->sl_notify_ssp(hisi_hba, phy_no); hisi_sas_bytes_dmaed(hisi_hba, phy_no); }
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index 410eccf0bc5eb..8aa3222fe4865 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -834,7 +834,7 @@ static void phys_init_v1_hw(struct hisi_hba *hisi_hba) mod_timer(timer, jiffies + HZ); }
-static void sl_notify_v1_hw(struct hisi_hba *hisi_hba, int phy_no) +static void sl_notify_ssp_v1_hw(struct hisi_hba *hisi_hba, int phy_no) { u32 sl_control;
@@ -1822,7 +1822,7 @@ static struct scsi_host_template sht_v1_hw = { static const struct hisi_sas_hw hisi_sas_v1_hw = { .hw_init = hisi_sas_v1_init, .setup_itct = setup_itct_v1_hw, - .sl_notify = sl_notify_v1_hw, + .sl_notify_ssp = sl_notify_ssp_v1_hw, .clear_itct = clear_itct_v1_hw, .prep_smp = prep_smp_v1_hw, .prep_ssp = prep_ssp_v1_hw, diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c index c4774d63d5d04..ebc984ffe6a22 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c @@ -1584,7 +1584,7 @@ static void phys_init_v2_hw(struct hisi_hba *hisi_hba) } }
-static void sl_notify_v2_hw(struct hisi_hba *hisi_hba, int phy_no) +static void sl_notify_ssp_v2_hw(struct hisi_hba *hisi_hba, int phy_no) { u32 sl_control;
@@ -3575,7 +3575,7 @@ static const struct hisi_sas_hw hisi_sas_v2_hw = { .setup_itct = setup_itct_v2_hw, .slot_index_alloc = slot_index_alloc_quirk_v2_hw, .alloc_dev = alloc_dev_quirk_v2_hw, - .sl_notify = sl_notify_v2_hw, + .sl_notify_ssp = sl_notify_ssp_v2_hw, .get_wideport_bitmap = get_wideport_bitmap_v2_hw, .clear_itct = clear_itct_v2_hw, .free_device = free_device_v2_hw, diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index a7407d5376ba2..ce2f232b3df38 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -827,7 +827,7 @@ static void phys_init_v3_hw(struct hisi_hba *hisi_hba) } }
-static void sl_notify_v3_hw(struct hisi_hba *hisi_hba, int phy_no) +static void sl_notify_ssp_v3_hw(struct hisi_hba *hisi_hba, int phy_no) { u32 sl_control;
@@ -2127,7 +2127,7 @@ static const struct hisi_sas_hw hisi_sas_v3_hw = { .get_wideport_bitmap = get_wideport_bitmap_v3_hw, .complete_hdr_size = sizeof(struct hisi_sas_complete_v3_hdr), .clear_itct = clear_itct_v3_hw, - .sl_notify = sl_notify_v3_hw, + .sl_notify_ssp = sl_notify_ssp_v3_hw, .prep_ssp = prep_ssp_v3_hw, .prep_smp = prep_smp_v3_hw, .prep_stp = prep_ata_v3_hw,
From: Luo Jiaxing luojiaxing@huawei.com
[ Upstream commit eb44e4d7b5a3090f0114927f42ae575c29664a09 ]
The SAS controller cannot support a programmed minimum linkrate of > 1.5G (it will always negotiate to 1.5G at least), so just reject it.
This solves a strange situation where the PHY negotiated linkrate may be less than the programmed minimum linkrate.
Signed-off-by: Luo Jiaxing luojiaxing@huawei.com Signed-off-by: John Garry john.garry@huawei.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/hisi_sas/hisi_sas_main.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 0ad8875c30e8e..f35c56217694b 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -886,7 +886,7 @@ static int hisi_sas_queue_command(struct sas_task *task, gfp_t gfp_flags) return hisi_sas_task_exec(task, gfp_flags, 0, NULL); }
-static void hisi_sas_phy_set_linkrate(struct hisi_hba *hisi_hba, int phy_no, +static int hisi_sas_phy_set_linkrate(struct hisi_hba *hisi_hba, int phy_no, struct sas_phy_linkrates *r) { struct sas_phy_linkrates _r; @@ -895,6 +895,9 @@ static void hisi_sas_phy_set_linkrate(struct hisi_hba *hisi_hba, int phy_no, struct asd_sas_phy *sas_phy = &phy->sas_phy; enum sas_linkrate min, max;
+ if (r->minimum_linkrate > SAS_LINK_RATE_1_5_GBPS) + return -EINVAL; + if (r->maximum_linkrate == SAS_LINK_RATE_UNKNOWN) { max = sas_phy->phy->maximum_linkrate; min = r->minimum_linkrate; @@ -902,7 +905,7 @@ static void hisi_sas_phy_set_linkrate(struct hisi_hba *hisi_hba, int phy_no, max = r->maximum_linkrate; min = sas_phy->phy->minimum_linkrate; } else - return; + return -EINVAL;
_r.maximum_linkrate = max; _r.minimum_linkrate = min; @@ -914,6 +917,8 @@ static void hisi_sas_phy_set_linkrate(struct hisi_hba *hisi_hba, int phy_no, msleep(100); hisi_hba->hw->phy_set_linkrate(hisi_hba, phy_no, &_r); hisi_hba->hw->phy_start(hisi_hba, phy_no); + + return 0; }
static int hisi_sas_control_phy(struct asd_sas_phy *sas_phy, enum phy_func func, @@ -939,8 +944,7 @@ static int hisi_sas_control_phy(struct asd_sas_phy *sas_phy, enum phy_func func, break;
case PHY_FUNC_SET_LINK_RATE: - hisi_sas_phy_set_linkrate(hisi_hba, phy_no, funcdata); - break; + return hisi_sas_phy_set_linkrate(hisi_hba, phy_no, funcdata); case PHY_FUNC_GET_EVENTS: if (hisi_hba->hw->get_events) { hisi_hba->hw->get_events(hisi_hba, phy_no);
From: Shirish S Shirish.S@amd.com
[ Upstream commit c95b323dcd3598dd7ef5005d6723c1ba3b801093 ]
MC4_MISC thresholding is not supported on all family 0x15 processors, hence skip the x86_model check when applying the quirk.
[ bp: massage commit message. ]
Signed-off-by: Shirish S shirish.s@amd.com Signed-off-by: Borislav Petkov bp@suse.de Cc: "H. Peter Anvin" hpa@zytor.com Cc: Ingo Molnar mingo@redhat.com Cc: Thomas Gleixner tglx@linutronix.de Cc: Tony Luck tony.luck@intel.com Cc: Vishal Verma vishal.l.verma@intel.com Cc: x86-ml x86@kernel.org Link: https://lkml.kernel.org/r/1547106849-3476-2-git-send-email-shirish.s@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/kernel/cpu/mcheck/mce.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index fee118b3b69fd..a0bc7f7570814 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c @@ -1632,11 +1632,10 @@ static int __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c) mce_flags.overflow_recov = 1;
/* - * Turn off MC4_MISC thresholding banks on those models since + * Turn off MC4_MISC thresholding banks on all models since * they're not supported there. */ - if (c->x86 == 0x15 && - (c->x86_model >= 0x10 && c->x86_model <= 0x1f)) { + if (c->x86 == 0x15) { int i; u64 hwcr; bool need_toggle;
From: Shirish S Shirish.S@amd.com
[ Upstream commit 30aa3d26edb0f3d7992757287eec0ca588a5c259 ]
The MC4_MISC thresholding quirk needs to be applied during S5 -> S0 and S3 -> S0 state transitions, which follow different code paths. Carve it out into a separate function and call it mce_amd_feature_init() where the two code paths of the state transitions converge.
[ bp: massage commit message and the carved out function. ]
Signed-off-by: Shirish S shirish.s@amd.com Signed-off-by: Borislav Petkov bp@suse.de Cc: "H. Peter Anvin" hpa@zytor.com Cc: Ingo Molnar mingo@redhat.com Cc: Kees Cook keescook@chromium.org Cc: Thomas Gleixner tglx@linutronix.de Cc: Tony Luck tony.luck@intel.com Cc: Vishal Verma vishal.l.verma@intel.com Cc: Yazen Ghannam yazen.ghannam@amd.com Cc: x86-ml x86@kernel.org Link: https://lkml.kernel.org/r/1547651417-23583-3-git-send-email-shirish.s@amd.co... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/kernel/cpu/mcheck/mce.c | 29 ---------------------- arch/x86/kernel/cpu/mcheck/mce_amd.c | 36 ++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 29 deletions(-)
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index a0bc7f7570814..87ed8462a5c72 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c @@ -1631,35 +1631,6 @@ static int __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c) if (c->x86 == 0x15 && c->x86_model <= 0xf) mce_flags.overflow_recov = 1;
- /* - * Turn off MC4_MISC thresholding banks on all models since - * they're not supported there. - */ - if (c->x86 == 0x15) { - int i; - u64 hwcr; - bool need_toggle; - u32 msrs[] = { - 0x00000413, /* MC4_MISC0 */ - 0xc0000408, /* MC4_MISC1 */ - }; - - rdmsrl(MSR_K7_HWCR, hwcr); - - /* McStatusWrEn has to be set */ - need_toggle = !(hwcr & BIT(18)); - - if (need_toggle) - wrmsrl(MSR_K7_HWCR, hwcr | BIT(18)); - - /* Clear CntP bit safely */ - for (i = 0; i < ARRAY_SIZE(msrs); i++) - msr_clear_bit(msrs[i], 62); - - /* restore old settings */ - if (need_toggle) - wrmsrl(MSR_K7_HWCR, hwcr); - } }
if (c->x86_vendor == X86_VENDOR_INTEL) { diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c index 9f915a8791cc7..5bdfe52b2c9d9 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c @@ -545,6 +545,40 @@ out: return offset; }
+/* + * Turn off MC4_MISC thresholding banks on all family 0x15 models since + * they're not supported there. + */ +void disable_err_thresholding(struct cpuinfo_x86 *c) +{ + int i; + u64 hwcr; + bool need_toggle; + u32 msrs[] = { + 0x00000413, /* MC4_MISC0 */ + 0xc0000408, /* MC4_MISC1 */ + }; + + if (c->x86 != 0x15) + return; + + rdmsrl(MSR_K7_HWCR, hwcr); + + /* McStatusWrEn has to be set */ + need_toggle = !(hwcr & BIT(18)); + + if (need_toggle) + wrmsrl(MSR_K7_HWCR, hwcr | BIT(18)); + + /* Clear CntP bit safely */ + for (i = 0; i < ARRAY_SIZE(msrs); i++) + msr_clear_bit(msrs[i], 62); + + /* restore old settings */ + if (need_toggle) + wrmsrl(MSR_K7_HWCR, hwcr); +} + /* cpu init entry point, called from mce.c with preempt off */ void mce_amd_feature_init(struct cpuinfo_x86 *c) { @@ -552,6 +586,8 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c) unsigned int bank, block, cpu = smp_processor_id(); int offset = -1;
+ disable_err_thresholding(c); + for (bank = 0; bank < mca_cfg.banks; ++bank) { if (mce_flags.smca) smca_configure(bank, cpu);
From: Tony Lindgren tony@atomide.com
[ Upstream commit c68b901ac4fa969db8917b6a9f9b40524a690d20 ]
The accumulator sample register is signed 32-bits wide register on droid 4. And only the earlier version of cpcap has a signed 24-bits wide register. We're currently passing it around as unsigned, so let's fix that and use sign_extend32() for the earlier revision.
Signed-off-by: Tony Lindgren tony@atomide.com Acked-by: Pavel Machek pavel@ucw.cz Signed-off-by: Sebastian Reichel sebastian.reichel@collabora.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/power/supply/cpcap-battery.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/drivers/power/supply/cpcap-battery.c b/drivers/power/supply/cpcap-battery.c index 3bae02380bb22..e183a22de7153 100644 --- a/drivers/power/supply/cpcap-battery.c +++ b/drivers/power/supply/cpcap-battery.c @@ -82,7 +82,7 @@ struct cpcap_battery_config { };
struct cpcap_coulomb_counter_data { - s32 sample; /* 24-bits */ + s32 sample; /* 24 or 32 bits */ s32 accumulator; s16 offset; /* 10-bits */ }; @@ -213,7 +213,7 @@ static int cpcap_battery_get_current(struct cpcap_battery_ddata *ddata) * TI or ST coulomb counter in the PMIC. */ static int cpcap_battery_cc_raw_div(struct cpcap_battery_ddata *ddata, - u32 sample, s32 accumulator, + s32 sample, s32 accumulator, s16 offset, u32 divider) { s64 acc; @@ -224,7 +224,6 @@ static int cpcap_battery_cc_raw_div(struct cpcap_battery_ddata *ddata, if (!divider) return 0;
- sample &= 0xffffff; /* 24-bits, unsigned */ offset &= 0x7ff; /* 10-bits, signed */
switch (ddata->vendor) { @@ -259,7 +258,7 @@ static int cpcap_battery_cc_raw_div(struct cpcap_battery_ddata *ddata,
/* 3600000μAms = 1μAh */ static int cpcap_battery_cc_to_uah(struct cpcap_battery_ddata *ddata, - u32 sample, s32 accumulator, + s32 sample, s32 accumulator, s16 offset) { return cpcap_battery_cc_raw_div(ddata, sample, @@ -268,7 +267,7 @@ static int cpcap_battery_cc_to_uah(struct cpcap_battery_ddata *ddata, }
static int cpcap_battery_cc_to_ua(struct cpcap_battery_ddata *ddata, - u32 sample, s32 accumulator, + s32 sample, s32 accumulator, s16 offset) { return cpcap_battery_cc_raw_div(ddata, sample, @@ -312,6 +311,8 @@ cpcap_battery_read_accumulated(struct cpcap_battery_ddata *ddata, /* Sample value CPCAP_REG_CCS1 & 2 */ ccd->sample = (buf[1] & 0x0fff) << 16; ccd->sample |= buf[0]; + if (ddata->vendor == CPCAP_VENDOR_TI) + ccd->sample = sign_extend32(24, ccd->sample);
/* Accumulator value CPCAP_REG_CCA1 & 2 */ ccd->accumulator = ((s16)buf[3]) << 16;
From: Ido Schimmel idosch@mellanox.com
[ Upstream commit 83d5782681cc12b3d485a83cb34c46b2445f510c ]
The driver tries to periodically refresh neighbours that are used to reach nexthops. This is done by periodically calling neigh_event_send().
However, if the neighbour becomes dead, there is nothing we can do to return it to a connected state and the above function call is basically a NOP.
This results in the nexthop never being written to the device's adjacency table and therefore never used to forward packets.
Fix this by dropping our reference from the dead neighbour and associating the nexthop with a new neigbhour which we will try to refresh.
Fixes: a7ff87acd995 ("mlxsw: spectrum_router: Implement next-hop routing") Signed-off-by: Ido Schimmel idosch@mellanox.com Reported-by: Alex Veber alexve@mellanox.com Tested-by: Alex Veber alexve@mellanox.com Acked-by: Jiri Pirko jiri@mellanox.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- .../ethernet/mellanox/mlxsw/spectrum_router.c | 73 ++++++++++++++++++- 1 file changed, 70 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c index 44b6c2ac5961d..76960d3adfc03 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c @@ -2228,7 +2228,7 @@ static void mlxsw_sp_router_probe_unresolved_nexthops(struct work_struct *work) static void mlxsw_sp_nexthop_neigh_update(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_neigh_entry *neigh_entry, - bool removing); + bool removing, bool dead);
static enum mlxsw_reg_rauht_op mlxsw_sp_rauht_op(bool adding) { @@ -2359,7 +2359,8 @@ static void mlxsw_sp_router_neigh_event_work(struct work_struct *work)
memcpy(neigh_entry->ha, ha, ETH_ALEN); mlxsw_sp_neigh_entry_update(mlxsw_sp, neigh_entry, entry_connected); - mlxsw_sp_nexthop_neigh_update(mlxsw_sp, neigh_entry, !entry_connected); + mlxsw_sp_nexthop_neigh_update(mlxsw_sp, neigh_entry, !entry_connected, + dead);
if (!neigh_entry->connected && list_empty(&neigh_entry->nexthop_list)) mlxsw_sp_neigh_entry_destroy(mlxsw_sp, neigh_entry); @@ -3323,13 +3324,79 @@ static void __mlxsw_sp_nexthop_neigh_update(struct mlxsw_sp_nexthop *nh, nh->update = 1; }
+static int +mlxsw_sp_nexthop_dead_neigh_replace(struct mlxsw_sp *mlxsw_sp, + struct mlxsw_sp_neigh_entry *neigh_entry) +{ + struct neighbour *n, *old_n = neigh_entry->key.n; + struct mlxsw_sp_nexthop *nh; + bool entry_connected; + u8 nud_state, dead; + int err; + + nh = list_first_entry(&neigh_entry->nexthop_list, + struct mlxsw_sp_nexthop, neigh_list_node); + + n = neigh_lookup(nh->nh_grp->neigh_tbl, &nh->gw_addr, nh->rif->dev); + if (!n) { + n = neigh_create(nh->nh_grp->neigh_tbl, &nh->gw_addr, + nh->rif->dev); + if (IS_ERR(n)) + return PTR_ERR(n); + neigh_event_send(n, NULL); + } + + mlxsw_sp_neigh_entry_remove(mlxsw_sp, neigh_entry); + neigh_entry->key.n = n; + err = mlxsw_sp_neigh_entry_insert(mlxsw_sp, neigh_entry); + if (err) + goto err_neigh_entry_insert; + + read_lock_bh(&n->lock); + nud_state = n->nud_state; + dead = n->dead; + read_unlock_bh(&n->lock); + entry_connected = nud_state & NUD_VALID && !dead; + + list_for_each_entry(nh, &neigh_entry->nexthop_list, + neigh_list_node) { + neigh_release(old_n); + neigh_clone(n); + __mlxsw_sp_nexthop_neigh_update(nh, !entry_connected); + mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh->nh_grp); + } + + neigh_release(n); + + return 0; + +err_neigh_entry_insert: + neigh_entry->key.n = old_n; + mlxsw_sp_neigh_entry_insert(mlxsw_sp, neigh_entry); + neigh_release(n); + return err; +} + static void mlxsw_sp_nexthop_neigh_update(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_neigh_entry *neigh_entry, - bool removing) + bool removing, bool dead) { struct mlxsw_sp_nexthop *nh;
+ if (list_empty(&neigh_entry->nexthop_list)) + return; + + if (dead) { + int err; + + err = mlxsw_sp_nexthop_dead_neigh_replace(mlxsw_sp, + neigh_entry); + if (err) + dev_err(mlxsw_sp->bus_info->dev, "Failed to replace dead neigh\n"); + return; + } + list_for_each_entry(nh, &neigh_entry->nexthop_list, neigh_list_node) { __mlxsw_sp_nexthop_neigh_update(nh, removing);
From: Helen Koike helen.koike@collabora.com
[ Upstream commit ee1c71a8e1456ab53fe667281d855849edf26a4d ]
If the system has other devices being registered in the component framework, the compare function will be called with a device that doesn't belong to vimc. This device is not necessarily a platform_device, nor have a platform_data (which causes a NULL pointer dereference error) and if it does have a pdata, it is not necessarily type of struct vimc_platform_data. So casting to any of these types is wrong.
Instead of expecting a given pdev with a given pdata, just expect for the device it self. vimc-core is the one who creates them, we know in advance exactly which object to expect in the match.
Fixes: 4a29b7090749 ("[media] vimc: Subdevices as modules")
Signed-off-by: Helen Koike helen.koike@collabora.com Reviewed-by: Boris Brezillon boris.brezillon@collabora.com Tested-by: Boris Brezillon boris.brezillon@collabora.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+samsung@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/vimc/vimc-core.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/media/platform/vimc/vimc-core.c b/drivers/media/platform/vimc/vimc-core.c index 27db8835c2410..8548fa93bcf65 100644 --- a/drivers/media/platform/vimc/vimc-core.c +++ b/drivers/media/platform/vimc/vimc-core.c @@ -243,10 +243,7 @@ static void vimc_comp_unbind(struct device *master)
static int vimc_comp_compare(struct device *comp, void *data) { - const struct platform_device *pdev = to_platform_device(comp); - const char *name = data; - - return !strcmp(pdev->dev.platform_data, name); + return comp == data; }
static struct component_match *vimc_add_subdevs(struct vimc_device *vimc) @@ -276,7 +273,7 @@ static struct component_match *vimc_add_subdevs(struct vimc_device *vimc) }
component_match_add(&vimc->pdev.dev, &match, vimc_comp_compare, - (void *)vimc->pipe_cfg->ents[i].name); + &vimc->subdevs[i]->dev); }
return match;
From: Miaoqing Pan miaoqing@codeaurora.org
[ Upstream commit 08d80e4cd27ba19f9bee9e5f788f9a9fc440a22f ]
On SMP platform, when continuously running wifi up/down, the napi poll can be scheduled during chip reset, which will call ath10k_pci_has_fw_crashed() to check the fw status. But in the reset period, the value from FW_INDICATOR_ADDRESS register will return 0xdeadbeef, which also be treated as fw crash. Fix the issue by moving chip reset after napi disabled.
ath10k_pci 0000:01:00.0: firmware crashed! (guid 73b30611-5b1e-4bdd-90b4-64c81eb947b6) ath10k_pci 0000:01:00.0: qca9984/qca9994 hw1.0 target 0x01000000 chip_id 0x00000000 sub 168c:cafe ath10k_pci 0000:01:00.0: htt-ver 2.2 wmi-op 6 htt-op 4 cal otp max-sta 512 raw 0 hwcrypto 1 ath10k_pci 0000:01:00.0: failed to get memcpy hi address for firmware address 4: -16 ath10k_pci 0000:01:00.0: failed to read firmware dump area: -16 ath10k_pci 0000:01:00.0: Copy Engine register dump: ath10k_pci 0000:01:00.0: [00]: 0x0004a000 0 0 0 0 ath10k_pci 0000:01:00.0: [01]: 0x0004a400 0 0 0 0 ath10k_pci 0000:01:00.0: [02]: 0x0004a800 0 0 0 0 ath10k_pci 0000:01:00.0: [03]: 0x0004ac00 0 0 0 0 ath10k_pci 0000:01:00.0: [04]: 0x0004b000 0 0 0 0 ath10k_pci 0000:01:00.0: [05]: 0x0004b400 0 0 0 0 ath10k_pci 0000:01:00.0: [06]: 0x0004b800 0 0 0 0 ath10k_pci 0000:01:00.0: [07]: 0x0004bc00 1 0 1 0 ath10k_pci 0000:01:00.0: [08]: 0x0004c000 0 0 0 0 ath10k_pci 0000:01:00.0: [09]: 0x0004c400 0 0 0 0 ath10k_pci 0000:01:00.0: [10]: 0x0004c800 0 0 0 0 ath10k_pci 0000:01:00.0: [11]: 0x0004cc00 0 0 0 0
Tested HW: QCA9984,QCA9887,WCN3990
Signed-off-by: Miaoqing Pan miaoqing@codeaurora.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath10k/pci.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index 50a801a5d4f15..2a503aacf0c64 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -2052,6 +2052,11 @@ static void ath10k_pci_hif_stop(struct ath10k *ar)
ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif stop\n");
+ ath10k_pci_irq_disable(ar); + ath10k_pci_irq_sync(ar); + napi_synchronize(&ar->napi); + napi_disable(&ar->napi); + /* Most likely the device has HTT Rx ring configured. The only way to * prevent the device from accessing (and possible corrupting) host * memory is to reset the chip now. @@ -2065,10 +2070,6 @@ static void ath10k_pci_hif_stop(struct ath10k *ar) */ ath10k_pci_safe_chip_reset(ar);
- ath10k_pci_irq_disable(ar); - ath10k_pci_irq_sync(ar); - napi_synchronize(&ar->napi); - napi_disable(&ar->napi); ath10k_pci_flush(ar);
spin_lock_irqsave(&ar_pci->ps_lock, flags);
From: Anders Roxell anders.roxell@linaro.org
[ Upstream commit 6f10419187d0d5fe395e2a2f2a64370961bf02a3 ]
When building with CONFIG_MFD_88PM800 and CONFIG_REGULATOR_88PM800 enabled as loadable modules, we see the following warning:
warning: same module names found: drivers/regulator/88pm800.ko drivers/mfd/88pm800.ko
Rework so that the file is named 88pm800-regulator.
Signed-off-by: Anders Roxell anders.roxell@linaro.org Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/regulator/{88pm800.c => 88pm800-regulator.c} | 0 drivers/regulator/Makefile | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename drivers/regulator/{88pm800.c => 88pm800-regulator.c} (100%)
diff --git a/drivers/regulator/88pm800.c b/drivers/regulator/88pm800-regulator.c similarity index 100% rename from drivers/regulator/88pm800.c rename to drivers/regulator/88pm800-regulator.c diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 801d9a34a2037..bba9c4851faf3 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -11,7 +11,7 @@ obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o
obj-$(CONFIG_REGULATOR_88PG86X) += 88pg86x.o -obj-$(CONFIG_REGULATOR_88PM800) += 88pm800.o +obj-$(CONFIG_REGULATOR_88PM800) += 88pm800-regulator.o obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o obj-$(CONFIG_REGULATOR_CPCAP) += cpcap-regulator.o obj-$(CONFIG_REGULATOR_AAT2870) += aat2870-regulator.o
From: Nathan Chancellor natechancellor@gmail.com
[ Upstream commit c9029ef9c95765e7b63c4d9aa780674447db1ec0 ]
Commit aea447141c7e ("powerpc: Disable -Wbuiltin-requires-header when setjmp is used") disabled -Wbuiltin-requires-header because of a warning about the setjmp and longjmp declarations.
r367387 in clang added another diagnostic around this, complaining that there is no jmp_buf declaration.
In file included from ../arch/powerpc/xmon/xmon.c:47: ../arch/powerpc/include/asm/setjmp.h:10:13: error: declaration of built-in function 'setjmp' requires the declaration of the 'jmp_buf' type, commonly provided in the header <setjmp.h>. [-Werror,-Wincomplete-setjmp-declaration] extern long setjmp(long *); ^ ../arch/powerpc/include/asm/setjmp.h:11:13: error: declaration of built-in function 'longjmp' requires the declaration of the 'jmp_buf' type, commonly provided in the header <setjmp.h>. [-Werror,-Wincomplete-setjmp-declaration] extern void longjmp(long *, long); ^ 2 errors generated.
We are not using the standard library's longjmp/setjmp implementations for obvious reasons; make this clear to clang by using -ffreestanding on these files.
Cc: stable@vger.kernel.org # 4.14+ Suggested-by: Segher Boessenkool segher@kernel.crashing.org Reviewed-by: Nick Desaulniers ndesaulniers@google.com Signed-off-by: Nathan Chancellor natechancellor@gmail.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20191119045712.39633-3-natechancellor@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/kernel/Makefile | 4 ++-- arch/powerpc/xmon/Makefile | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index eac18790d1b15..d450280e5c29c 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -5,8 +5,8 @@
CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"'
-# Disable clang warning for using setjmp without setjmp.h header -CFLAGS_crash.o += $(call cc-disable-warning, builtin-requires-header) +# Avoid clang warnings around longjmp/setjmp declarations +CFLAGS_crash.o += -ffreestanding
subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
diff --git a/arch/powerpc/xmon/Makefile b/arch/powerpc/xmon/Makefile index 9ba44e190e5e4..365e711bebabb 100644 --- a/arch/powerpc/xmon/Makefile +++ b/arch/powerpc/xmon/Makefile @@ -1,8 +1,8 @@ # SPDX-License-Identifier: GPL-2.0 # Makefile for xmon
-# Disable clang warning for using setjmp without setjmp.h header -subdir-ccflags-y := $(call cc-disable-warning, builtin-requires-header) +# Avoid clang warnings around longjmp/setjmp declarations +subdir-ccflags-y := -ffreestanding
subdir-ccflags-$(CONFIG_PPC_WERROR) += -Werror
From: Vincenzo Frascino vincenzo.frascino@arm.com
[ Upstream commit 552263456215ada7ee8700ce022d12b0cffe4802 ]
clock_getres in the vDSO library has to preserve the same behaviour of posix_get_hrtimer_res().
In particular, posix_get_hrtimer_res() does: sec = 0; ns = hrtimer_resolution; and hrtimer_resolution depends on the enablement of the high resolution timers that can happen either at compile or at run time.
Fix the powerpc vdso implementation of clock_getres keeping a copy of hrtimer_resolution in vdso data and using that directly.
Fixes: a7f290dad32e ("[PATCH] powerpc: Merge vdso's and add vdso support to 32 bits kernel") Cc: stable@vger.kernel.org Signed-off-by: Vincenzo Frascino vincenzo.frascino@arm.com Reviewed-by: Christophe Leroy christophe.leroy@c-s.fr Acked-by: Shuah Khan skhan@linuxfoundation.org [chleroy: changed CLOCK_REALTIME_RES to CLOCK_HRTIMER_RES] Signed-off-by: Christophe Leroy christophe.leroy@c-s.fr Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/a55eca3a5e85233838c2349783bcb5164dae1d09.157527321... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/include/asm/vdso_datapage.h | 2 ++ arch/powerpc/kernel/asm-offsets.c | 2 +- arch/powerpc/kernel/time.c | 1 + arch/powerpc/kernel/vdso32/gettimeofday.S | 7 +++++-- arch/powerpc/kernel/vdso64/gettimeofday.S | 7 +++++-- 5 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/arch/powerpc/include/asm/vdso_datapage.h b/arch/powerpc/include/asm/vdso_datapage.h index bbc06bd72b1f2..4333b9a473dc4 100644 --- a/arch/powerpc/include/asm/vdso_datapage.h +++ b/arch/powerpc/include/asm/vdso_datapage.h @@ -86,6 +86,7 @@ struct vdso_data { __s32 wtom_clock_nsec; /* Wall to monotonic clock nsec */ __s64 wtom_clock_sec; /* Wall to monotonic clock sec */ struct timespec stamp_xtime; /* xtime as at tb_orig_stamp */ + __u32 hrtimer_res; /* hrtimer resolution */ __u32 syscall_map_64[SYSCALL_MAP_SIZE]; /* map of syscalls */ __u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */ }; @@ -107,6 +108,7 @@ struct vdso_data { __s32 wtom_clock_nsec; struct timespec stamp_xtime; /* xtime as at tb_orig_stamp */ __u32 stamp_sec_fraction; /* fractional seconds of stamp_xtime */ + __u32 hrtimer_res; /* hrtimer resolution */ __u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */ __u32 dcache_block_size; /* L1 d-cache block size */ __u32 icache_block_size; /* L1 i-cache block size */ diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 7c3738d890e8b..50400f213bbf2 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -379,6 +379,7 @@ int main(void) OFFSET(WTOM_CLOCK_NSEC, vdso_data, wtom_clock_nsec); OFFSET(STAMP_XTIME, vdso_data, stamp_xtime); OFFSET(STAMP_SEC_FRAC, vdso_data, stamp_sec_fraction); + OFFSET(CLOCK_HRTIMER_RES, vdso_data, hrtimer_res); OFFSET(CFG_ICACHE_BLOCKSZ, vdso_data, icache_block_size); OFFSET(CFG_DCACHE_BLOCKSZ, vdso_data, dcache_block_size); OFFSET(CFG_ICACHE_LOGBLOCKSZ, vdso_data, icache_log_block_size); @@ -409,7 +410,6 @@ int main(void) DEFINE(CLOCK_REALTIME_COARSE, CLOCK_REALTIME_COARSE); DEFINE(CLOCK_MONOTONIC_COARSE, CLOCK_MONOTONIC_COARSE); DEFINE(NSEC_PER_SEC, NSEC_PER_SEC); - DEFINE(CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC);
#ifdef CONFIG_BUG DEFINE(BUG_ENTRY_SIZE, sizeof(struct bug_entry)); diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 7707990c4c169..8487ad6864621 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -929,6 +929,7 @@ void update_vsyscall(struct timekeeper *tk) vdso_data->wtom_clock_nsec = tk->wall_to_monotonic.tv_nsec; vdso_data->stamp_xtime = xt; vdso_data->stamp_sec_fraction = frac_sec; + vdso_data->hrtimer_res = hrtimer_resolution; smp_wmb(); ++(vdso_data->tb_update_count); } diff --git a/arch/powerpc/kernel/vdso32/gettimeofday.S b/arch/powerpc/kernel/vdso32/gettimeofday.S index afd516b572f86..49eecd28aef1e 100644 --- a/arch/powerpc/kernel/vdso32/gettimeofday.S +++ b/arch/powerpc/kernel/vdso32/gettimeofday.S @@ -160,12 +160,15 @@ V_FUNCTION_BEGIN(__kernel_clock_getres) cror cr0*4+eq,cr0*4+eq,cr1*4+eq bne cr0,99f
+ mflr r12 + .cfi_register lr,r12 + bl __get_datapage@local /* get data page */ + lwz r5, CLOCK_HRTIMER_RES(r3) + mtlr r12 li r3,0 cmpli cr0,r4,0 crclr cr0*4+so beqlr - lis r5,CLOCK_REALTIME_RES@h - ori r5,r5,CLOCK_REALTIME_RES@l stw r3,TSPC32_TV_SEC(r4) stw r5,TSPC32_TV_NSEC(r4) blr diff --git a/arch/powerpc/kernel/vdso64/gettimeofday.S b/arch/powerpc/kernel/vdso64/gettimeofday.S index 1f324c28705bc..020e90d1079dd 100644 --- a/arch/powerpc/kernel/vdso64/gettimeofday.S +++ b/arch/powerpc/kernel/vdso64/gettimeofday.S @@ -190,12 +190,15 @@ V_FUNCTION_BEGIN(__kernel_clock_getres) cror cr0*4+eq,cr0*4+eq,cr1*4+eq bne cr0,99f
+ mflr r12 + .cfi_register lr,r12 + bl V_LOCAL_FUNC(__get_datapage) + lwz r5, CLOCK_HRTIMER_RES(r3) + mtlr r12 li r3,0 cmpldi cr0,r4,0 crclr cr0*4+so beqlr - lis r5,CLOCK_REALTIME_RES@h - ori r5,r5,CLOCK_REALTIME_RES@l std r3,TSPC64_TV_SEC(r4) std r5,TSPC64_TV_NSEC(r4) blr
From: Theodore Ts'o tytso@mit.edu
commit c7df4a1ecb8579838ec8c56b2bb6a6716e974f37 upstream.
If the file system is corrupted such that a file's i_links_count is too small, then it's possible that when unlinking that file, i_nlink will already be zero. Previously we were working around this kind of corruption by forcing i_nlink to one; but we were doing this before trying to delete the directory entry --- and if the file system is corrupted enough that ext4_delete_entry() fails, then we exit with i_nlink elevated, and this causes the orphan inode list handling to be FUBAR'ed, such that when we unmount the file system, the orphan inode list can get corrupted.
A better way to fix this is to simply skip trying to call drop_nlink() if i_nlink is already zero, thus moving the check to the place where it makes the most sense.
https://bugzilla.kernel.org/show_bug.cgi?id=205433
Link: https://lore.kernel.org/r/20191112032903.8828-1-tytso@mit.edu Signed-off-by: Theodore Ts'o tytso@mit.edu Cc: stable@kernel.org Reviewed-by: Andreas Dilger adilger@dilger.ca Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/ext4/namei.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
--- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -3056,18 +3056,17 @@ static int ext4_unlink(struct inode *dir if (IS_DIRSYNC(dir)) ext4_handle_sync(handle);
- if (inode->i_nlink == 0) { - ext4_warning_inode(inode, "Deleting file '%.*s' with no links", - dentry->d_name.len, dentry->d_name.name); - set_nlink(inode, 1); - } retval = ext4_delete_entry(handle, dir, de, bh); if (retval) goto end_unlink; dir->i_ctime = dir->i_mtime = current_time(dir); ext4_update_dx_flag(dir); ext4_mark_inode_dirty(handle, dir); - drop_nlink(inode); + if (inode->i_nlink == 0) + ext4_warning_inode(inode, "Deleting file '%.*s' with no links", + dentry->d_name.len, dentry->d_name.name); + else + drop_nlink(inode); if (!inode->i_nlink) ext4_orphan_add(handle, inode); inode->i_ctime = current_time(inode);
From: Will Deacon will@kernel.org
commit ff34f3cce278a0982a7b66b1afaed6295141b1fc upstream.
The 'a0' member of 'struct arm_smccc_res' is declared as 'unsigned long', however the Qualcomm SCM firmware interface driver expects to receive negative error codes via this field, so ensure that it's cast to 'long' before comparing to see if it is less than 0.
Cc: stable@vger.kernel.org Reviewed-by: Bjorn Andersson bjorn.andersson@linaro.org Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/firmware/qcom_scm-64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/firmware/qcom_scm-64.c +++ b/drivers/firmware/qcom_scm-64.c @@ -158,7 +158,7 @@ static int qcom_scm_call(struct device * kfree(args_virt); }
- if (res->a0 < 0) + if ((long)res->a0 < 0) return qcom_scm_remap_error(res->a0);
return 0;
From: Chen Jun chenjun102@huawei.com
commit aa71ecd8d86500da6081a72da6b0b524007e0627 upstream.
In 64bit system. sb->s_maxbytes of shmem filesystem is MAX_LFS_FILESIZE, which equal LLONG_MAX.
If offset > LLONG_MAX - PAGE_SIZE, offset + len < LLONG_MAX in shmem_fallocate, which will pass the checking in vfs_fallocate.
/* Check for wrap through zero too */ if (((offset + len) > inode->i_sb->s_maxbytes) || ((offset + len) < 0)) return -EFBIG;
loff_t unmap_start = round_up(offset, PAGE_SIZE) in shmem_fallocate causes a overflow.
Syzkaller reports a overflow problem in mm/shmem:
UBSAN: Undefined behaviour in mm/shmem.c:2014:10 signed integer overflow: '9223372036854775807 + 1' cannot be represented in type 'long long int' CPU: 0 PID:17076 Comm: syz-executor0 Not tainted 4.1.46+ #1 Hardware name: linux, dummy-virt (DT) Call trace: dump_backtrace+0x0/0x2c8 arch/arm64/kernel/traps.c:100 show_stack+0x20/0x30 arch/arm64/kernel/traps.c:238 __dump_stack lib/dump_stack.c:15 [inline] ubsan_epilogue+0x18/0x70 lib/ubsan.c:164 handle_overflow+0x158/0x1b0 lib/ubsan.c:195 shmem_fallocate+0x6d0/0x820 mm/shmem.c:2104 vfs_fallocate+0x238/0x428 fs/open.c:312 SYSC_fallocate fs/open.c:335 [inline] SyS_fallocate+0x54/0xc8 fs/open.c:239
The highest bit of unmap_start will be appended with sign bit 1 (overflow) when calculate shmem_falloc.start:
shmem_falloc.start = unmap_start >> PAGE_SHIFT.
Fix it by casting the type of unmap_start to u64, when right shifted.
This bug is found in LTS Linux 4.1. It also seems to exist in mainline.
Link: http://lkml.kernel.org/r/1573867464-5107-1-git-send-email-chenjun102@huawei.... Signed-off-by: Chen Jun chenjun102@huawei.com Reviewed-by: Andrew Morton akpm@linux-foundation.org Cc: Hugh Dickins hughd@google.com Cc: Qian Cai cai@lca.pw Cc: Kefeng Wang wangkefeng.wang@huawei.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- mm/shmem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/mm/shmem.c +++ b/mm/shmem.c @@ -2692,7 +2692,7 @@ static long shmem_fallocate(struct file }
shmem_falloc.waitq = &shmem_falloc_waitq; - shmem_falloc.start = unmap_start >> PAGE_SHIFT; + shmem_falloc.start = (u64)unmap_start >> PAGE_SHIFT; shmem_falloc.next = (unmap_end + 1) >> PAGE_SHIFT; spin_lock(&inode->i_lock); inode->i_private = &shmem_falloc;
From: Alexandre Belloni alexandre.belloni@bootlin.com
commit 7e7c005b4b1f1f169bcc4b2c3a40085ecc663df2 upstream.
When setting the time in the future with the uie timer enabled, rtc_timer_do_work will loop for a while because the expiration of the uie timer was way before the current RTC time and a new timer will be enqueued until the current rtc time is reached.
If the uie timer is enabled, disable it before setting the time and enable it after expiring current timers (which may actually be an alarm).
This is the safest thing to do to ensure the uie timer is still synchronized with the RTC, especially in the UIE emulation case.
Reported-by: syzbot+08116743f8ad6f9a6de7@syzkaller.appspotmail.com Fixes: 6610e0893b8b ("RTC: Rework RTC code to use timerqueue for events") Link: https://lore.kernel.org/r/20191020231320.8191-1-alexandre.belloni@bootlin.co... Signed-off-by: Alexandre Belloni alexandre.belloni@bootlin.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/rtc/interface.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-)
--- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -127,7 +127,7 @@ EXPORT_SYMBOL_GPL(rtc_read_time);
int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm) { - int err; + int err, uie;
err = rtc_valid_tm(tm); if (err != 0) @@ -139,6 +139,17 @@ int rtc_set_time(struct rtc_device *rtc,
rtc_subtract_offset(rtc, tm);
+#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL + uie = rtc->uie_rtctimer.enabled || rtc->uie_irq_active; +#else + uie = rtc->uie_rtctimer.enabled; +#endif + if (uie) { + err = rtc_update_irq_enable(rtc, 0); + if (err) + return err; + } + err = mutex_lock_interruptible(&rtc->ops_lock); if (err) return err; @@ -162,6 +173,12 @@ int rtc_set_time(struct rtc_device *rtc, /* A timer might have just expired */ schedule_work(&rtc->irqwork);
+ if (uie) { + err = rtc_update_irq_enable(rtc, 1); + if (err) + return err; + } + trace_rtc_set_time(rtc_tm_to_time64(tm), err); return err; }
From: Darrick J. Wong darrick.wong@oracle.com
commit 3253d9d093376d62b4a56e609f15d2ec5085ac73 upstream.
Andreas Grünbacher reports that on the two filesystems that support iomap directio, it's possible for splice() to return -EAGAIN (instead of a short splice) if the pipe being written to has less space available in its pipe buffers than the length supplied by the calling process.
Months ago we fixed splice_direct_to_actor to clamp the length of the read request to the size of the splice pipe. Do the same to do_splice.
Fixes: 17614445576b6 ("splice: don't read more than available pipe space") Reported-by: syzbot+3c01db6025f26530cf8d@syzkaller.appspotmail.com Reported-by: Andreas Grünbacher andreas.gruenbacher@gmail.com Reviewed-by: Andreas Grünbacher andreas.gruenbacher@gmail.com Signed-off-by: Darrick J. Wong darrick.wong@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/splice.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
--- a/fs/splice.c +++ b/fs/splice.c @@ -949,12 +949,13 @@ ssize_t splice_direct_to_actor(struct fi WARN_ON_ONCE(pipe->nrbufs != 0);
while (len) { + unsigned int pipe_pages; size_t read_len; loff_t pos = sd->pos, prev_pos = pos;
/* Don't try to read more the pipe has space for. */ - read_len = min_t(size_t, len, - (pipe->buffers - pipe->nrbufs) << PAGE_SHIFT); + pipe_pages = pipe->buffers - pipe->nrbufs; + read_len = min(len, (size_t)pipe_pages << PAGE_SHIFT); ret = do_splice_to(in, &pos, pipe, read_len, flags); if (unlikely(ret <= 0)) goto out_release; @@ -1175,8 +1176,15 @@ static long do_splice(struct file *in, l
pipe_lock(opipe); ret = wait_for_space(opipe, flags); - if (!ret) + if (!ret) { + unsigned int pipe_pages; + + /* Don't try to read more the pipe has space for. */ + pipe_pages = opipe->buffers - opipe->nrbufs; + len = min(len, (size_t)pipe_pages << PAGE_SHIFT); + ret = do_splice_to(in, &offset, opipe, len, flags); + } pipe_unlock(opipe); if (ret > 0) wakeup_pipe_readers(opipe);
From: yangerkun yangerkun@huawei.com
commit 565333a1554d704789e74205989305c811fd9c7a upstream.
No need to wait for any commit once the page is fully truncated. Besides, it may confuse e.g. concurrent ext4_writepage() with the page still be dirty (will be cleared by truncate_pagecache() in ext4_setattr()) but buffers has been freed; and then trigger a bug show as below:
[ 26.057508] ------------[ cut here ]------------ [ 26.058531] kernel BUG at fs/ext4/inode.c:2134! ... [ 26.088130] Call trace: [ 26.088695] ext4_writepage+0x914/0xb28 [ 26.089541] writeout.isra.4+0x1b4/0x2b8 [ 26.090409] move_to_new_page+0x3b0/0x568 [ 26.091338] __unmap_and_move+0x648/0x988 [ 26.092241] unmap_and_move+0x48c/0xbb8 [ 26.093096] migrate_pages+0x220/0xb28 [ 26.093945] kernel_mbind+0x828/0xa18 [ 26.094791] __arm64_sys_mbind+0xc8/0x138 [ 26.095716] el0_svc_common+0x190/0x490 [ 26.096571] el0_svc_handler+0x60/0xd0 [ 26.097423] el0_svc+0x8/0xc
Run the procedure (generate by syzkaller) parallel with ext3.
void main() { int fd, fd1, ret; void *addr; size_t length = 4096; int flags; off_t offset = 0; char *str = "12345";
fd = open("a", O_RDWR | O_CREAT); assert(fd >= 0);
/* Truncate to 4k */ ret = ftruncate(fd, length); assert(ret == 0);
/* Journal data mode */ flags = 0xc00f; ret = ioctl(fd, _IOW('f', 2, long), &flags); assert(ret == 0);
/* Truncate to 0 */ fd1 = open("a", O_TRUNC | O_NOATIME); assert(fd1 >= 0);
addr = mmap(NULL, length, PROT_WRITE | PROT_READ, MAP_SHARED, fd, offset); assert(addr != (void *)-1);
memcpy(addr, str, 5); mbind(addr, length, 0, 0, 0, MPOL_MF_MOVE); }
And the bug will be triggered once we seen the below order.
reproduce1 reproduce2
... | ... truncate to 4k | change to journal data mode | | memcpy(set page dirty) truncate to 0: | ext4_setattr: | ... | ext4_wait_for_tail_page_commit | | mbind(trigger bug) truncate_pagecache(clean dirty)| ... ... |
mbind will call ext4_writepage() since the page still be dirty, and then report the bug since the buffers has been free. Fix it by return directly once offset equals to 0 which means the page has been fully truncated.
Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: yangerkun yangerkun@huawei.com Link: https://lore.kernel.org/r/20190919063508.1045-1-yangerkun@huawei.com Reviewed-by: Jan Kara jack@suse.cz Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/ext4/inode.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
--- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -5459,11 +5459,15 @@ static void ext4_wait_for_tail_page_comm
offset = inode->i_size & (PAGE_SIZE - 1); /* - * All buffers in the last page remain valid? Then there's nothing to - * do. We do the check mainly to optimize the common PAGE_SIZE == - * blocksize case + * If the page is fully truncated, we don't need to wait for any commit + * (and we even should not as __ext4_journalled_invalidatepage() may + * strip all buffers from the page but keep the page dirty which can then + * confuse e.g. concurrent ext4_writepage() seeing dirty page without + * buffers). Also we don't need to wait for any commit if all buffers in + * the page remain valid. This is most beneficial for the common case of + * blocksize == PAGESIZE. */ - if (offset > PAGE_SIZE - i_blocksize(inode)) + if (!offset || offset > (PAGE_SIZE - i_blocksize(inode))) return; while (1) { page = find_lock_page(inode->i_mapping,
From: Daniel Schultz d.schultz@phytec.de
[ Upstream commit 37ef8c2c15bdc1322b160e38986c187de2b877b2 ]
The Rockchip PMIC driver can automatically detect connected component versions by reading the ID_MSB and ID_LSB registers. The probe function will always fail with RK818 PMICs because the ID_MSK is 0xFFF0 and the RK818 template ID is 0x8181.
This patch changes this value to 0x8180.
Fixes: 9d6105e19f61 ("mfd: rk808: Fix up the chip id get failed") Cc: stable@vger.kernel.org Cc: Elaine Zhang zhangqing@rock-chips.com Cc: Joseph Chen chenjh@rock-chips.com Signed-off-by: Daniel Schultz d.schultz@phytec.de Signed-off-by: Heiko Stuebner heiko@sntech.de Signed-off-by: Lee Jones lee.jones@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/mfd/rk808.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h index d3156594674c2..338e0f6e2226b 100644 --- a/include/linux/mfd/rk808.h +++ b/include/linux/mfd/rk808.h @@ -443,7 +443,7 @@ enum { enum { RK805_ID = 0x8050, RK808_ID = 0x0000, - RK818_ID = 0x8181, + RK818_ID = 0x8180, };
struct rk808 {
From: Michal Hocko mhocko@suse.com
[ Upstream commit 7635d9cbe8327e131a1d3d8517dc186c2796ce2e ]
Userspace falls short when trying to find out whether a specific memory range is eligible for THP. There are usecases that would like to know that http://lkml.kernel.org/r/alpine.DEB.2.21.1809251248450.50347@chino.kir.corp.... : This is used to identify heap mappings that should be able to fault thp : but do not, and they normally point to a low-on-memory or fragmentation : issue.
The only way to deduce this now is to query for hg resp. nh flags and confronting the state with the global setting. Except that there is also PR_SET_THP_DISABLE that might change the picture. So the final logic is not trivial. Moreover the eligibility of the vma depends on the type of VMA as well. In the past we have supported only anononymous memory VMAs but things have changed and shmem based vmas are supported as well these days and the query logic gets even more complicated because the eligibility depends on the mount option and another global configuration knob.
Simplify the current state and report the THP eligibility in /proc/<pid>/smaps for each existing vma. Reuse transparent_hugepage_enabled for this purpose. The original implementation of this function assumes that the caller knows that the vma itself is supported for THP so make the core checks into __transparent_hugepage_enabled and use it for existing callers. __show_smap just use the new transparent_hugepage_enabled which also checks the vma support status (please note that this one has to be out of line due to include dependency issues).
[mhocko@kernel.org: fix oops with NULL ->f_mapping] Link: http://lkml.kernel.org/r/20181224185106.GC16738@dhcp22.suse.cz Link: http://lkml.kernel.org/r/20181211143641.3503-3-mhocko@kernel.org Signed-off-by: Michal Hocko mhocko@suse.com Acked-by: Vlastimil Babka vbabka@suse.cz Cc: Dan Williams dan.j.williams@intel.com Cc: David Rientjes rientjes@google.com Cc: Jan Kara jack@suse.cz Cc: Mike Rapoport rppt@linux.ibm.com Cc: Paul Oppenheimer bepvte@gmail.com Cc: William Kucharski william.kucharski@oracle.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- Documentation/filesystems/proc.txt | 3 +++ fs/proc/task_mmu.c | 2 ++ include/linux/huge_mm.h | 13 ++++++++++++- mm/huge_memory.c | 12 +++++++++++- mm/memory.c | 4 ++-- 5 files changed, 30 insertions(+), 4 deletions(-)
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt index 06ac6dda9b345..0d0ecc7df2600 100644 --- a/Documentation/filesystems/proc.txt +++ b/Documentation/filesystems/proc.txt @@ -425,6 +425,7 @@ SwapPss: 0 kB KernelPageSize: 4 kB MMUPageSize: 4 kB Locked: 0 kB +THPeligible: 0 VmFlags: rd ex mr mw me dw
the first of these lines shows the same information as is displayed for the @@ -462,6 +463,8 @@ replaced by copy-on-write) part of the underlying shmem object out on swap. "SwapPss" shows proportional swap share of this mapping. Unlike "Swap", this does not take into account swapped out page of underlying shmem objects. "Locked" indicates whether the mapping is locked in memory or not. +"THPeligible" indicates whether the mapping is eligible for THP pages - 1 if +true, 0 otherwise.
"VmFlags" field deserves a separate description. This member represents the kernel flags associated with the particular virtual memory area in two letter encoded diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 71aba44c4fa6d..efa6273c00067 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -800,6 +800,8 @@ static int show_smap(struct seq_file *m, void *v)
__show_smap(m, &mss);
+ seq_printf(m, "THPeligible: %d\n", transparent_hugepage_enabled(vma)); + if (arch_pkeys_enabled()) seq_printf(m, "ProtectionKey: %8u\n", vma_pkey(vma)); show_smap_vma_flags(m, vma); diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h index 77227224ca880..e375f2249f520 100644 --- a/include/linux/huge_mm.h +++ b/include/linux/huge_mm.h @@ -91,7 +91,11 @@ extern bool is_vma_temporary_stack(struct vm_area_struct *vma);
extern unsigned long transparent_hugepage_flags;
-static inline bool transparent_hugepage_enabled(struct vm_area_struct *vma) +/* + * to be used on vmas which are known to support THP. + * Use transparent_hugepage_enabled otherwise + */ +static inline bool __transparent_hugepage_enabled(struct vm_area_struct *vma) { if (vma->vm_flags & VM_NOHUGEPAGE) return false; @@ -115,6 +119,8 @@ static inline bool transparent_hugepage_enabled(struct vm_area_struct *vma) return false; }
+bool transparent_hugepage_enabled(struct vm_area_struct *vma); + #define transparent_hugepage_use_zero_page() \ (transparent_hugepage_flags & \ (1<<TRANSPARENT_HUGEPAGE_USE_ZERO_PAGE_FLAG)) @@ -255,6 +261,11 @@ static inline bool thp_migration_supported(void)
#define hpage_nr_pages(x) 1
+static inline bool __transparent_hugepage_enabled(struct vm_area_struct *vma) +{ + return false; +} + static inline bool transparent_hugepage_enabled(struct vm_area_struct *vma) { return false; diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 09ce8528bbdd9..5a1771bd5d04d 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -63,6 +63,16 @@ static struct shrinker deferred_split_shrinker; static atomic_t huge_zero_refcount; struct page *huge_zero_page __read_mostly;
+bool transparent_hugepage_enabled(struct vm_area_struct *vma) +{ + if (vma_is_anonymous(vma)) + return __transparent_hugepage_enabled(vma); + if (vma_is_shmem(vma) && shmem_huge_enabled(vma)) + return __transparent_hugepage_enabled(vma); + + return false; +} + static struct page *get_huge_zero_page(void) { struct page *zero_page; @@ -1329,7 +1339,7 @@ vm_fault_t do_huge_pmd_wp_page(struct vm_fault *vmf, pmd_t orig_pmd) get_page(page); spin_unlock(vmf->ptl); alloc: - if (transparent_hugepage_enabled(vma) && + if (__transparent_hugepage_enabled(vma) && !transparent_hugepage_debug_cow()) { huge_gfp = alloc_hugepage_direct_gfpmask(vma); new_page = alloc_hugepage_vma(huge_gfp, vma, haddr, HPAGE_PMD_ORDER); diff --git a/mm/memory.c b/mm/memory.c index fb5655b518c99..bbf0cc4066c84 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -4106,7 +4106,7 @@ static vm_fault_t __handle_mm_fault(struct vm_area_struct *vma, vmf.pud = pud_alloc(mm, p4d, address); if (!vmf.pud) return VM_FAULT_OOM; - if (pud_none(*vmf.pud) && transparent_hugepage_enabled(vma)) { + if (pud_none(*vmf.pud) && __transparent_hugepage_enabled(vma)) { ret = create_huge_pud(&vmf); if (!(ret & VM_FAULT_FALLBACK)) return ret; @@ -4132,7 +4132,7 @@ static vm_fault_t __handle_mm_fault(struct vm_area_struct *vma, vmf.pmd = pmd_alloc(mm, vmf.pud, address); if (!vmf.pmd) return VM_FAULT_OOM; - if (pmd_none(*vmf.pmd) && transparent_hugepage_enabled(vma)) { + if (pmd_none(*vmf.pmd) && __transparent_hugepage_enabled(vma)) { ret = create_huge_pmd(&vmf); if (!(ret & VM_FAULT_FALLBACK)) return ret;
From: Thomas Hellstrom thellstrom@vmware.com
[ Upstream commit 625110b5e9dae9074d8a7e67dd07f821a053eed7 ]
A huge pud page can theoretically be faulted in racing with pmd_alloc() in __handle_mm_fault(). That will lead to pmd_alloc() returning an invalid pmd pointer.
Fix this by adding a pud_trans_unstable() function similar to pmd_trans_unstable() and check whether the pud is really stable before using the pmd pointer.
Race: Thread 1: Thread 2: Comment create_huge_pud() Fallback - not taken. create_huge_pud() Taken. pmd_alloc() Returns an invalid pointer.
This will result in user-visible huge page data corruption.
Note that this was caught during a code audit rather than a real experienced problem. It looks to me like the only implementation that currently creates huge pud pagetable entries is dev_dax_huge_fault() which doesn't appear to care much about private (COW) mappings or write-tracking which is, I believe, a prerequisite for create_huge_pud() falling back on thread 1, but not in thread 2.
Link: http://lkml.kernel.org/r/20191115115808.21181-2-thomas_os@shipmail.org Fixes: a00cc7d9dd93 ("mm, x86: add support for PUD-sized transparent hugepages") Signed-off-by: Thomas Hellstrom thellstrom@vmware.com Acked-by: Kirill A. Shutemov kirill.shutemov@linux.intel.com Cc: Arnd Bergmann arnd@arndb.de Cc: Matthew Wilcox willy@infradead.org Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/asm-generic/pgtable.h | 25 +++++++++++++++++++++++++ mm/memory.c | 6 ++++++ 2 files changed, 31 insertions(+)
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h index 15fd0277ffa69..f94c39070dcca 100644 --- a/include/asm-generic/pgtable.h +++ b/include/asm-generic/pgtable.h @@ -874,6 +874,31 @@ static inline int pud_trans_huge(pud_t pud) } #endif
+/* See pmd_none_or_trans_huge_or_clear_bad for discussion. */ +static inline int pud_none_or_trans_huge_or_dev_or_clear_bad(pud_t *pud) +{ + pud_t pudval = READ_ONCE(*pud); + + if (pud_none(pudval) || pud_trans_huge(pudval) || pud_devmap(pudval)) + return 1; + if (unlikely(pud_bad(pudval))) { + pud_clear_bad(pud); + return 1; + } + return 0; +} + +/* See pmd_trans_unstable for discussion. */ +static inline int pud_trans_unstable(pud_t *pud) +{ +#if defined(CONFIG_TRANSPARENT_HUGEPAGE) && \ + defined(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD) + return pud_none_or_trans_huge_or_dev_or_clear_bad(pud); +#else + return 0; +#endif +} + #ifndef pmd_read_atomic static inline pmd_t pmd_read_atomic(pmd_t *pmdp) { diff --git a/mm/memory.c b/mm/memory.c index bbf0cc4066c84..f910da42a1f01 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -4106,6 +4106,7 @@ static vm_fault_t __handle_mm_fault(struct vm_area_struct *vma, vmf.pud = pud_alloc(mm, p4d, address); if (!vmf.pud) return VM_FAULT_OOM; +retry_pud: if (pud_none(*vmf.pud) && __transparent_hugepage_enabled(vma)) { ret = create_huge_pud(&vmf); if (!(ret & VM_FAULT_FALLBACK)) @@ -4132,6 +4133,11 @@ static vm_fault_t __handle_mm_fault(struct vm_area_struct *vma, vmf.pmd = pmd_alloc(mm, vmf.pud, address); if (!vmf.pmd) return VM_FAULT_OOM; + + /* Huge pud page fault raced with pmd_alloc? */ + if (pud_trans_unstable(vmf.pud)) + goto retry_pud; + if (pmd_none(*vmf.pmd) && __transparent_hugepage_enabled(vma)) { ret = create_huge_pmd(&vmf); if (!(ret & VM_FAULT_FALLBACK))
Greg, Sasha
On 12/16/19 7:07 PM, Greg Kroah-Hartman wrote:
From: Thomas Hellstrom thellstrom@vmware.com
[ Upstream commit 625110b5e9dae9074d8a7e67dd07f821a053eed7 ]
Just repeating to make sure it's dropped, since it re-appeared again.
Could we please drop this patch from -stable for now. I'll re-nominate for stable with the correct dependencies when it's seen some more testing. It's depending on another patch and it's touching a code path we definitely don't want to break with unforeseen corner-cases.
Thanks, Thomas
On Mon, Dec 16, 2019 at 06:36:57PM +0000, Thomas Hellstrom wrote:
Greg, Sasha
On 12/16/19 7:07 PM, Greg Kroah-Hartman wrote:
From: Thomas Hellstrom thellstrom@vmware.com
[ Upstream commit 625110b5e9dae9074d8a7e67dd07f821a053eed7 ]
Just repeating to make sure it's dropped, since it re-appeared again.
Could we please drop this patch from -stable for now. I'll re-nominate for stable with the correct dependencies when it's seen some more testing. It's depending on another patch and it's touching a code path we definitely don't want to break with unforeseen corner-cases.
Ugh, somehow Sasha added this one back in :(
I'll go drop it again, thanks for noticing and letting me know.
greg k-h
From: Heiko Carstens heiko.carstens@de.ibm.com
[ Upstream commit a2308c11ecbc3471ebb7435ee8075815b1502ef0 ]
When a secondary CPU is brought up it must initialize its control registers. CPU A which triggers that a secondary CPU B is brought up stores its control register contents into the lowcore of new CPU B, which then loads these values on startup.
This is problematic in various ways: the control register which contains the home space ASCE will correctly contain the kernel ASCE; however control registers for primary and secondary ASCEs are initialized with whatever values were present in CPU A.
Typically: - the primary ASCE will contain the user process ASCE of the process that triggered onlining of CPU B. - the secondary ASCE will contain the percpu VDSO ASCE of CPU A.
Due to lazy ASCE handling we may also end up with other combinations.
When then CPU B switches to a different process (!= idle) it will fixup the primary ASCE. However the problem is that the (wrong) ASCE from CPU A was loaded into control register 1: as soon as an ASCE is attached (aka loaded) a CPU is free to generate TLB entries using that address space. Even though it is very unlikey that CPU B will actually generate such entries, this could result in TLB entries of the address space of the process that ran on CPU A. These entries shouldn't exist at all and could cause problems later on.
Furthermore the secondary ASCE of CPU B will not be updated correctly. This means that processes may see wrong results or even crash if they access VDSO data on CPU B. The correct VDSO ASCE will eventually be loaded on return to user space as soon as the kernel executed a call to strnlen_user or an atomic futex operation on CPU B.
Fix both issues by intializing the to be loaded control register contents with the correct ASCEs and also enforce (re-)loading of the ASCEs upon first context switch and return to user space.
Fixes: 0aaba41b58bc ("s390: remove all code using the access register mode") Cc: stable@vger.kernel.org # v4.15+ Signed-off-by: Heiko Carstens heiko.carstens@de.ibm.com Signed-off-by: Vasily Gorbik gor@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/s390/kernel/smp.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index da02f4087d61f..df2413f26a8f2 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -261,9 +261,12 @@ static void pcpu_prepare_secondary(struct pcpu *pcpu, int cpu) lc->spinlock_index = 0; lc->percpu_offset = __per_cpu_offset[cpu]; lc->kernel_asce = S390_lowcore.kernel_asce; + lc->user_asce = S390_lowcore.kernel_asce; lc->machine_flags = S390_lowcore.machine_flags; lc->user_timer = lc->system_timer = lc->steal_timer = 0; __ctl_store(lc->cregs_save_area, 0, 15); + lc->cregs_save_area[1] = lc->kernel_asce; + lc->cregs_save_area[7] = lc->vdso_asce; save_access_regs((unsigned int *) lc->access_regs_save_area); memcpy(lc->stfle_fac_list, S390_lowcore.stfle_fac_list, sizeof(lc->stfle_fac_list)); @@ -810,6 +813,8 @@ static void smp_start_secondary(void *cpuvoid) restore_access_regs(S390_lowcore.access_regs_save_area); __ctl_load(S390_lowcore.cregs_save_area, 0, 15); __load_psw_mask(PSW_KERNEL_BITS | PSW_MASK_DAT); + set_cpu_flag(CIF_ASCE_PRIMARY); + set_cpu_flag(CIF_ASCE_SECONDARY); cpu_init(); preempt_disable(); init_cpu_timer();
On 12/16/19 10:47 AM, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.19.90 release. There are 140 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 Wed, 18 Dec 2019 17:41:25 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.19.90-rc1... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.19.y and the diffstat can be found below.
thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks, -- Shuah
On Mon, 16 Dec 2019 at 23:31, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 4.19.90 release. There are 140 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 Wed, 18 Dec 2019 17:41:25 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.19.90-rc1... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.19.y and the diffstat can be found below.
thanks,
greg k-h
Results from Linaro’s test farm. No regressions on arm64, arm, x86_64, and i386.
Summary ------------------------------------------------------------------------
kernel: 4.19.90-rc1 git repo: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git git branch: linux-4.19.y git commit: 9cc8b117a9932aaa067980374b1de1145afc4645 git describe: v4.19.89-140-g9cc8b117a993 Test details: https://qa-reports.linaro.org/lkft/linux-stable-rc-4.19-oe/build/v4.19.89-14...
No regressions (compared to build v4.19.89)
No fixes (compared to build v4.19.89)
Ran 22793 total tests in the following environments and test suites.
Environments -------------- - dragonboard-410c - arm64 - hi6220-hikey - arm64 - i386 - juno-r2 - arm64 - qemu_arm - qemu_arm64 - qemu_i386 - qemu_x86_64 - x15 - arm - x86_64
Test Suites ----------- * build * install-android-platform-tools-r2600 * kselftest * libhugetlbfs * linux-log-parser * ltp-containers-tests * ltp-cve-tests * ltp-hugetlb-tests * ltp-mm-tests * spectre-meltdown-checker-test * ltp-cap_bounds-tests * ltp-commands-tests * ltp-cpuhotplug-tests * ltp-dio-tests * ltp-fcntl-locktests-tests * ltp-filecaps-tests * ltp-fs-tests * ltp-fs_bind-tests * ltp-fs_perms_simple-tests * ltp-fsx-tests * ltp-io-tests * ltp-ipc-tests * ltp-math-tests * ltp-nptl-tests * ltp-pty-tests * ltp-sched-tests * ltp-securebits-tests * ltp-syscalls-tests * network-basic-tests * perf * v4l2-compliance * ltp-open-posix-tests * kvm-unit-tests * kselftest-vsyscall-mode-native * kselftest-vsyscall-mode-none * ssuite
On 16/12/2019 17:47, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.19.90 release. There are 140 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 Wed, 18 Dec 2019 17:41:25 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.19.90-rc1... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.19.y and the diffstat can be found below.
thanks,
greg k-h
All tests are passing for Tegra ...
Test results for stable-v4.19: 13 builds: 13 pass, 0 fail 22 boots: 22 pass, 0 fail 32 tests: 32 pass, 0 fail
Linux version: 4.19.90-rc1-g9cc8b117a993 Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000, tegra194-p2972-0000, tegra20-ventana, tegra210-p2371-2180, tegra30-cardhu-a04
Cheers Jon
On Mon, Dec 16, 2019 at 06:47:48PM +0100, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.19.90 release. There are 140 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 Wed, 18 Dec 2019 17:41:25 +0000. Anything received after that time might be too late.
Build results: total: 156 pass: 156 fail: 0 Qemu test results: total: 383 pass: 383 fail: 0
Guenter
linux-stable-mirror@lists.linaro.org