This is the start of the stable review cycle for the 4.16.4 release. There are 196 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Tue Apr 24 13:50:16 UTC 2018. 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.16.4-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.16.y and the diffstat can be found below.
thanks,
greg k-h
------------- Pseudo-Shortlog of commits:
Greg Kroah-Hartman gregkh@linuxfoundation.org Linux 4.16.4-rc1
Greg Thelen gthelen@google.com writeback: safer lock nesting
Jiri Kosina jkosina@suse.cz HID: i2c-hid: fix inverted return value from i2c_hid_command()
Weinan Li weinan.z.li@intel.com drm/i915/gvt: init mmio by lri command in vgpu inhibit context
Matthew Wilcox mawilcox@microsoft.com mm/filemap.c: fix NULL pointer in page_cache_tree_insert()
Ian Kent raven@themaw.net autofs: mount point create should honour passed in mode
Dave Jiang dave.jiang@intel.com device-dax: allow MAP_SYNC to succeed
Dan Williams dan.j.williams@intel.com libnvdimm, dimm: handle EACCES failures from label reads
Al Viro viro@zeniv.linux.org.uk Don't leak MNT_INTERNAL away from internal mounts
Al Viro viro@zeniv.linux.org.uk rpc_pipefs: fix double-dput()
Al Viro viro@zeniv.linux.org.uk orangefs_kill_sb(): deal with allocation failures
Al Viro viro@zeniv.linux.org.uk hypfs_kill_super(): deal with failed allocations
Al Viro viro@zeniv.linux.org.uk jffs2_kill_sb(): deal with failed allocations
Ville Syrjälä ville.syrjala@linux.intel.com drm/i915: Correctly handle limited range YCbCr data on VLV/CHV
Imre Deak imre.deak@intel.com drm/i915: Fix hibernation with ACPI S0 target state
Daniel Kurtz djkurtz@chromium.org mmc: sdhci-pci: Only do AMD tuning for HS200
Amir Goldstein amir73il@gmail.com fanotify: fix logic of events on child
Jan Kara jack@suse.cz udf: Fix leak of UTF-16 surrogates into encoded strings
Michael Ellerman mpe@ellerman.id.au powerpc/lib: Fix off-by-one in alternate feature patching
Benjamin Herrenschmidt benh@kernel.crashing.org powerpc/xive: Fix trying to "push" an already active pool VP
Michael Neuling mikey@neuling.org powerpc/eeh: Fix enabling bridge MMIO windows
Matt Redfearn matt.redfearn@mips.com MIPS: memset.S: Fix clobber of v1 in last_fixup
Matt Redfearn matt.redfearn@mips.com MIPS: memset.S: Fix return of __clear_user from Lpartial_fixup
Matt Redfearn matt.redfearn@mips.com MIPS: memset.S: EVA & fault support for small_memset
Matt Redfearn matt.redfearn@mips.com MIPS: uaccess: Add micromips clobbers to bzero invocation
Heiko Carstens heiko.carstens@de.ibm.com s390: add support for IBM z14 Model ZR1
Aaron Armstrong Skomra skomra@gmail.com HID: wacom: bluetooth: send exit report for recent Bluetooth devices
Rodrigo Rivas Costa rodrigorivascosta@gmail.com HID: hidraw: Fix crash on HIDIOCGFEATURE with a destroyed device
Dmitry Torokhov dmitry.torokhov@gmail.com HID: input: fix battery level reporting on BT mice
Aaron Ma aaron.ma@canonical.com HID: i2c-hid: Fix resume issue on Raydium touchscreen device
Theodore Ts'o tytso@mit.edu random: add new ioctl RNDRESEEDCRNG
Theodore Ts'o tytso@mit.edu random: crng_reseed() should lock the crng instance that it is modifying
Theodore Ts'o tytso@mit.edu random: set up the NUMA crng instances after the CRNG is fully initialized
Theodore Ts'o tytso@mit.edu random: use a different mixing algorithm for add_device_randomness()
Theodore Ts'o tytso@mit.edu random: fix crng_ready() test
Hui Wang hui.wang@canonical.com ALSA: hda/realtek - adjust the location of one mic
Hui Wang hui.wang@canonical.com ALSA: hda/realtek - set PINCFG_HEADSET_MIC to parse_flags
David Wang davidwang@zhaoxin.com ALSA: hda - New VIA controller suppor no-snoop path
Takashi Iwai tiwai@suse.de ALSA: rawmidi: Fix missing input substream checks in compat ioctls
Fabián Inostroza soulsonceonfire@gmail.com ALSA: line6: Use correct endpoint type for midi output
Paul Parsons lost.distance@yahoo.com drm/radeon: Fix PCIe lane width calculation
Nico Sneck nicosneck@hotmail.com drm/radeon: add PX quirk for Asus K73TK
Marc Zyngier marc.zyngier@arm.com drm/rockchip: Clear all interrupts before requesting the IRQ
Alex Deucher alexander.deucher@amd.com drm/amdgpu/si: implement get/set pcie_lanes asic callback
Alex Deucher alexander.deucher@amd.com drm/amdgpu: Fix PCIe lane width calculation
Alex Deucher alexander.deucher@amd.com drm/amdgpu/sdma: fix mask in emit_pipeline_sync
Bas Nieuwenhuizen basni@chromium.org drm/amdgpu: Fix always_valid bos multiple LRU insertions.
Alex Deucher alexander.deucher@amd.com drm/amdgpu: Add an ATPX quirk for hybrid laptop
Igor Pylypiv igor.pylypiv@gmail.com watchdog: f71808e_wdt: Fix WD_EN register read
Sean Wang sean.wang@mediatek.com dt-bindings: clock: mediatek: add binding for fixed-factor clock axisel_d4
Mikhail Lappo mikhail.lappo@esrlabs.com thermal: imx: Fix race condition in imx_thermal_probe()
Sean Wang sean.wang@mediatek.com pwm: mediatek: Improve precision in rate calculation
Sean Wang sean.wang@mediatek.com pwm: mediatek: Fix up PWM4 and PWM5 malfunction on MT7623
Ryo Kodama ryo.kodama.vz@renesas.com pwm: rcar: Fix a condition to prevent mismatch value setting to duty
Dmitry Osipenko digetx@gmail.com clk: tegra: Mark HCLK, SCLK and EMC as critical
Boris Brezillon boris.brezillon@bootlin.com clk: bcm2835: De-assert/assert PLL reset signal when appropriate
Sean Wang sean.wang@mediatek.com clk: mediatek: fix PWM clock source by adding a fixed-factor clock
Arnd Bergmann arnd@arndb.de clk: fix false-positive Wmaybe-uninitialized warning
Richard Genoud richard.genoud@gmail.com clk: mvebu: armada-38x: add support for missing clocks
Sinan Kaya okaya@codeaurora.org PCI: Mark Broadcom HT1100 and HT2000 Root Port Extended Tags as broken
Ravi Bangoria ravi.bangoria@linux.vnet.ibm.com trace_uprobe: Use %lx to display offset
Charlene Liu charlene.liu@amd.com drm/amd/display: HDMI has no sound after Panel power off/on
Harry Wentland harry.wentland@amd.com Revert "drm/amd/display: disable CRTCs with NULL FB on their primary plane (V2)"
Harry Wentland harry.wentland@amd.com Revert "drm/amd/display: fix dereferencing possible ERR_PTR()"
Masaharu Hayakawa masaharu.hayakawa.ry@renesas.com mmc: tmio: Fix error handling when issuing CMD23
Alex Smith alex.smith@imgtec.com mmc: jz4740: Fix race condition in IRQ mask update
Alexander Kappner agk@godking.net mmc: core: Prevent bus reference leak in mmc_blk_init()
Lu Baolu baolu.lu@linux.intel.com iommu/vt-d: Fix a potential memory leak
Krzysztof Mazur krzysiek@podlesie.net um: Use POSIX ucontext_t instead of struct ucontext
Jason A. Donenfeld Jason@zx2c4.com um: Compile with modern headers
Steven Rostedt (VMware) rostedt@goodmis.org ring-buffer: Check if memory is available before allocation
Dan Williams dan.j.williams@intel.com nfit: skip region registration for incomplete control regions
Dan Williams dan.j.williams@intel.com nfit, address-range-scrub: fix scrub in-progress reporting
Steven Rostedt (VMware) rostedt@goodmis.org vsprintf: Do not preprocess non-dereferenced pointers for bprintf (%px and %pK)
Dan Williams dan.j.williams@intel.com libnvdimm, namespace: use a safe lookup for dimm device name
Dan Williams dan.j.williams@intel.com libnvdimm, dimm: fix dpa reservation vs uninitialized label area
Chris Chiu chiu@endlessm.com tpm: self test failure should not cause suspend to fail
Frederic Barrat fbarrat@linux.vnet.ibm.com cxl: Fix possible deadlock when processing page faults from cxllib
Maxime Jayat maxime.jayat@mobile-devices.fr dmaengine: at_xdmac: fix rare residue corruption
Heinz Mauelshagen heinzm@redhat.com dm raid: fix nosync status
Andrew Morton akpm@linux-foundation.org drivers/infiniband/ulp/srpt/ib_srpt.c: fix build with gcc-4.4.4
Andrew Morton akpm@linux-foundation.org drivers/infiniband/core/verbs.c: fix build with gcc-4.4.4
Bart Van Assche bart.vanassche@wdc.com IB/srpt: Fix an out-of-bounds stack access in srpt_zerolength_write()
Bart Van Assche bart.vanassche@wdc.com IB/srp: Fix completion vector assignment algorithm
Bart Van Assche bart.vanassche@wdc.com IB/srp: Fix srp_abort()
Takashi Iwai tiwai@suse.de ALSA: pcm: Fix endless loop for XRUN recovery in OSS emulation
Takashi Iwai tiwai@suse.de ALSA: pcm: Fix UAF at PCM release via PCM timer access
Takashi Iwai tiwai@suse.de ALSA: pcm: Fix mutex unbalance in OSS emulation ioctls
Takashi Iwai tiwai@suse.de ALSA: pcm: Return -EBUSY for OSS ioctls changing busy streams
Takashi Iwai tiwai@suse.de ALSA: pcm: Avoid potential races between OSS ioctls and read/write
Chuck Lever chuck.lever@oracle.com xprtrdma: Fix corner cases when handling device removal
Chuck Lever chuck.lever@oracle.com xprtrdma: Fix latency regression on NUMA NFS/RDMA clients
Bart Van Assche bart.vanassche@wdc.com RDMA/core: Avoid that ib_drain_qp() triggers an out-of-bounds stack access
Bart Van Assche bart.vanassche@wdc.com RDMA/rxe: Fix an out-of-bounds read
Leon Romanovsky leonro@mellanox.com RDMA/mlx5: Protect from NULL pointer derefence
Roland Dreier roland@purestorage.com RDMA/ucma: Don't allow setting RDMA_OPTION_IB_PATH without an RDMA device
Mikulas Patocka mpatocka@redhat.com dm crypt: limit the number of allocated pages
Mike Snitzer snitzer@redhat.com dm: backfill abnormal IO support to non-splitting IO submission
Theodore Ts'o tytso@mit.edu ext4: force revalidation of directory pointer after seekdir(2)
Theodore Ts'o tytso@mit.edu ext4: add extra checks to ext4_xattr_block_get()
Theodore Ts'o tytso@mit.edu ext4: add bounds checking to ext4_xattr_find_entry()
Theodore Ts'o tytso@mit.edu ext4: move call to ext4_error() into ext4_xattr_check_block()
Theodore Ts'o tytso@mit.edu ext4: don't allow r/w mounts if metadata blocks overlap the superblock
Theodore Ts'o tytso@mit.edu ext4: always initialize the crc32c checksum driver
Theodore Ts'o tytso@mit.edu ext4: fail ext4_iget for root directory if unallocated
Eric Biggers ebiggers@google.com ext4: limit xattr size to INT_MAX
Theodore Ts'o tytso@mit.edu ext4: add validity checks for bitmap block numbers
Jiri Slaby jslaby@suse.cz ext4: fix offset overflow on 32-bit archs in ext4_iomap_begin()
Eryu Guan guaneryu@gmail.com ext4: protect i_disksize update by i_data_sem in direct write path
Theodore Ts'o tytso@mit.edu ext4: don't update checksum of new initialized bitmaps
Theodore Ts'o tytso@mit.edu ext4: pass -ESHUTDOWN code to jbd2 layer
Theodore Ts'o tytso@mit.edu ext4: eliminate sleep from shutdown ioctl
Theodore Ts'o tytso@mit.edu ext4: shutdown should not prevent get_write_access
Theodore Ts'o tytso@mit.edu jbd2: if the journal is aborted then don't allow update of the log tail
Mikulas Patocka mpatocka@redhat.com block: use 32-bit blk_status_t on Alpha
Hans de Goede hdegoede@redhat.com extcon: intel-cht-wc: Set direction and drv flags for V5 boost GPIO
Theodore Ts'o tytso@mit.edu random: use a tighter cap in credit_entropy_bits_safe()
Aniruddha Banerjee aniruddhab@nvidia.com irqchip/gic: Take lock when updating irq type
Mika Westerberg mika.westerberg@linux.intel.com thunderbolt: Prevent crash when ICM firmware is not running
Mika Westerberg mika.westerberg@linux.intel.com thunderbolt: Handle connecting device in place of host properly
Mika Westerberg mika.westerberg@linux.intel.com thunderbolt: Resume control channel after hibernation image is created
Mika Westerberg mika.westerberg@linux.intel.com thunderbolt: Serialize PCIe tunnel creation with PCI rescan
Mika Westerberg mika.westerberg@linux.intel.com thunderbolt: Wait a bit longer for ICM to authenticate the active NVM
Liam Girdwood liam.r.girdwood@linux.intel.com ASoC: topology: Fix kcontrol name string handling
James Kelly jamespeterkelly@gmail.com ASoC: ssm2602: Replace reg_default_raw with reg_default
Sean Wang sean.wang@mediatek.com soc: mediatek: fix the mistaken pointer accessed when subdomains are added
Aaron Ma aaron.ma@canonical.com HID: core: Fix size as type u32
Aaron Ma aaron.ma@canonical.com HID: Fix hid_report_len usage
Yan, Zheng zyan@redhat.com ceph: always update atime/mtime/ctime for new inode
Michael Ellerman mpe@ellerman.id.au powerpc/mm/radix: Fix checkstops caused by invalid tlbiel
Nicholas Piggin npiggin@gmail.com powerpc/powernv: Fix OPAL NVRAM driver OPAL_BUSY loops
Thiago Jung Bauermann bauerman@linux.vnet.ibm.com powerpc/kexec_file: Fix error code when trying to load kdump kernel
Naveen N. Rao naveen.n.rao@linux.vnet.ibm.com powerpc/kprobes: Fix call trace due to incorrect preempt count
Nicholas Piggin npiggin@gmail.com powerpc/64: Fix smp_wmb barrier definition use use lwsync consistently
Paul Mackerras paulus@ozlabs.org powerpc/64: Call H_REGISTER_PROC_TBL when running as a HPT guest on POWER9
Nicholas Piggin npiggin@gmail.com powerpc/64s: Fix dt_cpu_ftrs to have restore_cpu clear unwanted LPCR bits
Michael Neuling mikey@neuling.org powerpc/eeh: Fix race with driver un/bind
Nicholas Piggin npiggin@gmail.com powerpc/powernv: Handle unknown OPAL errors in opal_nvram_write()
Nicholas Piggin npiggin@gmail.com powerpc/64s: Fix pkey support in dt_cpu_ftrs, add CPU_FTR_PKEY bit
Takashi Iwai tiwai@suse.de swiotlb: fix unexpected swiotlb_alloc_coherent failures
Gustavo A. R. Silva gustavo@embeddedor.com CIFS: fix sha512 check in cifs_crypto_secmech_release
Aurelien Aptel aaptel@suse.com CIFS: implement v3.11 preauth integrity
Aurelien Aptel aaptel@suse.com CIFS: add sha512 secmech
Aurelien Aptel aaptel@suse.com CIFS: refactor crypto shash/sdesc allocation&free
Jean Delvare jdelvare@suse.de i2c: i801: Restore configuration at shutdown
Jean Delvare jdelvare@suse.de i2c: i801: Save register SMBSLVCMD value only once
Aaron Ma aaron.ma@canonical.com HID: i2c-hid: fix size check and type usage
Steve French stfrench@microsoft.com smb3: Fix root directory when server returns inode number of zero
Long Li longli@microsoft.com cifs: smbd: disconnect transport on RDMA errors
Long Li longli@microsoft.com cifs: smbd: avoid reconnect lockup
Steve French smfrench@gmail.com Tree connect for SMB3.1.1 must be signed for non-encrypted shares
Ronnie Sahlberg lsahlber@redhat.com fix smb3-encryption breakage when CONFIG_DEBUG_SG=y
Ronnie Sahlberg lsahlber@redhat.com cifs: fix memory leak in SMB2_open()
Felipe Balbi felipe.balbi@linux.intel.com usb: dwc3: gadget: never call ->complete() from ->ep_queue()
Thinh Nguyen Thinh.Nguyen@synopsys.com usb: dwc3: pci: Properly cleanup resource
Roger Quadros rogerq@ti.com usb: dwc3: prevent setting PRTCAP to OTG from debugfs
Zhengjun Xing zhengjun.xing@linux.intel.com USB:fix USB3 devices behind USB3 hubs not resuming at hibernate thaw
Yavuz, Tuba tuba@ece.ufl.edu USB: gadget: f_midi: fixing a possible double-free in f_midi
Dan Williams dan.j.williams@intel.com acpi, nfit: rework NVDIMM leaf method detection
Mika Westerberg mika.westerberg@linux.intel.com ACPI / hotplug / PCI: Check presence of slot itself in get_slot_status()
Hans de Goede hdegoede@redhat.com ACPI / video: Add quirk to force acpi-video backlight on Samsung 670Z5E
Dan Carpenter dan.carpenter@oracle.com regmap: Fix reversed bounds check in regmap_raw_write()
Jason Andryuk jandryuk@gmail.com x86/xen: Delay get_cpu_cap until stack canary is established
Kieran Bingham kieran.bingham@ideasonboard.com media: vsp1: Fix BRx conditional path in WPF
Sakari Ailus sakari.ailus@linux.intel.com media: vb2: core: Finish buffers at the end of the stream
Hans Verkuil hverkuil@xs4all.nl media: vivid: check if the cec_adapter is valid
Hans Verkuil hverkuil@xs4all.nl media: atomisp_fops.c: disable atomisp_compat_ioctl32
Sean Young sean@mess.org media: rc: oops in ir_timer_keyup after device unplug
Jarkko Nikula jarkko.nikula@linux.intel.com spi: Fix unregistration of controller with fixed SPI bus number
Maxime Chevallier maxime.chevallier@bootlin.com spi: Fix scatterlist elements size in spi_map_buf
Eugen Hristev eugen.hristev@microchip.com spi: atmel: init FIFOs before spi enable
Santiago Esteban Santiago.Esteban@microchip.com ARM: dts: at91: sama5d4: fix pinctrl compatible string
Marek Szyprowski m.szyprowski@samsung.com ARM: dts: exynos: Fix IOMMU support for GScaler devices on Exynos5250
Nicolas Ferre nicolas.ferre@microchip.com ARM: dts: at91: at91sam9g25: fix mux-mask pinctrl property
Sean Wang sean.wang@mediatek.com arm: dts: mt7623: fix USB initialization fails on bananapi-r2
Marek Szyprowski m.szyprowski@samsung.com ARM: EXYNOS: Fix coupled CPU idle freeze on Exynos4210
Marc Zyngier marc.zyngier@arm.com KVM: arm/arm64: vgic-its: Fix potential overrun in vgic_copy_lpi_list
Jerome Brunet jbrunet@baylibre.com ARM64: dts: meson: reduce odroid-c2 eMMC maximum rate
Felipe Balbi felipe.balbi@linux.intel.com usb: gadget: udc: core: update usb_ep_queue() documentation
Chen-Yu Tsai wens@csie.org phy: allwinner: sun4i-usb: poll vbus changes on A23/A33 when driving VBUS
Heinrich Schuchardt xypron.glpk@gmx.de usb: musb: gadget: misplaced out of bounds check
Vlastimil Babka vbabka@suse.cz mm, slab: reschedule cache_reap() on the same CPU
Eric Biggers ebiggers@google.com ipc/shm: fix use-after-free of shm file via remap_file_pages()
Takashi Iwai tiwai@suse.de resource: fix integer overflow at reallocation
Andrew Morton akpm@linux-foundation.org fs/reiserfs/journal.c: add missing resierfs_warning() arg
Kees Cook keescook@chromium.org task_struct: only use anon struct under randstruct plugin
Naoya Horiguchi n-horiguchi@ah.jp.nec.com mm: hwpoison: disable memory error handling on 1GB hugepage
Jérôme Glisse jglisse@redhat.com mm/hmm: hmm_pfns_bad() was accessing wrong struct
Jérôme Glisse jglisse@redhat.com mm/hmm: fix header file if/else/endif maze
Claudio Imbrenda imbrenda@linux.vnet.ibm.com mm/ksm.c: fix inconsistent accounting of zero pages
Richard Weinberger richard@nod.at ubi: Reject MLC NAND
Romain Izard romain.izard.pro@gmail.com ubi: Fix error for write access
Richard Weinberger richard@nod.at ubi: fastmap: Don't flush fastmap work on detach
Richard Weinberger richard@nod.at ubifs: Check ubifs_wbuf_sync() return code
Gregory CLEMENT gregory.clement@bootlin.com cpufreq: armada-37xx: Fix clock leak
George Cherian george.cherian@cavium.com cpufreq: CPPC: Use transition_delay_us depending transition_latency
Hans de Goede hdegoede@redhat.com Bluetooth: hci_bcm: Add irq_polarity module option
-------------
Diffstat:
Makefile | 4 +- arch/arm/boot/dts/at91sam9g25.dtsi | 2 +- arch/arm/boot/dts/exynos5250.dtsi | 8 +- arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts | 24 ++- arch/arm/boot/dts/sama5d4.dtsi | 2 +- arch/arm/mach-exynos/pm.c | 6 +- .../arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts | 2 +- arch/mips/include/asm/uaccess.h | 11 +- arch/mips/lib/memset.S | 11 +- arch/powerpc/include/asm/barrier.h | 3 +- arch/powerpc/include/asm/synch.h | 4 - arch/powerpc/kernel/dt_cpu_ftrs.c | 19 +- arch/powerpc/kernel/eeh_driver.c | 68 ++++--- arch/powerpc/kernel/eeh_pe.c | 3 +- arch/powerpc/kernel/kprobes.c | 30 +-- arch/powerpc/kernel/machine_kexec_file_64.c | 2 +- arch/powerpc/lib/feature-fixups.c | 2 +- arch/powerpc/mm/hash_utils_64.c | 6 + arch/powerpc/mm/tlb-radix.c | 5 +- arch/powerpc/platforms/powernv/opal-nvram.c | 11 +- arch/powerpc/platforms/pseries/lpar.c | 8 +- arch/powerpc/sysdev/xive/native.c | 4 + arch/s390/Kconfig | 8 +- arch/s390/hypfs/inode.c | 2 +- arch/s390/kernel/perf_cpum_cf_events.c | 1 + arch/s390/kernel/setup.c | 1 + arch/um/os-Linux/file.c | 1 + arch/um/os-Linux/signal.c | 3 +- arch/x86/um/stub_segv.c | 3 +- arch/x86/xen/enlighten_pv.c | 8 +- drivers/acpi/nfit/core.c | 59 +++--- drivers/acpi/nfit/nfit.h | 5 +- drivers/acpi/video_detect.c | 9 + drivers/base/regmap/regmap.c | 2 +- drivers/bluetooth/hci_bcm.c | 20 +- drivers/char/random.c | 130 +++++++++---- drivers/char/tpm/tpm-interface.c | 4 + drivers/clk/bcm/clk-bcm2835.c | 8 +- drivers/clk/mediatek/clk-mt2701.c | 15 +- drivers/clk/mvebu/armada-38x.c | 14 +- drivers/clk/renesas/clk-sh73a0.c | 6 +- drivers/clk/tegra/clk-emc.c | 2 +- drivers/clk/tegra/clk-tegra-periph.c | 2 +- drivers/clk/tegra/clk-tegra-super-gen4.c | 8 +- drivers/clk/tegra/clk-tegra114.c | 3 +- drivers/clk/tegra/clk-tegra124.c | 7 +- drivers/clk/tegra/clk-tegra20.c | 23 +-- drivers/clk/tegra/clk-tegra210.c | 3 +- drivers/clk/tegra/clk-tegra30.c | 14 +- drivers/cpufreq/armada-37xx-cpufreq.c | 2 + drivers/cpufreq/cppc_cpufreq.c | 3 + drivers/dax/device.c | 2 + drivers/dma/at_xdmac.c | 4 +- drivers/extcon/extcon-intel-cht-wc.c | 11 +- drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c | 6 +- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 2 +- drivers/gpu/drm/amd/amdgpu/cik_sdma.c | 2 +- drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c | 2 +- drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c | 2 +- drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c | 2 +- drivers/gpu/drm/amd/amdgpu/si.c | 67 +++++++ drivers/gpu/drm/amd/amdgpu/si_dpm.c | 4 +- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 31 --- .../drm/amd/display/dc/dce/dce_stream_encoder.c | 2 + drivers/gpu/drm/i915/gvt/gvt.h | 5 +- drivers/gpu/drm/i915/gvt/mmio_context.c | 210 +++++++++++++++++++-- drivers/gpu/drm/i915/gvt/mmio_context.h | 5 + drivers/gpu/drm/i915/gvt/scheduler.c | 5 + drivers/gpu/drm/i915/i915_drv.c | 22 +-- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/i915_reg.h | 10 + drivers/gpu/drm/i915/intel_sprite.c | 81 ++++++-- drivers/gpu/drm/radeon/radeon_device.c | 4 + drivers/gpu/drm/radeon/si_dpm.c | 4 +- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 23 +-- drivers/hid/hid-core.c | 10 +- drivers/hid/hid-ids.h | 3 + drivers/hid/hid-input.c | 27 ++- drivers/hid/hid-multitouch.c | 5 +- drivers/hid/hid-rmi.c | 4 +- drivers/hid/hidraw.c | 5 + drivers/hid/i2c-hid/i2c-hid.c | 26 ++- drivers/hid/wacom_sys.c | 4 +- drivers/hid/wacom_wac.c | 76 +++++--- drivers/i2c/busses/i2c-i801.c | 16 +- drivers/infiniband/core/ucma.c | 3 + drivers/infiniband/core/verbs.c | 12 +- drivers/infiniband/hw/mlx5/mr.c | 2 + drivers/infiniband/sw/rxe/rxe_verbs.c | 5 +- drivers/infiniband/ulp/srp/ib_srp.c | 18 +- drivers/infiniband/ulp/srpt/ib_srpt.c | 16 +- drivers/iommu/intel-svm.c | 1 + drivers/irqchip/irq-gic-common.c | 9 +- drivers/md/dm-crypt.c | 66 ++++++- drivers/md/dm-raid.c | 3 +- drivers/md/dm.c | 30 ++- drivers/media/common/videobuf2/videobuf2-core.c | 9 + drivers/media/platform/vivid/vivid-vid-common.c | 3 +- drivers/media/platform/vsp1/vsp1_wpf.c | 2 +- drivers/media/rc/rc-main.c | 6 +- drivers/misc/cxl/cxllib.c | 85 ++++++--- drivers/mmc/core/block.c | 1 + drivers/mmc/host/jz4740_mmc.c | 2 +- drivers/mmc/host/sdhci-pci-core.c | 25 ++- drivers/mmc/host/tmio_mmc_core.c | 2 +- drivers/mtd/ubi/block.c | 2 +- drivers/mtd/ubi/build.c | 11 ++ drivers/mtd/ubi/fastmap-wl.c | 1 - drivers/nvdimm/dimm.c | 8 +- drivers/nvdimm/dimm_devs.c | 22 ++- drivers/nvdimm/namespace_devs.c | 4 +- drivers/pci/hotplug/acpiphp_glue.c | 23 ++- drivers/pci/quirks.c | 4 + drivers/phy/allwinner/phy-sun4i-usb.c | 10 +- drivers/pwm/pwm-mediatek.c | 35 +++- drivers/pwm/pwm-rcar.c | 8 +- drivers/soc/mediatek/mtk-scpsys.c | 2 +- drivers/spi/spi-atmel.c | 8 +- drivers/spi/spi.c | 19 +- .../media/atomisp/pci/atomisp2/atomisp_fops.c | 6 + drivers/thermal/imx_thermal.c | 6 +- drivers/thunderbolt/icm.c | 36 ++-- drivers/thunderbolt/nhi.c | 1 + drivers/thunderbolt/switch.c | 9 + drivers/usb/core/generic.c | 9 +- drivers/usb/dwc3/core.c | 3 + drivers/usb/dwc3/dwc3-pci.c | 2 +- drivers/usb/dwc3/gadget.c | 43 +++-- drivers/usb/gadget/function/f_midi.c | 3 +- drivers/usb/gadget/u_f.h | 2 + drivers/usb/gadget/udc/core.c | 3 + drivers/usb/musb/musb_gadget_ep0.c | 14 +- drivers/watchdog/f71808e_wdt.c | 2 +- fs/autofs4/root.c | 2 +- fs/ceph/inode.c | 10 +- fs/cifs/Kconfig | 1 + fs/cifs/cifsencrypt.c | 85 ++------- fs/cifs/cifsfs.c | 1 + fs/cifs/cifsglob.h | 8 +- fs/cifs/cifsproto.h | 5 + fs/cifs/inode.c | 33 ++++ fs/cifs/link.c | 27 +-- fs/cifs/misc.c | 54 ++++++ fs/cifs/smb2misc.c | 64 +++++++ fs/cifs/smb2ops.c | 15 +- fs/cifs/smb2pdu.c | 38 +++- fs/cifs/smb2pdu.h | 1 + fs/cifs/smb2proto.h | 5 + fs/cifs/smb2transport.c | 97 ++++------ fs/cifs/smbdirect.c | 19 +- fs/cifs/smbencrypt.c | 27 +-- fs/cifs/transport.c | 17 ++ fs/ext4/balloc.c | 19 +- fs/ext4/dir.c | 8 +- fs/ext4/ext4_jbd2.c | 7 - fs/ext4/ialloc.c | 54 +----- fs/ext4/inode.c | 13 +- fs/ext4/ioctl.c | 8 +- fs/ext4/super.c | 21 ++- fs/ext4/xattr.c | 121 ++++++------ fs/ext4/xattr.h | 11 ++ fs/fs-writeback.c | 7 +- fs/jbd2/journal.c | 30 ++- fs/jffs2/super.c | 2 +- fs/namespace.c | 3 +- fs/notify/fanotify/fanotify.c | 34 ++-- fs/orangefs/super.c | 5 + fs/reiserfs/journal.c | 2 +- fs/ubifs/super.c | 14 +- fs/udf/unicode.c | 6 + include/dt-bindings/clock/mt2701-clk.h | 3 +- include/linux/backing-dev-defs.h | 5 + include/linux/backing-dev.h | 30 +-- include/linux/blk_types.h | 5 + include/linux/compiler-clang.h | 3 - include/linux/compiler-gcc.h | 12 +- include/linux/hid.h | 15 +- include/linux/hmm.h | 9 +- include/linux/mm.h | 1 + include/sound/pcm_oss.h | 1 + include/uapi/linux/random.h | 3 + ipc/shm.c | 23 ++- kernel/resource.c | 3 +- kernel/trace/ring_buffer.c | 5 + kernel/trace/trace_uprobe.c | 2 +- lib/swiotlb.c | 2 +- lib/vsprintf.c | 4 + mm/filemap.c | 9 +- mm/hmm.c | 3 +- mm/ksm.c | 7 + mm/memory-failure.c | 16 ++ mm/page-writeback.c | 18 +- mm/slab.c | 3 +- net/sunrpc/rpc_pipe.c | 1 + net/sunrpc/xprtrdma/rpc_rdma.c | 2 +- net/sunrpc/xprtrdma/transport.c | 2 - net/sunrpc/xprtrdma/verbs.c | 13 +- net/sunrpc/xprtrdma/xprt_rdma.h | 1 - sound/core/oss/pcm_oss.c | 186 ++++++++++++++---- sound/core/pcm.c | 8 +- sound/core/rawmidi_compat.c | 18 +- sound/pci/hda/hda_intel.c | 3 +- sound/pci/hda/patch_realtek.c | 3 + sound/soc/codecs/ssm2602.c | 19 +- sound/soc/soc-topology.c | 23 ++- sound/usb/line6/midi.c | 2 +- virt/kvm/arm/vgic/vgic-its.c | 15 +- 208 files changed, 2213 insertions(+), 1021 deletions(-)
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans de Goede hdegoede@redhat.com
commit e09070c51b280567695022237e57c428e548b355 upstream.
Add irq_polarity module option for easier troubleshooting of irq-polarity issues.
Cc: stable@vger.kernel.org Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Marcel Holtmann marcel@holtmann.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/bluetooth/hci_bcm.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-)
--- a/drivers/bluetooth/hci_bcm.c +++ b/drivers/bluetooth/hci_bcm.c @@ -126,6 +126,10 @@ struct bcm_data { static DEFINE_MUTEX(bcm_device_lock); static LIST_HEAD(bcm_device_list);
+static int irq_polarity = -1; +module_param(irq_polarity, int, 0444); +MODULE_PARM_DESC(irq_polarity, "IRQ polarity 0: active-high 1: active-low"); + static inline void host_set_baudrate(struct hci_uart *hu, unsigned int speed) { if (hu->serdev) @@ -975,11 +979,17 @@ static int bcm_acpi_probe(struct bcm_dev } acpi_dev_free_resource_list(&resources);
- dmi_id = dmi_first_match(bcm_active_low_irq_dmi_table); - if (dmi_id) { - dev_warn(dev->dev, "%s: Overwriting IRQ polarity to active low", - dmi_id->ident); - dev->irq_active_low = true; + if (irq_polarity != -1) { + dev->irq_active_low = irq_polarity; + dev_warn(dev->dev, "Overwriting IRQ polarity to active %s by module-param\n", + dev->irq_active_low ? "low" : "high"); + } else { + dmi_id = dmi_first_match(bcm_active_low_irq_dmi_table); + if (dmi_id) { + dev_warn(dev->dev, "%s: Overwriting IRQ polarity to active low", + dmi_id->ident); + dev->irq_active_low = true; + } }
return 0;
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: George Cherian george.cherian@cavium.com
commit 3d41386d556db9f720e00de3e11e45f39cb5071c upstream.
With commit e948bc8fbee0 (cpufreq: Cap the default transition delay value to 10 ms) the cpufreq was not honouring the delay passed via ACPI (PCCT). Due to which on ARM based platforms using CPPC the cpufreq governor tries to change the frequency of CPUs faster than expected.
This leads to continuous error messages like the following. " ACPI CPPC: PCC check channel failed. Status=0 "
Earlier (without above commit) the default transition delay was taken form the value passed from PCCT. Use the same value provided by PCCT to set the transition_delay_us.
Fixes: e948bc8fbee0 (cpufreq: Cap the default transition delay value to 10 ms) Signed-off-by: George Cherian george.cherian@cavium.com Cc: 4.14+ stable@vger.kernel.org # 4.14+ Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/cpufreq/cppc_cpufreq.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/drivers/cpufreq/cppc_cpufreq.c +++ b/drivers/cpufreq/cppc_cpufreq.c @@ -20,6 +20,7 @@ #include <linux/cpu.h> #include <linux/cpufreq.h> #include <linux/dmi.h> +#include <linux/time.h> #include <linux/vmalloc.h>
#include <asm/unaligned.h> @@ -162,6 +163,8 @@ static int cppc_cpufreq_cpu_init(struct policy->cpuinfo.max_freq = cppc_dmi_max_khz;
policy->cpuinfo.transition_latency = cppc_get_transition_latency(cpu_num); + policy->transition_delay_us = cppc_get_transition_latency(cpu_num) / + NSEC_PER_USEC; policy->shared_type = cpu->shared_type;
if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY)
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gregory CLEMENT gregory.clement@bootlin.com
commit bbcc328561040292f7d6796954d478e4a2335e6f upstream.
There was no clk_put() balancing the clk_get(). This commit fixes it.
Fixes: 92ce45fb875d (cpufreq: Add DVFS support for Armada 37xx) Cc: 4.16+ stable@vger.kernel.org # 4.16+ Reported-by: Thomas Petazzoni thomas.petazzoni@bootlin.com Signed-off-by: Gregory CLEMENT gregory.clement@bootlin.com Acked-by: Viresh Kumar viresh.kumar@linaro.org Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/cpufreq/armada-37xx-cpufreq.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/cpufreq/armada-37xx-cpufreq.c +++ b/drivers/cpufreq/armada-37xx-cpufreq.c @@ -202,6 +202,7 @@ static int __init armada37xx_cpufreq_dri cur_frequency = clk_get_rate(clk); if (!cur_frequency) { dev_err(cpu_dev, "Failed to get clock rate for CPU\n"); + clk_put(clk); return -EINVAL; }
@@ -210,6 +211,7 @@ static int __init armada37xx_cpufreq_dri return -EINVAL;
armada37xx_cpufreq_dvfs_setup(nb_pm_base, clk, dvfs->divider); + clk_put(clk);
for (load_lvl = ARMADA_37XX_DVFS_LOAD_0; load_lvl < LOAD_LEVEL_NR; load_lvl++) {
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Richard Weinberger richard@nod.at
commit aac17948a7ce01fb60b9ee6cf902967a47b3ce26 upstream.
If ubifs_wbuf_sync() fails we must not write a master node with the dirty marker cleared. Otherwise it is possible that in case of an IO error while syncing we mark the filesystem as clean and UBIFS refuses to recover upon next mount.
Cc: stable@vger.kernel.org Fixes: 1e51764a3c2a ("UBIFS: add new flash file system") Signed-off-by: Richard Weinberger richard@nod.at Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/ubifs/super.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
--- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c @@ -1737,8 +1737,11 @@ static void ubifs_remount_ro(struct ubif
dbg_save_space_info(c);
- for (i = 0; i < c->jhead_cnt; i++) - ubifs_wbuf_sync(&c->jheads[i].wbuf); + for (i = 0; i < c->jhead_cnt; i++) { + err = ubifs_wbuf_sync(&c->jheads[i].wbuf); + if (err) + ubifs_ro_mode(c, err); + }
c->mst_node->flags &= ~cpu_to_le32(UBIFS_MST_DIRTY); c->mst_node->flags |= cpu_to_le32(UBIFS_MST_NO_ORPHS); @@ -1804,8 +1807,11 @@ static void ubifs_put_super(struct super int err;
/* Synchronize write-buffers */ - for (i = 0; i < c->jhead_cnt; i++) - ubifs_wbuf_sync(&c->jheads[i].wbuf); + for (i = 0; i < c->jhead_cnt; i++) { + err = ubifs_wbuf_sync(&c->jheads[i].wbuf); + if (err) + ubifs_ro_mode(c, err); + }
/* * We are being cleanly unmounted which means the
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Richard Weinberger richard@nod.at
commit 29b7a6fa1ec07e8480b0d9caf635a4498a438bf4 upstream.
At this point UBI volumes have already been free()'ed and fastmap can no longer access these data structures.
Reported-by: Martin Townsend mtownsend1973@gmail.com Fixes: 74cdaf24004a ("UBI: Fastmap: Fix memory leaks while closing the WL sub-system") Cc: stable@vger.kernel.org Signed-off-by: Richard Weinberger richard@nod.at Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/mtd/ubi/fastmap-wl.c | 1 - 1 file changed, 1 deletion(-)
--- a/drivers/mtd/ubi/fastmap-wl.c +++ b/drivers/mtd/ubi/fastmap-wl.c @@ -362,7 +362,6 @@ static void ubi_fastmap_close(struct ubi { int i;
- flush_work(&ubi->fm_work); return_unused_pool_pebs(ubi, &ubi->fm_pool); return_unused_pool_pebs(ubi, &ubi->fm_wl_pool);
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Romain Izard romain.izard.pro@gmail.com
commit 78a8dfbabbece22bee58ac4cb26cab10e7a19c5d upstream.
When opening a device with write access, ubiblock_open returns an error code. Currently, this error code is -EPERM, but this is not the right value.
The open function for other block devices returns -EROFS when opening read-only devices with FMODE_WRITE set. When used with dm-verity, the veritysetup userspace tool is expecting EROFS, and refuses to use the ubiblock device.
Use -EROFS for ubiblock as well. As a result, veritysetup accepts the ubiblock device as valid.
Cc: stable@vger.kernel.org Fixes: 9d54c8a33eec (UBI: R/O block driver on top of UBI volumes) Signed-off-by: Romain Izard romain.izard.pro@gmail.com Signed-off-by: Richard Weinberger richard@nod.at Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/mtd/ubi/block.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/mtd/ubi/block.c +++ b/drivers/mtd/ubi/block.c @@ -244,7 +244,7 @@ static int ubiblock_open(struct block_de * in any case. */ if (mode & FMODE_WRITE) { - ret = -EPERM; + ret = -EROFS; goto out_unlock; }
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Richard Weinberger richard@nod.at
commit b5094b7f135be34630e3ea8a98fa215715d0f29d upstream.
While UBI and UBIFS seem to work at first sight with MLC NAND, you will most likely lose all your data upon a power-cut or due to read/write disturb. In order to protect users from bad surprises, refuse to attach to MLC NAND.
Cc: stable@vger.kernel.org Signed-off-by: Richard Weinberger richard@nod.at Acked-by: Boris Brezillon boris.brezillon@bootlin.com Acked-by: Artem Bityutskiy dedekind1@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/mtd/ubi/build.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
--- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -854,6 +854,17 @@ int ubi_attach_mtd_dev(struct mtd_info * return -EINVAL; }
+ /* + * Both UBI and UBIFS have been designed for SLC NAND and NOR flashes. + * MLC NAND is different and needs special care, otherwise UBI or UBIFS + * will die soon and you will lose all your data. + */ + if (mtd->type == MTD_MLCNANDFLASH) { + pr_err("ubi: refuse attaching mtd%d - MLC NAND is not supported\n", + mtd->index); + return -EINVAL; + } + if (ubi_num == UBI_DEV_NUM_AUTO) { /* Search for an empty slot in the @ubi_devices array */ for (ubi_num = 0; ubi_num < UBI_MAX_DEVICES; ubi_num++)
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Claudio Imbrenda imbrenda@linux.vnet.ibm.com
commit a38c015f3156895b07e71d4e4414289f8a3b2745 upstream.
When using KSM with use_zero_pages, we replace anonymous pages containing only zeroes with actual zero pages, which are not anonymous. We need to do proper accounting of the mm counters, otherwise we will get wrong values in /proc and a BUG message in dmesg when tearing down the mm.
Link: http://lkml.kernel.org/r/1522931274-15552-1-git-send-email-imbrenda@linux.vn... Fixes: e86c59b1b1 ("mm/ksm: improve deduplication of zero pages with colouring") Signed-off-by: Claudio Imbrenda imbrenda@linux.vnet.ibm.com Reviewed-by: Andrew Morton akpm@linux-foundation.org Cc: Andrea Arcangeli aarcange@redhat.com Cc: Minchan Kim minchan@kernel.org Cc: Kirill A. Shutemov kirill.shutemov@linux.intel.com Cc: Hugh Dickins hughd@google.com Cc: Christian Borntraeger borntraeger@de.ibm.com Cc: Gerald Schaefer gerald.schaefer@de.ibm.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- mm/ksm.c | 7 +++++++ 1 file changed, 7 insertions(+)
--- a/mm/ksm.c +++ b/mm/ksm.c @@ -1131,6 +1131,13 @@ static int replace_page(struct vm_area_s } else { newpte = pte_mkspecial(pfn_pte(page_to_pfn(kpage), vma->vm_page_prot)); + /* + * We're replacing an anonymous page with a zero page, which is + * not anonymous. We need to do proper accounting otherwise we + * will get wrong values in /proc, and a BUG message in dmesg + * when tearing down the mm. + */ + dec_mm_counter(mm, MM_ANONPAGES); }
flush_cache_page(vma, addr, pte_pfn(*ptep));
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Naoya Horiguchi n-horiguchi@ah.jp.nec.com
commit 31286a8484a85e8b4e91ddb0f5415aee8a416827 upstream.
Recently the following BUG was reported:
Injecting memory failure for pfn 0x3c0000 at process virtual address 0x7fe300000000 Memory failure: 0x3c0000: recovery action for huge page: Recovered BUG: unable to handle kernel paging request at ffff8dfcc0003000 IP: gup_pgd_range+0x1f0/0xc20 PGD 17ae72067 P4D 17ae72067 PUD 0 Oops: 0000 [#1] SMP PTI ... CPU: 3 PID: 5467 Comm: hugetlb_1gb Not tainted 4.15.0-rc8-mm1-abc+ #3 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.9.3-1.fc25 04/01/2014
You can easily reproduce this by calling madvise(MADV_HWPOISON) twice on a 1GB hugepage. This happens because get_user_pages_fast() is not aware of a migration entry on pud that was created in the 1st madvise() event.
I think that conversion to pud-aligned migration entry is working, but other MM code walking over page table isn't prepared for it. We need some time and effort to make all this work properly, so this patch avoids the reported bug by just disabling error handling for 1GB hugepage.
[n-horiguchi@ah.jp.nec.com: v2] Link: http://lkml.kernel.org/r/1517284444-18149-1-git-send-email-n-horiguchi@ah.jp... Link: http://lkml.kernel.org/r/1517207283-15769-1-git-send-email-n-horiguchi@ah.jp... Signed-off-by: Naoya Horiguchi n-horiguchi@ah.jp.nec.com Acked-by: Michal Hocko mhocko@suse.com Reviewed-by: Andrew Morton akpm@linux-foundation.org Reviewed-by: Mike Kravetz mike.kravetz@oracle.com Acked-by: Punit Agrawal punit.agrawal@arm.com Tested-by: Michael Ellerman mpe@ellerman.id.au Cc: Anshuman Khandual khandual@linux.vnet.ibm.com Cc: "Aneesh Kumar K.V" aneesh.kumar@linux.vnet.ibm.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- include/linux/mm.h | 1 + mm/memory-failure.c | 16 ++++++++++++++++ 2 files changed, 17 insertions(+)
--- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -2604,6 +2604,7 @@ enum mf_action_page_type { MF_MSG_POISONED_HUGE, MF_MSG_HUGE, MF_MSG_FREE_HUGE, + MF_MSG_NON_PMD_HUGE, MF_MSG_UNMAP_FAILED, MF_MSG_DIRTY_SWAPCACHE, MF_MSG_CLEAN_SWAPCACHE, --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -502,6 +502,7 @@ static const char * const action_page_ty [MF_MSG_POISONED_HUGE] = "huge page already hardware poisoned", [MF_MSG_HUGE] = "huge page", [MF_MSG_FREE_HUGE] = "free huge page", + [MF_MSG_NON_PMD_HUGE] = "non-pmd-sized huge page", [MF_MSG_UNMAP_FAILED] = "unmapping failed page", [MF_MSG_DIRTY_SWAPCACHE] = "dirty swapcache page", [MF_MSG_CLEAN_SWAPCACHE] = "clean swapcache page", @@ -1084,6 +1085,21 @@ static int memory_failure_hugetlb(unsign return 0; }
+ /* + * TODO: hwpoison for pud-sized hugetlb doesn't work right now, so + * simply disable it. In order to make it work properly, we need + * make sure that: + * - conversion of a pud that maps an error hugetlb into hwpoison + * entry properly works, and + * - other mm code walking over page table is aware of pud-aligned + * hwpoison entries. + */ + if (huge_page_size(page_hstate(head)) > PMD_SIZE) { + action_result(pfn, MF_MSG_NON_PMD_HUGE, MF_IGNORED); + res = -EBUSY; + goto out; + } + if (!hwpoison_user_mappings(p, pfn, flags, &head)) { action_result(pfn, MF_MSG_UNMAP_FAILED, MF_IGNORED); res = -EBUSY;
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kees Cook keescook@chromium.org
commit 2cfe0d3009418a132b93d78642a8059a38fe5944 upstream.
The original intent for always adding the anonymous struct in task_struct was to make sure we had compiler coverage.
However, this caused pathological padding of 40 bytes at the start of task_struct. Instead, move the anonymous struct to being only used when struct layout randomization is enabled.
Link: http://lkml.kernel.org/r/20180327213609.GA2964@beast Fixes: 29e48ce87f1e ("task_struct: Allow randomized") Signed-off-by: Kees Cook keescook@chromium.org Reported-by: Peter Zijlstra peterz@infradead.org Cc: Peter Zijlstra peterz@infradead.org Cc: Ingo Molnar mingo@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- include/linux/compiler-clang.h | 3 --- include/linux/compiler-gcc.h | 12 +++--------- 2 files changed, 3 insertions(+), 12 deletions(-)
--- a/include/linux/compiler-clang.h +++ b/include/linux/compiler-clang.h @@ -17,9 +17,6 @@ */ #define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
-#define randomized_struct_fields_start struct { -#define randomized_struct_fields_end }; - /* all clang versions usable with the kernel support KASAN ABI version 5 */ #define KASAN_ABI_VERSION 5
--- a/include/linux/compiler-gcc.h +++ b/include/linux/compiler-gcc.h @@ -242,6 +242,9 @@ #if defined(RANDSTRUCT_PLUGIN) && !defined(__CHECKER__) #define __randomize_layout __attribute__((randomize_layout)) #define __no_randomize_layout __attribute__((no_randomize_layout)) +/* This anon struct can add padding, so only enable it under randstruct. */ +#define randomized_struct_fields_start struct { +#define randomized_struct_fields_end } __randomize_layout; #endif
#endif /* GCC_VERSION >= 40500 */ @@ -256,15 +259,6 @@ */ #define __visible __attribute__((externally_visible))
-/* - * RANDSTRUCT_PLUGIN wants to use an anonymous struct, but it is only - * possible since GCC 4.6. To provide as much build testing coverage - * as possible, this is used for all GCC 4.6+ builds, and not just on - * RANDSTRUCT_PLUGIN builds. - */ -#define randomized_struct_fields_start struct { -#define randomized_struct_fields_end } __randomize_layout; - #endif /* GCC_VERSION >= 40600 */
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrew Morton akpm@linux-foundation.org
commit 9ad553abe66f8be3f4755e9fa0a6ba137ce76341 upstream.
One use of the reiserfs_warning() macro in journal_init_dev() is missing a parameter, causing the following warning:
REISERFS warning (device loop0): journal_init_dev: Cannot open '%s': %i journal_init_dev:
This also causes a WARN_ONCE() warning in the vsprintf code, and then a panic if panic_on_warn is set.
Please remove unsupported %/ in format string WARNING: CPU: 1 PID: 4480 at lib/vsprintf.c:2138 format_decode+0x77f/0x830 lib/vsprintf.c:2138 Kernel panic - not syncing: panic_on_warn set ...
Just add another string argument to the macro invocation.
Addresses https://syzkaller.appspot.com/bug?id=0627d4551fdc39bf1ef5d82cd9eef587047f771...
Link: http://lkml.kernel.org/r/d678ebe1-6f54-8090-df4c-b9affad62293@infradead.org Signed-off-by: Randy Dunlap rdunlap@infradead.org Reported-by: syzbot+6bd77b88c1977c03f584@syzkaller.appspotmail.com Tested-by: Randy Dunlap rdunlap@infradead.org Acked-by: Jeff Mahoney jeffm@suse.com Cc: Alexander Viro viro@zeniv.linux.org.uk Cc: Jan Kara jack@suse.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/reiserfs/journal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c @@ -2643,7 +2643,7 @@ static int journal_init_dev(struct super if (IS_ERR(journal->j_dev_bd)) { result = PTR_ERR(journal->j_dev_bd); journal->j_dev_bd = NULL; - reiserfs_warning(super, + reiserfs_warning(super, "sh-457", "journal_init_dev: Cannot open '%s': %i", jdev_name, result); return result;
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai tiwai@suse.de
commit 60bb83b81169820c691fbfa33a6a4aef32aa4b0b upstream.
We've got a bug report indicating a kernel panic at booting on an x86-32 system, and it turned out to be the invalid PCI resource assigned after reallocation. __find_resource() first aligns the resource start address and resets the end address with start+size-1 accordingly, then checks whether it's contained. Here the end address may overflow the integer, although resource_contains() still returns true because the function validates only start and end address. So this ends up with returning an invalid resource (start > end).
There was already an attempt to cover such a problem in the commit 47ea91b4052d ("Resource: fix wrong resource window calculation"), but this case is an overseen one.
This patch adds the validity check of the newly calculated resource for avoiding the integer overflow problem.
Bugzilla: http://bugzilla.opensuse.org/show_bug.cgi?id=1086739 Link: http://lkml.kernel.org/r/s5hpo37d5l8.wl-tiwai@suse.de Fixes: 23c570a67448 ("resource: ability to resize an allocated resource") Signed-off-by: Takashi Iwai tiwai@suse.de Reported-by: Michael Henders hendersm@shaw.ca Tested-by: Michael Henders hendersm@shaw.ca Reviewed-by: Andrew Morton akpm@linux-foundation.org Cc: Ram Pai linuxram@us.ibm.com Cc: Bjorn Helgaas bhelgaas@google.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- kernel/resource.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/kernel/resource.c +++ b/kernel/resource.c @@ -651,7 +651,8 @@ static int __find_resource(struct resour alloc.start = constraint->alignf(constraint->alignf_data, &avail, size, constraint->align); alloc.end = alloc.start + size - 1; - if (resource_contains(&avail, &alloc)) { + if (alloc.start <= alloc.end && + resource_contains(&avail, &alloc)) { new->start = alloc.start; new->end = alloc.end; return 0;
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers ebiggers@google.com
commit 3f05317d9889ab75c7190dcd39491d2a97921984 upstream.
syzbot reported a use-after-free of shm_file_data(file)->file->f_op in shm_get_unmapped_area(), called via sys_remap_file_pages().
Unfortunately it couldn't generate a reproducer, but I found a bug which I think caused it. When remap_file_pages() is passed a full System V shared memory segment, the memory is first unmapped, then a new map is created using the ->vm_file. Between these steps, the shm ID can be removed and reused for a new shm segment. But, shm_mmap() only checks whether the ID is currently valid before calling the underlying file's ->mmap(); it doesn't check whether it was reused. Thus it can use the wrong underlying file, one that was already freed.
Fix this by making the "outer" shm file (the one that gets put in ->vm_file) hold a reference to the real shm file, and by making __shm_open() require that the file associated with the shm ID matches the one associated with the "outer" file.
Taking the reference to the real shm file is needed to fully solve the problem, since otherwise sfd->file could point to a freed file, which then could be reallocated for the reused shm ID, causing the wrong shm segment to be mapped (and without the required permission checks).
Commit 1ac0b6dec656 ("ipc/shm: handle removed segments gracefully in shm_mmap()") almost fixed this bug, but it didn't go far enough because it didn't consider the case where the shm ID is reused.
The following program usually reproduces this bug:
#include <stdlib.h> #include <sys/shm.h> #include <sys/syscall.h> #include <unistd.h>
int main() { int is_parent = (fork() != 0); srand(getpid()); for (;;) { int id = shmget(0xF00F, 4096, IPC_CREAT|0700); if (is_parent) { void *addr = shmat(id, NULL, 0); usleep(rand() % 50); while (!syscall(__NR_remap_file_pages, addr, 4096, 0, 0, 0)); } else { usleep(rand() % 50); shmctl(id, IPC_RMID, NULL); } } }
It causes the following NULL pointer dereference due to a 'struct file' being used while it's being freed. (I couldn't actually get a KASAN use-after-free splat like in the syzbot report. But I think it's possible with this bug; it would just take a more extraordinary race...)
BUG: unable to handle kernel NULL pointer dereference at 0000000000000058 PGD 0 P4D 0 Oops: 0000 [#1] SMP NOPTI CPU: 9 PID: 258 Comm: syz_ipc Not tainted 4.16.0-05140-gf8cf2f16a7c95 #189 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.11.0-20171110_100015-anatol 04/01/2014 RIP: 0010:d_inode include/linux/dcache.h:519 [inline] RIP: 0010:touch_atime+0x25/0xd0 fs/inode.c:1724 [...] Call Trace: file_accessed include/linux/fs.h:2063 [inline] shmem_mmap+0x25/0x40 mm/shmem.c:2149 call_mmap include/linux/fs.h:1789 [inline] shm_mmap+0x34/0x80 ipc/shm.c:465 call_mmap include/linux/fs.h:1789 [inline] mmap_region+0x309/0x5b0 mm/mmap.c:1712 do_mmap+0x294/0x4a0 mm/mmap.c:1483 do_mmap_pgoff include/linux/mm.h:2235 [inline] SYSC_remap_file_pages mm/mmap.c:2853 [inline] SyS_remap_file_pages+0x232/0x310 mm/mmap.c:2769 do_syscall_64+0x64/0x1a0 arch/x86/entry/common.c:287 entry_SYSCALL_64_after_hwframe+0x42/0xb7
[ebiggers@google.com: add comment] Link: http://lkml.kernel.org/r/20180410192850.235835-1-ebiggers3@gmail.com Link: http://lkml.kernel.org/r/20180409043039.28915-1-ebiggers3@gmail.com Reported-by: syzbot+d11f321e7f1923157eac80aa990b446596f46439@syzkaller.appspotmail.com Fixes: c8d78c1823f4 ("mm: replace remap_file_pages() syscall with emulation") Signed-off-by: Eric Biggers ebiggers@google.com Acked-by: Kirill A. Shutemov kirill.shutemov@linux.intel.com Acked-by: Davidlohr Bueso dbueso@suse.de Cc: Manfred Spraul manfred@colorfullife.com Cc: "Eric W . Biederman" ebiederm@xmission.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- ipc/shm.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-)
--- a/ipc/shm.c +++ b/ipc/shm.c @@ -203,6 +203,12 @@ static int __shm_open(struct vm_area_str if (IS_ERR(shp)) return PTR_ERR(shp);
+ if (shp->shm_file != sfd->file) { + /* ID was reused */ + shm_unlock(shp); + return -EINVAL; + } + shp->shm_atim = ktime_get_real_seconds(); shp->shm_lprid = task_tgid_vnr(current); shp->shm_nattch++; @@ -431,8 +437,9 @@ static int shm_mmap(struct file *file, s int ret;
/* - * In case of remap_file_pages() emulation, the file can represent - * removed IPC ID: propogate shm_lock() error to caller. + * In case of remap_file_pages() emulation, the file can represent an + * IPC ID that was removed, and possibly even reused by another shm + * segment already. Propagate this case as an error to caller. */ ret = __shm_open(vma); if (ret) @@ -456,6 +463,7 @@ static int shm_release(struct inode *ino struct shm_file_data *sfd = shm_file_data(file);
put_ipc_ns(sfd->ns); + fput(sfd->file); shm_file_data(file) = NULL; kfree(sfd); return 0; @@ -1402,7 +1410,16 @@ long do_shmat(int shmid, char __user *sh file->f_mapping = shp->shm_file->f_mapping; sfd->id = shp->shm_perm.id; sfd->ns = get_ipc_ns(ns); - sfd->file = shp->shm_file; + /* + * We need to take a reference to the real shm file to prevent the + * pointer from becoming stale in cases where the lifetime of the outer + * file extends beyond that of the shm segment. It's not usually + * possible, but it can happen during remap_file_pages() emulation as + * that unmaps the memory, then does ->mmap() via file reference only. + * We'll deny the ->mmap() if the shm segment was since removed, but to + * detect shm ID reuse we need to compare the file pointers. + */ + sfd->file = get_file(shp->shm_file); sfd->vm_ops = NULL;
err = security_mmap_file(file, prot, flags);
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vlastimil Babka vbabka@suse.cz
commit a9f2a846f0503e7d729f552e3ccfe2279010fe94 upstream.
cache_reap() is initially scheduled in start_cpu_timer() via schedule_delayed_work_on(). But then the next iterations are scheduled via schedule_delayed_work(), i.e. using WORK_CPU_UNBOUND.
Thus since commit ef557180447f ("workqueue: schedule WORK_CPU_UNBOUND work on wq_unbound_cpumask CPUs") there is no guarantee the future iterations will run on the originally intended cpu, although it's still preferred. I was able to demonstrate this with /sys/module/workqueue/parameters/debug_force_rr_cpu. IIUC, it may also happen due to migrating timers in nohz context. As a result, some cpu's would be calling cache_reap() more frequently and others never.
This patch uses schedule_delayed_work_on() with the current cpu when scheduling the next iteration.
Link: http://lkml.kernel.org/r/20180411070007.32225-1-vbabka@suse.cz Fixes: ef557180447f ("workqueue: schedule WORK_CPU_UNBOUND work on wq_unbound_cpumask CPUs") Signed-off-by: Vlastimil Babka vbabka@suse.cz Acked-by: Pekka Enberg penberg@kernel.org Acked-by: Christoph Lameter cl@linux.com Cc: Joonsoo Kim iamjoonsoo.kim@lge.com Cc: David Rientjes rientjes@google.com Cc: Tejun Heo tj@kernel.org Cc: Lai Jiangshan jiangshanlai@gmail.com Cc: John Stultz john.stultz@linaro.org Cc: Thomas Gleixner tglx@linutronix.de Cc: Stephen Boyd sboyd@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- mm/slab.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/mm/slab.c +++ b/mm/slab.c @@ -4074,7 +4074,8 @@ next: next_reap_node(); out: /* Set up the next iteration */ - schedule_delayed_work(work, round_jiffies_relative(REAPTIMEOUT_AC)); + schedule_delayed_work_on(smp_processor_id(), work, + round_jiffies_relative(REAPTIMEOUT_AC)); }
void get_slabinfo(struct kmem_cache *cachep, struct slabinfo *sinfo)
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heinrich Schuchardt xypron.glpk@gmx.de
commit af6f8529098aeb0e56a68671b450cf74e7a64fcd upstream.
musb->endpoints[] has array size MUSB_C_NUM_EPS. We must check array bounds before accessing the array and not afterwards.
Signed-off-by: Heinrich Schuchardt xypron.glpk@gmx.de Signed-off-by: Bin Liu b-liu@ti.com Cc: stable stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/musb/musb_gadget_ep0.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
--- a/drivers/usb/musb/musb_gadget_ep0.c +++ b/drivers/usb/musb/musb_gadget_ep0.c @@ -89,15 +89,19 @@ static int service_tx_status_request( }
is_in = epnum & USB_DIR_IN; - if (is_in) { - epnum &= 0x0f; + epnum &= 0x0f; + if (epnum >= MUSB_C_NUM_EPS) { + handled = -EINVAL; + break; + } + + if (is_in) ep = &musb->endpoints[epnum].ep_in; - } else { + else ep = &musb->endpoints[epnum].ep_out; - } regs = musb->endpoints[epnum].regs;
- if (epnum >= MUSB_C_NUM_EPS || !ep->desc) { + if (!ep->desc) { handled = -EINVAL; break; }
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen-Yu Tsai wens@csie.org
commit d7119224bfe6e8efbf821a52db7da9530d790f07 upstream.
The AXP223 PMIC, like the AXP221, does not generate VBUS change interrupts when N_VBUSEN is used to drive VBUS for the OTG port on the board.
This was not noticed until recently, as most A23/A33 boards use a GPIO pin that does not support interrupts for OTG ID detection. This forces the driver to use polling. However the A33-OlinuXino uses a pin that does support interrupts, so the driver uses them. However the VBUS interrupt never fires, and the driver never gets to update the VBUS status. This results in musb timing out waiting for VBUS to rise.
This was worked around for the AXP221 by resorting to polling changes in commit 91d96f06a760 ("phy-sun4i-usb: Add workaround for missing Vbus det interrupts on A31"). This patch adds the A23 and A33 to the list of SoCs that need the workaround.
Fixes: fc1f45ed3043 ("phy-sun4i-usb: Add support for the usb-phys on the sun8i-a33 SoC") Fixes: 123dfdbcfaf5 ("phy-sun4i-usb: Add support for the usb-phys on the sun8i-a23 SoC") Cc: stable@vger.kernel.org # 4.3.x: 68dbc2ce77bb phy-sun4i-usb: Use of_match_node to get model specific config data Cc: stable@vger.kernel.org # 4.3.x: 5cf700ac9d50 phy: phy-sun4i-usb: Fix optional gpios failing probe Cc: stable@vger.kernel.org # 4.3.x: 04e59a0211ff phy-sun4i-usb: Fix irq free conditions to match request conditions Cc: stable@vger.kernel.org # 4.3.x: 91d96f06a760 phy-sun4i-usb: Add workaround for missing Vbus det interrupts on A31 Cc: stable@vger.kernel.org # 4.3.x Signed-off-by: Chen-Yu Tsai wens@csie.org Acked-by: Maxime Ripard maxime.ripard@free-electrons.com Signed-off-by: Kishon Vijay Abraham I kishon@ti.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
Signed-off-by: Kishon Vijay Abraham I kishon@ti.com
--- drivers/phy/allwinner/phy-sun4i-usb.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
--- a/drivers/phy/allwinner/phy-sun4i-usb.c +++ b/drivers/phy/allwinner/phy-sun4i-usb.c @@ -410,11 +410,13 @@ static bool sun4i_usb_phy0_poll(struct s return true;
/* - * The A31 companion pmic (axp221) does not generate vbus change - * interrupts when the board is driving vbus, so we must poll + * The A31/A23/A33 companion pmics (AXP221/AXP223) do not + * generate vbus change interrupts when the board is driving + * vbus using the N_VBUSEN pin on the pmic, so we must poll * when using the pmic for vbus-det _and_ we're driving vbus. */ - if (data->cfg->type == sun6i_a31_phy && + if ((data->cfg->type == sun6i_a31_phy || + data->cfg->type == sun8i_a33_phy) && data->vbus_power_supply && data->phys[0].regulator_on) return true;
@@ -885,7 +887,7 @@ static const struct sun4i_usb_phy_cfg su
static const struct sun4i_usb_phy_cfg sun8i_a23_cfg = { .num_phys = 2, - .type = sun4i_a10_phy, + .type = sun6i_a31_phy, .disc_thresh = 3, .phyctl_offset = REG_PHYCTL_A10, .dedicated_clocks = true,
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felipe Balbi felipe.balbi@linux.intel.com
commit eaa358c7790338d83bb6a31258bdc077de120414 upstream.
Mention that ->complete() should never be called from within usb_ep_queue().
Signed-off-by: Felipe Balbi felipe.balbi@linux.intel.com Cc: stable stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/gadget/udc/core.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c @@ -238,6 +238,9 @@ EXPORT_SYMBOL_GPL(usb_ep_free_request); * arranges to poll once per interval, and the gadget driver usually will * have queued some data to transfer at that time. * + * Note that @req's ->complete() callback must never be called from + * within usb_ep_queue() as that can create deadlock situations. + * * Returns zero, or a negative error code. Endpoints that are not enabled * report errors; errors will also be * reported when the usb peripheral is disconnected.
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jerome Brunet jbrunet@baylibre.com
commit c04ffa71ff491220cac28f55237c9aad379a8656 upstream.
Different modules maybe installed by the user on the eMMC connector of the odroid-c2. While the red modules are working without an issue, it seems some black modules (apparently Samsung based) are having issue at 200MHz
While the tuning algorithm introduced in v4.14 enables high speed modes on every other tested designs, it seems a problem remains for this particular combination of board and eMMC module.
Lowering the maximum frequency of the eMMC on this board until we can figure out a better solution.
Fixes: d341ca88eead ("mmc: meson-gx: rework tuning function") Suggested-by: Ellie Reeves ellierevves@gmail.com Signed-off-by: Jerome Brunet jbrunet@baylibre.com Cc: stable@vger.kernel.org Signed-off-by: Kevin Hilman khilman@baylibre.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts @@ -310,7 +310,7 @@ pinctrl-names = "default", "clk-gate";
bus-width = <8>; - max-frequency = <200000000>; + max-frequency = <100000000>; non-removable; disable-wp; cap-mmc-highspeed;
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marc Zyngier marc.zyngier@arm.com
commit 7d8b44c54e0c7c8f688e3a07f17e6083f849f01f upstream.
vgic_copy_lpi_list() parses the LPI list and picks LPIs targeting a given vcpu. We allocate the array containing the intids before taking the lpi_list_lock, which means we can have an array size that is not equal to the number of LPIs.
This is particularly obvious when looking at the path coming from vgic_enable_lpis, which is not a command, and thus can run in parallel with commands:
vcpu 0: vcpu 1: vgic_enable_lpis its_sync_lpi_pending_table vgic_copy_lpi_list intids = kmalloc_array(irq_count) MAPI(lpi targeting vcpu 0) list_for_each_entry(lpi_list_head) intids[i++] = irq->intid;
At that stage, we will happily overrun the intids array. Boo. An easy fix is is to break once the array is full. The MAPI command will update the config anyway, and we won't miss a thing. We also make sure that lpi_list_count is read exactly once, so that further updates of that value will not affect the array bound check.
Cc: stable@vger.kernel.org Fixes: ccb1d791ab9e ("KVM: arm64: vgic-its: Fix pending table sync") Reviewed-by: Andre Przywara andre.przywara@arm.com Reviewed-by: Eric Auger eric.auger@redhat.com Signed-off-by: Marc Zyngier marc.zyngier@arm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- virt/kvm/arm/vgic/vgic-its.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
--- a/virt/kvm/arm/vgic/vgic-its.c +++ b/virt/kvm/arm/vgic/vgic-its.c @@ -316,21 +316,24 @@ static int vgic_copy_lpi_list(struct kvm struct vgic_dist *dist = &vcpu->kvm->arch.vgic; struct vgic_irq *irq; u32 *intids; - int irq_count = dist->lpi_list_count, i = 0; + int irq_count, i = 0;
/* - * We use the current value of the list length, which may change - * after the kmalloc. We don't care, because the guest shouldn't - * change anything while the command handling is still running, - * and in the worst case we would miss a new IRQ, which one wouldn't - * expect to be covered by this command anyway. + * There is an obvious race between allocating the array and LPIs + * being mapped/unmapped. If we ended up here as a result of a + * command, we're safe (locks are held, preventing another + * command). If coming from another path (such as enabling LPIs), + * we must be careful not to overrun the array. */ + irq_count = READ_ONCE(dist->lpi_list_count); intids = kmalloc_array(irq_count, sizeof(intids[0]), GFP_KERNEL); if (!intids) return -ENOMEM;
spin_lock(&dist->lpi_list_lock); list_for_each_entry(irq, &dist->lpi_list_head, lpi_list) { + if (i == irq_count) + break; /* We don't need to "get" the IRQ, as we hold the list lock. */ if (irq->target_vcpu != vcpu) continue;
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marek Szyprowski m.szyprowski@samsung.com
commit a7480dbcf983c31d8111f864c848e8a75116a87d upstream.
Since commit 04c8b0f82c7d ("irqchip/gic: Make locking a BL_SWITCHER only feature") coupled CPU idle freezes from time to time on Exynos4210. Later commit 313c8c16ee62 ("PM / CPU: replace raw_notifier with atomic_notifier") changed the context in which the CPU idle code is executed, what results in fully reproducible freeze all the time. However, almost the same coupled CPU idle code works fine on Exynos3250 regardless of the changes made in the mentioned commits.
It turned out that the IPI call used on Exynos4210 is conflicting with the change done in the first mentioned commit in GIC. Fix this by using the same code path as for Exynos3250, instead of the IPI call for synchronization with second CPU core, call dsb_sev() directly.
Tested on Exynos4210-based Trats and Origen boards.
Signed-off-by: Marek Szyprowski m.szyprowski@samsung.com CC: stable@vger.kernel.org # v4.13+ Acked-by: Marc Zyngier marc.zyngier@arm.com Acked-by: Bartlomiej Zolnierkiewicz b.zolnierkie@samsung.com Signed-off-by: Krzysztof Kozlowski krzk@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/arm/mach-exynos/pm.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)
--- a/arch/arm/mach-exynos/pm.c +++ b/arch/arm/mach-exynos/pm.c @@ -271,11 +271,7 @@ abort: goto fail;
call_firmware_op(cpu_boot, 1); - - if (soc_is_exynos3250()) - dsb_sev(); - else - arch_send_wakeup_ipi_mask(cpumask_of(1)); + dsb_sev(); } } fail:
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Wang sean.wang@mediatek.com
commit 0629a01920c0f8a3f825361b24863d760610884a upstream.
Fix that USB initialization fails as below runtime log is present during booting on bananapi-r2 board by adding missing regulators the USB device requires. Current regulators USB device uses are being updated with the correct ones to reflect real configurations which are all from fixed regulators rather than MT6323 one's output.
xhci-mtk 1a1c0000.usb: 1a1c0000.usb supply vbus not found, using dummy regulator xhci-mtk 1a240000.usb: 1a240000.usb supply vbus not found, using dummy regulator
Cc: stable@vger.kernel.org Fixes: f4ff257cd160 ("arm: dts: mt7623: add support for Bananapi R2 (BPI-R2) board") Signed-off-by: Sean Wang sean.wang@mediatek.com [mb: update kernel log in commit message] Signed-off-by: Matthias Brugger matthias.bgg@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-)
--- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts +++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts @@ -39,6 +39,24 @@ }; };
+ reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "fixed-3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + reg_5v: regulator-5v { + compatible = "regulator-fixed"; + regulator-name = "fixed-5V"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-boot-on; + regulator-always-on; + }; + gpio_keys { compatible = "gpio-keys"; pinctrl-names = "default"; @@ -468,12 +486,14 @@ };
&usb1 { - vusb33-supply = <&mt6323_vusb_reg>; + vusb33-supply = <®_3p3v>; + vbus-supply = <®_5v>; status = "okay"; };
&usb2 { - vusb33-supply = <&mt6323_vusb_reg>; + vusb33-supply = <®_3p3v>; + vbus-supply = <®_5v>; status = "okay"; };
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicolas Ferre nicolas.ferre@microchip.com
commit e8fd0adf105e132fd84545997bbef3d5edc2c9c1 upstream.
There are only 19 PIOB pins having primary names PB0-PB18. Not all of them have a 'C' function. So the pinctrl property mask ends up being the same as the other SoC of the at91sam9x5 series.
Reported-by: Marek Sieranski marek.sieranski@microchip.com Signed-off-by: Nicolas Ferre nicolas.ferre@microchip.com Cc: stable@vger.kernel.org # v3.8+ Signed-off-by: Alexandre Belloni alexandre.belloni@bootlin.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/arm/boot/dts/at91sam9g25.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/arm/boot/dts/at91sam9g25.dtsi +++ b/arch/arm/boot/dts/at91sam9g25.dtsi @@ -21,7 +21,7 @@ atmel,mux-mask = < /* A B C */ 0xffffffff 0xffe0399f 0xc000001c /* pioA */ - 0x0007ffff 0x8000fe3f 0x00000000 /* pioB */ + 0x0007ffff 0x00047e3f 0x00000000 /* pioB */ 0x80000000 0x07c0ffff 0xb83fffff /* pioC */ 0x003fffff 0x003f8000 0x00000000 /* pioD */ >;
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marek Szyprowski m.szyprowski@samsung.com
commit 6f4870753f29edf7dc39444246f9e39987b8b158 upstream.
The proper name for the property, which assign given device to IOMMU is 'iommus', not 'iommu'. Fix incorrect name and let all GScaler devices to be properly handled when IOMMU support is enabled.
Reported-by: Andrzej Hajda a.hajda@samsung.com Signed-off-by: Marek Szyprowski m.szyprowski@samsung.com Fixes: 6cbfdd73a94f ("ARM: dts: add sysmmu nodes for exynos5250") Cc: stable@vger.kernel.org # v4.8+ Signed-off-by: Krzysztof Kozlowski krzk@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/arm/boot/dts/exynos5250.dtsi | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
--- a/arch/arm/boot/dts/exynos5250.dtsi +++ b/arch/arm/boot/dts/exynos5250.dtsi @@ -655,7 +655,7 @@ power-domains = <&pd_gsc>; clocks = <&clock CLK_GSCL0>; clock-names = "gscl"; - iommu = <&sysmmu_gsc0>; + iommus = <&sysmmu_gsc0>; };
gsc_1: gsc@13e10000 { @@ -665,7 +665,7 @@ power-domains = <&pd_gsc>; clocks = <&clock CLK_GSCL1>; clock-names = "gscl"; - iommu = <&sysmmu_gsc1>; + iommus = <&sysmmu_gsc1>; };
gsc_2: gsc@13e20000 { @@ -675,7 +675,7 @@ power-domains = <&pd_gsc>; clocks = <&clock CLK_GSCL2>; clock-names = "gscl"; - iommu = <&sysmmu_gsc2>; + iommus = <&sysmmu_gsc2>; };
gsc_3: gsc@13e30000 { @@ -685,7 +685,7 @@ power-domains = <&pd_gsc>; clocks = <&clock CLK_GSCL3>; clock-names = "gscl"; - iommu = <&sysmmu_gsc3>; + iommus = <&sysmmu_gsc3>; };
hdmi: hdmi@14530000 {
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Santiago Esteban Santiago.Esteban@microchip.com
commit 9a06757dcc8509c162ac00488c8c82fc98e04227 upstream.
The compatible string is incorrect. Add atmel,sama5d3-pinctrl since it's the appropriate compatible string. Remove the atmel,at91rm9200-pinctrl compatible string, this fallback is useless, there are too many changes.
Signed-off-by: Santiago Esteban Santiago.Esteban@microchip.com Signed-off-by: Ludovic Desroches ludovic.desroches@microchip.com Cc: stable@vger.kernel.org #v3.18 Signed-off-by: Alexandre Belloni alexandre.belloni@bootlin.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/arm/boot/dts/sama5d4.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/arm/boot/dts/sama5d4.dtsi +++ b/arch/arm/boot/dts/sama5d4.dtsi @@ -1379,7 +1379,7 @@ pinctrl@fc06a000 { #address-cells = <1>; #size-cells = <1>; - compatible = "atmel,at91sam9x5-pinctrl", "atmel,at91rm9200-pinctrl", "simple-bus"; + compatible = "atmel,sama5d3-pinctrl", "atmel,at91sam9x5-pinctrl", "simple-bus"; ranges = <0xfc068000 0xfc068000 0x100 0xfc06a000 0xfc06a000 0x4000>; /* WARNING: revisit as pin spec has changed */
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eugen Hristev eugen.hristev@microchip.com
commit 9581329eff9db72ab4fbb46a594fd7fdda3c51b0 upstream.
The datasheet recommends initializing FIFOs before SPI enable. If we do not do it like this, there may be a strange behavior. We noticed that DMA does not work properly with FIFOs if we do not clear them beforehand or enable them before SPIEN.
Signed-off-by: Eugen Hristev eugen.hristev@microchip.com Acked-by: Nicolas Ferre nicolas.ferre@microchip.com Signed-off-by: Mark Brown broonie@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/spi/spi-atmel.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
--- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c @@ -1512,6 +1512,11 @@ static void atmel_spi_init(struct atmel_ { spi_writel(as, CR, SPI_BIT(SWRST)); spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ + + /* It is recommended to enable FIFOs first thing after reset */ + if (as->fifo_size) + spi_writel(as, CR, SPI_BIT(FIFOEN)); + if (as->caps.has_wdrbt) { spi_writel(as, MR, SPI_BIT(WDRBT) | SPI_BIT(MODFDIS) | SPI_BIT(MSTR)); @@ -1522,9 +1527,6 @@ static void atmel_spi_init(struct atmel_ if (as->use_pdc) spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS)); spi_writel(as, CR, SPI_BIT(SPIEN)); - - if (as->fifo_size) - spi_writel(as, CR, SPI_BIT(FIFOEN)); }
static int atmel_spi_probe(struct platform_device *pdev)
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maxime Chevallier maxime.chevallier@bootlin.com
commit ce99319a182fe766be67f96338386f3ec73e321c upstream.
When SPI transfers can be offloaded using DMA, the SPI core need to build a scatterlist to make sure that the buffer to be transferred is dma-able.
This patch fixes the scatterlist entry size computation in the case where the maximum acceptable scatterlist entry supported by the DMA controller is less than PAGE_SIZE, when the buffer is vmalloced.
For each entry, the actual size is given by the minimum between the desc_len (which is the max buffer size supported by the DMA controller) and the remaining buffer length until we cross a page boundary.
Fixes: 65598c13fd66 ("spi: Fix per-page mapping of unaligned vmalloc-ed buffer") Signed-off-by: Maxime Chevallier maxime.chevallier@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/spi/spi.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
--- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -779,8 +779,14 @@ static int spi_map_buf(struct spi_contro for (i = 0; i < sgs; i++) {
if (vmalloced_buf || kmap_buf) { - min = min_t(size_t, - len, desc_len - offset_in_page(buf)); + /* + * Next scatterlist entry size is the minimum between + * the desc_len and the remaining buffer length that + * fits in a page. + */ + min = min_t(size_t, desc_len, + min_t(size_t, len, + PAGE_SIZE - offset_in_page(buf))); if (vmalloced_buf) vm_page = vmalloc_to_page(buf); else
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jarkko Nikula jarkko.nikula@linux.intel.com
commit 613bd1ea387bb48b7c9a71a0bb451ac15cfbbc01 upstream.
Commit 9b61e302210e (spi: Pick spi bus number from Linux idr or spi alias) ceased to unregister SPI buses with fixed bus numbers. Moreover this is visible only if CONFIG_SPI_DEBUG=y is set or when trying to re-register the same SPI controller.
rmmod spi_pxa2xx_platform (with CONFIG_SPI_DEBUG=y): [ 26.788362] spi_master spi1: attempting to delete unregistered controller [spi1]
modprobe spi_pxa2xx_platform: [ 37.883137] sysfs: cannot create duplicate filename '/devices/pci0000:00/0000:00:19.0/pxa2xx-spi.12/spi_master/spi1' [ 37.894984] CPU: 1 PID: 1467 Comm: modprobe Not tainted 4.16.0-rc4+ #21 [ 37.902384] Call Trace: ... [ 38.122680] kobject_add_internal failed for spi1 with -EEXIST, don't try to register things with the same name in the same directory. [ 38.136154] WARNING: CPU: 1 PID: 1467 at lib/kobject.c:238 kobject_add_internal+0x2a5/0x2f0 ... [ 38.513817] pxa2xx-spi pxa2xx-spi.12: problem registering spi master [ 38.521036] pxa2xx-spi: probe of pxa2xx-spi.12 failed with error -17
Fix this by not returning immediately from spi_unregister_controller() if idr_find() doesn't find controller with given ID/bus number. It finds only those controllers that were registered with dynamic SPI bus numbers. Only conditional cleanup between dynamic and fixed bus numbers is to remove allocated IDR.
Fixes: 9b61e302210e (spi: Pick spi bus number from Linux idr or spi alias) Cc: stable@vger.kernel.org Signed-off-by: Jarkko Nikula jarkko.nikula@linux.intel.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/spi/spi.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-)
--- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -2260,12 +2260,6 @@ void spi_unregister_controller(struct sp mutex_lock(&board_lock); found = idr_find(&spi_master_idr, id); mutex_unlock(&board_lock); - if (found != ctlr) { - dev_dbg(&ctlr->dev, - "attempting to delete unregistered controller [%s]\n", - dev_name(&ctlr->dev)); - return; - } if (ctlr->queued) { if (spi_destroy_queue(ctlr)) dev_err(&ctlr->dev, "queue remove failed\n"); @@ -2278,7 +2272,8 @@ void spi_unregister_controller(struct sp device_unregister(&ctlr->dev); /* free bus id */ mutex_lock(&board_lock); - idr_remove(&spi_master_idr, id); + if (found == ctlr) + idr_remove(&spi_master_idr, id); mutex_unlock(&board_lock); } EXPORT_SYMBOL_GPL(spi_unregister_controller);
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Young sean@mess.org
commit 8d4068810d9926250dd2435719a080b889eb44c3 upstream.
If there is IR in the raw kfifo when ir_raw_event_unregister() is called, then kthread_stop() causes ir_raw_event_thread to be scheduled, decode some scancodes and re-arm timer_keyup. The timer_keyup then fires when the rc device is long gone.
Cc: stable@vger.kernel.org Signed-off-by: Sean Young sean@mess.org Signed-off-by: Mauro Carvalho Chehab mchehab@s-opensource.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/media/rc/rc-main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -1929,12 +1929,12 @@ void rc_unregister_device(struct rc_dev if (!dev) return;
- del_timer_sync(&dev->timer_keyup); - del_timer_sync(&dev->timer_repeat); - if (dev->driver_type == RC_DRIVER_IR_RAW) ir_raw_event_unregister(dev);
+ del_timer_sync(&dev->timer_keyup); + del_timer_sync(&dev->timer_repeat); + rc_free_rx_device(dev);
mutex_lock(&dev->lock);
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans Verkuil hverkuil@xs4all.nl
commit 57e6b6f2303e596a6493078b53be14b789e7b79f upstream.
The atomisp_compat_ioctl32() code has problems. This patch disables the compat_ioctl32 support until those issues have been fixed.
Contact Sakari or me for more details.
Signed-off-by: Hans Verkuil hans.verkuil@cisco.com Cc: stable@vger.kernel.org # for v4.12 and up Signed-off-by: Sakari Ailus sakari.ailus@linux.intel.com Signed-off-by: Mauro Carvalho Chehab mchehab@s-opensource.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/staging/media/atomisp/pci/atomisp2/atomisp_fops.c | 6 ++++++ 1 file changed, 6 insertions(+)
--- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_fops.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_fops.c @@ -1279,7 +1279,10 @@ const struct v4l2_file_operations atomis .mmap = atomisp_mmap, .unlocked_ioctl = video_ioctl2, #ifdef CONFIG_COMPAT + /* + * There are problems with this code. Disable this for now. .compat_ioctl32 = atomisp_compat_ioctl32, + */ #endif .poll = atomisp_poll, }; @@ -1291,7 +1294,10 @@ const struct v4l2_file_operations atomis .mmap = atomisp_file_mmap, .unlocked_ioctl = video_ioctl2, #ifdef CONFIG_COMPAT + /* + * There are problems with this code. Disable this for now. .compat_ioctl32 = atomisp_compat_ioctl32, + */ #endif .poll = atomisp_poll, };
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans Verkuil hverkuil@xs4all.nl
commit ed356f110403f6acc64dcbbbfdc38662ab9b06c2 upstream.
If CEC is not enabled for the vivid driver, then the adap pointer is NULL and 'adap->phys_addr' will fail.
Cc: stable@vger.kernel.org # for v4.12 and up Signed-off-by: Hans Verkuil hans.verkuil@cisco.com Signed-off-by: Mauro Carvalho Chehab mchehab@s-opensource.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/media/platform/vivid/vivid-vid-common.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/media/platform/vivid/vivid-vid-common.c +++ b/drivers/media/platform/vivid/vivid-vid-common.c @@ -874,7 +874,8 @@ int vidioc_g_edid(struct file *file, voi return -EINVAL; if (edid->start_block + edid->blocks > dev->edid_blocks) edid->blocks = dev->edid_blocks - edid->start_block; - cec_set_edid_phys_addr(dev->edid, dev->edid_blocks * 128, adap->phys_addr); + if (adap) + cec_set_edid_phys_addr(dev->edid, dev->edid_blocks * 128, adap->phys_addr); memcpy(edid->edid, dev->edid + edid->start_block * 128, edid->blocks * 128); return 0; }
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sakari Ailus sakari.ailus@linux.intel.com
commit 03703ed1debf777ea845aa9b50ba2e80a5e7dd3c upstream.
If buffers were prepared or queued and the buffers were released without starting the queue, the finish mem op (corresponding to the prepare mem op) was never called to the buffers.
Before commit a136f59c0a1f there was no need to do this as in such a case the prepare mem op had not been called yet. Address the problem by explicitly calling finish mem op when the queue is stopped if the buffer is in either prepared or queued state.
Fixes: a136f59c0a1f ("[media] vb2: Move buffer cache synchronisation to prepare from queue")
Cc: stable@vger.kernel.org # for v4.13 and up Signed-off-by: Sakari Ailus sakari.ailus@linux.intel.com Tested-by: Devin Heitmueller dheitmueller@kernellabs.com Signed-off-by: Hans Verkuil hans.verkuil@cisco.com Signed-off-by: Mauro Carvalho Chehab mchehab@s-opensource.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/media/common/videobuf2/videobuf2-core.c | 9 +++++++++ 1 file changed, 9 insertions(+)
--- a/drivers/media/common/videobuf2/videobuf2-core.c +++ b/drivers/media/common/videobuf2/videobuf2-core.c @@ -1696,6 +1696,15 @@ static void __vb2_queue_cancel(struct vb for (i = 0; i < q->num_buffers; ++i) { struct vb2_buffer *vb = q->bufs[i];
+ if (vb->state == VB2_BUF_STATE_PREPARED || + vb->state == VB2_BUF_STATE_QUEUED) { + unsigned int plane; + + for (plane = 0; plane < vb->num_planes; ++plane) + call_void_memop(vb, finish, + vb->planes[plane].mem_priv); + } + if (vb->state != VB2_BUF_STATE_DEQUEUED) { vb->state = VB2_BUF_STATE_PREPARED; call_void_vb_qop(vb, buf_finish, vb);
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kieran Bingham kieran.bingham@ideasonboard.com
commit 639fa43d59e5a41ca8c55592cd5c1021fea2ab83 upstream.
When a BRx is provided by a pipeline, the WPF must determine the master layer. Currently the condition to check this identifies pipe->bru || pipe->num_inputs > 1.
The code then moves on to dereference pipe->bru, thus the check fails static analysers on the possibility that pipe->num_inputs could be greater than 1 without pipe->bru being set.
The reality is that the pipeline must have a BRx to support more than one input, thus this could never cause a fault - however it also identifies that the num_inputs > 1 check is redundant.
Remove the redundant check - and always configure the master layer appropriately when we have a BRx configured in our pipeline.
Fixes: 6134148f6098 ("v4l: vsp1: Add support for the BRS entity")
Cc: stable@vger.kernel.org Suggested-by: Mauro Carvalho Chehab mchehab@s-opensource.com Signed-off-by: Kieran Bingham kieran.bingham+renesas@ideasonboard.com Reviewed-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Mauro Carvalho Chehab mchehab@s-opensource.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/media/platform/vsp1/vsp1_wpf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/media/platform/vsp1/vsp1_wpf.c +++ b/drivers/media/platform/vsp1/vsp1_wpf.c @@ -452,7 +452,7 @@ static void wpf_configure(struct vsp1_en : VI6_WPF_SRCRPF_RPF_ACT_SUB(input->entity.index); }
- if (pipe->bru || pipe->num_inputs > 1) + if (pipe->bru) srcrpf |= pipe->bru->type == VSP1_ENTITY_BRU ? VI6_WPF_SRCRPF_VIRACT_MST : VI6_WPF_SRCRPF_VIRACT2_MST;
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Andryuk jandryuk@gmail.com
commit 36104cb9012a82e73c32a3b709257766b16bcd1d upstream.
Commit 2cc42bac1c79 ("x86-64/Xen: eliminate W+X mappings") introduced a call to get_cpu_cap, which is fstack-protected. This is works on x86-64 as commit 4f277295e54c ("x86/xen: init %gs very early to avoid page faults with stack protector") ensures the stack protector is configured, but it it did not cover x86-32.
Delay calling get_cpu_cap until after xen_setup_gdt has initialized the stack canary. Without this, a 32bit PV machine crashes early in boot. (XEN) Domain 0 (vcpu#0) crashed on cpu#0: (XEN) ----[ Xen-4.6.6-xc x86_64 debug=n Tainted: C ]---- (XEN) CPU: 0 (XEN) RIP: e019:[<00000000c10362f8>]
And the PV kernel IP corresponds to init_scattered_cpuid_features 0xc10362f8 <+24>: mov %gs:0x14,%eax
Fixes 2cc42bac1c79 ("x86-64/Xen: eliminate W+X mappings")
Signed-off-by: Jason Andryuk jandryuk@gmail.com Reviewed-by: Boris Ostrovsky boris.ostrovsky@oracle.com Signed-off-by: Boris Ostrovsky boris.ostrovsky@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/x86/xen/enlighten_pv.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
--- a/arch/x86/xen/enlighten_pv.c +++ b/arch/x86/xen/enlighten_pv.c @@ -1259,10 +1259,6 @@ asmlinkage __visible void __init xen_sta */ __userpte_alloc_gfp &= ~__GFP_HIGHMEM;
- /* Work out if we support NX */ - get_cpu_cap(&boot_cpu_data); - x86_configure_nx(); - /* Get mfn list */ xen_build_dynamic_phys_to_machine();
@@ -1272,6 +1268,10 @@ asmlinkage __visible void __init xen_sta */ xen_setup_gdt(0);
+ /* Work out if we support NX */ + get_cpu_cap(&boot_cpu_data); + x86_configure_nx(); + xen_init_irq_ops();
/* Let's presume PV guests always boot on vCPU with id 0. */
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter dan.carpenter@oracle.com
commit f00e71091ab92eba52122332586c6ecaa9cd1a56 upstream.
We're supposed to be checking that "val_len" is not too large but instead we check if it is smaller than the max.
The only function affected would be regmap_i2c_smbus_i2c_write() in drivers/base/regmap/regmap-i2c.c. Strangely that function has its own limit check which returns an error if (count >= I2C_SMBUS_BLOCK_MAX) so it doesn't look like it has ever been able to do anything except return an error.
Fixes: c335931ed9d2 ("regmap: Add raw_write/read checks for max_raw_write/read sizes") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Mark Brown broonie@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/base/regmap/regmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -1831,7 +1831,7 @@ int regmap_raw_write(struct regmap *map, return -EINVAL; if (val_len % map->format.val_bytes) return -EINVAL; - if (map->max_raw_write && map->max_raw_write > val_len) + if (map->max_raw_write && map->max_raw_write < val_len) return -E2BIG;
map->lock(map->lock_arg);
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans de Goede hdegoede@redhat.com
commit bbf038618a24d72e2efc19146ef421bb1e1eda1a upstream.
Just like many other Samsung models, the 670Z5E needs to use the acpi-video backlight interface rather then the native one for backlight control to work, add a quirk for this.
Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1557060 Cc: All applicable stable@vger.kernel.org Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/acpi/video_detect.c | 9 +++++++++ 1 file changed, 9 insertions(+)
--- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -220,6 +220,15 @@ static const struct dmi_system_id video_ }, }, { + /* https://bugzilla.redhat.com/show_bug.cgi?id=1557060 */ + .callback = video_detect_force_video, + .ident = "SAMSUNG 670Z5E", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), + DMI_MATCH(DMI_PRODUCT_NAME, "670Z5E"), + }, + }, + { /* https://bugzilla.redhat.com/show_bug.cgi?id=1094948 */ .callback = video_detect_force_video, .ident = "SAMSUNG 730U3E/740U3E",
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mika Westerberg mika.westerberg@linux.intel.com
commit 13d3047c81505cc0fb9bdae7810676e70523c8bf upstream.
Mike Lothian reported that plugging in a USB-C device does not work properly in his Dell Alienware system. This system has an Intel Alpine Ridge Thunderbolt controller providing USB-C functionality. In these systems the USB controller (xHCI) is hotplugged whenever a device is connected to the port using ACPI-based hotplug.
The ACPI description of the root port in question is as follows:
Device (RP01) { Name (_ADR, 0x001C0000)
Device (PXSX) { Name (_ADR, 0x02)
Method (_RMV, 0, NotSerialized) { // ... } }
Here _ADR 0x02 means device 0, function 2 on the bus under root port (RP01) but that seems to be incorrect because device 0 is the upstream port of the Alpine Ridge PCIe switch and it has no functions other than 0 (the bridge itself). When we get ACPI Notify() to the root port resulting from connecting a USB-C device, Linux tries to read PCI_VENDOR_ID from device 0, function 2 which of course always returns 0xffffffff because there is no such function and we never find the device.
In Windows this works fine.
Now, since we get ACPI Notify() to the root port and not to the PXSX device we should actually start our scan from there as well and not from the non-existent PXSX device. Fix this by checking presence of the slot itself (function 0) if we fail to do that otherwise.
While there use pci_bus_read_dev_vendor_id() in get_slot_status(), which is the recommended way to read Device and Vendor IDs of devices on PCI buses.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=198557 Reported-by: Mike Lothian mike@fireburn.co.uk Signed-off-by: Mika Westerberg mika.westerberg@linux.intel.com Signed-off-by: Bjorn Helgaas bhelgaas@google.com Reviewed-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/pci/hotplug/acpiphp_glue.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-)
--- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -541,6 +541,7 @@ static unsigned int get_slot_status(stru { unsigned long long sta = 0; struct acpiphp_func *func; + u32 dvid;
list_for_each_entry(func, &slot->funcs, sibling) { if (func->flags & FUNC_HAS_STA) { @@ -551,19 +552,27 @@ static unsigned int get_slot_status(stru if (ACPI_SUCCESS(status) && sta) break; } else { - u32 dvid; - - pci_bus_read_config_dword(slot->bus, - PCI_DEVFN(slot->device, - func->function), - PCI_VENDOR_ID, &dvid); - if (dvid != 0xffffffff) { + if (pci_bus_read_dev_vendor_id(slot->bus, + PCI_DEVFN(slot->device, func->function), + &dvid, 0)) { sta = ACPI_STA_ALL; break; } } }
+ if (!sta) { + /* + * Check for the slot itself since it may be that the + * ACPI slot is a device below PCIe upstream port so in + * that case it may not even be reachable yet. + */ + if (pci_bus_read_dev_vendor_id(slot->bus, + PCI_DEVFN(slot->device, 0), &dvid, 0)) { + sta = ACPI_STA_ALL; + } + } + return (unsigned int)sta; }
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Williams dan.j.williams@intel.com
commit 466d1493ea830789a2f063f478aaed2e324f0d3d upstream.
Some BIOSen do not handle 0-byte transfer lengths for the _LSR and _LSW (label storage read/write) methods. This causes Linux to fallback to the deprecated _DSM path, or otherwise disable label support.
Introduce acpi_nvdimm_has_method() to detect whether a method is available rather than calling the method, require _LSI and _LSR to be paired, and require read support before enabling write support.
Cc: stable@vger.kernel.org Fixes: 4b27db7e26cd ("acpi, nfit: add support for the _LS...") Suggested-by: Erik Schmauss erik.schmauss@intel.com Signed-off-by: Dan Williams dan.j.williams@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/acpi/nfit/core.c | 41 +++++++++++++++++++++-------------------- drivers/acpi/nfit/nfit.h | 5 ++--- 2 files changed, 23 insertions(+), 23 deletions(-)
--- a/drivers/acpi/nfit/core.c +++ b/drivers/acpi/nfit/core.c @@ -196,7 +196,7 @@ static int xlat_nvdimm_status(struct nvd * In the _LSI, _LSR, _LSW case the locked status is * communicated via the read/write commands */ - if (nfit_mem->has_lsi) + if (nfit_mem->has_lsr) break;
if (status >> 16 & ND_CONFIG_LOCKED) @@ -483,7 +483,7 @@ int acpi_nfit_ctl(struct nvdimm_bus_desc min_t(u32, 256, in_buf.buffer.length), true);
/* call the BIOS, prefer the named methods over _DSM if available */ - if (nvdimm && cmd == ND_CMD_GET_CONFIG_SIZE && nfit_mem->has_lsi) + if (nvdimm && cmd == ND_CMD_GET_CONFIG_SIZE && nfit_mem->has_lsr) out_obj = acpi_label_info(handle); else if (nvdimm && cmd == ND_CMD_GET_CONFIG_DATA && nfit_mem->has_lsr) { struct nd_cmd_get_config_data_hdr *p = buf; @@ -1654,12 +1654,23 @@ static void acpi_nvdimm_notify(acpi_hand device_unlock(dev->parent); }
+static bool acpi_nvdimm_has_method(struct acpi_device *adev, char *method) +{ + acpi_handle handle; + acpi_status status; + + status = acpi_get_handle(adev->handle, method, &handle); + + if (ACPI_SUCCESS(status)) + return true; + return false; +} + static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc, struct nfit_mem *nfit_mem, u32 device_handle) { struct acpi_device *adev, *adev_dimm; struct device *dev = acpi_desc->dev; - union acpi_object *obj; unsigned long dsm_mask; const guid_t *guid; int i; @@ -1732,25 +1743,15 @@ static int acpi_nfit_add_dimm(struct acp 1ULL << i)) set_bit(i, &nfit_mem->dsm_mask);
- obj = acpi_label_info(adev_dimm->handle); - if (obj) { - ACPI_FREE(obj); - nfit_mem->has_lsi = 1; - dev_dbg(dev, "%s: has _LSI\n", dev_name(&adev_dimm->dev)); - } - - obj = acpi_label_read(adev_dimm->handle, 0, 0); - if (obj) { - ACPI_FREE(obj); - nfit_mem->has_lsr = 1; + if (acpi_nvdimm_has_method(adev_dimm, "_LSI") + && acpi_nvdimm_has_method(adev_dimm, "_LSR")) { dev_dbg(dev, "%s: has _LSR\n", dev_name(&adev_dimm->dev)); + nfit_mem->has_lsr = true; }
- obj = acpi_label_write(adev_dimm->handle, 0, 0, NULL); - if (obj) { - ACPI_FREE(obj); - nfit_mem->has_lsw = 1; + if (nfit_mem->has_lsr && acpi_nvdimm_has_method(adev_dimm, "_LSW")) { dev_dbg(dev, "%s: has _LSW\n", dev_name(&adev_dimm->dev)); + nfit_mem->has_lsw = true; }
return 0; @@ -1839,10 +1840,10 @@ static int acpi_nfit_register_dimms(stru cmd_mask |= nfit_mem->dsm_mask & NVDIMM_STANDARD_CMDMASK; }
- if (nfit_mem->has_lsi) + if (nfit_mem->has_lsr) { set_bit(ND_CMD_GET_CONFIG_SIZE, &cmd_mask); - if (nfit_mem->has_lsr) set_bit(ND_CMD_GET_CONFIG_DATA, &cmd_mask); + } if (nfit_mem->has_lsw) set_bit(ND_CMD_SET_CONFIG_DATA, &cmd_mask);
--- a/drivers/acpi/nfit/nfit.h +++ b/drivers/acpi/nfit/nfit.h @@ -171,9 +171,8 @@ struct nfit_mem { struct resource *flush_wpq; unsigned long dsm_mask; int family; - u32 has_lsi:1; - u32 has_lsr:1; - u32 has_lsw:1; + bool has_lsr; + bool has_lsw; };
struct acpi_nfit_desc {
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yavuz, Tuba tuba@ece.ufl.edu
commit 7fafcfdf6377b18b2a726ea554d6e593ba44349f upstream.
It looks like there is a possibility of a double-free vulnerability on an error path of the f_midi_set_alt function in the f_midi driver. If the path is feasible then free_ep_req gets called twice:
req->complete = f_midi_complete; err = usb_ep_queue(midi->out_ep, req, GFP_ATOMIC); => ... usb_gadget_giveback_request => f_midi_complete (CALLBACK) (inside f_midi_complete, for various cases of status) free_ep_req(ep, req); // first kfree if (err) { ERROR(midi, "%s: couldn't enqueue request: %d\n", midi->out_ep->name, err); free_ep_req(midi->out_ep, req); // second kfree return err; }
The double-free possibility was introduced with commit ad0d1a058eac ("usb: gadget: f_midi: fix leak on failed to enqueue out requests").
Found by MOXCAFE tool.
Signed-off-by: Tuba Yavuz tuba@ece.ufl.edu Fixes: ad0d1a058eac ("usb: gadget: f_midi: fix leak on failed to enqueue out requests") Acked-by: Felipe Balbi felipe.balbi@linux.intel.com Cc: stable stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/gadget/function/f_midi.c | 3 ++- drivers/usb/gadget/u_f.h | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-)
--- a/drivers/usb/gadget/function/f_midi.c +++ b/drivers/usb/gadget/function/f_midi.c @@ -404,7 +404,8 @@ static int f_midi_set_alt(struct usb_fun if (err) { ERROR(midi, "%s: couldn't enqueue request: %d\n", midi->out_ep->name, err); - free_ep_req(midi->out_ep, req); + if (req->buf != NULL) + free_ep_req(midi->out_ep, req); return err; } } --- a/drivers/usb/gadget/u_f.h +++ b/drivers/usb/gadget/u_f.h @@ -61,7 +61,9 @@ struct usb_request *alloc_ep_req(struct /* Frees a usb_request previously allocated by alloc_ep_req() */ static inline void free_ep_req(struct usb_ep *ep, struct usb_request *req) { + WARN_ON(req->buf == NULL); kfree(req->buf); + req->buf = NULL; usb_ep_free_request(ep, req); }
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Roger Quadros rogerq@ti.com
commit daaecc6541d014dca073473ec8a4120c0babbeb4 upstream.
We don't support PRTCAP == OTG yet, so prevent user from setting it via debugfs.
Fixes: 41ce1456e1db ("usb: dwc3: core: make dwc3_set_mode() work properly") Cc: stable@vger.kernel.org # v4.12+ Signed-off-by: Roger Quadros rogerq@ti.com Signed-off-by: Felipe Balbi felipe.balbi@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/dwc3/core.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -119,6 +119,9 @@ static void __dwc3_set_mode(struct work_ if (dwc->dr_mode != USB_DR_MODE_OTG) return;
+ if (dwc->desired_dr_role == DWC3_GCTL_PRTCAP_OTG) + return; + switch (dwc->current_dr_role) { case DWC3_GCTL_PRTCAP_HOST: dwc3_host_exit(dwc);
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thinh Nguyen Thinh.Nguyen@synopsys.com
commit cabdf83dadfb3d83eec31e0f0638a92dbd716435 upstream.
Platform device is allocated before adding resources. Make sure to properly cleanup on error case.
Cc: stable@vger.kernel.org Fixes: f1c7e7108109 ("usb: dwc3: convert to pcim_enable_device()") Signed-off-by: Thinh Nguyen thinhn@synopsys.com 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 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -222,7 +222,7 @@ static int dwc3_pci_probe(struct pci_dev ret = platform_device_add_resources(dwc->dwc3, res, ARRAY_SIZE(res)); if (ret) { dev_err(dev, "couldn't add resources to dwc3 device\n"); - return ret; + goto err; }
dwc->pci = pci;
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felipe Balbi felipe.balbi@linux.intel.com
commit c91815b596245fd7da349ecc43c8def670d2269e upstream.
This is a requirement which has always existed but, somehow, wasn't reflected in the documentation and problems weren't found until now when Tuba Yavuz found a possible deadlock happening between dwc3 and f_hid. She described the situation as follows:
spin_lock_irqsave(&hidg->write_spinlock, flags); // first acquire /* we our function has been disabled by host */ if (!hidg->req) { free_ep_req(hidg->in_ep, hidg->req); goto try_again; }
[...]
status = usb_ep_queue(hidg->in_ep, hidg->req, GFP_ATOMIC); => [...] => usb_gadget_giveback_request => f_hidg_req_complete => spin_lock_irqsave(&hidg->write_spinlock, flags); // second acquire
Note that this happens because dwc3 would call ->complete() on a failed usb_ep_queue() due to failed Start Transfer command. This is, anyway, a theoretical situation because dwc3 currently uses "No Response Update Transfer" command for Bulk and Interrupt endpoints.
It's still good to make this case impossible to happen even if the "No Reponse Update Transfer" command is changed.
Reported-by: Tuba Yavuz tuba@ece.ufl.edu Signed-off-by: Felipe Balbi felipe.balbi@linux.intel.com Cc: stable stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/dwc3/gadget.c | 43 +++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 deletions(-)
--- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -166,18 +166,8 @@ static void dwc3_ep_inc_deq(struct dwc3_ dwc3_ep_inc_trb(&dep->trb_dequeue); }
-/** - * dwc3_gadget_giveback - call struct usb_request's ->complete callback - * @dep: The endpoint to whom the request belongs to - * @req: The request we're giving back - * @status: completion code for the request - * - * Must be called with controller's lock held and interrupts disabled. This - * function will unmap @req and call its ->complete() callback to notify upper - * layers that it has completed. - */ -void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, - int status) +void dwc3_gadget_del_and_unmap_request(struct dwc3_ep *dep, + struct dwc3_request *req, int status) { struct dwc3 *dwc = dep->dwc;
@@ -190,18 +180,35 @@ void dwc3_gadget_giveback(struct dwc3_ep
if (req->trb) usb_gadget_unmap_request_by_dev(dwc->sysdev, - &req->request, req->direction); + &req->request, req->direction);
req->trb = NULL; - trace_dwc3_gadget_giveback(req);
+ if (dep->number > 1) + pm_runtime_put(dwc->dev); +} + +/** + * dwc3_gadget_giveback - call struct usb_request's ->complete callback + * @dep: The endpoint to whom the request belongs to + * @req: The request we're giving back + * @status: completion code for the request + * + * Must be called with controller's lock held and interrupts disabled. This + * function will unmap @req and call its ->complete() callback to notify upper + * layers that it has completed. + */ +void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, + int status) +{ + struct dwc3 *dwc = dep->dwc; + + dwc3_gadget_del_and_unmap_request(dep, req, status); + spin_unlock(&dwc->lock); usb_gadget_giveback_request(&dep->endpoint, &req->request); spin_lock(&dwc->lock); - - if (dep->number > 1) - pm_runtime_put(dwc->dev); }
/** @@ -1227,7 +1234,7 @@ static int __dwc3_gadget_kick_transfer(s if (req->trb) memset(req->trb, 0, sizeof(struct dwc3_trb)); dep->queued_requests--; - dwc3_gadget_giveback(dep, req, ret); + dwc3_gadget_del_and_unmap_request(dep, req, ret); return ret; }
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ronnie Sahlberg lsahlber@redhat.com
commit b7a73c84eb96dabd6bb8e9d7c56f796d83efee8e upstream.
Signed-off-by: Ronnie Sahlberg lsahlber@redhat.com Signed-off-by: Steve French smfrench@gmail.com CC: Stable stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/cifs/smb2pdu.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
--- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -1738,8 +1738,10 @@ SMB2_open(const unsigned int xid, struct rc = alloc_path_with_tree_prefix(©_path, ©_size, &name_len, tcon->treeName, path); - if (rc) + if (rc) { + cifs_small_buf_release(req); return rc; + } req->NameLength = cpu_to_le16(name_len * 2); uni_path_len = copy_size; path = copy_path; @@ -1750,8 +1752,10 @@ SMB2_open(const unsigned int xid, struct if (uni_path_len % 8 != 0) { copy_size = roundup(uni_path_len, 8); copy_path = kzalloc(copy_size, GFP_KERNEL); - if (!copy_path) + if (!copy_path) { + cifs_small_buf_release(req); return -ENOMEM; + } memcpy((char *)copy_path, (const char *)path, uni_path_len); uni_path_len = copy_size;
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ronnie Sahlberg lsahlber@redhat.com
commit 262916bc69faf90104aa784d55e10760a4199594 upstream.
We can not use the standard sg_set_buf() fucntion since when CONFIG_DEBUG_SG=y this adds a check that will BUG_ON for cifs.ko when we pass it an object from the stack.
Create a new wrapper smb2_sg_set_buf() which avoids doing that particular check and use it for smb3 encryption instead.
Signed-off-by: Ronnie Sahlberg lsahlber@redhat.com Signed-off-by: Steve French smfrench@gmail.com CC: Stable stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/cifs/smb2ops.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)
--- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -2066,6 +2066,15 @@ fill_transform_hdr(struct smb2_transform inc_rfc1001_len(tr_hdr, orig_len); }
+/* We can not use the normal sg_set_buf() as we will sometimes pass a + * stack object as buf. + */ +static inline void smb2_sg_set_buf(struct scatterlist *sg, const void *buf, + unsigned int buflen) +{ + sg_set_page(sg, virt_to_page(buf), buflen, offset_in_page(buf)); +} + static struct scatterlist * init_sg(struct smb_rqst *rqst, u8 *sign) { @@ -2080,16 +2089,16 @@ init_sg(struct smb_rqst *rqst, u8 *sign) return NULL;
sg_init_table(sg, sg_len); - sg_set_buf(&sg[0], rqst->rq_iov[0].iov_base + 24, assoc_data_len); + smb2_sg_set_buf(&sg[0], rqst->rq_iov[0].iov_base + 24, assoc_data_len); for (i = 1; i < rqst->rq_nvec; i++) - sg_set_buf(&sg[i], rqst->rq_iov[i].iov_base, + smb2_sg_set_buf(&sg[i], rqst->rq_iov[i].iov_base, rqst->rq_iov[i].iov_len); for (j = 0; i < sg_len - 1; i++, j++) { unsigned int len = (j < rqst->rq_npages - 1) ? rqst->rq_pagesz : rqst->rq_tailsz; sg_set_page(&sg[i], rqst->rq_pages[j], len, 0); } - sg_set_buf(&sg[sg_len - 1], sign, SMB2_SIGNATURE_SIZE); + smb2_sg_set_buf(&sg[sg_len - 1], sign, SMB2_SIGNATURE_SIZE); return sg; }
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steve French smfrench@gmail.com
commit 6188f28bf608ddecc2377663b0f2f709440c19ba upstream.
SMB3.1.1 tree connect was only being signed when signing was mandatory but needs to always be signed (for non-guest users).
See MS-SMB2 section 3.2.4.1.1
Signed-off-by: Steve French smfrench@gmail.com Reviewed-by: Pavel Shilovsky pshilov@microsoft.com CC: Stable stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/cifs/smb2pdu.c | 5 +++++ 1 file changed, 5 insertions(+)
--- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -1280,6 +1280,11 @@ SMB2_tcon(const unsigned int xid, struct iov[1].iov_base = unc_path; iov[1].iov_len = unc_path_len;
+ /* 3.11 tcon req must be signed if not encrypted. See MS-SMB2 3.2.4.1.1 */ + if ((ses->server->dialect == SMB311_PROT_ID) && + !encryption_required(tcon)) + req->sync_hdr.Flags |= SMB2_FLAGS_SIGNED; + rc = smb2_send_recv(xid, ses, iov, 2, &resp_buftype, flags, &rsp_iov); cifs_small_buf_release(req); rsp = (struct smb2_tree_connect_rsp *)rsp_iov.iov_base;
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Long Li longli@microsoft.com
commit 48f238a79f668f8ff013024d83010de551833d7f upstream.
During transport reconnect, other processes may have registered memory and blocked on transport. This creates a deadlock situation because the transport resources can't be freed, and reconnect is blocked.
Fix this by returning to upper layer on timeout. Before returning, transport status is set to reconnecting so other processes will release memory registration resources.
Upper layer will retry the reconnect. This is not in fast I/O path so setting the timeout to 5 seconds.
Signed-off-by: Long Li longli@microsoft.com Signed-off-by: Steve French smfrench@gmail.com Reviewed-by: Ronnie Sahlberg lsahlber@redhat.com CC: Stable stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/cifs/smbdirect.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
--- a/fs/cifs/smbdirect.c +++ b/fs/cifs/smbdirect.c @@ -1498,8 +1498,8 @@ int smbd_reconnect(struct TCP_Server_Inf log_rdma_event(INFO, "reconnecting rdma session\n");
if (!server->smbd_conn) { - log_rdma_event(ERR, "rdma session already destroyed\n"); - return -EINVAL; + log_rdma_event(INFO, "rdma session already destroyed\n"); + goto create_conn; }
/* @@ -1512,15 +1512,19 @@ int smbd_reconnect(struct TCP_Server_Inf }
/* wait until the transport is destroyed */ - wait_event(server->smbd_conn->wait_destroy, - server->smbd_conn->transport_status == SMBD_DESTROYED); + if (!wait_event_timeout(server->smbd_conn->wait_destroy, + server->smbd_conn->transport_status == SMBD_DESTROYED, 5*HZ)) + return -EAGAIN;
destroy_workqueue(server->smbd_conn->workqueue); kfree(server->smbd_conn);
+create_conn: log_rdma_event(INFO, "creating rdma session\n"); server->smbd_conn = smbd_get_connection( server, (struct sockaddr *) &server->dstaddr); + log_rdma_event(INFO, "created rdma session info=%p\n", + server->smbd_conn);
return server->smbd_conn ? 0 : -ENOENT; }
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Long Li longli@microsoft.com
commit 21a4e14aaedbc85f203d37e56cb26235b22b43f6 upstream.
On RDMA errors, transport should disconnect the RDMA CM connection. This will notify the upper layer, and it will attempt transport reconnect.
Signed-off-by: Long Li longli@microsoft.com Signed-off-by: Steve French smfrench@gmail.com Reviewed-by: Ronnie Sahlberg lsahlber@redhat.com CC: Stable stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/cifs/smbdirect.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
--- a/fs/cifs/smbdirect.c +++ b/fs/cifs/smbdirect.c @@ -862,6 +862,8 @@ static int smbd_post_send_negotiate_req( ib_dma_unmap_single(info->id->device, request->sge[0].addr, request->sge[0].length, DMA_TO_DEVICE);
+ smbd_disconnect_rdma_connection(info); + dma_mapping_failed: mempool_free(request, info->request_mempool); return rc; @@ -1061,6 +1063,7 @@ static int smbd_post_send(struct smbd_co if (atomic_dec_and_test(&info->send_pending)) wake_up(&info->wait_send_pending); } + smbd_disconnect_rdma_connection(info); } else /* Reset timer for idle connection after packet is sent */ mod_delayed_work(info->workqueue, &info->idle_timer_work, @@ -1202,7 +1205,7 @@ static int smbd_post_recv( if (rc) { ib_dma_unmap_single(info->id->device, response->sge.addr, response->sge.length, DMA_FROM_DEVICE); - + smbd_disconnect_rdma_connection(info); log_rdma_recv(ERR, "ib_post_recv failed rc=%d\n", rc); }
@@ -2546,6 +2549,8 @@ dma_map_error: if (atomic_dec_and_test(&info->mr_used_count)) wake_up(&info->wait_for_mr_cleanup);
+ smbd_disconnect_rdma_connection(info); + return NULL; }
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steve French stfrench@microsoft.com
commit 7ea884c77e5c97f1e0a1a422d961d27f78ca2745 upstream.
Some servers return inode number zero for the root directory, which causes ls to display incorrect data (missing "." and "..").
If the server returns zero for the inode number of the root directory, fake an inode number for it.
Signed-off-by: Steve French smfrench@gmail.com Reviewed-by: Pavel Shilovsky pshilov@microsoft.com CC: Stable stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/cifs/cifsglob.h | 1 + fs/cifs/inode.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+)
--- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -1466,6 +1466,7 @@ struct dfs_info3_param { #define CIFS_FATTR_NEED_REVAL 0x4 #define CIFS_FATTR_INO_COLLISION 0x8 #define CIFS_FATTR_UNKNOWN_NLINK 0x10 +#define CIFS_FATTR_FAKE_ROOT_INO 0x20
struct cifs_fattr { u32 cf_flags; --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -707,6 +707,18 @@ cgfi_exit: return rc; }
+/* Simple function to return a 64 bit hash of string. Rarely called */ +static __u64 simple_hashstr(const char *str) +{ + const __u64 hash_mult = 1125899906842597L; /* a big enough prime */ + __u64 hash = 0; + + while (*str) + hash = (hash + (__u64) *str++) * hash_mult; + + return hash; +} + int cifs_get_inode_info(struct inode **inode, const char *full_path, FILE_ALL_INFO *data, struct super_block *sb, int xid, @@ -816,6 +828,14 @@ cifs_get_inode_info(struct inode **inode tmprc); fattr.cf_uniqueid = iunique(sb, ROOT_I); cifs_autodisable_serverino(cifs_sb); + } else if ((fattr.cf_uniqueid == 0) && + strlen(full_path) == 0) { + /* some servers ret bad root ino ie 0 */ + cifs_dbg(FYI, "Invalid (0) inodenum\n"); + fattr.cf_flags |= + CIFS_FATTR_FAKE_ROOT_INO; + fattr.cf_uniqueid = + simple_hashstr(tcon->treeName); } } } else @@ -832,6 +852,16 @@ cifs_get_inode_info(struct inode **inode &fattr.cf_uniqueid, data); if (tmprc) fattr.cf_uniqueid = CIFS_I(*inode)->uniqueid; + else if ((fattr.cf_uniqueid == 0) && + strlen(full_path) == 0) { + /* + * Reuse existing root inode num since + * inum zero for root causes ls of . and .. to + * not be returned + */ + cifs_dbg(FYI, "Srv ret 0 inode num for root\n"); + fattr.cf_uniqueid = CIFS_I(*inode)->uniqueid; + } } else fattr.cf_uniqueid = CIFS_I(*inode)->uniqueid; } @@ -893,6 +923,9 @@ cifs_get_inode_info(struct inode **inode }
cgii_exit: + if ((*inode) && ((*inode)->i_ino == 0)) + cifs_dbg(FYI, "inode number of zero returned\n"); + kfree(buf); cifs_put_tlink(tlink); return rc;
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aaron Ma aaron.ma@canonical.com
commit ac75a041048b8c1f7418e27621ca5efda8571043 upstream.
When convert char array with signed int, if the inbuf[x] is negative then upper bits will be set to 1. Fix this by using u8 instead of char.
ret_size has to be at least 3, hid_input_report use it after minus 2 bytes.
Cc: stable@vger.kernel.org Signed-off-by: Aaron Ma aaron.ma@canonical.com Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/hid/i2c-hid/i2c-hid.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
--- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c @@ -144,10 +144,10 @@ struct i2c_hid { * register of the HID * descriptor. */ unsigned int bufsize; /* i2c buffer size */ - char *inbuf; /* Input buffer */ - char *rawbuf; /* Raw Input buffer */ - char *cmdbuf; /* Command buffer */ - char *argsbuf; /* Command arguments buffer */ + u8 *inbuf; /* Input buffer */ + u8 *rawbuf; /* Raw Input buffer */ + u8 *cmdbuf; /* Command buffer */ + u8 *argsbuf; /* Command arguments buffer */
unsigned long flags; /* device flags */ unsigned long quirks; /* Various quirks */ @@ -455,7 +455,8 @@ out_unlock:
static void i2c_hid_get_input(struct i2c_hid *ihid) { - int ret, ret_size; + int ret; + u32 ret_size; int size = le16_to_cpu(ihid->hdesc.wMaxInputLength);
if (size > ihid->bufsize) @@ -480,7 +481,7 @@ static void i2c_hid_get_input(struct i2c return; }
- if (ret_size > size) { + if ((ret_size > size) || (ret_size <= 2)) { dev_err(&ihid->client->dev, "%s: incomplete report (%d/%d)\n", __func__, size, ret_size); return;
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jean Delvare jdelvare@suse.de
commit a086bb8317303dd74725dca933b9b29575159382 upstream.
Saving the original value of register SMBSLVCMD in i801_enable_host_notify() doesn't work, because this function is called not only at probe time but also at resume time. Do it in i801_probe() instead, so that the saved value is not overwritten at resume time.
Signed-off-by: Jean Delvare jdelvare@suse.de Fixes: 22e94bd6779e ("i2c: i801: store and restore the SLVCMD register at load and unload") Reviewed-by: Benjamin Tissoires benjamin.tissoires@redhat.com Tested-by: Jason Andryuk jandryuk@gmail.com Signed-off-by: Wolfram Sang wsa@the-dreams.de Cc: stable@vger.kernel.org # v4.10+ Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/i2c/busses/i2c-i801.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
--- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -966,8 +966,6 @@ static void i801_enable_host_notify(stru if (!(priv->features & FEATURE_HOST_NOTIFY)) return;
- priv->original_slvcmd = inb_p(SMBSLVCMD(priv)); - if (!(SMBSLVCMD_HST_NTFY_INTREN & priv->original_slvcmd)) outb_p(SMBSLVCMD_HST_NTFY_INTREN | priv->original_slvcmd, SMBSLVCMD(priv)); @@ -1615,6 +1613,10 @@ static int i801_probe(struct pci_dev *de outb_p(inb_p(SMBAUXCTL(priv)) & ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B), SMBAUXCTL(priv));
+ /* Remember original Host Notify setting */ + if (priv->features & FEATURE_HOST_NOTIFY) + priv->original_slvcmd = inb_p(SMBSLVCMD(priv)); + /* Default timeout in interrupt mode: 200 ms */ priv->adapter.timeout = HZ / 5;
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jean Delvare jdelvare@suse.de
commit f7f6d915a10f7f2bce17e3b1b7d3376562395a28 upstream.
On some systems, the BIOS expects certain SMBus register values to match the hardware defaults. Restore these configuration registers at shutdown time to avoid confusing the BIOS. This avoids hard-locking such systems upon reboot.
Signed-off-by: Jean Delvare jdelvare@suse.de Tested-by: Jason Andryuk jandryuk@gmail.com Signed-off-by: Wolfram Sang wsa@the-dreams.de Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/i2c/busses/i2c-i801.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
--- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -1701,6 +1701,15 @@ static void i801_remove(struct pci_dev * */ }
+static void i801_shutdown(struct pci_dev *dev) +{ + struct i801_priv *priv = pci_get_drvdata(dev); + + /* Restore config registers to avoid hard hang on some systems */ + i801_disable_host_notify(priv); + pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg); +} + #ifdef CONFIG_PM static int i801_suspend(struct device *dev) { @@ -1730,6 +1739,7 @@ static struct pci_driver i801_driver = { .id_table = i801_ids, .probe = i801_probe, .remove = i801_remove, + .shutdown = i801_shutdown, .driver = { .pm = &i801_pm_ops, },
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aurelien Aptel aaptel@suse.com
commit 82fb82be05585426405667dd5f0510aa953ba439 upstream.
shash and sdesc and always allocated and freed together. * abstract this in new functions cifs_alloc_hash() and cifs_free_hash(). * make smb2/3 crypto allocation independent from each other.
Signed-off-by: Aurelien Aptel aaptel@suse.com Signed-off-by: Steve French smfrench@gmail.com Reviewed-by: Ronnie Sahlberg lsahlber@redhat.com CC: Stable stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/cifs/cifsencrypt.c | 78 ++++-------------------------------------------- fs/cifs/cifsproto.h | 5 +++ fs/cifs/link.c | 25 +++------------ fs/cifs/misc.c | 54 +++++++++++++++++++++++++++++++++ fs/cifs/smb2transport.c | 75 +++++++++------------------------------------- fs/cifs/smbencrypt.c | 25 +++------------ 6 files changed, 91 insertions(+), 171 deletions(-)
--- a/fs/cifs/cifsencrypt.c +++ b/fs/cifs/cifsencrypt.c @@ -36,37 +36,6 @@ #include <crypto/skcipher.h> #include <crypto/aead.h>
-static int -cifs_crypto_shash_md5_allocate(struct TCP_Server_Info *server) -{ - int rc; - unsigned int size; - - if (server->secmech.sdescmd5 != NULL) - return 0; /* already allocated */ - - server->secmech.md5 = crypto_alloc_shash("md5", 0, 0); - if (IS_ERR(server->secmech.md5)) { - cifs_dbg(VFS, "could not allocate crypto md5\n"); - rc = PTR_ERR(server->secmech.md5); - server->secmech.md5 = NULL; - return rc; - } - - size = sizeof(struct shash_desc) + - crypto_shash_descsize(server->secmech.md5); - server->secmech.sdescmd5 = kmalloc(size, GFP_KERNEL); - if (!server->secmech.sdescmd5) { - crypto_free_shash(server->secmech.md5); - server->secmech.md5 = NULL; - return -ENOMEM; - } - server->secmech.sdescmd5->shash.tfm = server->secmech.md5; - server->secmech.sdescmd5->shash.flags = 0x0; - - return 0; -} - int __cifs_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server, char *signature, struct shash_desc *shash) @@ -132,13 +101,10 @@ static int cifs_calc_signature(struct sm if (!rqst->rq_iov || !signature || !server) return -EINVAL;
- if (!server->secmech.sdescmd5) { - rc = cifs_crypto_shash_md5_allocate(server); - if (rc) { - cifs_dbg(VFS, "%s: Can't alloc md5 crypto\n", __func__); - return -1; - } - } + rc = cifs_alloc_hash("md5", &server->secmech.md5, + &server->secmech.sdescmd5); + if (rc) + return -1;
rc = crypto_shash_init(&server->secmech.sdescmd5->shash); if (rc) { @@ -663,37 +629,6 @@ CalcNTLMv2_response(const struct cifs_se return rc; }
-static int crypto_hmacmd5_alloc(struct TCP_Server_Info *server) -{ - int rc; - unsigned int size; - - /* check if already allocated */ - if (server->secmech.sdeschmacmd5) - return 0; - - server->secmech.hmacmd5 = crypto_alloc_shash("hmac(md5)", 0, 0); - if (IS_ERR(server->secmech.hmacmd5)) { - cifs_dbg(VFS, "could not allocate crypto hmacmd5\n"); - rc = PTR_ERR(server->secmech.hmacmd5); - server->secmech.hmacmd5 = NULL; - return rc; - } - - size = sizeof(struct shash_desc) + - crypto_shash_descsize(server->secmech.hmacmd5); - server->secmech.sdeschmacmd5 = kmalloc(size, GFP_KERNEL); - if (!server->secmech.sdeschmacmd5) { - crypto_free_shash(server->secmech.hmacmd5); - server->secmech.hmacmd5 = NULL; - return -ENOMEM; - } - server->secmech.sdeschmacmd5->shash.tfm = server->secmech.hmacmd5; - server->secmech.sdeschmacmd5->shash.flags = 0x0; - - return 0; -} - int setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp) { @@ -757,9 +692,10 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, c
mutex_lock(&ses->server->srv_mutex);
- rc = crypto_hmacmd5_alloc(ses->server); + rc = cifs_alloc_hash("hmac(md5)", + &ses->server->secmech.hmacmd5, + &ses->server->secmech.sdeschmacmd5); if (rc) { - cifs_dbg(VFS, "could not crypto alloc hmacmd5 rc %d\n", rc); goto unlock; }
--- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -542,4 +542,9 @@ enum securityEnum cifs_select_sectype(st struct cifs_aio_ctx *cifs_aio_ctx_alloc(void); void cifs_aio_ctx_release(struct kref *refcount); int setup_aio_ctx_iter(struct cifs_aio_ctx *ctx, struct iov_iter *iter, int rw); + +int cifs_alloc_hash(const char *name, struct crypto_shash **shash, + struct sdesc **sdesc); +void cifs_free_hash(struct crypto_shash **shash, struct sdesc **sdesc); + #endif /* _CIFSPROTO_H */ --- a/fs/cifs/link.c +++ b/fs/cifs/link.c @@ -50,25 +50,12 @@ static int symlink_hash(unsigned int link_len, const char *link_str, u8 *md5_hash) { int rc; - unsigned int size; - struct crypto_shash *md5; - struct sdesc *sdescmd5; + struct crypto_shash *md5 = NULL; + struct sdesc *sdescmd5 = NULL;
- md5 = crypto_alloc_shash("md5", 0, 0); - if (IS_ERR(md5)) { - rc = PTR_ERR(md5); - cifs_dbg(VFS, "%s: Crypto md5 allocation error %d\n", - __func__, rc); - return rc; - } - size = sizeof(struct shash_desc) + crypto_shash_descsize(md5); - sdescmd5 = kmalloc(size, GFP_KERNEL); - if (!sdescmd5) { - rc = -ENOMEM; + rc = cifs_alloc_hash("md5", &md5, &sdescmd5); + if (rc) goto symlink_hash_err; - } - sdescmd5->shash.tfm = md5; - sdescmd5->shash.flags = 0x0;
rc = crypto_shash_init(&sdescmd5->shash); if (rc) { @@ -85,9 +72,7 @@ symlink_hash(unsigned int link_len, cons cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__);
symlink_hash_err: - crypto_free_shash(md5); - kfree(sdescmd5); - + cifs_free_hash(&md5, &sdescmd5); return rc; }
--- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -848,3 +848,57 @@ setup_aio_ctx_iter(struct cifs_aio_ctx * iov_iter_bvec(&ctx->iter, ITER_BVEC | rw, ctx->bv, npages, ctx->len); return 0; } + +/** + * cifs_alloc_hash - allocate hash and hash context together + * + * The caller has to make sure @sdesc is initialized to either NULL or + * a valid context. Both can be freed via cifs_free_hash(). + */ +int +cifs_alloc_hash(const char *name, + struct crypto_shash **shash, struct sdesc **sdesc) +{ + int rc = 0; + size_t size; + + if (*sdesc != NULL) + return 0; + + *shash = crypto_alloc_shash(name, 0, 0); + if (IS_ERR(*shash)) { + cifs_dbg(VFS, "could not allocate crypto %s\n", name); + rc = PTR_ERR(*shash); + *shash = NULL; + *sdesc = NULL; + return rc; + } + + size = sizeof(struct shash_desc) + crypto_shash_descsize(*shash); + *sdesc = kmalloc(size, GFP_KERNEL); + if (*sdesc == NULL) { + cifs_dbg(VFS, "no memory left to allocate crypto %s\n", name); + crypto_free_shash(*shash); + *shash = NULL; + return -ENOMEM; + } + + (*sdesc)->shash.tfm = *shash; + (*sdesc)->shash.flags = 0x0; + return 0; +} + +/** + * cifs_free_hash - free hash and hash context together + * + * Freeing a NULL hash or context is safe. + */ +void +cifs_free_hash(struct crypto_shash **shash, struct sdesc **sdesc) +{ + kfree(*sdesc); + *sdesc = NULL; + if (*shash) + crypto_free_shash(*shash); + *shash = NULL; +} --- a/fs/cifs/smb2transport.c +++ b/fs/cifs/smb2transport.c @@ -43,76 +43,31 @@ static int smb2_crypto_shash_allocate(struct TCP_Server_Info *server) { - int rc; - unsigned int size; - - if (server->secmech.sdeschmacsha256 != NULL) - return 0; /* already allocated */ - - server->secmech.hmacsha256 = crypto_alloc_shash("hmac(sha256)", 0, 0); - if (IS_ERR(server->secmech.hmacsha256)) { - cifs_dbg(VFS, "could not allocate crypto hmacsha256\n"); - rc = PTR_ERR(server->secmech.hmacsha256); - server->secmech.hmacsha256 = NULL; - return rc; - } - - size = sizeof(struct shash_desc) + - crypto_shash_descsize(server->secmech.hmacsha256); - server->secmech.sdeschmacsha256 = kmalloc(size, GFP_KERNEL); - if (!server->secmech.sdeschmacsha256) { - crypto_free_shash(server->secmech.hmacsha256); - server->secmech.hmacsha256 = NULL; - return -ENOMEM; - } - server->secmech.sdeschmacsha256->shash.tfm = server->secmech.hmacsha256; - server->secmech.sdeschmacsha256->shash.flags = 0x0; - - return 0; + return cifs_alloc_hash("hmac(sha256)", + &server->secmech.hmacsha256, + &server->secmech.sdeschmacsha256); }
static int smb3_crypto_shash_allocate(struct TCP_Server_Info *server) { - unsigned int size; + struct cifs_secmech *p = &server->secmech; int rc;
- if (server->secmech.sdesccmacaes != NULL) - return 0; /* already allocated */ - - rc = smb2_crypto_shash_allocate(server); + rc = cifs_alloc_hash("hmac(sha256)", + &p->hmacsha256, + &p->sdeschmacsha256); if (rc) - return rc; - - server->secmech.cmacaes = crypto_alloc_shash("cmac(aes)", 0, 0); - if (IS_ERR(server->secmech.cmacaes)) { - cifs_dbg(VFS, "could not allocate crypto cmac-aes"); - kfree(server->secmech.sdeschmacsha256); - server->secmech.sdeschmacsha256 = NULL; - crypto_free_shash(server->secmech.hmacsha256); - server->secmech.hmacsha256 = NULL; - rc = PTR_ERR(server->secmech.cmacaes); - server->secmech.cmacaes = NULL; - return rc; - } + goto err;
- size = sizeof(struct shash_desc) + - crypto_shash_descsize(server->secmech.cmacaes); - server->secmech.sdesccmacaes = kmalloc(size, GFP_KERNEL); - if (!server->secmech.sdesccmacaes) { - cifs_dbg(VFS, "%s: Can't alloc cmacaes\n", __func__); - kfree(server->secmech.sdeschmacsha256); - server->secmech.sdeschmacsha256 = NULL; - crypto_free_shash(server->secmech.hmacsha256); - crypto_free_shash(server->secmech.cmacaes); - server->secmech.hmacsha256 = NULL; - server->secmech.cmacaes = NULL; - return -ENOMEM; - } - server->secmech.sdesccmacaes->shash.tfm = server->secmech.cmacaes; - server->secmech.sdesccmacaes->shash.flags = 0x0; + rc = cifs_alloc_hash("cmac(aes)", &p->cmacaes, &p->sdesccmacaes); + if (rc) + goto err;
return 0; +err: + cifs_free_hash(&p->hmacsha256, &p->sdeschmacsha256); + return rc; }
static struct cifs_ses * @@ -457,7 +412,7 @@ smb3_calc_signature(struct smb_rqst *rqs cifs_dbg(VFS, "%s: Could not init cmac aes\n", __func__); return rc; } - + rc = __cifs_calc_signature(rqst, server, sigptr, &server->secmech.sdesccmacaes->shash);
--- a/fs/cifs/smbencrypt.c +++ b/fs/cifs/smbencrypt.c @@ -121,25 +121,12 @@ int mdfour(unsigned char *md4_hash, unsigned char *link_str, int link_len) { int rc; - unsigned int size; - struct crypto_shash *md4; - struct sdesc *sdescmd4; + struct crypto_shash *md4 = NULL; + struct sdesc *sdescmd4 = NULL;
- md4 = crypto_alloc_shash("md4", 0, 0); - if (IS_ERR(md4)) { - rc = PTR_ERR(md4); - cifs_dbg(VFS, "%s: Crypto md4 allocation error %d\n", - __func__, rc); - return rc; - } - size = sizeof(struct shash_desc) + crypto_shash_descsize(md4); - sdescmd4 = kmalloc(size, GFP_KERNEL); - if (!sdescmd4) { - rc = -ENOMEM; + rc = cifs_alloc_hash("md4", &md4, &sdescmd4); + if (rc) goto mdfour_err; - } - sdescmd4->shash.tfm = md4; - sdescmd4->shash.flags = 0x0;
rc = crypto_shash_init(&sdescmd4->shash); if (rc) { @@ -156,9 +143,7 @@ mdfour(unsigned char *md4_hash, unsigned cifs_dbg(VFS, "%s: Could not generate md4 hash\n", __func__);
mdfour_err: - crypto_free_shash(md4); - kfree(sdescmd4); - + cifs_free_hash(&md4, &sdescmd4); return rc; }
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aurelien Aptel aaptel@suse.com
commit 5fcd7f3f966f37f3f9a215af4cc1597fe338d0d5 upstream.
* prepare for SMB3.11 pre-auth integrity * enable sha512 when SMB311 is enabled in Kconfig * add sha512 as a soft dependency
Signed-off-by: Aurelien Aptel aaptel@suse.com Signed-off-by: Steve French smfrench@gmail.com CC: Stable stable@vger.kernel.org Reviewed-by: Ronnie Sahlberg lsahlber@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/cifs/Kconfig | 1 + fs/cifs/cifsencrypt.c | 7 +++++++ fs/cifs/cifsfs.c | 1 + fs/cifs/cifsglob.h | 2 ++ fs/cifs/smb2proto.h | 3 +++ fs/cifs/smb2transport.c | 30 ++++++++++++++++++++++++++++++ 6 files changed, 44 insertions(+)
--- a/fs/cifs/Kconfig +++ b/fs/cifs/Kconfig @@ -189,6 +189,7 @@ config CIFS_NFSD_EXPORT config CIFS_SMB311 bool "SMB3.1.1 network file system support (Experimental)" depends on CIFS + select CRYPTO_SHA512
help This enables experimental support for the newest, SMB3.1.1, dialect. --- a/fs/cifs/cifsencrypt.c +++ b/fs/cifs/cifsencrypt.c @@ -829,6 +829,11 @@ cifs_crypto_secmech_release(struct TCP_S server->secmech.md5 = NULL; }
+ if (server->secmech.md5) { + crypto_free_shash(server->secmech.sha512); + server->secmech.sha512 = NULL; + } + if (server->secmech.hmacmd5) { crypto_free_shash(server->secmech.hmacmd5); server->secmech.hmacmd5 = NULL; @@ -852,4 +857,6 @@ cifs_crypto_secmech_release(struct TCP_S server->secmech.sdeschmacmd5 = NULL; kfree(server->secmech.sdescmd5); server->secmech.sdescmd5 = NULL; + kfree(server->secmech.sdescsha512); + server->secmech.sdescsha512 = NULL; } --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -1486,6 +1486,7 @@ MODULE_SOFTDEP("pre: nls"); MODULE_SOFTDEP("pre: aes"); MODULE_SOFTDEP("pre: cmac"); MODULE_SOFTDEP("pre: sha256"); +MODULE_SOFTDEP("pre: sha512"); MODULE_SOFTDEP("pre: aead2"); MODULE_SOFTDEP("pre: ccm"); module_init(init_cifs) --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -130,10 +130,12 @@ struct cifs_secmech { struct crypto_shash *md5; /* md5 hash function */ struct crypto_shash *hmacsha256; /* hmac-sha256 hash function */ struct crypto_shash *cmacaes; /* block-cipher based MAC function */ + struct crypto_shash *sha512; /* sha512 hash function */ struct sdesc *sdeschmacmd5; /* ctxt to generate ntlmv2 hash, CR1 */ struct sdesc *sdescmd5; /* ctxt to generate cifs/smb signature */ struct sdesc *sdeschmacsha256; /* ctxt to generate smb2 signature */ struct sdesc *sdesccmacaes; /* ctxt to generate smb3 signature */ + struct sdesc *sdescsha512; /* ctxt to generate smb3.11 signing key */ struct crypto_aead *ccmaesencrypt; /* smb3 encryption aead */ struct crypto_aead *ccmaesdecrypt; /* smb3 decryption aead */ }; --- a/fs/cifs/smb2proto.h +++ b/fs/cifs/smb2proto.h @@ -202,4 +202,7 @@ extern int smb3_validate_negotiate(const
extern enum securityEnum smb2_select_sectype(struct TCP_Server_Info *, enum securityEnum); +#ifdef CONFIG_CIFS_SMB311 +extern int smb311_crypto_shash_allocate(struct TCP_Server_Info *server); +#endif #endif /* _SMB2PROTO_H */ --- a/fs/cifs/smb2transport.c +++ b/fs/cifs/smb2transport.c @@ -70,6 +70,36 @@ err: return rc; }
+#ifdef CONFIG_CIFS_SMB311 +int +smb311_crypto_shash_allocate(struct TCP_Server_Info *server) +{ + struct cifs_secmech *p = &server->secmech; + int rc = 0; + + rc = cifs_alloc_hash("hmac(sha256)", + &p->hmacsha256, + &p->sdeschmacsha256); + if (rc) + return rc; + + rc = cifs_alloc_hash("cmac(aes)", &p->cmacaes, &p->sdesccmacaes); + if (rc) + goto err; + + rc = cifs_alloc_hash("sha512", &p->sha512, &p->sdescsha512); + if (rc) + goto err; + + return 0; + +err: + cifs_free_hash(&p->cmacaes, &p->sdesccmacaes); + cifs_free_hash(&p->hmacsha256, &p->sdeschmacsha256); + return rc; +} +#endif + static struct cifs_ses * smb2_find_smb_ses_unlocked(struct TCP_Server_Info *server, __u64 ses_id) {
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aurelien Aptel aaptel@suse.com
commit 8bd68c6e47abff34e412a0c68cecb4a36bf0198b upstream.
SMB3.11 clients must implement pre-authentification integrity.
* new mechanism to certify requests/responses happening before Tree Connect. * supersedes VALIDATE_NEGOTIATE * fixes signing for SMB3.11
Signed-off-by: Aurelien Aptel aaptel@suse.com Signed-off-by: Steve French smfrench@gmail.com CC: Stable stable@vger.kernel.org Reviewed-by: Ronnie Sahlberg lsahlber@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/cifs/cifsglob.h | 5 ++-- fs/cifs/smb2misc.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++ fs/cifs/smb2pdu.c | 25 ++++++++++++++++++++ fs/cifs/smb2pdu.h | 1 fs/cifs/smb2proto.h | 2 + fs/cifs/transport.c | 17 +++++++++++++ 6 files changed, 112 insertions(+), 2 deletions(-)
--- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -675,7 +675,8 @@ struct TCP_Server_Info { unsigned int max_read; unsigned int max_write; #ifdef CONFIG_CIFS_SMB311 - __u8 preauth_sha_hash[64]; /* save initital negprot hash */ + /* save initital negprot hash */ + __u8 preauth_sha_hash[SMB2_PREAUTH_HASH_SIZE]; #endif /* 3.1.1 */ struct delayed_work reconnect; /* reconnect workqueue job */ struct mutex reconnect_mutex; /* prevent simultaneous reconnects */ @@ -864,7 +865,7 @@ struct cifs_ses { __u8 smb3encryptionkey[SMB3_SIGN_KEY_SIZE]; __u8 smb3decryptionkey[SMB3_SIGN_KEY_SIZE]; #ifdef CONFIG_CIFS_SMB311 - __u8 preauth_sha_hash[64]; + __u8 preauth_sha_hash[SMB2_PREAUTH_HASH_SIZE]; #endif /* 3.1.1 */ };
--- a/fs/cifs/smb2misc.c +++ b/fs/cifs/smb2misc.c @@ -706,3 +706,67 @@ smb2_handle_cancelled_mid(char *buffer,
return 0; } + +#ifdef CONFIG_CIFS_SMB311 +/** + * smb311_update_preauth_hash - update @ses hash with the packet data in @iov + * + * Assumes @iov does not contain the rfc1002 length and iov[0] has the + * SMB2 header. + */ +int +smb311_update_preauth_hash(struct cifs_ses *ses, struct kvec *iov, int nvec) +{ + int i, rc; + struct sdesc *d; + struct smb2_sync_hdr *hdr; + + if (ses->server->tcpStatus == CifsGood) { + /* skip non smb311 connections */ + if (ses->server->dialect != SMB311_PROT_ID) + return 0; + + /* skip last sess setup response */ + hdr = (struct smb2_sync_hdr *)iov[0].iov_base; + if (hdr->Flags & SMB2_FLAGS_SIGNED) + return 0; + } + + rc = smb311_crypto_shash_allocate(ses->server); + if (rc) + return rc; + + d = ses->server->secmech.sdescsha512; + rc = crypto_shash_init(&d->shash); + if (rc) { + cifs_dbg(VFS, "%s: could not init sha512 shash\n", __func__); + return rc; + } + + rc = crypto_shash_update(&d->shash, ses->preauth_sha_hash, + SMB2_PREAUTH_HASH_SIZE); + if (rc) { + cifs_dbg(VFS, "%s: could not update sha512 shash\n", __func__); + return rc; + } + + for (i = 0; i < nvec; i++) { + rc = crypto_shash_update(&d->shash, + iov[i].iov_base, iov[i].iov_len); + if (rc) { + cifs_dbg(VFS, "%s: could not update sha512 shash\n", + __func__); + return rc; + } + } + + rc = crypto_shash_final(&d->shash, ses->preauth_sha_hash); + if (rc) { + cifs_dbg(VFS, "%s: could not finalize sha512 shash\n", + __func__); + return rc; + } + + return 0; +} +#endif --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -453,6 +453,10 @@ SMB2_negotiate(const unsigned int xid, s return rc;
req->sync_hdr.SessionId = 0; +#ifdef CONFIG_CIFS_SMB311 + memset(server->preauth_sha_hash, 0, SMB2_PREAUTH_HASH_SIZE); + memset(ses->preauth_sha_hash, 0, SMB2_PREAUTH_HASH_SIZE); +#endif
if (strcmp(ses->server->vals->version_string, SMB3ANY_VERSION_STRING) == 0) { @@ -564,6 +568,15 @@ SMB2_negotiate(const unsigned int xid, s
/* BB: add check that dialect was valid given dialect(s) we asked for */
+#ifdef CONFIG_CIFS_SMB311 + /* + * Keep a copy of the hash after negprot. This hash will be + * the starting hash value for all sessions made from this + * server. + */ + memcpy(server->preauth_sha_hash, ses->preauth_sha_hash, + SMB2_PREAUTH_HASH_SIZE); +#endif /* SMB2 only has an extended negflavor */ server->negflavor = CIFS_NEGFLAVOR_EXTENDED; /* set it to the maximum buffer size value we can send with 1 credit */ @@ -621,6 +634,10 @@ int smb3_validate_negotiate(const unsign return 0; #endif
+ /* In SMB3.11 preauth integrity supersedes validate negotiate */ + if (tcon->ses->server->dialect == SMB311_PROT_ID) + return 0; + /* * validation ioctl must be signed, so no point sending this if we * can not sign it (ie are not known user). Even if signing is not @@ -1148,6 +1165,14 @@ SMB2_sess_setup(const unsigned int xid, sess_data->buf0_type = CIFS_NO_BUFFER; sess_data->nls_cp = (struct nls_table *) nls_cp;
+#ifdef CONFIG_CIFS_SMB311 + /* + * Initialize the session hash with the server one. + */ + memcpy(ses->preauth_sha_hash, ses->server->preauth_sha_hash, + SMB2_PREAUTH_HASH_SIZE); +#endif + while (sess_data->func) sess_data->func(sess_data);
--- a/fs/cifs/smb2pdu.h +++ b/fs/cifs/smb2pdu.h @@ -264,6 +264,7 @@ struct smb2_negotiate_req { #define SMB311_SALT_SIZE 32 /* Hash Algorithm Types */ #define SMB2_PREAUTH_INTEGRITY_SHA512 cpu_to_le16(0x0001) +#define SMB2_PREAUTH_HASH_SIZE 64
struct smb2_preauth_neg_context { __le16 ContextType; /* 1 */ --- a/fs/cifs/smb2proto.h +++ b/fs/cifs/smb2proto.h @@ -204,5 +204,7 @@ extern enum securityEnum smb2_select_sec enum securityEnum); #ifdef CONFIG_CIFS_SMB311 extern int smb311_crypto_shash_allocate(struct TCP_Server_Info *server); +extern int smb311_update_preauth_hash(struct cifs_ses *ses, + struct kvec *iov, int nvec); #endif #endif /* _SMB2PROTO_H */ --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -37,6 +37,7 @@ #include "cifsglob.h" #include "cifsproto.h" #include "cifs_debug.h" +#include "smb2proto.h" #include "smbdirect.h"
/* Max number of iovectors we can use off the stack when sending requests. */ @@ -751,6 +752,12 @@ cifs_send_recv(const unsigned int xid, s if (rc < 0) goto out;
+#ifdef CONFIG_CIFS_SMB311 + if (ses->status == CifsNew) + smb311_update_preauth_hash(ses, rqst->rq_iov+1, + rqst->rq_nvec-1); +#endif + if (timeout == CIFS_ASYNC_OP) goto out;
@@ -789,6 +796,16 @@ cifs_send_recv(const unsigned int xid, s else *resp_buf_type = CIFS_SMALL_BUFFER;
+#ifdef CONFIG_CIFS_SMB311 + if (ses->status == CifsNew) { + struct kvec iov = { + .iov_base = buf + 4, + .iov_len = get_rfc1002_length(buf) + }; + smb311_update_preauth_hash(ses, &iov, 1); + } +#endif + credits = ses->server->ops->get_credits(midQ);
rc = ses->server->ops->check_receive(midQ, ses->server,
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gustavo A. R. Silva gustavo@embeddedor.com
commit 70e80655f58e17a2e38e577e1b4fa7a8c99619a0 upstream.
It seems this is a copy-paste error and that the proper variable to use in this particular case is _sha512_ instead of _md5_.
Addresses-Coverity-ID: 1465358 ("Copy-paste error") Fixes: 1c6614d229e7 ("CIFS: add sha512 secmech") Signed-off-by: Gustavo A. R. Silva gustavo@embeddedor.com Reviewed-by: Aurelien Aptel aaptel@suse.com CC: Stable stable@vger.kernel.org Signed-off-by: Steve French smfrench@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/cifs/cifsencrypt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/cifs/cifsencrypt.c +++ b/fs/cifs/cifsencrypt.c @@ -829,7 +829,7 @@ cifs_crypto_secmech_release(struct TCP_S server->secmech.md5 = NULL; }
- if (server->secmech.md5) { + if (server->secmech.sha512) { crypto_free_shash(server->secmech.sha512); server->secmech.sha512 = NULL; }
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai tiwai@suse.de
commit 9e7f06c8beee304ee21b791653fefcd713f48b9a upstream.
The code refactoring by commit 0176adb00406 ("swiotlb: refactor coherent buffer allocation") made swiotlb_alloc_buffer almost always failing due to a thinko: namely, the function evaluates the dma_coherent_ok call incorrectly and dealing as if it's invalid. This ends up with weird errors like iwlwifi probe failure or amdgpu screen flickering.
This patch corrects the logic error.
Bugzilla: https://bugzilla.suse.com/show_bug.cgi?id=1088658 Bugzilla: https://bugzilla.suse.com/show_bug.cgi?id=1088902 Fixes: 0176adb00406 ("swiotlb: refactor coherent buffer allocation") Cc: stable@vger.kernel.org # v4.16+ Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Christoph Hellwig hch@lst.de Cc: Jean Delvare jdelvare@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- lib/swiotlb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -732,7 +732,7 @@ swiotlb_alloc_buffer(struct device *dev, goto out_warn;
*dma_handle = swiotlb_phys_to_dma(dev, phys_addr); - if (dma_coherent_ok(dev, *dma_handle, size)) + if (!dma_coherent_ok(dev, *dma_handle, size)) goto out_unmap;
memset(phys_to_virt(phys_addr), 0, size);
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicholas Piggin npiggin@gmail.com
commit c130153e453cba0f37ad10fa18a1aa9c9a598a59 upstream.
The pkey code added a CPU_FTR_PKEY bit, but did not add it to the dt_cpu_ftrs feature set. Although capability is supported by all processors in the base dt_cpu_ftrs set for 64s, it's a significant and sufficiently well defined feature to make it optional. So add it as a quirk for now, which can be versioned out then controlled by the firmware (once dt_cpu_ftrs gains versioning support).
Fixes: cf43d3b26452 ("powerpc: Enable pkey subsystem") Cc: stable@vger.kernel.org # v4.16+ Cc: Ram Pai linuxram@us.ibm.com Signed-off-by: Nicholas Piggin npiggin@gmail.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/powerpc/kernel/dt_cpu_ftrs.c | 7 +++++++ 1 file changed, 7 insertions(+)
--- a/arch/powerpc/kernel/dt_cpu_ftrs.c +++ b/arch/powerpc/kernel/dt_cpu_ftrs.c @@ -658,6 +658,13 @@ static void __init cpufeatures_setup_sta cur_cpu_spec->cpu_features |= CPU_FTR_ARCH_300; cur_cpu_spec->cpu_user_features2 |= PPC_FEATURE2_ARCH_3_00; } + + /* + * PKEY was not in the initial base or feature node + * specification, but it should become optional in the next + * cpu feature version sequence. + */ + cur_cpu_spec->cpu_features |= CPU_FTR_PKEY; }
static bool __init cpufeatures_process_feature(struct dt_cpu_feature *f)
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicholas Piggin npiggin@gmail.com
commit 741de617661794246f84a21a02fc5e327bffc9ad upstream.
opal_nvram_write currently just assumes success if it encounters an error other than OPAL_BUSY or OPAL_BUSY_EVENT. Have it return -EIO on other errors instead.
Fixes: 628daa8d5abf ("powerpc/powernv: Add RTC and NVRAM support plus RTAS fallbacks") Cc: stable@vger.kernel.org # v3.2+ Signed-off-by: Nicholas Piggin npiggin@gmail.com Reviewed-by: Vasant Hegde hegdevasant@linux.vnet.ibm.com Acked-by: Stewart Smith stewart@linux.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/powerpc/platforms/powernv/opal-nvram.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/arch/powerpc/platforms/powernv/opal-nvram.c +++ b/arch/powerpc/platforms/powernv/opal-nvram.c @@ -59,6 +59,10 @@ static ssize_t opal_nvram_write(char *bu if (rc == OPAL_BUSY_EVENT) opal_poll_events(NULL); } + + if (rc) + return -EIO; + *index += count; return count; }
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Neuling mikey@neuling.org
commit f0295e047fcf52ccb42561fb7de6942f5201b676 upstream.
The current EEH callbacks can race with a driver unbind. This can result in a backtraces like this:
EEH: Frozen PHB#0-PE#1fc detected EEH: PE location: S000009, PHB location: N/A CPU: 2 PID: 2312 Comm: kworker/u258:3 Not tainted 4.15.6-openpower1 #2 Workqueue: nvme-wq nvme_reset_work [nvme] Call Trace: dump_stack+0x9c/0xd0 (unreliable) eeh_dev_check_failure+0x420/0x470 eeh_check_failure+0xa0/0xa4 nvme_reset_work+0x138/0x1414 [nvme] process_one_work+0x1ec/0x328 worker_thread+0x2e4/0x3a8 kthread+0x14c/0x154 ret_from_kernel_thread+0x5c/0xc8 nvme nvme1: Removing after probe failure status: -19 <snip> cpu 0x23: Vector: 300 (Data Access) at [c000000ff50f3800] pc: c0080000089a0eb0: nvme_error_detected+0x4c/0x90 [nvme] lr: c000000000026564: eeh_report_error+0xe0/0x110 sp: c000000ff50f3a80 msr: 9000000000009033 dar: 400 dsisr: 40000000 current = 0xc000000ff507c000 paca = 0xc00000000fdc9d80 softe: 0 irq_happened: 0x01 pid = 782, comm = eehd Linux version 4.15.6-openpower1 (smc@smc-desktop) (gcc version 6.4.0 (Buildroot 2017.11.2-00008-g4b6188e)) #2 SM P Tue Feb 27 12:33:27 PST 2018 enter ? for help eeh_report_error+0xe0/0x110 eeh_pe_dev_traverse+0xc0/0xdc eeh_handle_normal_event+0x184/0x4c4 eeh_handle_event+0x30/0x288 eeh_event_handler+0x124/0x170 kthread+0x14c/0x154 ret_from_kernel_thread+0x5c/0xc8
The first part is an EEH (on boot), the second half is the resulting crash. nvme probe starts the nvme_reset_work() worker thread. This worker thread starts touching the device which see a device error (EEH) and hence queues up an event in the powerpc EEH worker thread. nvme_reset_work() then continues and runs nvme_remove_dead_ctrl_work() which results in unbinding the driver from the device and hence releases all resources. At the same time, the EEH worker thread starts doing the EEH .error_detected() driver callback, which no longer works since the resources have been freed.
This fixes the problem in the same way the generic PCIe AER code (in drivers/pci/pcie/aer/aerdrv_core.c) does. It makes the EEH code hold the device_lock() while performing the driver EEH callbacks and associated code. This ensures either the callbacks are no longer register, or if they are registered the driver will not be removed from underneath us.
This has been broken forever. The EEH call backs were first introduced in 2005 (in 77bd7415610) but it's not clear if a lock was needed back then.
Fixes: 77bd74156101 ("[PATCH] powerpc: PCI Error Recovery: PPC64 core recovery routines") Cc: stable@vger.kernel.org # v2.6.16+ Signed-off-by: Michael Neuling mikey@neuling.org Reviewed-by: Benjamin Herrenschmidt benh@kernel.crashing.org Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/powerpc/kernel/eeh_driver.c | 68 ++++++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 26 deletions(-)
--- a/arch/powerpc/kernel/eeh_driver.c +++ b/arch/powerpc/kernel/eeh_driver.c @@ -207,18 +207,18 @@ static void *eeh_report_error(void *data
if (!dev || eeh_dev_removed(edev) || eeh_pe_passed(edev->pe)) return NULL; + + device_lock(&dev->dev); dev->error_state = pci_channel_io_frozen;
driver = eeh_pcid_get(dev); - if (!driver) return NULL; + if (!driver) goto out_no_dev;
eeh_disable_irq(dev);
if (!driver->err_handler || - !driver->err_handler->error_detected) { - eeh_pcid_put(dev); - return NULL; - } + !driver->err_handler->error_detected) + goto out;
rc = driver->err_handler->error_detected(dev, pci_channel_io_frozen);
@@ -227,8 +227,12 @@ static void *eeh_report_error(void *data if (*res == PCI_ERS_RESULT_NONE) *res = rc;
edev->in_error = true; - eeh_pcid_put(dev); pci_uevent_ers(dev, PCI_ERS_RESULT_NONE); + +out: + eeh_pcid_put(dev); +out_no_dev: + device_unlock(&dev->dev); return NULL; }
@@ -251,15 +255,14 @@ static void *eeh_report_mmio_enabled(voi if (!dev || eeh_dev_removed(edev) || eeh_pe_passed(edev->pe)) return NULL;
+ device_lock(&dev->dev); driver = eeh_pcid_get(dev); - if (!driver) return NULL; + if (!driver) goto out_no_dev;
if (!driver->err_handler || !driver->err_handler->mmio_enabled || - (edev->mode & EEH_DEV_NO_HANDLER)) { - eeh_pcid_put(dev); - return NULL; - } + (edev->mode & EEH_DEV_NO_HANDLER)) + goto out;
rc = driver->err_handler->mmio_enabled(dev);
@@ -267,7 +270,10 @@ static void *eeh_report_mmio_enabled(voi if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc; if (*res == PCI_ERS_RESULT_NONE) *res = rc;
+out: eeh_pcid_put(dev); +out_no_dev: + device_unlock(&dev->dev); return NULL; }
@@ -290,20 +296,20 @@ static void *eeh_report_reset(void *data
if (!dev || eeh_dev_removed(edev) || eeh_pe_passed(edev->pe)) return NULL; + + device_lock(&dev->dev); dev->error_state = pci_channel_io_normal;
driver = eeh_pcid_get(dev); - if (!driver) return NULL; + if (!driver) goto out_no_dev;
eeh_enable_irq(dev);
if (!driver->err_handler || !driver->err_handler->slot_reset || (edev->mode & EEH_DEV_NO_HANDLER) || - (!edev->in_error)) { - eeh_pcid_put(dev); - return NULL; - } + (!edev->in_error)) + goto out;
rc = driver->err_handler->slot_reset(dev); if ((*res == PCI_ERS_RESULT_NONE) || @@ -311,7 +317,10 @@ static void *eeh_report_reset(void *data if (*res == PCI_ERS_RESULT_DISCONNECT && rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
+out: eeh_pcid_put(dev); +out_no_dev: + device_unlock(&dev->dev); return NULL; }
@@ -362,10 +371,12 @@ static void *eeh_report_resume(void *dat
if (!dev || eeh_dev_removed(edev) || eeh_pe_passed(edev->pe)) return NULL; + + device_lock(&dev->dev); dev->error_state = pci_channel_io_normal;
driver = eeh_pcid_get(dev); - if (!driver) return NULL; + if (!driver) goto out_no_dev;
was_in_error = edev->in_error; edev->in_error = false; @@ -375,18 +386,20 @@ static void *eeh_report_resume(void *dat !driver->err_handler->resume || (edev->mode & EEH_DEV_NO_HANDLER) || !was_in_error) { edev->mode &= ~EEH_DEV_NO_HANDLER; - eeh_pcid_put(dev); - return NULL; + goto out; }
driver->err_handler->resume(dev);
- eeh_pcid_put(dev); pci_uevent_ers(dev, PCI_ERS_RESULT_RECOVERED); +out: + eeh_pcid_put(dev); #ifdef CONFIG_PCI_IOV if (eeh_ops->notify_resume && eeh_dev_to_pdn(edev)) eeh_ops->notify_resume(eeh_dev_to_pdn(edev)); #endif +out_no_dev: + device_unlock(&dev->dev); return NULL; }
@@ -406,23 +419,26 @@ static void *eeh_report_failure(void *da
if (!dev || eeh_dev_removed(edev) || eeh_pe_passed(edev->pe)) return NULL; + + device_lock(&dev->dev); dev->error_state = pci_channel_io_perm_failure;
driver = eeh_pcid_get(dev); - if (!driver) return NULL; + if (!driver) goto out_no_dev;
eeh_disable_irq(dev);
if (!driver->err_handler || - !driver->err_handler->error_detected) { - eeh_pcid_put(dev); - return NULL; - } + !driver->err_handler->error_detected) + goto out;
driver->err_handler->error_detected(dev, pci_channel_io_perm_failure);
- eeh_pcid_put(dev); pci_uevent_ers(dev, PCI_ERS_RESULT_DISCONNECT); +out: + eeh_pcid_put(dev); +out_no_dev: + device_unlock(&dev->dev); return NULL; }
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicholas Piggin npiggin@gmail.com
commit a57ac411832384eb93df4bfed2bf644c4089720e upstream.
Presently the dt_cpu_ftrs restore_cpu will only add bits to the LPCR for secondaries, but some bits must be removed (e.g., UPRT for HPT). Not clearing these bits on secondaries causes checkstops when booting with disable_radix.
restore_cpu can not just set LPCR, because it is also called by the idle wakeup code which relies on opal_slw_set_reg to restore the value of LPCR, at least on P8 which does not save LPCR to stack in the idle code.
Fix this by including a mask of bits to clear from LPCR as well, which is used by restore_cpu.
This is a little messy now, but it's a minimal fix that can be backported. Longer term, the idle SPR save/restore code can be reworked to completely avoid calls to restore_cpu, then restore_cpu would be able to unconditionally set LPCR to match boot processor environment.
Fixes: 5a61ef74f269f ("powerpc/64s: Support new device tree binding for discovering CPU features") Cc: stable@vger.kernel.org # v4.12+ Signed-off-by: Nicholas Piggin npiggin@gmail.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/powerpc/kernel/dt_cpu_ftrs.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
--- a/arch/powerpc/kernel/dt_cpu_ftrs.c +++ b/arch/powerpc/kernel/dt_cpu_ftrs.c @@ -84,6 +84,7 @@ static int hv_mode;
static struct { u64 lpcr; + u64 lpcr_clear; u64 hfscr; u64 fscr; } system_registers; @@ -92,6 +93,8 @@ static void (*init_pmu_registers)(void);
static void __restore_cpu_cpufeatures(void) { + u64 lpcr; + /* * LPCR is restored by the power on engine already. It can be changed * after early init e.g., by radix enable, and we have no unified API @@ -104,8 +107,10 @@ static void __restore_cpu_cpufeatures(vo * The best we can do to accommodate secondary boot and idle restore * for now is "or" LPCR with existing. */ - - mtspr(SPRN_LPCR, system_registers.lpcr | mfspr(SPRN_LPCR)); + lpcr = mfspr(SPRN_LPCR); + lpcr |= system_registers.lpcr; + lpcr &= ~system_registers.lpcr_clear; + mtspr(SPRN_LPCR, lpcr); if (hv_mode) { mtspr(SPRN_LPID, 0); mtspr(SPRN_HFSCR, system_registers.hfscr); @@ -325,8 +330,9 @@ static int __init feat_enable_mmu_hash_v { u64 lpcr;
+ system_registers.lpcr_clear |= (LPCR_ISL | LPCR_UPRT | LPCR_HR); lpcr = mfspr(SPRN_LPCR); - lpcr &= ~LPCR_ISL; + lpcr &= ~(LPCR_ISL | LPCR_UPRT | LPCR_HR); mtspr(SPRN_LPCR, lpcr);
cur_cpu_spec->mmu_features |= MMU_FTRS_HASH_BASE;
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paul Mackerras paulus@ozlabs.org
commit dbfcf3cb9c681aa0c5d0bb46068f98d5b1823dd3 upstream.
On POWER9, since commit cc3d2940133d ("powerpc/64: Enable use of radix MMU under hypervisor on POWER9", 2017-01-30), we set both the radix and HPT bits in the client-architecture-support (CAS) vector, which tells the hypervisor that we can do either radix or HPT. According to PAPR, if we use this combination we are promising to do a H_REGISTER_PROC_TBL hcall later on to let the hypervisor know whether we are doing radix or HPT. We currently do this call if we are doing radix but not if we are doing HPT. If the hypervisor is able to support both radix and HPT guests, it would be entitled to defer allocation of the HPT until the H_REGISTER_PROC_TBL call, and to fail any attempts to create HPTEs until the H_REGISTER_PROC_TBL call. Thus we need to do a H_REGISTER_PROC_TBL call when we are doing HPT; otherwise we may crash at boot time.
This adds the code to call H_REGISTER_PROC_TBL in this case, before we attempt to create any HPT entries using H_ENTER.
Fixes: cc3d2940133d ("powerpc/64: Enable use of radix MMU under hypervisor on POWER9") Cc: stable@vger.kernel.org # v4.11+ Signed-off-by: Paul Mackerras paulus@ozlabs.org Reviewed-by: Suraj Jitindar Singh sjitindarsingh@gmail.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/powerpc/mm/hash_utils_64.c | 6 ++++++ arch/powerpc/platforms/pseries/lpar.c | 8 ++++++-- 2 files changed, 12 insertions(+), 2 deletions(-)
--- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -875,6 +875,12 @@ static void __init htab_initialize(void) /* Using a hypervisor which owns the htab */ htab_address = NULL; _SDR1 = 0; + /* + * On POWER9, we need to do a H_REGISTER_PROC_TBL hcall + * to inform the hypervisor that we wish to use the HPT. + */ + if (cpu_has_feature(CPU_FTR_ARCH_300)) + register_process_table(0, 0, 0); #ifdef CONFIG_FA_DUMP /* * If firmware assisted dump is active firmware preserves --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c @@ -726,15 +726,18 @@ static int pseries_lpar_resize_hpt(unsig return 0; }
-/* Actually only used for radix, so far */ static int pseries_lpar_register_process_table(unsigned long base, unsigned long page_size, unsigned long table_size) { long rc; - unsigned long flags = PROC_TABLE_NEW; + unsigned long flags = 0;
+ if (table_size) + flags |= PROC_TABLE_NEW; if (radix_enabled()) flags |= PROC_TABLE_RADIX | PROC_TABLE_GTSE; + else + flags |= PROC_TABLE_HPT_SLB; for (;;) { rc = plpar_hcall_norets(H_REGISTER_PROC_TBL, flags, base, page_size, table_size); @@ -760,6 +763,7 @@ void __init hpte_init_pseries(void) mmu_hash_ops.flush_hash_range = pSeries_lpar_flush_hash_range; mmu_hash_ops.hpte_clear_all = pseries_hpte_clear_all; mmu_hash_ops.hugepage_invalidate = pSeries_lpar_hugepage_invalidate; + register_process_table = pseries_lpar_register_process_table;
if (firmware_has_feature(FW_FEATURE_HPT_RESIZE)) mmu_hash_ops.resize_hpt = pseries_lpar_resize_hpt;
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicholas Piggin npiggin@gmail.com
commit 0bfdf598900fd62869659f360d3387ed80eb71cf upstream.
asm/barrier.h is not always included after asm/synch.h, which meant it was missing __SUBARCH_HAS_LWSYNC, so in some files smp_wmb() would be eieio when it should be lwsync. kernel/time/hrtimer.c is one case.
__SUBARCH_HAS_LWSYNC is only used in one place, so just fold it in to where it's used. Previously with my small simulator config, 377 instances of eieio in the tree. After this patch there are 55.
Fixes: 46d075be585e ("powerpc: Optimise smp_wmb") Cc: stable@vger.kernel.org # v2.6.29+ Signed-off-by: Nicholas Piggin npiggin@gmail.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/powerpc/include/asm/barrier.h | 3 ++- arch/powerpc/include/asm/synch.h | 4 ---- 2 files changed, 2 insertions(+), 5 deletions(-)
--- a/arch/powerpc/include/asm/barrier.h +++ b/arch/powerpc/include/asm/barrier.h @@ -35,7 +35,8 @@ #define rmb() __asm__ __volatile__ ("sync" : : : "memory") #define wmb() __asm__ __volatile__ ("sync" : : : "memory")
-#ifdef __SUBARCH_HAS_LWSYNC +/* The sub-arch has lwsync */ +#if defined(__powerpc64__) || defined(CONFIG_PPC_E500MC) # define SMPWMB LWSYNC #else # define SMPWMB eieio --- a/arch/powerpc/include/asm/synch.h +++ b/arch/powerpc/include/asm/synch.h @@ -6,10 +6,6 @@ #include <linux/stringify.h> #include <asm/feature-fixups.h>
-#if defined(__powerpc64__) || defined(CONFIG_PPC_E500MC) -#define __SUBARCH_HAS_LWSYNC -#endif - #ifndef __ASSEMBLY__ extern unsigned int __start___lwsync_fixup, __stop___lwsync_fixup; extern void do_lwsync_fixups(unsigned long value, void *fixup_start,
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Naveen N. Rao naveen.n.rao@linux.vnet.ibm.com
commit e6e133c47e6bd4d5dac05b35d06634a8e5648615 upstream.
Michael Ellerman reported the following call trace when running ftracetest:
BUG: using __this_cpu_write() in preemptible [00000000] code: ftracetest/6178 caller is opt_pre_handler+0xc4/0x110 CPU: 1 PID: 6178 Comm: ftracetest Not tainted 4.15.0-rc7-gcc6x-gb2cd1df #1 Call Trace: [c0000000f9ec39c0] [c000000000ac4304] dump_stack+0xb4/0x100 (unreliable) [c0000000f9ec3a00] [c00000000061159c] check_preemption_disabled+0x15c/0x170 [c0000000f9ec3a90] [c000000000217e84] opt_pre_handler+0xc4/0x110 [c0000000f9ec3af0] [c00000000004cf68] optimized_callback+0x148/0x170 [c0000000f9ec3b40] [c00000000004d954] optinsn_slot+0xec/0x10000 [c0000000f9ec3e30] [c00000000004bae0] kretprobe_trampoline+0x0/0x10
This is showing up since OPTPROBES is now enabled with CONFIG_PREEMPT.
trampoline_probe_handler() considers itself to be a special kprobe handler for kretprobes. In doing so, it expects to be called from kprobe_handler() on a trap, and re-enables preemption before returning a non-zero return value so as to suppress any subsequent processing of the trap by the kprobe_handler().
However, with optprobes, we don't deal with special handlers (we ignore the return code) and just try to re-enable preemption causing the above trace.
To address this, modify trampoline_probe_handler() to not be special. The only additional processing done in kprobe_handler() is to emulate the instruction (in this case, a 'nop'). We adjust the value of regs->nip for the purpose and delegate the job of re-enabling preemption and resetting current kprobe to the probe handlers (kprobe_handler() or optimized_callback()).
Fixes: 8a2d71a3f273 ("powerpc/kprobes: Disable preemption before invoking probe handler for optprobes") Cc: stable@vger.kernel.org # v4.15+ Reported-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Naveen N. Rao naveen.n.rao@linux.vnet.ibm.com Acked-by: Ananth N Mavinakayanahalli ananth@linux.vnet.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/powerpc/kernel/kprobes.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-)
--- a/arch/powerpc/kernel/kprobes.c +++ b/arch/powerpc/kernel/kprobes.c @@ -455,29 +455,33 @@ static int trampoline_probe_handler(stru }
kretprobe_assert(ri, orig_ret_address, trampoline_address); - regs->nip = orig_ret_address; + /* - * Make LR point to the orig_ret_address. - * When the 'nop' inside the kretprobe_trampoline - * is optimized, we can do a 'blr' after executing the - * detour buffer code. + * We get here through one of two paths: + * 1. by taking a trap -> kprobe_handler() -> here + * 2. by optprobe branch -> optimized_callback() -> opt_pre_handler() -> here + * + * When going back through (1), we need regs->nip to be setup properly + * as it is used to determine the return address from the trap. + * For (2), since nip is not honoured with optprobes, we instead setup + * the link register properly so that the subsequent 'blr' in + * kretprobe_trampoline jumps back to the right instruction. + * + * For nip, we should set the address to the previous instruction since + * we end up emulating it in kprobe_handler(), which increments the nip + * again. */ + regs->nip = orig_ret_address - 4; regs->link = orig_ret_address;
- reset_current_kprobe(); kretprobe_hash_unlock(current, &flags); - preempt_enable_no_resched();
hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) { hlist_del(&ri->hlist); kfree(ri); } - /* - * By returning a non-zero value, we are telling - * kprobe_handler() that we don't want the post_handler - * to run (and have re-enabled preemption) - */ - return 1; + + return 0; } NOKPROBE_SYMBOL(trampoline_probe_handler);
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thiago Jung Bauermann bauerman@linux.vnet.ibm.com
commit bf8a1abc3ddbd6e9a8312ea7d96e5dd89c140f18 upstream.
kexec_file_load() on powerpc doesn't support kdump kernels yet, so it returns -ENOTSUPP in that case.
I've recently learned that this errno is internal to the kernel and isn't supposed to be exposed to userspace. Therefore, change to -EOPNOTSUPP which is defined in an uapi header.
This does indeed make kexec-tools happier. Before the patch, on ppc64le:
# ~bauermann/src/kexec-tools/build/sbin/kexec -s -p /boot/vmlinuz kexec_file_load failed: Unknown error 524
After the patch:
# ~bauermann/src/kexec-tools/build/sbin/kexec -s -p /boot/vmlinuz kexec_file_load failed: Operation not supported
Fixes: a0458284f062 ("powerpc: Add support code for kexec_file_load()") Cc: stable@vger.kernel.org # v4.10+ Reported-by: Dave Young dyoung@redhat.com Signed-off-by: Thiago Jung Bauermann bauerman@linux.vnet.ibm.com Reviewed-by: Simon Horman horms@verge.net.au Reviewed-by: Dave Young dyoung@redhat.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/powerpc/kernel/machine_kexec_file_64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/powerpc/kernel/machine_kexec_file_64.c +++ b/arch/powerpc/kernel/machine_kexec_file_64.c @@ -43,7 +43,7 @@ int arch_kexec_kernel_image_probe(struct
/* We don't support crash kernels yet. */ if (image->type == KEXEC_TYPE_CRASH) - return -ENOTSUPP; + return -EOPNOTSUPP;
for (i = 0; i < ARRAY_SIZE(kexec_file_loaders); i++) { fops = kexec_file_loaders[i];
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicholas Piggin npiggin@gmail.com
commit 3b8070335f751aac9f1526ae2e012e6f5b8b0f21 upstream.
The OPAL NVRAM driver does not sleep in case it gets OPAL_BUSY or OPAL_BUSY_EVENT from firmware, which causes large scheduling latencies, and various lockup errors to trigger (again, BMC reboot can cause it).
Fix this by converting it to the standard form OPAL_BUSY loop that sleeps.
Fixes: 628daa8d5abf ("powerpc/powernv: Add RTC and NVRAM support plus RTAS fallbacks") Depends-on: 34dd25de9fe3 ("powerpc/powernv: define a standard delay for OPAL_BUSY type retry loops") Cc: stable@vger.kernel.org # v3.2+ Signed-off-by: Nicholas Piggin npiggin@gmail.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/powerpc/platforms/powernv/opal-nvram.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
--- a/arch/powerpc/platforms/powernv/opal-nvram.c +++ b/arch/powerpc/platforms/powernv/opal-nvram.c @@ -11,6 +11,7 @@
#define DEBUG
+#include <linux/delay.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/of.h> @@ -56,8 +57,12 @@ static ssize_t opal_nvram_write(char *bu
while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) { rc = opal_write_nvram(__pa(buf), count, off); - if (rc == OPAL_BUSY_EVENT) + if (rc == OPAL_BUSY_EVENT) { + msleep(OPAL_BUSY_DELAY_MS); opal_poll_events(NULL); + } else if (rc == OPAL_BUSY) { + msleep(OPAL_BUSY_DELAY_MS); + } }
if (rc)
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Ellerman mpe@ellerman.id.au
commit 2675c13b293a007b7b7f8229514126bd23df09a7 upstream.
In tlbiel_radix_set_isa300() we use the PPC_TLBIEL() macro to construct tlbiel instructions. The instruction takes 5 fields, two of which are registers, and the others are constants. But because it's constructed with inline asm the compiler doesn't know that.
We got the constraint wrong on the 'r' field, using "r" tells the compiler to put the value in a register. The value we then get in the macro is the *register number*, not the value of the field.
That means when we mask the register number with 0x1 we get 0 or 1 depending on which register the compiler happens to put the constant in, eg:
li r10,1 tlbiel r8,r9,2,0,0
li r7,1 tlbiel r10,r6,0,0,1
If we're unlucky we might generate an invalid instruction form, for example RIC=0, PRS=1 and R=0, tlbiel r8,r7,0,1,0, this has been observed to cause machine checks:
Oops: Machine check, sig: 7 [#1] CPU: 24 PID: 0 Comm: swapper NIP: 00000000000385f4 LR: 000000000100ed00 CTR: 000000000000007f REGS: c00000000110bb40 TRAP: 0200 MSR: 9000000000201003 <SF,HV,ME,RI,LE> CR: 48002222 XER: 20040000 CFAR: 00000000000385d0 DAR: 0000000000001c00 DSISR: 00000200 SOFTE: 1
If the machine check happens early in boot while we have MSR_ME=0 it will escalate into a checkstop and kill the box entirely.
To fix it we could change the inline asm constraint to "i" which tells the compiler the value is a constant. But a better fix is to just pass a literal 1 into the macro, which bypasses any problems with inline asm constraints.
Fixes: d4748276ae14 ("powerpc/64s: Improve local TLB flush for boot and MCE on POWER9") Cc: stable@vger.kernel.org # v4.16+ Signed-off-by: Michael Ellerman mpe@ellerman.id.au Reviewed-by: Nicholas Piggin npiggin@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/powerpc/mm/tlb-radix.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
--- a/arch/powerpc/mm/tlb-radix.c +++ b/arch/powerpc/mm/tlb-radix.c @@ -33,13 +33,12 @@ static inline void tlbiel_radix_set_isa3 { unsigned long rb; unsigned long rs; - unsigned int r = 1; /* radix format */
rb = (set << PPC_BITLSHIFT(51)) | (is << PPC_BITLSHIFT(53)); rs = ((unsigned long)pid << PPC_BITLSHIFT(31));
- asm volatile(PPC_TLBIEL(%0, %1, %2, %3, %4) - : : "r"(rb), "r"(rs), "i"(ric), "i"(prs), "r"(r) + asm volatile(PPC_TLBIEL(%0, %1, %2, %3, 1) + : : "r"(rb), "r"(rs), "i"(ric), "i"(prs) : "memory"); }
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yan, Zheng zyan@redhat.com
commit ffdeec7aa41aa61ca4ee68fddf4669df9ce661d1 upstream.
For new inode, atime/mtime/ctime are uninitialized. Don't compare against them.
Cc: stable@kernel.org Signed-off-by: "Yan, Zheng" zyan@redhat.com Reviewed-by: Ilya Dryomov idryomov@gmail.com Signed-off-by: Ilya Dryomov idryomov@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/ceph/inode.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
--- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -660,13 +660,15 @@ void ceph_fill_file_time(struct inode *i CEPH_CAP_FILE_BUFFER| CEPH_CAP_AUTH_EXCL| CEPH_CAP_XATTR_EXCL)) { - if (timespec_compare(ctime, &inode->i_ctime) > 0) { + if (ci->i_version == 0 || + timespec_compare(ctime, &inode->i_ctime) > 0) { dout("ctime %ld.%09ld -> %ld.%09ld inc w/ cap\n", inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec, ctime->tv_sec, ctime->tv_nsec); inode->i_ctime = *ctime; } - if (ceph_seq_cmp(time_warp_seq, ci->i_time_warp_seq) > 0) { + if (ci->i_version == 0 || + ceph_seq_cmp(time_warp_seq, ci->i_time_warp_seq) > 0) { /* the MDS did a utimes() */ dout("mtime %ld.%09ld -> %ld.%09ld " "tw %d -> %d\n", @@ -786,7 +788,6 @@ static int fill_inode(struct inode *inod new_issued = ~issued & le32_to_cpu(info->cap.caps);
/* update inode */ - ci->i_version = le64_to_cpu(info->version); inode->i_rdev = le32_to_cpu(info->rdev); inode->i_blkbits = fls(le32_to_cpu(info->layout.fl_stripe_unit)) - 1;
@@ -857,6 +858,9 @@ static int fill_inode(struct inode *inod xattr_blob = NULL; }
+ /* finally update i_version */ + ci->i_version = le64_to_cpu(info->version); + inode->i_mapping->a_ops = &ceph_aops;
switch (inode->i_mode & S_IFMT) {
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aaron Ma aaron.ma@canonical.com
commit 3064a03b94e60388f0955fcc29f3e8a978d28f75 upstream.
Follow the change of return type u32 of hid_report_len, fix all the types of variables those get the return value of hid_report_len to u32, and all other code already uses u32.
Cc: stable@vger.kernel.org Signed-off-by: Aaron Ma aaron.ma@canonical.com Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/hid/hid-input.c | 3 ++- drivers/hid/hid-multitouch.c | 5 +++-- drivers/hid/hid-rmi.c | 4 ++-- drivers/hid/wacom_sys.c | 4 ++-- 4 files changed, 9 insertions(+), 7 deletions(-)
--- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -1368,7 +1368,8 @@ static void hidinput_led_worker(struct w led_work); struct hid_field *field; struct hid_report *report; - int len, ret; + int ret; + u32 len; __u8 *buf;
field = hidinput_get_led_field(hid); --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -370,7 +370,8 @@ static const struct attribute_group mt_a static void mt_get_feature(struct hid_device *hdev, struct hid_report *report) { struct mt_device *td = hid_get_drvdata(hdev); - int ret, size = hid_report_len(report); + int ret; + u32 size = hid_report_len(report); u8 *buf;
/* @@ -1183,7 +1184,7 @@ static void mt_set_input_mode(struct hid struct hid_report_enum *re; struct mt_class *cls = &td->mtclass; char *buf; - int report_len; + u32 report_len;
if (td->inputmode < 0) return; --- a/drivers/hid/hid-rmi.c +++ b/drivers/hid/hid-rmi.c @@ -89,8 +89,8 @@ struct rmi_data { u8 *writeReport; u8 *readReport;
- int input_report_size; - int output_report_size; + u32 input_report_size; + u32 output_report_size;
unsigned long flags;
--- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -219,7 +219,7 @@ static void wacom_feature_mapping(struct unsigned int equivalent_usage = wacom_equivalent_usage(usage->hid); u8 *data; int ret; - int n; + u32 n;
switch (equivalent_usage) { case HID_DG_CONTACTMAX: @@ -519,7 +519,7 @@ static int wacom_set_device_mode(struct u8 *rep_data; struct hid_report *r; struct hid_report_enum *re; - int length; + u32 length; int error = -ENOMEM, limit = 0;
if (wacom_wac->mode_report < 0)
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aaron Ma aaron.ma@canonical.com
commit 6de0b13cc0b4ba10e98a9263d7a83b940720b77a upstream.
When size is negative, calling memset will make segment fault. Declare the size as type u32 to keep memset safe.
size in struct hid_report is unsigned, fix return type of hid_report_len to u32.
Cc: stable@vger.kernel.org Signed-off-by: Aaron Ma aaron.ma@canonical.com Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/hid/hid-core.c | 10 +++++----- include/linux/hid.h | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-)
--- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1365,7 +1365,7 @@ u8 *hid_alloc_report_buf(struct hid_repo * of implement() working on 8 byte chunks */
- int len = hid_report_len(report) + 7; + u32 len = hid_report_len(report) + 7;
return kmalloc(len, flags); } @@ -1430,7 +1430,7 @@ void __hid_request(struct hid_device *hi { char *buf; int ret; - int len; + u32 len;
buf = hid_alloc_report_buf(report, GFP_KERNEL); if (!buf) @@ -1456,14 +1456,14 @@ out: } EXPORT_SYMBOL_GPL(__hid_request);
-int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, +int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size, int interrupt) { struct hid_report_enum *report_enum = hid->report_enum + type; struct hid_report *report; struct hid_driver *hdrv; unsigned int a; - int rsize, csize = size; + u32 rsize, csize = size; u8 *cdata = data; int ret = 0;
@@ -1521,7 +1521,7 @@ EXPORT_SYMBOL_GPL(hid_report_raw_event); * * This is data entry for lower layers. */ -int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int interrupt) +int hid_input_report(struct hid_device *hid, int type, u8 *data, u32 size, int interrupt) { struct hid_report_enum *report_enum; struct hid_driver *hdrv; --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -851,7 +851,7 @@ extern int hidinput_connect(struct hid_d extern void hidinput_disconnect(struct hid_device *);
int hid_set_field(struct hid_field *, unsigned, __s32); -int hid_input_report(struct hid_device *, int type, u8 *, int, int); +int hid_input_report(struct hid_device *, int type, u8 *, u32, int); int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field); struct hid_field *hidinput_get_led_field(struct hid_device *hid); unsigned int hidinput_count_leds(struct hid_device *hid); @@ -1102,13 +1102,13 @@ static inline void hid_hw_wait(struct hi * * @report: the report we want to know the length */ -static inline int hid_report_len(struct hid_report *report) +static inline u32 hid_report_len(struct hid_report *report) { /* equivalent to DIV_ROUND_UP(report->size, 8) + !!(report->id > 0) */ return ((report->size - 1) >> 3) + 1 + (report->id > 0); }
-int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, +int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size, int interrupt);
/* HID quirks API */
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Wang sean.wang@mediatek.com
commit 73ce2ce129783813e1ebc37d2c757fe5e0fab1ef upstream.
Fix the pointer to struct scp_subdomian not being moved forward when each sub-domain is expected to be iteratively added through pm_genpd_add_subdomain call.
Cc: stable@vger.kernel.org Fixes: 53fddb1a66dd ("soc: mediatek: reduce code duplication of scpsys_probe across all SoCs") Reported-by: Weiyi Lu weiyi.lu@mediatek.com Signed-off-by: Sean Wang sean.wang@mediatek.com Signed-off-by: Matthias Brugger matthias.bgg@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/soc/mediatek/mtk-scpsys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/soc/mediatek/mtk-scpsys.c +++ b/drivers/soc/mediatek/mtk-scpsys.c @@ -992,7 +992,7 @@ static int scpsys_probe(struct platform_
pd_data = &scp->pd_data;
- for (i = 0, sd = soc->subdomains ; i < soc->num_subdomains ; i++) { + for (i = 0, sd = soc->subdomains; i < soc->num_subdomains; i++, sd++) { ret = pm_genpd_add_subdomain(pd_data->domains[sd->origin], pd_data->domains[sd->subdomain]); if (ret && IS_ENABLED(CONFIG_PM))
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: James Kelly jamespeterkelly@gmail.com
commit a01df75ce737951ad13a08d101306e88c3f57cb2 upstream.
SSM2602 driver is broken on recent kernels (at least since 4.9). User space applications such as amixer or alsamixer get EIO when attempting to access codec controls via the relevant IOCTLs.
Root cause of these failures is the regcache_hw_init function in drivers/base/regmap/regcache.c, which prevents regmap cache initalization from the reg_defaults_raw element of the regmap_config structure when registers are write only. It also disables the regmap cache entirely when all registers are write only or volatile as is the case for the SSM2602 driver.
Using the reg_defaults element of the regmap_config structure rather than the reg_defaults_raw element to initalize the regmap cache avoids the logic in the regcache_hw_init function entirely. It also makes this driver consistent with other ASoC codec drivers, as this driver was the ONLY codec driver that used the reg_defaults_raw element to initalize the cache.
Tested on Digilent Zybo Z7 development board which has a SSM2603 codec chip connected to a Xilinx Zynq SoC.
Signed-off-by: James Kelly jamespeterkelly@gmail.com Signed-off-by: Mark Brown broonie@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- sound/soc/codecs/ssm2602.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-)
--- a/sound/soc/codecs/ssm2602.c +++ b/sound/soc/codecs/ssm2602.c @@ -54,10 +54,17 @@ struct ssm2602_priv { * using 2 wire for device control, so we cache them instead. * There is no point in caching the reset register */ -static const u16 ssm2602_reg[SSM2602_CACHEREGNUM] = { - 0x0097, 0x0097, 0x0079, 0x0079, - 0x000a, 0x0008, 0x009f, 0x000a, - 0x0000, 0x0000 +static const struct reg_default ssm2602_reg[SSM2602_CACHEREGNUM] = { + { .reg = 0x00, .def = 0x0097 }, + { .reg = 0x01, .def = 0x0097 }, + { .reg = 0x02, .def = 0x0079 }, + { .reg = 0x03, .def = 0x0079 }, + { .reg = 0x04, .def = 0x000a }, + { .reg = 0x05, .def = 0x0008 }, + { .reg = 0x06, .def = 0x009f }, + { .reg = 0x07, .def = 0x000a }, + { .reg = 0x08, .def = 0x0000 }, + { .reg = 0x09, .def = 0x0000 } };
@@ -620,8 +627,8 @@ const struct regmap_config ssm2602_regma .volatile_reg = ssm2602_register_volatile,
.cache_type = REGCACHE_RBTREE, - .reg_defaults_raw = ssm2602_reg, - .num_reg_defaults_raw = ARRAY_SIZE(ssm2602_reg), + .reg_defaults = ssm2602_reg, + .num_reg_defaults = ARRAY_SIZE(ssm2602_reg), }; EXPORT_SYMBOL_GPL(ssm2602_regmap_config);
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Liam Girdwood liam.r.girdwood@linux.intel.com
commit 267e2c6fd7ca3d4076d20f9d52d49dc91addfe9d upstream.
Fix the topology kcontrol string handling so that string pointer references are strdup()ed instead of being copied. This fixes issues with kcontrol templates on the stack or ones that are freed. Remember and free the strings too when topology is unloaded.
Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com Signed-off-by: Mark Brown broonie@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- sound/soc/soc-topology.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-)
--- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c @@ -523,6 +523,7 @@ static void remove_widget(struct snd_soc kfree(se->dobj.control.dtexts[j]);
kfree(se); + kfree(w->kcontrol_news[i].name); } kfree(w->kcontrol_news); } else { @@ -540,6 +541,7 @@ static void remove_widget(struct snd_soc */ kfree((void *)kcontrol->private_value); snd_ctl_remove(card, kcontrol); + kfree(w->kcontrol_news[i].name); } kfree(w->kcontrol_news); } @@ -1233,7 +1235,9 @@ static struct snd_kcontrol_new *soc_tplg dev_dbg(tplg->dev, " adding DAPM widget mixer control %s at %d\n", mc->hdr.name, i);
- kc[i].name = mc->hdr.name; + kc[i].name = kstrdup(mc->hdr.name, GFP_KERNEL); + if (kc[i].name == NULL) + goto err_str; kc[i].private_value = (long)sm; kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER; kc[i].access = mc->hdr.access; @@ -1278,8 +1282,10 @@ static struct snd_kcontrol_new *soc_tplg err_str: kfree(sm); err: - for (--i; i >= 0; i--) + for (--i; i >= 0; i--) { kfree((void *)kc[i].private_value); + kfree(kc[i].name); + } kfree(kc); return NULL; } @@ -1310,7 +1316,9 @@ static struct snd_kcontrol_new *soc_tplg dev_dbg(tplg->dev, " adding DAPM widget enum control %s\n", ec->hdr.name);
- kc[i].name = ec->hdr.name; + kc[i].name = kstrdup(ec->hdr.name, GFP_KERNEL); + if (kc[i].name == NULL) + goto err_se; kc[i].private_value = (long)se; kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER; kc[i].access = ec->hdr.access; @@ -1386,6 +1394,7 @@ err_se: kfree(se->dobj.control.dtexts[j]);
kfree(se); + kfree(kc[i].name); } err: kfree(kc); @@ -1424,7 +1433,9 @@ static struct snd_kcontrol_new *soc_tplg "ASoC: adding bytes kcontrol %s with access 0x%x\n", be->hdr.name, be->hdr.access);
- kc[i].name = be->hdr.name; + kc[i].name = kstrdup(be->hdr.name, GFP_KERNEL); + if (kc[i].name == NULL) + goto err; kc[i].private_value = (long)sbe; kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER; kc[i].access = be->hdr.access; @@ -1454,8 +1465,10 @@ static struct snd_kcontrol_new *soc_tplg return kc;
err: - for (--i; i >= 0; i--) + for (--i; i >= 0; i--) { kfree((void *)kc[i].private_value); + kfree(kc[i].name); + }
kfree(kc); return NULL;
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mika Westerberg mika.westerberg@linux.intel.com
commit e4be8c9b6a512e274cb6bbac4ac869d73880a8b3 upstream.
Sometimes during cold boot ICM has not yet authenticated the active NVM image leading to timeout and failing the driver probe. Allow ICM to take some more time and increase the timeout to 3 seconds before we give up.
While there fix icm_firmware_init() to return the real error code without overwriting it with -ENODEV.
Fixes: f67cf491175a ("thunderbolt: Add support for Internal Connection Manager (ICM)") Signed-off-by: Mika Westerberg mika.westerberg@linux.intel.com Reviewed-by: Andy Shevchenko andy.shevchenko@gmail.com Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/thunderbolt/icm.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
--- a/drivers/thunderbolt/icm.c +++ b/drivers/thunderbolt/icm.c @@ -728,14 +728,14 @@ static bool icm_ar_is_supported(struct t static int icm_ar_get_mode(struct tb *tb) { struct tb_nhi *nhi = tb->nhi; - int retries = 5; + int retries = 60; u32 val;
do { val = ioread32(nhi->iobase + REG_FW_STS); if (val & REG_FW_STS_NVM_AUTH_DONE) break; - msleep(30); + msleep(50); } while (--retries);
if (!retries) { @@ -1054,6 +1054,9 @@ static int icm_firmware_init(struct tb * break;
default: + if (ret < 0) + return ret; + tb_err(tb, "ICM firmware is in wrong mode: %u\n", ret); return -ENODEV; }
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mika Westerberg mika.westerberg@linux.intel.com
commit a03e828915c00ed0ea5aa40647c81472cfa7a984 upstream.
We need to make sure a new PCIe tunnel is not created in a middle of previous PCI rescan because otherwise the rescan code might find too much and fail to reconfigure devices properly. This is important when native PCIe hotplug is used. In BIOS assisted hotplug there should be no such issue.
Fixes: f67cf491175a ("thunderbolt: Add support for Internal Connection Manager (ICM)") Signed-off-by: Mika Westerberg mika.westerberg@linux.intel.com Reviewed-by: Andy Shevchenko andy.shevchenko@gmail.com Cc: Bjorn Helgaas bhelgaas@google.com Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/thunderbolt/switch.c | 9 +++++++++ 1 file changed, 9 insertions(+)
--- a/drivers/thunderbolt/switch.c +++ b/drivers/thunderbolt/switch.c @@ -716,6 +716,13 @@ static int tb_switch_set_authorized(stru if (sw->authorized) goto unlock;
+ /* + * Make sure there is no PCIe rescan ongoing when a new PCIe + * tunnel is created. Otherwise the PCIe rescan code might find + * the new tunnel too early. + */ + pci_lock_rescan_remove(); + switch (val) { /* Approve switch */ case 1: @@ -735,6 +742,8 @@ static int tb_switch_set_authorized(stru break; }
+ pci_unlock_rescan_remove(); + if (!ret) { sw->authorized = val; /* Notify status change to the userspace */
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mika Westerberg mika.westerberg@linux.intel.com
commit f2a659f7d8d5da803836583aa16df06bdf324252 upstream.
The driver misses implementation of PM hook that undoes what ->freeze_noirq() does after the hibernation image is created. This means the control channel is not resumed properly and the Thunderbolt bus becomes useless in later stages of hibernation (when the image is stored or if the operation fails).
Fix this by pointing ->thaw_noirq to driver nhi_resume_noirq(). This makes sure the control channel is resumed properly.
Fixes: 23dd5bb49d98 ("thunderbolt: Add suspend/hibernate support") Signed-off-by: Mika Westerberg mika.westerberg@linux.intel.com Reviewed-by: Andy Shevchenko andy.shevchenko@gmail.com Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/thunderbolt/nhi.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/thunderbolt/nhi.c +++ b/drivers/thunderbolt/nhi.c @@ -1064,6 +1064,7 @@ static const struct dev_pm_ops nhi_pm_op * we just disable hotplug, the * pci-tunnels stay alive. */ + .thaw_noirq = nhi_resume_noirq, .restore_noirq = nhi_resume_noirq, .suspend = nhi_suspend, .freeze = nhi_suspend,
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mika Westerberg mika.westerberg@linux.intel.com
commit 79fae987518a3aa6c3c7b2e3ad5fe1e4080c12bc upstream.
If the system is suspended and user disconnects cable to another host and connects it to a Thunderbolt device instead we get a warning from driver core about adding duplicate sysfs attribute and adding the new device fails.
Handle this properly so that we first remove the existing XDomain connection before adding new devices.
Fixes: d1ff70241a27 ("thunderbolt: Add support for XDomain discovery protocol") Signed-off-by: Mika Westerberg mika.westerberg@linux.intel.com Reviewed-by: Andy Shevchenko andy.shevchenko@gmail.com Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/thunderbolt/icm.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-)
--- a/drivers/thunderbolt/icm.c +++ b/drivers/thunderbolt/icm.c @@ -383,6 +383,15 @@ static void remove_switch(struct tb_swit tb_switch_remove(sw); }
+static void remove_xdomain(struct tb_xdomain *xd) +{ + struct tb_switch *sw; + + sw = tb_to_switch(xd->dev.parent); + tb_port_at(xd->route, sw)->xdomain = NULL; + tb_xdomain_remove(xd); +} + static void icm_fr_device_connected(struct tb *tb, const struct icm_pkg_header *hdr) { @@ -391,6 +400,7 @@ icm_fr_device_connected(struct tb *tb, c struct tb_switch *sw, *parent_sw; struct icm *icm = tb_priv(tb); bool authorized = false; + struct tb_xdomain *xd; u8 link, depth; u64 route; int ret; @@ -467,6 +477,13 @@ icm_fr_device_connected(struct tb *tb, c tb_switch_put(sw); }
+ /* Remove existing XDomain connection if found */ + xd = tb_xdomain_find_by_link_depth(tb, link, depth); + if (xd) { + remove_xdomain(xd); + tb_xdomain_put(xd); + } + parent_sw = tb_switch_find_by_link_depth(tb, link, depth - 1); if (!parent_sw) { tb_err(tb, "failed to find parent switch for %u.%u\n", @@ -529,15 +546,6 @@ icm_fr_device_disconnected(struct tb *tb tb_switch_put(sw); }
-static void remove_xdomain(struct tb_xdomain *xd) -{ - struct tb_switch *sw; - - sw = tb_to_switch(xd->dev.parent); - tb_port_at(xd->route, sw)->xdomain = NULL; - tb_xdomain_remove(xd); -} - static void icm_fr_xdomain_connected(struct tb *tb, const struct icm_pkg_header *hdr) {
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mika Westerberg mika.westerberg@linux.intel.com
commit ea9d7bb798900096f26c585957d6ad9c532417e6 upstream.
On Lenovo ThinkPad Yoga 370 (and possibly some other Lenovo models as well) the Thunderbolt host controller sometimes comes up in such way that the ICM firmware is not running properly. This is most likely an issue in BIOS/firmware but as side-effect driver crashes the kernel due to NULL pointer dereference:
BUG: unable to handle kernel NULL pointer dereference at 0000000000000980 IP: pci_write_config_dword+0x5/0x20 Call Trace: pcie2cio_write+0x3b/0x70 [thunderbolt] icm_driver_ready+0x168/0x260 [thunderbolt] ? tb_ctl_start+0x50/0x70 [thunderbolt] tb_domain_add+0x73/0xf0 [thunderbolt] nhi_probe+0x182/0x300 [thunderbolt] local_pci_probe+0x42/0xa0 ? pci_match_device+0xd9/0x100 pci_device_probe+0x146/0x1b0 driver_probe_device+0x315/0x480 ...
Instead of crashing update the driver to bail out gracefully if we encounter such situation.
Fixes: f67cf491175a ("thunderbolt: Add support for Internal Connection Manager (ICM)") Reported-by: Jordan Glover Golden_Miller83@protonmail.ch Signed-off-by: Mika Westerberg mika.westerberg@linux.intel.com Acked-by: Yehezkel Bernat yehezkel.bernat@intel.com Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/thunderbolt/icm.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/drivers/thunderbolt/icm.c +++ b/drivers/thunderbolt/icm.c @@ -923,6 +923,9 @@ static int icm_firmware_reset(struct tb struct icm *icm = tb_priv(tb); u32 val;
+ if (!icm->upstream_port) + return -ENODEV; + /* Put ARC to wait for CIO reset event to happen */ val = ioread32(nhi->iobase + REG_FW_STS); val |= REG_FW_STS_CIO_RESET_REQ;
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aniruddha Banerjee aniruddhab@nvidia.com
commit aa08192a254d362a4d5317647a81de6996961aef upstream.
Most MMIO GIC register accesses use a 1-hot bit scheme that avoids requiring any form of locking. This isn't true for the GICD_ICFGRn registers, which require a RMW sequence.
Unfortunately, we seem to be missing a lock for these particular accesses, which could result in a race condition if changing the trigger type on any two interrupts within the same set of 16 interrupts (and thus controlled by the same CFGR register).
Introduce a private lock in the GIC common comde for this particular case, making it cover both GIC implementations in one go.
Cc: stable@vger.kernel.org Signed-off-by: Aniruddha Banerjee aniruddhab@nvidia.com [maz: updated changelog] Signed-off-by: Marc Zyngier marc.zyngier@arm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/irqchip/irq-gic-common.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
--- a/drivers/irqchip/irq-gic-common.c +++ b/drivers/irqchip/irq-gic-common.c @@ -21,6 +21,8 @@
#include "irq-gic-common.h"
+static DEFINE_RAW_SPINLOCK(irq_controller_lock); + static const struct gic_kvm_info *gic_kvm_info;
const struct gic_kvm_info *gic_get_kvm_info(void) @@ -53,11 +55,13 @@ int gic_configure_irq(unsigned int irq, u32 confoff = (irq / 16) * 4; u32 val, oldval; int ret = 0; + unsigned long flags;
/* * Read current configuration register, and insert the config * for "irq", depending on "type". */ + raw_spin_lock_irqsave(&irq_controller_lock, flags); val = oldval = readl_relaxed(base + GIC_DIST_CONFIG + confoff); if (type & IRQ_TYPE_LEVEL_MASK) val &= ~confmask; @@ -65,8 +69,10 @@ int gic_configure_irq(unsigned int irq, val |= confmask;
/* If the current configuration is the same, then we are done */ - if (val == oldval) + if (val == oldval) { + raw_spin_unlock_irqrestore(&irq_controller_lock, flags); return 0; + }
/* * Write back the new configuration, and possibly re-enable @@ -84,6 +90,7 @@ int gic_configure_irq(unsigned int irq, pr_warn("GIC: PPI%d is secure or misconfigured\n", irq - 16); } + raw_spin_unlock_irqrestore(&irq_controller_lock, flags);
if (sync_access) sync_access();
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o tytso@mit.edu
commit 9f886f4d1d292442b2f22a0a33321eae821bde40 upstream.
This fixes a harmless UBSAN where root could potentially end up causing an overflow while bumping the entropy_total field (which is ignored once the entropy pool has been initialized, and this generally is completed during the boot sequence).
This is marginal for the stable kernel series, but it's a really trivial patch, and it fixes UBSAN warning that might cause security folks to get overly excited for no reason.
Signed-off-by: Theodore Ts'o tytso@mit.edu Reported-by: Chen Feng puck.chen@hisilicon.com Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/char/random.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -732,7 +732,7 @@ retry:
static int credit_entropy_bits_safe(struct entropy_store *r, int nbits) { - const int nbits_max = (int)(~0U >> (ENTROPY_SHIFT + 1)); + const int nbits_max = r->poolinfo->poolwords * 32;
if (nbits < 0) return -EINVAL;
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans de Goede hdegoede@redhat.com
commit ad49aee401dd1997ec71360df6e51a91ad3cf516 upstream.
Sometimes (firmware bug?) the V5 boost GPIO is not configured as output by the BIOS, leading to the 5V boost convertor being permanently on,
Explicitly set the direction and drv flags rather then inheriting them from the firmware to fix this.
Fixes: 585cb239f4de ("extcon: intel-cht-wc: Disable external 5v boost ...") Cc: stable@vger.kernel.org Reviewed-by: Andy Shevchenko andy.shevchenko@gmail.com Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Chanwoo Choi cw00.choi@samsung.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/extcon/extcon-intel-cht-wc.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
--- a/drivers/extcon/extcon-intel-cht-wc.c +++ b/drivers/extcon/extcon-intel-cht-wc.c @@ -66,6 +66,8 @@
#define CHT_WC_VBUS_GPIO_CTLO 0x6e2d #define CHT_WC_VBUS_GPIO_CTLO_OUTPUT BIT(0) +#define CHT_WC_VBUS_GPIO_CTLO_DRV_OD BIT(4) +#define CHT_WC_VBUS_GPIO_CTLO_DIR_OUT BIT(5)
enum cht_wc_usb_id { USB_ID_OTG, @@ -183,14 +185,15 @@ static void cht_wc_extcon_set_5v_boost(s { int ret, val;
- val = enable ? CHT_WC_VBUS_GPIO_CTLO_OUTPUT : 0; - /* * The 5V boost converter is enabled through a gpio on the PMIC, since * there currently is no gpio driver we access the gpio reg directly. */ - ret = regmap_update_bits(ext->regmap, CHT_WC_VBUS_GPIO_CTLO, - CHT_WC_VBUS_GPIO_CTLO_OUTPUT, val); + val = CHT_WC_VBUS_GPIO_CTLO_DRV_OD | CHT_WC_VBUS_GPIO_CTLO_DIR_OUT; + if (enable) + val |= CHT_WC_VBUS_GPIO_CTLO_OUTPUT; + + ret = regmap_write(ext->regmap, CHT_WC_VBUS_GPIO_CTLO, val); if (ret) dev_err(ext->dev, "Error writing Vbus GPIO CTLO: %d\n", ret); }
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikulas Patocka mpatocka@redhat.com
commit 6e2fb22103b99c26ae30a46512abe75526d8e4c9 upstream.
Early alpha processors cannot write a single byte or word; they read 8 bytes, modify the value in registers and write back 8 bytes.
The type blk_status_t is defined as one byte, it is often written asynchronously by I/O completion routines, this asynchronous modification can corrupt content of nearby bytes if these nearby bytes can be written simultaneously by another CPU.
- one example of such corruption is the structure dm_io where "blk_status_t status" is written by an asynchronous completion routine and "atomic_t io_count" is modified synchronously - another example is the structure dm_buffer where "unsigned hold_count" is modified synchronously from process context and "blk_status_t write_error" is modified asynchronously from bio completion routine
This patch fixes the bug by changing the type blk_status_t to 32 bits if we are on Alpha and if we are compiling for a processor that doesn't have the byte-word-extension.
Signed-off-by: Mikulas Patocka mpatocka@redhat.com Cc: stable@vger.kernel.org # 4.13+ Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- include/linux/blk_types.h | 5 +++++ 1 file changed, 5 insertions(+)
--- a/include/linux/blk_types.h +++ b/include/linux/blk_types.h @@ -20,8 +20,13 @@ typedef void (bio_end_io_t) (struct bio
/* * Block error status values. See block/blk-core:blk_errors for the details. + * Alpha cannot write a byte atomically, so we need to use 32-bit value. */ +#if defined(CONFIG_ALPHA) && !defined(__alpha_bwx__) +typedef u32 __bitwise blk_status_t; +#else typedef u8 __bitwise blk_status_t; +#endif #define BLK_STS_OK 0 #define BLK_STS_NOTSUPP ((__force blk_status_t)1) #define BLK_STS_TIMEOUT ((__force blk_status_t)2)
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o tytso@mit.edu
commit 85e0c4e89c1b864e763c4e3bb15d0b6d501ad5d9 upstream.
This updates the jbd2 superblock unnecessarily, and on an abort we shouldn't truncate the log.
Signed-off-by: Theodore Ts'o tytso@mit.edu Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/jbd2/journal.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
--- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c @@ -974,7 +974,7 @@ out: }
/* - * This is a variaon of __jbd2_update_log_tail which checks for validity of + * This is a variation of __jbd2_update_log_tail which checks for validity of * provided log tail and locks j_checkpoint_mutex. So it is safe against races * with other threads updating log tail. */ @@ -1417,6 +1417,9 @@ int jbd2_journal_update_sb_log_tail(jour journal_superblock_t *sb = journal->j_superblock; int ret;
+ if (is_journal_aborted(journal)) + return -EIO; + BUG_ON(!mutex_is_locked(&journal->j_checkpoint_mutex)); jbd_debug(1, "JBD2: updating superblock (start %lu, seq %u)\n", tail_block, tail_tid);
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o tytso@mit.edu
commit 576d18ed60f5465110087c5e0eb1010de13e374d upstream.
The ext4 forced shutdown flag needs to prevent new handles from being started, but it needs to allow existing handles to complete. So the forced shutdown flag should not force ext4_journal_get_write_access to fail.
Signed-off-by: Theodore Ts'o tytso@mit.edu Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/ext4/ext4_jbd2.c | 7 ------- 1 file changed, 7 deletions(-)
--- a/fs/ext4/ext4_jbd2.c +++ b/fs/ext4/ext4_jbd2.c @@ -166,13 +166,6 @@ int __ext4_journal_get_write_access(cons might_sleep();
if (ext4_handle_valid(handle)) { - struct super_block *sb; - - sb = handle->h_transaction->t_journal->j_private; - if (unlikely(ext4_forced_shutdown(EXT4_SB(sb)))) { - jbd2_journal_abort_handle(handle); - return -EIO; - } err = jbd2_journal_get_write_access(handle, bh); if (err) ext4_journal_abort_handle(where, line, __func__, bh,
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o tytso@mit.edu
commit a6d9946bb925293fda9f5ed6d33d8580b001f006 upstream.
The msleep() when processing EXT4_GOING_FLAGS_NOLOGFLUSH was a hack to avoid some races (that are now fixed), but in fact it introduced its own race.
Signed-off-by: Theodore Ts'o tytso@mit.edu Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/ext4/ioctl.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
--- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c @@ -497,10 +497,8 @@ static int ext4_shutdown(struct super_bl break; case EXT4_GOING_FLAGS_NOLOGFLUSH: set_bit(EXT4_FLAGS_SHUTDOWN, &sbi->s_ext4_flags); - if (sbi->s_journal && !is_journal_aborted(sbi->s_journal)) { - msleep(100); + if (sbi->s_journal && !is_journal_aborted(sbi->s_journal)) jbd2_journal_abort(sbi->s_journal, 0); - } break; default: return -EINVAL;
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o tytso@mit.edu
commit fb7c02445c497943e7296cd3deee04422b63acb8 upstream.
Previously the jbd2 layer assumed that a file system check would be required after a journal abort. In the case of the deliberate file system shutdown, this should not be necessary. Allow the jbd2 layer to distinguish between these two cases by using the ESHUTDOWN errno.
Also add proper locking to __journal_abort_soft().
Signed-off-by: Theodore Ts'o tytso@mit.edu Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/ext4/ioctl.c | 4 ++-- fs/jbd2/journal.c | 25 +++++++++++++++++++------ 2 files changed, 21 insertions(+), 8 deletions(-)
--- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c @@ -492,13 +492,13 @@ static int ext4_shutdown(struct super_bl set_bit(EXT4_FLAGS_SHUTDOWN, &sbi->s_ext4_flags); if (sbi->s_journal && !is_journal_aborted(sbi->s_journal)) { (void) ext4_force_commit(sb); - jbd2_journal_abort(sbi->s_journal, 0); + jbd2_journal_abort(sbi->s_journal, -ESHUTDOWN); } break; case EXT4_GOING_FLAGS_NOLOGFLUSH: set_bit(EXT4_FLAGS_SHUTDOWN, &sbi->s_ext4_flags); if (sbi->s_journal && !is_journal_aborted(sbi->s_journal)) - jbd2_journal_abort(sbi->s_journal, 0); + jbd2_journal_abort(sbi->s_journal, -ESHUTDOWN); break; default: return -EINVAL; --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c @@ -1486,12 +1486,15 @@ static void jbd2_mark_journal_empty(jour void jbd2_journal_update_sb_errno(journal_t *journal) { journal_superblock_t *sb = journal->j_superblock; + int errcode;
read_lock(&journal->j_state_lock); - jbd_debug(1, "JBD2: updating superblock error (errno %d)\n", - journal->j_errno); - sb->s_errno = cpu_to_be32(journal->j_errno); + errcode = journal->j_errno; read_unlock(&journal->j_state_lock); + if (errcode == -ESHUTDOWN) + errcode = 0; + jbd_debug(1, "JBD2: updating superblock error (errno %d)\n", errcode); + sb->s_errno = cpu_to_be32(errcode);
jbd2_write_superblock(journal, REQ_SYNC | REQ_FUA); } @@ -2108,12 +2111,22 @@ void __jbd2_journal_abort_hard(journal_t * but don't do any other IO. */ static void __journal_abort_soft (journal_t *journal, int errno) { - if (journal->j_flags & JBD2_ABORT) - return; + int old_errno;
- if (!journal->j_errno) + write_lock(&journal->j_state_lock); + old_errno = journal->j_errno; + if (!journal->j_errno || errno == -ESHUTDOWN) journal->j_errno = errno;
+ if (journal->j_flags & JBD2_ABORT) { + write_unlock(&journal->j_state_lock); + if (!old_errno && old_errno != -ESHUTDOWN && + errno == -ESHUTDOWN) + jbd2_journal_update_sb_errno(journal); + return; + } + write_unlock(&journal->j_state_lock); + __jbd2_journal_abort_hard(journal);
if (errno) {
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o tytso@mit.edu
commit 044e6e3d74a3d7103a0c8a9305dfd94d64000660 upstream.
When reading the inode or block allocation bitmap, if the bitmap needs to be initialized, do not update the checksum in the block group descriptor. That's because we're not set up to journal those changes. Instead, just set the verified bit on the bitmap block, so that it's not necessary to validate the checksum.
When a block or inode allocation actually happens, at that point the checksum will be calculated, and update of the bg descriptor block will be properly journalled.
Signed-off-by: Theodore Ts'o tytso@mit.edu Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/ext4/balloc.c | 3 +-- fs/ext4/ialloc.c | 47 +++-------------------------------------------- 2 files changed, 4 insertions(+), 46 deletions(-)
--- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c @@ -243,8 +243,6 @@ static int ext4_init_block_bitmap(struct */ ext4_mark_bitmap_end(num_clusters_in_group(sb, block_group), sb->s_blocksize * 8, bh->b_data); - ext4_block_bitmap_csum_set(sb, block_group, gdp, bh); - ext4_group_desc_csum_set(sb, block_group, gdp); return 0; }
@@ -448,6 +446,7 @@ ext4_read_block_bitmap_nowait(struct sup err = ext4_init_block_bitmap(sb, bh, block_group, desc); set_bitmap_uptodate(bh); set_buffer_uptodate(bh); + set_buffer_verified(bh); ext4_unlock_group(sb, block_group); unlock_buffer(bh); if (err) { --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -66,44 +66,6 @@ void ext4_mark_bitmap_end(int start_bit, memset(bitmap + (i >> 3), 0xff, (end_bit - i) >> 3); }
-/* Initializes an uninitialized inode bitmap */ -static int ext4_init_inode_bitmap(struct super_block *sb, - struct buffer_head *bh, - ext4_group_t block_group, - struct ext4_group_desc *gdp) -{ - struct ext4_group_info *grp; - struct ext4_sb_info *sbi = EXT4_SB(sb); - J_ASSERT_BH(bh, buffer_locked(bh)); - - /* If checksum is bad mark all blocks and inodes use to prevent - * allocation, essentially implementing a per-group read-only flag. */ - if (!ext4_group_desc_csum_verify(sb, block_group, gdp)) { - grp = ext4_get_group_info(sb, block_group); - if (!EXT4_MB_GRP_BBITMAP_CORRUPT(grp)) - percpu_counter_sub(&sbi->s_freeclusters_counter, - grp->bb_free); - set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, &grp->bb_state); - if (!EXT4_MB_GRP_IBITMAP_CORRUPT(grp)) { - int count; - count = ext4_free_inodes_count(sb, gdp); - percpu_counter_sub(&sbi->s_freeinodes_counter, - count); - } - set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state); - return -EFSBADCRC; - } - - memset(bh->b_data, 0, (EXT4_INODES_PER_GROUP(sb) + 7) / 8); - ext4_mark_bitmap_end(EXT4_INODES_PER_GROUP(sb), sb->s_blocksize * 8, - bh->b_data); - ext4_inode_bitmap_csum_set(sb, block_group, gdp, bh, - EXT4_INODES_PER_GROUP(sb) / 8); - ext4_group_desc_csum_set(sb, block_group, gdp); - - return 0; -} - void ext4_end_bitmap_read(struct buffer_head *bh, int uptodate) { if (uptodate) { @@ -187,17 +149,14 @@ ext4_read_inode_bitmap(struct super_bloc
ext4_lock_group(sb, block_group); if (desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) { - err = ext4_init_inode_bitmap(sb, bh, block_group, desc); + memset(bh->b_data, 0, (EXT4_INODES_PER_GROUP(sb) + 7) / 8); + ext4_mark_bitmap_end(EXT4_INODES_PER_GROUP(sb), + sb->s_blocksize * 8, bh->b_data); set_bitmap_uptodate(bh); set_buffer_uptodate(bh); set_buffer_verified(bh); ext4_unlock_group(sb, block_group); unlock_buffer(bh); - if (err) { - ext4_error(sb, "Failed to init inode bitmap for group " - "%u: %d", block_group, err); - goto out; - } return bh; } ext4_unlock_group(sb, block_group);
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eryu Guan guaneryu@gmail.com
commit 73fdad00b208b139cf43f3163fbc0f67e4c6047c upstream.
i_disksize update should be protected by i_data_sem, by either taking the lock explicitly or by using ext4_update_i_disksize() helper. But the i_disksize updates in ext4_direct_IO_write() are not protected at all, which may be racing with i_disksize updates in writeback path in delalloc buffer write path.
This is found by code inspection, and I didn't hit any i_disksize corruption due to this bug. Thanks to Jan Kara for catching this bug and suggesting the fix!
Reported-by: Jan Kara jack@suse.cz Suggested-by: Jan Kara jack@suse.cz Signed-off-by: Eryu Guan guaneryu@gmail.com Signed-off-by: Theodore Ts'o tytso@mit.edu Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/ext4/inode.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
--- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -3658,7 +3658,6 @@ static ssize_t ext4_direct_IO_write(stru { struct file *file = iocb->ki_filp; struct inode *inode = file->f_mapping->host; - struct ext4_inode_info *ei = EXT4_I(inode); ssize_t ret; loff_t offset = iocb->ki_pos; size_t count = iov_iter_count(iter); @@ -3682,7 +3681,7 @@ static ssize_t ext4_direct_IO_write(stru goto out; } orphan = 1; - ei->i_disksize = inode->i_size; + ext4_update_i_disksize(inode, inode->i_size); ext4_journal_stop(handle); }
@@ -3790,7 +3789,7 @@ static ssize_t ext4_direct_IO_write(stru if (ret > 0) { loff_t end = offset + ret; if (end > inode->i_size) { - ei->i_disksize = end; + ext4_update_i_disksize(inode, end); i_size_write(inode, end); /* * We're going to return a positive `ret'
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiri Slaby jslaby@suse.cz
commit fe23cb65c2c394ea306f3714a17d46ab2e6a0af1 upstream.
ext4_iomap_begin() has a bug where offset returned in the iomap structure will be truncated to unsigned long size. On 64-bit architectures this is fine but on 32-bit architectures obviously not. Not many places actually use the offset stored in the iomap structure but one of visible failures is in SEEK_HOLE / SEEK_DATA implementation. If we create a file like:
dd if=/dev/urandom of=file bs=1k seek=8m count=1
then
lseek64("file", 0x100000000ULL, SEEK_DATA)
wrongly returns 0x100000000 on unfixed kernel while it should return 0x200000000. Avoid the overflow by proper type cast.
Fixes: 545052e9e35a ("ext4: Switch to iomap for SEEK_HOLE / SEEK_DATA") Signed-off-by: Jiri Slaby jslaby@suse.cz Signed-off-by: Jan Kara jack@suse.cz Signed-off-by: Theodore Ts'o tytso@mit.edu Cc: stable@vger.kernel.org # v4.15 Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/ext4/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -3524,7 +3524,7 @@ retry: iomap->flags |= IOMAP_F_DIRTY; iomap->bdev = inode->i_sb->s_bdev; iomap->dax_dev = sbi->s_daxdev; - iomap->offset = first_block << blkbits; + iomap->offset = (u64)first_block << blkbits; iomap->length = (u64)map.m_len << blkbits;
if (ret == 0) {
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o tytso@mit.edu
commit 7dac4a1726a9c64a517d595c40e95e2d0d135f6f upstream.
An privileged attacker can cause a crash by mounting a crafted ext4 image which triggers a out-of-bounds read in the function ext4_valid_block_bitmap() in fs/ext4/balloc.c.
This issue has been assigned CVE-2018-1093.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=199181 BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1560782 Reported-by: Wen Xu wen.xu@gatech.edu Signed-off-by: Theodore Ts'o tytso@mit.edu Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/ext4/balloc.c | 16 ++++++++++++++-- fs/ext4/ialloc.c | 7 +++++++ 2 files changed, 21 insertions(+), 2 deletions(-)
--- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c @@ -338,20 +338,25 @@ static ext4_fsblk_t ext4_valid_block_bit /* check whether block bitmap block number is set */ blk = ext4_block_bitmap(sb, desc); offset = blk - group_first_block; - if (!ext4_test_bit(EXT4_B2C(sbi, offset), bh->b_data)) + if (offset < 0 || EXT4_B2C(sbi, offset) >= sb->s_blocksize || + !ext4_test_bit(EXT4_B2C(sbi, offset), bh->b_data)) /* bad block bitmap */ return blk;
/* check whether the inode bitmap block number is set */ blk = ext4_inode_bitmap(sb, desc); offset = blk - group_first_block; - if (!ext4_test_bit(EXT4_B2C(sbi, offset), bh->b_data)) + if (offset < 0 || EXT4_B2C(sbi, offset) >= sb->s_blocksize || + !ext4_test_bit(EXT4_B2C(sbi, offset), bh->b_data)) /* bad block bitmap */ return blk;
/* check whether the inode table block number is set */ blk = ext4_inode_table(sb, desc); offset = blk - group_first_block; + if (offset < 0 || EXT4_B2C(sbi, offset) >= sb->s_blocksize || + EXT4_B2C(sbi, offset + sbi->s_itb_per_group) >= sb->s_blocksize) + return blk; next_zero_bit = ext4_find_next_zero_bit(bh->b_data, EXT4_B2C(sbi, offset + sbi->s_itb_per_group), EXT4_B2C(sbi, offset)); @@ -417,6 +422,7 @@ struct buffer_head * ext4_read_block_bitmap_nowait(struct super_block *sb, ext4_group_t block_group) { struct ext4_group_desc *desc; + struct ext4_sb_info *sbi = EXT4_SB(sb); struct buffer_head *bh; ext4_fsblk_t bitmap_blk; int err; @@ -425,6 +431,12 @@ ext4_read_block_bitmap_nowait(struct sup if (!desc) return ERR_PTR(-EFSCORRUPTED); bitmap_blk = ext4_block_bitmap(sb, desc); + if ((bitmap_blk <= le32_to_cpu(sbi->s_es->s_first_data_block)) || + (bitmap_blk >= ext4_blocks_count(sbi->s_es))) { + ext4_error(sb, "Invalid block bitmap block %llu in " + "block_group %u", bitmap_blk, block_group); + return ERR_PTR(-EFSCORRUPTED); + } bh = sb_getblk(sb, bitmap_blk); if (unlikely(!bh)) { ext4_error(sb, "Cannot get buffer for block bitmap - " --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -122,6 +122,7 @@ static struct buffer_head * ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group) { struct ext4_group_desc *desc; + struct ext4_sb_info *sbi = EXT4_SB(sb); struct buffer_head *bh = NULL; ext4_fsblk_t bitmap_blk; int err; @@ -131,6 +132,12 @@ ext4_read_inode_bitmap(struct super_bloc return ERR_PTR(-EFSCORRUPTED);
bitmap_blk = ext4_inode_bitmap(sb, desc); + if ((bitmap_blk <= le32_to_cpu(sbi->s_es->s_first_data_block)) || + (bitmap_blk >= ext4_blocks_count(sbi->s_es))) { + ext4_error(sb, "Invalid inode bitmap blk %llu in " + "block_group %u", bitmap_blk, block_group); + return ERR_PTR(-EFSCORRUPTED); + } bh = sb_getblk(sb, bitmap_blk); if (unlikely(!bh)) { ext4_error(sb, "Cannot read inode bitmap - "
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers ebiggers@google.com
commit ce3fd194fcc6fbdc00ce095a852f22df97baa401 upstream.
ext4 isn't validating the sizes of xattrs where the value of the xattr is stored in an external inode. This is problematic because ->e_value_size is a u32, but ext4_xattr_get() returns an int. A very large size is misinterpreted as an error code, which ext4_get_acl() translates into a bogus ERR_PTR() for which IS_ERR() returns false, causing a crash.
Fix this by validating that all xattrs are <= INT_MAX bytes.
This issue has been assigned CVE-2018-1095.
https://bugzilla.kernel.org/show_bug.cgi?id=199185 https://bugzilla.redhat.com/show_bug.cgi?id=1560793
Reported-by: Wen Xu wen.xu@gatech.edu Signed-off-by: Eric Biggers ebiggers@google.com Signed-off-by: Theodore Ts'o tytso@mit.edu Cc: stable@vger.kernel.org Fixes: e50e5129f384 ("ext4: xattr-in-inode support") Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/ext4/xattr.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
--- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -195,10 +195,13 @@ ext4_xattr_check_entries(struct ext4_xat
/* Check the values */ while (!IS_LAST_ENTRY(entry)) { - if (entry->e_value_size != 0 && - entry->e_value_inum == 0) { + u32 size = le32_to_cpu(entry->e_value_size); + + if (size > INT_MAX) + return -EFSCORRUPTED; + + if (size != 0 && entry->e_value_inum == 0) { u16 offs = le16_to_cpu(entry->e_value_offs); - u32 size = le32_to_cpu(entry->e_value_size); void *value;
/*
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o tytso@mit.edu
commit 8e4b5eae5decd9dfe5a4ee369c22028f90ab4c44 upstream.
If the root directory has an i_links_count of zero, then when the file system is mounted, then when ext4_fill_super() notices the problem and tries to call iput() the root directory in the error return path, ext4_evict_inode() will try to free the inode on disk, before all of the file system structures are set up, and this will result in an OOPS caused by a NULL pointer dereference.
This issue has been assigned CVE-2018-1092.
https://bugzilla.kernel.org/show_bug.cgi?id=199179 https://bugzilla.redhat.com/show_bug.cgi?id=1560777
Reported-by: Wen Xu wen.xu@gatech.edu Signed-off-by: Theodore Ts'o tytso@mit.edu Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/ext4/inode.c | 6 ++++++ 1 file changed, 6 insertions(+)
--- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -4745,6 +4745,12 @@ struct inode *ext4_iget(struct super_blo goto bad_inode; raw_inode = ext4_raw_inode(&iloc);
+ if ((ino == EXT4_ROOT_INO) && (raw_inode->i_links_count == 0)) { + EXT4_ERROR_INODE(inode, "root inode unallocated"); + ret = -EFSCORRUPTED; + 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 >
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o tytso@mit.edu
commit a45403b51582a87872927a3e0fc0a389c26867f1 upstream.
The extended attribute code now uses the crc32c checksum for hashing purposes, so we should just always always initialize it. We also want to prevent NULL pointer dereferences if one of the metadata checksum features is enabled after the file sytsem is originally mounted.
This issue has been assigned CVE-2018-1094.
https://bugzilla.kernel.org/show_bug.cgi?id=199183 https://bugzilla.redhat.com/show_bug.cgi?id=1560788
Signed-off-by: Theodore Ts'o tytso@mit.edu Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/ext4/super.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-)
--- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -3490,15 +3490,12 @@ static int ext4_fill_super(struct super_ }
/* Load the checksum driver */ - if (ext4_has_feature_metadata_csum(sb) || - ext4_has_feature_ea_inode(sb)) { - sbi->s_chksum_driver = crypto_alloc_shash("crc32c", 0, 0); - if (IS_ERR(sbi->s_chksum_driver)) { - ext4_msg(sb, KERN_ERR, "Cannot load crc32c driver."); - ret = PTR_ERR(sbi->s_chksum_driver); - sbi->s_chksum_driver = NULL; - goto failed_mount; - } + sbi->s_chksum_driver = crypto_alloc_shash("crc32c", 0, 0); + if (IS_ERR(sbi->s_chksum_driver)) { + ext4_msg(sb, KERN_ERR, "Cannot load crc32c driver."); + ret = PTR_ERR(sbi->s_chksum_driver); + sbi->s_chksum_driver = NULL; + goto failed_mount; }
/* Check superblock checksum */
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o tytso@mit.edu
commit 18db4b4e6fc31eda838dd1c1296d67dbcb3dc957 upstream.
If some metadata block, such as an allocation bitmap, overlaps the superblock, it's very likely that if the file system is mounted read/write, the results will not be pretty. So disallow r/w mounts for file systems corrupted in this particular way.
Signed-off-by: Theodore Ts'o tytso@mit.edu Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/ext4/super.c | 6 ++++++ 1 file changed, 6 insertions(+)
--- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -2333,6 +2333,8 @@ static int ext4_check_descriptors(struct ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " "Block bitmap for group %u overlaps " "superblock", i); + if (!sb_rdonly(sb)) + return 0; } if (block_bitmap < first_block || block_bitmap > last_block) { ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " @@ -2345,6 +2347,8 @@ static int ext4_check_descriptors(struct ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " "Inode bitmap for group %u overlaps " "superblock", i); + if (!sb_rdonly(sb)) + return 0; } if (inode_bitmap < first_block || inode_bitmap > last_block) { ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " @@ -2357,6 +2361,8 @@ static int ext4_check_descriptors(struct ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " "Inode table for group %u overlaps " "superblock", i); + if (!sb_rdonly(sb)) + return 0; } if (inode_table < first_block || inode_table + sbi->s_itb_per_group - 1 > last_block) {
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o tytso@mit.edu
commit de05ca8526796c7e9f7c7282b7f89a818af19818 upstream.
Refactor the call to EXT4_ERROR_INODE() into ext4_xattr_check_block(). This simplifies the code, and fixes a problem where not all callers of ext4_xattr_check_block() were not resulting in ext4_error() getting called when the xattr block is corrupted.
Signed-off-by: Theodore Ts'o tytso@mit.edu Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/ext4/xattr.c | 60 +++++++++++++++++++++++++------------------------------- 1 file changed, 27 insertions(+), 33 deletions(-)
--- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -225,25 +225,36 @@ ext4_xattr_check_entries(struct ext4_xat }
static inline int -ext4_xattr_check_block(struct inode *inode, struct buffer_head *bh) +__ext4_xattr_check_block(struct inode *inode, struct buffer_head *bh, + const char *function, unsigned int line) { - int error; + int error = -EFSCORRUPTED;
if (buffer_verified(bh)) return 0;
if (BHDR(bh)->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC) || BHDR(bh)->h_blocks != cpu_to_le32(1)) - return -EFSCORRUPTED; + goto errout; + error = -EFSBADCRC; if (!ext4_xattr_block_csum_verify(inode, bh)) - return -EFSBADCRC; + goto errout; error = ext4_xattr_check_entries(BFIRST(bh), bh->b_data + bh->b_size, bh->b_data); - if (!error) +errout: + if (error) + __ext4_error_inode(inode, function, line, 0, + "corrupted xattr block %llu", + (unsigned long long) bh->b_blocknr); + else set_buffer_verified(bh); return error; }
+#define ext4_xattr_check_block(inode, bh) \ + __ext4_xattr_check_block((inode), (bh), __func__, __LINE__) + + static int __xattr_check_inode(struct inode *inode, struct ext4_xattr_ibody_header *header, void *end, const char *function, unsigned int line) @@ -514,12 +525,9 @@ ext4_xattr_block_get(struct inode *inode goto cleanup; ea_bdebug(bh, "b_count=%d, refcount=%d", atomic_read(&(bh->b_count)), le32_to_cpu(BHDR(bh)->h_refcount)); - if (ext4_xattr_check_block(inode, bh)) { - EXT4_ERROR_INODE(inode, "bad block %llu", - EXT4_I(inode)->i_file_acl); - error = -EFSCORRUPTED; + error = ext4_xattr_check_block(inode, bh); + if (error) goto cleanup; - } ext4_xattr_block_cache_insert(ea_block_cache, bh); entry = BFIRST(bh); error = ext4_xattr_find_entry(&entry, name_index, name, 1); @@ -679,12 +687,9 @@ ext4_xattr_block_list(struct dentry *den goto cleanup; ea_bdebug(bh, "b_count=%d, refcount=%d", atomic_read(&(bh->b_count)), le32_to_cpu(BHDR(bh)->h_refcount)); - if (ext4_xattr_check_block(inode, bh)) { - EXT4_ERROR_INODE(inode, "bad block %llu", - EXT4_I(inode)->i_file_acl); - error = -EFSCORRUPTED; + 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);
@@ -811,10 +816,9 @@ int ext4_get_inode_usage(struct inode *i goto out; }
- if (ext4_xattr_check_block(inode, bh)) { - ret = -EFSCORRUPTED; + ret = ext4_xattr_check_block(inode, bh); + if (ret) goto out; - }
for (entry = BFIRST(bh); !IS_LAST_ENTRY(entry); entry = EXT4_XATTR_NEXT(entry)) @@ -1796,12 +1800,9 @@ ext4_xattr_block_find(struct inode *inod ea_bdebug(bs->bh, "b_count=%d, refcount=%d", atomic_read(&(bs->bh->b_count)), le32_to_cpu(BHDR(bs->bh)->h_refcount)); - if (ext4_xattr_check_block(inode, bs->bh)) { - EXT4_ERROR_INODE(inode, "bad block %llu", - EXT4_I(inode)->i_file_acl); - error = -EFSCORRUPTED; + error = ext4_xattr_check_block(inode, bs->bh); + if (error) goto cleanup; - } /* Find the named attribute. */ bs->s.base = BHDR(bs->bh); bs->s.first = BFIRST(bs->bh); @@ -2724,13 +2725,9 @@ retry: error = -EIO; if (!bh) goto cleanup; - if (ext4_xattr_check_block(inode, bh)) { - EXT4_ERROR_INODE(inode, "bad block %llu", - EXT4_I(inode)->i_file_acl); - error = -EFSCORRUPTED; - brelse(bh); + error = ext4_xattr_check_block(inode, bh); + if (error) goto cleanup; - } base = BHDR(bh); end = bh->b_data + bh->b_size; min_offs = end - base; @@ -2887,11 +2884,8 @@ int ext4_xattr_delete_inode(handle_t *ha goto cleanup; } error = ext4_xattr_check_block(inode, bh); - if (error) { - EXT4_ERROR_INODE(inode, "bad block %llu (error %d)", - EXT4_I(inode)->i_file_acl, error); + if (error) goto cleanup; - }
if (ext4_has_feature_ea_inode(inode->i_sb)) { for (entry = BFIRST(bh); !IS_LAST_ENTRY(entry);
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o tytso@mit.edu
commit 9496005d6ca4cf8f5ee8f828165a8956872dc59d upstream.
Add some paranoia checks to make sure we don't stray beyond the end of the valid memory region containing ext4 xattr entries while we are scanning for a match.
Also rename the function to xattr_find_entry() since it is static and thus only used in fs/ext4/xattr.c
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 | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-)
--- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -276,18 +276,22 @@ errout: __xattr_check_inode((inode), (header), (end), __func__, __LINE__)
static int -ext4_xattr_find_entry(struct ext4_xattr_entry **pentry, int name_index, - const char *name, int sorted) +xattr_find_entry(struct inode *inode, struct ext4_xattr_entry **pentry, + void *end, int name_index, const char *name, int sorted) { - struct ext4_xattr_entry *entry; + struct ext4_xattr_entry *entry, *next; size_t name_len; int cmp = 1;
if (name == NULL) return -EINVAL; name_len = strlen(name); - entry = *pentry; - for (; !IS_LAST_ENTRY(entry); entry = EXT4_XATTR_NEXT(entry)) { + for (entry = *pentry; !IS_LAST_ENTRY(entry); entry = next) { + next = EXT4_XATTR_NEXT(entry); + if ((void *) next >= end) { + EXT4_ERROR_INODE(inode, "corrupted xattr entries"); + return -EFSCORRUPTED; + } cmp = name_index - entry->e_name_index; if (!cmp) cmp = name_len - entry->e_name_len; @@ -509,6 +513,7 @@ ext4_xattr_block_get(struct inode *inode struct buffer_head *bh = NULL; struct ext4_xattr_entry *entry; size_t size; + void *end; int error; struct mb_cache *ea_block_cache = EA_BLOCK_CACHE(inode);
@@ -530,7 +535,8 @@ ext4_xattr_block_get(struct inode *inode goto cleanup; ext4_xattr_block_cache_insert(ea_block_cache, bh); entry = BFIRST(bh); - error = ext4_xattr_find_entry(&entry, name_index, name, 1); + end = bh->b_data + bh->b_size; + error = xattr_find_entry(inode, &entry, end, name_index, name, 1); if (error) goto cleanup; size = le32_to_cpu(entry->e_value_size); @@ -579,7 +585,7 @@ ext4_xattr_ibody_get(struct inode *inode if (error) goto cleanup; entry = IFIRST(header); - error = ext4_xattr_find_entry(&entry, name_index, name, 0); + error = xattr_find_entry(inode, &entry, end, name_index, name, 0); if (error) goto cleanup; size = le32_to_cpu(entry->e_value_size); @@ -1808,8 +1814,8 @@ ext4_xattr_block_find(struct inode *inod bs->s.first = BFIRST(bs->bh); bs->s.end = bs->bh->b_data + bs->bh->b_size; bs->s.here = bs->s.first; - error = ext4_xattr_find_entry(&bs->s.here, i->name_index, - i->name, 1); + error = xattr_find_entry(inode, &bs->s.here, bs->s.end, + i->name_index, i->name, 1); if (error && error != -ENODATA) goto cleanup; bs->s.not_found = error; @@ -2168,8 +2174,8 @@ int ext4_xattr_ibody_find(struct inode * if (error) return error; /* Find the named attribute. */ - error = ext4_xattr_find_entry(&is->s.here, i->name_index, - i->name, 0); + error = xattr_find_entry(inode, &is->s.here, is->s.end, + i->name_index, i->name, 0); if (error && error != -ENODATA) return error; is->s.not_found = error;
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o tytso@mit.edu
commit 54dd0e0a1b255f115f8647fc6fb93273251b01b9 upstream.
Add explicit checks in ext4_xattr_block_get() just in case the e_value_offs and e_value_size fields in the the xattr block are corrupted in memory after the buffer_verified bit is set on the xattr block.
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 | 26 +++++++++++++++++++------- fs/ext4/xattr.h | 11 +++++++++++ 2 files changed, 30 insertions(+), 7 deletions(-)
--- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -197,7 +197,7 @@ ext4_xattr_check_entries(struct ext4_xat while (!IS_LAST_ENTRY(entry)) { u32 size = le32_to_cpu(entry->e_value_size);
- if (size > INT_MAX) + if (size > EXT4_XATTR_SIZE_MAX) return -EFSCORRUPTED;
if (size != 0 && entry->e_value_inum == 0) { @@ -540,8 +540,10 @@ ext4_xattr_block_get(struct inode *inode if (error) goto cleanup; size = le32_to_cpu(entry->e_value_size); + error = -ERANGE; + if (unlikely(size > EXT4_XATTR_SIZE_MAX)) + goto cleanup; if (buffer) { - error = -ERANGE; if (size > buffer_size) goto cleanup; if (entry->e_value_inum) { @@ -550,8 +552,12 @@ ext4_xattr_block_get(struct inode *inode if (error) goto cleanup; } else { - memcpy(buffer, bh->b_data + - le16_to_cpu(entry->e_value_offs), size); + u16 offset = le16_to_cpu(entry->e_value_offs); + void *p = bh->b_data + offset; + + if (unlikely(p + size > end)) + goto cleanup; + memcpy(buffer, p, size); } } error = size; @@ -589,8 +595,10 @@ ext4_xattr_ibody_get(struct inode *inode if (error) goto cleanup; size = le32_to_cpu(entry->e_value_size); + error = -ERANGE; + if (unlikely(size > EXT4_XATTR_SIZE_MAX)) + goto cleanup; if (buffer) { - error = -ERANGE; if (size > buffer_size) goto cleanup; if (entry->e_value_inum) { @@ -599,8 +607,12 @@ ext4_xattr_ibody_get(struct inode *inode if (error) goto cleanup; } else { - memcpy(buffer, (void *)IFIRST(header) + - le16_to_cpu(entry->e_value_offs), size); + u16 offset = le16_to_cpu(entry->e_value_offs); + void *p = (void *)IFIRST(header) + offset; + + if (unlikely(p + size > end)) + goto cleanup; + memcpy(buffer, p, size); } } error = size; --- a/fs/ext4/xattr.h +++ b/fs/ext4/xattr.h @@ -71,6 +71,17 @@ struct ext4_xattr_entry { #define IFIRST(hdr) ((struct ext4_xattr_entry *)((hdr)+1))
/* + * XATTR_SIZE_MAX is currently 64k, but for the purposes of checking + * for file system consistency errors, we use a somewhat bigger value. + * This allows XATTR_SIZE_MAX to grow in the future, but by using this + * instead of INT_MAX for certain consistency checks, we don't need to + * worry about arithmetic overflows. (Actually XATTR_SIZE_MAX is + * defined in include/uapi/linux/limits.h, so changing it is going + * not going to be trivial....) + */ +#define EXT4_XATTR_SIZE_MAX (1 << 24) + +/* * The minimum size of EA value when you start storing it in an external inode * size of block - size of header - size of 1 entry - 4 null bytes */
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o tytso@mit.edu
commit e40ff213898502d299351cc2fe1e350cd186f0d3 upstream.
A malicious user could force the directory pointer to be in an invalid spot by using seekdir(2). Use the mechanism we already have to notice if the directory has changed since the last time we called ext4_readdir() to force a revalidation of the pointer.
Reported-by: syzbot+1236ce66f79263e8a862@syzkaller.appspotmail.com Signed-off-by: Theodore Ts'o tytso@mit.edu Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/ext4/dir.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
--- a/fs/ext4/dir.c +++ b/fs/ext4/dir.c @@ -365,13 +365,15 @@ static loff_t ext4_dir_llseek(struct fil { struct inode *inode = file->f_mapping->host; int dx_dir = is_dx_dir(inode); - loff_t htree_max = ext4_get_htree_eof(file); + loff_t ret, htree_max = ext4_get_htree_eof(file);
if (likely(dx_dir)) - return generic_file_llseek_size(file, offset, whence, + ret = generic_file_llseek_size(file, offset, whence, htree_max, htree_max); else - return ext4_llseek(file, offset, whence); + ret = ext4_llseek(file, offset, whence); + file->f_version = inode_peek_iversion(inode) - 1; + return ret; }
/*
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mike Snitzer snitzer@redhat.com
commit 0519c71e8d461ac3ef9a555bb7339243c9128d37 upstream.
Otherwise, these abnormal IOs would be sent to the DM target regardless of whether the target advertised support for them.
Factor out __process_abnormal_io() from __split_and_process_non_flush() so that discards, write same, etc may be conditionally processed.
Fixes: 978e51ba3 ("dm: optimize bio-based NVMe IO submission") Cc: stable@vger.kernel.org # 4.16 Signed-off-by: Mike Snitzer snitzer@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/md/dm.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-)
--- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -1477,6 +1477,23 @@ static int __send_write_zeroes(struct cl return __send_changing_extent_only(ci, ti, get_num_write_zeroes_bios, NULL); }
+static bool __process_abnormal_io(struct clone_info *ci, struct dm_target *ti, + int *result) +{ + struct bio *bio = ci->bio; + + if (bio_op(bio) == REQ_OP_DISCARD) + *result = __send_discard(ci, ti); + else if (bio_op(bio) == REQ_OP_WRITE_SAME) + *result = __send_write_same(ci, ti); + else if (bio_op(bio) == REQ_OP_WRITE_ZEROES) + *result = __send_write_zeroes(ci, ti); + else + return false; + + return true; +} + /* * Select the correct strategy for processing a non-flush bio. */ @@ -1491,12 +1508,8 @@ static int __split_and_process_non_flush if (!dm_target_is_valid(ti)) return -EIO;
- if (unlikely(bio_op(bio) == REQ_OP_DISCARD)) - return __send_discard(ci, ti); - else if (unlikely(bio_op(bio) == REQ_OP_WRITE_SAME)) - return __send_write_same(ci, ti); - else if (unlikely(bio_op(bio) == REQ_OP_WRITE_ZEROES)) - return __send_write_zeroes(ci, ti); + if (unlikely(__process_abnormal_io(ci, ti, &r))) + return r;
if (bio_op(bio) == REQ_OP_ZONE_REPORT) len = ci->sector_count; @@ -1617,9 +1630,12 @@ static blk_qc_t __process_bio(struct map goto out; }
- tio = alloc_tio(&ci, ti, 0, GFP_NOIO); ci.bio = bio; ci.sector_count = bio_sectors(bio); + if (unlikely(__process_abnormal_io(&ci, ti, &error))) + goto out; + + tio = alloc_tio(&ci, ti, 0, GFP_NOIO); ret = __clone_and_map_simple_bio(&ci, tio, NULL); } out:
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikulas Patocka mpatocka@redhat.com
commit 5059353df86e2573ccd9d43fd9d9396dcec47ca2 upstream.
dm-crypt consumes an excessive amount memory when the user attempts to zero a dm-crypt device with "blkdiscard -z". The command "blkdiscard -z" calls the BLKZEROOUT ioctl, it goes to the function __blkdev_issue_zeroout, __blkdev_issue_zeroout sends a large amount of write bios that contain the zero page as their payload.
For each incoming page, dm-crypt allocates another page that holds the encrypted data, so when processing "blkdiscard -z", dm-crypt tries to allocate the amount of memory that is equal to the size of the device. This can trigger OOM killer or cause system crash.
Fix this by limiting the amount of memory that dm-crypt allocates to 2% of total system memory. This limit is system-wide and is divided by the number of active dm-crypt devices and each device receives an equal share.
Cc: stable@vger.kernel.org Signed-off-by: Mikulas Patocka mpatocka@redhat.com Signed-off-by: Mike Snitzer snitzer@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/md/dm-crypt.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-)
--- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -148,6 +148,8 @@ struct crypt_config { mempool_t *tag_pool; unsigned tag_pool_max_sectors;
+ struct percpu_counter n_allocated_pages; + struct bio_set *bs; struct mutex bio_alloc_lock;
@@ -219,6 +221,12 @@ struct crypt_config { #define MAX_TAG_SIZE 480 #define POOL_ENTRY_SIZE 512
+static DEFINE_SPINLOCK(dm_crypt_clients_lock); +static unsigned dm_crypt_clients_n = 0; +static volatile unsigned long dm_crypt_pages_per_client; +#define DM_CRYPT_MEMORY_PERCENT 2 +#define DM_CRYPT_MIN_PAGES_PER_CLIENT (BIO_MAX_PAGES * 16) + static void clone_init(struct dm_crypt_io *, struct bio *); static void kcryptd_queue_crypt(struct dm_crypt_io *io); static struct scatterlist *crypt_get_sg_data(struct crypt_config *cc, @@ -2155,6 +2163,43 @@ static int crypt_wipe_key(struct crypt_c return r; }
+static void crypt_calculate_pages_per_client(void) +{ + unsigned long pages = (totalram_pages - totalhigh_pages) * DM_CRYPT_MEMORY_PERCENT / 100; + + if (!dm_crypt_clients_n) + return; + + pages /= dm_crypt_clients_n; + if (pages < DM_CRYPT_MIN_PAGES_PER_CLIENT) + pages = DM_CRYPT_MIN_PAGES_PER_CLIENT; + dm_crypt_pages_per_client = pages; +} + +static void *crypt_page_alloc(gfp_t gfp_mask, void *pool_data) +{ + struct crypt_config *cc = pool_data; + struct page *page; + + if (unlikely(percpu_counter_compare(&cc->n_allocated_pages, dm_crypt_pages_per_client) >= 0) && + likely(gfp_mask & __GFP_NORETRY)) + return NULL; + + page = alloc_page(gfp_mask); + if (likely(page != NULL)) + percpu_counter_add(&cc->n_allocated_pages, 1); + + return page; +} + +static void crypt_page_free(void *page, void *pool_data) +{ + struct crypt_config *cc = pool_data; + + __free_page(page); + percpu_counter_sub(&cc->n_allocated_pages, 1); +} + static void crypt_dtr(struct dm_target *ti) { struct crypt_config *cc = ti->private; @@ -2181,6 +2226,10 @@ static void crypt_dtr(struct dm_target * mempool_destroy(cc->req_pool); mempool_destroy(cc->tag_pool);
+ if (cc->page_pool) + WARN_ON(percpu_counter_sum(&cc->n_allocated_pages) != 0); + percpu_counter_destroy(&cc->n_allocated_pages); + if (cc->iv_gen_ops && cc->iv_gen_ops->dtr) cc->iv_gen_ops->dtr(cc);
@@ -2197,6 +2246,12 @@ static void crypt_dtr(struct dm_target *
/* Must zero key material before freeing */ kzfree(cc); + + spin_lock(&dm_crypt_clients_lock); + WARN_ON(!dm_crypt_clients_n); + dm_crypt_clients_n--; + crypt_calculate_pages_per_client(); + spin_unlock(&dm_crypt_clients_lock); }
static int crypt_ctr_ivmode(struct dm_target *ti, const char *ivmode) @@ -2644,6 +2699,15 @@ static int crypt_ctr(struct dm_target *t
ti->private = cc;
+ spin_lock(&dm_crypt_clients_lock); + dm_crypt_clients_n++; + crypt_calculate_pages_per_client(); + spin_unlock(&dm_crypt_clients_lock); + + ret = percpu_counter_init(&cc->n_allocated_pages, 0, GFP_KERNEL); + if (ret < 0) + goto bad; + /* Optional parameters need to be read before cipher constructor */ if (argc > 5) { ret = crypt_ctr_optional(ti, argc - 5, &argv[5]); @@ -2698,7 +2762,7 @@ static int crypt_ctr(struct dm_target *t ALIGN(sizeof(struct dm_crypt_io) + cc->dmreq_start + additional_req_size, ARCH_KMALLOC_MINALIGN);
- cc->page_pool = mempool_create_page_pool(BIO_MAX_PAGES, 0); + cc->page_pool = mempool_create(BIO_MAX_PAGES, crypt_page_alloc, crypt_page_free, cc); if (!cc->page_pool) { ti->error = "Cannot allocate page mempool"; goto bad;
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Roland Dreier roland@purestorage.com
commit 8435168d50e66fa5eae01852769d20a36f9e5e83 upstream.
Check to make sure that ctx->cm_id->device is set before we use it. Otherwise userspace can trigger a NULL dereference by doing RDMA_USER_CM_CMD_SET_OPTION on an ID that is not bound to a device.
Cc: stable@vger.kernel.org Reported-by: syzbot+a67bc93e14682d92fc2f@syzkaller.appspotmail.com Signed-off-by: Roland Dreier roland@purestorage.com Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/infiniband/core/ucma.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/drivers/infiniband/core/ucma.c +++ b/drivers/infiniband/core/ucma.c @@ -1241,6 +1241,9 @@ static int ucma_set_ib_path(struct ucma_ if (!optlen) return -EINVAL;
+ if (!ctx->cm_id->device) + return -EINVAL; + memset(&sa_path, 0, sizeof(sa_path));
sa_path.rec_type = SA_PATH_REC_TYPE_IB;
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Leon Romanovsky leonro@mellanox.com
commit 4289861d88d6c7b5e4c8cc7fe2ad6cdf0cdfc366 upstream.
The mlx5_ib_alloc_implicit_mr() can fail to acquire pages and the returned mr pointer won't be valid. Ensure that it is not error prior to access.
Cc: stable@vger.kernel.org # 4.10 Fixes: 81713d3788d2 ("IB/mlx5: Add implicit MR support") Reported-by: Noa Osherovich noaos@mellanox.com Signed-off-by: Leon Romanovsky leonro@mellanox.com Signed-off-by: Doug Ledford dledford@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/infiniband/hw/mlx5/mr.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/infiniband/hw/mlx5/mr.c +++ b/drivers/infiniband/hw/mlx5/mr.c @@ -1223,6 +1223,8 @@ struct ib_mr *mlx5_ib_reg_user_mr(struct return ERR_PTR(-EINVAL);
mr = mlx5_ib_alloc_implicit_mr(to_mpd(pd), access_flags); + if (IS_ERR(mr)) + return ERR_CAST(mr); return &mr->ibmr; } #endif
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche bart.vanassche@wdc.com
commit a6544a624c3ff92a64e4aca3931fa064607bd3da upstream.
This patch avoids that KASAN reports the following when the SRP initiator calls srp_post_send():
================================================================== BUG: KASAN: stack-out-of-bounds in rxe_post_send+0x5c4/0x980 [rdma_rxe] Read of size 8 at addr ffff880066606e30 by task 02-mq/1074
CPU: 2 PID: 1074 Comm: 02-mq Not tainted 4.16.0-rc3-dbg+ #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.0.0-prebuilt.qemu-project.org 04/01/2014 Call Trace: dump_stack+0x85/0xc7 print_address_description+0x65/0x270 kasan_report+0x231/0x350 rxe_post_send+0x5c4/0x980 [rdma_rxe] srp_post_send.isra.16+0x149/0x190 [ib_srp] srp_queuecommand+0x94d/0x1670 [ib_srp] scsi_dispatch_cmd+0x1c2/0x550 [scsi_mod] scsi_queue_rq+0x843/0xa70 [scsi_mod] blk_mq_dispatch_rq_list+0x143/0xac0 blk_mq_do_dispatch_ctx+0x1c5/0x260 blk_mq_sched_dispatch_requests+0x2bf/0x2f0 __blk_mq_run_hw_queue+0xdb/0x160 __blk_mq_delay_run_hw_queue+0xba/0x100 blk_mq_run_hw_queue+0xf2/0x190 blk_mq_sched_insert_request+0x163/0x2f0 blk_execute_rq+0xb0/0x130 scsi_execute+0x14e/0x260 [scsi_mod] scsi_probe_and_add_lun+0x366/0x13d0 [scsi_mod] __scsi_scan_target+0x18a/0x810 [scsi_mod] scsi_scan_target+0x11e/0x130 [scsi_mod] srp_create_target+0x1522/0x19e0 [ib_srp] kernfs_fop_write+0x180/0x210 __vfs_write+0xb1/0x2e0 vfs_write+0xf6/0x250 SyS_write+0x99/0x110 do_syscall_64+0xee/0x2b0 entry_SYSCALL_64_after_hwframe+0x42/0xb7
The buggy address belongs to the page: page:ffffea0001998180 count:0 mapcount:0 mapping:0000000000000000 index:0x0 flags: 0x4000000000000000() raw: 4000000000000000 0000000000000000 0000000000000000 00000000ffffffff raw: dead000000000100 dead000000000200 0000000000000000 0000000000000000 page dumped because: kasan: bad access detected
Memory state around the buggy address: ffff880066606d00: 00 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 ffff880066606d80: f1 00 f2 f2 f2 f2 f2 f2 f2 00 00 f2 f2 f2 f2 f2
ffff880066606e00: f2 00 00 00 00 00 f2 f2 f2 f3 f3 f3 f3 00 00 00
^ ffff880066606e80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ffff880066606f00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ==================================================================
Fixes: 8700e3e7c485 ("Soft RoCE driver") Signed-off-by: Bart Van Assche bart.vanassche@wdc.com Cc: Moni Shoua monis@mellanox.com Cc: stable@vger.kernel.org Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/infiniband/sw/rxe/rxe_verbs.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
--- a/drivers/infiniband/sw/rxe/rxe_verbs.c +++ b/drivers/infiniband/sw/rxe/rxe_verbs.c @@ -711,9 +711,8 @@ static int init_send_wqe(struct rxe_qp * memcpy(wqe->dma.sge, ibwr->sg_list, num_sge * sizeof(struct ib_sge));
- wqe->iova = (mask & WR_ATOMIC_MASK) ? - atomic_wr(ibwr)->remote_addr : - rdma_wr(ibwr)->remote_addr; + wqe->iova = mask & WR_ATOMIC_MASK ? atomic_wr(ibwr)->remote_addr : + mask & WR_READ_OR_WRITE_MASK ? rdma_wr(ibwr)->remote_addr : 0; wqe->mask = mask; wqe->dma.length = length; wqe->dma.resid = length;
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche bart.vanassche@wdc.com
commit a1ae7d0345edd593d6725d3218434d903a0af95d upstream.
This patch fixes the following KASAN complaint:
================================================================== BUG: KASAN: stack-out-of-bounds in rxe_post_send+0x77d/0x9b0 [rdma_rxe] Read of size 8 at addr ffff880061aef860 by task 01/1080
CPU: 2 PID: 1080 Comm: 01 Not tainted 4.16.0-rc3-dbg+ #2 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.0.0-prebuilt.qemu-project.org 04/01/2014 Call Trace: dump_stack+0x85/0xc7 print_address_description+0x65/0x270 kasan_report+0x231/0x350 rxe_post_send+0x77d/0x9b0 [rdma_rxe] __ib_drain_sq+0x1ad/0x250 [ib_core] ib_drain_qp+0x9/0x30 [ib_core] srp_destroy_qp+0x51/0x70 [ib_srp] srp_free_ch_ib+0xfc/0x380 [ib_srp] srp_create_target+0x1071/0x19e0 [ib_srp] kernfs_fop_write+0x180/0x210 __vfs_write+0xb1/0x2e0 vfs_write+0xf6/0x250 SyS_write+0x99/0x110 do_syscall_64+0xee/0x2b0 entry_SYSCALL_64_after_hwframe+0x42/0xb7
The buggy address belongs to the page: page:ffffea000186bbc0 count:0 mapcount:0 mapping:0000000000000000 index:0x0 flags: 0x4000000000000000() raw: 4000000000000000 0000000000000000 0000000000000000 00000000ffffffff raw: 0000000000000000 ffffea000186bbe0 0000000000000000 0000000000000000 page dumped because: kasan: bad access detected
Memory state around the buggy address: ffff880061aef700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ffff880061aef780: 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00
ffff880061aef800: f2 f2 f2 f2 f2 f2 f2 00 00 00 00 00 f2 f2 f2 f2
^ ffff880061aef880: f2 f2 f2 00 00 00 00 00 00 00 00 00 00 00 f2 f2 ffff880061aef900: f2 f2 f2 00 00 00 00 00 00 00 00 00 00 00 00 00 ==================================================================
Fixes: 765d67748bcf ("IB: new common API for draining queues") Signed-off-by: Bart Van Assche bart.vanassche@wdc.com Cc: Steve Wise swise@opengridcomputing.com Cc: Sagi Grimberg sagi@grimberg.me Cc: stable@vger.kernel.org Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/infiniband/core/verbs.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
--- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c @@ -2194,7 +2194,13 @@ static void __ib_drain_sq(struct ib_qp * struct ib_cq *cq = qp->send_cq; struct ib_qp_attr attr = { .qp_state = IB_QPS_ERR }; struct ib_drain_cqe sdrain; - struct ib_send_wr swr = {}, *bad_swr; + struct ib_send_wr *bad_swr; + struct ib_rdma_wr swr = { + .wr = { + .opcode = IB_WR_RDMA_WRITE, + .wr_cqe = &sdrain.cqe, + }, + }; int ret;
ret = ib_modify_qp(qp, &attr, IB_QP_STATE); @@ -2203,11 +2209,10 @@ static void __ib_drain_sq(struct ib_qp * return; }
- swr.wr_cqe = &sdrain.cqe; sdrain.cqe.done = ib_drain_qp_done; init_completion(&sdrain.done);
- ret = ib_post_send(qp, &swr, &bad_swr); + ret = ib_post_send(qp, &swr.wr, &bad_swr); if (ret) { WARN_ONCE(ret, "failed to drain send queue: %d\n", ret); return;
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever chuck.lever@oracle.com
commit 6720a89933739cb8dec748cd253f7c8df2c0ae4d upstream.
With v4.15, on one of my NFS/RDMA clients I measured a nearly doubling in the latency of small read and write system calls. There was no change in server round trip time. The extra latency appears in the whole RPC execution path.
"git bisect" settled on commit ccede7598588 ("xprtrdma: Spread reply processing over more CPUs") .
After some experimentation, I found that leaving the WQ bound and allowing the scheduler to pick the dispatch CPU seems to eliminate the long latencies, and it does not introduce any new regressions.
The fix is implemented by reverting only the part of commit ccede7598588 ("xprtrdma: Spread reply processing over more CPUs") that dispatches RPC replies specifically on the CPU where the matching RPC call was made.
Interestingly, saving the CPU number and later queuing reply processing there was effective _only_ for a NFS READ and WRITE request. On my NUMA client, in-kernel RPC reply processing for asynchronous RPCs was dispatched on the same CPU where the RPC call was made, as expected. However synchronous RPCs seem to get their reply dispatched on some other CPU than where the call was placed, every time.
Fixes: ccede7598588 ("xprtrdma: Spread reply processing over ... ") Signed-off-by: Chuck Lever chuck.lever@oracle.com Cc: stable@vger.kernel.org # v4.15+ Signed-off-by: Anna Schumaker Anna.Schumaker@Netapp.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- net/sunrpc/xprtrdma/rpc_rdma.c | 2 +- net/sunrpc/xprtrdma/transport.c | 2 -- net/sunrpc/xprtrdma/xprt_rdma.h | 1 - 3 files changed, 1 insertion(+), 4 deletions(-)
--- a/net/sunrpc/xprtrdma/rpc_rdma.c +++ b/net/sunrpc/xprtrdma/rpc_rdma.c @@ -1366,7 +1366,7 @@ void rpcrdma_reply_handler(struct rpcrdm
trace_xprtrdma_reply(rqst->rq_task, rep, req, credits);
- queue_work_on(req->rl_cpu, rpcrdma_receive_wq, &rep->rr_work); + queue_work(rpcrdma_receive_wq, &rep->rr_work); return;
out_badstatus: --- a/net/sunrpc/xprtrdma/transport.c +++ b/net/sunrpc/xprtrdma/transport.c @@ -52,7 +52,6 @@ #include <linux/slab.h> #include <linux/seq_file.h> #include <linux/sunrpc/addr.h> -#include <linux/smp.h>
#include "xprt_rdma.h"
@@ -651,7 +650,6 @@ xprt_rdma_allocate(struct rpc_task *task if (!rpcrdma_get_recvbuf(r_xprt, req, rqst->rq_rcvsize, flags)) goto out_fail;
- req->rl_cpu = smp_processor_id(); req->rl_connect_cookie = 0; /* our reserved value */ rpcrdma_set_xprtdata(rqst, req); rqst->rq_buffer = req->rl_sendbuf->rg_base; --- a/net/sunrpc/xprtrdma/xprt_rdma.h +++ b/net/sunrpc/xprtrdma/xprt_rdma.h @@ -334,7 +334,6 @@ enum { struct rpcrdma_buffer; struct rpcrdma_req { struct list_head rl_list; - int rl_cpu; unsigned int rl_connect_cookie; struct rpcrdma_buffer *rl_buffer; struct rpcrdma_rep *rl_reply;
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever chuck.lever@oracle.com
commit 25524288631fc5b7d33259fca1e0dc38146be5d6 upstream.
Michal Kalderon has found some corner cases around device unload with active NFS mounts that I didn't have the imagination to test when xprtrdma device removal was added last year.
- The ULP device removal handler is responsible for deallocating the PD. That wasn't clear to me initially, and my own testing suggested it was not necessary, but that is incorrect.
- The transport destruction path can no longer assume that there is a valid ID.
- When destroying a transport, ensure that ib_free_cq() is not invoked on a CQ that was already released.
Reported-by: Michal Kalderon Michal.Kalderon@cavium.com Fixes: bebd031866ca ("xprtrdma: Support unplugging an HCA from ...") Signed-off-by: Chuck Lever chuck.lever@oracle.com Cc: stable@vger.kernel.org # v4.12+ Signed-off-by: Anna Schumaker Anna.Schumaker@Netapp.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- net/sunrpc/xprtrdma/verbs.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
--- a/net/sunrpc/xprtrdma/verbs.c +++ b/net/sunrpc/xprtrdma/verbs.c @@ -250,7 +250,6 @@ rpcrdma_conn_upcall(struct rdma_cm_id *i wait_for_completion(&ia->ri_remove_done);
ia->ri_id = NULL; - ia->ri_pd = NULL; ia->ri_device = NULL; /* Return 1 to ensure the core destroys the id. */ return 1; @@ -445,7 +444,9 @@ rpcrdma_ia_remove(struct rpcrdma_ia *ia) ia->ri_id->qp = NULL; } ib_free_cq(ep->rep_attr.recv_cq); + ep->rep_attr.recv_cq = NULL; ib_free_cq(ep->rep_attr.send_cq); + ep->rep_attr.send_cq = NULL;
/* The ULP is responsible for ensuring all DMA * mappings and MRs are gone. @@ -458,6 +459,8 @@ rpcrdma_ia_remove(struct rpcrdma_ia *ia) rpcrdma_dma_unmap_regbuf(req->rl_recvbuf); } rpcrdma_mrs_destroy(buf); + ib_dealloc_pd(ia->ri_pd); + ia->ri_pd = NULL;
/* Allow waiters to continue */ complete(&ia->ri_remove_done); @@ -628,14 +631,16 @@ rpcrdma_ep_destroy(struct rpcrdma_ep *ep { cancel_delayed_work_sync(&ep->rep_connect_worker);
- if (ia->ri_id->qp) { + if (ia->ri_id && ia->ri_id->qp) { rpcrdma_ep_disconnect(ep, ia); rdma_destroy_qp(ia->ri_id); ia->ri_id->qp = NULL; }
- ib_free_cq(ep->rep_attr.recv_cq); - ib_free_cq(ep->rep_attr.send_cq); + if (ep->rep_attr.recv_cq) + ib_free_cq(ep->rep_attr.recv_cq); + if (ep->rep_attr.send_cq) + ib_free_cq(ep->rep_attr.send_cq); }
/* Re-establish a connection after a device removal event.
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai tiwai@suse.de
commit 02a5d6925cd34c3b774bdb8eefb057c40a30e870 upstream.
Although we apply the params_lock mutex to the whole read and write operations as well as snd_pcm_oss_change_params(), we may still face some races.
First off, the params_lock is taken inside the read and write loop. This is intentional for avoiding the too long locking, but it allows the in-between parameter change, which might lead to invalid pointers. We check the readiness of the stream and set up via snd_pcm_oss_make_ready() at the beginning of read and write, but it's called only once, by assuming that it remains ready in the rest.
Second, many ioctls that may change the actual parameters (i.e. setting runtime->oss.params=1) aren't protected, hence they can be processed in a half-baked state.
This patch is an attempt to plug these holes. The stream readiness check is moved inside the read/write inner loop, so that the stream is always set up in a proper state before further processing. Also, each ioctl that may change the parameter is wrapped with the params_lock for avoiding the races.
The issues were triggered by syzkaller in a few different scenarios, particularly the one below appearing as GPF in loopback_pos_update.
Reported-by: syzbot+c4227aec125487ec3efa@syzkaller.appspotmail.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/oss/pcm_oss.c | 134 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 106 insertions(+), 28 deletions(-)
--- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c @@ -823,8 +823,8 @@ static int choose_rate(struct snd_pcm_su return snd_pcm_hw_param_near(substream, params, SNDRV_PCM_HW_PARAM_RATE, best_rate, NULL); }
-static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream, - bool trylock) +/* call with params_lock held */ +static int snd_pcm_oss_change_params_locked(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_hw_params *params, *sparams; @@ -838,11 +838,8 @@ static int snd_pcm_oss_change_params(str const struct snd_mask *sformat_mask; struct snd_mask mask;
- if (trylock) { - if (!(mutex_trylock(&runtime->oss.params_lock))) - return -EAGAIN; - } else if (mutex_lock_interruptible(&runtime->oss.params_lock)) - return -ERESTARTSYS; + if (!runtime->oss.params) + return 0; sw_params = kzalloc(sizeof(*sw_params), GFP_KERNEL); params = kmalloc(sizeof(*params), GFP_KERNEL); sparams = kmalloc(sizeof(*sparams), GFP_KERNEL); @@ -1068,6 +1065,23 @@ failure: kfree(sw_params); kfree(params); kfree(sparams); + return err; +} + +/* this one takes the lock by itself */ +static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream, + bool trylock) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + int err; + + if (trylock) { + if (!(mutex_trylock(&runtime->oss.params_lock))) + return -EAGAIN; + } else if (mutex_lock_interruptible(&runtime->oss.params_lock)) + return -ERESTARTSYS; + + err = snd_pcm_oss_change_params_locked(substream); mutex_unlock(&runtime->oss.params_lock); return err; } @@ -1096,11 +1110,14 @@ static int snd_pcm_oss_get_active_substr return 0; }
+/* call with params_lock held */ static int snd_pcm_oss_prepare(struct snd_pcm_substream *substream) { int err; struct snd_pcm_runtime *runtime = substream->runtime;
+ if (!runtime->oss.prepare) + return 0; err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_PREPARE, NULL); if (err < 0) { pcm_dbg(substream->pcm, @@ -1120,8 +1137,6 @@ static int snd_pcm_oss_make_ready(struct struct snd_pcm_runtime *runtime; int err;
- if (substream == NULL) - return 0; runtime = substream->runtime; if (runtime->oss.params) { err = snd_pcm_oss_change_params(substream, false); @@ -1129,6 +1144,29 @@ static int snd_pcm_oss_make_ready(struct return err; } if (runtime->oss.prepare) { + if (mutex_lock_interruptible(&runtime->oss.params_lock)) + return -ERESTARTSYS; + err = snd_pcm_oss_prepare(substream); + mutex_unlock(&runtime->oss.params_lock); + if (err < 0) + return err; + } + return 0; +} + +/* call with params_lock held */ +static int snd_pcm_oss_make_ready_locked(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime; + int err; + + runtime = substream->runtime; + if (runtime->oss.params) { + err = snd_pcm_oss_change_params_locked(substream); + if (err < 0) + return err; + } + if (runtime->oss.prepare) { err = snd_pcm_oss_prepare(substream); if (err < 0) return err; @@ -1332,13 +1370,14 @@ static ssize_t snd_pcm_oss_write1(struct if (atomic_read(&substream->mmap_count)) return -ENXIO;
- if ((tmp = snd_pcm_oss_make_ready(substream)) < 0) - return tmp; while (bytes > 0) { if (mutex_lock_interruptible(&runtime->oss.params_lock)) { tmp = -ERESTARTSYS; break; } + tmp = snd_pcm_oss_make_ready_locked(substream); + if (tmp < 0) + goto err; if (bytes < runtime->oss.period_bytes || runtime->oss.buffer_used > 0) { tmp = bytes; if (tmp + runtime->oss.buffer_used > runtime->oss.period_bytes) @@ -1439,13 +1478,14 @@ static ssize_t snd_pcm_oss_read1(struct if (atomic_read(&substream->mmap_count)) return -ENXIO;
- if ((tmp = snd_pcm_oss_make_ready(substream)) < 0) - return tmp; while (bytes > 0) { if (mutex_lock_interruptible(&runtime->oss.params_lock)) { tmp = -ERESTARTSYS; break; } + tmp = snd_pcm_oss_make_ready_locked(substream); + if (tmp < 0) + goto err; if (bytes < runtime->oss.period_bytes || runtime->oss.buffer_used > 0) { if (runtime->oss.buffer_used == 0) { tmp = snd_pcm_oss_read2(substream, runtime->oss.buffer, runtime->oss.period_bytes, 1); @@ -1501,10 +1541,12 @@ static int snd_pcm_oss_reset(struct snd_ continue; runtime = substream->runtime; snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL); + mutex_lock(&runtime->oss.params_lock); runtime->oss.prepare = 1; runtime->oss.buffer_used = 0; runtime->oss.prev_hw_ptr_period = 0; runtime->oss.period_ptr = 0; + mutex_unlock(&runtime->oss.params_lock); } return 0; } @@ -1590,9 +1632,10 @@ static int snd_pcm_oss_sync(struct snd_p goto __direct; if ((err = snd_pcm_oss_make_ready(substream)) < 0) return err; + if (mutex_lock_interruptible(&runtime->oss.params_lock)) + return -ERESTARTSYS; format = snd_pcm_oss_format_from(runtime->oss.format); width = snd_pcm_format_physical_width(format); - mutex_lock(&runtime->oss.params_lock); if (runtime->oss.buffer_used > 0) { #ifdef OSS_DEBUG pcm_dbg(substream->pcm, "sync: buffer_used\n"); @@ -1643,7 +1686,9 @@ static int snd_pcm_oss_sync(struct snd_p substream->f_flags = saved_f_flags; if (err < 0) return err; + mutex_lock(&runtime->oss.params_lock); runtime->oss.prepare = 1; + mutex_unlock(&runtime->oss.params_lock); }
substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE]; @@ -1654,8 +1699,10 @@ static int snd_pcm_oss_sync(struct snd_p err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL); if (err < 0) return err; + mutex_lock(&runtime->oss.params_lock); runtime->oss.buffer_used = 0; runtime->oss.prepare = 1; + mutex_unlock(&runtime->oss.params_lock); } return 0; } @@ -1674,10 +1721,13 @@ static int snd_pcm_oss_set_rate(struct s rate = 1000; else if (rate > 192000) rate = 192000; + if (mutex_lock_interruptible(&runtime->oss.params_lock)) + return -ERESTARTSYS; if (runtime->oss.rate != rate) { runtime->oss.params = 1; runtime->oss.rate = rate; } + mutex_unlock(&runtime->oss.params_lock); } return snd_pcm_oss_get_rate(pcm_oss_file); } @@ -1705,10 +1755,13 @@ static int snd_pcm_oss_set_channels(stru if (substream == NULL) continue; runtime = substream->runtime; + if (mutex_lock_interruptible(&runtime->oss.params_lock)) + return -ERESTARTSYS; if (runtime->oss.channels != channels) { runtime->oss.params = 1; runtime->oss.channels = channels; } + mutex_unlock(&runtime->oss.params_lock); } return snd_pcm_oss_get_channels(pcm_oss_file); } @@ -1794,10 +1847,13 @@ static int snd_pcm_oss_set_format(struct if (substream == NULL) continue; runtime = substream->runtime; + if (mutex_lock_interruptible(&runtime->oss.params_lock)) + return -ERESTARTSYS; if (runtime->oss.format != format) { runtime->oss.params = 1; runtime->oss.format = format; } + mutex_unlock(&runtime->oss.params_lock); } } return snd_pcm_oss_get_format(pcm_oss_file); @@ -1817,8 +1873,6 @@ static int snd_pcm_oss_set_subdivide1(st { struct snd_pcm_runtime *runtime;
- if (substream == NULL) - return 0; runtime = substream->runtime; if (subdivide == 0) { subdivide = runtime->oss.subdivision; @@ -1842,9 +1896,16 @@ static int snd_pcm_oss_set_subdivide(str
for (idx = 1; idx >= 0; --idx) { struct snd_pcm_substream *substream = pcm_oss_file->streams[idx]; + struct snd_pcm_runtime *runtime; + if (substream == NULL) continue; - if ((err = snd_pcm_oss_set_subdivide1(substream, subdivide)) < 0) + runtime = substream->runtime; + if (mutex_lock_interruptible(&runtime->oss.params_lock)) + return -ERESTARTSYS; + err = snd_pcm_oss_set_subdivide1(substream, subdivide); + mutex_unlock(&runtime->oss.params_lock); + if (err < 0) return err; } return err; @@ -1854,8 +1915,6 @@ static int snd_pcm_oss_set_fragment1(str { struct snd_pcm_runtime *runtime;
- if (substream == NULL) - return 0; runtime = substream->runtime; if (runtime->oss.subdivision || runtime->oss.fragshift) return -EINVAL; @@ -1875,9 +1934,16 @@ static int snd_pcm_oss_set_fragment(stru
for (idx = 1; idx >= 0; --idx) { struct snd_pcm_substream *substream = pcm_oss_file->streams[idx]; + struct snd_pcm_runtime *runtime; + if (substream == NULL) continue; - if ((err = snd_pcm_oss_set_fragment1(substream, val)) < 0) + runtime = substream->runtime; + if (mutex_lock_interruptible(&runtime->oss.params_lock)) + return -ERESTARTSYS; + err = snd_pcm_oss_set_fragment1(substream, val); + mutex_unlock(&runtime->oss.params_lock); + if (err < 0) return err; } return err; @@ -1961,6 +2027,9 @@ static int snd_pcm_oss_set_trigger(struc } if (psubstream) { runtime = psubstream->runtime; + cmd = 0; + if (mutex_lock_interruptible(&runtime->oss.params_lock)) + return -ERESTARTSYS; if (trigger & PCM_ENABLE_OUTPUT) { if (runtime->oss.trigger) goto _skip1; @@ -1978,13 +2047,19 @@ static int snd_pcm_oss_set_trigger(struc cmd = SNDRV_PCM_IOCTL_DROP; runtime->oss.prepare = 1; } - err = snd_pcm_kernel_ioctl(psubstream, cmd, NULL); - if (err < 0) - return err; - } _skip1: + mutex_unlock(&runtime->oss.params_lock); + if (cmd) { + err = snd_pcm_kernel_ioctl(psubstream, cmd, NULL); + if (err < 0) + return err; + } + } if (csubstream) { runtime = csubstream->runtime; + cmd = 0; + if (mutex_lock_interruptible(&runtime->oss.params_lock)) + return -ERESTARTSYS; if (trigger & PCM_ENABLE_INPUT) { if (runtime->oss.trigger) goto _skip2; @@ -1999,11 +2074,14 @@ static int snd_pcm_oss_set_trigger(struc cmd = SNDRV_PCM_IOCTL_DROP; runtime->oss.prepare = 1; } - err = snd_pcm_kernel_ioctl(csubstream, cmd, NULL); - if (err < 0) - return err; - } _skip2: + mutex_unlock(&runtime->oss.params_lock); + if (cmd) { + err = snd_pcm_kernel_ioctl(csubstream, cmd, NULL); + if (err < 0) + return err; + } + } return 0; }
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai tiwai@suse.de
commit 40cab6e88cb0b6c56d3f30b7491a20e803f948f6 upstream.
OSS PCM stream management isn't modal but it allows ioctls issued at any time for changing the parameters. In the previous hardening patch ("ALSA: pcm: Avoid potential races between OSS ioctls and read/write"), we covered these races and prevent the corruption by protecting the concurrent accesses via params_lock mutex. However, this means that some ioctls that try to change the stream parameter (e.g. channels or format) would be blocked until the read/write finishes, and it may take really long.
Basically changing the parameter while reading/writing is an invalid operation, hence it's even more user-friendly from the API POV if it returns -EBUSY in such a situation.
This patch adds such checks in the relevant ioctls with the addition of read/write access refcount.
Cc: stable@vger.kernel.org Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- include/sound/pcm_oss.h | 1 + sound/core/oss/pcm_oss.c | 36 +++++++++++++++++++++++++++--------- 2 files changed, 28 insertions(+), 9 deletions(-)
--- a/include/sound/pcm_oss.h +++ b/include/sound/pcm_oss.h @@ -57,6 +57,7 @@ struct snd_pcm_oss_runtime { char *buffer; /* vmallocated period */ size_t buffer_used; /* used length from period buffer */ struct mutex params_lock; + atomic_t rw_ref; /* concurrent read/write accesses */ #ifdef CONFIG_SND_PCM_OSS_PLUGINS struct snd_pcm_plugin *plugin_first; struct snd_pcm_plugin *plugin_last; --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c @@ -1370,6 +1370,7 @@ static ssize_t snd_pcm_oss_write1(struct if (atomic_read(&substream->mmap_count)) return -ENXIO;
+ atomic_inc(&runtime->oss.rw_ref); while (bytes > 0) { if (mutex_lock_interruptible(&runtime->oss.params_lock)) { tmp = -ERESTARTSYS; @@ -1433,6 +1434,7 @@ static ssize_t snd_pcm_oss_write1(struct } tmp = 0; } + atomic_dec(&runtime->oss.rw_ref); return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp; }
@@ -1478,6 +1480,7 @@ static ssize_t snd_pcm_oss_read1(struct if (atomic_read(&substream->mmap_count)) return -ENXIO;
+ atomic_inc(&runtime->oss.rw_ref); while (bytes > 0) { if (mutex_lock_interruptible(&runtime->oss.params_lock)) { tmp = -ERESTARTSYS; @@ -1526,6 +1529,7 @@ static ssize_t snd_pcm_oss_read1(struct } tmp = 0; } + atomic_dec(&runtime->oss.rw_ref); return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp; }
@@ -1632,8 +1636,11 @@ static int snd_pcm_oss_sync(struct snd_p goto __direct; if ((err = snd_pcm_oss_make_ready(substream)) < 0) return err; - if (mutex_lock_interruptible(&runtime->oss.params_lock)) + atomic_inc(&runtime->oss.rw_ref); + if (mutex_lock_interruptible(&runtime->oss.params_lock)) { + atomic_dec(&runtime->oss.rw_ref); return -ERESTARTSYS; + } format = snd_pcm_oss_format_from(runtime->oss.format); width = snd_pcm_format_physical_width(format); if (runtime->oss.buffer_used > 0) { @@ -1645,10 +1652,8 @@ static int snd_pcm_oss_sync(struct snd_p runtime->oss.buffer + runtime->oss.buffer_used, size); err = snd_pcm_oss_sync1(substream, runtime->oss.period_bytes); - if (err < 0) { - mutex_unlock(&runtime->oss.params_lock); - return err; - } + if (err < 0) + goto unlock; } else if (runtime->oss.period_ptr > 0) { #ifdef OSS_DEBUG pcm_dbg(substream->pcm, "sync: period_ptr\n"); @@ -1658,10 +1663,8 @@ static int snd_pcm_oss_sync(struct snd_p runtime->oss.buffer, size * 8 / width); err = snd_pcm_oss_sync1(substream, size); - if (err < 0) { - mutex_unlock(&runtime->oss.params_lock); - return err; - } + if (err < 0) + goto unlock; } /* * The ALSA's period might be a bit large than OSS one. @@ -1675,7 +1678,11 @@ static int snd_pcm_oss_sync(struct snd_p else if (runtime->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) snd_pcm_lib_writev(substream, NULL, size); } +unlock: mutex_unlock(&runtime->oss.params_lock); + atomic_dec(&runtime->oss.rw_ref); + if (err < 0) + return err; /* * finish sync: drain the buffer */ @@ -1723,6 +1730,8 @@ static int snd_pcm_oss_set_rate(struct s rate = 192000; if (mutex_lock_interruptible(&runtime->oss.params_lock)) return -ERESTARTSYS; + if (atomic_read(&runtime->oss.rw_ref)) + return -EBUSY; if (runtime->oss.rate != rate) { runtime->oss.params = 1; runtime->oss.rate = rate; @@ -1757,6 +1766,8 @@ static int snd_pcm_oss_set_channels(stru runtime = substream->runtime; if (mutex_lock_interruptible(&runtime->oss.params_lock)) return -ERESTARTSYS; + if (atomic_read(&runtime->oss.rw_ref)) + return -EBUSY; if (runtime->oss.channels != channels) { runtime->oss.params = 1; runtime->oss.channels = channels; @@ -1847,6 +1858,8 @@ static int snd_pcm_oss_set_format(struct if (substream == NULL) continue; runtime = substream->runtime; + if (atomic_read(&runtime->oss.rw_ref)) + return -EBUSY; if (mutex_lock_interruptible(&runtime->oss.params_lock)) return -ERESTARTSYS; if (runtime->oss.format != format) { @@ -1901,6 +1914,8 @@ static int snd_pcm_oss_set_subdivide(str if (substream == NULL) continue; runtime = substream->runtime; + if (atomic_read(&runtime->oss.rw_ref)) + return -EBUSY; if (mutex_lock_interruptible(&runtime->oss.params_lock)) return -ERESTARTSYS; err = snd_pcm_oss_set_subdivide1(substream, subdivide); @@ -1939,6 +1954,8 @@ static int snd_pcm_oss_set_fragment(stru if (substream == NULL) continue; runtime = substream->runtime; + if (atomic_read(&runtime->oss.rw_ref)) + return -EBUSY; if (mutex_lock_interruptible(&runtime->oss.params_lock)) return -ERESTARTSYS; err = snd_pcm_oss_set_fragment1(substream, val); @@ -2333,6 +2350,7 @@ static void snd_pcm_oss_init_substream(s runtime->oss.maxfrags = 0; runtime->oss.subdivision = 0; substream->pcm_release = snd_pcm_oss_release_substream; + atomic_set(&runtime->oss.rw_ref, 0); }
static int snd_pcm_oss_release_file(struct snd_pcm_oss_file *pcm_oss_file)
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai tiwai@suse.de
commit f6d297df4dd47ef949540e4a201230d0c5308325 upstream.
The previous fix 40cab6e88cb0 ("ALSA: pcm: Return -EBUSY for OSS ioctls changing busy streams") introduced some mutex unbalance; the check of runtime->oss.rw_ref was inserted in a wrong place after the mutex lock.
This patch fixes the inconsistency by rewriting with the helper functions to lock/unlock parameters with the stream check.
Fixes: 40cab6e88cb0 ("ALSA: pcm: Return -EBUSY for OSS ioctls changing busy streams") Reported-by: Dan Carpenter dan.carpenter@oracle.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/oss/pcm_oss.c | 67 +++++++++++++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 25 deletions(-)
--- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c @@ -823,6 +823,23 @@ static int choose_rate(struct snd_pcm_su return snd_pcm_hw_param_near(substream, params, SNDRV_PCM_HW_PARAM_RATE, best_rate, NULL); }
+/* parameter locking: returns immediately if tried during streaming */ +static int lock_params(struct snd_pcm_runtime *runtime) +{ + if (mutex_lock_interruptible(&runtime->oss.params_lock)) + return -ERESTARTSYS; + if (atomic_read(&runtime->oss.rw_ref)) { + mutex_unlock(&runtime->oss.params_lock); + return -EBUSY; + } + return 0; +} + +static void unlock_params(struct snd_pcm_runtime *runtime) +{ + mutex_unlock(&runtime->oss.params_lock); +} + /* call with params_lock held */ static int snd_pcm_oss_change_params_locked(struct snd_pcm_substream *substream) { @@ -1721,6 +1738,8 @@ static int snd_pcm_oss_set_rate(struct s for (idx = 1; idx >= 0; --idx) { struct snd_pcm_substream *substream = pcm_oss_file->streams[idx]; struct snd_pcm_runtime *runtime; + int err; + if (substream == NULL) continue; runtime = substream->runtime; @@ -1728,15 +1747,14 @@ static int snd_pcm_oss_set_rate(struct s rate = 1000; else if (rate > 192000) rate = 192000; - if (mutex_lock_interruptible(&runtime->oss.params_lock)) - return -ERESTARTSYS; - if (atomic_read(&runtime->oss.rw_ref)) - return -EBUSY; + err = lock_params(runtime); + if (err < 0) + return err; if (runtime->oss.rate != rate) { runtime->oss.params = 1; runtime->oss.rate = rate; } - mutex_unlock(&runtime->oss.params_lock); + unlock_params(runtime); } return snd_pcm_oss_get_rate(pcm_oss_file); } @@ -1761,18 +1779,19 @@ static int snd_pcm_oss_set_channels(stru for (idx = 1; idx >= 0; --idx) { struct snd_pcm_substream *substream = pcm_oss_file->streams[idx]; struct snd_pcm_runtime *runtime; + int err; + if (substream == NULL) continue; runtime = substream->runtime; - if (mutex_lock_interruptible(&runtime->oss.params_lock)) - return -ERESTARTSYS; - if (atomic_read(&runtime->oss.rw_ref)) - return -EBUSY; + err = lock_params(runtime); + if (err < 0) + return err; if (runtime->oss.channels != channels) { runtime->oss.params = 1; runtime->oss.channels = channels; } - mutex_unlock(&runtime->oss.params_lock); + unlock_params(runtime); } return snd_pcm_oss_get_channels(pcm_oss_file); } @@ -1845,6 +1864,7 @@ static int snd_pcm_oss_get_formats(struc static int snd_pcm_oss_set_format(struct snd_pcm_oss_file *pcm_oss_file, int format) { int formats, idx; + int err; if (format != AFMT_QUERY) { formats = snd_pcm_oss_get_formats(pcm_oss_file); @@ -1858,15 +1878,14 @@ static int snd_pcm_oss_set_format(struct if (substream == NULL) continue; runtime = substream->runtime; - if (atomic_read(&runtime->oss.rw_ref)) - return -EBUSY; - if (mutex_lock_interruptible(&runtime->oss.params_lock)) - return -ERESTARTSYS; + err = lock_params(runtime); + if (err < 0) + return err; if (runtime->oss.format != format) { runtime->oss.params = 1; runtime->oss.format = format; } - mutex_unlock(&runtime->oss.params_lock); + unlock_params(runtime); } } return snd_pcm_oss_get_format(pcm_oss_file); @@ -1914,12 +1933,11 @@ static int snd_pcm_oss_set_subdivide(str if (substream == NULL) continue; runtime = substream->runtime; - if (atomic_read(&runtime->oss.rw_ref)) - return -EBUSY; - if (mutex_lock_interruptible(&runtime->oss.params_lock)) - return -ERESTARTSYS; + err = lock_params(runtime); + if (err < 0) + return err; err = snd_pcm_oss_set_subdivide1(substream, subdivide); - mutex_unlock(&runtime->oss.params_lock); + unlock_params(runtime); if (err < 0) return err; } @@ -1954,12 +1972,11 @@ static int snd_pcm_oss_set_fragment(stru if (substream == NULL) continue; runtime = substream->runtime; - if (atomic_read(&runtime->oss.rw_ref)) - return -EBUSY; - if (mutex_lock_interruptible(&runtime->oss.params_lock)) - return -ERESTARTSYS; + err = lock_params(runtime); + if (err < 0) + return err; err = snd_pcm_oss_set_fragment1(substream, val); - mutex_unlock(&runtime->oss.params_lock); + unlock_params(runtime); if (err < 0) return err; }
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai tiwai@suse.de
commit a820ccbe21e8ce8e86c39cd1d3bc8c7d1cbb949b upstream.
The PCM runtime object is created and freed dynamically at PCM stream open / close time. This is tracked via substream->runtime, and it's cleared at snd_pcm_detach_substream().
The runtime object assignment is protected by PCM open_mutex, so for all PCM operations, it's safely handled. However, each PCM substream provides also an ALSA timer interface, and user-space can access to this while closing a PCM substream. This may eventually lead to a UAF, as snd_pcm_timer_resolution() tries to access the runtime while clearing it in other side.
Fortunately, it's the only concurrent access from the PCM timer, and it merely reads runtime->timer_resolution field. So, we can avoid the race by reordering kfree() and wrapping the substream->runtime clearance with the corresponding timer lock.
Reported-by: syzbot+8e62ff4e07aa2ce87826@syzkaller.appspotmail.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 | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
--- a/sound/core/pcm.c +++ b/sound/core/pcm.c @@ -28,6 +28,7 @@ #include <sound/core.h> #include <sound/minors.h> #include <sound/pcm.h> +#include <sound/timer.h> #include <sound/control.h> #include <sound/info.h>
@@ -1054,8 +1055,13 @@ void snd_pcm_detach_substream(struct snd snd_free_pages((void*)runtime->control, PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control))); kfree(runtime->hw_constraints.rules); - kfree(runtime); + /* Avoid concurrent access to runtime via PCM timer interface */ + if (substream->timer) + spin_lock_irq(&substream->timer->lock); substream->runtime = NULL; + if (substream->timer) + spin_unlock_irq(&substream->timer->lock); + kfree(runtime); put_pid(substream->pid); substream->pid = NULL; substream->pstr->substream_opened--;
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai tiwai@suse.de
commit e15dc99dbb9cf99f6432e8e3c0b3a8f7a3403a86 upstream.
The commit 02a5d6925cd3 ("ALSA: pcm: Avoid potential races between OSS ioctls and read/write") split the PCM preparation code to a locked version, and it added a sanity check of runtime->oss.prepare flag along with the change. This leaded to an endless loop when the stream gets XRUN: namely, snd_pcm_oss_write3() and co call snd_pcm_oss_prepare() without setting runtime->oss.prepare flag and the loop continues until the PCM state reaches to another one.
As the function is supposed to execute the preparation unconditionally, drop the invalid state check there.
The bug was triggered by syzkaller.
Fixes: 02a5d6925cd3 ("ALSA: pcm: Avoid potential races between OSS ioctls and read/write") Reported-by: syzbot+150189c103427d31a053@syzkaller.appspotmail.com Reported-by: syzbot+7e3f31a52646f939c052@syzkaller.appspotmail.com Reported-by: syzbot+4f2016cf5185da7759dc@syzkaller.appspotmail.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/oss/pcm_oss.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
--- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c @@ -1128,13 +1128,14 @@ static int snd_pcm_oss_get_active_substr }
/* call with params_lock held */ +/* NOTE: this always call PREPARE unconditionally no matter whether + * runtime->oss.prepare is set or not + */ static int snd_pcm_oss_prepare(struct snd_pcm_substream *substream) { int err; struct snd_pcm_runtime *runtime = substream->runtime;
- if (!runtime->oss.prepare) - return 0; err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_PREPARE, NULL); if (err < 0) { pcm_dbg(substream->pcm,
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche bart.vanassche@wdc.com
commit e68088e78d82920632eba112b968e49d588d02a2 upstream.
Before commit e494f6a72839 ("[SCSI] improved eh timeout handler") it did not really matter whether or not abort handlers like srp_abort() called .scsi_done() when returning another value than SUCCESS. Since that commit however this matters. Hence only call .scsi_done() when returning SUCCESS.
Signed-off-by: Bart Van Assche bart.vanassche@wdc.com Cc: stable@vger.kernel.org Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/infiniband/ulp/srp/ib_srp.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
--- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -2974,9 +2974,11 @@ static int srp_abort(struct scsi_cmnd *s ret = FAST_IO_FAIL; else ret = FAILED; - srp_free_req(ch, req, scmnd, 0); - scmnd->result = DID_ABORT << 16; - scmnd->scsi_done(scmnd); + if (ret == SUCCESS) { + srp_free_req(ch, req, scmnd, 0); + scmnd->result = DID_ABORT << 16; + scmnd->scsi_done(scmnd); + }
return ret; }
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche bart.vanassche@wdc.com
commit 3a148896b24adf8688dc0c59af54531931677a40 upstream.
Ensure that cv_end is equal to ibdev->num_comp_vectors for the NUMA node with the highest index. This patch improves spreading of RDMA channels over completion vectors and thereby improves performance, especially on systems with only a single NUMA node. This patch drops support for the comp_vector login parameter by ignoring the value of that parameter since I have not found a good way to combine support for that parameter and automatic spreading of RDMA channels over completion vectors.
Fixes: d92c0da71a35 ("IB/srp: Add multichannel support") Reported-by: Alexander Schmid alex@modula-shop-systems.de Signed-off-by: Bart Van Assche bart.vanassche@wdc.com Cc: Alexander Schmid alex@modula-shop-systems.de Cc: stable@vger.kernel.org Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/infiniband/ulp/srp/ib_srp.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
--- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -3873,12 +3873,10 @@ static ssize_t srp_create_target(struct num_online_nodes()); const int ch_end = ((node_idx + 1) * target->ch_count / num_online_nodes()); - const int cv_start = (node_idx * ibdev->num_comp_vectors / - num_online_nodes() + target->comp_vector) - % ibdev->num_comp_vectors; - const int cv_end = ((node_idx + 1) * ibdev->num_comp_vectors / - num_online_nodes() + target->comp_vector) - % ibdev->num_comp_vectors; + const int cv_start = node_idx * ibdev->num_comp_vectors / + num_online_nodes(); + const int cv_end = (node_idx + 1) * ibdev->num_comp_vectors / + num_online_nodes(); int cpu_idx = 0;
for_each_online_cpu(cpu) {
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche bart.vanassche@wdc.com
commit 2a78cb4db487372152bed2055c038f9634d595e8 upstream.
Avoid triggering an out-of-bounds stack access by changing the type of 'wr' from ib_send_wr into ib_rdma_wr.
This patch fixes the following KASAN bug report:
BUG: KASAN: stack-out-of-bounds in rxe_post_send+0x7a9/0x9a0 [rdma_rxe] Read of size 8 at addr ffff880068197a48 by task kworker/2:1/44
Workqueue: ib_cm cm_work_handler [ib_cm] Call Trace: dump_stack+0x8e/0xcd print_address_description+0x6f/0x280 kasan_report+0x25a/0x380 __asan_load8+0x54/0x90 rxe_post_send+0x7a9/0x9a0 [rdma_rxe] srpt_zerolength_write+0xf0/0x180 [ib_srpt] srpt_cm_rtu_recv+0x68/0x110 [ib_srpt] srpt_rdma_cm_handler+0xbb/0x15b [ib_srpt] cma_ib_handler+0x1aa/0x4a0 [rdma_cm] cm_process_work+0x30/0x100 [ib_cm] cm_work_handler+0xa86/0x351b [ib_cm] process_one_work+0x475/0x9f0 worker_thread+0x69/0x690 kthread+0x1ad/0x1d0 ret_from_fork+0x3a/0x50
Fixes: aaf45bd83eba ("IB/srpt: Detect session shutdown reliably") Signed-off-by: Bart Van Assche bart.vanassche@wdc.com Cc: Christoph Hellwig hch@lst.de Cc: stable@vger.kernel.org Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/infiniband/ulp/srpt/ib_srpt.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
--- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -838,16 +838,19 @@ static int srpt_post_recv(struct srpt_de */ static int srpt_zerolength_write(struct srpt_rdma_ch *ch) { - struct ib_send_wr wr, *bad_wr; + struct ib_send_wr *bad_wr; + struct ib_rdma_wr wr = { + .wr = { + .opcode = IB_WR_RDMA_WRITE, + .wr_cqe = &ch->zw_cqe, + .send_flags = IB_SEND_SIGNALED, + } + };
pr_debug("%s-%d: queued zerolength write\n", ch->sess_name, ch->qp->qp_num);
- memset(&wr, 0, sizeof(wr)); - wr.opcode = IB_WR_RDMA_WRITE; - wr.wr_cqe = &ch->zw_cqe; - wr.send_flags = IB_SEND_SIGNALED; - return ib_post_send(ch->qp, &wr, &bad_wr); + return ib_post_send(ch->qp, &wr.wr, &bad_wr); }
static void srpt_zerolength_write_done(struct ib_cq *cq, struct ib_wc *wc)
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrew Morton akpm@linux-foundation.org
commit 6ee687735e745eafae9e6b93d1ea70bc52e7ad07 upstream.
gcc-4.4.4 has issues with initialization of anonymous unions.
drivers/infiniband/core/verbs.c: In function '__ib_drain_sq': drivers/infiniband/core/verbs.c:2204: error: unknown field 'wr_cqe' specified in initializer drivers/infiniband/core/verbs.c:2204: warning: initialization makes integer from pointer without a cast
Work around this.
Fixes: a1ae7d0345edd5 ("RDMA/core: Avoid that ib_drain_qp() triggers an out-of-bounds stack access") Cc: Bart Van Assche bart.vanassche@wdc.com Cc: Steve Wise swise@opengridcomputing.com Cc: Sagi Grimberg sagi@grimberg.me Cc: Jason Gunthorpe jgg@mellanox.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Doug Ledford dledford@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/infiniband/core/verbs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c @@ -2197,8 +2197,9 @@ static void __ib_drain_sq(struct ib_qp * struct ib_send_wr *bad_swr; struct ib_rdma_wr swr = { .wr = { + .next = NULL, + { .wr_cqe = &sdrain.cqe, }, .opcode = IB_WR_RDMA_WRITE, - .wr_cqe = &sdrain.cqe, }, }; int ret;
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrew Morton akpm@linux-foundation.org
commit 06892cc190550807d332c95a0114c7e175584012 upstream.
gcc-4.4.4 has issues with initialization of anonymous unions:
drivers/infiniband/ulp/srpt/ib_srpt.c: In function 'srpt_zerolength_write': drivers/infiniband/ulp/srpt/ib_srpt.c:854: error: unknown field 'wr_cqe' specified in initializer drivers/infiniband/ulp/srpt/ib_srpt.c:854: warning: initialization makes integer from pointer without a cast
Work aound this.
Fixes: 2a78cb4db487 ("IB/srpt: Fix an out-of-bounds stack access in srpt_zerolength_write()") Cc: Bart Van Assche bart.vanassche@wdc.com Cc: Christoph Hellwig hch@lst.de Cc: Jason Gunthorpe jgg@mellanox.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Doug Ledford dledford@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/infiniband/ulp/srpt/ib_srpt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -841,8 +841,9 @@ static int srpt_zerolength_write(struct struct ib_send_wr *bad_wr; struct ib_rdma_wr wr = { .wr = { + .next = NULL, + { .wr_cqe = &ch->zw_cqe, }, .opcode = IB_WR_RDMA_WRITE, - .wr_cqe = &ch->zw_cqe, .send_flags = IB_SEND_SIGNALED, } };
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heinz Mauelshagen heinzm@redhat.com
commit 880bcce0dcc3172fe865352b492c41d85290cb8d upstream.
Fix a race for "nosync" activations providing "aa.." device health characters and "0/N" sync ratio rather than "AA..." and "N/N". Occurs when status for the raid set is retrieved during resume before the MD sync thread starts and clears the MD_RECOVERY_NEEDED flag.
Cc: stable@vger.kernel.org # 4.16+ Signed-off-by: Heinz Mauelshagen heinzm@redhat.com Signed-off-by: Mike Snitzer snitzer@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/md/dm-raid.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c @@ -3408,7 +3408,8 @@ static sector_t rs_get_progress(struct r set_bit(RT_FLAG_RS_IN_SYNC, &rs->runtime_flags);
} else { - if (!test_bit(MD_RECOVERY_INTR, &recovery) && + if (!test_bit(__CTR_FLAG_NOSYNC, &rs->ctr_flags) && + !test_bit(MD_RECOVERY_INTR, &recovery) && (test_bit(MD_RECOVERY_NEEDED, &recovery) || test_bit(MD_RECOVERY_RESHAPE, &recovery) || test_bit(MD_RECOVERY_RUNNING, &recovery)))
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maxime Jayat maxime.jayat@mobile-devices.fr
commit c5637476bbf9bb86c7f0413b8f4822a73d8d2d07 upstream.
Despite the efforts made to correctly read the NDA and CUBC registers, the order in which the registers are read could sometimes lead to an inconsistent state.
Re-using the timeline from the comments, this following timing of registers reads could lead to reading NDA with value "@desc2" and CUBC with value "MAX desc1":
INITD -------- ------------ |____________________| _______________________ _______________ NDA @desc2 / @desc3 _______________________/_______________ __________ ___________ _______________ CUBC 0 / MAX desc1 / MAX desc2 __________/___________/_______________ | | | | Events:(1)(2) (3)(4)
(1) check_nda = @desc2 (2) initd = 1 (3) cur_ubc = MAX desc1 (4) cur_nda = @desc2
This is allowed by the condition ((check_nda == cur_nda) && initd), despite cur_ubc and cur_nda being in the precise state we don't want.
This error leads to incorrect residue computation.
Fix it by inversing the order in which CUBC and INITD are read. This makes sure that NDA and CUBC are always read together either _before_ INITD goes to 0 or _after_ it is back at 1. The case where NDA is read before INITD is at 0 and CUBC is read after INITD is back at 1 will be rejected by check_nda and cur_nda being different.
Fixes: 53398f488821 ("dmaengine: at_xdmac: fix residue corruption") Cc: stable@vger.kernel.org Signed-off-by: Maxime Jayat maxime.jayat@mobile-devices.fr Acked-by: Ludovic Desroches ludovic.desroches@microchip.com Signed-off-by: Vinod Koul vinod.koul@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/dma/at_xdmac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/dma/at_xdmac.c +++ b/drivers/dma/at_xdmac.c @@ -1471,10 +1471,10 @@ at_xdmac_tx_status(struct dma_chan *chan for (retry = 0; retry < AT_XDMAC_RESIDUE_MAX_RETRIES; retry++) { check_nda = at_xdmac_chan_read(atchan, AT_XDMAC_CNDA) & 0xfffffffc; rmb(); - initd = !!(at_xdmac_chan_read(atchan, AT_XDMAC_CC) & AT_XDMAC_CC_INITD); - rmb(); cur_ubc = at_xdmac_chan_read(atchan, AT_XDMAC_CUBC); rmb(); + initd = !!(at_xdmac_chan_read(atchan, AT_XDMAC_CC) & AT_XDMAC_CC_INITD); + rmb(); cur_nda = at_xdmac_chan_read(atchan, AT_XDMAC_CNDA) & 0xfffffffc; rmb();
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frederic Barrat fbarrat@linux.vnet.ibm.com
commit ad7b4e8022b9864c075fe71e1328b1d25cad82f6 upstream.
cxllib_handle_fault() is called by an external driver when it needs to have the host resolve page faults for a buffer. The buffer can cover several pages and VMAs. The function iterates over all the pages used by the buffer, based on the page size of the VMA.
To ensure some stability while processing the faults, the thread T1 grabs the mm->mmap_sem semaphore with read access (R1). However, when processing a page fault for a single page, one of the underlying functions, copro_handle_mm_fault(), also grabs the same semaphore with read access (R2). So the thread T1 takes the semaphore twice.
If another thread T2 tries to access the semaphore in write mode W1 (say, because it wants to allocate memory and calls 'brk'), then that thread T2 will have to wait because there's a reader (R1). If the thread T1 is processing a new page at that time, it won't get an automatic grant at R2, because there's now a writer thread waiting (T2). And we have a deadlock.
The timeline is: 1. thread T1 owns the semaphore with read access R1 2. thread T2 requests write access W1 and waits 3. thread T1 requests read access R2 and waits
The fix is for the thread T1 to release the semaphore R1 once it got the information it needs from the current VMA. The address space/VMAs could evolve while T1 iterates over the full buffer, but in the unlikely case where T1 misses a page, the external driver will raise a new page fault when retrying the memory access.
Fixes: 3ced8d730063 ("cxl: Export library to support IBM XSL") Cc: stable@vger.kernel.org # 4.13+ Signed-off-by: Frederic Barrat fbarrat@linux.vnet.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/misc/cxl/cxllib.c | 83 +++++++++++++++++++++++++++++----------------- 1 file changed, 54 insertions(+), 29 deletions(-)
--- a/drivers/misc/cxl/cxllib.c +++ b/drivers/misc/cxl/cxllib.c @@ -208,49 +208,74 @@ int cxllib_get_PE_attributes(struct task } EXPORT_SYMBOL_GPL(cxllib_get_PE_attributes);
-int cxllib_handle_fault(struct mm_struct *mm, u64 addr, u64 size, u64 flags) +static int get_vma_info(struct mm_struct *mm, u64 addr, + u64 *vma_start, u64 *vma_end, + unsigned long *page_size) { - int rc; - u64 dar; struct vm_area_struct *vma = NULL; - unsigned long page_size; - - if (mm == NULL) - return -EFAULT; + int rc = 0;
down_read(&mm->mmap_sem);
vma = find_vma(mm, addr); if (!vma) { - pr_err("Can't find vma for addr %016llx\n", addr); rc = -EFAULT; goto out; } - /* get the size of the pages allocated */ - page_size = vma_kernel_pagesize(vma); + *page_size = vma_kernel_pagesize(vma); + *vma_start = vma->vm_start; + *vma_end = vma->vm_end; +out: + up_read(&mm->mmap_sem); + return rc; +} + +int cxllib_handle_fault(struct mm_struct *mm, u64 addr, u64 size, u64 flags) +{ + int rc; + u64 dar, vma_start, vma_end; + unsigned long page_size;
- for (dar = (addr & ~(page_size - 1)); dar < (addr + size); dar += page_size) { - if (dar < vma->vm_start || dar >= vma->vm_end) { - vma = find_vma(mm, addr); - if (!vma) { - pr_err("Can't find vma for addr %016llx\n", addr); - rc = -EFAULT; - goto out; - } - /* get the size of the pages allocated */ - page_size = vma_kernel_pagesize(vma); + if (mm == NULL) + return -EFAULT; + + /* + * The buffer we have to process can extend over several pages + * and may also cover several VMAs. + * We iterate over all the pages. The page size could vary + * between VMAs. + */ + rc = get_vma_info(mm, addr, &vma_start, &vma_end, &page_size); + if (rc) + return rc; + + for (dar = (addr & ~(page_size - 1)); dar < (addr + size); + dar += page_size) { + if (dar < vma_start || dar >= vma_end) { + /* + * We don't hold the mm->mmap_sem semaphore + * while iterating, since the semaphore is + * required by one of the lower-level page + * fault processing functions and it could + * create a deadlock. + * + * It means the VMAs can be altered between 2 + * loop iterations and we could theoretically + * miss a page (however unlikely). But that's + * not really a problem, as the driver will + * retry access, get another page fault on the + * missing page and call us again. + */ + rc = get_vma_info(mm, dar, &vma_start, &vma_end, + &page_size); + if (rc) + return rc; }
rc = cxl_handle_mm_fault(mm, flags, dar); - if (rc) { - pr_err("cxl_handle_mm_fault failed %d", rc); - rc = -EFAULT; - goto out; - } + if (rc) + return -EFAULT; } - rc = 0; -out: - up_read(&mm->mmap_sem); - return rc; + return 0; } EXPORT_SYMBOL_GPL(cxllib_handle_fault);
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Chiu chiu@endlessm.com
commit 0803d7befa15cab5717d667a97a66214d2a4c083 upstream.
The Acer Acer Veriton X4110G has a TPM device detected as: tpm_tis 00:0b: 1.2 TPM (device-id 0xFE, rev-id 71)
After the first S3 suspend, the following error appears during resume: tpm tpm0: A TPM error(38) occurred continue selftest
Any following S3 suspend attempts will now fail with this error: tpm tpm0: Error (38) sending savestate before suspend PM: Device 00:0b failed to suspend: error 38
Error 38 is TPM_ERR_INVALID_POSTINIT which means the TPM is not in the correct state. This indicates that the platform BIOS is not sending the usual TPM_Startup command during S3 resume.
From this point onwards, all TPM commands will fail.
The same issue was previously reported on Foxconn 6150BK8MC and Sony Vaio TX3.
The platform behaviour seems broken here, but we should not break suspend/resume because of this.
When the unexpected TPM state is encountered, set a flag to skip the affected TPM_SaveState command on later suspends.
Cc: stable@vger.kernel.org Signed-off-by: Chris Chiu chiu@endlessm.com Signed-off-by: Daniel Drake drake@endlessm.com Link: http://lkml.kernel.org/r/CAB4CAwfSCvj1cudi+MWaB5g2Z67d9DwY1o475YOZD64ma23UiQ... Link: https://lkml.org/lkml/2011/3/28/192 Link: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=591031 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-interface.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c @@ -969,6 +969,10 @@ int tpm_do_selftest(struct tpm_chip *chi loops = jiffies_to_msecs(duration) / delay_msec;
rc = tpm_continue_selftest(chip); + if (rc == TPM_ERR_INVALID_POSTINIT) { + chip->flags |= TPM_CHIP_FLAG_ALWAYS_POWERED; + dev_info(&chip->dev, "TPM not ready (%d)\n", rc); + } /* This may fail if there was no TPM driver during a suspend/resume * cycle; some may return 10 (BAD_ORDINAL), others 28 (FAILEDSELFTEST) */
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Williams dan.j.williams@intel.com
commit c31898c8c711f2bbbcaebe802a55827e288d875a upstream.
At initialization time the 'dimm' driver caches a copy of the memory device's label area and reserves address space for each of the namespaces defined.
However, as can be seen below, the reservation occurs even when the index blocks are invalid:
nvdimm nmem0: nvdimm_init_config_data: len: 131072 rc: 0 nvdimm nmem0: config data size: 131072 nvdimm nmem0: __nd_label_validate: nsindex0 labelsize 1 invalid nvdimm nmem0: __nd_label_validate: nsindex1 labelsize 1 invalid nvdimm nmem0: : pmem-6025e505: 0x1000000000 @ 0xf50000000 reserve <-- bad
Gate dpa reservation on the presence of valid index blocks.
Cc: stable@vger.kernel.org Fixes: 4a826c83db4e ("libnvdimm: namespace indices: read and validate") Reported-by: Krzysztof Rusocki krzysztof.rusocki@intel.com Signed-off-by: Dan Williams dan.j.williams@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/nvdimm/dimm.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
--- a/drivers/nvdimm/dimm.c +++ b/drivers/nvdimm/dimm.c @@ -67,9 +67,11 @@ static int nvdimm_probe(struct device *d ndd->ns_next = nd_label_next_nsindex(ndd->ns_current); nd_label_copy(ndd, to_next_namespace_index(ndd), to_current_namespace_index(ndd)); - rc = nd_label_reserve_dpa(ndd); - if (ndd->ns_current >= 0) - nvdimm_set_aliasing(dev); + if (ndd->ns_current >= 0) { + rc = nd_label_reserve_dpa(ndd); + if (rc == 0) + nvdimm_set_aliasing(dev); + } nvdimm_clear_locked(dev); nvdimm_bus_unlock(dev);
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Williams dan.j.williams@intel.com
commit 4f8672201b7e7ed4f5f6c3cf6dcd080648580582 upstream.
The following NULL dereference results from incorrectly assuming that ndd is valid in this print:
struct nvdimm_drvdata *ndd = to_ndd(&nd_region->mapping[i]);
/* * Give up if we don't find an instance of a uuid at each * position (from 0 to nd_region->ndr_mappings - 1), or if we * find a dimm with two instances of the same uuid. */ dev_err(&nd_region->dev, "%s missing label for %pUb\n", dev_name(ndd->dev), nd_label->uuid);
BUG: unable to handle kernel NULL pointer dereference at 0000000000000000 IP: nd_region_register_namespaces+0xd67/0x13c0 [libnvdimm] PGD 0 P4D 0 Oops: 0000 [#1] SMP PTI CPU: 43 PID: 673 Comm: kworker/u609:10 Not tainted 4.16.0-rc4+ #1 [..] RIP: 0010:nd_region_register_namespaces+0xd67/0x13c0 [libnvdimm] [..] Call Trace: ? devres_add+0x2f/0x40 ? devm_kmalloc+0x52/0x60 ? nd_region_activate+0x9c/0x320 [libnvdimm] nd_region_probe+0x94/0x260 [libnvdimm] ? kernfs_add_one+0xe4/0x130 nvdimm_bus_probe+0x63/0x100 [libnvdimm]
Switch to using the nvdimm device directly.
Fixes: 0e3b0d123c8f ("libnvdimm, namespace: allow multiple pmem...") Cc: stable@vger.kernel.org Reported-by: Dave Jiang dave.jiang@intel.com Signed-off-by: Dan Williams dan.j.williams@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/nvdimm/namespace_devs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/nvdimm/namespace_devs.c +++ b/drivers/nvdimm/namespace_devs.c @@ -1926,7 +1926,7 @@ static struct device *create_namespace_p }
if (i < nd_region->ndr_mappings) { - struct nvdimm_drvdata *ndd = to_ndd(&nd_region->mapping[i]); + struct nvdimm *nvdimm = nd_region->mapping[i].nvdimm;
/* * Give up if we don't find an instance of a uuid at each @@ -1934,7 +1934,7 @@ static struct device *create_namespace_p * find a dimm with two instances of the same uuid. */ dev_err(&nd_region->dev, "%s missing label for %pUb\n", - dev_name(ndd->dev), nd_label->uuid); + nvdimm_name(nvdimm), nd_label->uuid); rc = -EINVAL; goto err; }
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt (VMware) rostedt@goodmis.org
commit 1e6338cfb50e244c445ad7d891b35385bd0ee757 upstream.
Commit 841a915d20c7b2 ("printf: Do not have bprintf dereference pointers") would preprocess various pointers that are dereferenced in the bprintf() because the recording and printing are done at two different times. Some pointers stayed dereferenced in the ring buffer because user space could handle them (namely "%pS" and friends). Pointers that are not dereferenced should not be processed immediately but instead just saved directly.
Cc: stable@vger.kernel.org Fixes: 841a915d20c7b2 ("printf: Do not have bprintf dereference pointers") Signed-off-by: Steven Rostedt (VMware) rostedt@goodmis.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- lib/vsprintf.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -2591,6 +2591,8 @@ int vbin_printf(u32 *bin_buf, size_t siz case 's': case 'F': case 'f': + case 'x': + case 'K': save_arg(void *); break; default: @@ -2765,6 +2767,8 @@ int bstr_printf(char *buf, size_t size, case 's': case 'F': case 'f': + case 'x': + case 'K': process = true; break; default:
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Williams dan.j.williams@intel.com
commit 78727137fdf49edf9f731bde79d7189067b4047a upstream.
There is a small window whereby ARS scan requests can schedule work that userspace will miss when polling scrub_show. Hold the init_mutex lock over calls to report the status to close this potential escape. Also, make sure that requests to cancel the ARS workqueue are treated as an idle event.
Cc: stable@vger.kernel.org Cc: Vishal Verma vishal.l.verma@intel.com Fixes: 37b137ff8c83 ("nfit, libnvdimm: allow an ARS scrub...") Reviewed-by: Dave Jiang dave.jiang@intel.com Signed-off-by: Dan Williams dan.j.williams@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/acpi/nfit/core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
--- a/drivers/acpi/nfit/core.c +++ b/drivers/acpi/nfit/core.c @@ -1250,8 +1250,11 @@ static ssize_t scrub_show(struct device if (nd_desc) { struct acpi_nfit_desc *acpi_desc = to_acpi_desc(nd_desc);
+ mutex_lock(&acpi_desc->init_mutex); rc = sprintf(buf, "%d%s", acpi_desc->scrub_count, - (work_busy(&acpi_desc->work)) ? "+\n" : "\n"); + work_busy(&acpi_desc->work) + && !acpi_desc->cancel ? "+\n" : "\n"); + mutex_unlock(&acpi_desc->init_mutex); } device_unlock(dev); return rc;
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Williams dan.j.williams@intel.com
commit 0731de476a37c33485af82d64041c9d193208df8 upstream.
Per the ACPI specification the only functional purpose for a DIMM Control Region to be mapped into the system physical address space, from an OSPM perspective, is to support block-apertures. However, there are some BIOSen that publish DIMM Control Region SPA entries for pre-boot environment consumption. Undo the kernel policy of generating disabled 'ndblk' regions when this configuration is detected.
Cc: stable@vger.kernel.org Fixes: 1f7df6f88b92 ("libnvdimm, nfit: regions (block-data-window...)") Reviewed-by: Toshi Kani toshi.kani@hpe.com Signed-off-by: Dan Williams dan.j.williams@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/acpi/nfit/core.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
--- a/drivers/acpi/nfit/core.c +++ b/drivers/acpi/nfit/core.c @@ -2583,7 +2583,7 @@ static int acpi_nfit_init_mapping(struct struct acpi_nfit_system_address *spa = nfit_spa->spa; struct nd_blk_region_desc *ndbr_desc; struct nfit_mem *nfit_mem; - int blk_valid = 0, rc; + int rc;
if (!nvdimm) { dev_err(acpi_desc->dev, "spa%d dimm: %#x not found\n", @@ -2603,15 +2603,14 @@ static int acpi_nfit_init_mapping(struct if (!nfit_mem || !nfit_mem->bdw) { dev_dbg(acpi_desc->dev, "spa%d %s missing bdw\n", spa->range_index, nvdimm_name(nvdimm)); - } else { - mapping->size = nfit_mem->bdw->capacity; - mapping->start = nfit_mem->bdw->start_address; - ndr_desc->num_lanes = nfit_mem->bdw->windows; - blk_valid = 1; + break; }
+ mapping->size = nfit_mem->bdw->capacity; + mapping->start = nfit_mem->bdw->start_address; + ndr_desc->num_lanes = nfit_mem->bdw->windows; ndr_desc->mapping = mapping; - ndr_desc->num_mappings = blk_valid; + ndr_desc->num_mappings = 1; ndbr_desc = to_blk_region_desc(ndr_desc); ndbr_desc->enable = acpi_nfit_blk_region_enable; ndbr_desc->do_io = acpi_desc->blk_do_io;
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt (VMware) rostedt@goodmis.org
commit 2a872fa4e9c8adc79c830e4009e1cc0c013a9d8a upstream.
The ring buffer is made up of a link list of pages. When making the ring buffer bigger, it will allocate all the pages it needs before adding to the ring buffer, and if it fails, it frees them and returns an error. This makes increasing the ring buffer size an all or nothing action. When this was first created, the pages were allocated with "NORETRY". This was to not cause any Out-Of-Memory (OOM) actions from allocating the ring buffer. But NORETRY was too strict, as the ring buffer would fail to expand even when there's memory available, but was taken up in the page cache.
Commit 848618857d253 ("tracing/ring_buffer: Try harder to allocate") changed the allocating from NORETRY to RETRY_MAYFAIL. The RETRY_MAYFAIL would allocate from the page cache, but if there was no memory available, it would simple fail the allocation and not trigger an OOM.
This worked fine, but had one problem. As the ring buffer would allocate one page at a time, it could take up all memory in the system before it failed to allocate and free that memory. If the allocation is happening and the ring buffer allocates all memory and then tries to take more than available, its allocation will not trigger an OOM, but if there's any allocation that happens someplace else, that could trigger an OOM, even though once the ring buffer's allocation fails, it would free up all the previous memory it tried to allocate, and allow other memory allocations to succeed.
Commit d02bd27bd33dd ("mm/page_alloc.c: calculate 'available' memory in a separate function") separated out si_mem_availble() as a separate function that could be used to see how much memory is available in the system. Using this function to make sure that the ring buffer could be allocated before it tries to allocate pages we can avoid allocating all memory in the system and making it vulnerable to OOMs if other allocations are taking place.
Link: http://lkml.kernel.org/r/1522320104-6573-1-git-send-email-zhaoyang.huang@spr...
CC: stable@vger.kernel.org Cc: linux-mm@kvack.org Fixes: 848618857d253 ("tracing/ring_buffer: Try harder to allocate") Requires: d02bd27bd33dd ("mm/page_alloc.c: calculate 'available' memory in a separate function") Reported-by: Zhaoyang Huang huangzhaoyang@gmail.com Tested-by: Joel Fernandes joelaf@google.com Signed-off-by: Steven Rostedt (VMware) rostedt@goodmis.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- kernel/trace/ring_buffer.c | 5 +++++ 1 file changed, 5 insertions(+)
--- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -1136,6 +1136,11 @@ static int __rb_allocate_pages(long nr_p struct buffer_page *bpage, *tmp; long i;
+ /* Check if the available memory is there first */ + i = si_mem_available(); + if (i < nr_pages) + return -ENOMEM; + for (i = 0; i < nr_pages; i++) { struct page *page; /*
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason A. Donenfeld Jason@zx2c4.com
commit 530ba6c7cb3c22435a4d26de47037bb6f86a5329 upstream.
Recent libcs have gotten a bit more strict, so we actually need to include the right headers and use the right types. This enables UML to compile again.
Signed-off-by: Jason A. Donenfeld Jason@zx2c4.com Cc: stable@vger.kernel.org Signed-off-by: Richard Weinberger richard@nod.at Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/um/os-Linux/file.c | 1 + arch/um/os-Linux/signal.c | 1 + arch/x86/um/stub_segv.c | 1 + 3 files changed, 3 insertions(+)
--- a/arch/um/os-Linux/file.c +++ b/arch/um/os-Linux/file.c @@ -12,6 +12,7 @@ #include <sys/mount.h> #include <sys/socket.h> #include <sys/stat.h> +#include <sys/sysmacros.h> #include <sys/un.h> #include <sys/types.h> #include <os.h> --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c @@ -16,6 +16,7 @@ #include <os.h> #include <sysdep/mcontext.h> #include <um_malloc.h> +#include <sys/ucontext.h>
void (*sig_info[NSIG])(int, struct siginfo *, struct uml_pt_regs *) = { [SIGTRAP] = relay_signal, --- a/arch/x86/um/stub_segv.c +++ b/arch/x86/um/stub_segv.c @@ -6,6 +6,7 @@ #include <sysdep/stub.h> #include <sysdep/faultinfo.h> #include <sysdep/mcontext.h> +#include <sys/ucontext.h>
void __attribute__ ((__section__ (".__syscall_stub"))) stub_segv_handler(int sig, siginfo_t *info, void *p)
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Mazur krzysiek@podlesie.net
commit 4d1a535b8ec5e74b42dfd9dc809142653b2597f6 upstream.
glibc 2.26 removed the 'struct ucontext' to "improve" POSIX compliance and break programs, including User Mode Linux. Fix User Mode Linux by using POSIX ucontext_t.
This fixes:
arch/um/os-Linux/signal.c: In function 'hard_handler': arch/um/os-Linux/signal.c:163:22: error: dereferencing pointer to incomplete type 'struct ucontext' mcontext_t *mc = &uc->uc_mcontext; arch/x86/um/stub_segv.c: In function 'stub_segv_handler': arch/x86/um/stub_segv.c:16:13: error: dereferencing pointer to incomplete type 'struct ucontext' &uc->uc_mcontext);
Cc: stable@vger.kernel.org Signed-off-by: Krzysztof Mazur krzysiek@podlesie.net Signed-off-by: Richard Weinberger richard@nod.at Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/um/os-Linux/signal.c | 2 +- arch/x86/um/stub_segv.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
--- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c @@ -160,7 +160,7 @@ static void (*handlers[_NSIG])(int sig,
static void hard_handler(int sig, siginfo_t *si, void *p) { - struct ucontext *uc = p; + ucontext_t *uc = p; mcontext_t *mc = &uc->uc_mcontext; unsigned long pending = 1UL << sig;
--- a/arch/x86/um/stub_segv.c +++ b/arch/x86/um/stub_segv.c @@ -11,7 +11,7 @@ void __attribute__ ((__section__ (".__syscall_stub"))) stub_segv_handler(int sig, siginfo_t *info, void *p) { - struct ucontext *uc = p; + ucontext_t *uc = p;
GET_FAULTINFO_FROM_MC(*((struct faultinfo *) STUB_DATA), &uc->uc_mcontext);
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lu Baolu baolu.lu@linux.intel.com
commit bbe4b3af9d9e3172fb9aa1f8dcdfaedcb381fc64 upstream.
A memory block was allocated in intel_svm_bind_mm() but never freed in a failure path. This patch fixes this by free it to avoid memory leakage.
Cc: Ashok Raj ashok.raj@intel.com Cc: Jacob Pan jacob.jun.pan@linux.intel.com Cc: stable@vger.kernel.org # v4.4+ Signed-off-by: Lu Baolu baolu.lu@linux.intel.com Fixes: 2f26e0a9c9860 ('iommu/vt-d: Add basic SVM PASID support') Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/iommu/intel-svm.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/iommu/intel-svm.c +++ b/drivers/iommu/intel-svm.c @@ -396,6 +396,7 @@ int intel_svm_bind_mm(struct device *dev pasid_max - 1, GFP_KERNEL); if (ret < 0) { kfree(svm); + kfree(sdev); goto out; } svm->pasid = ret;
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Kappner agk@godking.net
commit d0a0852b9f81cf5f793bf2eae7336ed40a1a1815 upstream.
Upon module load, mmc_block allocates a bus with bus_registeri() in mmc_blk_init(). This reference never gets freed during module unload, which leads to subsequent re-insertions of the module fails and a WARN() splat is triggered.
Fix the bug by dropping the reference for the bus in mmc_blk_exit().
Signed-off-by: Alexander Kappner agk@godking.net Fixes: 97548575bef3 ("mmc: block: Convert RPMB to a character device") Cc: stable@vger.kernel.org Reviewed-by: Shawn Lin shawn.lin@rock-chips.com Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/mmc/core/block.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -3087,6 +3087,7 @@ static void __exit mmc_blk_exit(void) mmc_unregister_driver(&mmc_driver); unregister_blkdev(MMC_BLOCK_MAJOR, "mmc"); unregister_chrdev_region(mmc_rpmb_devt, MAX_DEVICES); + bus_unregister(&mmc_rpmb_bus_type); }
module_init(mmc_blk_init);
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Smith alex.smith@imgtec.com
commit a04f0017c22453613d5f423326b190c61e3b4f98 upstream.
A spinlock is held while updating the internal copy of the IRQ mask, but not while writing it to the actual IMASK register. After the lock is released, an IRQ can occur before the IMASK register is written. If handling this IRQ causes the mask to be changed, when the handler returns back to the middle of the first mask update, a stale value will be written to the mask register.
If this causes an IRQ to become unmasked that cannot have its status cleared by writing a 1 to it in the IREG register, e.g. the SDIO IRQ, then we can end up stuck with the same IRQ repeatedly being fired but not handled. Normally the MMC IRQ handler attempts to clear any unexpected IRQs by writing IREG, but for those that cannot be cleared in this way then the IRQ will just repeatedly fire.
This was resulting in lockups after a while of using Wi-Fi on the CI20 (GitHub issue #19).
Resolve by holding the spinlock until after the IMASK register has been updated.
Cc: stable@vger.kernel.org Link: https://github.com/MIPS/CI20_linux/issues/19 Fixes: 61bfbdb85687 ("MMC: Add support for the controller on JZ4740 SoCs.") Tested-by: Mathieu Malaterre malat@debian.org Signed-off-by: Alex Smith alex.smith@imgtec.com Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/mmc/host/jz4740_mmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/mmc/host/jz4740_mmc.c +++ b/drivers/mmc/host/jz4740_mmc.c @@ -362,9 +362,9 @@ static void jz4740_mmc_set_irq_enabled(s host->irq_mask &= ~irq; else host->irq_mask |= irq; - spin_unlock_irqrestore(&host->lock, flags);
writew(host->irq_mask, host->base + JZ_REG_MMC_IMASK); + spin_unlock_irqrestore(&host->lock, flags); }
static void jz4740_mmc_clock_enable(struct jz4740_mmc_host *host,
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Masaharu Hayakawa masaharu.hayakawa.ry@renesas.com
commit fc167daff581c01ebce8695e9618231cae3561a1 upstream.
If an error was detected when CMD23 was issued, command sequence should be terminated with errors and CMD23 should be issued after retuning.
Fixes: 8b22c3c18be5 ("mmc: tmio: add CMD23 support") Signed-off-by: Masaharu Hayakawa masaharu.hayakawa.ry@renesas.com Signed-off-by: Wolfram Sang wsa+renesas@sang-engineering.com Cc: stable@vger.kernel.org # 4.13+ Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/mmc/host/tmio_mmc_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/mmc/host/tmio_mmc_core.c +++ b/drivers/mmc/host/tmio_mmc_core.c @@ -911,7 +911,7 @@ static void tmio_mmc_finish_request(stru host->check_scc_error(host);
/* If SET_BLOCK_COUNT, continue with main command */ - if (host->mrq) { + if (host->mrq && !mrq->cmd->error) { tmio_process_mrq(host, mrq); return; }
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Charlene Liu charlene.liu@amd.com
commit af2ac326087da632e9580f65205f4cc4205caf85 upstream.
Signed-off-by: Charlene Liu charlene.liu@amd.com Reviewed-by: Krunoslav Kovac Krunoslav.Kovac@amd.com Acked-by: Harry Wentland harry.wentland@amd.com Cc: stable@vger.kernel.org Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c @@ -736,6 +736,8 @@ static void dce110_stream_encoder_update if (info_frame->avi.valid) { const uint32_t *content = (const uint32_t *) &info_frame->avi.sb[0]; + /*we need turn on clock before programming AFMT block*/ + REG_UPDATE(AFMT_CNTL, AFMT_AUDIO_CLOCK_EN, 1);
REG_WRITE(AFMT_AVI_INFO0, content[0]);
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ravi Bangoria ravi.bangoria@linux.vnet.ibm.com
commit 18d45b11d96e6f9b3814960a1394083a3d6b7f74 upstream.
tu->offset is unsigned long, not a pointer, thus %lx should be used to print it, not the %px.
Link: http://lkml.kernel.org/r/20180315082756.9050-1-ravi.bangoria@linux.vnet.ibm....
Cc: stable@vger.kernel.org Acked-by: Masami Hiramatsu mhiramat@kernel.org Fixes: 0e4d819d0893 ("trace_uprobe: Display correct offset in uprobe_events") Suggested-by: Kees Cook keescook@chromium.org Signed-off-by: Ravi Bangoria ravi.bangoria@linux.vnet.ibm.com Signed-off-by: Steven Rostedt (VMware) rostedt@goodmis.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- kernel/trace/trace_uprobe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/kernel/trace/trace_uprobe.c +++ b/kernel/trace/trace_uprobe.c @@ -608,7 +608,7 @@ static int probes_seq_show(struct seq_fi
/* Don't print "0x (null)" when offset is 0 */ if (tu->offset) { - seq_printf(m, "0x%px", (void *)tu->offset); + seq_printf(m, "0x%0*lx", (int)(sizeof(void *) * 2), tu->offset); } else { switch (sizeof(void *)) { case 4:
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sinan Kaya okaya@codeaurora.org
commit 1b30dfd376e28e7f37eda5e2033f6823cdda222b upstream.
Per PCIe r3.1, sec 2.2.6.2 and 7.8.4, a Requester may not use 8-bit Tags unless its Extended Tag Field Enable is set, but all Receivers/Completers must handle 8-bit Tags correctly regardless of their Extended Tag Field Enable.
Some devices do not handle 8-bit Tags as Completers, so add a quirk for them. If we find such a device, we disable Extended Tags for the entire hierarchy to make peer-to-peer DMA possible.
The Broadcom HT1100/HT2000/HT2100 seems to have issues with handling 8-bit tags. Mark it as broken.
This fixes Xorg hangs and unresponsive keyboards with errors like this:
radeon 0000:06:00.0: GPU lockup (current fence id 0x000000000000000e last fence id 0x0000000000000 [drm:r600_ring_test [radeon]] *ERROR* radeon: ring 0 test failed (scratch(0x8504)=0xCAFEDEAD) [drm:r600_resume [radeon]] *ERROR* r600 startup failed on resume
Fixes: 60db3a4d8cc9 ("PCI: Enable PCIe Extended Tags if supported") Link: https://bugzilla.kernel.org/show_bug.cgi?id=196197 Signed-off-by: Sinan Kaya okaya@codeaurora.org Signed-off-by: Bjorn Helgaas helgaas@kernel.org CC: stable@vger.kernel.org # v4.11: 62ce94a7a5a5 PCI: Mark Broadcom HT2100 Root Port Extended Tags as broken CC: stable@vger.kernel.org # v4.11 Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/pci/quirks.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -4815,9 +4815,13 @@ static void quirk_no_ext_tags(struct pci
pci_walk_bus(bridge->bus, pci_configure_extended_tags, NULL); } +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0132, quirk_no_ext_tags); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0140, quirk_no_ext_tags); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0141, quirk_no_ext_tags); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0142, quirk_no_ext_tags); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0144, quirk_no_ext_tags); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0420, quirk_no_ext_tags); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0422, quirk_no_ext_tags);
#ifdef CONFIG_PCI_ATS /*
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Richard Genoud richard.genoud@gmail.com
commit 6a4a4595804548e173f0763a0e7274a3521c59a9 upstream.
Clearfog boards can come with a CPU clocked at 1600MHz (commercial) or 1333MHz (industrial).
They have also some dip-switches to select a different clock (666, 800, 1066, 1200).
The funny thing is that the recovery button is on the MPP34 fq selector. So, when booting an industrial board with this button down, the frequency 666MHz is selected (and the kernel didn't boot).
This patch add all the missing clocks.
The only mode I didn't test is 2GHz (uboot found 4294MHz instead :/ ).
Fixes: 0e85aeced4d6 ("clk: mvebu: add clock support for Armada 380/385") Cc: stable@vger.kernel.org # 3.16.x: 9593f4f56cf5: clk: mvebu: armada-38x: add support for 1866MHz variants Cc: stable@vger.kernel.org # 3.16.x
Signed-off-by: Richard Genoud richard.genoud@gmail.com Acked-by: Gregory CLEMENT gregory.clement@bootlin.com Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/clk/mvebu/armada-38x.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
--- a/drivers/clk/mvebu/armada-38x.c +++ b/drivers/clk/mvebu/armada-38x.c @@ -46,11 +46,11 @@ static u32 __init armada_38x_get_tclk_fr }
static const u32 armada_38x_cpu_frequencies[] __initconst = { - 0, 0, 0, 0, - 1066 * 1000 * 1000, 0, 0, 0, + 666 * 1000 * 1000, 0, 800 * 1000 * 1000, 0, + 1066 * 1000 * 1000, 0, 1200 * 1000 * 1000, 0, 1332 * 1000 * 1000, 0, 0, 0, 1600 * 1000 * 1000, 0, 0, 0, - 1866 * 1000 * 1000, + 1866 * 1000 * 1000, 0, 0, 2000 * 1000 * 1000, };
static u32 __init armada_38x_get_cpu_freq(void __iomem *sar) @@ -76,11 +76,11 @@ static const struct coreclk_ratio armada };
static const int armada_38x_cpu_l2_ratios[32][2] __initconst = { - {0, 1}, {0, 1}, {0, 1}, {0, 1}, - {1, 2}, {0, 1}, {0, 1}, {0, 1}, - {1, 2}, {0, 1}, {0, 1}, {0, 1}, + {1, 2}, {0, 1}, {1, 2}, {0, 1}, + {1, 2}, {0, 1}, {1, 2}, {0, 1}, {1, 2}, {0, 1}, {0, 1}, {0, 1}, {1, 2}, {0, 1}, {0, 1}, {0, 1}, + {1, 2}, {0, 1}, {0, 1}, {1, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, @@ -91,7 +91,7 @@ static const int armada_38x_cpu_ddr_rati {1, 2}, {0, 1}, {0, 1}, {0, 1}, {1, 2}, {0, 1}, {0, 1}, {0, 1}, {1, 2}, {0, 1}, {0, 1}, {0, 1}, - {1, 2}, {0, 1}, {0, 1}, {0, 1}, + {1, 2}, {0, 1}, {0, 1}, {7, 15}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1},
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnd Bergmann arnd@arndb.de
commit ce33f284935e08229046b30635e6aadcbab02b53 upstream.
When we build this driver with on x86-32, gcc produces a false-positive warning:
drivers/clk/renesas/clk-sh73a0.c: In function 'sh73a0_cpg_clocks_init': drivers/clk/renesas/clk-sh73a0.c:155:10: error: 'parent_name' may be used uninitialized in this function [-Werror=maybe-uninitialized] return clk_register_fixed_factor(NULL, name, parent_name, 0,
We can work around that warning by adding a fake initialization, I tried and failed to come up with any better workaround. This is currently one of few remaining warnings for a 4.14.y randconfig build, so it would be good to also have it backported at least to that version. Older versions have more randconfig warnings, so we might not care.
I had not noticed this earlier, because one patch in my randconfig test tree removes the '-ffreestanding' option on x86-32, and that avoids the warning. The -ffreestanding flag was originally global but moved into arch/i386 by Andi Kleen in commit 6edfba1b33c7 ("[PATCH] x86_64: Don't define string functions to builtin") as a 'temporary workaround'.
Like many temporary hacks, this turned out to be rather long-lived, from all I can tell we still need a simple fix to asm/string_32.h before it can be removed, but I'm not sure about how to best do that.
Cc: stable@vger.kernel.org Cc: Andi Kleen ak@linux.intel.com Signed-off-by: Arnd Bergmann arnd@arndb.de Acked-by: Geert Uytterhoeven geert+renesas@glider.be Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/clk/renesas/clk-sh73a0.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/clk/renesas/clk-sh73a0.c +++ b/drivers/clk/renesas/clk-sh73a0.c @@ -46,7 +46,7 @@ struct div4_clk { unsigned int shift; };
-static struct div4_clk div4_clks[] = { +static const struct div4_clk div4_clks[] = { { "zg", "pll0", CPG_FRQCRA, 16 }, { "m3", "pll1", CPG_FRQCRA, 12 }, { "b", "pll1", CPG_FRQCRA, 8 }, @@ -79,7 +79,7 @@ sh73a0_cpg_register_clock(struct device_ { const struct clk_div_table *table = NULL; unsigned int shift, reg, width; - const char *parent_name; + const char *parent_name = NULL; unsigned int mult = 1; unsigned int div = 1;
@@ -135,7 +135,7 @@ sh73a0_cpg_register_clock(struct device_ shift = 24; width = 5; } else { - struct div4_clk *c; + const struct div4_clk *c;
for (c = div4_clks; c->name; c++) { if (!strcmp(name, c->name)) {
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Wang sean.wang@mediatek.com
commit 89cd7aec21af26fd0c117bfc4bfc781724f201de upstream.
The clock for which all PWM devices on MT7623 or MT2701 actually depending on has to be divided by four from its parent clock axi_sel in the clock path prior to PWM devices.
Consequently, adding a fixed-factor clock axisel_d4 as one-fourth of clock axi_sel allows that PWM devices can have the correct resolution calculation.
Cc: stable@vger.kernel.org Fixes: e9862118272a ("clk: mediatek: Add MT2701 clock support") Signed-off-by: Sean Wang sean.wang@mediatek.com Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/clk/mediatek/clk-mt2701.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-)
--- a/drivers/clk/mediatek/clk-mt2701.c +++ b/drivers/clk/mediatek/clk-mt2701.c @@ -148,6 +148,7 @@ static const struct mtk_fixed_factor top FACTOR(CLK_TOP_CLK26M_D8, "clk26m_d8", "clk26m", 1, 8), FACTOR(CLK_TOP_32K_INTERNAL, "32k_internal", "clk26m", 1, 793), FACTOR(CLK_TOP_32K_EXTERNAL, "32k_external", "rtc32k", 1, 1), + FACTOR(CLK_TOP_AXISEL_D4, "axisel_d4", "axi_sel", 1, 4), };
static const char * const axi_parents[] = { @@ -857,13 +858,13 @@ static const struct mtk_gate peri_clks[] GATE_PERI0(CLK_PERI_USB1, "usb1_ck", "usb20_sel", 11), GATE_PERI0(CLK_PERI_USB0, "usb0_ck", "usb20_sel", 10), GATE_PERI0(CLK_PERI_PWM, "pwm_ck", "axi_sel", 9), - GATE_PERI0(CLK_PERI_PWM7, "pwm7_ck", "axi_sel", 8), - GATE_PERI0(CLK_PERI_PWM6, "pwm6_ck", "axi_sel", 7), - GATE_PERI0(CLK_PERI_PWM5, "pwm5_ck", "axi_sel", 6), - GATE_PERI0(CLK_PERI_PWM4, "pwm4_ck", "axi_sel", 5), - GATE_PERI0(CLK_PERI_PWM3, "pwm3_ck", "axi_sel", 4), - GATE_PERI0(CLK_PERI_PWM2, "pwm2_ck", "axi_sel", 3), - GATE_PERI0(CLK_PERI_PWM1, "pwm1_ck", "axi_sel", 2), + GATE_PERI0(CLK_PERI_PWM7, "pwm7_ck", "axisel_d4", 8), + GATE_PERI0(CLK_PERI_PWM6, "pwm6_ck", "axisel_d4", 7), + GATE_PERI0(CLK_PERI_PWM5, "pwm5_ck", "axisel_d4", 6), + GATE_PERI0(CLK_PERI_PWM4, "pwm4_ck", "axisel_d4", 5), + GATE_PERI0(CLK_PERI_PWM3, "pwm3_ck", "axisel_d4", 4), + GATE_PERI0(CLK_PERI_PWM2, "pwm2_ck", "axisel_d4", 3), + GATE_PERI0(CLK_PERI_PWM1, "pwm1_ck", "axisel_d4", 2), GATE_PERI0(CLK_PERI_THERM, "therm_ck", "axi_sel", 1), GATE_PERI0(CLK_PERI_NFI, "nfi_ck", "nfi2x_sel", 0),
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Boris Brezillon boris.brezillon@bootlin.com
commit 753872373b599384ac7df809aa61ea12d1c4d5d1 upstream.
In order to enable a PLL, not only the PLL has to be powered up and locked, but you also have to de-assert the reset signal. The last part was missing. Add it so PLLs that were not enabled by the FW/bootloader can be enabled from Linux.
Fixes: 41691b8862e2 ("clk: bcm2835: Add support for programming the audio domain clocks") Cc: stable@vger.kernel.org Signed-off-by: Boris Brezillon boris.brezillon@bootlin.com Reviewed-by: Eric Anholt eric@anholt.net Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/clk/bcm/clk-bcm2835.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
--- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -602,9 +602,7 @@ static void bcm2835_pll_off(struct clk_h const struct bcm2835_pll_data *data = pll->data;
spin_lock(&cprman->regs_lock); - cprman_write(cprman, data->cm_ctrl_reg, - cprman_read(cprman, data->cm_ctrl_reg) | - CM_PLL_ANARST); + cprman_write(cprman, data->cm_ctrl_reg, CM_PLL_ANARST); cprman_write(cprman, data->a2w_ctrl_reg, cprman_read(cprman, data->a2w_ctrl_reg) | A2W_PLL_CTRL_PWRDN); @@ -640,6 +638,10 @@ static int bcm2835_pll_on(struct clk_hw cpu_relax(); }
+ cprman_write(cprman, data->a2w_ctrl_reg, + cprman_read(cprman, data->a2w_ctrl_reg) | + A2W_PLL_CTRL_PRST_DISABLE); + return 0; }
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Osipenko digetx@gmail.com
commit 2dcabf053c6ecde46f7aa3612c5a57fb8bd185c4 upstream.
Machine dies if HCLK, SCLK or EMC is disabled. Hence mark these clocks as critical.
Signed-off-by: Dmitry Osipenko digetx@gmail.com Acked-by: Peter De Schrijver pdeschrijver@nvidia.com Cc: stable@vger.kernel.org # v4.16 Signed-off-by: Thierry Reding treding@nvidia.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/clk/tegra/clk-emc.c | 2 +- drivers/clk/tegra/clk-tegra-periph.c | 2 +- drivers/clk/tegra/clk-tegra-super-gen4.c | 8 +++++--- drivers/clk/tegra/clk-tegra114.c | 3 +-- drivers/clk/tegra/clk-tegra124.c | 7 +++---- drivers/clk/tegra/clk-tegra20.c | 23 ++++++++++------------- drivers/clk/tegra/clk-tegra210.c | 3 +-- drivers/clk/tegra/clk-tegra30.c | 14 ++++---------- 8 files changed, 26 insertions(+), 36 deletions(-)
--- a/drivers/clk/tegra/clk-emc.c +++ b/drivers/clk/tegra/clk-emc.c @@ -515,7 +515,7 @@ struct clk *tegra_clk_register_emc(void
init.name = "emc"; init.ops = &tegra_clk_emc_ops; - init.flags = 0; + init.flags = CLK_IS_CRITICAL; init.parent_names = emc_parent_clk_names; init.num_parents = ARRAY_SIZE(emc_parent_clk_names);
--- a/drivers/clk/tegra/clk-tegra-periph.c +++ b/drivers/clk/tegra/clk-tegra-periph.c @@ -830,7 +830,7 @@ static struct tegra_periph_init_data gat GATE("xusb_host", "xusb_host_src", 89, 0, tegra_clk_xusb_host, 0), GATE("xusb_ss", "xusb_ss_src", 156, 0, tegra_clk_xusb_ss, 0), GATE("xusb_dev", "xusb_dev_src", 95, 0, tegra_clk_xusb_dev, 0), - GATE("emc", "emc_mux", 57, 0, tegra_clk_emc, CLK_IGNORE_UNUSED), + GATE("emc", "emc_mux", 57, 0, tegra_clk_emc, CLK_IS_CRITICAL), GATE("sata_cold", "clk_m", 129, TEGRA_PERIPH_ON_APB, tegra_clk_sata_cold, 0), GATE("ispa", "isp", 23, 0, tegra_clk_ispa, 0), GATE("ispb", "isp", 3, 0, tegra_clk_ispb, 0), --- a/drivers/clk/tegra/clk-tegra-super-gen4.c +++ b/drivers/clk/tegra/clk-tegra-super-gen4.c @@ -125,7 +125,8 @@ static void __init tegra_sclk_init(void /* SCLK */ dt_clk = tegra_lookup_dt_id(tegra_clk_sclk, tegra_clks); if (dt_clk) { - clk = clk_register_divider(NULL, "sclk", "sclk_mux", 0, + clk = clk_register_divider(NULL, "sclk", "sclk_mux", + CLK_IS_CRITICAL, clk_base + SCLK_DIVIDER, 0, 8, 0, &sysrate_lock); *dt_clk = clk; @@ -137,7 +138,8 @@ static void __init tegra_sclk_init(void clk = tegra_clk_register_super_mux("sclk", gen_info->sclk_parents, gen_info->num_sclk_parents, - CLK_SET_RATE_PARENT, + CLK_SET_RATE_PARENT | + CLK_IS_CRITICAL, clk_base + SCLK_BURST_POLICY, 0, 4, 0, 0, NULL); *dt_clk = clk; @@ -151,7 +153,7 @@ static void __init tegra_sclk_init(void clk_base + SYSTEM_CLK_RATE, 4, 2, 0, &sysrate_lock); clk = clk_register_gate(NULL, "hclk", "hclk_div", - CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, + CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, clk_base + SYSTEM_CLK_RATE, 7, CLK_GATE_SET_TO_DISABLE, &sysrate_lock); *dt_clk = clk; --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -955,8 +955,7 @@ static void __init tegra114_pll_init(voi
/* PLLM */ clk = tegra_clk_register_pllm("pll_m", "pll_ref", clk_base, pmc, - CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, - &pll_m_params, NULL); + CLK_SET_RATE_GATE, &pll_m_params, NULL); clks[TEGRA114_CLK_PLL_M] = clk;
/* PLLM_OUT1 */ --- a/drivers/clk/tegra/clk-tegra124.c +++ b/drivers/clk/tegra/clk-tegra124.c @@ -1089,8 +1089,7 @@ static void __init tegra124_pll_init(voi
/* PLLM */ clk = tegra_clk_register_pllm("pll_m", "pll_ref", clk_base, pmc, - CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, - &pll_m_params, NULL); + CLK_SET_RATE_GATE, &pll_m_params, NULL); clk_register_clkdev(clk, "pll_m", NULL); clks[TEGRA124_CLK_PLL_M] = clk;
@@ -1099,7 +1098,7 @@ static void __init tegra124_pll_init(voi clk_base + PLLM_OUT, 0, TEGRA_DIVIDER_ROUND_UP, 8, 8, 1, NULL); clk = tegra_clk_register_pll_out("pll_m_out1", "pll_m_out1_div", - clk_base + PLLM_OUT, 1, 0, CLK_IGNORE_UNUSED | + clk_base + PLLM_OUT, 1, 0, CLK_SET_RATE_PARENT, 0, NULL); clk_register_clkdev(clk, "pll_m_out1", NULL); clks[TEGRA124_CLK_PLL_M_OUT1] = clk; @@ -1272,7 +1271,7 @@ static struct tegra_clk_init_table commo { TEGRA124_CLK_HOST1X, TEGRA124_CLK_PLL_P, 136000000, 1 }, { TEGRA124_CLK_DSIALP, TEGRA124_CLK_PLL_P, 68000000, 0 }, { TEGRA124_CLK_DSIBLP, TEGRA124_CLK_PLL_P, 68000000, 0 }, - { TEGRA124_CLK_SCLK, TEGRA124_CLK_PLL_P_OUT2, 102000000, 1 }, + { TEGRA124_CLK_SCLK, TEGRA124_CLK_PLL_P_OUT2, 102000000, 0 }, { TEGRA124_CLK_DFLL_SOC, TEGRA124_CLK_PLL_P, 51000000, 1 }, { TEGRA124_CLK_DFLL_REF, TEGRA124_CLK_PLL_P, 51000000, 1 }, { TEGRA124_CLK_PLL_C, TEGRA124_CLK_CLK_MAX, 768000000, 0 }, --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c @@ -576,6 +576,7 @@ static struct tegra_clk tegra20_clks[teg [tegra_clk_afi] = { .dt_id = TEGRA20_CLK_AFI, .present = true }, [tegra_clk_fuse] = { .dt_id = TEGRA20_CLK_FUSE, .present = true }, [tegra_clk_kfuse] = { .dt_id = TEGRA20_CLK_KFUSE, .present = true }, + [tegra_clk_emc] = { .dt_id = TEGRA20_CLK_EMC, .present = true }, };
static unsigned long tegra20_clk_measure_input_freq(void) @@ -651,8 +652,7 @@ static void tegra20_pll_init(void)
/* PLLM */ clk = tegra_clk_register_pll("pll_m", "pll_ref", clk_base, NULL, - CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, - &pll_m_params, NULL); + CLK_SET_RATE_GATE, &pll_m_params, NULL); clks[TEGRA20_CLK_PLL_M] = clk;
/* PLLM_OUT1 */ @@ -660,7 +660,7 @@ static void tegra20_pll_init(void) clk_base + PLLM_OUT, 0, TEGRA_DIVIDER_ROUND_UP, 8, 8, 1, NULL); clk = tegra_clk_register_pll_out("pll_m_out1", "pll_m_out1_div", - clk_base + PLLM_OUT, 1, 0, CLK_IGNORE_UNUSED | + clk_base + PLLM_OUT, 1, 0, CLK_SET_RATE_PARENT, 0, NULL); clks[TEGRA20_CLK_PLL_M_OUT1] = clk;
@@ -723,7 +723,8 @@ static void tegra20_super_clk_init(void)
/* SCLK */ clk = tegra_clk_register_super_mux("sclk", sclk_parents, - ARRAY_SIZE(sclk_parents), CLK_SET_RATE_PARENT, + ARRAY_SIZE(sclk_parents), + CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, clk_base + SCLK_BURST_POLICY, 0, 4, 0, 0, NULL); clks[TEGRA20_CLK_SCLK] = clk;
@@ -814,9 +815,6 @@ static void __init tegra20_periph_clk_in CLK_SET_RATE_NO_REPARENT, clk_base + CLK_SOURCE_EMC, 30, 2, 0, &emc_lock); - clk = tegra_clk_register_periph_gate("emc", "emc_mux", 0, clk_base, 0, - 57, periph_clk_enb_refcnt); - clks[TEGRA20_CLK_EMC] = clk;
clk = tegra_clk_register_mc("mc", "emc_mux", clk_base + CLK_SOURCE_EMC, &emc_lock); @@ -1019,13 +1017,12 @@ static struct tegra_clk_init_table init_ { TEGRA20_CLK_PLL_P_OUT2, TEGRA20_CLK_CLK_MAX, 48000000, 1 }, { TEGRA20_CLK_PLL_P_OUT3, TEGRA20_CLK_CLK_MAX, 72000000, 1 }, { TEGRA20_CLK_PLL_P_OUT4, TEGRA20_CLK_CLK_MAX, 24000000, 1 }, - { TEGRA20_CLK_PLL_C, TEGRA20_CLK_CLK_MAX, 600000000, 1 }, - { TEGRA20_CLK_PLL_C_OUT1, TEGRA20_CLK_CLK_MAX, 216000000, 1 }, - { TEGRA20_CLK_SCLK, TEGRA20_CLK_PLL_C_OUT1, 0, 1 }, - { TEGRA20_CLK_HCLK, TEGRA20_CLK_CLK_MAX, 0, 1 }, - { TEGRA20_CLK_PCLK, TEGRA20_CLK_CLK_MAX, 60000000, 1 }, + { TEGRA20_CLK_PLL_C, TEGRA20_CLK_CLK_MAX, 600000000, 0 }, + { TEGRA20_CLK_PLL_C_OUT1, TEGRA20_CLK_CLK_MAX, 216000000, 0 }, + { TEGRA20_CLK_SCLK, TEGRA20_CLK_PLL_C_OUT1, 0, 0 }, + { TEGRA20_CLK_HCLK, TEGRA20_CLK_CLK_MAX, 0, 0 }, + { TEGRA20_CLK_PCLK, TEGRA20_CLK_CLK_MAX, 60000000, 0 }, { TEGRA20_CLK_CSITE, TEGRA20_CLK_CLK_MAX, 0, 1 }, - { TEGRA20_CLK_EMC, TEGRA20_CLK_CLK_MAX, 0, 1 }, { TEGRA20_CLK_CCLK, TEGRA20_CLK_CLK_MAX, 0, 1 }, { TEGRA20_CLK_UARTA, TEGRA20_CLK_PLL_P, 0, 0 }, { TEGRA20_CLK_UARTB, TEGRA20_CLK_PLL_P, 0, 0 }, --- a/drivers/clk/tegra/clk-tegra210.c +++ b/drivers/clk/tegra/clk-tegra210.c @@ -3025,7 +3025,7 @@ static struct tegra_clk_init_table init_ { TEGRA210_CLK_I2S4, TEGRA210_CLK_PLL_A_OUT0, 11289600, 0 }, { TEGRA210_CLK_HOST1X, TEGRA210_CLK_PLL_P, 136000000, 1 }, { TEGRA210_CLK_SCLK_MUX, TEGRA210_CLK_PLL_P, 0, 1 }, - { TEGRA210_CLK_SCLK, TEGRA210_CLK_CLK_MAX, 102000000, 1 }, + { TEGRA210_CLK_SCLK, TEGRA210_CLK_CLK_MAX, 102000000, 0 }, { TEGRA210_CLK_DFLL_SOC, TEGRA210_CLK_PLL_P, 51000000, 1 }, { TEGRA210_CLK_DFLL_REF, TEGRA210_CLK_PLL_P, 51000000, 1 }, { TEGRA210_CLK_SBC4, TEGRA210_CLK_PLL_P, 12000000, 1 }, @@ -3040,7 +3040,6 @@ static struct tegra_clk_init_table init_ { TEGRA210_CLK_XUSB_DEV_SRC, TEGRA210_CLK_PLL_P_OUT_XUSB, 102000000, 0 }, { TEGRA210_CLK_SATA, TEGRA210_CLK_PLL_P, 104000000, 0 }, { TEGRA210_CLK_SATA_OOB, TEGRA210_CLK_PLL_P, 204000000, 0 }, - { TEGRA210_CLK_EMC, TEGRA210_CLK_CLK_MAX, 0, 1 }, { TEGRA210_CLK_MSELECT, TEGRA210_CLK_CLK_MAX, 0, 1 }, { TEGRA210_CLK_CSITE, TEGRA210_CLK_CLK_MAX, 0, 1 }, /* TODO find a way to enable this on-demand */ --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -819,6 +819,7 @@ static struct tegra_clk tegra30_clks[teg [tegra_clk_pll_a] = { .dt_id = TEGRA30_CLK_PLL_A, .present = true }, [tegra_clk_pll_a_out0] = { .dt_id = TEGRA30_CLK_PLL_A_OUT0, .present = true }, [tegra_clk_cec] = { .dt_id = TEGRA30_CLK_CEC, .present = true }, + [tegra_clk_emc] = { .dt_id = TEGRA30_CLK_EMC, .present = true }, };
static const char *pll_e_parents[] = { "pll_ref", "pll_p" }; @@ -843,8 +844,7 @@ static void __init tegra30_pll_init(void
/* PLLM */ clk = tegra_clk_register_pll("pll_m", "pll_ref", clk_base, pmc_base, - CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, - &pll_m_params, NULL); + CLK_SET_RATE_GATE, &pll_m_params, NULL); clks[TEGRA30_CLK_PLL_M] = clk;
/* PLLM_OUT1 */ @@ -852,7 +852,7 @@ static void __init tegra30_pll_init(void clk_base + PLLM_OUT, 0, TEGRA_DIVIDER_ROUND_UP, 8, 8, 1, NULL); clk = tegra_clk_register_pll_out("pll_m_out1", "pll_m_out1_div", - clk_base + PLLM_OUT, 1, 0, CLK_IGNORE_UNUSED | + clk_base + PLLM_OUT, 1, 0, CLK_SET_RATE_PARENT, 0, NULL); clks[TEGRA30_CLK_PLL_M_OUT1] = clk;
@@ -990,7 +990,7 @@ static void __init tegra30_super_clk_ini /* SCLK */ clk = tegra_clk_register_super_mux("sclk", sclk_parents, ARRAY_SIZE(sclk_parents), - CLK_SET_RATE_PARENT, + CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, clk_base + SCLK_BURST_POLICY, 0, 4, 0, 0, NULL); clks[TEGRA30_CLK_SCLK] = clk; @@ -1060,9 +1060,6 @@ static void __init tegra30_periph_clk_in CLK_SET_RATE_NO_REPARENT, clk_base + CLK_SOURCE_EMC, 30, 2, 0, &emc_lock); - clk = tegra_clk_register_periph_gate("emc", "emc_mux", 0, clk_base, 0, - 57, periph_clk_enb_refcnt); - clks[TEGRA30_CLK_EMC] = clk;
clk = tegra_clk_register_mc("mc", "emc_mux", clk_base + CLK_SOURCE_EMC, &emc_lock); @@ -1252,10 +1249,7 @@ static struct tegra_clk_init_table init_ { TEGRA30_CLK_SDMMC1, TEGRA30_CLK_PLL_P, 48000000, 0 }, { TEGRA30_CLK_SDMMC2, TEGRA30_CLK_PLL_P, 48000000, 0 }, { TEGRA30_CLK_SDMMC3, TEGRA30_CLK_PLL_P, 48000000, 0 }, - { TEGRA30_CLK_PLL_M, TEGRA30_CLK_CLK_MAX, 0, 1 }, - { TEGRA30_CLK_PCLK, TEGRA30_CLK_CLK_MAX, 0, 1 }, { TEGRA30_CLK_CSITE, TEGRA30_CLK_CLK_MAX, 0, 1 }, - { TEGRA30_CLK_EMC, TEGRA30_CLK_CLK_MAX, 0, 1 }, { TEGRA30_CLK_MSELECT, TEGRA30_CLK_CLK_MAX, 0, 1 }, { TEGRA30_CLK_SBC1, TEGRA30_CLK_PLL_P, 100000000, 0 }, { TEGRA30_CLK_SBC2, TEGRA30_CLK_PLL_P, 100000000, 0 },
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ryo Kodama ryo.kodama.vz@renesas.com
commit 6225f9c64b40bc8a22503e9cda70f55d7a9dd3c6 upstream.
This patch fixes an issue that is possible to set mismatch value to duty for R-Car PWM if we input the following commands:
# cd /sys/class/pwm/<pwmchip>/ # echo 0 > export # cd pwm0 # echo 30 > period # echo 30 > duty_cycle # echo 0 > duty_cycle # cat duty_cycle 0 # echo 1 > enable --> Then, the actual duty_cycle is 30, not 0.
So, this patch adds a condition into rcar_pwm_config() to fix this issue.
Signed-off-by: Ryo Kodama ryo.kodama.vz@renesas.com [shimoda: revise the commit log and add Fixes and Cc tags] Fixes: ed6c1476bf7f ("pwm: Add support for R-Car PWM Timer") Cc: Cc: stable@vger.kernel.org # v4.4+ Signed-off-by: Yoshihiro Shimoda yoshihiro.shimoda.uh@renesas.com Signed-off-by: Thierry Reding thierry.reding@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/pwm/pwm-rcar.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
--- a/drivers/pwm/pwm-rcar.c +++ b/drivers/pwm/pwm-rcar.c @@ -156,8 +156,12 @@ static int rcar_pwm_config(struct pwm_ch if (div < 0) return div;
- /* Let the core driver set pwm->period if disabled and duty_ns == 0 */ - if (!pwm_is_enabled(pwm) && !duty_ns) + /* + * Let the core driver set pwm->period if disabled and duty_ns == 0. + * But, this driver should prevent to set the new duty_ns if current + * duty_cycle is not set + */ + if (!pwm_is_enabled(pwm) && !duty_ns && !pwm->state.duty_cycle) return 0;
rcar_pwm_update(rp, RCAR_PWMCR_SYNC, RCAR_PWMCR_SYNC, RCAR_PWMCR);
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Wang sean.wang@mediatek.com
commit 360cc036563db27881ce08049f69138438f2ddd0 upstream.
Since the offset for both registers, PWMDWIDTH and PWMTHRES, used to control PWM4 or PWM5 are distinct from the other PWMs, whose wrong programming on PWM hardware causes waveform cannot be output as expected. Thus, the patch adds the extra condition for fixing up the weird case to let PWM4 or PWM5 able to work on MT7623.
v1 -> v2: use pwm45_fixup naming instead of pwm45_quirk v2 -> v3: add more tags for Reviewed-by, Fixes, and Cc stable
Cc: stable@vger.kernel.org Fixes: caf065f8fd58 ("pwm: Add MediaTek PWM support") Signed-off-by: Sean Wang sean.wang@mediatek.com Reviewed-by: Matthias Brugger matthias.bgg@gmail.com Cc: Zhi Mao zhi.mao@mediatek.com Cc: John Crispin john@phrozen.org Cc: Matthias Brugger matthias.bgg@gmail.com Signed-off-by: Thierry Reding thierry.reding@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/pwm/pwm-mediatek.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-)
--- a/drivers/pwm/pwm-mediatek.c +++ b/drivers/pwm/pwm-mediatek.c @@ -29,7 +29,9 @@ #define PWMGDUR 0x0c #define PWMWAVENUM 0x28 #define PWMDWIDTH 0x2c +#define PWM45DWIDTH_FIXUP 0x30 #define PWMTHRES 0x30 +#define PWM45THRES_FIXUP 0x34
#define PWM_CLK_DIV_MAX 7
@@ -54,6 +56,7 @@ static const char * const mtk_pwm_clk_na
struct mtk_pwm_platform_data { unsigned int num_pwms; + bool pwm45_fixup; };
/** @@ -66,6 +69,7 @@ struct mtk_pwm_chip { struct pwm_chip chip; void __iomem *regs; struct clk *clks[MTK_CLK_MAX]; + const struct mtk_pwm_platform_data *soc; };
static const unsigned int mtk_pwm_reg_offset[] = { @@ -131,7 +135,8 @@ static int mtk_pwm_config(struct pwm_chi { struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip); struct clk *clk = pc->clks[MTK_CLK_PWM1 + pwm->hwpwm]; - u32 resolution, clkdiv = 0; + u32 resolution, clkdiv = 0, reg_width = PWMDWIDTH, + reg_thres = PWMTHRES; int ret;
ret = mtk_pwm_clk_enable(chip, pwm); @@ -151,9 +156,18 @@ static int mtk_pwm_config(struct pwm_chi return -EINVAL; }
+ if (pc->soc->pwm45_fixup && pwm->hwpwm > 2) { + /* + * PWM[4,5] has distinct offset for PWMDWIDTH and PWMTHRES + * from the other PWMs on MT7623. + */ + reg_width = PWM45DWIDTH_FIXUP; + reg_thres = PWM45THRES_FIXUP; + } + mtk_pwm_writel(pc, pwm->hwpwm, PWMCON, BIT(15) | clkdiv); - mtk_pwm_writel(pc, pwm->hwpwm, PWMDWIDTH, period_ns / resolution); - mtk_pwm_writel(pc, pwm->hwpwm, PWMTHRES, duty_ns / resolution); + mtk_pwm_writel(pc, pwm->hwpwm, reg_width, period_ns / resolution); + mtk_pwm_writel(pc, pwm->hwpwm, reg_thres, duty_ns / resolution);
mtk_pwm_clk_disable(chip, pwm);
@@ -211,6 +225,7 @@ static int mtk_pwm_probe(struct platform data = of_device_get_match_data(&pdev->dev); if (data == NULL) return -EINVAL; + pc->soc = data;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); pc->regs = devm_ioremap_resource(&pdev->dev, res); @@ -251,14 +266,17 @@ static int mtk_pwm_remove(struct platfor
static const struct mtk_pwm_platform_data mt2712_pwm_data = { .num_pwms = 8, + .pwm45_fixup = false, };
static const struct mtk_pwm_platform_data mt7622_pwm_data = { .num_pwms = 6, + .pwm45_fixup = false, };
static const struct mtk_pwm_platform_data mt7623_pwm_data = { .num_pwms = 5, + .pwm45_fixup = true, };
static const struct of_device_id mtk_pwm_of_match[] = {
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Wang sean.wang@mediatek.com
commit 04c0a4e00dc11fedc0b0a8593adcf0f4310505d4 upstream.
Add a way that turning resolution from in nanosecond into in picosecond to improve noticeably almost 4.5% precision.
It's necessary to hold the new resolution with type u64 and thus related operations on u64 are applied instead in those rate calculations.
And the patch has a dependency on [1].
[1] http://lists.infradead.org/pipermail/linux-mediatek/2018-March/012225.html
Cc: stable@vger.kernel.org Fixes: caf065f8fd58 ("pwm: Add MediaTek PWM support") Signed-off-by: Sean Wang sean.wang@mediatek.com Signed-off-by: Thierry Reding thierry.reding@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/pwm/pwm-mediatek.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
--- a/drivers/pwm/pwm-mediatek.c +++ b/drivers/pwm/pwm-mediatek.c @@ -135,19 +135,25 @@ static int mtk_pwm_config(struct pwm_chi { struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip); struct clk *clk = pc->clks[MTK_CLK_PWM1 + pwm->hwpwm]; - u32 resolution, clkdiv = 0, reg_width = PWMDWIDTH, + u32 clkdiv = 0, cnt_period, cnt_duty, reg_width = PWMDWIDTH, reg_thres = PWMTHRES; + u64 resolution; int ret;
ret = mtk_pwm_clk_enable(chip, pwm); if (ret < 0) return ret;
- resolution = NSEC_PER_SEC / clk_get_rate(clk); + /* Using resolution in picosecond gets accuracy higher */ + resolution = (u64)NSEC_PER_SEC * 1000; + do_div(resolution, clk_get_rate(clk));
- while (period_ns / resolution > 8191) { + cnt_period = DIV_ROUND_CLOSEST_ULL((u64)period_ns * 1000, resolution); + while (cnt_period > 8191) { resolution *= 2; clkdiv++; + cnt_period = DIV_ROUND_CLOSEST_ULL((u64)period_ns * 1000, + resolution); }
if (clkdiv > PWM_CLK_DIV_MAX) { @@ -165,9 +171,10 @@ static int mtk_pwm_config(struct pwm_chi reg_thres = PWM45THRES_FIXUP; }
+ cnt_duty = DIV_ROUND_CLOSEST_ULL((u64)duty_ns * 1000, resolution); mtk_pwm_writel(pc, pwm->hwpwm, PWMCON, BIT(15) | clkdiv); - mtk_pwm_writel(pc, pwm->hwpwm, reg_width, period_ns / resolution); - mtk_pwm_writel(pc, pwm->hwpwm, reg_thres, duty_ns / resolution); + mtk_pwm_writel(pc, pwm->hwpwm, reg_width, cnt_period); + mtk_pwm_writel(pc, pwm->hwpwm, reg_thres, cnt_duty);
mtk_pwm_clk_disable(chip, pwm);
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikhail Lappo mikhail.lappo@esrlabs.com
commit cf1ba1d73a33944d8c1a75370a35434bf146b8a7 upstream.
When device boots with T > T_trip_1 and requests interrupt, the race condition takes place. The interrupt comes before THERMAL_DEVICE_ENABLED is set. This leads to an attempt to reading sensor value from irq and disabling the sensor, based on the data->mode field, which expected to be THERMAL_DEVICE_ENABLED, but still stays as THERMAL_DEVICE_DISABLED. Afher this issue sensor is never re-enabled, as the driver state is wrong.
Fix this problem by setting the 'data' members prior to requesting the interrupts.
Fixes: 37713a1e8e4c ("thermal: imx: implement thermal alarm interrupt handling") Cc: stable@vger.kernel.org Signed-off-by: Mikhail Lappo mikhail.lappo@esrlabs.com Signed-off-by: Fabio Estevam fabio.estevam@nxp.com Reviewed-by: Philipp Zabel p.zabel@pengutronix.de Acked-by: Dong Aisheng aisheng.dong@nxp.com Signed-off-by: Zhang Rui rui.zhang@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/thermal/imx_thermal.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/thermal/imx_thermal.c +++ b/drivers/thermal/imx_thermal.c @@ -637,6 +637,9 @@ static int imx_thermal_probe(struct plat regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN); regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_MEASURE_TEMP);
+ data->irq_enabled = true; + data->mode = THERMAL_DEVICE_ENABLED; + ret = devm_request_threaded_irq(&pdev->dev, data->irq, imx_thermal_alarm_irq, imx_thermal_alarm_irq_thread, 0, "imx_thermal", data); @@ -649,9 +652,6 @@ static int imx_thermal_probe(struct plat return ret; }
- data->irq_enabled = true; - data->mode = THERMAL_DEVICE_ENABLED; - return 0; }
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Wang sean.wang@mediatek.com
commit 55a5fcafe3a94e8a0777bb993d09107d362258d2 upstream.
Just add binding for a fixed-factor clock axisel_d4, which would be referenced by PWM devices on MT7623 or MT2701 SoC.
Cc: stable@vger.kernel.org Fixes: 1de9b21633d6 ("clk: mediatek: Add dt-bindings for MT2701 clocks") Signed-off-by: Sean Wang sean.wang@mediatek.com Reviewed-by: Rob Herring robh@kernel.org Cc: Mark Rutland mark.rutland@arm.com Cc: devicetree@vger.kernel.org Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- include/dt-bindings/clock/mt2701-clk.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/include/dt-bindings/clock/mt2701-clk.h +++ b/include/dt-bindings/clock/mt2701-clk.h @@ -176,7 +176,8 @@ #define CLK_TOP_AUD_EXT1 156 #define CLK_TOP_AUD_EXT2 157 #define CLK_TOP_NFI1X_PAD 158 -#define CLK_TOP_NR 159 +#define CLK_TOP_AXISEL_D4 159 +#define CLK_TOP_NR 160
/* APMIXEDSYS */
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Igor Pylypiv igor.pylypiv@gmail.com
commit 977f6f68331f94bb72ad84ee96b7b87ce737d89d upstream.
F71808FG_FLAG_WD_EN defines bit position, not a bitmask
Signed-off-by: Igor Pylypiv igor.pylypiv@gmail.com Reviewed-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Wim Van Sebroeck wim@iguana.be Cc: stable stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/watchdog/f71808e_wdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/watchdog/f71808e_wdt.c +++ b/drivers/watchdog/f71808e_wdt.c @@ -496,7 +496,7 @@ static bool watchdog_is_running(void)
is_running = (superio_inb(watchdog.sioaddr, SIO_REG_ENABLE) & BIT(0)) && (superio_inb(watchdog.sioaddr, F71808FG_REG_WDT_CONF) - & F71808FG_FLAG_WD_EN); + & BIT(F71808FG_FLAG_WD_EN));
superio_exit(watchdog.sioaddr);
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher alexander.deucher@amd.com
commit 13b40935cf64f59b93cf1c716a2033488e5a228c upstream.
_PR3 doesn't seem to work properly, use ATPX instead.
Bug: https://bugs.freedesktop.org/show_bug.cgi?id=104064 Reviewed-by: Huang Rui ray.huang@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c @@ -569,6 +569,7 @@ static const struct amdgpu_px_quirk amdg { 0x1002, 0x6900, 0x1002, 0x0124, AMDGPU_PX_QUIRK_FORCE_ATPX }, { 0x1002, 0x6900, 0x1028, 0x0812, AMDGPU_PX_QUIRK_FORCE_ATPX }, { 0x1002, 0x6900, 0x1028, 0x0813, AMDGPU_PX_QUIRK_FORCE_ATPX }, + { 0x1002, 0x67DF, 0x1028, 0x0774, AMDGPU_PX_QUIRK_FORCE_ATPX }, { 0, 0, 0, 0, 0 }, };
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marc Zyngier marc.zyngier@arm.com
commit 5f9e93fed4d45e9a8f84728aff1a8f2ab8922902 upstream.
Calling request_irq() followed by disable_irq() is usually a bad idea, specially if the interrupt can be pending, and you're not yet in a position to handle it.
This is exactly what happens on my kevin system when rebooting in a second kernel using kexec: Some interrupt is left pending from the previous kernel, and we take it too early, before disable_irq() could do anything.
Let's clear the pending interrupts as we initialize the HW, and move the interrupt request after that point. This ensures that we're in a sane state when the interrupt is requested.
Cc: stable@vger.kernel.org Signed-off-by: Marc Zyngier marc.zyngier@arm.com [adapted to recent rockchip-drm changes] Signed-off-by: Heiko Stuebner heiko@sntech.de Link: https://patchwork.freedesktop.org/patch/msgid/20180220130120.5254-2-marc.zyn... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-)
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -1414,6 +1414,9 @@ static int vop_initial(struct vop *vop) usleep_range(10, 20); reset_control_deassert(ahb_rst);
+ VOP_INTR_SET_TYPE(vop, clear, INTR_MASK, 1); + VOP_INTR_SET_TYPE(vop, enable, INTR_MASK, 0); + memcpy(vop->regsbak, vop->regs, vop->len);
VOP_REG_SET(vop, misc, global_regdone_en, 1); @@ -1569,17 +1572,9 @@ static int vop_bind(struct device *dev,
mutex_init(&vop->vsync_mutex);
- ret = devm_request_irq(dev, vop->irq, vop_isr, - IRQF_SHARED, dev_name(dev), vop); - if (ret) - return ret; - - /* IRQ is initially disabled; it gets enabled in power_on */ - disable_irq(vop->irq); - ret = vop_create_crtc(vop); if (ret) - goto err_enable_irq; + return ret;
pm_runtime_enable(&pdev->dev);
@@ -1590,13 +1585,19 @@ static int vop_bind(struct device *dev, goto err_disable_pm_runtime; }
+ ret = devm_request_irq(dev, vop->irq, vop_isr, + IRQF_SHARED, dev_name(dev), vop); + if (ret) + goto err_disable_pm_runtime; + + /* IRQ is initially disabled; it gets enabled in power_on */ + disable_irq(vop->irq); + return 0;
err_disable_pm_runtime: pm_runtime_disable(&pdev->dev); vop_destroy_crtc(vop); -err_enable_irq: - enable_irq(vop->irq); /* To balance out the disable_irq above */ return ret; }
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nico Sneck nicosneck@hotmail.com
commit b1550359d1eb392ee54f7cf47cffcfe0a602f6a7 upstream.
With this the dGPU turns on correctly.
Signed-off-by: Nico Sneck nicosneck@hotmail.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/gpu/drm/radeon/radeon_device.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -139,6 +139,10 @@ static struct radeon_px_quirk radeon_px_ * https://bugs.freedesktop.org/show_bug.cgi?id=101491 */ { PCI_VENDOR_ID_ATI, 0x6741, 0x1043, 0x2122, RADEON_PX_QUIRK_DISABLE_PX }, + /* Asus K73TK laptop with AMD A6-3420M APU and Radeon 7670m GPU + * https://bugzilla.kernel.org/show_bug.cgi?id=51381#c52 + */ + { PCI_VENDOR_ID_ATI, 0x6840, 0x1043, 0x2123, RADEON_PX_QUIRK_DISABLE_PX }, { 0, 0, 0, 0, 0 }, };
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai tiwai@suse.de
commit 8a56ef4f3ffba9ebf4967b61ef600b0a7ba10f11 upstream.
Some rawmidi compat ioctls lack of the input substream checks (although they do check only for rfile->output). This many eventually lead to an Oops as NULL substream is passed to the rawmidi core functions.
Fix it by adding the proper checks before each function call.
The bug was spotted by syzkaller.
Reported-by: syzbot+f7a0348affc3b67bc617@syzkaller.appspotmail.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/rawmidi_compat.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
--- a/sound/core/rawmidi_compat.c +++ b/sound/core/rawmidi_compat.c @@ -36,8 +36,6 @@ static int snd_rawmidi_ioctl_params_comp struct snd_rawmidi_params params; unsigned int val;
- if (rfile->output == NULL) - return -EINVAL; if (get_user(params.stream, &src->stream) || get_user(params.buffer_size, &src->buffer_size) || get_user(params.avail_min, &src->avail_min) || @@ -46,8 +44,12 @@ static int snd_rawmidi_ioctl_params_comp params.no_active_sensing = val; switch (params.stream) { case SNDRV_RAWMIDI_STREAM_OUTPUT: + if (!rfile->output) + return -EINVAL; return snd_rawmidi_output_params(rfile->output, ¶ms); case SNDRV_RAWMIDI_STREAM_INPUT: + if (!rfile->input) + return -EINVAL; return snd_rawmidi_input_params(rfile->input, ¶ms); } return -EINVAL; @@ -67,16 +69,18 @@ static int snd_rawmidi_ioctl_status_comp int err; struct snd_rawmidi_status status;
- if (rfile->output == NULL) - return -EINVAL; if (get_user(status.stream, &src->stream)) return -EFAULT;
switch (status.stream) { case SNDRV_RAWMIDI_STREAM_OUTPUT: + if (!rfile->output) + return -EINVAL; err = snd_rawmidi_output_status(rfile->output, &status); break; case SNDRV_RAWMIDI_STREAM_INPUT: + if (!rfile->input) + return -EINVAL; err = snd_rawmidi_input_status(rfile->input, &status); break; default: @@ -112,16 +116,18 @@ static int snd_rawmidi_ioctl_status_x32( int err; struct snd_rawmidi_status status;
- if (rfile->output == NULL) - return -EINVAL; if (get_user(status.stream, &src->stream)) return -EFAULT;
switch (status.stream) { case SNDRV_RAWMIDI_STREAM_OUTPUT: + if (!rfile->output) + return -EINVAL; err = snd_rawmidi_output_status(rfile->output, &status); break; case SNDRV_RAWMIDI_STREAM_INPUT: + if (!rfile->input) + return -EINVAL; err = snd_rawmidi_input_status(rfile->input, &status); break; default:
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Wang davidwang@zhaoxin.com
commit af52f9982e410edac21ca4b49563053ffc9da1eb upstream.
This patch is used to tell kernel that new VIA HDAC controller also support no-snoop path.
[ minor coding style fix by tiwai ]
Signed-off-by: David Wang davidwang@zhaoxin.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_intel.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1645,7 +1645,8 @@ static void azx_check_snoop_available(st */ u8 val; pci_read_config_byte(chip->pci, 0x42, &val); - if (!(val & 0x80) && chip->pci->revision == 0x30) + if (!(val & 0x80) && (chip->pci->revision == 0x30 || + chip->pci->revision == 0x20)) snoop = false; }
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hui Wang hui.wang@canonical.com
commit 3ce0d5aa265bcc0a4b281cb0cabf92491276101b upstream.
Otherwise, the pin will be regarded as microphone, and the jack name is "Mic Phantom", it is always on in the pulseaudio even nothing is plugged into the jack. So the UI is confusing to users since the microphone always shows up in the UI even there is no microphone plugged.
After adding this flag, the jack name is "Headset Mic Phantom", then the pulseaudio can handle its detection correctly.
Fixes: f0ba9d699e5c ("ALSA: hda/realtek - Fix Dell headset Mic can't record") Cc: stable@vger.kernel.org Signed-off-by: Hui Wang hui.wang@canonical.com 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, 2 insertions(+)
--- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6370,6 +6370,8 @@ static const struct hda_fixup alc269_fix { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */ { } }, + .chained = true, + .chain_id = ALC269_FIXUP_HEADSET_MIC }, };
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hui Wang hui.wang@canonical.com
commit a3dafb2200bf3c13905a088e82ae11f1eb275a83 upstream.
There are two front mics on this machine, if we don't adjust the location for one of them, they will have the same mixer name, pulseaudio can't handle this situation.
After applying this FIXUP, they will have different mixer name, then pulseaudio can handle them correctly.
Cc: stable@vger.kernel.org Signed-off-by: Hui Wang hui.wang@canonical.com 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 @@ -6575,6 +6575,7 @@ static const struct snd_pci_quirk alc269 SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), SND_PCI_QUIRK(0x17aa, 0x310c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION), + SND_PCI_QUIRK(0x17aa, 0x3138, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION), SND_PCI_QUIRK(0x17aa, 0x313c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION), SND_PCI_QUIRK(0x17aa, 0x3112, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o tytso@mit.edu
commit 43838a23a05fbd13e47d750d3dfd77001536dd33 upstream.
The crng_init variable has three states:
0: The CRNG is not initialized at all 1: The CRNG has a small amount of entropy, hopefully good enough for early-boot, non-cryptographical use cases 2: The CRNG is fully initialized and we are sure it is safe for cryptographic use cases.
The crng_ready() function should only return true once we are in the last state. This addresses CVE-2018-1108.
Reported-by: Jann Horn jannh@google.com Fixes: e192be9d9a30 ("random: replace non-blocking pool...") Cc: stable@kernel.org # 4.8+ Signed-off-by: Theodore Ts'o tytso@mit.edu Reviewed-by: Jann Horn jannh@google.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/char/random.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
--- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -427,7 +427,7 @@ struct crng_state primary_crng = { * its value (from 0->1->2). */ static int crng_init = 0; -#define crng_ready() (likely(crng_init > 0)) +#define crng_ready() (likely(crng_init > 1)) static int crng_init_cnt = 0; #define CRNG_INIT_CNT_THRESH (2*CHACHA20_KEY_SIZE) static void _extract_crng(struct crng_state *crng, @@ -793,7 +793,7 @@ static int crng_fast_load(const char *cp
if (!spin_trylock_irqsave(&primary_crng.lock, flags)) return 0; - if (crng_ready()) { + if (crng_init != 0) { spin_unlock_irqrestore(&primary_crng.lock, flags); return 0; } @@ -855,7 +855,7 @@ static void _extract_crng(struct crng_st { unsigned long v, flags;
- if (crng_init > 1 && + if (crng_ready() && time_after(jiffies, crng->init_time + CRNG_RESEED_INTERVAL)) crng_reseed(crng, crng == &primary_crng ? &input_pool : NULL); spin_lock_irqsave(&crng->lock, flags); @@ -1141,7 +1141,7 @@ void add_interrupt_randomness(int irq, i fast_mix(fast_pool); add_interrupt_bench(cycles);
- if (!crng_ready()) { + if (unlikely(crng_init == 0)) { if ((fast_pool->count >= 64) && crng_fast_load((char *) fast_pool->pool, sizeof(fast_pool->pool))) { @@ -2214,7 +2214,7 @@ void add_hwgenerator_randomness(const ch { struct entropy_store *poolp = &input_pool;
- if (!crng_ready()) { + if (unlikely(crng_init == 0)) { crng_fast_load(buffer, count); return; }
On Sun, Apr 22, 2018 at 03:53:03PM +0200, Greg Kroah-Hartman wrote:
4.16-stable review patch. If anyone has any objections, please let me know.
From: Theodore Ts'o tytso@mit.edu
commit 43838a23a05fbd13e47d750d3dfd77001536dd33 upstream.
The crng_init variable has three states:
0: The CRNG is not initialized at all 1: The CRNG has a small amount of entropy, hopefully good enough for early-boot, non-cryptographical use cases 2: The CRNG is fully initialized and we are sure it is safe for cryptographic use cases.
The crng_ready() function should only return true once we are in the last state. This addresses CVE-2018-1108.
Reported-by: Jann Horn jannh@google.com Fixes: e192be9d9a30 ("random: replace non-blocking pool...") Cc: stable@kernel.org # 4.8+ Signed-off-by: Theodore Ts'o tytso@mit.edu Reviewed-by: Jann Horn jannh@google.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
This patch has caused a regression on 4.16 using kselftest lib/printf.sh - specifically, when it runs "/sbin/modprobe test_printf". This regression has been detected on arm64 dragonboard 410c (not seen on other arm64 or x86_64 devices).
/sbin/modprobe test_printf [ 22.725551] test_printf: hashing plain 'p' has unexpected format [ 22.726031] test_printf: failed 1 out of 236 tests modprobe: ERROR: could not insert 'test_printf': Invalid argument
This problem has not been seen on 4.9 or 4.14 under the same conditions.
Dan
drivers/char/random.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
--- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -427,7 +427,7 @@ struct crng_state primary_crng = {
- its value (from 0->1->2).
*/ static int crng_init = 0; -#define crng_ready() (likely(crng_init > 0)) +#define crng_ready() (likely(crng_init > 1)) static int crng_init_cnt = 0; #define CRNG_INIT_CNT_THRESH (2*CHACHA20_KEY_SIZE) static void _extract_crng(struct crng_state *crng, @@ -793,7 +793,7 @@ static int crng_fast_load(const char *cp if (!spin_trylock_irqsave(&primary_crng.lock, flags)) return 0;
- if (crng_ready()) {
- if (crng_init != 0) { spin_unlock_irqrestore(&primary_crng.lock, flags); return 0; }
@@ -855,7 +855,7 @@ static void _extract_crng(struct crng_st { unsigned long v, flags;
- if (crng_init > 1 &&
- if (crng_ready() && time_after(jiffies, crng->init_time + CRNG_RESEED_INTERVAL)) crng_reseed(crng, crng == &primary_crng ? &input_pool : NULL); spin_lock_irqsave(&crng->lock, flags);
@@ -1141,7 +1141,7 @@ void add_interrupt_randomness(int irq, i fast_mix(fast_pool); add_interrupt_bench(cycles);
- if (!crng_ready()) {
- if (unlikely(crng_init == 0)) { if ((fast_pool->count >= 64) && crng_fast_load((char *) fast_pool->pool, sizeof(fast_pool->pool))) {
@@ -2214,7 +2214,7 @@ void add_hwgenerator_randomness(const ch { struct entropy_store *poolp = &input_pool;
- if (!crng_ready()) {
- if (unlikely(crng_init == 0)) { crng_fast_load(buffer, count); return; }
On Fri, Apr 27, 2018 at 11:34:43AM -0500, Dan Rue wrote:
On Sun, Apr 22, 2018 at 03:53:03PM +0200, Greg Kroah-Hartman wrote:
4.16-stable review patch. If anyone has any objections, please let me know.
From: Theodore Ts'o tytso@mit.edu
commit 43838a23a05fbd13e47d750d3dfd77001536dd33 upstream.
The crng_init variable has three states:
0: The CRNG is not initialized at all 1: The CRNG has a small amount of entropy, hopefully good enough for early-boot, non-cryptographical use cases 2: The CRNG is fully initialized and we are sure it is safe for cryptographic use cases.
The crng_ready() function should only return true once we are in the last state. This addresses CVE-2018-1108.
Reported-by: Jann Horn jannh@google.com Fixes: e192be9d9a30 ("random: replace non-blocking pool...") Cc: stable@kernel.org # 4.8+ Signed-off-by: Theodore Ts'o tytso@mit.edu Reviewed-by: Jann Horn jannh@google.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
This patch has caused a regression on 4.16 using kselftest lib/printf.sh
- specifically, when it runs "/sbin/modprobe test_printf". This
regression has been detected on arm64 dragonboard 410c (not seen on other arm64 or x86_64 devices).
/sbin/modprobe test_printf [ 22.725551] test_printf: hashing plain 'p' has unexpected format [ 22.726031] test_printf: failed 1 out of 236 tests modprobe: ERROR: could not insert 'test_printf': Invalid argument
This problem has not been seen on 4.9 or 4.14 under the same conditions.
Does 4.17-rc2 also fail like this?
You all are testing the -rc releases, right? :)
I think the random changes that will be in 4.17-rc3 should fix this, and if so, I'll suck them in here too. But testing that would be good to see happen...
thanks,
greg k-h
On Sat, Apr 28, 2018 at 08:00:03AM +0200, Greg Kroah-Hartman wrote:
On Fri, Apr 27, 2018 at 11:34:43AM -0500, Dan Rue wrote:
On Sun, Apr 22, 2018 at 03:53:03PM +0200, Greg Kroah-Hartman wrote:
4.16-stable review patch. If anyone has any objections, please let me know.
From: Theodore Ts'o tytso@mit.edu
commit 43838a23a05fbd13e47d750d3dfd77001536dd33 upstream.
The crng_init variable has three states:
0: The CRNG is not initialized at all 1: The CRNG has a small amount of entropy, hopefully good enough for early-boot, non-cryptographical use cases 2: The CRNG is fully initialized and we are sure it is safe for cryptographic use cases.
The crng_ready() function should only return true once we are in the last state. This addresses CVE-2018-1108.
Reported-by: Jann Horn jannh@google.com Fixes: e192be9d9a30 ("random: replace non-blocking pool...") Cc: stable@kernel.org # 4.8+ Signed-off-by: Theodore Ts'o tytso@mit.edu Reviewed-by: Jann Horn jannh@google.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
This patch has caused a regression on 4.16 using kselftest lib/printf.sh
- specifically, when it runs "/sbin/modprobe test_printf". This
regression has been detected on arm64 dragonboard 410c (not seen on other arm64 or x86_64 devices).
/sbin/modprobe test_printf [ 22.725551] test_printf: hashing plain 'p' has unexpected format [ 22.726031] test_printf: failed 1 out of 236 tests modprobe: ERROR: could not insert 'test_printf': Invalid argument
This problem has not been seen on 4.9 or 4.14 under the same conditions.
Does 4.17-rc2 also fail like this?
No, but I did see it in v4.17-rc2-102-g3442097b765c, and it was fixed in the subsequent build:
good: v4.17-rc2-64-g26ed24e429d8 bad: v4.17-rc2-102-g3442097b765c good: v4.17-rc2-104-g69bfd470f462
I haven't investigated deeper though, and I do not see any changes to random in those above revisions. This test passes on all the other mainline builds, including v4.17-rc2.
You all are testing the -rc releases, right? :)
We test every push to mainline and we test -next daily.
I think the random changes that will be in 4.17-rc3 should fix this, and if so, I'll suck them in here too. But testing that would be good to see happen...
Waiting is fine with me.
Thanks, Dan
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o tytso@mit.edu
commit dc12baacb95f205948f64dc936a47d89ee110117 upstream.
add_device_randomness() use of crng_fast_load() was highly problematic. Some callers of add_device_randomness() can pass in a large amount of static information. This would immediately promote the crng_init state from 0 to 1, without really doing much to initialize the primary_crng's internal state with something even vaguely unpredictable.
Since we don't have the speed constraints of add_interrupt_randomness(), we can do a better job mixing in the what unpredictability a device driver or architecture maintainer might see fit to give us, and do it in a way which does not bump the crng_init_cnt variable.
Also, since add_device_randomness() doesn't bump any entropy accounting in crng_init state 0, mix the device randomness into the input_pool entropy pool as well. This is related to CVE-2018-1108.
Reported-by: Jann Horn jannh@google.com Fixes: ee7998c50c26 ("random: do not ignore early device randomness") Cc: stable@kernel.org # 4.13+ Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/char/random.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 4 deletions(-)
--- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -786,6 +786,10 @@ static void crng_initialize(struct crng_ crng->init_time = jiffies - CRNG_RESEED_INTERVAL - 1; }
+/* + * crng_fast_load() can be called by code in the interrupt service + * path. So we can't afford to dilly-dally. + */ static int crng_fast_load(const char *cp, size_t len) { unsigned long flags; @@ -812,6 +816,51 @@ static int crng_fast_load(const char *cp return 1; }
+/* + * crng_slow_load() is called by add_device_randomness, which has two + * attributes. (1) We can't trust the buffer passed to it is + * guaranteed to be unpredictable (so it might not have any entropy at + * all), and (2) it doesn't have the performance constraints of + * crng_fast_load(). + * + * So we do something more comprehensive which is guaranteed to touch + * all of the primary_crng's state, and which uses a LFSR with a + * period of 255 as part of the mixing algorithm. Finally, we do + * *not* advance crng_init_cnt since buffer we may get may be something + * like a fixed DMI table (for example), which might very well be + * unique to the machine, but is otherwise unvarying. + */ +static int crng_slow_load(const char *cp, size_t len) +{ + unsigned long flags; + static unsigned char lfsr = 1; + unsigned char tmp; + unsigned i, max = CHACHA20_KEY_SIZE; + const char * src_buf = cp; + char * dest_buf = (char *) &primary_crng.state[4]; + + if (!spin_trylock_irqsave(&primary_crng.lock, flags)) + return 0; + if (crng_init != 0) { + spin_unlock_irqrestore(&primary_crng.lock, flags); + return 0; + } + if (len > max) + max = len; + + for (i = 0; i < max ; i++) { + tmp = lfsr; + lfsr >>= 1; + if (tmp & 1) + lfsr ^= 0xE1; + tmp = dest_buf[i % CHACHA20_KEY_SIZE]; + dest_buf[i % CHACHA20_KEY_SIZE] ^= src_buf[i % len] ^ lfsr; + lfsr += (tmp << 3) | (tmp >> 5); + } + spin_unlock_irqrestore(&primary_crng.lock, flags); + return 1; +} + static void crng_reseed(struct crng_state *crng, struct entropy_store *r) { unsigned long flags; @@ -981,10 +1030,8 @@ void add_device_randomness(const void *b unsigned long time = random_get_entropy() ^ jiffies; unsigned long flags;
- if (!crng_ready()) { - crng_fast_load(buf, size); - return; - } + if (!crng_ready() && size) + crng_slow_load(buf, size);
trace_add_device_randomness(size, _RET_IP_); spin_lock_irqsave(&input_pool.lock, flags);
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o tytso@mit.edu
commit 8ef35c866f8862df074a49a93b0309725812dea8 upstream.
Until the primary_crng is fully initialized, don't initialize the NUMA crng nodes. Otherwise users of /dev/urandom on NUMA systems before the CRNG is fully initialized can get very bad quality randomness. Of course everyone should move to getrandom(2) where this won't be an issue, but there's a lot of legacy code out there. This related to CVE-2018-1108.
Reported-by: Jann Horn jannh@google.com Fixes: 1e7f583af67b ("random: make /dev/urandom scalable for silly...") Cc: stable@kernel.org # 4.8+ Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/char/random.c | 46 +++++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 19 deletions(-)
--- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -786,6 +786,32 @@ static void crng_initialize(struct crng_ crng->init_time = jiffies - CRNG_RESEED_INTERVAL - 1; }
+#ifdef CONFIG_NUMA +static void numa_crng_init(void) +{ + int i; + struct crng_state *crng; + struct crng_state **pool; + + pool = kcalloc(nr_node_ids, sizeof(*pool), GFP_KERNEL|__GFP_NOFAIL); + for_each_online_node(i) { + crng = kmalloc_node(sizeof(struct crng_state), + GFP_KERNEL | __GFP_NOFAIL, i); + spin_lock_init(&crng->lock); + crng_initialize(crng); + pool[i] = crng; + } + mb(); + if (cmpxchg(&crng_node_pool, NULL, pool)) { + for_each_node(i) + kfree(pool[i]); + kfree(pool); + } +} +#else +static void numa_crng_init(void) {} +#endif + /* * crng_fast_load() can be called by code in the interrupt service * path. So we can't afford to dilly-dally. @@ -892,6 +918,7 @@ static void crng_reseed(struct crng_stat spin_unlock_irqrestore(&primary_crng.lock, flags); if (crng == &primary_crng && crng_init < 2) { invalidate_batched_entropy(); + numa_crng_init(); crng_init = 2; process_random_ready_list(); wake_up_interruptible(&crng_init_wait); @@ -1729,28 +1756,9 @@ static void init_std_data(struct entropy */ static int rand_initialize(void) { -#ifdef CONFIG_NUMA - int i; - struct crng_state *crng; - struct crng_state **pool; -#endif - init_std_data(&input_pool); init_std_data(&blocking_pool); crng_initialize(&primary_crng); - -#ifdef CONFIG_NUMA - pool = kcalloc(nr_node_ids, sizeof(*pool), GFP_KERNEL|__GFP_NOFAIL); - for_each_online_node(i) { - crng = kmalloc_node(sizeof(struct crng_state), - GFP_KERNEL | __GFP_NOFAIL, i); - spin_lock_init(&crng->lock); - crng_initialize(crng); - pool[i] = crng; - } - mb(); - crng_node_pool = pool; -#endif return 0; } early_initcall(rand_initialize);
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o tytso@mit.edu
commit 0bb29a849a6433b72e249eea7695477b02056e94 upstream.
Reported-by: Jann Horn jannh@google.com Fixes: 1e7f583af67b ("random: make /dev/urandom scalable for silly...") Cc: stable@kernel.org # 4.8+ Signed-off-by: Theodore Ts'o tytso@mit.edu Reviewed-by: Jann Horn jannh@google.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/char/random.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -905,7 +905,7 @@ static void crng_reseed(struct crng_stat _crng_backtrack_protect(&primary_crng, buf.block, CHACHA20_KEY_SIZE); } - spin_lock_irqsave(&primary_crng.lock, flags); + spin_lock_irqsave(&crng->lock, flags); for (i = 0; i < 8; i++) { unsigned long rv; if (!arch_get_random_seed_long(&rv) && @@ -915,7 +915,7 @@ static void crng_reseed(struct crng_stat } memzero_explicit(&buf, sizeof(buf)); crng->init_time = jiffies; - spin_unlock_irqrestore(&primary_crng.lock, flags); + spin_unlock_irqrestore(&crng->lock, flags); if (crng == &primary_crng && crng_init < 2) { invalidate_batched_entropy(); numa_crng_init();
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o tytso@mit.edu
commit d848e5f8e1ebdb227d045db55fe4f825e82965fa upstream.
Add a new ioctl which forces the the crng to be reseeded.
Signed-off-by: Theodore Ts'o tytso@mit.edu Cc: stable@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/char/random.c | 13 ++++++++++++- include/uapi/linux/random.h | 3 +++ 2 files changed, 15 insertions(+), 1 deletion(-)
--- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -429,6 +429,7 @@ struct crng_state primary_crng = { static int crng_init = 0; #define crng_ready() (likely(crng_init > 1)) static int crng_init_cnt = 0; +static unsigned long crng_global_init_time = 0; #define CRNG_INIT_CNT_THRESH (2*CHACHA20_KEY_SIZE) static void _extract_crng(struct crng_state *crng, __u32 out[CHACHA20_BLOCK_WORDS]); @@ -932,7 +933,8 @@ static void _extract_crng(struct crng_st unsigned long v, flags;
if (crng_ready() && - time_after(jiffies, crng->init_time + CRNG_RESEED_INTERVAL)) + (time_after(crng_global_init_time, crng->init_time) || + time_after(jiffies, crng->init_time + CRNG_RESEED_INTERVAL))) crng_reseed(crng, crng == &primary_crng ? &input_pool : NULL); spin_lock_irqsave(&crng->lock, flags); if (arch_get_random_long(&v)) @@ -1759,6 +1761,7 @@ static int rand_initialize(void) init_std_data(&input_pool); init_std_data(&blocking_pool); crng_initialize(&primary_crng); + crng_global_init_time = jiffies; return 0; } early_initcall(rand_initialize); @@ -1932,6 +1935,14 @@ static long random_ioctl(struct file *f, input_pool.entropy_count = 0; blocking_pool.entropy_count = 0; return 0; + case RNDRESEEDCRNG: + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + if (crng_init < 2) + return -ENODATA; + crng_reseed(&primary_crng, NULL); + crng_global_init_time = jiffies - 1; + return 0; default: return -EINVAL; } --- a/include/uapi/linux/random.h +++ b/include/uapi/linux/random.h @@ -35,6 +35,9 @@ /* Clear the entropy pool and associated counters. (Superuser only.) */ #define RNDCLEARPOOL _IO( 'R', 0x06 )
+/* Reseed CRNG. (Superuser only.) */ +#define RNDRESEEDCRNG _IO( 'R', 0x07 ) + struct rand_pool_info { int entropy_count; int buf_size;
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aaron Ma aaron.ma@canonical.com
commit 3e83eda467050f13fa69d888993458b76e733de9 upstream.
When Rayd touchscreen resumed from S3, it issues too many errors like: i2c_hid i2c-RAYD0001:00: i2c_hid_get_input: incomplete report (58/5442)
And all the report data are corrupted, touchscreen is unresponsive.
Fix this by re-sending report description command after resume. Add device ID as a quirk.
Cc: stable@vger.kernel.org Signed-off-by: Aaron Ma aaron.ma@canonical.com Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/hid/hid-ids.h | 3 +++ drivers/hid/i2c-hid/i2c-hid.c | 13 +++++++++++++ 2 files changed, 16 insertions(+)
--- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -519,6 +519,9 @@ #define I2C_VENDOR_ID_HANTICK 0x0911 #define I2C_PRODUCT_ID_HANTICK_5288 0x5288
+#define I2C_VENDOR_ID_RAYD 0x2386 +#define I2C_PRODUCT_ID_RAYD_3118 0x3118 + #define USB_VENDOR_ID_HANWANG 0x0b57 #define USB_DEVICE_ID_HANWANG_TABLET_FIRST 0x5000 #define USB_DEVICE_ID_HANWANG_TABLET_LAST 0x8fff --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c @@ -47,6 +47,7 @@ /* quirks to control the device */ #define I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV BIT(0) #define I2C_HID_QUIRK_NO_IRQ_AFTER_RESET BIT(1) +#define I2C_HID_QUIRK_RESEND_REPORT_DESCR BIT(2)
/* flags */ #define I2C_HID_STARTED 0 @@ -171,6 +172,8 @@ static const struct i2c_hid_quirks { I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV }, { I2C_VENDOR_ID_HANTICK, I2C_PRODUCT_ID_HANTICK_5288, I2C_HID_QUIRK_NO_IRQ_AFTER_RESET }, + { I2C_VENDOR_ID_RAYD, I2C_PRODUCT_ID_RAYD_3118, + I2C_HID_QUIRK_RESEND_REPORT_DESCR }, { 0, 0 } };
@@ -1220,6 +1223,16 @@ static int i2c_hid_resume(struct device if (ret) return ret;
+ /* RAYDIUM device (2386:3118) need to re-send report descr cmd + * after resume, after this it will be back normal. + * otherwise it issues too many incomplete reports. + */ + if (ihid->quirks & I2C_HID_QUIRK_RESEND_REPORT_DESCR) { + ret = i2c_hid_command(client, &hid_report_descr_cmd, NULL, 0); + if (!ret) + return ret; + } + if (hid->driver && hid->driver->reset_resume) { ret = hid->driver->reset_resume(hid); return ret;
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Torokhov dmitry.torokhov@gmail.com
commit 2e210bbb7429cdcf1a1a3ad00c1bf98bd9bf2452 upstream.
The commit 581c4484769e ("HID: input: map digitizer battery usage") assumed that devices having input (qas opposed to feature) report for battery strength would report the data on their own, without the need to be polled by the kernel; unfortunately it is not so. Many wireless mice do not send unsolicited reports with battery strength data and have to be polled explicitly. As a complication, stylus devices on digitizers are not normally connected to the base and thus can not be polled - the base can only determine battery strength in the stylus when it is in proximity.
To solve this issue, we add a special flag that tells the kernel to avoid polling the device (and expect unsolicited reports) and set it when report field with physical usage of digitizer stylus (HID_DG_STYLUS). Unless this flag is set, and we have not seen the unsolicited reports, the kernel will attempt to poll the device when userspace attempts to read "capacity" and "state" attributes of power_supply object corresponding to the devices battery.
Fixes: 581c4484769e ("HID: input: map digitizer battery usage") Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=198095 Cc: stable@vger.kernel.org Reported-and-tested-by: Martin van Es martin@mrvanes.com Signed-off-by: Dmitry Torokhov dmitry.torokhov@gmail.com Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/hid/hid-input.c | 24 +++++++++++++++++------- include/linux/hid.h | 9 ++++++++- 2 files changed, 25 insertions(+), 8 deletions(-)
--- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -387,7 +387,8 @@ static int hidinput_get_battery_property break;
case POWER_SUPPLY_PROP_CAPACITY: - if (dev->battery_report_type == HID_FEATURE_REPORT) { + if (dev->battery_status != HID_BATTERY_REPORTED && + !dev->battery_avoid_query) { value = hidinput_query_battery_capacity(dev); if (value < 0) return value; @@ -403,17 +404,17 @@ static int hidinput_get_battery_property break;
case POWER_SUPPLY_PROP_STATUS: - if (!dev->battery_reported && - dev->battery_report_type == HID_FEATURE_REPORT) { + if (dev->battery_status != HID_BATTERY_REPORTED && + !dev->battery_avoid_query) { value = hidinput_query_battery_capacity(dev); if (value < 0) return value;
dev->battery_capacity = value; - dev->battery_reported = true; + dev->battery_status = HID_BATTERY_QUERIED; }
- if (!dev->battery_reported) + if (dev->battery_status == HID_BATTERY_UNKNOWN) val->intval = POWER_SUPPLY_STATUS_UNKNOWN; else if (dev->battery_capacity == 100) val->intval = POWER_SUPPLY_STATUS_FULL; @@ -486,6 +487,14 @@ static int hidinput_setup_battery(struct dev->battery_report_type = report_type; dev->battery_report_id = field->report->id;
+ /* + * Stylus is normally not connected to the device and thus we + * can't query the device and get meaningful battery strength. + * We have to wait for the device to report it on its own. + */ + dev->battery_avoid_query = report_type == HID_INPUT_REPORT && + field->physical == HID_DG_STYLUS; + dev->battery = power_supply_register(&dev->dev, psy_desc, &psy_cfg); if (IS_ERR(dev->battery)) { error = PTR_ERR(dev->battery); @@ -530,9 +539,10 @@ static void hidinput_update_battery(stru
capacity = hidinput_scale_battery_capacity(dev, value);
- if (!dev->battery_reported || capacity != dev->battery_capacity) { + if (dev->battery_status != HID_BATTERY_REPORTED || + capacity != dev->battery_capacity) { dev->battery_capacity = capacity; - dev->battery_reported = true; + dev->battery_status = HID_BATTERY_REPORTED; power_supply_changed(dev->battery); } } --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -515,6 +515,12 @@ enum hid_type { HID_TYPE_USBNONE };
+enum hid_battery_status { + HID_BATTERY_UNKNOWN = 0, + HID_BATTERY_QUERIED, /* Kernel explicitly queried battery strength */ + HID_BATTERY_REPORTED, /* Device sent unsolicited battery strength report */ +}; + struct hid_driver; struct hid_ll_driver;
@@ -557,7 +563,8 @@ struct hid_device { /* device repo __s32 battery_max; __s32 battery_report_type; __s32 battery_report_id; - bool battery_reported; + enum hid_battery_status battery_status; + bool battery_avoid_query; #endif
unsigned int status; /* see STAT flags above */
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rodrigo Rivas Costa rodrigorivascosta@gmail.com
commit a955358d54695e4ad9f7d6489a7ac4d69a8fc711 upstream.
Doing `ioctl(HIDIOCGFEATURE)` in a tight loop on a hidraw device and then disconnecting the device, or unloading the driver, can cause a NULL pointer dereference.
When a hidraw device is destroyed it sets 0 to `dev->exist`. Most functions check 'dev->exist' before doing its work, but `hidraw_get_report()` was missing that check.
Cc: stable@vger.kernel.org Signed-off-by: Rodrigo Rivas Costa rodrigorivascosta@gmail.com Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/hid/hidraw.c | 5 +++++ 1 file changed, 5 insertions(+)
--- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c @@ -192,6 +192,11 @@ static ssize_t hidraw_get_report(struct int ret = 0, len; unsigned char report_number;
+ if (!hidraw_table[minor] || !hidraw_table[minor]->exist) { + ret = -ENODEV; + goto out; + } + dev = hidraw_table[minor]->hid;
if (!dev->ll_driver->raw_request) {
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aaron Armstrong Skomra skomra@gmail.com
commit 619d3a2922ce623ca2eca443cc936810d328317c upstream.
The code path for recent Bluetooth devices omits an exit report which resets all the values of the device.
Fixes: 4922cd26f0 ("HID: wacom: Support 2nd-gen Intuos Pro's Bluetooth classic interface") Cc: stable@vger.kernel.org # 4.11 Signed-off-by: Aaron Armstrong Skomra aaron.skomra@wacom.com Reviewed-by: Ping Cheng ping.cheng@wacom.com Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/hid/wacom_wac.c | 76 +++++++++++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 30 deletions(-)
--- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -689,6 +689,45 @@ static int wacom_intuos_get_tool_type(in return tool_type; }
+static void wacom_exit_report(struct wacom_wac *wacom) +{ + struct input_dev *input = wacom->pen_input; + struct wacom_features *features = &wacom->features; + unsigned char *data = wacom->data; + int idx = (features->type == INTUOS) ? (data[1] & 0x01) : 0; + + /* + * Reset all states otherwise we lose the initial states + * when in-prox next time + */ + input_report_abs(input, ABS_X, 0); + input_report_abs(input, ABS_Y, 0); + input_report_abs(input, ABS_DISTANCE, 0); + input_report_abs(input, ABS_TILT_X, 0); + input_report_abs(input, ABS_TILT_Y, 0); + if (wacom->tool[idx] >= BTN_TOOL_MOUSE) { + input_report_key(input, BTN_LEFT, 0); + input_report_key(input, BTN_MIDDLE, 0); + input_report_key(input, BTN_RIGHT, 0); + input_report_key(input, BTN_SIDE, 0); + input_report_key(input, BTN_EXTRA, 0); + input_report_abs(input, ABS_THROTTLE, 0); + input_report_abs(input, ABS_RZ, 0); + } else { + input_report_abs(input, ABS_PRESSURE, 0); + input_report_key(input, BTN_STYLUS, 0); + input_report_key(input, BTN_STYLUS2, 0); + input_report_key(input, BTN_TOUCH, 0); + input_report_abs(input, ABS_WHEEL, 0); + if (features->type >= INTUOS3S) + input_report_abs(input, ABS_Z, 0); + } + input_report_key(input, wacom->tool[idx], 0); + input_report_abs(input, ABS_MISC, 0); /* reset tool id */ + input_event(input, EV_MSC, MSC_SERIAL, wacom->serial[idx]); + wacom->id[idx] = 0; +} + static int wacom_intuos_inout(struct wacom_wac *wacom) { struct wacom_features *features = &wacom->features; @@ -741,36 +780,7 @@ static int wacom_intuos_inout(struct wac if (!wacom->id[idx]) return 1;
- /* - * Reset all states otherwise we lose the initial states - * when in-prox next time - */ - input_report_abs(input, ABS_X, 0); - input_report_abs(input, ABS_Y, 0); - input_report_abs(input, ABS_DISTANCE, 0); - input_report_abs(input, ABS_TILT_X, 0); - input_report_abs(input, ABS_TILT_Y, 0); - if (wacom->tool[idx] >= BTN_TOOL_MOUSE) { - input_report_key(input, BTN_LEFT, 0); - input_report_key(input, BTN_MIDDLE, 0); - input_report_key(input, BTN_RIGHT, 0); - input_report_key(input, BTN_SIDE, 0); - input_report_key(input, BTN_EXTRA, 0); - input_report_abs(input, ABS_THROTTLE, 0); - input_report_abs(input, ABS_RZ, 0); - } else { - input_report_abs(input, ABS_PRESSURE, 0); - input_report_key(input, BTN_STYLUS, 0); - input_report_key(input, BTN_STYLUS2, 0); - input_report_key(input, BTN_TOUCH, 0); - input_report_abs(input, ABS_WHEEL, 0); - if (features->type >= INTUOS3S) - input_report_abs(input, ABS_Z, 0); - } - input_report_key(input, wacom->tool[idx], 0); - input_report_abs(input, ABS_MISC, 0); /* reset tool id */ - input_event(input, EV_MSC, MSC_SERIAL, wacom->serial[idx]); - wacom->id[idx] = 0; + wacom_exit_report(wacom); return 2; }
@@ -1226,6 +1236,12 @@ static void wacom_intuos_pro2_bt_pen(str if (!valid) continue;
+ if (!prox) { + wacom->shared->stylus_in_proximity = false; + wacom_exit_report(wacom); + input_sync(pen_input); + return; + } if (range) { /* Fix rotation alignment: userspace expects zero at left */ int16_t rotation = (int16_t)get_unaligned_le16(&frame[9]);
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heiko Carstens heiko.carstens@de.ibm.com
commit 451239eb3d397bd197a79cc3aab943da41ba0905 upstream.
Just add the new machine type number to the two places that matter.
Cc: stable@vger.kernel.org # v4.14+ Signed-off-by: Heiko Carstens heiko.carstens@de.ibm.com Signed-off-by: Martin Schwidefsky schwidefsky@de.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/s390/Kconfig | 8 ++++---- arch/s390/kernel/perf_cpum_cf_events.c | 1 + arch/s390/kernel/setup.c | 1 + 3 files changed, 6 insertions(+), 4 deletions(-)
--- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -289,12 +289,12 @@ config MARCH_Z13 older machines.
config MARCH_Z14 - bool "IBM z14" + bool "IBM z14 ZR1 and z14" select HAVE_MARCH_Z14_FEATURES help - Select this to enable optimizations for IBM z14 (3906 series). - The kernel will be slightly faster but will not work on older - machines. + Select this to enable optimizations for IBM z14 ZR1 and z14 (3907 + and 3906 series). The kernel will be slightly faster but will not + work on older machines.
endchoice
--- a/arch/s390/kernel/perf_cpum_cf_events.c +++ b/arch/s390/kernel/perf_cpum_cf_events.c @@ -583,6 +583,7 @@ __init const struct attribute_group **cp model = cpumcf_z13_pmu_event_attr; break; case 0x3906: + case 0x3907: model = cpumcf_z14_pmu_event_attr; break; default: --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -819,6 +819,7 @@ static int __init setup_hwcaps(void) strcpy(elf_platform, "z13"); break; case 0x3906: + case 0x3907: strcpy(elf_platform, "z14"); break; }
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matt Redfearn matt.redfearn@mips.com
commit b3d7e55c3f886493235bfee08e1e5a4a27cbcce8 upstream.
The micromips implementation of bzero additionally clobbers registers t7 & t8. Specify this in the clobbers list when invoking bzero.
Fixes: 26c5e07d1478 ("MIPS: microMIPS: Optimise 'memset' core library function.") Reported-by: James Hogan jhogan@kernel.org Signed-off-by: Matt Redfearn matt.redfearn@mips.com Cc: Ralf Baechle ralf@linux-mips.org Cc: linux-mips@linux-mips.org Cc: stable@vger.kernel.org # 3.10+ Patchwork: https://patchwork.linux-mips.org/patch/19110/ Signed-off-by: James Hogan jhogan@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/mips/include/asm/uaccess.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
--- a/arch/mips/include/asm/uaccess.h +++ b/arch/mips/include/asm/uaccess.h @@ -654,6 +654,13 @@ __clear_user(void __user *addr, __kernel { __kernel_size_t res;
+#ifdef CONFIG_CPU_MICROMIPS +/* micromips memset / bzero also clobbers t7 & t8 */ +#define bzero_clobbers "$4", "$5", "$6", __UA_t0, __UA_t1, "$15", "$24", "$31" +#else +#define bzero_clobbers "$4", "$5", "$6", __UA_t0, __UA_t1, "$31" +#endif /* CONFIG_CPU_MICROMIPS */ + if (eva_kernel_access()) { __asm__ __volatile__( "move\t$4, %1\n\t" @@ -663,7 +670,7 @@ __clear_user(void __user *addr, __kernel "move\t%0, $6" : "=r" (res) : "r" (addr), "r" (size) - : "$4", "$5", "$6", __UA_t0, __UA_t1, "$31"); + : bzero_clobbers); } else { might_fault(); __asm__ __volatile__( @@ -674,7 +681,7 @@ __clear_user(void __user *addr, __kernel "move\t%0, $6" : "=r" (res) : "r" (addr), "r" (size) - : "$4", "$5", "$6", __UA_t0, __UA_t1, "$31"); + : bzero_clobbers); }
return res;
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matt Redfearn matt.redfearn@mips.com
commit 8a8158c85e1e774a44fbe81106fa41138580dfd1 upstream.
The MIPS kernel memset / bzero implementation includes a small_memset branch which is used when the region to be set is smaller than a long (4 bytes on 32bit, 8 bytes on 64bit). The current small_memset implementation uses a simple store byte loop to write the destination. There are 2 issues with this implementation:
1. When EVA mode is active, user and kernel address spaces may overlap. Currently the use of the sb instruction means kernel mode addressing is always used and an intended write to userspace may actually overwrite some critical kernel data.
2. If the write triggers a page fault, for example by calling __clear_user(NULL, 2), instead of gracefully handling the fault, an OOPS is triggered.
Fix these issues by replacing the sb instruction with the EX() macro, which will emit EVA compatible instuctions as required. Additionally implement a fault fixup for small_memset which sets a2 to the number of bytes that could not be cleared (as defined by __clear_user).
Reported-by: Chuanhua Lei chuanhua.lei@intel.com Signed-off-by: Matt Redfearn matt.redfearn@mips.com Cc: Ralf Baechle ralf@linux-mips.org Cc: linux-mips@linux-mips.org Cc: stable@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/18975/ Signed-off-by: James Hogan jhogan@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/mips/lib/memset.S | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
--- a/arch/mips/lib/memset.S +++ b/arch/mips/lib/memset.S @@ -219,7 +219,7 @@ 1: PTR_ADDIU a0, 1 /* fill bytewise */ R10KCBARRIER(0(ra)) bne t1, a0, 1b - sb a1, -1(a0) + EX(sb, a1, -1(a0), .Lsmall_fixup@)
2: jr ra /* done */ move a2, zero @@ -260,6 +260,11 @@ jr ra andi v1, a2, STORMASK
+.Lsmall_fixup@: + PTR_SUBU a2, t1, a0 + jr ra + PTR_ADDIU a2, 1 + .endm
/*
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matt Redfearn matt.redfearn@mips.com
commit daf70d89f80c6e1772233da9e020114b1254e7e0 upstream.
The __clear_user function is defined to return the number of bytes that could not be cleared. From the underlying memset / bzero implementation this means setting register a2 to that number on return. Currently if a page fault is triggered within the memset_partial block, the value loaded into a2 on return is meaningless.
The label .Lpartial_fixup@ is jumped to on page fault. In order to work out how many bytes failed to copy, the exception handler should find how many bytes left in the partial block (andi a2, STORMASK), add that to the partial block end address (a2), and subtract the faulting address to get the remainder. Currently it incorrectly subtracts the partial block start address (t1), which has additionally been clobbered to generate a jump target in memset_partial. Fix this by adding the block end address instead.
This issue was found with the following test code: int j, k; for (j = 0; j < 512; j++) { if ((k = clear_user(NULL, j)) != j) { pr_err("clear_user (NULL %d) returned %d\n", j, k); } } Which now passes on Creator Ci40 (MIPS32) and Cavium Octeon II (MIPS64).
Suggested-by: James Hogan jhogan@kernel.org Signed-off-by: Matt Redfearn matt.redfearn@mips.com Cc: Ralf Baechle ralf@linux-mips.org Cc: linux-mips@linux-mips.org Cc: stable@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/19108/ Signed-off-by: James Hogan jhogan@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/mips/lib/memset.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/mips/lib/memset.S +++ b/arch/mips/lib/memset.S @@ -252,7 +252,7 @@ PTR_L t0, TI_TASK($28) andi a2, STORMASK LONG_L t0, THREAD_BUADDR(t0) - LONG_ADDU a2, t1 + LONG_ADDU a2, a0 jr ra LONG_SUBU a2, t0
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matt Redfearn matt.redfearn@mips.com
commit c96eebf07692e53bf4dd5987510d8b550e793598 upstream.
The label .Llast_fixup@ is jumped to on page fault within the final byte set loop of memset (on < MIPSR6 architectures). For some reason, in this fault handler, the v1 register is randomly set to a2 & STORMASK. This clobbers v1 for the calling function. This can be observed with the following test code:
static int __init __attribute__((optimize("O0"))) test_clear_user(void) { register int t asm("v1"); char *test; int j, k;
pr_info("\n\n\nTesting clear_user\n"); test = vmalloc(PAGE_SIZE);
for (j = 256; j < 512; j++) { t = 0xa5a5a5a5; if ((k = clear_user(test + PAGE_SIZE - 256, j)) != j - 256) { pr_err("clear_user (%px %d) returned %d\n", test + PAGE_SIZE - 256, j, k); } if (t != 0xa5a5a5a5) { pr_err("v1 was clobbered to 0x%x!\n", t); } }
return 0; } late_initcall(test_clear_user);
Which demonstrates that v1 is indeed clobbered (MIPS64):
Testing clear_user v1 was clobbered to 0x1! v1 was clobbered to 0x2! v1 was clobbered to 0x3! v1 was clobbered to 0x4! v1 was clobbered to 0x5! v1 was clobbered to 0x6! v1 was clobbered to 0x7!
Since the number of bytes that could not be set is already contained in a2, the andi placing a value in v1 is not necessary and actively harmful in clobbering v1.
Reported-by: James Hogan jhogan@kernel.org Signed-off-by: Matt Redfearn matt.redfearn@mips.com Cc: Ralf Baechle ralf@linux-mips.org Cc: linux-mips@linux-mips.org Cc: stable@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/19109/ Signed-off-by: James Hogan jhogan@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/mips/lib/memset.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/mips/lib/memset.S +++ b/arch/mips/lib/memset.S @@ -258,7 +258,7 @@
.Llast_fixup@: jr ra - andi v1, a2, STORMASK + nop
.Lsmall_fixup@: PTR_SUBU a2, t1, a0
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Neuling mikey@neuling.org
commit 13a83eac373c49c0a081cbcd137e79210fe78acd upstream.
On boot we save the configuration space of PCIe bridges. We do this so when we get an EEH event and everything gets reset that we can restore them.
Unfortunately we save this state before we've enabled the MMIO space on the bridges. Hence if we have to reset the bridge when we come back MMIO is not enabled and we end up taking an PE freeze when the driver starts accessing again.
This patch forces the memory/MMIO and bus mastering on when restoring bridges on EEH. Ideally we'd do this correctly by saving the configuration space writes later, but that will have to come later in a larger EEH rewrite. For now we have this simple fix.
The original bug can be triggered on a boston machine by doing: echo 0x8000000000000000 > /sys/kernel/debug/powerpc/PCI0001/err_injct_outbound On boston, this PHB has a PCIe switch on it. Without this patch, you'll see two EEH events, 1 expected and 1 the failure we are fixing here. The second EEH event causes the anything under the PHB to disappear (i.e. the i40e eth).
With this patch, only 1 EEH event occurs and devices properly recover.
Fixes: 652defed4875 ("powerpc/eeh: Check PCIe link after reset") Cc: stable@vger.kernel.org # v3.11+ Reported-by: Pridhiviraj Paidipeddi ppaidipe@linux.vnet.ibm.com Signed-off-by: Michael Neuling mikey@neuling.org Acked-by: Russell Currey ruscur@russell.cc Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/powerpc/kernel/eeh_pe.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/arch/powerpc/kernel/eeh_pe.c +++ b/arch/powerpc/kernel/eeh_pe.c @@ -807,7 +807,8 @@ static void eeh_restore_bridge_bars(stru eeh_ops->write_config(pdn, 15*4, 4, edev->config_space[15]);
/* PCI Command: 0x4 */ - eeh_ops->write_config(pdn, PCI_COMMAND, 4, edev->config_space[1]); + eeh_ops->write_config(pdn, PCI_COMMAND, 4, edev->config_space[1] | + PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
/* Check the PCIe link is ready */ eeh_bridge_check_link(edev);
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benjamin Herrenschmidt benh@kernel.crashing.org
commit b32e56e5a87a1f9243db92bc7a5df0ffb4627cfb upstream.
When setting up a CPU, we "push" (activate) a pool VP for it.
However it's an error to do so if it already has an active pool VP.
This happens when doing soft CPU hotplug on powernv since we don't tear down the CPU on unplug. The HW flags the error which gets captured by the diagnostics.
Fix this by making sure to "pull" out any already active pool first.
Fixes: 243e25112d06 ("powerpc/xive: Native exploitation of the XIVE interrupt controller") Cc: stable@vger.kernel.org # v4.12+ Signed-off-by: Benjamin Herrenschmidt benh@kernel.crashing.org Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/powerpc/sysdev/xive/native.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/arch/powerpc/sysdev/xive/native.c +++ b/arch/powerpc/sysdev/xive/native.c @@ -389,6 +389,10 @@ static void xive_native_setup_cpu(unsign if (xive_pool_vps == XIVE_INVALID_VP) return;
+ /* Check if pool VP already active, if it is, pull it */ + if (in_be32(xive_tima + TM_QW2_HV_POOL + TM_WORD2) & TM_QW2W2_VP) + in_be64(xive_tima + TM_SPC_PULL_POOL_CTX); + /* Enable the pool VP */ vp = xive_pool_vps + cpu; pr_debug("CPU %d setting up pool VP 0x%x\n", cpu, vp);
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Ellerman mpe@ellerman.id.au
commit b8858581febb050688e276b956796bc4a78299ed upstream.
When we patch an alternate feature section, we have to adjust any relative branches that branch out of the alternate section.
But currently we have a bug if we have a branch that points to past the last instruction of the alternate section, eg:
FTR_SECTION_ELSE 1: b 2f or 6,6,6 2: ALT_FTR_SECTION_END(...) nop
This will result in a relative branch at 1 with a target that equals the end of the alternate section.
That branch does not need adjusting when it's moved to the non-else location. Currently we do adjust it, resulting in a branch that goes off into the link-time location of the else section, which is junk.
The fix is to not patch branches that have a target == end of the alternate section.
Fixes: d20fe50a7b3c ("KVM: PPC: Book3S HV: Branch inside feature section") Fixes: 9b1a735de64c ("powerpc: Add logic to patch alternative feature sections") Cc: stable@vger.kernel.org # v2.6.27+ Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/powerpc/lib/feature-fixups.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/powerpc/lib/feature-fixups.c +++ b/arch/powerpc/lib/feature-fixups.c @@ -55,7 +55,7 @@ static int patch_alt_instruction(unsigne unsigned int *target = (unsigned int *)branch_target(src);
/* Branch within the section doesn't need translating */ - if (target < alt_start || target >= alt_end) { + if (target < alt_start || target > alt_end) { instr = translate_branch(dest, src); if (!instr) return 1;
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jan Kara jack@suse.cz
commit 44f06ba8297c7e9dfd0e49b40cbe119113cca094 upstream.
OSTA UDF specification does not mention whether the CS0 charset in case of two bytes per character encoding should be treated in UTF-16 or UCS-2. The sample code in the standard does not treat UTF-16 surrogates in any special way but on systems such as Windows which work in UTF-16 internally, filenames would be treated as being in UTF-16 effectively. In Linux it is more difficult to handle characters outside of Base Multilingual plane (beyond 0xffff) as NLS framework works with 2-byte characters only. Just make sure we don't leak UTF-16 surrogates into the resulting string when loading names from the filesystem for now.
CC: stable@vger.kernel.org # >= v4.6 Reported-by: Mingye Wang arthur200126@gmail.com Signed-off-by: Jan Kara jack@suse.cz Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/udf/unicode.c | 6 ++++++ 1 file changed, 6 insertions(+)
--- a/fs/udf/unicode.c +++ b/fs/udf/unicode.c @@ -28,6 +28,9 @@
#include "udf_sb.h"
+#define SURROGATE_MASK 0xfffff800 +#define SURROGATE_PAIR 0x0000d800 + static int udf_uni2char_utf8(wchar_t uni, unsigned char *out, int boundlen) @@ -37,6 +40,9 @@ static int udf_uni2char_utf8(wchar_t uni if (boundlen <= 0) return -ENAMETOOLONG;
+ if ((uni & SURROGATE_MASK) == SURROGATE_PAIR) + return -EINVAL; + if (uni < 0x80) { out[u_len++] = (unsigned char)uni; } else if (uni < 0x800) {
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amir Goldstein amir73il@gmail.com
commit 54a307ba8d3cd00a3902337ffaae28f436eeb1a4 upstream.
When event on child inodes are sent to the parent inode mark and parent inode mark was not marked with FAN_EVENT_ON_CHILD, the event will not be delivered to the listener process. However, if the same process also has a mount mark, the event to the parent inode will be delivered regadless of the mount mark mask.
This behavior is incorrect in the case where the mount mark mask does not contain the specific event type. For example, the process adds a mark on a directory with mask FAN_MODIFY (without FAN_EVENT_ON_CHILD) and a mount mark with mask FAN_CLOSE_NOWRITE (without FAN_ONDIR).
A modify event on a file inside that directory (and inside that mount) should not create a FAN_MODIFY event, because neither of the marks requested to get that event on the file.
Fixes: 1968f5eed54c ("fanotify: use both marks when possible") Cc: stable stable@vger.kernel.org Signed-off-by: Amir Goldstein amir73il@gmail.com Signed-off-by: Jan Kara jack@suse.cz Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/notify/fanotify/fanotify.c | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-)
--- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -92,7 +92,7 @@ static bool fanotify_should_send_event(s u32 event_mask, const void *data, int data_type) { - __u32 marks_mask, marks_ignored_mask; + __u32 marks_mask = 0, marks_ignored_mask = 0; const struct path *path = data;
pr_debug("%s: inode_mark=%p vfsmnt_mark=%p mask=%x data=%p" @@ -108,24 +108,20 @@ static bool fanotify_should_send_event(s !d_can_lookup(path->dentry)) return false;
- if (inode_mark && vfsmnt_mark) { - marks_mask = (vfsmnt_mark->mask | inode_mark->mask); - marks_ignored_mask = (vfsmnt_mark->ignored_mask | inode_mark->ignored_mask); - } else if (inode_mark) { - /* - * if the event is for a child and this inode doesn't care about - * events on the child, don't send it! - */ - if ((event_mask & FS_EVENT_ON_CHILD) && - !(inode_mark->mask & FS_EVENT_ON_CHILD)) - return false; - marks_mask = inode_mark->mask; - marks_ignored_mask = inode_mark->ignored_mask; - } else if (vfsmnt_mark) { - marks_mask = vfsmnt_mark->mask; - marks_ignored_mask = vfsmnt_mark->ignored_mask; - } else { - BUG(); + /* + * if the event is for a child and this inode doesn't care about + * events on the child, don't send it! + */ + if (inode_mark && + (!(event_mask & FS_EVENT_ON_CHILD) || + (inode_mark->mask & FS_EVENT_ON_CHILD))) { + marks_mask |= inode_mark->mask; + marks_ignored_mask |= inode_mark->ignored_mask; + } + + if (vfsmnt_mark) { + marks_mask |= vfsmnt_mark->mask; + marks_ignored_mask |= vfsmnt_mark->ignored_mask; }
if (d_is_dir(path->dentry) &&
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Kurtz djkurtz@chromium.org
commit 300ad8992913025b4294d4fc37b6bfff4a8b7ad1 upstream.
Commit c31165d7400b ("mmc: sdhci-pci: Add support for HS200 tuning mode on AMD, eMMC-4.5.1") added a HS200 tuning method for use with AMD SDHCI controllers. As described in the commit subject, this tuning is specific for HS200. However, as implemented, this method is used for all host timings, because platform_execute_tuning, if it exists, is called unconditionally by sdhci_execute_tuning(). This breaks tuning when using the AMD controller with, for example, a DDR50 SD card.
Instead, we can implement an amd execute_tuning wrapper callback, and then conditionally do the HS200 specific tuning for HS200, and otherwise call back to the standard sdhci_execute_tuning().
Signed-off-by: Daniel Kurtz djkurtz@chromium.org Acked-by: Shyam Sundar S K Shyam-sundar.S-k@amd.com Acked-by: Adrian Hunter adrian.hunter@intel.com Fixes: c31165d7400b ("mmc: sdhci-pci: Add support for HS200 tuning mode on AMD, eMMC-4.5.1") Cc: stable@vger.kernel.org # v4.11+ Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/mmc/host/sdhci-pci-core.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-)
--- a/drivers/mmc/host/sdhci-pci-core.c +++ b/drivers/mmc/host/sdhci-pci-core.c @@ -1318,7 +1318,7 @@ static void amd_enable_manual_tuning(str pci_write_config_dword(pdev, AMD_SD_MISC_CONTROL, val); }
-static int amd_execute_tuning(struct sdhci_host *host, u32 opcode) +static int amd_execute_tuning_hs200(struct sdhci_host *host, u32 opcode) { struct sdhci_pci_slot *slot = sdhci_priv(host); struct pci_dev *pdev = slot->chip->pdev; @@ -1357,6 +1357,27 @@ static int amd_execute_tuning(struct sdh return 0; }
+static int amd_execute_tuning(struct mmc_host *mmc, u32 opcode) +{ + struct sdhci_host *host = mmc_priv(mmc); + + /* AMD requires custom HS200 tuning */ + if (host->timing == MMC_TIMING_MMC_HS200) + return amd_execute_tuning_hs200(host, opcode); + + /* Otherwise perform standard SDHCI tuning */ + return sdhci_execute_tuning(mmc, opcode); +} + +static int amd_probe_slot(struct sdhci_pci_slot *slot) +{ + struct mmc_host_ops *ops = &slot->host->mmc_host_ops; + + ops->execute_tuning = amd_execute_tuning; + + return 0; +} + static int amd_probe(struct sdhci_pci_chip *chip) { struct pci_dev *smbus_dev; @@ -1391,12 +1412,12 @@ static const struct sdhci_ops amd_sdhci_ .set_bus_width = sdhci_set_bus_width, .reset = sdhci_reset, .set_uhs_signaling = sdhci_set_uhs_signaling, - .platform_execute_tuning = amd_execute_tuning, };
static const struct sdhci_pci_fixes sdhci_amd = { .probe = amd_probe, .ops = &amd_sdhci_pci_ops, + .probe_slot = amd_probe_slot, };
static const struct pci_device_id pci_ids[] = {
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro viro@zeniv.linux.org.uk
commit c66b23c2840446a82c389e4cb1a12eb2a71fa2e4 upstream.
jffs2_fill_super() might fail to allocate jffs2_sb_info; jffs2_kill_sb() must survive that.
Cc: stable@kernel.org Signed-off-by: Al Viro viro@zeniv.linux.org.uk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/jffs2/super.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/jffs2/super.c +++ b/fs/jffs2/super.c @@ -342,7 +342,7 @@ static void jffs2_put_super (struct supe static void jffs2_kill_sb(struct super_block *sb) { struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); - if (!sb_rdonly(sb)) + if (c && !sb_rdonly(sb)) jffs2_stop_garbage_collect_thread(c); kill_mtd_super(sb); kfree(c);
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro viro@zeniv.linux.org.uk
commit a24cd490739586a7d2da3549a1844e1d7c4f4fc4 upstream.
hypfs_fill_super() might fail to allocate sbi; hypfs_kill_super() should not oops on that.
Cc: stable@vger.kernel.org Signed-off-by: Al Viro viro@zeniv.linux.org.uk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/s390/hypfs/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/s390/hypfs/inode.c +++ b/arch/s390/hypfs/inode.c @@ -320,7 +320,7 @@ static void hypfs_kill_super(struct supe
if (sb->s_root) hypfs_delete_tree(sb->s_root); - if (sb_info->update_file) + if (sb_info && sb_info->update_file) hypfs_remove(sb_info->update_file); kfree(sb->s_fs_info); sb->s_fs_info = NULL;
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro viro@zeniv.linux.org.uk
commit 659038428cb43a66e3eff71e2c845c9de3611a98 upstream.
orangefs_fill_sb() might've failed to allocate ORANGEFS_SB(s); don't oops in that case.
Cc: stable@kernel.org Signed-off-by: Al Viro viro@zeniv.linux.org.uk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/orangefs/super.c | 5 +++++ 1 file changed, 5 insertions(+)
--- a/fs/orangefs/super.c +++ b/fs/orangefs/super.c @@ -579,6 +579,11 @@ void orangefs_kill_sb(struct super_block /* provided sb cleanup */ kill_anon_super(sb);
+ if (!ORANGEFS_SB(sb)) { + mutex_lock(&orangefs_request_mutex); + mutex_unlock(&orangefs_request_mutex); + return; + } /* * issue the unmount to userspace to tell it to remove the * dynamic mount info it has for this superblock
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro viro@zeniv.linux.org.uk
commit 4a3877c4cedd95543f8726b0a98743ed8db0c0fb upstream.
if we ever hit rpc_gssd_dummy_depopulate() dentry passed to it has refcount equal to 1. __rpc_rmpipe() drops it and dput() done after that hits an already freed dentry.
Cc: stable@kernel.org Signed-off-by: Al Viro viro@zeniv.linux.org.uk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- net/sunrpc/rpc_pipe.c | 1 + 1 file changed, 1 insertion(+)
--- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c @@ -1375,6 +1375,7 @@ rpc_gssd_dummy_depopulate(struct dentry struct dentry *clnt_dir = pipe_dentry->d_parent; struct dentry *gssd_dir = clnt_dir->d_parent;
+ dget(pipe_dentry); __rpc_rmpipe(d_inode(clnt_dir), pipe_dentry); __rpc_depopulate(clnt_dir, gssd_dummy_info_file, 0, 1); __rpc_depopulate(gssd_dir, gssd_dummy_clnt_dir, 0, 1);
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro viro@zeniv.linux.org.uk
commit 16a34adb9392b2fe4195267475ab5b472e55292c upstream.
We want it only for the stuff created by SB_KERNMOUNT mounts, *not* for their copies. As it is, creating a deep stack of bindings of /proc/*/ns/* somewhere in a new namespace and exiting yields a stack overflow.
Cc: stable@kernel.org Reported-by: Alexander Aring aring@mojatatu.com Bisected-by: Kirill Tkhai ktkhai@virtuozzo.com Tested-by: Kirill Tkhai ktkhai@virtuozzo.com Tested-by: Alexander Aring aring@mojatatu.com Signed-off-by: Al Viro viro@zeniv.linux.org.uk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/namespace.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/fs/namespace.c +++ b/fs/namespace.c @@ -1089,7 +1089,8 @@ static struct mount *clone_mnt(struct mo goto out_free; }
- mnt->mnt.mnt_flags = old->mnt.mnt_flags & ~(MNT_WRITE_HOLD|MNT_MARKED); + mnt->mnt.mnt_flags = old->mnt.mnt_flags; + mnt->mnt.mnt_flags &= ~(MNT_WRITE_HOLD|MNT_MARKED|MNT_INTERNAL); /* Don't allow unprivileged users to change mount flags */ if (flag & CL_UNPRIVILEGED) { mnt->mnt.mnt_flags |= MNT_LOCK_ATIME;
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Williams dan.j.williams@intel.com
commit e7c5a571a8d6a266aee9ca3f3f26e5afe3717eca upstream.
The new support for the standard _LSR and _LSW methods neglected to also update the nvdimm_init_config_data() and nvdimm_set_config_data() to return the translated error code from failed commands. This precision is necessary because the locked status that was previously returned on ND_CMD_GET_CONFIG_SIZE commands is now returned on ND_CMD_{GET,SET}_CONFIG_DATA commands.
If the kernel misses this indication it can inadvertently fall back to label-less mode when it should otherwise avoid all access to locked regions.
Cc: stable@vger.kernel.org Fixes: 4b27db7e26cd ("acpi, nfit: add support for the _LSI, _LSR, and...") Signed-off-by: Dan Williams dan.j.williams@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/nvdimm/dimm_devs.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-)
--- a/drivers/nvdimm/dimm_devs.c +++ b/drivers/nvdimm/dimm_devs.c @@ -88,9 +88,9 @@ int nvdimm_init_nsarea(struct nvdimm_drv int nvdimm_init_config_data(struct nvdimm_drvdata *ndd) { struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(ndd->dev); + int rc = validate_dimm(ndd), cmd_rc = 0; struct nd_cmd_get_config_data_hdr *cmd; struct nvdimm_bus_descriptor *nd_desc; - int rc = validate_dimm(ndd); u32 max_cmd_size, config_size; size_t offset;
@@ -124,9 +124,11 @@ int nvdimm_init_config_data(struct nvdim cmd->in_offset = offset; rc = nd_desc->ndctl(nd_desc, to_nvdimm(ndd->dev), ND_CMD_GET_CONFIG_DATA, cmd, - cmd->in_length + sizeof(*cmd), NULL); - if (rc || cmd->status) { - rc = -ENXIO; + cmd->in_length + sizeof(*cmd), &cmd_rc); + if (rc < 0) + break; + if (cmd_rc < 0) { + rc = cmd_rc; break; } memcpy(ndd->data + offset, cmd->out_buf, cmd->in_length); @@ -140,9 +142,9 @@ int nvdimm_init_config_data(struct nvdim int nvdimm_set_config_data(struct nvdimm_drvdata *ndd, size_t offset, void *buf, size_t len) { - int rc = validate_dimm(ndd); size_t max_cmd_size, buf_offset; struct nd_cmd_set_config_hdr *cmd; + int rc = validate_dimm(ndd), cmd_rc = 0; struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(ndd->dev); struct nvdimm_bus_descriptor *nd_desc = nvdimm_bus->nd_desc;
@@ -164,7 +166,6 @@ int nvdimm_set_config_data(struct nvdimm for (buf_offset = 0; len; len -= cmd->in_length, buf_offset += cmd->in_length) { size_t cmd_size; - u32 *status;
cmd->in_offset = offset + buf_offset; cmd->in_length = min(max_cmd_size, len); @@ -172,12 +173,13 @@ int nvdimm_set_config_data(struct nvdimm
/* status is output in the last 4-bytes of the command buffer */ cmd_size = sizeof(*cmd) + cmd->in_length + sizeof(u32); - status = ((void *) cmd) + cmd_size - sizeof(u32);
rc = nd_desc->ndctl(nd_desc, to_nvdimm(ndd->dev), - ND_CMD_SET_CONFIG_DATA, cmd, cmd_size, NULL); - if (rc || *status) { - rc = rc ? rc : -ENXIO; + ND_CMD_SET_CONFIG_DATA, cmd, cmd_size, &cmd_rc); + if (rc < 0) + break; + if (cmd_rc < 0) { + rc = cmd_rc; break; } }
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Jiang dave.jiang@intel.com
commit ef8423022324cf79bd1b41d8707c766461e7e555 upstream.
MAP_SYNC is a nop for device-dax. Allow MAP_SYNC to succeed on device-dax to eliminate special casing between device-dax and fs-dax as to when the flag can be specified. Device-dax users already implicitly assume that they do not need to call fsync(), and this enables them to explicitly check for this capability.
Cc: stable@vger.kernel.org Fixes: b6fb293f2497 ("mm: Define MAP_SYNC and VM_SYNC flags") Signed-off-by: Dave Jiang dave.jiang@intel.com Reviewed-by: Dan Williams dan.j.williams@intel.com Signed-off-by: Dan Williams dan.j.williams@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/dax/device.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/dax/device.c +++ b/drivers/dax/device.c @@ -19,6 +19,7 @@ #include <linux/dax.h> #include <linux/fs.h> #include <linux/mm.h> +#include <linux/mman.h> #include "dax-private.h" #include "dax.h"
@@ -534,6 +535,7 @@ static const struct file_operations dax_ .release = dax_release, .get_unmapped_area = dax_get_unmapped_area, .mmap = dax_mmap, + .mmap_supported_flags = MAP_SYNC, };
static void dev_dax_release(struct device *dev)
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Kent raven@themaw.net
commit 1e6306652ba18723015d1b4967fe9de55f042499 upstream.
The autofs file system mkdir inode operation blindly sets the created directory mode to S_IFDIR | 0555, ingoring the passed in mode, which can cause selinux dac_override denials.
But the function also checks if the caller is the daemon (as no-one else should be able to do anything here) so there's no point in not honouring the passed in mode, allowing the daemon to set appropriate mode when required.
Link: http://lkml.kernel.org/r/152361593601.8051.14014139124905996173.stgit@pluto.... Signed-off-by: Ian Kent raven@themaw.net Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/autofs4/root.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c @@ -749,7 +749,7 @@ static int autofs4_dir_mkdir(struct inod
autofs4_del_active(dentry);
- inode = autofs4_get_inode(dir->i_sb, S_IFDIR | 0555); + inode = autofs4_get_inode(dir->i_sb, S_IFDIR | mode); if (!inode) return -ENOMEM; d_add(dentry, inode);
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthew Wilcox mawilcox@microsoft.com
commit abc1be13fd113ddef5e2d807a466286b864caed3 upstream.
f2fs specifies the __GFP_ZERO flag for allocating some of its pages. Unfortunately, the page cache also uses the mapping's GFP flags for allocating radix tree nodes. It always masked off the __GFP_HIGHMEM flag, and masks off __GFP_ZERO in some paths, but not all. That causes radix tree nodes to be allocated with a NULL list_head, which causes backtraces like:
__list_del_entry+0x30/0xd0 list_lru_del+0xac/0x1ac page_cache_tree_insert+0xd8/0x110
The __GFP_DMA and __GFP_DMA32 flags would also be able to sneak through if they are ever used. Fix them all by using GFP_RECLAIM_MASK at the innermost location, and remove it from earlier in the callchain.
Link: http://lkml.kernel.org/r/20180411060320.14458-2-willy@infradead.org Fixes: 449dd6984d0e ("mm: keep page cache radix tree nodes in check") Signed-off-by: Matthew Wilcox mawilcox@microsoft.com Reported-by: Chris Fries cfries@google.com Debugged-by: Minchan Kim minchan@kernel.org Acked-by: Johannes Weiner hannes@cmpxchg.org Acked-by: Michal Hocko mhocko@suse.com Reviewed-by: Jan Kara jack@suse.cz Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- mm/filemap.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
--- a/mm/filemap.c +++ b/mm/filemap.c @@ -785,7 +785,7 @@ int replace_page_cache_page(struct page VM_BUG_ON_PAGE(!PageLocked(new), new); VM_BUG_ON_PAGE(new->mapping, new);
- error = radix_tree_preload(gfp_mask & ~__GFP_HIGHMEM); + error = radix_tree_preload(gfp_mask & GFP_RECLAIM_MASK); if (!error) { struct address_space *mapping = old->mapping; void (*freepage)(struct page *); @@ -841,7 +841,7 @@ static int __add_to_page_cache_locked(st return error; }
- error = radix_tree_maybe_preload(gfp_mask & ~__GFP_HIGHMEM); + error = radix_tree_maybe_preload(gfp_mask & GFP_RECLAIM_MASK); if (error) { if (!huge) mem_cgroup_cancel_charge(page, memcg, false); @@ -1584,8 +1584,7 @@ no_page: if (fgp_flags & FGP_ACCESSED) __SetPageReferenced(page);
- err = add_to_page_cache_lru(page, mapping, offset, - gfp_mask & GFP_RECLAIM_MASK); + err = add_to_page_cache_lru(page, mapping, offset, gfp_mask); if (unlikely(err)) { put_page(page); page = NULL; @@ -2388,7 +2387,7 @@ static int page_cache_read(struct file * if (!page) return -ENOMEM;
- ret = add_to_page_cache_lru(page, mapping, offset, gfp_mask & GFP_KERNEL); + ret = add_to_page_cache_lru(page, mapping, offset, gfp_mask); if (ret == 0) ret = mapping->a_ops->readpage(file, page); else if (ret == -EEXIST)
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Weinan Li weinan.z.li@intel.com
commit cd7e61b93d068a80bfe6cb55bf00f17332d831a1 upstream.
There is one issue relates to Coarse Power Gating(CPG) on KBL NUC in GVT-g, vgpu can't get the correct default context by updating the registers before inhibit context submission. It always get back the hardware default value unless the inhibit context submission happened before the 1st time forcewake put. With this wrong default context, vgpu will run with incorrect state and meet unknown issues.
The solution is initialize these mmios by adding lri command in ring buffer of the inhibit context, then gpu hardware has no chance to go down RC6 when lri commands are right being executed, and then vgpu can get correct default context for further use.
v3: - fix code fault, use 'for' to loop through mmio render list(Zhenyu)
v4: - save the count of engine mmio need to be restored for inhibit context and refine some comments. (Kevin)
v5: - code rebase
Cc: Kevin Tian kevin.tian@intel.com Cc: Zhenyu Wang zhenyuw@linux.intel.com Signed-off-by: Weinan Li weinan.z.li@intel.com Signed-off-by: Zhenyu Wang zhenyuw@linux.intel.com Signed-off-by: Changbin Du changbin.du@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/i915/gvt/gvt.h | 5 drivers/gpu/drm/i915/gvt/mmio_context.c | 210 +++++++++++++++++++++++++++++--- drivers/gpu/drm/i915/gvt/mmio_context.h | 5 drivers/gpu/drm/i915/gvt/scheduler.c | 5 4 files changed, 205 insertions(+), 20 deletions(-)
--- a/drivers/gpu/drm/i915/gvt/gvt.h +++ b/drivers/gpu/drm/i915/gvt/gvt.h @@ -308,7 +308,10 @@ struct intel_gvt { wait_queue_head_t service_thread_wq; unsigned long service_request;
- struct engine_mmio *engine_mmio_list; + struct { + struct engine_mmio *mmio; + int ctx_mmio_count[I915_NUM_ENGINES]; + } engine_mmio_list;
struct dentry *debugfs_root; }; --- a/drivers/gpu/drm/i915/gvt/mmio_context.c +++ b/drivers/gpu/drm/i915/gvt/mmio_context.c @@ -50,6 +50,8 @@ #define RING_GFX_MODE(base) _MMIO((base) + 0x29c) #define VF_GUARDBAND _MMIO(0x83a4)
+#define GEN9_MOCS_SIZE 64 + /* Raw offset is appened to each line for convenience. */ static struct engine_mmio gen8_engine_mmio_list[] __cacheline_aligned = { {RCS, GFX_MODE_GEN7, 0xffff, false}, /* 0x229c */ @@ -152,8 +154,8 @@ static struct engine_mmio gen9_engine_mm
static struct { bool initialized; - u32 control_table[I915_NUM_ENGINES][64]; - u32 l3cc_table[32]; + u32 control_table[I915_NUM_ENGINES][GEN9_MOCS_SIZE]; + u32 l3cc_table[GEN9_MOCS_SIZE / 2]; } gen9_render_mocs;
static void load_render_mocs(struct drm_i915_private *dev_priv) @@ -170,7 +172,7 @@ static void load_render_mocs(struct drm_
for (ring_id = 0; ring_id < ARRAY_SIZE(regs); ring_id++) { offset.reg = regs[ring_id]; - for (i = 0; i < 64; i++) { + for (i = 0; i < GEN9_MOCS_SIZE; i++) { gen9_render_mocs.control_table[ring_id][i] = I915_READ_FW(offset); offset.reg += 4; @@ -178,7 +180,7 @@ static void load_render_mocs(struct drm_ }
offset.reg = 0xb020; - for (i = 0; i < 32; i++) { + for (i = 0; i < GEN9_MOCS_SIZE / 2; i++) { gen9_render_mocs.l3cc_table[i] = I915_READ_FW(offset); offset.reg += 4; @@ -186,6 +188,153 @@ static void load_render_mocs(struct drm_ gen9_render_mocs.initialized = true; }
+static int +restore_context_mmio_for_inhibit(struct intel_vgpu *vgpu, + struct drm_i915_gem_request *req) +{ + u32 *cs; + int ret; + struct engine_mmio *mmio; + struct intel_gvt *gvt = vgpu->gvt; + int ring_id = req->engine->id; + int count = gvt->engine_mmio_list.ctx_mmio_count[ring_id]; + + if (count == 0) + return 0; + + ret = req->engine->emit_flush(req, EMIT_BARRIER); + if (ret) + return ret; + + cs = intel_ring_begin(req, count * 2 + 2); + if (IS_ERR(cs)) + return PTR_ERR(cs); + + *cs++ = MI_LOAD_REGISTER_IMM(count); + for (mmio = gvt->engine_mmio_list.mmio; + i915_mmio_reg_valid(mmio->reg); mmio++) { + if (mmio->ring_id != ring_id || + !mmio->in_context) + continue; + + *cs++ = i915_mmio_reg_offset(mmio->reg); + *cs++ = vgpu_vreg_t(vgpu, mmio->reg) | + (mmio->mask << 16); + gvt_dbg_core("add lri reg pair 0x%x:0x%x in inhibit ctx, vgpu:%d, rind_id:%d\n", + *(cs-2), *(cs-1), vgpu->id, ring_id); + } + + *cs++ = MI_NOOP; + intel_ring_advance(req, cs); + + ret = req->engine->emit_flush(req, EMIT_BARRIER); + if (ret) + return ret; + + return 0; +} + +static int +restore_render_mocs_control_for_inhibit(struct intel_vgpu *vgpu, + struct drm_i915_gem_request *req) +{ + unsigned int index; + u32 *cs; + + cs = intel_ring_begin(req, 2 * GEN9_MOCS_SIZE + 2); + if (IS_ERR(cs)) + return PTR_ERR(cs); + + *cs++ = MI_LOAD_REGISTER_IMM(GEN9_MOCS_SIZE); + + for (index = 0; index < GEN9_MOCS_SIZE; index++) { + *cs++ = i915_mmio_reg_offset(GEN9_GFX_MOCS(index)); + *cs++ = vgpu_vreg_t(vgpu, GEN9_GFX_MOCS(index)); + gvt_dbg_core("add lri reg pair 0x%x:0x%x in inhibit ctx, vgpu:%d, rind_id:%d\n", + *(cs-2), *(cs-1), vgpu->id, req->engine->id); + + } + + *cs++ = MI_NOOP; + intel_ring_advance(req, cs); + + return 0; +} + +static int +restore_render_mocs_l3cc_for_inhibit(struct intel_vgpu *vgpu, + struct drm_i915_gem_request *req) +{ + unsigned int index; + u32 *cs; + + cs = intel_ring_begin(req, 2 * GEN9_MOCS_SIZE / 2 + 2); + if (IS_ERR(cs)) + return PTR_ERR(cs); + + *cs++ = MI_LOAD_REGISTER_IMM(GEN9_MOCS_SIZE / 2); + + for (index = 0; index < GEN9_MOCS_SIZE / 2; index++) { + *cs++ = i915_mmio_reg_offset(GEN9_LNCFCMOCS(index)); + *cs++ = vgpu_vreg_t(vgpu, GEN9_LNCFCMOCS(index)); + gvt_dbg_core("add lri reg pair 0x%x:0x%x in inhibit ctx, vgpu:%d, rind_id:%d\n", + *(cs-2), *(cs-1), vgpu->id, req->engine->id); + + } + + *cs++ = MI_NOOP; + intel_ring_advance(req, cs); + + return 0; +} + +/* + * Use lri command to initialize the mmio which is in context state image for + * inhibit context, it contains tracked engine mmio, render_mocs and + * render_mocs_l3cc. + */ +int intel_vgpu_restore_inhibit_context(struct intel_vgpu *vgpu, + struct drm_i915_gem_request *req) +{ + int ret; + u32 *cs; + + cs = intel_ring_begin(req, 2); + if (IS_ERR(cs)) + return PTR_ERR(cs); + + *cs++ = MI_ARB_ON_OFF | MI_ARB_DISABLE; + *cs++ = MI_NOOP; + intel_ring_advance(req, cs); + + ret = restore_context_mmio_for_inhibit(vgpu, req); + if (ret) + goto out; + + /* no MOCS register in context except render engine */ + if (req->engine->id != RCS) + goto out; + + ret = restore_render_mocs_control_for_inhibit(vgpu, req); + if (ret) + goto out; + + ret = restore_render_mocs_l3cc_for_inhibit(vgpu, req); + if (ret) + goto out; + +out: + cs = intel_ring_begin(req, 2); + if (IS_ERR(cs)) + return PTR_ERR(cs); + + *cs++ = MI_ARB_ON_OFF | MI_ARB_ENABLE; + *cs++ = MI_NOOP; + intel_ring_advance(req, cs); + + return ret; +} + static void handle_tlb_pending_event(struct intel_vgpu *vgpu, int ring_id) { struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; @@ -252,11 +401,14 @@ static void switch_mocs(struct intel_vgp if (WARN_ON(ring_id >= ARRAY_SIZE(regs))) return;
+ if (IS_KABYLAKE(dev_priv) && ring_id == RCS) + return; + if (!pre && !gen9_render_mocs.initialized) load_render_mocs(dev_priv);
offset.reg = regs[ring_id]; - for (i = 0; i < 64; i++) { + for (i = 0; i < GEN9_MOCS_SIZE; i++) { if (pre) old_v = vgpu_vreg_t(pre, offset); else @@ -274,7 +426,7 @@ static void switch_mocs(struct intel_vgp
if (ring_id == RCS) { l3_offset.reg = 0xb020; - for (i = 0; i < 32; i++) { + for (i = 0; i < GEN9_MOCS_SIZE / 2; i++) { if (pre) old_v = vgpu_vreg_t(pre, l3_offset); else @@ -294,6 +446,16 @@ static void switch_mocs(struct intel_vgp
#define CTX_CONTEXT_CONTROL_VAL 0x03
+bool is_inhibit_context(struct i915_gem_context *ctx, int ring_id) +{ + u32 *reg_state = ctx->engine[ring_id].lrc_reg_state; + u32 inhibit_mask = + _MASKED_BIT_ENABLE(CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT); + + return inhibit_mask == + (reg_state[CTX_CONTEXT_CONTROL_VAL] & inhibit_mask); +} + /* Switch ring mmio values (context). */ static void switch_mmio(struct intel_vgpu *pre, struct intel_vgpu *next, @@ -301,9 +463,6 @@ static void switch_mmio(struct intel_vgp { struct drm_i915_private *dev_priv; struct intel_vgpu_submission *s; - u32 *reg_state, ctx_ctrl; - u32 inhibit_mask = - _MASKED_BIT_ENABLE(CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT); struct engine_mmio *mmio; u32 old_v, new_v;
@@ -311,10 +470,18 @@ static void switch_mmio(struct intel_vgp if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) switch_mocs(pre, next, ring_id);
- for (mmio = dev_priv->gvt->engine_mmio_list; + for (mmio = dev_priv->gvt->engine_mmio_list.mmio; i915_mmio_reg_valid(mmio->reg); mmio++) { if (mmio->ring_id != ring_id) continue; + /* + * No need to do save or restore of the mmio which is in context + * state image on kabylake, it's initialized by lri command and + * save or restore with context together. + */ + if (IS_KABYLAKE(dev_priv) && mmio->in_context) + continue; + // save if (pre) { vgpu_vreg_t(pre, mmio->reg) = I915_READ_FW(mmio->reg); @@ -328,16 +495,13 @@ static void switch_mmio(struct intel_vgp // restore if (next) { s = &next->submission; - reg_state = - s->shadow_ctx->engine[ring_id].lrc_reg_state; - ctx_ctrl = reg_state[CTX_CONTEXT_CONTROL_VAL]; /* - * if it is an inhibit context, load in_context mmio - * into HW by mmio write. If it is not, skip this mmio - * write. + * No need to restore the mmio which is in context state + * image if it's not inhibit context, it will restore + * itself. */ if (mmio->in_context && - (ctx_ctrl & inhibit_mask) != inhibit_mask) + !is_inhibit_context(s->shadow_ctx, ring_id)) continue;
if (mmio->mask) @@ -408,8 +572,16 @@ void intel_gvt_switch_mmio(struct intel_ */ void intel_gvt_init_engine_mmio_context(struct intel_gvt *gvt) { + struct engine_mmio *mmio; + if (IS_SKYLAKE(gvt->dev_priv) || IS_KABYLAKE(gvt->dev_priv)) - gvt->engine_mmio_list = gen9_engine_mmio_list; + gvt->engine_mmio_list.mmio = gen9_engine_mmio_list; else - gvt->engine_mmio_list = gen8_engine_mmio_list; + gvt->engine_mmio_list.mmio = gen8_engine_mmio_list; + + for (mmio = gvt->engine_mmio_list.mmio; + i915_mmio_reg_valid(mmio->reg); mmio++) { + if (mmio->in_context) + gvt->engine_mmio_list.ctx_mmio_count[mmio->ring_id]++; + } } --- a/drivers/gpu/drm/i915/gvt/mmio_context.h +++ b/drivers/gpu/drm/i915/gvt/mmio_context.h @@ -49,4 +49,9 @@ void intel_gvt_switch_mmio(struct intel_
void intel_gvt_init_engine_mmio_context(struct intel_gvt *gvt);
+bool is_inhibit_context(struct i915_gem_context *ctx, int ring_id); + +int intel_vgpu_restore_inhibit_context(struct intel_vgpu *vgpu, + struct drm_i915_gem_request *req); + #endif --- a/drivers/gpu/drm/i915/gvt/scheduler.c +++ b/drivers/gpu/drm/i915/gvt/scheduler.c @@ -275,6 +275,11 @@ static int copy_workload_to_ring_buffer( struct intel_vgpu *vgpu = workload->vgpu; void *shadow_ring_buffer_va; u32 *cs; + struct drm_i915_gem_request *req = workload->req; + + if (IS_KABYLAKE(req->i915) && + is_inhibit_context(req->ctx, req->engine->id)) + intel_vgpu_restore_inhibit_context(vgpu, req);
/* allocate shadow ring buffer */ cs = intel_ring_begin(workload->req, workload->rb_len / sizeof(u32));
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiri Kosina jkosina@suse.cz
commit b658912cb023cd6f8e46963d29779903d3c10538 upstream.
i2c_hid_command() returns non-zero in error cases (the actual errno). Error handling in for I2C_HID_QUIRK_RESEND_REPORT_DESCR case in i2c_hid_resume() had the check inverted; fix that.
Fixes: 3e83eda467 ("HID: i2c-hid: Fix resume issue on Raydium touchscreen device") Reported-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Jiri Kosina jkosina@suse.cz Cc: Aaron Ma aaron.ma@canonical.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/hid/i2c-hid/i2c-hid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c @@ -1229,7 +1229,7 @@ static int i2c_hid_resume(struct device */ if (ihid->quirks & I2C_HID_QUIRK_RESEND_REPORT_DESCR) { ret = i2c_hid_command(client, &hid_report_descr_cmd, NULL, 0); - if (!ret) + if (ret) return ret; }
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Greg Thelen gthelen@google.com
commit 2e898e4c0a3897ccd434adac5abb8330194f527b upstream.
lock_page_memcg()/unlock_page_memcg() use spin_lock_irqsave/restore() if the page's memcg is undergoing move accounting, which occurs when a process leaves its memcg for a new one that has memory.move_charge_at_immigrate set.
unlocked_inode_to_wb_begin,end() use spin_lock_irq/spin_unlock_irq() if the given inode is switching writeback domains. Switches occur when enough writes are issued from a new domain.
This existing pattern is thus suspicious: lock_page_memcg(page); unlocked_inode_to_wb_begin(inode, &locked); ... unlocked_inode_to_wb_end(inode, locked); unlock_page_memcg(page);
If both inode switch and process memcg migration are both in-flight then unlocked_inode_to_wb_end() will unconditionally enable interrupts while still holding the lock_page_memcg() irq spinlock. This suggests the possibility of deadlock if an interrupt occurs before unlock_page_memcg().
truncate __cancel_dirty_page lock_page_memcg unlocked_inode_to_wb_begin unlocked_inode_to_wb_end <interrupts mistakenly enabled> <interrupt> end_page_writeback test_clear_page_writeback lock_page_memcg <deadlock> unlock_page_memcg
Due to configuration limitations this deadlock is not currently possible because we don't mix cgroup writeback (a cgroupv2 feature) and memory.move_charge_at_immigrate (a cgroupv1 feature).
If the kernel is hacked to always claim inode switching and memcg moving_account, then this script triggers lockup in less than a minute:
cd /mnt/cgroup/memory mkdir a b echo 1 > a/memory.move_charge_at_immigrate echo 1 > b/memory.move_charge_at_immigrate ( echo $BASHPID > a/cgroup.procs while true; do dd if=/dev/zero of=/mnt/big bs=1M count=256 done ) & while true; do sync done & sleep 1h & SLEEP=$! while true; do echo $SLEEP > a/cgroup.procs echo $SLEEP > b/cgroup.procs done
The deadlock does not seem possible, so it's debatable if there's any reason to modify the kernel. I suggest we should to prevent future surprises. And Wang Long said "this deadlock occurs three times in our environment", so there's more reason to apply this, even to stable. Stable 4.4 has minor conflicts applying this patch. For a clean 4.4 patch see "[PATCH for-4.4] writeback: safer lock nesting" https://lkml.org/lkml/2018/4/11/146
Wang Long said "this deadlock occurs three times in our environment"
[gthelen@google.com: v4] Link: http://lkml.kernel.org/r/20180411084653.254724-1-gthelen@google.com [akpm@linux-foundation.org: comment tweaks, struct initialization simplification] Change-Id: Ibb773e8045852978f6207074491d262f1b3fb613 Link: http://lkml.kernel.org/r/20180410005908.167976-1-gthelen@google.com Fixes: 682aa8e1a6a1 ("writeback: implement unlocked_inode_to_wb transaction and use it for stat updates") Signed-off-by: Greg Thelen gthelen@google.com Reported-by: Wang Long wanglong19@meituan.com Acked-by: Wang Long wanglong19@meituan.com Acked-by: Michal Hocko mhocko@suse.com Reviewed-by: Andrew Morton akpm@linux-foundation.org Cc: Johannes Weiner hannes@cmpxchg.org Cc: Tejun Heo tj@kernel.org Cc: Nicholas Piggin npiggin@gmail.com Cc: stable@vger.kernel.org [v4.2+] Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org [natechancellor: Adjust context due to lack of b93b016313b3b] Signed-off-by: Nathan Chancellor natechancellor@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/fs-writeback.c | 7 ++++--- include/linux/backing-dev-defs.h | 5 +++++ include/linux/backing-dev.h | 30 ++++++++++++++++-------------- mm/page-writeback.c | 18 +++++++++--------- 4 files changed, 34 insertions(+), 26 deletions(-)
--- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -745,11 +745,12 @@ int inode_congested(struct inode *inode, */ if (inode && inode_to_wb_is_valid(inode)) { struct bdi_writeback *wb; - bool locked, congested; + struct wb_lock_cookie lock_cookie = {}; + bool congested;
- wb = unlocked_inode_to_wb_begin(inode, &locked); + wb = unlocked_inode_to_wb_begin(inode, &lock_cookie); congested = wb_congested(wb, cong_bits); - unlocked_inode_to_wb_end(inode, locked); + unlocked_inode_to_wb_end(inode, &lock_cookie); return congested; }
--- a/include/linux/backing-dev-defs.h +++ b/include/linux/backing-dev-defs.h @@ -223,6 +223,11 @@ static inline void set_bdi_congested(str set_wb_congested(bdi->wb.congested, sync); }
+struct wb_lock_cookie { + bool locked; + unsigned long flags; +}; + #ifdef CONFIG_CGROUP_WRITEBACK
/** --- a/include/linux/backing-dev.h +++ b/include/linux/backing-dev.h @@ -346,7 +346,7 @@ static inline struct bdi_writeback *inod /** * unlocked_inode_to_wb_begin - begin unlocked inode wb access transaction * @inode: target inode - * @lockedp: temp bool output param, to be passed to the end function + * @cookie: output param, to be passed to the end function * * The caller wants to access the wb associated with @inode but isn't * holding inode->i_lock, mapping->tree_lock or wb->list_lock. This @@ -354,12 +354,12 @@ static inline struct bdi_writeback *inod * association doesn't change until the transaction is finished with * unlocked_inode_to_wb_end(). * - * The caller must call unlocked_inode_to_wb_end() with *@lockdep - * afterwards and can't sleep during transaction. IRQ may or may not be - * disabled on return. + * The caller must call unlocked_inode_to_wb_end() with *@cookie afterwards and + * can't sleep during the transaction. IRQs may or may not be disabled on + * return. */ static inline struct bdi_writeback * -unlocked_inode_to_wb_begin(struct inode *inode, bool *lockedp) +unlocked_inode_to_wb_begin(struct inode *inode, struct wb_lock_cookie *cookie) { rcu_read_lock();
@@ -367,10 +367,10 @@ unlocked_inode_to_wb_begin(struct inode * Paired with store_release in inode_switch_wb_work_fn() and * ensures that we see the new wb if we see cleared I_WB_SWITCH. */ - *lockedp = smp_load_acquire(&inode->i_state) & I_WB_SWITCH; + cookie->locked = smp_load_acquire(&inode->i_state) & I_WB_SWITCH;
- if (unlikely(*lockedp)) - spin_lock_irq(&inode->i_mapping->tree_lock); + if (unlikely(cookie->locked)) + spin_lock_irqsave(&inode->i_mapping->tree_lock, cookie->flags);
/* * Protected by either !I_WB_SWITCH + rcu_read_lock() or tree_lock. @@ -382,12 +382,13 @@ unlocked_inode_to_wb_begin(struct inode /** * unlocked_inode_to_wb_end - end inode wb access transaction * @inode: target inode - * @locked: *@lockedp from unlocked_inode_to_wb_begin() + * @cookie: @cookie from unlocked_inode_to_wb_begin() */ -static inline void unlocked_inode_to_wb_end(struct inode *inode, bool locked) +static inline void unlocked_inode_to_wb_end(struct inode *inode, + struct wb_lock_cookie *cookie) { - if (unlikely(locked)) - spin_unlock_irq(&inode->i_mapping->tree_lock); + if (unlikely(cookie->locked)) + spin_unlock_irqrestore(&inode->i_mapping->tree_lock, cookie->flags);
rcu_read_unlock(); } @@ -434,12 +435,13 @@ static inline struct bdi_writeback *inod }
static inline struct bdi_writeback * -unlocked_inode_to_wb_begin(struct inode *inode, bool *lockedp) +unlocked_inode_to_wb_begin(struct inode *inode, struct wb_lock_cookie *cookie) { return inode_to_wb(inode); }
-static inline void unlocked_inode_to_wb_end(struct inode *inode, bool locked) +static inline void unlocked_inode_to_wb_end(struct inode *inode, + struct wb_lock_cookie *cookie) { }
--- a/mm/page-writeback.c +++ b/mm/page-writeback.c @@ -2501,13 +2501,13 @@ void account_page_redirty(struct page *p if (mapping && mapping_cap_account_dirty(mapping)) { struct inode *inode = mapping->host; struct bdi_writeback *wb; - bool locked; + struct wb_lock_cookie cookie = {};
- wb = unlocked_inode_to_wb_begin(inode, &locked); + wb = unlocked_inode_to_wb_begin(inode, &cookie); current->nr_dirtied--; dec_node_page_state(page, NR_DIRTIED); dec_wb_stat(wb, WB_DIRTIED); - unlocked_inode_to_wb_end(inode, locked); + unlocked_inode_to_wb_end(inode, &cookie); } } EXPORT_SYMBOL(account_page_redirty); @@ -2613,15 +2613,15 @@ void __cancel_dirty_page(struct page *pa if (mapping_cap_account_dirty(mapping)) { struct inode *inode = mapping->host; struct bdi_writeback *wb; - bool locked; + struct wb_lock_cookie cookie = {};
lock_page_memcg(page); - wb = unlocked_inode_to_wb_begin(inode, &locked); + wb = unlocked_inode_to_wb_begin(inode, &cookie);
if (TestClearPageDirty(page)) account_page_cleaned(page, mapping, wb);
- unlocked_inode_to_wb_end(inode, locked); + unlocked_inode_to_wb_end(inode, &cookie); unlock_page_memcg(page); } else { ClearPageDirty(page); @@ -2653,7 +2653,7 @@ int clear_page_dirty_for_io(struct page if (mapping && mapping_cap_account_dirty(mapping)) { struct inode *inode = mapping->host; struct bdi_writeback *wb; - bool locked; + struct wb_lock_cookie cookie = {};
/* * Yes, Virginia, this is indeed insane. @@ -2690,14 +2690,14 @@ int clear_page_dirty_for_io(struct page * always locked coming in here, so we get the desired * exclusion. */ - wb = unlocked_inode_to_wb_begin(inode, &locked); + wb = unlocked_inode_to_wb_begin(inode, &cookie); if (TestClearPageDirty(page)) { dec_lruvec_page_state(page, NR_FILE_DIRTY); dec_zone_page_state(page, NR_ZONE_WRITE_PENDING); dec_wb_stat(wb, WB_RECLAIMABLE); ret = 1; } - unlocked_inode_to_wb_end(inode, locked); + unlocked_inode_to_wb_end(inode, &cookie); return ret; } return TestClearPageDirty(page);
On 04/22/2018 06:50 AM, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.16.4 release. There are 196 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Tue Apr 24 13:50:16 UTC 2018. Anything received after that time might be too late.
Build results: total: 143 pass: 141 fail: 2 Failed builds: powerpc:defconfig powerpc:allmodconfig Qemu test results: total: 139 pass: 133 fail: 6 Failed tests: powerpc:mac99:ppc64_book3s_defconfig:initrd:nosmp powerpc:mac99:ppc64_book3s_defconfig:initrd:smp4 powerpc:mac99:ppc64_book3s_defconfig:rootfs:smp4 powerpc:pseries:pseries_defconfig:initrd powerpc:pseries:pseries_defconfig:rootfs powerpc:powernv:powernv_defconfig:initrd
arch/powerpc/platforms/powernv/opal-nvram.c: In function 'opal_nvram_write': arch/powerpc/platforms/powernv/opal-nvram.c:61:11: error: 'OPAL_BUSY_DELAY_MS'
This problem affects _all_ pending releases.
Guenter
On Sun, Apr 22, 2018 at 01:13:53PM -0700, Guenter Roeck wrote:
On 04/22/2018 06:50 AM, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.16.4 release. There are 196 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Tue Apr 24 13:50:16 UTC 2018. Anything received after that time might be too late.
Build results: total: 143 pass: 141 fail: 2 Failed builds: powerpc:defconfig powerpc:allmodconfig Qemu test results: total: 139 pass: 133 fail: 6 Failed tests: powerpc:mac99:ppc64_book3s_defconfig:initrd:nosmp powerpc:mac99:ppc64_book3s_defconfig:initrd:smp4 powerpc:mac99:ppc64_book3s_defconfig:rootfs:smp4 powerpc:pseries:pseries_defconfig:initrd powerpc:pseries:pseries_defconfig:rootfs powerpc:powernv:powernv_defconfig:initrd
arch/powerpc/platforms/powernv/opal-nvram.c: In function 'opal_nvram_write': arch/powerpc/platforms/powernv/opal-nvram.c:61:11: error: 'OPAL_BUSY_DELAY_MS'
This problem affects _all_ pending releases.
Guenter
Looks like 3b8070335f75 ("powerpc/powernv: Fix OPAL NVRAM driver OPAL_BUSY loops") has a dependency commit that was missed: 34dd25de9fe3 ("powerpc/powernv: define a standard delay for OPAL_BUSY type retry loops").
Nathan
On Sun, Apr 22, 2018 at 01:25:01PM -0700, Nathan Chancellor wrote:
On Sun, Apr 22, 2018 at 01:13:53PM -0700, Guenter Roeck wrote:
On 04/22/2018 06:50 AM, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.16.4 release. There are 196 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Tue Apr 24 13:50:16 UTC 2018. Anything received after that time might be too late.
Build results: total: 143 pass: 141 fail: 2 Failed builds: powerpc:defconfig powerpc:allmodconfig Qemu test results: total: 139 pass: 133 fail: 6 Failed tests: powerpc:mac99:ppc64_book3s_defconfig:initrd:nosmp powerpc:mac99:ppc64_book3s_defconfig:initrd:smp4 powerpc:mac99:ppc64_book3s_defconfig:rootfs:smp4 powerpc:pseries:pseries_defconfig:initrd powerpc:pseries:pseries_defconfig:rootfs powerpc:powernv:powernv_defconfig:initrd
arch/powerpc/platforms/powernv/opal-nvram.c: In function 'opal_nvram_write': arch/powerpc/platforms/powernv/opal-nvram.c:61:11: error: 'OPAL_BUSY_DELAY_MS'
This problem affects _all_ pending releases.
Guenter
Looks like 3b8070335f75 ("powerpc/powernv: Fix OPAL NVRAM driver OPAL_BUSY loops") has a dependency commit that was missed: 34dd25de9fe3 ("powerpc/powernv: define a standard delay for OPAL_BUSY type retry loops").
Thanks, I've now queued this up everywhere to resolve this issue.
greg k-h
On Sun, Apr 22, 2018 at 03:50:20PM +0200, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.16.4 release. There are 196 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Tue Apr 24 13:50:16 UTC 2018. Anything received after that time might be too late.
For v4.16.3-197-g405d1f8:
Build results: total: 143 pass: 143 fail: 0 Qemu test results: total: 139 pass: 139 fail: 0
Details are available at http://kerneltests.org/builders.
Guenter
On Mon, Apr 23, 2018 at 09:56:05AM -0700, Guenter Roeck wrote:
On Sun, Apr 22, 2018 at 03:50:20PM +0200, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.16.4 release. There are 196 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Tue Apr 24 13:50:16 UTC 2018. Anything received after that time might be too late.
For v4.16.3-197-g405d1f8:
Build results: total: 143 pass: 143 fail: 0 Qemu test results: total: 139 pass: 139 fail: 0
Details are available at http://kerneltests.org/builders.
Thanks for testing all of these. I've pushed out new trees for 4.16.y, 4.14.y, and 4.9.y so I'll watch your builders to make sure all is good with them.
thanks,
greg k-h
On Mon, Apr 23, 2018 at 08:06:07PM +0200, Greg Kroah-Hartman wrote:
On Mon, Apr 23, 2018 at 09:56:05AM -0700, Guenter Roeck wrote:
On Sun, Apr 22, 2018 at 03:50:20PM +0200, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.16.4 release. There are 196 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Tue Apr 24 13:50:16 UTC 2018. Anything received after that time might be too late.
For v4.16.3-197-g405d1f8:
Build results: total: 143 pass: 143 fail: 0 Qemu test results: total: 139 pass: 139 fail: 0
Details are available at http://kerneltests.org/builders.
Thanks for testing all of these. I've pushed out new trees for 4.16.y, 4.14.y, and 4.9.y so I'll watch your builders to make sure all is good with them.
Still no failures after rebuilding all three releases.
Guenter
On Mon, Apr 23, 2018 at 02:58:13PM -0700, Guenter Roeck wrote:
On Mon, Apr 23, 2018 at 08:06:07PM +0200, Greg Kroah-Hartman wrote:
On Mon, Apr 23, 2018 at 09:56:05AM -0700, Guenter Roeck wrote:
On Sun, Apr 22, 2018 at 03:50:20PM +0200, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.16.4 release. There are 196 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Tue Apr 24 13:50:16 UTC 2018. Anything received after that time might be too late.
For v4.16.3-197-g405d1f8:
Build results: total: 143 pass: 143 fail: 0 Qemu test results: total: 139 pass: 139 fail: 0
Details are available at http://kerneltests.org/builders.
Thanks for testing all of these. I've pushed out new trees for 4.16.y, 4.14.y, and 4.9.y so I'll watch your builders to make sure all is good with them.
Still no failures after rebuilding all three releases.
Wonderful, thanks for letting me know.
greg k-h
On Sun, Apr 22, 2018 at 03:50:20PM +0200, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.16.4 release. There are 196 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Tue Apr 24 13:50:16 UTC 2018. 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.16.4-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.16.y and the diffstat can be found below.
There is a -rc3 out now, to fix some issues reported with -rc1 and -rc2 (I forgot to announce -rc2, sorry.): https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.16.4-rc3....
On 04/23/2018 12:03 PM, Greg Kroah-Hartman wrote:
On Sun, Apr 22, 2018 at 03:50:20PM +0200, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.16.4 release. There are 196 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Tue Apr 24 13:50:16 UTC 2018. 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.16.4-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.16.y and the diffstat can be found below.
There is a -rc3 out now, to fix some issues reported with -rc1 and -rc2 (I forgot to announce -rc2, sorry.): https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.16.4-rc3....
I just tried rc1 - will try rc3. Has the lock problem seen already: ( I will try rc3 and if I setill see the problem, will start bisect)
================================ WARNING: inconsistent lock state 4.16.4-rc1+ #4 Not tainted -------------------------------- inconsistent {HARDIRQ-ON-W} -> {IN-HARDIRQ-W} usage. swapper/3/0 [HC1[1]:SC1[1]:HE0:SE0] takes: (fs_reclaim){?.+.}, at: [< (ptrval)>] fs_reclaim_acquire.part.76+0x5/0x30 {HARDIRQ-ON-W} state was registered at: fs_reclaim_acquire.part.76+0x29/0x30 kmem_cache_alloc_node_trace+0x39/0x2a0 alloc_worker+0x2d/0xa0 create_worker+0xa0/0x2b0 workqueue_init+0x315/0x39a kernel_init_freeable+0x153/0x312 kernel_init+0xf/0x120 ret_from_fork+0x3a/0x50 irq event stamp: 164931 hardirqs last enabled at (164930): [< (ptrval)>] __do_softirq+0xe1/0x560 hardirqs last disabled at (164931): [< (ptrval)>] interrupt_entry+0xbd/0xf0 softirqs last enabled at (164928): [< (ptrval)>] irq_enter+0x75/0x80 softirqs last disabled at (164929): [< (ptrval)>] irq_exit+0x104/0x110
other info that might help us debug this: Possible unsafe locking scenario:
CPU0 ---- lock(fs_reclaim); <Interrupt> lock(fs_reclaim);
*** DEADLOCK ***
no locks held by swapper/3/0.
stack backtrace: CPU: 3 PID: 0 Comm: swapper/3 Not tainted 4.16.4-rc1+ #4 Hardware name: System76, Inc. Wild Dog Performance/H87-PLUS, BIOS 0705 12/05/2013 Call Trace: <IRQ> dump_stack+0x67/0x98 print_usage_bug+0x24c/0x266 mark_lock+0x6c1/0x7a0 ? check_usage_backwards+0x230/0x230 __lock_acquire+0x1237/0x1e20 ? debug_check_no_locks_freed+0x190/0x190 ? debug_check_no_locks_freed+0x190/0x190 ? memzero_explicit+0xa/0x10 ? extract_buf+0x1b1/0x220 ? trace_event_raw_event_xfer_secondary_pool+0x1b0/0x1b0 ? _raw_spin_unlock_irqrestore+0x3e/0x50 ? match_held_lock+0x1b/0x210 ? lock_acquire+0xcd/0x220 lock_acquire+0xcd/0x220 ? fs_reclaim_acquire.part.76+0x5/0x30 ? lock_acquire+0xcd/0x220 fs_reclaim_acquire.part.76+0x29/0x30 ? fs_reclaim_acquire.part.76+0x5/0x30 __kmalloc+0x51/0x2e0 ? crng_reseed+0x229/0x440 crng_reseed+0x229/0x440 ? init_std_data+0x1c0/0x1c0 ? add_interrupt_randomness+0x27d/0x340 credit_entropy_bits+0x3b7/0x3d0 add_interrupt_randomness+0x27d/0x340 ? extract_entropy.constprop.41+0x1b0/0x1b0 ? rcu_read_lock_sched_held+0x7c/0x80 ? __handle_irq_event_percpu+0xf9/0x3c0 handle_irq_event_percpu+0x8b/0xe0 ? __handle_irq_event_percpu+0x3c0/0x3c0 ? lock_acquire+0xcd/0x220 ? handle_edge_irq+0x28/0x2c0 ? do_raw_spin_unlock+0x91/0x120 handle_irq_event+0x5a/0x90 handle_edge_irq+0xef/0x2c0 handle_irq+0x32/0x40 do_IRQ+0x60/0x130 common_interrupt+0xf/0xf RIP: 0010:__do_softirq+0xe7/0x560 RSP: 0018:ffff8803cfec7f58 EFLAGS: 00000246 ORIG_RAX: ffffffffffffffde RAX: 00000000ffffffff RBX: ffff8803cd6b26c0 RCX: ffffffff8112890c RDX: 0000000000000007 RSI: dffffc0000000000 RDI: ffff8803cd6b2f24 RBP: ffff8803cd6b2ef4 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000 R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000202 ? common_interrupt+0xa/0xf ? trace_hardirqs_on_caller+0x18c/0x280 ? __do_softirq+0xe1/0x560 irq_exit+0x104/0x110 smp_apic_timer_interrupt+0xb8/0x300 apic_timer_interrupt+0xf/0x20 </IRQ> RIP: 0010:cpuidle_enter_state+0xc4/0x430 RSP: 0018:ffff8803cd6c7d90 EFLAGS: 00000212 ORIG_RAX: ffffffffffffff12 RAX: 0000000000000000 RBX: ffffe8ffffcca660 RCX: ffffffff8112890c RDX: 0000000000000007 RSI: dffffc0000000000 RDI: ffff8803cd6b2f24 RBP: 0000000000011c2f R08: 0000000000000001 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000002 R13: ffffffff82d17658 R14: ffffffff82d17640 R15: ffffffff82d17680 ? trace_hardirqs_on_caller+0x18c/0x280 do_idle+0x1a9/0x1f0 cpu_startup_entry+0xc2/0xd0 ? cpu_in_idle+0x20/0x20 ? _raw_spin_unlock_irqrestore+0x32/0x50 ? trace_hardirqs_on_caller+0x18c/0x280 start_secondary+0x282/0x2f0 ? set_cpu_sibling_map+0x840/0x840 secondary_startup_64+0xa5/0xb0 random: crng init done device: '0:44': device_add PM: Adding info for No Bus:0:44 device: 'lo': device_add PM: Adding info for No Bus:lo r8169 0000:03:00.0 eth0: link up IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready bridge: filtering via arp/ip/ip6tables is no longer available by default. Update your scripts to load br_netfilter if you need this. device: 'lxcbr0': device_add PM: Adding info for No Bus:lxcbr0 IPv6: ADDRCONF(NETDEV_UP): lxcbr0: link is not ready PM: Removing info for No Bus:lxcbr0
thanks, -- Shuah
On 04/23/2018 02:07 PM, Shuah Khan wrote:
On 04/23/2018 12:03 PM, Greg Kroah-Hartman wrote:
On Sun, Apr 22, 2018 at 03:50:20PM +0200, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.16.4 release. There are 196 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Tue Apr 24 13:50:16 UTC 2018. 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.16.4-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.16.y and the diffstat can be found below.
There is a -rc3 out now, to fix some issues reported with -rc1 and -rc2 (I forgot to announce -rc2, sorry.): https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.16.4-rc3....
I just tried rc1 - will try rc3. Has the lock problem seen already: ( I will try rc3 and if I setill see the problem, will start bisect)
rc3 looks good. Compiled and booted on my test system. No dmesg regressions.
thanks, -- Shuah
On Mon, Apr 23, 2018 at 06:32:03PM -0600, Shuah Khan wrote:
On 04/23/2018 02:07 PM, Shuah Khan wrote:
On 04/23/2018 12:03 PM, Greg Kroah-Hartman wrote:
On Sun, Apr 22, 2018 at 03:50:20PM +0200, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.16.4 release. There are 196 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Tue Apr 24 13:50:16 UTC 2018. 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.16.4-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.16.y and the diffstat can be found below.
There is a -rc3 out now, to fix some issues reported with -rc1 and -rc2 (I forgot to announce -rc2, sorry.): https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.16.4-rc3....
I just tried rc1 - will try rc3. Has the lock problem seen already: ( I will try rc3 and if I setill see the problem, will start bisect)
rc3 looks good. Compiled and booted on my test system. No dmesg regressions.
Oh good. Thanks for testing two rounds of these for all of these kernels and letting me know.
greg k-h
On 22 April 2018 at 19:20, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 4.16.4 release. There are 196 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Tue Apr 24 13:50:16 UTC 2018. 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.16.4-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.16.y and the diffstat can be found below.
thanks,
greg k-h
Results from Linaro’s test farm. No regressions on arm64, arm and x86_64.
NOTE: Few comments inline regarding the reported failures. You ignore these infrastructure failures.
LKFT: kselftest: qemu arm32: zram test causes NULL pointer deference https://bugs.linaro.org/show_bug.cgi?id=3765 This is currently happening every time on mainline and 4.16
Summary ------------------------------------------------------------------------
kernel: 4.16.4-rc3 git repo: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git git branch: linux-4.16.y git commit: bc36a03baa9f6a85680606030ddaf5c6495c030f git describe: v4.16.3-196-gbc36a03baa9f Test details: https://qa-reports.linaro.org/lkft/linux-stable-rc-4.16-oe/build/v4.16.3-196...
No regressions (compared to build v4.16.3-197-g405d1f8b04d1) ------------------------------------------------------------------------
Boards, architectures and test suites: -------------------------------------
dragonboard-410c - arm64 * boot - pass: 20, fail: 2, ^ infrastructure issues * kselftest - pass: 41, fail: 6, skip: 20 ^ kselftest failures caused by kselftest upgrade to 4.16 (in all cases in this report) * libhugetlbfs - pass: 89, fail: 1, skip: 1 * ltp-cap_bounds-tests - pass: 2, * ltp-containers-tests - pass: 64, skip: 17 * ltp-fcntl-locktests-tests - pass: 2, * ltp-filecaps-tests - pass: 2, * ltp-fs-tests - pass: 57, skip: 6 * ltp-fs_bind-tests - pass: 2, * ltp-fs_perms_simple-tests - pass: 19, * ltp-fsx-tests - pass: 2, * ltp-hugetlb-tests - pass: 21, skip: 1 * ltp-io-tests - pass: 3, * ltp-ipc-tests - pass: 9, * ltp-math-tests - pass: 11, * ltp-nptl-tests - pass: 2, * ltp-pty-tests - pass: 4, * ltp-sched-tests - pass: 14, * ltp-securebits-tests - pass: 4, * ltp-syscalls-tests - pass: 1017, skip: 133 * ltp-timers-tests - pass: 13,
hi6220-hikey - arm64 * boot - pass: 20, * kselftest - pass: 46, fail: 5, skip: 17 * libhugetlbfs - pass: 90, skip: 1 * ltp-cap_bounds-tests - pass: 2, * ltp-containers-tests - pass: 64, skip: 17 * ltp-fcntl-locktests-tests - pass: 2, * ltp-filecaps-tests - pass: 2, * ltp-fs-tests - pass: 57, skip: 6 * ltp-fs_bind-tests - pass: 2, * ltp-fs_perms_simple-tests - pass: 19, * ltp-fsx-tests - pass: 2, * ltp-hugetlb-tests - pass: 21, skip: 1 * ltp-io-tests - pass: 3, * ltp-ipc-tests - pass: 9, * ltp-math-tests - pass: 11, * ltp-nptl-tests - pass: 2, * ltp-pty-tests - pass: 4, * ltp-sched-tests - pass: 10, skip: 4 * ltp-securebits-tests - pass: 4, * ltp-syscalls-tests - pass: 1016, skip: 134 * ltp-timers-tests - pass: 13,
juno-r2 - arm64 * boot - pass: 20, * kselftest - pass: 45, fail: 5, skip: 18 * libhugetlbfs - pass: 90, skip: 1 * ltp-cap_bounds-tests - pass: 2, * ltp-containers-tests - pass: 64, skip: 17 * ltp-fcntl-locktests-tests - pass: 2, * ltp-filecaps-tests - pass: 2, * ltp-fs-tests - pass: 57, skip: 6 * ltp-fs_bind-tests - pass: 2, * ltp-fs_perms_simple-tests - pass: 19, * ltp-fsx-tests - pass: 2, * ltp-hugetlb-tests - pass: 22, * ltp-io-tests - pass: 3, * ltp-ipc-tests - pass: 9, * ltp-math-tests - pass: 11, * ltp-nptl-tests - pass: 2, * ltp-pty-tests - pass: 4, * ltp-sched-tests - pass: 10, skip: 4 * ltp-securebits-tests - pass: 4, * ltp-syscalls-tests - pass: 1017, skip: 133 * ltp-timers-tests - pass: 13,
qemu_arm * boot - pass: 21, fail: 4, ^ infrastructure issues * kselftest - pass: 75, fail: 9, skip: 52 * libhugetlbfs - pass: 1, * ltp-cap_bounds-tests - pass: 2, * ltp-containers-tests - pass: 62, fail: 2, skip: 17 * ltp-fcntl-locktests-tests - pass: 2, * ltp-fs-tests - pass: 58, skip: 5 * ltp-fs_bind-tests - pass: 2, * ltp-fs_perms_simple-tests - pass: 19, * ltp-fsx-tests - pass: 2, * ltp-hugetlb-tests - pass: 21, skip: 1 * ltp-io-tests - pass: 3, * ltp-ipc-tests - pass: 9, * ltp-nptl-tests - pass: 2, * ltp-pty-tests - pass: 4, * ltp-securebits-tests - pass: 4, * ltp-timers-tests - pass: 13,
qemu_arm64 * boot - pass: 22, fail: 4, ^ infrastructure issues * kselftest - pass: 84, fail: 6, skip: 50 * libhugetlbfs - pass: 90, skip: 1 * ltp-cap_bounds-tests - pass: 2, * ltp-containers-tests - pass: 64, skip: 17 * ltp-fcntl-locktests-tests - pass: 2, * ltp-filecaps-tests - pass: 2, * ltp-fs-tests - pass: 57, skip: 6 * ltp-fs_bind-tests - pass: 2, * ltp-fs_perms_simple-tests - pass: 19, * ltp-fsx-tests - pass: 2, * ltp-hugetlb-tests - pass: 22, * ltp-io-tests - pass: 3, * ltp-ipc-tests - pass: 9, * ltp-nptl-tests - pass: 2, * ltp-pty-tests - pass: 4, * ltp-securebits-tests - pass: 4, * ltp-timers-tests - pass: 13,
qemu_x86_64 * boot - pass: 22, * kselftest - pass: 51, fail: 3, skip: 26 * kselftest-vsyscall-mode-native - pass: 51, fail: 3, skip: 26 * kselftest-vsyscall-mode-none - pass: 51, fail: 3, skip: 26 * libhugetlbfs - pass: 90, skip: 1 * ltp-cap_bounds-tests - pass: 2, * ltp-containers-tests - pass: 64, skip: 17 * ltp-fcntl-locktests-tests - pass: 2, * ltp-filecaps-tests - pass: 2, * ltp-fs-tests - pass: 57, skip: 6 * ltp-fs_bind-tests - pass: 2, * ltp-fs_perms_simple-tests - pass: 19, * ltp-fsx-tests - pass: 2, * ltp-hugetlb-tests - pass: 22, * ltp-io-tests - pass: 3, * ltp-ipc-tests - pass: 9, * ltp-math-tests - pass: 11, * ltp-nptl-tests - pass: 2, * ltp-pty-tests - pass: 4, * ltp-sched-tests - pass: 13, skip: 1 * ltp-securebits-tests - pass: 4, * ltp-syscalls-tests - pass: 1003, skip: 147 * ltp-timers-tests - pass: 13,
x15 - arm * boot - pass: 20, * kselftest - pass: 38, fail: 6, skip: 21 * libhugetlbfs - pass: 87, skip: 1 * ltp-cap_bounds-tests - pass: 2, * ltp-containers-tests - pass: 63, skip: 18 * ltp-fcntl-locktests-tests - pass: 2, * ltp-filecaps-tests - pass: 2, * ltp-fs-tests - pass: 58, skip: 5 * ltp-fs_bind-tests - pass: 2, * ltp-fs_perms_simple-tests - pass: 19, * ltp-fsx-tests - pass: 2, * ltp-hugetlb-tests - pass: 20, skip: 2 * ltp-io-tests - pass: 3, * ltp-ipc-tests - pass: 9, * ltp-math-tests - pass: 11, * ltp-nptl-tests - pass: 2, * ltp-pty-tests - pass: 4, * ltp-sched-tests - pass: 13, skip: 1 * ltp-securebits-tests - pass: 4, * ltp-syscalls-tests - pass: 1075, skip: 75 * ltp-timers-tests - pass: 13,
x86_64 * boot - pass: 22, * kselftest - pass: 55, fail: 5, skip: 19 * kselftest-vsyscall-mode-native - pass: 55, fail: 5, skip: 19 * kselftest-vsyscall-mode-none - pass: 56, fail: 5, skip: 19 * libhugetlbfs - pass: 89, skip: 1 * ltp-cap_bounds-tests - pass: 2, * ltp-containers-tests - pass: 64, skip: 17 * ltp-fcntl-locktests-tests - pass: 2, * ltp-filecaps-tests - pass: 2, * ltp-fs-tests - pass: 58, skip: 5 * ltp-fs_bind-tests - pass: 2, * ltp-fs_perms_simple-tests - pass: 19, * ltp-fsx-tests - pass: 2, * ltp-hugetlb-tests - pass: 22, * ltp-io-tests - pass: 3, * ltp-ipc-tests - pass: 9, * ltp-math-tests - pass: 11, * ltp-nptl-tests - pass: 2, * ltp-pty-tests - pass: 4, * ltp-sched-tests - pass: 9, skip: 5 * ltp-securebits-tests - pass: 4, * ltp-syscalls-tests - pass: 1034, skip: 116 * ltp-timers-tests - pass: 13,
linux-stable-mirror@lists.linaro.org