This is the start of the stable review cycle for the 4.20.1 release. There are 145 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed Jan 9 10:43:39 UTC 2019. 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.20.1-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.20.y and the diffstat can be found below.
thanks,
greg k-h
------------- Pseudo-Shortlog of commits:
Greg Kroah-Hartman gregkh@linuxfoundation.org Linux 4.20.1-rc1
Tomas Winkler tomas.winkler@intel.com tpm: tpm_i2c_nuvoton: use correct command duration for TPM 2.x
Tomas Winkler tomas.winkler@intel.com tpm: tpm_try_transmit() refactor error flow.
Helge Deller deller@gmx.de parisc: Remap hugepage-aligned pages in set_kernel_text_rw()
Will Deacon will.deacon@arm.com arm64: compat: Don't pull syscall number from regs in arm_compat_syscall
Will Deacon will.deacon@arm.com arm64: compat: Avoid sending SIGILL for unallocated syscall numbers
Robin Murphy robin.murphy@arm.com iommu/arm-smmu-v3: Fix big-endian CMD_SYNC writes
Gustavo A. R. Silva gustavo@embeddedor.com KVM: arm/arm64: vgic: Fix off-by-one bug in vgic_get_irq()
Christoffer Dall christoffer.dall@arm.com KVM: arm/arm64: Fix VMID alloc race by reverting to lock-less
Christoffer Dall christoffer.dall@arm.com KVM: arm/arm64: vgic-v2: Set active_source to 0 when restoring state
Marc Zyngier marc.zyngier@arm.com KVM: arm/arm64: vgic: Cap SPIs to the VM-defined maximum
Julien Thierry julien.thierry@arm.com KVM: arm/arm64: vgic: Do not cond_resched_lock() with IRQs disabled
Maciej W. Rozycki macro@linux-mips.org rtc: m41t80: Correct alarm month range with RTC reads
Sylwester Nawrocki s.nawrocki@samsung.com ARM: dts: exynos: Specify I2S assigned clocks in proper node
Marc Zyngier marc.zyngier@arm.com arm/arm64: KVM: vgic: Force VM halt when changing the active state of GICv3 PPIs/SGIs
Will Deacon will.deacon@arm.com arm64: KVM: Avoid setting the upper 32 bits of VTCR_EL2 to 1
Long Li longli@microsoft.com CIFS: use the correct length when pinning memory for direct I/O for write
Long Li longli@microsoft.com CIFS: return correct errors when pinning memory failed for direct I/O
Paul Aurich paul@darkrain42.org smb3: fix large reads on encrypted connections
Georgy A Bystrenin gkot@altlinux.org CIFS: Fix error mapping for SMB2_LOCK command which caused OFD lock problem
Huacai Chen chenhc@lemote.com MIPS: Fix a R10000_LLSC_WAR logic in atomic.h
Aaro Koskinen aaro.koskinen@iki.fi MIPS: OCTEON: mark RGMII interface disabled on OCTEON III
Paul Burton paul.burton@mips.com MIPS: Expand MIPS32 ASIDs to 64 bits
Huacai Chen chenhc@lemote.com MIPS: Align kernel load address to 64KB
Huacai Chen chenhc@lemote.com MIPS: Ensure pmd_present() returns false after pmd_mknotpresent()
Huacai Chen chenhc@lemote.com MIPS: c-r4k: Add r4k_blast_scache_node for Loongson-3
Paul Burton paul.burton@mips.com MIPS: math-emu: Write-protect delay slot emulation pages
Steven Rostedt (VMware) rostedt@goodmis.org tools lib traceevent: Fix processing of dereferenced args in bprintk events
Ondrej Jirman megous@megous.com media: v4l2-fwnode: Fix setting V4L2_MBUS_DATA_ACTIVE_HIGH/LOW flag
Hans Verkuil hverkuil-cisco@xs4all.nl media: v4l2-tpg: array index could become negative
Hans Verkuil hverkuil-cisco@xs4all.nl media: vb2: check memory model for VIDIOC_CREATE_BUFS
Hans Verkuil hverkuil-cisco@xs4all.nl media: vim2m: use cancel_delayed_work_sync instead of flush_schedule_work
Hans Verkuil hverkuil-cisco@xs4all.nl media: vivid: free bitmap_cap when updating std/timings/etc.
Luca Ceresoli luca@lucaceresoli.net media: imx274: fix stack corruption in imx274_read_reg
Sean Young sean@mess.org media: rc: cec devices do not have a lirc chardev
Hans Verkuil hverkuil@xs4all.nl media: cec-pin: fix broken tx_ignore_nack_until_eom error injection
Hans Verkuil hverkuil-cisco@xs4all.nl media: cec: keep track of outstanding transmits
Nava kishore Manne nava.manne@xilinx.com serial: uartps: Fix interrupt mask issue to handle the RX interrupts properly
Jaegeuk Kim jaegeuk@kernel.org f2fs: sanity check of xattr entry size
Martin Blumenstingl martin.blumenstingl@googlemail.com f2fs: fix validation of the block count in sanity_check_raw_super
Jaegeuk Kim jaegeuk@kernel.org f2fs: fix missing unlock(sbi->gc_mutex)
Jia Zhu zhujia13@huawei.com f2fs: fix to update new block address correctly for OPU
Pan Bian bianpan2016@163.com f2fs: read page index before freeing
Breno Leitao leitao@debian.org powerpc/tm: Unset MSR[TS] if not recheckpointing
Breno Leitao leitao@debian.org powerpc/tm: Set MSR[TS] just prior to recheckpoint
Eric Biggers ebiggers@google.com KEYS: fix parsing invalid pkey info string
Lyude Paul lyude@redhat.com brcmfmac: Fix out of bounds memory access during fw load
Stijn Tintel stijn@linux-ipv6.be brcmfmac: fix roamoff=1 modparam
Filipe Manana fdmanana@suse.com Btrfs: send, fix race with transaction commits that create snapshots
Josef Bacik jbacik@fb.com btrfs: run delayed items before dropping the snapshot
Filipe Manana fdmanana@suse.com Btrfs: fix fsync of files with multiple hard links in new directories
Lu Fengqi lufq.fnst@cn.fujitsu.com btrfs: skip file_extent generation check for free_space_inode in run_delalloc_nocow
Filipe Manana fdmanana@suse.com Btrfs: fix deadlock with memory reclaim during scrub
Anand Jain anand.jain@oracle.com btrfs: dev-replace: go back to suspend state if another EXCL_OP is running
Anand Jain anand.jain@oracle.com btrfs: dev-replace: go back to suspended state if target device is missing
Macpaul Lin macpaul.lin@mediatek.com cdc-acm: fix abnormal DATA RX issue for Mediatek Preloader.
Todd Kjos tkjos@android.com binder: fix use-after-free due to ksys_close() during fdget()
Tejun Heo tj@kernel.org cgroup: fix CSS_TASK_ITER_PROCS
Dmitry Eremin-Solenikov dbaryshkov@gmail.com crypto: cfb - fix decryption
Dmitry Eremin-Solenikov dbaryshkov@gmail.com crypto: testmgr - add AES-CFB tests
Atul Gupta atul.gupta@chelsio.com crypto: chcr - small packet Tx stalls the queue
Wenwen Wang wang6495@umn.edu crypto: cavium/nitrox - fix a DMA pool free failure
Jernej Skrabec jernej.skrabec@siol.net clk: sunxi-ng: Use u64 for calculation of NM rate
Johan Jonker jbx9999@hotmail.com clk: rockchip: fix typo in rk3188 spdif_frac parent
Lukas Wunner lukas@wunner.de spi: bcm2835: Avoid finishing transfer prematurely in IRQ mode
Lukas Wunner lukas@wunner.de spi: bcm2835: Fix book-keeping of DMA termination
Lukas Wunner lukas@wunner.de spi: bcm2835: Fix race on DMA termination
Theodore Ts'o tytso@mit.edu ext4: check for shutdown and r/o file system in ext4_write_inode()
Theodore Ts'o tytso@mit.edu ext4: force inode writes when nfsd calls commit_metadata()
Theodore Ts'o tytso@mit.edu ext4: avoid declaring fs inconsistent due to invalid file handles
Theodore Ts'o tytso@mit.edu ext4: include terminating u32 in size of xattr entries when expanding inodes
ruippan (潘睿) ruippan@tencent.com ext4: fix EXT4_IOC_GROUP_ADD ioctl
Maurizio Lombardi mlombard@redhat.com ext4: missing unlock/put_page() in ext4_try_to_write_inline_data()
Pan Bian bianpan2016@163.com ext4: fix possible use after free in ext4_quota_enable
Theodore Ts'o tytso@mit.edu ext4: add ext4_sb_bread() to disambiguate ENOMEM cases
Greg Kurz groug@kaod.org ocxl: Fix endiannes bug in read_afu_name()
Greg Kurz groug@kaod.org ocxl: Fix endiannes bug in ocxl_link_update_pe()
Arnaldo Carvalho de Melo acme@redhat.com perf env: Also consider env->arch == NULL as local operation
Ben Hutchings ben@decadent.org.uk perf pmu: Suppress potential format-truncation warning
Adrian Hunter adrian.hunter@intel.com perf script: Use fallbacks for branch stacks
Adrian Hunter adrian.hunter@intel.com perf tools: Use fallback for sample_addr_correlates_sym() cases
Adrian Hunter adrian.hunter@intel.com perf thread: Add fallback functions for cases where cpumode is insufficient
Adrian Hunter adrian.hunter@intel.com perf machine: Record if a arch has a single user/kernel address space
Alexey Brodkin alexey.brodkin@synopsys.com clocksource/drivers/arc_timer: Utilize generic sched_clock
Eugeniy Paltsev Eugeniy.Paltsev@synopsys.com DRM: UDL: get rid of useless vblank initialization
Eric Anholt eric@anholt.net drm/v3d: Skip debugfs dumping GCA on platforms without GCA.
Miquel Raynal miquel.raynal@bootlin.com platform-msi: Free descriptors in platform_msi_domain_free()
Sean Christopherson sean.j.christopherson@intel.com KVM: nVMX: Free the VMREAD/VMWRITE bitmaps if alloc_kvm_area() fails
Paul Mackerras paulus@ozlabs.org KVM: PPC: Book3S HV: Fix race between kvm_unmap_hva_range and MMU mode switch
Marc Zyngier marc.zyngier@arm.com arm64: KVM: Make VHE Stage-2 TLB invalidation operations non-interruptible
Sean Christopherson sean.j.christopherson@intel.com KVM: x86: Use jmp to invoke kvm_spurious_fault() from .fixup
Dan Williams dan.j.williams@intel.com x86/mm: Drop usage of __flush_tlb_all() in kernel_physical_mapping_init()
Michal Hocko mhocko@suse.com x86/speculation/l1tf: Drop the swap storage limit restriction when l1tf=off
Patrick Dreyer Patrick@Dreyer.name Input: elan_i2c - add ACPI ID for touchpad in ASUS Aspire F5-573G
Sanjeev Chugh sanjeev_chugh@mentor.com Input: atmel_mxt_ts - don't try to free unallocated kernel memory
Sebastian Ott sebott@linux.ibm.com s390/pci: fix sleeping in atomic during hotplug
Hans de Goede hdegoede@redhat.com ASoC: intel: cht_bsw_max98090_ti: Add pmc_plt_clk_0 quirk for Chromebook Gnawty
Hans de Goede hdegoede@redhat.com ASoC: intel: cht_bsw_max98090_ti: Add pmc_plt_clk_0 quirk for Chromebook Clapper
Dan Carpenter dan.carpenter@oracle.com staging: bcm2835-audio: double free in init error path
Colin Ian King colin.king@canonical.com staging: wilc1000: fix missing read_write setting when reading data
Linus Torvalds torvalds@linux-foundation.org i915: fix missing user_access_end() in page fault exception case
Malcolm Priestley tvboxspy@gmail.com media: dvb-usb-v2: Fix incorrect use of transfer_flags URB_FREE_BUFFER
Heikki Krogerus heikki.krogerus@linux.intel.com usb: roles: Add a description for the class to Kconfig
Stephan Gerhold stephan@gerhold.net Revert "usb: dwc3: pci: Use devm functions to get the phy GPIOs"
Martin Blumenstingl martin.blumenstingl@googlemail.com usb: dwc2: disable power_down on Amlogic devices
Jia-Ju Bai baijiaju1990@gmail.com usb: r8a66597: Fix a possible concurrency use-after-free bug in r8a66597_endpoint_disable()
Jörgen Storvist jorgen.storvist@gmail.com USB: serial: option: add Fibocom NL678 series
Scott Chen scott@labau.com.tw USB: serial: pl2303: add ids for Hewlett-Packard HP POS pole displays
Terin Stock terin@terinstock.com usb: dwc2: host: use hrtimer for NAK retries
Sameer Pujar spujar@nvidia.com ALSA: hda/tegra: clear pending irq handlers
Jian-Hong Pan jian-hong@endlessm.com ALSA: hda/realtek: Enable the headset mic auto detection for ASUS laptops
Takashi Sakamoto o-takashi@sakamocchi.jp ALSA: firewire-lib: use the same print format for 'without_header' tracepoints
Takashi Sakamoto o-takashi@sakamocchi.jp ALSA: firewire-lib: fix wrong assignment for 'out_packet_without_header' tracepoint
Takashi Sakamoto o-takashi@sakamocchi.jp ALSA: firewire-lib: fix wrong handling payload_length as payload_quadlet
Takashi Sakamoto o-takashi@sakamocchi.jp ALSA: fireface: fix for state to fetch PCM frames
Wandrille RONCE w@ndrille.fr ALSA: hda/realtek: Enable audio jacks of ASUS UX391UA with ALC294
Mantas Mikulėnas grawity@gmail.com ALSA: hda: add mute LED support for HP EliteBook 840 G4
Boris Brezillon boris.brezillon@bootlin.com mtd: rawnand: omap2: Pass the parent of pdev to dma_request_chan()
Boris Brezillon boris.brezillon@bootlin.com mtd: rawnand: Fix JEDEC detection
Miquel Raynal miquel.raynal@bootlin.com mtd: rawnand: marvell: prevent timeouts on a loaded machine
Arnd Bergmann arnd@arndb.de mtd: atmel-quadspi: disallow building on ebsa110
Diana Craciun diana.craciun@nxp.com powerpc/fsl: Fix spectre_v2 mitigations reporting
Gustavo A. R. Silva gustavo@embeddedor.com ALSA: emux: Fix potential Spectre v1 vulnerabilities
Gustavo A. R. Silva gustavo@embeddedor.com ALSA: pcm: Fix potential Spectre v1 vulnerability
Gustavo A. R. Silva gustavo@embeddedor.com ALSA: emu10k1: Fix potential Spectre v1 vulnerabilities
Gustavo A. R. Silva gustavo@embeddedor.com ALSA: rme9652: Fix potential Spectre v1 vulnerability
Michael J. Ruhl michael.j.ruhl@intel.com IB/hfi1: Incorrect sizing of sge for PIO will OOPs
Cong Wang xiyou.wangcong@gmail.com tipc: fix a double free in tipc_enable_bearer()
Deepa Dinamani deepa.kernel@gmail.com sock: Make sock->sk_stamp thread-safe
Cong Wang xiyou.wangcong@gmail.com ptr_ring: wrap back ->producer in __ptr_ring_swap_queue()
Gustavo A. R. Silva gustavo@embeddedor.com phonet: af_phonet: Fix Spectre v1 vulnerability
Willem de Bruijn willemb@google.com packet: validate address length if non-zero
Cong Wang xiyou.wangcong@gmail.com net/wan: fix a double free in x25_asy_open_tty()
Cong Wang xiyou.wangcong@gmail.com netrom: fix locking in nr_find_socket()
Eric Dumazet edumazet@google.com isdn: fix kernel-infoleak in capi_unlocked_ioctl
Eric Dumazet edumazet@google.com net/hamradio/6pack: use mod_timer() to rearm timers
Gustavo A. R. Silva gustavo@embeddedor.com net: core: Fix Spectre v1 vulnerability
Willem de Bruijn willemb@google.com ip: validate header length on virtual device xmit
Willem de Bruijn willemb@google.com ieee802154: lowpan_header_create check must check daddr
Tyrel Datwyler tyreld@linux.vnet.ibm.com ibmveth: fix DMA unmap error in ibmveth_xmit_start error path
Cong Wang xiyou.wangcong@gmail.com ax25: fix a use-after-free in ax25_fillin_cb()
Willem de Bruijn willemb@google.com tap: call skb_probe_transport_header after setting skb->dev
Ivan Mironov mironov.ivan@gmail.com bnx2x: Fix NULL pointer dereference in bnx2x_del_all_vlans() on some hw
Jacopo Mondi jacopo+renesas@jmondi.org media: ov5640: Fix set format regression
Ihab Zhaika ihab.zhaika@intel.com iwlwifi: add new cards for 9560, 9462, 9461 and killer series
Sergey Senozhatsky sergey.senozhatsky.work@gmail.com panic: avoid deadlocks in re-entrant console drivers
-------------
Diffstat:
Documentation/admin-guide/kernel-parameters.txt | 3 + Documentation/admin-guide/l1tf.rst | 6 +- Makefile | 4 +- arch/arc/Kconfig | 1 + arch/arm/boot/dts/exynos5422-odroidxu3-audio.dtsi | 9 ++- arch/arm/boot/dts/exynos5422-odroidxu4.dts | 9 ++- arch/arm64/include/asm/kvm_arm.h | 2 +- arch/arm64/include/asm/unistd.h | 5 +- arch/arm64/kernel/sys_compat.c | 11 ++- arch/arm64/kernel/syscall.c | 9 ++- arch/arm64/kvm/hyp/tlb.c | 35 ++++++--- arch/mips/boot/compressed/calc_vmlinuz_load_addr.c | 7 +- arch/mips/cavium-octeon/executive/cvmx-helper.c | 3 +- arch/mips/include/asm/atomic.h | 2 +- arch/mips/include/asm/cpu-info.h | 2 +- arch/mips/include/asm/mach-generic/mmzone.h | 2 + arch/mips/include/asm/mach-loongson64/mmzone.h | 1 + arch/mips/include/asm/mmu.h | 2 +- arch/mips/include/asm/mmu_context.h | 10 ++- arch/mips/include/asm/mmzone.h | 8 +++ arch/mips/include/asm/pgtable-64.h | 5 ++ arch/mips/include/asm/r4kcache.h | 22 ++++++ arch/mips/kernel/vdso.c | 4 +- arch/mips/math-emu/dsemul.c | 38 +++++----- arch/mips/mm/c-r3k.c | 2 +- arch/mips/mm/c-r4k.c | 44 ++++++++++-- arch/parisc/mm/init.c | 4 +- arch/powerpc/kernel/security.c | 2 +- arch/powerpc/kernel/signal_32.c | 38 ++++++++-- arch/powerpc/kernel/signal_64.c | 64 ++++++++++++----- arch/powerpc/kvm/book3s_64_mmu_hv.c | 3 + arch/powerpc/kvm/book3s_hv.c | 17 +++-- arch/s390/pci/pci_clp.c | 2 +- arch/x86/include/asm/kvm_host.h | 2 +- arch/x86/kernel/cpu/bugs.c | 3 +- arch/x86/kvm/vmx.c | 7 +- arch/x86/mm/init.c | 2 +- arch/x86/mm/init_64.c | 6 -- crypto/cfb.c | 2 +- crypto/tcrypt.c | 5 ++ crypto/testmgr.c | 7 ++ crypto/testmgr.h | 76 ++++++++++++++++++++ drivers/android/binder.c | 63 +++++++++++++++- drivers/base/platform-msi.c | 6 +- drivers/char/tpm/tpm-interface.c | 15 ++-- drivers/char/tpm/tpm_i2c_nuvoton.c | 11 +-- drivers/clk/rockchip/clk-rk3188.c | 2 +- drivers/clk/sunxi-ng/ccu_nm.c | 18 ++++- drivers/clocksource/Kconfig | 1 + drivers/clocksource/arc_timer.c | 22 ++++++ drivers/crypto/cavium/nitrox/nitrox_algs.c | 12 ++-- drivers/crypto/cavium/nitrox/nitrox_lib.c | 22 ++++-- drivers/crypto/cavium/nitrox/nitrox_req.h | 7 ++ drivers/crypto/chelsio/chcr_ipsec.c | 5 +- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 1 + drivers/gpu/drm/udl/udl_main.c | 7 +- drivers/gpu/drm/v3d/v3d_debugfs.c | 11 +-- drivers/infiniband/hw/hfi1/verbs.c | 2 + drivers/input/mouse/elan_i2c_core.c | 1 + drivers/input/touchscreen/atmel_mxt_ts.c | 4 +- drivers/iommu/arm-smmu-v3.c | 8 ++- drivers/isdn/capi/kcapi.c | 4 +- drivers/media/cec/cec-adap.c | 27 ++++--- drivers/media/cec/cec-pin.c | 5 +- drivers/media/common/v4l2-tpg/v4l2-tpg-core.c | 2 +- drivers/media/common/videobuf2/videobuf2-core.c | 3 + drivers/media/i2c/imx274.c | 7 +- drivers/media/i2c/ov5640.c | 17 +++-- drivers/media/platform/vim2m.c | 3 +- drivers/media/platform/vivid/vivid-vid-cap.c | 2 + drivers/media/rc/rc-main.c | 6 +- drivers/media/usb/dvb-usb-v2/usb_urb.c | 5 +- drivers/media/v4l2-core/v4l2-fwnode.c | 4 +- drivers/misc/ocxl/config.c | 2 +- drivers/misc/ocxl/link.c | 2 +- drivers/mtd/nand/raw/marvell_nand.c | 17 ++++- drivers/mtd/nand/raw/nand_jedec.c | 2 + drivers/mtd/nand/raw/omap2.c | 2 +- drivers/mtd/spi-nor/Kconfig | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 14 ++-- drivers/net/ethernet/ibm/ibmveth.c | 6 +- drivers/net/hamradio/6pack.c | 16 ++--- drivers/net/tap.c | 3 +- drivers/net/wan/x25_asy.c | 2 + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 11 ++- .../broadcom/brcm80211/brcmfmac/cfg80211.h | 2 +- .../wireless/broadcom/brcm80211/brcmfmac/core.c | 2 +- .../broadcom/brcm80211/brcmfmac/firmware.c | 8 ++- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 50 +++++++++++++ drivers/rtc/rtc-m41t80.c | 2 +- drivers/spi/spi-bcm2835.c | 14 ++-- .../vc04_services/bcm2835-audio/bcm2835-vchiq.c | 1 - drivers/staging/wilc1000/wilc_sdio.c | 1 + drivers/tty/serial/xilinx_uartps.c | 4 +- drivers/usb/Kconfig | 4 -- drivers/usb/class/cdc-acm.c | 10 +++ drivers/usb/class/cdc-acm.h | 1 + drivers/usb/common/Makefile | 1 - drivers/usb/dwc2/hcd.h | 2 +- drivers/usb/dwc2/hcd_queue.c | 19 +++-- drivers/usb/dwc2/params.c | 1 + drivers/usb/dwc3/dwc3-pci.c | 8 +-- drivers/usb/host/r8a66597-hcd.c | 5 +- drivers/usb/roles/Kconfig | 13 ++++ drivers/usb/roles/Makefile | 4 +- drivers/usb/{common/roles.c => roles/class.c} | 0 drivers/usb/serial/option.c | 4 ++ drivers/usb/serial/pl2303.c | 5 ++ drivers/usb/serial/pl2303.h | 5 ++ fs/btrfs/btrfs_inode.h | 6 ++ fs/btrfs/ctree.c | 29 ++++++-- fs/btrfs/dev-replace.c | 6 ++ fs/btrfs/extent-tree.c | 4 ++ fs/btrfs/inode.c | 20 +++++- fs/btrfs/scrub.c | 35 ++++++++- fs/btrfs/tree-log.c | 16 +++++ fs/cifs/file.c | 12 +++- fs/cifs/smb2maperror.c | 4 +- fs/cifs/smb2ops.c | 4 +- fs/ext4/ext4.h | 17 ++++- fs/ext4/ialloc.c | 2 +- fs/ext4/inline.c | 5 +- fs/ext4/inode.c | 63 +++++++++++----- fs/ext4/ioctl.c | 2 +- fs/ext4/migrate.c | 36 +++++----- fs/ext4/namei.c | 4 +- fs/ext4/resize.c | 79 ++++++++++---------- fs/ext4/super.c | 55 ++++++++++---- fs/ext4/xattr.c | 83 +++++++++++----------- fs/f2fs/data.c | 4 +- fs/f2fs/node.c | 4 +- fs/f2fs/super.c | 13 ++-- fs/f2fs/xattr.c | 18 +++-- fs/file.c | 29 ++++++++ include/linux/fdtable.h | 1 + include/linux/msi.h | 2 + include/linux/ptr_ring.h | 2 + include/media/cec.h | 1 + include/net/ip_tunnels.h | 20 ++++++ include/net/sock.h | 38 +++++++++- include/trace/events/ext4.h | 20 ++++++ kernel/cgroup/cgroup.c | 29 ++++---- kernel/panic.c | 6 +- net/ax25/af_ax25.c | 11 ++- net/ax25/ax25_dev.c | 2 + net/compat.c | 15 ++-- net/core/filter.c | 2 + net/core/sock.c | 15 ++-- net/ieee802154/6lowpan/tx.c | 3 + net/ipv4/ip_gre.c | 9 +++ net/ipv4/ip_tunnel.c | 9 --- net/ipv4/ip_vti.c | 12 +++- net/ipv6/ip6_gre.c | 10 ++- net/ipv6/ip6_tunnel.c | 10 +-- net/ipv6/ip6_vti.c | 8 +-- net/ipv6/ip6mr.c | 17 +++-- net/ipv6/sit.c | 3 + net/netrom/af_netrom.c | 15 ++-- net/packet/af_packet.c | 4 +- net/phonet/af_phonet.c | 3 + net/sunrpc/svcsock.c | 2 +- net/tipc/bearer.c | 1 - security/keys/keyctl_pkey.c | 2 + sound/core/pcm.c | 2 + sound/firewire/amdtp-stream-trace.h | 4 +- sound/firewire/amdtp-stream.c | 4 +- sound/firewire/fireface/ff-protocol-ff400.c | 2 +- sound/pci/emu10k1/emufx.c | 5 ++ sound/pci/hda/hda_tegra.c | 2 + sound/pci/hda/patch_conexant.c | 1 + sound/pci/hda/patch_realtek.c | 3 +- sound/pci/rme9652/hdsp.c | 10 +-- sound/soc/intel/boards/cht_bsw_max98090_ti.c | 14 ++++ sound/synth/emux/emux_hwdep.c | 7 +- tools/lib/traceevent/event-parse.c | 1 + tools/perf/arch/common.c | 10 +++ tools/perf/arch/common.h | 1 + tools/perf/builtin-script.c | 12 ++-- tools/perf/util/env.c | 2 +- tools/perf/util/event.c | 29 +++++++- tools/perf/util/machine.c | 27 +++++++ tools/perf/util/machine.h | 3 + tools/perf/util/pmu.c | 8 +-- .../util/scripting-engines/trace-event-python.c | 16 ++--- tools/perf/util/session.c | 4 ++ tools/perf/util/thread.h | 4 ++ virt/kvm/arm/arm.c | 23 +++--- virt/kvm/arm/vgic/vgic-mmio.c | 44 ++++++------ virt/kvm/arm/vgic/vgic.c | 6 +- 189 files changed, 1528 insertions(+), 572 deletions(-)
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sergey Senozhatsky sergey.senozhatsky.work@gmail.com
commit c7c3f05e341a9a2bd1a92993d4f996cfd6e7348e upstream.
From printk()/serial console point of view panic() is special, because
it may force CPU to re-enter printk() or/and serial console driver. Therefore, some of serial consoles drivers are re-entrant. E.g. 8250:
serial8250_console_write() { if (port->sysrq) locked = 0; else if (oops_in_progress) locked = spin_trylock_irqsave(&port->lock, flags); else spin_lock_irqsave(&port->lock, flags); ... }
panic() does set oops_in_progress via bust_spinlocks(1), so in theory we should be able to re-enter serial console driver from panic():
CPU0 <NMI> uart_console_write() serial8250_console_write() // if (oops_in_progress) // spin_trylock_irqsave() call_console_drivers() console_unlock() console_flush_on_panic() bust_spinlocks(1) // oops_in_progress++ panic() <NMI/> spin_lock_irqsave(&port->lock, flags) // spin_lock_irqsave() serial8250_console_write() call_console_drivers() console_unlock() printk() ...
However, this does not happen and we deadlock in serial console on port->lock spinlock. And the problem is that console_flush_on_panic() called after bust_spinlocks(0):
void panic(const char *fmt, ...) { bust_spinlocks(1); ... bust_spinlocks(0); console_flush_on_panic(); ... }
bust_spinlocks(0) decrements oops_in_progress, so oops_in_progress can go back to zero. Thus even re-entrant console drivers will simply spin on port->lock spinlock. Given that port->lock may already be locked either by a stopped CPU, or by the very same CPU we execute panic() on (for instance, NMI panic() on printing CPU) the system deadlocks and does not reboot.
Fix this by removing bust_spinlocks(0), so oops_in_progress is always set in panic() now and, thus, re-entrant console drivers will trylock the port->lock instead of spinning on it forever, when we call them from console_flush_on_panic().
Link: http://lkml.kernel.org/r/20181025101036.6823-1-sergey.senozhatsky@gmail.com Cc: Steven Rostedt rostedt@goodmis.org Cc: Daniel Wang wonderfly@google.com Cc: Peter Zijlstra peterz@infradead.org Cc: Andrew Morton akpm@linux-foundation.org Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: Alan Cox gnomes@lxorguk.ukuu.org.uk Cc: Jiri Slaby jslaby@suse.com Cc: Peter Feiner pfeiner@google.com Cc: linux-serial@vger.kernel.org Cc: Sergey Senozhatsky sergey.senozhatsky.work@gmail.com Cc: stable@vger.kernel.org Signed-off-by: Sergey Senozhatsky sergey.senozhatsky@gmail.com Signed-off-by: Petr Mladek pmladek@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- kernel/panic.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
--- a/kernel/panic.c +++ b/kernel/panic.c @@ -14,6 +14,7 @@ #include <linux/kmsg_dump.h> #include <linux/kallsyms.h> #include <linux/notifier.h> +#include <linux/vt_kern.h> #include <linux/module.h> #include <linux/random.h> #include <linux/ftrace.h> @@ -237,7 +238,10 @@ void panic(const char *fmt, ...) if (_crash_kexec_post_notifiers) __crash_kexec(NULL);
- bust_spinlocks(0); +#ifdef CONFIG_VT + unblank_screen(); +#endif + console_unblank();
/* * We may have ended up stopping the CPU holding the lock (in
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ihab Zhaika ihab.zhaika@intel.com
commit f108703cb5f199d0fc98517ac29a997c4c646c94 upstream.
add few PCI ID'S for 9560, 9462, 9461 and killer series.
Cc: stable@vger.kernel.org Signed-off-by: Ihab Zhaika ihab.zhaika@intel.com Signed-off-by: Luca Coelho luciano.coelho@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 50 ++++++++++++++++++++++++++ 1 file changed, 50 insertions(+)
--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -513,6 +513,56 @@ static const struct pci_device_id iwl_hw {IWL_PCI_DEVICE(0x24FD, 0x9074, iwl8265_2ac_cfg)},
/* 9000 Series */ + {IWL_PCI_DEVICE(0x02F0, 0x0030, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x02F0, 0x0034, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x02F0, 0x0038, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x02F0, 0x003C, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x02F0, 0x0060, iwl9461_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x02F0, 0x0064, iwl9461_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x02F0, 0x00A0, iwl9462_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x02F0, 0x00A4, iwl9462_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x02F0, 0x0230, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x02F0, 0x0234, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x02F0, 0x0238, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x02F0, 0x023C, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x02F0, 0x0260, iwl9461_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x02F0, 0x0264, iwl9461_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x02F0, 0x02A0, iwl9462_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x02F0, 0x02A4, iwl9462_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x02F0, 0x1551, iwl9560_killer_s_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x02F0, 0x1552, iwl9560_killer_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x02F0, 0x2030, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x02F0, 0x2034, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x02F0, 0x4030, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x02F0, 0x4034, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x02F0, 0x40A4, iwl9462_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x02F0, 0x4234, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x02F0, 0x42A4, iwl9462_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x06F0, 0x0030, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x06F0, 0x0034, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x06F0, 0x0038, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x06F0, 0x003C, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x06F0, 0x0060, iwl9461_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x06F0, 0x0064, iwl9461_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x06F0, 0x00A0, iwl9462_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x06F0, 0x00A4, iwl9462_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x06F0, 0x0230, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x06F0, 0x0234, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x06F0, 0x0238, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x06F0, 0x023C, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x06F0, 0x0260, iwl9461_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x06F0, 0x0264, iwl9461_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x06F0, 0x02A0, iwl9462_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x06F0, 0x02A4, iwl9462_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x06F0, 0x1551, iwl9560_killer_s_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x06F0, 0x1552, iwl9560_killer_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x06F0, 0x2030, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x06F0, 0x2034, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x06F0, 0x4030, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x06F0, 0x4034, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x06F0, 0x40A4, iwl9462_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x06F0, 0x4234, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x06F0, 0x42A4, iwl9462_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x2526, 0x0010, iwl9260_2ac_cfg)}, {IWL_PCI_DEVICE(0x2526, 0x0014, iwl9260_2ac_cfg)}, {IWL_PCI_DEVICE(0x2526, 0x0018, iwl9260_2ac_cfg)},
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jacopo Mondi jacopo+renesas@jmondi.org
commit 07115449919383548d094ff83cc27bd08639a8a1 upstream.
The set_fmt operations updates the sensor format only when the image format is changed. When only the image sizes gets changed, the format do not get updated causing the sensor to always report the one that was previously in use.
Without this patch, updating frame size only fails: [fmt:UYVY8_2X8/640x480@1/30 field:none colorspace:srgb xfer:srgb ...]
With this patch applied: [fmt:UYVY8_2X8/1024x768@1/30 field:none colorspace:srgb xfer:srgb ...]
Fixes: 6949d864776e ("media: ov5640: do not change mode if format or frame interval is unchanged")
Signed-off-by: Jacopo Mondi jacopo+renesas@jmondi.org Signed-off-by: Maxime Ripard maxime.ripard@bootlin.com Tested-by: Adam Ford aford173@gmail.com #imx6 w/ CSI2 interface on 4.19.6 and 4.20-RC5 Signed-off-by: Sakari Ailus sakari.ailus@linux.intel.com Signed-off-by: Mauro Carvalho Chehab mchehab+samsung@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/media/i2c/ov5640.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-)
--- a/drivers/media/i2c/ov5640.c +++ b/drivers/media/i2c/ov5640.c @@ -2020,6 +2020,7 @@ static int ov5640_set_fmt(struct v4l2_su struct ov5640_dev *sensor = to_ov5640_dev(sd); const struct ov5640_mode_info *new_mode; struct v4l2_mbus_framefmt *mbus_fmt = &format->format; + struct v4l2_mbus_framefmt *fmt; int ret;
if (format->pad != 0) @@ -2037,22 +2038,20 @@ static int ov5640_set_fmt(struct v4l2_su if (ret) goto out;
- if (format->which == V4L2_SUBDEV_FORMAT_TRY) { - struct v4l2_mbus_framefmt *fmt = - v4l2_subdev_get_try_format(sd, cfg, 0); + if (format->which == V4L2_SUBDEV_FORMAT_TRY) + fmt = v4l2_subdev_get_try_format(sd, cfg, 0); + else + fmt = &sensor->fmt;
- *fmt = *mbus_fmt; - goto out; - } + *fmt = *mbus_fmt;
if (new_mode != sensor->current_mode) { sensor->current_mode = new_mode; sensor->pending_mode_change = true; } - if (mbus_fmt->code != sensor->fmt.code) { - sensor->fmt = *mbus_fmt; + if (mbus_fmt->code != sensor->fmt.code) sensor->pending_fmt_change = true; - } + out: mutex_unlock(&sensor->lock); return ret;
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ivan Mironov mironov.ivan@gmail.com
[ Upstream commit 38355a5f9a22bfa5bd5b1bb79805aca39fa53729 ]
This happened when I tried to boot normal Fedora 29 system with latest available kernel (from fedora rawhide, plus some unrelated custom patches):
BUG: unable to handle kernel NULL pointer dereference at 0000000000000000 PGD 0 P4D 0 Oops: 0010 [#1] SMP PTI CPU: 6 PID: 1422 Comm: libvirtd Tainted: G I 4.20.0-0.rc7.git3.hpsa2.1.fc29.x86_64 #1 Hardware name: HP ProLiant BL460c G6, BIOS I24 05/21/2018 RIP: 0010: (null) Code: Bad RIP value. RSP: 0018:ffffa47ccdc9fbe0 EFLAGS: 00010246 RAX: 0000000000000000 RBX: 00000000000003e8 RCX: ffffa47ccdc9fbf8 RDX: ffffa47ccdc9fc00 RSI: ffff97d9ee7b01f8 RDI: ffff97d9f0150b80 RBP: ffff97d9f0150b80 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000003 R13: ffff97d9ef1e53e8 R14: 0000000000000009 R15: ffff97d9f0ac6730 FS: 00007f4d224ef700(0000) GS:ffff97d9fa200000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffffffffffffffd6 CR3: 00000011ece52006 CR4: 00000000000206e0 Call Trace: ? bnx2x_chip_cleanup+0x195/0x610 [bnx2x] ? bnx2x_nic_unload+0x1e2/0x8f0 [bnx2x] ? bnx2x_reload_if_running+0x24/0x40 [bnx2x] ? bnx2x_set_features+0x79/0xa0 [bnx2x] ? __netdev_update_features+0x244/0x9e0 ? netlink_broadcast_filtered+0x136/0x4b0 ? netdev_update_features+0x22/0x60 ? dev_disable_lro+0x1c/0xe0 ? devinet_sysctl_forward+0x1c6/0x211 ? proc_sys_call_handler+0xab/0x100 ? __vfs_write+0x36/0x1a0 ? rcu_read_lock_sched_held+0x79/0x80 ? rcu_sync_lockdep_assert+0x2e/0x60 ? __sb_start_write+0x14c/0x1b0 ? vfs_write+0x159/0x1c0 ? vfs_write+0xba/0x1c0 ? ksys_write+0x52/0xc0 ? do_syscall_64+0x60/0x1f0 ? entry_SYSCALL_64_after_hwframe+0x49/0xbe
After some investigation I figured out that recently added cleanup code tries to call VLAN filtering de-initialization function which exist only for newer hardware. Corresponding function pointer is not set (== 0) for older hardware, namely these chips:
#define CHIP_NUM_57710 0x164e #define CHIP_NUM_57711 0x164f #define CHIP_NUM_57711E 0x1650
And I have one of those in my test system:
Broadcom Inc. and subsidiaries NetXtreme II BCM57711E 10-Gigabit PCIe [14e4:1650]
Function bnx2x_init_vlan_mac_fp_objs() from drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h decides whether to initialize relevant pointers in bnx2x_sp_objs.vlan_obj or not.
This regression was introduced after v4.20-rc7, and still exists in v4.20 release.
Fixes: 04f05230c5c13 ("bnx2x: Remove configured vlans as part of unload sequence.") Signed-off-by: Ivan Mironov mironov.ivan@gmail.com Signed-off-by: Ivan Mironov mironov.ivan@gmail.com Acked-by: Sudarsana Kalluru Sudarsana.Kalluru@cavium.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -9360,10 +9360,16 @@ void bnx2x_chip_cleanup(struct bnx2x *bp BNX2X_ERR("Failed to schedule DEL commands for UC MACs list: %d\n", rc);
- /* Remove all currently configured VLANs */ - rc = bnx2x_del_all_vlans(bp); - if (rc < 0) - BNX2X_ERR("Failed to delete all VLANs\n"); + /* The whole *vlan_obj structure may be not initialized if VLAN + * filtering offload is not supported by hardware. Currently this is + * true for all hardware covered by CHIP_IS_E1x(). + */ + if (!CHIP_IS_E1x(bp)) { + /* Remove all currently configured VLANs */ + rc = bnx2x_del_all_vlans(bp); + if (rc < 0) + BNX2X_ERR("Failed to delete all VLANs\n"); + }
/* Disable LLH */ if (!CHIP_IS_E1(bp))
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Willem de Bruijn willemb@google.com
[ Upstream commit 8c76e77f9069f10505c08e02646c3ee11ad79038 ]
The BPF flow dissector expects either skb->sk or skb->dev set on all skbs. Delay flow dissection until after skb->dev is set.
This requires calling from within an rcu read-side critical section. That is fine, see also the call from tun_xdp_one.
Fixes: d0e13a1488ad ("flow_dissector: lookup netns by skb->sk if skb->dev is NULL") Reported-by: Christian Borntraeger borntraeger@de.ibm.com Signed-off-by: Willem de Bruijn willemb@google.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/tap.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
--- a/drivers/net/tap.c +++ b/drivers/net/tap.c @@ -1177,8 +1177,6 @@ static int tap_get_user_xdp(struct tap_q goto err_kfree; }
- skb_probe_transport_header(skb, ETH_HLEN); - /* Move network header to the right position for VLAN tagged packets */ if ((skb->protocol == htons(ETH_P_8021Q) || skb->protocol == htons(ETH_P_8021AD)) && @@ -1189,6 +1187,7 @@ static int tap_get_user_xdp(struct tap_q tap = rcu_dereference(q->tap); if (tap) { skb->dev = tap->dev; + skb_probe_transport_header(skb, ETH_HLEN); dev_queue_xmit(skb); } else { kfree_skb(skb);
On 07.01.2019 13:30, Greg Kroah-Hartman wrote:
4.20-stable review patch. If anyone has any objections, please let me know.
From: Willem de Bruijn willemb@google.com
[ Upstream commit 8c76e77f9069f10505c08e02646c3ee11ad79038 ]
The BPF flow dissector expects either skb->sk or skb->dev set on all skbs. Delay flow dissection until after skb->dev is set.
This requires calling from within an rcu read-side critical section. That is fine, see also the call from tun_xdp_one.
Fixes: d0e13a1488ad ("flow_dissector: lookup netns by skb->sk if skb->dev is NULL") Reported-by: Christian Borntraeger borntraeger@de.ibm.com Signed-off-by: Willem de Bruijn willemb@google.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
I can confirm that this fixes my issue.
Tested-by: Christian Borntraeger borntraeger@de.ibm.com
drivers/net/tap.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
--- a/drivers/net/tap.c +++ b/drivers/net/tap.c @@ -1177,8 +1177,6 @@ static int tap_get_user_xdp(struct tap_q goto err_kfree; }
- skb_probe_transport_header(skb, ETH_HLEN);
- /* Move network header to the right position for VLAN tagged packets */ if ((skb->protocol == htons(ETH_P_8021Q) || skb->protocol == htons(ETH_P_8021AD)) &&
@@ -1189,6 +1187,7 @@ static int tap_get_user_xdp(struct tap_q tap = rcu_dereference(q->tap); if (tap) { skb->dev = tap->dev;
dev_queue_xmit(skb); } else { kfree_skb(skb);skb_probe_transport_header(skb, ETH_HLEN);
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cong Wang xiyou.wangcong@gmail.com
[ Upstream commit c433570458e49bccea5c551df628d058b3526289 ]
There are multiple issues here:
1. After freeing dev->ax25_ptr, we need to set it to NULL otherwise we may use a dangling pointer.
2. There is a race between ax25_setsockopt() and device notifier as reported by syzbot. Close it by holding RTNL lock.
3. We need to test if dev->ax25_ptr is NULL before using it.
Reported-and-tested-by: syzbot+ae6bb869cbed29b29040@syzkaller.appspotmail.com Signed-off-by: Cong Wang xiyou.wangcong@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/ax25/af_ax25.c | 11 +++++++++-- net/ax25/ax25_dev.c | 2 ++ 2 files changed, 11 insertions(+), 2 deletions(-)
--- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c @@ -653,15 +653,22 @@ static int ax25_setsockopt(struct socket break; }
- dev = dev_get_by_name(&init_net, devname); + rtnl_lock(); + dev = __dev_get_by_name(&init_net, devname); if (!dev) { + rtnl_unlock(); res = -ENODEV; break; }
ax25->ax25_dev = ax25_dev_ax25dev(dev); + if (!ax25->ax25_dev) { + rtnl_unlock(); + res = -ENODEV; + break; + } ax25_fillin_cb(ax25, ax25->ax25_dev); - dev_put(dev); + rtnl_unlock(); break;
default: --- a/net/ax25/ax25_dev.c +++ b/net/ax25/ax25_dev.c @@ -116,6 +116,7 @@ void ax25_dev_device_down(struct net_dev if ((s = ax25_dev_list) == ax25_dev) { ax25_dev_list = s->next; spin_unlock_bh(&ax25_dev_lock); + dev->ax25_ptr = NULL; dev_put(dev); kfree(ax25_dev); return; @@ -125,6 +126,7 @@ void ax25_dev_device_down(struct net_dev if (s->next == ax25_dev) { s->next = ax25_dev->next; spin_unlock_bh(&ax25_dev_lock); + dev->ax25_ptr = NULL; dev_put(dev); kfree(ax25_dev); return;
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tyrel Datwyler tyreld@linux.vnet.ibm.com
[ Upstream commit 756af9c642329d54f048bac2a62f829b391f6944 ]
Commit 33a48ab105a7 ("ibmveth: Fix DMA unmap error") fixed an issue in the normal code path of ibmveth_xmit_start() that was originally introduced by Commit 6e8ab30ec677 ("ibmveth: Add scatter-gather support"). This original fix missed the error path where dma_unmap_page is wrongly called on the header portion in descs[0] which was mapped with dma_map_single. As a result a failure to DMA map any of the frags results in a dmesg warning when CONFIG_DMA_API_DEBUG is enabled.
------------[ cut here ]------------ DMA-API: ibmveth 30000002: device driver frees DMA memory with wrong function [device address=0x000000000a430000] [size=172 bytes] [mapped as page] [unmapped as single] WARNING: CPU: 1 PID: 8426 at kernel/dma/debug.c:1085 check_unmap+0x4fc/0xe10 ... <snip> ... DMA-API: Mapped at: ibmveth_start_xmit+0x30c/0xb60 dev_hard_start_xmit+0x100/0x450 sch_direct_xmit+0x224/0x490 __qdisc_run+0x20c/0x980 __dev_queue_xmit+0x1bc/0xf20
This fixes the API misuse by unampping descs[0] with dma_unmap_single.
Fixes: 6e8ab30ec677 ("ibmveth: Add scatter-gather support") Signed-off-by: Tyrel Datwyler tyreld@linux.vnet.ibm.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/ibm/ibmveth.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
--- a/drivers/net/ethernet/ibm/ibmveth.c +++ b/drivers/net/ethernet/ibm/ibmveth.c @@ -1171,11 +1171,15 @@ out:
map_failed_frags: last = i+1; - for (i = 0; i < last; i++) + for (i = 1; i < last; i++) dma_unmap_page(&adapter->vdev->dev, descs[i].fields.address, descs[i].fields.flags_len & IBMVETH_BUF_LEN_MASK, DMA_TO_DEVICE);
+ dma_unmap_single(&adapter->vdev->dev, + descs[0].fields.address, + descs[0].fields.flags_len & IBMVETH_BUF_LEN_MASK, + DMA_TO_DEVICE); map_failed: if (!firmware_has_feature(FW_FEATURE_CMO)) netdev_err(netdev, "tx: unable to map xmit buffer\n");
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Willem de Bruijn willemb@google.com
[ Upstream commit 40c3ff6d5e0809505a067dd423c110c5658c478c ]
Packet sockets may call dev_header_parse with NULL daddr. Make lowpan_header_ops.create fail.
Fixes: 87a93e4eceb4 ("ieee802154: change needed headroom/tailroom") Signed-off-by: Willem de Bruijn willemb@google.com Acked-by: Alexander Aring aring@mojatatu.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/ieee802154/6lowpan/tx.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/net/ieee802154/6lowpan/tx.c +++ b/net/ieee802154/6lowpan/tx.c @@ -48,6 +48,9 @@ int lowpan_header_create(struct sk_buff const struct ipv6hdr *hdr = ipv6_hdr(skb); struct neighbour *n;
+ if (!daddr) + return -EINVAL; + /* TODO: * if this package isn't ipv6 one, where should it be routed? */
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Willem de Bruijn willemb@google.com
[ Upstream commit cb9f1b783850b14cbd7f87d061d784a666dfba1f ]
KMSAN detected read beyond end of buffer in vti and sit devices when passing truncated packets with PF_PACKET. The issue affects additional ip tunnel devices.
Extend commit 76c0ddd8c3a6 ("ip6_tunnel: be careful when accessing the inner header") and commit ccfec9e5cb2d ("ip_tunnel: be careful when accessing the inner header").
Move the check to a separate helper and call at the start of each ndo_start_xmit function in net/ipv4 and net/ipv6.
Minor changes: - convert dev_kfree_skb to kfree_skb on error path, as dev_kfree_skb calls consume_skb which is not for error paths. - use pskb_network_may_pull even though that is pedantic here, as the same as pskb_may_pull for devices without llheaders. - do not cache ipv6 hdrs if used only once (unsafe across pskb_may_pull, was more relevant to earlier patch)
Reported-by: syzbot syzkaller@googlegroups.com Signed-off-by: Willem de Bruijn willemb@google.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- include/net/ip_tunnels.h | 20 ++++++++++++++++++++ net/ipv4/ip_gre.c | 9 +++++++++ net/ipv4/ip_tunnel.c | 9 --------- net/ipv4/ip_vti.c | 12 +++++++++--- net/ipv6/ip6_gre.c | 10 +++++++--- net/ipv6/ip6_tunnel.c | 10 +++------- net/ipv6/ip6_vti.c | 8 ++++---- net/ipv6/ip6mr.c | 17 +++++++++++------ net/ipv6/sit.c | 3 +++ 9 files changed, 66 insertions(+), 32 deletions(-)
--- a/include/net/ip_tunnels.h +++ b/include/net/ip_tunnels.h @@ -307,6 +307,26 @@ int ip_tunnel_encap_del_ops(const struct int ip_tunnel_encap_setup(struct ip_tunnel *t, struct ip_tunnel_encap *ipencap);
+static inline bool pskb_inet_may_pull(struct sk_buff *skb) +{ + int nhlen; + + switch (skb->protocol) { +#if IS_ENABLED(CONFIG_IPV6) + case htons(ETH_P_IPV6): + nhlen = sizeof(struct ipv6hdr); + break; +#endif + case htons(ETH_P_IP): + nhlen = sizeof(struct iphdr); + break; + default: + nhlen = 0; + } + + return pskb_network_may_pull(skb, nhlen); +} + static inline int ip_encap_hlen(struct ip_tunnel_encap *e) { const struct ip_tunnel_encap_ops *ops; --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -674,6 +674,9 @@ static netdev_tx_t ipgre_xmit(struct sk_ struct ip_tunnel *tunnel = netdev_priv(dev); const struct iphdr *tnl_params;
+ if (!pskb_inet_may_pull(skb)) + goto free_skb; + if (tunnel->collect_md) { gre_fb_xmit(skb, dev, skb->protocol); return NETDEV_TX_OK; @@ -717,6 +720,9 @@ static netdev_tx_t erspan_xmit(struct sk struct ip_tunnel *tunnel = netdev_priv(dev); bool truncate = false;
+ if (!pskb_inet_may_pull(skb)) + goto free_skb; + if (tunnel->collect_md) { erspan_fb_xmit(skb, dev, skb->protocol); return NETDEV_TX_OK; @@ -760,6 +766,9 @@ static netdev_tx_t gre_tap_xmit(struct s { struct ip_tunnel *tunnel = netdev_priv(dev);
+ if (!pskb_inet_may_pull(skb)) + goto free_skb; + if (tunnel->collect_md) { gre_fb_xmit(skb, dev, htons(ETH_P_TEB)); return NETDEV_TX_OK; --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c @@ -627,7 +627,6 @@ void ip_tunnel_xmit(struct sk_buff *skb, const struct iphdr *tnl_params, u8 protocol) { struct ip_tunnel *tunnel = netdev_priv(dev); - unsigned int inner_nhdr_len = 0; const struct iphdr *inner_iph; struct flowi4 fl4; u8 tos, ttl; @@ -637,14 +636,6 @@ void ip_tunnel_xmit(struct sk_buff *skb, __be32 dst; bool connected;
- /* ensure we can access the inner net header, for several users below */ - if (skb->protocol == htons(ETH_P_IP)) - inner_nhdr_len = sizeof(struct iphdr); - else if (skb->protocol == htons(ETH_P_IPV6)) - inner_nhdr_len = sizeof(struct ipv6hdr); - if (unlikely(!pskb_may_pull(skb, inner_nhdr_len))) - goto tx_error; - inner_iph = (const struct iphdr *)skb_inner_network_header(skb); connected = (tunnel->parms.iph.daddr != 0);
--- a/net/ipv4/ip_vti.c +++ b/net/ipv4/ip_vti.c @@ -241,6 +241,9 @@ static netdev_tx_t vti_tunnel_xmit(struc struct ip_tunnel *tunnel = netdev_priv(dev); struct flowi fl;
+ if (!pskb_inet_may_pull(skb)) + goto tx_err; + memset(&fl, 0, sizeof(fl));
switch (skb->protocol) { @@ -253,15 +256,18 @@ static netdev_tx_t vti_tunnel_xmit(struc memset(IP6CB(skb), 0, sizeof(*IP6CB(skb))); break; default: - dev->stats.tx_errors++; - dev_kfree_skb(skb); - return NETDEV_TX_OK; + goto tx_err; }
/* override mark with tunnel output key */ fl.flowi_mark = be32_to_cpu(tunnel->parms.o_key);
return vti_xmit(skb, dev, &fl); + +tx_err: + dev->stats.tx_errors++; + kfree_skb(skb); + return NETDEV_TX_OK; }
static int vti4_err(struct sk_buff *skb, u32 info) --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c @@ -879,6 +879,9 @@ static netdev_tx_t ip6gre_tunnel_xmit(st struct net_device_stats *stats = &t->dev->stats; int ret;
+ if (!pskb_inet_may_pull(skb)) + goto tx_err; + if (!ip6_tnl_xmit_ctl(t, &t->parms.laddr, &t->parms.raddr)) goto tx_err;
@@ -921,6 +924,9 @@ static netdev_tx_t ip6erspan_tunnel_xmit int nhoff; int thoff;
+ if (!pskb_inet_may_pull(skb)) + goto tx_err; + if (!ip6_tnl_xmit_ctl(t, &t->parms.laddr, &t->parms.raddr)) goto tx_err;
@@ -993,8 +999,6 @@ static netdev_tx_t ip6erspan_tunnel_xmit goto tx_err; } } else { - struct ipv6hdr *ipv6h = ipv6_hdr(skb); - switch (skb->protocol) { case htons(ETH_P_IP): memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); @@ -1002,7 +1006,7 @@ static netdev_tx_t ip6erspan_tunnel_xmit &dsfield, &encap_limit); break; case htons(ETH_P_IPV6): - if (ipv6_addr_equal(&t->parms.raddr, &ipv6h->saddr)) + if (ipv6_addr_equal(&t->parms.raddr, &ipv6_hdr(skb)->saddr)) goto tx_err; if (prepare_ip6gre_xmit_ipv6(skb, dev, &fl6, &dsfield, &encap_limit)) --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -1243,10 +1243,6 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, str u8 tproto; int err;
- /* ensure we can access the full inner ip header */ - if (!pskb_may_pull(skb, sizeof(struct iphdr))) - return -1; - iph = ip_hdr(skb); memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
@@ -1321,9 +1317,6 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, str u8 tproto; int err;
- if (unlikely(!pskb_may_pull(skb, sizeof(*ipv6h)))) - return -1; - ipv6h = ipv6_hdr(skb); tproto = READ_ONCE(t->parms.proto); if ((tproto != IPPROTO_IPV6 && tproto != 0) || @@ -1405,6 +1398,9 @@ ip6_tnl_start_xmit(struct sk_buff *skb, struct net_device_stats *stats = &t->dev->stats; int ret;
+ if (!pskb_inet_may_pull(skb)) + goto tx_err; + switch (skb->protocol) { case htons(ETH_P_IP): ret = ip4ip6_tnl_xmit(skb, dev); --- a/net/ipv6/ip6_vti.c +++ b/net/ipv6/ip6_vti.c @@ -522,18 +522,18 @@ vti6_tnl_xmit(struct sk_buff *skb, struc { struct ip6_tnl *t = netdev_priv(dev); struct net_device_stats *stats = &t->dev->stats; - struct ipv6hdr *ipv6h; struct flowi fl; int ret;
+ if (!pskb_inet_may_pull(skb)) + goto tx_err; + memset(&fl, 0, sizeof(fl));
switch (skb->protocol) { case htons(ETH_P_IPV6): - ipv6h = ipv6_hdr(skb); - if ((t->parms.proto != IPPROTO_IPV6 && t->parms.proto != 0) || - vti6_addr_conflict(t, ipv6h)) + vti6_addr_conflict(t, ipv6_hdr(skb))) goto tx_err;
xfrm_decode_session(skb, &fl, AF_INET6); --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c @@ -51,6 +51,7 @@ #include <linux/export.h> #include <net/ip6_checksum.h> #include <linux/netconf.h> +#include <net/ip_tunnels.h>
#include <linux/nospec.h>
@@ -599,13 +600,12 @@ static netdev_tx_t reg_vif_xmit(struct s .flowi6_iif = skb->skb_iif ? : LOOPBACK_IFINDEX, .flowi6_mark = skb->mark, }; - int err;
- err = ip6mr_fib_lookup(net, &fl6, &mrt); - if (err < 0) { - kfree_skb(skb); - return err; - } + if (!pskb_inet_may_pull(skb)) + goto tx_err; + + if (ip6mr_fib_lookup(net, &fl6, &mrt) < 0) + goto tx_err;
read_lock(&mrt_lock); dev->stats.tx_bytes += skb->len; @@ -614,6 +614,11 @@ static netdev_tx_t reg_vif_xmit(struct s read_unlock(&mrt_lock); kfree_skb(skb); return NETDEV_TX_OK; + +tx_err: + dev->stats.tx_errors++; + kfree_skb(skb); + return NETDEV_TX_OK; }
static int reg_vif_get_iflink(const struct net_device *dev) --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -1021,6 +1021,9 @@ tx_error: static netdev_tx_t sit_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) { + if (!pskb_inet_may_pull(skb)) + goto tx_err; + switch (skb->protocol) { case htons(ETH_P_IP): sit_tunnel_xmit__(skb, dev, IPPROTO_IPIP);
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Gustavo A. R. Silva" gustavo@embeddedor.com
[ Upstream commit 50d5258634aee2e62832aa086d2fb0de00e72b91 ]
flen is indirectly controlled by user-space, hence leading to a potential exploitation of the Spectre variant 1 vulnerability.
This issue was detected with the help of Smatch:
net/core/filter.c:1101 bpf_check_classic() warn: potential spectre issue 'filter' [w]
Fix this by sanitizing flen before using it to index filter at line 1101:
switch (filter[flen - 1].code) {
and through pc at line 1040:
const struct sock_filter *ftest = &filter[pc];
Notice that given that speculation windows are large, the policy is to kill the speculation on the first load and not worry if it can be completed with a dependent load/store [1].
[1] https://marc.info/?l=linux-kernel&m=152449131114778&w=2
Signed-off-by: Gustavo A. R. Silva gustavo@embeddedor.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/core/filter.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/net/core/filter.c +++ b/net/core/filter.c @@ -73,6 +73,7 @@ #include <linux/seg6_local.h> #include <net/seg6.h> #include <net/seg6_local.h> +#include <linux/nospec.h>
/** * sk_filter_trim_cap - run a packet through a socket filter @@ -1038,6 +1039,7 @@ static int bpf_check_classic(const struc bool anc_found; int pc;
+ flen = array_index_nospec(flen, BPF_MAXINSNS + 1); /* Check the filter code now */ for (pc = 0; pc < flen; pc++) { const struct sock_filter *ftest = &filter[pc];
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet edumazet@google.com
[ Upstream commit 202700e30740c6568b5a6943662f3829566dd533 ]
Using del_timer() + add_timer() is generally unsafe on SMP, as noticed by syzbot. Use mod_timer() instead.
kernel BUG at kernel/time/timer.c:1136! invalid opcode: 0000 [#1] PREEMPT SMP KASAN CPU: 1 PID: 1026 Comm: kworker/u4:4 Not tainted 4.20.0+ #2 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Workqueue: events_unbound flush_to_ldisc RIP: 0010:add_timer kernel/time/timer.c:1136 [inline] RIP: 0010:add_timer+0xa81/0x1470 kernel/time/timer.c:1134 Code: 4d 89 7d 40 48 c7 85 70 fe ff ff 00 00 00 00 c7 85 7c fe ff ff ff ff ff ff 48 89 85 90 fe ff ff e9 e6 f7 ff ff e8 cf 42 12 00 <0f> 0b e8 c8 42 12 00 0f 0b e8 c1 42 12 00 4c 89 bd 60 fe ff ff e9 RSP: 0018:ffff8880a7fdf5a8 EFLAGS: 00010293 RAX: ffff8880a7846340 RBX: dffffc0000000000 RCX: 0000000000000000 RDX: 0000000000000000 RSI: ffffffff816f3ee1 RDI: ffff88808a514ff8 RBP: ffff8880a7fdf760 R08: 0000000000000007 R09: ffff8880a7846c58 R10: ffff8880a7846340 R11: 0000000000000000 R12: ffff88808a514ff8 R13: ffff88808a514ff8 R14: ffff88808a514dc0 R15: 0000000000000030 FS: 0000000000000000(0000) GS:ffff8880ae700000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000000000061c500 CR3: 00000000994d9000 CR4: 00000000001406e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: decode_prio_command drivers/net/hamradio/6pack.c:903 [inline] sixpack_decode drivers/net/hamradio/6pack.c:971 [inline] sixpack_receive_buf drivers/net/hamradio/6pack.c:457 [inline] sixpack_receive_buf+0xf9c/0x1470 drivers/net/hamradio/6pack.c:434 tty_ldisc_receive_buf+0x164/0x1c0 drivers/tty/tty_buffer.c:465 tty_port_default_receive_buf+0x114/0x190 drivers/tty/tty_port.c:38 receive_buf drivers/tty/tty_buffer.c:481 [inline] flush_to_ldisc+0x3b2/0x590 drivers/tty/tty_buffer.c:533 process_one_work+0xd0c/0x1ce0 kernel/workqueue.c:2153 worker_thread+0x143/0x14a0 kernel/workqueue.c:2296 kthread+0x357/0x430 kernel/kthread.c:246 ret_from_fork+0x3a/0x50 arch/x86/entry/entry_64.S:352
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Eric Dumazet edumazet@google.com Reported-by: syzbot syzkaller@googlegroups.com Cc: Andreas Koensgen ajk@comnets.uni-bremen.de Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/hamradio/6pack.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-)
--- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c @@ -523,10 +523,7 @@ static void resync_tnc(struct timer_list
/* Start resync timer again -- the TNC might be still absent */ - - del_timer(&sp->resync_t); - sp->resync_t.expires = jiffies + SIXP_RESYNC_TIMEOUT; - add_timer(&sp->resync_t); + mod_timer(&sp->resync_t, jiffies + SIXP_RESYNC_TIMEOUT); }
static inline int tnc_init(struct sixpack *sp) @@ -537,9 +534,7 @@ static inline int tnc_init(struct sixpac
sp->tty->ops->write(sp->tty, &inbyte, 1);
- del_timer(&sp->resync_t); - sp->resync_t.expires = jiffies + SIXP_RESYNC_TIMEOUT; - add_timer(&sp->resync_t); + mod_timer(&sp->resync_t, jiffies + SIXP_RESYNC_TIMEOUT);
return 0; } @@ -897,11 +892,8 @@ static void decode_prio_command(struct s /* if the state byte has been received, the TNC is present, so the resync timer can be reset. */
- if (sp->tnc_state == TNC_IN_SYNC) { - del_timer(&sp->resync_t); - sp->resync_t.expires = jiffies + SIXP_INIT_RESYNC_TIMEOUT; - add_timer(&sp->resync_t); - } + if (sp->tnc_state == TNC_IN_SYNC) + mod_timer(&sp->resync_t, jiffies + SIXP_INIT_RESYNC_TIMEOUT);
sp->status1 = cmd & SIXP_PRIO_DATA_MASK; }
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet edumazet@google.com
[ Upstream commit d63967e475ae10f286dbd35e189cb241e0b1f284 ]
Since capi_ioctl() copies 64 bytes after calling capi20_get_manufacturer() we need to ensure to not leak information to user.
BUG: KMSAN: kernel-infoleak in _copy_to_user+0x16b/0x1f0 lib/usercopy.c:32 CPU: 0 PID: 11245 Comm: syz-executor633 Not tainted 4.20.0-rc7+ #2 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0x173/0x1d0 lib/dump_stack.c:113 kmsan_report+0x12e/0x2a0 mm/kmsan/kmsan.c:613 kmsan_internal_check_memory+0x9d4/0xb00 mm/kmsan/kmsan.c:704 kmsan_copy_to_user+0xab/0xc0 mm/kmsan/kmsan_hooks.c:601 _copy_to_user+0x16b/0x1f0 lib/usercopy.c:32 capi_ioctl include/linux/uaccess.h:177 [inline] capi_unlocked_ioctl+0x1a0b/0x1bf0 drivers/isdn/capi/capi.c:939 do_vfs_ioctl+0xebd/0x2bf0 fs/ioctl.c:46 ksys_ioctl fs/ioctl.c:713 [inline] __do_sys_ioctl fs/ioctl.c:720 [inline] __se_sys_ioctl+0x1da/0x270 fs/ioctl.c:718 __x64_sys_ioctl+0x4a/0x70 fs/ioctl.c:718 do_syscall_64+0xbc/0xf0 arch/x86/entry/common.c:291 entry_SYSCALL_64_after_hwframe+0x63/0xe7 RIP: 0033:0x440019 Code: 18 89 d0 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 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 0f 83 fb 13 fc ff c3 66 2e 0f 1f 84 00 00 00 00 RSP: 002b:00007ffdd4659fb8 EFLAGS: 00000213 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 00000000004002c8 RCX: 0000000000440019 RDX: 0000000020000080 RSI: 00000000c0044306 RDI: 0000000000000003 RBP: 00000000006ca018 R08: 0000000000000000 R09: 00000000004002c8 R10: 0000000000000000 R11: 0000000000000213 R12: 00000000004018a0 R13: 0000000000401930 R14: 0000000000000000 R15: 0000000000000000
Local variable description: ----data.i@capi_unlocked_ioctl Variable was created at: capi_ioctl drivers/isdn/capi/capi.c:747 [inline] capi_unlocked_ioctl+0x82/0x1bf0 drivers/isdn/capi/capi.c:939 do_vfs_ioctl+0xebd/0x2bf0 fs/ioctl.c:46
Bytes 12-63 of 64 are uninitialized Memory access of size 64 starts at ffff88807ac5fce8 Data copied to user address 0000000020000080
Signed-off-by: Eric Dumazet edumazet@google.com Reported-by: syzbot syzkaller@googlegroups.com Cc: Karsten Keil isdn@linux-pingi.de Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/isdn/capi/kcapi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/isdn/capi/kcapi.c +++ b/drivers/isdn/capi/kcapi.c @@ -852,7 +852,7 @@ u16 capi20_get_manufacturer(u32 contr, u u16 ret;
if (contr == 0) { - strlcpy(buf, capi_manufakturer, CAPI_MANUFACTURER_LEN); + strncpy(buf, capi_manufakturer, CAPI_MANUFACTURER_LEN); return CAPI_NOERROR; }
@@ -860,7 +860,7 @@ u16 capi20_get_manufacturer(u32 contr, u
ctr = get_capi_ctr_by_nr(contr); if (ctr && ctr->state == CAPI_CTR_RUNNING) { - strlcpy(buf, ctr->manu, CAPI_MANUFACTURER_LEN); + strncpy(buf, ctr->manu, CAPI_MANUFACTURER_LEN); ret = CAPI_NOERROR; } else ret = CAPI_REGNOTINSTALLED;
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cong Wang xiyou.wangcong@gmail.com
[ Upstream commit 7314f5480f3e37e570104dc5e0f28823ef849e72 ]
nr_find_socket(), nr_find_peer() and nr_find_listener() lock the sock after finding it in the global list. However, the call path requires BH disabled for the sock lock consistently.
Actually the locking is unnecessary at this point, we can just hold the sock refcnt to make sure it is not gone after we unlock the global list, and lock it later only when needed.
Reported-and-tested-by: syzbot+f621cda8b7e598908efa@syzkaller.appspotmail.com Signed-off-by: Cong Wang xiyou.wangcong@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/netrom/af_netrom.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
--- a/net/netrom/af_netrom.c +++ b/net/netrom/af_netrom.c @@ -153,7 +153,7 @@ static struct sock *nr_find_listener(ax2 sk_for_each(s, &nr_list) if (!ax25cmp(&nr_sk(s)->source_addr, addr) && s->sk_state == TCP_LISTEN) { - bh_lock_sock(s); + sock_hold(s); goto found; } s = NULL; @@ -174,7 +174,7 @@ static struct sock *nr_find_socket(unsig struct nr_sock *nr = nr_sk(s);
if (nr->my_index == index && nr->my_id == id) { - bh_lock_sock(s); + sock_hold(s); goto found; } } @@ -198,7 +198,7 @@ static struct sock *nr_find_peer(unsigne
if (nr->your_index == index && nr->your_id == id && !ax25cmp(&nr->dest_addr, dest)) { - bh_lock_sock(s); + sock_hold(s); goto found; } } @@ -224,7 +224,7 @@ static unsigned short nr_find_next_circu if (i != 0 && j != 0) { if ((sk=nr_find_socket(i, j)) == NULL) break; - bh_unlock_sock(sk); + sock_put(sk); }
id++; @@ -920,6 +920,7 @@ int nr_rx_frame(struct sk_buff *skb, str }
if (sk != NULL) { + bh_lock_sock(sk); skb_reset_transport_header(skb);
if (frametype == NR_CONNACK && skb->len == 22) @@ -929,6 +930,7 @@ int nr_rx_frame(struct sk_buff *skb, str
ret = nr_process_rx_frame(sk, skb); bh_unlock_sock(sk); + sock_put(sk); return ret; }
@@ -960,10 +962,12 @@ int nr_rx_frame(struct sk_buff *skb, str (make = nr_make_new(sk)) == NULL) { nr_transmit_refusal(skb, 0); if (sk) - bh_unlock_sock(sk); + sock_put(sk); return 0; }
+ bh_lock_sock(sk); + window = skb->data[20];
skb->sk = make; @@ -1016,6 +1020,7 @@ int nr_rx_frame(struct sk_buff *skb, str sk->sk_data_ready(sk);
bh_unlock_sock(sk); + sock_put(sk);
nr_insert_socket(make);
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cong Wang xiyou.wangcong@gmail.com
[ Upstream commit d5c7c745f254c6cb98b3b3f15fe789b8bd770c72 ]
When x25_asy_open() fails, it already cleans up by itself, so its caller doesn't need to free the memory again.
It seems we still have to call x25_asy_free() to clear the SLF_INUSE bit, so just set these pointers to NULL after kfree().
Reported-and-tested-by: syzbot+5e5e969e525129229052@syzkaller.appspotmail.com Fixes: 3b780bed3138 ("x25_asy: Free x25_asy on x25_asy_open() failure.") Signed-off-by: Cong Wang xiyou.wangcong@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/wan/x25_asy.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/net/wan/x25_asy.c +++ b/drivers/net/wan/x25_asy.c @@ -485,8 +485,10 @@ static int x25_asy_open(struct net_devic
/* Cleanup */ kfree(sl->xbuff); + sl->xbuff = NULL; noxbuff: kfree(sl->rbuff); + sl->rbuff = NULL; norbuff: return -ENOMEM; }
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Willem de Bruijn willemb@google.com
[ Upstream commit 6b8d95f1795c42161dc0984b6863e95d6acf24ed ]
Validate packet socket address length if a length is given. Zero length is equivalent to not setting an address.
Fixes: 99137b7888f4 ("packet: validate address length") Reported-by: Ido Schimmel idosch@idosch.org Signed-off-by: Willem de Bruijn willemb@google.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/packet/af_packet.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -2625,7 +2625,7 @@ static int tpacket_snd(struct packet_soc sll_addr))) goto out; proto = saddr->sll_protocol; - addr = saddr->sll_addr; + addr = saddr->sll_halen ? saddr->sll_addr : NULL; dev = dev_get_by_index(sock_net(&po->sk), saddr->sll_ifindex); if (addr && dev && saddr->sll_halen < dev->addr_len) goto out; @@ -2825,7 +2825,7 @@ static int packet_snd(struct socket *soc if (msg->msg_namelen < (saddr->sll_halen + offsetof(struct sockaddr_ll, sll_addr))) goto out; proto = saddr->sll_protocol; - addr = saddr->sll_addr; + addr = saddr->sll_halen ? saddr->sll_addr : NULL; dev = dev_get_by_index(sock_net(sk), saddr->sll_ifindex); if (addr && dev && saddr->sll_halen < dev->addr_len) goto out;
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Gustavo A. R. Silva" gustavo@embeddedor.com
[ Upstream commit d686026b1e6ed4ea27d630d8f54f9a694db088b2 ]
protocol is indirectly controlled by user-space, hence leading to a potential exploitation of the Spectre variant 1 vulnerability.
This issue was detected with the help of Smatch:
net/phonet/af_phonet.c:48 phonet_proto_get() warn: potential spectre issue 'proto_tab' [w] (local cap)
Fix this by sanitizing protocol before using it to index proto_tab.
Notice that given that speculation windows are large, the policy is to kill the speculation on the first load and not worry if it can be completed with a dependent load/store [1].
[1] https://marc.info/?l=linux-kernel&m=152449131114778&w=2
Signed-off-by: Gustavo A. R. Silva gustavo@embeddedor.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/phonet/af_phonet.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/net/phonet/af_phonet.c +++ b/net/phonet/af_phonet.c @@ -34,6 +34,8 @@ #include <net/phonet/phonet.h> #include <net/phonet/pn_dev.h>
+#include <linux/nospec.h> + /* Transport protocol registration */ static const struct phonet_protocol *proto_tab[PHONET_NPROTO] __read_mostly;
@@ -43,6 +45,7 @@ static const struct phonet_protocol *pho
if (protocol >= PHONET_NPROTO) return NULL; + protocol = array_index_nospec(protocol, PHONET_NPROTO);
rcu_read_lock(); pp = rcu_dereference(proto_tab[protocol]);
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cong Wang xiyou.wangcong@gmail.com
[ Upstream commit aff6db454599d62191aabc208930e891748e4322 ]
__ptr_ring_swap_queue() tries to move pointers from the old ring to the new one, but it forgets to check if ->producer is beyond the new size at the end of the operation. This leads to an out-of-bound access in __ptr_ring_produce() as reported by syzbot.
Reported-by: syzbot+8993c0fa96d57c399735@syzkaller.appspotmail.com Fixes: 5d49de532002 ("ptr_ring: resize support") Cc: "Michael S. Tsirkin" mst@redhat.com Cc: John Fastabend john.fastabend@gmail.com Cc: Jason Wang jasowang@redhat.com Signed-off-by: Cong Wang xiyou.wangcong@gmail.com Acked-by: Michael S. Tsirkin mst@redhat.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- include/linux/ptr_ring.h | 2 ++ 1 file changed, 2 insertions(+)
--- a/include/linux/ptr_ring.h +++ b/include/linux/ptr_ring.h @@ -573,6 +573,8 @@ static inline void **__ptr_ring_swap_que else if (destroy) destroy(ptr);
+ if (producer >= size) + producer = 0; __ptr_ring_set_size(r, size); r->producer = producer; r->consumer_head = 0;
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Deepa Dinamani deepa.kernel@gmail.com
[ Upstream commit 3a0ed3e9619738067214871e9cb826fa23b2ddb9 ]
Al Viro mentioned (Message-ID 20170626041334.GZ10672@ZenIV.linux.org.uk) that there is probably a race condition lurking in accesses of sk_stamp on 32-bit machines.
sock->sk_stamp is of type ktime_t which is always an s64. On a 32 bit architecture, we might run into situations of unsafe access as the access to the field becomes non atomic.
Use seqlocks for synchronization. This allows us to avoid using spinlocks for readers as readers do not need mutual exclusion.
Another approach to solve this is to require sk_lock for all modifications of the timestamps. The current approach allows for timestamps to have their own lock: sk_stamp_lock. This allows for the patch to not compete with already existing critical sections, and side effects are limited to the paths in the patch.
The addition of the new field maintains the data locality optimizations from commit 9115e8cd2a0c ("net: reorganize struct sock for better data locality")
Note that all the instances of the sk_stamp accesses are either through the ioctl or the syscall recvmsg.
Signed-off-by: Deepa Dinamani deepa.kernel@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- include/net/sock.h | 38 +++++++++++++++++++++++++++++++++++--- net/compat.c | 15 +++++++++------ net/core/sock.c | 15 ++++++++++----- net/sunrpc/svcsock.c | 2 +- 4 files changed, 55 insertions(+), 15 deletions(-)
--- a/include/net/sock.h +++ b/include/net/sock.h @@ -298,6 +298,7 @@ struct sock_common { * @sk_filter: socket filtering instructions * @sk_timer: sock cleanup timer * @sk_stamp: time stamp of last packet received + * @sk_stamp_seq: lock for accessing sk_stamp on 32 bit architectures only * @sk_tsflags: SO_TIMESTAMPING socket options * @sk_tskey: counter to disambiguate concurrent tstamp requests * @sk_zckey: counter to order MSG_ZEROCOPY notifications @@ -474,6 +475,9 @@ struct sock { const struct cred *sk_peer_cred; long sk_rcvtimeo; ktime_t sk_stamp; +#if BITS_PER_LONG==32 + seqlock_t sk_stamp_seq; +#endif u16 sk_tsflags; u8 sk_shutdown; u32 sk_tskey; @@ -2287,6 +2291,34 @@ static inline void sk_drops_add(struct s atomic_add(segs, &sk->sk_drops); }
+static inline ktime_t sock_read_timestamp(struct sock *sk) +{ +#if BITS_PER_LONG==32 + unsigned int seq; + ktime_t kt; + + do { + seq = read_seqbegin(&sk->sk_stamp_seq); + kt = sk->sk_stamp; + } while (read_seqretry(&sk->sk_stamp_seq, seq)); + + return kt; +#else + return sk->sk_stamp; +#endif +} + +static inline void sock_write_timestamp(struct sock *sk, ktime_t kt) +{ +#if BITS_PER_LONG==32 + write_seqlock(&sk->sk_stamp_seq); + sk->sk_stamp = kt; + write_sequnlock(&sk->sk_stamp_seq); +#else + sk->sk_stamp = kt; +#endif +} + void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb); void __sock_recv_wifi_status(struct msghdr *msg, struct sock *sk, @@ -2311,7 +2343,7 @@ sock_recv_timestamp(struct msghdr *msg, (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE))) __sock_recv_timestamp(msg, sk, skb); else - sk->sk_stamp = kt; + sock_write_timestamp(sk, kt);
if (sock_flag(sk, SOCK_WIFI_STATUS) && skb->wifi_acked_valid) __sock_recv_wifi_status(msg, sk, skb); @@ -2332,9 +2364,9 @@ static inline void sock_recv_ts_and_drop if (sk->sk_flags & FLAGS_TS_OR_DROPS || sk->sk_tsflags & TSFLAGS_ANY) __sock_recv_ts_and_drops(msg, sk, skb); else if (unlikely(sock_flag(sk, SOCK_TIMESTAMP))) - sk->sk_stamp = skb->tstamp; + sock_write_timestamp(sk, skb->tstamp); else if (unlikely(sk->sk_stamp == SK_DEFAULT_STAMP)) - sk->sk_stamp = 0; + sock_write_timestamp(sk, 0); }
void __sock_tx_timestamp(__u16 tsflags, __u8 *tx_flags); --- a/net/compat.c +++ b/net/compat.c @@ -467,12 +467,14 @@ int compat_sock_get_timestamp(struct soc ctv = (struct compat_timeval __user *) userstamp; err = -ENOENT; sock_enable_timestamp(sk, SOCK_TIMESTAMP); - tv = ktime_to_timeval(sk->sk_stamp); + tv = ktime_to_timeval(sock_read_timestamp(sk)); + if (tv.tv_sec == -1) return err; if (tv.tv_sec == 0) { - sk->sk_stamp = ktime_get_real(); - tv = ktime_to_timeval(sk->sk_stamp); + ktime_t kt = ktime_get_real(); + sock_write_timestamp(sk, kt); + tv = ktime_to_timeval(kt); } err = 0; if (put_user(tv.tv_sec, &ctv->tv_sec) || @@ -494,12 +496,13 @@ int compat_sock_get_timestampns(struct s ctv = (struct compat_timespec __user *) userstamp; err = -ENOENT; sock_enable_timestamp(sk, SOCK_TIMESTAMP); - ts = ktime_to_timespec(sk->sk_stamp); + ts = ktime_to_timespec(sock_read_timestamp(sk)); if (ts.tv_sec == -1) return err; if (ts.tv_sec == 0) { - sk->sk_stamp = ktime_get_real(); - ts = ktime_to_timespec(sk->sk_stamp); + ktime_t kt = ktime_get_real(); + sock_write_timestamp(sk, kt); + ts = ktime_to_timespec(kt); } err = 0; if (put_user(ts.tv_sec, &ctv->tv_sec) || --- a/net/core/sock.c +++ b/net/core/sock.c @@ -2743,6 +2743,9 @@ void sock_init_data(struct socket *sock, sk->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT;
sk->sk_stamp = SK_DEFAULT_STAMP; +#if BITS_PER_LONG==32 + seqlock_init(&sk->sk_stamp_seq); +#endif atomic_set(&sk->sk_zckey, 0);
#ifdef CONFIG_NET_RX_BUSY_POLL @@ -2842,12 +2845,13 @@ int sock_get_timestamp(struct sock *sk, struct timeval tv;
sock_enable_timestamp(sk, SOCK_TIMESTAMP); - tv = ktime_to_timeval(sk->sk_stamp); + tv = ktime_to_timeval(sock_read_timestamp(sk)); if (tv.tv_sec == -1) return -ENOENT; if (tv.tv_sec == 0) { - sk->sk_stamp = ktime_get_real(); - tv = ktime_to_timeval(sk->sk_stamp); + ktime_t kt = ktime_get_real(); + sock_write_timestamp(sk, kt); + tv = ktime_to_timeval(kt); } return copy_to_user(userstamp, &tv, sizeof(tv)) ? -EFAULT : 0; } @@ -2858,11 +2862,12 @@ int sock_get_timestampns(struct sock *sk struct timespec ts;
sock_enable_timestamp(sk, SOCK_TIMESTAMP); - ts = ktime_to_timespec(sk->sk_stamp); + ts = ktime_to_timespec(sock_read_timestamp(sk)); if (ts.tv_sec == -1) return -ENOENT; if (ts.tv_sec == 0) { - sk->sk_stamp = ktime_get_real(); + ktime_t kt = ktime_get_real(); + sock_write_timestamp(sk, kt); ts = ktime_to_timespec(sk->sk_stamp); } return copy_to_user(userstamp, &ts, sizeof(ts)) ? -EFAULT : 0; --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -549,7 +549,7 @@ static int svc_udp_recvfrom(struct svc_r /* Don't enable netstamp, sunrpc doesn't need that much accuracy */ } - svsk->sk_sk->sk_stamp = skb->tstamp; + sock_write_timestamp(svsk->sk_sk, skb->tstamp); set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); /* there may be more data... */
len = skb->len;
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cong Wang xiyou.wangcong@gmail.com
[ Upstream commit dc4501ff287547dea7ca10f1c580c741291a8760 ]
bearer_disable() already calls kfree_rcu() to free struct tipc_bearer, we don't need to call kfree() again.
Fixes: cb30a63384bc ("tipc: refactor function tipc_enable_bearer()") Reported-by: syzbot+b981acf1fb240c0c128b@syzkaller.appspotmail.com Cc: Ying Xue ying.xue@windriver.com Cc: Jon Maloy jon.maloy@ericsson.com Signed-off-by: Cong Wang xiyou.wangcong@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/tipc/bearer.c | 1 - 1 file changed, 1 deletion(-)
--- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c @@ -317,7 +317,6 @@ static int tipc_enable_bearer(struct net res = tipc_disc_create(net, b, &b->bcast_addr, &skb); if (res) { bearer_disable(net, b); - kfree(b); errstr = "failed to create discoverer"; goto rejected; }
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael J. Ruhl michael.j.ruhl@intel.com
commit dbc2970caef74e8ff41923d302aa6fb5a4812d0e upstream.
An incorrect sge sizing in the HFI PIO path will cause an OOPs similar to this:
BUG: unable to handle kernel NULL pointer dereference at (null) IP: [] hfi1_verbs_send_pio+0x3d8/0x530 [hfi1] PGD 0 Oops: 0000 1 SMP Call Trace: ? hfi1_verbs_send_dma+0xad0/0xad0 [hfi1] hfi1_verbs_send+0xdf/0x250 [hfi1] ? make_rc_ack+0xa80/0xa80 [hfi1] hfi1_do_send+0x192/0x430 [hfi1] hfi1_do_send_from_rvt+0x10/0x20 [hfi1] rvt_post_send+0x369/0x820 [rdmavt] ib_uverbs_post_send+0x317/0x570 [ib_uverbs] ib_uverbs_write+0x26f/0x420 [ib_uverbs] ? security_file_permission+0x21/0xa0 vfs_write+0xbd/0x1e0 ? mntput+0x24/0x40 SyS_write+0x7f/0xe0 system_call_fastpath+0x16/0x1b
Fix by adding the missing sizing check to correctly determine the sge length.
Fixes: 7724105686e7 ("IB/hfi1: add driver files") Reviewed-by: Mike Marciniszyn mike.marciniszyn@intel.com Signed-off-by: Michael J. Ruhl michael.j.ruhl@intel.com Signed-off-by: Dennis Dalessandro dennis.dalessandro@intel.com Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/infiniband/hw/hfi1/verbs.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/infiniband/hw/hfi1/verbs.c +++ b/drivers/infiniband/hw/hfi1/verbs.c @@ -919,6 +919,8 @@ int hfi1_verbs_send_pio(struct rvt_qp *q
if (slen > len) slen = len; + if (slen > ss->sge.sge_length) + slen = ss->sge.sge_length; rvt_update_sge(ss, slen, false); seg_pio_copy_mid(pbuf, addr, slen); len -= slen;
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gustavo A. R. Silva gustavo@embeddedor.com
commit 0b84304ef5da92add8dc75a1b07879c5374cdb05 upstream.
info->channel is indirectly controlled by user-space, hence leading to a potential exploitation of the Spectre variant 1 vulnerability.
This issue was detected with the help of Smatch:
sound/pci/rme9652/hdsp.c:4100 snd_hdsp_channel_info() warn: potential spectre issue 'hdsp->channel_map' [r] (local cap)
Fix this by sanitizing info->channel before using it to index hdsp->channel_map
Notice that given that speculation windows are large, the policy is to kill the speculation on the first load and not worry if it can be completed with a dependent load/store [1].
Also, notice that I refactored the code a bit in order to get rid of the following checkpatch warning:
ERROR: do not use assignment in if condition FILE: sound/pci/rme9652/hdsp.c:4103: if ((mapped_channel = hdsp->channel_map[info->channel]) < 0)
[1] https://marc.info/?l=linux-kernel&m=152449131114778&w=2
Cc: stable@vger.kernel.org Signed-off-by: Gustavo A. R. Silva gustavo@embeddedor.com Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- sound/pci/rme9652/hdsp.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
--- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c @@ -30,6 +30,7 @@ #include <linux/math64.h> #include <linux/vmalloc.h> #include <linux/io.h> +#include <linux/nospec.h>
#include <sound/core.h> #include <sound/control.h> @@ -4092,15 +4093,16 @@ static int snd_hdsp_channel_info(struct struct snd_pcm_channel_info *info) { struct hdsp *hdsp = snd_pcm_substream_chip(substream); - int mapped_channel; + unsigned int channel = info->channel;
- if (snd_BUG_ON(info->channel >= hdsp->max_channels)) + if (snd_BUG_ON(channel >= hdsp->max_channels)) return -EINVAL; + channel = array_index_nospec(channel, hdsp->max_channels);
- if ((mapped_channel = hdsp->channel_map[info->channel]) < 0) + if (hdsp->channel_map[channel] < 0) return -EINVAL;
- info->offset = mapped_channel * HDSP_CHANNEL_BUFFER_BYTES; + info->offset = hdsp->channel_map[channel] * HDSP_CHANNEL_BUFFER_BYTES; info->first = 0; info->step = 32; return 0;
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gustavo A. R. Silva gustavo@embeddedor.com
commit 5ae4f61f012a097df93de2285070ec8e34716d29 upstream.
ipcm->substream is indirectly controlled by user-space, hence leading to a potential exploitation of the Spectre variant 1 vulnerability.
This issue was detected with the help of Smatch:
sound/pci/emu10k1/emufx.c:1031 snd_emu10k1_ipcm_poke() warn: potential spectre issue 'emu->fx8010.pcm' [r] (local cap) sound/pci/emu10k1/emufx.c:1075 snd_emu10k1_ipcm_peek() warn: potential spectre issue 'emu->fx8010.pcm' [r] (local cap)
Fix this by sanitizing ipcm->substream before using it to index emu->fx8010.pcm
Notice that given that speculation windows are large, the policy is to kill the speculation on the first load and not worry if it can be completed with a dependent load/store [1].
[1] https://marc.info/?l=linux-kernel&m=152449131114778&w=2
Cc: stable@vger.kernel.org Signed-off-by: Gustavo A. R. Silva gustavo@embeddedor.com Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- sound/pci/emu10k1/emufx.c | 5 +++++ 1 file changed, 5 insertions(+)
--- a/sound/pci/emu10k1/emufx.c +++ b/sound/pci/emu10k1/emufx.c @@ -36,6 +36,7 @@ #include <linux/init.h> #include <linux/mutex.h> #include <linux/moduleparam.h> +#include <linux/nospec.h>
#include <sound/core.h> #include <sound/tlv.h> @@ -1026,6 +1027,8 @@ static int snd_emu10k1_ipcm_poke(struct
if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT) return -EINVAL; + ipcm->substream = array_index_nospec(ipcm->substream, + EMU10K1_FX8010_PCM_COUNT); if (ipcm->channels > 32) return -EINVAL; pcm = &emu->fx8010.pcm[ipcm->substream]; @@ -1072,6 +1075,8 @@ static int snd_emu10k1_ipcm_peek(struct
if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT) return -EINVAL; + ipcm->substream = array_index_nospec(ipcm->substream, + EMU10K1_FX8010_PCM_COUNT); pcm = &emu->fx8010.pcm[ipcm->substream]; mutex_lock(&emu->fx8010.lock); spin_lock_irq(&emu->reg_lock);
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gustavo A. R. Silva gustavo@embeddedor.com
commit 94ffb030b6d31ec840bb811be455dd2e26a4f43e upstream.
stream is indirectly controlled by user-space, hence leading to a potential exploitation of the Spectre variant 1 vulnerability.
This issue was detected with the help of Smatch:
sound/core/pcm.c:140 snd_pcm_control_ioctl() warn: potential spectre issue 'pcm->streams' [r] (local cap)
Fix this by sanitizing stream before using it to index pcm->streams
Notice that given that speculation windows are large, the policy is to kill the speculation on the first load and not worry if it can be completed with a dependent load/store [1].
[1] https://marc.info/?l=linux-kernel&m=152449131114778&w=2
Signed-off-by: Gustavo A. R. Silva gustavo@embeddedor.com Cc: stable@vger.kernel.org Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- sound/core/pcm.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/sound/core/pcm.c +++ b/sound/core/pcm.c @@ -25,6 +25,7 @@ #include <linux/time.h> #include <linux/mutex.h> #include <linux/device.h> +#include <linux/nospec.h> #include <sound/core.h> #include <sound/minors.h> #include <sound/pcm.h> @@ -129,6 +130,7 @@ static int snd_pcm_control_ioctl(struct return -EFAULT; if (stream < 0 || stream > 1) return -EINVAL; + stream = array_index_nospec(stream, 2); if (get_user(subdevice, &info->subdevice)) return -EFAULT; mutex_lock(®ister_mutex);
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gustavo A. R. Silva gustavo@embeddedor.com
commit 4aea96f4237cea0c51a8bc87c0db31f0f932f1f0 upstream.
info.mode and info.port are indirectly controlled by user-space, hence leading to a potential exploitation of the Spectre variant 1 vulnerability.
These issues were detected with the help of Smatch:
sound/synth/emux/emux_hwdep.c:72 snd_emux_hwdep_misc_mode() warn: potential spectre issue 'emu->portptrs[i]->ctrls' [w] (local cap) sound/synth/emux/emux_hwdep.c:75 snd_emux_hwdep_misc_mode() warn: potential spectre issue 'emu->portptrs' [w] (local cap) sound/synth/emux/emux_hwdep.c:75 snd_emux_hwdep_misc_mode() warn: potential spectre issue 'emu->portptrs[info.port]->ctrls' [w] (local cap)
Fix this by sanitizing both info.mode and info.port before using them to index emu->portptrs[i]->ctrls, emu->portptrs[info.port]->ctrls and emu->portptrs.
Notice that given that speculation windows are large, the policy is to kill the speculation on the first load and not worry if it can be completed with a dependent load/store [1].
[1] https://marc.info/?l=linux-kernel&m=152449131114778&w=2
Signed-off-by: Gustavo A. R. Silva gustavo@embeddedor.com Cc: stable@vger.kernel.org Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- sound/synth/emux/emux_hwdep.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
--- a/sound/synth/emux/emux_hwdep.c +++ b/sound/synth/emux/emux_hwdep.c @@ -22,9 +22,9 @@ #include <sound/core.h> #include <sound/hwdep.h> #include <linux/uaccess.h> +#include <linux/nospec.h> #include "emux_voice.h"
- #define TMP_CLIENT_ID 0x1001
/* @@ -66,13 +66,16 @@ snd_emux_hwdep_misc_mode(struct snd_emux return -EFAULT; if (info.mode < 0 || info.mode >= EMUX_MD_END) return -EINVAL; + info.mode = array_index_nospec(info.mode, EMUX_MD_END);
if (info.port < 0) { for (i = 0; i < emu->num_ports; i++) emu->portptrs[i]->ctrls[info.mode] = info.value; } else { - if (info.port < emu->num_ports) + if (info.port < emu->num_ports) { + info.port = array_index_nospec(info.port, emu->num_ports); emu->portptrs[info.port]->ctrls[info.mode] = info.value; + } } return 0; }
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Diana Craciun diana.craciun@nxp.com
commit 7d8bad99ba5a22892f0cad6881289fdc3875a930 upstream.
Currently for CONFIG_PPC_FSL_BOOK3E the spectre_v2 file is incorrect:
$ cat /sys/devices/system/cpu/vulnerabilities/spectre_v2 "Mitigation: Software count cache flush"
Which is wrong. Fix it to report vulnerable for now.
Fixes: ee13cb249fab ("powerpc/64s: Add support for software count cache flush") Cc: stable@vger.kernel.org # v4.19+ Signed-off-by: Diana Craciun diana.craciun@nxp.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/powerpc/kernel/security.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/powerpc/kernel/security.c +++ b/arch/powerpc/kernel/security.c @@ -22,7 +22,7 @@ enum count_cache_flush_type { COUNT_CACHE_FLUSH_SW = 0x2, COUNT_CACHE_FLUSH_HW = 0x4, }; -static enum count_cache_flush_type count_cache_flush_type; +static enum count_cache_flush_type count_cache_flush_type = COUNT_CACHE_FLUSH_NONE;
bool barrier_nospec_enabled; static bool no_nospec;
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnd Bergmann arnd@arndb.de
commit 2a9d92fb3a1282a4659f1bb6d5684018846537b7 upstream.
I ran into a link-time error with the atmel-quadspi driver on the EBSA110 platform:
drivers/mtd/built-in.o: In function `atmel_qspi_run_command': :(.text+0x1ee3c): undefined reference to `_memcpy_toio' :(.text+0x1ee48): undefined reference to `_memcpy_fromio'
The problem is that _memcpy_toio/_memcpy_fromio are not available on that platform, and we have to prevent building the driver there.
In case we want to backport this to older kernels: between linux-4.8 and linux-4.20, the Kconfig entry was in drivers/mtd/spi-nor/Kconfig but had the same problem.
Link: https://lore.kernel.org/patchwork/patch/812860/ Fixes: 161aaab8a067 ("mtd: atmel-quadspi: add driver for Atmel QSPI controller") Signed-off-by: Arnd Bergmann arnd@arndb.de Reviewed-by: Boris Brezillon boris.brezillon@bootlin.com Signed-off-by: Mark Brown broonie@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/mtd/spi-nor/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/mtd/spi-nor/Kconfig +++ b/drivers/mtd/spi-nor/Kconfig @@ -41,7 +41,7 @@ config SPI_ASPEED_SMC
config SPI_ATMEL_QUADSPI tristate "Atmel Quad SPI Controller" - depends on ARCH_AT91 || (ARM && COMPILE_TEST) + depends on ARCH_AT91 || (ARM && COMPILE_TEST && !ARCH_EBSA110) depends on OF && HAS_IOMEM help This enables support for the Quad SPI controller in master mode.
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miquel Raynal miquel.raynal@bootlin.com
commit cafb56dd741e61c99709bcd2b193a9a1d36def3b upstream.
marvell_nfc_wait_op() waits for completion during 'timeout_ms' milliseconds before throwing an error. While the logic is fine, the value of 'timeout_ms' is given by the core and actually correspond to the maximum time the NAND chip will take to complete the operation. Assuming there is no overhead in the propagation of the interrupt signal to the the NAND controller (through the Ready/Busy line), this delay does not take into account the latency of the operating system. For instance, for a page write, the delay given by the core is rounded up to 1ms. Hence, when the machine is over loaded, there is chances that this timeout will be reached.
There are two ways to solve this issue that are not incompatible: 1/ Enlarge the timeout value (if so, how much?). 2/ Check after the waiting method if we did not miss any interrupt because of the OS latency (an interrupt is still pending). In this case, we assume the operation exited successfully.
We choose the second approach that is a must in all cases, with the possibility to also modify the timeout value to be, e.g. at least 1 second in all cases.
Fixes: 02f26ecf8c77 ("mtd: nand: add reworked Marvell NAND controller driver") Cc: stable@vger.kernel.org Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Reviewed-by: Boris Brezillon boris.brezillon@bootlin.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/mtd/nand/raw/marvell_nand.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-)
--- a/drivers/mtd/nand/raw/marvell_nand.c +++ b/drivers/mtd/nand/raw/marvell_nand.c @@ -514,9 +514,14 @@ static void marvell_nfc_enable_int(struc writel_relaxed(reg & ~int_mask, nfc->regs + NDCR); }
-static void marvell_nfc_clear_int(struct marvell_nfc *nfc, u32 int_mask) +static u32 marvell_nfc_clear_int(struct marvell_nfc *nfc, u32 int_mask) { + u32 reg; + + reg = readl_relaxed(nfc->regs + NDSR); writel_relaxed(int_mask, nfc->regs + NDSR); + + return reg & int_mask; }
static void marvell_nfc_force_byte_access(struct nand_chip *chip, @@ -683,6 +688,7 @@ static int marvell_nfc_wait_cmdd(struct static int marvell_nfc_wait_op(struct nand_chip *chip, unsigned int timeout_ms) { struct marvell_nfc *nfc = to_marvell_nfc(chip->controller); + u32 pending; int ret;
/* Timeout is expressed in ms */ @@ -695,8 +701,13 @@ static int marvell_nfc_wait_op(struct na ret = wait_for_completion_timeout(&nfc->complete, msecs_to_jiffies(timeout_ms)); marvell_nfc_disable_int(nfc, NDCR_RDYM); - marvell_nfc_clear_int(nfc, NDSR_RDY(0) | NDSR_RDY(1)); - if (!ret) { + pending = marvell_nfc_clear_int(nfc, NDSR_RDY(0) | NDSR_RDY(1)); + + /* + * In case the interrupt was not served in the required time frame, + * check if the ISR was not served or if something went actually wrong. + */ + if (ret && !pending) { dev_err(nfc->dev, "Timeout waiting for RB signal\n"); return -ETIMEDOUT; }
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Boris Brezillon boris.brezillon@bootlin.com
commit b637ef779575a977068025f842ecd480a9671f3f upstream.
nand_jedec_detect() should return 1 when the PARAM page parsing succeeds, otherwise the core considers JEDEC detection failed and falls back to ID-based detection.
Fixes: 480139d9229e ("mtd: rawnand: get rid of the JEDEC parameter page in nand_chip") Cc: stable@vger.kernel.org Signed-off-by: Boris Brezillon boris.brezillon@bootlin.com Acked-by: Miquel Raynal miquel.raynal@bootlin.com Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/mtd/nand/raw/nand_jedec.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/mtd/nand/raw/nand_jedec.c +++ b/drivers/mtd/nand/raw/nand_jedec.c @@ -107,6 +107,8 @@ int nand_jedec_detect(struct nand_chip * pr_warn("Invalid codeword size\n"); }
+ ret = 1; + free_jedec_param_page: kfree(p); return ret;
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Boris Brezillon boris.brezillon@bootlin.com
commit 9b432630e0150b777c423fdef6a7b8d17dfa70b6 upstream.
Commit e1e6255c311b ("mtd: rawnand: omap2: convert driver to nand_scan()") moved part of the init code in the ->attach_chip hook and at the same time changed the struct device object passed to dma_request_chan() (&pdev->dev instead of pdev->dev.parent).
Fixes: e1e6255c311b ("mtd: rawnand: omap2: convert driver to nand_scan()") Reported-by: Alexander Sverdlin alexander.sverdlin@gmail.com Cc: stable@vger.kernel.org Signed-off-by: Boris Brezillon boris.brezillon@bootlin.com Tested-by: Alexander Sverdlin alexander.sverdlin@gmail.com Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/mtd/nand/raw/omap2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/mtd/nand/raw/omap2.c +++ b/drivers/mtd/nand/raw/omap2.c @@ -1944,7 +1944,7 @@ static int omap_nand_attach_chip(struct case NAND_OMAP_PREFETCH_DMA: dma_cap_zero(mask); dma_cap_set(DMA_SLAVE, mask); - info->dma = dma_request_chan(dev, "rxtx"); + info->dma = dma_request_chan(dev->parent, "rxtx");
if (IS_ERR(info->dma)) { dev_err(dev, "DMA engine request failed\n");
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mantas Mikulėnas grawity@gmail.com
commit 40906ebe3af6a48457151b3c6726b480f6a6cb13 upstream.
Tested with 4.19.9.
v2: Changed from CXT_FIXUP_MUTE_LED_GPIO to CXT_FIXUP_HP_DOCK because that's what the existing fixups for EliteBooks use.
Signed-off-by: Mantas Mikulėnas grawity@gmail.com Cc: stable@vger.kernel.org Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- sound/pci/hda/patch_conexant.c | 1 + 1 file changed, 1 insertion(+)
--- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -923,6 +923,7 @@ static const struct snd_pci_quirk cxt506 SND_PCI_QUIRK(0x103c, 0x8079, "HP EliteBook 840 G3", CXT_FIXUP_HP_DOCK), SND_PCI_QUIRK(0x103c, 0x807C, "HP EliteBook 820 G3", CXT_FIXUP_HP_DOCK), SND_PCI_QUIRK(0x103c, 0x80FD, "HP ProBook 640 G2", CXT_FIXUP_HP_DOCK), + SND_PCI_QUIRK(0x103c, 0x828c, "HP EliteBook 840 G4", CXT_FIXUP_HP_DOCK), SND_PCI_QUIRK(0x103c, 0x83b3, "HP EliteBook 830 G5", CXT_FIXUP_HP_DOCK), SND_PCI_QUIRK(0x103c, 0x83d3, "HP ProBook 640 G4", CXT_FIXUP_HP_DOCK), SND_PCI_QUIRK(0x103c, 0x8174, "HP Spectre x360", CXT_FIXUP_HP_SPECTRE),
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wandrille RONCE w@ndrille.fr
commit 9cf6533e8060d3896b88ea14b27f620e6504b84b upstream.
By default, there is no sound on Asus UX391UA on Linux.
This patch adds sound support on Asus UX391UA. Tested working by three different users.
The problem has also been described at https://bugs.launchpad.net/ubuntu/+source/alsa-driver/+bug/1784485
Signed-off-by: Wandrille RONCE w@ndrille.fr Cc: stable@vger.kernel.org Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
--- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6573,6 +6573,7 @@ static const struct snd_pci_quirk alc269 SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), + SND_PCI_QUIRK(0x1043, 0x10a1, "ASUS UX391UA", ALC294_FIXUP_ASUS_SPK), SND_PCI_QUIRK(0x1043, 0x10c0, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), SND_PCI_QUIRK(0x1043, 0x10d0, "ASUS X540LA/X540LJ", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Sakamoto o-takashi@sakamocchi.jp
commit 3d16200a3e55a39caa1c88419cb559c00316f721 upstream.
According to my memo at hand and saved records, writing 0x00000001 to SND_FF_REG_FETCH_PCM_FRAMES disables fetching PCM frames in corresponding channel, however current implement uses reversed logic. This results in muted volume in device side during playback.
This commit corrects the bug.
Cc: stable@vger.kernel.org # v4.12+ Fixes: 76fdb3a9e13a ('ALSA: fireface: add support for Fireface 400') Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- sound/firewire/fireface/ff-protocol-ff400.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/sound/firewire/fireface/ff-protocol-ff400.c +++ b/sound/firewire/fireface/ff-protocol-ff400.c @@ -152,7 +152,7 @@ static int ff400_switch_fetching_mode(st if (reg == NULL) return -ENOMEM;
- if (enable) { + if (!enable) { /* * Each quadlet is corresponding to data channels in a data * blocks in reverse order. Precisely, quadlets for available
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Sakamoto o-takashi@sakamocchi.jp
commit ada79fa5a0b374dd2c2262137c734da7524a8263 upstream.
In IEC 61883-1/6 engine of ALSA firewire stack, a packet handler has a second argument for 'the number of bytes in payload of isochronous packet'. However, an incoming packet handler without CIP header uses the value as 'the number of quadlets in the payload'. This brings userspace applications to receive the number of PCM frames as four times against real time.
This commit fixes the bug.
Cc: stable@vger.kernel.org # v4.12+ Fixes: 3b196c394dd ('ALSA: firewire-lib: add no-header packet processing') Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- sound/firewire/amdtp-stream.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/sound/firewire/amdtp-stream.c +++ b/sound/firewire/amdtp-stream.c @@ -654,15 +654,17 @@ end: }
static int handle_in_packet_without_header(struct amdtp_stream *s, - unsigned int payload_quadlets, unsigned int cycle, + unsigned int payload_length, unsigned int cycle, unsigned int index) { __be32 *buffer; + unsigned int payload_quadlets; unsigned int data_blocks; struct snd_pcm_substream *pcm; unsigned int pcm_frames;
buffer = s->buffer.packets[s->packet_index].buffer; + payload_quadlets = payload_length / 4; data_blocks = payload_quadlets / s->data_block_quadlets;
trace_in_packet_without_header(s, cycle, payload_quadlets, data_blocks,
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Sakamoto o-takashi@sakamocchi.jp
commit aa9a9e39b4f65733bf19d90cbd026e85a74efb99 upstream.
An initial commit to add tracepoints for packets without CIP headers introduces a wrong assignment to 'data_blocks' value of 'out_packet_without_header' tracepoint.
This commit fixes the bug.
Cc: stable@vger.kernel.org # v4.12+ Fixes: b164d2fd6e49 ('ALSA: firewire_lib: add tracepoints for packets without CIP headers') Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- sound/firewire/amdtp-stream-trace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/sound/firewire/amdtp-stream-trace.h +++ b/sound/firewire/amdtp-stream-trace.h @@ -169,7 +169,7 @@ TRACE_EVENT(out_packet_without_header, __entry->dest = fw_parent_device(s->unit)->node_id; __entry->payload_quadlets = payload_length / 4; __entry->data_blocks = data_blocks, - __entry->data_blocks = s->data_block_counter, + __entry->data_block_counter = s->data_block_counter, __entry->packet_index = s->packet_index; __entry->irq = !!in_interrupt(); __entry->index = index;
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Sakamoto o-takashi@sakamocchi.jp
commit 5ef108c53e6efd695e32aad969638ccbc35b4be9 upstream.
An initial commit to add tracepoints for packets without CIP headers uses different print formats for added tracepoints. However this is not convenient for users/developers to prepare debug tools.
This commit uses the same format for the two tracepoints.
Cc: stable@vger.kernel.org # v4.12+ Fixes: b164d2fd6e49 ('ALSA: firewire_lib: add tracepoints for packets without CIP headers') Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- sound/firewire/amdtp-stream-trace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/sound/firewire/amdtp-stream-trace.h +++ b/sound/firewire/amdtp-stream-trace.h @@ -131,7 +131,7 @@ TRACE_EVENT(in_packet_without_header, __entry->index = index; ), TP_printk( - "%02u %04u %04x %04x %02d %03u %3u %3u %02u %01u %02u", + "%02u %04u %04x %04x %02d %03u %02u %03u %02u %01u %02u", __entry->second, __entry->cycle, __entry->src,
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jian-Hong Pan jian-hong@endlessm.com
commit 82b01149ec94d746867d7f9156c44d775d4d2d67 upstream.
The headset mic of ASUS laptops like UX533FD, UX433FN and UX333FA, whose CODEC is Realtek ALC294 has jack auto detection feature. This patch enables the feature.
Fixes: 4e051106730d ("ALSA: hda/realtek: Enable audio jacks of ASUS UX533FD with ALC294") Signed-off-by: Daniel Drake drake@endlessm.com Signed-off-by: Jian-Hong Pan jian-hong@endlessm.com Cc: stable@vger.kernel.org Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- sound/pci/hda/patch_realtek.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6424,7 +6424,7 @@ static const struct hda_fixup alc269_fix [ALC294_FIXUP_ASUS_HEADSET_MIC] = { .type = HDA_FIXUP_PINS, .v.pins = (const struct hda_pintbl[]) { - { 0x19, 0x01a1113c }, /* use as headset mic, without its own jack detect */ + { 0x19, 0x01a1103c }, /* use as headset mic */ { } }, .chained = true,
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sameer Pujar spujar@nvidia.com
commit 63d2a9ec310d8bcc955574220d4631aa55c1a80c upstream.
Even after disabling interrupts on the module, it could be possible that irq handlers are still running. System hang is seen during suspend path. It was found that, there were pending writes on the HDA bus and clock was disabled by that time.
Above mentioned issue is fixed by clearing any pending irq handlers before disabling clocks and returning from hda suspend.
Suggested-by: Mohan Kumar mkumard@nvidia.com Suggested-by: Dara Ramesh dramesh@nvidia.com Signed-off-by: Sameer Pujar spujar@nvidia.com Cc: stable@vger.kernel.org Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- sound/pci/hda/hda_tegra.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/sound/pci/hda/hda_tegra.c +++ b/sound/pci/hda/hda_tegra.c @@ -233,10 +233,12 @@ static int hda_tegra_suspend(struct devi struct snd_card *card = dev_get_drvdata(dev); struct azx *chip = card->private_data; struct hda_tegra *hda = container_of(chip, struct hda_tegra, chip); + struct hdac_bus *bus = azx_bus(chip);
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
azx_stop_chip(chip); + synchronize_irq(bus->irq); azx_enter_link_reset(chip); hda_tegra_disable_clocks(hda);
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Terin Stock terin@terinstock.com
commit 6ed30a7d8ec29d3aba46e47aa8b4a44f077dda4e upstream.
Modify the wait delay utilize the high resolution timer API to allow for more precisely scheduled callbacks.
A previous commit added a 1ms retry delay after multiple consecutive NAKed transactions using jiffies. On systems with a low timer interrupt frequency, this delay may be significantly longer than specified, resulting in misbehavior with some USB devices.
This scenario was reached on a Raspberry Pi 3B with a Macally FDD-USB floppy drive (identified as 0424:0fdc Standard Microsystems Corp. Floppy, based on the USB97CFDC USB FDC). With the relay delay, the drive would be unable to mount a disk, replying with NAKs until the device was reset.
Using ktime, the delta between starting the timer (in dwc2_hcd_qh_add) and the callback function can be determined. With the original delay implementation, this value was consistently approximately 12ms. (output in us).
<idle>-0 [000] ..s. 1600.559974: dwc2_wait_timer_fn: wait_timer delta: 11976 <idle>-0 [000] ..s. 1600.571974: dwc2_wait_timer_fn: wait_timer delta: 11977 <idle>-0 [000] ..s. 1600.583974: dwc2_wait_timer_fn: wait_timer delta: 11976 <idle>-0 [000] ..s. 1600.595974: dwc2_wait_timer_fn: wait_timer delta: 11977
After converting the relay delay to using a higher resolution timer, the delay was much closer to 1ms.
<idle>-0 [000] d.h. 1956.553017: dwc2_wait_timer_fn: wait_timer delta: 1002 <idle>-0 [000] d.h. 1956.554114: dwc2_wait_timer_fn: wait_timer delta: 1002 <idle>-0 [000] d.h. 1957.542660: dwc2_wait_timer_fn: wait_timer delta: 1004 <idle>-0 [000] d.h. 1957.543701: dwc2_wait_timer_fn: wait_timer delta: 1002
The floppy drive operates properly with delays up to approximately 5ms, and sends NAKs for any delays that are longer.
Fixes: 38d2b5fb75c1 ("usb: dwc2: host: Don't retry NAKed transactions right away") Cc: stable@vger.kernel.org Reviewed-by: Douglas Anderson dianders@chromium.org Acked-by: Minas Harutyunyan hminas@synopsys.com Signed-off-by: Terin Stock terin@terinstock.com Signed-off-by: Felipe Balbi felipe.balbi@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/dwc2/hcd.h | 2 +- drivers/usb/dwc2/hcd_queue.c | 19 ++++++++++++------- 2 files changed, 13 insertions(+), 8 deletions(-)
--- a/drivers/usb/dwc2/hcd.h +++ b/drivers/usb/dwc2/hcd.h @@ -366,7 +366,7 @@ struct dwc2_qh { u32 desc_list_sz; u32 *n_bytes; struct timer_list unreserve_timer; - struct timer_list wait_timer; + struct hrtimer wait_timer; struct dwc2_tt *dwc_tt; int ttport; unsigned tt_buffer_dirty:1; --- a/drivers/usb/dwc2/hcd_queue.c +++ b/drivers/usb/dwc2/hcd_queue.c @@ -59,7 +59,7 @@ #define DWC2_UNRESERVE_DELAY (msecs_to_jiffies(5))
/* If we get a NAK, wait this long before retrying */ -#define DWC2_RETRY_WAIT_DELAY (msecs_to_jiffies(1)) +#define DWC2_RETRY_WAIT_DELAY 1*1E6L
/** * dwc2_periodic_channel_available() - Checks that a channel is available for a @@ -1464,10 +1464,12 @@ static void dwc2_deschedule_periodic(str * qh back to the "inactive" list, then queues transactions. * * @t: Pointer to wait_timer in a qh. + * + * Return: HRTIMER_NORESTART to not automatically restart this timer. */ -static void dwc2_wait_timer_fn(struct timer_list *t) +static enum hrtimer_restart dwc2_wait_timer_fn(struct hrtimer *t) { - struct dwc2_qh *qh = from_timer(qh, t, wait_timer); + struct dwc2_qh *qh = container_of(t, struct dwc2_qh, wait_timer); struct dwc2_hsotg *hsotg = qh->hsotg; unsigned long flags;
@@ -1491,6 +1493,7 @@ static void dwc2_wait_timer_fn(struct ti }
spin_unlock_irqrestore(&hsotg->lock, flags); + return HRTIMER_NORESTART; }
/** @@ -1521,7 +1524,8 @@ static void dwc2_qh_init(struct dwc2_hso /* Initialize QH */ qh->hsotg = hsotg; timer_setup(&qh->unreserve_timer, dwc2_unreserve_timer_fn, 0); - timer_setup(&qh->wait_timer, dwc2_wait_timer_fn, 0); + hrtimer_init(&qh->wait_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + qh->wait_timer.function = &dwc2_wait_timer_fn; qh->ep_type = ep_type; qh->ep_is_in = ep_is_in;
@@ -1690,7 +1694,7 @@ void dwc2_hcd_qh_free(struct dwc2_hsotg * won't do anything anyway, but we want it to finish before we free * memory. */ - del_timer_sync(&qh->wait_timer); + hrtimer_cancel(&qh->wait_timer);
dwc2_host_put_tt_info(hsotg, qh->dwc_tt);
@@ -1716,6 +1720,7 @@ int dwc2_hcd_qh_add(struct dwc2_hsotg *h { int status; u32 intr_mask; + ktime_t delay;
if (dbg_qh(qh)) dev_vdbg(hsotg->dev, "%s()\n", __func__); @@ -1734,8 +1739,8 @@ int dwc2_hcd_qh_add(struct dwc2_hsotg *h list_add_tail(&qh->qh_list_entry, &hsotg->non_periodic_sched_waiting); qh->wait_timer_cancel = false; - mod_timer(&qh->wait_timer, - jiffies + DWC2_RETRY_WAIT_DELAY + 1); + delay = ktime_set(0, DWC2_RETRY_WAIT_DELAY); + hrtimer_start(&qh->wait_timer, delay, HRTIMER_MODE_REL); } else { list_add_tail(&qh->qh_list_entry, &hsotg->non_periodic_sched_inactive);
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Scott Chen scott@labau.com.tw
commit 8d503f206c336677954160ac62f0c7d9c219cd89 upstream.
Add device ids to pl2303 for the HP POS pole displays: LM920: 03f0:026b TD620: 03f0:0956 LD960TA: 03f0:4439 LD220TA: 03f0:4349 LM940: 03f0:5039
Signed-off-by: Scott Chen scott@labau.com.tw Cc: stable stable@vger.kernel.org Signed-off-by: Johan Hovold johan@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/serial/pl2303.c | 5 +++++ drivers/usb/serial/pl2303.h | 5 +++++ 2 files changed, 10 insertions(+)
--- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -91,9 +91,14 @@ static const struct usb_device_id id_tab { USB_DEVICE(YCCABLE_VENDOR_ID, YCCABLE_PRODUCT_ID) }, { USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) }, { USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) }, + { USB_DEVICE(HP_VENDOR_ID, HP_LD220TA_PRODUCT_ID) }, { USB_DEVICE(HP_VENDOR_ID, HP_LD960_PRODUCT_ID) }, + { USB_DEVICE(HP_VENDOR_ID, HP_LD960TA_PRODUCT_ID) }, { USB_DEVICE(HP_VENDOR_ID, HP_LCM220_PRODUCT_ID) }, { USB_DEVICE(HP_VENDOR_ID, HP_LCM960_PRODUCT_ID) }, + { USB_DEVICE(HP_VENDOR_ID, HP_LM920_PRODUCT_ID) }, + { USB_DEVICE(HP_VENDOR_ID, HP_LM940_PRODUCT_ID) }, + { USB_DEVICE(HP_VENDOR_ID, HP_TD620_PRODUCT_ID) }, { USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) }, { USB_DEVICE(ZEAGLE_VENDOR_ID, ZEAGLE_N2ITION3_PRODUCT_ID) }, { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) }, --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h @@ -119,10 +119,15 @@
/* Hewlett-Packard POS Pole Displays */ #define HP_VENDOR_ID 0x03f0 +#define HP_LM920_PRODUCT_ID 0x026b +#define HP_TD620_PRODUCT_ID 0x0956 #define HP_LD960_PRODUCT_ID 0x0b39 #define HP_LCM220_PRODUCT_ID 0x3139 #define HP_LCM960_PRODUCT_ID 0x3239 #define HP_LD220_PRODUCT_ID 0x3524 +#define HP_LD220TA_PRODUCT_ID 0x4349 +#define HP_LD960TA_PRODUCT_ID 0x4439 +#define HP_LM940_PRODUCT_ID 0x5039
/* Cressi Edy (diving computer) PC interface */ #define CRESSI_VENDOR_ID 0x04b8
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jörgen Storvist jorgen.storvist@gmail.com
commit 4b2c01ad902ec02fa962b233decd2f14be3714ba upstream.
Added USB serial option driver support for Fibocom NL678 series cellular module: VID 2cb7 and PIDs 0x0104 and 0x0105. Reserved network and ADB interfaces.
T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=2cb7 ProdID=0104 Rev=03.10 S: Manufacturer=Fibocom S: Product=Fibocom NL678-E Modem S: SerialNumber=12345678 C: #Ifs= 6 Cfg#= 1 Atr=a0 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option I: If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option I: If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qmi_wwan I: If#= 5 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none)
T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 3 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=2cb7 ProdID=0105 Rev=03.10 S: Manufacturer=Fibocom S: Product=Fibocom NL678-E Modem S: SerialNumber=12345678 C: #Ifs= 7 Cfg#= 1 Atr=a0 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option I: If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option I: If#= 4 Alt= 0 #EPs= 1 Cls=02(commc) Sub=06 Prot=00 Driver=cdc_ether I: If#= 5 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=cdc_ether I: If#= 6 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none)
Signed-off-by: Jörgen Storvist jorgen.storvist@gmail.com Cc: stable stable@vger.kernel.org Acked-by: Johan Hovold johan@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/serial/option.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -1955,6 +1955,10 @@ static const struct usb_device_id option { USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0xa31d, 0xff, 0x06, 0x1b) }, { USB_DEVICE(0x1508, 0x1001), /* Fibocom NL668 */ .driver_info = RSVD(4) | RSVD(5) | RSVD(6) }, + { USB_DEVICE(0x2cb7, 0x0104), /* Fibocom NL678 series */ + .driver_info = RSVD(4) | RSVD(5) }, + { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0105, 0xff), /* Fibocom NL678 series */ + .driver_info = RSVD(6) }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, option_ids);
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jia-Ju Bai baijiaju1990@gmail.com
commit c85400f886e3d41e69966470879f635a2b50084c upstream.
The function r8a66597_endpoint_disable() and r8a66597_urb_enqueue() may be concurrently executed. The two functions both access a possible shared variable "hep->hcpriv".
This shared variable is freed by r8a66597_endpoint_disable() via the call path: r8a66597_endpoint_disable kfree(hep->hcpriv) (line 1995 in Linux-4.19)
This variable is read by r8a66597_urb_enqueue() via the call path: r8a66597_urb_enqueue spin_lock_irqsave(&r8a66597->lock) init_pipe_info enable_r8a66597_pipe pipe = hep->hcpriv (line 802 in Linux-4.19)
The read operation is protected by a spinlock, but the free operation is not protected by this spinlock, thus a concurrency use-after-free bug may occur.
To fix this bug, the spin-lock and spin-unlock function calls in r8a66597_endpoint_disable() are moved to protect the free operation.
Signed-off-by: Jia-Ju Bai baijiaju1990@gmail.com Cc: stable stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/host/r8a66597-hcd.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
--- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -1979,6 +1979,8 @@ static int r8a66597_urb_dequeue(struct u
static void r8a66597_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep) +__acquires(r8a66597->lock) +__releases(r8a66597->lock) { struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd); struct r8a66597_pipe *pipe = (struct r8a66597_pipe *)hep->hcpriv; @@ -1991,13 +1993,14 @@ static void r8a66597_endpoint_disable(st return; pipenum = pipe->info.pipenum;
+ spin_lock_irqsave(&r8a66597->lock, flags); if (pipenum == 0) { kfree(hep->hcpriv); hep->hcpriv = NULL; + spin_unlock_irqrestore(&r8a66597->lock, flags); return; }
- spin_lock_irqsave(&r8a66597->lock, flags); pipe_stop(r8a66597, pipe); pipe_irq_disable(r8a66597, pipenum); disable_irq_empty(r8a66597, pipenum);
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Martin Blumenstingl martin.blumenstingl@googlemail.com
commit cc10ce0c51b13d1566d0ec1dcb472fb86330b391 upstream.
Disable power_down by setting the parameter to DWC2_POWER_DOWN_PARAM_NONE. This fixes a problem on various Amlogic Meson SoCs where USB devices are only recognized when plugged in before booting Linux. A hot-plugged USB device was not detected even though the device got power (my USB thumb drive for example has an LED which lit up).
A similar fix was implemented for Rockchip SoCs in commit c216765d3a1def ("usb: dwc2: disable power_down on rockchip devices"). That commit suggests that a change in the dwc2 driver is the cause because the default value for the "hibernate" parameter (which then got renamed to "power_down" to support other modes) was changed in the v4.17 merge window with: commit 6d23ee9caa6790 ("Merge tag 'usb-for-v4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-testing").
Cc: stable@vger.kernel.org # 4.19 Acked-by: Minas Harutyunyan hminas@synopsys.com Suggested-by: Christian Hewitt christianshewitt@gmail.com Signed-off-by: Martin Blumenstingl martin.blumenstingl@googlemail.com Signed-off-by: Felipe Balbi felipe.balbi@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/dwc2/params.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/usb/dwc2/params.c +++ b/drivers/usb/dwc2/params.c @@ -111,6 +111,7 @@ static void dwc2_set_amlogic_params(stru p->phy_type = DWC2_PHY_TYPE_PARAM_UTMI; p->ahbcfg = GAHBCFG_HBSTLEN_INCR8 << GAHBCFG_HBSTLEN_SHIFT; + p->power_down = DWC2_POWER_DOWN_PARAM_NONE; }
static void dwc2_set_amcc_params(struct dwc2_hsotg *hsotg)
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stephan Gerhold stephan@gerhold.net
commit 3004cfd6204927c1294060b849029cf0c2651074 upstream.
Commit 211f658b7b40 ("usb: dwc3: pci: Use devm functions to get the phy GPIOs") changed the code to claim the PHY GPIOs permanently for Intel Baytrail devices.
This causes issues when the actual PHY driver attempts to claim the same GPIO descriptors. For example, tusb1210 now fails to probe with:
tusb1210: probe of dwc3.0.auto.ulpi failed with error -16 (EBUSY)
dwc3-pci needs to turn on the PHY once before dwc3 is loaded, but usually the PHY driver will then hold the GPIOs to turn off the PHY when requested (e.g. during suspend).
To fix the problem, this reverts the commit to restore the old behavior to put the GPIOs immediately after usage.
Link: https://www.spinics.net/lists/linux-usb/msg174681.html Cc: stable@vger.kernel.org Signed-off-by: Stephan Gerhold stephan@gerhold.net Signed-off-by: Felipe Balbi felipe.balbi@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/dwc3/dwc3-pci.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
--- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -170,20 +170,20 @@ static int dwc3_pci_quirks(struct dwc3_p * put the gpio descriptors again here because the phy driver * might want to grab them, too. */ - gpio = devm_gpiod_get_optional(&pdev->dev, "cs", - GPIOD_OUT_LOW); + gpio = gpiod_get_optional(&pdev->dev, "cs", GPIOD_OUT_LOW); if (IS_ERR(gpio)) return PTR_ERR(gpio);
gpiod_set_value_cansleep(gpio, 1); + gpiod_put(gpio);
- gpio = devm_gpiod_get_optional(&pdev->dev, "reset", - GPIOD_OUT_LOW); + gpio = gpiod_get_optional(&pdev->dev, "reset", GPIOD_OUT_LOW); if (IS_ERR(gpio)) return PTR_ERR(gpio);
if (gpio) { gpiod_set_value_cansleep(gpio, 1); + gpiod_put(gpio); usleep_range(10000, 11000); } }
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heikki Krogerus heikki.krogerus@linux.intel.com
commit c3788cd9963eb2e77de3c24142fb7c67b61f1a26 upstream.
That makes the USB role switch support option visible and selectable for the user. The class driver is also moved to drivers/usb/roles/ directory.
This will fix an issue that we have with the Intel USB role switch driver on systems that don't have USB Type-C connectors:
Intel USB role switch driver depends on the USB role switch class as it should, but since there was no way for the user to enable the USB role switch class, there was also no way to select that driver. USB Type-C drivers select the USB role switch class which makes the Intel USB role switch driver available and therefore hides the problem.
So in practice Intel USB role switch driver was depending on USB Type-C drivers.
Fixes: f6fb9ec02be1 ("usb: roles: Add Intel xHCI USB role switch driver") Cc: stable@vger.kernel.org Signed-off-by: Heikki Krogerus heikki.krogerus@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/Kconfig | 4 drivers/usb/common/Makefile | 1 drivers/usb/common/roles.c | 314 -------------------------------------------- drivers/usb/roles/Kconfig | 13 + drivers/usb/roles/Makefile | 4 drivers/usb/roles/class.c | 314 ++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 330 insertions(+), 320 deletions(-)
--- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig @@ -205,8 +205,4 @@ config USB_ULPI_BUS To compile this driver as a module, choose M here: the module will be called ulpi.
-config USB_ROLE_SWITCH - tristate - select USB_COMMON - endif # USB_SUPPORT --- a/drivers/usb/common/Makefile +++ b/drivers/usb/common/Makefile @@ -9,4 +9,3 @@ usb-common-$(CONFIG_USB_LED_TRIG) += led
obj-$(CONFIG_USB_OTG_FSM) += usb-otg-fsm.o obj-$(CONFIG_USB_ULPI_BUS) += ulpi.o -obj-$(CONFIG_USB_ROLE_SWITCH) += roles.o --- a/drivers/usb/common/roles.c +++ /dev/null @@ -1,314 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * USB Role Switch Support - * - * Copyright (C) 2018 Intel Corporation - * Author: Heikki Krogerus heikki.krogerus@linux.intel.com - * Hans de Goede hdegoede@redhat.com - */ - -#include <linux/usb/role.h> -#include <linux/device.h> -#include <linux/module.h> -#include <linux/mutex.h> -#include <linux/slab.h> - -static struct class *role_class; - -struct usb_role_switch { - struct device dev; - struct mutex lock; /* device lock*/ - enum usb_role role; - - /* From descriptor */ - struct device *usb2_port; - struct device *usb3_port; - struct device *udc; - usb_role_switch_set_t set; - usb_role_switch_get_t get; - bool allow_userspace_control; -}; - -#define to_role_switch(d) container_of(d, struct usb_role_switch, dev) - -/** - * usb_role_switch_set_role - Set USB role for a switch - * @sw: USB role switch - * @role: USB role to be switched to - * - * Set USB role @role for @sw. - */ -int usb_role_switch_set_role(struct usb_role_switch *sw, enum usb_role role) -{ - int ret; - - if (IS_ERR_OR_NULL(sw)) - return 0; - - mutex_lock(&sw->lock); - - ret = sw->set(sw->dev.parent, role); - if (!ret) - sw->role = role; - - mutex_unlock(&sw->lock); - - return ret; -} -EXPORT_SYMBOL_GPL(usb_role_switch_set_role); - -/** - * usb_role_switch_get_role - Get the USB role for a switch - * @sw: USB role switch - * - * Depending on the role-switch-driver this function returns either a cached - * value of the last set role, or reads back the actual value from the hardware. - */ -enum usb_role usb_role_switch_get_role(struct usb_role_switch *sw) -{ - enum usb_role role; - - if (IS_ERR_OR_NULL(sw)) - return USB_ROLE_NONE; - - mutex_lock(&sw->lock); - - if (sw->get) - role = sw->get(sw->dev.parent); - else - role = sw->role; - - mutex_unlock(&sw->lock); - - return role; -} -EXPORT_SYMBOL_GPL(usb_role_switch_get_role); - -static int __switch_match(struct device *dev, const void *name) -{ - return !strcmp((const char *)name, dev_name(dev)); -} - -static void *usb_role_switch_match(struct device_connection *con, int ep, - void *data) -{ - struct device *dev; - - dev = class_find_device(role_class, NULL, con->endpoint[ep], - __switch_match); - - return dev ? to_role_switch(dev) : ERR_PTR(-EPROBE_DEFER); -} - -/** - * usb_role_switch_get - Find USB role switch linked with the caller - * @dev: The caller device - * - * Finds and returns role switch linked with @dev. The reference count for the - * found switch is incremented. - */ -struct usb_role_switch *usb_role_switch_get(struct device *dev) -{ - struct usb_role_switch *sw; - - sw = device_connection_find_match(dev, "usb-role-switch", NULL, - usb_role_switch_match); - - if (!IS_ERR_OR_NULL(sw)) - WARN_ON(!try_module_get(sw->dev.parent->driver->owner)); - - return sw; -} -EXPORT_SYMBOL_GPL(usb_role_switch_get); - -/** - * usb_role_switch_put - Release handle to a switch - * @sw: USB Role Switch - * - * Decrement reference count for @sw. - */ -void usb_role_switch_put(struct usb_role_switch *sw) -{ - if (!IS_ERR_OR_NULL(sw)) { - put_device(&sw->dev); - module_put(sw->dev.parent->driver->owner); - } -} -EXPORT_SYMBOL_GPL(usb_role_switch_put); - -static umode_t -usb_role_switch_is_visible(struct kobject *kobj, struct attribute *attr, int n) -{ - struct device *dev = container_of(kobj, typeof(*dev), kobj); - struct usb_role_switch *sw = to_role_switch(dev); - - if (sw->allow_userspace_control) - return attr->mode; - - return 0; -} - -static const char * const usb_roles[] = { - [USB_ROLE_NONE] = "none", - [USB_ROLE_HOST] = "host", - [USB_ROLE_DEVICE] = "device", -}; - -static ssize_t -role_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct usb_role_switch *sw = to_role_switch(dev); - enum usb_role role = usb_role_switch_get_role(sw); - - return sprintf(buf, "%s\n", usb_roles[role]); -} - -static ssize_t role_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t size) -{ - struct usb_role_switch *sw = to_role_switch(dev); - int ret; - - ret = sysfs_match_string(usb_roles, buf); - if (ret < 0) { - bool res; - - /* Extra check if the user wants to disable the switch */ - ret = kstrtobool(buf, &res); - if (ret || res) - return -EINVAL; - } - - ret = usb_role_switch_set_role(sw, ret); - if (ret) - return ret; - - return size; -} -static DEVICE_ATTR_RW(role); - -static struct attribute *usb_role_switch_attrs[] = { - &dev_attr_role.attr, - NULL, -}; - -static const struct attribute_group usb_role_switch_group = { - .is_visible = usb_role_switch_is_visible, - .attrs = usb_role_switch_attrs, -}; - -static const struct attribute_group *usb_role_switch_groups[] = { - &usb_role_switch_group, - NULL, -}; - -static int -usb_role_switch_uevent(struct device *dev, struct kobj_uevent_env *env) -{ - int ret; - - ret = add_uevent_var(env, "USB_ROLE_SWITCH=%s", dev_name(dev)); - if (ret) - dev_err(dev, "failed to add uevent USB_ROLE_SWITCH\n"); - - return ret; -} - -static void usb_role_switch_release(struct device *dev) -{ - struct usb_role_switch *sw = to_role_switch(dev); - - kfree(sw); -} - -static const struct device_type usb_role_dev_type = { - .name = "usb_role_switch", - .groups = usb_role_switch_groups, - .uevent = usb_role_switch_uevent, - .release = usb_role_switch_release, -}; - -/** - * usb_role_switch_register - Register USB Role Switch - * @parent: Parent device for the switch - * @desc: Description of the switch - * - * USB Role Switch is a device capable or choosing the role for USB connector. - * On platforms where the USB controller is dual-role capable, the controller - * driver will need to register the switch. On platforms where the USB host and - * USB device controllers behind the connector are separate, there will be a - * mux, and the driver for that mux will need to register the switch. - * - * Returns handle to a new role switch or ERR_PTR. The content of @desc is - * copied. - */ -struct usb_role_switch * -usb_role_switch_register(struct device *parent, - const struct usb_role_switch_desc *desc) -{ - struct usb_role_switch *sw; - int ret; - - if (!desc || !desc->set) - return ERR_PTR(-EINVAL); - - sw = kzalloc(sizeof(*sw), GFP_KERNEL); - if (!sw) - return ERR_PTR(-ENOMEM); - - mutex_init(&sw->lock); - - sw->allow_userspace_control = desc->allow_userspace_control; - sw->usb2_port = desc->usb2_port; - sw->usb3_port = desc->usb3_port; - sw->udc = desc->udc; - sw->set = desc->set; - sw->get = desc->get; - - sw->dev.parent = parent; - sw->dev.class = role_class; - sw->dev.type = &usb_role_dev_type; - dev_set_name(&sw->dev, "%s-role-switch", dev_name(parent)); - - ret = device_register(&sw->dev); - if (ret) { - put_device(&sw->dev); - return ERR_PTR(ret); - } - - /* TODO: Symlinks for the host port and the device controller. */ - - return sw; -} -EXPORT_SYMBOL_GPL(usb_role_switch_register); - -/** - * usb_role_switch_unregister - Unregsiter USB Role Switch - * @sw: USB Role Switch - * - * Unregister switch that was registered with usb_role_switch_register(). - */ -void usb_role_switch_unregister(struct usb_role_switch *sw) -{ - if (!IS_ERR_OR_NULL(sw)) - device_unregister(&sw->dev); -} -EXPORT_SYMBOL_GPL(usb_role_switch_unregister); - -static int __init usb_roles_init(void) -{ - role_class = class_create(THIS_MODULE, "usb_role"); - return PTR_ERR_OR_ZERO(role_class); -} -subsys_initcall(usb_roles_init); - -static void __exit usb_roles_exit(void) -{ - class_destroy(role_class); -} -module_exit(usb_roles_exit); - -MODULE_AUTHOR("Heikki Krogerus heikki.krogerus@linux.intel.com"); -MODULE_AUTHOR("Hans de Goede hdegoede@redhat.com"); -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("USB Role Class"); --- a/drivers/usb/roles/Kconfig +++ b/drivers/usb/roles/Kconfig @@ -1,3 +1,16 @@ +config USB_ROLE_SWITCH + tristate "USB Role Switch Support" + help + USB Role Switch is a device that can select the USB role - host or + device - for a USB port (connector). In most cases dual-role capable + USB controller will also represent the switch, but on some platforms + multiplexer/demultiplexer switch is used to route the data lines on + the USB connector between separate USB host and device controllers. + + Say Y here if your USB connectors support both device and host roles. + To compile the driver as module, choose M here: the module will be + called roles.ko. + if USB_ROLE_SWITCH
config USB_ROLES_INTEL_XHCI --- a/drivers/usb/roles/Makefile +++ b/drivers/usb/roles/Makefile @@ -1 +1,3 @@ -obj-$(CONFIG_USB_ROLES_INTEL_XHCI) += intel-xhci-usb-role-switch.o +obj-$(CONFIG_USB_ROLE_SWITCH) += roles.o +roles-y := class.o +obj-$(CONFIG_USB_ROLES_INTEL_XHCI) += intel-xhci-usb-role-switch.o --- /dev/null +++ b/drivers/usb/roles/class.c @@ -0,0 +1,314 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * USB Role Switch Support + * + * Copyright (C) 2018 Intel Corporation + * Author: Heikki Krogerus heikki.krogerus@linux.intel.com + * Hans de Goede hdegoede@redhat.com + */ + +#include <linux/usb/role.h> +#include <linux/device.h> +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/slab.h> + +static struct class *role_class; + +struct usb_role_switch { + struct device dev; + struct mutex lock; /* device lock*/ + enum usb_role role; + + /* From descriptor */ + struct device *usb2_port; + struct device *usb3_port; + struct device *udc; + usb_role_switch_set_t set; + usb_role_switch_get_t get; + bool allow_userspace_control; +}; + +#define to_role_switch(d) container_of(d, struct usb_role_switch, dev) + +/** + * usb_role_switch_set_role - Set USB role for a switch + * @sw: USB role switch + * @role: USB role to be switched to + * + * Set USB role @role for @sw. + */ +int usb_role_switch_set_role(struct usb_role_switch *sw, enum usb_role role) +{ + int ret; + + if (IS_ERR_OR_NULL(sw)) + return 0; + + mutex_lock(&sw->lock); + + ret = sw->set(sw->dev.parent, role); + if (!ret) + sw->role = role; + + mutex_unlock(&sw->lock); + + return ret; +} +EXPORT_SYMBOL_GPL(usb_role_switch_set_role); + +/** + * usb_role_switch_get_role - Get the USB role for a switch + * @sw: USB role switch + * + * Depending on the role-switch-driver this function returns either a cached + * value of the last set role, or reads back the actual value from the hardware. + */ +enum usb_role usb_role_switch_get_role(struct usb_role_switch *sw) +{ + enum usb_role role; + + if (IS_ERR_OR_NULL(sw)) + return USB_ROLE_NONE; + + mutex_lock(&sw->lock); + + if (sw->get) + role = sw->get(sw->dev.parent); + else + role = sw->role; + + mutex_unlock(&sw->lock); + + return role; +} +EXPORT_SYMBOL_GPL(usb_role_switch_get_role); + +static int __switch_match(struct device *dev, const void *name) +{ + return !strcmp((const char *)name, dev_name(dev)); +} + +static void *usb_role_switch_match(struct device_connection *con, int ep, + void *data) +{ + struct device *dev; + + dev = class_find_device(role_class, NULL, con->endpoint[ep], + __switch_match); + + return dev ? to_role_switch(dev) : ERR_PTR(-EPROBE_DEFER); +} + +/** + * usb_role_switch_get - Find USB role switch linked with the caller + * @dev: The caller device + * + * Finds and returns role switch linked with @dev. The reference count for the + * found switch is incremented. + */ +struct usb_role_switch *usb_role_switch_get(struct device *dev) +{ + struct usb_role_switch *sw; + + sw = device_connection_find_match(dev, "usb-role-switch", NULL, + usb_role_switch_match); + + if (!IS_ERR_OR_NULL(sw)) + WARN_ON(!try_module_get(sw->dev.parent->driver->owner)); + + return sw; +} +EXPORT_SYMBOL_GPL(usb_role_switch_get); + +/** + * usb_role_switch_put - Release handle to a switch + * @sw: USB Role Switch + * + * Decrement reference count for @sw. + */ +void usb_role_switch_put(struct usb_role_switch *sw) +{ + if (!IS_ERR_OR_NULL(sw)) { + put_device(&sw->dev); + module_put(sw->dev.parent->driver->owner); + } +} +EXPORT_SYMBOL_GPL(usb_role_switch_put); + +static umode_t +usb_role_switch_is_visible(struct kobject *kobj, struct attribute *attr, int n) +{ + struct device *dev = container_of(kobj, typeof(*dev), kobj); + struct usb_role_switch *sw = to_role_switch(dev); + + if (sw->allow_userspace_control) + return attr->mode; + + return 0; +} + +static const char * const usb_roles[] = { + [USB_ROLE_NONE] = "none", + [USB_ROLE_HOST] = "host", + [USB_ROLE_DEVICE] = "device", +}; + +static ssize_t +role_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct usb_role_switch *sw = to_role_switch(dev); + enum usb_role role = usb_role_switch_get_role(sw); + + return sprintf(buf, "%s\n", usb_roles[role]); +} + +static ssize_t role_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + struct usb_role_switch *sw = to_role_switch(dev); + int ret; + + ret = sysfs_match_string(usb_roles, buf); + if (ret < 0) { + bool res; + + /* Extra check if the user wants to disable the switch */ + ret = kstrtobool(buf, &res); + if (ret || res) + return -EINVAL; + } + + ret = usb_role_switch_set_role(sw, ret); + if (ret) + return ret; + + return size; +} +static DEVICE_ATTR_RW(role); + +static struct attribute *usb_role_switch_attrs[] = { + &dev_attr_role.attr, + NULL, +}; + +static const struct attribute_group usb_role_switch_group = { + .is_visible = usb_role_switch_is_visible, + .attrs = usb_role_switch_attrs, +}; + +static const struct attribute_group *usb_role_switch_groups[] = { + &usb_role_switch_group, + NULL, +}; + +static int +usb_role_switch_uevent(struct device *dev, struct kobj_uevent_env *env) +{ + int ret; + + ret = add_uevent_var(env, "USB_ROLE_SWITCH=%s", dev_name(dev)); + if (ret) + dev_err(dev, "failed to add uevent USB_ROLE_SWITCH\n"); + + return ret; +} + +static void usb_role_switch_release(struct device *dev) +{ + struct usb_role_switch *sw = to_role_switch(dev); + + kfree(sw); +} + +static const struct device_type usb_role_dev_type = { + .name = "usb_role_switch", + .groups = usb_role_switch_groups, + .uevent = usb_role_switch_uevent, + .release = usb_role_switch_release, +}; + +/** + * usb_role_switch_register - Register USB Role Switch + * @parent: Parent device for the switch + * @desc: Description of the switch + * + * USB Role Switch is a device capable or choosing the role for USB connector. + * On platforms where the USB controller is dual-role capable, the controller + * driver will need to register the switch. On platforms where the USB host and + * USB device controllers behind the connector are separate, there will be a + * mux, and the driver for that mux will need to register the switch. + * + * Returns handle to a new role switch or ERR_PTR. The content of @desc is + * copied. + */ +struct usb_role_switch * +usb_role_switch_register(struct device *parent, + const struct usb_role_switch_desc *desc) +{ + struct usb_role_switch *sw; + int ret; + + if (!desc || !desc->set) + return ERR_PTR(-EINVAL); + + sw = kzalloc(sizeof(*sw), GFP_KERNEL); + if (!sw) + return ERR_PTR(-ENOMEM); + + mutex_init(&sw->lock); + + sw->allow_userspace_control = desc->allow_userspace_control; + sw->usb2_port = desc->usb2_port; + sw->usb3_port = desc->usb3_port; + sw->udc = desc->udc; + sw->set = desc->set; + sw->get = desc->get; + + sw->dev.parent = parent; + sw->dev.class = role_class; + sw->dev.type = &usb_role_dev_type; + dev_set_name(&sw->dev, "%s-role-switch", dev_name(parent)); + + ret = device_register(&sw->dev); + if (ret) { + put_device(&sw->dev); + return ERR_PTR(ret); + } + + /* TODO: Symlinks for the host port and the device controller. */ + + return sw; +} +EXPORT_SYMBOL_GPL(usb_role_switch_register); + +/** + * usb_role_switch_unregister - Unregsiter USB Role Switch + * @sw: USB Role Switch + * + * Unregister switch that was registered with usb_role_switch_register(). + */ +void usb_role_switch_unregister(struct usb_role_switch *sw) +{ + if (!IS_ERR_OR_NULL(sw)) + device_unregister(&sw->dev); +} +EXPORT_SYMBOL_GPL(usb_role_switch_unregister); + +static int __init usb_roles_init(void) +{ + role_class = class_create(THIS_MODULE, "usb_role"); + return PTR_ERR_OR_ZERO(role_class); +} +subsys_initcall(usb_roles_init); + +static void __exit usb_roles_exit(void) +{ + class_destroy(role_class); +} +module_exit(usb_roles_exit); + +MODULE_AUTHOR("Heikki Krogerus heikki.krogerus@linux.intel.com"); +MODULE_AUTHOR("Hans de Goede hdegoede@redhat.com"); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("USB Role Class");
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Malcolm Priestley tvboxspy@gmail.com
commit 255095fa7f62ff09b6f61393414535c59c6b4cb0 upstream.
commit 1a0c10ed7bb1 ("media: dvb-usb-v2: stop using coherent memory for URBs") incorrectly adds URB_FREE_BUFFER after every urb transfer.
It cannot use this flag because it reconfigures the URBs accordingly to suit connected devices. In doing a call to usb_free_urb is made and invertedly frees the buffers.
The stream buffer should remain constant while driver is up.
Signed-off-by: Malcolm Priestley tvboxspy@gmail.com CC: stable@vger.kernel.org # v4.18+ Signed-off-by: Sean Young sean@mess.org Signed-off-by: Mauro Carvalho Chehab mchehab+samsung@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/media/usb/dvb-usb-v2/usb_urb.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
--- a/drivers/media/usb/dvb-usb-v2/usb_urb.c +++ b/drivers/media/usb/dvb-usb-v2/usb_urb.c @@ -155,7 +155,6 @@ static int usb_urb_alloc_bulk_urbs(struc stream->props.u.bulk.buffersize, usb_urb_complete, stream);
- stream->urb_list[i]->transfer_flags = URB_FREE_BUFFER; stream->urbs_initialized++; } return 0; @@ -186,7 +185,7 @@ static int usb_urb_alloc_isoc_urbs(struc urb->complete = usb_urb_complete; urb->pipe = usb_rcvisocpipe(stream->udev, stream->props.endpoint); - urb->transfer_flags = URB_ISO_ASAP | URB_FREE_BUFFER; + urb->transfer_flags = URB_ISO_ASAP; urb->interval = stream->props.u.isoc.interval; urb->number_of_packets = stream->props.u.isoc.framesperurb; urb->transfer_buffer_length = stream->props.u.isoc.framesize * @@ -210,7 +209,7 @@ static int usb_free_stream_buffers(struc if (stream->state & USB_STATE_URB_BUF) { while (stream->buf_num) { stream->buf_num--; - stream->buf_list[stream->buf_num] = NULL; + kfree(stream->buf_list[stream->buf_num]); } }
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Torvalds torvalds@linux-foundation.org
commit 0b2c8f8b6b0c7530e2866c95862546d0da2057b0 upstream.
When commit fddcd00a49e9 ("drm/i915: Force the slow path after a user-write error") unified the error handling for various user access problems, it didn't do the user_access_end() that is needed for the unsafe_put_user() case.
It's not a huge deal: a missed user_access_end() will only mean that SMAP protection isn't active afterwards, and for the error case we'll be returning to user mode soon enough anyway. But it's wrong, and adding the proper user_access_end() is trivial enough (and doing it for the other error cases where it isn't needed doesn't hurt).
I noticed it while doing the same prep-work for changing user_access_begin() that precipitated the access_ok() changes in commit 96d4f267e40f ("Remove 'type' argument from access_ok() function").
Fixes: fddcd00a49e9 ("drm/i915: Force the slow path after a user-write error") Cc: Chris Wilson chris@chris-wilson.co.uk Cc: Joonas Lahtinen joonas.lahtinen@linux.intel.com Cc: stable@kernel.org # v4.20 Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -1605,6 +1605,7 @@ static int eb_copy_relocations(const str (char __user *)urelocs + copied, len)) { end_user: + user_access_end(); kvfree(relocs); err = -EFAULT; goto err;
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Colin Ian King colin.king@canonical.com
commit c58eef061dda7d843dcc0ad6fea7e597d4c377c0 upstream.
Currently the cmd.read_write setting is not initialized so it contains garbage from the stack. Fix this by setting it to 0 to indicate a read is required.
Detected by CoverityScan, CID#1357925 ("Uninitialized scalar variable")
Fixes: c5c77ba18ea6 ("staging: wilc1000: Add SDIO/SPI 802.11 driver") Signed-off-by: Colin Ian King colin.king@canonical.com Cc: stable stable@vger.kernel.org Acked-by: Ajay Singh ajay.kathat@microchip.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/staging/wilc1000/wilc_sdio.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/staging/wilc1000/wilc_sdio.c +++ b/drivers/staging/wilc1000/wilc_sdio.c @@ -841,6 +841,7 @@ static int sdio_read_int(struct wilc *wi if (!sdio_priv->irq_gpio) { int i;
+ cmd.read_write = 0; cmd.function = 1; cmd.address = 0x04; cmd.data = 0;
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter dan.carpenter@oracle.com
commit 649496b603000135683ee76d7ea499456617bf17 upstream.
We free instance here and in the caller. It should be only the caller which handles it.
Fixes: d7ca3a71545b ("staging: bcm2835-audio: Operate non-atomic PCM ops") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Reviewed-by: Takashi Iwai tiwai@suse.de Cc: stable stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c | 1 - 1 file changed, 1 deletion(-)
--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c +++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c @@ -143,7 +143,6 @@ vc_vchi_audio_init(VCHI_INSTANCE_T vchi_ dev_err(instance->dev, "failed to open VCHI service connection (status=%d)\n", status); - kfree(instance); return -EPERM; }
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans de Goede hdegoede@redhat.com
commit 984bfb398a3af6fa9b7e80165e524933b0616686 upstream.
The Clapper model Chromebook uses pmc_plt_clk_0 instead of pmc_plt_clk_3 for the mclk, just like the Swanky model.
This commit adds a DMI based quirk for this.
This fixing audio no longer working on these devices after commit 648e921888ad ("clk: x86: Stop marking clocks as CLK_IS_CRITICAL") that commit fixes us unnecessary keeping unused clocks on, but in case of the Clapper that was breaking audio support since we were not using the right clock in the cht_bsw_max98090_ti machine driver.
Cc: stable@vger.kernel.org Fixes: 648e921888ad ("clk: x86: Stop marking clocks as CLK_IS_CRITICAL") Signed-off-by: Hans de Goede hdegoede@redhat.com Acked-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- sound/soc/intel/boards/cht_bsw_max98090_ti.c | 7 +++++++ 1 file changed, 7 insertions(+)
--- a/sound/soc/intel/boards/cht_bsw_max98090_ti.c +++ b/sound/soc/intel/boards/cht_bsw_max98090_ti.c @@ -390,6 +390,13 @@ static struct snd_soc_card snd_soc_card_
static const struct dmi_system_id cht_max98090_quirk_table[] = { { + /* Clapper model Chromebook */ + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "Clapper"), + }, + .driver_data = (void *)QUIRK_PMC_PLT_CLK_0, + }, + { /* Swanky model Chromebook (Toshiba Chromebook 2) */ .matches = { DMI_MATCH(DMI_PRODUCT_NAME, "Swanky"),
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans de Goede hdegoede@redhat.com
commit 94ea56cff506c769a509c5dd87904c7fe3806a81 upstream.
The Gnawty model Chromebook uses pmc_plt_clk_0 instead of pmc_plt_clk_3 for the mclk, just like the Clapper and Swanky models.
This commit adds a DMI based quirk for this.
This fixing audio no longer working on these devices after commit 648e921888ad ("clk: x86: Stop marking clocks as CLK_IS_CRITICAL") that commit fixes us unnecessary keeping unused clocks on, but in case of the Gnawty that was breaking audio support since we were not using the right clock in the cht_bsw_max98090_ti machine driver.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=201787 Cc: stable@vger.kernel.org Fixes: 648e921888ad ("clk: x86: Stop marking clocks as CLK_IS_CRITICAL") Reported-and-tested-by: Jaime Pérez 19.jaime.91@gmail.com Signed-off-by: Hans de Goede hdegoede@redhat.com Acked-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- sound/soc/intel/boards/cht_bsw_max98090_ti.c | 7 +++++++ 1 file changed, 7 insertions(+)
--- a/sound/soc/intel/boards/cht_bsw_max98090_ti.c +++ b/sound/soc/intel/boards/cht_bsw_max98090_ti.c @@ -397,6 +397,13 @@ static const struct dmi_system_id cht_ma .driver_data = (void *)QUIRK_PMC_PLT_CLK_0, }, { + /* Gnawty model Chromebook (Acer Chromebook CB3-111) */ + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "Gnawty"), + }, + .driver_data = (void *)QUIRK_PMC_PLT_CLK_0, + }, + { /* Swanky model Chromebook (Toshiba Chromebook 2) */ .matches = { DMI_MATCH(DMI_PRODUCT_NAME, "Swanky"),
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Ott sebott@linux.ibm.com
commit 98dfd32620e970eb576ebce5ea39d905cb005e72 upstream.
When triggered by pci hotplug (PEC 0x306) clp_get_state is called with spinlocks held resulting in the following warning:
zpci: n/a: Event 0x306 reconfigured PCI function 0x0 BUG: sleeping function called from invalid context at mm/page_alloc.c:4324 in_atomic(): 1, irqs_disabled(): 0, pid: 98, name: kmcheck 2 locks held by kmcheck/98:
Change the allocation to use GFP_ATOMIC.
Cc: stable@vger.kernel.org # 4.13+ Signed-off-by: Sebastian Ott sebott@linux.ibm.com Signed-off-by: Martin Schwidefsky schwidefsky@de.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/s390/pci/pci_clp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/s390/pci/pci_clp.c +++ b/arch/s390/pci/pci_clp.c @@ -436,7 +436,7 @@ int clp_get_state(u32 fid, enum zpci_sta struct clp_state_data sd = {fid, ZPCI_FN_STATE_RESERVED}; int rc;
- rrb = clp_alloc_block(GFP_KERNEL); + rrb = clp_alloc_block(GFP_ATOMIC); if (!rrb) return -ENOMEM;
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sanjeev Chugh sanjeev_chugh@mentor.com
commit 1e3c336ad8f40f88a8961c434640920fe35cc08b upstream.
If the user attempts to update Atmel device with an invalid configuration cfg file, error handling code is trying to free cfg file memory which is not allocated yet hence results into kernel crash.
This patch fixes the order of memory free operations.
Signed-off-by: Sanjeev Chugh sanjeev_chugh@mentor.com Fixes: a4891f105837 ("Input: atmel_mxt_ts - zero terminate config firmware file") Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov dmitry.torokhov@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/input/touchscreen/atmel_mxt_ts.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -1585,10 +1585,10 @@ static int mxt_update_cfg(struct mxt_dat /* T7 config may have changed */ mxt_init_t7_power_cfg(data);
-release_raw: - kfree(cfg.raw); release_mem: kfree(cfg.mem); +release_raw: + kfree(cfg.raw); return ret; }
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Patrick Dreyer Patrick@Dreyer.name
commit 7db54c89f0b30a101584e09d3729144e6170059d upstream.
This adds ELAN0501 to the ACPI table to support Elan touchpad found in ASUS Aspire F5-573G.
Signed-off-by: Patrick Dreyer Patrick.Dreyer@gmail.com Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov dmitry.torokhov@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/input/mouse/elan_i2c_core.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/input/mouse/elan_i2c_core.c +++ b/drivers/input/mouse/elan_i2c_core.c @@ -1336,6 +1336,7 @@ MODULE_DEVICE_TABLE(i2c, elan_id); static const struct acpi_device_id elan_acpi_id[] = { { "ELAN0000", 0 }, { "ELAN0100", 0 }, + { "ELAN0501", 0 }, { "ELAN0600", 0 }, { "ELAN0602", 0 }, { "ELAN0605", 0 },
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Hocko mhocko@suse.com
commit 5b5e4d623ec8a34689df98e42d038a3b594d2ff9 upstream.
Swap storage is restricted to max_swapfile_size (~16TB on x86_64) whenever the system is deemed affected by L1TF vulnerability. Even though the limit is quite high for most deployments it seems to be too restrictive for deployments which are willing to live with the mitigation disabled.
We have a customer to deploy 8x 6,4TB PCIe/NVMe SSD swap devices which is clearly out of the limit.
Drop the swap restriction when l1tf=off is specified. It also doesn't make much sense to warn about too much memory for the l1tf mitigation when it is forcefully disabled by the administrator.
[ tglx: Folded the documentation delta change ]
Fixes: 377eeaa8e11f ("x86/speculation/l1tf: Limit swap file size to MAX_PA/2") Signed-off-by: Michal Hocko mhocko@suse.com Signed-off-by: Thomas Gleixner tglx@linutronix.de Reviewed-by: Pavel Tatashin pasha.tatashin@soleen.com Reviewed-by: Andi Kleen ak@linux.intel.com Acked-by: Jiri Kosina jkosina@suse.cz Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Dave Hansen dave.hansen@intel.com Cc: Andi Kleen ak@linux.intel.com Cc: Borislav Petkov bp@suse.de Cc: linux-mm@kvack.org Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/20181113184910.26697-1-mhocko@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- Documentation/admin-guide/kernel-parameters.txt | 3 +++ Documentation/admin-guide/l1tf.rst | 6 +++++- arch/x86/kernel/cpu/bugs.c | 3 ++- arch/x86/mm/init.c | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-)
--- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -2096,6 +2096,9 @@ off Disables hypervisor mitigations and doesn't emit any warnings. + It also drops the swap size and available + RAM limit restriction on both hypervisor and + bare metal.
Default is 'flush'.
--- a/Documentation/admin-guide/l1tf.rst +++ b/Documentation/admin-guide/l1tf.rst @@ -405,6 +405,9 @@ time with the option "l1tf=". The valid
off Disables hypervisor mitigations and doesn't emit any warnings. + It also drops the swap size and available RAM limit restrictions + on both hypervisor and bare metal. + ============ =============================================================
The default is 'flush'. For details about L1D flushing see :ref:`l1d_flush`. @@ -576,7 +579,8 @@ Default mitigations The kernel default mitigations for vulnerable processors are:
- PTE inversion to protect against malicious user space. This is done - unconditionally and cannot be controlled. + unconditionally and cannot be controlled. The swap storage is limited + to ~16TB.
- L1D conditional flushing on VMENTER when EPT is enabled for a guest. --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -1002,7 +1002,8 @@ static void __init l1tf_select_mitigatio #endif
half_pa = (u64)l1tf_pfn_limit() << PAGE_SHIFT; - if (e820__mapped_any(half_pa, ULLONG_MAX - half_pa, E820_TYPE_RAM)) { + if (l1tf_mitigation != L1TF_MITIGATION_OFF && + e820__mapped_any(half_pa, ULLONG_MAX - half_pa, E820_TYPE_RAM)) { pr_warn("System has more than MAX_PA/2 memory. L1TF mitigation not effective.\n"); pr_info("You may make it effective by booting the kernel with mem=%llu parameter.\n", half_pa); --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c @@ -931,7 +931,7 @@ unsigned long max_swapfile_size(void)
pages = generic_max_swapfile_size();
- if (boot_cpu_has_bug(X86_BUG_L1TF)) { + if (boot_cpu_has_bug(X86_BUG_L1TF) && l1tf_mitigation != L1TF_MITIGATION_OFF) { /* Limit the swap file size to MAX_PA/2 for L1TF workaround */ unsigned long long l1tf_limit = l1tf_pfn_limit(); /*
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Williams dan.j.williams@intel.com
commit ba6f508d0ec4adb09f0a939af6d5e19cdfa8667d upstream.
Commit:
f77084d96355 "x86/mm/pat: Disable preemption around __flush_tlb_all()"
addressed a case where __flush_tlb_all() is called without preemption being disabled. It also left a warning to catch other cases where preemption is not disabled.
That warning triggers for the memory hotplug path which is also used for persistent memory enabling:
WARNING: CPU: 35 PID: 911 at ./arch/x86/include/asm/tlbflush.h:460 RIP: 0010:__flush_tlb_all+0x1b/0x3a [..] Call Trace: phys_pud_init+0x29c/0x2bb kernel_physical_mapping_init+0xfc/0x219 init_memory_mapping+0x1a5/0x3b0 arch_add_memory+0x2c/0x50 devm_memremap_pages+0x3aa/0x610 pmem_attach_disk+0x585/0x700 [nd_pmem]
Andy wondered why a path that can sleep was using __flush_tlb_all() [1] and Dave confirmed the expectation for TLB flush is for modifying / invalidating existing PTE entries, but not initial population [2]. Drop the usage of __flush_tlb_all() in phys_{p4d,pud,pmd}_init() on the expectation that this path is only ever populating empty entries for the linear map. Note, at linear map teardown time there is a call to the all-cpu flush_tlb_all() to invalidate the removed mappings.
[1]: https://lkml.kernel.org/r/9DFD717D-857D-493D-A606-B635D72BAC21@amacapital.ne... [2]: https://lkml.kernel.org/r/749919a4-cdb1-48a3-adb4-adb81a5fa0b5@intel.com
[ mingo: Minor readability edits. ]
Suggested-by: Dave Hansen dave.hansen@linux.intel.com Reported-by: Andy Lutomirski luto@kernel.org Signed-off-by: Dan Williams dan.j.williams@intel.com Acked-by: Peter Zijlstra (Intel) peterz@infradead.org Acked-by: Kirill A. Shutemov kirill.shutemov@linux.intel.com Cc: stable@vger.kernel.org Cc: Borislav Petkov bp@alien8.de Cc: H. Peter Anvin hpa@zytor.com Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Peter Zijlstra peterz@infradead.org Cc: Rik van Riel riel@surriel.com Cc: Sebastian Andrzej Siewior bigeasy@linutronix.de Cc: Thomas Gleixner tglx@linutronix.de Cc: dave.hansen@intel.com Fixes: f77084d96355 ("x86/mm/pat: Disable preemption around __flush_tlb_all()") Link: http://lkml.kernel.org/r/154395944713.32119.15611079023837132638.stgit@dwill... Signed-off-by: Ingo Molnar mingo@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/x86/mm/init_64.c | 6 ------ 1 file changed, 6 deletions(-)
--- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -584,7 +584,6 @@ phys_pud_init(pud_t *pud_page, unsigned paddr_end, page_size_mask, prot); - __flush_tlb_all(); continue; } /* @@ -627,7 +626,6 @@ phys_pud_init(pud_t *pud_page, unsigned pud_populate(&init_mm, pud, pmd); spin_unlock(&init_mm.page_table_lock); } - __flush_tlb_all();
update_page_count(PG_LEVEL_1G, pages);
@@ -668,7 +666,6 @@ phys_p4d_init(p4d_t *p4d_page, unsigned paddr_last = phys_pud_init(pud, paddr, paddr_end, page_size_mask); - __flush_tlb_all(); continue; }
@@ -680,7 +677,6 @@ phys_p4d_init(p4d_t *p4d_page, unsigned p4d_populate(&init_mm, p4d, pud); spin_unlock(&init_mm.page_table_lock); } - __flush_tlb_all();
return paddr_last; } @@ -733,8 +729,6 @@ kernel_physical_mapping_init(unsigned lo if (pgd_changed) sync_global_pgds(vaddr_start, vaddr_end - 1);
- __flush_tlb_all(); - return paddr_last; }
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson sean.j.christopherson@intel.com
commit e81434995081fd7efb755fd75576b35dbb0850b1 upstream.
____kvm_handle_fault_on_reboot() provides a generic exception fixup handler that is used to cleanly handle faults on VMX/SVM instructions during reboot (or at least try to). If there isn't a reboot in progress, ____kvm_handle_fault_on_reboot() treats any exception as fatal to KVM and invokes kvm_spurious_fault(), which in turn generates a BUG() to get a stack trace and die.
When it was originally added by commit 4ecac3fd6dc2 ("KVM: Handle virtualization instruction #UD faults during reboot"), the "call" to kvm_spurious_fault() was handcoded as PUSH+JMP, where the PUSH'd value is the RIP of the faulting instructing.
The PUSH+JMP trickery is necessary because the exception fixup handler code lies outside of its associated function, e.g. right after the function. An actual CALL from the .fixup code would show a slightly bogus stack trace, e.g. an extra "random" function would be inserted into the trace, as the return RIP on the stack would point to no known function (and the unwinder will likely try to guess who owns the RIP).
Unfortunately, the JMP was replaced with a CALL when the macro was reworked to not spin indefinitely during reboot (commit b7c4145ba2eb "KVM: Don't spin on virt instruction faults during reboot"). This causes the aforementioned behavior where a bogus function is inserted into the stack trace, e.g. my builds like to blame free_kvm_area().
Revert the CALL back to a JMP. The changelog for commit b7c4145ba2eb ("KVM: Don't spin on virt instruction faults during reboot") contains nothing that indicates the switch to CALL was deliberate. This is backed up by the fact that the PUSH <insn RIP> was left intact.
Note that an alternative to the PUSH+JMP magic would be to JMP back to the "real" code and CALL from there, but that would require adding a JMP in the non-faulting path to avoid calling kvm_spurious_fault() and would add no value, i.e. the stack trace would be the same.
Using CALL:
------------[ cut here ]------------ kernel BUG at /home/sean/go/src/kernel.org/linux/arch/x86/kvm/x86.c:356! invalid opcode: 0000 [#1] SMP CPU: 4 PID: 1057 Comm: qemu-system-x86 Not tainted 4.20.0-rc6+ #75 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015 RIP: 0010:kvm_spurious_fault+0x5/0x10 [kvm] Code: <0f> 0b 66 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 41 55 49 89 fd 41 RSP: 0018:ffffc900004bbcc8 EFLAGS: 00010046 RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffffffffffffff RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 RBP: ffff888273fd8000 R08: 00000000000003e8 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000784 R12: ffffc90000371fb0 R13: 0000000000000000 R14: 000000026d763cf4 R15: ffff888273fd8000 FS: 00007f3d69691700(0000) GS:ffff888277800000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000055f89bc56fe0 CR3: 0000000271a5a001 CR4: 0000000000362ee0 Call Trace: free_kvm_area+0x1044/0x43ea [kvm_intel] ? vmx_vcpu_run+0x156/0x630 [kvm_intel] ? kvm_arch_vcpu_ioctl_run+0x447/0x1a40 [kvm] ? kvm_vcpu_ioctl+0x368/0x5c0 [kvm] ? kvm_vcpu_ioctl+0x368/0x5c0 [kvm] ? __set_task_blocked+0x38/0x90 ? __set_current_blocked+0x50/0x60 ? __fpu__restore_sig+0x97/0x490 ? do_vfs_ioctl+0xa1/0x620 ? __x64_sys_futex+0x89/0x180 ? ksys_ioctl+0x66/0x70 ? __x64_sys_ioctl+0x16/0x20 ? do_syscall_64+0x4f/0x100 ? entry_SYSCALL_64_after_hwframe+0x44/0xa9 Modules linked in: vhost_net vhost tap kvm_intel kvm irqbypass bridge stp llc ---[ end trace 9775b14b123b1713 ]---
Using JMP:
------------[ cut here ]------------ kernel BUG at /home/sean/go/src/kernel.org/linux/arch/x86/kvm/x86.c:356! invalid opcode: 0000 [#1] SMP CPU: 6 PID: 1067 Comm: qemu-system-x86 Not tainted 4.20.0-rc6+ #75 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015 RIP: 0010:kvm_spurious_fault+0x5/0x10 [kvm] Code: <0f> 0b 66 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 41 55 49 89 fd 41 RSP: 0018:ffffc90000497cd0 EFLAGS: 00010046 RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffffffffffffff RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 RBP: ffff88827058bd40 R08: 00000000000003e8 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000784 R12: ffffc90000369fb0 R13: 0000000000000000 R14: 00000003c8fc6642 R15: ffff88827058bd40 FS: 00007f3d7219e700(0000) GS:ffff888277900000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f3d64001000 CR3: 0000000271c6b004 CR4: 0000000000362ee0 Call Trace: vmx_vcpu_run+0x156/0x630 [kvm_intel] ? kvm_arch_vcpu_ioctl_run+0x447/0x1a40 [kvm] ? kvm_vcpu_ioctl+0x368/0x5c0 [kvm] ? kvm_vcpu_ioctl+0x368/0x5c0 [kvm] ? __set_task_blocked+0x38/0x90 ? __set_current_blocked+0x50/0x60 ? __fpu__restore_sig+0x97/0x490 ? do_vfs_ioctl+0xa1/0x620 ? __x64_sys_futex+0x89/0x180 ? ksys_ioctl+0x66/0x70 ? __x64_sys_ioctl+0x16/0x20 ? do_syscall_64+0x4f/0x100 ? entry_SYSCALL_64_after_hwframe+0x44/0xa9 Modules linked in: vhost_net vhost tap kvm_intel kvm irqbypass bridge stp llc ---[ end trace f9daedb85ab3ddba ]---
Fixes: b7c4145ba2eb ("KVM: Don't spin on virt instruction faults during reboot") Cc: stable@vger.kernel.org Signed-off-by: Sean Christopherson sean.j.christopherson@intel.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/x86/include/asm/kvm_host.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1492,7 +1492,7 @@ asmlinkage void kvm_spurious_fault(void) "cmpb $0, kvm_rebooting \n\t" \ "jne 668b \n\t" \ __ASM_SIZE(push) " $666b \n\t" \ - "call kvm_spurious_fault \n\t" \ + "jmp kvm_spurious_fault \n\t" \ ".popsection \n\t" \ _ASM_EXTABLE(666b, 667b)
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marc Zyngier marc.zyngier@arm.com
commit c987876a80e7bcb98a839f10dca9ce7fda4feced upstream.
Contrary to the non-VHE version of the TLB invalidation helpers, the VHE code has interrupts enabled, meaning that we can take an interrupt in the middle of such a sequence, and start running something else with HCR_EL2.TGE cleared.
That's really not a good idea.
Take the heavy-handed option and disable interrupts in __tlb_switch_to_guest_vhe, restoring them in __tlb_switch_to_host_vhe. The latter also gain an ISB in order to make sure that TGE really has taken effect.
Cc: stable@vger.kernel.org Acked-by: Christoffer Dall christoffer.dall@arm.com Reviewed-by: James Morse james.morse@arm.com Signed-off-by: Marc Zyngier marc.zyngier@arm.com Signed-off-by: Will Deacon will.deacon@arm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/arm64/kvm/hyp/tlb.c | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-)
--- a/arch/arm64/kvm/hyp/tlb.c +++ b/arch/arm64/kvm/hyp/tlb.c @@ -15,14 +15,19 @@ * along with this program. If not, see http://www.gnu.org/licenses/. */
+#include <linux/irqflags.h> + #include <asm/kvm_hyp.h> #include <asm/kvm_mmu.h> #include <asm/tlbflush.h>
-static void __hyp_text __tlb_switch_to_guest_vhe(struct kvm *kvm) +static void __hyp_text __tlb_switch_to_guest_vhe(struct kvm *kvm, + unsigned long *flags) { u64 val;
+ local_irq_save(*flags); + /* * With VHE enabled, we have HCR_EL2.{E2H,TGE} = {1,1}, and * most TLB operations target EL2/EL0. In order to affect the @@ -37,7 +42,8 @@ static void __hyp_text __tlb_switch_to_g isb(); }
-static void __hyp_text __tlb_switch_to_guest_nvhe(struct kvm *kvm) +static void __hyp_text __tlb_switch_to_guest_nvhe(struct kvm *kvm, + unsigned long *flags) { __load_guest_stage2(kvm); isb(); @@ -48,7 +54,8 @@ static hyp_alternate_select(__tlb_switch __tlb_switch_to_guest_vhe, ARM64_HAS_VIRT_HOST_EXTN);
-static void __hyp_text __tlb_switch_to_host_vhe(struct kvm *kvm) +static void __hyp_text __tlb_switch_to_host_vhe(struct kvm *kvm, + unsigned long flags) { /* * We're done with the TLB operation, let's restore the host's @@ -56,9 +63,12 @@ static void __hyp_text __tlb_switch_to_h */ write_sysreg(0, vttbr_el2); write_sysreg(HCR_HOST_VHE_FLAGS, hcr_el2); + isb(); + local_irq_restore(flags); }
-static void __hyp_text __tlb_switch_to_host_nvhe(struct kvm *kvm) +static void __hyp_text __tlb_switch_to_host_nvhe(struct kvm *kvm, + unsigned long flags) { write_sysreg(0, vttbr_el2); } @@ -70,11 +80,13 @@ static hyp_alternate_select(__tlb_switch
void __hyp_text __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa) { + unsigned long flags; + dsb(ishst);
/* Switch to requested VMID */ kvm = kern_hyp_va(kvm); - __tlb_switch_to_guest()(kvm); + __tlb_switch_to_guest()(kvm, &flags);
/* * We could do so much better if we had the VA as well. @@ -117,36 +129,39 @@ void __hyp_text __kvm_tlb_flush_vmid_ipa if (!has_vhe() && icache_is_vpipt()) __flush_icache_all();
- __tlb_switch_to_host()(kvm); + __tlb_switch_to_host()(kvm, flags); }
void __hyp_text __kvm_tlb_flush_vmid(struct kvm *kvm) { + unsigned long flags; + dsb(ishst);
/* Switch to requested VMID */ kvm = kern_hyp_va(kvm); - __tlb_switch_to_guest()(kvm); + __tlb_switch_to_guest()(kvm, &flags);
__tlbi(vmalls12e1is); dsb(ish); isb();
- __tlb_switch_to_host()(kvm); + __tlb_switch_to_host()(kvm, flags); }
void __hyp_text __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu) { struct kvm *kvm = kern_hyp_va(kern_hyp_va(vcpu)->kvm); + unsigned long flags;
/* Switch to requested VMID */ - __tlb_switch_to_guest()(kvm); + __tlb_switch_to_guest()(kvm, &flags);
__tlbi(vmalle1); dsb(nsh); isb();
- __tlb_switch_to_host()(kvm); + __tlb_switch_to_host()(kvm, flags); }
void __hyp_text __kvm_flush_vm_context(void)
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paul Mackerras paulus@ozlabs.org
commit 234ff0b729ad882d20f7996591a964965647addf upstream.
Testing has revealed an occasional crash which appears to be caused by a race between kvmppc_switch_mmu_to_hpt and kvm_unmap_hva_range_hv. The symptom is a NULL pointer dereference in __find_linux_pte() called from kvm_unmap_radix() with kvm->arch.pgtable == NULL.
Looking at kvmppc_switch_mmu_to_hpt(), it does indeed clear kvm->arch.pgtable (via kvmppc_free_radix()) before setting kvm->arch.radix to NULL, and there is nothing to prevent kvm_unmap_hva_range_hv() or the other MMU callback functions from being called concurrently with kvmppc_switch_mmu_to_hpt() or kvmppc_switch_mmu_to_radix().
This patch therefore adds calls to spin_lock/unlock on the kvm->mmu_lock around the assignments to kvm->arch.radix, and makes sure that the partition-scoped radix tree or HPT is only freed after changing kvm->arch.radix.
This also takes the kvm->mmu_lock in kvmppc_rmap_reset() to make sure that the clearing of each rmap array (one per memslot) doesn't happen concurrently with use of the array in the kvm_unmap_hva_range_hv() or the other MMU callbacks.
Fixes: 18c3640cefc7 ("KVM: PPC: Book3S HV: Add infrastructure for running HPT guests on radix host") Cc: stable@vger.kernel.org # v4.15+ Signed-off-by: Paul Mackerras paulus@ozlabs.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/powerpc/kvm/book3s_64_mmu_hv.c | 3 +++ arch/powerpc/kvm/book3s_hv.c | 17 +++++++++++------ 2 files changed, 14 insertions(+), 6 deletions(-)
--- a/arch/powerpc/kvm/book3s_64_mmu_hv.c +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c @@ -743,12 +743,15 @@ void kvmppc_rmap_reset(struct kvm *kvm) srcu_idx = srcu_read_lock(&kvm->srcu); slots = kvm_memslots(kvm); kvm_for_each_memslot(memslot, slots) { + /* Mutual exclusion with kvm_unmap_hva_range etc. */ + spin_lock(&kvm->mmu_lock); /* * This assumes it is acceptable to lose reference and * change bits across a reset. */ memset(memslot->arch.rmap, 0, memslot->npages * sizeof(*memslot->arch.rmap)); + spin_unlock(&kvm->mmu_lock); } srcu_read_unlock(&kvm->srcu, srcu_idx); } --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -4532,12 +4532,15 @@ int kvmppc_switch_mmu_to_hpt(struct kvm { if (nesting_enabled(kvm)) kvmhv_release_all_nested(kvm); + kvmppc_rmap_reset(kvm); + kvm->arch.process_table = 0; + /* Mutual exclusion with kvm_unmap_hva_range etc. */ + spin_lock(&kvm->mmu_lock); + kvm->arch.radix = 0; + spin_unlock(&kvm->mmu_lock); kvmppc_free_radix(kvm); kvmppc_update_lpcr(kvm, LPCR_VPM1, LPCR_VPM1 | LPCR_UPRT | LPCR_GTSE | LPCR_HR); - kvmppc_rmap_reset(kvm); - kvm->arch.radix = 0; - kvm->arch.process_table = 0; return 0; }
@@ -4549,12 +4552,14 @@ int kvmppc_switch_mmu_to_radix(struct kv err = kvmppc_init_vm_radix(kvm); if (err) return err; - + kvmppc_rmap_reset(kvm); + /* Mutual exclusion with kvm_unmap_hva_range etc. */ + spin_lock(&kvm->mmu_lock); + kvm->arch.radix = 1; + spin_unlock(&kvm->mmu_lock); kvmppc_free_hpt(&kvm->arch.hpt); kvmppc_update_lpcr(kvm, LPCR_UPRT | LPCR_GTSE | LPCR_HR, LPCR_VPM1 | LPCR_UPRT | LPCR_GTSE | LPCR_HR); - kvmppc_rmap_reset(kvm); - kvm->arch.radix = 1; return 0; }
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson sean.j.christopherson@intel.com
commit 1b3ab5ad1b8ad99bae76ec583809c5f5a31c707c upstream.
Fixes: 34a1cd60d17f ("kvm: x86: vmx: move some vmx setting from vmx_init() to hardware_setup()") Cc: stable@vger.kernel.org Signed-off-by: Sean Christopherson sean.j.christopherson@intel.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/x86/kvm/vmx.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
--- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -8031,13 +8031,16 @@ static __init int hardware_setup(void)
kvm_mce_cap_supported |= MCG_LMCE_P;
- return alloc_kvm_area(); + r = alloc_kvm_area(); + if (r) + goto out; + return 0;
out: for (i = 0; i < VMX_BITMAP_NR; i++) free_page((unsigned long)vmx_bitmap[i]);
- return r; + return r; }
static __exit void hardware_unsetup(void)
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miquel Raynal miquel.raynal@bootlin.com
commit 81b1e6e6a8590a19257e37a1633bec098d499c57 upstream.
Since the addition of platform MSI support, there were two helpers supposed to allocate/free IRQs for a device:
platform_msi_domain_alloc_irqs() platform_msi_domain_free_irqs()
In these helpers, IRQ descriptors are allocated in the "alloc" routine while they are freed in the "free" one.
Later, two other helpers have been added to handle IRQ domains on top of MSI domains:
platform_msi_domain_alloc() platform_msi_domain_free()
Seen from the outside, the logic is pretty close with the former helpers and people used it with the same logic as before: a platform_msi_domain_alloc() call should be balanced with a platform_msi_domain_free() call. While this is probably what was intended to do, the platform_msi_domain_free() does not remove/free the IRQ descriptor(s) created/inserted in platform_msi_domain_alloc().
One effect of such situation is that removing a module that requested an IRQ will let one orphaned IRQ descriptor (with an allocated MSI entry) in the device descriptors list. Next time the module will be inserted back, one will observe that the allocation will happen twice in the MSI domain, one time for the remaining descriptor, one time for the new one. It also has the side effect to quickly overshoot the maximum number of allocated MSI and then prevent any module requesting an interrupt in the same domain to be inserted anymore.
This situation has been met with loops of insertion/removal of the mvpp2.ko module (requesting 15 MSIs each time).
Fixes: 552c494a7666 ("platform-msi: Allow creation of a MSI-based stacked irq domain") Cc: stable@vger.kernel.org Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Signed-off-by: Marc Zyngier marc.zyngier@arm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/base/platform-msi.c | 6 ++++-- include/linux/msi.h | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-)
--- a/drivers/base/platform-msi.c +++ b/drivers/base/platform-msi.c @@ -368,14 +368,16 @@ void platform_msi_domain_free(struct irq unsigned int nvec) { struct platform_msi_priv_data *data = domain->host_data; - struct msi_desc *desc; - for_each_msi_entry(desc, data->dev) { + struct msi_desc *desc, *tmp; + for_each_msi_entry_safe(desc, tmp, data->dev) { if (WARN_ON(!desc->irq || desc->nvec_used != 1)) return; if (!(desc->irq >= virq && desc->irq < (virq + nvec))) continue;
irq_domain_free_irqs_common(domain, desc->irq, 1); + list_del(&desc->list); + free_msi_entry(desc); } }
--- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -116,6 +116,8 @@ struct msi_desc { list_first_entry(dev_to_msi_list((dev)), struct msi_desc, list) #define for_each_msi_entry(desc, dev) \ list_for_each_entry((desc), dev_to_msi_list((dev)), list) +#define for_each_msi_entry_safe(desc, tmp, dev) \ + list_for_each_entry_safe((desc), (tmp), dev_to_msi_list((dev)), list)
#ifdef CONFIG_PCI_MSI #define first_pci_msi_entry(pdev) first_msi_entry(&(pdev)->dev)
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Anholt eric@anholt.net
commit 2f20fa8d12e859a03f68bdd81d75830141bc9ac9 upstream.
Fixes an oops reading this debugfs entry on BCM7278.
Signed-off-by: Eric Anholt eric@anholt.net Link: https://patchwork.freedesktop.org/patch/msgid/20180928232126.4332-4-eric@anh... Fixes: 57692c94dcbe ("drm/v3d: Introduce a new DRM driver for Broadcom V3D V3.x+") Cc: stable@vger.kernel.org Reviewed-by: Boris Brezillon boris.brezillon@bootlin.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/gpu/drm/v3d/v3d_debugfs.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
--- a/drivers/gpu/drm/v3d/v3d_debugfs.c +++ b/drivers/gpu/drm/v3d/v3d_debugfs.c @@ -71,10 +71,13 @@ static int v3d_v3d_debugfs_regs(struct s V3D_READ(v3d_hub_reg_defs[i].reg)); }
- for (i = 0; i < ARRAY_SIZE(v3d_gca_reg_defs); i++) { - seq_printf(m, "%s (0x%04x): 0x%08x\n", - v3d_gca_reg_defs[i].name, v3d_gca_reg_defs[i].reg, - V3D_GCA_READ(v3d_gca_reg_defs[i].reg)); + if (v3d->ver < 41) { + for (i = 0; i < ARRAY_SIZE(v3d_gca_reg_defs); i++) { + seq_printf(m, "%s (0x%04x): 0x%08x\n", + v3d_gca_reg_defs[i].name, + v3d_gca_reg_defs[i].reg, + V3D_GCA_READ(v3d_gca_reg_defs[i].reg)); + } }
for (core = 0; core < v3d->cores; core++) {
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eugeniy Paltsev Eugeniy.Paltsev@synopsys.com
commit 32e932e37e6b6e13b66add307192c7ddd40a781d upstream.
UDL doesn't support vblank functionality so we don't need to initialize vblank here (we are able to send page flip completion events even without vblank initialization)
Moreover current drm_vblank_init call with num_crtcs > 0 causes sending DRM_EVENT_FLIP_COMPLETE event with zero timestamp every time. This breaks userspace apps (for example weston) which relies on timestamp value.
Cc: stable@vger.kernel.org Signed-off-by: Eugeniy Paltsev Eugeniy.Paltsev@synopsys.com Signed-off-by: Daniel Vetter daniel.vetter@ffwll.ch Link: https://patchwork.freedesktop.org/patch/msgid/20180928144126.21598-1-Eugeniy... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/gpu/drm/udl/udl_main.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-)
--- a/drivers/gpu/drm/udl/udl_main.c +++ b/drivers/gpu/drm/udl/udl_main.c @@ -350,15 +350,10 @@ int udl_driver_load(struct drm_device *d if (ret) goto err;
- ret = drm_vblank_init(dev, 1); - if (ret) - goto err_fb; - drm_kms_helper_poll_init(dev);
return 0; -err_fb: - udl_fbdev_cleanup(dev); + err: if (udl->urbs.count) udl_free_urb_list(dev);
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexey Brodkin alexey.brodkin@synopsys.com
commit bf287607c80f24387fedb431a346dc67f25be12c upstream.
It turned out we used to use default implementation of sched_clock() from kernel/sched/clock.c which was as precise as 1/HZ, i.e. by default we had 10 msec granularity of time measurement.
Now given ARC built-in timers are clocked with the same frequency as CPU cores we may get much higher precision of time tracking.
Thus we switch to generic sched_clock which really reads ARC hardware counters.
This is especially helpful for measuring short events. That's what we used to have: ------------------------------>8------------------------ $ perf stat /bin/sh -c /root/lmbench-master/bin/arc/hello > /dev/null
Performance counter stats for '/bin/sh -c /root/lmbench-master/bin/arc/hello':
10.000000 task-clock (msec) # 2.832 CPUs utilized 1 context-switches # 0.100 K/sec 1 cpu-migrations # 0.100 K/sec 63 page-faults # 0.006 M/sec 3049480 cycles # 0.305 GHz 1091259 instructions # 0.36 insn per cycle 256828 branches # 25.683 M/sec 27026 branch-misses # 10.52% of all branches
0.003530687 seconds time elapsed
0.000000000 seconds user 0.010000000 seconds sys ------------------------------>8------------------------
And now we'll see: ------------------------------>8------------------------ $ perf stat /bin/sh -c /root/lmbench-master/bin/arc/hello > /dev/null
Performance counter stats for '/bin/sh -c /root/lmbench-master/bin/arc/hello':
3.004322 task-clock (msec) # 0.865 CPUs utilized 1 context-switches # 0.333 K/sec 1 cpu-migrations # 0.333 K/sec 63 page-faults # 0.021 M/sec 2986734 cycles # 0.994 GHz 1087466 instructions # 0.36 insn per cycle 255209 branches # 84.947 M/sec 26002 branch-misses # 10.19% of all branches
0.003474829 seconds time elapsed
0.003519000 seconds user 0.000000000 seconds sys ------------------------------>8------------------------
Note how much more meaningful is the second output - time spent for execution pretty much matches number of cycles spent (we're runnign @ 1GHz here).
Signed-off-by: Alexey Brodkin abrodkin@synopsys.com Cc: Daniel Lezcano daniel.lezcano@linaro.org Cc: Vineet Gupta vgupta@synopsys.com Cc: Thomas Gleixner tglx@linutronix.de Cc: stable@vger.kernel.org Acked-by: Vineet Gupta vgupta@synopsys.com Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/arc/Kconfig | 1 + drivers/clocksource/Kconfig | 1 + drivers/clocksource/arc_timer.c | 22 ++++++++++++++++++++++ 3 files changed, 24 insertions(+)
--- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -26,6 +26,7 @@ config ARC select GENERIC_IRQ_SHOW select GENERIC_PCI_IOMAP select GENERIC_PENDING_IRQ if SMP + select GENERIC_SCHED_CLOCK select GENERIC_SMP_IDLE_THREAD select HAVE_ARCH_KGDB select HAVE_ARCH_TRACEHOOK --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -290,6 +290,7 @@ config CLKSRC_MPS2
config ARC_TIMERS bool "Support for 32-bit TIMERn counters in ARC Cores" if COMPILE_TEST + depends on GENERIC_SCHED_CLOCK select TIMER_OF help These are legacy 32-bit TIMER0 and TIMER1 counters found on all ARC cores --- a/drivers/clocksource/arc_timer.c +++ b/drivers/clocksource/arc_timer.c @@ -23,6 +23,7 @@ #include <linux/cpu.h> #include <linux/of.h> #include <linux/of_irq.h> +#include <linux/sched_clock.h>
#include <soc/arc/timers.h> #include <soc/arc/mcip.h> @@ -88,6 +89,11 @@ static u64 arc_read_gfrc(struct clocksou return (((u64)h) << 32) | l; }
+static notrace u64 arc_gfrc_clock_read(void) +{ + return arc_read_gfrc(NULL); +} + static struct clocksource arc_counter_gfrc = { .name = "ARConnect GFRC", .rating = 400, @@ -111,6 +117,8 @@ static int __init arc_cs_setup_gfrc(stru if (ret) return ret;
+ sched_clock_register(arc_gfrc_clock_read, 64, arc_timer_freq); + return clocksource_register_hz(&arc_counter_gfrc, arc_timer_freq); } TIMER_OF_DECLARE(arc_gfrc, "snps,archs-timer-gfrc", arc_cs_setup_gfrc); @@ -139,6 +147,11 @@ static u64 arc_read_rtc(struct clocksour return (((u64)h) << 32) | l; }
+static notrace u64 arc_rtc_clock_read(void) +{ + return arc_read_rtc(NULL); +} + static struct clocksource arc_counter_rtc = { .name = "ARCv2 RTC", .rating = 350, @@ -170,6 +183,8 @@ static int __init arc_cs_setup_rtc(struc
write_aux_reg(AUX_RTC_CTRL, 1);
+ sched_clock_register(arc_rtc_clock_read, 64, arc_timer_freq); + return clocksource_register_hz(&arc_counter_rtc, arc_timer_freq); } TIMER_OF_DECLARE(arc_rtc, "snps,archs-timer-rtc", arc_cs_setup_rtc); @@ -185,6 +200,11 @@ static u64 arc_read_timer1(struct clocks return (u64) read_aux_reg(ARC_REG_TIMER1_CNT); }
+static notrace u64 arc_timer1_clock_read(void) +{ + return arc_read_timer1(NULL); +} + static struct clocksource arc_counter_timer1 = { .name = "ARC Timer1", .rating = 300, @@ -209,6 +229,8 @@ static int __init arc_cs_setup_timer1(st write_aux_reg(ARC_REG_TIMER1_CNT, 0); write_aux_reg(ARC_REG_TIMER1_CTRL, TIMER_CTRL_NH);
+ sched_clock_register(arc_timer1_clock_read, 32, arc_timer_freq); + return clocksource_register_hz(&arc_counter_timer1, arc_timer_freq); }
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Adrian Hunter adrian.hunter@intel.com
commit ec1891afae740be581ecf5abc8bda74c4549203f upstream.
Some architectures have a single address space for kernel and user addresses, which makes it possible to determine if an address is in kernel space or user space. Some don't, e.g.: sparc.
Cache that info in perf_env so that, for instance, code needing to fallback failed symbol lookups at the kernel space in single address space arches can lookup at userspace.
Signed-off-by: Adrian Hunter adrian.hunter@intel.com Cc: Andi Kleen ak@linux.intel.com Cc: David S. Miller davem@davemloft.net Cc: Jiri Olsa jolsa@redhat.com Cc: Leo Yan leo.yan@linaro.org Cc: Mathieu Poirier mathieu.poirier@linaro.org Cc: stable@vger.kernel.org # 4.19 Link: http://lkml.kernel.org/r/20181106210712.12098-2-adrian.hunter@intel.com [ split from a larger patch ] Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- tools/perf/arch/common.c | 10 ++++++++++ tools/perf/arch/common.h | 1 + tools/perf/util/machine.h | 1 + tools/perf/util/session.c | 4 ++++ 4 files changed, 16 insertions(+)
--- a/tools/perf/arch/common.c +++ b/tools/perf/arch/common.c @@ -200,3 +200,13 @@ int perf_env__lookup_objdump(struct perf
return perf_env__lookup_binutils_path(env, "objdump", path); } + +/* + * Some architectures have a single address space for kernel and user addresses, + * which makes it possible to determine if an address is in kernel space or user + * space. + */ +bool perf_env__single_address_space(struct perf_env *env) +{ + return strcmp(perf_env__arch(env), "sparc"); +} --- a/tools/perf/arch/common.h +++ b/tools/perf/arch/common.h @@ -5,5 +5,6 @@ #include "../util/env.h"
int perf_env__lookup_objdump(struct perf_env *env, const char **path); +bool perf_env__single_address_space(struct perf_env *env);
#endif /* ARCH_PERF_COMMON_H */ --- a/tools/perf/util/machine.h +++ b/tools/perf/util/machine.h @@ -42,6 +42,7 @@ struct machine { u16 id_hdr_size; bool comm_exec; bool kptr_restrict_warned; + bool single_address_space; char *root_dir; char *mmap_name; struct threads threads[THREADS__TABLE_SIZE]; --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -24,6 +24,7 @@ #include "thread.h" #include "thread-stack.h" #include "stat.h" +#include "arch/common.h"
static int perf_session__deliver_event(struct perf_session *session, union perf_event *event, @@ -150,6 +151,9 @@ struct perf_session *perf_session__new(s session->machines.host.env = &perf_env; }
+ session->machines.host.single_address_space = + perf_env__single_address_space(session->machines.host.env); + if (!data || perf_data__is_write(data)) { /* * In O_RDONLY mode this will be performed when reading the
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Adrian Hunter adrian.hunter@intel.com
commit 8e80ad9983caeee09c3a0a1a37e05bff93becce4 upstream.
For branch stacks or branch samples, the sample cpumode might not be correct because it applies only to the sample 'ip' and not necessary to 'addr' or branch stack addresses. Add fallback functions that can be used to deal with those cases
Signed-off-by: Adrian Hunter adrian.hunter@intel.com Cc: Andi Kleen ak@linux.intel.com Cc: David S. Miller davem@davemloft.net Cc: Jiri Olsa jolsa@redhat.com Cc: Leo Yan leo.yan@linaro.org Cc: Mathieu Poirier mathieu.poirier@linaro.org Cc: stable@vger.kernel.org # 4.19 Link: http://lkml.kernel.org/r/20181106210712.12098-2-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- tools/perf/util/event.c | 27 +++++++++++++++++++++++++++ tools/perf/util/machine.c | 27 +++++++++++++++++++++++++++ tools/perf/util/machine.h | 2 ++ tools/perf/util/thread.h | 4 ++++ 4 files changed, 60 insertions(+)
--- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -1577,6 +1577,24 @@ struct map *thread__find_map(struct thre return al->map; }
+/* + * For branch stacks or branch samples, the sample cpumode might not be correct + * because it applies only to the sample 'ip' and not necessary to 'addr' or + * branch stack addresses. If possible, use a fallback to deal with those cases. + */ +struct map *thread__find_map_fb(struct thread *thread, u8 cpumode, u64 addr, + struct addr_location *al) +{ + struct map *map = thread__find_map(thread, cpumode, addr, al); + struct machine *machine = thread->mg->machine; + u8 addr_cpumode = machine__addr_cpumode(machine, cpumode, addr); + + if (map || addr_cpumode == cpumode) + return map; + + return thread__find_map(thread, addr_cpumode, addr, al); +} + struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode, u64 addr, struct addr_location *al) { @@ -1585,6 +1603,15 @@ struct symbol *thread__find_symbol(struc al->sym = map__find_symbol(al->map, al->addr); return al->sym; } + +struct symbol *thread__find_symbol_fb(struct thread *thread, u8 cpumode, + u64 addr, struct addr_location *al) +{ + al->sym = NULL; + if (thread__find_map_fb(thread, cpumode, addr, al)) + al->sym = map__find_symbol(al->map, al->addr); + return al->sym; +}
/* * Callers need to drop the reference to al->thread, obtained in --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -2592,6 +2592,33 @@ int machine__get_kernel_start(struct mac return err; }
+u8 machine__addr_cpumode(struct machine *machine, u8 cpumode, u64 addr) +{ + u8 addr_cpumode = cpumode; + bool kernel_ip; + + if (!machine->single_address_space) + goto out; + + kernel_ip = machine__kernel_ip(machine, addr); + switch (cpumode) { + case PERF_RECORD_MISC_KERNEL: + case PERF_RECORD_MISC_USER: + addr_cpumode = kernel_ip ? PERF_RECORD_MISC_KERNEL : + PERF_RECORD_MISC_USER; + break; + case PERF_RECORD_MISC_GUEST_KERNEL: + case PERF_RECORD_MISC_GUEST_USER: + addr_cpumode = kernel_ip ? PERF_RECORD_MISC_GUEST_KERNEL : + PERF_RECORD_MISC_GUEST_USER; + break; + default: + break; + } +out: + return addr_cpumode; +} + struct dso *machine__findnew_dso(struct machine *machine, const char *filename) { return dsos__findnew(&machine->dsos, filename); --- a/tools/perf/util/machine.h +++ b/tools/perf/util/machine.h @@ -100,6 +100,8 @@ static inline bool machine__kernel_ip(st return ip >= kernel_start; }
+u8 machine__addr_cpumode(struct machine *machine, u8 cpumode, u64 addr); + struct thread *machine__find_thread(struct machine *machine, pid_t pid, pid_t tid); struct comm *machine__thread_exec_comm(struct machine *machine, --- a/tools/perf/util/thread.h +++ b/tools/perf/util/thread.h @@ -96,9 +96,13 @@ struct thread *thread__main_thread(struc
struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr, struct addr_location *al); +struct map *thread__find_map_fb(struct thread *thread, u8 cpumode, u64 addr, + struct addr_location *al);
struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode, u64 addr, struct addr_location *al); +struct symbol *thread__find_symbol_fb(struct thread *thread, u8 cpumode, + u64 addr, struct addr_location *al);
void thread__find_cpumode_addr_location(struct thread *thread, u64 addr, struct addr_location *al);
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Adrian Hunter adrian.hunter@intel.com
commit 225f99e0c811e23836c4911a2ff147e167dd1fe8 upstream.
thread__resolve() is used in the sample_addr_correlates_sym() cases where 'addr' is a destination of a branch which does not necessarily have the same cpumode as the 'ip'. Use the fallback function in that case.
This patch depends on patch "perf tools: Add fallback functions for cases where cpumode is insufficient".
Signed-off-by: Adrian Hunter adrian.hunter@intel.com Cc: Andi Kleen ak@linux.intel.com Cc: David S. Miller davem@davemloft.net Cc: Jiri Olsa jolsa@redhat.com Cc: Leo Yan leo.yan@linaro.org Cc: Mathieu Poirier mathieu.poirier@linaro.org Cc: stable@vger.kernel.org # 4.19 Link: http://lkml.kernel.org/r/20181106210712.12098-3-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- tools/perf/util/event.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -1706,7 +1706,7 @@ bool sample_addr_correlates_sym(struct p void thread__resolve(struct thread *thread, struct addr_location *al, struct perf_sample *sample) { - thread__find_map(thread, sample->cpumode, sample->addr, al); + thread__find_map_fb(thread, sample->cpumode, sample->addr, al);
al->cpu = sample->cpu; al->sym = NULL;
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Adrian Hunter adrian.hunter@intel.com
commit 692d0e63324d2954a0c63a812a8588e97023a295 upstream.
Branch stacks do not necessarily have the same cpumode as the 'ip'. Use the fallback functions in those cases.
This patch depends on patch "perf tools: Add fallback functions for cases where cpumode is insufficient".
Signed-off-by: Adrian Hunter adrian.hunter@intel.com Cc: Andi Kleen ak@linux.intel.com Cc: David S. Miller davem@davemloft.net Cc: Jiri Olsa jolsa@redhat.com Cc: Leo Yan leo.yan@linaro.org Cc: Mathieu Poirier mathieu.poirier@linaro.org Cc: stable@vger.kernel.org # 4.19 Link: http://lkml.kernel.org/r/20181106210712.12098-4-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- tools/perf/builtin-script.c | 12 ++++++------ tools/perf/util/scripting-engines/trace-event-python.c | 16 ++++++++-------- 2 files changed, 14 insertions(+), 14 deletions(-)
--- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -728,8 +728,8 @@ static int perf_sample__fprintf_brstack( if (PRINT_FIELD(DSO)) { memset(&alf, 0, sizeof(alf)); memset(&alt, 0, sizeof(alt)); - thread__find_map(thread, sample->cpumode, from, &alf); - thread__find_map(thread, sample->cpumode, to, &alt); + thread__find_map_fb(thread, sample->cpumode, from, &alf); + thread__find_map_fb(thread, sample->cpumode, to, &alt); }
printed += fprintf(fp, " 0x%"PRIx64, from); @@ -775,8 +775,8 @@ static int perf_sample__fprintf_brstacks from = br->entries[i].from; to = br->entries[i].to;
- thread__find_symbol(thread, sample->cpumode, from, &alf); - thread__find_symbol(thread, sample->cpumode, to, &alt); + thread__find_symbol_fb(thread, sample->cpumode, from, &alf); + thread__find_symbol_fb(thread, sample->cpumode, to, &alt);
printed += symbol__fprintf_symname_offs(alf.sym, &alf, fp); if (PRINT_FIELD(DSO)) { @@ -820,11 +820,11 @@ static int perf_sample__fprintf_brstacko from = br->entries[i].from; to = br->entries[i].to;
- if (thread__find_map(thread, sample->cpumode, from, &alf) && + if (thread__find_map_fb(thread, sample->cpumode, from, &alf) && !alf.map->dso->adjust_symbols) from = map__map_ip(alf.map, from);
- if (thread__find_map(thread, sample->cpumode, to, &alt) && + if (thread__find_map_fb(thread, sample->cpumode, to, &alt) && !alt.map->dso->adjust_symbols) to = map__map_ip(alt.map, to);
--- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -494,14 +494,14 @@ static PyObject *python_process_brstack( pydict_set_item_string_decref(pyelem, "cycles", PyLong_FromUnsignedLongLong(br->entries[i].flags.cycles));
- thread__find_map(thread, sample->cpumode, - br->entries[i].from, &al); + thread__find_map_fb(thread, sample->cpumode, + br->entries[i].from, &al); dsoname = get_dsoname(al.map); pydict_set_item_string_decref(pyelem, "from_dsoname", _PyUnicode_FromString(dsoname));
- thread__find_map(thread, sample->cpumode, - br->entries[i].to, &al); + thread__find_map_fb(thread, sample->cpumode, + br->entries[i].to, &al); dsoname = get_dsoname(al.map); pydict_set_item_string_decref(pyelem, "to_dsoname", _PyUnicode_FromString(dsoname)); @@ -576,14 +576,14 @@ static PyObject *python_process_brstacks if (!pyelem) Py_FatalError("couldn't create Python dictionary");
- thread__find_symbol(thread, sample->cpumode, - br->entries[i].from, &al); + thread__find_symbol_fb(thread, sample->cpumode, + br->entries[i].from, &al); get_symoff(al.sym, &al, true, bf, sizeof(bf)); pydict_set_item_string_decref(pyelem, "from", _PyUnicode_FromString(bf));
- thread__find_symbol(thread, sample->cpumode, - br->entries[i].to, &al); + thread__find_symbol_fb(thread, sample->cpumode, + br->entries[i].to, &al); get_symoff(al.sym, &al, true, bf, sizeof(bf)); pydict_set_item_string_decref(pyelem, "to", _PyUnicode_FromString(bf));
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ben Hutchings ben@decadent.org.uk
commit 11a64a05dc649815670b1be9fe63d205cb076401 upstream.
Depending on which functions are inlined in util/pmu.c, the snprintf() calls in perf_pmu__parse_{scale,unit,per_pkg,snapshot}() might trigger a warning:
util/pmu.c: In function 'pmu_aliases': util/pmu.c:178:31: error: '%s' directive output may be truncated writing up to 255 bytes into a region of size between 0 and 4095 [-Werror=format-truncation=] snprintf(path, PATH_MAX, "%s/%s.unit", dir, name); ^~
I found this when trying to build perf from Linux 3.16 with gcc 8. However I can reproduce the problem in mainline if I force __perf_pmu__new_alias() to be inlined.
Suppress this by using scnprintf() as has been done elsewhere in perf.
Signed-off-by: Ben Hutchings ben@decadent.org.uk Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: Jiri Olsa jolsa@redhat.com Cc: Namhyung Kim namhyung@kernel.org Cc: Peter Zijlstra peterz@infradead.org Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/20181111184524.fux4taownc6ndbx6@decadent.org.uk Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- tools/perf/util/pmu.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
--- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -145,7 +145,7 @@ static int perf_pmu__parse_scale(struct int fd, ret = -1; char path[PATH_MAX];
- snprintf(path, PATH_MAX, "%s/%s.scale", dir, name); + scnprintf(path, PATH_MAX, "%s/%s.scale", dir, name);
fd = open(path, O_RDONLY); if (fd == -1) @@ -175,7 +175,7 @@ static int perf_pmu__parse_unit(struct p ssize_t sret; int fd;
- snprintf(path, PATH_MAX, "%s/%s.unit", dir, name); + scnprintf(path, PATH_MAX, "%s/%s.unit", dir, name);
fd = open(path, O_RDONLY); if (fd == -1) @@ -205,7 +205,7 @@ perf_pmu__parse_per_pkg(struct perf_pmu_ char path[PATH_MAX]; int fd;
- snprintf(path, PATH_MAX, "%s/%s.per-pkg", dir, name); + scnprintf(path, PATH_MAX, "%s/%s.per-pkg", dir, name);
fd = open(path, O_RDONLY); if (fd == -1) @@ -223,7 +223,7 @@ static int perf_pmu__parse_snapshot(stru char path[PATH_MAX]; int fd;
- snprintf(path, PATH_MAX, "%s/%s.snapshot", dir, name); + scnprintf(path, PATH_MAX, "%s/%s.snapshot", dir, name);
fd = open(path, O_RDONLY); if (fd == -1)
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnaldo Carvalho de Melo acme@redhat.com
commit 804234f27180dcf9a25cb98a88d5212f65b7f3fd upstream.
We'll set a new machine field based on env->arch, which for live mode, like with 'perf top' means we need to use uname() to figure the name of the arch, fix perf_env__arch() to consider both (env == NULL) and (env->arch == NULL) as local operation.
Cc: Adrian Hunter adrian.hunter@intel.com Cc: Andi Kleen ak@linux.intel.com Cc: David Ahern dsahern@gmail.com Cc: David S. Miller davem@davemloft.net Cc: Jiri Olsa jolsa@redhat.com Cc: Leo Yan leo.yan@linaro.org Cc: Mathieu Poirier mathieu.poirier@linaro.org Cc: Namhyung Kim namhyung@kernel.org Cc: Wang Nan wangnan0@huawei.com Cc: stable@vger.kernel.org # 4.19 Link: https://lkml.kernel.org/n/tip-vcz4ufzdon7cwy8dm2ua53xk@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- tools/perf/util/env.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/tools/perf/util/env.c +++ b/tools/perf/util/env.c @@ -166,7 +166,7 @@ const char *perf_env__arch(struct perf_e struct utsname uts; char *arch_name;
- if (!env) { /* Assume local operation */ + if (!env || !env->arch) { /* Assume local operation */ if (uname(&uts) < 0) return NULL; arch_name = uts.machine;
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Greg Kurz groug@kaod.org
commit e1e71e201703500f708bdeaf64660a2a178cb6a0 upstream.
All fields in the PE are big-endian. Use cpu_to_be32() like everywhere else something is written to the PE. Otherwise a wrong TID will be used by the NPU. If this TID happens to point to an existing thread sharing the same mm, it could be woken up by error. This is highly improbable though. The likely outcome of this is the NPU not finding the target thread and forcing the AFU into sending an interrupt, which userspace is supposed to handle anyway.
Fixes: e948e06fc63a ("ocxl: Expose the thread_id needed for wait on POWER9") Cc: stable@vger.kernel.org # v4.18 Signed-off-by: Greg Kurz groug@kaod.org Acked-by: Andrew Donnellan andrew.donnellan@au1.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/misc/ocxl/link.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/misc/ocxl/link.c +++ b/drivers/misc/ocxl/link.c @@ -566,7 +566,7 @@ int ocxl_link_update_pe(void *link_handl
mutex_lock(&spa->spa_lock);
- pe->tid = tid; + pe->tid = cpu_to_be32(tid);
/* * The barrier makes sure the PE is updated
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Greg Kurz groug@kaod.org
commit 2f07229f02d4c55affccd11a61af4fd4b94dc436 upstream.
The AFU Descriptor Template in the PCI config space has a Name Space field which is a 24 Byte ASCII character string of descriptive name space for the AFU. The OCXL driver read the string four characters at a time with pci_read_config_dword().
This optimization is valid on a little-endian system since this is PCI, but a big-endian system ends up with each subset of four characters in reverse order.
This could be fixed by switching to read characters one by one. Another option is to swap the bytes if we're big-endian.
Go for the latter with le32_to_cpu().
Cc: stable@vger.kernel.org # v4.16 Signed-off-by: Greg Kurz groug@kaod.org Acked-by: Frederic Barrat fbarrat@linux.ibm.com Acked-by: Andrew Donnellan andrew.donnellan@au1.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/misc/ocxl/config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/misc/ocxl/config.c +++ b/drivers/misc/ocxl/config.c @@ -318,7 +318,7 @@ static int read_afu_name(struct pci_dev if (rc) return rc; ptr = (u32 *) &afu->name[i]; - *ptr = val; + *ptr = le32_to_cpu((__force __le32) val); } afu->name[OCXL_AFU_NAME_SZ - 1] = '\0'; /* play safe */ return 0;
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o tytso@mit.edu
commit fb265c9cb49e2074ddcdd4de99728aefdd3b3592 upstream.
Today, when sb_bread() returns NULL, this can either be because of an I/O error or because the system failed to allocate the buffer. Since it's an old interface, changing would require changing many call sites.
So instead we create our own ext4_sb_bread(), which also allows us to set the REQ_META flag.
Also fixed a problem in the xattr code where a NULL return in a function could also mean that the xattr was not found, which could lead to the wrong error getting returned to userspace.
Fixes: ac27a0ec112a ("ext4: initial copy of files from ext3") Cc: stable@kernel.org # 2.6.19 Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/ext4/ext4.h | 2 + fs/ext4/migrate.c | 36 ++++++++++++------------- fs/ext4/resize.c | 72 +++++++++++++++++++++++++-------------------------- fs/ext4/super.c | 23 ++++++++++++++++ fs/ext4/xattr.c | 76 +++++++++++++++++++++++++----------------------------- 5 files changed, 115 insertions(+), 94 deletions(-)
--- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -2538,6 +2538,8 @@ extern int ext4_group_extend(struct supe extern int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count);
/* super.c */ +extern struct buffer_head *ext4_sb_bread(struct super_block *sb, + sector_t block, int op_flags); extern int ext4_seq_options_show(struct seq_file *seq, void *offset); extern int ext4_calculate_overhead(struct super_block *sb); extern void ext4_superblock_csum_set(struct super_block *sb); --- a/fs/ext4/migrate.c +++ b/fs/ext4/migrate.c @@ -116,9 +116,9 @@ static int update_ind_extent_range(handl int i, retval = 0; unsigned long max_entries = inode->i_sb->s_blocksize >> 2;
- bh = sb_bread(inode->i_sb, pblock); - if (!bh) - return -EIO; + bh = ext4_sb_bread(inode->i_sb, pblock, 0); + if (IS_ERR(bh)) + return PTR_ERR(bh);
i_data = (__le32 *)bh->b_data; for (i = 0; i < max_entries; i++) { @@ -145,9 +145,9 @@ static int update_dind_extent_range(hand int i, retval = 0; unsigned long max_entries = inode->i_sb->s_blocksize >> 2;
- bh = sb_bread(inode->i_sb, pblock); - if (!bh) - return -EIO; + bh = ext4_sb_bread(inode->i_sb, pblock, 0); + if (IS_ERR(bh)) + return PTR_ERR(bh);
i_data = (__le32 *)bh->b_data; for (i = 0; i < max_entries; i++) { @@ -175,9 +175,9 @@ static int update_tind_extent_range(hand int i, retval = 0; unsigned long max_entries = inode->i_sb->s_blocksize >> 2;
- bh = sb_bread(inode->i_sb, pblock); - if (!bh) - return -EIO; + bh = ext4_sb_bread(inode->i_sb, pblock, 0); + if (IS_ERR(bh)) + return PTR_ERR(bh);
i_data = (__le32 *)bh->b_data; for (i = 0; i < max_entries; i++) { @@ -224,9 +224,9 @@ static int free_dind_blocks(handle_t *ha struct buffer_head *bh; unsigned long max_entries = inode->i_sb->s_blocksize >> 2;
- bh = sb_bread(inode->i_sb, le32_to_cpu(i_data)); - if (!bh) - return -EIO; + bh = ext4_sb_bread(inode->i_sb, le32_to_cpu(i_data), 0); + if (IS_ERR(bh)) + return PTR_ERR(bh);
tmp_idata = (__le32 *)bh->b_data; for (i = 0; i < max_entries; i++) { @@ -254,9 +254,9 @@ static int free_tind_blocks(handle_t *ha struct buffer_head *bh; unsigned long max_entries = inode->i_sb->s_blocksize >> 2;
- bh = sb_bread(inode->i_sb, le32_to_cpu(i_data)); - if (!bh) - return -EIO; + bh = ext4_sb_bread(inode->i_sb, le32_to_cpu(i_data), 0); + if (IS_ERR(bh)) + return PTR_ERR(bh);
tmp_idata = (__le32 *)bh->b_data; for (i = 0; i < max_entries; i++) { @@ -382,9 +382,9 @@ static int free_ext_idx(handle_t *handle struct ext4_extent_header *eh;
block = ext4_idx_pblock(ix); - bh = sb_bread(inode->i_sb, block); - if (!bh) - return -EIO; + bh = ext4_sb_bread(inode->i_sb, block, 0); + if (IS_ERR(bh)) + return PTR_ERR(bh);
eh = (struct ext4_extent_header *)bh->b_data; if (eh->eh_depth != 0) { --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c @@ -127,10 +127,12 @@ static int verify_group_input(struct sup else if (free_blocks_count < 0) ext4_warning(sb, "Bad blocks count %u", input->blocks_count); - else if (!(bh = sb_bread(sb, end - 1))) + else if (IS_ERR(bh = ext4_sb_bread(sb, end - 1, 0))) { + err = PTR_ERR(bh); + bh = NULL; ext4_warning(sb, "Cannot read last block (%llu)", end - 1); - else if (outside(input->block_bitmap, start, end)) + } else if (outside(input->block_bitmap, start, end)) ext4_warning(sb, "Block bitmap not in group (block %llu)", (unsigned long long)input->block_bitmap); else if (outside(input->inode_bitmap, start, end)) @@ -781,11 +783,11 @@ static int add_new_gdb(handle_t *handle, struct ext4_super_block *es = EXT4_SB(sb)->s_es; unsigned long gdb_num = group / EXT4_DESC_PER_BLOCK(sb); ext4_fsblk_t gdblock = EXT4_SB(sb)->s_sbh->b_blocknr + 1 + gdb_num; - struct buffer_head **o_group_desc, **n_group_desc; - struct buffer_head *dind; - struct buffer_head *gdb_bh; + struct buffer_head **o_group_desc, **n_group_desc = NULL; + struct buffer_head *dind = NULL; + struct buffer_head *gdb_bh = NULL; int gdbackups; - struct ext4_iloc iloc; + struct ext4_iloc iloc = { .bh = NULL }; __le32 *data; int err;
@@ -794,21 +796,22 @@ static int add_new_gdb(handle_t *handle, "EXT4-fs: ext4_add_new_gdb: adding group block %lu\n", gdb_num);
- gdb_bh = sb_bread(sb, gdblock); - if (!gdb_bh) - return -EIO; + gdb_bh = ext4_sb_bread(sb, gdblock, 0); + if (IS_ERR(gdb_bh)) + return PTR_ERR(gdb_bh);
gdbackups = verify_reserved_gdb(sb, group, gdb_bh); if (gdbackups < 0) { err = gdbackups; - goto exit_bh; + goto errout; }
data = EXT4_I(inode)->i_data + EXT4_DIND_BLOCK; - dind = sb_bread(sb, le32_to_cpu(*data)); - if (!dind) { - err = -EIO; - goto exit_bh; + dind = ext4_sb_bread(sb, le32_to_cpu(*data), 0); + if (IS_ERR(dind)) { + err = PTR_ERR(dind); + dind = NULL; + goto errout; }
data = (__le32 *)dind->b_data; @@ -816,18 +819,18 @@ static int add_new_gdb(handle_t *handle, ext4_warning(sb, "new group %u GDT block %llu not reserved", group, gdblock); err = -EINVAL; - goto exit_dind; + goto errout; }
BUFFER_TRACE(EXT4_SB(sb)->s_sbh, "get_write_access"); err = ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh); if (unlikely(err)) - goto exit_dind; + goto errout;
BUFFER_TRACE(gdb_bh, "get_write_access"); err = ext4_journal_get_write_access(handle, gdb_bh); if (unlikely(err)) - goto exit_dind; + goto errout;
BUFFER_TRACE(dind, "get_write_access"); err = ext4_journal_get_write_access(handle, dind); @@ -837,7 +840,7 @@ static int add_new_gdb(handle_t *handle, /* ext4_reserve_inode_write() gets a reference on the iloc */ err = ext4_reserve_inode_write(handle, inode, &iloc); if (unlikely(err)) - goto exit_dind; + goto errout;
n_group_desc = ext4_kvmalloc((gdb_num + 1) * sizeof(struct buffer_head *), @@ -846,7 +849,7 @@ static int add_new_gdb(handle_t *handle, err = -ENOMEM; ext4_warning(sb, "not enough memory for %lu groups", gdb_num + 1); - goto exit_inode; + goto errout; }
/* @@ -862,7 +865,7 @@ static int add_new_gdb(handle_t *handle, err = ext4_handle_dirty_metadata(handle, NULL, dind); if (unlikely(err)) { ext4_std_error(sb, err); - goto exit_inode; + goto errout; } inode->i_blocks -= (gdbackups + 1) * sb->s_blocksize >> (9 - EXT4_SB(sb)->s_cluster_bits); @@ -871,8 +874,7 @@ static int add_new_gdb(handle_t *handle, err = ext4_handle_dirty_metadata(handle, NULL, gdb_bh); if (unlikely(err)) { ext4_std_error(sb, err); - iloc.bh = NULL; - goto exit_inode; + goto errout; } brelse(dind);
@@ -888,15 +890,11 @@ static int add_new_gdb(handle_t *handle, err = ext4_handle_dirty_super(handle, sb); if (err) ext4_std_error(sb, err); - return err; - -exit_inode: +errout: kvfree(n_group_desc); brelse(iloc.bh); -exit_dind: brelse(dind); -exit_bh: brelse(gdb_bh);
ext4_debug("leaving with error %d\n", err); @@ -916,9 +914,9 @@ static int add_new_gdb_meta_bg(struct su
gdblock = ext4_meta_bg_first_block_no(sb, group) + ext4_bg_has_super(sb, group); - gdb_bh = sb_bread(sb, gdblock); - if (!gdb_bh) - return -EIO; + gdb_bh = ext4_sb_bread(sb, gdblock, 0); + if (IS_ERR(gdb_bh)) + return PTR_ERR(gdb_bh); n_group_desc = ext4_kvmalloc((gdb_num + 1) * sizeof(struct buffer_head *), GFP_NOFS); @@ -975,9 +973,10 @@ static int reserve_backup_gdb(handle_t * return -ENOMEM;
data = EXT4_I(inode)->i_data + EXT4_DIND_BLOCK; - dind = sb_bread(sb, le32_to_cpu(*data)); - if (!dind) { - err = -EIO; + dind = ext4_sb_bread(sb, le32_to_cpu(*data), 0); + if (IS_ERR(dind)) { + err = PTR_ERR(dind); + dind = NULL; goto exit_free; }
@@ -996,9 +995,10 @@ static int reserve_backup_gdb(handle_t * err = -EINVAL; goto exit_bh; } - primary[res] = sb_bread(sb, blk); - if (!primary[res]) { - err = -EIO; + primary[res] = ext4_sb_bread(sb, blk, 0); + if (IS_ERR(primary[res])) { + err = PTR_ERR(primary[res]); + primary[res] = NULL; goto exit_bh; } gdbackups = verify_reserved_gdb(sb, group, primary[res]); --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -140,6 +140,29 @@ MODULE_ALIAS_FS("ext3"); MODULE_ALIAS("ext3"); #define IS_EXT3_SB(sb) ((sb)->s_bdev->bd_holder == &ext3_fs_type)
+/* + * This works like sb_bread() except it uses ERR_PTR for error + * returns. Currently with sb_bread it's impossible to distinguish + * between ENOMEM and EIO situations (since both result in a NULL + * return. + */ +struct buffer_head * +ext4_sb_bread(struct super_block *sb, sector_t block, int op_flags) +{ + struct buffer_head *bh = sb_getblk(sb, block); + + if (bh == NULL) + return ERR_PTR(-ENOMEM); + if (buffer_uptodate(bh)) + return bh; + ll_rw_block(REQ_OP_READ, REQ_META | op_flags, 1, &bh); + wait_on_buffer(bh); + if (buffer_uptodate(bh)) + return bh; + put_bh(bh); + return ERR_PTR(-EIO); +} + static int ext4_verify_csum_type(struct super_block *sb, struct ext4_super_block *es) { --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -522,14 +522,13 @@ ext4_xattr_block_get(struct inode *inode ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld", name_index, name, buffer, (long)buffer_size);
- error = -ENODATA; if (!EXT4_I(inode)->i_file_acl) - goto cleanup; + return -ENODATA; ea_idebug(inode, "reading block %llu", (unsigned long long)EXT4_I(inode)->i_file_acl); - bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl); - if (!bh) - goto cleanup; + bh = ext4_sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl, REQ_PRIO); + if (IS_ERR(bh)) + return PTR_ERR(bh); ea_bdebug(bh, "b_count=%d, refcount=%d", atomic_read(&(bh->b_count)), le32_to_cpu(BHDR(bh)->h_refcount)); error = ext4_xattr_check_block(inode, bh); @@ -696,26 +695,23 @@ ext4_xattr_block_list(struct dentry *den ea_idebug(inode, "buffer=%p, buffer_size=%ld", buffer, (long)buffer_size);
- error = 0; if (!EXT4_I(inode)->i_file_acl) - goto cleanup; + return 0; ea_idebug(inode, "reading block %llu", (unsigned long long)EXT4_I(inode)->i_file_acl); - bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl); - error = -EIO; - if (!bh) - goto cleanup; + bh = ext4_sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl, REQ_PRIO); + if (IS_ERR(bh)) + return PTR_ERR(bh); ea_bdebug(bh, "b_count=%d, refcount=%d", atomic_read(&(bh->b_count)), le32_to_cpu(BHDR(bh)->h_refcount)); error = ext4_xattr_check_block(inode, bh); if (error) goto cleanup; ext4_xattr_block_cache_insert(EA_BLOCK_CACHE(inode), bh); - error = ext4_xattr_list_entries(dentry, BFIRST(bh), buffer, buffer_size); - + error = ext4_xattr_list_entries(dentry, BFIRST(bh), buffer, + buffer_size); cleanup: brelse(bh); - return error; }
@@ -830,9 +826,9 @@ int ext4_get_inode_usage(struct inode *i }
if (EXT4_I(inode)->i_file_acl) { - bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl); - if (!bh) { - ret = -EIO; + bh = ext4_sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl, REQ_PRIO); + if (IS_ERR(bh)) { + ret = PTR_ERR(bh); goto out; }
@@ -1821,16 +1817,15 @@ ext4_xattr_block_find(struct inode *inod
if (EXT4_I(inode)->i_file_acl) { /* The inode already has an extended attribute block. */ - bs->bh = sb_bread(sb, EXT4_I(inode)->i_file_acl); - error = -EIO; - if (!bs->bh) - goto cleanup; + bs->bh = ext4_sb_bread(sb, EXT4_I(inode)->i_file_acl, REQ_PRIO); + if (IS_ERR(bs->bh)) + return PTR_ERR(bs->bh); ea_bdebug(bs->bh, "b_count=%d, refcount=%d", atomic_read(&(bs->bh->b_count)), le32_to_cpu(BHDR(bs->bh)->h_refcount)); error = ext4_xattr_check_block(inode, bs->bh); if (error) - goto cleanup; + return error; /* Find the named attribute. */ bs->s.base = BHDR(bs->bh); bs->s.first = BFIRST(bs->bh); @@ -1839,13 +1834,10 @@ ext4_xattr_block_find(struct inode *inod error = xattr_find_entry(inode, &bs->s.here, bs->s.end, i->name_index, i->name, 1); if (error && error != -ENODATA) - goto cleanup; + return error; bs->s.not_found = error; } - error = 0; - -cleanup: - return error; + return 0; }
static int @@ -2274,9 +2266,9 @@ static struct buffer_head *ext4_xattr_ge
if (!EXT4_I(inode)->i_file_acl) return NULL; - bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl); - if (!bh) - return ERR_PTR(-EIO); + bh = ext4_sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl, REQ_PRIO); + if (IS_ERR(bh)) + return bh; error = ext4_xattr_check_block(inode, bh); if (error) { brelse(bh); @@ -2746,10 +2738,11 @@ retry: if (EXT4_I(inode)->i_file_acl) { struct buffer_head *bh;
- bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl); - error = -EIO; - if (!bh) + bh = ext4_sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl, REQ_PRIO); + if (IS_ERR(bh)) { + error = PTR_ERR(bh); goto cleanup; + } error = ext4_xattr_check_block(inode, bh); if (error) { brelse(bh); @@ -2903,11 +2896,12 @@ int ext4_xattr_delete_inode(handle_t *ha }
if (EXT4_I(inode)->i_file_acl) { - bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl); - if (!bh) { - EXT4_ERROR_INODE(inode, "block %llu read error", - EXT4_I(inode)->i_file_acl); - error = -EIO; + bh = ext4_sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl, REQ_PRIO); + if (IS_ERR(bh)) { + error = PTR_ERR(bh); + if (error == -EIO) + EXT4_ERROR_INODE(inode, "block %llu read error", + EXT4_I(inode)->i_file_acl); goto cleanup; } error = ext4_xattr_check_block(inode, bh); @@ -3060,8 +3054,10 @@ ext4_xattr_block_cache_find(struct inode while (ce) { struct buffer_head *bh;
- bh = sb_bread(inode->i_sb, ce->e_value); - if (!bh) { + bh = ext4_sb_bread(inode->i_sb, ce->e_value, REQ_PRIO); + if (IS_ERR(bh)) { + if (PTR_ERR(bh) == -ENOMEM) + return NULL; EXT4_ERROR_INODE(inode, "block %lu read error", (unsigned long)ce->e_value); } else if (ext4_xattr_cmp(header, BHDR(bh)) == 0) {
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pan Bian bianpan2016@163.com
commit 61157b24e60fb3cd1f85f2c76a7b1d628f970144 upstream.
The function frees qf_inode via iput but then pass qf_inode to lockdep_set_quota_inode on the failure path. This may result in a use-after-free bug. The patch frees df_inode only when it is never used.
Fixes: daf647d2dd5 ("ext4: add lockdep annotations for i_data_sem") Cc: stable@kernel.org # 4.6 Reviewed-by: Jan Kara jack@suse.cz Signed-off-by: Pan Bian bianpan2016@163.com Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/ext4/super.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -5713,9 +5713,9 @@ static int ext4_quota_enable(struct supe qf_inode->i_flags |= S_NOQUOTA; lockdep_set_quota_inode(qf_inode, I_DATA_SEM_QUOTA); err = dquot_enable(qf_inode, type, format_id, flags); - iput(qf_inode); if (err) lockdep_set_quota_inode(qf_inode, I_DATA_SEM_NORMAL); + iput(qf_inode);
return err; }
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maurizio Lombardi mlombard@redhat.com
commit 132d00becb31e88469334e1e62751c81345280e0 upstream.
In case of error, ext4_try_to_write_inline_data() should unlock and release the page it holds.
Fixes: f19d5870cbf7 ("ext4: add normal write support for inline data") Cc: stable@kernel.org # 3.8 Signed-off-by: Maurizio Lombardi mlombard@redhat.com Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/ext4/inline.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
--- a/fs/ext4/inline.c +++ b/fs/ext4/inline.c @@ -705,8 +705,11 @@ int ext4_try_to_write_inline_data(struct
if (!PageUptodate(page)) { ret = ext4_read_inline_page(inode, page); - if (ret < 0) + if (ret < 0) { + unlock_page(page); + put_page(page); goto out_up_read; + } }
ret = 1;
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: ruippan (潘睿) ruippan@tencent.com
commit e647e29196b7f802f8242c39ecb7cc937f5ef217 upstream.
Commit e2b911c53584 ("ext4: clean up feature test macros with predicate functions") broke the EXT4_IOC_GROUP_ADD ioctl. This was not noticed since only very old versions of resize2fs (before e2fsprogs 1.42) use this ioctl. However, using a new kernel with an enterprise Linux userspace will cause attempts to use online resize to fail with "No reserved GDT blocks".
Fixes: e2b911c53584 ("ext4: clean up feature test macros with predicate...") Cc: stable@kernel.org # v4.4 Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: ruippan (潘睿) ruippan@tencent.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/ext4/resize.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c @@ -1631,7 +1631,7 @@ int ext4_group_add(struct super_block *s }
if (reserved_gdb || gdb_off == 0) { - if (ext4_has_feature_resize_inode(sb) || + if (!ext4_has_feature_resize_inode(sb) || !le16_to_cpu(es->s_reserved_gdt_blocks)) { ext4_warning(sb, "No reserved GDT blocks, can't resize");
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o tytso@mit.edu
commit a805622a757b6d7f65def4141d29317d8e37b8a1 upstream.
In ext4_expand_extra_isize_ea(), we calculate the total size of the xattr header, plus the xattr entries so we know how much of the beginning part of the xattrs to move when expanding the inode extra size. We need to include the terminating u32 at the end of the xattr entries, or else if there is uninitialized, non-zero bytes after the xattr entries and before the xattr values, the list of xattr entries won't be properly terminated.
Reported-by: Steve Graham stgraham2000@gmail.com Signed-off-by: Theodore Ts'o tytso@mit.edu Cc: stable@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/ext4/xattr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -2721,7 +2721,7 @@ retry: base = IFIRST(header); end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size; min_offs = end - base; - total_ino = sizeof(struct ext4_xattr_ibody_header); + total_ino = sizeof(struct ext4_xattr_ibody_header) + sizeof(u32);
error = xattr_check_inode(inode, header, end); if (error)
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o tytso@mit.edu
commit 8a363970d1dc38c4ec4ad575c862f776f468d057 upstream.
If we receive a file handle, either from NFS or open_by_handle_at(2), and it points at an inode which has not been initialized, and the file system has metadata checksums enabled, we shouldn't try to get the inode, discover the checksum is invalid, and then declare the file system as being inconsistent.
This can be reproduced by creating a test file system via "mke2fs -t ext4 -O metadata_csum /tmp/foo.img 8M", mounting it, cd'ing into that directory, and then running the following program.
#define _GNU_SOURCE #include <fcntl.h>
struct handle { struct file_handle fh; unsigned char fid[MAX_HANDLE_SZ]; };
int main(int argc, char **argv) { struct handle h = {{8, 1 }, { 12, }};
open_by_handle_at(AT_FDCWD, &h.fh, O_RDONLY); return 0; }
Google-Bug-Id: 120690101 Signed-off-by: Theodore Ts'o tytso@mit.edu Cc: stable@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/ext4/ext4.h | 15 +++++++++++++-- fs/ext4/ialloc.c | 2 +- fs/ext4/inode.c | 54 +++++++++++++++++++++++++++++++++++++----------------- fs/ext4/ioctl.c | 2 +- fs/ext4/namei.c | 4 ++-- fs/ext4/resize.c | 5 +++-- fs/ext4/super.c | 19 +++++-------------- fs/ext4/xattr.c | 5 +++-- 8 files changed, 65 insertions(+), 41 deletions(-)
--- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -2454,8 +2454,19 @@ int do_journal_get_write_access(handle_t #define FALL_BACK_TO_NONDELALLOC 1 #define CONVERT_INLINE_DATA 2
-extern struct inode *ext4_iget(struct super_block *, unsigned long); -extern struct inode *ext4_iget_normal(struct super_block *, unsigned long); +typedef enum { + EXT4_IGET_NORMAL = 0, + EXT4_IGET_SPECIAL = 0x0001, /* OK to iget a system inode */ + EXT4_IGET_HANDLE = 0x0002 /* Inode # is from a handle */ +} ext4_iget_flags; + +extern struct inode *__ext4_iget(struct super_block *sb, unsigned long ino, + ext4_iget_flags flags, const char *function, + unsigned int line); + +#define ext4_iget(sb, ino, flags) \ + __ext4_iget((sb), (ino), (flags), __func__, __LINE__) + extern int ext4_write_inode(struct inode *, struct writeback_control *); extern int ext4_setattr(struct dentry *, struct iattr *); extern int ext4_getattr(const struct path *, struct kstat *, u32, unsigned int); --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -1225,7 +1225,7 @@ struct inode *ext4_orphan_get(struct sup if (!ext4_test_bit(bit, bitmap_bh->b_data)) goto bad_orphan;
- inode = ext4_iget(sb, ino); + inode = ext4_iget(sb, ino, EXT4_IGET_NORMAL); if (IS_ERR(inode)) { err = PTR_ERR(inode); ext4_error(sb, "couldn't read orphan inode %lu (err %d)", --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -4817,7 +4817,9 @@ static inline u64 ext4_inode_peek_iversi return inode_peek_iversion(inode); }
-struct inode *ext4_iget(struct super_block *sb, unsigned long ino) +struct inode *__ext4_iget(struct super_block *sb, unsigned long ino, + ext4_iget_flags flags, const char *function, + unsigned int line) { struct ext4_iloc iloc; struct ext4_inode *raw_inode; @@ -4831,6 +4833,18 @@ struct inode *ext4_iget(struct super_blo gid_t i_gid; projid_t i_projid;
+ if (((flags & EXT4_IGET_NORMAL) && + (ino < EXT4_FIRST_INO(sb) && ino != EXT4_ROOT_INO)) || + (ino < EXT4_ROOT_INO) || + (ino > le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count))) { + if (flags & EXT4_IGET_HANDLE) + return ERR_PTR(-ESTALE); + __ext4_error(sb, function, line, + "inode #%lu: comm %s: iget: illegal inode #", + ino, current->comm); + return ERR_PTR(-EFSCORRUPTED); + } + inode = iget_locked(sb, ino); if (!inode) return ERR_PTR(-ENOMEM); @@ -4846,18 +4860,26 @@ struct inode *ext4_iget(struct super_blo raw_inode = ext4_raw_inode(&iloc);
if ((ino == EXT4_ROOT_INO) && (raw_inode->i_links_count == 0)) { - EXT4_ERROR_INODE(inode, "root inode unallocated"); + ext4_error_inode(inode, function, line, 0, + "iget: root inode unallocated"); ret = -EFSCORRUPTED; goto bad_inode; }
+ if ((flags & EXT4_IGET_HANDLE) && + (raw_inode->i_links_count == 0) && (raw_inode->i_mode == 0)) { + ret = -ESTALE; + goto bad_inode; + } + if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) { ei->i_extra_isize = le16_to_cpu(raw_inode->i_extra_isize); if (EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize > EXT4_INODE_SIZE(inode->i_sb) || (ei->i_extra_isize & 3)) { - EXT4_ERROR_INODE(inode, - "bad extra_isize %u (inode size %u)", + ext4_error_inode(inode, function, line, 0, + "iget: bad extra_isize %u " + "(inode size %u)", ei->i_extra_isize, EXT4_INODE_SIZE(inode->i_sb)); ret = -EFSCORRUPTED; @@ -4879,7 +4901,8 @@ struct inode *ext4_iget(struct super_blo }
if (!ext4_inode_csum_verify(inode, raw_inode, ei)) { - EXT4_ERROR_INODE(inode, "checksum invalid"); + ext4_error_inode(inode, function, line, 0, + "iget: checksum invalid"); ret = -EFSBADCRC; goto bad_inode; } @@ -4936,7 +4959,8 @@ struct inode *ext4_iget(struct super_blo ((__u64)le16_to_cpu(raw_inode->i_file_acl_high)) << 32; inode->i_size = ext4_isize(sb, raw_inode); if ((size = i_size_read(inode)) < 0) { - EXT4_ERROR_INODE(inode, "bad i_size value: %lld", size); + ext4_error_inode(inode, function, line, 0, + "iget: bad i_size value: %lld", size); ret = -EFSCORRUPTED; goto bad_inode; } @@ -5012,7 +5036,8 @@ struct inode *ext4_iget(struct super_blo ret = 0; if (ei->i_file_acl && !ext4_data_block_valid(EXT4_SB(sb), ei->i_file_acl, 1)) { - EXT4_ERROR_INODE(inode, "bad extended attribute block %llu", + ext4_error_inode(inode, function, line, 0, + "iget: bad extended attribute block %llu", ei->i_file_acl); ret = -EFSCORRUPTED; goto bad_inode; @@ -5040,8 +5065,9 @@ struct inode *ext4_iget(struct super_blo } else if (S_ISLNK(inode->i_mode)) { /* VFS does not allow setting these so must be corruption */ if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) { - EXT4_ERROR_INODE(inode, - "immutable or append flags not allowed on symlinks"); + ext4_error_inode(inode, function, line, 0, + "iget: immutable or append flags " + "not allowed on symlinks"); ret = -EFSCORRUPTED; goto bad_inode; } @@ -5071,7 +5097,8 @@ struct inode *ext4_iget(struct super_blo make_bad_inode(inode); } else { ret = -EFSCORRUPTED; - EXT4_ERROR_INODE(inode, "bogus i_mode (%o)", inode->i_mode); + ext4_error_inode(inode, function, line, 0, + "iget: bogus i_mode (%o)", inode->i_mode); goto bad_inode; } brelse(iloc.bh); @@ -5085,13 +5112,6 @@ bad_inode: return ERR_PTR(ret); }
-struct inode *ext4_iget_normal(struct super_block *sb, unsigned long ino) -{ - if (ino < EXT4_FIRST_INO(sb) && ino != EXT4_ROOT_INO) - return ERR_PTR(-EFSCORRUPTED); - return ext4_iget(sb, ino); -} - static int ext4_inode_blocks_set(handle_t *handle, struct ext4_inode *raw_inode, struct ext4_inode_info *ei) --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c @@ -125,7 +125,7 @@ static long swap_inode_boot_loader(struc !inode_owner_or_capable(inode) || !capable(CAP_SYS_ADMIN)) return -EPERM;
- inode_bl = ext4_iget(sb, EXT4_BOOT_LOADER_INO); + inode_bl = ext4_iget(sb, EXT4_BOOT_LOADER_INO, EXT4_IGET_SPECIAL); if (IS_ERR(inode_bl)) return PTR_ERR(inode_bl); ei_bl = EXT4_I(inode_bl); --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -1571,7 +1571,7 @@ static struct dentry *ext4_lookup(struct dentry); return ERR_PTR(-EFSCORRUPTED); } - inode = ext4_iget_normal(dir->i_sb, ino); + inode = ext4_iget(dir->i_sb, ino, EXT4_IGET_NORMAL); if (inode == ERR_PTR(-ESTALE)) { EXT4_ERROR_INODE(dir, "deleted inode referenced: %u", @@ -1613,7 +1613,7 @@ struct dentry *ext4_get_parent(struct de return ERR_PTR(-EFSCORRUPTED); }
- return d_obtain_alias(ext4_iget_normal(child->d_sb, ino)); + return d_obtain_alias(ext4_iget(child->d_sb, ino, EXT4_IGET_NORMAL)); }
/* --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c @@ -1637,7 +1637,7 @@ int ext4_group_add(struct super_block *s "No reserved GDT blocks, can't resize"); return -EPERM; } - inode = ext4_iget(sb, EXT4_RESIZE_INO); + inode = ext4_iget(sb, EXT4_RESIZE_INO, EXT4_IGET_SPECIAL); if (IS_ERR(inode)) { ext4_warning(sb, "Error opening resize inode"); return PTR_ERR(inode); @@ -1965,7 +1965,8 @@ retry: }
if (!resize_inode) - resize_inode = ext4_iget(sb, EXT4_RESIZE_INO); + resize_inode = ext4_iget(sb, EXT4_RESIZE_INO, + EXT4_IGET_SPECIAL); if (IS_ERR(resize_inode)) { ext4_warning(sb, "Error opening resize inode"); return PTR_ERR(resize_inode); --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1174,20 +1174,11 @@ static struct inode *ext4_nfs_get_inode( { struct inode *inode;
- if (ino < EXT4_FIRST_INO(sb) && ino != EXT4_ROOT_INO) - return ERR_PTR(-ESTALE); - if (ino > le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count)) - return ERR_PTR(-ESTALE); - - /* iget isn't really right if the inode is currently unallocated!! - * - * ext4_read_inode will return a bad_inode if the inode had been - * deleted, so we should be safe. - * + /* * Currently we don't know the generation for parent directory, so * a generation of 0 means "accept any" */ - inode = ext4_iget_normal(sb, ino); + inode = ext4_iget(sb, ino, EXT4_IGET_HANDLE); if (IS_ERR(inode)) return ERR_CAST(inode); if (generation && inode->i_generation != generation) { @@ -4351,7 +4342,7 @@ no_journal: * so we can safely mount the rest of the filesystem now. */
- root = ext4_iget(sb, EXT4_ROOT_INO); + root = ext4_iget(sb, EXT4_ROOT_INO, EXT4_IGET_SPECIAL); if (IS_ERR(root)) { ext4_msg(sb, KERN_ERR, "get root inode failed"); ret = PTR_ERR(root); @@ -4621,7 +4612,7 @@ static struct inode *ext4_get_journal_in * happen if we iget() an unused inode, as the subsequent iput() * will try to delete it. */ - journal_inode = ext4_iget(sb, journal_inum); + journal_inode = ext4_iget(sb, journal_inum, EXT4_IGET_SPECIAL); if (IS_ERR(journal_inode)) { ext4_msg(sb, KERN_ERR, "no journal found"); return NULL; @@ -5703,7 +5694,7 @@ static int ext4_quota_enable(struct supe if (!qf_inums[type]) return -EPERM;
- qf_inode = ext4_iget(sb, qf_inums[type]); + qf_inode = ext4_iget(sb, qf_inums[type], EXT4_IGET_SPECIAL); if (IS_ERR(qf_inode)) { ext4_error(sb, "Bad quota inode # %lu", qf_inums[type]); return PTR_ERR(qf_inode); --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -384,7 +384,7 @@ static int ext4_xattr_inode_iget(struct struct inode *inode; int err;
- inode = ext4_iget(parent->i_sb, ea_ino); + inode = ext4_iget(parent->i_sb, ea_ino, EXT4_IGET_NORMAL); if (IS_ERR(inode)) { err = PTR_ERR(inode); ext4_error(parent->i_sb, @@ -1482,7 +1482,8 @@ ext4_xattr_inode_cache_find(struct inode }
while (ce) { - ea_inode = ext4_iget(inode->i_sb, ce->e_value); + ea_inode = ext4_iget(inode->i_sb, ce->e_value, + EXT4_IGET_NORMAL); if (!IS_ERR(ea_inode) && !is_bad_inode(ea_inode) && (EXT4_I(ea_inode)->i_flags & EXT4_EA_INODE_FL) &&
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o tytso@mit.edu
commit fde872682e175743e0c3ef939c89e3c6008a1529 upstream.
Some time back, nfsd switched from calling vfs_fsync() to using a new commit_metadata() hook in export_operations(). If the file system did not provide a commit_metadata() hook, it fell back to using sync_inode_metadata(). Unfortunately doesn't work on all file systems. In particular, it doesn't work on ext4 due to how the inode gets journalled --- the VFS writeback code will not always call ext4_write_inode().
So we need to provide our own ext4_nfs_commit_metdata() method which calls ext4_write_inode() directly.
Google-Bug-Id: 121195940 Signed-off-by: Theodore Ts'o tytso@mit.edu Cc: stable@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/ext4/super.c | 11 +++++++++++ include/trace/events/ext4.h | 20 ++++++++++++++++++++ 2 files changed, 31 insertions(+)
--- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1203,6 +1203,16 @@ static struct dentry *ext4_fh_to_parent( ext4_nfs_get_inode); }
+static int ext4_nfs_commit_metadata(struct inode *inode) +{ + struct writeback_control wbc = { + .sync_mode = WB_SYNC_ALL + }; + + trace_ext4_nfs_commit_metadata(inode); + return ext4_write_inode(inode, &wbc); +} + /* * Try to release metadata pages (indirect blocks, directories) which are * mapped via the block device. Since these pages could have journal heads @@ -1407,6 +1417,7 @@ static const struct export_operations ex .fh_to_dentry = ext4_fh_to_dentry, .fh_to_parent = ext4_fh_to_parent, .get_parent = ext4_get_parent, + .commit_metadata = ext4_nfs_commit_metadata, };
enum { --- a/include/trace/events/ext4.h +++ b/include/trace/events/ext4.h @@ -226,6 +226,26 @@ TRACE_EVENT(ext4_drop_inode, (unsigned long) __entry->ino, __entry->drop) );
+TRACE_EVENT(ext4_nfs_commit_metadata, + TP_PROTO(struct inode *inode), + + TP_ARGS(inode), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + ), + + TP_printk("dev %d,%d ino %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino) +); + TRACE_EVENT(ext4_mark_inode_dirty, TP_PROTO(struct inode *inode, unsigned long IP),
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o tytso@mit.edu
commit 18f2c4fcebf2582f96cbd5f2238f4f354a0e4847 upstream.
If the file system has been shut down or is read-only, then ext4_write_inode() needs to bail out early.
Also use jbd2_complete_transaction() instead of ext4_force_commit() so we only force a commit if it is needed.
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 | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
--- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -5400,9 +5400,13 @@ int ext4_write_inode(struct inode *inode { int err;
- if (WARN_ON_ONCE(current->flags & PF_MEMALLOC)) + if (WARN_ON_ONCE(current->flags & PF_MEMALLOC) || + sb_rdonly(inode->i_sb)) return 0;
+ if (unlikely(ext4_forced_shutdown(EXT4_SB(inode->i_sb)))) + return -EIO; + if (EXT4_SB(inode->i_sb)->s_journal) { if (ext4_journal_current_handle()) { jbd_debug(1, "called recursively, non-PF_MEMALLOC!\n"); @@ -5418,7 +5422,8 @@ int ext4_write_inode(struct inode *inode if (wbc->sync_mode != WB_SYNC_ALL || wbc->for_sync) return 0;
- err = ext4_force_commit(inode->i_sb); + err = jbd2_complete_transaction(EXT4_SB(inode->i_sb)->s_journal, + EXT4_I(inode)->i_sync_tid); } else { struct ext4_iloc iloc;
On Mon, Jan 07, 2019 at 01:31:56PM +0100, Greg Kroah-Hartman wrote:
4.20-stable review patch. If anyone has any objections, please let me know.
From: Theodore Ts'o tytso@mit.edu
commit 18f2c4fcebf2582f96cbd5f2238f4f354a0e4847 upstream.
If the file system has been shut down or is read-only, then ext4_write_inode() needs to bail out early.
Also use jbd2_complete_transaction() instead of ext4_force_commit() so we only force a commit if it is needed.
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 | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
--- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -5400,9 +5400,13 @@ int ext4_write_inode(struct inode *inode { int err;
- if (WARN_ON_ONCE(current->flags & PF_MEMALLOC))
if (WARN_ON_ONCE(current->flags & PF_MEMALLOC) ||
sb_rdonly(inode->i_sb))
return 0;
if (unlikely(ext4_forced_shutdown(EXT4_SB(inode->i_sb))))
return -EIO;
if (EXT4_SB(inode->i_sb)->s_journal) { if (ext4_journal_current_handle()) { jbd_debug(1, "called recursively, non-PF_MEMALLOC!\n");
@@ -5418,7 +5422,8 @@ int ext4_write_inode(struct inode *inode if (wbc->sync_mode != WB_SYNC_ALL || wbc->for_sync) return 0;
err = ext4_force_commit(inode->i_sb);
err = jbd2_complete_transaction(EXT4_SB(inode->i_sb)->s_journal,
} else { struct ext4_iloc iloc;EXT4_I(inode)->i_sync_tid);
Hi Ted,
I'm not sure if this patch is the culprit or no, but testing with xfstests on 4.20.1-rc1 started failing generic/390 with:
[ 3405.656893] run fstests generic/390 at 2019-01-07 20:26:55 [ 3406.524380] EXT4-fs (nvme0n1p2): mounted filesystem without journal. Opts: acl,user_xattr [ 3406.731410] WARNING: CPU: 0 PID: 93128 at fs/ext4/ext4_jbd2.c:53 ext4_journal_check_start+0x121/0x190 [ 3406.731418] CPU: 0 PID: 93128 Comm: fsstress Tainted: G B W 4.20.1-rc1+ #1 [ 3406.731420] Hardware name: Microsoft Corporation Virtual Machine/Virtual Machine, BIOS 090007 05/18/2018 [ 3406.731425] RIP: 0010:ext4_journal_check_start+0x121/0x190 [ 3406.731430] Code: 4d 85 e4 74 1e 4c 89 e2 48 b8 00 00 00 00 00 fc ff df 48 c1 ea 03 80 3c 02 00 75 4f 41 f6 04 24 02 75 0b 31 c0 5b 41 5c 5d c3 <0f> 0b eb ab 48 c7 c1 60 b4 f9 a4 ba 3d 00 00 00 48 c7 c6 a0 b8 f9 [ 3406.731432] RSP: 0018:ffff888f30317648 EFLAGS: 00010246 [ 3406.731437] RAX: 0000000000000000 RBX: ffff888ee6ce12c8 RCX: 000000000000000c [ 3406.731440] RDX: 1ffff111dcd9c2a0 RSI: 0000000000000b33 RDI: ffff888ee6ce1500 [ 3406.731442] RBP: ffff888f30317658 R08: 0000000000000000 R09: ffffed11db5f01a7 [ 3406.731444] R10: 0000000000000001 R11: ffffed11db5f01a6 R12: ffff888ee6ce2ee8 [ 3406.731447] R13: dffffc0000000000 R14: 0000000000000000 R15: ffff888f303178e0 [ 3406.731450] FS: 00007fc015d5cb80(0000) GS:ffff888f6b800000(0000) knlGS:0000000000000000 [ 3406.731452] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 3406.731455] CR2: 0000557f34651000 CR3: 0000000f2c722000 CR4: 00000000003406f0 [ 3406.731459] Call Trace: [ 3406.731465] __ext4_journal_start_sb+0x95/0x380 [ 3406.731479] ext4_writepages+0x10e1/0x3170 [ 3406.731567] do_writepages+0xc7/0x120 [ 3406.731577] __filemap_fdatawrite_range+0x313/0x470 [ 3406.731594] file_write_and_wait_range+0x7c/0xd0 [ 3406.731598] __generic_file_fsync+0x6c/0x180 [ 3406.731601] ext4_sync_file+0x60b/0xf90 [ 3406.731626] vfs_fsync_range+0xf5/0x210 [ 3406.731630] do_fsync+0x3d/0x70 [ 3406.731634] __x64_sys_fdatasync+0x36/0x50 [ 3406.731638] do_syscall_64+0x153/0x460 [ 3406.731666] entry_SYSCALL_64_after_hwframe+0x44/0xa9 [ 3406.731669] RIP: 0033:0x7fc0152412c4 [ 3406.731673] Code: 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 8d 05 41 96 2d 00 8b 00 85 c0 75 13 b8 4b 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 3c f3 c3 66 90 53 89 fb 48 83 ec 10 e8 04 94 [ 3406.731675] RSP: 002b:00007ffc445f72f8 EFLAGS: 00000246 ORIG_RAX: 000000000000004b [ 3406.731679] RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 00007fc0152412c4 [ 3406.731681] RDX: 00007ffc445f7250 RSI: 00007ffc445f7250 RDI: 0000000000000003 [ 3406.731683] RBP: 0000000000000034 R08: 00007fc015515c40 R09: 0000000000000000 [ 3406.731685] R10: 0000000000000000 R11: 0000000000000246 R12: 00000000000001f4 [ 3406.731687] R13: 0000000051eb851f R14: 00007ffc445f73f6 R15: 0000557f33ad1930 [ 3406.731690] ---[ end trace 698eba2a0467d312 ]---
I'm also slightly confused here because this test is for ext4 without journal (see even "EXT4-fs (nvme0n1p2): mounted filesystem without journal") but for some reason it seems that this still goes to the journal?
-- Thanks, Sasha
On Mon, Jan 07, 2019 at 04:56:06PM -0500, Sasha Levin wrote:
On Mon, Jan 07, 2019 at 01:31:56PM +0100, Greg Kroah-Hartman wrote:
4.20-stable review patch. If anyone has any objections, please let me know.
From: Theodore Ts'o tytso@mit.edu
commit 18f2c4fcebf2582f96cbd5f2238f4f354a0e4847 upstream.
If the file system has been shut down or is read-only, then ext4_write_inode() needs to bail out early.
Also use jbd2_complete_transaction() instead of ext4_force_commit() so we only force a commit if it is needed.
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 | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
--- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -5400,9 +5400,13 @@ int ext4_write_inode(struct inode *inode { int err;
- if (WARN_ON_ONCE(current->flags & PF_MEMALLOC))
if (WARN_ON_ONCE(current->flags & PF_MEMALLOC) ||
sb_rdonly(inode->i_sb))
return 0;
if (unlikely(ext4_forced_shutdown(EXT4_SB(inode->i_sb))))
return -EIO;
if (EXT4_SB(inode->i_sb)->s_journal) { if (ext4_journal_current_handle()) { jbd_debug(1, "called recursively, non-PF_MEMALLOC!\n");
@@ -5418,7 +5422,8 @@ int ext4_write_inode(struct inode *inode if (wbc->sync_mode != WB_SYNC_ALL || wbc->for_sync) return 0;
err = ext4_force_commit(inode->i_sb);
err = jbd2_complete_transaction(EXT4_SB(inode->i_sb)->s_journal,
} else { struct ext4_iloc iloc;EXT4_I(inode)->i_sync_tid);
Hi Ted,
I'm not sure if this patch is the culprit or no, but testing with xfstests on 4.20.1-rc1 started failing generic/390 with:
[ 3405.656893] run fstests generic/390 at 2019-01-07 20:26:55 [ 3406.524380] EXT4-fs (nvme0n1p2): mounted filesystem without journal. Opts: acl,user_xattr [ 3406.731410] WARNING: CPU: 0 PID: 93128 at fs/ext4/ext4_jbd2.c:53 ext4_journal_check_start+0x121/0x190 [ 3406.731418] CPU: 0 PID: 93128 Comm: fsstress Tainted: G B W 4.20.1-rc1+ #1 [ 3406.731420] Hardware name: Microsoft Corporation Virtual Machine/Virtual Machine, BIOS 090007 05/18/2018 [ 3406.731425] RIP: 0010:ext4_journal_check_start+0x121/0x190 [ 3406.731430] Code: 4d 85 e4 74 1e 4c 89 e2 48 b8 00 00 00 00 00 fc ff df 48 c1 ea 03 80 3c 02 00 75 4f 41 f6 04 24 02 75 0b 31 c0 5b 41 5c 5d c3 <0f> 0b eb ab 48 c7 c1 60 b4 f9 a4 ba 3d 00 00 00 48 c7 c6 a0 b8 f9 [ 3406.731432] RSP: 0018:ffff888f30317648 EFLAGS: 00010246 [ 3406.731437] RAX: 0000000000000000 RBX: ffff888ee6ce12c8 RCX: 000000000000000c [ 3406.731440] RDX: 1ffff111dcd9c2a0 RSI: 0000000000000b33 RDI: ffff888ee6ce1500 [ 3406.731442] RBP: ffff888f30317658 R08: 0000000000000000 R09: ffffed11db5f01a7 [ 3406.731444] R10: 0000000000000001 R11: ffffed11db5f01a6 R12: ffff888ee6ce2ee8 [ 3406.731447] R13: dffffc0000000000 R14: 0000000000000000 R15: ffff888f303178e0 [ 3406.731450] FS: 00007fc015d5cb80(0000) GS:ffff888f6b800000(0000) knlGS:0000000000000000 [ 3406.731452] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 3406.731455] CR2: 0000557f34651000 CR3: 0000000f2c722000 CR4: 00000000003406f0 [ 3406.731459] Call Trace: [ 3406.731465] __ext4_journal_start_sb+0x95/0x380 [ 3406.731479] ext4_writepages+0x10e1/0x3170 [ 3406.731567] do_writepages+0xc7/0x120 [ 3406.731577] __filemap_fdatawrite_range+0x313/0x470 [ 3406.731594] file_write_and_wait_range+0x7c/0xd0 [ 3406.731598] __generic_file_fsync+0x6c/0x180 [ 3406.731601] ext4_sync_file+0x60b/0xf90 [ 3406.731626] vfs_fsync_range+0xf5/0x210 [ 3406.731630] do_fsync+0x3d/0x70 [ 3406.731634] __x64_sys_fdatasync+0x36/0x50 [ 3406.731638] do_syscall_64+0x153/0x460 [ 3406.731666] entry_SYSCALL_64_after_hwframe+0x44/0xa9 [ 3406.731669] RIP: 0033:0x7fc0152412c4 [ 3406.731673] Code: 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 8d 05 41 96 2d 00 8b 00 85 c0 75 13 b8 4b 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 3c f3 c3 66 90 53 89 fb 48 83 ec 10 e8 04 94 [ 3406.731675] RSP: 002b:00007ffc445f72f8 EFLAGS: 00000246 ORIG_RAX: 000000000000004b [ 3406.731679] RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 00007fc0152412c4 [ 3406.731681] RDX: 00007ffc445f7250 RSI: 00007ffc445f7250 RDI: 0000000000000003 [ 3406.731683] RBP: 0000000000000034 R08: 00007fc015515c40 R09: 0000000000000000 [ 3406.731685] R10: 0000000000000000 R11: 0000000000000246 R12: 00000000000001f4 [ 3406.731687] R13: 0000000051eb851f R14: 00007ffc445f73f6 R15: 0000557f33ad1930 [ 3406.731690] ---[ end trace 698eba2a0467d312 ]---
I'm also slightly confused here because this test is for ext4 without journal (see even "EXT4-fs (nvme0n1p2): mounted filesystem without journal") but for some reason it seems that this still goes to the journal?
Following up on this, I can reproduce this failure somewhat reliably with 4.20.1-rc1 but can't with 4.20. If there's anything I can do to help debug this please let me know.
-- Thanks, Sasha
On Mon, Jan 07, 2019 at 04:56:06PM -0500, Sasha Levin wrote:
On Mon, Jan 07, 2019 at 01:31:56PM +0100, Greg Kroah-Hartman wrote:
4.20-stable review patch. If anyone has any objections, please let me know.
From: Theodore Ts'o tytso@mit.edu
commit 18f2c4fcebf2582f96cbd5f2238f4f354a0e4847 upstream.
If the file system has been shut down or is read-only, then ext4_write_inode() needs to bail out early.
Also use jbd2_complete_transaction() instead of ext4_force_commit() so we only force a commit if it is needed.
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 | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
--- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -5400,9 +5400,13 @@ int ext4_write_inode(struct inode *inode { int err;
- if (WARN_ON_ONCE(current->flags & PF_MEMALLOC))
if (WARN_ON_ONCE(current->flags & PF_MEMALLOC) ||
sb_rdonly(inode->i_sb))
return 0;
if (unlikely(ext4_forced_shutdown(EXT4_SB(inode->i_sb))))
return -EIO;
if (EXT4_SB(inode->i_sb)->s_journal) { if (ext4_journal_current_handle()) { jbd_debug(1, "called recursively, non-PF_MEMALLOC!\n");
@@ -5418,7 +5422,8 @@ int ext4_write_inode(struct inode *inode if (wbc->sync_mode != WB_SYNC_ALL || wbc->for_sync) return 0;
err = ext4_force_commit(inode->i_sb);
err = jbd2_complete_transaction(EXT4_SB(inode->i_sb)->s_journal,
} else { struct ext4_iloc iloc;EXT4_I(inode)->i_sync_tid);
Hi Ted,
I'm not sure if this patch is the culprit or no, but testing with xfstests on 4.20.1-rc1 started failing generic/390 with:
[ 3405.656893] run fstests generic/390 at 2019-01-07 20:26:55 [ 3406.524380] EXT4-fs (nvme0n1p2): mounted filesystem without journal. Opts: acl,user_xattr [ 3406.731410] WARNING: CPU: 0 PID: 93128 at fs/ext4/ext4_jbd2.c:53 ext4_journal_check_start+0x121/0x190 [ 3406.731418] CPU: 0 PID: 93128 Comm: fsstress Tainted: G B W 4.20.1-rc1+ #1 [ 3406.731420] Hardware name: Microsoft Corporation Virtual Machine/Virtual Machine, BIOS 090007 05/18/2018 [ 3406.731425] RIP: 0010:ext4_journal_check_start+0x121/0x190 [ 3406.731430] Code: 4d 85 e4 74 1e 4c 89 e2 48 b8 00 00 00 00 00 fc ff df 48 c1 ea 03 80 3c 02 00 75 4f 41 f6 04 24 02 75 0b 31 c0 5b 41 5c 5d c3 <0f> 0b eb ab 48 c7 c1 60 b4 f9 a4 ba 3d 00 00 00 48 c7 c6 a0 b8 f9 [ 3406.731432] RSP: 0018:ffff888f30317648 EFLAGS: 00010246 [ 3406.731437] RAX: 0000000000000000 RBX: ffff888ee6ce12c8 RCX: 000000000000000c [ 3406.731440] RDX: 1ffff111dcd9c2a0 RSI: 0000000000000b33 RDI: ffff888ee6ce1500 [ 3406.731442] RBP: ffff888f30317658 R08: 0000000000000000 R09: ffffed11db5f01a7 [ 3406.731444] R10: 0000000000000001 R11: ffffed11db5f01a6 R12: ffff888ee6ce2ee8 [ 3406.731447] R13: dffffc0000000000 R14: 0000000000000000 R15: ffff888f303178e0 [ 3406.731450] FS: 00007fc015d5cb80(0000) GS:ffff888f6b800000(0000) knlGS:0000000000000000 [ 3406.731452] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 3406.731455] CR2: 0000557f34651000 CR3: 0000000f2c722000 CR4: 00000000003406f0 [ 3406.731459] Call Trace: [ 3406.731465] __ext4_journal_start_sb+0x95/0x380 [ 3406.731479] ext4_writepages+0x10e1/0x3170 [ 3406.731567] do_writepages+0xc7/0x120 [ 3406.731577] __filemap_fdatawrite_range+0x313/0x470 [ 3406.731594] file_write_and_wait_range+0x7c/0xd0 [ 3406.731598] __generic_file_fsync+0x6c/0x180 [ 3406.731601] ext4_sync_file+0x60b/0xf90 [ 3406.731626] vfs_fsync_range+0xf5/0x210 [ 3406.731630] do_fsync+0x3d/0x70 [ 3406.731634] __x64_sys_fdatasync+0x36/0x50 [ 3406.731638] do_syscall_64+0x153/0x460 [ 3406.731666] entry_SYSCALL_64_after_hwframe+0x44/0xa9 [ 3406.731669] RIP: 0033:0x7fc0152412c4 [ 3406.731673] Code: 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 8d 05 41 96 2d 00 8b 00 85 c0 75 13 b8 4b 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 3c f3 c3 66 90 53 89 fb 48 83 ec 10 e8 04 94 [ 3406.731675] RSP: 002b:00007ffc445f72f8 EFLAGS: 00000246 ORIG_RAX: 000000000000004b [ 3406.731679] RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 00007fc0152412c4 [ 3406.731681] RDX: 00007ffc445f7250 RSI: 00007ffc445f7250 RDI: 0000000000000003 [ 3406.731683] RBP: 0000000000000034 R08: 00007fc015515c40 R09: 0000000000000000 [ 3406.731685] R10: 0000000000000000 R11: 0000000000000246 R12: 00000000000001f4 [ 3406.731687] R13: 0000000051eb851f R14: 00007ffc445f73f6 R15: 0000557f33ad1930 [ 3406.731690] ---[ end trace 698eba2a0467d312 ]---
I'm also slightly confused here because this test is for ext4 without journal (see even "EXT4-fs (nvme0n1p2): mounted filesystem without journal") but for some reason it seems that this still goes to the journal?
Does this also fail on 4.19? The same patch is here and in 4.14 as well.
thanks,
greg k-h
On Wed, Jan 09, 2019 at 05:44:55PM +0100, Greg Kroah-Hartman wrote:
On Mon, Jan 07, 2019 at 04:56:06PM -0500, Sasha Levin wrote:
On Mon, Jan 07, 2019 at 01:31:56PM +0100, Greg Kroah-Hartman wrote:
4.20-stable review patch. If anyone has any objections, please let me know.
From: Theodore Ts'o tytso@mit.edu
commit 18f2c4fcebf2582f96cbd5f2238f4f354a0e4847 upstream.
If the file system has been shut down or is read-only, then ext4_write_inode() needs to bail out early.
Also use jbd2_complete_transaction() instead of ext4_force_commit() so we only force a commit if it is needed.
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 | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
--- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -5400,9 +5400,13 @@ int ext4_write_inode(struct inode *inode { int err;
- if (WARN_ON_ONCE(current->flags & PF_MEMALLOC))
if (WARN_ON_ONCE(current->flags & PF_MEMALLOC) ||
sb_rdonly(inode->i_sb))
return 0;
if (unlikely(ext4_forced_shutdown(EXT4_SB(inode->i_sb))))
return -EIO;
if (EXT4_SB(inode->i_sb)->s_journal) { if (ext4_journal_current_handle()) { jbd_debug(1, "called recursively, non-PF_MEMALLOC!\n");
@@ -5418,7 +5422,8 @@ int ext4_write_inode(struct inode *inode if (wbc->sync_mode != WB_SYNC_ALL || wbc->for_sync) return 0;
err = ext4_force_commit(inode->i_sb);
err = jbd2_complete_transaction(EXT4_SB(inode->i_sb)->s_journal,
} else { struct ext4_iloc iloc;EXT4_I(inode)->i_sync_tid);
Hi Ted,
I'm not sure if this patch is the culprit or no, but testing with xfstests on 4.20.1-rc1 started failing generic/390 with:
[ 3405.656893] run fstests generic/390 at 2019-01-07 20:26:55 [ 3406.524380] EXT4-fs (nvme0n1p2): mounted filesystem without journal. Opts: acl,user_xattr [ 3406.731410] WARNING: CPU: 0 PID: 93128 at fs/ext4/ext4_jbd2.c:53 ext4_journal_check_start+0x121/0x190 [ 3406.731418] CPU: 0 PID: 93128 Comm: fsstress Tainted: G B W 4.20.1-rc1+ #1 [ 3406.731420] Hardware name: Microsoft Corporation Virtual Machine/Virtual Machine, BIOS 090007 05/18/2018 [ 3406.731425] RIP: 0010:ext4_journal_check_start+0x121/0x190 [ 3406.731430] Code: 4d 85 e4 74 1e 4c 89 e2 48 b8 00 00 00 00 00 fc ff df 48 c1 ea 03 80 3c 02 00 75 4f 41 f6 04 24 02 75 0b 31 c0 5b 41 5c 5d c3 <0f> 0b eb ab 48 c7 c1 60 b4 f9 a4 ba 3d 00 00 00 48 c7 c6 a0 b8 f9 [ 3406.731432] RSP: 0018:ffff888f30317648 EFLAGS: 00010246 [ 3406.731437] RAX: 0000000000000000 RBX: ffff888ee6ce12c8 RCX: 000000000000000c [ 3406.731440] RDX: 1ffff111dcd9c2a0 RSI: 0000000000000b33 RDI: ffff888ee6ce1500 [ 3406.731442] RBP: ffff888f30317658 R08: 0000000000000000 R09: ffffed11db5f01a7 [ 3406.731444] R10: 0000000000000001 R11: ffffed11db5f01a6 R12: ffff888ee6ce2ee8 [ 3406.731447] R13: dffffc0000000000 R14: 0000000000000000 R15: ffff888f303178e0 [ 3406.731450] FS: 00007fc015d5cb80(0000) GS:ffff888f6b800000(0000) knlGS:0000000000000000 [ 3406.731452] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 3406.731455] CR2: 0000557f34651000 CR3: 0000000f2c722000 CR4: 00000000003406f0 [ 3406.731459] Call Trace: [ 3406.731465] __ext4_journal_start_sb+0x95/0x380 [ 3406.731479] ext4_writepages+0x10e1/0x3170 [ 3406.731567] do_writepages+0xc7/0x120 [ 3406.731577] __filemap_fdatawrite_range+0x313/0x470 [ 3406.731594] file_write_and_wait_range+0x7c/0xd0 [ 3406.731598] __generic_file_fsync+0x6c/0x180 [ 3406.731601] ext4_sync_file+0x60b/0xf90 [ 3406.731626] vfs_fsync_range+0xf5/0x210 [ 3406.731630] do_fsync+0x3d/0x70 [ 3406.731634] __x64_sys_fdatasync+0x36/0x50 [ 3406.731638] do_syscall_64+0x153/0x460 [ 3406.731666] entry_SYSCALL_64_after_hwframe+0x44/0xa9 [ 3406.731669] RIP: 0033:0x7fc0152412c4 [ 3406.731673] Code: 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 8d 05 41 96 2d 00 8b 00 85 c0 75 13 b8 4b 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 3c f3 c3 66 90 53 89 fb 48 83 ec 10 e8 04 94 [ 3406.731675] RSP: 002b:00007ffc445f72f8 EFLAGS: 00000246 ORIG_RAX: 000000000000004b [ 3406.731679] RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 00007fc0152412c4 [ 3406.731681] RDX: 00007ffc445f7250 RSI: 00007ffc445f7250 RDI: 0000000000000003 [ 3406.731683] RBP: 0000000000000034 R08: 00007fc015515c40 R09: 0000000000000000 [ 3406.731685] R10: 0000000000000000 R11: 0000000000000246 R12: 00000000000001f4 [ 3406.731687] R13: 0000000051eb851f R14: 00007ffc445f73f6 R15: 0000557f33ad1930 [ 3406.731690] ---[ end trace 698eba2a0467d312 ]---
I'm also slightly confused here because this test is for ext4 without journal (see even "EXT4-fs (nvme0n1p2): mounted filesystem without journal") but for some reason it seems that this still goes to the journal?
Does this also fail on 4.19? The same patch is here and in 4.14 as well.
I'm seeing a failure with this config only on 4.20.
-- Thanks, Sasha
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lukas Wunner lukas@wunner.de
commit e82b0b3828451c1cd331d9f304c6078fcd43b62e upstream.
If a DMA transfer finishes orderly right when spi_transfer_one_message() determines that it has timed out, the callbacks bcm2835_spi_dma_done() and bcm2835_spi_handle_err() race to call dmaengine_terminate_all(), potentially leading to double termination.
Prevent by atomically changing the dma_pending flag before calling dmaengine_terminate_all().
Signed-off-by: Lukas Wunner lukas@wunner.de Fixes: 3ecd37edaa2a ("spi: bcm2835: enable dma modes for transfers meeting certain conditions") Cc: stable@vger.kernel.org # v4.2+ Cc: Mathias Duckeck m.duckeck@kunbus.de Cc: Frank Pavlic f.pavlic@kunbus.de Cc: Martin Sperl kernel@martin.sperl.org Cc: Noralf Trønnes noralf@tronnes.org Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/spi/spi-bcm2835.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
--- a/drivers/spi/spi-bcm2835.c +++ b/drivers/spi/spi-bcm2835.c @@ -233,10 +233,9 @@ static void bcm2835_spi_dma_done(void *d * is called the tx-dma must have finished - can't get to this * situation otherwise... */ - dmaengine_terminate_all(master->dma_tx); - - /* mark as no longer pending */ - bs->dma_pending = 0; + if (cmpxchg(&bs->dma_pending, true, false)) { + dmaengine_terminate_all(master->dma_tx); + }
/* and mark as completed */; complete(&master->xfer_completion); @@ -617,10 +616,9 @@ static void bcm2835_spi_handle_err(struc struct bcm2835_spi *bs = spi_master_get_devdata(master);
/* if an error occurred and we have an active dma, then terminate */ - if (bs->dma_pending) { + if (cmpxchg(&bs->dma_pending, true, false)) { dmaengine_terminate_all(master->dma_tx); dmaengine_terminate_all(master->dma_rx); - bs->dma_pending = 0; } /* and reset */ bcm2835_spi_reset_hw(master);
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lukas Wunner lukas@wunner.de
commit dbc944115eed48af110646992893dc43321368d8 upstream.
If submission of a DMA TX transfer succeeds but submission of the corresponding RX transfer does not, the BCM2835 SPI driver terminates the TX transfer but neglects to reset the dma_pending flag to false.
Thus, if the next transfer uses interrupt mode (because it is shorter than BCM2835_SPI_DMA_MIN_LENGTH) and runs into a timeout, dmaengine_terminate_all() will be called both for TX (once more) and for RX (which was never started in the first place). Fix it.
Signed-off-by: Lukas Wunner lukas@wunner.de Fixes: 3ecd37edaa2a ("spi: bcm2835: enable dma modes for transfers meeting certain conditions") Cc: stable@vger.kernel.org # v4.2+ Cc: Mathias Duckeck m.duckeck@kunbus.de Cc: Frank Pavlic f.pavlic@kunbus.de Cc: Martin Sperl kernel@martin.sperl.org Cc: Noralf Trønnes noralf@tronnes.org Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/spi/spi-bcm2835.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/spi/spi-bcm2835.c +++ b/drivers/spi/spi-bcm2835.c @@ -341,6 +341,7 @@ static int bcm2835_spi_transfer_one_dma( if (ret) { /* need to reset on errors */ dmaengine_terminate_all(master->dma_tx); + bs->dma_pending = false; bcm2835_spi_reset_hw(master); return ret; }
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lukas Wunner lukas@wunner.de
commit 56c1723426d3cfd4723bfbfce531d7b38bae6266 upstream.
The IRQ handler bcm2835_spi_interrupt() first reads as much as possible from the RX FIFO, then writes as much as possible to the TX FIFO. Afterwards it decides whether the transfer is finished by checking if the TX FIFO is empty.
If very few bytes were written to the TX FIFO, they may already have been transmitted by the time the FIFO's emptiness is checked. As a result, the transfer will be declared finished and the chip will be reset without reading the corresponding received bytes from the RX FIFO.
The odds of this happening increase with a high clock frequency (such that the TX FIFO drains quickly) and either passing "threadirqs" on the command line or enabling CONFIG_PREEMPT_RT_BASE (such that the IRQ handler may be preempted between filling the TX FIFO and checking its emptiness).
Fix by instead checking whether rx_len has reached zero, which means that the transfer has been received in full. This is also more efficient as it avoids one bus read access per interrupt. Note that bcm2835_spi_transfer_one_poll() likewise uses rx_len to determine whether the transfer has finished.
Signed-off-by: Lukas Wunner lukas@wunner.de Fixes: e34ff011c70e ("spi: bcm2835: move to the transfer_one driver model") Cc: stable@vger.kernel.org # v4.1+ Cc: Mathias Duckeck m.duckeck@kunbus.de Cc: Frank Pavlic f.pavlic@kunbus.de Cc: Martin Sperl kernel@martin.sperl.org Cc: Noralf Trønnes noralf@tronnes.org Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/spi/spi-bcm2835.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
--- a/drivers/spi/spi-bcm2835.c +++ b/drivers/spi/spi-bcm2835.c @@ -155,8 +155,7 @@ static irqreturn_t bcm2835_spi_interrupt /* Write as many bytes as possible to FIFO */ bcm2835_wr_fifo(bs);
- /* based on flags decide if we can finish the transfer */ - if (bcm2835_rd(bs, BCM2835_SPI_CS) & BCM2835_SPI_CS_DONE) { + if (!bs->rx_len) { /* Transfer complete - reset SPI HW */ bcm2835_spi_reset_hw(master); /* wake up the framework */
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Jonker jbx9999@hotmail.com
commit 8b19faf6fae2867e2c177212c541e8ae36aa4d32 upstream.
Fix typo in common_clk_branches. Make spdif_pre parent of spdif_frac.
Fixes: 667464208989 ("clk: rockchip: include downstream muxes into fractional dividers") Cc: stable@vger.kernel.org Signed-off-by: Johan Jonker jbx9999@hotmail.com Acked-by: Elaine Zhang zhangqing@rock-chips.com Signed-off-by: Heiko Stuebner heiko@sntech.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/clk/rockchip/clk-rk3188.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/clk/rockchip/clk-rk3188.c +++ b/drivers/clk/rockchip/clk-rk3188.c @@ -382,7 +382,7 @@ static struct rockchip_clk_branch common COMPOSITE_NOMUX(0, "spdif_pre", "i2s_src", 0, RK2928_CLKSEL_CON(5), 0, 7, DFLAGS, RK2928_CLKGATE_CON(0), 13, GFLAGS), - COMPOSITE_FRACMUX(0, "spdif_frac", "spdif_pll", CLK_SET_RATE_PARENT, + COMPOSITE_FRACMUX(0, "spdif_frac", "spdif_pre", CLK_SET_RATE_PARENT, RK2928_CLKSEL_CON(9), 0, RK2928_CLKGATE_CON(0), 14, GFLAGS, &common_spdif_fracmux),
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jernej Skrabec jernej.skrabec@siol.net
commit 65b6657672388b72822e0367f06d41c1e3ffb5bb upstream.
Allwinner H6 SoC has multiplier N range between 1 and 254. Since parent rate is 24MHz, intermediate result when calculating final rate easily overflows 32 bit variable.
Because of that, introduce function for calculating clock rate which uses 64 bit variable for intermediate result.
Fixes: 6174a1e24b0d ("clk: sunxi-ng: Add N-M-factor clock support") Fixes: ee28648cb2b4 ("clk: sunxi-ng: Remove the use of rational computations")
CC: stable@vger.kernel.org Signed-off-by: Jernej Skrabec jernej.skrabec@siol.net Signed-off-by: Maxime Ripard maxime.ripard@bootlin.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/clk/sunxi-ng/ccu_nm.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-)
--- a/drivers/clk/sunxi-ng/ccu_nm.c +++ b/drivers/clk/sunxi-ng/ccu_nm.c @@ -19,6 +19,17 @@ struct _ccu_nm { unsigned long m, min_m, max_m; };
+static unsigned long ccu_nm_calc_rate(unsigned long parent, + unsigned long n, unsigned long m) +{ + u64 rate = parent; + + rate *= n; + do_div(rate, m); + + return rate; +} + static void ccu_nm_find_best(unsigned long parent, unsigned long rate, struct _ccu_nm *nm) { @@ -28,7 +39,8 @@ static void ccu_nm_find_best(unsigned lo
for (_n = nm->min_n; _n <= nm->max_n; _n++) { for (_m = nm->min_m; _m <= nm->max_m; _m++) { - unsigned long tmp_rate = parent * _n / _m; + unsigned long tmp_rate = ccu_nm_calc_rate(parent, + _n, _m);
if (tmp_rate > rate) continue; @@ -100,7 +112,7 @@ static unsigned long ccu_nm_recalc_rate( if (ccu_sdm_helper_is_enabled(&nm->common, &nm->sdm)) rate = ccu_sdm_helper_read_rate(&nm->common, &nm->sdm, m, n); else - rate = parent_rate * n / m; + rate = ccu_nm_calc_rate(parent_rate, n, m);
if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV) rate /= nm->fixed_post_div; @@ -149,7 +161,7 @@ static long ccu_nm_round_rate(struct clk _nm.max_m = nm->m.max ?: 1 << nm->m.width;
ccu_nm_find_best(*parent_rate, rate, &_nm); - rate = *parent_rate * _nm.n / _nm.m; + rate = ccu_nm_calc_rate(*parent_rate, _nm.n, _nm.m);
if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV) rate /= nm->fixed_post_div;
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wenwen Wang wang6495@umn.edu
commit 7172122be6a4712d699da4d261f92aa5ab3a78b8 upstream.
In crypto_alloc_context(), a DMA pool is allocated through dma_pool_alloc() to hold the crypto context. The meta data of the DMA pool, including the pool used for the allocation 'ndev->ctx_pool' and the base address of the DMA pool used by the device 'dma', are then stored to the beginning of the pool. These meta data are eventually used in crypto_free_context() to free the DMA pool through dma_pool_free(). However, given that the DMA pool can also be accessed by the device, a malicious device can modify these meta data, especially when the device is controlled to deploy an attack. This can cause an unexpected DMA pool free failure.
To avoid the above issue, this patch introduces a new structure crypto_ctx_hdr and a new field chdr in the structure nitrox_crypto_ctx hold the meta data information of the DMA pool after the allocation. Note that the original structure ctx_hdr is not changed to ensure the compatibility.
Cc: stable@vger.kernel.org Signed-off-by: Wenwen Wang wang6495@umn.edu Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/crypto/cavium/nitrox/nitrox_algs.c | 12 +++++++----- drivers/crypto/cavium/nitrox/nitrox_lib.c | 22 +++++++++++++++++----- drivers/crypto/cavium/nitrox/nitrox_req.h | 7 +++++++ 3 files changed, 31 insertions(+), 10 deletions(-)
--- a/drivers/crypto/cavium/nitrox/nitrox_algs.c +++ b/drivers/crypto/cavium/nitrox/nitrox_algs.c @@ -73,7 +73,7 @@ static int flexi_aes_keylen(int keylen) static int nitrox_skcipher_init(struct crypto_skcipher *tfm) { struct nitrox_crypto_ctx *nctx = crypto_skcipher_ctx(tfm); - void *fctx; + struct crypto_ctx_hdr *chdr;
/* get the first device */ nctx->ndev = nitrox_get_first_device(); @@ -81,12 +81,14 @@ static int nitrox_skcipher_init(struct c return -ENODEV;
/* allocate nitrox crypto context */ - fctx = crypto_alloc_context(nctx->ndev); - if (!fctx) { + chdr = crypto_alloc_context(nctx->ndev); + if (!chdr) { nitrox_put_device(nctx->ndev); return -ENOMEM; } - nctx->u.ctx_handle = (uintptr_t)fctx; + nctx->chdr = chdr; + nctx->u.ctx_handle = (uintptr_t)((u8 *)chdr->vaddr + + sizeof(struct ctx_hdr)); crypto_skcipher_set_reqsize(tfm, crypto_skcipher_reqsize(tfm) + sizeof(struct nitrox_kcrypt_request)); return 0; @@ -102,7 +104,7 @@ static void nitrox_skcipher_exit(struct
memset(&fctx->crypto, 0, sizeof(struct crypto_keys)); memset(&fctx->auth, 0, sizeof(struct auth_keys)); - crypto_free_context((void *)fctx); + crypto_free_context((void *)nctx->chdr); } nitrox_put_device(nctx->ndev);
--- a/drivers/crypto/cavium/nitrox/nitrox_lib.c +++ b/drivers/crypto/cavium/nitrox/nitrox_lib.c @@ -158,12 +158,19 @@ static void destroy_crypto_dma_pool(stru void *crypto_alloc_context(struct nitrox_device *ndev) { struct ctx_hdr *ctx; + struct crypto_ctx_hdr *chdr; void *vaddr; dma_addr_t dma;
+ chdr = kmalloc(sizeof(*chdr), GFP_KERNEL); + if (!chdr) + return NULL; + vaddr = dma_pool_zalloc(ndev->ctx_pool, GFP_KERNEL, &dma); - if (!vaddr) + if (!vaddr) { + kfree(chdr); return NULL; + }
/* fill meta data */ ctx = vaddr; @@ -171,7 +178,11 @@ void *crypto_alloc_context(struct nitrox ctx->dma = dma; ctx->ctx_dma = dma + sizeof(struct ctx_hdr);
- return ((u8 *)vaddr + sizeof(struct ctx_hdr)); + chdr->pool = ndev->ctx_pool; + chdr->dma = dma; + chdr->vaddr = vaddr; + + return chdr; }
/** @@ -180,13 +191,14 @@ void *crypto_alloc_context(struct nitrox */ void crypto_free_context(void *ctx) { - struct ctx_hdr *ctxp; + struct crypto_ctx_hdr *ctxp;
if (!ctx) return;
- ctxp = (struct ctx_hdr *)((u8 *)ctx - sizeof(struct ctx_hdr)); - dma_pool_free(ctxp->pool, ctxp, ctxp->dma); + ctxp = ctx; + dma_pool_free(ctxp->pool, ctxp->vaddr, ctxp->dma); + kfree(ctxp); }
/** --- a/drivers/crypto/cavium/nitrox/nitrox_req.h +++ b/drivers/crypto/cavium/nitrox/nitrox_req.h @@ -181,12 +181,19 @@ struct flexi_crypto_context { struct auth_keys auth; };
+struct crypto_ctx_hdr { + struct dma_pool *pool; + dma_addr_t dma; + void *vaddr; +}; + struct nitrox_crypto_ctx { struct nitrox_device *ndev; union { u64 ctx_handle; struct flexi_crypto_context *fctx; } u; + struct crypto_ctx_hdr *chdr; };
struct nitrox_kcrypt_request {
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Atul Gupta atul.gupta@chelsio.com
commit c35828ea906a7c76632a0211e59c392903cd4615 upstream.
Immediate packets sent to hardware should include the work request length in calculating the flits. WR occupy one flit and if not accounted result in invalid request which stalls the HW queue.
Cc: stable@vger.kernel.org Signed-off-by: Atul Gupta atul.gupta@chelsio.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/crypto/chelsio/chcr_ipsec.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
--- a/drivers/crypto/chelsio/chcr_ipsec.c +++ b/drivers/crypto/chelsio/chcr_ipsec.c @@ -303,7 +303,10 @@ static bool chcr_ipsec_offload_ok(struct
static inline int is_eth_imm(const struct sk_buff *skb, unsigned int kctx_len) { - int hdrlen = sizeof(struct chcr_ipsec_req) + kctx_len; + int hdrlen; + + hdrlen = sizeof(struct fw_ulptx_wr) + + sizeof(struct chcr_ipsec_req) + kctx_len;
hdrlen += sizeof(struct cpl_tx_pkt); if (skb->len <= MAX_IMM_TX_PKT_LEN - hdrlen)
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Eremin-Solenikov dbaryshkov@gmail.com
commit 7da66670775d201f633577f5b15a4bbeebaaa2b0 upstream.
Add AES128/192/256-CFB testvectors from NIST SP800-38A.
Signed-off-by: Dmitry Eremin-Solenikov dbaryshkov@gmail.com Cc: stable@vger.kernel.org Signed-off-by: Dmitry Eremin-Solenikov dbaryshkov@gmail.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- crypto/tcrypt.c | 5 +++ crypto/testmgr.c | 7 +++++ crypto/testmgr.h | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+)
--- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -1736,6 +1736,7 @@ static int do_test(const char *alg, u32 ret += tcrypt_test("ctr(aes)"); ret += tcrypt_test("rfc3686(ctr(aes))"); ret += tcrypt_test("ofb(aes)"); + ret += tcrypt_test("cfb(aes)"); break;
case 11: @@ -2060,6 +2061,10 @@ static int do_test(const char *alg, u32 speed_template_16_24_32); test_cipher_speed("ctr(aes)", DECRYPT, sec, NULL, 0, speed_template_16_24_32); + test_cipher_speed("cfb(aes)", ENCRYPT, sec, NULL, 0, + speed_template_16_24_32); + test_cipher_speed("cfb(aes)", DECRYPT, sec, NULL, 0, + speed_template_16_24_32); break;
case 201: --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -2691,6 +2691,13 @@ static const struct alg_test_desc alg_te } } }, { + .alg = "cfb(aes)", + .test = alg_test_skcipher, + .fips_allowed = 1, + .suite = { + .cipher = __VECS(aes_cfb_tv_template) + }, + }, { .alg = "chacha20", .test = alg_test_skcipher, .suite = { --- a/crypto/testmgr.h +++ b/crypto/testmgr.h @@ -11449,6 +11449,82 @@ static const struct cipher_testvec aes_c }, };
+static const struct cipher_testvec aes_cfb_tv_template[] = { + { /* From NIST SP800-38A */ + .key = "\x2b\x7e\x15\x16\x28\xae\xd2\xa6" + "\xab\xf7\x15\x88\x09\xcf\x4f\x3c", + .klen = 16, + .iv = "\x00\x01\x02\x03\x04\x05\x06\x07" + "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + .ptext = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96" + "\xe9\x3d\x7e\x11\x73\x93\x17\x2a" + "\xae\x2d\x8a\x57\x1e\x03\xac\x9c" + "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51" + "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11" + "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef" + "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17" + "\xad\x2b\x41\x7b\xe6\x6c\x37\x10", + .ctext = "\x3b\x3f\xd9\x2e\xb7\x2d\xad\x20" + "\x33\x34\x49\xf8\xe8\x3c\xfb\x4a" + "\xc8\xa6\x45\x37\xa0\xb3\xa9\x3f" + "\xcd\xe3\xcd\xad\x9f\x1c\xe5\x8b" + "\x26\x75\x1f\x67\xa3\xcb\xb1\x40" + "\xb1\x80\x8c\xf1\x87\xa4\xf4\xdf" + "\xc0\x4b\x05\x35\x7c\x5d\x1c\x0e" + "\xea\xc4\xc6\x6f\x9f\xf7\xf2\xe6", + .len = 64, + }, { + .key = "\x8e\x73\xb0\xf7\xda\x0e\x64\x52" + "\xc8\x10\xf3\x2b\x80\x90\x79\xe5" + "\x62\xf8\xea\xd2\x52\x2c\x6b\x7b", + .klen = 24, + .iv = "\x00\x01\x02\x03\x04\x05\x06\x07" + "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + .ptext = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96" + "\xe9\x3d\x7e\x11\x73\x93\x17\x2a" + "\xae\x2d\x8a\x57\x1e\x03\xac\x9c" + "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51" + "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11" + "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef" + "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17" + "\xad\x2b\x41\x7b\xe6\x6c\x37\x10", + .ctext = "\xcd\xc8\x0d\x6f\xdd\xf1\x8c\xab" + "\x34\xc2\x59\x09\xc9\x9a\x41\x74" + "\x67\xce\x7f\x7f\x81\x17\x36\x21" + "\x96\x1a\x2b\x70\x17\x1d\x3d\x7a" + "\x2e\x1e\x8a\x1d\xd5\x9b\x88\xb1" + "\xc8\xe6\x0f\xed\x1e\xfa\xc4\xc9" + "\xc0\x5f\x9f\x9c\xa9\x83\x4f\xa0" + "\x42\xae\x8f\xba\x58\x4b\x09\xff", + .len = 64, + }, { + .key = "\x60\x3d\xeb\x10\x15\xca\x71\xbe" + "\x2b\x73\xae\xf0\x85\x7d\x77\x81" + "\x1f\x35\x2c\x07\x3b\x61\x08\xd7" + "\x2d\x98\x10\xa3\x09\x14\xdf\xf4", + .klen = 32, + .iv = "\x00\x01\x02\x03\x04\x05\x06\x07" + "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + .ptext = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96" + "\xe9\x3d\x7e\x11\x73\x93\x17\x2a" + "\xae\x2d\x8a\x57\x1e\x03\xac\x9c" + "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51" + "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11" + "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef" + "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17" + "\xad\x2b\x41\x7b\xe6\x6c\x37\x10", + .ctext = "\xdc\x7e\x84\xbf\xda\x79\x16\x4b" + "\x7e\xcd\x84\x86\x98\x5d\x38\x60" + "\x39\xff\xed\x14\x3b\x28\xb1\xc8" + "\x32\x11\x3c\x63\x31\xe5\x40\x7b" + "\xdf\x10\x13\x24\x15\xe5\x4b\x92" + "\xa1\x3e\xd0\xa8\x26\x7a\xe2\xf9" + "\x75\xa3\x85\x74\x1a\xb9\xce\xf8" + "\x20\x31\x62\x3d\x55\xb1\xe4\x71", + .len = 64, + }, +}; + static const struct aead_testvec hmac_md5_ecb_cipher_null_enc_tv_template[] = { { /* Input data from RFC 2410 Case 1 */ #ifdef __LITTLE_ENDIAN
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Eremin-Solenikov dbaryshkov@gmail.com
commit fa4600734b74f74d9169c3015946d4722f8bcf79 upstream.
crypto_cfb_decrypt_segment() incorrectly XOR'ed generated keystream with IV, rather than with data stream, resulting in incorrect decryption. Test vectors will be added in the next patch.
Signed-off-by: Dmitry Eremin-Solenikov dbaryshkov@gmail.com Cc: stable@vger.kernel.org Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- crypto/cfb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/crypto/cfb.c +++ b/crypto/cfb.c @@ -144,7 +144,7 @@ static int crypto_cfb_decrypt_segment(st
do { crypto_cfb_encrypt_one(tfm, iv, dst); - crypto_xor(dst, iv, bsize); + crypto_xor(dst, src, bsize); iv = src;
src += bsize;
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tejun Heo tj@kernel.org
commit e9d81a1bc2c48ea9782e3e8b53875f419766ef47 upstream.
CSS_TASK_ITER_PROCS implements process-only iteration by making css_task_iter_advance() skip tasks which aren't threadgroup leaders; however, when an iteration is started css_task_iter_start() calls the inner helper function css_task_iter_advance_css_set() instead of css_task_iter_advance(). As the helper doesn't have the skip logic, when the first task to visit is a non-leader thread, it doesn't get skipped correctly as shown in the following example.
# ps -L 2030 PID LWP TTY STAT TIME COMMAND 2030 2030 pts/0 Sl+ 0:00 ./test-thread 2030 2031 pts/0 Sl+ 0:00 ./test-thread # mkdir -p /sys/fs/cgroup/x/a/b # echo threaded > /sys/fs/cgroup/x/a/cgroup.type # echo threaded > /sys/fs/cgroup/x/a/b/cgroup.type # echo 2030 > /sys/fs/cgroup/x/a/cgroup.procs # cat /sys/fs/cgroup/x/a/cgroup.threads 2030 2031 # cat /sys/fs/cgroup/x/cgroup.procs 2030 # echo 2030 > /sys/fs/cgroup/x/a/b/cgroup.threads # cat /sys/fs/cgroup/x/cgroup.procs 2031 2030
The last read of cgroup.procs is incorrectly showing non-leader 2031 in cgroup.procs output.
This can be fixed by updating css_task_iter_advance() to handle the first advance and css_task_iters_tart() to call css_task_iter_advance() instead of the inner helper. After the fix, the same commands result in the following (correct) result:
# ps -L 2062 PID LWP TTY STAT TIME COMMAND 2062 2062 pts/0 Sl+ 0:00 ./test-thread 2062 2063 pts/0 Sl+ 0:00 ./test-thread # mkdir -p /sys/fs/cgroup/x/a/b # echo threaded > /sys/fs/cgroup/x/a/cgroup.type # echo threaded > /sys/fs/cgroup/x/a/b/cgroup.type # echo 2062 > /sys/fs/cgroup/x/a/cgroup.procs # cat /sys/fs/cgroup/x/a/cgroup.threads 2062 2063 # cat /sys/fs/cgroup/x/cgroup.procs 2062 # echo 2062 > /sys/fs/cgroup/x/a/b/cgroup.threads # cat /sys/fs/cgroup/x/cgroup.procs 2062
Signed-off-by: Tejun Heo tj@kernel.org Reported-by: "Michael Kerrisk (man-pages)" mtk.manpages@gmail.com Fixes: 8cfd8147df67 ("cgroup: implement cgroup v2 thread support") Cc: stable@vger.kernel.org # v4.14+ Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- kernel/cgroup/cgroup.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-)
--- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -4202,20 +4202,25 @@ static void css_task_iter_advance(struct
lockdep_assert_held(&css_set_lock); repeat: - /* - * Advance iterator to find next entry. cset->tasks is consumed - * first and then ->mg_tasks. After ->mg_tasks, we move onto the - * next cset. - */ - next = it->task_pos->next; - - if (next == it->tasks_head) - next = it->mg_tasks_head->next; - - if (next == it->mg_tasks_head) + if (it->task_pos) { + /* + * Advance iterator to find next entry. cset->tasks is + * consumed first and then ->mg_tasks. After ->mg_tasks, + * we move onto the next cset. + */ + next = it->task_pos->next; + + if (next == it->tasks_head) + next = it->mg_tasks_head->next; + + if (next == it->mg_tasks_head) + css_task_iter_advance_css_set(it); + else + it->task_pos = next; + } else { + /* called from start, proceed to the first cset */ css_task_iter_advance_css_set(it); - else - it->task_pos = next; + }
/* if PROCS, skip over tasks which aren't group leaders */ if ((it->flags & CSS_TASK_ITER_PROCS) && it->task_pos && @@ -4255,7 +4260,7 @@ void css_task_iter_start(struct cgroup_s
it->cset_head = it->cset_pos;
- css_task_iter_advance_css_set(it); + css_task_iter_advance(it);
spin_unlock_irq(&css_set_lock); }
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Todd Kjos tkjos@android.com
commit 80cd795630d6526ba729a089a435bf74a57af927 upstream.
44d8047f1d8 ("binder: use standard functions to allocate fds") exposed a pre-existing issue in the binder driver.
fdget() is used in ksys_ioctl() as a performance optimization. One of the rules associated with fdget() is that ksys_close() must not be called between the fdget() and the fdput(). There is a case where this requirement is not met in the binder driver which results in the reference count dropping to 0 when the device is still in use. This can result in use-after-free or other issues.
If userpace has passed a file-descriptor for the binder driver using a BINDER_TYPE_FDA object, then kys_close() is called on it when handling a binder_ioctl(BC_FREE_BUFFER) command. This violates the assumptions for using fdget().
The problem is fixed by deferring the close using task_work_add(). A new variant of __close_fd() was created that returns a struct file with a reference. The fput() is deferred instead of using ksys_close().
Fixes: 44d8047f1d87a ("binder: use standard functions to allocate fds") Suggested-by: Al Viro viro@zeniv.linux.org.uk Signed-off-by: Todd Kjos tkjos@google.com Cc: stable stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/android/binder.c | 63 +++++++++++++++++++++++++++++++++++++++++++++-- fs/file.c | 29 +++++++++++++++++++++ include/linux/fdtable.h | 1 3 files changed, 91 insertions(+), 2 deletions(-)
--- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -72,6 +72,7 @@ #include <linux/spinlock.h> #include <linux/ratelimit.h> #include <linux/syscalls.h> +#include <linux/task_work.h>
#include <uapi/linux/android/binder.h>
@@ -2160,6 +2161,64 @@ static bool binder_validate_fixup(struct return (fixup_offset >= last_min_offset); }
+/** + * struct binder_task_work_cb - for deferred close + * + * @twork: callback_head for task work + * @fd: fd to close + * + * Structure to pass task work to be handled after + * returning from binder_ioctl() via task_work_add(). + */ +struct binder_task_work_cb { + struct callback_head twork; + struct file *file; +}; + +/** + * binder_do_fd_close() - close list of file descriptors + * @twork: callback head for task work + * + * It is not safe to call ksys_close() during the binder_ioctl() + * function if there is a chance that binder's own file descriptor + * might be closed. This is to meet the requirements for using + * fdget() (see comments for __fget_light()). Therefore use + * task_work_add() to schedule the close operation once we have + * returned from binder_ioctl(). This function is a callback + * for that mechanism and does the actual ksys_close() on the + * given file descriptor. + */ +static void binder_do_fd_close(struct callback_head *twork) +{ + struct binder_task_work_cb *twcb = container_of(twork, + struct binder_task_work_cb, twork); + + fput(twcb->file); + kfree(twcb); +} + +/** + * binder_deferred_fd_close() - schedule a close for the given file-descriptor + * @fd: file-descriptor to close + * + * See comments in binder_do_fd_close(). This function is used to schedule + * a file-descriptor to be closed after returning from binder_ioctl(). + */ +static void binder_deferred_fd_close(int fd) +{ + struct binder_task_work_cb *twcb; + + twcb = kzalloc(sizeof(*twcb), GFP_KERNEL); + if (!twcb) + return; + init_task_work(&twcb->twork, binder_do_fd_close); + __close_fd_get_file(fd, &twcb->file); + if (twcb->file) + task_work_add(current, &twcb->twork, true); + else + kfree(twcb); +} + static void binder_transaction_buffer_release(struct binder_proc *proc, struct binder_buffer *buffer, binder_size_t *failed_at) @@ -2299,7 +2358,7 @@ static void binder_transaction_buffer_re } fd_array = (u32 *)(parent_buffer + (uintptr_t)fda->parent_offset); for (fd_index = 0; fd_index < fda->num_fds; fd_index++) - ksys_close(fd_array[fd_index]); + binder_deferred_fd_close(fd_array[fd_index]); } break; default: pr_err("transaction release %d bad object type %x\n", @@ -3912,7 +3971,7 @@ static int binder_apply_fd_fixups(struct } else if (ret) { u32 *fdp = (u32 *)(t->buffer->data + fixup->offset);
- ksys_close(*fdp); + binder_deferred_fd_close(*fdp); } list_del(&fixup->fixup_entry); kfree(fixup); --- a/fs/file.c +++ b/fs/file.c @@ -640,6 +640,35 @@ out_unlock: } EXPORT_SYMBOL(__close_fd); /* for ksys_close() */
+/* + * variant of __close_fd that gets a ref on the file for later fput + */ +int __close_fd_get_file(unsigned int fd, struct file **res) +{ + struct files_struct *files = current->files; + struct file *file; + struct fdtable *fdt; + + spin_lock(&files->file_lock); + fdt = files_fdtable(files); + if (fd >= fdt->max_fds) + goto out_unlock; + file = fdt->fd[fd]; + if (!file) + goto out_unlock; + rcu_assign_pointer(fdt->fd[fd], NULL); + __put_unused_fd(files, fd); + spin_unlock(&files->file_lock); + get_file(file); + *res = file; + return filp_close(file, files); + +out_unlock: + spin_unlock(&files->file_lock); + *res = NULL; + return -ENOENT; +} + void do_close_on_exec(struct files_struct *files) { unsigned i; --- a/include/linux/fdtable.h +++ b/include/linux/fdtable.h @@ -121,6 +121,7 @@ extern void __fd_install(struct files_st unsigned int fd, struct file *file); extern int __close_fd(struct files_struct *files, unsigned int fd); +extern int __close_fd_get_file(unsigned int fd, struct file **res);
extern struct kmem_cache *files_cachep;
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Macpaul Lin macpaul.lin@mediatek.com
commit eafb27fa5283599ce6c5492ea18cf636a28222bb upstream.
Mediatek Preloader is a proprietary embedded boot loader for loading Little Kernel and Linux into device DRAM.
This boot loader also handle firmware update. Mediatek Preloader will be enumerated as a virtual COM port when the device is connected to Windows or Linux OS via CDC-ACM class driver. When the USB enumeration has been done, Mediatek Preloader will send out handshake command "READY" to PC actively instead of waiting command from the download tool.
Since Linux 4.12, the commit "tty: reset termios state on device registration" (93857edd9829e144acb6c7e72d593f6e01aead66) causes Mediatek Preloader receiving some abnoraml command like "READYXX" as it sent. This will be recognized as an incorrect response. The behavior change also causes the download handshake fail. This change only affects subsequent connects if the reconnected device happens to get the same minor number.
By disabling the ECHO termios flag could avoid this problem. However, it cannot be done by user space configuration when download tool open /dev/ttyACM0. This is because the device running Mediatek Preloader will send handshake command "READY" immediately once the CDC-ACM driver is ready.
This patch wants to fix above problem by introducing "DISABLE_ECHO" property in driver_info. When Mediatek Preloader is connected, the CDC-ACM driver could disable ECHO flag in termios to avoid the problem.
Signed-off-by: Macpaul Lin macpaul.lin@mediatek.com Cc: stable@vger.kernel.org Reviewed-by: Johan Hovold johan@kernel.org Acked-by: Oliver Neukum oneukum@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/class/cdc-acm.c | 10 ++++++++++ drivers/usb/class/cdc-acm.h | 1 + 2 files changed, 11 insertions(+)
--- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -581,6 +581,13 @@ static int acm_tty_install(struct tty_dr if (retval) goto error_init_termios;
+ /* + * Suppress initial echoing for some devices which might send data + * immediately after acm driver has been installed. + */ + if (acm->quirks & DISABLE_ECHO) + tty->termios.c_lflag &= ~ECHO; + tty->driver_data = acm;
return 0; @@ -1657,6 +1664,9 @@ static const struct usb_device_id acm_id { USB_DEVICE(0x0e8d, 0x0003), /* FIREFLY, MediaTek Inc; andrey.arapov@gmail.com */ .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ }, + { USB_DEVICE(0x0e8d, 0x2000), /* MediaTek Inc Preloader */ + .driver_info = DISABLE_ECHO, /* DISABLE ECHO in termios flag */ + }, { USB_DEVICE(0x0e8d, 0x3329), /* MediaTek Inc GPS */ .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ }, --- a/drivers/usb/class/cdc-acm.h +++ b/drivers/usb/class/cdc-acm.h @@ -140,3 +140,4 @@ struct acm { #define QUIRK_CONTROL_LINE_STATE BIT(6) #define CLEAR_HALT_CONDITIONS BIT(7) #define SEND_ZERO_PACKET BIT(8) +#define DISABLE_ECHO BIT(9)
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Anand Jain anand.jain@oracle.com
commit 0d228ece59a35a9b9e8ff0d40653234a6d90f61e upstream.
At the time of forced unmount we place the running replace to BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED state, so when the system comes back and expect the target device is missing.
Then let the replace state continue to be in BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED state instead of BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED as there isn't any matching scrub running as part of replace.
Fixes: e93c89c1aaaa ("Btrfs: add new sources for device replace code") CC: stable@vger.kernel.org # 4.4+ Signed-off-by: Anand Jain anand.jain@oracle.com Reviewed-by: David Sterba dsterba@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/btrfs/dev-replace.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/fs/btrfs/dev-replace.c +++ b/fs/btrfs/dev-replace.c @@ -884,6 +884,8 @@ int btrfs_resume_dev_replace_async(struc "cannot continue dev_replace, tgtdev is missing"); btrfs_info(fs_info, "you may cancel the operation after 'mount -o degraded'"); + dev_replace->replace_state = + BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED; btrfs_dev_replace_write_unlock(dev_replace); return 0; }
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Anand Jain anand.jain@oracle.com
commit 05c49e6bc1e8866ecfd674ebeeb58cdbff9145c2 upstream.
In a secnario where balance and replace co-exists as below,
- start balance - pause balance - start replace - reboot
and when system restarts, balance resumes first. Then the replace is attempted to restart but will fail as the EXCL_OP lock is already held by the balance. If so place the replace state back to BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED state.
Fixes: 010a47bde9420 ("btrfs: add proper safety check before resuming dev-replace") CC: stable@vger.kernel.org # 4.18+ Signed-off-by: Anand Jain anand.jain@oracle.com Reviewed-by: David Sterba dsterba@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/btrfs/dev-replace.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/fs/btrfs/dev-replace.c +++ b/fs/btrfs/dev-replace.c @@ -897,6 +897,10 @@ int btrfs_resume_dev_replace_async(struc * dev-replace to start anyway. */ if (test_and_set_bit(BTRFS_FS_EXCL_OP, &fs_info->flags)) { + btrfs_dev_replace_write_lock(dev_replace); + dev_replace->replace_state = + BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED; + btrfs_dev_replace_write_unlock(dev_replace); btrfs_info(fs_info, "cannot resume dev-replace, other exclusive operation running"); return 0;
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana fdmanana@suse.com
commit a5fb11429167ee6ddeeacc554efaf5776b36433a upstream.
When a transaction commit starts, it attempts to pause scrub and it blocks until the scrub is paused. So while the transaction is blocked waiting for scrub to pause, we can not do memory allocation with GFP_KERNEL from scrub, otherwise we risk getting into a deadlock with reclaim.
Checking for scrub pause requests is done early at the beginning of the while loop of scrub_stripe() and later in the loop, scrub_extent() and scrub_raid56_parity() are called, which in turn call scrub_pages() and scrub_pages_for_parity() respectively. These last two functions do memory allocations using GFP_KERNEL. Same problem could happen while scrubbing the super blocks, since it calls scrub_pages().
We also can not have any of the worker tasks, created by the scrub task, doing GFP_KERNEL allocations, because before pausing, the scrub task waits for all the worker tasks to complete (also done at scrub_stripe()).
So make sure GFP_NOFS is used for the memory allocations because at any time a scrub pause request can happen from another task that started to commit a transaction.
Fixes: 58c4e173847a ("btrfs: scrub: use GFP_KERNEL on the submission path") CC: stable@vger.kernel.org # 4.6+ Reviewed-by: Nikolay Borisov nborisov@suse.com Signed-off-by: Filipe Manana fdmanana@suse.com Reviewed-by: David Sterba dsterba@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/btrfs/scrub.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-)
--- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c @@ -322,6 +322,7 @@ static struct full_stripe_lock *insert_f struct rb_node *parent = NULL; struct full_stripe_lock *entry; struct full_stripe_lock *ret; + unsigned int nofs_flag;
lockdep_assert_held(&locks_root->lock);
@@ -339,8 +340,17 @@ static struct full_stripe_lock *insert_f } }
- /* Insert new lock */ + /* + * Insert new lock. + * + * We must use GFP_NOFS because the scrub task might be waiting for a + * worker task executing this function and in turn a transaction commit + * might be waiting the scrub task to pause (which needs to wait for all + * the worker tasks to complete before pausing). + */ + nofs_flag = memalloc_nofs_save(); ret = kmalloc(sizeof(*ret), GFP_KERNEL); + memalloc_nofs_restore(nofs_flag); if (!ret) return ERR_PTR(-ENOMEM); ret->logical = fstripe_logical; @@ -1620,8 +1630,19 @@ static int scrub_add_page_to_wr_bio(stru mutex_lock(&sctx->wr_lock); again: if (!sctx->wr_curr_bio) { + unsigned int nofs_flag; + + /* + * We must use GFP_NOFS because the scrub task might be waiting + * for a worker task executing this function and in turn a + * transaction commit might be waiting the scrub task to pause + * (which needs to wait for all the worker tasks to complete + * before pausing). + */ + nofs_flag = memalloc_nofs_save(); sctx->wr_curr_bio = kzalloc(sizeof(*sctx->wr_curr_bio), GFP_KERNEL); + memalloc_nofs_restore(nofs_flag); if (!sctx->wr_curr_bio) { mutex_unlock(&sctx->wr_lock); return -ENOMEM; @@ -3772,6 +3793,7 @@ int btrfs_scrub_dev(struct btrfs_fs_info struct scrub_ctx *sctx; int ret; struct btrfs_device *dev; + unsigned int nofs_flag;
if (btrfs_fs_closing(fs_info)) return -EINVAL; @@ -3875,6 +3897,16 @@ int btrfs_scrub_dev(struct btrfs_fs_info atomic_inc(&fs_info->scrubs_running); mutex_unlock(&fs_info->scrub_lock);
+ /* + * In order to avoid deadlock with reclaim when there is a transaction + * trying to pause scrub, make sure we use GFP_NOFS for all the + * allocations done at btrfs_scrub_pages() and scrub_pages_for_parity() + * invoked by our callees. The pausing request is done when the + * transaction commit starts, and it blocks the transaction until scrub + * is paused (done at specific points at scrub_stripe() or right above + * before incrementing fs_info->scrubs_running). + */ + nofs_flag = memalloc_nofs_save(); if (!is_dev_replace) { /* * by holding device list mutex, we can @@ -3887,6 +3919,7 @@ int btrfs_scrub_dev(struct btrfs_fs_info
if (!ret) ret = scrub_enumerate_chunks(sctx, dev, start, end); + memalloc_nofs_restore(nofs_flag);
wait_event(sctx->list_wait, atomic_read(&sctx->bios_in_flight) == 0); atomic_dec(&fs_info->scrubs_running);
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lu Fengqi lufq.fnst@cn.fujitsu.com
commit 27a7ff554e8d349627a90bda275c527b7348adae upstream.
The test case btrfs/001 with inode_cache mount option will encounter the following warning:
WARNING: CPU: 1 PID: 23700 at fs/btrfs/inode.c:956 cow_file_range.isra.19+0x32b/0x430 [btrfs] CPU: 1 PID: 23700 Comm: btrfs Kdump: loaded Tainted: G W O 4.20.0-rc4-custom+ #30 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015 RIP: 0010:cow_file_range.isra.19+0x32b/0x430 [btrfs] Call Trace: ? free_extent_buffer+0x46/0x90 [btrfs] run_delalloc_nocow+0x455/0x900 [btrfs] btrfs_run_delalloc_range+0x1a7/0x360 [btrfs] writepage_delalloc+0xf9/0x150 [btrfs] __extent_writepage+0x125/0x3e0 [btrfs] extent_write_cache_pages+0x1b6/0x3e0 [btrfs] ? __wake_up_common_lock+0x63/0xc0 extent_writepages+0x50/0x80 [btrfs] do_writepages+0x41/0xd0 ? __filemap_fdatawrite_range+0x9e/0xf0 __filemap_fdatawrite_range+0xbe/0xf0 btrfs_fdatawrite_range+0x1b/0x50 [btrfs] __btrfs_write_out_cache+0x42c/0x480 [btrfs] btrfs_write_out_ino_cache+0x84/0xd0 [btrfs] btrfs_save_ino_cache+0x551/0x660 [btrfs] commit_fs_roots+0xc5/0x190 [btrfs] btrfs_commit_transaction+0x2bf/0x8d0 [btrfs] btrfs_mksubvol+0x48d/0x4d0 [btrfs] btrfs_ioctl_snap_create_transid+0x170/0x180 [btrfs] btrfs_ioctl_snap_create_v2+0x124/0x180 [btrfs] btrfs_ioctl+0x123f/0x3030 [btrfs]
The file extent generation of the free space inode is equal to the last snapshot of the file root, so the inode will be passed to cow_file_rage. But the inode was created and its extents were preallocated in btrfs_save_ino_cache, there are no cow copies on disk.
The preallocated extent is not yet in the extent tree, and btrfs_cross_ref_exist will ignore the -ENOENT returned by check_committed_ref, so we can directly write the inode to the disk.
Fixes: 78d4295b1eee ("btrfs: lift some btrfs_cross_ref_exist checks in nocow path") CC: stable@vger.kernel.org # 4.18+ Reviewed-by: Filipe Manana fdmanana@suse.com Signed-off-by: Lu Fengqi lufq.fnst@cn.fujitsu.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/btrfs/inode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -1372,7 +1372,8 @@ next_slot: * Do the same check as in btrfs_cross_ref_exist but * without the unnecessary search. */ - if (btrfs_file_extent_generation(leaf, fi) <= + if (!nolock && + btrfs_file_extent_generation(leaf, fi) <= btrfs_root_last_snapshot(&root->root_item)) goto out_check; if (extent_type == BTRFS_FILE_EXTENT_REG && !force)
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana fdmanana@suse.com
commit 41bd60676923822de1df2c50b3f9a10171f4338a upstream.
The log tree has a long standing problem that when a file is fsync'ed we only check for new ancestors, created in the current transaction, by following only the hard link for which the fsync was issued. We follow the ancestors using the VFS' dget_parent() API. This means that if we create a new link for a file in a directory that is new (or in an any other new ancestor directory) and then fsync the file using an old hard link, we end up not logging the new ancestor, and on log replay that new hard link and ancestor do not exist. In some cases, involving renames, the file will not exist at all.
Example:
mkfs.btrfs -f /dev/sdb mount /dev/sdb /mnt
mkdir /mnt/A touch /mnt/foo ln /mnt/foo /mnt/A/bar xfs_io -c fsync /mnt/foo
<power failure>
In this example after log replay only the hard link named 'foo' exists and directory A does not exist, which is unexpected. In other major linux filesystems, such as ext4, xfs and f2fs for example, both hard links exist and so does directory A after mounting again the filesystem.
Checking if any new ancestors are new and need to be logged was added in 2009 by commit 12fcfd22fe5b ("Btrfs: tree logging unlink/rename fixes"), however only for the ancestors of the hard link (dentry) for which the fsync was issued, instead of checking for all ancestors for all of the inode's hard links.
So fix this by tracking the id of the last transaction where a hard link was created for an inode and then on fsync fallback to a full transaction commit when an inode has more than one hard link and at least one new hard link was created in the current transaction. This is the simplest solution since this is not a common use case (adding frequently hard links for which there's an ancestor created in the current transaction and then fsync the file). In case it ever becomes a common use case, a solution that consists of iterating the fs/subvol btree for each hard link and check if any ancestor is new, could be implemented.
This solves many unexpected scenarios reported by Jayashree Mohan and Vijay Chidambaram, and for which there is a new test case for fstests under review.
Fixes: 12fcfd22fe5b ("Btrfs: tree logging unlink/rename fixes") CC: stable@vger.kernel.org # 4.4+ Reported-by: Vijay Chidambaram vvijay03@gmail.com Reported-by: Jayashree Mohan jayashree2912@gmail.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/btrfs_inode.h | 6 ++++++ fs/btrfs/inode.c | 17 +++++++++++++++++ fs/btrfs/tree-log.c | 16 ++++++++++++++++ 3 files changed, 39 insertions(+)
--- a/fs/btrfs/btrfs_inode.h +++ b/fs/btrfs/btrfs_inode.h @@ -147,6 +147,12 @@ struct btrfs_inode { u64 last_unlink_trans;
/* + * Track the transaction id of the last transaction used to create a + * hard link for the inode. This is used by the log tree (fsync). + */ + u64 last_link_trans; + + /* * Number of bytes outstanding that are going to need csums. This is * used in ENOSPC accounting. */ --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -3687,6 +3687,21 @@ cache_index: * inode is not a directory, logging its parent unnecessarily. */ BTRFS_I(inode)->last_unlink_trans = BTRFS_I(inode)->last_trans; + /* + * Similar reasoning for last_link_trans, needs to be set otherwise + * for a case like the following: + * + * mkdir A + * touch foo + * ln foo A/bar + * echo 2 > /proc/sys/vm/drop_caches + * fsync foo + * <power failure> + * + * Would result in link bar and directory A not existing after the power + * failure. + */ + BTRFS_I(inode)->last_link_trans = BTRFS_I(inode)->last_trans;
path->slots[0]++; if (inode->i_nlink != 1 || @@ -6626,6 +6641,7 @@ static int btrfs_link(struct dentry *old if (err) goto fail; } + BTRFS_I(inode)->last_link_trans = trans->transid; d_instantiate(dentry, inode); ret = btrfs_log_new_name(trans, BTRFS_I(inode), NULL, parent, true, NULL); @@ -9158,6 +9174,7 @@ struct inode *btrfs_alloc_inode(struct s ei->index_cnt = (u64)-1; ei->dir_index = 0; ei->last_unlink_trans = 0; + ei->last_link_trans = 0; ei->last_log_commit = 0;
spin_lock_init(&ei->lock); --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -5778,6 +5778,22 @@ static int btrfs_log_inode_parent(struct goto end_trans; }
+ /* + * If a new hard link was added to the inode in the current transaction + * and its link count is now greater than 1, we need to fallback to a + * transaction commit, otherwise we can end up not logging all its new + * parents for all the hard links. Here just from the dentry used to + * fsync, we can not visit the ancestor inodes for all the other hard + * links to figure out if any is new, so we fallback to a transaction + * commit (instead of adding a lot of complexity of scanning a btree, + * since this scenario is not a common use case). + */ + if (inode->vfs_inode.i_nlink > 1 && + inode->last_link_trans > last_committed) { + ret = -EMLINK; + goto end_trans; + } + while (1) { if (!parent || d_really_is_negative(parent) || sb != parent->d_sb) break;
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik jbacik@fb.com
commit 0568e82dbe2510fc1fa664f58e5c997d3f1e649e upstream.
With my delayed refs patches in place we started seeing a large amount of aborts in __btrfs_free_extent:
BTRFS error (device sdb1): unable to find ref byte nr 91947008 parent 0 root 35964 owner 1 offset 0 Call Trace: ? btrfs_merge_delayed_refs+0xaf/0x340 __btrfs_run_delayed_refs+0x6ea/0xfc0 ? btrfs_set_path_blocking+0x31/0x60 btrfs_run_delayed_refs+0xeb/0x180 btrfs_commit_transaction+0x179/0x7f0 ? btrfs_check_space_for_delayed_refs+0x30/0x50 ? should_end_transaction.isra.19+0xe/0x40 btrfs_drop_snapshot+0x41c/0x7c0 btrfs_clean_one_deleted_snapshot+0xb5/0xd0 cleaner_kthread+0xf6/0x120 kthread+0xf8/0x130 ? btree_invalidatepage+0x90/0x90 ? kthread_bind+0x10/0x10 ret_from_fork+0x35/0x40
This was because btrfs_drop_snapshot depends on the root not being modified while it's dropping the snapshot. It will unlock the root node (and really every node) as it walks down the tree, only to re-lock it when it needs to do something. This is a problem because if we modify the tree we could cow a block in our path, which frees our reference to that block. Then once we get back to that shared block we'll free our reference to it again, and get ENOENT when trying to lookup our extent reference to that block in __btrfs_free_extent.
This is ultimately happening because we have delayed items left to be processed for our deleted snapshot _after_ all of the inodes are closed for the snapshot. We only run the delayed inode item if we're deleting the inode, and even then we do not run the delayed insertions or delayed removals. These can be run at any point after our final inode does its last iput, which is what triggers the snapshot deletion. We can end up with the snapshot deletion happening and then have the delayed items run on that file system, resulting in the above problem.
This problem has existed forever, however my patches made it much easier to hit as I wake up the cleaner much more often to deal with delayed iputs, which made us more likely to start the snapshot dropping work before the transaction commits, which is when the delayed items would generally be run. Before, generally speaking, we would run the delayed items, commit the transaction, and wakeup the cleaner thread to start deleting snapshots, which means we were less likely to hit this problem. You could still hit it if you had multiple snapshots to be deleted and ended up with lots of delayed items, but it was definitely harder.
Fix for now by simply running all the delayed items before starting to drop the snapshot. We could make this smarter in the future by making the delayed items per-root, and then simply drop any delayed items for roots that we are going to delete. But for now just a quick and easy solution is the safest.
CC: stable@vger.kernel.org # 4.4+ Reviewed-by: Filipe Manana fdmanana@suse.com Signed-off-by: Josef Bacik josef@toxicpanda.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/btrfs/extent-tree.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -8944,6 +8944,10 @@ int btrfs_drop_snapshot(struct btrfs_roo goto out_free; }
+ err = btrfs_run_delayed_items(trans); + if (err) + goto out_end_trans; + if (block_rsv) trans->block_rsv = block_rsv;
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana fdmanana@suse.com
commit be6821f82c3cc36e026f5afd10249988852b35ea upstream.
If we create a snapshot of a snapshot currently being used by a send operation, we can end up with send failing unexpectedly (returning -ENOENT error to user space for example). The following diagram shows how this happens.
CPU 1 CPU2 CPU3
btrfs_ioctl_send() (...) create_snapshot() -> creates snapshot of a root used by the send task btrfs_commit_transaction() create_pending_snapshot() __get_inode_info() btrfs_search_slot() btrfs_search_slot_get_root() down_read commit_root_sem
get reference on eb of the commit root -> eb with bytenr == X
up_read commit_root_sem
btrfs_cow_block(root node) btrfs_free_tree_block() -> creates delayed ref to free the extent
btrfs_run_delayed_refs() -> runs the delayed ref, adds extent to fs_info->pinned_extents
btrfs_finish_extent_commit() unpin_extent_range() -> marks extent as free in the free space cache
transaction commit finishes
btrfs_start_transaction() (...) btrfs_cow_block() btrfs_alloc_tree_block() btrfs_reserve_extent() -> allocates extent at bytenr == X btrfs_init_new_buffer(bytenr X) btrfs_find_create_tree_block() alloc_extent_buffer(bytenr X) find_extent_buffer(bytenr X) -> returns existing eb, which the send task got
(...) -> modifies content of the eb with bytenr == X
-> uses an eb that now belongs to some other tree and no more matches the commit root of the snapshot, resuts will be unpredictable
The consequences of this race can be various, and can lead to searches in the commit root performed by the send task failing unexpectedly (unable to find inode items, returning -ENOENT to user space, for example) or not failing because an inode item with the same number was added to the tree that reused the metadata extent, in which case send can behave incorrectly in the worst case or just fail later for some reason.
Fix this by performing a copy of the commit root's extent buffer when doing a search in the context of a send operation.
CC: stable@vger.kernel.org # 4.4.x: 1fc28d8e2e9: Btrfs: move get root out of btrfs_search_slot to a helper CC: stable@vger.kernel.org # 4.4.x: f9ddfd0592a: Btrfs: remove unused check of skip_locking CC: stable@vger.kernel.org # 4.4.x 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/ctree.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-)
--- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -2584,14 +2584,27 @@ static struct extent_buffer *btrfs_searc root_lock = BTRFS_READ_LOCK;
if (p->search_commit_root) { - /* The commit roots are read only so we always do read locks */ - if (p->need_commit_sem) + /* + * The commit roots are read only so we always do read locks, + * and we always must hold the commit_root_sem when doing + * searches on them, the only exception is send where we don't + * want to block transaction commits for a long time, so + * we need to clone the commit root in order to avoid races + * with transaction commits that create a snapshot of one of + * the roots used by a send operation. + */ + if (p->need_commit_sem) { down_read(&fs_info->commit_root_sem); - b = root->commit_root; - extent_buffer_get(b); - level = btrfs_header_level(b); - if (p->need_commit_sem) + b = btrfs_clone_extent_buffer(root->commit_root); up_read(&fs_info->commit_root_sem); + if (!b) + return ERR_PTR(-ENOMEM); + + } else { + b = root->commit_root; + extent_buffer_get(b); + } + level = btrfs_header_level(b); /* * Ensure that all callers have set skip_locking when * p->search_commit_root = 1. @@ -2717,6 +2730,10 @@ int btrfs_search_slot(struct btrfs_trans again: prev_cmp = -1; b = btrfs_search_slot_get_root(root, p, write_lock_level); + if (IS_ERR(b)) { + ret = PTR_ERR(b); + goto done; + }
while (b) { level = btrfs_header_level(b);
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stijn Tintel stijn@linux-ipv6.be
commit 8c892df41500469729e0d662816300196e4f463d upstream.
When the update_connect_param callback is set, nl80211 expects the flag WIPHY_FLAG_SUPPORTS_FW_ROAM to be set as well. However, this flag is only set when modparam roamoff=0, while the callback is set unconditionally. Since commit 7f9a3e150ec7 this causes a warning in wiphy_register, which breaks brcmfmac.
Disable the update_connect_param callback when roamoff=0 to fix this.
Fixes: 7f9a3e150ec7 ("nl80211: Update ERP info using NL80211_CMD_UPDATE_CONNECT_PARAMS") Cc: Stable stable@vger.kernel.org # 4.19+ Signed-off-by: Jonas Gorski jonas.gorski@gmail.com Signed-off-by: Stijn Tintel stijn@linux-ipv6.be Signed-off-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 11 +++++++++-- drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h | 2 +- drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -5196,10 +5196,17 @@ static struct cfg80211_ops brcmf_cfg8021 .del_pmk = brcmf_cfg80211_del_pmk, };
-struct cfg80211_ops *brcmf_cfg80211_get_ops(void) +struct cfg80211_ops *brcmf_cfg80211_get_ops(struct brcmf_mp_device *settings) { - return kmemdup(&brcmf_cfg80211_ops, sizeof(brcmf_cfg80211_ops), + struct cfg80211_ops *ops; + + ops = kmemdup(&brcmf_cfg80211_ops, sizeof(brcmf_cfg80211_ops), GFP_KERNEL); + + if (ops && settings->roamoff) + ops->update_connect_params = NULL; + + return ops; }
struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h @@ -404,7 +404,7 @@ struct brcmf_cfg80211_info *brcmf_cfg802 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg); s32 brcmf_cfg80211_up(struct net_device *ndev); s32 brcmf_cfg80211_down(struct net_device *ndev); -struct cfg80211_ops *brcmf_cfg80211_get_ops(void); +struct cfg80211_ops *brcmf_cfg80211_get_ops(struct brcmf_mp_device *settings); enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp);
struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c @@ -1130,7 +1130,7 @@ int brcmf_attach(struct device *dev, str
brcmf_dbg(TRACE, "Enter\n");
- ops = brcmf_cfg80211_get_ops(); + ops = brcmf_cfg80211_get_ops(settings); if (!ops) return -ENOMEM;
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lyude Paul lyude@redhat.com
commit b72c51a58e6d63ef673ac96b8ab5bc98799c5f7b upstream.
I ended up tracking down some rather nasty issues with f2fs (and other filesystem modules) constantly crashing on my kernel down to a combination of out of bounds memory accesses, one of which was coming from brcmfmac during module load:
[ 30.891382] brcmfmac: brcmf_fw_alloc_request: using brcm/brcmfmac4356-sdio for chip BCM4356/2 [ 30.894437] ================================================================== [ 30.901581] BUG: KASAN: global-out-of-bounds in brcmf_fw_alloc_request+0x42c/0x480 [brcmfmac] [ 30.909935] Read of size 1 at addr ffff2000024865df by task kworker/6:2/387 [ 30.916805] [ 30.918261] CPU: 6 PID: 387 Comm: kworker/6:2 Tainted: G O 4.20.0-rc3Lyude-Test+ #19 [ 30.927251] Hardware name: amlogic khadas-vim2/khadas-vim2, BIOS 2018.07-rc2-armbian 09/11/2018 [ 30.935964] Workqueue: events brcmf_driver_register [brcmfmac] [ 30.941641] Call trace: [ 30.944058] dump_backtrace+0x0/0x3e8 [ 30.947676] show_stack+0x14/0x20 [ 30.950968] dump_stack+0x130/0x1c4 [ 30.954406] print_address_description+0x60/0x25c [ 30.959066] kasan_report+0x1b4/0x368 [ 30.962683] __asan_report_load1_noabort+0x18/0x20 [ 30.967547] brcmf_fw_alloc_request+0x42c/0x480 [brcmfmac] [ 30.967639] brcmf_sdio_probe+0x163c/0x2050 [brcmfmac] [ 30.978035] brcmf_ops_sdio_probe+0x598/0xa08 [brcmfmac] [ 30.983254] sdio_bus_probe+0x190/0x398 [ 30.983270] really_probe+0x2a0/0xa70 [ 30.983296] driver_probe_device+0x1b4/0x2d8 [ 30.994901] __driver_attach+0x200/0x280 [ 30.994914] bus_for_each_dev+0x10c/0x1a8 [ 30.994925] driver_attach+0x38/0x50 [ 30.994935] bus_add_driver+0x330/0x608 [ 30.994953] driver_register+0x140/0x388 [ 31.013965] sdio_register_driver+0x74/0xa0 [ 31.014076] brcmf_sdio_register+0x14/0x60 [brcmfmac] [ 31.023177] brcmf_driver_register+0xc/0x18 [brcmfmac] [ 31.023209] process_one_work+0x654/0x1080 [ 31.032266] worker_thread+0x4f0/0x1308 [ 31.032286] kthread+0x2a8/0x320 [ 31.039254] ret_from_fork+0x10/0x1c [ 31.039269] [ 31.044226] The buggy address belongs to the variable: [ 31.044351] brcmf_firmware_path+0x11f/0xfffffffffffd3b40 [brcmfmac] [ 31.055601] [ 31.057031] Memory state around the buggy address: [ 31.061800] ffff200002486480: 04 fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00 [ 31.068983] ffff200002486500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 31.068993] >ffff200002486580: 00 00 00 00 00 00 00 00 fa fa fa fa 00 00 00 00 [ 31.068999] ^ [ 31.069017] ffff200002486600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 31.096521] ffff200002486680: 00 00 00 00 00 00 00 00 00 00 00 00 fa fa fa fa [ 31.096528] ================================================================== [ 31.096533] Disabling lock debugging due to kernel taint
It appears that when trying to determine the length of the string in the alternate firmware path, we make the mistake of not handling the case where the firmware path is empty correctly. Since strlen(mp_path) can return 0, we'll end up accessing mp_path[-1] when the firmware_path isn't provided through the module arguments.
So, fix this by just setting the end char to '\0' by default, and only changing it if we have a non-zero length. Additionally, use strnlen() with BRCMF_FW_ALTPATH_LEN instead of strlen() just to be extra safe.
Fixes: 2baa3aaee27f ("brcmfmac: introduce brcmf_fw_alloc_request() function") Cc: Hante Meuleman hante.meuleman@broadcom.com Cc: Pieter-Paul Giesberts pieter-paul.giesberts@broadcom.com Cc: Franky Lin franky.lin@broadcom.com Cc: Arend van Spriel arend.vanspriel@broadcom.com Cc: Kalle Valo kvalo@codeaurora.org Cc: Arend Van Spriel arend.vanspriel@broadcom.com Cc: Himanshu Jha himanshujha199640@gmail.com Cc: Dan Haab dhaab@luxul.com Cc: Jia-Shyr Chuang saint.chuang@cypress.com Cc: Ian Molton ian@mnementh.co.uk Cc: stable@vger.kernel.org # v4.17+ Signed-off-by: Lyude Paul lyude@redhat.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c @@ -641,8 +641,9 @@ brcmf_fw_alloc_request(u32 chip, u32 chi struct brcmf_fw_request *fwreq; char chipname[12]; const char *mp_path; + size_t mp_path_len; u32 i, j; - char end; + char end = '\0'; size_t reqsz;
for (i = 0; i < table_size; i++) { @@ -667,7 +668,10 @@ brcmf_fw_alloc_request(u32 chip, u32 chi mapping_table[i].fw_base, chipname);
mp_path = brcmf_mp_global.firmware_path; - end = mp_path[strlen(mp_path) - 1]; + mp_path_len = strnlen(mp_path, BRCMF_FW_ALTPATH_LEN); + if (mp_path_len) + end = mp_path[mp_path_len - 1]; + fwreq->n_items = n_fwnames;
for (j = 0; j < n_fwnames; j++) {
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers ebiggers@google.com
commit 57b0e31453209d746c99e513d80b3d0c44a80891 upstream.
We need to check the return value of match_token() for Opt_err before doing anything with it.
[ Not only did the old "-1" value for Opt_err cause problems for the __test_and_set_bit(), as fixed in commit 94c13f66e13c ("security: don't use a negative Opt_err token index"), but accessing "args[0].from" is invalid for the Opt_err case, as pointed out by Eric later. - Linus ]
Reported-by: syzbot+a22e0dc07567662c50bc@syzkaller.appspotmail.com Fixes: 00d60fd3b932 ("KEYS: Provide keyctls to drive the new key type ops for asymmetric keys [ver #2]") Signed-off-by: Eric Biggers ebiggers@google.com Cc: stable@kernel.org # 4.20 Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- security/keys/keyctl_pkey.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/security/keys/keyctl_pkey.c +++ b/security/keys/keyctl_pkey.c @@ -50,6 +50,8 @@ static int keyctl_pkey_params_parse(stru if (*p == '\0' || *p == ' ' || *p == '\t') continue; token = match_token(p, param_keys, args); + if (token == Opt_err) + return -EINVAL; if (__test_and_set_bit(token, &token_mask)) return -EINVAL; q = args[0].from;
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao leitao@debian.org
commit e1c3743e1a20647c53b719dbf28b48f45d23f2cd upstream.
On a signal handler return, the user could set a context with MSR[TS] bits set, and these bits would be copied to task regs->msr.
At restore_tm_sigcontexts(), after current task regs->msr[TS] bits are set, several __get_user() are called and then a recheckpoint is executed.
This is a problem since a page fault (in kernel space) could happen when calling __get_user(). If it happens, the process MSR[TS] bits were already set, but recheckpoint was not executed, and SPRs are still invalid.
The page fault can cause the current process to be de-scheduled, with MSR[TS] active and without tm_recheckpoint() being called. More importantly, without TEXASR[FS] bit set also.
Since TEXASR might not have the FS bit set, and when the process is scheduled back, it will try to reclaim, which will be aborted because of the CPU is not in the suspended state, and, then, recheckpoint. This recheckpoint will restore thread->texasr into TEXASR SPR, which might be zero, hitting a BUG_ON().
kernel BUG at /build/linux-sf3Co9/linux-4.9.30/arch/powerpc/kernel/tm.S:434! cpu 0xb: Vector: 700 (Program Check) at [c00000041f1576d0] pc: c000000000054550: restore_gprs+0xb0/0x180 lr: 0000000000000000 sp: c00000041f157950 msr: 8000000100021033 current = 0xc00000041f143000 paca = 0xc00000000fb86300 softe: 0 irq_happened: 0x01 pid = 1021, comm = kworker/11:1 kernel BUG at /build/linux-sf3Co9/linux-4.9.30/arch/powerpc/kernel/tm.S:434! Linux version 4.9.0-3-powerpc64le (debian-kernel@lists.debian.org) (gcc version 6.3.0 20170516 (Debian 6.3.0-18) ) #1 SMP Debian 4.9.30-2+deb9u2 (2017-06-26) enter ? for help [c00000041f157b30] c00000000001bc3c tm_recheckpoint.part.11+0x6c/0xa0 [c00000041f157b70] c00000000001d184 __switch_to+0x1e4/0x4c0 [c00000041f157bd0] c00000000082eeb8 __schedule+0x2f8/0x990 [c00000041f157cb0] c00000000082f598 schedule+0x48/0xc0 [c00000041f157ce0] c0000000000f0d28 worker_thread+0x148/0x610 [c00000041f157d80] c0000000000f96b0 kthread+0x120/0x140 [c00000041f157e30] c00000000000c0e0 ret_from_kernel_thread+0x5c/0x7c
This patch simply delays the MSR[TS] set, so, if there is any page fault in the __get_user() section, it does not have regs->msr[TS] set, since the TM structures are still invalid, thus avoiding doing TM operations for in-kernel exceptions and possible process reschedule.
With this patch, the MSR[TS] will only be set just before recheckpointing and setting TEXASR[FS] = 1, thus avoiding an interrupt with TM registers in invalid state.
Other than that, if CONFIG_PREEMPT is set, there might be a preemption just after setting MSR[TS] and before tm_recheckpoint(), thus, this block must be atomic from a preemption perspective, thus, calling preempt_disable/enable() on this code.
It is not possible to move tm_recheckpoint to happen earlier, because it is required to get the checkpointed registers from userspace, with __get_user(), thus, the only way to avoid this undesired behavior is delaying the MSR[TS] set.
The 32-bits signal handler seems to be safe this current issue, but, it might be exposed to the preemption issue, thus, disabling preemption in this chunk of code.
Changes from v2: * Run the critical section with preempt_disable.
Fixes: 87b4e5393af7 ("powerpc/tm: Fix return of active 64bit signals") Cc: stable@vger.kernel.org (v3.9+) Signed-off-by: Breno Leitao leitao@debian.org Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/powerpc/kernel/signal_32.c | 20 +++++++++++++++++- arch/powerpc/kernel/signal_64.c | 44 +++++++++++++++++++++++++++------------- 2 files changed, 49 insertions(+), 15 deletions(-)
--- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -848,7 +848,23 @@ static long restore_tm_user_regs(struct /* If TM bits are set to the reserved value, it's an invalid context */ if (MSR_TM_RESV(msr_hi)) return 1; - /* Pull in the MSR TM bits from the user context */ + + /* + * Disabling preemption, since it is unsafe to be preempted + * with MSR[TS] set without recheckpointing. + */ + preempt_disable(); + + /* + * CAUTION: + * After regs->MSR[TS] being updated, make sure that get_user(), + * put_user() or similar functions are *not* called. These + * functions can generate page faults which will cause the process + * to be de-scheduled with MSR[TS] set but without calling + * tm_recheckpoint(). This can cause a bug. + * + * Pull in the MSR TM bits from the user context + */ regs->msr = (regs->msr & ~MSR_TS_MASK) | (msr_hi & MSR_TS_MASK); /* Now, recheckpoint. This loads up all of the checkpointed (older) * registers, including FP and V[S]Rs. After recheckpointing, the @@ -873,6 +889,8 @@ static long restore_tm_user_regs(struct } #endif
+ preempt_enable(); + return 0; } #endif --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -467,20 +467,6 @@ static long restore_tm_sigcontexts(struc if (MSR_TM_RESV(msr)) return -EINVAL;
- /* pull in MSR TS bits from user context */ - regs->msr = (regs->msr & ~MSR_TS_MASK) | (msr & MSR_TS_MASK); - - /* - * Ensure that TM is enabled in regs->msr before we leave the signal - * handler. It could be the case that (a) user disabled the TM bit - * through the manipulation of the MSR bits in uc_mcontext or (b) the - * TM bit was disabled because a sufficient number of context switches - * happened whilst in the signal handler and load_tm overflowed, - * disabling the TM bit. In either case we can end up with an illegal - * TM state leading to a TM Bad Thing when we return to userspace. - */ - regs->msr |= MSR_TM; - /* pull in MSR LE from user context */ regs->msr = (regs->msr & ~MSR_LE) | (msr & MSR_LE);
@@ -572,6 +558,34 @@ static long restore_tm_sigcontexts(struc tm_enable(); /* Make sure the transaction is marked as failed */ tsk->thread.tm_texasr |= TEXASR_FS; + + /* + * Disabling preemption, since it is unsafe to be preempted + * with MSR[TS] set without recheckpointing. + */ + preempt_disable(); + + /* pull in MSR TS bits from user context */ + regs->msr = (regs->msr & ~MSR_TS_MASK) | (msr & MSR_TS_MASK); + + /* + * Ensure that TM is enabled in regs->msr before we leave the signal + * handler. It could be the case that (a) user disabled the TM bit + * through the manipulation of the MSR bits in uc_mcontext or (b) the + * TM bit was disabled because a sufficient number of context switches + * happened whilst in the signal handler and load_tm overflowed, + * disabling the TM bit. In either case we can end up with an illegal + * TM state leading to a TM Bad Thing when we return to userspace. + * + * CAUTION: + * After regs->MSR[TS] being updated, make sure that get_user(), + * put_user() or similar functions are *not* called. These + * functions can generate page faults which will cause the process + * to be de-scheduled with MSR[TS] set but without calling + * tm_recheckpoint(). This can cause a bug. + */ + regs->msr |= MSR_TM; + /* This loads the checkpointed FP/VEC state, if used */ tm_recheckpoint(&tsk->thread);
@@ -585,6 +599,8 @@ static long restore_tm_sigcontexts(struc regs->msr |= MSR_VEC; }
+ preempt_enable(); + return err; } #endif
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao leitao@debian.org
commit 6f5b9f018f4c7686fd944d920209d1382d320e4e upstream.
There is a TM Bad Thing bug that can be caused when you return from a signal context in a suspended transaction but with ucontext MSR[TS] unset.
This forces regs->msr[TS] to be set at syscall entrance (since the CPU state is transactional). It also calls treclaim() to flush the transaction state, which is done based on the live (mfmsr) MSR state.
Since user context MSR[TS] is not set, then restore_tm_sigcontexts() is not called, thus, not executing recheckpoint, keeping the CPU state as not transactional. When calling rfid, SRR1 will have MSR[TS] set, but the CPU state is non transactional, causing the TM Bad Thing with the following stack:
[ 33.862316] Bad kernel stack pointer 3fffd9dce3e0 at c00000000000c47c cpu 0x8: Vector: 700 (Program Check) at [c00000003ff7fd40] pc: c00000000000c47c: fast_exception_return+0xac/0xb4 lr: 00003fff865f442c sp: 3fffd9dce3e0 msr: 8000000102a03031 current = 0xc00000041f68b700 paca = 0xc00000000fb84800 softe: 0 irq_happened: 0x01 pid = 1721, comm = tm-signal-sigre Linux version 4.9.0-3-powerpc64le (debian-kernel@lists.debian.org) (gcc version 6.3.0 20170516 (Debian 6.3.0-18) ) #1 SMP Debian 4.9.30-2+deb9u2 (2017-06-26) WARNING: exception is not recoverable, can't continue
The same problem happens on 32-bits signal handler, and the fix is very similar, if tm_recheckpoint() is not executed, then regs->msr[TS] should be zeroed.
This patch also fixes a sparse warning related to lack of indentation when CONFIG_PPC_TRANSACTIONAL_MEM is set.
Fixes: 2b0a576d15e0e ("powerpc: Add new transactional memory state to the signal context") CC: Stable stable@vger.kernel.org # 3.10+ Signed-off-by: Breno Leitao leitao@debian.org Tested-by: Michal Suchánek msuchanek@suse.de Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/powerpc/kernel/signal_32.c | 18 +++++++++++++----- arch/powerpc/kernel/signal_64.c | 20 ++++++++++++++++---- 2 files changed, 29 insertions(+), 9 deletions(-)
--- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -1158,11 +1158,11 @@ SYSCALL_DEFINE0(rt_sigreturn) { struct rt_sigframe __user *rt_sf; struct pt_regs *regs = current_pt_regs(); + int tm_restore = 0; #ifdef CONFIG_PPC_TRANSACTIONAL_MEM struct ucontext __user *uc_transact; unsigned long msr_hi; unsigned long tmp; - int tm_restore = 0; #endif /* Always make any pending restarted system calls return -EINTR */ current->restart_block.fn = do_no_restart_syscall; @@ -1210,11 +1210,19 @@ SYSCALL_DEFINE0(rt_sigreturn) goto bad; } } - if (!tm_restore) - /* Fall through, for non-TM restore */ + if (!tm_restore) { + /* + * Unset regs->msr because ucontext MSR TS is not + * set, and recheckpoint was not called. This avoid + * hitting a TM Bad thing at RFID + */ + regs->msr &= ~MSR_TS_MASK; + } + /* Fall through, for non-TM restore */ #endif - if (do_setcontext(&rt_sf->uc, regs, 1)) - goto bad; + if (!tm_restore) + if (do_setcontext(&rt_sf->uc, regs, 1)) + goto bad;
/* * It's not clear whether or why it is desirable to save the --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -756,11 +756,23 @@ SYSCALL_DEFINE0(rt_sigreturn) &uc_transact->uc_mcontext)) goto badframe; } - else - /* Fall through, for non-TM restore */ #endif - if (restore_sigcontext(current, NULL, 1, &uc->uc_mcontext)) - goto badframe; + /* Fall through, for non-TM restore */ + if (!MSR_TM_ACTIVE(msr)) { + /* + * Unset MSR[TS] on the thread regs since MSR from user + * context does not have MSR active, and recheckpoint was + * not called since restore_tm_sigcontexts() was not called + * also. + * + * If not unsetting it, the code can RFID to userspace with + * MSR[TS] set, but without CPU in the proper state, + * causing a TM bad thing. + */ + current->thread.regs->msr &= ~MSR_TS_MASK; + if (restore_sigcontext(current, NULL, 1, &uc->uc_mcontext)) + goto badframe; + }
if (restore_altstack(&uc->uc_stack)) goto badframe;
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pan Bian bianpan2016@163.com
commit 0ea295dd853e0879a9a30ab61f923c26be35b902 upstream.
The function truncate_node frees the page with f2fs_put_page. However, the page index is read after that. So, the patch reads the index before freeing the page.
Fixes: bf39c00a9a7f ("f2fs: drop obsolete node page when it is truncated") Cc: stable@vger.kernel.org Signed-off-by: Pan Bian bianpan2016@163.com Reviewed-by: Chao Yu yuchao0@huawei.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/f2fs/node.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -826,6 +826,7 @@ static int truncate_node(struct dnode_of struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode); struct node_info ni; int err; + pgoff_t index;
err = f2fs_get_node_info(sbi, dn->nid, &ni); if (err) @@ -845,10 +846,11 @@ static int truncate_node(struct dnode_of clear_node_page_dirty(dn->node_page); set_sbi_flag(sbi, SBI_IS_DIRTY);
+ index = dn->node_page->index; f2fs_put_page(dn->node_page, 1);
invalidate_mapping_pages(NODE_MAPPING(sbi), - dn->node_page->index, dn->node_page->index); + index, index);
dn->node_page = NULL; trace_f2fs_truncate_node(dn->inode, dn->nid, ni.blk_addr);
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jia Zhu zhujia13@huawei.com
commit 73c0a9272a7d2942bcae29d4829bf63277cc57c8 upstream.
Previously, we allocated a new block address for OPU mode in direct_IO.
But the new address couldn't be assigned to @map->m_pblk correctly.
This patch fix it.
Cc: stable@vger.kernel.org Fixes: 511f52d02f05 ("f2fs: allow out-place-update for direct IO in LFS mode") Signed-off-by: Jia Zhu zhujia13@huawei.com Reviewed-by: Chao Yu yuchao0@huawei.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/f2fs/data.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -1102,8 +1102,10 @@ next_block: if (test_opt(sbi, LFS) && create && flag == F2FS_GET_BLOCK_DIO) { err = __allocate_data_block(&dn, map->m_seg_type); - if (!err) + if (!err) { + blkaddr = dn.data_blkaddr; set_inode_flag(inode, FI_APPEND_WRITE); + } } } else { if (create) {
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jaegeuk Kim jaegeuk@kernel.org
commit 8f31b4665c14fe19593601a250275e58c7ad0ef1 upstream.
This fixes missing unlock call.
Cc: stable@vger.kernel.org Reviewed-by: Chao Yu yuchao0@huawei.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/f2fs/super.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
--- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -1457,19 +1457,16 @@ static int f2fs_disable_checkpoint(struc
sbi->sb->s_flags |= SB_ACTIVE;
- mutex_lock(&sbi->gc_mutex); f2fs_update_time(sbi, DISABLE_TIME);
while (!f2fs_time_over(sbi, DISABLE_TIME)) { + mutex_lock(&sbi->gc_mutex); err = f2fs_gc(sbi, true, false, NULL_SEGNO); if (err == -ENODATA) break; - if (err && err != -EAGAIN) { - mutex_unlock(&sbi->gc_mutex); + if (err && err != -EAGAIN) return err; - } } - mutex_unlock(&sbi->gc_mutex);
err = sync_filesystem(sbi->sb); if (err)
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Martin Blumenstingl martin.blumenstingl@googlemail.com
commit 88960068f25fcc3759455d85460234dcc9d43fef upstream.
Treat "block_count" from struct f2fs_super_block as 64-bit little endian value in sanity_check_raw_super() because struct f2fs_super_block declares "block_count" as "__le64".
This fixes a bug where the superblock validation fails on big endian devices with the following error: F2FS-fs (sda1): Wrong segment_count / block_count (61439 > 0) F2FS-fs (sda1): Can't find valid F2FS filesystem in 1th superblock F2FS-fs (sda1): Wrong segment_count / block_count (61439 > 0) F2FS-fs (sda1): Can't find valid F2FS filesystem in 2th superblock As result of this the partition cannot be mounted.
With this patch applied the superblock validation works fine and the partition can be mounted again: F2FS-fs (sda1): Mounted with checkpoint version = 7c84
My little endian x86-64 hardware was able to mount the partition without this fix. To confirm that mounting f2fs filesystems works on big endian machines again I tested this on a 32-bit MIPS big endian (lantiq) device.
Fixes: 0cfe75c5b01199 ("f2fs: enhance sanity_check_raw_super() to avoid potential overflows") Cc: stable@vger.kernel.org Signed-off-by: Martin Blumenstingl martin.blumenstingl@googlemail.com Reviewed-by: Chao Yu yuchao0@huawei.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/f2fs/super.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
--- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -2493,10 +2493,10 @@ static int sanity_check_raw_super(struct return 1; }
- if (segment_count > (le32_to_cpu(raw_super->block_count) >> 9)) { + if (segment_count > (le64_to_cpu(raw_super->block_count) >> 9)) { f2fs_msg(sb, KERN_INFO, - "Wrong segment_count / block_count (%u > %u)", - segment_count, le32_to_cpu(raw_super->block_count)); + "Wrong segment_count / block_count (%u > %llu)", + segment_count, le64_to_cpu(raw_super->block_count)); return 1; }
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jaegeuk Kim jaegeuk@kernel.org
commit 64beba0558fce7b59e9a8a7afd77290e82a22163 upstream.
There is a security report where f2fs_getxattr() has a hole to expose wrong memory region when the image is malformed like this.
f2fs_getxattr: entry->e_name_len: 4, size: 12288, buffer_size: 16384, len: 4
Cc: stable@vger.kernel.org Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/f2fs/xattr.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-)
--- a/fs/f2fs/xattr.c +++ b/fs/f2fs/xattr.c @@ -288,7 +288,7 @@ static int read_xattr_block(struct inode static int lookup_all_xattrs(struct inode *inode, struct page *ipage, unsigned int index, unsigned int len, const char *name, struct f2fs_xattr_entry **xe, - void **base_addr) + void **base_addr, int *base_size) { void *cur_addr, *txattr_addr, *last_addr = NULL; nid_t xnid = F2FS_I(inode)->i_xattr_nid; @@ -299,8 +299,8 @@ static int lookup_all_xattrs(struct inod if (!size && !inline_size) return -ENODATA;
- txattr_addr = f2fs_kzalloc(F2FS_I_SB(inode), - inline_size + size + XATTR_PADDING_SIZE, GFP_NOFS); + *base_size = inline_size + size + XATTR_PADDING_SIZE; + txattr_addr = f2fs_kzalloc(F2FS_I_SB(inode), *base_size, GFP_NOFS); if (!txattr_addr) return -ENOMEM;
@@ -312,8 +312,10 @@ static int lookup_all_xattrs(struct inod
*xe = __find_inline_xattr(inode, txattr_addr, &last_addr, index, len, name); - if (*xe) + if (*xe) { + *base_size = inline_size; goto check; + } }
/* read from xattr node block */ @@ -474,6 +476,7 @@ int f2fs_getxattr(struct inode *inode, i int error = 0; unsigned int size, len; void *base_addr = NULL; + int base_size;
if (name == NULL) return -EINVAL; @@ -484,7 +487,7 @@ int f2fs_getxattr(struct inode *inode, i
down_read(&F2FS_I(inode)->i_xattr_sem); error = lookup_all_xattrs(inode, ipage, index, len, name, - &entry, &base_addr); + &entry, &base_addr, &base_size); up_read(&F2FS_I(inode)->i_xattr_sem); if (error) return error; @@ -498,6 +501,11 @@ int f2fs_getxattr(struct inode *inode, i
if (buffer) { char *pval = entry->e_name + entry->e_name_len; + + if (base_size - (pval - (char *)base_addr) < size) { + error = -ERANGE; + goto out; + } memcpy(buffer, pval, size); } error = size;
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nava kishore Manne nava.manne@xilinx.com
commit 260683137ab5276113fc322fdbbc578024185fee upstream.
This patch Correct the RX interrupt mask value to handle the RX interrupts properly.
Fixes: c8dbdc842d30 ("serial: xuartps: Rewrite the interrupt handling logic") Signed-off-by: Nava kishore Manne nava.manne@xilinx.com Cc: stable stable@vger.kernel.org Signed-off-by: Michal Simek michal.simek@xilinx.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/tty/serial/xilinx_uartps.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c @@ -123,7 +123,7 @@ MODULE_PARM_DESC(rx_timeout, "Rx timeout #define CDNS_UART_IXR_RXTRIG 0x00000001 /* RX FIFO trigger interrupt */ #define CDNS_UART_IXR_RXFULL 0x00000004 /* RX FIFO full interrupt. */ #define CDNS_UART_IXR_RXEMPTY 0x00000002 /* RX FIFO empty interrupt. */ -#define CDNS_UART_IXR_MASK 0x00001FFF /* Valid bit mask */ +#define CDNS_UART_IXR_RXMASK 0x000021e7 /* Valid RX bit mask */
/* * Do not enable parity error interrupt for the following @@ -364,7 +364,7 @@ static irqreturn_t cdns_uart_isr(int irq cdns_uart_handle_tx(dev_id); isrstatus &= ~CDNS_UART_IXR_TXEMPTY; } - if (isrstatus & CDNS_UART_IXR_MASK) + if (isrstatus & CDNS_UART_IXR_RXMASK) cdns_uart_handle_rx(dev_id, isrstatus);
spin_unlock(&port->lock);
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans Verkuil hverkuil-cisco@xs4all.nl
commit 32804fcb612bf867034a093f459415e485cf044b upstream.
I noticed that repeatedly running 'cec-ctl --playback' would occasionally select 'Playback Device 2' instead of 'Playback Device 1', even though there were no other Playback devices in the HDMI topology. This happened both with 'real' hardware and with the vivid CEC emulation, suggesting that this was an issue in the core code that claims a logical address.
What 'cec-ctl --playback' does is to first clear all existing logical addresses, and immediately after that configure the new desired device type.
The core code will poll the logical addresses trying to find a free address. When found it will issue a few standard messages as per the CEC spec and return. Those messages are queued up and will be transmitted asynchronously.
What happens is that if you run two 'cec-ctl --playback' commands in quick succession, there is still a message of the first cec-ctl command being transmitted when you reconfigure the adapter again in the second cec-ctl command.
When the logical addresses are cleared, then all information about outstanding transmits inside the CEC core is also cleared, and the core is no longer aware that there is still a transmit in flight.
When the hardware finishes the transmit it calls transmit_done and the CEC core thinks it is actually in response of a POLL messages that is trying to find a free logical address. The result of all this is that the core thinks that the logical address for Playback Device 1 is in use, when it is really an earlier transmit that ended.
The main transmit thread looks at adap->transmitting to check if a transmit is in progress, but that is set to NULL when the adapter is unconfigured. adap->transmitting represents the view of userspace, not that of the hardware. So when unconfiguring the adapter the message is marked aborted from the point of view of userspace, but seen from the PoV of the hardware it is still ongoing.
So introduce a new bool transmit_in_progress that represents the hardware state and use that instead of adap->transmitting. Now the CEC core waits until the hardware finishes the transmit before starting a new transmit.
Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Cc: stable@vger.kernel.org # for v4.18 and up Signed-off-by: Mauro Carvalho Chehab mchehab+samsung@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/media/cec/cec-adap.c | 27 ++++++++++++++++++--------- include/media/cec.h | 1 + 2 files changed, 19 insertions(+), 9 deletions(-)
--- a/drivers/media/cec/cec-adap.c +++ b/drivers/media/cec/cec-adap.c @@ -455,7 +455,7 @@ int cec_thread_func(void *_adap) (adap->needs_hpd && (!adap->is_configured && !adap->is_configuring)) || kthread_should_stop() || - (!adap->transmitting && + (!adap->transmit_in_progress && !list_empty(&adap->transmit_queue)), msecs_to_jiffies(CEC_XFER_TIMEOUT_MS)); timeout = err == 0; @@ -463,7 +463,7 @@ int cec_thread_func(void *_adap) /* Otherwise we just wait for something to happen. */ wait_event_interruptible(adap->kthread_waitq, kthread_should_stop() || - (!adap->transmitting && + (!adap->transmit_in_progress && !list_empty(&adap->transmit_queue))); }
@@ -488,6 +488,7 @@ int cec_thread_func(void *_adap) pr_warn("cec-%s: message %*ph timed out\n", adap->name, adap->transmitting->msg.len, adap->transmitting->msg.msg); + adap->transmit_in_progress = false; adap->tx_timeouts++; /* Just give up on this. */ cec_data_cancel(adap->transmitting, @@ -499,7 +500,7 @@ int cec_thread_func(void *_adap) * If we are still transmitting, or there is nothing new to * transmit, then just continue waiting. */ - if (adap->transmitting || list_empty(&adap->transmit_queue)) + if (adap->transmit_in_progress || list_empty(&adap->transmit_queue)) goto unlock;
/* Get a new message to transmit */ @@ -545,6 +546,8 @@ int cec_thread_func(void *_adap) if (adap->ops->adap_transmit(adap, data->attempts, signal_free_time, &data->msg)) cec_data_cancel(data, CEC_TX_STATUS_ABORTED); + else + adap->transmit_in_progress = true;
unlock: mutex_unlock(&adap->lock); @@ -575,14 +578,17 @@ void cec_transmit_done_ts(struct cec_ada data = adap->transmitting; if (!data) { /* - * This can happen if a transmit was issued and the cable is + * This might happen if a transmit was issued and the cable is * unplugged while the transmit is ongoing. Ignore this * transmit in that case. */ - dprintk(1, "%s was called without an ongoing transmit!\n", - __func__); - goto unlock; + if (!adap->transmit_in_progress) + dprintk(1, "%s was called without an ongoing transmit!\n", + __func__); + adap->transmit_in_progress = false; + goto wake_thread; } + adap->transmit_in_progress = false;
msg = &data->msg;
@@ -648,7 +654,6 @@ wake_thread: * for transmitting or to retry the current message. */ wake_up_interruptible(&adap->kthread_waitq); -unlock: mutex_unlock(&adap->lock); } EXPORT_SYMBOL_GPL(cec_transmit_done_ts); @@ -1496,8 +1501,11 @@ void __cec_s_phys_addr(struct cec_adapte if (adap->monitor_all_cnt) WARN_ON(call_op(adap, adap_monitor_all_enable, false)); mutex_lock(&adap->devnode.lock); - if (adap->needs_hpd || list_empty(&adap->devnode.fhs)) + if (adap->needs_hpd || list_empty(&adap->devnode.fhs)) { WARN_ON(adap->ops->adap_enable(adap, false)); + adap->transmit_in_progress = false; + wake_up_interruptible(&adap->kthread_waitq); + } mutex_unlock(&adap->devnode.lock); if (phys_addr == CEC_PHYS_ADDR_INVALID) return; @@ -1505,6 +1513,7 @@ void __cec_s_phys_addr(struct cec_adapte
mutex_lock(&adap->devnode.lock); adap->last_initiator = 0xff; + adap->transmit_in_progress = false;
if ((adap->needs_hpd || list_empty(&adap->devnode.fhs)) && adap->ops->adap_enable(adap, true)) { --- a/include/media/cec.h +++ b/include/media/cec.h @@ -155,6 +155,7 @@ struct cec_adapter { unsigned int transmit_queue_sz; struct list_head wait_queue; struct cec_data *transmitting; + bool transmit_in_progress;
struct task_struct *kthread_config; struct completion config_completion;
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans Verkuil hverkuil@xs4all.nl
commit ac791f19a273a7fe254a7596f193af6534582a9f upstream.
If the tx_ignore_nack_until_eom error injection was activated, then tx_nacked was never set instead of setting it when the last byte of the message was transmitted.
As a result the transmit was marked as OK, when it should have been NACKed.
Modify the condition so that it always sets tx_nacked when the last byte of the message was transmitted.
Signed-off-by: Hans Verkuil hans.verkuil@cisco.com Cc: stable@vger.kernel.org # for v4.17 and up Signed-off-by: Hans Verkuil hansverk@cisco.com Signed-off-by: Mauro Carvalho Chehab mchehab+samsung@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/media/cec/cec-pin.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
--- a/drivers/media/cec/cec-pin.c +++ b/drivers/media/cec/cec-pin.c @@ -601,8 +601,9 @@ static void cec_pin_tx_states(struct cec break; /* Was the message ACKed? */ ack = cec_msg_is_broadcast(&pin->tx_msg) ? v : !v; - if (!ack && !pin->tx_ignore_nack_until_eom && - pin->tx_bit / 10 < pin->tx_msg.len && !pin->tx_post_eom) { + if (!ack && (!pin->tx_ignore_nack_until_eom || + pin->tx_bit / 10 == pin->tx_msg.len - 1) && + !pin->tx_post_eom) { /* * Note: the CEC spec is ambiguous regarding * what action to take when a NACK appears
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Young sean@mess.org
commit e5bb9d3d755f128956ed467ae50b41d22bb680c6 upstream.
This fixes an oops in ir_lirc_scancode_event().
BUG: unable to handle kernel NULL pointer dereference at 0000000000000038 PGD 0 P4D 0 Oops: 0000 [#1] SMP PTI CPU: 9 PID: 27687 Comm: kworker/9:2 Tainted: P OE 4.18.12-200.fc28.x86_64 #1 Hardware name: Supermicro C7X99-OCE-F/C7X99-OCE-F, BIOS 2.1a 06/15/2018 Workqueue: events pulse8_irq_work_handler [pulse8_cec] RIP: 0010:ir_lirc_scancode_event+0x3d/0xb0 [rc_core] Code: 8d ae b4 07 00 00 49 81 c6 b8 07 00 00 53 e8 4a df c3 d5 48 89 ef 49 89 45 00 e8 4e 84 41 d6 49 8b 1e 49 89 c4 4c 39 f3 74 58 <8b> 43 38 8b 53 40 89 c1 2b 4b 3c 39 ca 72 41 21 d0 49 8b 7d 00 49 RSP: 0018:ffffaa10e3c07d58 EFLAGS: 00010017 RAX: 0000000000000002 RBX: 0000000000000000 RCX: 0000000000000018 RDX: 0000000000000001 RSI: 00316245397fa93c RDI: ffff966d31c8d7b4 RBP: ffff966d31c8d7b4 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000003 R11: ffffaa10e3c07e28 R12: 0000000000000002 R13: ffffaa10e3c07d88 R14: ffff966d31c8d7b8 R15: 0000000000000073 FS: 0000000000000000(0000) GS:ffff966d3f440000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000038 CR3: 00000009d820a003 CR4: 00000000003606e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: ir_do_keydown+0x75/0x260 [rc_core] rc_keydown+0x54/0xc0 [rc_core] cec_received_msg_ts+0xaa8/0xaf0 [cec] process_one_work+0x1a1/0x350 worker_thread+0x30/0x380 ? pwq_unbound_release_workfn+0xd0/0xd0 kthread+0x112/0x130 ? kthread_create_worker_on_cpu+0x70/0x70 ret_from_fork+0x35/0x40 Modules linked in: rc_tt_1500 dvb_usb_dvbsky dvb_usb_v2 uas usb_storage fuse vhost_net vhost tap xt_CHECKSUM iptable_mangle ip6t_REJECT nf_reject_ipv6 tun 8021q garp mrp xt_nat macvlan xfs devlink ebta si2157 si2168 cx25840 cx23885 kvm altera_ci tda18271 joydev ir_rc6_decoder rc_rc6_mce crct10dif_pclmul crc32_pclmul ghash_clmulni_intel intel_cstate intel_uncore altera_stapl m88ds3103 tveeprom cx2341 mxm_wmi igb crc32c_intel megaraid_sas dca i2c_algo_bit wmi vfio_pci irqbypass vfio_virqfd vfio_iommu_type1 vfio i2c_dev CR2: 0000000000000038
Cc: stable@vger.kernel.org # v4.16+ Signed-off-by: Sean Young sean@mess.org Signed-off-by: Mauro Carvalho Chehab mchehab+samsung@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/media/rc/rc-main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
--- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -695,7 +695,8 @@ void rc_repeat(struct rc_dev *dev) (dev->last_toggle ? LIRC_SCANCODE_FLAG_TOGGLE : 0) };
- ir_lirc_scancode_event(dev, &sc); + if (dev->allowed_protocols != RC_PROTO_BIT_CEC) + ir_lirc_scancode_event(dev, &sc);
spin_lock_irqsave(&dev->keylock, flags);
@@ -735,7 +736,8 @@ static void ir_do_keydown(struct rc_dev .keycode = keycode };
- ir_lirc_scancode_event(dev, &sc); + if (dev->allowed_protocols != RC_PROTO_BIT_CEC) + ir_lirc_scancode_event(dev, &sc);
if (new_event && dev->keypressed) ir_do_keyup(dev, false);
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luca Ceresoli luca@lucaceresoli.net
commit cea8c0077d6cf3a0cea2f18a8e914af78d46b2ff upstream.
imx274_read_reg() takes a u8 pointer ("reg") and casts it to pass it to regmap_read(), which takes an unsigned int pointer. This results in a corrupted stack and random crashes.
Fixes: 0985dd306f72 ("media: imx274: V4l2 driver for Sony imx274 CMOS sensor")
Cc: stable@vger.kernel.org # for 4.15 and up Signed-off-by: Luca Ceresoli luca@lucaceresoli.net Signed-off-by: Sakari Ailus sakari.ailus@linux.intel.com Signed-off-by: Mauro Carvalho Chehab mchehab+samsung@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/media/i2c/imx274.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
--- a/drivers/media/i2c/imx274.c +++ b/drivers/media/i2c/imx274.c @@ -619,16 +619,19 @@ static int imx274_write_table(struct sti
static inline int imx274_read_reg(struct stimx274 *priv, u16 addr, u8 *val) { + unsigned int uint_val; int err;
- err = regmap_read(priv->regmap, addr, (unsigned int *)val); + err = regmap_read(priv->regmap, addr, &uint_val); if (err) dev_err(&priv->client->dev, "%s : i2c read failed, addr = %x\n", __func__, addr); else dev_dbg(&priv->client->dev, "%s : addr 0x%x, val=0x%x\n", __func__, - addr, *val); + addr, uint_val); + + *val = uint_val; return err; }
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans Verkuil hverkuil-cisco@xs4all.nl
commit 560ccb75c2caa6b1039dec1a53cd2ef526f5bf03 upstream.
When vivid_update_format_cap() is called it should free any overlay bitmap since the compose size will change.
Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Reported-by: syzbot+0cc8e3cc63ca373722c6@syzkaller.appspotmail.com Cc: stable@vger.kernel.org # for v3.18 and up 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, 2 insertions(+)
--- a/drivers/media/platform/vivid/vivid-vid-cap.c +++ b/drivers/media/platform/vivid/vivid-vid-cap.c @@ -449,6 +449,8 @@ void vivid_update_format_cap(struct vivi tpg_s_rgb_range(&dev->tpg, v4l2_ctrl_g_ctrl(dev->rgb_range_cap)); break; } + vfree(dev->bitmap_cap); + dev->bitmap_cap = NULL; vivid_update_quality(dev); tpg_reset_source(&dev->tpg, dev->src_rect.width, dev->src_rect.height, dev->field_cap); dev->crop_cap = dev->src_rect;
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans Verkuil hverkuil-cisco@xs4all.nl
commit 52117be68b82ee05c96da0a7beec319906ccf6cc upstream.
The use of flush_schedule_work() made no sense and caused a syzkaller error. Replace with the correct cancel_delayed_work_sync().
Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Reported-by: syzbot+69780d144754b8071f4b@syzkaller.appspotmail.com Cc: stable@vger.kernel.org # for v4.20 and up Signed-off-by: Mauro Carvalho Chehab mchehab+samsung@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/media/platform/vim2m.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/media/platform/vim2m.c +++ b/drivers/media/platform/vim2m.c @@ -805,10 +805,11 @@ static int vim2m_start_streaming(struct static void vim2m_stop_streaming(struct vb2_queue *q) { struct vim2m_ctx *ctx = vb2_get_drv_priv(q); + struct vim2m_dev *dev = ctx->dev; struct vb2_v4l2_buffer *vbuf; unsigned long flags;
- flush_scheduled_work(); + cancel_delayed_work_sync(&dev->work_run); for (;;) { if (V4L2_TYPE_IS_OUTPUT(q->type)) vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans Verkuil hverkuil-cisco@xs4all.nl
commit 62dcb4f41836bd3c44b5b651bb6df07ea4cb1551 upstream.
vb2_core_create_bufs did not check if the memory model for newly added buffers is the same as for already existing buffers. It should return an error if they aren't the same.
Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Reported-by: syzbot+e1fb118a2ebb88031d21@syzkaller.appspotmail.com Cc: stable@vger.kernel.org # for v4.16 and up Signed-off-by: Mauro Carvalho Chehab mchehab+samsung@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/media/common/videobuf2/videobuf2-core.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/drivers/media/common/videobuf2/videobuf2-core.c +++ b/drivers/media/common/videobuf2/videobuf2-core.c @@ -812,6 +812,9 @@ int vb2_core_create_bufs(struct vb2_queu memset(q->alloc_devs, 0, sizeof(q->alloc_devs)); q->memory = memory; q->waiting_for_buffers = !q->is_output; + } else if (q->memory != memory) { + dprintk(1, "memory model mismatch\n"); + return -EINVAL; }
num_buffers = min(*count, VB2_MAX_FRAME - q->num_buffers);
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans Verkuil hverkuil-cisco@xs4all.nl
commit e5f71a27fa12c1a1b02ad478a568e76260f1815e upstream.
text[s] is a signed char, so using that as index into the font8x16 array can result in negative indices. Cast it to u8 to be safe.
Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Reported-by: syzbot+ccf0a61ed12f2a7313ee@syzkaller.appspotmail.com Cc: stable@vger.kernel.org # for v4.7 and up Signed-off-by: Mauro Carvalho Chehab mchehab+samsung@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/media/common/v4l2-tpg/v4l2-tpg-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c +++ b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c @@ -1769,7 +1769,7 @@ typedef struct { u16 __; u8 _; } __packe unsigned s; \ \ for (s = 0; s < len; s++) { \ - u8 chr = font8x16[text[s] * 16 + line]; \ + u8 chr = font8x16[(u8)text[s] * 16 + line]; \ \ if (hdiv == 2 && tpg->hflip) { \ pos[3] = (chr & (0x01 << 6) ? fg : bg); \
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ondrej Jirman megous@megous.com
commit fa09d06522ceac428fdc5c2b57c572f6cfd0a8bb upstream.
When parallel bus is used and data-active is being parsed, incorrect flags are cleared.
Clear the correct flag bits.
Fixes: e9be1b863e2c2948deb003df8edd9635b4611a8a (media: v4l: fwnode: Use default parallel flags).
Cc: stable@vger.kernel.org # for Kernel 4.20 Signed-off-by: Ondrej Jirman megous@megous.com Signed-off-by: Sakari Ailus sakari.ailus@linux.intel.com Signed-off-by: Mauro Carvalho Chehab mchehab+samsung@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/media/v4l2-core/v4l2-fwnode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/media/v4l2-core/v4l2-fwnode.c +++ b/drivers/media/v4l2-core/v4l2-fwnode.c @@ -310,8 +310,8 @@ v4l2_fwnode_endpoint_parse_parallel_bus( }
if (!fwnode_property_read_u32(fwnode, "data-active", &v)) { - flags &= ~(V4L2_MBUS_PCLK_SAMPLE_RISING | - V4L2_MBUS_PCLK_SAMPLE_FALLING); + flags &= ~(V4L2_MBUS_DATA_ACTIVE_HIGH | + V4L2_MBUS_DATA_ACTIVE_LOW); flags |= v ? V4L2_MBUS_DATA_ACTIVE_HIGH : V4L2_MBUS_DATA_ACTIVE_LOW; pr_debug("data-active %s\n", v ? "high" : "low");
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt (VMware) rostedt@goodmis.org
commit f024cf085c423bac7512479f45c34ee9a24af7ce upstream.
In the case that a bprintk event has a dereferenced pointer that is stored as a string, and there's more values to process (more args), the arg was not updated to point to the next arg after processing the dereferenced pointer, and it screwed up what was to be displayed.
Signed-off-by: Steven Rostedt (VMware) rostedt@goodmis.org Cc: Jiri Olsa jolsa@redhat.com Cc: Namhyung Kim namhyung@kernel.org Cc: linux-trace-devel@vger.kernel.org Cc: stable@vger.kernel.org Fixes: 37db96bb49629 ("tools lib traceevent: Handle new pointer processing of bprint strings") Link: http://lkml.kernel.org/r/20181210134522.3f71e2ca@gandalf.local.home Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- tools/lib/traceevent/event-parse.c | 1 + 1 file changed, 1 insertion(+)
--- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c @@ -4970,6 +4970,7 @@ static void pretty_print(struct trace_se
if (arg->type == TEP_PRINT_BSTRING) { trace_seq_puts(s, arg->string.string); + arg = arg->next; break; }
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paul Burton paul.burton@mips.com
commit adcc81f148d733b7e8e641300c5590a2cdc13bf3 upstream.
Mapping the delay slot emulation page as both writeable & executable presents a security risk, in that if an exploit can write to & jump into the page then it can be used as an easy way to execute arbitrary code.
Prevent this by mapping the page read-only for userland, and using access_process_vm() with the FOLL_FORCE flag to write to it from mips_dsemul().
This will likely be less efficient due to copy_to_user_page() performing cache maintenance on a whole page, rather than a single line as in the previous use of flush_cache_sigtramp(). However this delay slot emulation code ought not to be running in any performance critical paths anyway so this isn't really a problem, and we can probably do better in copy_to_user_page() anyway in future.
A major advantage of this approach is that the fix is small & simple to backport to stable kernels.
Reported-by: Andy Lutomirski luto@kernel.org Signed-off-by: Paul Burton paul.burton@mips.com Fixes: 432c6bacbd0c ("MIPS: Use per-mm page to execute branch delay slot instructions") Cc: stable@vger.kernel.org # v4.8+ Cc: linux-mips@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: Rich Felker dalias@libc.org Cc: David Daney david.daney@cavium.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/mips/kernel/vdso.c | 4 ++-- arch/mips/math-emu/dsemul.c | 38 ++++++++++++++++++++------------------ 2 files changed, 22 insertions(+), 20 deletions(-)
--- a/arch/mips/kernel/vdso.c +++ b/arch/mips/kernel/vdso.c @@ -126,8 +126,8 @@ int arch_setup_additional_pages(struct l
/* Map delay slot emulation page */ base = mmap_region(NULL, STACK_TOP, PAGE_SIZE, - VM_READ|VM_WRITE|VM_EXEC| - VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC, + VM_READ | VM_EXEC | + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC, 0, NULL); if (IS_ERR_VALUE(base)) { ret = base; --- a/arch/mips/math-emu/dsemul.c +++ b/arch/mips/math-emu/dsemul.c @@ -214,8 +214,9 @@ int mips_dsemul(struct pt_regs *regs, mi { int isa16 = get_isa16_mode(regs->cp0_epc); mips_instruction break_math; - struct emuframe __user *fr; - int err, fr_idx; + unsigned long fr_uaddr; + struct emuframe fr; + int fr_idx, ret;
/* NOP is easy */ if (ir == 0) @@ -250,27 +251,31 @@ int mips_dsemul(struct pt_regs *regs, mi fr_idx = alloc_emuframe(); if (fr_idx == BD_EMUFRAME_NONE) return SIGBUS; - fr = &dsemul_page()[fr_idx];
/* Retrieve the appropriately encoded break instruction */ break_math = BREAK_MATH(isa16);
/* Write the instructions to the frame */ if (isa16) { - err = __put_user(ir >> 16, - (u16 __user *)(&fr->emul)); - err |= __put_user(ir & 0xffff, - (u16 __user *)((long)(&fr->emul) + 2)); - err |= __put_user(break_math >> 16, - (u16 __user *)(&fr->badinst)); - err |= __put_user(break_math & 0xffff, - (u16 __user *)((long)(&fr->badinst) + 2)); + union mips_instruction _emul = { + .halfword = { ir >> 16, ir } + }; + union mips_instruction _badinst = { + .halfword = { break_math >> 16, break_math } + }; + + fr.emul = _emul.word; + fr.badinst = _badinst.word; } else { - err = __put_user(ir, &fr->emul); - err |= __put_user(break_math, &fr->badinst); + fr.emul = ir; + fr.badinst = break_math; }
- if (unlikely(err)) { + /* Write the frame to user memory */ + fr_uaddr = (unsigned long)&dsemul_page()[fr_idx]; + ret = access_process_vm(current, fr_uaddr, &fr, sizeof(fr), + FOLL_FORCE | FOLL_WRITE); + if (unlikely(ret != sizeof(fr))) { MIPS_FPU_EMU_INC_STATS(errors); free_emuframe(fr_idx, current->mm); return SIGBUS; @@ -282,10 +287,7 @@ int mips_dsemul(struct pt_regs *regs, mi atomic_set(¤t->thread.bd_emu_frame, fr_idx);
/* Change user register context to execute the frame */ - regs->cp0_epc = (unsigned long)&fr->emul | isa16; - - /* Ensure the icache observes our newly written frame */ - flush_cache_sigtramp((unsigned long)&fr->emul); + regs->cp0_epc = fr_uaddr | isa16;
return 0; }
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Huacai Chen chenhc@lemote.com
commit bb53fdf395eed103f85061bfff3b116cee123895 upstream.
For multi-node Loongson-3 (NUMA configuration), r4k_blast_scache() can only flush Node-0's scache. So we add r4k_blast_scache_node() by using (CAC_BASE | (node_id << NODE_ADDRSPACE_SHIFT)) instead of CKSEG0 as the start address.
Signed-off-by: Huacai Chen chenhc@lemote.com [paul.burton@mips.com: Include asm/mmzone.h from asm/r4kcache.h for nid_to_addrbase(). Add asm/mach-generic/mmzone.h to allow inclusion for all platforms.] Signed-off-by: Paul Burton paul.burton@mips.com Patchwork: https://patchwork.linux-mips.org/patch/21129/ Cc: Ralf Baechle ralf@linux-mips.org Cc: James Hogan james.hogan@mips.com Cc: Steven J . Hill Steven.Hill@cavium.com Cc: linux-mips@linux-mips.org Cc: Fuxin Zhang zhangfx@lemote.com Cc: Zhangjin Wu wuzhangjin@gmail.com Cc: stable@vger.kernel.org # 3.15+ Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/mips/include/asm/mach-generic/mmzone.h | 2 + arch/mips/include/asm/mach-loongson64/mmzone.h | 1 arch/mips/include/asm/mmzone.h | 8 ++++ arch/mips/include/asm/r4kcache.h | 22 ++++++++++++ arch/mips/mm/c-r4k.c | 44 +++++++++++++++++++++---- 5 files changed, 70 insertions(+), 7 deletions(-)
--- /dev/null +++ b/arch/mips/include/asm/mach-generic/mmzone.h @@ -0,0 +1,2 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Intentionally empty */ --- a/arch/mips/include/asm/mach-loongson64/mmzone.h +++ b/arch/mips/include/asm/mach-loongson64/mmzone.h @@ -21,6 +21,7 @@ #define NODE3_ADDRSPACE_OFFSET 0x300000000000UL
#define pa_to_nid(addr) (((addr) & 0xf00000000000) >> NODE_ADDRSPACE_SHIFT) +#define nid_to_addrbase(nid) ((nid) << NODE_ADDRSPACE_SHIFT)
#define LEVELS_PER_SLICE 128
--- a/arch/mips/include/asm/mmzone.h +++ b/arch/mips/include/asm/mmzone.h @@ -9,6 +9,14 @@ #include <asm/page.h> #include <mmzone.h>
+#ifndef pa_to_nid +#define pa_to_nid(addr) 0 +#endif + +#ifndef nid_to_addrbase +#define nid_to_addrbase(nid) 0 +#endif + #ifdef CONFIG_DISCONTIGMEM
#define pfn_to_nid(pfn) pa_to_nid((pfn) << PAGE_SHIFT) --- a/arch/mips/include/asm/r4kcache.h +++ b/arch/mips/include/asm/r4kcache.h @@ -20,6 +20,7 @@ #include <asm/cpu-features.h> #include <asm/cpu-type.h> #include <asm/mipsmtregs.h> +#include <asm/mmzone.h> #include <linux/uaccess.h> /* for uaccess_kernel() */
extern void (*r4k_blast_dcache)(void); @@ -674,4 +675,25 @@ __BUILD_BLAST_CACHE_RANGE(s, scache, Hit __BUILD_BLAST_CACHE_RANGE(inv_d, dcache, Hit_Invalidate_D, , ) __BUILD_BLAST_CACHE_RANGE(inv_s, scache, Hit_Invalidate_SD, , )
+/* Currently, this is very specific to Loongson-3 */ +#define __BUILD_BLAST_CACHE_NODE(pfx, desc, indexop, hitop, lsize) \ +static inline void blast_##pfx##cache##lsize##_node(long node) \ +{ \ + unsigned long start = CAC_BASE | nid_to_addrbase(node); \ + unsigned long end = start + current_cpu_data.desc.waysize; \ + unsigned long ws_inc = 1UL << current_cpu_data.desc.waybit; \ + unsigned long ws_end = current_cpu_data.desc.ways << \ + current_cpu_data.desc.waybit; \ + unsigned long ws, addr; \ + \ + for (ws = 0; ws < ws_end; ws += ws_inc) \ + for (addr = start; addr < end; addr += lsize * 32) \ + cache##lsize##_unroll32(addr|ws, indexop); \ +} + +__BUILD_BLAST_CACHE_NODE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 16) +__BUILD_BLAST_CACHE_NODE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 32) +__BUILD_BLAST_CACHE_NODE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 64) +__BUILD_BLAST_CACHE_NODE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 128) + #endif /* _ASM_R4KCACHE_H */ --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -459,11 +459,28 @@ static void r4k_blast_scache_setup(void) r4k_blast_scache = blast_scache128; }
+static void (*r4k_blast_scache_node)(long node); + +static void r4k_blast_scache_node_setup(void) +{ + unsigned long sc_lsize = cpu_scache_line_size(); + + if (current_cpu_type() != CPU_LOONGSON3) + r4k_blast_scache_node = (void *)cache_noop; + else if (sc_lsize == 16) + r4k_blast_scache_node = blast_scache16_node; + else if (sc_lsize == 32) + r4k_blast_scache_node = blast_scache32_node; + else if (sc_lsize == 64) + r4k_blast_scache_node = blast_scache64_node; + else if (sc_lsize == 128) + r4k_blast_scache_node = blast_scache128_node; +} + static inline void local_r4k___flush_cache_all(void * args) { switch (current_cpu_type()) { case CPU_LOONGSON2: - case CPU_LOONGSON3: case CPU_R4000SC: case CPU_R4000MC: case CPU_R4400SC: @@ -480,6 +497,11 @@ static inline void local_r4k___flush_cac r4k_blast_scache(); break;
+ case CPU_LOONGSON3: + /* Use get_ebase_cpunum() for both NUMA=y/n */ + r4k_blast_scache_node(get_ebase_cpunum() >> 2); + break; + case CPU_BMIPS5000: r4k_blast_scache(); __sync(); @@ -840,10 +862,14 @@ static void r4k_dma_cache_wback_inv(unsi
preempt_disable(); if (cpu_has_inclusive_pcaches) { - if (size >= scache_size) - r4k_blast_scache(); - else + if (size >= scache_size) { + if (current_cpu_type() != CPU_LOONGSON3) + r4k_blast_scache(); + else + r4k_blast_scache_node(pa_to_nid(addr)); + } else { blast_scache_range(addr, addr + size); + } preempt_enable(); __sync(); return; @@ -877,9 +903,12 @@ static void r4k_dma_cache_inv(unsigned l
preempt_disable(); if (cpu_has_inclusive_pcaches) { - if (size >= scache_size) - r4k_blast_scache(); - else { + if (size >= scache_size) { + if (current_cpu_type() != CPU_LOONGSON3) + r4k_blast_scache(); + else + r4k_blast_scache_node(pa_to_nid(addr)); + } else { /* * There is no clearly documented alignment requirement * for the cache instruction on MIPS processors and @@ -1918,6 +1947,7 @@ void r4k_cache_init(void) r4k_blast_scache_page_setup(); r4k_blast_scache_page_indexed_setup(); r4k_blast_scache_setup(); + r4k_blast_scache_node_setup(); #ifdef CONFIG_EVA r4k_blast_dcache_user_page_setup(); r4k_blast_icache_user_page_setup();
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Huacai Chen chenhc@lemote.com
commit 92aa0718c9fa5160ad2f0e7b5bffb52f1ea1e51a upstream.
This patch is borrowed from ARM64 to ensure pmd_present() returns false after pmd_mknotpresent(). This is needed for THP.
References: 5bb1cc0ff9a6 ("arm64: Ensure pmd_present() returns false after pmd_mknotpresent()") Reviewed-by: James Hogan jhogan@kernel.org Signed-off-by: Huacai Chen chenhc@lemote.com Signed-off-by: Paul Burton paul.burton@mips.com Patchwork: https://patchwork.linux-mips.org/patch/21135/ Cc: Ralf Baechle ralf@linux-mips.org Cc: James Hogan james.hogan@mips.com Cc: Steven J . Hill Steven.Hill@cavium.com Cc: linux-mips@linux-mips.org Cc: Fuxin Zhang zhangfx@lemote.com Cc: Zhangjin Wu wuzhangjin@gmail.com Cc: stable@vger.kernel.org # 3.8+ Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/mips/include/asm/pgtable-64.h | 5 +++++ 1 file changed, 5 insertions(+)
--- a/arch/mips/include/asm/pgtable-64.h +++ b/arch/mips/include/asm/pgtable-64.h @@ -265,6 +265,11 @@ static inline int pmd_bad(pmd_t pmd)
static inline int pmd_present(pmd_t pmd) { +#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT + if (unlikely(pmd_val(pmd) & _PAGE_HUGE)) + return pmd_val(pmd) & _PAGE_PRESENT; +#endif + return pmd_val(pmd) != (unsigned long) invalid_pte_table; }
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Huacai Chen chenhc@lemote.com
commit bec0de4cfad21bd284dbddee016ed1767a5d2823 upstream.
KEXEC needs the new kernel's load address to be aligned on a page boundary (see sanity_check_segment_list()), but on MIPS the default vmlinuz load address is only explicitly aligned to 16 bytes.
Since the largest PAGE_SIZE supported by MIPS kernels is 64KB, increase the alignment calculated by calc_vmlinuz_load_addr to 64KB.
Signed-off-by: Huacai Chen chenhc@lemote.com Signed-off-by: Paul Burton paul.burton@mips.com Patchwork: https://patchwork.linux-mips.org/patch/21131/ Cc: Ralf Baechle ralf@linux-mips.org Cc: James Hogan james.hogan@mips.com Cc: Steven J . Hill Steven.Hill@cavium.com Cc: linux-mips@linux-mips.org Cc: Fuxin Zhang zhangfx@lemote.com Cc: Zhangjin Wu wuzhangjin@gmail.com Cc: stable@vger.kernel.org # 2.6.36+ Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/mips/boot/compressed/calc_vmlinuz_load_addr.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
--- a/arch/mips/boot/compressed/calc_vmlinuz_load_addr.c +++ b/arch/mips/boot/compressed/calc_vmlinuz_load_addr.c @@ -13,6 +13,7 @@ #include <stdint.h> #include <stdio.h> #include <stdlib.h> +#include "../../../../include/linux/sizes.h"
int main(int argc, char *argv[]) { @@ -45,11 +46,11 @@ int main(int argc, char *argv[]) vmlinuz_load_addr = vmlinux_load_addr + vmlinux_size;
/* - * Align with 16 bytes: "greater than that used for any standard data - * types by a MIPS compiler." -- See MIPS Run Linux (Second Edition). + * Align with 64KB: KEXEC needs load sections to be aligned to PAGE_SIZE, + * which may be as large as 64KB depending on the kernel configuration. */
- vmlinuz_load_addr += (16 - vmlinux_size % 16); + vmlinuz_load_addr += (SZ_64K - vmlinux_size % SZ_64K);
printf("0x%llx\n", vmlinuz_load_addr);
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paul Burton paul.burton@mips.com
commit ff4dd232ec45a0e45ea69f28f069f2ab22b4908a upstream.
ASIDs have always been stored as unsigned longs, ie. 32 bits on MIPS32 kernels. This is problematic because it is feasible for the ASID version to overflow & wrap around to zero.
We currently attempt to handle this overflow by simply setting the ASID version to 1, using asid_first_version(), but we make no attempt to account for the fact that there may be mm_structs with stale ASIDs that have versions which we now reuse due to the overflow & wrap around.
Encountering this requires that:
1) A struct mm_struct X is active on CPU A using ASID (V,n).
2) That mm is not used on CPU A for the length of time that it takes for CPU A's asid_cache to overflow & wrap around to the same version V that the mm had in step 1. During this time tasks using the mm could either be sleeping or only scheduled on other CPUs.
3) Some other mm Y becomes active on CPU A and is allocated the same ASID (V,n).
4) mm X now becomes active on CPU A again, and now incorrectly has the same ASID as mm Y.
Where struct mm_struct ASIDs are represented above in the format (version, EntryHi.ASID), and on a typical MIPS32 system version will be 24 bits wide & EntryHi.ASID will be 8 bits wide.
The length of time required in step 2 is highly dependent upon the CPU & workload, but for a hypothetical 2GHz CPU running a workload which generates a new ASID every 10000 cycles this period is around 248 days. Due to this long period of time & the fact that tasks need to be scheduled in just the right (or wrong, depending upon your inclination) way, this is obviously a difficult bug to encounter but it's entirely possible as evidenced by reports.
In order to fix this, simply extend ASIDs to 64 bits even on MIPS32 builds. This will extend the period of time required for the hypothetical system above to encounter the problem from 28 days to around 3 trillion years, which feels safely outside of the realms of possibility.
The cost of this is slightly more generated code in some commonly executed paths, but this is pretty minimal:
| Code Size Gain | Percentage -----------------------|----------------|------------- decstation_defconfig | +270 | +0.00% 32r2el_defconfig | +652 | +0.01% 32r6el_defconfig | +1000 | +0.01%
I have been unable to measure any change in performance of the LMbench lat_ctx or lat_proc tests resulting from the 64b ASIDs on either 32r2el_defconfig+interAptiv or 32r6el_defconfig+I6500 systems.
Signed-off-by: Paul Burton paul.burton@mips.com Suggested-by: James Hogan jhogan@kernel.org References: https://lore.kernel.org/linux-mips/80B78A8B8FEE6145A87579E8435D78C30205D5F3@... References: https://lore.kernel.org/linux-mips/1488684260-18867-1-git-send-email-jiwei.s... Cc: Jiwei Sun jiwei.sun@windriver.com Cc: Yu Huabing yhb@ruijie.com.cn Cc: stable@vger.kernel.org # 2.6.12+ Cc: linux-mips@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/mips/include/asm/cpu-info.h | 2 +- arch/mips/include/asm/mmu.h | 2 +- arch/mips/include/asm/mmu_context.h | 10 ++++------ arch/mips/mm/c-r3k.c | 2 +- 4 files changed, 7 insertions(+), 9 deletions(-)
--- a/arch/mips/include/asm/cpu-info.h +++ b/arch/mips/include/asm/cpu-info.h @@ -50,7 +50,7 @@ struct guest_info { #define MIPS_CACHE_PINDEX 0x00000020 /* Physically indexed cache */
struct cpuinfo_mips { - unsigned long asid_cache; + u64 asid_cache; #ifdef CONFIG_MIPS_ASID_BITS_VARIABLE unsigned long asid_mask; #endif --- a/arch/mips/include/asm/mmu.h +++ b/arch/mips/include/asm/mmu.h @@ -7,7 +7,7 @@ #include <linux/wait.h>
typedef struct { - unsigned long asid[NR_CPUS]; + u64 asid[NR_CPUS]; void *vdso; atomic_t fp_mode_switching;
--- a/arch/mips/include/asm/mmu_context.h +++ b/arch/mips/include/asm/mmu_context.h @@ -76,14 +76,14 @@ extern unsigned long pgd_current[]; * All unused by hardware upper bits will be considered * as a software asid extension. */ -static unsigned long asid_version_mask(unsigned int cpu) +static inline u64 asid_version_mask(unsigned int cpu) { unsigned long asid_mask = cpu_asid_mask(&cpu_data[cpu]);
- return ~(asid_mask | (asid_mask - 1)); + return ~(u64)(asid_mask | (asid_mask - 1)); }
-static unsigned long asid_first_version(unsigned int cpu) +static inline u64 asid_first_version(unsigned int cpu) { return ~asid_version_mask(cpu) + 1; } @@ -102,14 +102,12 @@ static inline void enter_lazy_tlb(struct static inline void get_new_mmu_context(struct mm_struct *mm, unsigned long cpu) { - unsigned long asid = asid_cache(cpu); + u64 asid = asid_cache(cpu);
if (!((asid += cpu_asid_inc()) & cpu_asid_mask(&cpu_data[cpu]))) { if (cpu_has_vtag_icache) flush_icache_all(); local_flush_tlb_all(); /* start new asid cycle */ - if (!asid) /* fix version if needed */ - asid = asid_first_version(cpu); }
cpu_context(cpu, mm) = asid_cache(cpu) = asid; --- a/arch/mips/mm/c-r3k.c +++ b/arch/mips/mm/c-r3k.c @@ -245,7 +245,7 @@ static void r3k_flush_cache_page(struct pmd_t *pmdp; pte_t *ptep;
- pr_debug("cpage[%08lx,%08lx]\n", + pr_debug("cpage[%08llx,%08lx]\n", cpu_context(smp_processor_id(), mm), addr);
/* No ASID => no such page in the cache. */
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aaro Koskinen aaro.koskinen@iki.fi
commit edefae94b7b9f10d5efe32dece5a36e9d9ecc29e upstream.
Commit 885872b722b7 ("MIPS: Octeon: Add Octeon III CN7xxx interface detection") added RGMII interface detection for OCTEON III, but it results in the following logs:
[ 7.165984] ERROR: Unsupported Octeon model in __cvmx_helper_rgmii_probe [ 7.173017] ERROR: Unsupported Octeon model in __cvmx_helper_rgmii_probe
The current RGMII routines are valid only for older OCTEONS that use GMX/ASX hardware blocks. On later chips AGL should be used, but support for that is missing in the mainline. Until that is added, mark the interface as disabled.
Fixes: 885872b722b7 ("MIPS: Octeon: Add Octeon III CN7xxx interface detection") Signed-off-by: Aaro Koskinen aaro.koskinen@iki.fi Signed-off-by: Paul Burton paul.burton@mips.com Cc: Ralf Baechle ralf@linux-mips.org Cc: James Hogan jhogan@kernel.org Cc: linux-mips@vger.kernel.org Cc: stable@vger.kernel.org # 4.7+ Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/mips/cavium-octeon/executive/cvmx-helper.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/arch/mips/cavium-octeon/executive/cvmx-helper.c +++ b/arch/mips/cavium-octeon/executive/cvmx-helper.c @@ -286,7 +286,8 @@ static cvmx_helper_interface_mode_t __cv case 3: return CVMX_HELPER_INTERFACE_MODE_LOOP; case 4: - return CVMX_HELPER_INTERFACE_MODE_RGMII; + /* TODO: Implement support for AGL (RGMII). */ + return CVMX_HELPER_INTERFACE_MODE_DISABLED; default: return CVMX_HELPER_INTERFACE_MODE_DISABLED; }
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Huacai Chen chenhc@lemote.com
commit db1ce3f5d01d2d6d5714aefba0159d2cb5167a0b upstream.
Commit 4936084c2ee2 ("MIPS: Cleanup R10000_LLSC_WAR logic in atomic.h") introduce a mistake in atomic64_fetch_##op##_relaxed(), because it forget to delete R10000_LLSC_WAR in the if-condition. So fix it.
Fixes: 4936084c2ee2 ("MIPS: Cleanup R10000_LLSC_WAR logic in atomic.h") Signed-off-by: Huacai Chen chenhc@lemote.com Signed-off-by: Paul Burton paul.burton@mips.com Cc: Joshua Kinard kumba@gentoo.org Cc: Ralf Baechle ralf@linux-mips.org Cc: Steven J . Hill Steven.Hill@cavium.com Cc: Fuxin Zhang zhangfx@lemote.com Cc: Zhangjin Wu wuzhangjin@gmail.com Cc: linux-mips@linux-mips.org Cc: stable@vger.kernel.org # 4.19+ Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/mips/include/asm/atomic.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/mips/include/asm/atomic.h +++ b/arch/mips/include/asm/atomic.h @@ -306,7 +306,7 @@ static __inline__ long atomic64_fetch_## { \ long result; \ \ - if (kernel_uses_llsc && R10000_LLSC_WAR) { \ + if (kernel_uses_llsc) { \ long temp; \ \ __asm__ __volatile__( \
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Georgy A Bystrenin gkot@altlinux.org
commit 9a596f5b39593414c0ec80f71b94a226286f084e upstream.
While resolving a bug with locks on samba shares found a strange behavior. When a file locked by one node and we trying to lock it from another node it fail with errno 5 (EIO) but in that case errno must be set to (EACCES | EAGAIN). This isn't happening when we try to lock file second time on same node. In this case it returns EACCES as expected. Also this issue not reproduces when we use SMB1 protocol (vers=1.0 in mount options).
Further investigation showed that the mapping from status_to_posix_error is different for SMB1 and SMB2+ implementations. For SMB1 mapping is [NT_STATUS_LOCK_NOT_GRANTED to ERRlock] (See fs/cifs/netmisc.c line 66) but for SMB2+ mapping is [STATUS_LOCK_NOT_GRANTED to -EIO] (see fs/cifs/smb2maperror.c line 383)
Quick changes in SMB2+ mapping from EIO to EACCES has fixed issue.
BUG: https://bugzilla.kernel.org/show_bug.cgi?id=201971
Signed-off-by: Georgy A Bystrenin gkot@altlinux.org Reviewed-by: Pavel Shilovsky pshilov@microsoft.com CC: Stable stable@vger.kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/cifs/smb2maperror.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/fs/cifs/smb2maperror.c +++ b/fs/cifs/smb2maperror.c @@ -379,8 +379,8 @@ static const struct status_to_posix_erro {STATUS_NONEXISTENT_EA_ENTRY, -EIO, "STATUS_NONEXISTENT_EA_ENTRY"}, {STATUS_NO_EAS_ON_FILE, -ENODATA, "STATUS_NO_EAS_ON_FILE"}, {STATUS_EA_CORRUPT_ERROR, -EIO, "STATUS_EA_CORRUPT_ERROR"}, - {STATUS_FILE_LOCK_CONFLICT, -EIO, "STATUS_FILE_LOCK_CONFLICT"}, - {STATUS_LOCK_NOT_GRANTED, -EIO, "STATUS_LOCK_NOT_GRANTED"}, + {STATUS_FILE_LOCK_CONFLICT, -EACCES, "STATUS_FILE_LOCK_CONFLICT"}, + {STATUS_LOCK_NOT_GRANTED, -EACCES, "STATUS_LOCK_NOT_GRANTED"}, {STATUS_DELETE_PENDING, -ENOENT, "STATUS_DELETE_PENDING"}, {STATUS_CTL_FILE_NOT_SUPPORTED, -ENOSYS, "STATUS_CTL_FILE_NOT_SUPPORTED"},
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paul Aurich paul@darkrain42.org
commit 6d2f84eee098540ae857998fe32f29b9e2cd9613 upstream.
When passing a large read to receive_encrypted_read(), ensure that the demultiplex_thread knows that a MID was processed. Without this, those operations never complete.
This is a similar issue/fix to lease break handling: commit 7af929d6d05ba5564139718e30d5bc96bdbc716a ("smb3: fix lease break problem introduced by compounding")
CC: Stable stable@vger.kernel.org # 4.19+ Fixes: b24df3e30cbf ("cifs: update receive_encrypted_standard to handle compounded responses") Signed-off-by: Paul Aurich paul@darkrain42.org Tested-by: Yves-Alexis Perez corsac@corsac.net Signed-off-by: Steve French stfrench@microsoft.com Reviewed-by: Ronnie Sahlberg lsahlber@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/cifs/smb2ops.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -3384,8 +3384,10 @@ smb3_receive_transform(struct TCP_Server }
/* TODO: add support for compounds containing READ. */ - if (pdu_length > CIFSMaxBufSize + MAX_HEADER_SIZE(server)) + if (pdu_length > CIFSMaxBufSize + MAX_HEADER_SIZE(server)) { + *num_mids = 1; return receive_encrypted_read(server, &mids[0]); + }
return receive_encrypted_standard(server, mids, bufs, num_mids); }
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Long Li longli@microsoft.com
commit 54e94ff94eac887ddb59cfd46b18896da5695e35 upstream.
When pinning memory failed, we should return the correct error code and rewind the SMB credits.
Reported-by: Murphy Zhou jencce.kernel@gmail.com Signed-off-by: Long Li longli@microsoft.com Cc: stable@vger.kernel.org Cc: Murphy Zhou jencce.kernel@gmail.com Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/cifs/file.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
--- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -2630,6 +2630,9 @@ cifs_write_from_iter(loff_t offset, size result, from->type, from->iov_offset, from->count); dump_stack(); + + rc = result; + add_credits_and_wake_if(server, credits, 0); break; } cur_len = (size_t)result; @@ -3313,13 +3316,16 @@ cifs_send_async_read(loff_t offset, size cur_len, &start); if (result < 0) { cifs_dbg(VFS, - "couldn't get user pages (cur_len=%zd)" + "couldn't get user pages (rc=%zd)" " iter type %d" " iov_offset %zd count %zd\n", result, direct_iov.type, direct_iov.iov_offset, direct_iov.count); dump_stack(); + + rc = result; + add_credits_and_wake_if(server, credits, 0); break; } cur_len = (size_t)result;
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Long Li longli@microsoft.com
commit b6bc8a7b993e62f82415a5e3e4a6469e80fea19c upstream.
The current code attempts to pin memory using the largest possible wsize based on the currect SMB credits. This doesn't cause kernel oops but this is not optimal as we may pin more pages then actually needed.
Fix this by only pinning what are needed for doing this write I/O.
Signed-off-by: Long Li longli@microsoft.com Cc: stable@vger.kernel.org Signed-off-by: Steve French stfrench@microsoft.com Reviewed-by: Joey Pabalinas joeypabalinas@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/cifs/file.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -2617,11 +2617,13 @@ cifs_write_from_iter(loff_t offset, size if (rc) break;
+ cur_len = min_t(const size_t, len, wsize); + if (ctx->direct_io) { ssize_t result;
result = iov_iter_get_pages_alloc( - from, &pagevec, wsize, &start); + from, &pagevec, cur_len, &start); if (result < 0) { cifs_dbg(VFS, "direct_writev couldn't get user pages "
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Will Deacon will.deacon@arm.com
commit df655b75c43fba0f2621680ab261083297fd6d16 upstream.
Although bit 31 of VTCR_EL2 is RES1, we inadvertently end up setting all of the upper 32 bits to 1 as well because we define VTCR_EL2_RES1 as signed, which is sign-extended when assigning to kvm->arch.vtcr.
Lucky for us, the architecture currently treats these upper bits as RES0 so, whilst we've been naughty, we haven't set fire to anything yet.
Cc: stable@vger.kernel.org Cc: Marc Zyngier marc.zyngier@arm.com Cc: Christoffer Dall christoffer.dall@arm.com Signed-off-by: Will Deacon will.deacon@arm.com Signed-off-by: Marc Zyngier marc.zyngier@arm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/arm64/include/asm/kvm_arm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/arm64/include/asm/kvm_arm.h +++ b/arch/arm64/include/asm/kvm_arm.h @@ -104,7 +104,7 @@ TCR_EL2_ORGN0_MASK | TCR_EL2_IRGN0_MASK | TCR_EL2_T0SZ_MASK)
/* VTCR_EL2 Registers bits */ -#define VTCR_EL2_RES1 (1 << 31) +#define VTCR_EL2_RES1 (1U << 31) #define VTCR_EL2_HD (1 << 22) #define VTCR_EL2_HA (1 << 21) #define VTCR_EL2_PS_SHIFT TCR_EL2_PS_SHIFT
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marc Zyngier marc.zyngier@arm.com
commit 107352a24900fb458152b92a4e72fbdc83fd5510 upstream.
We currently only halt the guest when a vCPU messes with the active state of an SPI. This is perfectly fine for GICv2, but isn't enough for GICv3, where all vCPUs can access the state of any other vCPU.
Let's broaden the condition to include any GICv3 interrupt that has an active state (i.e. all but LPIs).
Cc: stable@vger.kernel.org Reviewed-by: Christoffer Dall christoffer.dall@arm.com Signed-off-by: Marc Zyngier marc.zyngier@arm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- virt/kvm/arm/vgic/vgic-mmio.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
--- a/virt/kvm/arm/vgic/vgic-mmio.c +++ b/virt/kvm/arm/vgic/vgic-mmio.c @@ -368,14 +368,16 @@ static void vgic_mmio_change_active(stru */ static void vgic_change_active_prepare(struct kvm_vcpu *vcpu, u32 intid) { - if (intid > VGIC_NR_PRIVATE_IRQS) + if (vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3 || + intid > VGIC_NR_PRIVATE_IRQS) kvm_arm_halt_guest(vcpu->kvm); }
/* See vgic_change_active_prepare */ static void vgic_change_active_finish(struct kvm_vcpu *vcpu, u32 intid) { - if (intid > VGIC_NR_PRIVATE_IRQS) + if (vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3 || + intid > VGIC_NR_PRIVATE_IRQS) kvm_arm_resume_guest(vcpu->kvm); }
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sylwester Nawrocki s.nawrocki@samsung.com
commit 8ac686d7dfed721102860ff2571e6b9f529ae81a upstream.
The assigned parent clocks should be normally specified in the consumer device's DT node, this ensures respective driver always sees correct clock settings when required.
This patch fixes regression in audio subsystem on Odroid XU3/XU4 boards that appeared after commits:
commit 647d04f8e07a ("ASoC: samsung: i2s: Ensure the RCLK rate is properly determined") commit 995e73e55f46 ("ASoC: samsung: i2s: Fix rclk_srcrate handling") commit 48279c53fd1d ("ASoC: samsung: i2s: Prevent external abort on exynos5433 I2S1 access")
Without this patch the driver gets wrong clock as the I2S function clock (op_clk) in probe() and effectively the clock which is finally assigned from DT is not being enabled/disabled in the runtime resume/suspend ops.
Without the above listed commits the EXYNOS_I2S_BUS clock was always set as parent of CLK_I2S_RCLK_SRC regardless of DT settings so there was no issue with not enabled EXYNOS_SCLK_I2S.
Cc: stable@vger.kernel.org # 4.17.x Signed-off-by: Sylwester Nawrocki s.nawrocki@samsung.com Signed-off-by: Krzysztof Kozlowski krzk@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/arm/boot/dts/exynos5422-odroidxu3-audio.dtsi | 9 ++++----- arch/arm/boot/dts/exynos5422-odroidxu4.dts | 9 ++++----- 2 files changed, 8 insertions(+), 10 deletions(-)
--- a/arch/arm/boot/dts/exynos5422-odroidxu3-audio.dtsi +++ b/arch/arm/boot/dts/exynos5422-odroidxu3-audio.dtsi @@ -26,8 +26,7 @@ "Speakers", "SPKL", "Speakers", "SPKR";
- assigned-clocks = <&i2s0 CLK_I2S_RCLK_SRC>, - <&clock CLK_MOUT_EPLL>, + assigned-clocks = <&clock CLK_MOUT_EPLL>, <&clock CLK_MOUT_MAU_EPLL>, <&clock CLK_MOUT_USER_MAU_EPLL>, <&clock_audss EXYNOS_MOUT_AUDSS>, @@ -36,8 +35,7 @@ <&clock_audss EXYNOS_DOUT_AUD_BUS>, <&clock_audss EXYNOS_DOUT_I2S>;
- assigned-clock-parents = <&clock_audss EXYNOS_SCLK_I2S>, - <&clock CLK_FOUT_EPLL>, + assigned-clock-parents = <&clock CLK_FOUT_EPLL>, <&clock CLK_MOUT_EPLL>, <&clock CLK_MOUT_MAU_EPLL>, <&clock CLK_MAU_EPLL>, @@ -48,7 +46,6 @@ <0>, <0>, <0>, - <0>, <196608001>, <(196608002 / 2)>, <196608000>; @@ -84,4 +81,6 @@
&i2s0 { status = "okay"; + assigned-clocks = <&i2s0 CLK_I2S_RCLK_SRC>; + assigned-clock-parents = <&clock_audss EXYNOS_SCLK_I2S>; }; --- a/arch/arm/boot/dts/exynos5422-odroidxu4.dts +++ b/arch/arm/boot/dts/exynos5422-odroidxu4.dts @@ -33,8 +33,7 @@ compatible = "samsung,odroid-xu3-audio"; model = "Odroid-XU4";
- assigned-clocks = <&i2s0 CLK_I2S_RCLK_SRC>, - <&clock CLK_MOUT_EPLL>, + assigned-clocks = <&clock CLK_MOUT_EPLL>, <&clock CLK_MOUT_MAU_EPLL>, <&clock CLK_MOUT_USER_MAU_EPLL>, <&clock_audss EXYNOS_MOUT_AUDSS>, @@ -43,8 +42,7 @@ <&clock_audss EXYNOS_DOUT_AUD_BUS>, <&clock_audss EXYNOS_DOUT_I2S>;
- assigned-clock-parents = <&clock_audss EXYNOS_SCLK_I2S>, - <&clock CLK_FOUT_EPLL>, + assigned-clock-parents = <&clock CLK_FOUT_EPLL>, <&clock CLK_MOUT_EPLL>, <&clock CLK_MOUT_MAU_EPLL>, <&clock CLK_MAU_EPLL>, @@ -55,7 +53,6 @@ <0>, <0>, <0>, - <0>, <196608001>, <(196608002 / 2)>, <196608000>; @@ -79,6 +76,8 @@
&i2s0 { status = "okay"; + assigned-clocks = <&i2s0 CLK_I2S_RCLK_SRC>; + assigned-clock-parents = <&clock_audss EXYNOS_SCLK_I2S>; };
&pwm {
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maciej W. Rozycki macro@linux-mips.org
commit 3cc9ffbb1f51eb4320575a48e4805a8f52e0e26b upstream.
Add the missing adjustment of the month range on alarm reads from the RTC, correcting an issue coming from commit 9c6dfed92c3e ("rtc: m41t80: add alarm functionality"). The range is 1-12 for hardware and 0-11 for `struct rtc_time', and is already correctly handled on alarm writes to the RTC.
It was correct up until commit 48e9766726eb ("drivers/rtc/rtc-m41t80.c: remove disabled alarm functionality") too, which removed the previous implementation of alarm support.
Signed-off-by: Maciej W. Rozycki macro@linux-mips.org Fixes: 9c6dfed92c3e ("rtc: m41t80: add alarm functionality") References: 48e9766726eb ("drivers/rtc/rtc-m41t80.c: remove disabled alarm functionality") Cc: stable@vger.kernel.org # 4.7+ Signed-off-by: Alexandre Belloni alexandre.belloni@bootlin.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/rtc/rtc-m41t80.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -393,7 +393,7 @@ static int m41t80_read_alarm(struct devi alrm->time.tm_min = bcd2bin(alarmvals[3] & 0x7f); alrm->time.tm_hour = bcd2bin(alarmvals[2] & 0x3f); alrm->time.tm_mday = bcd2bin(alarmvals[1] & 0x3f); - alrm->time.tm_mon = bcd2bin(alarmvals[0] & 0x3f); + alrm->time.tm_mon = bcd2bin(alarmvals[0] & 0x3f) - 1;
alrm->enabled = !!(alarmvals[0] & M41T80_ALMON_AFE); alrm->pending = (flags & M41T80_FLAGS_AF) && alrm->enabled;
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Julien Thierry julien.thierry@arm.com
commit 2e2f6c3c0b08eed3fcf7de3c7684c940451bdeb1 upstream.
To change the active state of an MMIO, halt is requested for all vcpus of the affected guest before modifying the IRQ state. This is done by calling cond_resched_lock() in vgic_mmio_change_active(). However interrupts are disabled at this point and we cannot reschedule a vcpu.
We actually don't need any of this, as kvm_arm_halt_guest ensures that all the other vcpus are out of the guest. Let's just drop that useless code.
Signed-off-by: Julien Thierry julien.thierry@arm.com Suggested-by: Christoffer Dall christoffer.dall@arm.com Cc: stable@vger.kernel.org Signed-off-by: Marc Zyngier marc.zyngier@arm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- virt/kvm/arm/vgic/vgic-mmio.c | 21 --------------------- 1 file changed, 21 deletions(-)
--- a/virt/kvm/arm/vgic/vgic-mmio.c +++ b/virt/kvm/arm/vgic/vgic-mmio.c @@ -313,27 +313,6 @@ static void vgic_mmio_change_active(stru
spin_lock_irqsave(&irq->irq_lock, flags);
- /* - * If this virtual IRQ was written into a list register, we - * have to make sure the CPU that runs the VCPU thread has - * synced back the LR state to the struct vgic_irq. - * - * As long as the conditions below are true, we know the VCPU thread - * may be on its way back from the guest (we kicked the VCPU thread in - * vgic_change_active_prepare) and still has to sync back this IRQ, - * so we release and re-acquire the spin_lock to let the other thread - * sync back the IRQ. - * - * When accessing VGIC state from user space, requester_vcpu is - * NULL, which is fine, because we guarantee that no VCPUs are running - * when accessing VGIC state from user space so irq->vcpu->cpu is - * always -1. - */ - while (irq->vcpu && /* IRQ may have state in an LR somewhere */ - irq->vcpu != requester_vcpu && /* Current thread is not the VCPU thread */ - irq->vcpu->cpu != -1) /* VCPU thread is running */ - cond_resched_lock(&irq->irq_lock); - if (irq->hw) { vgic_hw_irq_change_active(vcpu, irq, active, !requester_vcpu); } else {
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marc Zyngier marc.zyngier@arm.com
commit bea2ef803ade3359026d5d357348842bca9edcf1 upstream.
SPIs should be checked against the VMs specific configuration, and not the architectural maximum.
Cc: stable@vger.kernel.org Signed-off-by: Marc Zyngier marc.zyngier@arm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- virt/kvm/arm/vgic/vgic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/virt/kvm/arm/vgic/vgic.c +++ b/virt/kvm/arm/vgic/vgic.c @@ -108,8 +108,8 @@ struct vgic_irq *vgic_get_irq(struct kvm }
/* SPIs */ - if (intid <= VGIC_MAX_SPI) { - intid = array_index_nospec(intid, VGIC_MAX_SPI); + if (intid < (kvm->arch.vgic.nr_spis + VGIC_NR_PRIVATE_IRQS)) { + intid = array_index_nospec(intid, kvm->arch.vgic.nr_spis + VGIC_NR_PRIVATE_IRQS); return &kvm->arch.vgic.spis[intid - VGIC_NR_PRIVATE_IRQS]; }
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoffer Dall christoffer.dall@arm.com
commit 60c3ab30d8c2ff3a52606df03f05af2aae07dc6b upstream.
When restoring the active state from userspace, we don't know which CPU was the source for the active state, and this is not architecturally exposed in any of the register state.
Set the active_source to 0 in this case. In the future, we can expand on this and exposse the information as additional information to userspace for GICv2 if anyone cares.
Cc: stable@vger.kernel.org Signed-off-by: Christoffer Dall christoffer.dall@arm.com Signed-off-by: Marc Zyngier marc.zyngier@arm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- virt/kvm/arm/vgic/vgic-mmio.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-)
--- a/virt/kvm/arm/vgic/vgic-mmio.c +++ b/virt/kvm/arm/vgic/vgic-mmio.c @@ -317,11 +317,26 @@ static void vgic_mmio_change_active(stru vgic_hw_irq_change_active(vcpu, irq, active, !requester_vcpu); } else { u32 model = vcpu->kvm->arch.vgic.vgic_model; + u8 active_source;
irq->active = active; + + /* + * The GICv2 architecture indicates that the source CPUID for + * an SGI should be provided during an EOI which implies that + * the active state is stored somewhere, but at the same time + * this state is not architecturally exposed anywhere and we + * have no way of knowing the right source. + * + * This may lead to a VCPU not being able to receive + * additional instances of a particular SGI after migration + * for a GICv2 VM on some GIC implementations. Oh well. + */ + active_source = (requester_vcpu) ? requester_vcpu->vcpu_id : 0; + if (model == KVM_DEV_TYPE_ARM_VGIC_V2 && active && vgic_irq_is_sgi(irq->intid)) - irq->active_source = requester_vcpu->vcpu_id; + irq->active_source = active_source; }
if (irq->active)
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoffer Dall christoffer.dall@arm.com
commit fb544d1ca65a89f7a3895f7531221ceeed74ada7 upstream.
We recently addressed a VMID generation race by introducing a read/write lock around accesses and updates to the vmid generation values.
However, kvm_arch_vcpu_ioctl_run() also calls need_new_vmid_gen() but does so without taking the read lock.
As far as I can tell, this can lead to the same kind of race:
VM 0, VCPU 0 VM 0, VCPU 1 ------------ ------------ update_vttbr (vmid 254) update_vttbr (vmid 1) // roll over read_lock(kvm_vmid_lock); force_vm_exit() local_irq_disable need_new_vmid_gen == false //because vmid gen matches
enter_guest (vmid 254) kvm_arch.vttbr = <PGD>:<VMID 1> read_unlock(kvm_vmid_lock);
enter_guest (vmid 1)
Which results in running two VCPUs in the same VM with different VMIDs and (even worse) other VCPUs from other VMs could now allocate clashing VMID 254 from the new generation as long as VCPU 0 is not exiting.
Attempt to solve this by making sure vttbr is updated before another CPU can observe the updated VMID generation.
Cc: stable@vger.kernel.org Fixes: f0cf47d939d0 "KVM: arm/arm64: Close VMID generation race" Reviewed-by: Julien Thierry julien.thierry@arm.com Signed-off-by: Christoffer Dall christoffer.dall@arm.com Signed-off-by: Marc Zyngier marc.zyngier@arm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- virt/kvm/arm/arm.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-)
--- a/virt/kvm/arm/arm.c +++ b/virt/kvm/arm/arm.c @@ -66,7 +66,7 @@ static DEFINE_PER_CPU(struct kvm_vcpu *, static atomic64_t kvm_vmid_gen = ATOMIC64_INIT(1); static u32 kvm_next_vmid; static unsigned int kvm_vmid_bits __read_mostly; -static DEFINE_RWLOCK(kvm_vmid_lock); +static DEFINE_SPINLOCK(kvm_vmid_lock);
static bool vgic_present;
@@ -484,7 +484,9 @@ void force_vm_exit(const cpumask_t *mask */ static bool need_new_vmid_gen(struct kvm *kvm) { - return unlikely(kvm->arch.vmid_gen != atomic64_read(&kvm_vmid_gen)); + u64 current_vmid_gen = atomic64_read(&kvm_vmid_gen); + smp_rmb(); /* Orders read of kvm_vmid_gen and kvm->arch.vmid */ + return unlikely(READ_ONCE(kvm->arch.vmid_gen) != current_vmid_gen); }
/** @@ -499,16 +501,11 @@ static void update_vttbr(struct kvm *kvm { phys_addr_t pgd_phys; u64 vmid, cnp = kvm_cpu_has_cnp() ? VTTBR_CNP_BIT : 0; - bool new_gen;
- read_lock(&kvm_vmid_lock); - new_gen = need_new_vmid_gen(kvm); - read_unlock(&kvm_vmid_lock); - - if (!new_gen) + if (!need_new_vmid_gen(kvm)) return;
- write_lock(&kvm_vmid_lock); + spin_lock(&kvm_vmid_lock);
/* * We need to re-check the vmid_gen here to ensure that if another vcpu @@ -516,7 +513,7 @@ static void update_vttbr(struct kvm *kvm * use the same vmid. */ if (!need_new_vmid_gen(kvm)) { - write_unlock(&kvm_vmid_lock); + spin_unlock(&kvm_vmid_lock); return; }
@@ -539,7 +536,6 @@ static void update_vttbr(struct kvm *kvm kvm_call_hyp(__kvm_flush_vm_context); }
- kvm->arch.vmid_gen = atomic64_read(&kvm_vmid_gen); kvm->arch.vmid = kvm_next_vmid; kvm_next_vmid++; kvm_next_vmid &= (1 << kvm_vmid_bits) - 1; @@ -550,7 +546,10 @@ static void update_vttbr(struct kvm *kvm vmid = ((u64)(kvm->arch.vmid) << VTTBR_VMID_SHIFT) & VTTBR_VMID_MASK(kvm_vmid_bits); kvm->arch.vttbr = kvm_phys_to_vttbr(pgd_phys) | vmid | cnp;
- write_unlock(&kvm_vmid_lock); + smp_wmb(); + WRITE_ONCE(kvm->arch.vmid_gen, atomic64_read(&kvm_vmid_gen)); + + spin_unlock(&kvm_vmid_lock); }
static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu)
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gustavo A. R. Silva gustavo@embeddedor.com
commit c23b2e6fc4ca346018618266bcabd335c0a8a49e upstream.
When using the nospec API, it should be taken into account that:
"...if the CPU speculates past the bounds check then * array_index_nospec() will clamp the index within the range of [0, * size)."
The above is part of the header for macro array_index_nospec() in linux/nospec.h
Now, in this particular case, if intid evaluates to exactly VGIC_MAX_SPI or to exaclty VGIC_MAX_PRIVATE, the array_index_nospec() macro ends up returning VGIC_MAX_SPI - 1 or VGIC_MAX_PRIVATE - 1 respectively, instead of VGIC_MAX_SPI or VGIC_MAX_PRIVATE, which, based on the original logic:
/* SGIs and PPIs */ if (intid <= VGIC_MAX_PRIVATE) return &vcpu->arch.vgic_cpu.private_irqs[intid];
/* SPIs */ if (intid <= VGIC_MAX_SPI) return &kvm->arch.vgic.spis[intid - VGIC_NR_PRIVATE_IRQS];
are valid values for intid.
Fix this by calling array_index_nospec() macro with VGIC_MAX_PRIVATE + 1 and VGIC_MAX_SPI + 1 as arguments for its parameter size.
Fixes: 41b87599c743 ("KVM: arm/arm64: vgic: fix possible spectre-v1 in vgic_get_irq()") Cc: stable@vger.kernel.org Signed-off-by: Gustavo A. R. Silva gustavo@embeddedor.com [dropped the SPI part which was fixed separately] Signed-off-by: Marc Zyngier marc.zyngier@arm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- virt/kvm/arm/vgic/vgic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/virt/kvm/arm/vgic/vgic.c +++ b/virt/kvm/arm/vgic/vgic.c @@ -103,7 +103,7 @@ struct vgic_irq *vgic_get_irq(struct kvm { /* SGIs and PPIs */ if (intid <= VGIC_MAX_PRIVATE) { - intid = array_index_nospec(intid, VGIC_MAX_PRIVATE); + intid = array_index_nospec(intid, VGIC_MAX_PRIVATE + 1); return &vcpu->arch.vgic_cpu.private_irqs[intid]; }
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Robin Murphy robin.murphy@arm.com
commit 3cd508a8c1379427afb5e16c2e0a7c986d907853 upstream.
When we insert the sync sequence number into the CMD_SYNC.MSIData field, we do so in CPU-native byte order, before writing out the whole command as explicitly little-endian dwords. Thus on big-endian systems, the SMMU will receive and write back a byteswapped version of sync_nr, which would be perfect if it were targeting a similarly-little-endian ITS, but since it's actually writing back to memory being polled by the CPUs, they're going to end up seeing the wrong thing.
Since the SMMU doesn't care what the MSIData actually contains, the minimal-overhead solution is to simply add an extra byteswap initially, such that it then writes back the big-endian format directly.
Cc: stable@vger.kernel.org Fixes: 37de98f8f1cf ("iommu/arm-smmu-v3: Use CMD_SYNC completion MSI") Signed-off-by: Robin Murphy robin.murphy@arm.com Signed-off-by: Will Deacon will.deacon@arm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/iommu/arm-smmu-v3.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
--- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -828,7 +828,13 @@ static int arm_smmu_cmdq_build_cmd(u64 * cmd[0] |= FIELD_PREP(CMDQ_SYNC_0_CS, CMDQ_SYNC_0_CS_SEV); cmd[0] |= FIELD_PREP(CMDQ_SYNC_0_MSH, ARM_SMMU_SH_ISH); cmd[0] |= FIELD_PREP(CMDQ_SYNC_0_MSIATTR, ARM_SMMU_MEMATTR_OIWB); - cmd[0] |= FIELD_PREP(CMDQ_SYNC_0_MSIDATA, ent->sync.msidata); + /* + * Commands are written little-endian, but we want the SMMU to + * receive MSIData, and thus write it back to memory, in CPU + * byte order, so big-endian needs an extra byteswap here. + */ + cmd[0] |= FIELD_PREP(CMDQ_SYNC_0_MSIDATA, + cpu_to_le32(ent->sync.msidata)); cmd[1] |= ent->sync.msiaddr & CMDQ_SYNC_1_MSIADDR_MASK; break; default:
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Will Deacon will.deacon@arm.com
commit 169113ece0f29ebe884a6cfcf57c1ace04d8a36a upstream.
The ARM Linux kernel handles the EABI syscall numbers as follows:
0 - NR_SYSCALLS-1 : Invoke syscall via syscall table NR_SYSCALLS - 0xeffff : -ENOSYS (to be allocated in future) 0xf0000 - 0xf07ff : Private syscall or -ENOSYS if not allocated
0xf07ff : SIGILL
Our compat code gets this wrong and ends up sending SIGILL in response to all syscalls greater than NR_SYSCALLS which have a value greater than 0x7ff in the bottom 16 bits.
Fix this by defining the end of the ARM private syscall region and checking the syscall number against that directly. Update the comment while we're at it.
Cc: stable@vger.kernel.org Cc: Dave Martin Dave.Martin@arm.com Reported-by: Pi-Hsun Shih pihsun@chromium.org Signed-off-by: Will Deacon will.deacon@arm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/arm64/include/asm/unistd.h | 5 +++-- arch/arm64/kernel/sys_compat.c | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-)
--- a/arch/arm64/include/asm/unistd.h +++ b/arch/arm64/include/asm/unistd.h @@ -40,8 +40,9 @@ * The following SVCs are ARM private. */ #define __ARM_NR_COMPAT_BASE 0x0f0000 -#define __ARM_NR_compat_cacheflush (__ARM_NR_COMPAT_BASE+2) -#define __ARM_NR_compat_set_tls (__ARM_NR_COMPAT_BASE+5) +#define __ARM_NR_compat_cacheflush (__ARM_NR_COMPAT_BASE + 2) +#define __ARM_NR_compat_set_tls (__ARM_NR_COMPAT_BASE + 5) +#define __ARM_NR_COMPAT_END (__ARM_NR_COMPAT_BASE + 0x800)
#define __NR_compat_syscalls 399 #endif --- a/arch/arm64/kernel/sys_compat.c +++ b/arch/arm64/kernel/sys_compat.c @@ -102,12 +102,12 @@ long compat_arm_syscall(struct pt_regs *
default: /* - * Calls 9f00xx..9f07ff are defined to return -ENOSYS + * Calls 0xf0xxx..0xf07ff are defined to return -ENOSYS * if not implemented, rather than raising SIGILL. This * way the calling program can gracefully determine whether * a feature is supported. */ - if ((no & 0xffff) <= 0x7ff) + if (no < __ARM_NR_COMPAT_END) return -ENOSYS; break; }
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Will Deacon will.deacon@arm.com
commit 53290432145a8eb143fe29e06e9c1465d43dc723 upstream.
The syscall number may have been changed by a tracer, so we should pass the actual number in from the caller instead of pulling it from the saved r7 value directly.
Cc: stable@vger.kernel.org Cc: Pi-Hsun Shih pihsun@chromium.org Reviewed-by: Dave Martin Dave.Martin@arm.com Signed-off-by: Will Deacon will.deacon@arm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/arm64/kernel/sys_compat.c | 9 ++++----- arch/arm64/kernel/syscall.c | 9 ++++----- 2 files changed, 8 insertions(+), 10 deletions(-)
--- a/arch/arm64/kernel/sys_compat.c +++ b/arch/arm64/kernel/sys_compat.c @@ -66,12 +66,11 @@ do_compat_cache_op(unsigned long start, /* * Handle all unrecognised system calls. */ -long compat_arm_syscall(struct pt_regs *regs) +long compat_arm_syscall(struct pt_regs *regs, int scno) { - unsigned int no = regs->regs[7]; void __user *addr;
- switch (no) { + switch (scno) { /* * Flush a region from virtual address 'r0' to virtual address 'r1' * _exclusive_. There is no alignment requirement on either address; @@ -107,7 +106,7 @@ long compat_arm_syscall(struct pt_regs * * way the calling program can gracefully determine whether * a feature is supported. */ - if (no < __ARM_NR_COMPAT_END) + if (scno < __ARM_NR_COMPAT_END) return -ENOSYS; break; } @@ -116,6 +115,6 @@ long compat_arm_syscall(struct pt_regs * (compat_thumb_mode(regs) ? 2 : 4);
arm64_notify_die("Oops - bad compat syscall(2)", regs, - SIGILL, ILL_ILLTRP, addr, no); + SIGILL, ILL_ILLTRP, addr, scno); return 0; } --- a/arch/arm64/kernel/syscall.c +++ b/arch/arm64/kernel/syscall.c @@ -13,16 +13,15 @@ #include <asm/thread_info.h> #include <asm/unistd.h>
-long compat_arm_syscall(struct pt_regs *regs); - +long compat_arm_syscall(struct pt_regs *regs, int scno); long sys_ni_syscall(void);
-asmlinkage long do_ni_syscall(struct pt_regs *regs) +static long do_ni_syscall(struct pt_regs *regs, int scno) { #ifdef CONFIG_COMPAT long ret; if (is_compat_task()) { - ret = compat_arm_syscall(regs); + ret = compat_arm_syscall(regs, scno); if (ret != -ENOSYS) return ret; } @@ -47,7 +46,7 @@ static void invoke_syscall(struct pt_reg syscall_fn = syscall_table[array_index_nospec(scno, sc_nr)]; ret = __invoke_syscall(regs, syscall_fn); } else { - ret = do_ni_syscall(regs); + ret = do_ni_syscall(regs, scno); }
regs->regs[0] = ret;
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Helge Deller deller@gmx.de
commit dfbaecb2b707cfdc5276b548d52b437384bd6483 upstream.
The alternative coding patch for parisc in kernel 4.20 broke booting machines with PA8500-PA8700 CPUs. The problem is, that for such machines the parisc kernel automatically utilizes huge pages to access kernel text code, but the set_kernel_text_rw() function, which is used shortly before applying any alternative patches, didn't used the correctly hugepage-aligned addresses to remap the kernel text read-writeable.
Fixes: 3847dab77421 ("parisc: Add alternative coding infrastructure") Cc: stable@vger.kernel.org [4.20] Signed-off-by: Helge Deller deller@gmx.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/parisc/mm/init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/arch/parisc/mm/init.c +++ b/arch/parisc/mm/init.c @@ -512,8 +512,8 @@ static void __init map_pages(unsigned lo
void __init set_kernel_text_rw(int enable_read_write) { - unsigned long start = (unsigned long)__init_begin; - unsigned long end = (unsigned long)_etext; + unsigned long start = (unsigned long) _text; + unsigned long end = (unsigned long) &data_start;
map_pages(start, __pa(start), end-start, PAGE_KERNEL_RWX, enable_read_write ? 1:0);
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tomas Winkler tomas.winkler@intel.com
commit 01f54664a4db0d612de0ece8e0022f21f9374e9b upstream.
First, rename out_no_locality to out_locality for bailing out on both tpm_cmd_ready() and tpm_request_locality() failure. Second, ignore the return value of go_to_idle() as it may override the return value of the actual tpm operation, the go_to_idle() error will be caught on any consequent command. Last, fix the wrong 'goto out', that jumped back instead of forward.
Cc: stable@vger.kernel.org Fixes: 627448e85c76 ("tpm: separate cmd_ready/go_idle from runtime_pm") Signed-off-by: Tomas Winkler tomas.winkler@intel.com Reviewed-by: Jarkko Sakkinen jarkko.sakkinen@linux.intel.com Tested-by: Jarkko Sakkinen jarkko.sakkinen@linux.intel.com Signed-off-by: Jarkko Sakkinen jarkko.sakkinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/char/tpm/tpm-interface.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-)
--- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c @@ -477,13 +477,15 @@ static ssize_t tpm_try_transmit(struct t
if (need_locality) { rc = tpm_request_locality(chip, flags); - if (rc < 0) - goto out_no_locality; + if (rc < 0) { + need_locality = false; + goto out_locality; + } }
rc = tpm_cmd_ready(chip, flags); if (rc) - goto out; + goto out_locality;
rc = tpm2_prepare_space(chip, space, ordinal, buf); if (rc) @@ -547,14 +549,13 @@ out_recv: dev_err(&chip->dev, "tpm2_commit_space: error %d\n", rc);
out: - rc = tpm_go_idle(chip, flags); - if (rc) - goto out; + /* may fail but do not override previous error value in rc */ + tpm_go_idle(chip, flags);
+out_locality: if (need_locality) tpm_relinquish_locality(chip, flags);
-out_no_locality: if (chip->ops->clk_enable != NULL) chip->ops->clk_enable(chip, false);
4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tomas Winkler tomas.winkler@intel.com
commit 2ba5780ce30549cf57929b01d8cba6fe656e31c5 upstream.
tpm_i2c_nuvoton calculated commands duration using TPM 1.x values via tpm_calc_ordinal_duration() also for TPM 2.x chips. Call tpm2_calc_ordinal_duration() for retrieving ordinal duration for TPM 2.X chips.
Cc: stable@vger.kernel.org Cc: Nayna Jain nayna@linux.vnet.ibm.com Signed-off-by: Tomas Winkler tomas.winkler@intel.com Reviewed-by: Nayna Jain nayna@linux.ibm.com Tested-by: Nayna Jain nayna@linux.ibm.com (For TPM 2.0) Reviewed-by: Jarkko Sakkinen jarkko.sakkinen@linux.intel.com Signed-off-by: Jarkko Sakkinen jarkko.sakkinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/char/tpm/tpm_i2c_nuvoton.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
--- a/drivers/char/tpm/tpm_i2c_nuvoton.c +++ b/drivers/char/tpm/tpm_i2c_nuvoton.c @@ -369,6 +369,7 @@ static int i2c_nuvoton_send(struct tpm_c struct device *dev = chip->dev.parent; struct i2c_client *client = to_i2c_client(dev); u32 ordinal; + unsigned long duration; size_t count = 0; int burst_count, bytes2write, retries, rc = -EIO;
@@ -455,10 +456,12 @@ static int i2c_nuvoton_send(struct tpm_c return rc; } ordinal = be32_to_cpu(*((__be32 *) (buf + 6))); - rc = i2c_nuvoton_wait_for_data_avail(chip, - tpm_calc_ordinal_duration(chip, - ordinal), - &priv->read_queue); + if (chip->flags & TPM_CHIP_FLAG_TPM2) + duration = tpm2_calc_ordinal_duration(chip, ordinal); + else + duration = tpm_calc_ordinal_duration(chip, ordinal); + + rc = i2c_nuvoton_wait_for_data_avail(chip, duration, &priv->read_queue); if (rc) { dev_err(dev, "%s() timeout command duration\n", __func__); i2c_nuvoton_ready(chip);
On Mon, Jan 07, 2019 at 01:30:37PM +0100, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.20.1 release. There are 145 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed Jan 9 10:43:39 UTC 2019. Anything received after that time might be too late.
[ partial results, qemu tests incomplete ]
Build results: total: 158 pass: 154 fail: 4 Failed builds: arm:allmodconfig mips:allmodconfig parisc:allmodconfig xtensa:allmodconfig Qemu test results: total: 332 pass: 331 fail: 1 Failed tests: mipsel64:fuloong2e_defconfig:fulong2e:rootfs
For the allmodconfig builds:
ERROR: "__bad_cmpxchg" [drivers/spi/spi-bcm2835.ko] undefined!
Qemu/mips64:
Building mipsel64:fuloong2e_defconfig:fulong2e:rootfs ... failed ------------ Error log: In file included from ./arch/mips/include/asm/mmzone.h:10:0, from ./arch/mips/include/asm/r4kcache.h:23, from arch/mips/mm/c-r4k.c:33: ./arch/mips/include/asm/mach-loongson64/mmzone.h:48:0: error: "NODE_DATA" redefined
Guenter
On Mon, Jan 07, 2019 at 01:30:37PM +0100, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.20.1 release. There are 145 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed Jan 9 10:43:39 UTC 2019. Anything received after that time might be too late.
Build results: total: 158 pass: 154 fail: 4 Failed builds: arm:allmodconfig mips:allmodconfig parisc:allmodconfig xtensa:allmodconfig Qemu test results: total: 332 pass: 327 fail: 5 Failed tests: mipsel64:fuloong2e_defconfig:fulong2e:rootfs sh:rts7751r2dplus_defconfig:nvme:rootfs sh:rts7751r2dplus_defconfig:usb:rootfs sh:rts7751r2dplus_defconfig:usb-hub:rootfs sh:rts7751r2dplus_defconfig:usb-ohci:rootfs
--- Build errors:
ERROR: "__bad_cmpxchg" [drivers/spi/spi-bcm2835.ko] undefined!
Qemu errors:
Building mipsel64:fuloong2e_defconfig:fulong2e:rootfs ... failed ------------ Error log: In file included from ./arch/mips/include/asm/mmzone.h:10:0, from ./arch/mips/include/asm/r4kcache.h:23, from arch/mips/mm/c-r4k.c:33: ./arch/mips/include/asm/mach-loongson64/mmzone.h:48:0: error: "NODE_DATA" redefined
sh images fail silently. That may be a recently introduced spurious problem. I'll try to track that down.
Guenter
On Mon, Jan 07, 2019 at 01:17:49PM -0800, Guenter Roeck wrote:
On Mon, Jan 07, 2019 at 01:30:37PM +0100, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.20.1 release. There are 145 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed Jan 9 10:43:39 UTC 2019. Anything received after that time might be too late.
Build results: total: 158 pass: 154 fail: 4 Failed builds: arm:allmodconfig mips:allmodconfig parisc:allmodconfig xtensa:allmodconfig Qemu test results: total: 332 pass: 327 fail: 5 Failed tests: mipsel64:fuloong2e_defconfig:fulong2e:rootfs sh:rts7751r2dplus_defconfig:nvme:rootfs sh:rts7751r2dplus_defconfig:usb:rootfs sh:rts7751r2dplus_defconfig:usb-hub:rootfs sh:rts7751r2dplus_defconfig:usb-ohci:rootfs
Build errors:
ERROR: "__bad_cmpxchg" [drivers/spi/spi-bcm2835.ko] undefined!
Found the fix for this thanks.
Qemu errors:
Building mipsel64:fuloong2e_defconfig:fulong2e:rootfs ... failed
Error log: In file included from ./arch/mips/include/asm/mmzone.h:10:0, from ./arch/mips/include/asm/r4kcache.h:23, from arch/mips/mm/c-r4k.c:33: ./arch/mips/include/asm/mach-loongson64/mmzone.h:48:0: error: "NODE_DATA" redefined
This one is odd, let me dig...
thanks,
greg k-h
On Tue, Jan 08, 2019 at 08:45:18AM +0100, Greg Kroah-Hartman wrote:
On Mon, Jan 07, 2019 at 01:17:49PM -0800, Guenter Roeck wrote:
On Mon, Jan 07, 2019 at 01:30:37PM +0100, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.20.1 release. There are 145 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed Jan 9 10:43:39 UTC 2019. Anything received after that time might be too late.
Building mipsel64:fuloong2e_defconfig:fulong2e:rootfs ... failed
Error log: In file included from ./arch/mips/include/asm/mmzone.h:10:0, from ./arch/mips/include/asm/r4kcache.h:23, from arch/mips/mm/c-r4k.c:33: ./arch/mips/include/asm/mach-loongson64/mmzone.h:48:0: error: "NODE_DATA" redefined
This one is odd, let me dig...
Ok, commit 66a4059ba72c ("MIPS: Only include mmzone.h when CONFIG_NEED_MULTIPLE_NODES=y") is supposed to fix this issue, but that is included here already.
So I don't know what to suggest, does this issue also show up in Linus's tree?
Paul, any ideas what is happening here?
thanks,
greg k-h
On Tue, Jan 08, 2019 at 10:33:10AM +0100, Greg Kroah-Hartman wrote:
On Tue, Jan 08, 2019 at 08:45:18AM +0100, Greg Kroah-Hartman wrote:
On Mon, Jan 07, 2019 at 01:17:49PM -0800, Guenter Roeck wrote:
On Mon, Jan 07, 2019 at 01:30:37PM +0100, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.20.1 release. There are 145 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed Jan 9 10:43:39 UTC 2019. Anything received after that time might be too late.
Building mipsel64:fuloong2e_defconfig:fulong2e:rootfs ... failed
Error log: In file included from ./arch/mips/include/asm/mmzone.h:10:0, from ./arch/mips/include/asm/r4kcache.h:23, from arch/mips/mm/c-r4k.c:33: ./arch/mips/include/asm/mach-loongson64/mmzone.h:48:0: error: "NODE_DATA" redefined
This one is odd, let me dig...
Ok, commit 66a4059ba72c ("MIPS: Only include mmzone.h when CONFIG_NEED_MULTIPLE_NODES=y") is supposed to fix this issue, but that is included here already.
Nope, it wasn't in the trees, my fault, now added, hopefully this fixes the issue.
thanks,
greg k-h
On 1/7/19 5:30 AM, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.20.1 release. There are 145 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed Jan 9 10:43:39 UTC 2019. 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.20.1-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.20.y and the diffstat can be found below.
thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks, -- Shuah
On Mon, Jan 07, 2019 at 03:36:48PM -0700, shuah wrote:
On 1/7/19 5:30 AM, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.20.1 release. There are 145 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed Jan 9 10:43:39 UTC 2019. 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.20.1-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.20.y and the diffstat can be found below.
thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks for testing all of these and letting me know.
greg k-h
On Mon, 7 Jan 2019 at 18:04, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 4.20.1 release. There are 145 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed Jan 9 10:43:39 UTC 2019. 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.20.1-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.20.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.20.1-rc1 git repo: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git git branch: linux-4.20.y git commit: b3b71d0e3c63a729d9d98c74e0a2db10b4133d9e git describe: v4.20-146-gb3b71d0e3c63 Test details: https://qa-reports.linaro.org/lkft/linux-stable-rc-4.20-oe/build/v4.20-146-g...
No regressions (compared to build v4.20-46-g6fb31b79ec72)
No fixes (compared to build v4.20-46-g6fb31b79ec72)
Ran 20523 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 ----------- * boot * install-android-platform-tools-r2600 * kselftest * libhugetlbfs * ltp-cap_bounds-tests * ltp-containers-tests * ltp-cpuhotplug-tests * ltp-cve-tests * ltp-fcntl-locktests-tests * ltp-filecaps-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-nptl-tests * ltp-pty-tests * ltp-sched-tests * ltp-securebits-tests * ltp-syscalls-tests * ltp-timers-tests * spectre-meltdown-checker-test * ltp-fs-tests * ltp-open-posix-tests * kselftest-vsyscall-mode-native * kselftest-vsyscall-mode-none
On Tue, Jan 08, 2019 at 04:28:53PM +0530, Naresh Kamboju wrote:
On Mon, 7 Jan 2019 at 18:04, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 4.20.1 release. There are 145 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed Jan 9 10:43:39 UTC 2019. 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.20.1-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.20.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.
Thanks for testing all of these and letting me know.
greg k-h
On Mon, Jan 07, 2019 at 01:30:37PM +0100, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.20.1 release. There are 145 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed Jan 9 10:43:39 UTC 2019. 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.20.1-rc1....
-rc2 is out: https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.20.1-rc2....
Hello,
Don't have anything against listed patches, just curious: doesn't upstream commit 574823bfab82d9d8fa47f422778043fbb4b4f50e (Change mincore() to count "mapped" pages rather than "cached" pages) need to be backported as a security fix for CVE-2019-5489[1] to stable kernels?
[1] https://www.openwall.com/lists/oss-security/2019/01/07/2
On Tue, Jan 08, 2019 at 07:39:44PM +0000, Dmitrii Tcvetkov wrote:
Hello,
Don't have anything against listed patches, just curious: doesn't upstream commit 574823bfab82d9d8fa47f422778043fbb4b4f50e (Change mincore() to count "mapped" pages rather than "cached" pages) need to be backported as a security fix for CVE-2019-5489[1] to stable kernels?
[1] https://www.openwall.com/lists/oss-security/2019/01/07/2
Please read the email thread for that patch on the linux kernel mailing list as to why it is not to be applied at this point in time.
If you are worried about this issue, please weigh in on that thread.
thanks,
greg k-h
On Mon, Jan 07, 2019 at 01:30:37PM +0100, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.20.1 release. There are 145 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed Jan 9 10:43:39 UTC 2019. Anything received after that time might be too late.
For v4.20-146-g212b8222d189:
Build results: total: 158 pass: 158 fail: 0 Qemu test results: total: 332 pass: 332 fail: 0
Guenter
linux-stable-mirror@lists.linaro.org