This is the start of the stable review cycle for the 4.9.180 release. There are 128 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sat 01 Jun 2019 03:02:06 AM UTC. 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.9.180-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.9.y and the diffstat can be found below.
thanks,
greg k-h
------------- Pseudo-Shortlog of commits:
Greg Kroah-Hartman gregkh@linuxfoundation.org Linux 4.9.180-rc1
Chris Wilson chris@chris-wilson.co.uk drm: Wake up next in drm_read() chain if we are forced to putback the event
Arnd Bergmann arnd@arndb.de ASoC: davinci-mcasp: Fix clang warning without CONFIG_PM
Chris Lesiak chris.lesiak@licor.com spi: Fix zero length xfer bug
Geert Uytterhoeven geert+renesas@glider.be spi: rspi: Fix sequencer reset during initialization
Aditya Pakki pakki001@umn.edu spi : spi-topcliff-pch: Fix to handle empty DMA buffers
James Smart jsmart2021@gmail.com scsi: lpfc: Fix SLI3 commands being issued on SLI4 devices
Arnd Bergmann arnd@arndb.de media: saa7146: avoid high stack usage with clang
James Smart jsmart2021@gmail.com scsi: lpfc: Fix FDMI manufacturer attribute value
Arnd Bergmann arnd@arndb.de media: go7007: avoid clang frame overflow warning with KASAN
James Hutchinson jahutchinson99@googlemail.com media: m88ds3103: serialize reset messages in m88ds3103_set_frontend
Sameer Pujar spujar@nvidia.com dmaengine: tegra210-adma: use devm_clk_*() helpers
Arnd Bergmann arnd@arndb.de scsi: qla4xxx: avoid freeing unallocated dma memory
Tony Lindgren tony@atomide.com usb: core: Add PM runtime calls to usb_hcd_platform_shutdown
Paul E. McKenney paulmck@linux.ibm.com rcuperf: Fix cleanup path for invalid perf_type strings
Paul E. McKenney paulmck@linux.ibm.com rcutorture: Fix cleanup path for invalid torture_type strings
Tony Luck tony.luck@intel.com x86/mce: Fix machine_check_poll() tests for error types
Kangjie Lu kjlu@umn.edu tty: ipwireless: fix missing checks for ioremap
Pankaj Gupta pagupta@redhat.com virtio_console: initialize vtermno value for ports
Dan Carpenter dan.carpenter@oracle.com media: wl128x: prevent two potential buffer overflows
Sowjanya Komatineni skomatineni@nvidia.com spi: tegra114: reset controller on probe
Gustavo A. R. Silva gustavo@embeddedor.com cxgb3/l2t: Fix undefined behaviour
Wen Yang wen.yang99@zte.com.cn ASoC: fsl_utils: fix a leaked reference by adding missing of_node_put
Wen Yang wen.yang99@zte.com.cn ASoC: eukrea-tlv320: fix a leaked reference by adding missing of_node_put
Nicolas Saenz Julienne nsaenzjulienne@suse.de HID: core: move Usage Page concatenation to Main item
Chengguang Xu cgxu519@gmx.com chardev: add additional check for minor range overlap
Peter Zijlstra peterz@infradead.org x86/ia32: Fix ia32_restore_sigcontext() AC leak
Peter Zijlstra peterz@infradead.org x86/uaccess, signal: Fix AC=1 bloat
Wen Yang wen.yang99@zte.com.cn arm64: cpu_ops: fix a leaked reference by adding missing of_node_put
Stanley Chu stanley.chu@mediatek.com scsi: ufs: Avoid configuring regulator with undefined voltage range
Stanley Chu stanley.chu@mediatek.com scsi: ufs: Fix regulator load and icc-level configuration
Piotr Figiel p.figiel@camlintechnologies.com brcmfmac: fix Oops when bringing up interface during USB disconnect
Piotr Figiel p.figiel@camlintechnologies.com brcmfmac: fix race during disconnect when USB completion is in progress
Piotr Figiel p.figiel@camlintechnologies.com brcmfmac: convert dev_init_lock mutex to completion
Arnd Bergmann arnd@arndb.de b43: shut up clang -Wuninitialized variable warning
Kangjie Lu kjlu@umn.edu brcmfmac: fix missing checks for kmemdup
YueHaibing yuehaibing@huawei.com mwifiex: Fix mem leak in mwifiex_tm_cmd
Kangjie Lu kjlu@umn.edu rtlwifi: fix a potential NULL pointer dereference
Nathan Chancellor natechancellor@gmail.com iio: common: ssp_sensors: Initialize calculated_time in ssp_common_process_data
Kangjie Lu kjlu@umn.edu iio: hmc5843: fix potential NULL pointer dereferences
Lars-Peter Clausen lars@metafoo.de iio: ad_sigma_delta: Properly handle SPI bus locking vs CS assertion
Kees Cook keescook@chromium.org x86/build: Keep local relocations with ld.lld
Wen Yang wen.yang99@zte.com.cn cpufreq: pmac32: fix possible object reference leak
Wen Yang wen.yang99@zte.com.cn cpufreq/pasemi: fix possible object reference leak
Wen Yang wen.yang99@zte.com.cn cpufreq: ppc_cbe: fix possible object reference leak
Arnd Bergmann arnd@arndb.de s390: cio: fix cio_irb declaration
Charles Keepax ckeepax@opensource.cirrus.com extcon: arizona: Disable mic detect if running when driver is removed
Ulf Hansson ulf.hansson@linaro.org PM / core: Propagate dev->power.wakeup_path when no callbacks
Yinbo Zhu yinbo.zhu@nxp.com mmc: sdhci-of-esdhc: add erratum eSDHC-A001 and A-008358 support
Yinbo Zhu yinbo.zhu@nxp.com mmc: sdhci-of-esdhc: add erratum eSDHC5 support
Kangjie Lu kjlu@umn.edu mmc_spi: add a status check for spi_sync_locked
Andrea Merello andrea.merello@gmail.com mmc: core: make pwrseq_emmc (partially) support sleepy GPIO controllers
John Garry john.garry@huawei.com scsi: libsas: Do discovery on empty PHY to update PHY info
Guenter Roeck linux@roeck-us.net hwmon: (f71805f) Use request_muxed_region for Super-IO accesses
Guenter Roeck linux@roeck-us.net hwmon: (pc87427) Use request_muxed_region for Super-IO accesses
Guenter Roeck linux@roeck-us.net hwmon: (smsc47b397) Use request_muxed_region for Super-IO accesses
Guenter Roeck linux@roeck-us.net hwmon: (smsc47m1) Use request_muxed_region for Super-IO accesses
Guenter Roeck linux@roeck-us.net hwmon: (vt1211) Use request_muxed_region for Super-IO accesses
Colin Ian King colin.king@canonical.com RDMA/cxgb4: Fix null pointer dereference on alloc_skb failure
Vincenzo Frascino vincenzo.frascino@arm.com arm64: vdso: Fix clock_getres() for CLOCK_REALTIME
Nicholas Nunley nicholas.d.nunley@intel.com i40e: don't allow changes to HW VLAN stripping on active port VLANs
Thomas Gleixner tglx@linutronix.de x86/irq/64: Limit IST stack overflow check to #DB stack
Alan Stern stern@rowland.harvard.edu USB: core: Don't unbind interfaces following device reset failure
Konstantin Khlebnikov khlebnikov@yandex-team.ru sched/core: Handle overflow in cpu_shares_write_u64
Konstantin Khlebnikov khlebnikov@yandex-team.ru sched/core: Check quota and period overflow at usec to nsec conversion
Nathan Lynch nathanl@linux.ibm.com powerpc/numa: improve control of topology updates
Dan Carpenter dan.carpenter@oracle.com media: pvrusb2: Prevent a buffer overflow
Shuah Khan shuah@kernel.org media: au0828: Fix NULL pointer dereference in au0828_analog_stream_enable()
Wenwen Wang wang6495@umn.edu audit: fix a memory leak bug
Akinobu Mita akinobu.mita@gmail.com media: ov2659: make S_FMT succeed even if requested format doesn't match
Hans Verkuil hverkuil@xs4all.nl media: au0828: stop video streaming only when last user stops
Janusz Krzysztofik jmkrzyszt@gmail.com media: ov6650: Move v4l2_clk_get() to ov6650_video_probe() helper
Philipp Zabel p.zabel@pengutronix.de media: coda: clear error return value before picture run
Nicolas Ferre nicolas.ferre@microchip.com dmaengine: at_xdmac: remove BUG_ON macro in tasklet
Wen Yang wen.yang99@zte.com.cn pinctrl: pistachio: fix leaked of_node references
Hans de Goede hdegoede@redhat.com HID: logitech-hidpp: use RAP instead of FAP to get the protocol version
Peter Zijlstra peterz@infradead.org mm/uaccess: Use 'unsigned long' to placate UBSAN warnings on older GCC versions
Jiri Kosina jkosina@suse.cz x86/mm: Remove in_nmi() warning from 64-bit implementation of vmalloc_fault()
Sebastian Andrzej Siewior bigeasy@linutronix.de smpboot: Place the __percpu annotation correctly
Kees Cook keescook@chromium.org x86/build: Move _etext to actual end of .text
Arnd Bergmann arnd@arndb.de bcache: avoid clang -Wunintialized warning
Coly Li colyli@suse.de bcache: add failure check to run_cache_set() for journal replay
Tang Junhui tang.junhui.linux@gmail.com bcache: fix failure in journal relplay
Coly Li colyli@suse.de bcache: return error immediately in bch_journal_replay()
Corentin Labbe clabbe.montjoie@gmail.com crypto: sun4i-ss - Fix invalid calculation of hash end
Kangjie Lu kjlu@umn.edu net: cw1200: fix a NULL pointer dereference
Dan Carpenter dan.carpenter@oracle.com mwifiex: prevent an array overflow
Daniel Baluta daniel.baluta@nxp.com ASoC: fsl_sai: Update is_slave_mode with correct value
Sergey Matyukevich sergey.matyukevich.os@quantenna.com mac80211/cfg80211: update bss channel on channel switch
Sugar Zhang sugar.zhang@rock-chips.com dmaengine: pl330: _stop: clear interrupt status
Mariusz Bialonczyk manio@skyboo.net w1: fix the resume command API
Sven Van Asbroeck thesven73@gmail.com rtc: 88pm860x: prevent use-after-free on device remove
Johannes Berg johannes.berg@intel.com iwlwifi: pcie: don't crash on invalid RX interrupt
Bart Van Assche bvanassche@acm.org scsi: qla2xxx: Fix a qla24xx_enable_msix() error path
Viresh Kumar viresh.kumar@linaro.org sched/cpufreq: Fix kobject memleak
Qian Cai cai@lca.pw arm64: Fix compiler warning from pte_unmap() with -Wunused-but-set-variable
Marc Zyngier marc.zyngier@arm.com ARM: vdso: Remove dependency with the arch_timer driver internals
Dan Carpenter dan.carpenter@oracle.com brcm80211: potential NULL dereference in brcmf_cfg80211_vndr_cmds_dcmd_handler()
Flavio Suligoi f.suligoi@asem.it spi: pxa2xx: fix SCR (divisor) calculation
Arnd Bergmann arnd@arndb.de ASoC: imx: fix fiq dependencies
Bo YU tsu.yubo@gmail.com powerpc/boot: Fix missing check of lseek() return value
Jerome Brunet jbrunet@baylibre.com ASoC: hdmi-codec: unlock the device on startup errors
Sameeh Jubran sameehj@amazon.com net: ena: gcc 8: fix compilation warning
Sameer Pujar spujar@nvidia.com dmaengine: tegra210-dma: free dma controller in remove()
Raul E Rangel rrangel@chromium.org mmc: core: Verify SD bus width
YueHaibing yuehaibing@huawei.com cxgb4: Fix error path in cxgb4_init_module
Ross Lagerwall ross.lagerwall@citrix.com gfs2: Fix lru_count going negative
David Sterba dsterba@suse.com Revert "btrfs: Honour FITRIM range constraints during free space trim"
Arnaldo Carvalho de Melo acme@redhat.com tools include: Adopt linux/bits.h
Arnaldo Carvalho de Melo acme@redhat.com perf tools: No need to include bitops.h in util.h
YueHaibing yuehaibing@huawei.com at76c50x-usb: Don't register led_trigger if usb_register_driver failed
YueHaibing yuehaibing@huawei.com ssb: Fix possible NULL pointer dereference in ssb_host_pcmcia_exit
Alexander Potapenko glider@google.com media: vivid: use vfree() instead of kfree() for dev->bitmap_cap
YueHaibing yuehaibing@huawei.com media: cpia2: Fix use-after-free in cpia2_exit
Jiufei Xue jiufei.xue@linux.alibaba.com fbdev: fix WARNING in __alloc_pages_nodemask bug
Mike Kravetz mike.kravetz@oracle.com hugetlb: use same fault hash key for shared and private mappings
Shile Zhang shile.zhang@linux.alibaba.com fbdev: fix divide error in fb_var_to_videomode
Tobin C. Harding tobin@kernel.org btrfs: sysfs: don't leak memory when failing add fsid
Filipe Manana fdmanana@suse.com Btrfs: fix race between ranged fsync and writeback of adjacent ranges
Filipe Manana fdmanana@suse.com Btrfs: do not abort transaction at btrfs_update_root() after failure to COW path
Andreas Gruenbacher agruenba@redhat.com gfs2: Fix sign extension bug in gfs2_update_stats
Jean-Philippe Brucker jean-philippe.brucker@arm.com arm64: Save and restore OSDLR_EL1 across suspend/resume
Dan Williams dan.j.williams@intel.com libnvdimm/namespace: Fix label tracking error
Suthikulpanit, Suravee Suravee.Suthikulpanit@amd.com kvm: svm/avic: fix off-by-one in checking host APIC ID
Daniel Axtens dja@axtens.net crypto: vmx - CTR: always increment IV as quadword
Martin K. Petersen martin.petersen@oracle.com Revert "scsi: sd: Keep disk read-only when re-reading partition"
Andrea Parri andrea.parri@amarulasolutions.com bio: fix improper use of smp_mb__before_atomic()
Paolo Bonzini pbonzini@redhat.com KVM: x86: fix return value for reserved EFER
Jan Kara jack@suse.cz ext4: do not delete unlinked inode from orphan list on failed truncate
-------------
Diffstat:
Makefile | 4 +- arch/arm/include/asm/cp15.h | 2 + arch/arm/vdso/vgettimeofday.c | 5 ++- arch/arm64/include/asm/pgtable.h | 3 +- arch/arm64/include/asm/vdso_datapage.h | 1 + arch/arm64/kernel/asm-offsets.c | 2 +- arch/arm64/kernel/cpu_ops.c | 1 + arch/arm64/kernel/vdso.c | 3 ++ arch/arm64/kernel/vdso/gettimeofday.S | 7 ++-- arch/arm64/mm/proc.S | 26 +++++++------ arch/powerpc/boot/addnote.c | 6 ++- arch/powerpc/mm/numa.c | 18 ++++++--- arch/x86/Makefile | 2 +- arch/x86/ia32/ia32_signal.c | 29 ++++++++------ arch/x86/kernel/cpu/mcheck/mce.c | 44 ++++++++++++++++++---- arch/x86/kernel/irq_64.c | 19 +++++++--- arch/x86/kernel/signal.c | 29 ++++++++------ arch/x86/kernel/vmlinux.lds.S | 6 +-- arch/x86/kvm/svm.c | 6 ++- arch/x86/kvm/x86.c | 2 +- arch/x86/mm/fault.c | 2 - drivers/base/power/main.c | 4 ++ drivers/char/virtio_console.c | 3 +- drivers/cpufreq/cpufreq.c | 1 + drivers/cpufreq/cpufreq_governor.c | 2 + drivers/cpufreq/pasemi-cpufreq.c | 1 + drivers/cpufreq/pmac32-cpufreq.c | 2 + drivers/cpufreq/ppc_cbe_cpufreq.c | 1 + drivers/crypto/sunxi-ss/sun4i-ss-hash.c | 5 ++- drivers/crypto/vmx/aesp8-ppc.pl | 2 +- drivers/dma/at_xdmac.c | 6 ++- drivers/dma/pl330.c | 10 +++-- drivers/dma/tegra210-adma.c | 28 +++++++------- drivers/extcon/extcon-arizona.c | 10 +++++ drivers/gpu/drm/drm_fops.c | 1 + drivers/hid/hid-core.c | 36 ++++++++++++------ drivers/hid/hid-logitech-hidpp.c | 17 +++++++-- drivers/hwmon/f71805f.c | 15 ++++++-- drivers/hwmon/pc87427.c | 14 ++++++- drivers/hwmon/smsc47b397.c | 13 ++++++- drivers/hwmon/smsc47m1.c | 28 +++++++++----- drivers/hwmon/vt1211.c | 15 ++++++-- drivers/iio/adc/ad_sigma_delta.c | 16 +++++--- drivers/iio/common/ssp_sensors/ssp_iio.c | 2 +- drivers/iio/magnetometer/hmc5843_i2c.c | 7 +++- drivers/iio/magnetometer/hmc5843_spi.c | 7 +++- drivers/infiniband/hw/cxgb4/cm.c | 2 + drivers/md/bcache/alloc.c | 5 ++- drivers/md/bcache/journal.c | 26 +++++++++++-- drivers/md/bcache/super.c | 17 ++++++--- drivers/media/dvb-frontends/m88ds3103.c | 9 ++--- drivers/media/i2c/ov2659.c | 6 ++- drivers/media/i2c/soc_camera/ov6650.c | 25 ++++++------ drivers/media/pci/saa7146/hexium_gemini.c | 5 +-- drivers/media/pci/saa7146/hexium_orion.c | 5 +-- drivers/media/platform/coda/coda-bit.c | 3 ++ drivers/media/platform/vivid/vivid-vid-cap.c | 2 +- drivers/media/radio/wl128x/fmdrv_common.c | 7 +++- drivers/media/usb/au0828/au0828-video.c | 16 +++++--- drivers/media/usb/cpia2/cpia2_v4l.c | 3 +- drivers/media/usb/go7007/go7007-fw.c | 4 +- drivers/media/usb/pvrusb2/pvrusb2-hdw.c | 2 + drivers/media/usb/pvrusb2/pvrusb2-hdw.h | 1 + drivers/mmc/core/pwrseq_emmc.c | 38 ++++++++++--------- drivers/mmc/core/sd.c | 8 ++++ drivers/mmc/host/mmc_spi.c | 4 ++ drivers/mmc/host/sdhci-of-esdhc.c | 5 +++ drivers/net/ethernet/amazon/ena/ena_netdev.c | 2 +- drivers/net/ethernet/chelsio/cxgb3/l2t.h | 2 +- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 15 ++++++-- drivers/net/ethernet/intel/i40e/i40e_main.c | 8 ++++ drivers/net/wireless/atmel/at76c50x-usb.c | 4 +- drivers/net/wireless/broadcom/b43/phy_lp.c | 6 +-- .../broadcom/brcm80211/brcmfmac/cfg80211.c | 4 ++ .../wireless/broadcom/brcm80211/brcmfmac/core.c | 10 +++-- .../net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 27 +++++++------ .../wireless/broadcom/brcm80211/brcmfmac/vendor.c | 5 ++- drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 7 +++- drivers/net/wireless/marvell/mwifiex/cfg80211.c | 6 ++- drivers/net/wireless/marvell/mwifiex/cfp.c | 3 ++ drivers/net/wireless/realtek/rtlwifi/base.c | 5 +++ drivers/net/wireless/st/cw1200/main.c | 5 +++ drivers/nvdimm/label.c | 29 +++++++------- drivers/nvdimm/namespace_devs.c | 15 ++++++++ drivers/nvdimm/nd.h | 4 ++ drivers/pinctrl/pinctrl-pistachio.c | 2 + drivers/rtc/rtc-88pm860x.c | 2 +- drivers/s390/cio/cio.h | 2 +- drivers/scsi/libsas/sas_expander.c | 5 +++ drivers/scsi/lpfc/lpfc_ct.c | 3 ++ drivers/scsi/lpfc/lpfc_hbadisc.c | 11 +++++- drivers/scsi/qla2xxx/qla_isr.c | 6 ++- drivers/scsi/qla4xxx/ql4_os.c | 2 +- drivers/scsi/sd.c | 3 +- drivers/scsi/ufs/ufshcd.c | 28 ++++++++++---- drivers/spi/spi-pxa2xx.c | 8 +++- drivers/spi/spi-rspi.c | 9 +++-- drivers/spi/spi-tegra114.c | 32 +++++++++------- drivers/spi/spi-topcliff-pch.c | 15 +++++++- drivers/spi/spi.c | 2 + drivers/ssb/bridge_pcmcia_80211.c | 9 ++++- drivers/tty/ipwireless/main.c | 8 ++++ drivers/usb/core/hcd.c | 3 ++ drivers/usb/core/hub.c | 5 ++- drivers/video/fbdev/core/fbcmap.c | 2 + drivers/video/fbdev/core/modedb.c | 3 ++ drivers/w1/w1_io.c | 3 +- fs/btrfs/extent-tree.c | 25 +++--------- fs/btrfs/file.c | 12 ++++++ fs/btrfs/root-tree.c | 4 +- fs/btrfs/sysfs.c | 7 +++- fs/char_dev.c | 6 +++ fs/ext4/inode.c | 2 +- fs/gfs2/glock.c | 22 ++++++----- fs/gfs2/lock_dlm.c | 9 +++-- fs/hugetlbfs/inode.c | 8 +--- include/linux/bio.h | 2 +- include/linux/hid.h | 1 + include/linux/hugetlb.h | 4 +- include/linux/iio/adc/ad_sigma_delta.h | 1 + include/linux/smpboot.h | 2 +- kernel/auditfilter.c | 12 +++--- kernel/rcu/rcuperf.c | 5 +++ kernel/rcu/rcutorture.c | 5 +++ kernel/sched/core.c | 9 ++++- lib/strncpy_from_user.c | 5 ++- lib/strnlen_user.c | 4 +- mm/hugetlb.c | 19 +++------- net/mac80211/mlme.c | 3 -- net/wireless/nl80211.c | 5 +++ sound/soc/codecs/hdmi-codec.c | 6 ++- sound/soc/davinci/davinci-mcasp.c | 2 + sound/soc/fsl/Kconfig | 9 +++-- sound/soc/fsl/eukrea-tlv320.c | 4 +- sound/soc/fsl/fsl_sai.c | 2 + sound/soc/fsl/fsl_utils.c | 1 + tools/include/linux/bitops.h | 7 +--- tools/include/linux/bits.h | 26 +++++++++++++ tools/perf/check-headers.sh | 1 + tools/perf/util/util.h | 1 - 140 files changed, 836 insertions(+), 371 deletions(-)
From: Jan Kara jack@suse.cz
commit ee0ed02ca93ef1ecf8963ad96638795d55af2c14 upstream.
It is possible that unlinked inode enters ext4_setattr() (e.g. if somebody calls ftruncate(2) on unlinked but still open file). In such case we should not delete the inode from the orphan list if truncate fails. Note that this is mostly a theoretical concern as filesystem is corrupted if we reach this path anyway but let's be consistent in our orphan handling.
Reviewed-by: Ira Weiny ira.weiny@intel.com Signed-off-by: Jan Kara jack@suse.cz Signed-off-by: Theodore Ts'o tytso@mit.edu Cc: stable@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/ext4/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -5223,7 +5223,7 @@ int ext4_setattr(struct dentry *dentry, up_write(&EXT4_I(inode)->i_data_sem); ext4_journal_stop(handle); if (error) { - if (orphan) + if (orphan && inode->i_nlink) ext4_orphan_del(NULL, inode); goto err_out; }
From: Paolo Bonzini pbonzini@redhat.com
commit 66f61c92889ff3ca365161fb29dd36d6354682ba upstream.
Commit 11988499e62b ("KVM: x86: Skip EFER vs. guest CPUID checks for host-initiated writes", 2019-04-02) introduced a "return false" in a function returning int, and anyway set_efer has a "nonzero on error" conventon so it should be returning 1.
Reported-by: Pavel Machek pavel@denx.de Fixes: 11988499e62b ("KVM: x86: Skip EFER vs. guest CPUID checks for host-initiated writes") Cc: Sean Christopherson sean.j.christopherson@intel.com Cc: stable@vger.kernel.org Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/x86/kvm/x86.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1109,7 +1109,7 @@ static int set_efer(struct kvm_vcpu *vcp u64 efer = msr_info->data;
if (efer & efer_reserved_bits) - return false; + return 1;
if (!msr_info->host_initiated) { if (!__kvm_valid_efer(vcpu, efer))
From: Andrea Parri andrea.parri@amarulasolutions.com
commit f381c6a4bd0ae0fde2d6340f1b9bb0f58d915de6 upstream.
This barrier only applies to the read-modify-write operations; in particular, it does not apply to the atomic_set() primitive.
Replace the barrier with an smp_mb().
Fixes: dac56212e8127 ("bio: skip atomic inc/dec of ->bi_cnt for most use cases") Cc: stable@vger.kernel.org Reported-by: "Paul E. McKenney" paulmck@linux.ibm.com Reported-by: Peter Zijlstra peterz@infradead.org Signed-off-by: Andrea Parri andrea.parri@amarulasolutions.com Reviewed-by: Ming Lei ming.lei@redhat.com Cc: Jens Axboe axboe@kernel.dk Cc: Ming Lei ming.lei@redhat.com Cc: linux-block@vger.kernel.org Cc: "Paul E. McKenney" paulmck@linux.ibm.com Cc: Peter Zijlstra peterz@infradead.org Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- include/linux/bio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -237,7 +237,7 @@ static inline void bio_cnt_set(struct bi { if (count != 1) { bio->bi_flags |= (1 << BIO_REFFED); - smp_mb__before_atomic(); + smp_mb(); } atomic_set(&bio->__bi_cnt, count); }
From: Martin K. Petersen martin.petersen@oracle.com
commit 8acf608e602f6ec38b7cc37b04c80f1ce9a1a6cc upstream.
This reverts commit 20bd1d026aacc5399464f8328f305985c493cde3.
This patch introduced regressions for devices that come online in read-only state and subsequently switch to read-write.
Given how the partition code is currently implemented it is not possible to persist the read-only flag across a device revalidate call. This may need to get addressed in the future since it is common for user applications to proactively call BLKRRPART.
Reverting this commit will re-introduce a regression where a device-initiated revalidate event will cause the admin state to be forgotten. A separate patch will address this issue.
Fixes: 20bd1d026aac ("scsi: sd: Keep disk read-only when re-reading partition") Cc: stable@vger.kernel.org Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/scsi/sd.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
--- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -2403,7 +2403,6 @@ sd_read_write_protect_flag(struct scsi_d int res; struct scsi_device *sdp = sdkp->device; struct scsi_mode_data data; - int disk_ro = get_disk_ro(sdkp->disk); int old_wp = sdkp->write_prot;
set_disk_ro(sdkp->disk, 0); @@ -2444,7 +2443,7 @@ sd_read_write_protect_flag(struct scsi_d "Test WP failed, assume Write Enabled\n"); } else { sdkp->write_prot = ((data.device_specific & 0x80) != 0); - set_disk_ro(sdkp->disk, sdkp->write_prot || disk_ro); + set_disk_ro(sdkp->disk, sdkp->write_prot); if (sdkp->first_scan || old_wp != sdkp->write_prot) { sd_printk(KERN_NOTICE, sdkp, "Write Protect is %s\n", sdkp->write_prot ? "on" : "off");
From: Daniel Axtens dja@axtens.net
commit 009b30ac7444c17fae34c4f435ebce8e8e2b3250 upstream.
The kernel self-tests picked up an issue with CTR mode: alg: skcipher: p8_aes_ctr encryption test failed (wrong result) on test vector 3, cfg="uneven misaligned splits, may sleep"
Test vector 3 has an IV of FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD, so after 3 increments it should wrap around to 0.
In the aesp8-ppc code from OpenSSL, there are two paths that increment IVs: the bulk (8 at a time) path, and the individual path which is used when there are fewer than 8 AES blocks to process.
In the bulk path, the IV is incremented with vadduqm: "Vector Add Unsigned Quadword Modulo", which does 128-bit addition.
In the individual path, however, the IV is incremented with vadduwm: "Vector Add Unsigned Word Modulo", which instead does 4 32-bit additions. Thus the IV would instead become FFFFFFFFFFFFFFFFFFFFFFFF00000000, throwing off the result.
Use vadduqm.
This was probably a typo originally, what with q and w being adjacent. It is a pretty narrow edge case: I am really impressed by the quality of the kernel self-tests!
Fixes: 5c380d623ed3 ("crypto: vmx - Add support for VMS instructions by ASM") Cc: stable@vger.kernel.org Signed-off-by: Daniel Axtens dja@axtens.net Acked-by: Nayna Jain nayna@linux.ibm.com Tested-by: Nayna Jain nayna@linux.ibm.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/crypto/vmx/aesp8-ppc.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/crypto/vmx/aesp8-ppc.pl +++ b/drivers/crypto/vmx/aesp8-ppc.pl @@ -1318,7 +1318,7 @@ Loop_ctr32_enc: addi $idx,$idx,16 bdnz Loop_ctr32_enc
- vadduwm $ivec,$ivec,$one + vadduqm $ivec,$ivec,$one vmr $dat,$inptail lvx $inptail,0,$inp addi $inp,$inp,16
From: Suthikulpanit, Suravee Suravee.Suthikulpanit@amd.com
commit c9bcd3e3335d0a29d89fabd2c385e1b989e6f1b0 upstream.
Current logic does not allow VCPU to be loaded onto CPU with APIC ID 255. This should be allowed since the host physical APIC ID field in the AVIC Physical APIC table entry is an 8-bit value, and APIC ID 255 is valid in system with x2APIC enabled. Instead, do not allow VCPU load if the host APIC ID cannot be represented by an 8-bit value.
Also, use the more appropriate AVIC_PHYSICAL_ID_ENTRY_HOST_PHYSICAL_ID_MASK instead of AVIC_MAX_PHYSICAL_ID_COUNT.
Signed-off-by: Suravee Suthikulpanit suravee.suthikulpanit@amd.com Cc: stable@vger.kernel.org Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/x86/kvm/svm.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
--- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1518,7 +1518,11 @@ static void avic_vcpu_load(struct kvm_vc if (!kvm_vcpu_apicv_active(vcpu)) return;
- if (WARN_ON(h_physical_id >= AVIC_MAX_PHYSICAL_ID_COUNT)) + /* + * Since the host physical APIC id is 8 bits, + * we can support host APIC ID upto 255. + */ + if (WARN_ON(h_physical_id > AVIC_PHYSICAL_ID_ENTRY_HOST_PHYSICAL_ID_MASK)) return;
entry = READ_ONCE(*(svm->avic_physical_id_cache));
From: Dan Williams dan.j.williams@intel.com
commit c4703ce11c23423d4b46e3d59aef7979814fd608 upstream.
Users have reported intermittent occurrences of DIMM initialization failures due to duplicate allocations of address capacity detected in the labels, or errors of the form below, both have the same root cause.
nd namespace1.4: failed to track label: 0 WARNING: CPU: 17 PID: 1381 at drivers/nvdimm/label.c:863
RIP: 0010:__pmem_label_update+0x56c/0x590 [libnvdimm] Call Trace: ? nd_pmem_namespace_label_update+0xd6/0x160 [libnvdimm] nd_pmem_namespace_label_update+0xd6/0x160 [libnvdimm] uuid_store+0x17e/0x190 [libnvdimm] kernfs_fop_write+0xf0/0x1a0 vfs_write+0xb7/0x1b0 ksys_write+0x57/0xd0 do_syscall_64+0x60/0x210
Unfortunately those reports were typically with a busy parallel namespace creation / destruction loop making it difficult to see the components of the bug. However, Jane provided a simple reproducer using the work-in-progress sub-section implementation.
When ndctl is reconfiguring a namespace it may take an existing defunct / disabled namespace and reconfigure it with a new uuid and other parameters. Critically namespace_update_uuid() takes existing address resources and renames them for the new namespace to use / reconfigure as it sees fit. The bug is that this rename only happens in the resource tracking tree. Existing labels with the old uuid are not reaped leading to a scenario where multiple active labels reference the same span of address range.
Teach namespace_update_uuid() to flag any references to the old uuid for reaping at the next label update attempt.
Cc: stable@vger.kernel.org Fixes: bf9bccc14c05 ("libnvdimm: pmem label sets and namespace instantiation") Link: https://github.com/pmem/ndctl/issues/91 Reported-by: Jane Chu jane.chu@oracle.com Reported-by: Jeff Moyer jmoyer@redhat.com Reported-by: Erwin Tsaur erwin.tsaur@oracle.com Cc: Johannes Thumshirn jthumshirn@suse.de Signed-off-by: Dan Williams dan.j.williams@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/nvdimm/label.c | 29 ++++++++++++++++------------- drivers/nvdimm/namespace_devs.c | 15 +++++++++++++++ drivers/nvdimm/nd.h | 4 ++++ 3 files changed, 35 insertions(+), 13 deletions(-)
--- a/drivers/nvdimm/label.c +++ b/drivers/nvdimm/label.c @@ -490,15 +490,26 @@ static unsigned long nd_label_offset(str - (unsigned long) to_namespace_index(ndd, 0); }
+static void reap_victim(struct nd_mapping *nd_mapping, + struct nd_label_ent *victim) +{ + struct nvdimm_drvdata *ndd = to_ndd(nd_mapping); + u32 slot = to_slot(ndd, victim->label); + + dev_dbg(ndd->dev, "free: %d\n", slot); + nd_label_free_slot(ndd, slot); + victim->label = NULL; +} + static int __pmem_label_update(struct nd_region *nd_region, struct nd_mapping *nd_mapping, struct nd_namespace_pmem *nspm, int pos, unsigned long flags) { u64 cookie = nd_region_interleave_set_cookie(nd_region); struct nvdimm_drvdata *ndd = to_ndd(nd_mapping); - struct nd_label_ent *label_ent, *victim = NULL; struct nd_namespace_label *nd_label; struct nd_namespace_index *nsindex; + struct nd_label_ent *label_ent; struct nd_label_id label_id; struct resource *res; unsigned long *free; @@ -551,18 +562,10 @@ static int __pmem_label_update(struct nd list_for_each_entry(label_ent, &nd_mapping->labels, list) { if (!label_ent->label) continue; - if (memcmp(nspm->uuid, label_ent->label->uuid, - NSLABEL_UUID_LEN) != 0) - continue; - victim = label_ent; - list_move_tail(&victim->list, &nd_mapping->labels); - break; - } - if (victim) { - dev_dbg(ndd->dev, "%s: free: %d\n", __func__, slot); - slot = to_slot(ndd, victim->label); - nd_label_free_slot(ndd, slot); - victim->label = NULL; + if (test_and_clear_bit(ND_LABEL_REAP, &label_ent->flags) + || memcmp(nspm->uuid, label_ent->label->uuid, + NSLABEL_UUID_LEN) == 0) + reap_victim(nd_mapping, label_ent); }
/* update index */ --- a/drivers/nvdimm/namespace_devs.c +++ b/drivers/nvdimm/namespace_devs.c @@ -1210,12 +1210,27 @@ static int namespace_update_uuid(struct for (i = 0; i < nd_region->ndr_mappings; i++) { struct nd_mapping *nd_mapping = &nd_region->mapping[i]; struct nvdimm_drvdata *ndd = to_ndd(nd_mapping); + struct nd_label_ent *label_ent; struct resource *res;
for_each_dpa_resource(ndd, res) if (strcmp(res->name, old_label_id.id) == 0) sprintf((void *) res->name, "%s", new_label_id.id); + + mutex_lock(&nd_mapping->lock); + list_for_each_entry(label_ent, &nd_mapping->labels, list) { + struct nd_namespace_label *nd_label = label_ent->label; + struct nd_label_id label_id; + + if (!nd_label) + continue; + nd_label_gen_id(&label_id, nd_label->uuid, + __le32_to_cpu(nd_label->flags)); + if (strcmp(old_label_id.id, label_id.id) == 0) + set_bit(ND_LABEL_REAP, &label_ent->flags); + } + mutex_unlock(&nd_mapping->lock); } kfree(*old_uuid); out: --- a/drivers/nvdimm/nd.h +++ b/drivers/nvdimm/nd.h @@ -113,8 +113,12 @@ struct nd_percpu_lane { spinlock_t lock; };
+enum nd_label_flags { + ND_LABEL_REAP, +}; struct nd_label_ent { struct list_head list; + unsigned long flags; struct nd_namespace_label *label; };
From: Jean-Philippe Brucker jean-philippe.brucker@arm.com
commit 827a108e354db633698f0b4a10c1ffd2b1f8d1d0 upstream.
When the CPU comes out of suspend, the firmware may have modified the OS Double Lock Register. Save it in an unused slot of cpu_suspend_ctx, and restore it on resume.
Cc: stable@vger.kernel.org Signed-off-by: Jean-Philippe Brucker jean-philippe.brucker@arm.com Signed-off-by: Will Deacon will.deacon@arm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/arm64/mm/proc.S | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-)
--- a/arch/arm64/mm/proc.S +++ b/arch/arm64/mm/proc.S @@ -64,17 +64,18 @@ ENTRY(cpu_do_suspend) mrs x2, tpidr_el0 mrs x3, tpidrro_el0 mrs x4, contextidr_el1 - mrs x5, cpacr_el1 - mrs x6, tcr_el1 - mrs x7, vbar_el1 - mrs x8, mdscr_el1 - mrs x9, oslsr_el1 - mrs x10, sctlr_el1 + mrs x5, osdlr_el1 + mrs x6, cpacr_el1 + mrs x7, tcr_el1 + mrs x8, vbar_el1 + mrs x9, mdscr_el1 + mrs x10, oslsr_el1 + mrs x11, sctlr_el1 stp x2, x3, [x0] - stp x4, xzr, [x0, #16] - stp x5, x6, [x0, #32] - stp x7, x8, [x0, #48] - stp x9, x10, [x0, #64] + stp x4, x5, [x0, #16] + stp x6, x7, [x0, #32] + stp x8, x9, [x0, #48] + stp x10, x11, [x0, #64] ret ENDPROC(cpu_do_suspend)
@@ -96,8 +97,8 @@ ENTRY(cpu_do_resume) msr cpacr_el1, x6
/* Don't change t0sz here, mask those bits when restoring */ - mrs x5, tcr_el1 - bfi x8, x5, TCR_T0SZ_OFFSET, TCR_TxSZ_WIDTH + mrs x7, tcr_el1 + bfi x8, x7, TCR_T0SZ_OFFSET, TCR_TxSZ_WIDTH
msr tcr_el1, x8 msr vbar_el1, x9 @@ -115,6 +116,7 @@ ENTRY(cpu_do_resume) /* * Restore oslsr_el1 by writing oslar_el1 */ + msr osdlr_el1, x5 ubfx x11, x11, #1, #1 msr oslar_el1, x11 reset_pmuserenr_el0 x0 // Disable PMU access from EL0
From: Andreas Gruenbacher agruenba@redhat.com
commit 5a5ec83d6ac974b12085cd99b196795f14079037 upstream.
Commit 4d207133e9c3 changed the types of the statistic values in struct gfs2_lkstats from s64 to u64. Because of that, what should be a signed value in gfs2_update_stats turned into an unsigned value. When shifted right, we end up with a large positive value instead of a small negative value, which results in an incorrect variance estimate.
Fixes: 4d207133e9c3 ("gfs2: Make statistics unsigned, suitable for use with do_div()") Signed-off-by: Andreas Gruenbacher agruenba@redhat.com Cc: stable@vger.kernel.org # v4.4+ Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/gfs2/lock_dlm.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
--- a/fs/gfs2/lock_dlm.c +++ b/fs/gfs2/lock_dlm.c @@ -32,9 +32,10 @@ extern struct workqueue_struct *gfs2_con * @delta is the difference between the current rtt sample and the * running average srtt. We add 1/8 of that to the srtt in order to * update the current srtt estimate. The variance estimate is a bit - * more complicated. We subtract the abs value of the @delta from - * the current variance estimate and add 1/4 of that to the running - * total. + * more complicated. We subtract the current variance estimate from + * the abs value of the @delta and add 1/4 of that to the running + * total. That's equivalent to 3/4 of the current variance + * estimate plus 1/4 of the abs of @delta. * * Note that the index points at the array entry containing the smoothed * mean value, and the variance is always in the following entry @@ -50,7 +51,7 @@ static inline void gfs2_update_stats(str s64 delta = sample - s->stats[index]; s->stats[index] += (delta >> 3); index++; - s->stats[index] += ((abs(delta) - s->stats[index]) >> 2); + s->stats[index] += (s64)(abs(delta) - s->stats[index]) >> 2; }
/**
From: Filipe Manana fdmanana@suse.com
commit 72bd2323ec87722c115a5906bc6a1b31d11e8f54 upstream.
Currently when we fail to COW a path at btrfs_update_root() we end up always aborting the transaction. However all the current callers of btrfs_update_root() are able to deal with errors returned from it, many do end up aborting the transaction themselves (directly or not, such as the transaction commit path), other BUG_ON() or just gracefully cancel whatever they were doing.
When syncing the fsync log, we call btrfs_update_root() through tree-log.c:update_log_root(), and if it returns an -ENOSPC error, the log sync code does not abort the transaction, instead it gracefully handles the error and returns -EAGAIN to the fsync handler, so that it falls back to a transaction commit. Any other error different from -ENOSPC, makes the log sync code abort the transaction.
So remove the transaction abort from btrfs_update_log() when we fail to COW a path to update the root item, so that if an -ENOSPC failure happens we avoid aborting the current transaction and have a chance of the fsync succeeding after falling back to a transaction commit.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=203413 Fixes: 79787eaab46121 ("btrfs: replace many BUG_ONs with proper error handling") Cc: stable@vger.kernel.org # 4.4+ Signed-off-by: Filipe Manana fdmanana@suse.com Reviewed-by: Anand Jain anand.jain@oracle.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/btrfs/root-tree.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
--- a/fs/btrfs/root-tree.c +++ b/fs/btrfs/root-tree.c @@ -144,10 +144,8 @@ int btrfs_update_root(struct btrfs_trans return -ENOMEM;
ret = btrfs_search_slot(trans, root, key, path, 0, 1); - if (ret < 0) { - btrfs_abort_transaction(trans, ret); + if (ret < 0) goto out; - }
if (ret != 0) { btrfs_print_leaf(root, path->nodes[0]);
From: Filipe Manana fdmanana@suse.com
commit 0c713cbab6200b0ab6473b50435e450a6e1de85d upstream.
When we do a full fsync (the bit BTRFS_INODE_NEEDS_FULL_SYNC is set in the inode) that happens to be ranged, which happens during a msync() or writes for files opened with O_SYNC for example, we can end up with a corrupt log, due to different file extent items representing ranges that overlap with each other, or hit some assertion failures.
When doing a ranged fsync we only flush delalloc and wait for ordered exents within that range. If while we are logging items from our inode ordered extents for adjacent ranges complete, we end up in a race that can make us insert the file extent items that overlap with others we logged previously and the assertion failures.
For example, if tree-log.c:copy_items() receives a leaf that has the following file extents items, all with a length of 4K and therefore there is an implicit hole in the range 68K to 72K - 1:
(257 EXTENT_ITEM 64K), (257 EXTENT_ITEM 72K), (257 EXTENT_ITEM 76K), ...
It copies them to the log tree. However due to the need to detect implicit holes, it may release the path, in order to look at the previous leaf to detect an implicit hole, and then later it will search again in the tree for the first file extent item key, with the goal of locking again the leaf (which might have changed due to concurrent changes to other inodes).
However when it locks again the leaf containing the first key, the key corresponding to the extent at offset 72K may not be there anymore since there is an ordered extent for that range that is finishing (that is, somewhere in the middle of btrfs_finish_ordered_io()), and it just removed the file extent item but has not yet replaced it with a new file extent item, so the part of copy_items() that does hole detection will decide that there is a hole in the range starting from 68K to 76K - 1, and therefore insert a file extent item to represent that hole, having a key offset of 68K. After that we now have a log tree with 2 different extent items that have overlapping ranges:
1) The file extent item copied before copy_items() released the path, which has a key offset of 72K and a length of 4K, representing the file range 72K to 76K - 1.
2) And a file extent item representing a hole that has a key offset of 68K and a length of 8K, representing the range 68K to 76K - 1. This item was inserted after releasing the path, and overlaps with the extent item inserted before.
The overlapping extent items can cause all sorts of unpredictable and incorrect behaviour, either when replayed or if a fast (non full) fsync happens later, which can trigger a BUG_ON() when calling btrfs_set_item_key_safe() through __btrfs_drop_extents(), producing a trace like the following:
[61666.783269] ------------[ cut here ]------------ [61666.783943] kernel BUG at fs/btrfs/ctree.c:3182! [61666.784644] invalid opcode: 0000 [#1] PREEMPT SMP (...) [61666.786253] task: ffff880117b88c40 task.stack: ffffc90008168000 [61666.786253] RIP: 0010:btrfs_set_item_key_safe+0x7c/0xd2 [btrfs] [61666.786253] RSP: 0018:ffffc9000816b958 EFLAGS: 00010246 [61666.786253] RAX: 0000000000000000 RBX: 000000000000000f RCX: 0000000000030000 [61666.786253] RDX: 0000000000000000 RSI: ffffc9000816ba4f RDI: ffffc9000816b937 [61666.786253] RBP: ffffc9000816b998 R08: ffff88011dae2428 R09: 0000000000001000 [61666.786253] R10: 0000160000000000 R11: 6db6db6db6db6db7 R12: ffff88011dae2418 [61666.786253] R13: ffffc9000816ba4f R14: ffff8801e10c4118 R15: ffff8801e715c000 [61666.786253] FS: 00007f6060a18700(0000) GS:ffff88023f5c0000(0000) knlGS:0000000000000000 [61666.786253] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [61666.786253] CR2: 00007f6060a28000 CR3: 0000000213e69000 CR4: 00000000000006e0 [61666.786253] Call Trace: [61666.786253] __btrfs_drop_extents+0x5e3/0xaad [btrfs] [61666.786253] ? time_hardirqs_on+0x9/0x14 [61666.786253] btrfs_log_changed_extents+0x294/0x4e0 [btrfs] [61666.786253] ? release_extent_buffer+0x38/0xb4 [btrfs] [61666.786253] btrfs_log_inode+0xb6e/0xcdc [btrfs] [61666.786253] ? lock_acquire+0x131/0x1c5 [61666.786253] ? btrfs_log_inode_parent+0xee/0x659 [btrfs] [61666.786253] ? arch_local_irq_save+0x9/0xc [61666.786253] ? btrfs_log_inode_parent+0x1f5/0x659 [btrfs] [61666.786253] btrfs_log_inode_parent+0x223/0x659 [btrfs] [61666.786253] ? arch_local_irq_save+0x9/0xc [61666.786253] ? lockref_get_not_zero+0x2c/0x34 [61666.786253] ? rcu_read_unlock+0x3e/0x5d [61666.786253] btrfs_log_dentry_safe+0x60/0x7b [btrfs] [61666.786253] btrfs_sync_file+0x317/0x42c [btrfs] [61666.786253] vfs_fsync_range+0x8c/0x9e [61666.786253] SyS_msync+0x13c/0x1c9 [61666.786253] entry_SYSCALL_64_fastpath+0x18/0xad
A sample of a corrupt log tree leaf with overlapping extents I got from running btrfs/072:
item 14 key (295 108 200704) itemoff 2599 itemsize 53 extent data disk bytenr 0 nr 0 extent data offset 0 nr 458752 ram 458752 item 15 key (295 108 659456) itemoff 2546 itemsize 53 extent data disk bytenr 4343541760 nr 770048 extent data offset 606208 nr 163840 ram 770048 item 16 key (295 108 663552) itemoff 2493 itemsize 53 extent data disk bytenr 4343541760 nr 770048 extent data offset 610304 nr 155648 ram 770048 item 17 key (295 108 819200) itemoff 2440 itemsize 53 extent data disk bytenr 4334788608 nr 4096 extent data offset 0 nr 4096 ram 4096
The file extent item at offset 659456 (item 15) ends at offset 823296 (659456 + 163840) while the next file extent item (item 16) starts at offset 663552.
Another different problem that the race can trigger is a failure in the assertions at tree-log.c:copy_items(), which expect that the first file extent item key we found before releasing the path exists after we have released path and that the last key we found before releasing the path also exists after releasing the path:
$ cat -n fs/btrfs/tree-log.c 4080 if (need_find_last_extent) { 4081 /* btrfs_prev_leaf could return 1 without releasing the path */ 4082 btrfs_release_path(src_path); 4083 ret = btrfs_search_slot(NULL, inode->root, &first_key, 4084 src_path, 0, 0); 4085 if (ret < 0) 4086 return ret; 4087 ASSERT(ret == 0); (...) 4103 if (i >= btrfs_header_nritems(src_path->nodes[0])) { 4104 ret = btrfs_next_leaf(inode->root, src_path); 4105 if (ret < 0) 4106 return ret; 4107 ASSERT(ret == 0); 4108 src = src_path->nodes[0]; 4109 i = 0; 4110 need_find_last_extent = true; 4111 } (...)
The second assertion implicitly expects that the last key before the path release still exists, because the surrounding while loop only stops after we have found that key. When this assertion fails it produces a stack like this:
[139590.037075] assertion failed: ret == 0, file: fs/btrfs/tree-log.c, line: 4107 [139590.037406] ------------[ cut here ]------------ [139590.037707] kernel BUG at fs/btrfs/ctree.h:3546! [139590.038034] invalid opcode: 0000 [#1] SMP DEBUG_PAGEALLOC PTI [139590.038340] CPU: 1 PID: 31841 Comm: fsstress Tainted: G W 5.0.0-btrfs-next-46 #1 (...) [139590.039354] RIP: 0010:assfail.constprop.24+0x18/0x1a [btrfs] (...) [139590.040397] RSP: 0018:ffffa27f48f2b9b0 EFLAGS: 00010282 [139590.040730] RAX: 0000000000000041 RBX: ffff897c635d92c8 RCX: 0000000000000000 [139590.041105] RDX: 0000000000000000 RSI: ffff897d36a96868 RDI: ffff897d36a96868 [139590.041470] RBP: ffff897d1b9a0708 R08: 0000000000000000 R09: 0000000000000000 [139590.041815] R10: 0000000000000008 R11: 0000000000000000 R12: 0000000000000013 [139590.042159] R13: 0000000000000227 R14: ffff897cffcbba88 R15: 0000000000000001 [139590.042501] FS: 00007f2efc8dee80(0000) GS:ffff897d36a80000(0000) knlGS:0000000000000000 [139590.042847] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [139590.043199] CR2: 00007f8c064935e0 CR3: 0000000232252002 CR4: 00000000003606e0 [139590.043547] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [139590.043899] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [139590.044250] Call Trace: [139590.044631] copy_items+0xa3f/0x1000 [btrfs] [139590.045009] ? generic_bin_search.constprop.32+0x61/0x200 [btrfs] [139590.045396] btrfs_log_inode+0x7b3/0xd70 [btrfs] [139590.045773] btrfs_log_inode_parent+0x2b3/0xce0 [btrfs] [139590.046143] ? do_raw_spin_unlock+0x49/0xc0 [139590.046510] btrfs_log_dentry_safe+0x4a/0x70 [btrfs] [139590.046872] btrfs_sync_file+0x3b6/0x440 [btrfs] [139590.047243] btrfs_file_write_iter+0x45b/0x5c0 [btrfs] [139590.047592] __vfs_write+0x129/0x1c0 [139590.047932] vfs_write+0xc2/0x1b0 [139590.048270] ksys_write+0x55/0xc0 [139590.048608] do_syscall_64+0x60/0x1b0 [139590.048946] entry_SYSCALL_64_after_hwframe+0x49/0xbe [139590.049287] RIP: 0033:0x7f2efc4be190 (...) [139590.050342] RSP: 002b:00007ffe743243a8 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 [139590.050701] RAX: ffffffffffffffda RBX: 0000000000008d58 RCX: 00007f2efc4be190 [139590.051067] RDX: 0000000000008d58 RSI: 00005567eca0f370 RDI: 0000000000000003 [139590.051459] RBP: 0000000000000024 R08: 0000000000000003 R09: 0000000000008d60 [139590.051863] R10: 0000000000000078 R11: 0000000000000246 R12: 0000000000000003 [139590.052252] R13: 00000000003d3507 R14: 00005567eca0f370 R15: 0000000000000000 (...) [139590.055128] ---[ end trace 193f35d0215cdeeb ]---
So fix this race between a full ranged fsync and writeback of adjacent ranges by flushing all delalloc and waiting for all ordered extents to complete before logging the inode. This is the simplest way to solve the problem because currently the full fsync path does not deal with ranges at all (it assumes a full range from 0 to LLONG_MAX) and it always needs to look at adjacent ranges for hole detection. For use cases of ranged fsyncs this can make a few fsyncs slower but on the other hand it can make some following fsyncs to other ranges do less work or no need to do anything at all. A full fsync is rare anyway and happens only once after loading/creating an inode and once after less common operations such as a shrinking truncate.
This is an issue that exists for a long time, and was often triggered by generic/127, because it does mmap'ed writes and msync (which triggers a ranged fsync). Adding support for the tree checker to detect overlapping extents (next patch in the series) and trigger a WARN() when such cases are found, and then calling btrfs_check_leaf_full() at the end of btrfs_insert_file_extent() made the issue much easier to detect. Running btrfs/072 with that change to the tree checker and making fsstress open files always with O_SYNC made it much easier to trigger the issue (as triggering it with generic/127 is very rare).
CC: stable@vger.kernel.org # 3.16+ Reviewed-by: Josef Bacik josef@toxicpanda.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/file.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
--- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1952,6 +1952,18 @@ int btrfs_sync_file(struct file *file, l u64 len;
/* + * If the inode needs a full sync, make sure we use a full range to + * avoid log tree corruption, due to hole detection racing with ordered + * extent completion for adjacent ranges, and assertion failures during + * hole detection. + */ + if (test_bit(BTRFS_INODE_NEEDS_FULL_SYNC, + &BTRFS_I(inode)->runtime_flags)) { + start = 0; + end = LLONG_MAX; + } + + /* * The range length can be represented by u64, we have to do the typecasts * to avoid signed overflow if it's [0, LLONG_MAX] eg. from fsync() */
From: Tobin C. Harding tobin@kernel.org
commit e32773357d5cc271b1d23550b3ed026eb5c2a468 upstream.
A failed call to kobject_init_and_add() must be followed by a call to kobject_put(). Currently in the error path when adding fs_devices we are missing this call. This could be fixed by calling btrfs_sysfs_remove_fsid() if btrfs_sysfs_add_fsid() returns an error or by adding a call to kobject_put() directly in btrfs_sysfs_add_fsid(). Here we choose the second option because it prevents the slightly unusual error path handling requirements of kobject from leaking out into btrfs functions.
Add a call to kobject_put() in the error path of kobject_add_and_init(). This causes the release method to be called if kobject_init_and_add() fails. open_tree() is the function that calls btrfs_sysfs_add_fsid() and the error code in this function is already written with the assumption that the release method is called during the error path of open_tree() (as seen by the call to btrfs_sysfs_remove_fsid() under the fail_fsdev_sysfs label).
Cc: stable@vger.kernel.org # v4.4+ Reviewed-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Tobin C. Harding tobin@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/sysfs.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
--- a/fs/btrfs/sysfs.c +++ b/fs/btrfs/sysfs.c @@ -751,7 +751,12 @@ int btrfs_sysfs_add_fsid(struct btrfs_fs fs_devs->fsid_kobj.kset = btrfs_kset; error = kobject_init_and_add(&fs_devs->fsid_kobj, &btrfs_ktype, parent, "%pU", fs_devs->fsid); - return error; + if (error) { + kobject_put(&fs_devs->fsid_kobj); + return error; + } + + return 0; }
int btrfs_sysfs_add_mounted(struct btrfs_fs_info *fs_info)
From: Shile Zhang shile.zhang@linux.alibaba.com
commit cf84807f6dd0be5214378e66460cfc9187f532f9 upstream.
To fix following divide-by-zero error found by Syzkaller:
divide error: 0000 [#1] SMP PTI CPU: 7 PID: 8447 Comm: test Kdump: loaded Not tainted 4.19.24-8.al7.x86_64 #1 Hardware name: Alibaba Cloud Alibaba Cloud ECS, BIOS rel-1.12.0-0-ga698c8995f-prebuilt.qemu.org 04/01/2014 RIP: 0010:fb_var_to_videomode+0xae/0xc0 Code: 04 44 03 46 78 03 4e 7c 44 03 46 68 03 4e 70 89 ce d1 ee 69 c0 e8 03 00 00 f6 c2 01 0f 45 ce 83 e2 02 8d 34 09 0f 45 ce 31 d2 <41> f7 f0 31 d2 f7 f1 89 47 08 f3 c3 66 0f 1f 44 00 00 0f 1f 44 00 RSP: 0018:ffffb7e189347bf0 EFLAGS: 00010246 RAX: 00000000e1692410 RBX: ffffb7e189347d60 RCX: 0000000000000000 RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffffb7e189347c10 RBP: ffff99972a091c00 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000100 R13: 0000000000010000 R14: 00007ffd66baf6d0 R15: 0000000000000000 FS: 00007f2054d11740(0000) GS:ffff99972fbc0000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f205481fd20 CR3: 00000004288a0001 CR4: 00000000001606a0 Call Trace: fb_set_var+0x257/0x390 ? lookup_fast+0xbb/0x2b0 ? fb_open+0xc0/0x140 ? chrdev_open+0xa6/0x1a0 do_fb_ioctl+0x445/0x5a0 do_vfs_ioctl+0x92/0x5f0 ? __alloc_fd+0x3d/0x160 ksys_ioctl+0x60/0x90 __x64_sys_ioctl+0x16/0x20 do_syscall_64+0x5b/0x190 entry_SYSCALL_64_after_hwframe+0x44/0xa9 RIP: 0033:0x7f20548258d7 Code: 44 00 00 48 8b 05 b9 15 2d 00 64 c7 00 26 00 00 00 48 c7 c0 ff ff ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 89 15 2d 00 f7 d8 64 89 01 48
It can be triggered easily with following test code:
#include <linux/fb.h> #include <fcntl.h> #include <sys/ioctl.h> int main(void) { struct fb_var_screeninfo var = {.activate = 0x100, .pixclock = 60}; int fd = open("/dev/fb0", O_RDWR); if (fd < 0) return 1;
if (ioctl(fd, FBIOPUT_VSCREENINFO, &var)) return 1;
return 0; }
Signed-off-by: Shile Zhang shile.zhang@linux.alibaba.com Cc: Fredrik Noring noring@nocrew.org Cc: Daniel Vetter daniel.vetter@ffwll.ch Reviewed-by: Mukesh Ojha mojha@codeaurora.org Signed-off-by: Bartlomiej Zolnierkiewicz b.zolnierkie@samsung.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/video/fbdev/core/modedb.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/drivers/video/fbdev/core/modedb.c +++ b/drivers/video/fbdev/core/modedb.c @@ -933,6 +933,9 @@ void fb_var_to_videomode(struct fb_video if (var->vmode & FB_VMODE_DOUBLE) vtotal *= 2;
+ if (!htotal || !vtotal) + return; + hfreq = pixclock/htotal; mode->refresh = hfreq/vtotal; }
From: Mike Kravetz mike.kravetz@oracle.com
commit 1b426bac66e6cc83c9f2d92b96e4e72acf43419a upstream.
hugetlb uses a fault mutex hash table to prevent page faults of the same pages concurrently. The key for shared and private mappings is different. Shared keys off address_space and file index. Private keys off mm and virtual address. Consider a private mappings of a populated hugetlbfs file. A fault will map the page from the file and if needed do a COW to map a writable page.
Hugetlbfs hole punch uses the fault mutex to prevent mappings of file pages. It uses the address_space file index key. However, private mappings will use a different key and could race with this code to map the file page. This causes problems (BUG) for the page cache remove code as it expects the page to be unmapped. A sample stack is:
page dumped because: VM_BUG_ON_PAGE(page_mapped(page)) kernel BUG at mm/filemap.c:169! ... RIP: 0010:unaccount_page_cache_page+0x1b8/0x200 ... Call Trace: __delete_from_page_cache+0x39/0x220 delete_from_page_cache+0x45/0x70 remove_inode_hugepages+0x13c/0x380 ? __add_to_page_cache_locked+0x162/0x380 hugetlbfs_fallocate+0x403/0x540 ? _cond_resched+0x15/0x30 ? __inode_security_revalidate+0x5d/0x70 ? selinux_file_permission+0x100/0x130 vfs_fallocate+0x13f/0x270 ksys_fallocate+0x3c/0x80 __x64_sys_fallocate+0x1a/0x20 do_syscall_64+0x5b/0x180 entry_SYSCALL_64_after_hwframe+0x44/0xa9
There seems to be another potential COW issue/race with this approach of different private and shared keys as noted in commit 8382d914ebf7 ("mm, hugetlb: improve page-fault scalability").
Since every hugetlb mapping (even anon and private) is actually a file mapping, just use the address_space index key for all mappings. This results in potentially more hash collisions. However, this should not be the common case.
Link: http://lkml.kernel.org/r/20190328234704.27083-3-mike.kravetz@oracle.com Link: http://lkml.kernel.org/r/20190412165235.t4sscoujczfhuiyt@linux-r8p5 Fixes: b5cec28d36f5 ("hugetlbfs: truncate_hugepages() takes a range of pages") Signed-off-by: Mike Kravetz mike.kravetz@oracle.com Reviewed-by: Naoya Horiguchi n-horiguchi@ah.jp.nec.com Reviewed-by: Davidlohr Bueso dbueso@suse.de Cc: Joonsoo Kim iamjoonsoo.kim@lge.com Cc: "Kirill A . Shutemov" kirill.shutemov@linux.intel.com Cc: Michal Hocko mhocko@kernel.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: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/hugetlbfs/inode.c | 8 ++------ include/linux/hugetlb.h | 4 +--- mm/hugetlb.c | 19 +++++-------------- 3 files changed, 8 insertions(+), 23 deletions(-)
--- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -451,9 +451,7 @@ static void remove_inode_hugepages(struc if (next >= end) break;
- hash = hugetlb_fault_mutex_hash(h, current->mm, - &pseudo_vma, - mapping, next, 0); + hash = hugetlb_fault_mutex_hash(h, mapping, next, 0); mutex_lock(&hugetlb_fault_mutex_table[hash]);
/* @@ -573,7 +571,6 @@ static long hugetlbfs_fallocate(struct f struct address_space *mapping = inode->i_mapping; struct hstate *h = hstate_inode(inode); struct vm_area_struct pseudo_vma; - struct mm_struct *mm = current->mm; loff_t hpage_size = huge_page_size(h); unsigned long hpage_shift = huge_page_shift(h); pgoff_t start, index, end; @@ -637,8 +634,7 @@ static long hugetlbfs_fallocate(struct f addr = index * hpage_size;
/* mutex taken here, fault path and hole punch */ - hash = hugetlb_fault_mutex_hash(h, mm, &pseudo_vma, mapping, - index, addr); + hash = hugetlb_fault_mutex_hash(h, mapping, index, addr); mutex_lock(&hugetlb_fault_mutex_table[hash]);
/* See if already present in mapping to avoid alloc/free */ --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -92,9 +92,7 @@ void putback_active_hugepage(struct page void free_huge_page(struct page *page); void hugetlb_fix_reserve_counts(struct inode *inode); extern struct mutex *hugetlb_fault_mutex_table; -u32 hugetlb_fault_mutex_hash(struct hstate *h, struct mm_struct *mm, - struct vm_area_struct *vma, - struct address_space *mapping, +u32 hugetlb_fault_mutex_hash(struct hstate *h, struct address_space *mapping, pgoff_t idx, unsigned long address);
pte_t *huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud); --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -3812,21 +3812,14 @@ backout_unlocked: }
#ifdef CONFIG_SMP -u32 hugetlb_fault_mutex_hash(struct hstate *h, struct mm_struct *mm, - struct vm_area_struct *vma, - struct address_space *mapping, +u32 hugetlb_fault_mutex_hash(struct hstate *h, struct address_space *mapping, pgoff_t idx, unsigned long address) { unsigned long key[2]; u32 hash;
- if (vma->vm_flags & VM_SHARED) { - key[0] = (unsigned long) mapping; - key[1] = idx; - } else { - key[0] = (unsigned long) mm; - key[1] = address >> huge_page_shift(h); - } + key[0] = (unsigned long) mapping; + key[1] = idx;
hash = jhash2((u32 *)&key, sizeof(key)/sizeof(u32), 0);
@@ -3837,9 +3830,7 @@ u32 hugetlb_fault_mutex_hash(struct hsta * For uniprocesor systems we always use a single mutex, so just * return 0 and avoid the hashing overhead. */ -u32 hugetlb_fault_mutex_hash(struct hstate *h, struct mm_struct *mm, - struct vm_area_struct *vma, - struct address_space *mapping, +u32 hugetlb_fault_mutex_hash(struct hstate *h, struct address_space *mapping, pgoff_t idx, unsigned long address) { return 0; @@ -3885,7 +3876,7 @@ int hugetlb_fault(struct mm_struct *mm, * get spurious allocation failures if two CPUs race to instantiate * the same page in the page cache. */ - hash = hugetlb_fault_mutex_hash(h, mm, vma, mapping, idx, address); + hash = hugetlb_fault_mutex_hash(h, mapping, idx, address); mutex_lock(&hugetlb_fault_mutex_table[hash]);
entry = huge_ptep_get(ptep);
From: Jiufei Xue jiufei.xue@linux.alibaba.com
commit 8c40292be9169a9cbe19aadd1a6fc60cbd1af82f upstream.
Syzkaller hit 'WARNING in __alloc_pages_nodemask' bug.
WARNING: CPU: 1 PID: 1473 at mm/page_alloc.c:4377 __alloc_pages_nodemask+0x4da/0x2130 Kernel panic - not syncing: panic_on_warn set ...
Call Trace: alloc_pages_current+0xb1/0x1e0 kmalloc_order+0x1f/0x60 kmalloc_order_trace+0x1d/0x120 fb_alloc_cmap_gfp+0x85/0x2b0 fb_set_user_cmap+0xff/0x370 do_fb_ioctl+0x949/0xa20 fb_ioctl+0xdd/0x120 do_vfs_ioctl+0x186/0x1070 ksys_ioctl+0x89/0xa0 __x64_sys_ioctl+0x74/0xb0 do_syscall_64+0xc8/0x550 entry_SYSCALL_64_after_hwframe+0x49/0xbe
This is a warning about order >= MAX_ORDER and the order is from userspace ioctl. Add flag __NOWARN to silence this warning.
Signed-off-by: Jiufei Xue jiufei.xue@linux.alibaba.com Signed-off-by: Bartlomiej Zolnierkiewicz b.zolnierkie@samsung.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/video/fbdev/core/fbcmap.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/video/fbdev/core/fbcmap.c +++ b/drivers/video/fbdev/core/fbcmap.c @@ -94,6 +94,8 @@ int fb_alloc_cmap_gfp(struct fb_cmap *cm int size = len * sizeof(u16); int ret = -ENOMEM;
+ flags |= __GFP_NOWARN; + if (cmap->len != len) { fb_dealloc_cmap(cmap); if (!len)
From: YueHaibing yuehaibing@huawei.com
commit dea37a97265588da604c6ba80160a287b72c7bfd upstream.
Syzkaller report this:
BUG: KASAN: use-after-free in sysfs_remove_file_ns+0x5f/0x70 fs/sysfs/file.c:468 Read of size 8 at addr ffff8881f59a6b70 by task syz-executor.0/8363
CPU: 0 PID: 8363 Comm: syz-executor.0 Not tainted 5.0.0-rc8+ #3 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1ubuntu1 04/01/2014 Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0xfa/0x1ce lib/dump_stack.c:113 print_address_description+0x65/0x270 mm/kasan/report.c:187 kasan_report+0x149/0x18d mm/kasan/report.c:317 sysfs_remove_file_ns+0x5f/0x70 fs/sysfs/file.c:468 sysfs_remove_file include/linux/sysfs.h:519 [inline] driver_remove_file+0x40/0x50 drivers/base/driver.c:122 usb_remove_newid_files drivers/usb/core/driver.c:212 [inline] usb_deregister+0x12a/0x3b0 drivers/usb/core/driver.c:1005 cpia2_exit+0xa/0x16 [cpia2] __do_sys_delete_module kernel/module.c:1018 [inline] __se_sys_delete_module kernel/module.c:961 [inline] __x64_sys_delete_module+0x3dc/0x5e0 kernel/module.c:961 do_syscall_64+0x147/0x600 arch/x86/entry/common.c:290 entry_SYSCALL_64_after_hwframe+0x49/0xbe RIP: 0033:0x462e99 Code: f7 d8 64 89 02 b8 ff ff ff ff c3 66 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 bc ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007f86f3754c58 EFLAGS: 00000246 ORIG_RAX: 00000000000000b0 RAX: ffffffffffffffda RBX: 000000000073bf00 RCX: 0000000000462e99 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000020000300 RBP: 0000000000000002 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 00007f86f37556bc R13: 00000000004bcca9 R14: 00000000006f6b48 R15: 00000000ffffffff
Allocated by task 8363: set_track mm/kasan/common.c:85 [inline] __kasan_kmalloc.constprop.3+0xa0/0xd0 mm/kasan/common.c:495 kmalloc include/linux/slab.h:545 [inline] kzalloc include/linux/slab.h:740 [inline] bus_add_driver+0xc0/0x610 drivers/base/bus.c:651 driver_register+0x1bb/0x3f0 drivers/base/driver.c:170 usb_register_driver+0x267/0x520 drivers/usb/core/driver.c:965 0xffffffffc1b4817c do_one_initcall+0xfa/0x5ca init/main.c:887 do_init_module+0x204/0x5f6 kernel/module.c:3460 load_module+0x66b2/0x8570 kernel/module.c:3808 __do_sys_finit_module+0x238/0x2a0 kernel/module.c:3902 do_syscall_64+0x147/0x600 arch/x86/entry/common.c:290 entry_SYSCALL_64_after_hwframe+0x49/0xbe
Freed by task 8363: set_track mm/kasan/common.c:85 [inline] __kasan_slab_free+0x130/0x180 mm/kasan/common.c:457 slab_free_hook mm/slub.c:1430 [inline] slab_free_freelist_hook mm/slub.c:1457 [inline] slab_free mm/slub.c:3005 [inline] kfree+0xe1/0x270 mm/slub.c:3957 kobject_cleanup lib/kobject.c:662 [inline] kobject_release lib/kobject.c:691 [inline] kref_put include/linux/kref.h:67 [inline] kobject_put+0x146/0x240 lib/kobject.c:708 bus_remove_driver+0x10e/0x220 drivers/base/bus.c:732 driver_unregister+0x6c/0xa0 drivers/base/driver.c:197 usb_register_driver+0x341/0x520 drivers/usb/core/driver.c:980 0xffffffffc1b4817c do_one_initcall+0xfa/0x5ca init/main.c:887 do_init_module+0x204/0x5f6 kernel/module.c:3460 load_module+0x66b2/0x8570 kernel/module.c:3808 __do_sys_finit_module+0x238/0x2a0 kernel/module.c:3902 do_syscall_64+0x147/0x600 arch/x86/entry/common.c:290 entry_SYSCALL_64_after_hwframe+0x49/0xbe
The buggy address belongs to the object at ffff8881f59a6b40 which belongs to the cache kmalloc-256 of size 256 The buggy address is located 48 bytes inside of 256-byte region [ffff8881f59a6b40, ffff8881f59a6c40) The buggy address belongs to the page: page:ffffea0007d66980 count:1 mapcount:0 mapping:ffff8881f6c02e00 index:0x0 flags: 0x2fffc0000000200(slab) raw: 02fffc0000000200 dead000000000100 dead000000000200 ffff8881f6c02e00 raw: 0000000000000000 00000000800c000c 00000001ffffffff 0000000000000000 page dumped because: kasan: bad access detected
Memory state around the buggy address: ffff8881f59a6a00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ffff8881f59a6a80: 00 00 00 00 00 00 00 00 00 00 fc fc fc fc fc fc
ffff8881f59a6b00: fc fc fc fc fc fc fc fc fb fb fb fb fb fb fb fb
^ ffff8881f59a6b80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ffff8881f59a6c00: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
cpia2_init does not check return value of cpia2_init, if it failed in usb_register_driver, there is already cleanup using driver_unregister. No need call cpia2_usb_cleanup on module exit.
Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: YueHaibing yuehaibing@huawei.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+samsung@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/media/usb/cpia2/cpia2_v4l.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
--- a/drivers/media/usb/cpia2/cpia2_v4l.c +++ b/drivers/media/usb/cpia2/cpia2_v4l.c @@ -1248,8 +1248,7 @@ static int __init cpia2_init(void) LOG("%s v%s\n", ABOUT, CPIA_VERSION); check_parameters(); - cpia2_usb_init(); - return 0; + return cpia2_usb_init(); }
From: Alexander Potapenko glider@google.com
commit dad7e270ba712ba1c99cd2d91018af6044447a06 upstream.
syzkaller reported crashes on kfree() called from vivid_vid_cap_s_selection(). This looks like a simple typo, as dev->bitmap_cap is allocated with vzalloc() throughout the file.
Fixes: ef834f7836ec0 ("[media] vivid: add the video capture and output parts")
Signed-off-by: Alexander Potapenko glider@google.com Reported-by: Syzbot syzbot+6c0effb5877f6b0344e2@syzkaller.appspotmail.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+samsung@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/media/platform/vivid/vivid-vid-cap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/media/platform/vivid/vivid-vid-cap.c +++ b/drivers/media/platform/vivid/vivid-vid-cap.c @@ -984,7 +984,7 @@ int vivid_vid_cap_s_selection(struct fil v4l2_rect_map_inside(&s->r, &dev->fmt_cap_rect); if (dev->bitmap_cap && (compose->width != s->r.width || compose->height != s->r.height)) { - kfree(dev->bitmap_cap); + vfree(dev->bitmap_cap); dev->bitmap_cap = NULL; } *compose = s->r;
From: YueHaibing yuehaibing@huawei.com
commit b2c01aab9646ed8ffb7c549afe55d5349c482425 upstream.
Syzkaller report this:
kasan: GPF could be caused by NULL-ptr deref or user memory access general protection fault: 0000 [#1] SMP KASAN PTI CPU: 0 PID: 4492 Comm: syz-executor.0 Not tainted 5.0.0-rc7+ #45 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1ubuntu1 04/01/2014 RIP: 0010:sysfs_remove_file_ns+0x27/0x70 fs/sysfs/file.c:468 Code: 00 00 00 41 54 55 48 89 fd 53 49 89 d4 48 89 f3 e8 ee 76 9c ff 48 8d 7d 30 48 b8 00 00 00 00 00 fc ff df 48 89 fa 48 c1 ea 03 <80> 3c 02 00 75 2d 48 89 da 48 b8 00 00 00 00 00 fc ff df 48 8b 6d RSP: 0018:ffff8881e9d9fc00 EFLAGS: 00010206 RAX: dffffc0000000000 RBX: ffffffff900367e0 RCX: ffffffff81a95952 RDX: 0000000000000006 RSI: ffffc90001405000 RDI: 0000000000000030 RBP: 0000000000000000 R08: fffffbfff1fa22ed R09: fffffbfff1fa22ed R10: 0000000000000001 R11: fffffbfff1fa22ec R12: 0000000000000000 R13: ffffffffc1abdac0 R14: 1ffff1103d3b3f8b R15: 0000000000000000 FS: 00007fe409dc1700(0000) GS:ffff8881f1200000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000001b2d721000 CR3: 00000001e98b6005 CR4: 00000000007606f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 PKRU: 55555554 Call Trace: sysfs_remove_file include/linux/sysfs.h:519 [inline] driver_remove_file+0x40/0x50 drivers/base/driver.c:122 pcmcia_remove_newid_file drivers/pcmcia/ds.c:163 [inline] pcmcia_unregister_driver+0x7d/0x2b0 drivers/pcmcia/ds.c:209 ssb_modexit+0xa/0x1b [ssb] __do_sys_delete_module kernel/module.c:1018 [inline] __se_sys_delete_module kernel/module.c:961 [inline] __x64_sys_delete_module+0x3dc/0x5e0 kernel/module.c:961 do_syscall_64+0x147/0x600 arch/x86/entry/common.c:290 entry_SYSCALL_64_after_hwframe+0x49/0xbe RIP: 0033:0x462e99 Code: f7 d8 64 89 02 b8 ff ff ff ff c3 66 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 bc ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007fe409dc0c58 EFLAGS: 00000246 ORIG_RAX: 00000000000000b0 RAX: ffffffffffffffda RBX: 000000000073bf00 RCX: 0000000000462e99 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 00000000200000c0 RBP: 0000000000000002 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 00007fe409dc16bc R13: 00000000004bccaa R14: 00000000006f6bc8 R15: 00000000ffffffff Modules linked in: ssb(-) 3c59x nvme_core macvlan tap pata_hpt3x3 rt2x00pci null_blk tsc40 pm_notifier_error_inject notifier_error_inject mdio cdc_wdm nf_reject_ipv4 ath9k_common ath9k_hw ath pppox ppp_generic slhc ehci_platform wl12xx wlcore tps6507x_ts ioc4 nf_synproxy_core ide_gd_mod ax25 can_dev iwlwifi can_raw atm tm2_touchkey can_gw can sundance adp5588_keys rt2800mmio rt2800lib rt2x00mmio rt2x00lib eeprom_93cx6 pn533 lru_cache elants_i2c ip_set nfnetlink gameport tipc hampshire nhc_ipv6 nhc_hop nhc_udp nhc_fragment nhc_routing nhc_mobility nhc_dest 6lowpan silead brcmutil nfc mt76_usb mt76 mac80211 iptable_security iptable_raw iptable_mangle iptable_nat nf_nat_ipv4 nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 iptable_filter bpfilter ip6_vti ip_gre sit hsr veth vxcan batman_adv cfg80211 rfkill chnl_net caif nlmon vcan bridge stp llc ip6_gre ip6_tunnel tunnel6 tun joydev mousedev serio_raw ide_pci_generic piix floppy ide_core sch_fq_codel ip_tables x_tables ipv6 [last unloaded: 3c59x] Dumping ftrace buffer: (ftrace buffer empty) ---[ end trace 3913cbf8011e1c05 ]---
In ssb_modinit, it does not fail SSB init when ssb_host_pcmcia_init failed, however in ssb_modexit, ssb_host_pcmcia_exit calls pcmcia_unregister_driver unconditionally, which may tigger a NULL pointer dereference issue as above.
Reported-by: Hulk Robot hulkci@huawei.com Fixes: 399500da18f7 ("ssb: pick PCMCIA host code support from b43 driver") Signed-off-by: YueHaibing yuehaibing@huawei.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/ssb/bridge_pcmcia_80211.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
--- a/drivers/ssb/bridge_pcmcia_80211.c +++ b/drivers/ssb/bridge_pcmcia_80211.c @@ -113,16 +113,21 @@ static struct pcmcia_driver ssb_host_pcm .resume = ssb_host_pcmcia_resume, };
+static int pcmcia_init_failed; + /* * These are not module init/exit functions! * The module_pcmcia_driver() helper cannot be used here. */ int ssb_host_pcmcia_init(void) { - return pcmcia_register_driver(&ssb_host_pcmcia_driver); + pcmcia_init_failed = pcmcia_register_driver(&ssb_host_pcmcia_driver); + + return pcmcia_init_failed; }
void ssb_host_pcmcia_exit(void) { - pcmcia_unregister_driver(&ssb_host_pcmcia_driver); + if (!pcmcia_init_failed) + pcmcia_unregister_driver(&ssb_host_pcmcia_driver); }
From: YueHaibing yuehaibing@huawei.com
commit 09ac2694b0475f96be895848687ebcbba97eeecf upstream.
Syzkaller report this:
[ 1213.468581] BUG: unable to handle kernel paging request at fffffbfff83bf338 [ 1213.469530] #PF error: [normal kernel read fault] [ 1213.469530] PGD 237fe4067 P4D 237fe4067 PUD 237e60067 PMD 1c868b067 PTE 0 [ 1213.473514] Oops: 0000 [#1] SMP KASAN PTI [ 1213.473514] CPU: 0 PID: 6321 Comm: syz-executor.0 Tainted: G C 5.1.0-rc3+ #8 [ 1213.473514] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1ubuntu1 04/01/2014 [ 1213.473514] RIP: 0010:strcmp+0x31/0xa0 [ 1213.473514] Code: 00 00 00 00 fc ff df 55 53 48 83 ec 08 eb 0a 84 db 48 89 ef 74 5a 4c 89 e6 48 89 f8 48 89 fa 48 8d 6f 01 48 c1 e8 03 83 e2 07 <42> 0f b6 04 28 38 d0 7f 04 84 c0 75 50 48 89 f0 48 89 f2 0f b6 5d [ 1213.473514] RSP: 0018:ffff8881f2b7f950 EFLAGS: 00010246 [ 1213.473514] RAX: 1ffffffff83bf338 RBX: ffff8881ea6f7240 RCX: ffffffff825350c6 [ 1213.473514] RDX: 0000000000000000 RSI: ffffffffc1ee19c0 RDI: ffffffffc1df99c0 [ 1213.473514] RBP: ffffffffc1df99c1 R08: 0000000000000001 R09: 0000000000000004 [ 1213.473514] R10: 0000000000000000 R11: ffff8881de353f00 R12: ffff8881ee727900 [ 1213.473514] R13: dffffc0000000000 R14: 0000000000000001 R15: ffffffffc1eeaaf0 [ 1213.473514] FS: 00007fa66fa01700(0000) GS:ffff8881f7200000(0000) knlGS:0000000000000000 [ 1213.473514] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 1213.473514] CR2: fffffbfff83bf338 CR3: 00000001ebb9e005 CR4: 00000000007606f0 [ 1213.473514] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 1213.473514] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 1213.473514] PKRU: 55555554 [ 1213.473514] Call Trace: [ 1213.473514] led_trigger_register+0x112/0x3f0 [ 1213.473514] led_trigger_register_simple+0x7a/0x110 [ 1213.473514] ? 0xffffffffc1c10000 [ 1213.473514] at76_mod_init+0x77/0x1000 [at76c50x_usb] [ 1213.473514] do_one_initcall+0xbc/0x47d [ 1213.473514] ? perf_trace_initcall_level+0x3a0/0x3a0 [ 1213.473514] ? kasan_unpoison_shadow+0x30/0x40 [ 1213.473514] ? kasan_unpoison_shadow+0x30/0x40 [ 1213.473514] do_init_module+0x1b5/0x547 [ 1213.473514] load_module+0x6405/0x8c10 [ 1213.473514] ? module_frob_arch_sections+0x20/0x20 [ 1213.473514] ? kernel_read_file+0x1e6/0x5d0 [ 1213.473514] ? find_held_lock+0x32/0x1c0 [ 1213.473514] ? cap_capable+0x1ae/0x210 [ 1213.473514] ? __do_sys_finit_module+0x162/0x190 [ 1213.473514] __do_sys_finit_module+0x162/0x190 [ 1213.473514] ? __ia32_sys_init_module+0xa0/0xa0 [ 1213.473514] ? __mutex_unlock_slowpath+0xdc/0x690 [ 1213.473514] ? wait_for_completion+0x370/0x370 [ 1213.473514] ? vfs_write+0x204/0x4a0 [ 1213.473514] ? do_syscall_64+0x18/0x450 [ 1213.473514] do_syscall_64+0x9f/0x450 [ 1213.473514] entry_SYSCALL_64_after_hwframe+0x49/0xbe [ 1213.473514] RIP: 0033:0x462e99 [ 1213.473514] Code: f7 d8 64 89 02 b8 ff ff ff ff c3 66 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 bc ff ff ff f7 d8 64 89 01 48 [ 1213.473514] RSP: 002b:00007fa66fa00c58 EFLAGS: 00000246 ORIG_RAX: 0000000000000139 [ 1213.473514] RAX: ffffffffffffffda RBX: 000000000073bf00 RCX: 0000000000462e99 [ 1213.473514] RDX: 0000000000000000 RSI: 0000000020000300 RDI: 0000000000000003 [ 1213.473514] RBP: 00007fa66fa00c70 R08: 0000000000000000 R09: 0000000000000000 [ 1213.473514] R10: 0000000000000000 R11: 0000000000000246 R12: 00007fa66fa016bc [ 1213.473514] R13: 00000000004bcefa R14: 00000000006f6fb0 R15: 0000000000000004
If usb_register failed, no need to call led_trigger_register_simple.
Reported-by: Hulk Robot hulkci@huawei.com Fixes: 1264b951463a ("at76c50x-usb: add driver") Signed-off-by: YueHaibing yuehaibing@huawei.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/net/wireless/atmel/at76c50x-usb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/net/wireless/atmel/at76c50x-usb.c +++ b/drivers/net/wireless/atmel/at76c50x-usb.c @@ -2583,8 +2583,8 @@ static int __init at76_mod_init(void) if (result < 0) printk(KERN_ERR DRIVER_NAME ": usb_register failed (status %d)\n", result); - - led_trigger_register_simple("at76_usb-tx", &ledtrig_tx); + else + led_trigger_register_simple("at76_usb-tx", &ledtrig_tx); return result; }
From: Arnaldo Carvalho de Melo acme@redhat.com
commit 6dcca6df4b73d409628c7b4464c63d4eb9d4d13a upstream.
When we switched to the kernel's roundup_pow_of_two we forgot to remove this include from util.h, do it now.
Cc: Adrian Hunter adrian.hunter@intel.com Cc: David Ahern dsahern@gmail.com Cc: Jiri Olsa jolsa@kernel.org Cc: Namhyung Kim namhyung@kernel.org Cc: Wang Nan wangnan0@huawei.com Fixes: 91529834d1de ("perf evlist: Use roundup_pow_of_two") Link: http://lkml.kernel.org/n/tip-kfye5rxivib6155cltx0bw4h@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com [bwh: Backported to 4.9 as dependency of "tools include: Adopt linux/bits.h"; adjusted context] Signed-off-by: Ben Hutchings ben@decadent.org.uk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- tools/perf/util/util.h | 1 - 1 file changed, 1 deletion(-)
--- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -74,7 +74,6 @@ #include <sys/ttydefaults.h> #include <api/fs/tracing_path.h> #include <termios.h> -#include <linux/bitops.h> #include <termios.h> #include "strlist.h"
From: Arnaldo Carvalho de Melo acme@redhat.com
commit ba4aa02b417f08a0bee5e7b8ed70cac788a7c854 upstream.
So that we reduce the difference of tools/include/linux/bitops.h to the original kernel file, include/linux/bitops.h, trying to remove the need to define BITS_PER_LONG, to avoid clashes with asm/bitsperlong.h.
And the things removed from tools/include/linux/bitops.h are really in linux/bits.h, so that we can have a copy and then tools/perf/check_headers.sh will tell us when new stuff gets added to linux/bits.h so that we can check if it is useful and if any adjustment needs to be done to the tools/{include,arch}/ copies.
Cc: Adrian Hunter adrian.hunter@intel.com Cc: Alexander Sverdlin alexander.sverdlin@nokia.com Cc: David Ahern dsahern@gmail.com Cc: Jiri Olsa jolsa@kernel.org Cc: Namhyung Kim namhyung@kernel.org Cc: Wang Nan wangnan0@huawei.com Link: https://lkml.kernel.org/n/tip-y1sqyydvfzo0bjjoj4zsl562@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com [bwh: Backported to 4.9 as dependency of "x86/msr-index: Cleanup bit defines"; adjusted context] Signed-off-by: Ben Hutchings ben@decadent.org.uk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- tools/include/linux/bitops.h | 7 ++----- tools/include/linux/bits.h | 26 ++++++++++++++++++++++++++ tools/perf/check-headers.sh | 1 + 3 files changed, 29 insertions(+), 5 deletions(-) create mode 100644 tools/include/linux/bits.h
--- a/tools/include/linux/bitops.h +++ b/tools/include/linux/bitops.h @@ -3,8 +3,6 @@
#include <asm/types.h> #include <linux/kernel.h> -#include <linux/compiler.h> - #ifndef __WORDSIZE #define __WORDSIZE (__SIZEOF_LONG__ * 8) #endif @@ -12,10 +10,9 @@ #ifndef BITS_PER_LONG # define BITS_PER_LONG __WORDSIZE #endif +#include <linux/bits.h> +#include <linux/compiler.h>
-#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) -#define BIT_WORD(nr) ((nr) / BITS_PER_LONG) -#define BITS_PER_BYTE 8 #define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) #define BITS_TO_U64(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u64)) #define BITS_TO_U32(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u32)) --- /dev/null +++ b/tools/include/linux/bits.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __LINUX_BITS_H +#define __LINUX_BITS_H +#include <asm/bitsperlong.h> + +#define BIT(nr) (1UL << (nr)) +#define BIT_ULL(nr) (1ULL << (nr)) +#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) +#define BIT_WORD(nr) ((nr) / BITS_PER_LONG) +#define BIT_ULL_MASK(nr) (1ULL << ((nr) % BITS_PER_LONG_LONG)) +#define BIT_ULL_WORD(nr) ((nr) / BITS_PER_LONG_LONG) +#define BITS_PER_BYTE 8 + +/* + * Create a contiguous bitmask starting at bit position @l and ending at + * position @h. For example + * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000. + */ +#define GENMASK(h, l) \ + (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h)))) + +#define GENMASK_ULL(h, l) \ + (((~0ULL) - (1ULL << (l)) + 1) & \ + (~0ULL >> (BITS_PER_LONG_LONG - 1 - (h)))) + +#endif /* __LINUX_BITS_H */ --- a/tools/perf/check-headers.sh +++ b/tools/perf/check-headers.sh @@ -4,6 +4,7 @@ HEADERS=' include/uapi/linux/fcntl.h include/uapi/linux/perf_event.h include/uapi/linux/stat.h +include/linux/bits.h include/linux/hash.h include/uapi/linux/hw_breakpoint.h arch/x86/include/asm/disabled-features.h
From: David Sterba dsterba@suse.com
This reverts commit 038ec2c13e0d1f7b9d45a081786f18f75b65f11b.
There is currently no corresponding patch in master due to additional changes that would be significantly different from plain revert in the respective stable branch.
The range argument was not handled correctly and could cause trim to overlap allocated areas or reach beyond the end of the device. The address space that fitrim normally operates on is in logical coordinates, while the discards are done on the physical device extents. This distinction cannot be made with the current ioctl interface and caused the confusion.
The bug depends on the layout of block groups and does not always happen. The whole-fs trim (run by default by the fstrim tool) is not affected.
Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/btrfs/extent-tree.c | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-)
--- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -11150,9 +11150,9 @@ int btrfs_error_unpin_extent_range(struc * transaction. */ static int btrfs_trim_free_extents(struct btrfs_device *device, - struct fstrim_range *range, u64 *trimmed) + u64 minlen, u64 *trimmed) { - u64 start = range->start, len = 0; + u64 start = 0, len = 0; int ret;
*trimmed = 0; @@ -11188,8 +11188,8 @@ static int btrfs_trim_free_extents(struc atomic_inc(&trans->use_count); spin_unlock(&fs_info->trans_lock);
- ret = find_free_dev_extent_start(trans, device, range->minlen, - start, &start, &len); + ret = find_free_dev_extent_start(trans, device, minlen, start, + &start, &len); if (trans) btrfs_put_transaction(trans);
@@ -11201,16 +11201,6 @@ static int btrfs_trim_free_extents(struc break; }
- /* If we are out of the passed range break */ - if (start > range->start + range->len - 1) { - mutex_unlock(&fs_info->chunk_mutex); - ret = 0; - break; - } - - start = max(range->start, start); - len = min(range->len, len); - ret = btrfs_issue_discard(device->bdev, start, len, &bytes); up_read(&fs_info->commit_root_sem); mutex_unlock(&fs_info->chunk_mutex); @@ -11221,10 +11211,6 @@ static int btrfs_trim_free_extents(struc start += len; *trimmed += bytes;
- /* We've trimmed enough */ - if (*trimmed >= range->len) - break; - if (fatal_signal_pending(current)) { ret = -ERESTARTSYS; break; @@ -11309,7 +11295,8 @@ int btrfs_trim_fs(struct btrfs_root *roo mutex_lock(&fs_info->fs_devices->device_list_mutex); devices = &fs_info->fs_devices->devices; list_for_each_entry(device, devices, dev_list) { - ret = btrfs_trim_free_extents(device, range, &group_trimmed); + ret = btrfs_trim_free_extents(device, range->minlen, + &group_trimmed); if (ret) { dev_failed++; dev_ret = ret;
[ Upstream commit 7881ef3f33bb80f459ea6020d1e021fc524a6348 ]
Under certain conditions, lru_count may drop below zero resulting in a large amount of log spam like this:
vmscan: shrink_slab: gfs2_dump_glock+0x3b0/0x630 [gfs2] \ negative objects to delete nr=-1
This happens as follows: 1) A glock is moved from lru_list to the dispose list and lru_count is decremented. 2) The dispose function calls cond_resched() and drops the lru lock. 3) Another thread takes the lru lock and tries to add the same glock to lru_list, checking if the glock is on an lru list. 4) It is on a list (actually the dispose list) and so it avoids incrementing lru_count. 5) The glock is moved to lru_list. 5) The original thread doesn't dispose it because it has been re-added to the lru list but the lru_count has still decreased by one.
Fix by checking if the LRU flag is set on the glock rather than checking if the glock is on some list and rearrange the code so that the LRU flag is added/removed precisely when the glock is added/removed from lru_list.
Signed-off-by: Ross Lagerwall ross.lagerwall@citrix.com Signed-off-by: Andreas Gruenbacher agruenba@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/gfs2/glock.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 7a8b1d72e3d91..efd44d5645d83 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -136,22 +136,26 @@ static int demote_ok(const struct gfs2_glock *gl)
void gfs2_glock_add_to_lru(struct gfs2_glock *gl) { + if (!(gl->gl_ops->go_flags & GLOF_LRU)) + return; + spin_lock(&lru_lock);
- if (!list_empty(&gl->gl_lru)) - list_del_init(&gl->gl_lru); - else + list_del(&gl->gl_lru); + list_add_tail(&gl->gl_lru, &lru_list); + + if (!test_bit(GLF_LRU, &gl->gl_flags)) { + set_bit(GLF_LRU, &gl->gl_flags); atomic_inc(&lru_count); + }
- list_add_tail(&gl->gl_lru, &lru_list); - set_bit(GLF_LRU, &gl->gl_flags); spin_unlock(&lru_lock); }
static void gfs2_glock_remove_from_lru(struct gfs2_glock *gl) { spin_lock(&lru_lock); - if (!list_empty(&gl->gl_lru)) { + if (test_bit(GLF_LRU, &gl->gl_flags)) { list_del_init(&gl->gl_lru); atomic_dec(&lru_count); clear_bit(GLF_LRU, &gl->gl_flags); @@ -1048,8 +1052,7 @@ void gfs2_glock_dq(struct gfs2_holder *gh) !test_bit(GLF_DEMOTE, &gl->gl_flags)) fast_path = 1; } - if (!test_bit(GLF_LFLUSH, &gl->gl_flags) && demote_ok(gl) && - (glops->go_flags & GLOF_LRU)) + if (!test_bit(GLF_LFLUSH, &gl->gl_flags) && demote_ok(gl)) gfs2_glock_add_to_lru(gl);
trace_gfs2_glock_queue(gh, 0); @@ -1349,6 +1352,7 @@ __acquires(&lru_lock) if (!spin_trylock(&gl->gl_lockref.lock)) { add_back_to_lru: list_add(&gl->gl_lru, &lru_list); + set_bit(GLF_LRU, &gl->gl_flags); atomic_inc(&lru_count); continue; } @@ -1356,7 +1360,6 @@ __acquires(&lru_lock) spin_unlock(&gl->gl_lockref.lock); goto add_back_to_lru; } - clear_bit(GLF_LRU, &gl->gl_flags); gl->gl_lockref.count++; if (demote_ok(gl)) handle_callback(gl, LM_ST_UNLOCKED, 0, false); @@ -1392,6 +1395,7 @@ static long gfs2_scan_glock_lru(int nr) if (!test_bit(GLF_LOCK, &gl->gl_flags)) { list_move(&gl->gl_lru, &dispose); atomic_dec(&lru_count); + clear_bit(GLF_LRU, &gl->gl_flags); freed++; continue; }
[ Upstream commit a3147770bea76c8dbad73eca3a24c2118da5e719 ]
BUG: unable to handle kernel paging request at ffffffffa016a270 PGD 3270067 P4D 3270067 PUD 3271063 PMD 230bbd067 PTE 0 Oops: 0000 [#1 CPU: 0 PID: 6134 Comm: modprobe Not tainted 5.1.0+ #33 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.9.3-0-ge2fc41e-prebuilt.qemu-project.org 04/01/2014 RIP: 0010:atomic_notifier_chain_register+0x24/0x60 Code: 1f 80 00 00 00 00 55 48 89 e5 41 54 49 89 f4 53 48 89 fb e8 ae b4 38 01 48 8b 53 38 48 8d 4b 38 48 85 d2 74 20 45 8b 44 24 10 <44> 3b 42 10 7e 08 eb 13 44 39 42 10 7c 0d 48 8d 4a 08 48 8b 52 08 RSP: 0018:ffffc90000e2bc60 EFLAGS: 00010086 RAX: 0000000000000292 RBX: ffffffff83467240 RCX: ffffffff83467278 RDX: ffffffffa016a260 RSI: ffffffff83752140 RDI: ffffffff83467240 RBP: ffffc90000e2bc70 R08: 0000000000000000 R09: 0000000000000001 R10: 0000000000000000 R11: 00000000014fa61f R12: ffffffffa01c8260 R13: ffff888231091e00 R14: 0000000000000000 R15: ffffc90000e2be78 FS: 00007fbd8d7cd540(0000) GS:ffff888237a00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffffffffa016a270 CR3: 000000022c7e3000 CR4: 00000000000006f0 Call Trace: register_inet6addr_notifier+0x13/0x20 cxgb4_init_module+0x6c/0x1000 [cxgb4 ? 0xffffffffa01d7000 do_one_initcall+0x6c/0x3cc ? do_init_module+0x22/0x1f1 ? rcu_read_lock_sched_held+0x97/0xb0 ? kmem_cache_alloc_trace+0x325/0x3b0 do_init_module+0x5b/0x1f1 load_module+0x1db1/0x2690 ? m_show+0x1d0/0x1d0 __do_sys_finit_module+0xc5/0xd0 __x64_sys_finit_module+0x15/0x20 do_syscall_64+0x6b/0x1d0 entry_SYSCALL_64_after_hwframe+0x49/0xbe
If pci_register_driver fails, register inet6addr_notifier is pointless. This patch fix the error path in cxgb4_init_module.
Fixes: b5a02f503caa ("cxgb4 : Update ipv6 address handling api") Signed-off-by: YueHaibing yuehaibing@huawei.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index c71a52a2f8017..5478a2ab45c4c 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -5203,15 +5203,24 @@ static int __init cxgb4_init_module(void)
ret = pci_register_driver(&cxgb4_driver); if (ret < 0) - debugfs_remove(cxgb4_debugfs_root); + goto err_pci;
#if IS_ENABLED(CONFIG_IPV6) if (!inet6addr_registered) { - register_inet6addr_notifier(&cxgb4_inet6addr_notifier); - inet6addr_registered = true; + ret = register_inet6addr_notifier(&cxgb4_inet6addr_notifier); + if (ret) + pci_unregister_driver(&cxgb4_driver); + else + inet6addr_registered = true; } #endif
+ if (ret == 0) + return ret; + +err_pci: + debugfs_remove(cxgb4_debugfs_root); + return ret; }
[ Upstream commit 9e4be8d03f50d1b25c38e2b59e73b194c130df7d ]
The SD Physical Layer Spec says the following: Since the SD Memory Card shall support at least the two bus modes 1-bit or 4-bit width, then any SD Card shall set at least bits 0 and 2 (SD_BUS_WIDTH="0101").
This change verifies the card has specified a bus width.
AMD SDHC Device 7806 can get into a bad state after a card disconnect where anything transferred via the DATA lines will always result in a zero filled buffer. Currently the driver will continue without error if the HC is in this condition. A block device will be created, but reading from it will result in a zero buffer. This makes it seem like the SD device has been erased, when in actuality the data is never getting copied from the DATA lines to the data buffer.
SCR is the first command in the SD initialization sequence that uses the DATA lines. By checking that the response was invalid, we can abort mounting the card.
Reviewed-by: Avri Altman avri.altman@wdc.com Signed-off-by: Raul E Rangel rrangel@chromium.org Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mmc/core/sd.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index f09148a4ab557..00ba8807dafe4 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -214,6 +214,14 @@ static int mmc_decode_scr(struct mmc_card *card)
if (scr->sda_spec3) scr->cmds = UNSTUFF_BITS(resp, 32, 2); + + /* SD Spec says: any SD Card shall set at least bits 0 and 2 */ + if (!(scr->bus_widths & SD_SCR_BUS_WIDTH_1) || + !(scr->bus_widths & SD_SCR_BUS_WIDTH_4)) { + pr_err("%s: invalid bus width\n", mmc_hostname(card->host)); + return -EINVAL; + } + return 0; }
[ Upstream commit f030e419501cb95e961e9ed35c493b5d46a04eca ]
Following kernel panic is seen during DMA driver unload->load sequence ========================================================================== Unable to handle kernel paging request at virtual address ffffff8001198880 Internal error: Oops: 86000007 [#1] PREEMPT SMP CPU: 0 PID: 5907 Comm: HwBinder:4123_1 Tainted: G C 4.9.128-tegra-g065839f Hardware name: galen (DT) task: ffffffc3590d1a80 task.stack: ffffffc3d0678000 PC is at 0xffffff8001198880 LR is at of_dma_request_slave_channel+0xd8/0x1f8 pc : [<ffffff8001198880>] lr : [<ffffff8008746f30>] pstate: 60400045 sp : ffffffc3d067b710 x29: ffffffc3d067b710 x28: 000000000000002f x27: ffffff800949e000 x26: ffffff800949e750 x25: ffffff800949e000 x24: ffffffbefe817d84 x23: ffffff8009f77cb0 x22: 0000000000000028 x21: ffffffc3ffda49c8 x20: 0000000000000029 x19: 0000000000000001 x18: ffffffffffffffff x17: 0000000000000000 x16: ffffff80082b66a0 x15: ffffff8009e78250 x14: 000000000000000a x13: 0000000000000038 x12: 0101010101010101 x11: 0000000000000030 x10: 0101010101010101 x9 : fffffffffffffffc x8 : 7f7f7f7f7f7f7f7f x7 : 62ff726b6b64622c x6 : 0000000000008064 x5 : 6400000000000000 x4 : ffffffbefe817c44 x3 : ffffffc3ffda3e08 x2 : ffffff8001198880 x1 : ffffffc3d48323c0 x0 : ffffffc3d067b788
Process HwBinder:4123_1 (pid: 5907, stack limit = 0xffffffc3d0678028) Call trace: [<ffffff8001198880>] 0xffffff8001198880 [<ffffff80087459f8>] dma_request_chan+0x50/0x1f0 [<ffffff8008745bc0>] dma_request_slave_channel+0x28/0x40 [<ffffff8001552c44>] tegra_alt_pcm_open+0x114/0x170 [<ffffff8008d65fa4>] soc_pcm_open+0x10c/0x878 [<ffffff8008d18618>] snd_pcm_open_substream+0xc0/0x170 [<ffffff8008d1878c>] snd_pcm_open+0xc4/0x240 [<ffffff8008d189e0>] snd_pcm_playback_open+0x58/0x80 [<ffffff8008cfc6d4>] snd_open+0xb4/0x178 [<ffffff8008250628>] chrdev_open+0xb8/0x1d0 [<ffffff8008246fdc>] do_dentry_open+0x214/0x318 [<ffffff80082485d0>] vfs_open+0x58/0x88 [<ffffff800825bce0>] do_last+0x450/0xde0 [<ffffff800825c718>] path_openat+0xa8/0x368 [<ffffff800825dd84>] do_filp_open+0x8c/0x110 [<ffffff8008248a74>] do_sys_open+0x164/0x220 [<ffffff80082b66dc>] compat_SyS_openat+0x3c/0x50 [<ffffff8008083040>] el0_svc_naked+0x34/0x38 ---[ end trace 67e6d544e65b5145 ]--- Kernel panic - not syncing: Fatal exception ==========================================================================
In device probe(), of_dma_controller_register() registers DMA controller. But when driver is removed, this is not freed. During driver reload this results in data abort and kernel panic. Add of_dma_controller_free() in driver remove path to fix the issue.
Fixes: f46b195799b5 ("dmaengine: tegra-adma: Add support for Tegra210 ADMA") Signed-off-by: Sameer Pujar spujar@nvidia.com Reviewed-by: Jon Hunter jonathanh@nvidia.com Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/tegra210-adma.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/dma/tegra210-adma.c b/drivers/dma/tegra210-adma.c index b10cbaa82ff53..af3487538c191 100644 --- a/drivers/dma/tegra210-adma.c +++ b/drivers/dma/tegra210-adma.c @@ -786,6 +786,7 @@ static int tegra_adma_remove(struct platform_device *pdev) struct tegra_adma *tdma = platform_get_drvdata(pdev); int i;
+ of_dma_controller_free(pdev->dev.of_node); dma_async_device_unregister(&tdma->dma_dev);
for (i = 0; i < tdma->nr_channels; ++i)
[ Upstream commit f913308879bc6ae437ce64d878c7b05643ddea44 ]
GCC 8 contains a number of new warnings as well as enhancements to existing checkers. The warning - Wstringop-truncation - warns for calls to bounded string manipulation functions such as strncat, strncpy, and stpncpy that may either truncate the copied string or leave the destination unchanged.
In our case the destination string length (32 bytes) is much shorter than the source string (64 bytes) which causes this warning to show up. In general the destination has to be at least a byte larger than the length of the source string with strncpy for this warning not to showup.
This can be easily fixed by using strlcpy instead which already does the truncation to the string. Documentation for this function can be found here:
https://elixir.bootlin.com/linux/latest/source/lib/string.c#L141
Fixes: 1738cd3ed342 ("net: ena: Add a driver for Amazon Elastic Network Adapters (ENA)") Signed-off-by: Sameeh Jubran sameehj@amazon.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/amazon/ena/ena_netdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c index 0c298878bf46f..0780900b37c72 100644 --- a/drivers/net/ethernet/amazon/ena/ena_netdev.c +++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c @@ -2116,7 +2116,7 @@ static void ena_config_host_info(struct ena_com_dev *ena_dev)
host_info->os_type = ENA_ADMIN_OS_LINUX; host_info->kernel_ver = LINUX_VERSION_CODE; - strncpy(host_info->kernel_ver_str, utsname()->version, + strlcpy(host_info->kernel_ver_str, utsname()->version, sizeof(host_info->kernel_ver_str) - 1); host_info->os_dist = 0; strncpy(host_info->os_dist_str, utsname()->release,
[ Upstream commit 30180e8436046344b12813dc954b2e01dfdcd22d ]
If the hdmi codec startup fails, it should clear the current_substream pointer to free the device. This is properly done for the audio_startup() callback but for snd_pcm_hw_constraint_eld().
Make sure the pointer cleared if an error is reported.
Signed-off-by: Jerome Brunet jbrunet@baylibre.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/hdmi-codec.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c index 90b5948e0ff36..cba5b5a29da0f 100644 --- a/sound/soc/codecs/hdmi-codec.c +++ b/sound/soc/codecs/hdmi-codec.c @@ -137,8 +137,12 @@ static int hdmi_codec_startup(struct snd_pcm_substream *substream, if (!ret) { ret = snd_pcm_hw_constraint_eld(substream->runtime, hcp->eld); - if (ret) + if (ret) { + mutex_lock(&hcp->current_stream_lock); + hcp->current_stream = NULL; + mutex_unlock(&hcp->current_stream_lock); return ret; + } } } return 0;
[ Upstream commit 5d085ec04a000fefb5182d3b03ee46ca96d8389b ]
This is detected by Coverity scan: CID: 1440481
Signed-off-by: Bo YU tsu.yubo@gmail.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/boot/addnote.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/boot/addnote.c b/arch/powerpc/boot/addnote.c index 9d9f6f334d3cc..3da3e2b1b51bc 100644 --- a/arch/powerpc/boot/addnote.c +++ b/arch/powerpc/boot/addnote.c @@ -223,7 +223,11 @@ main(int ac, char **av) PUT_16(E_PHNUM, np + 2);
/* write back */ - lseek(fd, (long) 0, SEEK_SET); + i = lseek(fd, (long) 0, SEEK_SET); + if (i < 0) { + perror("lseek"); + exit(1); + } i = write(fd, buf, n); if (i < 0) { perror("write");
[ Upstream commit ea751227c813ab833609afecfeedaf0aa26f327e ]
During randconfig builds, I occasionally run into an invalid configuration of the freescale FIQ sound support:
WARNING: unmet direct dependencies detected for SND_SOC_IMX_PCM_FIQ Depends on [m]: SOUND [=y] && !UML && SND [=y] && SND_SOC [=y] && SND_IMX_SOC [=m] Selected by [y]: - SND_SOC_FSL_SPDIF [=y] && SOUND [=y] && !UML && SND [=y] && SND_SOC [=y] && SND_IMX_SOC [=m]!=n && (MXC_TZIC [=n] || MXC_AVIC [=y])
sound/soc/fsl/imx-ssi.o: In function `imx_ssi_remove': imx-ssi.c:(.text+0x28): undefined reference to `imx_pcm_fiq_exit' sound/soc/fsl/imx-ssi.o: In function `imx_ssi_probe': imx-ssi.c:(.text+0xa64): undefined reference to `imx_pcm_fiq_init'
The Kconfig warning is a result of the symbol being defined inside of the "if SND_IMX_SOC" block, and is otherwise harmless. The link error is more tricky and happens with SND_SOC_IMX_SSI=y, which may or may not imply FIQ support. However, if SND_SOC_FSL_SSI is set to =m at the same time, that selects SND_SOC_IMX_PCM_FIQ as a loadable module dependency, which then causes a link failure from imx-ssi.
The solution here is to make SND_SOC_IMX_PCM_FIQ built-in whenever one of its potential users is built-in.
Fixes: ff40260f79dc ("ASoC: fsl: refine DMA/FIQ dependencies") Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/fsl/Kconfig | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index a732b3a065c92..8a2873a7899a7 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig @@ -172,16 +172,17 @@ config SND_MPC52xx_SOC_EFIKA
endif # SND_POWERPC_SOC
+config SND_SOC_IMX_PCM_FIQ + tristate + default y if SND_SOC_IMX_SSI=y && (SND_SOC_FSL_SSI=m || SND_SOC_FSL_SPDIF=m) && (MXC_TZIC || MXC_AVIC) + select FIQ + if SND_IMX_SOC
config SND_SOC_IMX_SSI tristate select SND_SOC_FSL_UTILS
-config SND_SOC_IMX_PCM_FIQ - tristate - select FIQ - comment "SoC Audio support for Freescale i.MX boards:"
config SND_MXC_SOC_WM1133_EV1
[ Upstream commit 29f2133717c527f492933b0622a4aafe0b3cbe9e ]
Calculate the divisor for the SCR (Serial Clock Rate), avoiding that the SSP transmission rate can be greater than the device rate.
When the division between the SSP clock and the device rate generates a reminder, we have to increment by one the divisor. In this way the resulting SSP clock will never be greater than the device SPI max frequency.
For example, with:
- ssp_clk = 50 MHz - dev freq = 15 MHz
without this patch the SSP clock will be greater than 15 MHz:
- 25 MHz for PXA25x_SSP and CE4100_SSP - 16,56 MHz for the others
Instead, with this patch, we have in both case an SSP clock of 12.5MHz, so the max rate of the SPI device clock is respected.
Signed-off-by: Flavio Suligoi f.suligoi@asem.it Reviewed-by: Jarkko Nikula jarkko.nikula@linux.intel.com Reviewed-by: Jarkko Nikula jarkko.nikula@linux.intel.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi-pxa2xx.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index f2209ec4cb68d..8b618f0fa459f 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -921,10 +921,14 @@ static unsigned int ssp_get_clk_div(struct driver_data *drv_data, int rate)
rate = min_t(int, ssp_clk, rate);
+ /* + * Calculate the divisor for the SCR (Serial Clock Rate), avoiding + * that the SSP transmission rate can be greater than the device rate + */ if (ssp->type == PXA25x_SSP || ssp->type == CE4100_SSP) - return (ssp_clk / (2 * rate) - 1) & 0xff; + return (DIV_ROUND_UP(ssp_clk, 2 * rate) - 1) & 0xff; else - return (ssp_clk / rate - 1) & 0xfff; + return (DIV_ROUND_UP(ssp_clk, rate) - 1) & 0xfff; }
static unsigned int pxa2xx_ssp_get_clk_div(struct driver_data *drv_data,
[ Upstream commit e025da3d7aa4770bb1d1b3b0aa7cc4da1744852d ]
If "ret_len" is negative then it could lead to a NULL dereference.
The "ret_len" value comes from nl80211_vendor_cmd(), if it's negative then we don't allocate the "dcmd_buf" buffer. Then we pass "ret_len" to brcmf_fil_cmd_data_set() where it is cast to a very high u32 value. Most of the functions in that call tree check whether the buffer we pass is NULL but there are at least a couple places which don't such as brcmf_dbg_hex_dump() and brcmf_msgbuf_query_dcmd(). We memcpy() to and from the buffer so it would result in a NULL dereference.
The fix is to change the types so that "ret_len" can't be negative. (If we memcpy() zero bytes to NULL, that's a no-op and doesn't cause an issue).
Fixes: 1bacb0487d0e ("brcmfmac: replace cfg80211 testmode with vendor command") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c index 8eff2753abade..d493021f60318 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c @@ -35,9 +35,10 @@ static int brcmf_cfg80211_vndr_cmds_dcmd_handler(struct wiphy *wiphy, struct brcmf_if *ifp; const struct brcmf_vndr_dcmd_hdr *cmdhdr = data; struct sk_buff *reply; - int ret, payload, ret_len; + unsigned int payload, ret_len; void *dcmd_buf = NULL, *wr_pointer; u16 msglen, maxmsglen = PAGE_SIZE - 0x100; + int ret;
if (len < sizeof(*cmdhdr)) { brcmf_err("vendor command too short: %d\n", len); @@ -65,7 +66,7 @@ static int brcmf_cfg80211_vndr_cmds_dcmd_handler(struct wiphy *wiphy, brcmf_err("oversize return buffer %d\n", ret_len); ret_len = BRCMF_DCMD_MAXLEN; } - payload = max(ret_len, len) + 1; + payload = max_t(unsigned int, ret_len, len) + 1; dcmd_buf = vzalloc(payload); if (NULL == dcmd_buf) return -ENOMEM;
[ Upstream commit 1f5b62f09f6b314c8d70b9de5182dae4de1f94da ]
The VDSO code uses the kernel helper that was originally designed to abstract the access between 32 and 64bit systems. It worked so far because this function is declared as 'inline'.
As we're about to revamp that part of the code, the VDSO would break. Let's fix it by doing what should have been done from the start, a proper system register access.
Reviewed-by: Mark Rutland mark.rutland@arm.com Signed-off-by: Marc Zyngier marc.zyngier@arm.com Signed-off-by: Will Deacon will.deacon@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/include/asm/cp15.h | 2 ++ arch/arm/vdso/vgettimeofday.c | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/arch/arm/include/asm/cp15.h b/arch/arm/include/asm/cp15.h index b74b174ac9fcd..b458e41227943 100644 --- a/arch/arm/include/asm/cp15.h +++ b/arch/arm/include/asm/cp15.h @@ -67,6 +67,8 @@ #define BPIALL __ACCESS_CP15(c7, 0, c5, 6) #define ICIALLU __ACCESS_CP15(c7, 0, c5, 0)
+#define CNTVCT __ACCESS_CP15_64(1, c14) + extern unsigned long cr_alignment; /* defined in entry-armv.S */
static inline unsigned long get_cr(void) diff --git a/arch/arm/vdso/vgettimeofday.c b/arch/arm/vdso/vgettimeofday.c index 79214d5ff0970..3af02d2a0b7f2 100644 --- a/arch/arm/vdso/vgettimeofday.c +++ b/arch/arm/vdso/vgettimeofday.c @@ -18,9 +18,9 @@ #include <linux/compiler.h> #include <linux/hrtimer.h> #include <linux/time.h> -#include <asm/arch_timer.h> #include <asm/barrier.h> #include <asm/bug.h> +#include <asm/cp15.h> #include <asm/page.h> #include <asm/unistd.h> #include <asm/vdso_datapage.h> @@ -123,7 +123,8 @@ static notrace u64 get_ns(struct vdso_data *vdata) u64 cycle_now; u64 nsec;
- cycle_now = arch_counter_get_cntvct(); + isb(); + cycle_now = read_sysreg(CNTVCT);
cycle_delta = (cycle_now - vdata->cs_cycle_last) & vdata->cs_mask;
[ Upstream commit 74dd022f9e6260c3b5b8d15901d27ebcc5f21eda ]
When building with -Wunused-but-set-variable, the compiler shouts about a number of pte_unmap() users, since this expands to an empty macro on arm64:
| mm/gup.c: In function 'gup_pte_range': | mm/gup.c:1727:16: warning: variable 'ptem' set but not used | [-Wunused-but-set-variable] | mm/gup.c: At top level: | mm/memory.c: In function 'copy_pte_range': | mm/memory.c:821:24: warning: variable 'orig_dst_pte' set but not used | [-Wunused-but-set-variable] | mm/memory.c:821:9: warning: variable 'orig_src_pte' set but not used | [-Wunused-but-set-variable] | mm/swap_state.c: In function 'swap_ra_info': | mm/swap_state.c:641:15: warning: variable 'orig_pte' set but not used | [-Wunused-but-set-variable] | mm/madvise.c: In function 'madvise_free_pte_range': | mm/madvise.c:318:9: warning: variable 'orig_pte' set but not used | [-Wunused-but-set-variable]
Rewrite pte_unmap() as a static inline function, which silences the warnings.
Signed-off-by: Qian Cai cai@lca.pw Signed-off-by: Will Deacon will.deacon@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/include/asm/pgtable.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index 3a30a3994e4a2..73e3718356b05 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -413,6 +413,8 @@ static inline phys_addr_t pmd_page_paddr(pmd_t pmd) return pmd_val(pmd) & PHYS_MASK & (s32)PAGE_MASK; }
+static inline void pte_unmap(pte_t *pte) { } + /* Find an entry in the third-level page table. */ #define pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
@@ -421,7 +423,6 @@ static inline phys_addr_t pmd_page_paddr(pmd_t pmd)
#define pte_offset_map(dir,addr) pte_offset_kernel((dir), (addr)) #define pte_offset_map_nested(dir,addr) pte_offset_kernel((dir), (addr)) -#define pte_unmap(pte) do { } while (0) #define pte_unmap_nested(pte) do { } while (0)
#define pte_set_fixmap(addr) ((pte_t *)set_fixmap_offset(FIX_PTE, addr))
[ Upstream commit 9a4f26cc98d81b67ecc23b890c28e2df324e29f3 ]
Currently the error return path from kobject_init_and_add() is not followed by a call to kobject_put() - which means we are leaking the kobject.
Fix it by adding a call to kobject_put() in the error path of kobject_init_and_add().
Signed-off-by: Tobin C. Harding tobin@kernel.org Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Peter Zijlstra peterz@infradead.org Cc: Rafael J. Wysocki rafael.j.wysocki@intel.com Cc: Thomas Gleixner tglx@linutronix.de Cc: Tobin C. Harding tobin@kernel.org Cc: Vincent Guittot vincent.guittot@linaro.org Cc: Viresh Kumar viresh.kumar@linaro.org Link: http://lkml.kernel.org/r/20190430001144.24890-1-tobin@kernel.org Signed-off-by: Ingo Molnar mingo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cpufreq/cpufreq.c | 1 + drivers/cpufreq/cpufreq_governor.c | 2 ++ 2 files changed, 3 insertions(+)
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index a38a23f0b3f41..e917521a3ef9b 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1065,6 +1065,7 @@ static struct cpufreq_policy *cpufreq_policy_alloc(unsigned int cpu) cpufreq_global_kobject, "policy%u", cpu); if (ret) { pr_err("%s: failed to init policy->kobj: %d\n", __func__, ret); + kobject_put(&policy->kobj); goto err_free_real_cpus; }
diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c index 38d1a8216084c..32c9524a6ec54 100644 --- a/drivers/cpufreq/cpufreq_governor.c +++ b/drivers/cpufreq/cpufreq_governor.c @@ -449,6 +449,8 @@ int cpufreq_dbs_governor_init(struct cpufreq_policy *policy) /* Failure, so roll back. */ pr_err("initialization failed (dbs_data kobject init error %d)\n", ret);
+ kobject_put(&dbs_data->attr_set.kobj); + policy->governor_data = NULL;
if (!have_governor_per_policy())
[ Upstream commit 24afabdbd0b3553963a2bbf465895492b14d1107 ]
Make sure that the allocated interrupts are freed if allocating memory for the msix_entries array fails.
Cc: Himanshu Madhani hmadhani@marvell.com Cc: Giridhar Malavali gmalavali@marvell.com Signed-off-by: Bart Van Assche bvanassche@acm.org Acked-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_isr.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 73c99f237b10c..f0fcff032f8ac 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -3089,7 +3089,7 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp) ql_log(ql_log_fatal, vha, 0x00c8, "Failed to allocate memory for ha->msix_entries.\n"); ret = -ENOMEM; - goto msix_out; + goto free_irqs; } ha->flags.msix_enabled = 1;
@@ -3177,6 +3177,10 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp) msix_out: kfree(entries); return ret; + +free_irqs: + pci_free_irq_vectors(ha->pdev); + goto msix_out; }
int
[ Upstream commit 30f24eabab8cd801064c5c37589d803cb4341929 ]
If for some reason the device gives us an RX interrupt before we're ready for it, perhaps during device power-on with misconfigured IRQ causes mapping or so, we can crash trying to access the queues.
Prevent that by checking that we actually have RXQs and that they were properly allocated.
Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Luca Coelho luciano.coelho@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c index c21f8bd32d08f..25f2a0aceaa21 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c @@ -1225,10 +1225,15 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, static void iwl_pcie_rx_handle(struct iwl_trans *trans, int queue) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct iwl_rxq *rxq = &trans_pcie->rxq[queue]; + struct iwl_rxq *rxq; u32 r, i, count = 0; bool emergency = false;
+ if (WARN_ON_ONCE(!trans_pcie->rxq || !trans_pcie->rxq[queue].bd)) + return; + + rxq = &trans_pcie->rxq[queue]; + restart: spin_lock(&rxq->lock); /* uCode's read index (stored in shared DRAM) indicates the last Rx
[ Upstream commit f22b1ba15ee5785aa028384ebf77dd39e8e47b70 ]
The device's remove() attempts to shut down the delayed_work scheduled on the kernel-global workqueue by calling flush_scheduled_work().
Unfortunately, flush_scheduled_work() does not prevent the delayed_work from re-scheduling itself. The delayed_work might run after the device has been removed, and touch the already de-allocated info structure. This is a potential use-after-free.
Fix by calling cancel_delayed_work_sync() during remove(): this ensures that the delayed work is properly cancelled, is no longer running, and is not able to re-schedule itself.
This issue was detected with the help of Coccinelle.
Signed-off-by: Sven Van Asbroeck TheSven73@gmail.com Signed-off-by: Alexandre Belloni alexandre.belloni@bootlin.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/rtc/rtc-88pm860x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/rtc/rtc-88pm860x.c b/drivers/rtc/rtc-88pm860x.c index 19e53b3b8e005..166faae3a59cd 100644 --- a/drivers/rtc/rtc-88pm860x.c +++ b/drivers/rtc/rtc-88pm860x.c @@ -414,7 +414,7 @@ static int pm860x_rtc_remove(struct platform_device *pdev) struct pm860x_rtc_info *info = platform_get_drvdata(pdev);
#ifdef VRTC_CALIBRATION - flush_scheduled_work(); + cancel_delayed_work_sync(&info->calib_work); /* disable measurement */ pm860x_set_bits(info->i2c, PM8607_MEAS_EN2, MEAS2_VRTC, 0); #endif /* VRTC_CALIBRATION */
[ Upstream commit 62909da8aca048ecf9fbd7e484e5100608f40a63 ]
From the DS2408 datasheet [1]:
"Resume Command function checks the status of the RC flag and, if it is set, directly transfers control to the control functions, similar to a Skip ROM command. The only way to set the RC flag is through successfully executing the Match ROM, Search ROM, Conditional Search ROM, or Overdrive-Match ROM command"
The function currently works perfectly fine in a multidrop bus, but when we have only a single slave connected, then only a Skip ROM is used and Match ROM is not called at all. This is leading to problems e.g. with single one DS2408 connected, as the Resume Command is not working properly and the device is responding with failing results after the Resume Command.
This commit is fixing this by using a Skip ROM instead in those cases. The bandwidth / performance advantage is exactly the same.
Refs: [1] https://datasheets.maximintegrated.com/en/ds/DS2408.pdf
Signed-off-by: Mariusz Bialonczyk manio@skyboo.net Reviewed-by: Jean-Francois Dagenais jeff.dagenais@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/w1/w1_io.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/w1/w1_io.c b/drivers/w1/w1_io.c index f4bc8c100a01b..a3ac582420ec4 100644 --- a/drivers/w1/w1_io.c +++ b/drivers/w1/w1_io.c @@ -437,8 +437,7 @@ int w1_reset_resume_command(struct w1_master *dev) if (w1_reset_bus(dev)) return -1;
- /* This will make only the last matched slave perform a skip ROM. */ - w1_write_8(dev, W1_RESUME_CMD); + w1_write_8(dev, dev->slave_count > 1 ? W1_RESUME_CMD : W1_SKIP_ROM); return 0; } EXPORT_SYMBOL_GPL(w1_reset_resume_command);
[ Upstream commit 2da254cc7908105a60a6bb219d18e8dced03dcb9 ]
This patch kill instructs the DMAC to immediately terminate execution of a thread. and then clear the interrupt status, at last, stop generating interrupts for DMA_SEV. to guarantee the next dma start is clean. otherwise, one interrupt maybe leave to next start and make some mistake.
we can reporduce the problem as follows:
DMASEV: modify the event-interrupt resource, and if the INTEN sets function as interrupt, the DMAC will set irq<event_num> HIGH to generate interrupt. write INTCLR to clear interrupt.
DMA EXECUTING INSTRUCTS DMA TERMINATE | | | | ... _stop | | | spin_lock_irqsave DMASEV | | | | mask INTEN | | | DMAKILL | | | spin_unlock_irqrestore
in above case, a interrupt was left, and if we unmask INTEN, the DMAC will set irq<event_num> HIGH to generate interrupt.
to fix this, do as follows:
DMA EXECUTING INSTRUCTS DMA TERMINATE | | | | ... _stop | | | spin_lock_irqsave DMASEV | | | | DMAKILL | | | clear INTCLR | mask INTEN | | | spin_unlock_irqrestore
Signed-off-by: Sugar Zhang sugar.zhang@rock-chips.com Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/pl330.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 6d7e3cd4aba4c..57b375d0de292 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -1020,6 +1020,7 @@ static void _stop(struct pl330_thread *thrd) { void __iomem *regs = thrd->dmac->base; u8 insn[6] = {0, 0, 0, 0, 0, 0}; + u32 inten = readl(regs + INTEN);
if (_state(thrd) == PL330_STATE_FAULT_COMPLETING) UNTIL(thrd, PL330_STATE_FAULTING | PL330_STATE_KILLING); @@ -1032,10 +1033,13 @@ static void _stop(struct pl330_thread *thrd)
_emit_KILL(0, insn);
- /* Stop generating interrupts for SEV */ - writel(readl(regs + INTEN) & ~(1 << thrd->ev), regs + INTEN); - _execute_DBGINSN(thrd, insn, is_manager(thrd)); + + /* clear the event */ + if (inten & (1 << thrd->ev)) + writel(1 << thrd->ev, regs + INTCLR); + /* Stop generating interrupts for SEV */ + writel(inten & ~(1 << thrd->ev), regs + INTEN); }
/* Start doing req 'idx' of thread 'thrd' */
[ Upstream commit 5dc8cdce1d722c733f8c7af14c5fb595cfedbfa8 ]
FullMAC STAs have no way to update bss channel after CSA channel switch completion. As a result, user-space tools may provide inconsistent channel info. For instance, consider the following two commands: $ sudo iw dev wlan0 link $ sudo iw dev wlan0 info The latter command gets channel info from the hardware, so most probably its output will be correct. However the former command gets channel info from scan cache, so its output will contain outdated channel info. In fact, current bss channel info will not be updated until the next [re-]connect.
Note that mac80211 STAs have a workaround for this, but it requires access to internal cfg80211 data, see ieee80211_chswitch_work:
/* XXX: shouldn't really modify cfg80211-owned data! */ ifmgd->associated->channel = sdata->csa_chandef.chan;
This patch suggests to convert mac80211 workaround into cfg80211 behavior and to update current bss channel in cfg80211_ch_switch_notify.
Signed-off-by: Sergey Matyukevich sergey.matyukevich.os@quantenna.com Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/mac80211/mlme.c | 3 --- net/wireless/nl80211.c | 5 +++++ 2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 6e0aa296f1346..d787717140e54 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1072,9 +1072,6 @@ static void ieee80211_chswitch_work(struct work_struct *work) goto out; }
- /* XXX: shouldn't really modify cfg80211-owned data! */ - ifmgd->associated->channel = sdata->csa_chandef.chan; - ifmgd->csa_waiting_bcn = true;
ieee80211_sta_reset_beacon_monitor(sdata); diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 09a353c6373a8..d6e6293157717 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -14014,6 +14014,11 @@ void cfg80211_ch_switch_notify(struct net_device *dev,
wdev->chandef = *chandef; wdev->preset_chandef = *chandef; + + if (wdev->iftype == NL80211_IFTYPE_STATION && + !WARN_ON(!wdev->current_bss)) + wdev->current_bss->pub.channel = chandef->chan; + nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL, NL80211_CMD_CH_SWITCH_NOTIFY, 0); }
[ Upstream commit ddb351145a967ee791a0fb0156852ec2fcb746ba ]
is_slave_mode defaults to false because sai structure that contains it is kzalloc'ed.
Anyhow, if we decide to set the following configuration SAI slave -> SAI master, is_slave_mode will remain set on true although SAI being master it should be set to false.
Fix this by updating is_slave_mode for each call of fsl_sai_set_dai_fmt.
Signed-off-by: Daniel Baluta daniel.baluta@nxp.com Acked-by: Nicolin Chen nicoleotsuka@gmail.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/fsl/fsl_sai.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 9fadf7e31c5f8..cb43f57f978b1 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -274,12 +274,14 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai, case SND_SOC_DAIFMT_CBS_CFS: val_cr2 |= FSL_SAI_CR2_BCD_MSTR; val_cr4 |= FSL_SAI_CR4_FSD_MSTR; + sai->is_slave_mode = false; break; case SND_SOC_DAIFMT_CBM_CFM: sai->is_slave_mode = true; break; case SND_SOC_DAIFMT_CBS_CFM: val_cr2 |= FSL_SAI_CR2_BCD_MSTR; + sai->is_slave_mode = false; break; case SND_SOC_DAIFMT_CBM_CFS: val_cr4 |= FSL_SAI_CR4_FSD_MSTR;
[ Upstream commit b4c35c17227fe437ded17ce683a6927845f8c4a4 ]
The "rate_index" is only used as an index into the phist_data->rx_rate[] array in the mwifiex_hist_data_set() function. That array has MWIFIEX_MAX_AC_RX_RATES (74) elements and it's used to generate some debugfs information. The "rate_index" variable comes from the network skb->data[] and it is a u8 so it's in the 0-255 range. We need to cap it to prevent an array overflow.
Fixes: cbf6e05527a7 ("mwifiex: add rx histogram statistics support") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/marvell/mwifiex/cfp.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/net/wireless/marvell/mwifiex/cfp.c b/drivers/net/wireless/marvell/mwifiex/cfp.c index 1ff22055e54f8..9ddaa767ea747 100644 --- a/drivers/net/wireless/marvell/mwifiex/cfp.c +++ b/drivers/net/wireless/marvell/mwifiex/cfp.c @@ -533,5 +533,8 @@ u8 mwifiex_adjust_data_rate(struct mwifiex_private *priv, rate_index = (rx_rate > MWIFIEX_RATE_INDEX_OFDM0) ? rx_rate - 1 : rx_rate;
+ if (rate_index >= MWIFIEX_MAX_AC_RX_RATES) + rate_index = MWIFIEX_MAX_AC_RX_RATES - 1; + return rate_index; }
[ Upstream commit 0ed2a005347400500a39ea7c7318f1fea57fb3ca ]
In case create_singlethread_workqueue fails, the fix free the hardware and returns NULL to avoid NULL pointer dereference.
Signed-off-by: Kangjie Lu kjlu@umn.edu Signed-off-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/st/cw1200/main.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/net/wireless/st/cw1200/main.c b/drivers/net/wireless/st/cw1200/main.c index dc478cedbde0d..84624c812a15f 100644 --- a/drivers/net/wireless/st/cw1200/main.c +++ b/drivers/net/wireless/st/cw1200/main.c @@ -345,6 +345,11 @@ static struct ieee80211_hw *cw1200_init_common(const u8 *macaddr, mutex_init(&priv->wsm_cmd_mux); mutex_init(&priv->conf_mutex); priv->workqueue = create_singlethread_workqueue("cw1200_wq"); + if (!priv->workqueue) { + ieee80211_free_hw(hw); + return NULL; + } + sema_init(&priv->scan.lock, 1); INIT_WORK(&priv->scan.work, cw1200_scan_work); INIT_DELAYED_WORK(&priv->scan.probe_work, cw1200_probe_work);
[ Upstream commit f87391558acf816b48f325a493d81d45dec40da0 ]
When nbytes < 4, end is wronlgy set to a negative value which, due to uint, is then interpreted to a large value leading to a deadlock in the following code.
This patch fix this problem.
Fixes: 6298e948215f ("crypto: sunxi-ss - Add Allwinner Security System crypto accelerator") Signed-off-by: Corentin Labbe clabbe.montjoie@gmail.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/sunxi-ss/sun4i-ss-hash.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/crypto/sunxi-ss/sun4i-ss-hash.c b/drivers/crypto/sunxi-ss/sun4i-ss-hash.c index 0de2f62d51ff7..ec16ec2e284d0 100644 --- a/drivers/crypto/sunxi-ss/sun4i-ss-hash.c +++ b/drivers/crypto/sunxi-ss/sun4i-ss-hash.c @@ -250,7 +250,10 @@ static int sun4i_hash(struct ahash_request *areq) } } else { /* Since we have the flag final, we can go up to modulo 4 */ - end = ((areq->nbytes + op->len) / 4) * 4 - op->len; + if (areq->nbytes < 4) + end = 0; + else + end = ((areq->nbytes + op->len) / 4) * 4 - op->len; }
/* TODO if SGlen % 4 and op->len == 0 then DMA */
[ Upstream commit 68d10e6979a3b59e3cd2e90bfcafed79c4cf180a ]
When failure happens inside bch_journal_replay(), calling cache_set_err_on() and handling the failure in async way is not a good idea. Because after bch_journal_replay() returns, registering code will continue to execute following steps, and unregistering code triggered by cache_set_err_on() is running in same time. First it is unnecessary to handle failure and unregister cache set in an async way, second there might be potential race condition to run register and unregister code for same cache set.
So in this patch, if failure happens in bch_journal_replay(), we don't call cache_set_err_on(), and just print out the same error message to kernel message buffer, then return -EIO immediately caller. Then caller can detect such failure and handle it in synchrnozied way.
Signed-off-by: Coly Li colyli@suse.de Reviewed-by: Hannes Reinecke hare@suse.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/bcache/journal.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/md/bcache/journal.c b/drivers/md/bcache/journal.c index c76a0176b5c68..f8ae7ce29809d 100644 --- a/drivers/md/bcache/journal.c +++ b/drivers/md/bcache/journal.c @@ -322,9 +322,12 @@ int bch_journal_replay(struct cache_set *s, struct list_head *list) list_for_each_entry(i, list, list) { BUG_ON(i->pin && atomic_read(i->pin) != 1);
- cache_set_err_on(n != i->j.seq, s, -"bcache: journal entries %llu-%llu missing! (replaying %llu-%llu)", - n, i->j.seq - 1, start, end); + if (n != i->j.seq) { + pr_err("bcache: journal entries %llu-%llu missing! (replaying %llu-%llu)", + n, i->j.seq - 1, start, end); + ret = -EIO; + goto err; + }
for (k = i->j.start; k < bset_bkey_last(&i->j);
[ Upstream commit 631207314d88e9091be02fbdd1fdadb1ae2ed79a ]
journal replay failed with messages: Sep 10 19:10:43 ceph kernel: bcache: error on bb379a64-e44e-4812-b91d-a5599871a3b1: bcache: journal entries 2057493-2057567 missing! (replaying 2057493-2076601), disabling caching
The reason is in journal_reclaim(), when discard is enabled, we send discard command and reclaim those journal buckets whose seq is old than the last_seq_now, but before we write a journal with last_seq_now, the machine is restarted, so the journal with the last_seq_now is not written to the journal bucket, and the last_seq_wrote in the newest journal is old than last_seq_now which we expect to be, so when we doing replay, journals from last_seq_wrote to last_seq_now are missing.
It's hard to write a journal immediately after journal_reclaim(), and it harmless if those missed journal are caused by discarding since those journals are already wrote to btree node. So, if miss seqs are started from the beginning journal, we treat it as normal, and only print a message to show the miss journal, and point out it maybe caused by discarding.
Patch v2 add a judgement condition to ignore the missed journal only when discard enabled as Coly suggested.
(Coly Li: rebase the patch with other changes in bch_journal_replay())
Signed-off-by: Tang Junhui tang.junhui.linux@gmail.com Tested-by: Dennis Schridde devurandom@gmx.net Signed-off-by: Coly Li colyli@suse.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/bcache/journal.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-)
diff --git a/drivers/md/bcache/journal.c b/drivers/md/bcache/journal.c index f8ae7ce29809d..6ee5370eb9169 100644 --- a/drivers/md/bcache/journal.c +++ b/drivers/md/bcache/journal.c @@ -309,6 +309,18 @@ void bch_journal_mark(struct cache_set *c, struct list_head *list) } }
+bool is_discard_enabled(struct cache_set *s) +{ + struct cache *ca; + unsigned int i; + + for_each_cache(ca, s, i) + if (ca->discard) + return true; + + return false; +} + int bch_journal_replay(struct cache_set *s, struct list_head *list) { int ret = 0, keys = 0, entries = 0; @@ -323,10 +335,15 @@ int bch_journal_replay(struct cache_set *s, struct list_head *list) BUG_ON(i->pin && atomic_read(i->pin) != 1);
if (n != i->j.seq) { - pr_err("bcache: journal entries %llu-%llu missing! (replaying %llu-%llu)", - n, i->j.seq - 1, start, end); - ret = -EIO; - goto err; + if (n == start && is_discard_enabled(s)) + pr_info("bcache: journal entries %llu-%llu may be discarded! (replaying %llu-%llu)", + n, i->j.seq - 1, start, end); + else { + pr_err("bcache: journal entries %llu-%llu missing! (replaying %llu-%llu)", + n, i->j.seq - 1, start, end); + ret = -EIO; + goto err; + } }
for (k = i->j.start;
[ Upstream commit ce3e4cfb59cb382f8e5ce359238aa580d4ae7778 ]
Currently run_cache_set() has no return value, if there is failure in bch_journal_replay(), the caller of run_cache_set() has no idea about such failure and just continue to execute following code after run_cache_set(). The internal failure is triggered inside bch_journal_replay() and being handled in async way. This behavior is inefficient, while failure handling inside bch_journal_replay(), cache register code is still running to start the cache set. Registering and unregistering code running as same time may introduce some rare race condition, and make the code to be more hard to be understood.
This patch adds return value to run_cache_set(), and returns -EIO if bch_journal_rreplay() fails. Then caller of run_cache_set() may detect such failure and stop registering code flow immedidately inside register_cache_set().
If journal replay fails, run_cache_set() can report error immediately to register_cache_set(). This patch makes the failure handling for bch_journal_replay() be in synchronized way, easier to understand and debug, and avoid poetential race condition for register-and-unregister in same time.
Signed-off-by: Coly Li colyli@suse.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/bcache/super.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c index 362efc8dd16fb..9f2588eaaf5f8 100644 --- a/drivers/md/bcache/super.c +++ b/drivers/md/bcache/super.c @@ -1561,7 +1561,7 @@ struct cache_set *bch_cache_set_alloc(struct cache_sb *sb) return NULL; }
-static void run_cache_set(struct cache_set *c) +static int run_cache_set(struct cache_set *c) { const char *err = "cannot allocate memory"; struct cached_dev *dc, *t; @@ -1653,7 +1653,9 @@ static void run_cache_set(struct cache_set *c) if (j->version < BCACHE_JSET_VERSION_UUID) __uuid_write(c);
- bch_journal_replay(c, &journal); + err = "bcache: replay journal failed"; + if (bch_journal_replay(c, &journal)) + goto err; } else { pr_notice("invalidating existing data");
@@ -1721,11 +1723,13 @@ static void run_cache_set(struct cache_set *c) flash_devs_run(c);
set_bit(CACHE_SET_RUNNING, &c->flags); - return; + return 0; err: closure_sync(&cl); /* XXX: test this, it's broken */ bch_cache_set_error(c, "%s", err); + + return -EIO; }
static bool can_attach_cache(struct cache *ca, struct cache_set *c) @@ -1789,8 +1793,11 @@ static const char *register_cache_set(struct cache *ca) ca->set->cache[ca->sb.nr_this_dev] = ca; c->cache_by_alloc[c->caches_loaded++] = ca;
- if (c->caches_loaded == c->sb.nr_in_set) - run_cache_set(c); + if (c->caches_loaded == c->sb.nr_in_set) { + err = "failed to run cache set"; + if (run_cache_set(c) < 0) + goto err; + }
return NULL; err:
[ Upstream commit 78d4eb8ad9e1d413449d1b7a060f50b6efa81ebd ]
clang has identified a code path in which it thinks a variable may be unused:
drivers/md/bcache/alloc.c:333:4: error: variable 'bucket' is used uninitialized whenever 'if' condition is false [-Werror,-Wsometimes-uninitialized] fifo_pop(&ca->free_inc, bucket); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/md/bcache/util.h:219:27: note: expanded from macro 'fifo_pop' #define fifo_pop(fifo, i) fifo_pop_front(fifo, (i)) ^~~~~~~~~~~~~~~~~~~~~~~~~ drivers/md/bcache/util.h:189:6: note: expanded from macro 'fifo_pop_front' if (_r) { \ ^~ drivers/md/bcache/alloc.c:343:46: note: uninitialized use occurs here allocator_wait(ca, bch_allocator_push(ca, bucket)); ^~~~~~ drivers/md/bcache/alloc.c:287:7: note: expanded from macro 'allocator_wait' if (cond) \ ^~~~ drivers/md/bcache/alloc.c:333:4: note: remove the 'if' if its condition is always true fifo_pop(&ca->free_inc, bucket); ^ drivers/md/bcache/util.h:219:27: note: expanded from macro 'fifo_pop' #define fifo_pop(fifo, i) fifo_pop_front(fifo, (i)) ^ drivers/md/bcache/util.h:189:2: note: expanded from macro 'fifo_pop_front' if (_r) { \ ^ drivers/md/bcache/alloc.c:331:15: note: initialize the variable 'bucket' to silence this warning long bucket; ^
This cannot happen in practice because we only enter the loop if there is at least one element in the list.
Slightly rearranging the code makes this clearer to both the reader and the compiler, which avoids the warning.
Signed-off-by: Arnd Bergmann arnd@arndb.de Reviewed-by: Nathan Chancellor natechancellor@gmail.com Signed-off-by: Coly Li colyli@suse.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/bcache/alloc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/md/bcache/alloc.c b/drivers/md/bcache/alloc.c index dd344ee9e62b7..ebacd21714efa 100644 --- a/drivers/md/bcache/alloc.c +++ b/drivers/md/bcache/alloc.c @@ -322,10 +322,11 @@ static int bch_allocator_thread(void *arg) * possibly issue discards to them, then we add the bucket to * the free list: */ - while (!fifo_empty(&ca->free_inc)) { + while (1) { long bucket;
- fifo_pop(&ca->free_inc, bucket); + if (!fifo_pop(&ca->free_inc, bucket)) + break;
if (ca->discard) { mutex_unlock(&ca->set->bucket_lock);
[ Upstream commit 392bef709659abea614abfe53cf228e7a59876a4 ]
When building x86 with Clang LTO and CFI, CFI jump regions are automatically added to the end of the .text section late in linking. As a result, the _etext position was being labelled before the appended jump regions, causing confusion about where the boundaries of the executable region actually are in the running kernel, and broke at least the fault injection code. This moves the _etext mark to outside (and immediately after) the .text area, as it already the case on other architectures (e.g. arm64, arm).
Reported-and-tested-by: Sami Tolvanen samitolvanen@google.com Signed-off-by: Kees Cook keescook@chromium.org Cc: Borislav Petkov bp@suse.de Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Peter Zijlstra peterz@infradead.org Cc: Thomas Gleixner tglx@linutronix.de Link: http://lkml.kernel.org/r/20190423183827.GA4012@beast Signed-off-by: Ingo Molnar mingo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/kernel/vmlinux.lds.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S index 55f04875293fa..51b772f9d886a 100644 --- a/arch/x86/kernel/vmlinux.lds.S +++ b/arch/x86/kernel/vmlinux.lds.S @@ -111,11 +111,11 @@ SECTIONS *(.text.__x86.indirect_thunk) __indirect_thunk_end = .; #endif - - /* End of text section */ - _etext = .; } :text = 0x9090
+ /* End of text section */ + _etext = .; + NOTES :text :note
EXCEPTION_TABLE(16) :text = 0x9090
[ Upstream commit d4645d30b50d1691c26ff0f8fa4e718b08f8d3bb ]
The test robot reported a wrong assignment of a per-CPU variable which it detected by using sparse and sent a report. The assignment itself is correct. The annotation for sparse was wrong and hence the report. The first pointer is a "normal" pointer and points to the per-CPU memory area. That means that the __percpu annotation has to be moved.
Move the __percpu annotation to pointer which points to the per-CPU area. This change affects only the sparse tool (and is ignored by the compiler).
Reported-by: kbuild test robot lkp@intel.com Signed-off-by: Sebastian Andrzej Siewior bigeasy@linutronix.de Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Paul E. McKenney paulmck@linux.ibm.com Cc: Peter Zijlstra peterz@infradead.org Cc: Thomas Gleixner tglx@linutronix.de Fixes: f97f8f06a49fe ("smpboot: Provide infrastructure for percpu hotplug threads") Link: http://lkml.kernel.org/r/20190424085253.12178-1-bigeasy@linutronix.de Signed-off-by: Ingo Molnar mingo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/smpboot.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/smpboot.h b/include/linux/smpboot.h index 12910cf19869c..12a4b09f4d08b 100644 --- a/include/linux/smpboot.h +++ b/include/linux/smpboot.h @@ -30,7 +30,7 @@ struct smpboot_thread_data; * @thread_comm: The base name of the thread */ struct smp_hotplug_thread { - struct task_struct __percpu **store; + struct task_struct * __percpu *store; struct list_head list; int (*thread_should_run)(unsigned int cpu); void (*thread_fn)(unsigned int cpu);
[ Upstream commit a65c88e16f32aa9ef2e8caa68ea5c29bd5eb0ff0 ]
In-NMI warnings have been added to vmalloc_fault() via:
ebc8827f75 ("x86: Barf when vmalloc and kmemcheck faults happen in NMI")
back in the time when our NMI entry code could not cope with nested NMIs.
These days, it's perfectly fine to take a fault in NMI context and we don't have to care about the fact that IRET from the fault handler might cause NMI nesting.
This warning has already been removed from 32-bit implementation of vmalloc_fault() in:
6863ea0cda8 ("x86/mm: Remove in_nmi() warning from vmalloc_fault()")
but the 64-bit version was omitted.
Remove the bogus warning also from 64-bit implementation of vmalloc_fault().
Reported-by: Nicolai Stange nstange@suse.de Signed-off-by: Jiri Kosina jkosina@suse.cz Acked-by: Peter Zijlstra (Intel) peterz@infradead.org Cc: Andy Lutomirski luto@kernel.org Cc: Borislav Petkov bp@alien8.de Cc: Dave Hansen dave.hansen@linux.intel.com Cc: Frederic Weisbecker fweisbec@gmail.com Cc: Joerg Roedel jroedel@suse.de Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Peter Zijlstra peterz@infradead.org Cc: Thomas Gleixner tglx@linutronix.de Fixes: 6863ea0cda8 ("x86/mm: Remove in_nmi() warning from vmalloc_fault()") Link: http://lkml.kernel.org/r/nycvar.YFH.7.76.1904240902280.9803@cbobk.fhfr.pm Signed-off-by: Ingo Molnar mingo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/mm/fault.c | 2 -- 1 file changed, 2 deletions(-)
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 5c419b8f99a03..c140198d9fa5e 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -430,8 +430,6 @@ static noinline int vmalloc_fault(unsigned long address) if (!(address >= VMALLOC_START && address < VMALLOC_END)) return -1;
- WARN_ON_ONCE(in_nmi()); - /* * Copy kernel mappings over when needed. This can also * happen within a race in page table update. In the later
[ Upstream commit 29da93fea3ea39ab9b12270cc6be1b70ef201c9e ]
Randy reported objtool triggered on his (GCC-7.4) build:
lib/strncpy_from_user.o: warning: objtool: strncpy_from_user()+0x315: call to __ubsan_handle_add_overflow() with UACCESS enabled lib/strnlen_user.o: warning: objtool: strnlen_user()+0x337: call to __ubsan_handle_sub_overflow() with UACCESS enabled
This is due to UBSAN generating signed-overflow-UB warnings where it should not. Prior to GCC-8 UBSAN ignored -fwrapv (which the kernel uses through -fno-strict-overflow).
Make the functions use 'unsigned long' throughout.
Reported-by: Randy Dunlap rdunlap@infradead.org Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Acked-by: Randy Dunlap rdunlap@infradead.org # build-tested Acked-by: Linus Torvalds torvalds@linux-foundation.org Cc: Peter Zijlstra peterz@infradead.org Cc: Thomas Gleixner tglx@linutronix.de Cc: luto@kernel.org Link: http://lkml.kernel.org/r/20190424072208.754094071@infradead.org Signed-off-by: Ingo Molnar mingo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- lib/strncpy_from_user.c | 5 +++-- lib/strnlen_user.c | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/lib/strncpy_from_user.c b/lib/strncpy_from_user.c index 7e35fc450c5bb..5a07f19059c36 100644 --- a/lib/strncpy_from_user.c +++ b/lib/strncpy_from_user.c @@ -22,10 +22,11 @@ * hit it), 'max' is the address space maximum (and we return * -EFAULT if we hit it). */ -static inline long do_strncpy_from_user(char *dst, const char __user *src, long count, unsigned long max) +static inline long do_strncpy_from_user(char *dst, const char __user *src, + unsigned long count, unsigned long max) { const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS; - long res = 0; + unsigned long res = 0;
/* * Truncate 'max' to the user-specified limit, so that diff --git a/lib/strnlen_user.c b/lib/strnlen_user.c index 8e105ed4df12b..9ff4f3bbb1aae 100644 --- a/lib/strnlen_user.c +++ b/lib/strnlen_user.c @@ -27,7 +27,7 @@ static inline long do_strnlen_user(const char __user *src, unsigned long count, unsigned long max) { const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS; - long align, res = 0; + unsigned long align, res = 0; unsigned long c;
/* @@ -41,7 +41,7 @@ static inline long do_strnlen_user(const char __user *src, unsigned long count, * Do everything aligned. But that means that we * need to also expand the maximum.. */ - align = (sizeof(long) - 1) & (unsigned long)src; + align = (sizeof(unsigned long) - 1) & (unsigned long)src; src -= align; max += align;
[ Upstream commit 096377525cdb8251e4656085efc988bdf733fb4c ]
According to the logitech_hidpp_2.0_specification_draft_2012-06-04.pdf doc: https://lekensteyn.nl/files/logitech/logitech_hidpp_2.0_specification_draft_...
We should use a register-access-protocol request using the short input / output report ids. This is necessary because 27MHz HID++ receivers have a max-packetsize on their HIP++ endpoint of 8, so they cannot support long reports. Using a feature-access-protocol request (which is always long or very-long) with these will cause a timeout error, followed by the hidpp driver treating the device as not being HID++ capable.
This commit fixes this by switching to using a rap request to get the protocol version.
Besides being tested with a (046d:c517) 27MHz receiver with various 27MHz keyboards and mice, this has also been tested to not cause regressions on a non-unifying dual-HID++ nano receiver (046d:c534) with k270 and m185 HID++-2.0 devices connected and on a unifying/dj receiver (046d:c52b) with a HID++-2.0 Logitech Rechargeable Touchpad T650.
Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Benjamin Tissoires benjamin.tissoires@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hid/hid-logitech-hidpp.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index 3198faf5cff4d..38d9deb03d16c 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -449,13 +449,16 @@ static int hidpp_root_get_feature(struct hidpp_device *hidpp, u16 feature,
static int hidpp_root_get_protocol_version(struct hidpp_device *hidpp) { + const u8 ping_byte = 0x5a; + u8 ping_data[3] = { 0, 0, ping_byte }; struct hidpp_report response; int ret;
- ret = hidpp_send_fap_command_sync(hidpp, + ret = hidpp_send_rap_command_sync(hidpp, + REPORT_ID_HIDPP_SHORT, HIDPP_PAGE_ROOT_IDX, CMD_ROOT_GET_PROTOCOL_VERSION, - NULL, 0, &response); + ping_data, sizeof(ping_data), &response);
if (ret == HIDPP_ERROR_INVALID_SUBID) { hidpp->protocol_major = 1; @@ -475,8 +478,14 @@ static int hidpp_root_get_protocol_version(struct hidpp_device *hidpp) if (ret) return ret;
- hidpp->protocol_major = response.fap.params[0]; - hidpp->protocol_minor = response.fap.params[1]; + if (response.rap.params[2] != ping_byte) { + hid_err(hidpp->hid_dev, "%s: ping mismatch 0x%02x != 0x%02x\n", + __func__, response.rap.params[2], ping_byte); + return -EPROTO; + } + + hidpp->protocol_major = response.rap.params[0]; + hidpp->protocol_minor = response.rap.params[1];
return ret; }
[ Upstream commit 44a4455ac2c6b0981eace683a2b6eccf47689022 ]
The call to of_get_child_by_name returns a node pointer with refcount incremented thus it must be explicitly decremented after the last usage.
Detected by coccinelle with the following warnings: ./drivers/pinctrl/pinctrl-pistachio.c:1422:1-7: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 1360, but without a corresponding object release within this function.
Signed-off-by: Wen Yang wen.yang99@zte.com.cn Cc: Linus Walleij linus.walleij@linaro.org Cc: linux-gpio@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/pinctrl-pistachio.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/pinctrl/pinctrl-pistachio.c b/drivers/pinctrl/pinctrl-pistachio.c index 55375b1b3cc81..b2b7e238bda97 100644 --- a/drivers/pinctrl/pinctrl-pistachio.c +++ b/drivers/pinctrl/pinctrl-pistachio.c @@ -1368,6 +1368,7 @@ static int pistachio_gpio_register(struct pistachio_pinctrl *pctl) if (!of_find_property(child, "gpio-controller", NULL)) { dev_err(pctl->dev, "No gpio-controller property for bank %u\n", i); + of_node_put(child); ret = -ENODEV; goto err; } @@ -1375,6 +1376,7 @@ static int pistachio_gpio_register(struct pistachio_pinctrl *pctl) irq = irq_of_parse_and_map(child, 0); if (irq < 0) { dev_err(pctl->dev, "No IRQ for bank %u: %d\n", i, irq); + of_node_put(child); ret = irq; goto err; }
[ Upstream commit e2c114c06da2d9ffad5b16690abf008d6696f689 ]
Even if this case shouldn't happen when controller is properly programmed, it's still better to avoid dumping a kernel Oops for this. As the sequence may happen only for debugging purposes, log the error and just finish the tasklet call.
Signed-off-by: Nicolas Ferre nicolas.ferre@microchip.com Acked-by: Ludovic Desroches ludovic.desroches@microchip.com Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/at_xdmac.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c index b222dd7afe8e2..12d9048293245 100644 --- a/drivers/dma/at_xdmac.c +++ b/drivers/dma/at_xdmac.c @@ -1608,7 +1608,11 @@ static void at_xdmac_tasklet(unsigned long data) struct at_xdmac_desc, xfer_node); dev_vdbg(chan2dev(&atchan->chan), "%s: desc 0x%p\n", __func__, desc); - BUG_ON(!desc->active_xfer); + if (!desc->active_xfer) { + dev_err(chan2dev(&atchan->chan), "Xfer not active: exiting"); + spin_unlock_bh(&atchan->lock); + return; + }
txd = &desc->tx_dma_desc;
[ Upstream commit bbeefa7357a648afe70e7183914c87c3878d528d ]
The error return value is not written by some firmware codecs, such as MPEG-2 decode on CodaHx4. Clear the error return value before starting the picture run to avoid misinterpreting unrelated values returned by sequence initialization as error return value.
Signed-off-by: Philipp Zabel p.zabel@pengutronix.de 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/coda/coda-bit.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c index b6625047250d6..717ee9a6a80ef 100644 --- a/drivers/media/platform/coda/coda-bit.c +++ b/drivers/media/platform/coda/coda-bit.c @@ -1829,6 +1829,9 @@ static int coda_prepare_decode(struct coda_ctx *ctx) /* Clear decode success flag */ coda_write(dev, 0, CODA_RET_DEC_PIC_SUCCESS);
+ /* Clear error return value */ + coda_write(dev, 0, CODA_RET_DEC_PIC_ERR_MB); + trace_coda_dec_pic_run(ctx, meta);
coda_command_async(ctx, CODA_COMMAND_PIC_RUN);
[ Upstream commit ccdd85d518d8b9320ace1d87271f0ba2175f21fa ]
In preparation for adding asynchronous subdevice support to the driver, don't acquire v4l2_clk from the driver .probe() callback as that may fail if the clock is provided by a bridge driver which may be not yet initialized. Move the v4l2_clk_get() to ov6650_video_probe() helper which is going to be converted to v4l2_subdev_internal_ops.registered() callback, executed only when the bridge driver is ready.
Signed-off-by: Janusz Krzysztofik jmkrzyszt@gmail.com Signed-off-by: Sakari Ailus sakari.ailus@linux.intel.com Signed-off-by: Mauro Carvalho Chehab mchehab+samsung@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/i2c/soc_camera/ov6650.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-)
diff --git a/drivers/media/i2c/soc_camera/ov6650.c b/drivers/media/i2c/soc_camera/ov6650.c index e21b7e1c2ee15..fc187c5aeb1e9 100644 --- a/drivers/media/i2c/soc_camera/ov6650.c +++ b/drivers/media/i2c/soc_camera/ov6650.c @@ -840,9 +840,16 @@ static int ov6650_video_probe(struct i2c_client *client) u8 pidh, pidl, midh, midl; int ret;
+ priv->clk = v4l2_clk_get(&client->dev, NULL); + if (IS_ERR(priv->clk)) { + ret = PTR_ERR(priv->clk); + dev_err(&client->dev, "v4l2_clk request err: %d\n", ret); + return ret; + } + ret = ov6650_s_power(&priv->subdev, 1); if (ret < 0) - return ret; + goto eclkput;
msleep(20);
@@ -879,6 +886,11 @@ static int ov6650_video_probe(struct i2c_client *client)
done: ov6650_s_power(&priv->subdev, 0); + if (!ret) + return 0; +eclkput: + v4l2_clk_put(priv->clk); + return ret; }
@@ -1035,18 +1047,9 @@ static int ov6650_probe(struct i2c_client *client, priv->code = MEDIA_BUS_FMT_YUYV8_2X8; priv->colorspace = V4L2_COLORSPACE_JPEG;
- priv->clk = v4l2_clk_get(&client->dev, NULL); - if (IS_ERR(priv->clk)) { - ret = PTR_ERR(priv->clk); - goto eclkget; - } - ret = ov6650_video_probe(client); - if (ret) { - v4l2_clk_put(priv->clk); -eclkget: + if (ret) v4l2_ctrl_handler_free(&priv->hdl); - }
return ret; }
[ Upstream commit f604f0f5afb88045944567f604409951b5eb6af8 ]
If the application was streaming from both videoX and vbiX, and streaming from videoX was stopped, then the vbi streaming also stopped.
The cause being that stop_streaming for video stopped the subdevs as well, instead of only doing that if dev->streaming_users reached 0.
au0828_stop_vbi_streaming was also wrong since it didn't stop the subdevs at all when dev->streaming_users reached 0.
Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Tested-by: Shuah Khan shuah@kernel.org Signed-off-by: Mauro Carvalho Chehab mchehab+samsung@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/usb/au0828/au0828-video.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index 85dd9a8e83ff1..40594c8a71f4f 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -852,9 +852,9 @@ int au0828_start_analog_streaming(struct vb2_queue *vq, unsigned int count) return rc; }
+ v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 1); + if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { - v4l2_device_call_all(&dev->v4l2_dev, 0, video, - s_stream, 1); dev->vid_timeout_running = 1; mod_timer(&dev->vid_timeout, jiffies + (HZ / 10)); } else if (vq->type == V4L2_BUF_TYPE_VBI_CAPTURE) { @@ -874,10 +874,11 @@ static void au0828_stop_streaming(struct vb2_queue *vq)
dprintk(1, "au0828_stop_streaming called %d\n", dev->streaming_users);
- if (dev->streaming_users-- == 1) + if (dev->streaming_users-- == 1) { au0828_uninit_isoc(dev); + v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0); + }
- v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0); dev->vid_timeout_running = 0; del_timer_sync(&dev->vid_timeout);
@@ -906,8 +907,10 @@ void au0828_stop_vbi_streaming(struct vb2_queue *vq) dprintk(1, "au0828_stop_vbi_streaming called %d\n", dev->streaming_users);
- if (dev->streaming_users-- == 1) + if (dev->streaming_users-- == 1) { au0828_uninit_isoc(dev); + v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0); + }
spin_lock_irqsave(&dev->slock, flags); if (dev->isoc_ctl.vbi_buf != NULL) {
[ Upstream commit bccb89cf9cd07a0690d519696a00c00a973b3fe4 ]
This driver returns an error if unsupported media bus pixel code is requested by VIDIOC_SUBDEV_S_FMT.
But according to Documentation/media/uapi/v4l/vidioc-subdev-g-fmt.rst,
Drivers must not return an error solely because the requested format doesn't match the device capabilities. They must instead modify the format to match what the hardware can provide.
So select default format code and return success in that case.
This is detected by v4l2-compliance.
Cc: "Lad, Prabhakar" prabhakar.csengg@gmail.com Signed-off-by: Akinobu Mita akinobu.mita@gmail.com Acked-by: Lad, Prabhakar prabhakar.csengg@gmail.com Signed-off-by: Sakari Ailus sakari.ailus@linux.intel.com Signed-off-by: Mauro Carvalho Chehab mchehab+samsung@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/i2c/ov2659.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c index 1f999e9c0118e..3554eea77e04c 100644 --- a/drivers/media/i2c/ov2659.c +++ b/drivers/media/i2c/ov2659.c @@ -1117,8 +1117,10 @@ static int ov2659_set_fmt(struct v4l2_subdev *sd, if (ov2659_formats[index].code == mf->code) break;
- if (index < 0) - return -EINVAL; + if (index < 0) { + index = 0; + mf->code = ov2659_formats[index].code; + }
mf->colorspace = V4L2_COLORSPACE_SRGB; mf->code = ov2659_formats[index].code;
[ Upstream commit 70c4cf17e445264453bc5323db3e50aa0ac9e81f ]
In audit_rule_change(), audit_data_to_entry() is firstly invoked to translate the payload data to the kernel's rule representation. In audit_data_to_entry(), depending on the audit field type, an audit tree may be created in audit_make_tree(), which eventually invokes kmalloc() to allocate the tree. Since this tree is a temporary tree, it will be then freed in the following execution, e.g., audit_add_rule() if the message type is AUDIT_ADD_RULE or audit_del_rule() if the message type is AUDIT_DEL_RULE. However, if the message type is neither AUDIT_ADD_RULE nor AUDIT_DEL_RULE, i.e., the default case of the switch statement, this temporary tree is not freed.
To fix this issue, only allocate the tree when the type is AUDIT_ADD_RULE or AUDIT_DEL_RULE.
Signed-off-by: Wenwen Wang wang6495@umn.edu Reviewed-by: Richard Guy Briggs rgb@redhat.com Signed-off-by: Paul Moore paul@paul-moore.com Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/auditfilter.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index cd4f41397c7e8..42b7251c597fb 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -1095,22 +1095,24 @@ int audit_rule_change(int type, __u32 portid, int seq, void *data, int err = 0; struct audit_entry *entry;
- entry = audit_data_to_entry(data, datasz); - if (IS_ERR(entry)) - return PTR_ERR(entry); - switch (type) { case AUDIT_ADD_RULE: + entry = audit_data_to_entry(data, datasz); + if (IS_ERR(entry)) + return PTR_ERR(entry); err = audit_add_rule(entry); audit_log_rule_change("add_rule", &entry->rule, !err); break; case AUDIT_DEL_RULE: + entry = audit_data_to_entry(data, datasz); + if (IS_ERR(entry)) + return PTR_ERR(entry); err = audit_del_rule(entry); audit_log_rule_change("remove_rule", &entry->rule, !err); break; default: - err = -EINVAL; WARN_ON(1); + return -EINVAL; }
if (err || type == AUDIT_DEL_RULE) {
[ Upstream commit 898bc40bfcc26abb6e06e960d6d4754c36c58b50 ]
Fix au0828_analog_stream_enable() to check if device is in the right state first. When unbind happens while bind is in progress, usbdev pointer could be invalid in au0828_analog_stream_enable() and a call to usb_ifnum_to_if() will result in the null pointer dereference.
This problem is found with the new media_dev_allocator.sh test.
kernel: [ 590.359623] BUG: unable to handle kernel NULL pointer dereference at 00000000000004e8 kernel: [ 590.359627] #PF error: [normal kernel read fault] kernel: [ 590.359629] PGD 0 P4D 0 kernel: [ 590.359632] Oops: 0000 [#1] SMP PTI kernel: [ 590.359634] CPU: 3 PID: 1458 Comm: v4l_id Not tainted 5.1.0-rc2+ #30 kernel: [ 590.359636] Hardware name: Dell Inc. OptiPlex 7 90/0HY9JP, BIOS A18 09/24/2013 kernel: [ 590.359641] RIP: 0010:usb_ifnum_to_if+0x6/0x60 kernel: [ 590.359643] Code: 5d 41 5e 41 5f 5d c3 48 83 c4 10 b8 fa ff ff ff 5b 41 5c 41 5d 41 5e 41 5f 5d c3 b8 fa ff ff ff c3 0f 1f 00 6 6 66 66 66 90 55 <48> 8b 97 e8 04 00 00 48 89 e5 48 85 d2 74 41 0f b6 4a 04 84 c 9 74 kernel: [ 590.359645] RSP: 0018:ffffad3cc3c1fc00 EFLAGS: 00010246 kernel: [ 590.359646] RAX: 0000000000000000 RBX: ffff8ded b1f3c000 RCX: 1f377e4500000000 kernel: [ 590.359648] RDX: ffff8dedfa3a6b50 RSI: 00000000 00000000 RDI: 0000000000000000 kernel: [ 590.359649] RBP: ffffad3cc3c1fc28 R08: 00000000 8574acc2 R09: ffff8dedfa3a6b50 kernel: [ 590.359650] R10: 0000000000000001 R11: 00000000 00000000 R12: 0000000000000000 kernel: [ 590.359652] R13: ffff8dedb1f3f0f0 R14: ffffffff adcf7ec0 R15: 0000000000000000 kernel: [ 590.359654] FS: 00007f7917198540(0000) GS:ffff 8dee258c0000(0000) knlGS:0000000000000000 kernel: [ 590.359655] CS: 0010 DS: 0000 ES: 0000 CR0: 00 00000080050033 kernel: [ 590.359657] CR2: 00000000000004e8 CR3: 00000001 a388e002 CR4: 00000000000606e0 kernel: [ 590.359658] Call Trace: kernel: [ 590.359664] ? au0828_analog_stream_enable+0x2c/0x180 kernel: [ 590.359666] au0828_v4l2_open+0xa4/0x110 kernel: [ 590.359670] v4l2_open+0x8b/0x120 kernel: [ 590.359674] chrdev_open+0xa6/0x1c0 kernel: [ 590.359676] ? cdev_put.part.3+0x20/0x20 kernel: [ 590.359678] do_dentry_open+0x1f6/0x360 kernel: [ 590.359681] vfs_open+0x2f/0x40 kernel: [ 590.359684] path_openat+0x299/0xc20 kernel: [ 590.359688] do_filp_open+0x9b/0x110 kernel: [ 590.359695] ? _raw_spin_unlock+0x27/0x40 kernel: [ 590.359697] ? __alloc_fd+0xb2/0x160 kernel: [ 590.359700] do_sys_open+0x1ba/0x260 kernel: [ 590.359702] ? do_sys_open+0x1ba/0x260 kernel: [ 590.359712] __x64_sys_openat+0x20/0x30 kernel: [ 590.359715] do_syscall_64+0x5a/0x120 kernel: [ 590.359718] entry_SYSCALL_64_after_hwframe+0x44/0xa9
Signed-off-by: Shuah Khan shuah@kernel.org 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/usb/au0828/au0828-video.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index 40594c8a71f4f..48eeb5a6a2099 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -764,6 +764,9 @@ static int au0828_analog_stream_enable(struct au0828_dev *d)
dprintk(1, "au0828_analog_stream_enable called\n");
+ if (test_bit(DEV_DISCONNECTED, &d->dev_state)) + return -ENODEV; + iface = usb_ifnum_to_if(d->usbdev, 0); if (iface && iface->cur_altsetting->desc.bAlternateSetting != 5) { dprintk(1, "Changing intf#0 to alt 5\n");
[ Upstream commit c1ced46c7b49ad7bc064e68d966e0ad303f917fb ]
The ctrl_check_input() function is called from pvr2_ctrl_range_check(). It's supposed to validate user supplied input and return true or false depending on whether the input is valid or not. The problem is that negative shifts or shifts greater than 31 are undefined in C. In practice with GCC they result in shift wrapping so this function returns true for some inputs which are not valid and this could result in a buffer overflow:
drivers/media/usb/pvrusb2/pvrusb2-ctrl.c:205 pvr2_ctrl_get_valname() warn: uncapped user index 'names[val]'
The cptr->hdw->input_allowed_mask mask is configured in pvr2_hdw_create() and the highest valid bit is BIT(4).
Fixes: 7fb20fa38caa ("V4L/DVB (7299): pvrusb2: Improve logic which handles input choice availability")
Signed-off-by: Dan Carpenter dan.carpenter@oracle.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/usb/pvrusb2/pvrusb2-hdw.c | 2 ++ drivers/media/usb/pvrusb2/pvrusb2-hdw.h | 1 + 2 files changed, 3 insertions(+)
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c index 1eb4f7ba2967d..ff489645e0701 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c @@ -670,6 +670,8 @@ static int ctrl_get_input(struct pvr2_ctrl *cptr,int *vp)
static int ctrl_check_input(struct pvr2_ctrl *cptr,int v) { + if (v < 0 || v > PVR2_CVAL_INPUT_MAX) + return 0; return ((1 << v) & cptr->hdw->input_allowed_mask) != 0; }
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.h b/drivers/media/usb/pvrusb2/pvrusb2-hdw.h index a82a00dd73293..80869990ffbbb 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.h +++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.h @@ -54,6 +54,7 @@ #define PVR2_CVAL_INPUT_COMPOSITE 2 #define PVR2_CVAL_INPUT_SVIDEO 3 #define PVR2_CVAL_INPUT_RADIO 4 +#define PVR2_CVAL_INPUT_MAX PVR2_CVAL_INPUT_RADIO
enum pvr2_config { pvr2_config_empty, /* No configuration */
[ Upstream commit 2d4d9b308f8f8dec68f6dbbff18c68ec7c6bd26f ]
When booted with "topology_updates=no", or when "off" is written to /proc/powerpc/topology_updates, NUMA reassignments are inhibited for PRRN and VPHN events. However, migration and suspend unconditionally re-enable reassignments via start_topology_update(). This is incoherent.
Check the topology_updates_enabled flag in start/stop_topology_update() so that callers of those APIs need not be aware of whether reassignments are enabled. This allows the administrative decision on reassignments to remain in force across migrations and suspensions.
Signed-off-by: Nathan Lynch nathanl@linux.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/mm/numa.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 9cad2ed812ab7..31e9064ba6281 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -1574,6 +1574,9 @@ int start_topology_update(void) { int rc = 0;
+ if (!topology_updates_enabled) + return 0; + if (firmware_has_feature(FW_FEATURE_PRRN)) { if (!prrn_enabled) { prrn_enabled = 1; @@ -1603,6 +1606,9 @@ int stop_topology_update(void) { int rc = 0;
+ if (!topology_updates_enabled) + return 0; + if (prrn_enabled) { prrn_enabled = 0; #ifdef CONFIG_SMP @@ -1648,11 +1654,13 @@ static ssize_t topology_write(struct file *file, const char __user *buf,
kbuf[read_len] = '\0';
- if (!strncmp(kbuf, "on", 2)) + if (!strncmp(kbuf, "on", 2)) { + topology_updates_enabled = true; start_topology_update(); - else if (!strncmp(kbuf, "off", 3)) + } else if (!strncmp(kbuf, "off", 3)) { stop_topology_update(); - else + topology_updates_enabled = false; + } else return -EINVAL;
return count; @@ -1667,9 +1675,7 @@ static const struct file_operations topology_ops = {
static int topology_update_init(void) { - /* Do not poll for changes if disabled at boot */ - if (topology_updates_enabled) - start_topology_update(); + start_topology_update();
if (!proc_create("powerpc/topology_updates", 0644, NULL, &topology_ops)) return -ENOMEM;
[ Upstream commit 1a8b4540db732ca16c9e43ac7c08b1b8f0b252d8 ]
Large values could overflow u64 and pass following sanity checks.
# echo 18446744073750000 > cpu.cfs_period_us # cat cpu.cfs_period_us 40448
# echo 18446744073750000 > cpu.cfs_quota_us # cat cpu.cfs_quota_us 40448
After this patch they will fail with -EINVAL.
Signed-off-by: Konstantin Khlebnikov khlebnikov@yandex-team.ru Acked-by: Peter Zijlstra a.p.zijlstra@chello.nl Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Peter Zijlstra peterz@infradead.org Cc: Thomas Gleixner tglx@linutronix.de Link: http://lkml.kernel.org/r/155125502079.293431.3947497929372138600.stgit@buzz Signed-off-by: Ingo Molnar mingo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/sched/core.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 50e80b1be2c8f..4617ede80f020 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -8611,8 +8611,10 @@ int tg_set_cfs_quota(struct task_group *tg, long cfs_quota_us) period = ktime_to_ns(tg->cfs_bandwidth.period); if (cfs_quota_us < 0) quota = RUNTIME_INF; - else + else if ((u64)cfs_quota_us <= U64_MAX / NSEC_PER_USEC) quota = (u64)cfs_quota_us * NSEC_PER_USEC; + else + return -EINVAL;
return tg_set_cfs_bandwidth(tg, period, quota); } @@ -8634,6 +8636,9 @@ int tg_set_cfs_period(struct task_group *tg, long cfs_period_us) { u64 quota, period;
+ if ((u64)cfs_period_us > U64_MAX / NSEC_PER_USEC) + return -EINVAL; + period = (u64)cfs_period_us * NSEC_PER_USEC; quota = tg->cfs_bandwidth.quota;
[ Upstream commit 5b61d50ab4ef590f5e1d4df15cd2cea5f5715308 ]
Bit shift in scale_load() could overflow shares. This patch saturates it to MAX_SHARES like following sched_group_set_shares().
Example:
# echo 9223372036854776832 > cpu.shares # cat cpu.shares
Before patch: 1024 After pattch: 262144
Signed-off-by: Konstantin Khlebnikov khlebnikov@yandex-team.ru Acked-by: Peter Zijlstra a.p.zijlstra@chello.nl Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Peter Zijlstra peterz@infradead.org Cc: Thomas Gleixner tglx@linutronix.de Link: http://lkml.kernel.org/r/155125501891.293431.3345233332801109696.stgit@buzz Signed-off-by: Ingo Molnar mingo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/sched/core.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 4617ede80f020..3861dd6da91e7 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -8512,6 +8512,8 @@ static void cpu_cgroup_attach(struct cgroup_taskset *tset) static int cpu_shares_write_u64(struct cgroup_subsys_state *css, struct cftype *cftype, u64 shareval) { + if (shareval > scale_load_down(ULONG_MAX)) + shareval = MAX_SHARES; return sched_group_set_shares(css_tg(css), scale_load(shareval)); }
[ Upstream commit 381419fa720060ba48b7bbc483be787d5b1dca6f ]
The SCSI core does not like to have devices or hosts unregistered while error recovery is in progress. Trying to do so can lead to self-deadlock: Part of the removal code tries to obtain a lock already held by the error handler.
This can cause problems for the usb-storage and uas drivers, because their error handler routines perform a USB reset, and if the reset fails then the USB core automatically goes on to unbind all drivers from the device's interfaces -- all while still in the context of the SCSI error handler.
As it turns out, practically all the scenarios leading to a USB reset failure end up causing a device disconnect (the main error pathway in usb_reset_and_verify_device(), at the end of the routine, calls hub_port_logical_disconnect() before returning). As a result, the hub_wq thread will soon become aware of the problem and will unbind all the device's drivers in its own context, not in the error-handler's context.
This means that usb_reset_device() does not need to call usb_unbind_and_rebind_marked_interfaces() in cases where usb_reset_and_verify_device() has returned an error, because hub_wq will take care of everything anyway.
This particular problem was observed in somewhat artificial circumstances, by using usbfs to tell a hub to power-down a port connected to a USB-3 mass storage device using the UAS protocol. With the port turned off, the currently executing command timed out and the error handler started running. The USB reset naturally failed, because the hub port was off, and the error handler deadlocked as described above. Not carrying out the call to usb_unbind_and_rebind_marked_interfaces() fixes this issue.
Signed-off-by: Alan Stern stern@rowland.harvard.edu Reported-by: Kento Kobayashi Kento.A.Kobayashi@sony.com Tested-by: Kento Kobayashi Kento.A.Kobayashi@sony.com CC: Bart Van Assche bvanassche@acm.org CC: Martin K. Petersen martin.petersen@oracle.com CC: Jacky Cao Jacky.Cao@sony.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/core/hub.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 8fddb94f1874e..3941df076ccac 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -5703,7 +5703,10 @@ int usb_reset_device(struct usb_device *udev) cintf->needs_binding = 1; } } - usb_unbind_and_rebind_marked_interfaces(udev); + + /* If the reset failed, hub_wq will unbind drivers later */ + if (ret == 0) + usb_unbind_and_rebind_marked_interfaces(udev); }
usb_autosuspend_device(udev);
[ Upstream commit 7dbcf2b0b770eeb803a416ee8dcbef78e6389d40 ]
Commit
37fe6a42b343 ("x86: Check stack overflow in detail")
added a broad check for the full exception stack area, i.e. it considers the full exception stack area as valid.
That's wrong in two aspects:
1) It does not check the individual areas one by one
2) #DF, NMI and #MCE are not enabling interrupts which means that a regular device interrupt cannot happen in their context. In fact if a device interrupt hits one of those IST stacks that's a bug because some code path enabled interrupts while handling the exception.
Limit the check to the #DB stack and consider all other IST stacks as 'overflow' or invalid.
Signed-off-by: Thomas Gleixner tglx@linutronix.de Signed-off-by: Borislav Petkov bp@suse.de Cc: Andy Lutomirski luto@kernel.org Cc: "H. Peter Anvin" hpa@zytor.com Cc: Ingo Molnar mingo@redhat.com Cc: Josh Poimboeuf jpoimboe@redhat.com Cc: Mitsuo Hayasaka mitsuo.hayasaka.hu@hitachi.com Cc: Nicolai Stange nstange@suse.de Cc: Sean Christopherson sean.j.christopherson@intel.com Cc: x86-ml x86@kernel.org Link: https://lkml.kernel.org/r/20190414160143.682135110@linutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/kernel/irq_64.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/arch/x86/kernel/irq_64.c b/arch/x86/kernel/irq_64.c index bcd1b82c86e81..005e9a77a664e 100644 --- a/arch/x86/kernel/irq_64.c +++ b/arch/x86/kernel/irq_64.c @@ -25,9 +25,18 @@ int sysctl_panic_on_stackoverflow; /* * Probabilistic stack overflow check: * - * Only check the stack in process context, because everything else - * runs on the big interrupt stacks. Checking reliably is too expensive, - * so we just check from interrupts. + * Regular device interrupts can enter on the following stacks: + * + * - User stack + * + * - Kernel task stack + * + * - Interrupt stack if a device driver reenables interrupts + * which should only happen in really old drivers. + * + * - Debug IST stack + * + * All other contexts are invalid. */ static inline void stack_overflow_check(struct pt_regs *regs) { @@ -52,8 +61,8 @@ static inline void stack_overflow_check(struct pt_regs *regs) return;
oist = this_cpu_ptr(&orig_ist); - estack_top = (u64)oist->ist[0] - EXCEPTION_STKSZ + STACK_TOP_MARGIN; - estack_bottom = (u64)oist->ist[N_EXCEPTION_STACKS - 1]; + estack_bottom = (u64)oist->ist[DEBUG_STACK]; + estack_top = estack_bottom - DEBUG_STKSZ + STACK_TOP_MARGIN; if (regs->sp >= estack_top && regs->sp <= estack_bottom) return;
[ Upstream commit bfb0ebed53857cfc57f11c63fa3689940d71c1c8 ]
Modifying the VLAN stripping options when a port VLAN is configured will break traffic for the VSI, and conceptually doesn't make sense, so don't allow this.
Signed-off-by: Nicholas Nunley nicholas.d.nunley@intel.com Signed-off-by: Jeff Kirsher jeffrey.t.kirsher@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/i40e/i40e_main.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 7836072d3f631..886378c5334fa 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -2285,6 +2285,10 @@ void i40e_vlan_stripping_enable(struct i40e_vsi *vsi) struct i40e_vsi_context ctxt; i40e_status ret;
+ /* Don't modify stripping options if a port VLAN is active */ + if (vsi->info.pvid) + return; + if ((vsi->info.valid_sections & cpu_to_le16(I40E_AQ_VSI_PROP_VLAN_VALID)) && ((vsi->info.port_vlan_flags & I40E_AQ_VSI_PVLAN_MODE_MASK) == 0)) @@ -2315,6 +2319,10 @@ void i40e_vlan_stripping_disable(struct i40e_vsi *vsi) struct i40e_vsi_context ctxt; i40e_status ret;
+ /* Don't modify stripping options if a port VLAN is active */ + if (vsi->info.pvid) + return; + if ((vsi->info.valid_sections & cpu_to_le16(I40E_AQ_VSI_PROP_VLAN_VALID)) && ((vsi->info.port_vlan_flags & I40E_AQ_VSI_PVLAN_EMOD_MASK) ==
[ Upstream commit 81fb8736dd81da3fe94f28968dac60f392ec6746 ]
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;
where 'hrtimer_resolution' depends on whether or not high resolution timers are enabled, which is a runtime decision.
The vDSO incorrectly returns the constant CLOCK_REALTIME_RES. Fix this by exposing 'hrtimer_resolution' in the vDSO datapage and returning that instead.
Reviewed-by: Catalin Marinas catalin.marinas@arm.com Signed-off-by: Vincenzo Frascino vincenzo.frascino@arm.com [will: Use WRITE_ONCE(), move adr off COARSE path, renumber labels, use 'w' reg] Signed-off-by: Will Deacon will.deacon@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/include/asm/vdso_datapage.h | 1 + arch/arm64/kernel/asm-offsets.c | 2 +- arch/arm64/kernel/vdso.c | 3 +++ arch/arm64/kernel/vdso/gettimeofday.S | 7 +++---- 4 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/arch/arm64/include/asm/vdso_datapage.h b/arch/arm64/include/asm/vdso_datapage.h index 2b9a63771eda8..f89263c8e11af 100644 --- a/arch/arm64/include/asm/vdso_datapage.h +++ b/arch/arm64/include/asm/vdso_datapage.h @@ -38,6 +38,7 @@ struct vdso_data { __u32 tz_minuteswest; /* Whacky timezone stuff */ __u32 tz_dsttime; __u32 use_syscall; + __u32 hrtimer_res; };
#endif /* !__ASSEMBLY__ */ diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c index bd239b1b7a681..95878bea27f93 100644 --- a/arch/arm64/kernel/asm-offsets.c +++ b/arch/arm64/kernel/asm-offsets.c @@ -92,7 +92,7 @@ int main(void) DEFINE(CLOCK_REALTIME, CLOCK_REALTIME); DEFINE(CLOCK_MONOTONIC, CLOCK_MONOTONIC); DEFINE(CLOCK_MONOTONIC_RAW, CLOCK_MONOTONIC_RAW); - DEFINE(CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC); + DEFINE(CLOCK_REALTIME_RES, offsetof(struct vdso_data, hrtimer_res)); DEFINE(CLOCK_REALTIME_COARSE, CLOCK_REALTIME_COARSE); DEFINE(CLOCK_MONOTONIC_COARSE,CLOCK_MONOTONIC_COARSE); DEFINE(CLOCK_COARSE_RES, LOW_RES_NSEC); diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c index 4bcfe01b5aad4..c9b9a5a322eb1 100644 --- a/arch/arm64/kernel/vdso.c +++ b/arch/arm64/kernel/vdso.c @@ -213,6 +213,9 @@ void update_vsyscall(struct timekeeper *tk) vdso_data->wtm_clock_sec = tk->wall_to_monotonic.tv_sec; vdso_data->wtm_clock_nsec = tk->wall_to_monotonic.tv_nsec;
+ /* Read without the seqlock held by clock_getres() */ + WRITE_ONCE(vdso_data->hrtimer_res, hrtimer_resolution); + if (!use_syscall) { /* tkr_mono.cycle_last == tkr_raw.cycle_last */ vdso_data->cs_cycle_last = tk->tkr_mono.cycle_last; diff --git a/arch/arm64/kernel/vdso/gettimeofday.S b/arch/arm64/kernel/vdso/gettimeofday.S index 76320e9209651..df829c4346fac 100644 --- a/arch/arm64/kernel/vdso/gettimeofday.S +++ b/arch/arm64/kernel/vdso/gettimeofday.S @@ -301,13 +301,14 @@ ENTRY(__kernel_clock_getres) ccmp w0, #CLOCK_MONOTONIC_RAW, #0x4, ne b.ne 1f
- ldr x2, 5f + adr vdso_data, _vdso_data + ldr w2, [vdso_data, #CLOCK_REALTIME_RES] b 2f 1: cmp w0, #CLOCK_REALTIME_COARSE ccmp w0, #CLOCK_MONOTONIC_COARSE, #0x4, ne b.ne 4f - ldr x2, 6f + ldr x2, 5f 2: cbz w1, 3f stp xzr, x2, [x1] @@ -321,8 +322,6 @@ ENTRY(__kernel_clock_getres) svc #0 ret 5: - .quad CLOCK_REALTIME_RES -6: .quad CLOCK_COARSE_RES .cfi_endproc ENDPROC(__kernel_clock_getres)
[ Upstream commit a6d2a5a92e67d151c98886babdc86d530d27111c ]
Currently if alloc_skb fails to allocate the skb a null skb is passed to t4_set_arp_err_handler and this ends up dereferencing the null skb. Avoid the NULL pointer dereference by checking for a NULL skb and returning early.
Addresses-Coverity: ("Dereference null return") Fixes: b38a0ad8ec11 ("RDMA/cxgb4: Set arp error handler for PASS_ACCEPT_RPL messages") Signed-off-by: Colin Ian King colin.king@canonical.com Acked-by: Potnuri Bharat Teja bharat@chelsio.com Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/cxgb4/cm.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index a2322b2dbd82c..e5752352e0fb1 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c @@ -455,6 +455,8 @@ static struct sk_buff *get_skb(struct sk_buff *skb, int len, gfp_t gfp) skb_reset_transport_header(skb); } else { skb = alloc_skb(len, gfp); + if (!skb) + return NULL; } t4_set_arp_err_handler(skb, NULL, NULL); return skb;
[ Upstream commit 14b97ba5c20056102b3dd22696bf17b057e60976 ]
Super-IO accesses may fail on a system with no or unmapped LPC bus.
Also, other drivers may attempt to access the LPC bus at the same time, resulting in undefined behavior.
Use request_muxed_region() to ensure that IO access on the requested address space is supported, and to ensure that access by multiple drivers is synchronized.
Fixes: 2219cd81a6cd ("hwmon/vt1211: Add probing of alternate config index port") Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwmon/vt1211.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/vt1211.c b/drivers/hwmon/vt1211.c index 3a6bfa51cb94f..95d5e8ec8b7fc 100644 --- a/drivers/hwmon/vt1211.c +++ b/drivers/hwmon/vt1211.c @@ -226,15 +226,21 @@ static inline void superio_select(int sio_cip, int ldn) outb(ldn, sio_cip + 1); }
-static inline void superio_enter(int sio_cip) +static inline int superio_enter(int sio_cip) { + if (!request_muxed_region(sio_cip, 2, DRVNAME)) + return -EBUSY; + outb(0x87, sio_cip); outb(0x87, sio_cip); + + return 0; }
static inline void superio_exit(int sio_cip) { outb(0xaa, sio_cip); + release_region(sio_cip, 2); }
/* --------------------------------------------------------------------- @@ -1282,11 +1288,14 @@ static int __init vt1211_device_add(unsigned short address)
static int __init vt1211_find(int sio_cip, unsigned short *address) { - int err = -ENODEV; + int err; int devid;
- superio_enter(sio_cip); + err = superio_enter(sio_cip); + if (err) + return err;
+ err = -ENODEV; devid = force_id ? force_id : superio_inb(sio_cip, SIO_VT1211_DEVID); if (devid != SIO_VT1211_ID) goto EXIT;
[ Upstream commit d6410408ad2a798c4cc685252c1baa713be0ad69 ]
Super-IO accesses may fail on a system with no or unmapped LPC bus.
Also, other drivers may attempt to access the LPC bus at the same time, resulting in undefined behavior.
Use request_muxed_region() to ensure that IO access on the requested address space is supported, and to ensure that access by multiple drivers is synchronized.
Fixes: 8d5d45fb1468 ("I2C: Move hwmon drivers (2/3)") Reported-by: Kefeng Wang wangkefeng.wang@huawei.com Reported-by: John Garry john.garry@huawei.com Cc: John Garry john.garry@huawei.com Acked-by: John Garry john.garry@huawei.com Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwmon/smsc47m1.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-)
diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c index 5d323186d2c10..d24df0c50bea4 100644 --- a/drivers/hwmon/smsc47m1.c +++ b/drivers/hwmon/smsc47m1.c @@ -73,16 +73,21 @@ superio_inb(int reg) /* logical device for fans is 0x0A */ #define superio_select() superio_outb(0x07, 0x0A)
-static inline void +static inline int superio_enter(void) { + if (!request_muxed_region(REG, 2, DRVNAME)) + return -EBUSY; + outb(0x55, REG); + return 0; }
static inline void superio_exit(void) { outb(0xAA, REG); + release_region(REG, 2); }
#define SUPERIO_REG_ACT 0x30 @@ -531,8 +536,12 @@ static int __init smsc47m1_find(struct smsc47m1_sio_data *sio_data) { u8 val; unsigned short addr; + int err; + + err = superio_enter(); + if (err) + return err;
- superio_enter(); val = force_id ? force_id : superio_inb(SUPERIO_REG_DEVID);
/* @@ -608,13 +617,14 @@ static int __init smsc47m1_find(struct smsc47m1_sio_data *sio_data) static void smsc47m1_restore(const struct smsc47m1_sio_data *sio_data) { if ((sio_data->activate & 0x01) == 0) { - superio_enter(); - superio_select(); - - pr_info("Disabling device\n"); - superio_outb(SUPERIO_REG_ACT, sio_data->activate); - - superio_exit(); + if (!superio_enter()) { + superio_select(); + pr_info("Disabling device\n"); + superio_outb(SUPERIO_REG_ACT, sio_data->activate); + superio_exit(); + } else { + pr_warn("Failed to disable device\n"); + } } }
[ Upstream commit 8c0826756744c0ac1df600a5e4cca1a341b13101 ]
Super-IO accesses may fail on a system with no or unmapped LPC bus.
Also, other drivers may attempt to access the LPC bus at the same time, resulting in undefined behavior.
Use request_muxed_region() to ensure that IO access on the requested address space is supported, and to ensure that access by multiple drivers is synchronized.
Fixes: 8d5d45fb1468 ("I2C: Move hwmon drivers (2/3)") Reported-by: Kefeng Wang wangkefeng.wang@huawei.com Reported-by: John Garry john.garry@huawei.com Cc: John Garry john.garry@huawei.com Acked-by: John Garry john.garry@huawei.com Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwmon/smsc47b397.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/drivers/hwmon/smsc47b397.c b/drivers/hwmon/smsc47b397.c index 6bd2007565603..cbdb5c4991ae3 100644 --- a/drivers/hwmon/smsc47b397.c +++ b/drivers/hwmon/smsc47b397.c @@ -72,14 +72,19 @@ static inline void superio_select(int ld) superio_outb(0x07, ld); }
-static inline void superio_enter(void) +static inline int superio_enter(void) { + if (!request_muxed_region(REG, 2, DRVNAME)) + return -EBUSY; + outb(0x55, REG); + return 0; }
static inline void superio_exit(void) { outb(0xAA, REG); + release_region(REG, 2); }
#define SUPERIO_REG_DEVID 0x20 @@ -300,8 +305,12 @@ static int __init smsc47b397_find(void) u8 id, rev; char *name; unsigned short addr; + int err; + + err = superio_enter(); + if (err) + return err;
- superio_enter(); id = force_id ? force_id : superio_inb(SUPERIO_REG_DEVID);
switch (id) {
[ Upstream commit 755a9b0f8aaa5639ba5671ca50080852babb89ce ]
Super-IO accesses may fail on a system with no or unmapped LPC bus.
Also, other drivers may attempt to access the LPC bus at the same time, resulting in undefined behavior.
Use request_muxed_region() to ensure that IO access on the requested address space is supported, and to ensure that access by multiple drivers is synchronized.
Fixes: ba224e2c4f0a7 ("hwmon: New PC87427 hardware monitoring driver") Reported-by: Kefeng Wang wangkefeng.wang@huawei.com Reported-by: John Garry john.garry@huawei.com Cc: John Garry john.garry@huawei.com Acked-by: John Garry john.garry@huawei.com Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwmon/pc87427.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/drivers/hwmon/pc87427.c b/drivers/hwmon/pc87427.c index cb9fdd37bd0d9..2b5b8c3de8fce 100644 --- a/drivers/hwmon/pc87427.c +++ b/drivers/hwmon/pc87427.c @@ -106,6 +106,13 @@ static const char *logdev_str[2] = { DRVNAME " FMC", DRVNAME " HMC" }; #define LD_IN 1 #define LD_TEMP 1
+static inline int superio_enter(int sioaddr) +{ + if (!request_muxed_region(sioaddr, 2, DRVNAME)) + return -EBUSY; + return 0; +} + static inline void superio_outb(int sioaddr, int reg, int val) { outb(reg, sioaddr); @@ -122,6 +129,7 @@ static inline void superio_exit(int sioaddr) { outb(0x02, sioaddr); outb(0x02, sioaddr + 1); + release_region(sioaddr, 2); }
/* @@ -1220,7 +1228,11 @@ static int __init pc87427_find(int sioaddr, struct pc87427_sio_data *sio_data) { u16 val; u8 cfg, cfg_b; - int i, err = 0; + int i, err; + + err = superio_enter(sioaddr); + if (err) + return err;
/* Identify device */ val = force_id ? force_id : superio_inb(sioaddr, SIOREG_DEVID);
[ Upstream commit 73e6ff71a7ea924fb7121d576a2d41e3be3fc6b5 ]
Super-IO accesses may fail on a system with no or unmapped LPC bus.
Unable to handle kernel paging request at virtual address ffffffbffee0002e pgd = ffffffc1d68d4000 [ffffffbffee0002e] *pgd=0000000000000000, *pud=0000000000000000 Internal error: Oops: 94000046 [#1] PREEMPT SMP Modules linked in: f71805f(+) hwmon CPU: 3 PID: 1659 Comm: insmod Not tainted 4.5.0+ #88 Hardware name: linux,dummy-virt (DT) task: ffffffc1f6665400 ti: ffffffc1d6418000 task.ti: ffffffc1d6418000 PC is at f71805f_find+0x6c/0x358 [f71805f]
Also, other drivers may attempt to access the LPC bus at the same time, resulting in undefined behavior.
Use request_muxed_region() to ensure that IO access on the requested address space is supported, and to ensure that access by multiple drivers is synchronized.
Fixes: e53004e20a58e ("hwmon: New f71805f driver") Reported-by: Kefeng Wang wangkefeng.wang@huawei.com Reported-by: John Garry john.garry@huawei.com Cc: John Garry john.garry@huawei.com Acked-by: John Garry john.garry@huawei.com Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwmon/f71805f.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c index facd05cda26da..e8c0898864277 100644 --- a/drivers/hwmon/f71805f.c +++ b/drivers/hwmon/f71805f.c @@ -96,17 +96,23 @@ superio_select(int base, int ld) outb(ld, base + 1); }
-static inline void +static inline int superio_enter(int base) { + if (!request_muxed_region(base, 2, DRVNAME)) + return -EBUSY; + outb(0x87, base); outb(0x87, base); + + return 0; }
static inline void superio_exit(int base) { outb(0xaa, base); + release_region(base, 2); }
/* @@ -1561,7 +1567,7 @@ static int __init f71805f_device_add(unsigned short address, static int __init f71805f_find(int sioaddr, unsigned short *address, struct f71805f_sio_data *sio_data) { - int err = -ENODEV; + int err; u16 devid;
static const char * const names[] = { @@ -1569,8 +1575,11 @@ static int __init f71805f_find(int sioaddr, unsigned short *address, "F71872F/FG or F71806F/FG", };
- superio_enter(sioaddr); + err = superio_enter(sioaddr); + if (err) + return err;
+ err = -ENODEV; devid = superio_inw(sioaddr, SIO_REG_MANID); if (devid != SIO_FINTEK_ID) goto exit;
[ Upstream commit d8649fc1c5e40e691d589ed825998c36a947491c ]
When we discover the PHY is empty in sas_rediscover_dev(), the PHY information (like negotiated linkrate) is not updated.
As such, for a user examining sysfs for that PHY, they would see incorrect values:
root@(none)$ cd /sys/class/sas_phy/phy-0:0:20 root@(none)$ more negotiated_linkrate 3.0 Gbit root@(none)$ echo 0 > enable root@(none)$ more negotiated_linkrate 3.0 Gbit
So fix this, simply discover the PHY again, even though we know it's empty; in the above example, this gives us:
root@(none)$ more negotiated_linkrate Phy disabled
We must do this after unregistering the device associated with the PHY (in sas_unregister_devs_sas_addr()).
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/libsas/sas_expander.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index 1a6f65db615e8..ee1f9ee995e53 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c @@ -2027,6 +2027,11 @@ static int sas_rediscover_dev(struct domain_device *dev, int phy_id, bool last) if ((SAS_ADDR(sas_addr) == 0) || (res == -ECOMM)) { phy->phy_state = PHY_EMPTY; sas_unregister_devs_sas_addr(dev, phy_id, last); + /* + * Even though the PHY is empty, for convenience we discover + * the PHY to update the PHY info, like negotiated linkrate. + */ + sas_ex_phy_discover(dev, phy_id); return res; } else if (SAS_ADDR(sas_addr) == SAS_ADDR(phy->attached_sas_addr) && dev_type_flutter(type, phy->attached_dev_type)) {
[ Upstream commit 002ee28e8b322d4d4b7b83234b5d0f4ebd428eda ]
pwrseq_emmc.c implements a HW reset procedure for eMMC chip by driving a GPIO line.
It registers the .reset() cb on mmc_pwrseq_ops and it registers a system restart notification handler; both of them perform reset by unconditionally calling gpiod_set_value().
If the eMMC reset line is tied to a GPIO controller whose driver can sleep (i.e. I2C GPIO controller), then the kernel would spit warnings when trying to reset the eMMC chip by means of .reset() mmc_pwrseq_ops cb (that is exactly what I'm seeing during boot).
Furthermore, on system reset we would gets to the system restart notification handler with disabled interrupts - local_irq_disable() is called in machine_restart() at least on ARM/ARM64 - and we would be in trouble when the GPIO driver tries to sleep (which indeed doesn't happen here, likely because in my case the machine specific code doesn't call do_kernel_restart(), I guess..).
This patch fixes the .reset() cb to make use of gpiod_set_value_cansleep(), so that the eMMC gets reset on boot without complaints, while, since there isn't that much we can do, we avoid register the restart handler if the GPIO controller has a sleepy driver (and we spit a dev_notice() message to let people know)..
This had been tested on a downstream 4.9 kernel with backported commit 83f37ee7ba33 ("mmc: pwrseq: Add reset callback to the struct mmc_pwrseq_ops") and commit ae60fb031cf2 ("mmc: core: Don't do eMMC HW reset when resuming the eMMC card"), because I couldn't boot my board otherwise. Maybe worth to RFT.
Signed-off-by: Andrea Merello andrea.merello@gmail.com Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mmc/core/pwrseq_emmc.c | 38 ++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 18 deletions(-)
diff --git a/drivers/mmc/core/pwrseq_emmc.c b/drivers/mmc/core/pwrseq_emmc.c index adc9c0c614fb1..4493c299d85ee 100644 --- a/drivers/mmc/core/pwrseq_emmc.c +++ b/drivers/mmc/core/pwrseq_emmc.c @@ -30,19 +30,14 @@ struct mmc_pwrseq_emmc {
#define to_pwrseq_emmc(p) container_of(p, struct mmc_pwrseq_emmc, pwrseq)
-static void __mmc_pwrseq_emmc_reset(struct mmc_pwrseq_emmc *pwrseq) -{ - gpiod_set_value(pwrseq->reset_gpio, 1); - udelay(1); - gpiod_set_value(pwrseq->reset_gpio, 0); - udelay(200); -} - static void mmc_pwrseq_emmc_reset(struct mmc_host *host) { struct mmc_pwrseq_emmc *pwrseq = to_pwrseq_emmc(host->pwrseq);
- __mmc_pwrseq_emmc_reset(pwrseq); + gpiod_set_value_cansleep(pwrseq->reset_gpio, 1); + udelay(1); + gpiod_set_value_cansleep(pwrseq->reset_gpio, 0); + udelay(200); }
static int mmc_pwrseq_emmc_reset_nb(struct notifier_block *this, @@ -50,8 +45,11 @@ static int mmc_pwrseq_emmc_reset_nb(struct notifier_block *this, { struct mmc_pwrseq_emmc *pwrseq = container_of(this, struct mmc_pwrseq_emmc, reset_nb); + gpiod_set_value(pwrseq->reset_gpio, 1); + udelay(1); + gpiod_set_value(pwrseq->reset_gpio, 0); + udelay(200);
- __mmc_pwrseq_emmc_reset(pwrseq); return NOTIFY_DONE; }
@@ -72,14 +70,18 @@ static int mmc_pwrseq_emmc_probe(struct platform_device *pdev) if (IS_ERR(pwrseq->reset_gpio)) return PTR_ERR(pwrseq->reset_gpio);
- /* - * register reset handler to ensure emmc reset also from - * emergency_reboot(), priority 255 is the highest priority - * so it will be executed before any system reboot handler. - */ - pwrseq->reset_nb.notifier_call = mmc_pwrseq_emmc_reset_nb; - pwrseq->reset_nb.priority = 255; - register_restart_handler(&pwrseq->reset_nb); + if (!gpiod_cansleep(pwrseq->reset_gpio)) { + /* + * register reset handler to ensure emmc reset also from + * emergency_reboot(), priority 255 is the highest priority + * so it will be executed before any system reboot handler. + */ + pwrseq->reset_nb.notifier_call = mmc_pwrseq_emmc_reset_nb; + pwrseq->reset_nb.priority = 255; + register_restart_handler(&pwrseq->reset_nb); + } else { + dev_notice(dev, "EMMC reset pin tied to a sleepy GPIO driver; reset on emergency-reboot disabled\n"); + }
pwrseq->pwrseq.ops = &mmc_pwrseq_emmc_ops; pwrseq->pwrseq.dev = dev;
[ Upstream commit 611025983b7976df0183390a63a2166411d177f1 ]
In case spi_sync_locked fails, the fix reports the error and returns the error code upstream.
Signed-off-by: Kangjie Lu kjlu@umn.edu Reviewed-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mmc/host/mmc_spi.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c index 6224ad37fd80b..c2df68e958b33 100644 --- a/drivers/mmc/host/mmc_spi.c +++ b/drivers/mmc/host/mmc_spi.c @@ -819,6 +819,10 @@ mmc_spi_readblock(struct mmc_spi_host *host, struct spi_transfer *t, }
status = spi_sync_locked(spi, &host->m); + if (status < 0) { + dev_dbg(&spi->dev, "read error %d\n", status); + return status; + }
if (host->dma_dev) { dma_sync_single_for_cpu(host->dma_dev,
[ Upstream commit a46e42712596b51874f04c73f1cdf1017f88df52 ]
Software writing to the Transfer Type configuration register (system clock domain) can cause a setup/hold violation in the CRC flops (card clock domain), which can cause write accesses to be sent with corrupt CRC values. This issue occurs only for write preceded by read. this erratum is to fix this issue.
Signed-off-by: Yinbo Zhu yinbo.zhu@nxp.com Acked-by: Adrian Hunter adrian.hunter@intel.com Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mmc/host/sdhci-of-esdhc.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c index a51d636c23121..4db2769ea20c1 100644 --- a/drivers/mmc/host/sdhci-of-esdhc.c +++ b/drivers/mmc/host/sdhci-of-esdhc.c @@ -636,6 +636,9 @@ static int sdhci_esdhc_probe(struct platform_device *pdev) if (esdhc->vendor_ver > VENDOR_V_22) host->quirks &= ~SDHCI_QUIRK_NO_BUSY_IRQ;
+ if (of_find_compatible_node(NULL, NULL, "fsl,p2020-esdhc")) + host->quirks2 |= SDHCI_QUIRK_RESET_AFTER_REQUEST; + if (of_device_is_compatible(np, "fsl,p5040-esdhc") || of_device_is_compatible(np, "fsl,p5020-esdhc") || of_device_is_compatible(np, "fsl,p4080-esdhc") ||
[ Upstream commit 05cb6b2a66fa7837211a060878e91be5eb10cb07 ]
eSDHC-A001: The data timeout counter (SYSCTL[DTOCV]) is not reliable for DTOCV values 0x4(2^17 SD clock), 0x8(2^21 SD clock), and 0xC(2^25 SD clock). The data timeout counter can count from 2^13–2^27, but for values 2^17, 2^21, and 2^25, the timeout counter counts for only 2^13 SD clocks. A-008358: The data timeout counter value loaded into the timeout counter is less than expected and can result into early timeout error in case of eSDHC data transactions. The table below shows the expected vs actual timeout period for different values of SYSCTL[DTOCV]: these two erratum has the same quirk to control it, and set SDHCI_QUIRK_RESET_AFTER_REQUEST to fix above issue.
Signed-off-by: Yinbo Zhu yinbo.zhu@nxp.com Acked-by: Adrian Hunter adrian.hunter@intel.com Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mmc/host/sdhci-of-esdhc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c index 4db2769ea20c1..6f11cd95bb5fb 100644 --- a/drivers/mmc/host/sdhci-of-esdhc.c +++ b/drivers/mmc/host/sdhci-of-esdhc.c @@ -636,8 +636,10 @@ static int sdhci_esdhc_probe(struct platform_device *pdev) if (esdhc->vendor_ver > VENDOR_V_22) host->quirks &= ~SDHCI_QUIRK_NO_BUSY_IRQ;
- if (of_find_compatible_node(NULL, NULL, "fsl,p2020-esdhc")) + if (of_find_compatible_node(NULL, NULL, "fsl,p2020-esdhc")) { host->quirks2 |= SDHCI_QUIRK_RESET_AFTER_REQUEST; + host->quirks2 |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; + }
if (of_device_is_compatible(np, "fsl,p5040-esdhc") || of_device_is_compatible(np, "fsl,p5020-esdhc") ||
[ Upstream commit dc351d4c5f4fe4d0f274d6d660227be0c3a03317 ]
The dev->power.direct_complete flag may become set in device_prepare() in case the device don't have any PM callbacks (dev->power.no_pm_callbacks is set). This leads to a broken behaviour, when there is child having wakeup enabled and relies on its parent to be used in the wakeup path.
More precisely, when the direct complete path becomes selected for the child in __device_suspend(), the propagation of the dev->power.wakeup_path becomes skipped as well.
Let's address this problem, by checking if the device is a part the wakeup path or has wakeup enabled, then prevent the direct complete path from being used.
Reported-by: Loic Pallardy loic.pallardy@st.com Signed-off-by: Ulf Hansson ulf.hansson@linaro.org [ rjw: Comment cleanup ] Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/base/power/main.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 98517216879d5..a2714890fe431 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -1383,6 +1383,10 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) if (dev->power.syscore) goto Complete;
+ /* Avoid direct_complete to let wakeup_path propagate. */ + if (device_may_wakeup(dev) || dev->power.wakeup_path) + dev->power.direct_complete = false; + if (dev->power.direct_complete) { if (pm_runtime_status_suspended(dev)) { pm_runtime_disable(dev);
[ Upstream commit 00053de52231117ddc154042549f2256183ffb86 ]
Microphone detection provides the button detection features on the Arizona CODECs as such it will be running if the jack is currently inserted. If the driver is unbound whilst the jack is still inserted this will cause warnings from the regulator framework as the MICVDD regulator is put but was never disabled.
Correct this by disabling microphone detection on driver removal and if the microphone detection was running disable the regulator and put the runtime reference that was currently held.
Signed-off-by: Charles Keepax ckeepax@opensource.cirrus.com Signed-off-by: Chanwoo Choi cw00.choi@samsung.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/extcon/extcon-arizona.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c index 56e6c4c7c60d2..4c0b6df8b5ddb 100644 --- a/drivers/extcon/extcon-arizona.c +++ b/drivers/extcon/extcon-arizona.c @@ -1684,6 +1684,16 @@ static int arizona_extcon_remove(struct platform_device *pdev) struct arizona_extcon_info *info = platform_get_drvdata(pdev); struct arizona *arizona = info->arizona; int jack_irq_rise, jack_irq_fall; + bool change; + + regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1, + ARIZONA_MICD_ENA, 0, + &change); + + if (change) { + regulator_disable(info->micvdd); + pm_runtime_put(info->dev); + }
gpiod_put(info->micd_pol_gpio);
[ Upstream commit e91012ee855ad9f5ef2ab106a3de51db93fe4d0c ]
clang points out that the declaration of cio_irb does not match the definition exactly, it is missing the alignment attribute:
../drivers/s390/cio/cio.c:50:1: warning: section does not match previous declaration [-Wsection] DEFINE_PER_CPU_ALIGNED(struct irb, cio_irb); ^ ../include/linux/percpu-defs.h:150:2: note: expanded from macro 'DEFINE_PER_CPU_ALIGNED' DEFINE_PER_CPU_SECTION(type, name, PER_CPU_ALIGNED_SECTION) \ ^ ../include/linux/percpu-defs.h:93:9: note: expanded from macro 'DEFINE_PER_CPU_SECTION' extern __PCPU_ATTRS(sec) __typeof__(type) name; \ ^ ../include/linux/percpu-defs.h:49:26: note: expanded from macro '__PCPU_ATTRS' __percpu __attribute__((section(PER_CPU_BASE_SECTION sec))) \ ^ ../drivers/s390/cio/cio.h:118:1: note: previous attribute is here DECLARE_PER_CPU(struct irb, cio_irb); ^ ../include/linux/percpu-defs.h:111:2: note: expanded from macro 'DECLARE_PER_CPU' DECLARE_PER_CPU_SECTION(type, name, "") ^ ../include/linux/percpu-defs.h:87:9: note: expanded from macro 'DECLARE_PER_CPU_SECTION' extern __PCPU_ATTRS(sec) __typeof__(type) name ^ ../include/linux/percpu-defs.h:49:26: note: expanded from macro '__PCPU_ATTRS' __percpu __attribute__((section(PER_CPU_BASE_SECTION sec))) \ ^ Use DECLARE_PER_CPU_ALIGNED() here, to make the two match.
Signed-off-by: Arnd Bergmann arnd@arndb.de Reviewed-by: Nathan Chancellor natechancellor@gmail.com Signed-off-by: Sebastian Ott sebott@linux.ibm.com Signed-off-by: Martin Schwidefsky schwidefsky@de.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/s390/cio/cio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h index f0e57aefb5f29..d167652a6a23d 100644 --- a/drivers/s390/cio/cio.h +++ b/drivers/s390/cio/cio.h @@ -114,7 +114,7 @@ struct subchannel { struct schib_config config; } __attribute__ ((aligned(8)));
-DECLARE_PER_CPU(struct irb, cio_irb); +DECLARE_PER_CPU_ALIGNED(struct irb, cio_irb);
#define to_subchannel(n) container_of(n, struct subchannel, dev)
[ Upstream commit 233298032803f2802fe99892d0de4ab653bfece4 ]
The call to of_get_cpu_node returns a node pointer with refcount incremented thus it must be explicitly decremented after the last usage.
Detected by coccinelle with the following warnings: ./drivers/cpufreq/ppc_cbe_cpufreq.c:89:2-8: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 76, but without a corresponding object release within this function. ./drivers/cpufreq/ppc_cbe_cpufreq.c:89:2-8: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 76, but without a corresponding object release within this function.
Signed-off-by: Wen Yang wen.yang99@zte.com.cn Cc: "Rafael J. Wysocki" rjw@rjwysocki.net Cc: Viresh Kumar viresh.kumar@linaro.org Cc: linux-pm@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Viresh Kumar viresh.kumar@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cpufreq/ppc_cbe_cpufreq.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/cpufreq/ppc_cbe_cpufreq.c b/drivers/cpufreq/ppc_cbe_cpufreq.c index 5a4c5a639f618..2eaeebcc93afe 100644 --- a/drivers/cpufreq/ppc_cbe_cpufreq.c +++ b/drivers/cpufreq/ppc_cbe_cpufreq.c @@ -86,6 +86,7 @@ static int cbe_cpufreq_cpu_init(struct cpufreq_policy *policy) if (!cbe_get_cpu_pmd_regs(policy->cpu) || !cbe_get_cpu_mic_tm_regs(policy->cpu)) { pr_info("invalid CBE regs pointers for cpufreq\n"); + of_node_put(cpu); return -EINVAL; }
[ Upstream commit a9acc26b75f652f697e02a9febe2ab0da648a571 ]
The call to of_get_cpu_node returns a node pointer with refcount incremented thus it must be explicitly decremented after the last usage.
Detected by coccinelle with the following warnings: ./drivers/cpufreq/pasemi-cpufreq.c:212:1-7: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 147, but without a corresponding object release within this function. ./drivers/cpufreq/pasemi-cpufreq.c:220:1-7: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 147, but without a corresponding object release within this function.
Signed-off-by: Wen Yang wen.yang99@zte.com.cn Cc: "Rafael J. Wysocki" rjw@rjwysocki.net Cc: Viresh Kumar viresh.kumar@linaro.org Cc: linuxppc-dev@lists.ozlabs.org Cc: linux-pm@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Viresh Kumar viresh.kumar@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cpufreq/pasemi-cpufreq.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/cpufreq/pasemi-cpufreq.c b/drivers/cpufreq/pasemi-cpufreq.c index 35dd4d7ffee08..58c933f483004 100644 --- a/drivers/cpufreq/pasemi-cpufreq.c +++ b/drivers/cpufreq/pasemi-cpufreq.c @@ -146,6 +146,7 @@ static int pas_cpufreq_cpu_init(struct cpufreq_policy *policy)
cpu = of_get_cpu_node(policy->cpu, NULL);
+ of_node_put(cpu); if (!cpu) goto out;
[ Upstream commit 8d10dc28a9ea6e8c02e825dab28699f3c72b02d9 ]
The call to of_find_node_by_name returns a node pointer with refcount incremented thus it must be explicitly decremented after the last usage.
Detected by coccinelle with the following warnings: ./drivers/cpufreq/pmac32-cpufreq.c:557:2-8: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 552, but without a corresponding object release within this function. ./drivers/cpufreq/pmac32-cpufreq.c:569:1-7: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 552, but without a corresponding object release within this function. ./drivers/cpufreq/pmac32-cpufreq.c:598:1-7: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 587, but without a corresponding object release within this function.
Signed-off-by: Wen Yang wen.yang99@zte.com.cn Cc: "Rafael J. Wysocki" rjw@rjwysocki.net Cc: Viresh Kumar viresh.kumar@linaro.org Cc: Benjamin Herrenschmidt benh@kernel.crashing.org Cc: Paul Mackerras paulus@samba.org Cc: Michael Ellerman mpe@ellerman.id.au Cc: linux-pm@vger.kernel.org Cc: linuxppc-dev@lists.ozlabs.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Viresh Kumar viresh.kumar@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cpufreq/pmac32-cpufreq.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/cpufreq/pmac32-cpufreq.c b/drivers/cpufreq/pmac32-cpufreq.c index ff44016ea0312..641f8021855a7 100644 --- a/drivers/cpufreq/pmac32-cpufreq.c +++ b/drivers/cpufreq/pmac32-cpufreq.c @@ -551,6 +551,7 @@ static int pmac_cpufreq_init_7447A(struct device_node *cpunode) volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select"); if (volt_gpio_np) voltage_gpio = read_gpio(volt_gpio_np); + of_node_put(volt_gpio_np); if (!voltage_gpio){ pr_err("missing cpu-vcore-select gpio\n"); return 1; @@ -587,6 +588,7 @@ static int pmac_cpufreq_init_750FX(struct device_node *cpunode) if (volt_gpio_np) voltage_gpio = read_gpio(volt_gpio_np);
+ of_node_put(volt_gpio_np); pvr = mfspr(SPRN_PVR); has_cpu_l2lve = !((pvr & 0xf00) == 0x100);
[ Upstream commit 7c21383f3429dd70da39c0c7f1efa12377a47ab6 ]
The LLVM linker (ld.lld) defaults to removing local relocations, which causes KASLR boot failures. ld.bfd and ld.gold already handle this correctly. This adds the explicit instruction "--discard-none" during the link phase. There is no change in output for ld.bfd and ld.gold, but ld.lld now produces an image with all the needed relocations.
Signed-off-by: Kees Cook keescook@chromium.org Signed-off-by: Borislav Petkov bp@suse.de Cc: "H. Peter Anvin" hpa@zytor.com Cc: Ingo Molnar mingo@redhat.com Cc: Nick Desaulniers ndesaulniers@google.com Cc: Thomas Gleixner tglx@linutronix.de Cc: clang-built-linux@googlegroups.com Cc: x86-ml x86@kernel.org Link: https://lkml.kernel.org/r/20190404214027.GA7324@beast Link: https://github.com/ClangBuiltLinux/linux/issues/404 Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/x86/Makefile b/arch/x86/Makefile index b5226a009973f..2996a1d0a410a 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -47,7 +47,7 @@ export REALMODE_CFLAGS export BITS
ifdef CONFIG_X86_NEED_RELOCS - LDFLAGS_vmlinux := --emit-relocs + LDFLAGS_vmlinux := --emit-relocs --discard-none endif
#
[ Upstream commit df1d80aee963480c5c2938c64ec0ac3e4a0df2e0 ]
For devices from the SigmaDelta family we need to keep CS low when doing a conversion, since the device will use the MISO line as a interrupt to indicate that the conversion is complete.
This is why the driver locks the SPI bus and when the SPI bus is locked keeps as long as a conversion is going on. The current implementation gets one small detail wrong though. CS is only de-asserted after the SPI bus is unlocked. This means it is possible for a different SPI device on the same bus to send a message which would be wrongfully be addressed to the SigmaDelta device as well. Make sure that the last SPI transfer that is done while holding the SPI bus lock de-asserts the CS signal.
Signed-off-by: Lars-Peter Clausen lars@metafoo.de Signed-off-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/iio/adc/ad_sigma_delta.c | 16 +++++++++++----- include/linux/iio/adc/ad_sigma_delta.h | 1 + 2 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/drivers/iio/adc/ad_sigma_delta.c b/drivers/iio/adc/ad_sigma_delta.c index a1d072ecb7171..30f200ad6b978 100644 --- a/drivers/iio/adc/ad_sigma_delta.c +++ b/drivers/iio/adc/ad_sigma_delta.c @@ -62,7 +62,7 @@ int ad_sd_write_reg(struct ad_sigma_delta *sigma_delta, unsigned int reg, struct spi_transfer t = { .tx_buf = data, .len = size + 1, - .cs_change = sigma_delta->bus_locked, + .cs_change = sigma_delta->keep_cs_asserted, }; struct spi_message m; int ret; @@ -217,6 +217,7 @@ static int ad_sd_calibrate(struct ad_sigma_delta *sigma_delta,
spi_bus_lock(sigma_delta->spi->master); sigma_delta->bus_locked = true; + sigma_delta->keep_cs_asserted = true; reinit_completion(&sigma_delta->completion);
ret = ad_sigma_delta_set_mode(sigma_delta, mode); @@ -234,9 +235,10 @@ static int ad_sd_calibrate(struct ad_sigma_delta *sigma_delta, ret = 0; } out: + sigma_delta->keep_cs_asserted = false; + ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE); sigma_delta->bus_locked = false; spi_bus_unlock(sigma_delta->spi->master); - ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE);
return ret; } @@ -288,6 +290,7 @@ int ad_sigma_delta_single_conversion(struct iio_dev *indio_dev,
spi_bus_lock(sigma_delta->spi->master); sigma_delta->bus_locked = true; + sigma_delta->keep_cs_asserted = true; reinit_completion(&sigma_delta->completion);
ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_SINGLE); @@ -297,9 +300,6 @@ int ad_sigma_delta_single_conversion(struct iio_dev *indio_dev, ret = wait_for_completion_interruptible_timeout( &sigma_delta->completion, HZ);
- sigma_delta->bus_locked = false; - spi_bus_unlock(sigma_delta->spi->master); - if (ret == 0) ret = -EIO; if (ret < 0) @@ -315,7 +315,10 @@ int ad_sigma_delta_single_conversion(struct iio_dev *indio_dev, sigma_delta->irq_dis = true; }
+ sigma_delta->keep_cs_asserted = false; ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE); + sigma_delta->bus_locked = false; + spi_bus_unlock(sigma_delta->spi->master); mutex_unlock(&indio_dev->mlock);
if (ret) @@ -352,6 +355,8 @@ static int ad_sd_buffer_postenable(struct iio_dev *indio_dev)
spi_bus_lock(sigma_delta->spi->master); sigma_delta->bus_locked = true; + sigma_delta->keep_cs_asserted = true; + ret = ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_CONTINUOUS); if (ret) goto err_unlock; @@ -380,6 +385,7 @@ static int ad_sd_buffer_postdisable(struct iio_dev *indio_dev) sigma_delta->irq_dis = true; }
+ sigma_delta->keep_cs_asserted = false; ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE);
sigma_delta->bus_locked = false; diff --git a/include/linux/iio/adc/ad_sigma_delta.h b/include/linux/iio/adc/ad_sigma_delta.h index 6cc48ac55fd2a..40b14736c73de 100644 --- a/include/linux/iio/adc/ad_sigma_delta.h +++ b/include/linux/iio/adc/ad_sigma_delta.h @@ -66,6 +66,7 @@ struct ad_sigma_delta { bool irq_dis;
bool bus_locked; + bool keep_cs_asserted;
uint8_t comm;
[ Upstream commit 536cc27deade8f1ec3c1beefa60d5fbe0f6fcb28 ]
devm_regmap_init_i2c may fail and return NULL. The fix returns the error when it fails.
Signed-off-by: Kangjie Lu kjlu@umn.edu Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/magnetometer/hmc5843_i2c.c | 7 ++++++- drivers/iio/magnetometer/hmc5843_spi.c | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/magnetometer/hmc5843_i2c.c b/drivers/iio/magnetometer/hmc5843_i2c.c index 3de7f4426ac40..86abba5827a25 100644 --- a/drivers/iio/magnetometer/hmc5843_i2c.c +++ b/drivers/iio/magnetometer/hmc5843_i2c.c @@ -58,8 +58,13 @@ static const struct regmap_config hmc5843_i2c_regmap_config = { static int hmc5843_i2c_probe(struct i2c_client *cli, const struct i2c_device_id *id) { + struct regmap *regmap = devm_regmap_init_i2c(cli, + &hmc5843_i2c_regmap_config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + return hmc5843_common_probe(&cli->dev, - devm_regmap_init_i2c(cli, &hmc5843_i2c_regmap_config), + regmap, id->driver_data, id->name); }
diff --git a/drivers/iio/magnetometer/hmc5843_spi.c b/drivers/iio/magnetometer/hmc5843_spi.c index 535f03a70d630..79b2b707f90e7 100644 --- a/drivers/iio/magnetometer/hmc5843_spi.c +++ b/drivers/iio/magnetometer/hmc5843_spi.c @@ -58,6 +58,7 @@ static const struct regmap_config hmc5843_spi_regmap_config = { static int hmc5843_spi_probe(struct spi_device *spi) { int ret; + struct regmap *regmap; const struct spi_device_id *id = spi_get_device_id(spi);
spi->mode = SPI_MODE_3; @@ -67,8 +68,12 @@ static int hmc5843_spi_probe(struct spi_device *spi) if (ret) return ret;
+ regmap = devm_regmap_init_spi(spi, &hmc5843_spi_regmap_config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + return hmc5843_common_probe(&spi->dev, - devm_regmap_init_spi(spi, &hmc5843_spi_regmap_config), + regmap, id->driver_data, id->name); }
[ Upstream commit 6f9ca1d3eb74b81f811a87002de2d51640d135b1 ]
When building with -Wsometimes-uninitialized, Clang warns:
drivers/iio/common/ssp_sensors/ssp_iio.c:95:6: warning: variable 'calculated_time' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized]
While it isn't wrong, this will never be a problem because iio_push_to_buffers_with_timestamp only uses calculated_time on the same condition that it is assigned (when scan_timestamp is not zero). While iio_push_to_buffers_with_timestamp is marked as inline, Clang does inlining in the optimization stage, which happens after the semantic analysis phase (plus inline is merely a hint to the compiler).
Fix this by just zero initializing calculated_time.
Link: https://github.com/ClangBuiltLinux/linux/issues/394 Signed-off-by: Nathan Chancellor natechancellor@gmail.com Reviewed-by: Nick Desaulniers ndesaulniers@google.com Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/common/ssp_sensors/ssp_iio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/common/ssp_sensors/ssp_iio.c b/drivers/iio/common/ssp_sensors/ssp_iio.c index a3ae165f8d9f3..16180e6321bd4 100644 --- a/drivers/iio/common/ssp_sensors/ssp_iio.c +++ b/drivers/iio/common/ssp_sensors/ssp_iio.c @@ -80,7 +80,7 @@ int ssp_common_process_data(struct iio_dev *indio_dev, void *buf, unsigned int len, int64_t timestamp) { __le32 time; - int64_t calculated_time; + int64_t calculated_time = 0; struct ssp_sensor_data *spd = iio_priv(indio_dev);
if (indio_dev->scan_bytes == 0)
[ Upstream commit 765976285a8c8db3f0eb7f033829a899d0c2786e ]
In case alloc_workqueue fails, the fix reports the error and returns to avoid NULL pointer dereference.
Signed-off-by: Kangjie Lu kjlu@umn.edu Signed-off-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/realtek/rtlwifi/base.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/net/wireless/realtek/rtlwifi/base.c b/drivers/net/wireless/realtek/rtlwifi/base.c index 4ac928bf1f8e6..7de18ed10db8e 100644 --- a/drivers/net/wireless/realtek/rtlwifi/base.c +++ b/drivers/net/wireless/realtek/rtlwifi/base.c @@ -466,6 +466,11 @@ static void _rtl_init_deferred_work(struct ieee80211_hw *hw) /* <2> work queue */ rtlpriv->works.hw = hw; rtlpriv->works.rtl_wq = alloc_workqueue("%s", 0, 0, rtlpriv->cfg->name); + if (unlikely(!rtlpriv->works.rtl_wq)) { + pr_err("Failed to allocate work queue\n"); + return; + } + INIT_DELAYED_WORK(&rtlpriv->works.watchdog_wq, (void *)rtl_watchdog_wq_callback); INIT_DELAYED_WORK(&rtlpriv->works.ips_nic_off_wq,
[ Upstream commit 003b686ace820ce2d635a83f10f2d7f9c147dabc ]
'hostcmd' is alloced by kzalloc, should be freed before leaving from the error handling cases, otherwise it will cause mem leak.
Fixes: 3935ccc14d2c ("mwifiex: add cfg80211 testmode support") Signed-off-by: YueHaibing yuehaibing@huawei.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/marvell/mwifiex/cfg80211.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c index 4da3541471e61..46d0099fd6e82 100644 --- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c +++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c @@ -4018,16 +4018,20 @@ static int mwifiex_tm_cmd(struct wiphy *wiphy, struct wireless_dev *wdev,
if (mwifiex_send_cmd(priv, 0, 0, 0, hostcmd, true)) { dev_err(priv->adapter->dev, "Failed to process hostcmd\n"); + kfree(hostcmd); return -EFAULT; }
/* process hostcmd response*/ skb = cfg80211_testmode_alloc_reply_skb(wiphy, hostcmd->len); - if (!skb) + if (!skb) { + kfree(hostcmd); return -ENOMEM; + } err = nla_put(skb, MWIFIEX_TM_ATTR_DATA, hostcmd->len, hostcmd->cmd); if (err) { + kfree(hostcmd); kfree_skb(skb); return -EMSGSIZE; }
[ Upstream commit 46953f97224d56a12ccbe9c6acaa84ca0dab2780 ]
In case kmemdup fails, the fix sets conn_info->req_ie_len and conn_info->resp_ie_len to zero to avoid buffer overflows.
Signed-off-by: Kangjie Lu kjlu@umn.edu Acked-by: Arend van Spriel arend.vanspriel@broadcom.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index 530f521209728..8f8fe6f2af5b0 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -5374,6 +5374,8 @@ static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg, conn_info->req_ie = kmemdup(cfg->extra_buf, conn_info->req_ie_len, GFP_KERNEL); + if (!conn_info->req_ie) + conn_info->req_ie_len = 0; } else { conn_info->req_ie_len = 0; conn_info->req_ie = NULL; @@ -5390,6 +5392,8 @@ static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg, conn_info->resp_ie = kmemdup(cfg->extra_buf, conn_info->resp_ie_len, GFP_KERNEL); + if (!conn_info->resp_ie) + conn_info->resp_ie_len = 0; } else { conn_info->resp_ie_len = 0; conn_info->resp_ie = NULL;
[ Upstream commit d825db346270dbceef83b7b750dbc29f1d7dcc0e ]
Clang warns about what is clearly a case of passing an uninitalized variable into a static function:
drivers/net/wireless/broadcom/b43/phy_lp.c:1852:23: error: variable 'gains' is uninitialized when used here [-Werror,-Wuninitialized] lpphy_papd_cal(dev, gains, 0, 1, 30); ^~~~~ drivers/net/wireless/broadcom/b43/phy_lp.c:1838:2: note: variable 'gains' is declared here struct lpphy_tx_gains gains, oldgains; ^ 1 error generated.
However, this function is empty, and its arguments are never evaluated, so gcc in contrast does not warn here. Both compilers behave in a reasonable way as far as I can tell, so we should change the code to avoid the warning everywhere.
We could just eliminate the lpphy_papd_cal() function entirely, given that it has had the TODO comment in it for 10 years now and is rather unlikely to ever get done. I'm doing a simpler change here, and just pass the 'oldgains' variable in that has been initialized, based on the guess that this is what was originally meant.
Fixes: 2c0d6100da3e ("b43: LP-PHY: Begin implementing calibration & software RFKILL support") Signed-off-by: Arnd Bergmann arnd@arndb.de Acked-by: Larry Finger Larry.Finger@lwfinger.net Reviewed-by: Nathan Chancellor natechancellor@gmail.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/broadcom/b43/phy_lp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/broadcom/b43/phy_lp.c b/drivers/net/wireless/broadcom/b43/phy_lp.c index 6922cbb99a044..5a0699fb4b9ab 100644 --- a/drivers/net/wireless/broadcom/b43/phy_lp.c +++ b/drivers/net/wireless/broadcom/b43/phy_lp.c @@ -1834,7 +1834,7 @@ static void lpphy_papd_cal(struct b43_wldev *dev, struct lpphy_tx_gains gains, static void lpphy_papd_cal_txpwr(struct b43_wldev *dev) { struct b43_phy_lp *lpphy = dev->phy.lp; - struct lpphy_tx_gains gains, oldgains; + struct lpphy_tx_gains oldgains; int old_txpctl, old_afe_ovr, old_rf, old_bbmult;
lpphy_read_tx_pctl_mode_from_hardware(dev); @@ -1848,9 +1848,9 @@ static void lpphy_papd_cal_txpwr(struct b43_wldev *dev) lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_OFF);
if (dev->dev->chip_id == 0x4325 && dev->dev->chip_rev == 0) - lpphy_papd_cal(dev, gains, 0, 1, 30); + lpphy_papd_cal(dev, oldgains, 0, 1, 30); else - lpphy_papd_cal(dev, gains, 0, 1, 65); + lpphy_papd_cal(dev, oldgains, 0, 1, 65);
if (old_afe_ovr) lpphy_set_tx_gains(dev, oldgains);
[ Upstream commit a9fd0953fa4a62887306be28641b4b0809f3b2fd ]
Leaving dev_init_lock mutex locked in probe causes BUG and a WARNING when kernel is compiled with CONFIG_PROVE_LOCKING. Convert mutex to completion which silences those warnings and improves code readability.
Fix below errors when connecting the USB WiFi dongle:
brcmfmac: brcmf_fw_alloc_request: using brcm/brcmfmac43143 for chip BCM43143/2 BUG: workqueue leaked lock or atomic: kworker/0:2/0x00000000/434 last function: hub_event 1 lock held by kworker/0:2/434: #0: 18d5dcdf (&devinfo->dev_init_lock){+.+.}, at: brcmf_usb_probe+0x78/0x550 [brcmfmac] CPU: 0 PID: 434 Comm: kworker/0:2 Not tainted 4.19.23-00084-g454a789-dirty #123 Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree) Workqueue: usb_hub_wq hub_event [<8011237c>] (unwind_backtrace) from [<8010d74c>] (show_stack+0x10/0x14) [<8010d74c>] (show_stack) from [<809c4324>] (dump_stack+0xa8/0xd4) [<809c4324>] (dump_stack) from [<8014195c>] (process_one_work+0x710/0x808) [<8014195c>] (process_one_work) from [<80141a80>] (worker_thread+0x2c/0x564) [<80141a80>] (worker_thread) from [<80147bcc>] (kthread+0x13c/0x16c) [<80147bcc>] (kthread) from [<801010b4>] (ret_from_fork+0x14/0x20) Exception stack(0xed1d9fb0 to 0xed1d9ff8) 9fa0: 00000000 00000000 00000000 00000000 9fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 9fe0: 00000000 00000000 00000000 00000000 00000013 00000000
====================================================== WARNING: possible circular locking dependency detected 4.19.23-00084-g454a789-dirty #123 Not tainted ------------------------------------------------------ kworker/0:2/434 is trying to acquire lock: e29cf799 ((wq_completion)"events"){+.+.}, at: process_one_work+0x174/0x808
but task is already holding lock: 18d5dcdf (&devinfo->dev_init_lock){+.+.}, at: brcmf_usb_probe+0x78/0x550 [brcmfmac]
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #2 (&devinfo->dev_init_lock){+.+.}: mutex_lock_nested+0x1c/0x24 brcmf_usb_probe+0x78/0x550 [brcmfmac] usb_probe_interface+0xc0/0x1bc really_probe+0x228/0x2c0 __driver_attach+0xe4/0xe8 bus_for_each_dev+0x68/0xb4 bus_add_driver+0x19c/0x214 driver_register+0x78/0x110 usb_register_driver+0x84/0x148 process_one_work+0x228/0x808 worker_thread+0x2c/0x564 kthread+0x13c/0x16c ret_from_fork+0x14/0x20 (null)
-> #1 (brcmf_driver_work){+.+.}: worker_thread+0x2c/0x564 kthread+0x13c/0x16c ret_from_fork+0x14/0x20 (null)
-> #0 ((wq_completion)"events"){+.+.}: process_one_work+0x1b8/0x808 worker_thread+0x2c/0x564 kthread+0x13c/0x16c ret_from_fork+0x14/0x20 (null)
other info that might help us debug this:
Chain exists of: (wq_completion)"events" --> brcmf_driver_work --> &devinfo->dev_init_lock
Possible unsafe locking scenario:
CPU0 CPU1 ---- ---- lock(&devinfo->dev_init_lock); lock(brcmf_driver_work); lock(&devinfo->dev_init_lock); lock((wq_completion)"events");
*** DEADLOCK ***
1 lock held by kworker/0:2/434: #0: 18d5dcdf (&devinfo->dev_init_lock){+.+.}, at: brcmf_usb_probe+0x78/0x550 [brcmfmac]
stack backtrace: CPU: 0 PID: 434 Comm: kworker/0:2 Not tainted 4.19.23-00084-g454a789-dirty #123 Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree) Workqueue: events request_firmware_work_func [<8011237c>] (unwind_backtrace) from [<8010d74c>] (show_stack+0x10/0x14) [<8010d74c>] (show_stack) from [<809c4324>] (dump_stack+0xa8/0xd4) [<809c4324>] (dump_stack) from [<80172838>] (print_circular_bug+0x210/0x330) [<80172838>] (print_circular_bug) from [<80175940>] (__lock_acquire+0x160c/0x1a30) [<80175940>] (__lock_acquire) from [<8017671c>] (lock_acquire+0xe0/0x268) [<8017671c>] (lock_acquire) from [<80141404>] (process_one_work+0x1b8/0x808) [<80141404>] (process_one_work) from [<80141a80>] (worker_thread+0x2c/0x564) [<80141a80>] (worker_thread) from [<80147bcc>] (kthread+0x13c/0x16c) [<80147bcc>] (kthread) from [<801010b4>] (ret_from_fork+0x14/0x20) Exception stack(0xed1d9fb0 to 0xed1d9ff8) 9fa0: 00000000 00000000 00000000 00000000 9fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 9fe0: 00000000 00000000 00000000 00000000 00000013 00000000
Signed-off-by: Piotr Figiel p.figiel@camlintechnologies.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Sasha Levin sashal@kernel.org --- .../wireless/broadcom/brcm80211/brcmfmac/usb.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c index 053f3b59f21e0..bfdf6ef224437 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c @@ -157,7 +157,7 @@ struct brcmf_usbdev_info {
struct usb_device *usbdev; struct device *dev; - struct mutex dev_init_lock; + struct completion dev_init_done;
int ctl_in_pipe, ctl_out_pipe; struct urb *ctl_urb; /* URB for control endpoint */ @@ -1189,11 +1189,11 @@ static void brcmf_usb_probe_phase2(struct device *dev, int ret, if (ret) goto error;
- mutex_unlock(&devinfo->dev_init_lock); + complete(&devinfo->dev_init_done); return; error: brcmf_dbg(TRACE, "failed: dev=%s, err=%d\n", dev_name(dev), ret); - mutex_unlock(&devinfo->dev_init_lock); + complete(&devinfo->dev_init_done); device_release_driver(dev); }
@@ -1239,7 +1239,7 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo) if (ret) goto fail; /* we are done */ - mutex_unlock(&devinfo->dev_init_lock); + complete(&devinfo->dev_init_done); return 0; } bus->chip = bus_pub->devid; @@ -1300,11 +1300,10 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
devinfo->usbdev = usb; devinfo->dev = &usb->dev; - /* Take an init lock, to protect for disconnect while still loading. + /* Init completion, to protect for disconnect while still loading. * Necessary because of the asynchronous firmware load construction */ - mutex_init(&devinfo->dev_init_lock); - mutex_lock(&devinfo->dev_init_lock); + init_completion(&devinfo->dev_init_done);
usb_set_intfdata(intf, devinfo);
@@ -1382,7 +1381,7 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) return 0;
fail: - mutex_unlock(&devinfo->dev_init_lock); + complete(&devinfo->dev_init_done); kfree(devinfo); usb_set_intfdata(intf, NULL); return ret; @@ -1397,7 +1396,7 @@ brcmf_usb_disconnect(struct usb_interface *intf) devinfo = (struct brcmf_usbdev_info *)usb_get_intfdata(intf);
if (devinfo) { - mutex_lock(&devinfo->dev_init_lock); + wait_for_completion(&devinfo->dev_init_done); /* Make sure that devinfo still exists. Firmware probe routines * may have released the device and cleared the intfdata. */
[ Upstream commit db3b9e2e1d58080d0754bdf9293dabf8c6491b67 ]
It was observed that rarely during USB disconnect happening shortly after connect (before full initialization completes) usb_hub_wq would wait forever for the dev_init_lock to be unlocked. dev_init_lock would remain locked though because of infinite wait during usb_kill_urb:
[ 2730.656472] kworker/0:2 D 0 260 2 0x00000000 [ 2730.660700] Workqueue: events request_firmware_work_func [ 2730.664807] [<809dca20>] (__schedule) from [<809dd164>] (schedule+0x4c/0xac) [ 2730.670587] [<809dd164>] (schedule) from [<8069af44>] (usb_kill_urb+0xdc/0x114) [ 2730.676815] [<8069af44>] (usb_kill_urb) from [<7f258b50>] (brcmf_usb_free_q+0x34/0xa8 [brcmfmac]) [ 2730.684833] [<7f258b50>] (brcmf_usb_free_q [brcmfmac]) from [<7f2517d4>] (brcmf_detach+0xa0/0xb8 [brcmfmac]) [ 2730.693557] [<7f2517d4>] (brcmf_detach [brcmfmac]) from [<7f251a34>] (brcmf_attach+0xac/0x3d8 [brcmfmac]) [ 2730.702094] [<7f251a34>] (brcmf_attach [brcmfmac]) from [<7f2587ac>] (brcmf_usb_probe_phase2+0x468/0x4a0 [brcmfmac]) [ 2730.711601] [<7f2587ac>] (brcmf_usb_probe_phase2 [brcmfmac]) from [<7f252888>] (brcmf_fw_request_done+0x194/0x220 [brcmfmac]) [ 2730.721795] [<7f252888>] (brcmf_fw_request_done [brcmfmac]) from [<805748e4>] (request_firmware_work_func+0x4c/0x88) [ 2730.731125] [<805748e4>] (request_firmware_work_func) from [<80141474>] (process_one_work+0x228/0x808) [ 2730.739223] [<80141474>] (process_one_work) from [<80141a80>] (worker_thread+0x2c/0x564) [ 2730.746105] [<80141a80>] (worker_thread) from [<80147bcc>] (kthread+0x13c/0x16c) [ 2730.752227] [<80147bcc>] (kthread) from [<801010b4>] (ret_from_fork+0x14/0x20)
[ 2733.099695] kworker/0:3 D 0 1065 2 0x00000000 [ 2733.103926] Workqueue: usb_hub_wq hub_event [ 2733.106914] [<809dca20>] (__schedule) from [<809dd164>] (schedule+0x4c/0xac) [ 2733.112693] [<809dd164>] (schedule) from [<809e2a8c>] (schedule_timeout+0x214/0x3e4) [ 2733.119621] [<809e2a8c>] (schedule_timeout) from [<809dde2c>] (wait_for_common+0xc4/0x1c0) [ 2733.126810] [<809dde2c>] (wait_for_common) from [<7f258d00>] (brcmf_usb_disconnect+0x1c/0x4c [brcmfmac]) [ 2733.135206] [<7f258d00>] (brcmf_usb_disconnect [brcmfmac]) from [<8069e0c8>] (usb_unbind_interface+0x5c/0x1e4) [ 2733.143943] [<8069e0c8>] (usb_unbind_interface) from [<8056d3e8>] (device_release_driver_internal+0x164/0x1fc) [ 2733.152769] [<8056d3e8>] (device_release_driver_internal) from [<8056c078>] (bus_remove_device+0xd0/0xfc) [ 2733.161138] [<8056c078>] (bus_remove_device) from [<8056977c>] (device_del+0x11c/0x310) [ 2733.167939] [<8056977c>] (device_del) from [<8069cba8>] (usb_disable_device+0xa0/0x1cc) [ 2733.174743] [<8069cba8>] (usb_disable_device) from [<8069507c>] (usb_disconnect+0x74/0x1dc) [ 2733.181823] [<8069507c>] (usb_disconnect) from [<80695e88>] (hub_event+0x478/0xf88) [ 2733.188278] [<80695e88>] (hub_event) from [<80141474>] (process_one_work+0x228/0x808) [ 2733.194905] [<80141474>] (process_one_work) from [<80141a80>] (worker_thread+0x2c/0x564) [ 2733.201724] [<80141a80>] (worker_thread) from [<80147bcc>] (kthread+0x13c/0x16c) [ 2733.207913] [<80147bcc>] (kthread) from [<801010b4>] (ret_from_fork+0x14/0x20)
It was traced down to a case where usb_kill_urb would be called on an URB structure containing more or less random data, including large number in its use_count. During the debugging it appeared that in brcmf_usb_free_q() the traversal over URBs' lists is not synchronized with operations on those lists in brcmf_usb_rx_complete() leading to handling brcmf_usbdev_info structure (holding lists' head) as lists' element and in result causing above problem.
Fix it by walking through all URBs during brcmf_cancel_all_urbs using the arrays of requests instead of linked lists.
Signed-off-by: Piotr Figiel p.figiel@camlintechnologies.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c index bfdf6ef224437..acf513fd9e6d5 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c @@ -681,12 +681,18 @@ static int brcmf_usb_up(struct device *dev)
static void brcmf_cancel_all_urbs(struct brcmf_usbdev_info *devinfo) { + int i; + if (devinfo->ctl_urb) usb_kill_urb(devinfo->ctl_urb); if (devinfo->bulk_urb) usb_kill_urb(devinfo->bulk_urb); - brcmf_usb_free_q(&devinfo->tx_postq, true); - brcmf_usb_free_q(&devinfo->rx_postq, true); + if (devinfo->tx_reqs) + for (i = 0; i < devinfo->bus_pub.ntxq; i++) + usb_kill_urb(devinfo->tx_reqs[i].urb); + if (devinfo->rx_reqs) + for (i = 0; i < devinfo->bus_pub.nrxq; i++) + usb_kill_urb(devinfo->rx_reqs[i].urb); }
static void brcmf_usb_down(struct device *dev)
[ Upstream commit 24d413a31afaee9bbbf79226052c386b01780ce2 ]
Fix a race which leads to an Oops with NULL pointer dereference. The dereference is in brcmf_config_dongle() when cfg_to_ndev() attempts to get net_device structure of interface with index 0 via if2bss mapping. This shouldn't fail because of check for bus being ready in brcmf_netdev_open(), but it's not synchronised with USB disconnect and there is a race: after the check the bus can be marked down and the mapping for interface 0 may be gone.
Solve this by modifying disconnect handling so that the removal of mapping of ifidx to brcmf_if structure happens after netdev removal (which is synchronous with brcmf_netdev_open() thanks to rtln being locked in devinet_ioctl()). This assures brcmf_netdev_open() returns before the mapping is removed during disconnect.
Unable to handle kernel NULL pointer dereference at virtual address 00000008 pgd = bcae2612 [00000008] *pgd=8be73831 Internal error: Oops: 17 [#1] PREEMPT SMP ARM Modules linked in: brcmfmac brcmutil nf_log_ipv4 nf_log_common xt_LOG xt_limit iptable_mangle xt_connmark xt_tcpudp xt_conntrack nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 iptable_filter ip_tables x_tables usb_f_mass_storage usb_f_rndis u_ether usb_serial_simple usbserial cdc_acm smsc95xx usbnet ci_hdrc_imx ci_hdrc usbmisc_imx ulpi 8250_exar 8250_pci 8250 8250_base libcomposite configfs udc_core [last unloaded: brcmutil] CPU: 2 PID: 24478 Comm: ifconfig Not tainted 4.19.23-00078-ga62866d-dirty #115 Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree) PC is at brcmf_cfg80211_up+0x94/0x29c [brcmfmac] LR is at brcmf_cfg80211_up+0x8c/0x29c [brcmfmac] pc : [<7f26a91c>] lr : [<7f26a914>] psr: a0070013 sp : eca99d28 ip : 00000000 fp : ee9c6c00 r10: 00000036 r9 : 00000000 r8 : ece4002c r7 : edb5b800 r6 : 00000000 r5 : 80f08448 r4 : edb5b968 r3 : ffffffff r2 : 00000000 r1 : 00000002 r0 : 00000000 Flags: NzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none Control: 10c5387d Table: 7ca0c04a DAC: 00000051 Process ifconfig (pid: 24478, stack limit = 0xd9e85a0e) Stack: (0xeca99d28 to 0xeca9a000) 9d20: 00000000 80f873b0 0000000d 80f08448 eca99d68 50d45f32 9d40: 7f27de94 ece40000 80f08448 80f08448 7f27de94 ece4002c 00000000 00000036 9d60: ee9c6c00 7f27262c 00001002 50d45f32 ece40000 00000000 80f08448 80772008 9d80: 00000001 00001043 00001002 ece40000 00000000 50d45f32 ece40000 00000001 9da0: 80f08448 00001043 00001002 807723d0 00000000 50d45f32 80f08448 eca99e58 9dc0: 80f87113 50d45f32 80f08448 ece40000 ece40138 00001002 80f08448 00000000 9de0: 00000000 80772434 edbd5380 eca99e58 edbd5380 80f08448 ee9c6c0c 80805f70 9e00: 00000000 ede08e00 00008914 ece40000 00000014 ee9c6c0c 600c0013 00001043 9e20: 0208a8c0 ffffffff 00000000 50d45f32 eca98000 80f08448 7ee9fc38 00008914 9e40: 80f68e40 00000051 eca98000 00000036 00000003 80808b9c 6e616c77 00000030 9e60: 00000000 00000000 00001043 0208a8c0 ffffffff 00000000 80f08448 00000000 9e80: 00000000 816d8b20 600c0013 00000001 ede09320 801763d4 00000000 50d45f32 9ea0: eca98000 80f08448 7ee9fc38 50d45f32 00008914 80f08448 7ee9fc38 80f68e40 9ec0: ed531540 8074721c 00000800 00000001 00000000 6e616c77 00000030 00000000 9ee0: 00000000 00001002 0208a8c0 ffffffff 00000000 50d45f32 80f08448 7ee9fc38 9f00: ed531560 ec8fc900 80285a6c 80285138 edb910c0 00000000 ecd91008 ede08e00 9f20: 80f08448 00000000 00000000 816d8b20 600c0013 00000001 ede09320 801763d4 9f40: 00000000 50d45f32 00021000 edb91118 edb910c0 80f08448 01b29000 edb91118 9f60: eca99f7c 50d45f32 00021000 ec8fc900 00000003 ec8fc900 00008914 7ee9fc38 9f80: eca98000 00000036 00000003 80285a6c 00086364 7ee9fe1c 000000c3 00000036 9fa0: 801011c4 80101000 00086364 7ee9fe1c 00000003 00008914 7ee9fc38 00086364 9fc0: 00086364 7ee9fe1c 000000c3 00000036 0008630c 7ee9fe1c 7ee9fc38 00000003 9fe0: 000a42b8 7ee9fbd4 00019914 76e09acc 600c0010 00000003 00000000 00000000 [<7f26a91c>] (brcmf_cfg80211_up [brcmfmac]) from [<7f27262c>] (brcmf_netdev_open+0x74/0xe8 [brcmfmac]) [<7f27262c>] (brcmf_netdev_open [brcmfmac]) from [<80772008>] (__dev_open+0xcc/0x150) [<80772008>] (__dev_open) from [<807723d0>] (__dev_change_flags+0x168/0x1b4) [<807723d0>] (__dev_change_flags) from [<80772434>] (dev_change_flags+0x18/0x48) [<80772434>] (dev_change_flags) from [<80805f70>] (devinet_ioctl+0x67c/0x79c) [<80805f70>] (devinet_ioctl) from [<80808b9c>] (inet_ioctl+0x210/0x3d4) [<80808b9c>] (inet_ioctl) from [<8074721c>] (sock_ioctl+0x350/0x524) [<8074721c>] (sock_ioctl) from [<80285138>] (do_vfs_ioctl+0xb0/0x9b0) [<80285138>] (do_vfs_ioctl) from [<80285a6c>] (ksys_ioctl+0x34/0x5c) [<80285a6c>] (ksys_ioctl) from [<80101000>] (ret_fast_syscall+0x0/0x28) Exception stack(0xeca99fa8 to 0xeca99ff0) 9fa0: 00086364 7ee9fe1c 00000003 00008914 7ee9fc38 00086364 9fc0: 00086364 7ee9fe1c 000000c3 00000036 0008630c 7ee9fe1c 7ee9fc38 00000003 9fe0: 000a42b8 7ee9fbd4 00019914 76e09acc Code: e5970328 eb002021 e1a02006 e3a01002 (e5909008) ---[ end trace 5cbac2333f3ac5df ]---
Signed-off-by: Piotr Figiel p.figiel@camlintechnologies.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Sasha Levin sashal@kernel.org --- .../net/wireless/broadcom/brcm80211/brcmfmac/core.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c index f877301c9454b..ecfe056d76437 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c @@ -685,17 +685,17 @@ static void brcmf_del_if(struct brcmf_pub *drvr, s32 bsscfgidx, bool rtnl_locked) { struct brcmf_if *ifp; + int ifidx;
ifp = drvr->iflist[bsscfgidx]; - drvr->iflist[bsscfgidx] = NULL; if (!ifp) { brcmf_err("Null interface, bsscfgidx=%d\n", bsscfgidx); return; } brcmf_dbg(TRACE, "Enter, bsscfgidx=%d, ifidx=%d\n", bsscfgidx, ifp->ifidx); - if (drvr->if2bss[ifp->ifidx] == bsscfgidx) - drvr->if2bss[ifp->ifidx] = BRCMF_BSSIDX_INVALID; + ifidx = ifp->ifidx; + if (ifp->ndev) { if (bsscfgidx == 0) { if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) { @@ -723,6 +723,10 @@ static void brcmf_del_if(struct brcmf_pub *drvr, s32 bsscfgidx, brcmf_p2p_ifp_removed(ifp, rtnl_locked); kfree(ifp); } + + drvr->iflist[bsscfgidx] = NULL; + if (drvr->if2bss[ifidx] == bsscfgidx) + drvr->if2bss[ifidx] = BRCMF_BSSIDX_INVALID; }
void brcmf_remove_interface(struct brcmf_if *ifp, bool rtnl_locked)
[ Upstream commit 0487fff76632ec023d394a05b82e87a971db8c03 ]
Currently if a regulator has "<name>-fixed-regulator" property in device tree, it will skip current limit initialization. This lead to a zero "max_uA" value in struct ufs_vreg.
However, "regulator_set_load" operation shall be required on regulators which have valid current limits, otherwise a zero "max_uA" set by "regulator_set_load" may cause unexpected behavior when this regulator is enabled or set as high power mode.
Similarly, in device's icc_level configuration flow, the target icc_level shall be updated if regulator also has valid current limit, otherwise a wrong icc_level will be calculated by zero "max_uA" and thus causes unexpected results after it is written to device.
Signed-off-by: Stanley Chu stanley.chu@mediatek.com Reviewed-by: Avri Altman avri.altman@wdc.com Acked-by: Alim Akhtar alim.akhtar@samsung.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/ufs/ufshcd.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 0b858414c558b..8869c666d458c 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -4875,19 +4875,19 @@ static u32 ufshcd_find_max_sup_active_icc_level(struct ufs_hba *hba, goto out; }
- if (hba->vreg_info.vcc) + if (hba->vreg_info.vcc && hba->vreg_info.vcc->max_uA) icc_level = ufshcd_get_max_icc_level( hba->vreg_info.vcc->max_uA, POWER_DESC_MAX_ACTV_ICC_LVLS - 1, &desc_buf[PWR_DESC_ACTIVE_LVLS_VCC_0]);
- if (hba->vreg_info.vccq) + if (hba->vreg_info.vccq && hba->vreg_info.vccq->max_uA) icc_level = ufshcd_get_max_icc_level( hba->vreg_info.vccq->max_uA, icc_level, &desc_buf[PWR_DESC_ACTIVE_LVLS_VCCQ_0]);
- if (hba->vreg_info.vccq2) + if (hba->vreg_info.vccq2 && hba->vreg_info.vccq2->max_uA) icc_level = ufshcd_get_max_icc_level( hba->vreg_info.vccq2->max_uA, icc_level, @@ -5449,6 +5449,15 @@ static int ufshcd_config_vreg_load(struct device *dev, struct ufs_vreg *vreg, if (!vreg) return 0;
+ /* + * "set_load" operation shall be required on those regulators + * which specifically configured current limitation. Otherwise + * zero max_uA may cause unexpected behavior when regulator is + * enabled or set as high power mode. + */ + if (!vreg->max_uA) + return 0; + ret = regulator_set_load(vreg->reg, ua); if (ret < 0) { dev_err(dev, "%s: %s set load (ua=%d) failed, err=%d\n",
[ Upstream commit 3b141e8cfd54ba3e5c610717295b2a02aab26a05 ]
For regulators used by UFS, vcc, vccq and vccq2 will have voltage range initialized by ufshcd_populate_vreg(), however other regulators may have undefined voltage range if dt-bindings have no such definition.
In above undefined case, both "min_uV" and "max_uV" fields in ufs_vreg struct will be zero values and these values will be configured on regulators in different power modes.
Currently this may have no harm if both "min_uV" and "max_uV" always keep "zero values" because regulator_set_voltage() will always bypass such invalid values and return "good" results.
However improper values shall be fixed to avoid potential bugs. Simply bypass voltage configuration if voltage range is not defined.
Signed-off-by: Stanley Chu stanley.chu@mediatek.com Reviewed-by: Avri Altman avri.altman@wdc.com Acked-by: Alim Akhtar alim.akhtar@samsung.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/ufs/ufshcd.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 8869c666d458c..0fe4f8e8c8c91 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -5504,12 +5504,15 @@ static int ufshcd_config_vreg(struct device *dev, name = vreg->name;
if (regulator_count_voltages(reg) > 0) { - min_uV = on ? vreg->min_uV : 0; - ret = regulator_set_voltage(reg, min_uV, vreg->max_uV); - if (ret) { - dev_err(dev, "%s: %s set voltage failed, err=%d\n", + if (vreg->min_uV && vreg->max_uV) { + min_uV = on ? vreg->min_uV : 0; + ret = regulator_set_voltage(reg, min_uV, vreg->max_uV); + if (ret) { + dev_err(dev, + "%s: %s set voltage failed, err=%d\n", __func__, name, ret); - goto out; + goto out; + } }
uA_load = on ? vreg->max_uA : 0;
[ Upstream commit 92606ec9285fb84cd9b5943df23f07d741384bfc ]
The call to of_get_next_child returns a node pointer with refcount incremented thus it must be explicitly decremented after the last usage.
Detected by coccinelle with the following warnings: ./arch/arm64/kernel/cpu_ops.c:102:1-7: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 69, but without a corresponding object release within this function.
Signed-off-by: Wen Yang wen.yang99@zte.com.cn Reviewed-by: Florian Fainelli f.fainelli@gmail.com Cc: Catalin Marinas catalin.marinas@arm.com Cc: Will Deacon will.deacon@arm.com Cc: linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Will Deacon will.deacon@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/kernel/cpu_ops.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm64/kernel/cpu_ops.c b/arch/arm64/kernel/cpu_ops.c index e137ceaf5016b..82b465207ed0a 100644 --- a/arch/arm64/kernel/cpu_ops.c +++ b/arch/arm64/kernel/cpu_ops.c @@ -85,6 +85,7 @@ static const char *__init cpu_read_enable_method(int cpu) pr_err("%s: missing enable-method property\n", dn->full_name); } + of_node_put(dn); } else { enable_method = acpi_get_enable_method(cpu); if (!enable_method) {
[ Upstream commit 88e4718275c1bddca6f61f300688b4553dc8584b ]
Occasionally GCC is less agressive with inlining and the following is observed:
arch/x86/kernel/signal.o: warning: objtool: restore_sigcontext()+0x3cc: call to force_valid_ss.isra.5() with UACCESS enabled arch/x86/kernel/signal.o: warning: objtool: do_signal()+0x384: call to frame_uc_flags.isra.0() with UACCESS enabled
Cure this by moving this code out of the AC=1 region, since it really isn't needed for the user access.
Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Reviewed-by: Andy Lutomirski luto@kernel.org Cc: Borislav Petkov bp@alien8.de Cc: Josh Poimboeuf jpoimboe@redhat.com Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Peter Zijlstra peterz@infradead.org Cc: Thomas Gleixner tglx@linutronix.de Signed-off-by: Ingo Molnar mingo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/kernel/signal.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-)
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c index b1a5d252d482a..ca010dfb9682b 100644 --- a/arch/x86/kernel/signal.c +++ b/arch/x86/kernel/signal.c @@ -129,16 +129,6 @@ static int restore_sigcontext(struct pt_regs *regs, COPY_SEG_CPL3(cs); COPY_SEG_CPL3(ss);
-#ifdef CONFIG_X86_64 - /* - * Fix up SS if needed for the benefit of old DOSEMU and - * CRIU. - */ - if (unlikely(!(uc_flags & UC_STRICT_RESTORE_SS) && - user_64bit_mode(regs))) - force_valid_ss(regs); -#endif - get_user_ex(tmpflags, &sc->flags); regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS); regs->orig_ax = -1; /* disable syscall checks */ @@ -147,6 +137,15 @@ static int restore_sigcontext(struct pt_regs *regs, buf = (void __user *)buf_val; } get_user_catch(err);
+#ifdef CONFIG_X86_64 + /* + * Fix up SS if needed for the benefit of old DOSEMU and + * CRIU. + */ + if (unlikely(!(uc_flags & UC_STRICT_RESTORE_SS) && user_64bit_mode(regs))) + force_valid_ss(regs); +#endif + err |= fpu__restore_sig(buf, IS_ENABLED(CONFIG_X86_32));
force_iret(); @@ -458,6 +457,7 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig, { struct rt_sigframe __user *frame; void __user *fp = NULL; + unsigned long uc_flags; int err = 0;
frame = get_sigframe(&ksig->ka, regs, sizeof(struct rt_sigframe), &fp); @@ -470,9 +470,11 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig, return -EFAULT; }
+ uc_flags = frame_uc_flags(regs); + put_user_try { /* Create the ucontext. */ - put_user_ex(frame_uc_flags(regs), &frame->uc.uc_flags); + put_user_ex(uc_flags, &frame->uc.uc_flags); put_user_ex(0, &frame->uc.uc_link); save_altstack_ex(&frame->uc.uc_stack, regs->sp);
@@ -538,6 +540,7 @@ static int x32_setup_rt_frame(struct ksignal *ksig, { #ifdef CONFIG_X86_X32_ABI struct rt_sigframe_x32 __user *frame; + unsigned long uc_flags; void __user *restorer; int err = 0; void __user *fpstate = NULL; @@ -552,9 +555,11 @@ static int x32_setup_rt_frame(struct ksignal *ksig, return -EFAULT; }
+ uc_flags = frame_uc_flags(regs); + put_user_try { /* Create the ucontext. */ - put_user_ex(frame_uc_flags(regs), &frame->uc.uc_flags); + put_user_ex(uc_flags, &frame->uc.uc_flags); put_user_ex(0, &frame->uc.uc_link); compat_save_altstack_ex(&frame->uc.uc_stack, regs->sp); put_user_ex(0, &frame->uc.uc__pad0);
[ Upstream commit 67a0514afdbb8b2fc70b771b8c77661a9cb9d3a9 ]
Objtool spotted that we call native_load_gs_index() with AC set. Re-arrange the code to avoid that.
Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Cc: Borislav Petkov bp@alien8.de Cc: Josh Poimboeuf jpoimboe@redhat.com Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Peter Zijlstra peterz@infradead.org Cc: Thomas Gleixner tglx@linutronix.de Signed-off-by: Ingo Molnar mingo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/ia32/ia32_signal.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-)
diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c index cb13c0564ea7b..9978ea4382bf6 100644 --- a/arch/x86/ia32/ia32_signal.c +++ b/arch/x86/ia32/ia32_signal.c @@ -60,9 +60,8 @@ } while (0)
#define RELOAD_SEG(seg) { \ - unsigned int pre = GET_SEG(seg); \ + unsigned int pre = (seg) | 3; \ unsigned int cur = get_user_seg(seg); \ - pre |= 3; \ if (pre != cur) \ set_user_seg(seg, pre); \ } @@ -71,6 +70,7 @@ static int ia32_restore_sigcontext(struct pt_regs *regs, struct sigcontext_32 __user *sc) { unsigned int tmpflags, err = 0; + u16 gs, fs, es, ds; void __user *buf; u32 tmp;
@@ -78,16 +78,10 @@ static int ia32_restore_sigcontext(struct pt_regs *regs, current->restart_block.fn = do_no_restart_syscall;
get_user_try { - /* - * Reload fs and gs if they have changed in the signal - * handler. This does not handle long fs/gs base changes in - * the handler, but does not clobber them at least in the - * normal case. - */ - RELOAD_SEG(gs); - RELOAD_SEG(fs); - RELOAD_SEG(ds); - RELOAD_SEG(es); + gs = GET_SEG(gs); + fs = GET_SEG(fs); + ds = GET_SEG(ds); + es = GET_SEG(es);
COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx); COPY(dx); COPY(cx); COPY(ip); COPY(ax); @@ -105,6 +99,17 @@ static int ia32_restore_sigcontext(struct pt_regs *regs, buf = compat_ptr(tmp); } get_user_catch(err);
+ /* + * Reload fs and gs if they have changed in the signal + * handler. This does not handle long fs/gs base changes in + * the handler, but does not clobber them at least in the + * normal case. + */ + RELOAD_SEG(gs); + RELOAD_SEG(fs); + RELOAD_SEG(ds); + RELOAD_SEG(es); + err |= fpu__restore_sig(buf, 1);
force_iret();
[ Upstream commit de36e16d1557a0b6eb328bc3516359a12ba5c25c ]
Current overlap checking cannot correctly handle a case which is baseminor < existing baseminor && baseminor + minorct > existing baseminor + minorct.
Signed-off-by: Chengguang Xu cgxu519@gmx.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/char_dev.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/fs/char_dev.c b/fs/char_dev.c index 44a240c4bb658..a112a4745d8b3 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c @@ -134,6 +134,12 @@ __register_chrdev_region(unsigned int major, unsigned int baseminor, ret = -EBUSY; goto out; } + + if (new_min < old_min && new_max > old_max) { + ret = -EBUSY; + goto out; + } + }
cd->next = *cp;
[ Upstream commit 58e75155009cc800005629955d3482f36a1e0eec ]
As seen on some USB wireless keyboards manufactured by Primax, the HID parser was using some assumptions that are not always true. In this case it's s the fact that, inside the scope of a main item, an Usage Page will always precede an Usage.
The spec is not pretty clear as 6.2.2.7 states "Any usage that follows is interpreted as a Usage ID and concatenated with the Usage Page". While 6.2.2.8 states "When the parser encounters a main item it concatenates the last declared Usage Page with a Usage to form a complete usage value." Being somewhat contradictory it was decided to match Window's implementation, which follows 6.2.2.8.
In summary, the patch moves the Usage Page concatenation from the local item parsing function to the main item parsing function.
Signed-off-by: Nicolas Saenz Julienne nsaenzjulienne@suse.de Reviewed-by: Terry Junge terry.junge@poly.com Signed-off-by: Benjamin Tissoires benjamin.tissoires@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hid/hid-core.c | 36 ++++++++++++++++++++++++------------ include/linux/hid.h | 1 + 2 files changed, 25 insertions(+), 12 deletions(-)
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 70597854397fc..ceb4df96e0d55 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -200,13 +200,14 @@ static unsigned hid_lookup_collection(struct hid_parser *parser, unsigned type) * Add a usage to the temporary parser table. */
-static int hid_add_usage(struct hid_parser *parser, unsigned usage) +static int hid_add_usage(struct hid_parser *parser, unsigned usage, u8 size) { if (parser->local.usage_index >= HID_MAX_USAGES) { hid_err(parser->device, "usage index exceeded\n"); return -1; } parser->local.usage[parser->local.usage_index] = usage; + parser->local.usage_size[parser->local.usage_index] = size; parser->local.collection_index[parser->local.usage_index] = parser->collection_stack_ptr ? parser->collection_stack[parser->collection_stack_ptr - 1] : 0; @@ -463,10 +464,7 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item) return 0; }
- if (item->size <= 2) - data = (parser->global.usage_page << 16) + data; - - return hid_add_usage(parser, data); + return hid_add_usage(parser, data, item->size);
case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM:
@@ -475,9 +473,6 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item) return 0; }
- if (item->size <= 2) - data = (parser->global.usage_page << 16) + data; - parser->local.usage_minimum = data; return 0;
@@ -488,9 +483,6 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item) return 0; }
- if (item->size <= 2) - data = (parser->global.usage_page << 16) + data; - count = data - parser->local.usage_minimum; if (count + parser->local.usage_index >= HID_MAX_USAGES) { /* @@ -510,7 +502,7 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item) }
for (n = parser->local.usage_minimum; n <= data; n++) - if (hid_add_usage(parser, n)) { + if (hid_add_usage(parser, n, item->size)) { dbg_hid("hid_add_usage failed\n"); return -1; } @@ -524,6 +516,22 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item) return 0; }
+/* + * Concatenate Usage Pages into Usages where relevant: + * As per specification, 6.2.2.8: "When the parser encounters a main item it + * concatenates the last declared Usage Page with a Usage to form a complete + * usage value." + */ + +static void hid_concatenate_usage_page(struct hid_parser *parser) +{ + int i; + + for (i = 0; i < parser->local.usage_index; i++) + if (parser->local.usage_size[i] <= 2) + parser->local.usage[i] += parser->global.usage_page << 16; +} + /* * Process a main item. */ @@ -533,6 +541,8 @@ static int hid_parser_main(struct hid_parser *parser, struct hid_item *item) __u32 data; int ret;
+ hid_concatenate_usage_page(parser); + data = item_udata(item);
switch (item->tag) { @@ -746,6 +756,8 @@ static int hid_scan_main(struct hid_parser *parser, struct hid_item *item) __u32 data; int i;
+ hid_concatenate_usage_page(parser); + data = item_udata(item);
switch (item->tag) { diff --git a/include/linux/hid.h b/include/linux/hid.h index fab65b61d6d4e..04bdf5477ec51 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -374,6 +374,7 @@ struct hid_global {
struct hid_local { unsigned usage[HID_MAX_USAGES]; /* usage array */ + u8 usage_size[HID_MAX_USAGES]; /* usage size array */ unsigned collection_index[HID_MAX_USAGES]; /* collection index array */ unsigned usage_index; unsigned usage_minimum;
[ Upstream commit b820d52e7eed7b30b2dfef5f4213a2bc3cbea6f3 ]
The call to of_parse_phandle returns a node pointer with refcount incremented thus it must be explicitly decremented after the last usage.
Detected by coccinelle with the following warnings: ./sound/soc/fsl/eukrea-tlv320.c:121:3-9: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 102, but without a correspo nding object release within this function. ./sound/soc/fsl/eukrea-tlv320.c:127:3-9: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 102, but without a correspo nding object release within this function.
Signed-off-by: Wen Yang wen.yang99@zte.com.cn Cc: Liam Girdwood lgirdwood@gmail.com Cc: Mark Brown broonie@kernel.org Cc: Jaroslav Kysela perex@perex.cz Cc: Takashi Iwai tiwai@suse.com Cc: alsa-devel@alsa-project.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/fsl/eukrea-tlv320.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/soc/fsl/eukrea-tlv320.c b/sound/soc/fsl/eukrea-tlv320.c index 883087f2b092b..38132143b7d5e 100644 --- a/sound/soc/fsl/eukrea-tlv320.c +++ b/sound/soc/fsl/eukrea-tlv320.c @@ -119,13 +119,13 @@ static int eukrea_tlv320_probe(struct platform_device *pdev) if (ret) { dev_err(&pdev->dev, "fsl,mux-int-port node missing or invalid.\n"); - return ret; + goto err; } ret = of_property_read_u32(np, "fsl,mux-ext-port", &ext_port); if (ret) { dev_err(&pdev->dev, "fsl,mux-ext-port node missing or invalid.\n"); - return ret; + goto err; }
/*
[ Upstream commit c705247136a523488eac806bd357c3e5d79a7acd ]
The call to of_parse_phandle returns a node pointer with refcount incremented thus it must be explicitly decremented after the last usage.
Detected by coccinelle with the following warnings: ./sound/soc/fsl/fsl_utils.c:74:2-8: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 38, but without a corresponding object release within this function.
Signed-off-by: Wen Yang wen.yang99@zte.com.cn Cc: Timur Tabi timur@kernel.org Cc: Nicolin Chen nicoleotsuka@gmail.com Cc: Xiubo Li Xiubo.Lee@gmail.com Cc: Fabio Estevam festevam@gmail.com Cc: Liam Girdwood lgirdwood@gmail.com Cc: Mark Brown broonie@kernel.org Cc: Jaroslav Kysela perex@perex.cz Cc: Takashi Iwai tiwai@suse.com Cc: alsa-devel@alsa-project.org Cc: linuxppc-dev@lists.ozlabs.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/fsl/fsl_utils.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/sound/soc/fsl/fsl_utils.c b/sound/soc/fsl/fsl_utils.c index b9e42b503a377..4f8bdb7650e84 100644 --- a/sound/soc/fsl/fsl_utils.c +++ b/sound/soc/fsl/fsl_utils.c @@ -75,6 +75,7 @@ int fsl_asoc_get_dma_channel(struct device_node *ssi_np, iprop = of_get_property(dma_np, "cell-index", NULL); if (!iprop) { of_node_put(dma_np); + of_node_put(dma_channel_np); return -EINVAL; } *dma_id = be32_to_cpup(iprop);
[ Upstream commit 76497732932f15e7323dc805e8ea8dc11bb587cf ]
The use of zero-sized array causes undefined behaviour when it is not the last member in a structure. As it happens to be in this case.
Also, the current code makes use of a language extension to the C90 standard, but the preferred mechanism to declare variable-length types such as this one is a flexible array member, introduced in C99:
struct foo { int stuff; struct boo array[]; };
By making use of the mechanism above, we will get a compiler warning in case the flexible array does not occur last. Which is beneficial to cultivate a high-quality code.
Fixes: e48f129c2f20 ("[SCSI] cxgb3i: convert cdev->l2opt to use rcu to prevent NULL dereference") Signed-off-by: Gustavo A. R. Silva gustavo@embeddedor.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/chelsio/cxgb3/l2t.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb3/l2t.h b/drivers/net/ethernet/chelsio/cxgb3/l2t.h index 8cffcdfd56782..38b5858c335a9 100644 --- a/drivers/net/ethernet/chelsio/cxgb3/l2t.h +++ b/drivers/net/ethernet/chelsio/cxgb3/l2t.h @@ -75,8 +75,8 @@ struct l2t_data { struct l2t_entry *rover; /* starting point for next allocation */ atomic_t nfree; /* number of free entries */ rwlock_t lock; - struct l2t_entry l2tab[0]; struct rcu_head rcu_head; /* to handle rcu cleanup */ + struct l2t_entry l2tab[]; };
typedef void (*arp_failure_handler_func)(struct t3cdev * dev,
[ Upstream commit 019194933339b3e9b486639c8cb3692020844d65 ]
Fixes: SPI driver can be built as module so perform SPI controller reset on probe to make sure it is in valid state before initiating transfer.
Signed-off-by: Sowjanya Komatineni skomatineni@nvidia.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi-tegra114.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-)
diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c index 73779cecc3bbc..705f515863d4f 100644 --- a/drivers/spi/spi-tegra114.c +++ b/drivers/spi/spi-tegra114.c @@ -1067,27 +1067,19 @@ static int tegra_spi_probe(struct platform_device *pdev)
spi_irq = platform_get_irq(pdev, 0); tspi->irq = spi_irq; - ret = request_threaded_irq(tspi->irq, tegra_spi_isr, - tegra_spi_isr_thread, IRQF_ONESHOT, - dev_name(&pdev->dev), tspi); - if (ret < 0) { - dev_err(&pdev->dev, "Failed to register ISR for IRQ %d\n", - tspi->irq); - goto exit_free_master; - }
tspi->clk = devm_clk_get(&pdev->dev, "spi"); if (IS_ERR(tspi->clk)) { dev_err(&pdev->dev, "can not get clock\n"); ret = PTR_ERR(tspi->clk); - goto exit_free_irq; + goto exit_free_master; }
tspi->rst = devm_reset_control_get(&pdev->dev, "spi"); if (IS_ERR(tspi->rst)) { dev_err(&pdev->dev, "can not get reset\n"); ret = PTR_ERR(tspi->rst); - goto exit_free_irq; + goto exit_free_master; }
tspi->max_buf_size = SPI_FIFO_DEPTH << 2; @@ -1095,7 +1087,7 @@ static int tegra_spi_probe(struct platform_device *pdev)
ret = tegra_spi_init_dma_param(tspi, true); if (ret < 0) - goto exit_free_irq; + goto exit_free_master; ret = tegra_spi_init_dma_param(tspi, false); if (ret < 0) goto exit_rx_dma_free; @@ -1117,18 +1109,32 @@ static int tegra_spi_probe(struct platform_device *pdev) dev_err(&pdev->dev, "pm runtime get failed, e = %d\n", ret); goto exit_pm_disable; } + + reset_control_assert(tspi->rst); + udelay(2); + reset_control_deassert(tspi->rst); tspi->def_command1_reg = SPI_M_S; tegra_spi_writel(tspi, tspi->def_command1_reg, SPI_COMMAND1); pm_runtime_put(&pdev->dev); + ret = request_threaded_irq(tspi->irq, tegra_spi_isr, + tegra_spi_isr_thread, IRQF_ONESHOT, + dev_name(&pdev->dev), tspi); + if (ret < 0) { + dev_err(&pdev->dev, "Failed to register ISR for IRQ %d\n", + tspi->irq); + goto exit_pm_disable; + }
master->dev.of_node = pdev->dev.of_node; ret = devm_spi_register_master(&pdev->dev, master); if (ret < 0) { dev_err(&pdev->dev, "can not register to master err %d\n", ret); - goto exit_pm_disable; + goto exit_free_irq; } return ret;
+exit_free_irq: + free_irq(spi_irq, tspi); exit_pm_disable: pm_runtime_disable(&pdev->dev); if (!pm_runtime_status_suspended(&pdev->dev)) @@ -1136,8 +1142,6 @@ static int tegra_spi_probe(struct platform_device *pdev) tegra_spi_deinit_dma_param(tspi, false); exit_rx_dma_free: tegra_spi_deinit_dma_param(tspi, true); -exit_free_irq: - free_irq(spi_irq, tspi); exit_free_master: spi_master_put(master); return ret;
[ Upstream commit 9c2ccc324b3a6cbc865ab8b3e1a09e93d3c8ade9 ]
Smatch marks skb->data as untrusted so it warns that "evt_hdr->dlen" can copy up to 255 bytes and we only have room for two bytes. Even if this comes from the firmware and we trust it, the new policy generally is just to fix it as kernel hardenning.
I can't test this code so I tried to be very conservative. I considered not allowing "evt_hdr->dlen == 1" because it doesn't initialize the whole variable but in the end I decided to allow it and manually initialized "asic_id" and "asic_ver" to zero.
Fixes: e8454ff7b9a4 ("[media] drivers:media:radio: wl128x: FM Driver Common sources")
Signed-off-by: Dan Carpenter dan.carpenter@oracle.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/radio/wl128x/fmdrv_common.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/media/radio/wl128x/fmdrv_common.c b/drivers/media/radio/wl128x/fmdrv_common.c index 642b89c66bcb9..c1457cf466981 100644 --- a/drivers/media/radio/wl128x/fmdrv_common.c +++ b/drivers/media/radio/wl128x/fmdrv_common.c @@ -494,7 +494,8 @@ int fmc_send_cmd(struct fmdev *fmdev, u8 fm_op, u16 type, void *payload, return -EIO; } /* Send response data to caller */ - if (response != NULL && response_len != NULL && evt_hdr->dlen) { + if (response != NULL && response_len != NULL && evt_hdr->dlen && + evt_hdr->dlen <= payload_len) { /* Skip header info and copy only response data */ skb_pull(skb, sizeof(struct fm_event_msg_hdr)); memcpy(response, skb->data, evt_hdr->dlen); @@ -590,6 +591,8 @@ static void fm_irq_handle_flag_getcmd_resp(struct fmdev *fmdev) return;
fm_evt_hdr = (void *)skb->data; + if (fm_evt_hdr->dlen > sizeof(fmdev->irq_info.flag)) + return;
/* Skip header info and copy only response data */ skb_pull(skb, sizeof(struct fm_event_msg_hdr)); @@ -1315,7 +1318,7 @@ static int load_default_rx_configuration(struct fmdev *fmdev) static int fm_power_up(struct fmdev *fmdev, u8 mode) { u16 payload; - __be16 asic_id, asic_ver; + __be16 asic_id = 0, asic_ver = 0; int resp_len, ret; u8 fw_name[50];
[ Upstream commit 4b0a2c5ff7215206ea6135a405f17c5f6fca7d00 ]
For regular serial ports we do not initialize value of vtermno variable. A garbage value is assigned for non console ports. The value can be observed as a random integer with [1].
[1] vim /sys/kernel/debug/virtio-ports/vport*p*
This patch initialize the value of vtermno for console serial ports to '1' and regular serial ports are initiaized to '0'.
Reported-by: siliu@redhat.com Signed-off-by: Pankaj Gupta pagupta@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/char/virtio_console.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 8c0017d485717..800ced0a5a247 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -75,7 +75,7 @@ struct ports_driver_data { /* All the console devices handled by this driver */ struct list_head consoles; }; -static struct ports_driver_data pdrvdata; +static struct ports_driver_data pdrvdata = { .next_vtermno = 1};
static DEFINE_SPINLOCK(pdrvdata_lock); static DECLARE_COMPLETION(early_console_added); @@ -1425,6 +1425,7 @@ static int add_port(struct ports_device *portdev, u32 id) port->async_queue = NULL;
port->cons.ws.ws_row = port->cons.ws.ws_col = 0; + port->cons.vtermno = 0;
port->host_connected = port->guest_connected = false; port->stats = (struct port_stats) { 0 };
[ Upstream commit 1bbb1c318cd8a3a39e8c3e2e83d5e90542d6c3e3 ]
ipw->attr_memory and ipw->common_memory are assigned with the return value of ioremap. ioremap may fail, but no checks are enforced. The fix inserts the checks to avoid potential NULL pointer dereferences.
Signed-off-by: Kangjie Lu kjlu@umn.edu Reviewed-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/ipwireless/main.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/tty/ipwireless/main.c b/drivers/tty/ipwireless/main.c index 655c7948261c7..2fa4f91234693 100644 --- a/drivers/tty/ipwireless/main.c +++ b/drivers/tty/ipwireless/main.c @@ -113,6 +113,10 @@ static int ipwireless_probe(struct pcmcia_device *p_dev, void *priv_data)
ipw->common_memory = ioremap(p_dev->resource[2]->start, resource_size(p_dev->resource[2])); + if (!ipw->common_memory) { + ret = -ENOMEM; + goto exit1; + } if (!request_mem_region(p_dev->resource[2]->start, resource_size(p_dev->resource[2]), IPWIRELESS_PCCARD_NAME)) { @@ -133,6 +137,10 @@ static int ipwireless_probe(struct pcmcia_device *p_dev, void *priv_data)
ipw->attr_memory = ioremap(p_dev->resource[3]->start, resource_size(p_dev->resource[3])); + if (!ipw->attr_memory) { + ret = -ENOMEM; + goto exit3; + } if (!request_mem_region(p_dev->resource[3]->start, resource_size(p_dev->resource[3]), IPWIRELESS_PCCARD_NAME)) {
[ Upstream commit f19501aa07f18268ab14f458b51c1c6b7f72a134 ]
There has been a lurking "TBD" in the machine check poll routine ever since it was first split out from the machine check handler. The potential issue is that the poll routine may have just begun a read from the STATUS register in a machine check bank when the hardware logs an error in that bank and signals a machine check.
That race used to be pretty small back when machine checks were broadcast, but the addition of local machine check means that the poll code could continue running and clear the error from the bank before the local machine check handler on another CPU gets around to reading it.
Fix the code to be sure to only process errors that need to be processed in the poll code, leaving other logged errors alone for the machine check handler to find and process.
[ bp: Massage a bit and flip the "== 0" check to the usual !(..) test. ]
Fixes: b79109c3bbcf ("x86, mce: separate correct machine check poller and fatal exception handler") Fixes: ed7290d0ee8f ("x86, mce: implement new status bits") Reported-by: Ashok Raj ashok.raj@intel.com Signed-off-by: Tony Luck tony.luck@intel.com Signed-off-by: Borislav Petkov bp@suse.de Cc: Ashok Raj ashok.raj@intel.com Cc: "H. Peter Anvin" hpa@zytor.com Cc: Ingo Molnar mingo@redhat.com Cc: linux-edac linux-edac@vger.kernel.org Cc: Thomas Gleixner tglx@linutronix.de Cc: x86-ml x86@kernel.org Cc: Yazen Ghannam Yazen.Ghannam@amd.com Link: https://lkml.kernel.org/r/20190312170938.GA23035@agluck-desk Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/kernel/cpu/mcheck/mce.c | 44 +++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 7 deletions(-)
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index d9ad49ca3cbe2..e348bee411e35 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c @@ -673,20 +673,50 @@ bool machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
barrier(); m.status = mce_rdmsrl(msr_ops.status(i)); + + /* If this entry is not valid, ignore it */ if (!(m.status & MCI_STATUS_VAL)) continue;
/* - * Uncorrected or signalled events are handled by the exception - * handler when it is enabled, so don't process those here. - * - * TBD do the same check for MCI_STATUS_EN here? + * If we are logging everything (at CPU online) or this + * is a corrected error, then we must log it. */ - if (!(flags & MCP_UC) && - (m.status & (mca_cfg.ser ? MCI_STATUS_S : MCI_STATUS_UC))) - continue; + if ((flags & MCP_UC) || !(m.status & MCI_STATUS_UC)) + goto log_it; + + /* + * Newer Intel systems that support software error + * recovery need to make additional checks. Other + * CPUs should skip over uncorrected errors, but log + * everything else. + */ + if (!mca_cfg.ser) { + if (m.status & MCI_STATUS_UC) + continue; + goto log_it; + } + + /* Log "not enabled" (speculative) errors */ + if (!(m.status & MCI_STATUS_EN)) + goto log_it; + + /* + * Log UCNA (SDM: 15.6.3 "UCR Error Classification") + * UC == 1 && PCC == 0 && S == 0 + */ + if (!(m.status & MCI_STATUS_PCC) && !(m.status & MCI_STATUS_S)) + goto log_it; + + /* + * Skip anything else. Presumption is that our read of this + * bank is racing with a machine check. Leave the log alone + * for do_machine_check() to deal with it. + */ + continue;
+log_it: error_seen = true;
mce_read_aux(&m, i);
[ Upstream commit b813afae7ab6a5e91b4e16cc567331d9c2ae1f04 ]
If the specified rcutorture.torture_type is not in the rcu_torture_init() function's torture_ops[] array, rcutorture prints some console messages and then invokes rcu_torture_cleanup() to set state so that a future torture test can run. However, rcu_torture_cleanup() also attempts to end the test that didn't actually start, and in doing so relies on the value of cur_ops, a value that is not particularly relevant in this case. This can result in confusing output or even follow-on failures due to attempts to use facilities that have not been properly initialized.
This commit therefore sets the value of cur_ops to NULL in this case and inserts a check near the beginning of rcu_torture_cleanup(), thus avoiding relying on an irrelevant cur_ops value.
Reported-by: kernel test robot rong.a.chen@intel.com Signed-off-by: Paul E. McKenney paulmck@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/rcu/rcutorture.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c index bf08fee53dc75..5393bbcf3c1ad 100644 --- a/kernel/rcu/rcutorture.c +++ b/kernel/rcu/rcutorture.c @@ -1595,6 +1595,10 @@ rcu_torture_cleanup(void) cur_ops->cb_barrier(); return; } + if (!cur_ops) { + torture_cleanup_end(); + return; + }
rcu_torture_barrier_cleanup(); torture_stop_kthread(rcu_torture_stall, stall_task); @@ -1730,6 +1734,7 @@ rcu_torture_init(void) pr_alert(" %s", torture_ops[i]->name); pr_alert("\n"); firsterr = -EINVAL; + cur_ops = NULL; goto unwind; } if (cur_ops->fqs == NULL && fqs_duration != 0) {
[ Upstream commit ad092c027713a68a34168942a5ef422e42e039f4 ]
If the specified rcuperf.perf_type is not in the rcu_perf_init() function's perf_ops[] array, rcuperf prints some console messages and then invokes rcu_perf_cleanup() to set state so that a future torture test can run. However, rcu_perf_cleanup() also attempts to end the test that didn't actually start, and in doing so relies on the value of cur_ops, a value that is not particularly relevant in this case. This can result in confusing output or even follow-on failures due to attempts to use facilities that have not been properly initialized.
This commit therefore sets the value of cur_ops to NULL in this case and inserts a check near the beginning of rcu_perf_cleanup(), thus avoiding relying on an irrelevant cur_ops value.
Signed-off-by: Paul E. McKenney paulmck@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/rcu/rcuperf.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/kernel/rcu/rcuperf.c b/kernel/rcu/rcuperf.c index 123ccbd224492..2b8579d5a5445 100644 --- a/kernel/rcu/rcuperf.c +++ b/kernel/rcu/rcuperf.c @@ -453,6 +453,10 @@ rcu_perf_cleanup(void)
if (torture_cleanup_begin()) return; + if (!cur_ops) { + torture_cleanup_end(); + return; + }
if (reader_tasks) { for (i = 0; i < nrealreaders; i++) @@ -574,6 +578,7 @@ rcu_perf_init(void) pr_alert(" %s", perf_ops[i]->name); pr_alert("\n"); firsterr = -EINVAL; + cur_ops = NULL; goto unwind; } if (cur_ops->init)
[ Upstream commit 8ead7e817224d7832fe51a19783cb8fcadc79467 ]
If ohci-platform is runtime suspended, we can currently get an "imprecise external abort" on reboot with ohci-platform loaded when PM runtime is implemented for the SoC.
Let's fix this by adding PM runtime support to usb_hcd_platform_shutdown.
Signed-off-by: Tony Lindgren tony@atomide.com Acked-by: Alan Stern stern@rowland.harvard.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/core/hcd.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index bdb0d7a08ff9b..1dd4c65e9188a 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -3033,6 +3033,9 @@ usb_hcd_platform_shutdown(struct platform_device *dev) { struct usb_hcd *hcd = platform_get_drvdata(dev);
+ /* No need for pm_runtime_put(), we're shutting down */ + pm_runtime_get_sync(&dev->dev); + if (hcd->driver->shutdown) hcd->driver->shutdown(hcd); }
[ Upstream commit 608f729c31d4caf52216ea00d20092a80959256d ]
Clang -Wuninitialized notices that on is_qla40XX we never allocate any DMA memory in get_fw_boot_info() but attempt to free it anyway:
drivers/scsi/qla4xxx/ql4_os.c:5915:7: error: variable 'buf_dma' is used uninitialized whenever 'if' condition is false [-Werror,-Wsometimes-uninitialized] if (!(val & 0x07)) { ^~~~~~~~~~~~~ drivers/scsi/qla4xxx/ql4_os.c:5985:47: note: uninitialized use occurs here dma_free_coherent(&ha->pdev->dev, size, buf, buf_dma); ^~~~~~~ drivers/scsi/qla4xxx/ql4_os.c:5915:3: note: remove the 'if' if its condition is always true if (!(val & 0x07)) { ^~~~~~~~~~~~~~~~~~~ drivers/scsi/qla4xxx/ql4_os.c:5885:20: note: initialize the variable 'buf_dma' to silence this warning dma_addr_t buf_dma; ^ = 0
Skip the call to dma_free_coherent() here.
Fixes: 2a991c215978 ("[SCSI] qla4xxx: Boot from SAN support for open-iscsi") Signed-off-by: Arnd Bergmann arnd@arndb.de Reviewed-by: Nathan Chancellor natechancellor@gmail.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla4xxx/ql4_os.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index c158967b59d7b..d220b4f691c77 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@ -5939,7 +5939,7 @@ static int get_fw_boot_info(struct scsi_qla_host *ha, uint16_t ddb_index[]) val = rd_nvram_byte(ha, sec_addr); if (val & BIT_7) ddb_index[1] = (val & 0x7f); - + goto exit_boot_info; } else if (is_qla80XX(ha)) { buf = dma_alloc_coherent(&ha->pdev->dev, size, &buf_dma, GFP_KERNEL);
[ Upstream commit f6ed6491d565c336a360471e0c29228e34f4380e ]
adma driver is using pm_clk_*() interface for managing clock resources. With this it is observed that clocks remain ON always. This happens on Tegra devices which use BPMP co-processor to manage clock resources, where clocks are enabled during prepare phase. This is necessary because clocks to BPMP are always blocking. When pm_clk_*() interface is used on such Tegra devices, clock prepare count is not balanced till remove call happens for the driver and hence clocks are seen ON always. Thus this patch replaces pm_clk_*() with devm_clk_*() framework.
Suggested-by: Mohan Kumar D mkumard@nvidia.com Reviewed-by: Jonathan Hunter jonathanh@nvidia.com Signed-off-by: Sameer Pujar spujar@nvidia.com Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/tegra210-adma.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-)
diff --git a/drivers/dma/tegra210-adma.c b/drivers/dma/tegra210-adma.c index af3487538c191..e9e46a5207452 100644 --- a/drivers/dma/tegra210-adma.c +++ b/drivers/dma/tegra210-adma.c @@ -22,7 +22,6 @@ #include <linux/of_device.h> #include <linux/of_dma.h> #include <linux/of_irq.h> -#include <linux/pm_clock.h> #include <linux/pm_runtime.h> #include <linux/slab.h>
@@ -141,6 +140,7 @@ struct tegra_adma { struct dma_device dma_dev; struct device *dev; void __iomem *base_addr; + struct clk *ahub_clk; unsigned int nr_channels; unsigned long rx_requests_reserved; unsigned long tx_requests_reserved; @@ -637,8 +637,9 @@ static int tegra_adma_runtime_suspend(struct device *dev) struct tegra_adma *tdma = dev_get_drvdata(dev);
tdma->global_cmd = tdma_read(tdma, ADMA_GLOBAL_CMD); + clk_disable_unprepare(tdma->ahub_clk);
- return pm_clk_suspend(dev); + return 0; }
static int tegra_adma_runtime_resume(struct device *dev) @@ -646,10 +647,11 @@ static int tegra_adma_runtime_resume(struct device *dev) struct tegra_adma *tdma = dev_get_drvdata(dev); int ret;
- ret = pm_clk_resume(dev); - if (ret) + ret = clk_prepare_enable(tdma->ahub_clk); + if (ret) { + dev_err(dev, "ahub clk_enable failed: %d\n", ret); return ret; - + } tdma_write(tdma, ADMA_GLOBAL_CMD, tdma->global_cmd);
return 0; @@ -692,13 +694,11 @@ static int tegra_adma_probe(struct platform_device *pdev) if (IS_ERR(tdma->base_addr)) return PTR_ERR(tdma->base_addr);
- ret = pm_clk_create(&pdev->dev); - if (ret) - return ret; - - ret = of_pm_clk_add_clk(&pdev->dev, "d_audio"); - if (ret) - goto clk_destroy; + tdma->ahub_clk = devm_clk_get(&pdev->dev, "d_audio"); + if (IS_ERR(tdma->ahub_clk)) { + dev_err(&pdev->dev, "Error: Missing ahub controller clock\n"); + return PTR_ERR(tdma->ahub_clk); + }
pm_runtime_enable(&pdev->dev);
@@ -775,8 +775,6 @@ static int tegra_adma_probe(struct platform_device *pdev) pm_runtime_put_sync(&pdev->dev); rpm_disable: pm_runtime_disable(&pdev->dev); -clk_destroy: - pm_clk_destroy(&pdev->dev);
return ret; } @@ -794,7 +792,6 @@ static int tegra_adma_remove(struct platform_device *pdev)
pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); - pm_clk_destroy(&pdev->dev);
return 0; }
[ Upstream commit 981fbe3da20a6f35f17977453bce7dfc1664d74f ]
Ref: https://bugzilla.kernel.org/show_bug.cgi?id=199323
Users are experiencing problems with the DVBSky S960/S960C USB devices since the following commit:
9d659ae: ("locking/mutex: Add lock handoff to avoid starvation")
The device malfunctions after running for an indeterminable period of time, and the problem can only be cleared by rebooting the machine.
It is possible to encourage the problem to surface by blocking the signal to the LNB.
Further debugging revealed the cause of the problem.
In the following capture: - thread #1325 is running m88ds3103_set_frontend - thread #42 is running ts2020_stat_work
a> [1325] usb 1-1: dvb_usb_v2_generic_io: >>> 08 68 02 07 80 [1325] usb 1-1: dvb_usb_v2_generic_io: <<< 08 [42] usb 1-1: dvb_usb_v2_generic_io: >>> 09 01 01 68 3f [42] usb 1-1: dvb_usb_v2_generic_io: <<< 08 ff [42] usb 1-1: dvb_usb_v2_generic_io: >>> 08 68 02 03 11 [42] usb 1-1: dvb_usb_v2_generic_io: <<< 07 [42] usb 1-1: dvb_usb_v2_generic_io: >>> 09 01 01 60 3d [42] usb 1-1: dvb_usb_v2_generic_io: <<< 07 ff b> [1325] usb 1-1: dvb_usb_v2_generic_io: >>> 08 68 02 07 00 [1325] usb 1-1: dvb_usb_v2_generic_io: <<< 07 [42] usb 1-1: dvb_usb_v2_generic_io: >>> 08 68 02 03 11 [42] usb 1-1: dvb_usb_v2_generic_io: <<< 07 [42] usb 1-1: dvb_usb_v2_generic_io: >>> 09 01 01 60 21 [42] usb 1-1: dvb_usb_v2_generic_io: <<< 07 ff [42] usb 1-1: dvb_usb_v2_generic_io: >>> 08 68 02 03 11 [42] usb 1-1: dvb_usb_v2_generic_io: <<< 07 [42] usb 1-1: dvb_usb_v2_generic_io: >>> 09 01 01 60 66 [42] usb 1-1: dvb_usb_v2_generic_io: <<< 07 ff [1325] usb 1-1: dvb_usb_v2_generic_io: >>> 08 68 02 03 11 [1325] usb 1-1: dvb_usb_v2_generic_io: <<< 07 [1325] usb 1-1: dvb_usb_v2_generic_io: >>> 08 60 02 10 0b [1325] usb 1-1: dvb_usb_v2_generic_io: <<< 07
Two i2c messages are sent to perform a reset in m88ds3103_set_frontend:
a. 0x07, 0x80 b. 0x07, 0x00
However, as shown in the capture, the regmap mutex is being handed over to another thread (ts2020_stat_work) in between these two messages.
From here, the device responds to every i2c message with an 07 message,
and will only return to normal operation following a power cycle.
Use regmap_multi_reg_write to group the two reset messages, ensuring both are processed before the regmap mutex is unlocked.
Signed-off-by: James Hutchinson jahutchinson99@googlemail.com Reviewed-by: Antti Palosaari crope@iki.fi Signed-off-by: Sean Young sean@mess.org Signed-off-by: Mauro Carvalho Chehab mchehab+samsung@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/dvb-frontends/m88ds3103.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c index 31f16105184c0..59a4563c0466e 100644 --- a/drivers/media/dvb-frontends/m88ds3103.c +++ b/drivers/media/dvb-frontends/m88ds3103.c @@ -309,6 +309,9 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) u16 u16tmp; u32 tuner_frequency_khz, target_mclk; s32 s32tmp; + static const struct reg_sequence reset_buf[] = { + {0x07, 0x80}, {0x07, 0x00} + };
dev_dbg(&client->dev, "delivery_system=%d modulation=%d frequency=%u symbol_rate=%d inversion=%d pilot=%d rolloff=%d\n", @@ -321,11 +324,7 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) }
/* reset */ - ret = regmap_write(dev->regmap, 0x07, 0x80); - if (ret) - goto err; - - ret = regmap_write(dev->regmap, 0x07, 0x00); + ret = regmap_multi_reg_write(dev->regmap, reset_buf, 2); if (ret) goto err;
[ Upstream commit ed713a4a1367aca5c0f2f329579465db00c17995 ]
clang-8 warns about one function here when KASAN is enabled, even without the 'asan-stack' option:
drivers/media/usb/go7007/go7007-fw.c:1551:5: warning: stack frame size of 2656 bytes in function
I have reported this issue in the llvm bugzilla, but to make it work with the clang-8 release, a small annotation is still needed.
Link: https://bugs.llvm.org/show_bug.cgi?id=38809
Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl [hverkuil-cisco@xs4all.nl: fix checkpatch warning] Signed-off-by: Mauro Carvalho Chehab mchehab+samsung@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/usb/go7007/go7007-fw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/media/usb/go7007/go7007-fw.c b/drivers/media/usb/go7007/go7007-fw.c index 60bf5f0644d11..a5efcd4f7b4f5 100644 --- a/drivers/media/usb/go7007/go7007-fw.c +++ b/drivers/media/usb/go7007/go7007-fw.c @@ -1499,8 +1499,8 @@ static int modet_to_package(struct go7007 *go, __le16 *code, int space) return cnt; }
-static int do_special(struct go7007 *go, u16 type, __le16 *code, int space, - int *framelen) +static noinline_for_stack int do_special(struct go7007 *go, u16 type, + __le16 *code, int space, int *framelen) { switch (type) { case SPECIAL_FRM_HEAD:
[ Upstream commit d67f935b79a76ac9d86dde1a27bdd413feb5d987 ]
The FDMI manufacturer value being reported on Linux is inconsistent with other OS's.
Set the value to "Emulex Corporation" for consistency.
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_ct.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 4ac03b16d17f5..52afbcff362f9 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -1561,6 +1561,9 @@ lpfc_fdmi_hba_attr_manufacturer(struct lpfc_vport *vport, ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; memset(ae, 0, 256);
+ /* This string MUST be consistent with other FC platforms + * supported by Broadcom. + */ strncpy(ae->un.AttrString, "Emulex Corporation", sizeof(ae->un.AttrString));
[ Upstream commit 03aa4f191a36f33fce015387f84efa0eee94408e ]
Two saa7146/hexium files contain a construct that causes a warning when built with clang:
drivers/media/pci/saa7146/hexium_orion.c:210:12: error: stack frame size of 2272 bytes in function 'hexium_probe' [-Werror,-Wframe-larger-than=] static int hexium_probe(struct saa7146_dev *dev) ^ drivers/media/pci/saa7146/hexium_gemini.c:257:12: error: stack frame size of 2304 bytes in function 'hexium_attach' [-Werror,-Wframe-larger-than=] static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info) ^
This one happens regardless of KASAN, and the problem is that a constructor to initialize a dynamically allocated structure leads to a copy of that structure on the stack, whereas gcc initializes it in place.
Link: https://bugs.llvm.org/show_bug.cgi?id=40776
Signed-off-by: Arnd Bergmann arnd@arndb.de Reviewed-by: Nick Desaulniers ndesaulniers@google.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl [hverkuil-cisco@xs4all.nl: fix checkpatch warnings] Signed-off-by: Mauro Carvalho Chehab mchehab+samsung@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/pci/saa7146/hexium_gemini.c | 5 ++--- drivers/media/pci/saa7146/hexium_orion.c | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/drivers/media/pci/saa7146/hexium_gemini.c b/drivers/media/pci/saa7146/hexium_gemini.c index c889ec9f8a5a0..f5fc8bcbd14b1 100644 --- a/drivers/media/pci/saa7146/hexium_gemini.c +++ b/drivers/media/pci/saa7146/hexium_gemini.c @@ -270,9 +270,8 @@ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_d /* enable i2c-port pins */ saa7146_write(dev, MC1, (MASK_08 | MASK_24 | MASK_10 | MASK_26));
- hexium->i2c_adapter = (struct i2c_adapter) { - .name = "hexium gemini", - }; + strscpy(hexium->i2c_adapter.name, "hexium gemini", + sizeof(hexium->i2c_adapter.name)); saa7146_i2c_adapter_prepare(dev, &hexium->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480); if (i2c_add_adapter(&hexium->i2c_adapter) < 0) { DEB_S("cannot register i2c-device. skipping.\n"); diff --git a/drivers/media/pci/saa7146/hexium_orion.c b/drivers/media/pci/saa7146/hexium_orion.c index c306a92e89095..dc07ca37ebd06 100644 --- a/drivers/media/pci/saa7146/hexium_orion.c +++ b/drivers/media/pci/saa7146/hexium_orion.c @@ -232,9 +232,8 @@ static int hexium_probe(struct saa7146_dev *dev) saa7146_write(dev, DD1_STREAM_B, 0x00000000); saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
- hexium->i2c_adapter = (struct i2c_adapter) { - .name = "hexium orion", - }; + strscpy(hexium->i2c_adapter.name, "hexium orion", + sizeof(hexium->i2c_adapter.name)); saa7146_i2c_adapter_prepare(dev, &hexium->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480); if (i2c_add_adapter(&hexium->i2c_adapter) < 0) { DEB_S("cannot register i2c-device. skipping.\n");
[ Upstream commit c95a3b4b0fb8d351e2329a96f87c4fc96a149505 ]
During debug, it was seen that the driver is issuing commands specific to SLI3 on SLI4 devices. Although the adapter correctly rejected the command, this should not be done.
Revise the code to stop sending these commands on a SLI4 adapter.
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_hbadisc.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 81736457328a1..9cca5ddbc50cc 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -901,7 +901,11 @@ lpfc_linkdown(struct lpfc_hba *phba) lpfc_linkdown_port(vports[i]); } lpfc_destroy_vport_work_array(phba, vports); - /* Clean up any firmware default rpi's */ + + /* Clean up any SLI3 firmware default rpi's */ + if (phba->sli_rev > LPFC_SLI_REV3) + goto skip_unreg_did; + mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); if (mb) { lpfc_unreg_did(phba, 0xffff, LPFC_UNREG_ALL_DFLT_RPIS, mb); @@ -913,6 +917,7 @@ lpfc_linkdown(struct lpfc_hba *phba) } }
+ skip_unreg_did: /* Setup myDID for link up if we are in pt2pt mode */ if (phba->pport->fc_flag & FC_PT2PT) { phba->pport->fc_myDID = 0; @@ -4654,6 +4659,10 @@ lpfc_unreg_default_rpis(struct lpfc_vport *vport) LPFC_MBOXQ_t *mbox; int rc;
+ /* Unreg DID is an SLI3 operation. */ + if (phba->sli_rev > LPFC_SLI_REV3) + return; + mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); if (mbox) { lpfc_unreg_did(phba, vport->vpi, LPFC_UNREG_ALL_DFLT_RPIS,
[ Upstream commit f37d8e67f39e6d3eaf4cc5471e8a3d21209843c6 ]
pch_alloc_dma_buf allocated tx, rx DMA buffers which can fail. Further, these buffers are used without a check. The patch checks for these failures and sends the error upstream.
Signed-off-by: Aditya Pakki pakki001@umn.edu Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi-topcliff-pch.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/drivers/spi/spi-topcliff-pch.c b/drivers/spi/spi-topcliff-pch.c index c54ee66744710..fe707440f8c3b 100644 --- a/drivers/spi/spi-topcliff-pch.c +++ b/drivers/spi/spi-topcliff-pch.c @@ -1306,18 +1306,27 @@ static void pch_free_dma_buf(struct pch_spi_board_data *board_dat, return; }
-static void pch_alloc_dma_buf(struct pch_spi_board_data *board_dat, +static int pch_alloc_dma_buf(struct pch_spi_board_data *board_dat, struct pch_spi_data *data) { struct pch_spi_dma_ctrl *dma; + int ret;
dma = &data->dma; + ret = 0; /* Get Consistent memory for Tx DMA */ dma->tx_buf_virt = dma_alloc_coherent(&board_dat->pdev->dev, PCH_BUF_SIZE, &dma->tx_buf_dma, GFP_KERNEL); + if (!dma->tx_buf_virt) + ret = -ENOMEM; + /* Get Consistent memory for Rx DMA */ dma->rx_buf_virt = dma_alloc_coherent(&board_dat->pdev->dev, PCH_BUF_SIZE, &dma->rx_buf_dma, GFP_KERNEL); + if (!dma->rx_buf_virt) + ret = -ENOMEM; + + return ret; }
static int pch_spi_pd_probe(struct platform_device *plat_dev) @@ -1394,7 +1403,9 @@ static int pch_spi_pd_probe(struct platform_device *plat_dev)
if (use_dma) { dev_info(&plat_dev->dev, "Use DMA for data transfers\n"); - pch_alloc_dma_buf(board_dat, data); + ret = pch_alloc_dma_buf(board_dat, data); + if (ret) + goto err_spi_register_master; }
ret = spi_register_master(master);
[ Upstream commit 26843bb128590edd7eba1ad7ce22e4b9f1066ce3 ]
While the sequencer is reset after each SPI message since commit 880c6d114fd79a69 ("spi: rspi: Add support for Quad and Dual SPI Transfers on QSPI"), it was never reset for the first message, thus relying on reset state or bootloader settings.
Fix this by initializing it explicitly during configuration.
Fixes: 0b2182ddac4b8837 ("spi: add support for Renesas RSPI") Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi-rspi.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index 093c9cf92bfd3..07612e8c58ee8 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c @@ -279,7 +279,8 @@ static int rspi_set_config_register(struct rspi_data *rspi, int access_size) /* Sets parity, interrupt mask */ rspi_write8(rspi, 0x00, RSPI_SPCR2);
- /* Sets SPCMD */ + /* Resets sequencer */ + rspi_write8(rspi, 0, RSPI_SPSCR); rspi->spcmd |= SPCMD_SPB_8_TO_16(access_size); rspi_write16(rspi, rspi->spcmd, RSPI_SPCMD0);
@@ -323,7 +324,8 @@ static int rspi_rz_set_config_register(struct rspi_data *rspi, int access_size) rspi_write8(rspi, 0x00, RSPI_SSLND); rspi_write8(rspi, 0x00, RSPI_SPND);
- /* Sets SPCMD */ + /* Resets sequencer */ + rspi_write8(rspi, 0, RSPI_SPSCR); rspi->spcmd |= SPCMD_SPB_8_TO_16(access_size); rspi_write16(rspi, rspi->spcmd, RSPI_SPCMD0);
@@ -374,7 +376,8 @@ static int qspi_set_config_register(struct rspi_data *rspi, int access_size) /* Sets buffer to allow normal operation */ rspi_write8(rspi, 0x00, QSPI_SPBFCR);
- /* Sets SPCMD */ + /* Resets sequencer */ + rspi_write8(rspi, 0, RSPI_SPSCR); rspi_write16(rspi, rspi->spcmd, RSPI_SPCMD0);
/* Enables SPI function in master mode */
[ Upstream commit 5442dcaa0d90fc376bdfc179a018931a8f43dea4 ]
This fixes a bug for messages containing both zero length and unidirectional xfers.
The function spi_map_msg will allocate dummy tx and/or rx buffers for use with unidirectional transfers when the hardware can only do a bidirectional transfer. That dummy buffer will be used in place of a NULL buffer even when the xfer length is 0.
Then in the function __spi_map_msg, if he hardware can dma, the zero length xfer will have spi_map_buf called on the dummy buffer.
Eventually, __sg_alloc_table is called and returns -EINVAL because nents == 0.
This fix prevents the error by not using the dummy buffer when the xfer length is zero.
Signed-off-by: Chris Lesiak chris.lesiak@licor.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index c2e85e23d538e..d74d341f9890d 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -955,6 +955,8 @@ static int spi_map_msg(struct spi_master *master, struct spi_message *msg) if (max_tx || max_rx) { list_for_each_entry(xfer, &msg->transfers, transfer_list) { + if (!xfer->len) + continue; if (!xfer->tx_buf) xfer->tx_buf = master->dummy_tx; if (!xfer->rx_buf)
[ Upstream commit 8ca5104715cfd14254ea5aecc390ae583b707607 ]
Building with clang shows a variable that is only used by the suspend/resume functions but defined outside of their #ifdef block:
sound/soc/ti/davinci-mcasp.c:48:12: error: variable 'context_regs' is not needed and will not be emitted
We commonly fix these by marking the PM functions as __maybe_unused, but here that would grow the davinci_mcasp structure, so instead add another #ifdef here.
Fixes: 1cc0c054f380 ("ASoC: davinci-mcasp: Convert the context save/restore to use array") Signed-off-by: Arnd Bergmann arnd@arndb.de Acked-by: Peter Ujfalusi peter.ujfalusi@ti.com Reviewed-by: Nathan Chancellor natechancellor@gmail.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/davinci/davinci-mcasp.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 3c5a9804d3f5e..5a0b17ebfc025 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -43,6 +43,7 @@
#define MCASP_MAX_AFIFO_DEPTH 64
+#ifdef CONFIG_PM static u32 context_regs[] = { DAVINCI_MCASP_TXFMCTL_REG, DAVINCI_MCASP_RXFMCTL_REG, @@ -65,6 +66,7 @@ struct davinci_mcasp_context { u32 *xrsr_regs; /* for serializer configuration */ bool pm_state; }; +#endif
struct davinci_mcasp_ruledata { struct davinci_mcasp *mcasp;
[ Upstream commit 60b801999c48b6c1dd04e653a38e2e613664264e ]
After an event is sent, we try to copy it into the user buffer of the first waiter in drm_read() and if the user buffer doesn't have enough room we put it back onto the list. However, we didn't wake up any subsequent waiter, so that event may sit on the list until either a new vblank event is sent or a new waiter appears. Rare, but in the worst case may lead to a stuck process.
Testcase: igt/drm_read/short-buffer-wakeup Signed-off-by: Chris Wilson chris@chris-wilson.co.uk Cc: Daniel Vetter daniel.vetter@ffwll.ch Reviewed-by: Ville Syrjälä ville.syrjala@linux.intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20170804082328.17173-1-chris@c... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/drm_fops.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index c37b7b5f1dd31..921f7f690ae9b 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c @@ -515,6 +515,7 @@ ssize_t drm_read(struct file *filp, char __user *buffer, file_priv->event_space -= length; list_add(&e->link, &file_priv->event_list); spin_unlock_irq(&dev->event_lock); + wake_up_interruptible(&file_priv->event_wait); break; }
stable-rc/linux-4.9.y boot: 103 boots: 0 failed, 103 passed (v4.9.179-129-g545b59ea794c)
Full Boot Summary: https://kernelci.org/boot/all/job/stable-rc/branch/linux-4.9.y/kernel/v4.9.1... Full Build Summary: https://kernelci.org/build/stable-rc/branch/linux-4.9.y/kernel/v4.9.179-129-...
Tree: stable-rc Branch: linux-4.9.y Git Describe: v4.9.179-129-g545b59ea794c Git Commit: 545b59ea794cfbac3646ccfab4a34c9f7753621e Git URL: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git Tested: 49 unique boards, 21 SoC families, 15 builds out of 197
--- For more info write to info@kernelci.org
On 30/05/2019 04:05, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.9.180 release. There are 128 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sat 01 Jun 2019 03:02:06 AM UTC. 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.9.180-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.9.y and the diffstat can be found below.
thanks,
greg k-h
All tests are passing for Tegra ...
Test results for stable-v4.9: 8 builds: 8 pass, 0 fail 16 boots: 16 pass, 0 fail 24 tests: 24 pass, 0 fail
Linux version: 4.9.180-rc1-g545b59e Boards tested: tegra124-jetson-tk1, tegra20-ventana, tegra210-p2371-2180, tegra30-cardhu-a04
Cheers Jon
On Thu, 30 May 2019 at 08:59, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 4.9.180 release. There are 128 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sat 01 Jun 2019 03:02:06 AM UTC. 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.9.180-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.9.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.9.180-rc1 git repo: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git git branch: linux-4.9.y git commit: 545b59ea794cfbac3646ccfab4a34c9f7753621e git describe: v4.9.179-129-g545b59ea794c Test details: https://qa-reports.linaro.org/lkft/linux-stable-rc-4.9-oe/build/v4.9.179-129...
No regressions (compared to build v4.9.179)
No fixes (compared to build v4.9.179)
Ran 18444 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 * ltp-cap_bounds-tests * ltp-commands-tests * ltp-containers-tests * ltp-cpuhotplug-tests * ltp-cve-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-hugetlb-tests * ltp-io-tests * ltp-ipc-tests * ltp-math-tests * ltp-mm-tests * ltp-nptl-tests * ltp-pty-tests * ltp-sched-tests * ltp-securebits-tests * ltp-syscalls-tests * ltp-timers-tests * perf * spectre-meltdown-checker-test * v4l2-compliance * ltp-open-posix-tests * network-basic-tests * kselftest-vsyscall-mode-native * kselftest-vsyscall-mode-none * kvm-unit-tests * prep-tmp-disk
On Wed, May 29, 2019 at 08:05:32PM -0700, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.9.180 release. There are 128 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sat 01 Jun 2019 03:02:06 AM UTC. Anything received after that time might be too late.
Build results: total: 172 pass: 172 fail: 0 Qemu test results: total: 320 pass: 320 fail: 0
Guenter
On 5/29/19 9:05 PM, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.9.180 release. There are 128 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sat 01 Jun 2019 03:02:06 AM UTC. 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.9.180-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.9.y and the diffstat can be found below.
thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks, -- Shuah
linux-stable-mirror@lists.linaro.org