This is the start of the stable review cycle for the 5.4.35 release. There are 118 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 Fri, 24 Apr 2020 09:48:23 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.4.35-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.4.y and the diffstat can be found below.
thanks,
greg k-h
------------- Pseudo-Shortlog of commits:
Greg Kroah-Hartman gregkh@linuxfoundation.org Linux 5.4.35-rc1
Daniel Borkmann daniel@iogearbox.net bpf, test_verifier: switch bpf_get_stack's 0 s> r8 test
John Fastabend john.fastabend@gmail.com bpf: Test_progs, add test to catch retval refine error handling
John Fastabend john.fastabend@gmail.com bpf: Test_verifier, bpf_get_stack return value add <0
Daniel Borkmann daniel@iogearbox.net bpf: fix buggy r0 retval refinement for tracing helpers
Waiman Long longman@redhat.com KEYS: Don't write out to userspace while holding key semaphore
Wen Yang wenyang@linux.alibaba.com mtd: phram: fix a double free issue in error path
Dan Carpenter dan.carpenter@oracle.com mtd: lpddr: Fix a double free in probe()
Jonathan Neuschäfer j.neuschaefer@gmx.net docs: Fix path to MTD command line partition parser
Frieder Schrempf frieder.schrempf@kontron.de mtd: spinand: Explicitly use MTD_OPS_RAW to write the bad block marker to OOB
Christophe Kerello christophe.kerello@st.com mtd: rawnand: free the nand_device object
Paul E. McKenney paulmck@kernel.org locktorture: Print ratio of acquisitions, not failures
Stephen Rothwell sfr@canb.auug.org.au tty: evh_bytechan: Fix out of bounds accesses
Nathan Chancellor natechancellor@gmail.com fbmem: Adjust indentation in fb_prepare_logo and fb_blank
Maxime Roussin-Bélanger maxime.roussinbelanger@gmail.com iio: si1133: read 24-bit signed integer for measurement
Jernej Skrabec jernej.skrabec@siol.net ARM: dts: sunxi: Fix DE2 clocks register range
Dan Carpenter dan.carpenter@oracle.com fbdev: potential information leak in do_fb_ioctl()
Grygorii Strashko grygorii.strashko@ti.com dma-debug: fix displaying of dma allocation type
Florian Fainelli f.fainelli@gmail.com net: dsa: bcm_sf2: Fix overflow checks
Ben Skeggs bskeggs@redhat.com drm/nouveau/gr/gp107,gp108: implement workaround for HW hanging during init
Chao Yu chao@kernel.org f2fs: fix to wait all node page writeback
Adrian Huang ahuang12@lenovo.com iommu/amd: Fix the configuration of GCR3 table root pointer
Dan Carpenter dan.carpenter@oracle.com libnvdimm: Out of bounds read in __nd_ioctl()
Jeffery Miller jmiller@neverware.com power: supply: axp288_fuel_gauge: Broaden vendor check for Intel Compute Sticks.
Guo Ren guoren@linux.alibaba.com csky: Fixup init_fpu compile warning with __init
Chuck Lever chuck.lever@oracle.com sunrpc: Fix gss_unwrap_resp_integ() again
Jan Kara jack@suse.cz ext2: fix debug reference to ext2_xattr_cache
Jacob Pan jacob.jun.pan@linux.intel.com iommu/vt-d: Fix page request descriptor size
Qian Cai cai@lca.pw iommu/vt-d: Silence RCU-list debugging warning in dmar_find_atsr()
Randy Dunlap rdunlap@infradead.org ext2: fix empty body warnings when -Wextra is used
Olga Kornievskaia olga.kornievskaia@gmail.com SUNRPC: fix krb5p mount to provide large enough buffer in rq_rcvsize
Jacob Pan jacob.jun.pan@linux.intel.com iommu/vt-d: Fix mm reference leak
Jean-Philippe Brucker jean-philippe@linaro.org iommu/virtio: Fix freeing of incomplete domains
Nicolas Saenz Julienne nsaenzjulienne@suse.de drm/vc4: Fix HDMI mode validation
Alan Maguire alan.maguire@oracle.com um: falloc.h needs to be directly included for older libc
Bob Moore robert.moore@intel.com ACPICA: Fixes for acpiExec namespace init file
Chao Yu chao@kernel.org f2fs: fix NULL pointer dereference in f2fs_write_begin()
Guo Ren guoren@linux.alibaba.com csky: Fixup get wrong psr value from phyical reg
Trond Myklebust trond.myklebust@hammerspace.com NFS: Fix memory leaks in nfs_pageio_stop_mirroring()
Jack Zhang Jack.Zhang1@amd.com drm/amdkfd: kfree the wrong pointer
Guo Ren guoren@linux.alibaba.com csky: Fixup cpu speculative execution to IO area
Qian Cai cai@lca.pw x86: ACPI: fix CPU hotplug deadlock
Ricardo Ribalda Delgado ribalda@kernel.org leds: core: Fix warning message when init_data
Karol Herbst kherbst@redhat.com drm/nouveau: workaround runpm fail by disabling PCI power management on certain intel bridges
David Hildenbrand david@redhat.com KVM: s390: vsie: Fix possible race when shadowing region 3 tables
Vegard Nossum vegard.nossum@oracle.com compiler.h: fix error in BUILD_BUG_ON() reporting
Qian Cai cai@lca.pw percpu_counter: fix a data race at vm_committed_as
Steven Price steven.price@arm.com include/linux/swapops.h: correct guards for non_swap_entry()
Ralph Campbell rcampbell@nvidia.com drm/nouveau/svm: fix vma range check for migration
Ralph Campbell rcampbell@nvidia.com drm/nouveau/svm: check for SVM initialized before migrating
Christophe Leroy christophe.leroy@c-s.fr mm/hugetlb: fix build failure with HUGETLB_PAGE but not HUGEBTLBFS
Long Li longli@microsoft.com cifs: Allocate encryption header through kmalloc
Gabriel Krisman Bertazi krisman@collabora.com um: ubd: Prevent buffer overrun on command completion
Eric Sandeen sandeen@redhat.com ext4: do not commit super on read-only bdev
Thomas Richter tmricht@linux.ibm.com s390/cpum_sf: Fix wrong page count in error message
Nathan Chancellor natechancellor@gmail.com powerpc/maple: Fix declaration made after definition
Alexey Kardashevskiy aik@ozlabs.ru powerpc/prom_init: Pass the "os-term" message to hypervisor
Madhuparna Bhowmik madhuparnabhowmik10@gmail.com btrfs: add RCU locks around block group initialization
Domenico Andreoli domenico.andreoli@linux.com hibernate: Allow uswsusp to write to swap
Alexander Gordeev agordeev@linux.ibm.com s390/cpuinfo: fix wrong output when CPU0 is offline
Sahitya Tummala stummala@codeaurora.org f2fs: Add a new CP flag to help fsck fix resize SPO issues
Sahitya Tummala stummala@codeaurora.org f2fs: Fix mount failure due to SPO after a successful online resize FS
Misono Tomohiro misono.tomohiro@jp.fujitsu.com NFS: direct.c: Fix memory leak of dreq when nfs_get_lock_context fails
Kunihiko Hayashi hayashi.kunihiko@socionext.com phy: uniphier-usb3ss: Add Pro5 support
Chao Yu chao@kernel.org f2fs: fix to show norecovery mount option
Michael Roth mdroth@linux.vnet.ibm.com KVM: PPC: Book3S HV: Fix H_CEDE return code for nested guests
Johan Jonker jbx6244@gmail.com ARM: dts: rockchip: fix lvds-encoder ports subnode for rk3188-bqedison2qc
Murphy Zhou jencce.kernel@gmail.com NFSv4.2: error out when relink swapfile
Trond Myklebust trond.myklebust@hammerspace.com NFSv4/pnfs: Return valid stateids in nfs_layout_find_inode_by_stateid()
Trond Myklebust trond.myklebust@hammerspace.com NFS: alloc_nfs_open_context() must use the file cred when available
Alexandre Belloni alexandre.belloni@bootlin.com rtc: 88pm860x: fix possible race condition
Kevin Grandemange kevin.grandemange@allegrodvt.com dma-coherent: fix integer overflow in the reserved-memory dma allocation
Lucas Stach l.stach@pengutronix.de soc: imx: gpc: fix power up sequencing
Russell King rmk+kernel@armlinux.org.uk arm64: dts: clearfog-gt-8k: set gigabit PHY reset deassert delay
Jon Hunter jonathanh@nvidia.com arm64: tegra: Fix Tegra194 PCIe compatible string
Vidya Sagar vidyas@nvidia.com arm64: tegra: Add PCIe endpoint controllers nodes for Tegra194
Sowjanya Komatineni skomatineni@nvidia.com clk: tegra: Fix Tegra PMC clock out parents
Dmitry Osipenko digetx@gmail.com power: supply: bq27xxx_battery: Silence deferred-probe error
Jernej Skrabec jernej.skrabec@siol.net arm64: dts: allwinner: a64: Fix display clock register range
Johan Jonker jbx6244@gmail.com ARM: dts: rockchip: fix vqmmc-supply property name for rk3188-bqedison2qc
Sahitya Tummala stummala@codeaurora.org f2fs: fix the panic in do_checkpoint()
Aya Levin ayal@mellanox.com net/mlx5e: Enforce setting of a single FEC mode
Claudiu Beznea claudiu.beznea@microchip.com clk: at91: usb: continue if clk_hw_round_rate() return zero
Stephen Boyd sboyd@kernel.org clk: Don't cache errors from clk_ops::get_phase()
xinhui pan xinhui.pan@amd.com drm/ttm: flush the fence on the bo after we individualize the reservation object
Tianyu Lan Tianyu.Lan@microsoft.com x86/Hyper-V: Free hv_panic_page when fail to register kmsg dump
Ilya Dryomov idryomov@gmail.com rbd: call rbd_dev_unprobe() after unwatching and flushing notifies
Ilya Dryomov idryomov@gmail.com rbd: avoid a deadlock on header_rwsem when flushing notifies
Paolo Valente paolo.valente@linaro.org block, bfq: invoke flush_idle_tree after reparent_active_queues in pd_offline
Paolo Valente paolo.valente@linaro.org block, bfq: make reparent_leaf_entity actually work only on leaf entities
Paolo Valente paolo.valente@linaro.org block, bfq: turn put_queue into release_process_ref in __bfq_bic_change_cgroup
David Howells dhowells@redhat.com afs: Fix race between post-modification dir edit and readdir/d_revalidate
David Howells dhowells@redhat.com afs: Fix afs_d_validate() to set the right directory version
David Howells dhowells@redhat.com afs: Fix rename operation status delivery
David Howells dhowells@redhat.com afs: Fix decoding of inline abort codes from version 1 status records
David Howells dhowells@redhat.com afs: Fix missing XDR advance in xdr_decode_{AFS,YFS}FSFetchStatus()
Tianyu Lan Tianyu.Lan@microsoft.com x86/Hyper-V: Report crash data in die() when panic_on_oops is set
Tianyu Lan Tianyu.Lan@microsoft.com x86/Hyper-V: Report crash register data when sysctl_record_panic_msg is not set
Tianyu Lan Tianyu.Lan@microsoft.com x86/Hyper-V: Report crash register data or kmsg before running crash kernel
Tianyu Lan Tianyu.Lan@microsoft.com x86/Hyper-V: Trigger crash enlightenment only once during system crash.
Tianyu Lan Tianyu.Lan@microsoft.com x86/Hyper-V: Unload vmbus channel in hv panic callback
Frank Rowand frank.rowand@sony.com of: overlay: kmemleak in dup_and_fixup_symbol_prop()
Frank Rowand frank.rowand@sony.com of: unittest: kmemleak in of_unittest_overlay_high_level()
Frank Rowand frank.rowand@sony.com of: unittest: kmemleak in of_unittest_platform_populate()
Frank Rowand frank.rowand@sony.com of: unittest: kmemleak on changeset destroy
Magnus Karlsson magnus.karlsson@intel.com xsk: Add missing check on user supplied headroom size
Takashi Iwai tiwai@suse.de ALSA: hda: Don't release card at firmware loading error
Zenghui Yu yuzenghui@huawei.com irqchip/mbigen: Free msi_desc on device teardown
Pablo Neira Ayuso pablo@netfilter.org netfilter: nf_tables: report EOPNOTSUPP on unsupported flags/object type
Slava Bacherikov slava@bacher09.org kbuild, btf: Fix dependencies for DEBUG_INFO_BTF
Martin Fuzzey martin.fuzzey@flowbird.group ARM: dts: imx6: Use gpc for FEC interrupt controller to fix wake on LAN.
Takashi Iwai tiwai@suse.de ALSA: hda: Honor PM disablement in PM freeze and thaw_noirq ops
Li Bin huawei.libin@huawei.com scsi: sg: add sg_remove_request in sg_common_write
Josh Poimboeuf jpoimboe@redhat.com objtool: Fix switch table detection in .text.unlikely
Luke Nelson lukenels@cs.washington.edu arm, bpf: Fix offset overflow for BPF_MEM BPF_DW
Luke Nelson lukenels@cs.washington.edu arm, bpf: Fix bugs with ALU64 {RSH, ARSH} BPF_K shift by 0
Li RongQing lirongqing@baidu.com xsk: Fix out of boundary write in __xsk_rcv_memcpy
Michael Walle michael@walle.cc watchdog: sp805: fix restart handler
Roman Gushchin guro@fb.com ext4: use non-movable memory for superblock readahead
-------------
Diffstat:
Documentation/admin-guide/kernel-parameters.txt | 2 +- .../bindings/pci/nvidia,tegra194-pcie.txt | 2 +- Makefile | 4 +- arch/arm/boot/dts/imx6qdl.dtsi | 5 +- arch/arm/boot/dts/imx6qp.dtsi | 1 - arch/arm/boot/dts/rk3188-bqedison2qc.dts | 29 +++--- arch/arm/boot/dts/sun8i-a83t.dtsi | 2 +- arch/arm/boot/dts/sun8i-r40.dtsi | 2 +- arch/arm/boot/dts/sun8i-v3s.dtsi | 2 +- arch/arm/boot/dts/sunxi-h3-h5.dtsi | 2 +- arch/arm/net/bpf_jit_32.c | 52 ++++++---- arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 2 +- .../dts/marvell/armada-8040-clearfog-gt-8k.dts | 1 + arch/arm64/boot/dts/nvidia/tegra194.dtsi | 111 +++++++++++++++++++-- arch/csky/abiv1/inc/abi/entry.h | 5 +- arch/csky/abiv2/fpu.c | 5 - arch/csky/abiv2/inc/abi/entry.h | 7 +- arch/csky/abiv2/inc/abi/fpu.h | 3 +- arch/csky/include/asm/processor.h | 1 + arch/csky/kernel/head.S | 5 + arch/csky/kernel/setup.c | 63 +++--------- arch/csky/kernel/smp.c | 6 ++ arch/csky/kernel/traps.c | 11 +- arch/csky/mm/fault.c | 7 ++ arch/powerpc/kernel/prom_init.c | 3 + arch/powerpc/kvm/book3s_hv.c | 1 + arch/powerpc/platforms/maple/setup.c | 34 +++---- arch/s390/kernel/perf_cpum_sf.c | 1 + arch/s390/kernel/processor.c | 5 +- arch/s390/mm/gmap.c | 1 + arch/um/drivers/ubd_kern.c | 4 +- arch/um/os-Linux/file.c | 1 + arch/x86/hyperv/hv_init.c | 6 +- arch/x86/kernel/acpi/cstate.c | 3 +- arch/x86/kernel/cpu/mshyperv.c | 10 ++ block/bfq-cgroup.c | 73 ++++++++------ block/bfq-iosched.c | 2 - block/bfq-iosched.h | 1 + drivers/acpi/acpica/acnamesp.h | 2 + drivers/acpi/acpica/dbinput.c | 16 ++- drivers/acpi/acpica/dswexec.c | 33 ++++++ drivers/acpi/acpica/dswload.c | 2 - drivers/acpi/acpica/dswload2.c | 35 +++++++ drivers/acpi/acpica/nsnames.c | 6 +- drivers/acpi/acpica/utdelete.c | 9 +- drivers/acpi/processor_throttling.c | 7 -- drivers/block/rbd.c | 25 +++-- drivers/clk/at91/clk-usb.c | 3 + drivers/clk/clk.c | 48 ++++++--- drivers/clk/tegra/clk-tegra-pmc.c | 12 +-- drivers/gpu/drm/amd/amdkfd/kfd_device.c | 4 +- drivers/gpu/drm/nouveau/nouveau_drm.c | 63 ++++++++++++ drivers/gpu/drm/nouveau/nouveau_drv.h | 2 + drivers/gpu/drm/nouveau/nouveau_svm.c | 6 ++ drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 26 +++++ drivers/gpu/drm/ttm/ttm_bo.c | 4 +- drivers/gpu/drm/vc4/vc4_hdmi.c | 20 +++- drivers/hv/channel_mgmt.c | 3 + drivers/hv/vmbus_drv.c | 62 ++++++++---- drivers/iio/light/si1133.c | 37 ++++--- drivers/iommu/amd_iommu_types.h | 2 +- drivers/iommu/intel-iommu.c | 3 +- drivers/iommu/intel-svm.c | 9 +- drivers/iommu/virtio-iommu.c | 16 +-- drivers/irqchip/irq-mbigen.c | 8 +- drivers/leds/led-class.c | 2 +- drivers/mtd/devices/phram.c | 15 +-- drivers/mtd/lpddr/lpddr_cmds.c | 1 - drivers/mtd/nand/raw/nand_base.c | 2 + drivers/mtd/nand/spi/core.c | 1 + drivers/net/dsa/bcm_sf2_cfp.c | 9 +- .../net/ethernet/mellanox/mlx5/core/en_ethtool.c | 4 + drivers/nvdimm/bus.c | 6 +- drivers/of/overlay.c | 2 + drivers/of/unittest.c | 16 ++- drivers/phy/socionext/phy-uniphier-usb3ss.c | 4 + drivers/power/supply/axp288_fuel_gauge.c | 4 +- drivers/power/supply/bq27xxx_battery.c | 5 +- drivers/rtc/rtc-88pm860x.c | 14 +-- drivers/scsi/sg.c | 4 +- drivers/soc/imx/gpc.c | 24 +++-- drivers/tty/ehv_bytechan.c | 21 +++- drivers/video/fbdev/core/fbmem.c | 38 +++---- drivers/watchdog/sp805_wdt.c | 4 + fs/afs/dir.c | 108 ++++++++++++-------- fs/afs/dir_silly.c | 22 ++-- fs/afs/fsclient.c | 27 +++-- fs/afs/yfsclient.c | 20 ++-- fs/block_dev.c | 4 +- fs/btrfs/block-group.c | 2 + fs/buffer.c | 11 ++ fs/cifs/transport.c | 28 ++++-- fs/ext2/xattr.c | 8 +- fs/ext4/inode.c | 2 +- fs/ext4/super.c | 5 +- fs/f2fs/checkpoint.c | 24 +++-- fs/f2fs/f2fs.h | 3 +- fs/f2fs/gc.c | 6 ++ fs/f2fs/node.c | 7 +- fs/f2fs/super.c | 14 ++- fs/nfs/callback_proc.c | 2 + fs/nfs/direct.c | 2 + fs/nfs/inode.c | 10 +- fs/nfs/nfs4file.c | 3 + fs/nfs/pagelist.c | 17 ++-- include/acpi/processor.h | 8 ++ include/asm-generic/mshyperv.h | 2 +- include/keys/big_key-type.h | 2 +- include/keys/user-type.h | 3 +- include/linux/buffer_head.h | 8 ++ include/linux/compiler.h | 2 +- include/linux/f2fs_fs.h | 1 + include/linux/hugetlb.h | 19 ++-- include/linux/key-type.h | 2 +- include/linux/percpu_counter.h | 4 +- include/linux/swapops.h | 3 +- kernel/bpf/verifier.c | 45 +++++++-- kernel/dma/coherent.c | 13 +-- kernel/dma/debug.c | 9 +- kernel/locking/locktorture.c | 8 +- lib/Kconfig.debug | 2 + net/dns_resolver/dns_key.c | 2 +- net/netfilter/nf_tables_api.c | 4 +- net/rxrpc/key.c | 27 ++--- net/sunrpc/auth_gss/auth_gss.c | 80 +++++++++++---- net/xdp/xdp_umem.c | 5 +- net/xdp/xsk.c | 5 +- security/keys/big_key.c | 11 +- security/keys/encrypted-keys/encrypted.c | 7 +- security/keys/keyctl.c | 73 +++++++++++--- security/keys/keyring.c | 6 +- security/keys/request_key_auth.c | 7 +- security/keys/trusted.c | 14 +-- security/keys/user_defined.c | 5 +- sound/pci/hda/hda_intel.c | 23 ++--- tools/objtool/check.c | 5 +- .../selftests/bpf/prog_tests/get_stack_raw_tp.c | 5 + .../selftests/bpf/progs/test_get_stack_rawtp_err.c | 26 +++++ .../testing/selftests/bpf/verifier/bpf_get_stack.c | 8 +- 139 files changed, 1263 insertions(+), 620 deletions(-)
From: Roman Gushchin guro@fb.com
commit d87f639258a6a5980183f11876c884931ad93da2 upstream.
Since commit a8ac900b8163 ("ext4: use non-movable memory for the superblock") buffers for ext4 superblock were allocated using the sb_bread_unmovable() helper which allocated buffer heads out of non-movable memory blocks. It was necessarily to not block page migrations and do not cause cma allocation failures.
However commit 85c8f176a611 ("ext4: preload block group descriptors") broke this by introducing pre-reading of the ext4 superblock. The problem is that __breadahead() is using __getblk() underneath, which allocates buffer heads out of movable memory.
It resulted in page migration failures I've seen on a machine with an ext4 partition and a preallocated cma area.
Fix this by introducing sb_breadahead_unmovable() and __breadahead_gfp() helpers which use non-movable memory for buffer head allocations and use them for the ext4 superblock readahead.
Reviewed-by: Andreas Dilger adilger@dilger.ca Fixes: 85c8f176a611 ("ext4: preload block group descriptors") Signed-off-by: Roman Gushchin guro@fb.com Link: https://lore.kernel.org/r/20200229001411.128010-1-guro@fb.com Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/buffer.c | 11 +++++++++++ fs/ext4/inode.c | 2 +- fs/ext4/super.c | 2 +- include/linux/buffer_head.h | 8 ++++++++ 4 files changed, 21 insertions(+), 2 deletions(-)
--- a/fs/buffer.c +++ b/fs/buffer.c @@ -1337,6 +1337,17 @@ void __breadahead(struct block_device *b } EXPORT_SYMBOL(__breadahead);
+void __breadahead_gfp(struct block_device *bdev, sector_t block, unsigned size, + gfp_t gfp) +{ + struct buffer_head *bh = __getblk_gfp(bdev, block, size, gfp); + if (likely(bh)) { + ll_rw_block(REQ_OP_READ, REQ_RAHEAD, 1, &bh); + brelse(bh); + } +} +EXPORT_SYMBOL(__breadahead_gfp); + /** * __bread_gfp() - reads a specified block and returns the bh * @bdev: the block_device to read from --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -4680,7 +4680,7 @@ make_io: if (end > table) end = table; while (b <= end) - sb_breadahead(sb, b++); + sb_breadahead_unmovable(sb, b++); }
/* --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -4283,7 +4283,7 @@ static int ext4_fill_super(struct super_ /* Pre-read the descriptors into the buffer cache */ for (i = 0; i < db_count; i++) { block = descriptor_loc(sb, logical_sb_block, i); - sb_breadahead(sb, block); + sb_breadahead_unmovable(sb, block); }
for (i = 0; i < db_count; i++) { --- a/include/linux/buffer_head.h +++ b/include/linux/buffer_head.h @@ -189,6 +189,8 @@ struct buffer_head *__getblk_gfp(struct void __brelse(struct buffer_head *); void __bforget(struct buffer_head *); void __breadahead(struct block_device *, sector_t block, unsigned int size); +void __breadahead_gfp(struct block_device *, sector_t block, unsigned int size, + gfp_t gfp); struct buffer_head *__bread_gfp(struct block_device *, sector_t block, unsigned size, gfp_t gfp); void invalidate_bh_lrus(void); @@ -319,6 +321,12 @@ sb_breadahead(struct super_block *sb, se __breadahead(sb->s_bdev, block, sb->s_blocksize); }
+static inline void +sb_breadahead_unmovable(struct super_block *sb, sector_t block) +{ + __breadahead_gfp(sb->s_bdev, block, sb->s_blocksize, 0); +} + static inline struct buffer_head * sb_getblk(struct super_block *sb, sector_t block) {
From: Michael Walle michael@walle.cc
commit ea104a9e4d3e9ebc26fb78dac35585b142ee288b upstream.
The restart handler is missing two things, first, the registers has to be unlocked and second there is no synchronization for the write_relaxed() calls.
This was tested on a custom board with the NXP LS1028A SoC.
Fixes: 6c5c0d48b686c ("watchdog: sp805: add restart handler") Signed-off-by: Michael Walle michael@walle.cc Reviewed-by: Guenter Roeck linux@roeck-us.net Link: https://lore.kernel.org/r/20200327162450.28506-1-michael@walle.cc Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Wim Van Sebroeck wim@linux-watchdog.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/watchdog/sp805_wdt.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/drivers/watchdog/sp805_wdt.c +++ b/drivers/watchdog/sp805_wdt.c @@ -137,10 +137,14 @@ wdt_restart(struct watchdog_device *wdd, { struct sp805_wdt *wdt = watchdog_get_drvdata(wdd);
+ writel_relaxed(UNLOCK, wdt->base + WDTLOCK); writel_relaxed(0, wdt->base + WDTCONTROL); writel_relaxed(0, wdt->base + WDTLOAD); writel_relaxed(INT_ENABLE | RESET_ENABLE, wdt->base + WDTCONTROL);
+ /* Flush posted writes. */ + readl_relaxed(wdt->base + WDTLOCK); + return 0; }
From: Li RongQing lirongqing@baidu.com
commit db5c97f02373917efe2c218ebf8e3d8b19e343b6 upstream.
first_len is the remainder of the first page we're copying. If this size is larger, then out of page boundary write will otherwise happen.
Fixes: c05cd3645814 ("xsk: add support to allow unaligned chunk placement") Signed-off-by: Li RongQing lirongqing@baidu.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Acked-by: Jonathan Lemon jonathan.lemon@gmail.com Acked-by: Björn Töpel bjorn.topel@intel.com Link: https://lore.kernel.org/bpf/1585813930-19712-1-git-send-email-lirongqing@bai... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- net/xdp/xsk.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
--- a/net/xdp/xsk.c +++ b/net/xdp/xsk.c @@ -129,8 +129,9 @@ static void __xsk_rcv_memcpy(struct xdp_ u64 page_start = addr & ~(PAGE_SIZE - 1); u64 first_len = PAGE_SIZE - (addr - page_start);
- memcpy(to_buf, from_buf, first_len + metalen); - memcpy(next_pg_addr, from_buf + first_len, len - first_len); + memcpy(to_buf, from_buf, first_len); + memcpy(next_pg_addr, from_buf + first_len, + len + metalen - first_len);
return; }
From: Luke Nelson lukenels@cs.washington.edu
commit bb9562cf5c67813034c96afb50bd21130a504441 upstream.
The current arm BPF JIT does not correctly compile RSH or ARSH when the immediate shift amount is 0. This causes the "rsh64 by 0 imm" and "arsh64 by 0 imm" BPF selftests to hang the kernel by reaching an instruction the verifier determines to be unreachable.
The root cause is in how immediate right shifts are encoded on arm. For LSR and ASR (logical and arithmetic right shift), a bit-pattern of 00000 in the immediate encodes a shift amount of 32. When the BPF immediate is 0, the generated code shifts by 32 instead of the expected behavior (a no-op).
This patch fixes the bugs by adding an additional check if the BPF immediate is 0. After the change, the above mentioned BPF selftests pass.
Fixes: 39c13c204bb11 ("arm: eBPF JIT compiler") Co-developed-by: Xi Wang xi.wang@gmail.com Signed-off-by: Xi Wang xi.wang@gmail.com Signed-off-by: Luke Nelson luke.r.nels@gmail.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Link: https://lore.kernel.org/bpf/20200408181229.10909-1-luke.r.nels@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/arm/net/bpf_jit_32.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
--- a/arch/arm/net/bpf_jit_32.c +++ b/arch/arm/net/bpf_jit_32.c @@ -929,7 +929,11 @@ static inline void emit_a32_rsh_i64(cons rd = arm_bpf_get_reg64(dst, tmp, ctx);
/* Do LSR operation */ - if (val < 32) { + if (val == 0) { + /* An immediate value of 0 encodes a shift amount of 32 + * for LSR. To shift by 0, don't do anything. + */ + } else if (val < 32) { emit(ARM_MOV_SI(tmp2[1], rd[1], SRTYPE_LSR, val), ctx); emit(ARM_ORR_SI(rd[1], tmp2[1], rd[0], SRTYPE_ASL, 32 - val), ctx); emit(ARM_MOV_SI(rd[0], rd[0], SRTYPE_LSR, val), ctx); @@ -955,7 +959,11 @@ static inline void emit_a32_arsh_i64(con rd = arm_bpf_get_reg64(dst, tmp, ctx);
/* Do ARSH operation */ - if (val < 32) { + if (val == 0) { + /* An immediate value of 0 encodes a shift amount of 32 + * for ASR. To shift by 0, don't do anything. + */ + } else if (val < 32) { emit(ARM_MOV_SI(tmp2[1], rd[1], SRTYPE_LSR, val), ctx); emit(ARM_ORR_SI(rd[1], tmp2[1], rd[0], SRTYPE_ASL, 32 - val), ctx); emit(ARM_MOV_SI(rd[0], rd[0], SRTYPE_ASR, val), ctx);
From: Luke Nelson lukenels@cs.washington.edu
commit 4178417cc5359c329790a4a8f4a6604612338cca upstream.
This patch fixes an incorrect check in how immediate memory offsets are computed for BPF_DW on arm.
For BPF_LDX/ST/STX + BPF_DW, the 32-bit arm JIT breaks down an 8-byte access into two separate 4-byte accesses using off+0 and off+4. If off fits in imm12, the JIT emits a ldr/str instruction with the immediate and avoids the use of a temporary register. While the current check off <= 0xfff ensures that the first immediate off+0 doesn't overflow imm12, it's not sufficient for the second immediate off+4, which may cause the second access of BPF_DW to read/write the wrong address.
This patch fixes the problem by changing the check to off <= 0xfff - 4 for BPF_DW, ensuring off+4 will never overflow.
A side effect of simplifying the check is that it now allows using negative immediate offsets in ldr/str. This means that small negative offsets can also avoid the use of a temporary register.
This patch introduces no new failures in test_verifier or test_bpf.c.
Fixes: c5eae692571d6 ("ARM: net: bpf: improve 64-bit store implementation") Fixes: ec19e02b343db ("ARM: net: bpf: fix LDX instructions") Co-developed-by: Xi Wang xi.wang@gmail.com Signed-off-by: Xi Wang xi.wang@gmail.com Signed-off-by: Luke Nelson luke.r.nels@gmail.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Link: https://lore.kernel.org/bpf/20200409221752.28448-1-luke.r.nels@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/arm/net/bpf_jit_32.c | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-)
--- a/arch/arm/net/bpf_jit_32.c +++ b/arch/arm/net/bpf_jit_32.c @@ -1000,21 +1000,35 @@ static inline void emit_a32_mul_r64(cons arm_bpf_put_reg32(dst_hi, rd[0], ctx); }
+static bool is_ldst_imm(s16 off, const u8 size) +{ + s16 off_max = 0; + + switch (size) { + case BPF_B: + case BPF_W: + off_max = 0xfff; + break; + case BPF_H: + off_max = 0xff; + break; + case BPF_DW: + /* Need to make sure off+4 does not overflow. */ + off_max = 0xfff - 4; + break; + } + return -off_max <= off && off <= off_max; +} + /* *(size *)(dst + off) = src */ static inline void emit_str_r(const s8 dst, const s8 src[], - s32 off, struct jit_ctx *ctx, const u8 sz){ + s16 off, struct jit_ctx *ctx, const u8 sz){ const s8 *tmp = bpf2a32[TMP_REG_1]; - s32 off_max; s8 rd;
rd = arm_bpf_get_reg32(dst, tmp[1], ctx);
- if (sz == BPF_H) - off_max = 0xff; - else - off_max = 0xfff; - - if (off < 0 || off > off_max) { + if (!is_ldst_imm(off, sz)) { emit_a32_mov_i(tmp[0], off, ctx); emit(ARM_ADD_R(tmp[0], tmp[0], rd), ctx); rd = tmp[0]; @@ -1043,18 +1057,12 @@ static inline void emit_str_r(const s8 d
/* dst = *(size*)(src + off) */ static inline void emit_ldx_r(const s8 dst[], const s8 src, - s32 off, struct jit_ctx *ctx, const u8 sz){ + s16 off, struct jit_ctx *ctx, const u8 sz){ const s8 *tmp = bpf2a32[TMP_REG_1]; const s8 *rd = is_stacked(dst_lo) ? tmp : dst; s8 rm = src; - s32 off_max; - - if (sz == BPF_H) - off_max = 0xff; - else - off_max = 0xfff;
- if (off < 0 || off > off_max) { + if (!is_ldst_imm(off, sz)) { emit_a32_mov_i(tmp[0], off, ctx); emit(ARM_ADD_R(tmp[0], tmp[0], src), ctx); rm = tmp[0];
From: Josh Poimboeuf jpoimboe@redhat.com
commit b401efc120a399dfda1f4d2858a4de365c9b08ef upstream.
If a switch jump table's indirect branch is in a ".cold" subfunction in .text.unlikely, objtool doesn't detect it, and instead prints a false warning:
drivers/media/v4l2-core/v4l2-ioctl.o: warning: objtool: v4l_print_format.cold()+0xd6: sibling call from callable instruction with modified stack frame drivers/hwmon/max6650.o: warning: objtool: max6650_probe.cold()+0xa5: sibling call from callable instruction with modified stack frame drivers/media/dvb-frontends/drxk_hard.o: warning: objtool: init_drxk.cold()+0x16f: sibling call from callable instruction with modified stack frame
Fix it by comparing the function, instead of the section and offset.
Fixes: 13810435b9a7 ("objtool: Support GCC 8's cold subfunctions") Signed-off-by: Josh Poimboeuf jpoimboe@redhat.com Signed-off-by: Borislav Petkov bp@suse.de Reviewed-by: Miroslav Benes mbenes@suse.cz Acked-by: Peter Zijlstra (Intel) peterz@infradead.org Link: https://lkml.kernel.org/r/157c35d42ca9b6354bbb1604fe9ad7d1153ccb21.158576102... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- tools/objtool/check.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
--- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -1010,10 +1010,7 @@ static struct rela *find_jump_table(stru * it. */ for (; - &insn->list != &file->insn_list && - insn->sec == func->sec && - insn->offset >= func->offset; - + &insn->list != &file->insn_list && insn->func && insn->func->pfunc == func; insn = insn->first_jump_src ?: list_prev_entry(insn, list)) {
if (insn != orig_insn && insn->type == INSN_JUMP_DYNAMIC)
From: Li Bin huawei.libin@huawei.com
commit 849f8583e955dbe3a1806e03ecacd5e71cce0a08 upstream.
If the dxfer_len is greater than 256M then the request is invalid and we need to call sg_remove_request in sg_common_write.
Link: https://lore.kernel.org/r/1586777361-17339-1-git-send-email-huawei.libin@hua... Fixes: f930c7043663 ("scsi: sg: only check for dxfer_len greater than 256M") Acked-by: Douglas Gilbert dgilbert@interlog.com Signed-off-by: Li Bin huawei.libin@huawei.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/scsi/sg.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -803,8 +803,10 @@ sg_common_write(Sg_fd * sfp, Sg_request "sg_common_write: scsi opcode=0x%02x, cmd_size=%d\n", (int) cmnd[0], (int) hp->cmd_len));
- if (hp->dxfer_len >= SZ_256M) + if (hp->dxfer_len >= SZ_256M) { + sg_remove_request(sfp, srp); return -EINVAL; + }
k = sg_start_req(srp, cmnd); if (k) {
From: Takashi Iwai tiwai@suse.de
commit 10db5bccc390e8e4bd9fcd1fbd4f1b23f271a405 upstream.
freeze_noirq and thaw_noirq need to check the PM availability like other PM ops. There are cases where the device got disabled due to the error, and the PM operation should be ignored for that.
Fixes: 3e6db33aaf1d ("ALSA: hda - Set SKL+ hda controller power at freeze() and thaw()") BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=207043 Link: https://lore.kernel.org/r/20200413082034.25166-3-tiwai@suse.de Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- sound/pci/hda/hda_intel.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1068,6 +1068,8 @@ static int azx_freeze_noirq(struct devic struct azx *chip = card->private_data; struct pci_dev *pci = to_pci_dev(dev);
+ if (!azx_is_pm_ready(card)) + return 0; if (chip->driver_type == AZX_DRIVER_SKL) pci_set_power_state(pci, PCI_D3hot);
@@ -1080,6 +1082,8 @@ static int azx_thaw_noirq(struct device struct azx *chip = card->private_data; struct pci_dev *pci = to_pci_dev(dev);
+ if (!azx_is_pm_ready(card)) + return 0; if (chip->driver_type == AZX_DRIVER_SKL) pci_set_power_state(pci, PCI_D0);
From: Martin Fuzzey martin.fuzzey@flowbird.group
commit 4141f1a40fc0789f6fd4330e171e1edf155426aa upstream.
In order to wake from suspend by ethernet magic packets the GPC must be used as intc does not have wakeup functionality.
But the FEC DT node currently uses interrupt-extended, specificying intc, thus breaking WoL.
This problem is probably fallout from the stacked domain conversion as intc used to chain to GPC.
So replace "interrupts-extended" by "interrupts" to use the default parent which is GPC.
Fixes: b923ff6af0d5 ("ARM: imx6: convert GPC to stacked domains")
Signed-off-by: Martin Fuzzey martin.fuzzey@flowbird.group Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/arm/boot/dts/imx6qdl.dtsi | 5 ++--- arch/arm/boot/dts/imx6qp.dtsi | 1 - 2 files changed, 2 insertions(+), 4 deletions(-)
--- a/arch/arm/boot/dts/imx6qdl.dtsi +++ b/arch/arm/boot/dts/imx6qdl.dtsi @@ -1039,9 +1039,8 @@ compatible = "fsl,imx6q-fec"; reg = <0x02188000 0x4000>; interrupt-names = "int0", "pps"; - interrupts-extended = - <&intc 0 118 IRQ_TYPE_LEVEL_HIGH>, - <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <0 118 IRQ_TYPE_LEVEL_HIGH>, + <0 119 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clks IMX6QDL_CLK_ENET>, <&clks IMX6QDL_CLK_ENET>, <&clks IMX6QDL_CLK_ENET_REF>; --- a/arch/arm/boot/dts/imx6qp.dtsi +++ b/arch/arm/boot/dts/imx6qp.dtsi @@ -77,7 +77,6 @@ };
&fec { - /delete-property/interrupts-extended; interrupts = <0 118 IRQ_TYPE_LEVEL_HIGH>, <0 119 IRQ_TYPE_LEVEL_HIGH>; };
From: Slava Bacherikov slava@bacher09.org
commit 7d32e69310d67e6b04af04f26193f79dfc2f05c7 upstream.
Currently turning on DEBUG_INFO_SPLIT when DEBUG_INFO_BTF is also enabled will produce invalid btf file, since gen_btf function in link-vmlinux.sh script doesn't handle *.dwo files.
Enabling DEBUG_INFO_REDUCED will also produce invalid btf file, and using GCC_PLUGIN_RANDSTRUCT with BTF makes no sense.
Fixes: e83b9f55448a ("kbuild: add ability to generate BTF type info for vmlinux") Reported-by: Jann Horn jannh@google.com Reported-by: Liu Yiding liuyd.fnst@cn.fujitsu.com Signed-off-by: Slava Bacherikov slava@bacher09.org Signed-off-by: Daniel Borkmann daniel@iogearbox.net Reviewed-by: Kees Cook keescook@chromium.org Acked-by: KP Singh kpsingh@google.com Acked-by: Andrii Nakryiko andriin@fb.com Link: https://lore.kernel.org/bpf/20200402204138.408021-1-slava@bacher09.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- lib/Kconfig.debug | 2 ++ 1 file changed, 2 insertions(+)
--- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -223,6 +223,8 @@ config DEBUG_INFO_DWARF4 config DEBUG_INFO_BTF bool "Generate BTF typeinfo" depends on DEBUG_INFO + depends on !DEBUG_INFO_SPLIT && !DEBUG_INFO_REDUCED + depends on !GCC_PLUGIN_RANDSTRUCT || COMPILE_TEST help Generate deduplicated BTF type information from DWARF debug info. Turning this on expects presence of pahole tool, which will convert
From: Pablo Neira Ayuso pablo@netfilter.org
commit d9583cdf2f38d0f526d9a8c8564dd2e35e649bc7 upstream.
EINVAL should be used for malformed netlink messages. New userspace utility and old kernels might easily result in EINVAL when exercising new set features, which is misleading.
Fixes: 8aeff920dcc9 ("netfilter: nf_tables: add stateful object reference to set elements") Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- net/netfilter/nf_tables_api.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -3598,7 +3598,7 @@ static int nf_tables_newset(struct net * NFT_SET_INTERVAL | NFT_SET_TIMEOUT | NFT_SET_MAP | NFT_SET_EVAL | NFT_SET_OBJECT)) - return -EINVAL; + return -EOPNOTSUPP; /* Only one of these operations is supported */ if ((flags & (NFT_SET_MAP | NFT_SET_OBJECT)) == (NFT_SET_MAP | NFT_SET_OBJECT)) @@ -3636,7 +3636,7 @@ static int nf_tables_newset(struct net * objtype = ntohl(nla_get_be32(nla[NFTA_SET_OBJ_TYPE])); if (objtype == NFT_OBJECT_UNSPEC || objtype > NFT_OBJECT_MAX) - return -EINVAL; + return -EOPNOTSUPP; } else if (flags & NFT_SET_OBJECT) return -EINVAL; else
From: Zenghui Yu yuzenghui@huawei.com
commit edfc23f6f9fdbd7825d50ac1f380243cde19b679 upstream.
Using irq_domain_free_irqs_common() on the irqdomain free path will leave the MSI descriptor unfreed when platform devices get removed. Properly free it by MSI domain free function.
Fixes: 9650c60ebfec0 ("irqchip/mbigen: Create irq domain for each mbigen device") Signed-off-by: Zenghui Yu yuzenghui@huawei.com Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20200408114352.1604-1-yuzenghui@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/irqchip/irq-mbigen.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
--- a/drivers/irqchip/irq-mbigen.c +++ b/drivers/irqchip/irq-mbigen.c @@ -220,10 +220,16 @@ static int mbigen_irq_domain_alloc(struc return 0; }
+static void mbigen_irq_domain_free(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs) +{ + platform_msi_domain_free(domain, virq, nr_irqs); +} + static const struct irq_domain_ops mbigen_domain_ops = { .translate = mbigen_domain_translate, .alloc = mbigen_irq_domain_alloc, - .free = irq_domain_free_irqs_common, + .free = mbigen_irq_domain_free, };
static int mbigen_of_create_domain(struct platform_device *pdev,
From: Takashi Iwai tiwai@suse.de
commit 25faa4bd37c10f19e4b848b9032a17a3d44c6f09 upstream.
At the error path of the firmware loading error, the driver tries to release the card object and set NULL to drvdata. This may be referred badly at the possible PM action, as the driver itself is still bound and the PM callbacks read the card object.
Instead, we continue the probing as if it were no option set. This is often a better choice than the forced abort, too.
Fixes: 5cb543dba986 ("ALSA: hda - Deferred probing with request_firmware_nowait()") BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=207043 Link: https://lore.kernel.org/r/20200413082034.25166-2-tiwai@suse.de Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- sound/pci/hda/hda_intel.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-)
--- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1980,24 +1980,15 @@ static void azx_firmware_cb(const struct { struct snd_card *card = context; struct azx *chip = card->private_data; - struct pci_dev *pci = chip->pci;
- if (!fw) { - dev_err(card->dev, "Cannot load firmware, aborting\n"); - goto error; - } - - chip->fw = fw; + if (fw) + chip->fw = fw; + else + dev_err(card->dev, "Cannot load firmware, continue without patching\n"); if (!chip->disabled) { /* continue probing */ - if (azx_probe_continue(chip)) - goto error; + azx_probe_continue(chip); } - return; /* OK */ - - error: - snd_card_free(card); - pci_set_drvdata(pci, NULL); } #endif
From: Magnus Karlsson magnus.karlsson@intel.com
commit 99e3a236dd43d06c65af0a2ef9cb44306aef6e02 upstream.
Add a check that the headroom cannot be larger than the available space in the chunk. In the current code, a malicious user can set the headroom to a value larger than the chunk size minus the fixed XDP headroom. That way packets with a length larger than the supported size in the umem could get accepted and result in an out-of-bounds write.
Fixes: c0c77d8fb787 ("xsk: add user memory registration support sockopt") Reported-by: Bui Quang Minh minhquangbui99@gmail.com Signed-off-by: Magnus Karlsson magnus.karlsson@intel.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Link: https://bugzilla.kernel.org/show_bug.cgi?id=207225 Link: https://lore.kernel.org/bpf/1586849715-23490-1-git-send-email-magnus.karlsso... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- net/xdp/xdp_umem.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
--- a/net/xdp/xdp_umem.c +++ b/net/xdp/xdp_umem.c @@ -343,7 +343,7 @@ static int xdp_umem_reg(struct xdp_umem u32 chunk_size = mr->chunk_size, headroom = mr->headroom; unsigned int chunks, chunks_per_page; u64 addr = mr->addr, size = mr->len; - int size_chk, err; + int err;
if (chunk_size < XDP_UMEM_MIN_CHUNK_SIZE || chunk_size > PAGE_SIZE) { /* Strictly speaking we could support this, if: @@ -382,8 +382,7 @@ static int xdp_umem_reg(struct xdp_umem return -EINVAL; }
- size_chk = chunk_size - headroom - XDP_PACKET_HEADROOM; - if (size_chk < 0) + if (headroom >= chunk_size - XDP_PACKET_HEADROOM) return -EINVAL;
umem->address = (unsigned long)addr;
From: Frank Rowand frank.rowand@sony.com
commit b3fb36ed694b05738d45218ea72cf7feb10ce2b1 upstream.
kmemleak reports several memory leaks from devicetree unittest. This is the fix for problem 1 of 5.
of_unittest_changeset() reaches deeply into the dynamic devicetree functions. Several nodes were left with an elevated reference count and thus were not properly cleaned up. Fix the reference counts so that the memory will be freed.
Fixes: 201c910bd689 ("of: Transactional DT support.") Reported-by: Erhard F. erhard_f@mailbox.org Signed-off-by: Frank Rowand frank.rowand@sony.com Signed-off-by: Rob Herring robh@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/of/unittest.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -776,6 +776,10 @@ static void __init of_unittest_changeset unittest(!of_changeset_revert(&chgset), "revert failed\n");
of_changeset_destroy(&chgset); + + of_node_put(n1); + of_node_put(n2); + of_node_put(n21); #endif }
From: Frank Rowand frank.rowand@sony.com
commit 216830d2413cc61be3f76bc02ffd905e47d2439e upstream.
kmemleak reports several memory leaks from devicetree unittest. This is the fix for problem 2 of 5.
of_unittest_platform_populate() left an elevated reference count for grandchild nodes (which are platform devices). Fix the platform device reference counts so that the memory will be freed.
Fixes: fb2caa50fbac ("of/selftest: add testcase for nodes with same name and address") Reported-by: Erhard F. erhard_f@mailbox.org Signed-off-by: Frank Rowand frank.rowand@sony.com Signed-off-by: Rob Herring robh@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/of/unittest.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
--- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -1065,10 +1065,13 @@ static void __init of_unittest_platform_
of_platform_populate(np, match, NULL, &test_bus->dev); for_each_child_of_node(np, child) { - for_each_child_of_node(child, grandchild) - unittest(of_find_device_by_node(grandchild), + for_each_child_of_node(child, grandchild) { + pdev = of_find_device_by_node(grandchild); + unittest(pdev, "Could not create device for node '%pOFn'\n", grandchild); + of_dev_put(pdev); + } }
of_platform_depopulate(&test_bus->dev);
From: Frank Rowand frank.rowand@sony.com
commit 145fc138f9aae4f9e1331352e301df28e16aed35 upstream.
kmemleak reports several memory leaks from devicetree unittest. This is the fix for problem 3 of 5.
of_unittest_overlay_high_level() failed to kfree the newly created property when the property named 'name' is skipped.
Fixes: 39a751a4cb7e ("of: change overlay apply input data from unflattened to FDT") Reported-by: Erhard F. erhard_f@mailbox.org Signed-off-by: Frank Rowand frank.rowand@sony.com Signed-off-by: Rob Herring robh@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/of/unittest.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
--- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -2481,8 +2481,11 @@ static __init void of_unittest_overlay_h goto err_unlock; } if (__of_add_property(of_symbols, new_prop)) { + kfree(new_prop->name); + kfree(new_prop->value); + kfree(new_prop); /* "name" auto-generated by unflatten */ - if (!strcmp(new_prop->name, "name")) + if (!strcmp(prop->name, "name")) continue; unittest(0, "duplicate property '%s' in overlay_base node __symbols__", prop->name);
From: Frank Rowand frank.rowand@sony.com
commit 478ff649b1c8eb2409b1a54fb75eb46f7c29f140 upstream.
kmemleak reports several memory leaks from devicetree unittest. This is the fix for problem 4 of 5.
target_path was not freed in the non-error path.
Fixes: e0a58f3e08d4 ("of: overlay: remove a dependency on device node full_name") Reported-by: Erhard F. erhard_f@mailbox.org Signed-off-by: Frank Rowand frank.rowand@sony.com Signed-off-by: Rob Herring robh@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/of/overlay.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c @@ -261,6 +261,8 @@ static struct property *dup_and_fixup_sy
of_property_set_flag(new_prop, OF_DYNAMIC);
+ kfree(target_path); + return new_prop;
err_free_new_prop:
From: Tianyu Lan Tianyu.Lan@microsoft.com
commit 74347a99e73ae00b8385f1209aaea193c670f901 upstream.
When kdump is not configured, a Hyper-V VM might still respond to network traffic after a kernel panic when kernel parameter panic=0. The panic CPU goes into an infinite loop with interrupts enabled, and the VMbus driver interrupt handler still works because the VMbus connection is unloaded only in the kdump path. The network responses make the other end of the connection think the VM is still functional even though it has panic'ed, which could affect any failover actions that should be taken.
Fix this by unloading the VMbus connection during the panic process. vmbus_initiate_unload() could then be called twice (e.g., by hyperv_panic_event() and hv_crash_handler(), so reset the connection state in vmbus_initiate_unload() to ensure the unload is done only once.
Fixes: 81b18bce48af ("Drivers: HV: Send one page worth of kmsg dump over Hyper-V during panic") Reviewed-by: Michael Kelley mikelley@microsoft.com Signed-off-by: Tianyu Lan Tianyu.Lan@microsoft.com Link: https://lore.kernel.org/r/20200406155331.2105-2-Tianyu.Lan@microsoft.com Signed-off-by: Wei Liu wei.liu@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/hv/channel_mgmt.c | 3 +++ drivers/hv/vmbus_drv.c | 21 +++++++++++++-------- 2 files changed, 16 insertions(+), 8 deletions(-)
--- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c @@ -839,6 +839,9 @@ void vmbus_initiate_unload(bool crash) { struct vmbus_channel_message_header hdr;
+ if (xchg(&vmbus_connection.conn_state, DISCONNECTED) == DISCONNECTED) + return; + /* Pre-Win2012R2 hosts don't support reconnect */ if (vmbus_proto_version < VERSION_WIN8_1) return; --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -53,9 +53,12 @@ static int hyperv_panic_event(struct not { struct pt_regs *regs;
- regs = current_pt_regs(); + vmbus_initiate_unload(true);
- hyperv_report_panic(regs, val); + if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) { + regs = current_pt_regs(); + hyperv_report_panic(regs, val); + } return NOTIFY_DONE; }
@@ -1389,10 +1392,16 @@ static int vmbus_bus_init(void) }
register_die_notifier(&hyperv_die_block); - atomic_notifier_chain_register(&panic_notifier_list, - &hyperv_panic_block); }
+ /* + * Always register the panic notifier because we need to unload + * the VMbus channel connection to prevent any VMbus + * activity after the VM panics. + */ + atomic_notifier_chain_register(&panic_notifier_list, + &hyperv_panic_block); + vmbus_request_offers();
return 0; @@ -2202,8 +2211,6 @@ static int vmbus_bus_suspend(struct devi
vmbus_initiate_unload(false);
- vmbus_connection.conn_state = DISCONNECTED; - /* Reset the event for the next resume. */ reinit_completion(&vmbus_connection.ready_for_resume_event);
@@ -2288,7 +2295,6 @@ static void hv_kexec_handler(void) { hv_stimer_global_cleanup(); vmbus_initiate_unload(false); - vmbus_connection.conn_state = DISCONNECTED; /* Make sure conn_state is set as hv_synic_cleanup checks for it */ mb(); cpuhp_remove_state(hyperv_cpuhp_online); @@ -2305,7 +2311,6 @@ static void hv_crash_handler(struct pt_r * doing the cleanup for current CPU only. This should be sufficient * for kdump. */ - vmbus_connection.conn_state = DISCONNECTED; cpu = smp_processor_id(); hv_stimer_cleanup(cpu); hv_synic_disable_regs(cpu);
From: Tianyu Lan Tianyu.Lan@microsoft.com
commit 73f26e526f19afb3a06b76b970a76bcac2cafd05 upstream.
When a guest VM panics, Hyper-V should be notified only once via the crash synthetic MSRs. Current Linux code might write these crash MSRs twice during a system panic: 1) hyperv_panic/die_event() calling hyperv_report_panic() 2) hv_kmsg_dump() calling hyperv_report_panic_msg()
Fix this by not calling hyperv_report_panic() if a kmsg dump has been successfully registered. The notification will happen later via hyperv_report_panic_msg().
Fixes: 7ed4325a44ea ("Drivers: hv: vmbus: Make panic reporting to be more useful") Reviewed-by: Michael Kelley mikelley@microsoft.com Signed-off-by: Tianyu Lan Tianyu.Lan@microsoft.com Link: https://lore.kernel.org/r/20200406155331.2105-4-Tianyu.Lan@microsoft.com Signed-off-by: Wei Liu wei.liu@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/hv/vmbus_drv.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-)
--- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -55,7 +55,13 @@ static int hyperv_panic_event(struct not
vmbus_initiate_unload(true);
- if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) { + /* + * Hyper-V should be notified only once about a panic. If we will be + * doing hyperv_report_panic_msg() later with kmsg data, don't do + * the notification here. + */ + if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE + && !hv_panic_page) { regs = current_pt_regs(); hyperv_report_panic(regs, val); } @@ -68,7 +74,13 @@ static int hyperv_die_event(struct notif struct die_args *die = (struct die_args *)args; struct pt_regs *regs = die->regs;
- hyperv_report_panic(regs, val); + /* + * Hyper-V should be notified only once about a panic. If we will be + * doing hyperv_report_panic_msg() later with kmsg data, don't do + * the notification here. + */ + if (!hv_panic_page) + hyperv_report_panic(regs, val); return NOTIFY_DONE; }
From: Tianyu Lan Tianyu.Lan@microsoft.com
commit a11589563e96bf262767294b89b25a9d44e7303b upstream.
We want to notify Hyper-V when a Linux guest VM crash occurs, so there is a record of the crash even when kdump is enabled. But crash_kexec_post_notifiers defaults to "false", so the kdump kernel runs before the notifiers and Hyper-V never gets notified. Fix this by always setting crash_kexec_post_notifiers to be true for Hyper-V VMs.
Fixes: 81b18bce48af ("Drivers: HV: Send one page worth of kmsg dump over Hyper-V during panic") Reviewed-by: Michael Kelley mikelley@microsoft.com Signed-off-by: Tianyu Lan Tianyu.Lan@microsoft.com Link: https://lore.kernel.org/r/20200406155331.2105-5-Tianyu.Lan@microsoft.com Signed-off-by: Wei Liu wei.liu@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/x86/kernel/cpu/mshyperv.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
--- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c @@ -263,6 +263,16 @@ static void __init ms_hyperv_init_platfo cpuid_eax(HYPERV_CPUID_NESTED_FEATURES); }
+ /* + * Hyper-V expects to get crash register data or kmsg when + * crash enlightment is available and system crashes. Set + * crash_kexec_post_notifiers to be true to make sure that + * calling crash enlightment interface before running kdump + * kernel. + */ + if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) + crash_kexec_post_notifiers = true; + #ifdef CONFIG_X86_LOCAL_APIC if (ms_hyperv.features & HV_X64_ACCESS_FREQUENCY_MSRS && ms_hyperv.misc_features & HV_FEATURE_FREQUENCY_MSRS_AVAILABLE) {
From: Tianyu Lan Tianyu.Lan@microsoft.com
commit 040026df7088c56ccbad28f7042308f67bde63df upstream.
When sysctl_record_panic_msg is not set, the panic will not be reported to Hyper-V via hyperv_report_panic_msg(). So the crash should be reported via hyperv_report_panic().
Fixes: 81b18bce48af ("Drivers: HV: Send one page worth of kmsg dump over Hyper-V during panic") Reviewed-by: Michael Kelley mikelley@microsoft.com Signed-off-by: Tianyu Lan Tianyu.Lan@microsoft.com Link: https://lore.kernel.org/r/20200406155331.2105-6-Tianyu.Lan@microsoft.com Signed-off-by: Wei Liu wei.liu@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/hv/vmbus_drv.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-)
--- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -48,6 +48,18 @@ static int hyperv_cpuhp_online;
static void *hv_panic_page;
+/* + * Boolean to control whether to report panic messages over Hyper-V. + * + * It can be set via /proc/sys/kernel/hyperv/record_panic_msg + */ +static int sysctl_record_panic_msg = 1; + +static int hyperv_report_reg(void) +{ + return !sysctl_record_panic_msg || !hv_panic_page; +} + static int hyperv_panic_event(struct notifier_block *nb, unsigned long val, void *args) { @@ -61,7 +73,7 @@ static int hyperv_panic_event(struct not * the notification here. */ if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE - && !hv_panic_page) { + && hyperv_report_reg()) { regs = current_pt_regs(); hyperv_report_panic(regs, val); } @@ -79,7 +91,7 @@ static int hyperv_die_event(struct notif * doing hyperv_report_panic_msg() later with kmsg data, don't do * the notification here. */ - if (!hv_panic_page) + if (hyperv_report_reg()) hyperv_report_panic(regs, val); return NOTIFY_DONE; } @@ -1262,13 +1274,6 @@ static void vmbus_isr(void) }
/* - * Boolean to control whether to report panic messages over Hyper-V. - * - * It can be set via /proc/sys/kernel/hyperv/record_panic_msg - */ -static int sysctl_record_panic_msg = 1; - -/* * Callback from kmsg_dump. Grab as much as possible from the end of the kmsg * buffer and call into Hyper-V to transfer the data. */
From: Tianyu Lan Tianyu.Lan@microsoft.com
commit f3a99e761efa616028b255b4de58e9b5b87c5545 upstream.
When oops happens with panic_on_oops unset, the oops thread is killed by die() and system continues to run. In such case, guest should not report crash register data to host since system still runs. Check panic_on_oops and return directly in hyperv_report_panic() when the function is called in the die() and panic_on_oops is unset. Fix it.
Fixes: 7ed4325a44ea ("Drivers: hv: vmbus: Make panic reporting to be more useful") Signed-off-by: Tianyu Lan Tianyu.Lan@microsoft.com Reviewed-by: Michael Kelley mikelley@microsoft.com Link: https://lore.kernel.org/r/20200406155331.2105-7-Tianyu.Lan@microsoft.com Signed-off-by: Wei Liu wei.liu@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/x86/hyperv/hv_init.c | 6 +++++- drivers/hv/vmbus_drv.c | 5 +++-- include/asm-generic/mshyperv.h | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-)
--- a/arch/x86/hyperv/hv_init.c +++ b/arch/x86/hyperv/hv_init.c @@ -19,6 +19,7 @@ #include <linux/mm.h> #include <linux/hyperv.h> #include <linux/slab.h> +#include <linux/kernel.h> #include <linux/cpuhotplug.h> #include <clocksource/hyperv_timer.h>
@@ -354,11 +355,14 @@ void hyperv_cleanup(void) } EXPORT_SYMBOL_GPL(hyperv_cleanup);
-void hyperv_report_panic(struct pt_regs *regs, long err) +void hyperv_report_panic(struct pt_regs *regs, long err, bool in_die) { static bool panic_reported; u64 guest_id;
+ if (in_die && !panic_on_oops) + return; + /* * We prefer to report panic on 'die' chain as we have proper * registers to report, but if we miss it (e.g. on BUG()) we need --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -31,6 +31,7 @@ #include <linux/kdebug.h> #include <linux/efi.h> #include <linux/random.h> +#include <linux/kernel.h> #include <linux/syscore_ops.h> #include <clocksource/hyperv_timer.h> #include "hyperv_vmbus.h" @@ -75,7 +76,7 @@ static int hyperv_panic_event(struct not if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE && hyperv_report_reg()) { regs = current_pt_regs(); - hyperv_report_panic(regs, val); + hyperv_report_panic(regs, val, false); } return NOTIFY_DONE; } @@ -92,7 +93,7 @@ static int hyperv_die_event(struct notif * the notification here. */ if (hyperv_report_reg()) - hyperv_report_panic(regs, val); + hyperv_report_panic(regs, val, true); return NOTIFY_DONE; }
--- a/include/asm-generic/mshyperv.h +++ b/include/asm-generic/mshyperv.h @@ -163,7 +163,7 @@ static inline int cpumask_to_vpset(struc return nr_bank; }
-void hyperv_report_panic(struct pt_regs *regs, long err); +void hyperv_report_panic(struct pt_regs *regs, long err, bool in_die); void hyperv_report_panic_msg(phys_addr_t pa, size_t size); bool hv_is_hyperv_initialized(void); void hyperv_cleanup(void);
From: David Howells dhowells@redhat.com
commit c72057b56f7e24865840a6961d801a7f21d30a5f upstream.
If we receive a status record that has VNOVNODE set in the abort field, xdr_decode_AFSFetchStatus() and xdr_decode_YFSFetchStatus() don't advance the XDR pointer, thereby corrupting anything subsequent decodes from the same block of data.
This has the potential to affect AFS.InlineBulkStatus and YFS.InlineBulkStatus operation, but probably doesn't since the status records are extracted as individual blocks of data and the buffer pointer is reset between blocks.
It does affect YFS.RemoveFile2 operation, corrupting the volsync record - though that is not currently used.
Other operations abort the entire operation rather than returning an error inline, in which case there is no decoding to be done.
Fix this by unconditionally advancing the xdr pointer.
Fixes: 684b0f68cf1c ("afs: Fix AFSFetchStatus decoder to provide OpenAFS compatibility") Signed-off-by: David Howells dhowells@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/afs/fsclient.c | 14 +++++++++----- fs/afs/yfsclient.c | 12 ++++++++---- 2 files changed, 17 insertions(+), 9 deletions(-)
--- a/fs/afs/fsclient.c +++ b/fs/afs/fsclient.c @@ -65,6 +65,7 @@ static int xdr_decode_AFSFetchStatus(con bool inline_error = (call->operation_ID == afs_FS_InlineBulkStatus); u64 data_version, size; u32 type, abort_code; + int ret;
abort_code = ntohl(xdr->abort_code);
@@ -78,7 +79,7 @@ static int xdr_decode_AFSFetchStatus(con */ status->abort_code = abort_code; scb->have_error = true; - return 0; + goto good; }
pr_warn("Unknown AFSFetchStatus version %u\n", ntohl(xdr->if_version)); @@ -87,7 +88,7 @@ static int xdr_decode_AFSFetchStatus(con
if (abort_code != 0 && inline_error) { status->abort_code = abort_code; - return 0; + goto good; }
type = ntohl(xdr->type); @@ -123,13 +124,16 @@ static int xdr_decode_AFSFetchStatus(con data_version |= (u64)ntohl(xdr->data_version_hi) << 32; status->data_version = data_version; scb->have_status = true; - +good: + ret = 0; +advance: *_bp = (const void *)*_bp + sizeof(*xdr); - return 0; + return ret;
bad: xdr_dump_bad(*_bp); - return afs_protocol_error(call, -EBADMSG, afs_eproto_bad_status); + ret = afs_protocol_error(call, -EBADMSG, afs_eproto_bad_status); + goto advance; }
static time64_t xdr_decode_expiry(struct afs_call *call, u32 expiry) --- a/fs/afs/yfsclient.c +++ b/fs/afs/yfsclient.c @@ -186,13 +186,14 @@ static int xdr_decode_YFSFetchStatus(con const struct yfs_xdr_YFSFetchStatus *xdr = (const void *)*_bp; struct afs_file_status *status = &scb->status; u32 type; + int ret;
status->abort_code = ntohl(xdr->abort_code); if (status->abort_code != 0) { if (status->abort_code == VNOVNODE) status->nlink = 0; scb->have_error = true; - return 0; + goto good; }
type = ntohl(xdr->type); @@ -220,13 +221,16 @@ static int xdr_decode_YFSFetchStatus(con status->size = xdr_to_u64(xdr->size); status->data_version = xdr_to_u64(xdr->data_version); scb->have_status = true; - +good: + ret = 0; +advance: *_bp += xdr_size(xdr); - return 0; + return ret;
bad: xdr_dump_bad(*_bp); - return afs_protocol_error(call, -EBADMSG, afs_eproto_bad_status); + ret = afs_protocol_error(call, -EBADMSG, afs_eproto_bad_status); + goto advance; }
/*
From: David Howells dhowells@redhat.com
commit 3e0d9892c0e7fa426ca6bf921cb4b543ca265714 upstream.
If we're decoding an AFSFetchStatus record and we see that the version is 1 and the abort code is set and we're expecting inline errors, then we store the abort code and ignore the remaining status record (which is correct), but we don't set the flag to say we got a valid abort code.
This can affect operation of YFS.RemoveFile2 when removing a file and the operation of {,Y}FS.InlineBulkStatus when prospectively constructing or updating of a set of inodes during a lookup.
Fix this to indicate the reception of a valid abort code.
Fixes: a38a75581e6e ("afs: Fix unlink to handle YFS.RemoveFile2 better") Signed-off-by: David Howells dhowells@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/afs/fsclient.c | 1 + 1 file changed, 1 insertion(+)
--- a/fs/afs/fsclient.c +++ b/fs/afs/fsclient.c @@ -88,6 +88,7 @@ static int xdr_decode_AFSFetchStatus(con
if (abort_code != 0 && inline_error) { status->abort_code = abort_code; + scb->have_error = true; goto good; }
From: David Howells dhowells@redhat.com
commit b98f0ec91c42d87a70da42726b852ac8d78a3257 upstream.
The afs_deliver_fs_rename() and yfs_deliver_fs_rename() functions both only decode the second file status returned unless the parent directories are different - unfortunately, this means that the xdr pointer isn't advanced and the volsync record will be read incorrectly in such an instance.
Fix this by always decoding the second status into the second status/callback block which wasn't being used if the dirs were the same.
The afs_update_dentry_version() calls that update the directory data version numbers on the dentries can then unconditionally use the second status record as this will always reflect the state of the destination dir (the two records will be identical if the destination dir is the same as the source dir)
Fixes: 260a980317da ("[AFS]: Add "directory write" support.") Fixes: 30062bd13e36 ("afs: Implement YFS support in the fs client") Signed-off-by: David Howells dhowells@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/afs/dir.c | 13 +++---------- fs/afs/fsclient.c | 12 ++++++------ fs/afs/yfsclient.c | 8 +++----- 3 files changed, 12 insertions(+), 21 deletions(-)
--- a/fs/afs/dir.c +++ b/fs/afs/dir.c @@ -1892,7 +1892,6 @@ static int afs_rename(struct inode *old_ if (afs_begin_vnode_operation(&fc, orig_dvnode, key, true)) { afs_dataversion_t orig_data_version; afs_dataversion_t new_data_version; - struct afs_status_cb *new_scb = &scb[1];
orig_data_version = orig_dvnode->status.data_version + 1;
@@ -1904,7 +1903,6 @@ static int afs_rename(struct inode *old_ new_data_version = new_dvnode->status.data_version + 1; } else { new_data_version = orig_data_version; - new_scb = &scb[0]; }
while (afs_select_fileserver(&fc)) { @@ -1912,7 +1910,7 @@ static int afs_rename(struct inode *old_ fc.cb_break_2 = afs_calc_vnode_cb_break(new_dvnode); afs_fs_rename(&fc, old_dentry->d_name.name, new_dvnode, new_dentry->d_name.name, - &scb[0], new_scb); + &scb[0], &scb[1]); }
afs_vnode_commit_status(&fc, orig_dvnode, fc.cb_break, @@ -1957,13 +1955,8 @@ static int afs_rename(struct inode *old_ * Note that if we ever implement RENAME_EXCHANGE, we'll have * to update both dentries with opposing dir versions. */ - if (new_dvnode != orig_dvnode) { - afs_update_dentry_version(&fc, old_dentry, &scb[1]); - afs_update_dentry_version(&fc, new_dentry, &scb[1]); - } else { - afs_update_dentry_version(&fc, old_dentry, &scb[0]); - afs_update_dentry_version(&fc, new_dentry, &scb[0]); - } + afs_update_dentry_version(&fc, old_dentry, &scb[1]); + afs_update_dentry_version(&fc, new_dentry, &scb[1]); d_move(old_dentry, new_dentry); goto error_tmp; } --- a/fs/afs/fsclient.c +++ b/fs/afs/fsclient.c @@ -988,16 +988,16 @@ static int afs_deliver_fs_rename(struct if (ret < 0) return ret;
- /* unmarshall the reply once we've received all of it */ + /* If the two dirs are the same, we have two copies of the same status + * report, so we just decode it twice. + */ bp = call->buffer; ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_dir_scb); if (ret < 0) return ret; - if (call->out_dir_scb != call->out_scb) { - ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb); - if (ret < 0) - return ret; - } + ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb); + if (ret < 0) + return ret; xdr_decode_AFSVolSync(&bp, call->out_volsync);
_leave(" = 0 [done]"); --- a/fs/afs/yfsclient.c +++ b/fs/afs/yfsclient.c @@ -1158,11 +1158,9 @@ static int yfs_deliver_fs_rename(struct ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb); if (ret < 0) return ret; - if (call->out_dir_scb != call->out_scb) { - ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb); - if (ret < 0) - return ret; - } + ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb); + if (ret < 0) + return ret;
xdr_decode_YFSVolSync(&bp, call->out_volsync); _leave(" = 0 [done]");
From: David Howells dhowells@redhat.com
commit 40fc81027f892284ce31f8b6de1e497f5b47e71f upstream.
If a dentry's version is somewhere between invalid_before and the current directory version, we should be setting it forward to the current version, not backwards to the invalid_before version. Note that we're only doing this at all because dentry::d_fsdata isn't large enough on a 32-bit system.
Fix this by using a separate variable for invalid_before so that we don't accidentally clobber the current dir version.
Fixes: a4ff7401fbfa ("afs: Keep track of invalid-before version for dentry coherency") Signed-off-by: David Howells dhowells@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/afs/dir.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
--- a/fs/afs/dir.c +++ b/fs/afs/dir.c @@ -1032,7 +1032,7 @@ static int afs_d_revalidate(struct dentr struct dentry *parent; struct inode *inode; struct key *key; - afs_dataversion_t dir_version; + afs_dataversion_t dir_version, invalid_before; long de_version; int ret;
@@ -1084,8 +1084,8 @@ static int afs_d_revalidate(struct dentr if (de_version == (long)dir_version) goto out_valid_noupdate;
- dir_version = dir->invalid_before; - if (de_version - (long)dir_version >= 0) + invalid_before = dir->invalid_before; + if (de_version - (long)invalid_before >= 0) goto out_valid;
_debug("dir modified");
From: David Howells dhowells@redhat.com
commit 2105c2820d366b76f38e6ad61c75771881ecc532 upstream.
AFS directories are retained locally as a structured file, with lookup being effected by a local search of the file contents. When a modification (such as mkdir) happens, the dir file content is modified locally rather than redownloading the directory.
The directory contents are accessed in a number of ways, with a number of different locks schemes:
(1) Download of contents - dvnode->validate_lock/write in afs_read_dir().
(2) Lookup and readdir - dvnode->validate_lock/read in afs_dir_iterate(), downgrading from (1) if necessary.
(3) d_revalidate of child dentry - dvnode->validate_lock/read in afs_do_lookup_one() downgrading from (1) if necessary.
(4) Edit of dir after modification - page locks on individual dir pages.
Unfortunately, because (4) uses different locking scheme to (1) - (3), nothing protects against the page being scanned whilst the edit is underway. Even download is not safe as it doesn't lock the pages - relying instead on the validate_lock to serialise as a whole (the theory being that directory contents are treated as a block and always downloaded as a block).
Fix this by write-locking dvnode->validate_lock around the edits. Care must be taken in the rename case as there may be two different dirs - but they need not be locked at the same time. In any case, once the lock is taken, the directory version must be rechecked, and the edit skipped if a later version has been downloaded by revalidation (there can't have been any local changes because the VFS holds the inode lock, but there can have been remote changes).
Fixes: 63a4681ff39c ("afs: Locally edit directory data for mkdir/create/unlink/...") Signed-off-by: David Howells dhowells@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/afs/dir.c | 91 ++++++++++++++++++++++++++++++++++++----------------- fs/afs/dir_silly.c | 22 ++++++++---- 2 files changed, 77 insertions(+), 36 deletions(-)
--- a/fs/afs/dir.c +++ b/fs/afs/dir.c @@ -1275,6 +1275,7 @@ static int afs_mkdir(struct inode *dir, struct afs_fs_cursor fc; struct afs_vnode *dvnode = AFS_FS_I(dir); struct key *key; + afs_dataversion_t data_version; int ret;
mode |= S_IFDIR; @@ -1295,7 +1296,7 @@ static int afs_mkdir(struct inode *dir,
ret = -ERESTARTSYS; if (afs_begin_vnode_operation(&fc, dvnode, key, true)) { - afs_dataversion_t data_version = dvnode->status.data_version + 1; + data_version = dvnode->status.data_version + 1;
while (afs_select_fileserver(&fc)) { fc.cb_break = afs_calc_vnode_cb_break(dvnode); @@ -1316,10 +1317,14 @@ static int afs_mkdir(struct inode *dir, goto error_key; }
- if (ret == 0 && - test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) - afs_edit_dir_add(dvnode, &dentry->d_name, &iget_data.fid, - afs_edit_dir_for_create); + if (ret == 0) { + down_write(&dvnode->validate_lock); + if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) && + dvnode->status.data_version == data_version) + afs_edit_dir_add(dvnode, &dentry->d_name, &iget_data.fid, + afs_edit_dir_for_create); + up_write(&dvnode->validate_lock); + }
key_put(key); kfree(scb); @@ -1360,6 +1365,7 @@ static int afs_rmdir(struct inode *dir, struct afs_fs_cursor fc; struct afs_vnode *dvnode = AFS_FS_I(dir), *vnode = NULL; struct key *key; + afs_dataversion_t data_version; int ret;
_enter("{%llx:%llu},{%pd}", @@ -1391,7 +1397,7 @@ static int afs_rmdir(struct inode *dir,
ret = -ERESTARTSYS; if (afs_begin_vnode_operation(&fc, dvnode, key, true)) { - afs_dataversion_t data_version = dvnode->status.data_version + 1; + data_version = dvnode->status.data_version + 1;
while (afs_select_fileserver(&fc)) { fc.cb_break = afs_calc_vnode_cb_break(dvnode); @@ -1404,9 +1410,12 @@ static int afs_rmdir(struct inode *dir, ret = afs_end_vnode_operation(&fc); if (ret == 0) { afs_dir_remove_subdir(dentry); - if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) + down_write(&dvnode->validate_lock); + if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) && + dvnode->status.data_version == data_version) afs_edit_dir_remove(dvnode, &dentry->d_name, afs_edit_dir_for_rmdir); + up_write(&dvnode->validate_lock); } }
@@ -1544,10 +1553,15 @@ static int afs_unlink(struct inode *dir, ret = afs_end_vnode_operation(&fc); if (ret == 0 && !(scb[1].have_status || scb[1].have_error)) ret = afs_dir_remove_link(dvnode, dentry, key); - if (ret == 0 && - test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) - afs_edit_dir_remove(dvnode, &dentry->d_name, - afs_edit_dir_for_unlink); + + if (ret == 0) { + down_write(&dvnode->validate_lock); + if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) && + dvnode->status.data_version == data_version) + afs_edit_dir_remove(dvnode, &dentry->d_name, + afs_edit_dir_for_unlink); + up_write(&dvnode->validate_lock); + } }
if (need_rehash && ret < 0 && ret != -ENOENT) @@ -1573,6 +1587,7 @@ static int afs_create(struct inode *dir, struct afs_status_cb *scb; struct afs_vnode *dvnode = AFS_FS_I(dir); struct key *key; + afs_dataversion_t data_version; int ret;
mode |= S_IFREG; @@ -1597,7 +1612,7 @@ static int afs_create(struct inode *dir,
ret = -ERESTARTSYS; if (afs_begin_vnode_operation(&fc, dvnode, key, true)) { - afs_dataversion_t data_version = dvnode->status.data_version + 1; + data_version = dvnode->status.data_version + 1;
while (afs_select_fileserver(&fc)) { fc.cb_break = afs_calc_vnode_cb_break(dvnode); @@ -1618,9 +1633,12 @@ static int afs_create(struct inode *dir, goto error_key; }
- if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) + down_write(&dvnode->validate_lock); + if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) && + dvnode->status.data_version == data_version) afs_edit_dir_add(dvnode, &dentry->d_name, &iget_data.fid, afs_edit_dir_for_create); + up_write(&dvnode->validate_lock);
kfree(scb); key_put(key); @@ -1648,6 +1666,7 @@ static int afs_link(struct dentry *from, struct afs_vnode *dvnode = AFS_FS_I(dir); struct afs_vnode *vnode = AFS_FS_I(d_inode(from)); struct key *key; + afs_dataversion_t data_version; int ret;
_enter("{%llx:%llu},{%llx:%llu},{%pd}", @@ -1672,7 +1691,7 @@ static int afs_link(struct dentry *from,
ret = -ERESTARTSYS; if (afs_begin_vnode_operation(&fc, dvnode, key, true)) { - afs_dataversion_t data_version = dvnode->status.data_version + 1; + data_version = dvnode->status.data_version + 1;
if (mutex_lock_interruptible_nested(&vnode->io_lock, 1) < 0) { afs_end_vnode_operation(&fc); @@ -1702,9 +1721,12 @@ static int afs_link(struct dentry *from, goto error_key; }
- if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) + down_write(&dvnode->validate_lock); + if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) && + dvnode->status.data_version == data_version) afs_edit_dir_add(dvnode, &dentry->d_name, &vnode->fid, afs_edit_dir_for_link); + up_write(&dvnode->validate_lock);
key_put(key); kfree(scb); @@ -1732,6 +1754,7 @@ static int afs_symlink(struct inode *dir struct afs_status_cb *scb; struct afs_vnode *dvnode = AFS_FS_I(dir); struct key *key; + afs_dataversion_t data_version; int ret;
_enter("{%llx:%llu},{%pd},%s", @@ -1759,7 +1782,7 @@ static int afs_symlink(struct inode *dir
ret = -ERESTARTSYS; if (afs_begin_vnode_operation(&fc, dvnode, key, true)) { - afs_dataversion_t data_version = dvnode->status.data_version + 1; + data_version = dvnode->status.data_version + 1;
while (afs_select_fileserver(&fc)) { fc.cb_break = afs_calc_vnode_cb_break(dvnode); @@ -1780,9 +1803,12 @@ static int afs_symlink(struct inode *dir goto error_key; }
- if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) + down_write(&dvnode->validate_lock); + if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) && + dvnode->status.data_version == data_version) afs_edit_dir_add(dvnode, &dentry->d_name, &iget_data.fid, afs_edit_dir_for_symlink); + up_write(&dvnode->validate_lock);
key_put(key); kfree(scb); @@ -1812,6 +1838,8 @@ static int afs_rename(struct inode *old_ struct dentry *tmp = NULL, *rehash = NULL; struct inode *new_inode; struct key *key; + afs_dataversion_t orig_data_version; + afs_dataversion_t new_data_version; bool new_negative = d_is_negative(new_dentry); int ret;
@@ -1890,9 +1918,6 @@ static int afs_rename(struct inode *old_
ret = -ERESTARTSYS; if (afs_begin_vnode_operation(&fc, orig_dvnode, key, true)) { - afs_dataversion_t orig_data_version; - afs_dataversion_t new_data_version; - orig_data_version = orig_dvnode->status.data_version + 1;
if (orig_dvnode != new_dvnode) { @@ -1928,18 +1953,25 @@ static int afs_rename(struct inode *old_ if (ret == 0) { if (rehash) d_rehash(rehash); - if (test_bit(AFS_VNODE_DIR_VALID, &orig_dvnode->flags)) - afs_edit_dir_remove(orig_dvnode, &old_dentry->d_name, - afs_edit_dir_for_rename_0); - - if (!new_negative && - test_bit(AFS_VNODE_DIR_VALID, &new_dvnode->flags)) - afs_edit_dir_remove(new_dvnode, &new_dentry->d_name, - afs_edit_dir_for_rename_1); + down_write(&orig_dvnode->validate_lock); + if (test_bit(AFS_VNODE_DIR_VALID, &orig_dvnode->flags) && + orig_dvnode->status.data_version == orig_data_version) + afs_edit_dir_remove(orig_dvnode, &old_dentry->d_name, + afs_edit_dir_for_rename_0); + if (orig_dvnode != new_dvnode) { + up_write(&orig_dvnode->validate_lock); + + down_write(&new_dvnode->validate_lock); + } + if (test_bit(AFS_VNODE_DIR_VALID, &new_dvnode->flags) && + orig_dvnode->status.data_version == new_data_version) { + if (!new_negative) + afs_edit_dir_remove(new_dvnode, &new_dentry->d_name, + afs_edit_dir_for_rename_1);
- if (test_bit(AFS_VNODE_DIR_VALID, &new_dvnode->flags)) afs_edit_dir_add(new_dvnode, &new_dentry->d_name, &vnode->fid, afs_edit_dir_for_rename_2); + }
new_inode = d_inode(new_dentry); if (new_inode) { @@ -1958,6 +1990,7 @@ static int afs_rename(struct inode *old_ afs_update_dentry_version(&fc, old_dentry, &scb[1]); afs_update_dentry_version(&fc, new_dentry, &scb[1]); d_move(old_dentry, new_dentry); + up_write(&new_dvnode->validate_lock); goto error_tmp; }
--- a/fs/afs/dir_silly.c +++ b/fs/afs/dir_silly.c @@ -21,6 +21,7 @@ static int afs_do_silly_rename(struct af { struct afs_fs_cursor fc; struct afs_status_cb *scb; + afs_dataversion_t dir_data_version; int ret = -ERESTARTSYS;
_enter("%pd,%pd", old, new); @@ -31,7 +32,7 @@ static int afs_do_silly_rename(struct af
trace_afs_silly_rename(vnode, false); if (afs_begin_vnode_operation(&fc, dvnode, key, true)) { - afs_dataversion_t dir_data_version = dvnode->status.data_version + 1; + dir_data_version = dvnode->status.data_version + 1;
while (afs_select_fileserver(&fc)) { fc.cb_break = afs_calc_vnode_cb_break(dvnode); @@ -54,12 +55,15 @@ static int afs_do_silly_rename(struct af dvnode->silly_key = key_get(key); }
- if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) + down_write(&dvnode->validate_lock); + if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) && + dvnode->status.data_version == dir_data_version) { afs_edit_dir_remove(dvnode, &old->d_name, afs_edit_dir_for_silly_0); - if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) afs_edit_dir_add(dvnode, &new->d_name, &vnode->fid, afs_edit_dir_for_silly_1); + } + up_write(&dvnode->validate_lock); }
kfree(scb); @@ -181,10 +185,14 @@ static int afs_do_silly_unlink(struct af clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags); } } - if (ret == 0 && - test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) - afs_edit_dir_remove(dvnode, &dentry->d_name, - afs_edit_dir_for_unlink); + if (ret == 0) { + down_write(&dvnode->validate_lock); + if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) && + dvnode->status.data_version == dir_data_version) + afs_edit_dir_remove(dvnode, &dentry->d_name, + afs_edit_dir_for_unlink); + up_write(&dvnode->validate_lock); + } }
kfree(scb);
From: Paolo Valente paolo.valente@linaro.org
commit c8997736650060594845e42c5d01d3118aec8d25 upstream.
A bfq_put_queue() may be invoked in __bfq_bic_change_cgroup(). The goal of this put is to release a process reference to a bfq_queue. But process-reference releases may trigger also some extra operation, and, to this goal, are handled through bfq_release_process_ref(). So, turn the invocation of bfq_put_queue() into an invocation of bfq_release_process_ref().
Tested-by: cki-project@redhat.com Signed-off-by: Paolo Valente paolo.valente@linaro.org Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- block/bfq-cgroup.c | 5 +---- block/bfq-iosched.c | 2 -- block/bfq-iosched.h | 1 + 3 files changed, 2 insertions(+), 6 deletions(-)
--- a/block/bfq-cgroup.c +++ b/block/bfq-cgroup.c @@ -697,10 +697,7 @@ static struct bfq_group *__bfq_bic_chang
if (entity->sched_data != &bfqg->sched_data) { bic_set_bfqq(bic, NULL, 0); - bfq_log_bfqq(bfqd, async_bfqq, - "bic_change_group: %p %d", - async_bfqq, async_bfqq->ref); - bfq_put_queue(async_bfqq); + bfq_release_process_ref(bfqd, async_bfqq); } }
--- a/block/bfq-iosched.c +++ b/block/bfq-iosched.c @@ -2717,8 +2717,6 @@ static void bfq_bfqq_save_state(struct b } }
- -static void bfq_release_process_ref(struct bfq_data *bfqd, struct bfq_queue *bfqq) { /* --- a/block/bfq-iosched.h +++ b/block/bfq-iosched.h @@ -950,6 +950,7 @@ void bfq_bfqq_expire(struct bfq_data *bf bool compensate, enum bfqq_expiration reason); void bfq_put_queue(struct bfq_queue *bfqq); void bfq_end_wr_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg); +void bfq_release_process_ref(struct bfq_data *bfqd, struct bfq_queue *bfqq); void bfq_schedule_dispatch(struct bfq_data *bfqd); void bfq_put_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg);
From: Paolo Valente paolo.valente@linaro.org
commit 576682fa52cbd95deb3773449566274f206acc58 upstream.
bfq_reparent_leaf_entity() reparents the input leaf entity (a leaf entity represents just a bfq_queue in an entity tree). Yet, the input entity is guaranteed to always be a leaf entity only in two-level entity trees. In this respect, because of the error fixed by commit 14afc5936197 ("block, bfq: fix overwrite of bfq_group pointer in bfq_find_set_group()"), all (wrongly collapsed) entity trees happened to actually have only two levels. After the latter commit, this does not hold any longer.
This commit fixes this problem by modifying bfq_reparent_leaf_entity(), so that it searches an active leaf entity down the path that stems from the input entity. Such a leaf entity is guaranteed to exist when bfq_reparent_leaf_entity() is invoked.
Tested-by: cki-project@redhat.com Signed-off-by: Paolo Valente paolo.valente@linaro.org Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- block/bfq-cgroup.c | 48 +++++++++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 17 deletions(-)
--- a/block/bfq-cgroup.c +++ b/block/bfq-cgroup.c @@ -798,39 +798,53 @@ static void bfq_flush_idle_tree(struct b /** * bfq_reparent_leaf_entity - move leaf entity to the root_group. * @bfqd: the device data structure with the root group. - * @entity: the entity to move. + * @entity: the entity to move, if entity is a leaf; or the parent entity + * of an active leaf entity to move, if entity is not a leaf. */ static void bfq_reparent_leaf_entity(struct bfq_data *bfqd, - struct bfq_entity *entity) + struct bfq_entity *entity, + int ioprio_class) { - struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); + struct bfq_queue *bfqq; + struct bfq_entity *child_entity = entity;
+ while (child_entity->my_sched_data) { /* leaf not reached yet */ + struct bfq_sched_data *child_sd = child_entity->my_sched_data; + struct bfq_service_tree *child_st = child_sd->service_tree + + ioprio_class; + struct rb_root *child_active = &child_st->active; + + child_entity = bfq_entity_of(rb_first(child_active)); + + if (!child_entity) + child_entity = child_sd->in_service_entity; + } + + bfqq = bfq_entity_to_bfqq(child_entity); bfq_bfqq_move(bfqd, bfqq, bfqd->root_group); }
/** - * bfq_reparent_active_entities - move to the root group all active - * entities. + * bfq_reparent_active_queues - move to the root group all active queues. * @bfqd: the device data structure with the root group. * @bfqg: the group to move from. - * @st: the service tree with the entities. + * @st: the service tree to start the search from. */ -static void bfq_reparent_active_entities(struct bfq_data *bfqd, - struct bfq_group *bfqg, - struct bfq_service_tree *st) +static void bfq_reparent_active_queues(struct bfq_data *bfqd, + struct bfq_group *bfqg, + struct bfq_service_tree *st, + int ioprio_class) { struct rb_root *active = &st->active; - struct bfq_entity *entity = NULL; - - if (!RB_EMPTY_ROOT(&st->active)) - entity = bfq_entity_of(rb_first(active)); + struct bfq_entity *entity;
- for (; entity ; entity = bfq_entity_of(rb_first(active))) - bfq_reparent_leaf_entity(bfqd, entity); + while ((entity = bfq_entity_of(rb_first(active)))) + bfq_reparent_leaf_entity(bfqd, entity, ioprio_class);
if (bfqg->sched_data.in_service_entity) bfq_reparent_leaf_entity(bfqd, - bfqg->sched_data.in_service_entity); + bfqg->sched_data.in_service_entity, + ioprio_class); }
/** @@ -881,7 +895,7 @@ static void bfq_pd_offline(struct blkg_p * There is no need to put the sync queues, as the * scheduler has taken no reference. */ - bfq_reparent_active_entities(bfqd, bfqg, st); + bfq_reparent_active_queues(bfqd, bfqg, st, i); }
__bfq_deactivate_entity(entity, false);
From: Paolo Valente paolo.valente@linaro.org
commit 4d38a87fbb77fb9ff2ff4e914162a8ae6453eff5 upstream.
In bfq_pd_offline(), the function bfq_flush_idle_tree() is invoked to flush the rb tree that contains all idle entities belonging to the pd (cgroup) being destroyed. In particular, bfq_flush_idle_tree() is invoked before bfq_reparent_active_queues(). Yet the latter may happen to add some entities to the idle tree. It happens if, in some of the calls to bfq_bfqq_move() performed by bfq_reparent_active_queues(), the queue to move is empty and gets expired.
This commit simply reverses the invocation order between bfq_flush_idle_tree() and bfq_reparent_active_queues().
Tested-by: cki-project@redhat.com Signed-off-by: Paolo Valente paolo.valente@linaro.org Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- block/bfq-cgroup.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-)
--- a/block/bfq-cgroup.c +++ b/block/bfq-cgroup.c @@ -877,13 +877,6 @@ static void bfq_pd_offline(struct blkg_p st = bfqg->sched_data.service_tree + i;
/* - * The idle tree may still contain bfq_queues belonging - * to exited task because they never migrated to a different - * cgroup from the one being destroyed now. - */ - bfq_flush_idle_tree(st); - - /* * It may happen that some queues are still active * (busy) upon group destruction (if the corresponding * processes have been forced to terminate). We move @@ -896,6 +889,19 @@ static void bfq_pd_offline(struct blkg_p * scheduler has taken no reference. */ bfq_reparent_active_queues(bfqd, bfqg, st, i); + + /* + * The idle tree may still contain bfq_queues + * belonging to exited task because they never + * migrated to a different cgroup from the one being + * destroyed now. In addition, even + * bfq_reparent_active_queues() may happen to add some + * entities to the idle tree. It happens if, in some + * of the calls to bfq_bfqq_move() performed by + * bfq_reparent_active_queues(), the queue to move is + * empty and gets expired. + */ + bfq_flush_idle_tree(st); }
__bfq_deactivate_entity(entity, false);
From: Ilya Dryomov idryomov@gmail.com
[ Upstream commit 0e4e1de5b63fa423b13593337a27fd2d2b0bcf77 ]
rbd_unregister_watch() flushes notifies and therefore cannot be called under header_rwsem because a header update notify takes header_rwsem to synchronize with "rbd map". If mapping an image fails after the watch is established and a header update notify sneaks in, we deadlock when erroring out from rbd_dev_image_probe().
Move watch registration and unregistration out of the critical section. The only reason they were put there was to make header_rwsem management slightly more obvious.
Fixes: 811c66887746 ("rbd: fix rbd map vs notify races") Signed-off-by: Ilya Dryomov idryomov@gmail.com Reviewed-by: Jason Dillaman dillaman@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/rbd.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index a67315786db47..bab9c546ba334 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -4636,6 +4636,10 @@ static void cancel_tasks_sync(struct rbd_device *rbd_dev) cancel_work_sync(&rbd_dev->unlock_work); }
+/* + * header_rwsem must not be held to avoid a deadlock with + * rbd_dev_refresh() when flushing notifies. + */ static void rbd_unregister_watch(struct rbd_device *rbd_dev) { cancel_tasks_sync(rbd_dev); @@ -6942,6 +6946,9 @@ static void rbd_dev_image_release(struct rbd_device *rbd_dev) * device. If this image is the one being mapped (i.e., not a * parent), initiate a watch on its header object before using that * object to get detailed information about the rbd image. + * + * On success, returns with header_rwsem held for write if called + * with @depth == 0. */ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth) { @@ -6974,6 +6981,9 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth) } }
+ if (!depth) + down_write(&rbd_dev->header_rwsem); + ret = rbd_dev_header_info(rbd_dev); if (ret) goto err_out_watch; @@ -7027,6 +7037,8 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth) err_out_probe: rbd_dev_unprobe(rbd_dev); err_out_watch: + if (!depth) + up_write(&rbd_dev->header_rwsem); if (!depth) rbd_unregister_watch(rbd_dev); err_out_format: @@ -7085,12 +7097,9 @@ static ssize_t do_rbd_add(struct bus_type *bus, goto err_out_rbd_dev; }
- down_write(&rbd_dev->header_rwsem); rc = rbd_dev_image_probe(rbd_dev, 0); - if (rc < 0) { - up_write(&rbd_dev->header_rwsem); + if (rc < 0) goto err_out_rbd_dev; - }
/* If we are mapping a snapshot it must be marked read-only */ if (rbd_dev->spec->snap_id != CEPH_NOSNAP)
From: Ilya Dryomov idryomov@gmail.com
[ Upstream commit 952c48b0ed18919bff7528501e9a3fff8a24f8cd ]
rbd_dev_unprobe() is supposed to undo most of rbd_dev_image_probe(), including rbd_dev_header_info(), which means that rbd_dev_header_info() isn't supposed to be called after rbd_dev_unprobe().
However, rbd_dev_image_release() calls rbd_dev_unprobe() before rbd_unregister_watch(). This is racy because a header update notify can sneak in:
"rbd unmap" thread ceph-watch-notify worker
rbd_dev_image_release() rbd_dev_unprobe() free and zero out header rbd_watch_cb() rbd_dev_refresh() rbd_dev_header_info() read in header
The same goes for "rbd map" because rbd_dev_image_probe() calls rbd_dev_unprobe() on errors. In both cases this results in a memory leak.
Fixes: fd22aef8b47c ("rbd: move rbd_unregister_watch() call into rbd_dev_image_release()") Signed-off-by: Ilya Dryomov idryomov@gmail.com Reviewed-by: Jason Dillaman dillaman@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/rbd.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index bab9c546ba334..274beda31c356 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -6933,9 +6933,10 @@ static int rbd_dev_header_name(struct rbd_device *rbd_dev)
static void rbd_dev_image_release(struct rbd_device *rbd_dev) { - rbd_dev_unprobe(rbd_dev); if (rbd_dev->opts) rbd_unregister_watch(rbd_dev); + + rbd_dev_unprobe(rbd_dev); rbd_dev->image_format = 0; kfree(rbd_dev->spec->image_id); rbd_dev->spec->image_id = NULL; @@ -6986,7 +6987,7 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth)
ret = rbd_dev_header_info(rbd_dev); if (ret) - goto err_out_watch; + goto err_out_probe;
/* * If this image is the one being mapped, we have pool name and @@ -7035,12 +7036,11 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth) return 0;
err_out_probe: - rbd_dev_unprobe(rbd_dev); -err_out_watch: if (!depth) up_write(&rbd_dev->header_rwsem); if (!depth) rbd_unregister_watch(rbd_dev); + rbd_dev_unprobe(rbd_dev); err_out_format: rbd_dev->image_format = 0; kfree(rbd_dev->spec->image_id);
From: Tianyu Lan Tianyu.Lan@microsoft.com
[ Upstream commit 7f11a2cc10a4ae3a70e2c73361f4a9a33503539b ]
If kmsg_dump_register() fails, hv_panic_page will not be used anywhere. So free and reset it.
Fixes: 81b18bce48af ("Drivers: HV: Send one page worth of kmsg dump over Hyper-V during panic") Reviewed-by: Michael Kelley mikelley@microsoft.com Signed-off-by: Tianyu Lan Tianyu.Lan@microsoft.com Link: https://lore.kernel.org/r/20200406155331.2105-3-Tianyu.Lan@microsoft.com Signed-off-by: Wei Liu wei.liu@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hv/vmbus_drv.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index 593107c20e977..40f6b73dae940 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -1401,9 +1401,13 @@ static int vmbus_bus_init(void) hv_panic_page = (void *)get_zeroed_page(GFP_KERNEL); if (hv_panic_page) { ret = kmsg_dump_register(&hv_kmsg_dumper); - if (ret) + if (ret) { pr_err("Hyper-V: kmsg dump register " "error 0x%x\n", ret); + hv_free_hyperv_page( + (unsigned long)hv_panic_page); + hv_panic_page = NULL; + } } else pr_err("Hyper-V: panic message page memory " "allocation failed"); @@ -1433,7 +1437,6 @@ static int vmbus_bus_init(void) hv_remove_vmbus_irq();
bus_unregister(&hv_bus); - free_page((unsigned long)hv_panic_page); unregister_sysctl_table(hv_ctl_table_hdr); hv_ctl_table_hdr = NULL; return ret;
From: xinhui pan xinhui.pan@amd.com
[ Upstream commit 1bbcf69e42fe7fd49b6f4339c970729d0e343753 ]
As we move the ttm_bo_individualize_resv() upwards, we need flush the copied fence too. Otherwise the driver keeps waiting for fence.
run&Kill kfdtest, then perf top.
25.53% [ttm] [k] ttm_bo_delayed_delete 24.29% [kernel] [k] dma_resv_test_signaled_rcu 19.72% [kernel] [k] ww_mutex_lock
Fix: 378e2d5b("drm/ttm: fix ttm_bo_cleanup_refs_or_queue once more") Signed-off-by: xinhui pan xinhui.pan@amd.com Reviewed-by: Christian König christian.koenig@amd.com Link: https://patchwork.freedesktop.org/series/72339/ Signed-off-by: Christian König christian.koenig@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/ttm/ttm_bo.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index f078036998092..abf165b2f64fc 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -517,8 +517,10 @@ static void ttm_bo_cleanup_refs_or_queue(struct ttm_buffer_object *bo)
dma_resv_unlock(bo->base.resv); } - if (bo->base.resv != &bo->base._resv) + if (bo->base.resv != &bo->base._resv) { + ttm_bo_flush_all_fences(bo); dma_resv_unlock(&bo->base._resv); + }
error: kref_get(&bo->list_kref);
From: Stephen Boyd sboyd@kernel.org
[ Upstream commit f21cf9c77ee82ef8adfeb2143adfacf21ec1d5cc ]
We don't check for errors from clk_ops::get_phase() before storing away the result into the clk_core::phase member. This can lead to some fairly confusing debugfs information if these ops do return an error. Let's skip the store when this op fails to fix this. While we're here, move the locking outside of clk_core_get_phase() to simplify callers from the debugfs side.
Cc: Douglas Anderson dianders@chromium.org Cc: Heiko Stuebner heiko@sntech.de Cc: Jerome Brunet jbrunet@baylibre.com Signed-off-by: Stephen Boyd sboyd@kernel.org Link: https://lkml.kernel.org/r/20200205232802.29184-2-sboyd@kernel.org Acked-by: Jerome Brunet jbrunet@baylibre.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/clk.c | 48 +++++++++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 16 deletions(-)
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 62d0fc486d3a2..80b029713722b 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -2642,12 +2642,14 @@ static int clk_core_get_phase(struct clk_core *core) { int ret;
- clk_prepare_lock(); + lockdep_assert_held(&prepare_lock); + if (!core->ops->get_phase) + return 0; + /* Always try to update cached phase if possible */ - if (core->ops->get_phase) - core->phase = core->ops->get_phase(core->hw); - ret = core->phase; - clk_prepare_unlock(); + ret = core->ops->get_phase(core->hw); + if (ret >= 0) + core->phase = ret;
return ret; } @@ -2661,10 +2663,16 @@ static int clk_core_get_phase(struct clk_core *core) */ int clk_get_phase(struct clk *clk) { + int ret; + if (!clk) return 0;
- return clk_core_get_phase(clk->core); + clk_prepare_lock(); + ret = clk_core_get_phase(clk->core); + clk_prepare_unlock(); + + return ret; } EXPORT_SYMBOL_GPL(clk_get_phase);
@@ -2878,13 +2886,21 @@ static struct hlist_head *orphan_list[] = { static void clk_summary_show_one(struct seq_file *s, struct clk_core *c, int level) { - seq_printf(s, "%*s%-*s %7d %8d %8d %11lu %10lu %5d %6d\n", + int phase; + + seq_printf(s, "%*s%-*s %7d %8d %8d %11lu %10lu ", level * 3 + 1, "", 30 - level * 3, c->name, c->enable_count, c->prepare_count, c->protect_count, - clk_core_get_rate(c), clk_core_get_accuracy(c), - clk_core_get_phase(c), - clk_core_get_scaled_duty_cycle(c, 100000)); + clk_core_get_rate(c), clk_core_get_accuracy(c)); + + phase = clk_core_get_phase(c); + if (phase >= 0) + seq_printf(s, "%5d", phase); + else + seq_puts(s, "-----"); + + seq_printf(s, " %6d\n", clk_core_get_scaled_duty_cycle(c, 100000)); }
static void clk_summary_show_subtree(struct seq_file *s, struct clk_core *c, @@ -2921,6 +2937,7 @@ DEFINE_SHOW_ATTRIBUTE(clk_summary);
static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level) { + int phase; unsigned long min_rate, max_rate;
clk_core_get_boundaries(c, &min_rate, &max_rate); @@ -2934,7 +2951,9 @@ static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level) seq_printf(s, ""min_rate": %lu,", min_rate); seq_printf(s, ""max_rate": %lu,", max_rate); seq_printf(s, ""accuracy": %lu,", clk_core_get_accuracy(c)); - seq_printf(s, ""phase": %d,", clk_core_get_phase(c)); + phase = clk_core_get_phase(c); + if (phase >= 0) + seq_printf(s, ""phase": %d,", phase); seq_printf(s, ""duty_cycle": %u", clk_core_get_scaled_duty_cycle(c, 100000)); } @@ -3375,14 +3394,11 @@ static int __clk_core_init(struct clk_core *core) core->accuracy = 0;
/* - * Set clk's phase. + * Set clk's phase by clk_core_get_phase() caching the phase. * Since a phase is by definition relative to its parent, just * query the current clock phase, or just assume it's in phase. */ - if (core->ops->get_phase) - core->phase = core->ops->get_phase(core->hw); - else - core->phase = 0; + clk_core_get_phase(core);
/* * Set clk's duty cycle.
From: Claudiu Beznea claudiu.beznea@microchip.com
[ Upstream commit b0ecf1c6c6e82da4847900fad0272abfd014666d ]
clk_hw_round_rate() may call round rate function of its parents. In case of SAM9X60 two of USB parrents are PLLA and UPLL. These clocks are controlled by clk-sam9x60-pll.c driver. The round rate function for this driver is sam9x60_pll_round_rate() which call in turn sam9x60_pll_get_best_div_mul(). In case the requested rate is not in the proper range (rate < characteristics->output[0].min && rate > characteristics->output[0].max) the sam9x60_pll_round_rate() will return a negative number to its caller (called by clk_core_round_rate_nolock()). clk_hw_round_rate() will return zero in case a negative number is returned by clk_core_round_rate_nolock(). With this, the USB clock will continue its rate computation even caller of clk_hw_round_rate() returned an error. With this, the USB clock on SAM9X60 may not chose the best parent. I detected this after a suspend/resume cycle on SAM9X60.
Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com Link: https://lkml.kernel.org/r/1579261009-4573-2-git-send-email-claudiu.beznea@mi... Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/at91/clk-usb.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/clk/at91/clk-usb.c b/drivers/clk/at91/clk-usb.c index bda92980e0155..c0895c993cce2 100644 --- a/drivers/clk/at91/clk-usb.c +++ b/drivers/clk/at91/clk-usb.c @@ -75,6 +75,9 @@ static int at91sam9x5_clk_usb_determine_rate(struct clk_hw *hw, tmp_parent_rate = req->rate * div; tmp_parent_rate = clk_hw_round_rate(parent, tmp_parent_rate); + if (!tmp_parent_rate) + continue; + tmp_rate = DIV_ROUND_CLOSEST(tmp_parent_rate, div); if (tmp_rate < req->rate) tmp_diff = req->rate - tmp_rate;
From: Aya Levin ayal@mellanox.com
[ Upstream commit 4bd9d5070b92da012f2715cf8e4859acb78b8f35 ]
Ethtool command allow setting of several FEC modes in a single set command. The driver can only set a single FEC mode at a time. With this patch driver will reply not-supported on setting several FEC modes.
Signed-off-by: Aya Levin ayal@mellanox.com Signed-off-by: Saeed Mahameed saeedm@mellanox.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c index 304ddce6b0872..39ee32518b106 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c @@ -1548,6 +1548,10 @@ static int mlx5e_set_fecparam(struct net_device *netdev, int mode; int err;
+ if (bitmap_weight((unsigned long *)&fecparam->fec, + ETHTOOL_FEC_BASER_BIT + 1) > 1) + return -EOPNOTSUPP; + for (mode = 0; mode < ARRAY_SIZE(pplm_fec_2_ethtool); mode++) { if (!(pplm_fec_2_ethtool[mode] & fecparam->fec)) continue;
From: Sahitya Tummala stummala@codeaurora.org
[ Upstream commit bf22c3cc8ce71454dddd772284773306a68031d8 ]
There could be a scenario where f2fs_sync_meta_pages() will not ensure that all F2FS_DIRTY_META pages are submitted for IO. Thus, resulting in the below panic in do_checkpoint() -
f2fs_bug_on(sbi, get_pages(sbi, F2FS_DIRTY_META) && !f2fs_cp_error(sbi));
This can happen in a low-memory condition, where shrinker could also be doing the writepage operation (stack shown below) at the same time when checkpoint is running on another core.
schedule down_write f2fs_submit_page_write -> by this time, this page in page cache is tagged as PAGECACHE_TAG_WRITEBACK and PAGECACHE_TAG_DIRTY is cleared, due to which f2fs_sync_meta_pages() cannot sync this page in do_checkpoint() path. f2fs_do_write_meta_page __f2fs_write_meta_page f2fs_write_meta_page shrink_page_list shrink_inactive_list shrink_node_memcg shrink_node kswapd
Signed-off-by: Sahitya Tummala stummala@codeaurora.org Reviewed-by: Chao Yu yuchao0@huawei.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/checkpoint.c | 16 +++++++--------- fs/f2fs/f2fs.h | 2 +- fs/f2fs/super.c | 2 +- 3 files changed, 9 insertions(+), 11 deletions(-)
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index a0eef95b9e0ed..410f5c2c6ef17 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -1250,20 +1250,20 @@ static void unblock_operations(struct f2fs_sb_info *sbi) f2fs_unlock_all(sbi); }
-void f2fs_wait_on_all_pages_writeback(struct f2fs_sb_info *sbi) +void f2fs_wait_on_all_pages(struct f2fs_sb_info *sbi, int type) { DEFINE_WAIT(wait);
for (;;) { prepare_to_wait(&sbi->cp_wait, &wait, TASK_UNINTERRUPTIBLE);
- if (!get_pages(sbi, F2FS_WB_CP_DATA)) + if (!get_pages(sbi, type)) break;
if (unlikely(f2fs_cp_error(sbi))) break;
- io_schedule_timeout(5*HZ); + io_schedule_timeout(HZ/50); } finish_wait(&sbi->cp_wait, &wait); } @@ -1384,8 +1384,6 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
/* Flush all the NAT/SIT pages */ f2fs_sync_meta_pages(sbi, META, LONG_MAX, FS_CP_META_IO); - f2fs_bug_on(sbi, get_pages(sbi, F2FS_DIRTY_META) && - !f2fs_cp_error(sbi));
/* * modify checkpoint @@ -1493,11 +1491,11 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
/* Here, we have one bio having CP pack except cp pack 2 page */ f2fs_sync_meta_pages(sbi, META, LONG_MAX, FS_CP_META_IO); - f2fs_bug_on(sbi, get_pages(sbi, F2FS_DIRTY_META) && - !f2fs_cp_error(sbi)); + /* Wait for all dirty meta pages to be submitted for IO */ + f2fs_wait_on_all_pages(sbi, F2FS_DIRTY_META);
/* wait for previous submitted meta pages writeback */ - f2fs_wait_on_all_pages_writeback(sbi); + f2fs_wait_on_all_pages(sbi, F2FS_WB_CP_DATA);
/* flush all device cache */ err = f2fs_flush_device_cache(sbi); @@ -1506,7 +1504,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
/* barrier and flush checkpoint cp pack 2 page if it can */ commit_checkpoint(sbi, ckpt, start_blk); - f2fs_wait_on_all_pages_writeback(sbi); + f2fs_wait_on_all_pages(sbi, F2FS_WB_CP_DATA);
/* * invalidate intermediate page cache borrowed from meta inode diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 9046432b87c2d..1a8b68ceaa62f 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -3185,7 +3185,7 @@ int f2fs_get_valid_checkpoint(struct f2fs_sb_info *sbi); void f2fs_update_dirty_page(struct inode *inode, struct page *page); void f2fs_remove_dirty_inode(struct inode *inode); int f2fs_sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type); -void f2fs_wait_on_all_pages_writeback(struct f2fs_sb_info *sbi); +void f2fs_wait_on_all_pages(struct f2fs_sb_info *sbi, int type); int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc); void f2fs_init_ino_entry_info(struct f2fs_sb_info *sbi); int __init f2fs_create_checkpoint_caches(void); diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index ea8dbf1458c99..28441f4971b8d 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -1105,7 +1105,7 @@ static void f2fs_put_super(struct super_block *sb) /* our cp_error case, we can wait for any writeback page */ f2fs_flush_merged_writes(sbi);
- f2fs_wait_on_all_pages_writeback(sbi); + f2fs_wait_on_all_pages(sbi, F2FS_WB_CP_DATA);
f2fs_bug_on(sbi, sbi->fsync_node_num);
From: Johan Jonker jbx6244@gmail.com
[ Upstream commit 9cd568dc588c5d168615bf34f325fabe33b2c9a0 ]
A test with the command below does not detect all errors in combination with 'additionalProperties: false' and allOf: - $ref: "synopsys-dw-mshc-common.yaml#" allOf: - $ref: "mmc-controller.yaml#"
'additionalProperties' applies to all properties that are not accounted-for by 'properties' or 'patternProperties' in the immediate schema.
First when we combine rockchip-dw-mshc.yaml, synopsys-dw-mshc-common.yaml and mmc-controller.yaml it gives this error:
arch/arm/boot/dts/rk3188-bqedison2qc.dt.yaml: mmc@10218000: 'vmmcq-supply' does not match any of the regexes: '^.*@[0-9]+$', '^clk-phase-(legacy|sd-hs|mmc-(hs|hs[24]00|ddr52)| uhs-(sdr(12|25|50|104)|ddr50))$', 'pinctrl-[0-9]+'
'vmmcq-supply' is not a valid property name for mmc nodes. Fix this error by renaming it to 'vqmmc-supply'.
make ARCH=arm dtbs_check DT_SCHEMA_FILES=Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.yaml
Signed-off-by: Johan Jonker jbx6244@gmail.com Link: https://lore.kernel.org/r/20200307134841.13803-1-jbx6244@gmail.com Signed-off-by: Heiko Stuebner heiko@sntech.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/rk3188-bqedison2qc.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/rk3188-bqedison2qc.dts b/arch/arm/boot/dts/rk3188-bqedison2qc.dts index ad1afd403052a..8afb2fd5d9f1b 100644 --- a/arch/arm/boot/dts/rk3188-bqedison2qc.dts +++ b/arch/arm/boot/dts/rk3188-bqedison2qc.dts @@ -465,7 +465,7 @@ non-removable; pinctrl-names = "default"; pinctrl-0 = <&sd1_clk>, <&sd1_cmd>, <&sd1_bus4>; - vmmcq-supply = <&vccio_wl>; + vqmmc-supply = <&vccio_wl>; #address-cells = <1>; #size-cells = <0>; status = "okay";
From: Jernej Skrabec jernej.skrabec@siol.net
[ Upstream commit 3e9a1a8b7f811de3eb1445d72f68766b704ad17c ]
Register range of display clocks is 0x10000, as it can be seen from DE2 documentation.
Fix it.
Signed-off-by: Jernej Skrabec jernej.skrabec@siol.net Fixes: 2c796fc8f5dbd ("arm64: dts: allwinner: a64: add necessary device tree nodes for DE2 CCU") [wens@csie.org: added fixes tag] Signed-off-by: Chen-Yu Tsai wens@csie.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi index ba41c1b85887a..367699c8c9028 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi @@ -227,7 +227,7 @@
display_clocks: clock@0 { compatible = "allwinner,sun50i-a64-de2-clk"; - reg = <0x0 0x100000>; + reg = <0x0 0x10000>; clocks = <&ccu CLK_BUS_DE>, <&ccu CLK_DE>; clock-names = "bus",
From: Dmitry Osipenko digetx@gmail.com
[ Upstream commit 583b53ece0b0268c542a1eafadb62e3d4b0aab8c ]
The driver fails to probe with -EPROBE_DEFER if battery's power supply (charger driver) isn't ready yet and this results in a bit noisy error message in KMSG during kernel's boot up. Let's silence the harmless error message.
Signed-off-by: Dmitry Osipenko digetx@gmail.com Reviewed-by: Andrew F. Davis afd@ti.com Reviewed-by: Pali Rohár pali@kernel.org Signed-off-by: Sebastian Reichel sebastian.reichel@collabora.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/power/supply/bq27xxx_battery.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c index 195c18c2f426e..664e50103eaaf 100644 --- a/drivers/power/supply/bq27xxx_battery.c +++ b/drivers/power/supply/bq27xxx_battery.c @@ -1885,7 +1885,10 @@ int bq27xxx_battery_setup(struct bq27xxx_device_info *di)
di->bat = power_supply_register_no_ws(di->dev, psy_desc, &psy_cfg); if (IS_ERR(di->bat)) { - dev_err(di->dev, "failed to register battery\n"); + if (PTR_ERR(di->bat) == -EPROBE_DEFER) + dev_dbg(di->dev, "failed to register battery, deferring probe\n"); + else + dev_err(di->dev, "failed to register battery\n"); return PTR_ERR(di->bat); }
From: Sowjanya Komatineni skomatineni@nvidia.com
[ Upstream commit 6fe38aa8cac3a5db38154331742835a4d9740788 ]
Tegra PMC clocks clk_out_1, clk_out_2, and clk_out_3 supported parents are osc, osc_div2, osc_div4 and extern clock.
Clock driver is using incorrect parents clk_m, clk_m_div2, clk_m_div4 for PMC clocks.
This patch fixes this.
Tested-by: Dmitry Osipenko digetx@gmail.com Reviewed-by: Dmitry Osipenko digetx@gmail.com Signed-off-by: Sowjanya Komatineni skomatineni@nvidia.com Signed-off-by: Thierry Reding treding@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/tegra/clk-tegra-pmc.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/clk/tegra/clk-tegra-pmc.c b/drivers/clk/tegra/clk-tegra-pmc.c index bec3e008335f3..5e044ba1ae364 100644 --- a/drivers/clk/tegra/clk-tegra-pmc.c +++ b/drivers/clk/tegra/clk-tegra-pmc.c @@ -49,16 +49,16 @@ struct pmc_clk_init_data {
static DEFINE_SPINLOCK(clk_out_lock);
-static const char *clk_out1_parents[] = { "clk_m", "clk_m_div2", - "clk_m_div4", "extern1", +static const char *clk_out1_parents[] = { "osc", "osc_div2", + "osc_div4", "extern1", };
-static const char *clk_out2_parents[] = { "clk_m", "clk_m_div2", - "clk_m_div4", "extern2", +static const char *clk_out2_parents[] = { "osc", "osc_div2", + "osc_div4", "extern2", };
-static const char *clk_out3_parents[] = { "clk_m", "clk_m_div2", - "clk_m_div4", "extern3", +static const char *clk_out3_parents[] = { "osc", "osc_div2", + "osc_div4", "extern3", };
static struct pmc_clk_init_data pmc_clks[] = {
From: Vidya Sagar vidyas@nvidia.com
[ Upstream commit 0c988b731e6430f0081991fdb4f63f7fc837df9a ]
Add endpoint mode controllers nodes for the dual mode PCIe controllers present in Tegra194 SoC.
Signed-off-by: Vidya Sagar vidyas@nvidia.com Signed-off-by: Thierry Reding treding@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/nvidia/tegra194.dtsi | 99 ++++++++++++++++++++++++ 1 file changed, 99 insertions(+)
diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi b/arch/arm64/boot/dts/nvidia/tegra194.dtsi index 3c0cf54f0aab3..57adcbb7352d6 100644 --- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi @@ -1430,6 +1430,105 @@ 0x82000000 0x0 0x40000000 0x1f 0x40000000 0x0 0xc0000000>; /* non-prefetchable memory (3GB) */ };
+ pcie_ep@14160000 { + compatible = "nvidia,tegra194-pcie-ep", "snps,dw-pcie-ep"; + power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX4A>; + reg = <0x00 0x14160000 0x0 0x00020000 /* appl registers (128K) */ + 0x00 0x36040000 0x0 0x00040000 /* iATU_DMA reg space (256K) */ + 0x00 0x36080000 0x0 0x00040000 /* DBI reg space (256K) */ + 0x14 0x00000000 0x4 0x00000000>; /* Address Space (16G) */ + reg-names = "appl", "atu_dma", "dbi", "addr_space"; + + status = "disabled"; + + num-lanes = <4>; + num-ib-windows = <2>; + num-ob-windows = <8>; + + clocks = <&bpmp TEGRA194_CLK_PEX0_CORE_4>; + clock-names = "core"; + + resets = <&bpmp TEGRA194_RESET_PEX0_CORE_4_APB>, + <&bpmp TEGRA194_RESET_PEX0_CORE_4>; + reset-names = "apb", "core"; + + interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>; /* controller interrupt */ + interrupt-names = "intr"; + + nvidia,bpmp = <&bpmp 4>; + + nvidia,aspm-cmrt-us = <60>; + nvidia,aspm-pwr-on-t-us = <20>; + nvidia,aspm-l0s-entrance-latency-us = <3>; + }; + + pcie_ep@14180000 { + compatible = "nvidia,tegra194-pcie-ep", "snps,dw-pcie-ep"; + power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX8B>; + reg = <0x00 0x14180000 0x0 0x00020000 /* appl registers (128K) */ + 0x00 0x38040000 0x0 0x00040000 /* iATU_DMA reg space (256K) */ + 0x00 0x38080000 0x0 0x00040000 /* DBI reg space (256K) */ + 0x18 0x00000000 0x4 0x00000000>; /* Address Space (16G) */ + reg-names = "appl", "atu_dma", "dbi", "addr_space"; + + status = "disabled"; + + num-lanes = <8>; + num-ib-windows = <2>; + num-ob-windows = <8>; + + clocks = <&bpmp TEGRA194_CLK_PEX0_CORE_0>; + clock-names = "core"; + + resets = <&bpmp TEGRA194_RESET_PEX0_CORE_0_APB>, + <&bpmp TEGRA194_RESET_PEX0_CORE_0>; + reset-names = "apb", "core"; + + interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>; /* controller interrupt */ + interrupt-names = "intr"; + + nvidia,bpmp = <&bpmp 0>; + + nvidia,aspm-cmrt-us = <60>; + nvidia,aspm-pwr-on-t-us = <20>; + nvidia,aspm-l0s-entrance-latency-us = <3>; + }; + + pcie_ep@141a0000 { + compatible = "nvidia,tegra194-pcie-ep", "snps,dw-pcie-ep"; + power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX8A>; + reg = <0x00 0x141a0000 0x0 0x00020000 /* appl registers (128K) */ + 0x00 0x3a040000 0x0 0x00040000 /* iATU_DMA reg space (256K) */ + 0x00 0x3a080000 0x0 0x00040000 /* DBI reg space (256K) */ + 0x1c 0x00000000 0x4 0x00000000>; /* Address Space (16G) */ + reg-names = "appl", "atu_dma", "dbi", "addr_space"; + + status = "disabled"; + + num-lanes = <8>; + num-ib-windows = <2>; + num-ob-windows = <8>; + + pinctrl-names = "default"; + pinctrl-0 = <&clkreq_c5_bi_dir_state>; + + clocks = <&bpmp TEGRA194_CLK_PEX1_CORE_5>; + clock-names = "core"; + + resets = <&bpmp TEGRA194_RESET_PEX1_CORE_5_APB>, + <&bpmp TEGRA194_RESET_PEX1_CORE_5>; + reset-names = "apb", "core"; + + interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>; /* controller interrupt */ + interrupt-names = "intr"; + + nvidia,bpmp = <&bpmp 5>; + + nvidia,aspm-cmrt-us = <60>; + nvidia,aspm-pwr-on-t-us = <20>; + nvidia,aspm-l0s-entrance-latency-us = <3>; + }; + sysram@40000000 { compatible = "nvidia,tegra194-sysram", "mmio-sram"; reg = <0x0 0x40000000 0x0 0x50000>;
From: Jon Hunter jonathanh@nvidia.com
[ Upstream commit f9f711efd441ad0d22874be49986d92121862335 ]
If the kernel configuration option CONFIG_PCIE_DW_PLAT_HOST is enabled then this can cause the kernel to incorrectly probe the generic designware PCIe platform driver instead of the Tegra194 designware PCIe driver. This causes a boot failure on Tegra194 because the necessary configuration to access the hardware is not performed.
The order in which the compatible strings are populated in Device-Tree is not relevant in this case, because the kernel will attempt to probe the device as soon as a driver is loaded and if the generic designware PCIe driver is loaded first, then this driver will be probed first. Therefore, to fix this problem, remove the "snps,dw-pcie" string from the compatible string as we never want this driver to be probe on Tegra194.
Fixes: 2602c32f15e7 ("arm64: tegra: Add P2U and PCIe controller nodes to Tegra194 DT") Signed-off-by: Jon Hunter jonathanh@nvidia.com Signed-off-by: Thierry Reding treding@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../devicetree/bindings/pci/nvidia,tegra194-pcie.txt | 2 +- arch/arm64/boot/dts/nvidia/tegra194.dtsi | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/Documentation/devicetree/bindings/pci/nvidia,tegra194-pcie.txt b/Documentation/devicetree/bindings/pci/nvidia,tegra194-pcie.txt index b739f92da58e5..1f90eb39870be 100644 --- a/Documentation/devicetree/bindings/pci/nvidia,tegra194-pcie.txt +++ b/Documentation/devicetree/bindings/pci/nvidia,tegra194-pcie.txt @@ -118,7 +118,7 @@ Tegra194: --------
pcie@14180000 { - compatible = "nvidia,tegra194-pcie", "snps,dw-pcie"; + compatible = "nvidia,tegra194-pcie"; power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX8B>; reg = <0x00 0x14180000 0x0 0x00020000 /* appl registers (128K) */ 0x00 0x38000000 0x0 0x00040000 /* configuration space (256K) */ diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi b/arch/arm64/boot/dts/nvidia/tegra194.dtsi index 57adcbb7352d6..457b815d57f40 100644 --- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi @@ -1151,7 +1151,7 @@ };
pcie@14100000 { - compatible = "nvidia,tegra194-pcie", "snps,dw-pcie"; + compatible = "nvidia,tegra194-pcie"; power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX1A>; reg = <0x00 0x14100000 0x0 0x00020000 /* appl registers (128K) */ 0x00 0x30000000 0x0 0x00040000 /* configuration space (256K) */ @@ -1197,7 +1197,7 @@ };
pcie@14120000 { - compatible = "nvidia,tegra194-pcie", "snps,dw-pcie"; + compatible = "nvidia,tegra194-pcie"; power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX1A>; reg = <0x00 0x14120000 0x0 0x00020000 /* appl registers (128K) */ 0x00 0x32000000 0x0 0x00040000 /* configuration space (256K) */ @@ -1243,7 +1243,7 @@ };
pcie@14140000 { - compatible = "nvidia,tegra194-pcie", "snps,dw-pcie"; + compatible = "nvidia,tegra194-pcie"; power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX1A>; reg = <0x00 0x14140000 0x0 0x00020000 /* appl registers (128K) */ 0x00 0x34000000 0x0 0x00040000 /* configuration space (256K) */ @@ -1289,7 +1289,7 @@ };
pcie@14160000 { - compatible = "nvidia,tegra194-pcie", "snps,dw-pcie"; + compatible = "nvidia,tegra194-pcie"; power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX4A>; reg = <0x00 0x14160000 0x0 0x00020000 /* appl registers (128K) */ 0x00 0x36000000 0x0 0x00040000 /* configuration space (256K) */ @@ -1335,7 +1335,7 @@ };
pcie@14180000 { - compatible = "nvidia,tegra194-pcie", "snps,dw-pcie"; + compatible = "nvidia,tegra194-pcie"; power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX8B>; reg = <0x00 0x14180000 0x0 0x00020000 /* appl registers (128K) */ 0x00 0x38000000 0x0 0x00040000 /* configuration space (256K) */ @@ -1381,7 +1381,7 @@ };
pcie@141a0000 { - compatible = "nvidia,tegra194-pcie", "snps,dw-pcie"; + compatible = "nvidia,tegra194-pcie"; power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX8A>; reg = <0x00 0x141a0000 0x0 0x00020000 /* appl registers (128K) */ 0x00 0x3a000000 0x0 0x00040000 /* configuration space (256K) */
From: Russell King rmk+kernel@armlinux.org.uk
[ Upstream commit 46f94c7818e7ab82758fca74935ef3d454340b4e ]
If the mv88e6xxx DSA driver is built as a module, it causes the ethernet driver to re-probe when it's loaded. This in turn causes the gigabit PHY to be momentarily reset and reprogrammed. However, we attempt to reprogram the PHY immediately after deasserting reset, and the PHY ignores the writes.
This results in the PHY operating in the wrong mode, and the copper link states down.
Set a reset deassert delay of 10ms for the gigabit PHY to avoid this.
Fixes: babc5544c293 ("arm64: dts: clearfog-gt-8k: 1G eth PHY reset signal") Signed-off-by: Russell King rmk+kernel@armlinux.org.uk Acked-by: Baruch Siach baruch@tkos.co.il Signed-off-by: Gregory CLEMENT gregory.clement@bootlin.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts b/arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts index a211a046b2f2f..b90d78a5724b2 100644 --- a/arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts +++ b/arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts @@ -367,6 +367,7 @@ pinctrl-0 = <&cp0_copper_eth_phy_reset>; reset-gpios = <&cp0_gpio2 11 GPIO_ACTIVE_LOW>; reset-assert-us = <10000>; + reset-deassert-us = <10000>; };
switch0: switch0@4 {
From: Lucas Stach l.stach@pengutronix.de
[ Upstream commit e0ea2d11f8a08ba7066ff897e16c5217215d1e68 ]
Currently we wait only until the PGC inverts the isolation setting before disabling the peripheral clocks. This doesn't ensure that the reset is properly propagated through the peripheral devices in the power domain.
Wait until the PGC signals that the power up request is done and wait a bit for resets to propagate before disabling the clocks.
Signed-off-by: Lucas Stach l.stach@pengutronix.de Signed-off-by: Shawn Guo shawnguo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soc/imx/gpc.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-)
diff --git a/drivers/soc/imx/gpc.c b/drivers/soc/imx/gpc.c index 98b9d9a902ae3..90a8b2c0676ff 100644 --- a/drivers/soc/imx/gpc.c +++ b/drivers/soc/imx/gpc.c @@ -87,8 +87,8 @@ static int imx6_pm_domain_power_off(struct generic_pm_domain *genpd) static int imx6_pm_domain_power_on(struct generic_pm_domain *genpd) { struct imx_pm_domain *pd = to_imx_pm_domain(genpd); - int i, ret, sw, sw2iso; - u32 val; + int i, ret; + u32 val, req;
if (pd->supply) { ret = regulator_enable(pd->supply); @@ -107,17 +107,18 @@ static int imx6_pm_domain_power_on(struct generic_pm_domain *genpd) regmap_update_bits(pd->regmap, pd->reg_offs + GPC_PGC_CTRL_OFFS, 0x1, 0x1);
- /* Read ISO and ISO2SW power up delays */ - regmap_read(pd->regmap, pd->reg_offs + GPC_PGC_PUPSCR_OFFS, &val); - sw = val & 0x3f; - sw2iso = (val >> 8) & 0x3f; - /* Request GPC to power up domain */ - val = BIT(pd->cntr_pdn_bit + 1); - regmap_update_bits(pd->regmap, GPC_CNTR, val, val); + req = BIT(pd->cntr_pdn_bit + 1); + regmap_update_bits(pd->regmap, GPC_CNTR, req, req);
- /* Wait ISO + ISO2SW IPG clock cycles */ - udelay(DIV_ROUND_UP(sw + sw2iso, pd->ipg_rate_mhz)); + /* Wait for the PGC to handle the request */ + ret = regmap_read_poll_timeout(pd->regmap, GPC_CNTR, val, !(val & req), + 1, 50); + if (ret) + pr_err("powerup request on domain %s timed out\n", genpd->name); + + /* Wait for reset to propagate through peripherals */ + usleep_range(5, 10);
/* Disable reset clocks for all devices in the domain */ for (i = 0; i < pd->num_clks; i++) @@ -343,6 +344,7 @@ static const struct regmap_config imx_gpc_regmap_config = { .rd_table = &access_table, .wr_table = &access_table, .max_register = 0x2ac, + .fast_io = true, };
static struct generic_pm_domain *imx_gpc_onecell_domains[] = {
From: Kevin Grandemange kevin.grandemange@allegrodvt.com
[ Upstream commit 286c21de32b904131f8cf6a36ce40b8b0c9c5da3 ]
pageno is an int and the PAGE_SHIFT shift is done on an int, overflowing if the memory is bigger than 2G
This can be reproduced using for example a reserved-memory of 4G
reserved-memory { #address-cells = <2>; #size-cells = <2>; ranges;
reserved_dma: buffer@0 { compatible = "shared-dma-pool"; no-map; reg = <0x5 0x00000000 0x1 0x0>; }; };
Signed-off-by: Kevin Grandemange kevin.grandemange@allegrodvt.com Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/dma/coherent.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/kernel/dma/coherent.c b/kernel/dma/coherent.c index 551b0eb7028a3..2a0c4985f38e4 100644 --- a/kernel/dma/coherent.c +++ b/kernel/dma/coherent.c @@ -134,7 +134,7 @@ static void *__dma_alloc_from_coherent(struct device *dev,
spin_lock_irqsave(&mem->spinlock, flags);
- if (unlikely(size > (mem->size << PAGE_SHIFT))) + if (unlikely(size > ((dma_addr_t)mem->size << PAGE_SHIFT))) goto err;
pageno = bitmap_find_free_region(mem->bitmap, mem->size, order); @@ -144,8 +144,9 @@ static void *__dma_alloc_from_coherent(struct device *dev, /* * Memory was found in the coherent area. */ - *dma_handle = dma_get_device_base(dev, mem) + (pageno << PAGE_SHIFT); - ret = mem->virt_base + (pageno << PAGE_SHIFT); + *dma_handle = dma_get_device_base(dev, mem) + + ((dma_addr_t)pageno << PAGE_SHIFT); + ret = mem->virt_base + ((dma_addr_t)pageno << PAGE_SHIFT); spin_unlock_irqrestore(&mem->spinlock, flags); memset(ret, 0, size); return ret; @@ -194,7 +195,7 @@ static int __dma_release_from_coherent(struct dma_coherent_mem *mem, int order, void *vaddr) { if (mem && vaddr >= mem->virt_base && vaddr < - (mem->virt_base + (mem->size << PAGE_SHIFT))) { + (mem->virt_base + ((dma_addr_t)mem->size << PAGE_SHIFT))) { int page = (vaddr - mem->virt_base) >> PAGE_SHIFT; unsigned long flags;
@@ -238,10 +239,10 @@ static int __dma_mmap_from_coherent(struct dma_coherent_mem *mem, struct vm_area_struct *vma, void *vaddr, size_t size, int *ret) { if (mem && vaddr >= mem->virt_base && vaddr + size <= - (mem->virt_base + (mem->size << PAGE_SHIFT))) { + (mem->virt_base + ((dma_addr_t)mem->size << PAGE_SHIFT))) { unsigned long off = vma->vm_pgoff; int start = (vaddr - mem->virt_base) >> PAGE_SHIFT; - int user_count = vma_pages(vma); + unsigned long user_count = vma_pages(vma); int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
*ret = -ENXIO;
From: Alexandre Belloni alexandre.belloni@bootlin.com
[ Upstream commit 9cf4789e6e4673d0b2c96fa6bb0c35e81b43111a ]
The RTC IRQ is requested before the struct rtc_device is allocated, this may lead to a NULL pointer dereference in the IRQ handler.
To fix this issue, allocating the rtc_device struct before requesting the RTC IRQ using devm_rtc_allocate_device, and use rtc_register_device to register the RTC device.
Also remove the unnecessary error message as the core already prints the info.
Link: https://lore.kernel.org/r/20200311223956.51352-1-alexandre.belloni@bootlin.c... Signed-off-by: Alexandre Belloni alexandre.belloni@bootlin.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/rtc/rtc-88pm860x.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/rtc/rtc-88pm860x.c b/drivers/rtc/rtc-88pm860x.c index 4743b16a8d849..1526402e126b2 100644 --- a/drivers/rtc/rtc-88pm860x.c +++ b/drivers/rtc/rtc-88pm860x.c @@ -336,6 +336,10 @@ static int pm860x_rtc_probe(struct platform_device *pdev) info->dev = &pdev->dev; dev_set_drvdata(&pdev->dev, info);
+ info->rtc_dev = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(info->rtc_dev)) + return PTR_ERR(info->rtc_dev); + ret = devm_request_threaded_irq(&pdev->dev, info->irq, NULL, rtc_update_handler, IRQF_ONESHOT, "rtc", info); @@ -377,13 +381,11 @@ static int pm860x_rtc_probe(struct platform_device *pdev) } }
- info->rtc_dev = devm_rtc_device_register(&pdev->dev, "88pm860x-rtc", - &pm860x_rtc_ops, THIS_MODULE); - ret = PTR_ERR(info->rtc_dev); - if (IS_ERR(info->rtc_dev)) { - dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret); + info->rtc_dev->ops = &pm860x_rtc_ops; + + ret = rtc_register_device(info->rtc_dev); + if (ret) return ret; - }
/* * enable internal XO instead of internal 3.25MHz clock since it can
From: Trond Myklebust trond.myklebust@hammerspace.com
[ Upstream commit 1d179d6bd67369a52edea8562154b31ee20be1cc ]
If we're creating a nfs_open_context() for a specific file pointer, we must use the cred assigned to that file.
Fixes: a52458b48af1 ("NFS/NFSD/SUNRPC: replace generic creds with 'struct cred'.") Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/inode.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 2a03bfeec10a4..3802c88e83720 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -959,16 +959,16 @@ struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, struct file *filp) { struct nfs_open_context *ctx; - const struct cred *cred = get_current_cred();
ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); - if (!ctx) { - put_cred(cred); + if (!ctx) return ERR_PTR(-ENOMEM); - } nfs_sb_active(dentry->d_sb); ctx->dentry = dget(dentry); - ctx->cred = cred; + if (filp) + ctx->cred = get_cred(filp->f_cred); + else + ctx->cred = get_current_cred(); ctx->ll_cred = NULL; ctx->state = NULL; ctx->mode = f_mode;
From: Trond Myklebust trond.myklebust@hammerspace.com
[ Upstream commit d911c57a19551c6bef116a3b55c6b089901aacb0 ]
Make sure to test the stateid for validity so that we catch instances where the server may have been reusing stateids in nfs_layout_find_inode_by_stateid().
Fixes: 7b410d9ce460 ("pNFS: Delay getting the layout header in CB_LAYOUTRECALL handlers") Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/callback_proc.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index f39924ba050b1..fc775b0b5194f 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c @@ -130,6 +130,8 @@ static struct inode *nfs_layout_find_inode_by_stateid(struct nfs_client *clp,
list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) { list_for_each_entry(lo, &server->layouts, plh_layouts) { + if (!pnfs_layout_is_valid(lo)) + continue; if (stateid != NULL && !nfs4_stateid_match_other(stateid, &lo->plh_stateid)) continue;
From: Murphy Zhou jencce.kernel@gmail.com
[ Upstream commit f5fdf1243fb750598b46305dd03c553949cfa14f ]
This fixes xfstests generic/356 failure on NFSv4.2.
Signed-off-by: Murphy Zhou jencce.kernel@gmail.com Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/nfs4file.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c index 54f1c1f626fc5..fb55c04cdc6bd 100644 --- a/fs/nfs/nfs4file.c +++ b/fs/nfs/nfs4file.c @@ -210,6 +210,9 @@ static loff_t nfs42_remap_file_range(struct file *src_file, loff_t src_off, if (remap_flags & ~REMAP_FILE_ADVISORY) return -EINVAL;
+ if (IS_SWAPFILE(dst_inode) || IS_SWAPFILE(src_inode)) + return -ETXTBSY; + /* check alignment w.r.t. clone_blksize */ ret = -EINVAL; if (bs) {
From: Johan Jonker jbx6244@gmail.com
[ Upstream commit 1a7e99599dffd836fcb720cdc0eaf3cd43d7af4a ]
A test with the command below gives this error:
arch/arm/boot/dts/rk3188-bqedison2qc.dt.yaml: lvds-encoder: 'ports' is a required property
Fix error by adding a ports wrapper for port@0 and port@1 inside the 'lvds-encoder' node for rk3188-bqedison2qc.
make ARCH=arm dtbs_check DT_SCHEMA_FILES=Documentation/devicetree/bindings/display/ bridge/lvds-codec.yaml
Signed-off-by: Johan Jonker jbx6244@gmail.com Link: https://lore.kernel.org/r/20200316174647.5598-1-jbx6244@gmail.com Signed-off-by: Heiko Stuebner heiko@sntech.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/rk3188-bqedison2qc.dts | 27 ++++++++++++++---------- 1 file changed, 16 insertions(+), 11 deletions(-)
diff --git a/arch/arm/boot/dts/rk3188-bqedison2qc.dts b/arch/arm/boot/dts/rk3188-bqedison2qc.dts index 8afb2fd5d9f1b..66a0ff196eb1f 100644 --- a/arch/arm/boot/dts/rk3188-bqedison2qc.dts +++ b/arch/arm/boot/dts/rk3188-bqedison2qc.dts @@ -58,20 +58,25 @@
lvds-encoder { compatible = "ti,sn75lvds83", "lvds-encoder"; - #address-cells = <1>; - #size-cells = <0>;
- port@0 { - reg = <0>; - lvds_in_vop0: endpoint { - remote-endpoint = <&vop0_out_lvds>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + lvds_in_vop0: endpoint { + remote-endpoint = <&vop0_out_lvds>; + }; }; - };
- port@1 { - reg = <1>; - lvds_out_panel: endpoint { - remote-endpoint = <&panel_in_lvds>; + port@1 { + reg = <1>; + + lvds_out_panel: endpoint { + remote-endpoint = <&panel_in_lvds>; + }; }; }; };
From: Michael Roth mdroth@linux.vnet.ibm.com
[ Upstream commit 1f50cc1705350a4697923203fedd7d8fb1087fe2 ]
The h_cede_tm kvm-unit-test currently fails when run inside an L1 guest via the guest/nested hypervisor.
./run-tests.sh -v ... TESTNAME=h_cede_tm TIMEOUT=90s ACCEL= ./powerpc/run powerpc/tm.elf -smp 2,threads=2 -machine cap-htm=on -append "h_cede_tm" FAIL h_cede_tm (2 tests, 1 unexpected failures)
While the test relates to transactional memory instructions, the actual failure is due to the return code of the H_CEDE hypercall, which is reported as 224 instead of 0. This happens even when no TM instructions are issued.
224 is the value placed in r3 to execute a hypercall for H_CEDE, and r3 is where the caller expects the return code to be placed upon return.
In the case of guest running under a nested hypervisor, issuing H_CEDE causes a return from H_ENTER_NESTED. In this case H_CEDE is specially-handled immediately rather than later in kvmppc_pseries_do_hcall() as with most other hcalls, but we forget to set the return code for the caller, hence why kvm-unit-test sees the 224 return code and reports an error.
Guest kernels generally don't check the return value of H_CEDE, so that likely explains why this hasn't caused issues outside of kvm-unit-tests so far.
Fix this by setting r3 to 0 after we finish processing the H_CEDE.
RHBZ: 1778556
Fixes: 4bad77799fed ("KVM: PPC: Book3S HV: Handle hypercalls correctly when nested") Cc: linuxppc-dev@ozlabs.org Cc: David Gibson david@gibson.dropbear.id.au Cc: Paul Mackerras paulus@ozlabs.org Signed-off-by: Michael Roth mdroth@linux.vnet.ibm.com Reviewed-by: David Gibson david@gibson.dropbear.id.au Signed-off-by: Paul Mackerras paulus@ozlabs.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/kvm/book3s_hv.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 36abbe3c346df..e2183fed947d4 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -3623,6 +3623,7 @@ int kvmhv_p9_guest_entry(struct kvm_vcpu *vcpu, u64 time_limit, if (trap == BOOK3S_INTERRUPT_SYSCALL && !vcpu->arch.nested && kvmppc_get_gpr(vcpu, 3) == H_CEDE) { kvmppc_nested_cede(vcpu); + kvmppc_set_gpr(vcpu, 3, 0); trap = 0; } } else {
From: Chao Yu yuchao0@huawei.com
[ Upstream commit a9117eca1de6b738e713d2142126db2cfbf6fb36 ]
Previously, 'norecovery' mount option will be shown as 'disable_roll_forward', fix to show original option name correctly.
Signed-off-by: Chao Yu yuchao0@huawei.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/f2fs.h | 1 + fs/f2fs/super.c | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 1a8b68ceaa62f..3edde3d6d089d 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -100,6 +100,7 @@ extern const char *f2fs_fault_name[FAULT_MAX]; #define F2FS_MOUNT_INLINE_XATTR_SIZE 0x00800000 #define F2FS_MOUNT_RESERVE_ROOT 0x01000000 #define F2FS_MOUNT_DISABLE_CHECKPOINT 0x02000000 +#define F2FS_MOUNT_NORECOVERY 0x04000000
#define F2FS_OPTION(sbi) ((sbi)->mount_opt) #define clear_opt(sbi, option) (F2FS_OPTION(sbi).opt &= ~F2FS_MOUNT_##option) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 28441f4971b8d..94caf26901e0b 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -439,7 +439,7 @@ static int parse_options(struct super_block *sb, char *options) break; case Opt_norecovery: /* this option mounts f2fs with ro */ - set_opt(sbi, DISABLE_ROLL_FORWARD); + set_opt(sbi, NORECOVERY); if (!f2fs_readonly(sb)) return -EINVAL; break; @@ -1348,6 +1348,8 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root) } if (test_opt(sbi, DISABLE_ROLL_FORWARD)) seq_puts(seq, ",disable_roll_forward"); + if (test_opt(sbi, NORECOVERY)) + seq_puts(seq, ",norecovery"); if (test_opt(sbi, DISCARD)) seq_puts(seq, ",discard"); else @@ -3488,7 +3490,8 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) goto reset_checkpoint;
/* recover fsynced data */ - if (!test_opt(sbi, DISABLE_ROLL_FORWARD)) { + if (!test_opt(sbi, DISABLE_ROLL_FORWARD) && + !test_opt(sbi, NORECOVERY)) { /* * mount should be failed, when device has readonly mode, and * previous checkpoint was not done by clean system shutdown.
From: Kunihiko Hayashi hayashi.kunihiko@socionext.com
[ Upstream commit 9376fa634afc207a3ce99e0957e04948c34d6510 ]
Pro5 SoC has same scheme of USB3 ss-phy as Pro4, so the data for Pro5 is equivalent to Pro4.
Signed-off-by: Kunihiko Hayashi hayashi.kunihiko@socionext.com Signed-off-by: Kishon Vijay Abraham I kishon@ti.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/phy/socionext/phy-uniphier-usb3ss.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/phy/socionext/phy-uniphier-usb3ss.c b/drivers/phy/socionext/phy-uniphier-usb3ss.c index ec231e40ef2ac..a7577e316baf5 100644 --- a/drivers/phy/socionext/phy-uniphier-usb3ss.c +++ b/drivers/phy/socionext/phy-uniphier-usb3ss.c @@ -314,6 +314,10 @@ static const struct of_device_id uniphier_u3ssphy_match[] = { .compatible = "socionext,uniphier-pro4-usb3-ssphy", .data = &uniphier_pro4_data, }, + { + .compatible = "socionext,uniphier-pro5-usb3-ssphy", + .data = &uniphier_pro4_data, + }, { .compatible = "socionext,uniphier-pxs2-usb3-ssphy", .data = &uniphier_pxs2_data,
From: Misono Tomohiro misono.tomohiro@jp.fujitsu.com
[ Upstream commit 8605cf0e852af3b2c771c18417499dc4ceed03d5 ]
When dreq is allocated by nfs_direct_req_alloc(), dreq->kref is initialized to 2. Therefore we need to call nfs_direct_req_release() twice to release the allocated dreq. Usually it is called in nfs_file_direct_{read, write}() and nfs_direct_complete().
However, current code only calls nfs_direct_req_relese() once if nfs_get_lock_context() fails in nfs_file_direct_{read, write}(). So, that case would result in memory leak.
Fix this by adding the missing call.
Signed-off-by: Misono Tomohiro misono.tomohiro@jp.fujitsu.com Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/direct.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 29f00da8a0b7f..6b0bf4ebd8124 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -571,6 +571,7 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, struct iov_iter *iter) l_ctx = nfs_get_lock_context(dreq->ctx); if (IS_ERR(l_ctx)) { result = PTR_ERR(l_ctx); + nfs_direct_req_release(dreq); goto out_release; } dreq->l_ctx = l_ctx; @@ -989,6 +990,7 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter) l_ctx = nfs_get_lock_context(dreq->ctx); if (IS_ERR(l_ctx)) { result = PTR_ERR(l_ctx); + nfs_direct_req_release(dreq); goto out_release; } dreq->l_ctx = l_ctx;
From: Sahitya Tummala stummala@codeaurora.org
[ Upstream commit 682756827501dc52593bf490f2d437c65ec9efcb ]
Even though online resize is successfully done, a SPO immediately after resize, still causes below error in the next mount.
[ 11.294650] F2FS-fs (sda8): Wrong user_block_count: 2233856 [ 11.300272] F2FS-fs (sda8): Failed to get valid F2FS checkpoint
This is because after FS metadata is updated in update_fs_metadata() if the SBI_IS_DIRTY is not dirty, then CP will not be done to reflect the new user_block_count.
Signed-off-by: Sahitya Tummala stummala@codeaurora.org Reviewed-by: Chao Yu yuchao0@huawei.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/gc.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index 5877bd7296896..e611d768efde3 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -1532,11 +1532,17 @@ int f2fs_resize_fs(struct f2fs_sb_info *sbi, __u64 block_count) goto out; }
+ mutex_lock(&sbi->cp_mutex); update_fs_metadata(sbi, -secs); clear_sbi_flag(sbi, SBI_IS_RESIZEFS); + set_sbi_flag(sbi, SBI_IS_DIRTY); + mutex_unlock(&sbi->cp_mutex); + err = f2fs_sync_fs(sbi->sb, 1); if (err) { + mutex_lock(&sbi->cp_mutex); update_fs_metadata(sbi, secs); + mutex_unlock(&sbi->cp_mutex); update_sb_metadata(sbi, secs); f2fs_commit_super(sbi, false); }
From: Sahitya Tummala stummala@codeaurora.org
[ Upstream commit c84ef3c5e65ccf99a7a91a4d731ebb5d6331a178 ]
Add and set a new CP flag CP_RESIZEFS_FLAG during online resize FS to help fsck fix the metadata mismatch that may happen due to SPO during resize, where SB got updated but CP data couldn't be written yet.
fsck errors - Info: CKPT version = 6ed7bccb Wrong user_block_count(2233856) [f2fs_do_mount:3365] Checkpoint is polluted
Signed-off-by: Sahitya Tummala stummala@codeaurora.org Reviewed-by: Chao Yu yuchao0@huawei.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/checkpoint.c | 8 ++++++-- include/linux/f2fs_fs.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index 410f5c2c6ef17..a28ffecc0f95a 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -1301,10 +1301,14 @@ static void update_ckpt_flags(struct f2fs_sb_info *sbi, struct cp_control *cpc) else __clear_ckpt_flags(ckpt, CP_ORPHAN_PRESENT_FLAG);
- if (is_sbi_flag_set(sbi, SBI_NEED_FSCK) || - is_sbi_flag_set(sbi, SBI_IS_RESIZEFS)) + if (is_sbi_flag_set(sbi, SBI_NEED_FSCK)) __set_ckpt_flags(ckpt, CP_FSCK_FLAG);
+ if (is_sbi_flag_set(sbi, SBI_IS_RESIZEFS)) + __set_ckpt_flags(ckpt, CP_RESIZEFS_FLAG); + else + __clear_ckpt_flags(ckpt, CP_RESIZEFS_FLAG); + if (is_sbi_flag_set(sbi, SBI_CP_DISABLED)) __set_ckpt_flags(ckpt, CP_DISABLED_FLAG); else diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h index 2847389960281..6bb6f718a1023 100644 --- a/include/linux/f2fs_fs.h +++ b/include/linux/f2fs_fs.h @@ -124,6 +124,7 @@ struct f2fs_super_block { /* * For checkpoint */ +#define CP_RESIZEFS_FLAG 0x00004000 #define CP_DISABLED_QUICK_FLAG 0x00002000 #define CP_DISABLED_FLAG 0x00001000 #define CP_QUOTA_NEED_FSCK_FLAG 0x00000800
From: Alexander Gordeev agordeev@linux.ibm.com
[ Upstream commit 872f27103874a73783aeff2aac2b41a489f67d7c ]
/proc/cpuinfo should not print information about CPU 0 when it is offline.
Fixes: 281eaa8cb67c ("s390/cpuinfo: simplify locking and skip offline cpus early") Signed-off-by: Alexander Gordeev agordeev@linux.ibm.com Reviewed-by: Heiko Carstens heiko.carstens@de.ibm.com [heiko.carstens@de.ibm.com: shortened commit message] Signed-off-by: Heiko Carstens heiko.carstens@de.ibm.com Signed-off-by: Vasily Gorbik gor@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/s390/kernel/processor.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/arch/s390/kernel/processor.c b/arch/s390/kernel/processor.c index 6ebc2117c66c7..91b9b3f73de6e 100644 --- a/arch/s390/kernel/processor.c +++ b/arch/s390/kernel/processor.c @@ -165,8 +165,9 @@ static void show_cpu_mhz(struct seq_file *m, unsigned long n) static int show_cpuinfo(struct seq_file *m, void *v) { unsigned long n = (unsigned long) v - 1; + unsigned long first = cpumask_first(cpu_online_mask);
- if (!n) + if (n == first) show_cpu_summary(m, v); if (!machine_has_cpu_mhz) return 0; @@ -179,6 +180,8 @@ static inline void *c_update(loff_t *pos) { if (*pos) *pos = cpumask_next(*pos - 1, cpu_online_mask); + else + *pos = cpumask_first(cpu_online_mask); return *pos < nr_cpu_ids ? (void *)*pos + 1 : NULL; }
From: Domenico Andreoli domenico.andreoli@linux.com
[ Upstream commit 56939e014a6c212b317414faa307029e2e80c3b9 ]
It turns out that there is one use case for programs being able to write to swap devices, and that is the userspace hibernation code.
Quick fix: disable the S_SWAPFILE check if hibernation is configured.
Fixes: dc617f29dbe5 ("vfs: don't allow writes to swap files") Reported-by: Domenico Andreoli domenico.andreoli@linux.com Reported-by: Marian Klein mkleinsoft@gmail.com Signed-off-by: Domenico Andreoli domenico.andreoli@linux.com Reviewed-by: Darrick J. Wong darrick.wong@oracle.com Signed-off-by: Darrick J. Wong darrick.wong@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/block_dev.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/block_dev.c b/fs/block_dev.c index d612468ee66bf..34644ce4b5025 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -34,6 +34,7 @@ #include <linux/task_io_accounting_ops.h> #include <linux/falloc.h> #include <linux/uaccess.h> +#include <linux/suspend.h> #include "internal.h"
struct bdev_inode { @@ -1975,7 +1976,8 @@ ssize_t blkdev_write_iter(struct kiocb *iocb, struct iov_iter *from) if (bdev_read_only(I_BDEV(bd_inode))) return -EPERM;
- if (IS_SWAPFILE(bd_inode)) + /* uswsusp needs write permission to the swap */ + if (IS_SWAPFILE(bd_inode) && !hibernation_available()) return -ETXTBSY;
if (!iov_iter_count(from))
Hi Everyone I am glad the official patch made it into 5.4 finally. Well done everyone. Now distros should pick it up quickly , especially ubuntu 20.04 Long Term Support. Your most faithful fan Marian
On Wed, 22 Apr 2020 at 11:18, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
From: Domenico Andreoli domenico.andreoli@linux.com
[ Upstream commit 56939e014a6c212b317414faa307029e2e80c3b9 ]
It turns out that there is one use case for programs being able to write to swap devices, and that is the userspace hibernation code.
Quick fix: disable the S_SWAPFILE check if hibernation is configured.
Fixes: dc617f29dbe5 ("vfs: don't allow writes to swap files") Reported-by: Domenico Andreoli domenico.andreoli@linux.com Reported-by: Marian Klein mkleinsoft@gmail.com Signed-off-by: Domenico Andreoli domenico.andreoli@linux.com Reviewed-by: Darrick J. Wong darrick.wong@oracle.com Signed-off-by: Darrick J. Wong darrick.wong@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org
fs/block_dev.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/block_dev.c b/fs/block_dev.c index d612468ee66bf..34644ce4b5025 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -34,6 +34,7 @@ #include <linux/task_io_accounting_ops.h> #include <linux/falloc.h> #include <linux/uaccess.h> +#include <linux/suspend.h> #include "internal.h"
struct bdev_inode { @@ -1975,7 +1976,8 @@ ssize_t blkdev_write_iter(struct kiocb *iocb, struct iov_iter *from) if (bdev_read_only(I_BDEV(bd_inode))) return -EPERM;
if (IS_SWAPFILE(bd_inode))
/* uswsusp needs write permission to the swap */
if (IS_SWAPFILE(bd_inode) && !hibernation_available()) return -ETXTBSY; if (!iov_iter_count(from))
-- 2.20.1
From: Madhuparna Bhowmik madhuparnabhowmik10@gmail.com
[ Upstream commit 29566c9c773456467933ee22bbca1c2b72a3506c ]
The space_info list is normally RCU protected and should be traversed with rcu_read_lock held. There's a warning
[29.104756] WARNING: suspicious RCU usage [29.105046] 5.6.0-rc4-next-20200305 #1 Not tainted [29.105231] ----------------------------- [29.105401] fs/btrfs/block-group.c:2011 RCU-list traversed in non-reader section!!
pointing out that the locking is missing in btrfs_read_block_groups. However this is not necessary as the list traversal happens at mount time when there's no other thread potentially accessing the list.
To fix the warning and for consistency let's add the RCU lock/unlock, the code won't be affected much as it's doing some lightweight operations.
Reported-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Madhuparna Bhowmik madhuparnabhowmik10@gmail.com Reviewed-by: David Sterba dsterba@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/btrfs/block-group.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c index 7dcfa7d7632a1..95330f40f998c 100644 --- a/fs/btrfs/block-group.c +++ b/fs/btrfs/block-group.c @@ -1829,6 +1829,7 @@ int btrfs_read_block_groups(struct btrfs_fs_info *info) } }
+ rcu_read_lock(); list_for_each_entry_rcu(space_info, &info->space_info, list) { if (!(btrfs_get_alloc_profile(info, space_info->flags) & (BTRFS_BLOCK_GROUP_RAID10 | @@ -1849,6 +1850,7 @@ int btrfs_read_block_groups(struct btrfs_fs_info *info) list) inc_block_group_ro(cache, 1); } + rcu_read_unlock();
btrfs_init_global_block_rsv(info); ret = check_chunk_block_group_mappings(info);
From: Alexey Kardashevskiy aik@ozlabs.ru
[ Upstream commit 74bb84e5117146fa73eb9d01305975c53022b3c3 ]
The "os-term" RTAS calls has one argument with a message address of OS termination cause. rtas_os_term() already passes it but the recently added prom_init's version of that missed it; it also does not fill args correctly.
This passes the message address and initializes the number of arguments.
Fixes: 6a9c930bd775 ("powerpc/prom_init: Add the ESM call to prom_init") Signed-off-by: Alexey Kardashevskiy aik@ozlabs.ru Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20200312074404.87293-1-aik@ozlabs.ru Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/kernel/prom_init.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index eba9d4ee4baf6..689664cd4e79b 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -1761,6 +1761,9 @@ static void __init prom_rtas_os_term(char *str) if (token == 0) prom_panic("Could not get token for ibm,os-term\n"); os_term_args.token = cpu_to_be32(token); + os_term_args.nargs = cpu_to_be32(1); + os_term_args.nret = cpu_to_be32(1); + os_term_args.args[0] = cpu_to_be32(__pa(str)); prom_rtas_hcall((uint64_t)&os_term_args); } #endif /* CONFIG_PPC_SVM */
From: Nathan Chancellor natechancellor@gmail.com
[ Upstream commit af6cf95c4d003fccd6c2ecc99a598fb854b537e7 ]
When building ppc64 defconfig, Clang errors (trimmed for brevity):
arch/powerpc/platforms/maple/setup.c:365:1: error: attribute declaration must precede definition [-Werror,-Wignored-attributes] machine_device_initcall(maple, maple_cpc925_edac_setup); ^
machine_device_initcall expands to __define_machine_initcall, which in turn has the macro machine_is used in it, which declares mach_##name with an __attribute__((weak)). define_machine actually defines mach_##name, which in this file happens before the declaration, hence the warning.
To fix this, move define_machine after machine_device_initcall so that the declaration occurs before the definition, which matches how machine_device_initcall and define_machine work throughout arch/powerpc.
While we're here, remove some spaces before tabs.
Fixes: 8f101a051ef0 ("edac: cpc925 MC platform device setup") Reported-by: Nick Desaulniers ndesaulniers@google.com Suggested-by: Ilie Halip ilie.halip@gmail.com Signed-off-by: Nathan Chancellor natechancellor@gmail.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20200323222729.15365-1-natechancellor@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/platforms/maple/setup.c | 34 ++++++++++++++-------------- 1 file changed, 17 insertions(+), 17 deletions(-)
diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c index 9cd6f3e1000b3..09a0594350b69 100644 --- a/arch/powerpc/platforms/maple/setup.c +++ b/arch/powerpc/platforms/maple/setup.c @@ -294,23 +294,6 @@ static int __init maple_probe(void) return 1; }
-define_machine(maple) { - .name = "Maple", - .probe = maple_probe, - .setup_arch = maple_setup_arch, - .init_IRQ = maple_init_IRQ, - .pci_irq_fixup = maple_pci_irq_fixup, - .pci_get_legacy_ide_irq = maple_pci_get_legacy_ide_irq, - .restart = maple_restart, - .halt = maple_halt, - .get_boot_time = maple_get_boot_time, - .set_rtc_time = maple_set_rtc_time, - .get_rtc_time = maple_get_rtc_time, - .calibrate_decr = generic_calibrate_decr, - .progress = maple_progress, - .power_save = power4_idle, -}; - #ifdef CONFIG_EDAC /* * Register a platform device for CPC925 memory controller on @@ -367,3 +350,20 @@ static int __init maple_cpc925_edac_setup(void) } machine_device_initcall(maple, maple_cpc925_edac_setup); #endif + +define_machine(maple) { + .name = "Maple", + .probe = maple_probe, + .setup_arch = maple_setup_arch, + .init_IRQ = maple_init_IRQ, + .pci_irq_fixup = maple_pci_irq_fixup, + .pci_get_legacy_ide_irq = maple_pci_get_legacy_ide_irq, + .restart = maple_restart, + .halt = maple_halt, + .get_boot_time = maple_get_boot_time, + .set_rtc_time = maple_set_rtc_time, + .get_rtc_time = maple_get_rtc_time, + .calibrate_decr = generic_calibrate_decr, + .progress = maple_progress, + .power_save = power4_idle, +};
From: Thomas Richter tmricht@linux.ibm.com
[ Upstream commit 4141b6a5e9f171325effc36a22eb92bf961e7a5c ]
When perf record -e SF_CYCLES_BASIC_DIAG runs with very high frequency, the samples arrive faster than the perf process can save them to file. Eventually, for longer running processes, this leads to the siutation where the trace buffers allocated by perf slowly fills up. At one point the auxiliary trace buffer is full and the CPU Measurement sampling facility is turned off. Furthermore a warning is printed to the kernel log buffer:
cpum_sf: The AUX buffer with 0 pages for the diagnostic-sampling mode is full
The number of allocated pages for the auxiliary trace buffer is shown as zero pages. That is wrong.
Fix this by saving the number of allocated pages before entering the work loop in the interrupt handler. When the interrupt handler processes the samples, it may detect the buffer full condition and stop sampling, reducing the buffer size to zero. Print the correct value in the error message:
cpum_sf: The AUX buffer with 256 pages for the diagnostic-sampling mode is full
Signed-off-by: Thomas Richter tmricht@linux.ibm.com Signed-off-by: Vasily Gorbik gor@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/s390/kernel/perf_cpum_sf.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/s390/kernel/perf_cpum_sf.c b/arch/s390/kernel/perf_cpum_sf.c index fdb8083e7870c..229e1e2f8253a 100644 --- a/arch/s390/kernel/perf_cpum_sf.c +++ b/arch/s390/kernel/perf_cpum_sf.c @@ -1589,6 +1589,7 @@ static void hw_collect_aux(struct cpu_hw_sf *cpuhw) perf_aux_output_end(handle, size); num_sdb = aux->sfb.num_sdb;
+ num_sdb = aux->sfb.num_sdb; while (!done) { /* Get an output handle */ aux = perf_aux_output_begin(handle, cpuhw->event);
From: Eric Sandeen sandeen@redhat.com
[ Upstream commit c96e2b8564adfb8ac14469ebc51ddc1bfecb3ae2 ]
Under some circumstances we may encounter a filesystem error on a read-only block device, and if we try to save the error info to the superblock and commit it, we'll wind up with a noisy error and backtrace, i.e.:
[ 3337.146838] EXT4-fs error (device pmem1p2): ext4_get_journal_inode:4634: comm mount: inode #0: comm mount: iget: illegal inode # ------------[ cut here ]------------ generic_make_request: Trying to write to read-only block-device pmem1p2 (partno 2) WARNING: CPU: 107 PID: 115347 at block/blk-core.c:788 generic_make_request_checks+0x6b4/0x7d0 ...
To avoid this, commit the error info in the superblock only if the block device is writable.
Reported-by: Ritesh Harjani riteshh@linux.ibm.com Signed-off-by: Eric Sandeen sandeen@redhat.com Reviewed-by: Andreas Dilger adilger@dilger.ca Link: https://lore.kernel.org/r/4b6e774d-cc00-3469-7abb-108eb151071a@sandeen.net Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Sasha Levin sashal@kernel.org --- fs/ext4/super.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 8f7a46d3abffb..53d4c67a20df9 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -389,7 +389,8 @@ static void save_error_info(struct super_block *sb, const char *func, unsigned int line) { __save_error_info(sb, func, line); - ext4_commit_super(sb, 1); + if (!bdev_read_only(sb->s_bdev)) + ext4_commit_super(sb, 1); }
/*
From: Gabriel Krisman Bertazi krisman@collabora.com
[ Upstream commit 6e682d53fc1ef73a169e2a5300326cb23abb32ee ]
On the hypervisor side, when completing commands and the pipe is full, we retry writing only the entries that failed, by offsetting io_req_buffer, but we don't reduce the number of bytes written, which can cause a buffer overrun of io_req_buffer, and write garbage to the pipe.
Cc: Martyn Welch martyn.welch@collabora.com Signed-off-by: Gabriel Krisman Bertazi krisman@collabora.com Signed-off-by: Richard Weinberger richard@nod.at Signed-off-by: Sasha Levin sashal@kernel.org --- arch/um/drivers/ubd_kern.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 6627d7c30f370..0f5d0a699a49b 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -1606,7 +1606,9 @@ int io_thread(void *arg) written = 0;
do { - res = os_write_file(kernel_fd, ((char *) io_req_buffer) + written, n); + res = os_write_file(kernel_fd, + ((char *) io_req_buffer) + written, + n - written); if (res >= 0) { written += res; }
From: Long Li longli@microsoft.com
[ Upstream commit 3946d0d04bb360acca72db5efe9ae8440012d9dc ]
When encryption is used, smb2_transform_hdr is defined on the stack and is passed to the transport. This doesn't work with RDMA as the buffer needs to be DMA'ed.
Fix it by using kmalloc.
Signed-off-by: Long Li longli@microsoft.com Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/cifs/transport.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-)
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index e67a43fd037c9..fe1552cc8a0a7 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -466,7 +466,7 @@ smb_send_rqst(struct TCP_Server_Info *server, int num_rqst, struct smb_rqst *rqst, int flags) { struct kvec iov; - struct smb2_transform_hdr tr_hdr; + struct smb2_transform_hdr *tr_hdr; struct smb_rqst cur_rqst[MAX_COMPOUND]; int rc;
@@ -476,28 +476,34 @@ smb_send_rqst(struct TCP_Server_Info *server, int num_rqst, if (num_rqst > MAX_COMPOUND - 1) return -ENOMEM;
- memset(&cur_rqst[0], 0, sizeof(cur_rqst)); - memset(&iov, 0, sizeof(iov)); - memset(&tr_hdr, 0, sizeof(tr_hdr)); - - iov.iov_base = &tr_hdr; - iov.iov_len = sizeof(tr_hdr); - cur_rqst[0].rq_iov = &iov; - cur_rqst[0].rq_nvec = 1; - if (!server->ops->init_transform_rq) { cifs_server_dbg(VFS, "Encryption requested but transform " "callback is missing\n"); return -EIO; }
+ tr_hdr = kmalloc(sizeof(*tr_hdr), GFP_NOFS); + if (!tr_hdr) + return -ENOMEM; + + memset(&cur_rqst[0], 0, sizeof(cur_rqst)); + memset(&iov, 0, sizeof(iov)); + memset(tr_hdr, 0, sizeof(*tr_hdr)); + + iov.iov_base = tr_hdr; + iov.iov_len = sizeof(*tr_hdr); + cur_rqst[0].rq_iov = &iov; + cur_rqst[0].rq_nvec = 1; + rc = server->ops->init_transform_rq(server, num_rqst + 1, &cur_rqst[0], rqst); if (rc) - return rc; + goto out;
rc = __smb_send_rqst(server, num_rqst + 1, &cur_rqst[0]); smb3_free_compound_rqst(num_rqst, &cur_rqst[1]); +out: + kfree(tr_hdr); return rc; }
From: Christophe Leroy christophe.leroy@c-s.fr
[ Upstream commit bb297bb2de517e41199185021f043bbc5d75b377 ]
When CONFIG_HUGETLB_PAGE is set but not CONFIG_HUGETLBFS, the following build failure is encoutered:
In file included from arch/powerpc/mm/fault.c:33:0: include/linux/hugetlb.h: In function 'hstate_inode': include/linux/hugetlb.h:477:9: error: implicit declaration of function 'HUGETLBFS_SB' [-Werror=implicit-function-declaration] return HUGETLBFS_SB(i->i_sb)->hstate; ^ include/linux/hugetlb.h:477:30: error: invalid type argument of '->' (have 'int') return HUGETLBFS_SB(i->i_sb)->hstate; ^
Gate hstate_inode() with CONFIG_HUGETLBFS instead of CONFIG_HUGETLB_PAGE.
Fixes: a137e1cc6d6e ("hugetlbfs: per mount huge page sizes") Reported-by: kbuild test robot lkp@intel.com Signed-off-by: Christophe Leroy christophe.leroy@c-s.fr Signed-off-by: Andrew Morton akpm@linux-foundation.org Reviewed-by: Mike Kravetz mike.kravetz@oracle.com Cc: Baoquan He bhe@redhat.com Cc: Nishanth Aravamudan nacc@us.ibm.com Cc: Nick Piggin npiggin@suse.de Cc: Adam Litke agl@us.ibm.com Cc: Andi Kleen ak@suse.de Link: http://lkml.kernel.org/r/7e8c3a3c9a587b9cd8a2f146df32a421b961f3a2.1584432148... Link: https://patchwork.ozlabs.org/patch/1255548/#2386036 Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/hugetlb.h | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-)
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 53fc34f930d08..8a03f392f3680 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -298,7 +298,10 @@ static inline bool is_file_hugepages(struct file *file) return is_file_shm_hugepages(file); }
- +static inline struct hstate *hstate_inode(struct inode *i) +{ + return HUGETLBFS_SB(i->i_sb)->hstate; +} #else /* !CONFIG_HUGETLBFS */
#define is_file_hugepages(file) false @@ -310,6 +313,10 @@ hugetlb_file_setup(const char *name, size_t size, vm_flags_t acctflag, return ERR_PTR(-ENOSYS); }
+static inline struct hstate *hstate_inode(struct inode *i) +{ + return NULL; +} #endif /* !CONFIG_HUGETLBFS */
#ifdef HAVE_ARCH_HUGETLB_UNMAPPED_AREA @@ -379,11 +386,6 @@ extern unsigned int default_hstate_idx;
#define default_hstate (hstates[default_hstate_idx])
-static inline struct hstate *hstate_inode(struct inode *i) -{ - return HUGETLBFS_SB(i->i_sb)->hstate; -} - static inline struct hstate *hstate_file(struct file *f) { return hstate_inode(file_inode(f)); @@ -636,11 +638,6 @@ static inline struct hstate *hstate_vma(struct vm_area_struct *vma) return NULL; }
-static inline struct hstate *hstate_inode(struct inode *i) -{ - return NULL; -} - static inline struct hstate *page_hstate(struct page *page) { return NULL;
From: Ralph Campbell rcampbell@nvidia.com
[ Upstream commit 822cab6150d3002952407a8297ff5a0d32bb7b54 ]
When migrating system memory to GPU memory, check that SVM has been enabled. Even though most errors can be ignored since migration is a performance optimization, return an error because this is a violation of the API.
Signed-off-by: Ralph Campbell rcampbell@nvidia.com Signed-off-by: Ben Skeggs bskeggs@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/nouveau/nouveau_svm.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/gpu/drm/nouveau/nouveau_svm.c b/drivers/gpu/drm/nouveau/nouveau_svm.c index 668d4bd0c118f..25b7055949c45 100644 --- a/drivers/gpu/drm/nouveau/nouveau_svm.c +++ b/drivers/gpu/drm/nouveau/nouveau_svm.c @@ -173,6 +173,11 @@ nouveau_svmm_bind(struct drm_device *dev, void *data, mm = get_task_mm(current); down_read(&mm->mmap_sem);
+ if (!cli->svm.svmm) { + up_read(&mm->mmap_sem); + return -EINVAL; + } + for (addr = args->va_start, end = args->va_start + size; addr < end;) { struct vm_area_struct *vma; unsigned long next;
From: Ralph Campbell rcampbell@nvidia.com
[ Upstream commit b92103b559c77abc5f8b7bec269230a219c880b7 ]
find_vma_intersection(mm, start, end) only guarantees that end is greater than or equal to vma->vm_start but doesn't guarantee that start is greater than or equal to vma->vm_start. The calculation for the intersecting range in nouveau_svmm_bind() isn't accounting for this and can call migrate_vma_setup() with a starting address less than vma->vm_start. This results in migrate_vma_setup() returning -EINVAL for the range instead of nouveau skipping that part of the range and migrating the rest.
Signed-off-by: Ralph Campbell rcampbell@nvidia.com Signed-off-by: Ben Skeggs bskeggs@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/nouveau/nouveau_svm.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/nouveau/nouveau_svm.c b/drivers/gpu/drm/nouveau/nouveau_svm.c index 25b7055949c45..824654742a604 100644 --- a/drivers/gpu/drm/nouveau/nouveau_svm.c +++ b/drivers/gpu/drm/nouveau/nouveau_svm.c @@ -186,6 +186,7 @@ nouveau_svmm_bind(struct drm_device *dev, void *data, if (!vma) break;
+ addr = max(addr, vma->vm_start); next = min(vma->vm_end, end); /* This is a best effort so we ignore errors */ nouveau_dmem_migrate_vma(cli->drm, vma, addr, next);
From: Steven Price steven.price@arm.com
[ Upstream commit 3f3673d7d324d872d9d8ddb73b3e5e47fbf12e0d ]
If CONFIG_DEVICE_PRIVATE is defined, but neither CONFIG_MEMORY_FAILURE nor CONFIG_MIGRATION, then non_swap_entry() will return 0, meaning that the condition (non_swap_entry(entry) && is_device_private_entry(entry)) in zap_pte_range() will never be true even if the entry is a device private one.
Equally any other code depending on non_swap_entry() will not function as expected.
I originally spotted this just by looking at the code, I haven't actually observed any problems.
Looking a bit more closely it appears that actually this situation (currently at least) cannot occur:
DEVICE_PRIVATE depends on ZONE_DEVICE ZONE_DEVICE depends on MEMORY_HOTREMOVE MEMORY_HOTREMOVE depends on MIGRATION
Fixes: 5042db43cc26 ("mm/ZONE_DEVICE: new type of ZONE_DEVICE for unaddressable memory") Signed-off-by: Steven Price steven.price@arm.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Cc: Jérôme Glisse jglisse@redhat.com Cc: Arnd Bergmann arnd@arndb.de Cc: Dan Williams dan.j.williams@intel.com Cc: John Hubbard jhubbard@nvidia.com Link: http://lkml.kernel.org/r/20200305130550.22693-1-steven.price@arm.com Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/swapops.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/include/linux/swapops.h b/include/linux/swapops.h index 877fd239b6fff..3208a520d0be3 100644 --- a/include/linux/swapops.h +++ b/include/linux/swapops.h @@ -348,7 +348,8 @@ static inline void num_poisoned_pages_inc(void) } #endif
-#if defined(CONFIG_MEMORY_FAILURE) || defined(CONFIG_MIGRATION) +#if defined(CONFIG_MEMORY_FAILURE) || defined(CONFIG_MIGRATION) || \ + defined(CONFIG_DEVICE_PRIVATE) static inline int non_swap_entry(swp_entry_t entry) { return swp_type(entry) >= MAX_SWAPFILES;
From: Qian Cai cai@lca.pw
[ Upstream commit 7e2345200262e4a6056580f0231cccdaffc825f3 ]
"vm_committed_as.count" could be accessed concurrently as reported by KCSAN,
BUG: KCSAN: data-race in __vm_enough_memory / percpu_counter_add_batch
write to 0xffffffff9451c538 of 8 bytes by task 65879 on cpu 35: percpu_counter_add_batch+0x83/0xd0 percpu_counter_add_batch at lib/percpu_counter.c:91 __vm_enough_memory+0xb9/0x260 dup_mm+0x3a4/0x8f0 copy_process+0x2458/0x3240 _do_fork+0xaa/0x9f0 __do_sys_clone+0x125/0x160 __x64_sys_clone+0x70/0x90 do_syscall_64+0x91/0xb05 entry_SYSCALL_64_after_hwframe+0x49/0xbe
read to 0xffffffff9451c538 of 8 bytes by task 66773 on cpu 19: __vm_enough_memory+0x199/0x260 percpu_counter_read_positive at include/linux/percpu_counter.h:81 (inlined by) __vm_enough_memory at mm/util.c:839 mmap_region+0x1b2/0xa10 do_mmap+0x45c/0x700 vm_mmap_pgoff+0xc0/0x130 ksys_mmap_pgoff+0x6e/0x300 __x64_sys_mmap+0x33/0x40 do_syscall_64+0x91/0xb05 entry_SYSCALL_64_after_hwframe+0x49/0xbe
The read is outside percpu_counter::lock critical section which results in a data race. Fix it by adding a READ_ONCE() in percpu_counter_read_positive() which could also service as the existing compiler memory barrier.
Signed-off-by: Qian Cai cai@lca.pw Signed-off-by: Andrew Morton akpm@linux-foundation.org Acked-by: Marco Elver elver@google.com Link: http://lkml.kernel.org/r/1582302724-2804-1-git-send-email-cai@lca.pw Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/percpu_counter.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/linux/percpu_counter.h b/include/linux/percpu_counter.h index 4f052496cdfd7..0a4f54dd4737b 100644 --- a/include/linux/percpu_counter.h +++ b/include/linux/percpu_counter.h @@ -78,9 +78,9 @@ static inline s64 percpu_counter_read(struct percpu_counter *fbc) */ static inline s64 percpu_counter_read_positive(struct percpu_counter *fbc) { - s64 ret = fbc->count; + /* Prevent reloads of fbc->count */ + s64 ret = READ_ONCE(fbc->count);
- barrier(); /* Prevent reloads of fbc->count */ if (ret >= 0) return ret; return 0;
From: Vegard Nossum vegard.nossum@oracle.com
[ Upstream commit af9c5d2e3b355854ff0e4acfbfbfadcd5198a349 ]
compiletime_assert() uses __LINE__ to create a unique function name. This means that if you have more than one BUILD_BUG_ON() in the same source line (which can happen if they appear e.g. in a macro), then the error message from the compiler might output the wrong condition.
For this source file:
#include <linux/build_bug.h>
#define macro() \ BUILD_BUG_ON(1); \ BUILD_BUG_ON(0);
void foo() { macro(); }
gcc would output:
./include/linux/compiler.h:350:38: error: call to `__compiletime_assert_9' declared with attribute error: BUILD_BUG_ON failed: 0 _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
However, it was not the BUILD_BUG_ON(0) that failed, so it should say 1 instead of 0. With this patch, we use __COUNTER__ instead of __LINE__, so each BUILD_BUG_ON() gets a different function name and the correct condition is printed:
./include/linux/compiler.h:350:38: error: call to `__compiletime_assert_0' declared with attribute error: BUILD_BUG_ON failed: 1 _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
Signed-off-by: Vegard Nossum vegard.nossum@oracle.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Reviewed-by: Masahiro Yamada yamada.masahiro@socionext.com Reviewed-by: Daniel Santos daniel.santos@pobox.com Cc: Rasmus Villemoes linux@rasmusvillemoes.dk Cc: Ian Abbott abbotti@mev.co.uk Cc: Joe Perches joe@perches.com Link: http://lkml.kernel.org/r/20200331112637.25047-1-vegard.nossum@oracle.com Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/compiler.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 5e88e7e33abec..034b0a644efcc 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -347,7 +347,7 @@ static inline void *offset_to_ptr(const int *off) * compiler has support to do so. */ #define compiletime_assert(condition, msg) \ - _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__) + _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
#define compiletime_assert_atomic_type(t) \ compiletime_assert(__native_word(t), \
From: David Hildenbrand david@redhat.com
[ Upstream commit 1493e0f944f3c319d11e067c185c904d01c17ae5 ]
We have to properly retry again by returning -EINVAL immediately in case somebody else instantiated the table concurrently. We missed to add the goto in this function only. The code now matches the other, similar shadowing functions.
We are overwriting an existing region 2 table entry. All allocated pages are added to the crst_list to be freed later, so they are not lost forever. However, when unshadowing the region 2 table, we wouldn't trigger unshadowing of the original shadowed region 3 table that we replaced. It would get unshadowed when the original region 3 table is modified. As it's not connected to the page table hierarchy anymore, it's not going to get used anymore. However, for a limited time, this page table will stick around, so it's in some sense a temporary memory leak.
Identified by manual code inspection. I don't think this classifies as stable material.
Fixes: 998f637cc4b9 ("s390/mm: avoid races on region/segment/page table shadowing") Signed-off-by: David Hildenbrand david@redhat.com Link: https://lore.kernel.org/r/20200403153050.20569-4-david@redhat.com Reviewed-by: Claudio Imbrenda imbrenda@linux.ibm.com Reviewed-by: Christian Borntraeger borntraeger@de.ibm.com Signed-off-by: Christian Borntraeger borntraeger@de.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/s390/mm/gmap.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/s390/mm/gmap.c b/arch/s390/mm/gmap.c index 9d9ab77d02dd3..364e3a89c0969 100644 --- a/arch/s390/mm/gmap.c +++ b/arch/s390/mm/gmap.c @@ -1844,6 +1844,7 @@ int gmap_shadow_r3t(struct gmap *sg, unsigned long saddr, unsigned long r3t, goto out_free; } else if (*table & _REGION_ENTRY_ORIGIN) { rc = -EAGAIN; /* Race with shadow */ + goto out_free; } crst_table_init(s_r3t, _REGION3_ENTRY_EMPTY); /* mark as invalid as long as the parent table is not protected */
From: Karol Herbst kherbst@redhat.com
[ Upstream commit 434fdb51513bf3057ac144d152e6f2f2b509e857 ]
Fixes the infamous 'runtime PM' bug many users are facing on Laptops with Nvidia Pascal GPUs by skipping said PCI power state changes on the GPU.
Depending on the used kernel there might be messages like those in demsg:
"nouveau 0000:01:00.0: Refused to change power state, currently in D3" "nouveau 0000:01:00.0: can't change power state from D3cold to D0 (config space inaccessible)" followed by backtraces of kernel crashes or timeouts within nouveau.
It's still unkown why this issue exists, but this is a reliable workaround and solves a very annoying issue for user having to choose between a crashing kernel or higher power consumption of their Laptops.
Signed-off-by: Karol Herbst kherbst@redhat.com Cc: Bjorn Helgaas bhelgaas@google.com Cc: Lyude Paul lyude@redhat.com Cc: Rafael J. Wysocki rjw@rjwysocki.net Cc: Mika Westerberg mika.westerberg@intel.com Cc: linux-pci@vger.kernel.org Cc: linux-pm@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: nouveau@lists.freedesktop.org Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=205623 Signed-off-by: Ben Skeggs bskeggs@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/nouveau/nouveau_drm.c | 63 +++++++++++++++++++++++++++ drivers/gpu/drm/nouveau/nouveau_drv.h | 2 + 2 files changed, 65 insertions(+)
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 2cd83849600f3..b1beed40e746a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -618,6 +618,64 @@ nouveau_drm_device_fini(struct drm_device *dev) kfree(drm); }
+/* + * On some Intel PCIe bridge controllers doing a + * D0 -> D3hot -> D3cold -> D0 sequence causes Nvidia GPUs to not reappear. + * Skipping the intermediate D3hot step seems to make it work again. This is + * probably caused by not meeting the expectation the involved AML code has + * when the GPU is put into D3hot state before invoking it. + * + * This leads to various manifestations of this issue: + * - AML code execution to power on the GPU hits an infinite loop (as the + * code waits on device memory to change). + * - kernel crashes, as all PCI reads return -1, which most code isn't able + * to handle well enough. + * + * In all cases dmesg will contain at least one line like this: + * 'nouveau 0000:01:00.0: Refused to change power state, currently in D3' + * followed by a lot of nouveau timeouts. + * + * In the _SB.PCI0.PEG0.PG00._OFF code deeper down writes bit 0x80 to the not + * documented PCI config space register 0x248 of the Intel PCIe bridge + * controller (0x1901) in order to change the state of the PCIe link between + * the PCIe port and the GPU. There are alternative code paths using other + * registers, which seem to work fine (executed pre Windows 8): + * - 0xbc bit 0x20 (publicly available documentation claims 'reserved') + * - 0xb0 bit 0x10 (link disable) + * Changing the conditions inside the firmware by poking into the relevant + * addresses does resolve the issue, but it seemed to be ACPI private memory + * and not any device accessible memory at all, so there is no portable way of + * changing the conditions. + * On a XPS 9560 that means bits [0,3] on \CPEX need to be cleared. + * + * The only systems where this behavior can be seen are hybrid graphics laptops + * with a secondary Nvidia Maxwell, Pascal or Turing GPU. It's unclear whether + * this issue only occurs in combination with listed Intel PCIe bridge + * controllers and the mentioned GPUs or other devices as well. + * + * documentation on the PCIe bridge controller can be found in the + * "7th Generation Intel® Processor Families for H Platforms Datasheet Volume 2" + * Section "12 PCI Express* Controller (x16) Registers" + */ + +static void quirk_broken_nv_runpm(struct pci_dev *pdev) +{ + struct drm_device *dev = pci_get_drvdata(pdev); + struct nouveau_drm *drm = nouveau_drm(dev); + struct pci_dev *bridge = pci_upstream_bridge(pdev); + + if (!bridge || bridge->vendor != PCI_VENDOR_ID_INTEL) + return; + + switch (bridge->device) { + case 0x1901: + drm->old_pm_cap = pdev->pm_cap; + pdev->pm_cap = 0; + NV_INFO(drm, "Disabling PCI power management to avoid bug\n"); + break; + } +} + static int nouveau_drm_probe(struct pci_dev *pdev, const struct pci_device_id *pent) { @@ -699,6 +757,7 @@ static int nouveau_drm_probe(struct pci_dev *pdev, if (ret) goto fail_drm_dev_init;
+ quirk_broken_nv_runpm(pdev); return 0;
fail_drm_dev_init: @@ -736,7 +795,11 @@ static void nouveau_drm_remove(struct pci_dev *pdev) { struct drm_device *dev = pci_get_drvdata(pdev); + struct nouveau_drm *drm = nouveau_drm(dev);
+ /* revert our workaround */ + if (drm->old_pm_cap) + pdev->pm_cap = drm->old_pm_cap; nouveau_drm_device_remove(dev); }
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 70f34cacc552c..8104e3806499d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -138,6 +138,8 @@ struct nouveau_drm {
struct list_head clients;
+ u8 old_pm_cap; + struct { struct agp_bridge_data *bridge; u32 base;
From: Ricardo Ribalda Delgado ribalda@kernel.org
[ Upstream commit 64ed6588c2ea618d3f9ca9d8b365ae4c19f76225 ]
The warning message when a led is renamed due to name collition can fail to show proper original name if init_data is used. Eg:
[ 9.073996] leds-gpio a0040000.leds_0: Led (null) renamed to red_led_1 due to name collision
Fixes: bb4e9af0348d ("leds: core: Add support for composing LED class device names") Signed-off-by: Ricardo Ribalda Delgado ribalda@kernel.org Acked-by: Jacek Anaszewski jacek.anaszewski@gmail.com Signed-off-by: Pavel Machek pavel@ucw.cz Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/leds/led-class.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index 647b1263c5794..d3e83c33783e5 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -281,7 +281,7 @@ int led_classdev_register_ext(struct device *parent,
if (ret) dev_warn(parent, "Led %s renamed to %s due to name collision", - led_cdev->name, dev_name(led_cdev->dev)); + proposed_name, dev_name(led_cdev->dev));
if (led_cdev->flags & LED_BRIGHT_HW_CHANGED) { ret = led_add_brightness_hw_changed(led_cdev);
From: Qian Cai cai@lca.pw
[ Upstream commit 696ac2e3bf267f5a2b2ed7d34e64131f2287d0ad ]
Similar to commit 0266d81e9bf5 ("acpi/processor: Prevent cpu hotplug deadlock") except this is for acpi_processor_ffh_cstate_probe():
"The problem is that the work is scheduled on the current CPU from the hotplug thread associated with that CPU.
It's not required to invoke these functions via the workqueue because the hotplug thread runs on the target CPU already.
Check whether current is a per cpu thread pinned on the target CPU and invoke the function directly to avoid the workqueue."
WARNING: possible circular locking dependency detected ------------------------------------------------------ cpuhp/1/15 is trying to acquire lock: ffffc90003447a28 ((work_completion)(&wfc.work)){+.+.}-{0:0}, at: __flush_work+0x4c6/0x630
but task is already holding lock: ffffffffafa1c0e8 (cpuidle_lock){+.+.}-{3:3}, at: cpuidle_pause_and_lock+0x17/0x20
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #1 (cpu_hotplug_lock){++++}-{0:0}: cpus_read_lock+0x3e/0xc0 irq_calc_affinity_vectors+0x5f/0x91 __pci_enable_msix_range+0x10f/0x9a0 pci_alloc_irq_vectors_affinity+0x13e/0x1f0 pci_alloc_irq_vectors_affinity at drivers/pci/msi.c:1208 pqi_ctrl_init+0x72f/0x1618 [smartpqi] pqi_pci_probe.cold.63+0x882/0x892 [smartpqi] local_pci_probe+0x7a/0xc0 work_for_cpu_fn+0x2e/0x50 process_one_work+0x57e/0xb90 worker_thread+0x363/0x5b0 kthread+0x1f4/0x220 ret_from_fork+0x27/0x50
-> #0 ((work_completion)(&wfc.work)){+.+.}-{0:0}: __lock_acquire+0x2244/0x32a0 lock_acquire+0x1a2/0x680 __flush_work+0x4e6/0x630 work_on_cpu+0x114/0x160 acpi_processor_ffh_cstate_probe+0x129/0x250 acpi_processor_evaluate_cst+0x4c8/0x580 acpi_processor_get_power_info+0x86/0x740 acpi_processor_hotplug+0xc3/0x140 acpi_soft_cpu_online+0x102/0x1d0 cpuhp_invoke_callback+0x197/0x1120 cpuhp_thread_fun+0x252/0x2f0 smpboot_thread_fn+0x255/0x440 kthread+0x1f4/0x220 ret_from_fork+0x27/0x50
other info that might help us debug this:
Chain exists of: (work_completion)(&wfc.work) --> cpuhp_state-up --> cpuidle_lock
Possible unsafe locking scenario:
CPU0 CPU1 ---- ---- lock(cpuidle_lock); lock(cpuhp_state-up); lock(cpuidle_lock); lock((work_completion)(&wfc.work));
*** DEADLOCK ***
3 locks held by cpuhp/1/15: #0: ffffffffaf51ab10 (cpu_hotplug_lock){++++}-{0:0}, at: cpuhp_thread_fun+0x69/0x2f0 #1: ffffffffaf51ad40 (cpuhp_state-up){+.+.}-{0:0}, at: cpuhp_thread_fun+0x69/0x2f0 #2: ffffffffafa1c0e8 (cpuidle_lock){+.+.}-{3:3}, at: cpuidle_pause_and_lock+0x17/0x20
Call Trace: dump_stack+0xa0/0xea print_circular_bug.cold.52+0x147/0x14c check_noncircular+0x295/0x2d0 __lock_acquire+0x2244/0x32a0 lock_acquire+0x1a2/0x680 __flush_work+0x4e6/0x630 work_on_cpu+0x114/0x160 acpi_processor_ffh_cstate_probe+0x129/0x250 acpi_processor_evaluate_cst+0x4c8/0x580 acpi_processor_get_power_info+0x86/0x740 acpi_processor_hotplug+0xc3/0x140 acpi_soft_cpu_online+0x102/0x1d0 cpuhp_invoke_callback+0x197/0x1120 cpuhp_thread_fun+0x252/0x2f0 smpboot_thread_fn+0x255/0x440 kthread+0x1f4/0x220 ret_from_fork+0x27/0x50
Signed-off-by: Qian Cai cai@lca.pw Tested-by: Borislav Petkov bp@suse.de [ rjw: Subject ] Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/kernel/acpi/cstate.c | 3 ++- drivers/acpi/processor_throttling.c | 7 ------- include/acpi/processor.h | 8 ++++++++ 3 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/arch/x86/kernel/acpi/cstate.c b/arch/x86/kernel/acpi/cstate.c index caf2edccbad2e..49ae4e1ac9cd8 100644 --- a/arch/x86/kernel/acpi/cstate.c +++ b/arch/x86/kernel/acpi/cstate.c @@ -161,7 +161,8 @@ int acpi_processor_ffh_cstate_probe(unsigned int cpu,
/* Make sure we are running on right CPU */
- retval = work_on_cpu(cpu, acpi_processor_ffh_cstate_probe_cpu, cx); + retval = call_on_cpu(cpu, acpi_processor_ffh_cstate_probe_cpu, cx, + false); if (retval == 0) { /* Use the hint in CST */ percpu_entry->states[cx->index].eax = cx->address; diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index 532a1ae3595a7..a0bd56ece3ff5 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c @@ -897,13 +897,6 @@ static long __acpi_processor_get_throttling(void *data) return pr->throttling.acpi_processor_get_throttling(pr); }
-static int call_on_cpu(int cpu, long (*fn)(void *), void *arg, bool direct) -{ - if (direct || (is_percpu_thread() && cpu == smp_processor_id())) - return fn(arg); - return work_on_cpu(cpu, fn, arg); -} - static int acpi_processor_get_throttling(struct acpi_processor *pr) { if (!pr) diff --git a/include/acpi/processor.h b/include/acpi/processor.h index 47805172e73d8..683e124ad517d 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h @@ -297,6 +297,14 @@ static inline void acpi_processor_ffh_cstate_enter(struct acpi_processor_cx } #endif
+static inline int call_on_cpu(int cpu, long (*fn)(void *), void *arg, + bool direct) +{ + if (direct || (is_percpu_thread() && cpu == smp_processor_id())) + return fn(arg); + return work_on_cpu(cpu, fn, arg); +} + /* in processor_perflib.c */
#ifdef CONFIG_CPU_FREQ
From: Guo Ren guoren@linux.alibaba.com
[ Upstream commit aefd9461d34a1b0a2acad0750c43216c1c27b9d4 ]
For the memory size ( > 512MB, < 1GB), the MSA setting is:
- SSEG0: PHY_START , PHY_START + 512MB - SSEG1: PHY_START + 512MB, PHY_START + 1GB
But the real memory is no more than 1GB, there is a gap between the end size of memory and border of 1GB. CPU could speculatively execute to that gap and if the gap of the bus couldn't respond to the CPU request, then the crash will happen.
Now make the setting with:
- SSEG0: PHY_START , PHY_START + 512MB (no change) - SSEG1: Disabled (We use highmem to use the memory of 512MB~1GB)
We also deprecated zhole_szie[] settings, it's only used by arm style CPUs. All memory gap should use Reserved setting of dts in csky system.
Signed-off-by: Guo Ren guoren@linux.alibaba.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/csky/abiv1/inc/abi/entry.h | 5 +-- arch/csky/abiv2/inc/abi/entry.h | 7 ++-- arch/csky/kernel/head.S | 5 +++ arch/csky/kernel/setup.c | 63 ++++++++------------------------- arch/csky/kernel/smp.c | 3 ++ 5 files changed, 25 insertions(+), 58 deletions(-)
diff --git a/arch/csky/abiv1/inc/abi/entry.h b/arch/csky/abiv1/inc/abi/entry.h index f35a9f3315ee6..5056ebb902d18 100644 --- a/arch/csky/abiv1/inc/abi/entry.h +++ b/arch/csky/abiv1/inc/abi/entry.h @@ -172,10 +172,7 @@ addi r6, 0xe cpwcr r6, cpcr30
- lsri r6, 28 - addi r6, 2 - lsli r6, 28 - addi r6, 0xe + movi r6, 0 cpwcr r6, cpcr31 .endm
diff --git a/arch/csky/abiv2/inc/abi/entry.h b/arch/csky/abiv2/inc/abi/entry.h index 94a7a58765dff..111973c6c713f 100644 --- a/arch/csky/abiv2/inc/abi/entry.h +++ b/arch/csky/abiv2/inc/abi/entry.h @@ -230,11 +230,8 @@ addi r6, 0x1ce mtcr r6, cr<30, 15> /* Set MSA0 */
- lsri r6, 28 - addi r6, 2 - lsli r6, 28 - addi r6, 0x1ce - mtcr r6, cr<31, 15> /* Set MSA1 */ + movi r6, 0 + mtcr r6, cr<31, 15> /* Clr MSA1 */
/* enable MMU */ mfcr r6, cr18 diff --git a/arch/csky/kernel/head.S b/arch/csky/kernel/head.S index 61989f9241c02..17ed9d2504807 100644 --- a/arch/csky/kernel/head.S +++ b/arch/csky/kernel/head.S @@ -21,6 +21,11 @@ END(_start) ENTRY(_start_smp_secondary) SETUP_MMU
+ /* copy msa1 from CPU0 */ + lrw r6, secondary_msa1 + ld.w r6, (r6, 0) + mtcr r6, cr<31, 15> + /* set stack point */ lrw r6, secondary_stack ld.w r6, (r6, 0) diff --git a/arch/csky/kernel/setup.c b/arch/csky/kernel/setup.c index 23ee604aafdb6..2c1e253abb74c 100644 --- a/arch/csky/kernel/setup.c +++ b/arch/csky/kernel/setup.c @@ -24,26 +24,9 @@ struct screen_info screen_info = { }; #endif
-phys_addr_t __init_memblock memblock_end_of_REG0(void) -{ - return (memblock.memory.regions[0].base + - memblock.memory.regions[0].size); -} - -phys_addr_t __init_memblock memblock_start_of_REG1(void) -{ - return memblock.memory.regions[1].base; -} - -size_t __init_memblock memblock_size_of_REG1(void) -{ - return memblock.memory.regions[1].size; -} - static void __init csky_memblock_init(void) { unsigned long zone_size[MAX_NR_ZONES]; - unsigned long zhole_size[MAX_NR_ZONES]; signed long size;
memblock_reserve(__pa(_stext), _end - _stext); @@ -57,54 +40,36 @@ static void __init csky_memblock_init(void) memblock_dump_all();
memset(zone_size, 0, sizeof(zone_size)); - memset(zhole_size, 0, sizeof(zhole_size));
min_low_pfn = PFN_UP(memblock_start_of_DRAM()); - max_pfn = PFN_DOWN(memblock_end_of_DRAM()); - - max_low_pfn = PFN_UP(memblock_end_of_REG0()); - if (max_low_pfn == 0) - max_low_pfn = max_pfn; + max_low_pfn = max_pfn = PFN_DOWN(memblock_end_of_DRAM());
size = max_pfn - min_low_pfn;
- if (memblock.memory.cnt > 1) { - zone_size[ZONE_NORMAL] = - PFN_DOWN(memblock_start_of_REG1()) - min_low_pfn; - zhole_size[ZONE_NORMAL] = - PFN_DOWN(memblock_start_of_REG1()) - max_low_pfn; + if (size <= PFN_DOWN(SSEG_SIZE - PHYS_OFFSET_OFFSET)) + zone_size[ZONE_NORMAL] = size; + else if (size < PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET)) { + zone_size[ZONE_NORMAL] = + PFN_DOWN(SSEG_SIZE - PHYS_OFFSET_OFFSET); + max_low_pfn = min_low_pfn + zone_size[ZONE_NORMAL]; } else { - if (size <= PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET)) - zone_size[ZONE_NORMAL] = max_pfn - min_low_pfn; - else { - zone_size[ZONE_NORMAL] = + zone_size[ZONE_NORMAL] = PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET); - max_low_pfn = min_low_pfn + zone_size[ZONE_NORMAL]; - } + max_low_pfn = min_low_pfn + zone_size[ZONE_NORMAL]; + write_mmu_msa1(read_mmu_msa0() + SSEG_SIZE); }
#ifdef CONFIG_HIGHMEM - size = 0; - if (memblock.memory.cnt > 1) { - size = PFN_DOWN(memblock_size_of_REG1()); - highstart_pfn = PFN_DOWN(memblock_start_of_REG1()); - } else { - size = max_pfn - min_low_pfn - - PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET); - highstart_pfn = min_low_pfn + - PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET); - } - - if (size > 0) - zone_size[ZONE_HIGHMEM] = size; + zone_size[ZONE_HIGHMEM] = max_pfn - max_low_pfn;
- highend_pfn = max_pfn; + highstart_pfn = max_low_pfn; + highend_pfn = max_pfn; #endif memblock_set_current_limit(PFN_PHYS(max_low_pfn));
dma_contiguous_reserve(0);
- free_area_init_node(0, zone_size, min_low_pfn, zhole_size); + free_area_init_node(0, zone_size, min_low_pfn, NULL); }
void __init setup_arch(char **cmdline_p) diff --git a/arch/csky/kernel/smp.c b/arch/csky/kernel/smp.c index 0bb0954d55709..de61feb4b6df2 100644 --- a/arch/csky/kernel/smp.c +++ b/arch/csky/kernel/smp.c @@ -156,6 +156,8 @@ volatile unsigned int secondary_hint; volatile unsigned int secondary_ccr; volatile unsigned int secondary_stack;
+unsigned long secondary_msa1; + int __cpu_up(unsigned int cpu, struct task_struct *tidle) { unsigned long mask = 1 << cpu; @@ -164,6 +166,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *tidle) (unsigned int) task_stack_page(tidle) + THREAD_SIZE - 8; secondary_hint = mfcr("cr31"); secondary_ccr = mfcr("cr18"); + secondary_msa1 = read_mmu_msa1();
/* * Because other CPUs are in reset status, we must flush data
From: Jack Zhang Jack.Zhang1@amd.com
[ Upstream commit 3148a6a0ef3cf93570f30a477292768f7eb5d3c3 ]
Originally, it kfrees the wrong pointer for mem_obj. It would cause memory leak under stress test.
Signed-off-by: Jack Zhang Jack.Zhang1@amd.com Acked-by: Nirmoy Das nirmoy.das@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdkfd/kfd_device.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index 0dc1084b5e829..ad9483b9eea32 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c @@ -1112,9 +1112,9 @@ int kfd_gtt_sa_allocate(struct kfd_dev *kfd, unsigned int size, return 0;
kfd_gtt_no_free_chunk: - pr_debug("Allocation failed with mem_obj = %p\n", mem_obj); + pr_debug("Allocation failed with mem_obj = %p\n", *mem_obj); mutex_unlock(&kfd->gtt_sa_lock); - kfree(mem_obj); + kfree(*mem_obj); return -ENOMEM; }
From: Trond Myklebust trond.myklebust@hammerspace.com
[ Upstream commit 862f35c94730c9270833f3ad05bd758a29f204ed ]
If we just set the mirror count to 1 without first clearing out the mirrors, we can leak queued up requests.
Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/pagelist.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index 8b7c525dbbf7c..b736912098eee 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c @@ -886,15 +886,6 @@ static void nfs_pageio_setup_mirroring(struct nfs_pageio_descriptor *pgio, pgio->pg_mirror_count = mirror_count; }
-/* - * nfs_pageio_stop_mirroring - stop using mirroring (set mirror count to 1) - */ -void nfs_pageio_stop_mirroring(struct nfs_pageio_descriptor *pgio) -{ - pgio->pg_mirror_count = 1; - pgio->pg_mirror_idx = 0; -} - static void nfs_pageio_cleanup_mirroring(struct nfs_pageio_descriptor *pgio) { pgio->pg_mirror_count = 1; @@ -1320,6 +1311,14 @@ void nfs_pageio_cond_complete(struct nfs_pageio_descriptor *desc, pgoff_t index) } }
+/* + * nfs_pageio_stop_mirroring - stop using mirroring (set mirror count to 1) + */ +void nfs_pageio_stop_mirroring(struct nfs_pageio_descriptor *pgio) +{ + nfs_pageio_complete(pgio); +} + int __init nfs_init_nfspagecache(void) { nfs_page_cachep = kmem_cache_create("nfs_page",
From: Guo Ren guoren@linux.alibaba.com
[ Upstream commit 9c0e343d7654a329d1f9b53d253cbf7fb6eff85d ]
We should get psr value from regs->psr in stack, not directly get it from phyiscal register then save the vector number in tsk->trap_no.
Signed-off-by: Guo Ren guoren@linux.alibaba.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/csky/include/asm/processor.h | 1 + arch/csky/kernel/traps.c | 11 ++++++++++- arch/csky/mm/fault.c | 7 +++++++ 3 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/arch/csky/include/asm/processor.h b/arch/csky/include/asm/processor.h index 21e0bd5293dde..c6bcd7f7c720b 100644 --- a/arch/csky/include/asm/processor.h +++ b/arch/csky/include/asm/processor.h @@ -43,6 +43,7 @@ extern struct cpuinfo_csky cpu_data[]; struct thread_struct { unsigned long ksp; /* kernel stack pointer */ unsigned long sr; /* saved status register */ + unsigned long trap_no; /* saved status register */
/* FPU regs */ struct user_fp __aligned(16) user_fp; diff --git a/arch/csky/kernel/traps.c b/arch/csky/kernel/traps.c index b057480e7463c..63715cb90ee99 100644 --- a/arch/csky/kernel/traps.c +++ b/arch/csky/kernel/traps.c @@ -115,8 +115,9 @@ asmlinkage void trap_c(struct pt_regs *regs) int sig; unsigned long vector; siginfo_t info; + struct task_struct *tsk = current;
- vector = (mfcr("psr") >> 16) & 0xff; + vector = (regs->sr >> 16) & 0xff;
switch (vector) { case VEC_ZERODIV: @@ -129,6 +130,7 @@ asmlinkage void trap_c(struct pt_regs *regs) sig = SIGTRAP; break; case VEC_ILLEGAL: + tsk->thread.trap_no = vector; die_if_kernel("Kernel mode ILLEGAL", regs, vector); #ifndef CONFIG_CPU_NO_USER_BKPT if (*(uint16_t *)instruction_pointer(regs) != USR_BKPT) @@ -146,16 +148,20 @@ asmlinkage void trap_c(struct pt_regs *regs) sig = SIGTRAP; break; case VEC_ACCESS: + tsk->thread.trap_no = vector; return buserr(regs); #ifdef CONFIG_CPU_NEED_SOFTALIGN case VEC_ALIGN: + tsk->thread.trap_no = vector; return csky_alignment(regs); #endif #ifdef CONFIG_CPU_HAS_FPU case VEC_FPE: + tsk->thread.trap_no = vector; die_if_kernel("Kernel mode FPE", regs, vector); return fpu_fpe(regs); case VEC_PRIV: + tsk->thread.trap_no = vector; die_if_kernel("Kernel mode PRIV", regs, vector); if (fpu_libc_helper(regs)) return; @@ -164,5 +170,8 @@ asmlinkage void trap_c(struct pt_regs *regs) sig = SIGSEGV; break; } + + tsk->thread.trap_no = vector; + send_sig(sig, current, 0); } diff --git a/arch/csky/mm/fault.c b/arch/csky/mm/fault.c index f76618b630f91..562c7f7087490 100644 --- a/arch/csky/mm/fault.c +++ b/arch/csky/mm/fault.c @@ -179,11 +179,14 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write, bad_area_nosemaphore: /* User mode accesses just cause a SIGSEGV */ if (user_mode(regs)) { + tsk->thread.trap_no = (regs->sr >> 16) & 0xff; force_sig_fault(SIGSEGV, si_code, (void __user *)address); return; }
no_context: + tsk->thread.trap_no = (regs->sr >> 16) & 0xff; + /* Are we prepared to handle this kernel fault? */ if (fixup_exception(regs)) return; @@ -198,6 +201,8 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write, die_if_kernel("Oops", regs, write);
out_of_memory: + tsk->thread.trap_no = (regs->sr >> 16) & 0xff; + /* * We ran out of memory, call the OOM killer, and return the userspace * (which will retry the fault, or kill us if we got oom-killed). @@ -206,6 +211,8 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write, return;
do_sigbus: + tsk->thread.trap_no = (regs->sr >> 16) & 0xff; + up_read(&mm->mmap_sem);
/* Kernel mode? Handle exceptions or die */
From: Chao Yu yuchao0@huawei.com
[ Upstream commit 62f63eea291b50a5677ae7503ac128803174698a ]
BUG: kernel NULL pointer dereference, address: 0000000000000000 RIP: 0010:f2fs_write_begin+0x823/0xb90 [f2fs] Call Trace: f2fs_quota_write+0x139/0x1d0 [f2fs] write_blk+0x36/0x80 [quota_tree] get_free_dqblk+0x42/0xa0 [quota_tree] do_insert_tree+0x235/0x4a0 [quota_tree] do_insert_tree+0x26e/0x4a0 [quota_tree] do_insert_tree+0x26e/0x4a0 [quota_tree] do_insert_tree+0x26e/0x4a0 [quota_tree] qtree_write_dquot+0x70/0x190 [quota_tree] v2_write_dquot+0x43/0x90 [quota_v2] dquot_acquire+0x77/0x100 f2fs_dquot_acquire+0x2f/0x60 [f2fs] dqget+0x310/0x450 dquot_transfer+0x7e/0x120 f2fs_setattr+0x11a/0x4a0 [f2fs] notify_change+0x349/0x480 chown_common+0x168/0x1c0 do_fchownat+0xbc/0xf0 __x64_sys_fchownat+0x20/0x30 do_syscall_64+0x5f/0x220 entry_SYSCALL_64_after_hwframe+0x44/0xa9
Passing fsdata parameter to .write_{begin,end} in f2fs_quota_write(), so that if quota file is compressed one, we can avoid above NULL pointer dereference when updating quota content.
Signed-off-by: Chao Yu yuchao0@huawei.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/super.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 94caf26901e0b..5e1d4d9243a95 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -1826,6 +1826,7 @@ static ssize_t f2fs_quota_write(struct super_block *sb, int type, int offset = off & (sb->s_blocksize - 1); size_t towrite = len; struct page *page; + void *fsdata = NULL; char *kaddr; int err = 0; int tocopy; @@ -1835,7 +1836,7 @@ static ssize_t f2fs_quota_write(struct super_block *sb, int type, towrite); retry: err = a_ops->write_begin(NULL, mapping, off, tocopy, 0, - &page, NULL); + &page, &fsdata); if (unlikely(err)) { if (err == -ENOMEM) { congestion_wait(BLK_RW_ASYNC, HZ/50); @@ -1851,7 +1852,7 @@ static ssize_t f2fs_quota_write(struct super_block *sb, int type, flush_dcache_page(page);
a_ops->write_end(NULL, mapping, off, tocopy, tocopy, - page, NULL); + page, fsdata); offset = 0; towrite -= tocopy; off += tocopy;
From: Bob Moore robert.moore@intel.com
[ Upstream commit 9a1ae80412dcaa67a29eecf19de44f32b5f1c357 ]
This is the result of squashing the following ACPICA commit ID's: 6803997e5b4f3635cea6610b51ff69e29d251de3 f31cdf8bfda22fe265c1a176d0e33d311c82a7f7
This change fixes several problems with the support for the acpi_exec namespace init file (-fi option). Specifically, it fixes AE_ALREADY_EXISTS errors, as well as various seg faults.
Link: https://github.com/acpica/acpica/commit/f31cdf8b Link: https://github.com/acpica/acpica/commit/6803997e Signed-off-by: Bob Moore robert.moore@intel.com Signed-off-by: Erik Kaneda erik.kaneda@intel.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/acpi/acpica/acnamesp.h | 2 ++ drivers/acpi/acpica/dbinput.c | 16 +++++++--------- drivers/acpi/acpica/dswexec.c | 33 ++++++++++++++++++++++++++++++++ drivers/acpi/acpica/dswload.c | 2 -- drivers/acpi/acpica/dswload2.c | 35 ++++++++++++++++++++++++++++++++++ drivers/acpi/acpica/nsnames.c | 6 +----- drivers/acpi/acpica/utdelete.c | 9 +++++---- 7 files changed, 83 insertions(+), 20 deletions(-)
diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index 7da1864798a0e..ecaa28733dc61 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h @@ -256,6 +256,8 @@ u32 acpi_ns_build_normalized_path(struct acpi_namespace_node *node, char *full_path, u32 path_size, u8 no_trailing);
+void acpi_ns_normalize_pathname(char *original_path); + char *acpi_ns_get_normalized_pathname(struct acpi_namespace_node *node, u8 no_trailing);
diff --git a/drivers/acpi/acpica/dbinput.c b/drivers/acpi/acpica/dbinput.c index 55a7e10998d87..1ef053585bbb8 100644 --- a/drivers/acpi/acpica/dbinput.c +++ b/drivers/acpi/acpica/dbinput.c @@ -464,16 +464,14 @@ char *acpi_db_get_next_token(char *string, return (NULL); }
- /* Remove any spaces at the beginning */ + /* Remove any spaces at the beginning, ignore blank lines */
- if (*string == ' ') { - while (*string && (*string == ' ')) { - string++; - } + while (*string && isspace(*string)) { + string++; + }
- if (!(*string)) { - return (NULL); - } + if (!(*string)) { + return (NULL); }
switch (*string) { @@ -551,7 +549,7 @@ char *acpi_db_get_next_token(char *string,
/* Find end of token */
- while (*string && (*string != ' ')) { + while (*string && !isspace(*string)) { string++; } break; diff --git a/drivers/acpi/acpica/dswexec.c b/drivers/acpi/acpica/dswexec.c index d75aae3045958..a68237b97c4c8 100644 --- a/drivers/acpi/acpica/dswexec.c +++ b/drivers/acpi/acpica/dswexec.c @@ -16,6 +16,9 @@ #include "acinterp.h" #include "acnamesp.h" #include "acdebug.h" +#ifdef ACPI_EXEC_APP +#include "aecommon.h" +#endif
#define _COMPONENT ACPI_DISPATCHER ACPI_MODULE_NAME("dswexec") @@ -329,6 +332,10 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) u32 op_class; union acpi_parse_object *next_op; union acpi_parse_object *first_arg; +#ifdef ACPI_EXEC_APP + char *namepath; + union acpi_operand_object *obj_desc; +#endif
ACPI_FUNCTION_TRACE_PTR(ds_exec_end_op, walk_state);
@@ -537,6 +544,32 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
status = acpi_ds_eval_buffer_field_operands(walk_state, op); + if (ACPI_FAILURE(status)) { + break; + } +#ifdef ACPI_EXEC_APP + /* + * acpi_exec support for namespace initialization file (initialize + * buffer_fields in this code.) + */ + namepath = + acpi_ns_get_external_pathname(op->common.node); + status = ae_lookup_init_file_entry(namepath, &obj_desc); + if (ACPI_SUCCESS(status)) { + status = + acpi_ex_write_data_to_field(obj_desc, + op->common. + node->object, + NULL); + if ACPI_FAILURE + (status) { + ACPI_EXCEPTION((AE_INFO, status, + "While writing to buffer field")); + } + } + ACPI_FREE(namepath); + status = AE_OK; +#endif break;
case AML_TYPE_CREATE_OBJECT: diff --git a/drivers/acpi/acpica/dswload.c b/drivers/acpi/acpica/dswload.c index 4bcf15bf03ded..6cf93fae4d07f 100644 --- a/drivers/acpi/acpica/dswload.c +++ b/drivers/acpi/acpica/dswload.c @@ -14,7 +14,6 @@ #include "acdispat.h" #include "acinterp.h" #include "acnamesp.h" - #ifdef ACPI_ASL_COMPILER #include "acdisasm.h" #endif @@ -399,7 +398,6 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state) union acpi_parse_object *op; acpi_object_type object_type; acpi_status status = AE_OK; - #ifdef ACPI_ASL_COMPILER u8 param_count; #endif diff --git a/drivers/acpi/acpica/dswload2.c b/drivers/acpi/acpica/dswload2.c index 935a8e2623e4b..15d92bf15f0b6 100644 --- a/drivers/acpi/acpica/dswload2.c +++ b/drivers/acpi/acpica/dswload2.c @@ -15,6 +15,9 @@ #include "acinterp.h" #include "acnamesp.h" #include "acevents.h" +#ifdef ACPI_EXEC_APP +#include "aecommon.h" +#endif
#define _COMPONENT ACPI_DISPATCHER ACPI_MODULE_NAME("dswload2") @@ -373,6 +376,10 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) struct acpi_namespace_node *new_node; u32 i; u8 region_space; +#ifdef ACPI_EXEC_APP + union acpi_operand_object *obj_desc; + char *namepath; +#endif
ACPI_FUNCTION_TRACE(ds_load2_end_op);
@@ -466,6 +473,11 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) * be evaluated later during the execution phase */ status = acpi_ds_create_buffer_field(op, walk_state); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, + "CreateBufferField failure")); + goto cleanup; + } break;
case AML_TYPE_NAMED_FIELD: @@ -604,6 +616,29 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) case AML_NAME_OP:
status = acpi_ds_create_node(walk_state, node, op); + if (ACPI_FAILURE(status)) { + goto cleanup; + } +#ifdef ACPI_EXEC_APP + /* + * acpi_exec support for namespace initialization file (initialize + * Name opcodes in this code.) + */ + namepath = acpi_ns_get_external_pathname(node); + status = ae_lookup_init_file_entry(namepath, &obj_desc); + if (ACPI_SUCCESS(status)) { + + /* Detach any existing object, attach new object */ + + if (node->object) { + acpi_ns_detach_object(node); + } + acpi_ns_attach_object(node, obj_desc, + obj_desc->common.type); + } + ACPI_FREE(namepath); + status = AE_OK; +#endif break;
case AML_METHOD_OP: diff --git a/drivers/acpi/acpica/nsnames.c b/drivers/acpi/acpica/nsnames.c index 370bbc8677453..c717fff7d9b57 100644 --- a/drivers/acpi/acpica/nsnames.c +++ b/drivers/acpi/acpica/nsnames.c @@ -13,9 +13,6 @@ #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nsnames")
-/* Local Prototypes */ -static void acpi_ns_normalize_pathname(char *original_path); - /******************************************************************************* * * FUNCTION: acpi_ns_get_external_pathname @@ -30,7 +27,6 @@ static void acpi_ns_normalize_pathname(char *original_path); * for error and debug statements. * ******************************************************************************/ - char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node) { char *name_buffer; @@ -411,7 +407,7 @@ char *acpi_ns_build_prefixed_pathname(union acpi_generic_state *prefix_scope, * ******************************************************************************/
-static void acpi_ns_normalize_pathname(char *original_path) +void acpi_ns_normalize_pathname(char *original_path) { char *input_path = original_path; char *new_path_buffer; diff --git a/drivers/acpi/acpica/utdelete.c b/drivers/acpi/acpica/utdelete.c index eee263cb7beb0..c365faf4e6cd4 100644 --- a/drivers/acpi/acpica/utdelete.c +++ b/drivers/acpi/acpica/utdelete.c @@ -452,13 +452,13 @@ acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action) * * FUNCTION: acpi_ut_update_object_reference * - * PARAMETERS: object - Increment ref count for this object - * and all sub-objects + * PARAMETERS: object - Increment or decrement the ref count for + * this object and all sub-objects * action - Either REF_INCREMENT or REF_DECREMENT * * RETURN: Status * - * DESCRIPTION: Increment the object reference count + * DESCRIPTION: Increment or decrement the object reference count * * Object references are incremented when: * 1) An object is attached to a Node (namespace object) @@ -492,7 +492,7 @@ acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action) }
/* - * All sub-objects must have their reference count incremented + * All sub-objects must have their reference count updated * also. Different object types have different subobjects. */ switch (object->common.type) { @@ -559,6 +559,7 @@ acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action) break; } } + next_object = NULL; break;
From: Alan Maguire alan.maguire@oracle.com
[ Upstream commit 35f3401317a3b26aa01fde8facfd320f2628fdcc ]
When building UML with glibc 2.17 installed, compilation of arch/um/os-Linux/file.c fails due to failure to find FALLOC_FL_PUNCH_HOLE and FALLOC_FL_KEEP_SIZE definitions.
It appears that /usr/include/bits/fcntl-linux.h (indirectly included by /usr/include/fcntl.h) does not include falloc.h with an older glibc, whereas a more up-to-date version does.
Adding the direct include to file.c resolves the issue and does not cause problems for more recent glibc.
Fixes: 50109b5a03b4 ("um: Add support for DISCARD in the UBD Driver") Cc: Brendan Higgins brendanhiggins@google.com Signed-off-by: Alan Maguire alan.maguire@oracle.com Reviewed-by: Brendan Higgins brendanhiggins@google.com Acked-By: Anton Ivanov anton.ivanov@cambridgegreys.com Signed-off-by: Richard Weinberger richard@nod.at Signed-off-by: Sasha Levin sashal@kernel.org --- arch/um/os-Linux/file.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c index 5133e3afb96f7..3996937e2c0dd 100644 --- a/arch/um/os-Linux/file.c +++ b/arch/um/os-Linux/file.c @@ -8,6 +8,7 @@ #include <errno.h> #include <fcntl.h> #include <signal.h> +#include <linux/falloc.h> #include <sys/ioctl.h> #include <sys/mount.h> #include <sys/socket.h>
From: Nicolas Saenz Julienne nsaenzjulienne@suse.de
[ Upstream commit b1e7396a1d0e6af6806337fdaaa44098d6b3343c ]
Current mode validation impedes setting up some video modes which should be supported otherwise. Namely 1920x1200@60Hz.
Fix this by lowering the minimum HDMI state machine clock to pixel clock ratio allowed.
Fixes: 32e823c63e90 ("drm/vc4: Reject HDMI modes with too high of clocks.") Reported-by: Stefan Wahren stefan.wahren@i2se.com Suggested-by: Dave Stevenson dave.stevenson@raspberrypi.com Signed-off-by: Nicolas Saenz Julienne nsaenzjulienne@suse.de Signed-off-by: Maxime Ripard maxime@cerno.tech Link: https://patchwork.freedesktop.org/patch/msgid/20200326122001.22215-1-nsaenzj... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vc4/vc4_hdmi.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index 0853b980bcb31..d5f5ba4105241 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -681,11 +681,23 @@ static enum drm_mode_status vc4_hdmi_encoder_mode_valid(struct drm_encoder *crtc, const struct drm_display_mode *mode) { - /* HSM clock must be 108% of the pixel clock. Additionally, - * the AXI clock needs to be at least 25% of pixel clock, but - * HSM ends up being the limiting factor. + /* + * As stated in RPi's vc4 firmware "HDMI state machine (HSM) clock must + * be faster than pixel clock, infinitesimally faster, tested in + * simulation. Otherwise, exact value is unimportant for HDMI + * operation." This conflicts with bcm2835's vc4 documentation, which + * states HSM's clock has to be at least 108% of the pixel clock. + * + * Real life tests reveal that vc4's firmware statement holds up, and + * users are able to use pixel clocks closer to HSM's, namely for + * 1920x1200@60Hz. So it was decided to have leave a 1% margin between + * both clocks. Which, for RPi0-3 implies a maximum pixel clock of + * 162MHz. + * + * Additionally, the AXI clock needs to be at least 25% of + * pixel clock, but HSM ends up being the limiting factor. */ - if (mode->clock > HSM_CLOCK_FREQ / (1000 * 108 / 100)) + if (mode->clock > HSM_CLOCK_FREQ / (1000 * 101 / 100)) return MODE_CLOCK_HIGH;
return MODE_OK;
From: Jean-Philippe Brucker jean-philippe@linaro.org
[ Upstream commit 7062af3ed2ba451029e3733d9f677c68f5ea9e77 ]
Calling viommu_domain_free() on a domain that hasn't been finalised (not attached to any device, for example) can currently cause an Oops, because we attempt to call ida_free() on ID 0, which may either be unallocated or used by another domain.
Only initialise the vdomain->viommu pointer, which denotes a finalised domain, at the end of a successful viommu_domain_finalise().
Fixes: edcd69ab9a32 ("iommu: Add virtio-iommu driver") Reported-by: Eric Auger eric.auger@redhat.com Signed-off-by: Jean-Philippe Brucker jean-philippe@linaro.org Reviewed-by: Robin Murphy robin.murphy@arm.com Link: https://lore.kernel.org/r/20200326093558.2641019-3-jean-philippe@linaro.org Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iommu/virtio-iommu.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c index 3ea9d76829995..6c340a4f4fd28 100644 --- a/drivers/iommu/virtio-iommu.c +++ b/drivers/iommu/virtio-iommu.c @@ -614,18 +614,20 @@ static int viommu_domain_finalise(struct viommu_dev *viommu, int ret; struct viommu_domain *vdomain = to_viommu_domain(domain);
- vdomain->viommu = viommu; - vdomain->map_flags = viommu->map_flags; + ret = ida_alloc_range(&viommu->domain_ids, viommu->first_domain, + viommu->last_domain, GFP_KERNEL); + if (ret < 0) + return ret; + + vdomain->id = (unsigned int)ret;
domain->pgsize_bitmap = viommu->pgsize_bitmap; domain->geometry = viommu->geometry;
- ret = ida_alloc_range(&viommu->domain_ids, viommu->first_domain, - viommu->last_domain, GFP_KERNEL); - if (ret >= 0) - vdomain->id = (unsigned int)ret; + vdomain->map_flags = viommu->map_flags; + vdomain->viommu = viommu;
- return ret > 0 ? 0 : ret; + return 0; }
static void viommu_domain_free(struct iommu_domain *domain)
From: Jacob Pan jacob.jun.pan@linux.intel.com
[ Upstream commit 902baf61adf6b187f0a6b789e70d788ea71ff5bc ]
Move canonical address check before mmget_not_zero() to avoid mm reference leak.
Fixes: 9d8c3af31607 ("iommu/vt-d: IOMMU Page Request needs to check if address is canonical.") Signed-off-by: Jacob Pan jacob.jun.pan@linux.intel.com Acked-by: Lu Baolu baolu.lu@linux.intel.com Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iommu/intel-svm.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c index 518d0b2d12afd..3020506180c10 100644 --- a/drivers/iommu/intel-svm.c +++ b/drivers/iommu/intel-svm.c @@ -583,14 +583,15 @@ static irqreturn_t prq_event_thread(int irq, void *d) * any faults on kernel addresses. */ if (!svm->mm) goto bad_req; - /* If the mm is already defunct, don't handle faults. */ - if (!mmget_not_zero(svm->mm)) - goto bad_req;
/* If address is not canonical, return invalid response */ if (!is_canonical_address(address)) goto bad_req;
+ /* If the mm is already defunct, don't handle faults. */ + if (!mmget_not_zero(svm->mm)) + goto bad_req; + down_read(&svm->mm->mmap_sem); vma = find_extend_vma(svm->mm, address); if (!vma || address < vma->vm_start)
From: Olga Kornievskaia olga.kornievskaia@gmail.com
[ Upstream commit df513a7711712758b9cb1a48d86712e7e1ee03f4 ]
Ever since commit 2c94b8eca1a2 ("SUNRPC: Use au_rslack when computing reply buffer size"). It changed how "req->rq_rcvsize" is calculated. It used to use au_cslack value which was nice and large and changed it to au_rslack value which turns out to be too small.
Since 5.1, v3 mount with sec=krb5p fails against an Ontap server because client's receive buffer it too small.
For gss krb5p, we need to account for the mic token in the verifier, and the wrap token in the wrap token.
RFC 4121 defines: mic token Octet no Name Description -------------------------------------------------------------- 0..1 TOK_ID Identification field. Tokens emitted by GSS_GetMIC() contain the hex value 04 04 expressed in big-endian order in this field. 2 Flags Attributes field, as described in section 4.2.2. 3..7 Filler Contains five octets of hex value FF. 8..15 SND_SEQ Sequence number field in clear text, expressed in big-endian order. 16..last SGN_CKSUM Checksum of the "to-be-signed" data and octet 0..15, as described in section 4.2.4.
that's 16bytes (GSS_KRB5_TOK_HDR_LEN) + chksum
wrap token Octet no Name Description -------------------------------------------------------------- 0..1 TOK_ID Identification field. Tokens emitted by GSS_Wrap() contain the hex value 05 04 expressed in big-endian order in this field. 2 Flags Attributes field, as described in section 4.2.2. 3 Filler Contains the hex value FF. 4..5 EC Contains the "extra count" field, in big- endian order as described in section 4.2.3. 6..7 RRC Contains the "right rotation count" in big- endian order, as described in section 4.2.5. 8..15 SND_SEQ Sequence number field in clear text, expressed in big-endian order. 16..last Data Encrypted data for Wrap tokens with confidentiality, or plaintext data followed by the checksum for Wrap tokens without confidentiality, as described in section 4.2.4.
Also 16bytes of header (GSS_KRB5_TOK_HDR_LEN), encrypted data, and cksum (other things like padding)
RFC 3961 defines known cksum sizes: Checksum type sumtype checksum section or value size reference --------------------------------------------------------------------- CRC32 1 4 6.1.3 rsa-md4 2 16 6.1.2 rsa-md4-des 3 24 6.2.5 des-mac 4 16 6.2.7 des-mac-k 5 8 6.2.8 rsa-md4-des-k 6 16 6.2.6 rsa-md5 7 16 6.1.1 rsa-md5-des 8 24 6.2.4 rsa-md5-des3 9 24 ?? sha1 (unkeyed) 10 20 ?? hmac-sha1-des3-kd 12 20 6.3 hmac-sha1-des3 13 20 ?? sha1 (unkeyed) 14 20 ?? hmac-sha1-96-aes128 15 20 [KRB5-AES] hmac-sha1-96-aes256 16 20 [KRB5-AES] [reserved] 0x8003 ? [GSS-KRB5]
Linux kernel now mainly supports type 15,16 so max cksum size is 20bytes. (GSS_KRB5_MAX_CKSUM_LEN)
Re-use already existing define of GSS_KRB5_MAX_SLACK_NEEDED that's used for encoding the gss_wrap tokens (same tokens are used in reply).
Fixes: 2c94b8eca1a2 ("SUNRPC: Use au_rslack when computing reply buffer size") Signed-off-by: Olga Kornievskaia kolga@netapp.com Reviewed-by: Chuck Lever chuck.lever@oracle.com Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/sunrpc/auth_gss/auth_gss.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index d75fddca44c94..f9e1a7e61eda0 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c @@ -20,6 +20,7 @@ #include <linux/sunrpc/clnt.h> #include <linux/sunrpc/auth.h> #include <linux/sunrpc/auth_gss.h> +#include <linux/sunrpc/gss_krb5.h> #include <linux/sunrpc/svcauth_gss.h> #include <linux/sunrpc/gss_err.h> #include <linux/workqueue.h> @@ -1050,7 +1051,7 @@ gss_create_new(const struct rpc_auth_create_args *args, struct rpc_clnt *clnt) goto err_put_mech; auth = &gss_auth->rpc_auth; auth->au_cslack = GSS_CRED_SLACK >> 2; - auth->au_rslack = GSS_VERF_SLACK >> 2; + auth->au_rslack = GSS_KRB5_MAX_SLACK_NEEDED >> 2; auth->au_verfsize = GSS_VERF_SLACK >> 2; auth->au_ralign = GSS_VERF_SLACK >> 2; auth->au_flags = 0;
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit 44a52022e7f15cbaab957df1c14f7a4f527ef7cf ]
When EXT2_ATTR_DEBUG is not defined, modify the 2 debug macros to use the no_printk() macro instead of <nothing>. This fixes gcc warnings when -Wextra is used:
../fs/ext2/xattr.c:252:42: warning: suggest braces around empty body in an ‘if’ statement [-Wempty-body] ../fs/ext2/xattr.c:258:42: warning: suggest braces around empty body in an ‘if’ statement [-Wempty-body] ../fs/ext2/xattr.c:330:42: warning: suggest braces around empty body in an ‘if’ statement [-Wempty-body] ../fs/ext2/xattr.c:872:45: warning: suggest braces around empty body in an ‘else’ statement [-Wempty-body]
I have verified that the only object code change (with gcc 7.5.0) is the reversal of some instructions from 'cmp a,b' to 'cmp b,a'.
Link: https://lore.kernel.org/r/e18a7395-61fb-2093-18e8-ed4f8cf56248@infradead.org Signed-off-by: Randy Dunlap rdunlap@infradead.org Cc: Jan Kara jack@suse.com Cc: linux-ext4@vger.kernel.org Signed-off-by: Jan Kara jack@suse.cz Signed-off-by: Sasha Levin sashal@kernel.org --- fs/ext2/xattr.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c index 0456bc990b5ee..b91f99d9482e9 100644 --- a/fs/ext2/xattr.c +++ b/fs/ext2/xattr.c @@ -56,6 +56,7 @@
#include <linux/buffer_head.h> #include <linux/init.h> +#include <linux/printk.h> #include <linux/slab.h> #include <linux/mbcache.h> #include <linux/quotaops.h> @@ -84,8 +85,8 @@ printk("\n"); \ } while (0) #else -# define ea_idebug(f...) -# define ea_bdebug(f...) +# define ea_idebug(inode, f...) no_printk(f) +# define ea_bdebug(bh, f...) no_printk(f) #endif
static int ext2_xattr_set2(struct inode *, struct buffer_head *,
From: Qian Cai cai@lca.pw
[ Upstream commit c6f4ebdeba4cff590594df931ff1ee610c426431 ]
dmar_find_atsr() calls list_for_each_entry_rcu() outside of an RCU read side critical section but with dmar_global_lock held. Silence this false positive.
drivers/iommu/intel-iommu.c:4504 RCU-list traversed in non-reader section!! 1 lock held by swapper/0/1: #0: ffffffff9755bee8 (dmar_global_lock){+.+.}, at: intel_iommu_init+0x1a6/0xe19
Call Trace: dump_stack+0xa4/0xfe lockdep_rcu_suspicious+0xeb/0xf5 dmar_find_atsr+0x1ab/0x1c0 dmar_parse_one_atsr+0x64/0x220 dmar_walk_remapping_entries+0x130/0x380 dmar_table_init+0x166/0x243 intel_iommu_init+0x1ab/0xe19 pci_iommu_init+0x1a/0x44 do_one_initcall+0xae/0x4d0 kernel_init_freeable+0x412/0x4c5 kernel_init+0x19/0x193
Signed-off-by: Qian Cai cai@lca.pw Acked-by: Lu Baolu baolu.lu@linux.intel.com Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iommu/intel-iommu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 0d922eeae3579..773ac2b0d6068 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -4335,7 +4335,8 @@ static struct dmar_atsr_unit *dmar_find_atsr(struct acpi_dmar_atsr *atsr) struct dmar_atsr_unit *atsru; struct acpi_dmar_atsr *tmp;
- list_for_each_entry_rcu(atsru, &dmar_atsr_units, list) { + list_for_each_entry_rcu(atsru, &dmar_atsr_units, list, + dmar_rcu_check()) { tmp = (struct acpi_dmar_atsr *)atsru->hdr; if (atsr->segment != tmp->segment) continue;
From: Jacob Pan jacob.jun.pan@linux.intel.com
[ Upstream commit 52355fb1919ef7ed9a38e0f3de6e928de1f57217 ]
Intel VT-d might support PRS (Page Reqest Support) when it's running in the scalable mode. Each page request descriptor occupies 32 bytes and is 32-bytes aligned. The page request descriptor offset mask should be 32-bytes aligned.
Fixes: 5b438f4ba315d ("iommu/vt-d: Support page request in scalable mode") Signed-off-by: Lu Baolu baolu.lu@linux.intel.com Signed-off-by: Liu Yi L yi.l.liu@intel.com Signed-off-by: Jacob Pan jacob.jun.pan@linux.intel.com Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iommu/intel-svm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c index 3020506180c10..1d3816cd65d57 100644 --- a/drivers/iommu/intel-svm.c +++ b/drivers/iommu/intel-svm.c @@ -502,7 +502,7 @@ struct page_req_dsc { u64 priv_data[2]; };
-#define PRQ_RING_MASK ((0x1000 << PRQ_ORDER) - 0x10) +#define PRQ_RING_MASK ((0x1000 << PRQ_ORDER) - 0x20)
static bool access_error(struct vm_area_struct *vma, struct page_req_dsc *req) {
From: Jan Kara jack@suse.cz
[ Upstream commit 32302085a8d90859c40cf1a5e8313f575d06ec75 ]
Fix a debug-only build error in ext2/xattr.c:
When building without extra debugging, (and with another patch that uses no_printk() instead of <empty> for the ext2-xattr debug-print macros, this build error happens:
../fs/ext2/xattr.c: In function ‘ext2_xattr_cache_insert’: ../fs/ext2/xattr.c:869:18: error: ‘ext2_xattr_cache’ undeclared (first use in this function); did you mean ‘ext2_xattr_list’? atomic_read(&ext2_xattr_cache->c_entry_count));
Fix the problem by removing cached entry count from the debug message since otherwise we'd have to export the mbcache structure just for that.
Fixes: be0726d33cb8 ("ext2: convert to mbcache2") Reported-by: Randy Dunlap rdunlap@infradead.org Signed-off-by: Jan Kara jack@suse.cz Signed-off-by: Sasha Levin sashal@kernel.org --- fs/ext2/xattr.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c index b91f99d9482e9..62acbe27d8bf4 100644 --- a/fs/ext2/xattr.c +++ b/fs/ext2/xattr.c @@ -865,8 +865,7 @@ ext2_xattr_cache_insert(struct mb_cache *cache, struct buffer_head *bh) true); if (error) { if (error == -EBUSY) { - ea_bdebug(bh, "already in cache (%d cache entries)", - atomic_read(&ext2_xattr_cache->c_entry_count)); + ea_bdebug(bh, "already in cache"); error = 0; } } else
From: Chuck Lever chuck.lever@oracle.com
[ Upstream commit 4047aa909c4a40fceebc36fff708d465a4d3c6e2 ]
xdr_buf_read_mic() tries to find unused contiguous space in a received xdr_buf in order to linearize the checksum for the call to gss_verify_mic. However, the corner cases in this code are numerous and we seem to keep missing them. I've just hit yet another buffer overrun related to it.
This overrun is at the end of xdr_buf_read_mic():
1284 if (buf->tail[0].iov_len != 0) 1285 mic->data = buf->tail[0].iov_base + buf->tail[0].iov_len; 1286 else 1287 mic->data = buf->head[0].iov_base + buf->head[0].iov_len; 1288 __read_bytes_from_xdr_buf(&subbuf, mic->data, mic->len); 1289 return 0;
This logic assumes the transport has set the length of the tail based on the size of the received message. base + len is then supposed to be off the end of the message but still within the actual buffer.
In fact, the length of the tail is set by the upper layer when the Call is encoded so that the end of the tail is actually the end of the allocated buffer itself. This causes the logic above to set mic->data to point past the end of the receive buffer.
The "mic->data = head" arm of this if statement is no less fragile.
As near as I can tell, this has been a problem forever. I'm not sure that minimizing au_rslack recently changed this pathology much.
So instead, let's use a more straightforward approach: kmalloc a separate buffer to linearize the checksum. This is similar to how gss_validate() currently works.
Coming back to this code, I had some trouble understanding what was going on. So I've cleaned up the variable naming and added a few comments that point back to the XDR definition in RFC 2203 to help guide future spelunkers, including myself.
As an added clean up, the functionality that was in xdr_buf_read_mic() is folded directly into gss_unwrap_resp_integ(), as that is its only caller.
Signed-off-by: Chuck Lever chuck.lever@oracle.com Reviewed-by: Benjamin Coddington bcodding@redhat.com Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/sunrpc/auth_gss/auth_gss.c | 77 +++++++++++++++++++++++++--------- 1 file changed, 58 insertions(+), 19 deletions(-)
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index f9e1a7e61eda0..ff5fcb3e12084 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c @@ -1935,35 +1935,69 @@ gss_unwrap_resp_auth(struct rpc_cred *cred) return 0; }
+/* + * RFC 2203, Section 5.3.2.2 + * + * struct rpc_gss_integ_data { + * opaque databody_integ<>; + * opaque checksum<>; + * }; + * + * struct rpc_gss_data_t { + * unsigned int seq_num; + * proc_req_arg_t arg; + * }; + */ static int gss_unwrap_resp_integ(struct rpc_task *task, struct rpc_cred *cred, struct gss_cl_ctx *ctx, struct rpc_rqst *rqstp, struct xdr_stream *xdr) { - struct xdr_buf integ_buf, *rcv_buf = &rqstp->rq_rcv_buf; - u32 data_offset, mic_offset, integ_len, maj_stat; + struct xdr_buf gss_data, *rcv_buf = &rqstp->rq_rcv_buf; struct rpc_auth *auth = cred->cr_auth; + u32 len, offset, seqno, maj_stat; struct xdr_netobj mic; - __be32 *p; + int ret;
- p = xdr_inline_decode(xdr, 2 * sizeof(*p)); - if (unlikely(!p)) + ret = -EIO; + mic.data = NULL; + + /* opaque databody_integ<>; */ + if (xdr_stream_decode_u32(xdr, &len)) goto unwrap_failed; - integ_len = be32_to_cpup(p++); - if (integ_len & 3) + if (len & 3) goto unwrap_failed; - data_offset = (u8 *)(p) - (u8 *)rcv_buf->head[0].iov_base; - mic_offset = integ_len + data_offset; - if (mic_offset > rcv_buf->len) + offset = rcv_buf->len - xdr_stream_remaining(xdr); + if (xdr_stream_decode_u32(xdr, &seqno)) goto unwrap_failed; - if (be32_to_cpup(p) != rqstp->rq_seqno) + if (seqno != rqstp->rq_seqno) goto bad_seqno; + if (xdr_buf_subsegment(rcv_buf, &gss_data, offset, len)) + goto unwrap_failed;
- if (xdr_buf_subsegment(rcv_buf, &integ_buf, data_offset, integ_len)) + /* + * The xdr_stream now points to the beginning of the + * upper layer payload, to be passed below to + * rpcauth_unwrap_resp_decode(). The checksum, which + * follows the upper layer payload in @rcv_buf, is + * located and parsed without updating the xdr_stream. + */ + + /* opaque checksum<>; */ + offset += len; + if (xdr_decode_word(rcv_buf, offset, &len)) + goto unwrap_failed; + offset += sizeof(__be32); + if (offset + len > rcv_buf->len) goto unwrap_failed; - if (xdr_buf_read_mic(rcv_buf, &mic, mic_offset)) + mic.len = len; + mic.data = kmalloc(len, GFP_NOFS); + if (!mic.data) + goto unwrap_failed; + if (read_bytes_from_xdr_buf(rcv_buf, offset, mic.data, mic.len)) goto unwrap_failed; - maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &integ_buf, &mic); + + maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &gss_data, &mic); if (maj_stat == GSS_S_CONTEXT_EXPIRED) clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); if (maj_stat != GSS_S_COMPLETE) @@ -1971,16 +2005,21 @@ gss_unwrap_resp_integ(struct rpc_task *task, struct rpc_cred *cred,
auth->au_rslack = auth->au_verfsize + 2 + 1 + XDR_QUADLEN(mic.len); auth->au_ralign = auth->au_verfsize + 2; - return 0; + ret = 0; + +out: + kfree(mic.data); + return ret; + unwrap_failed: trace_rpcgss_unwrap_failed(task); - return -EIO; + goto out; bad_seqno: - trace_rpcgss_bad_seqno(task, rqstp->rq_seqno, be32_to_cpup(p)); - return -EIO; + trace_rpcgss_bad_seqno(task, rqstp->rq_seqno, seqno); + goto out; bad_mic: trace_rpcgss_verify_mic(task, maj_stat); - return -EIO; + goto out; }
static int
From: Guo Ren guoren@linux.alibaba.com
[ Upstream commit 12879bda3c2a974b7e4fe199a9c21f0c5f6bca04 ]
WARNING: vmlinux.o(.text+0x2366): Section mismatch in reference from the function csky_start_secondary() to the function .init.text:init_fpu()
The function csky_start_secondary() references the function __init init_fpu(). This is often because csky_start_secondary lacks a __init annotation or the annotation of init_fpu is wrong.
Reported-by: Lu Chongzhi chongzhi.lcz@alibaba-inc.com Signed-off-by: Guo Ren guoren@linux.alibaba.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/csky/abiv2/fpu.c | 5 ----- arch/csky/abiv2/inc/abi/fpu.h | 3 ++- arch/csky/kernel/smp.c | 3 +++ 3 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/arch/csky/abiv2/fpu.c b/arch/csky/abiv2/fpu.c index 86d187d4e5af1..5acc5c2e544e1 100644 --- a/arch/csky/abiv2/fpu.c +++ b/arch/csky/abiv2/fpu.c @@ -10,11 +10,6 @@ #define MTCR_DIST 0xC0006420 #define MFCR_DIST 0xC0006020
-void __init init_fpu(void) -{ - mtcr("cr<1, 2>", 0); -} - /* * fpu_libc_helper() is to help libc to excute: * - mfcr %a, cr<1, 2> diff --git a/arch/csky/abiv2/inc/abi/fpu.h b/arch/csky/abiv2/inc/abi/fpu.h index 22ca3cf2794a1..09e2700a36936 100644 --- a/arch/csky/abiv2/inc/abi/fpu.h +++ b/arch/csky/abiv2/inc/abi/fpu.h @@ -9,7 +9,8 @@
int fpu_libc_helper(struct pt_regs *regs); void fpu_fpe(struct pt_regs *regs); -void __init init_fpu(void); + +static inline void init_fpu(void) { mtcr("cr<1, 2>", 0); }
void save_to_user_fp(struct user_fp *user_fp); void restore_from_user_fp(struct user_fp *user_fp); diff --git a/arch/csky/kernel/smp.c b/arch/csky/kernel/smp.c index de61feb4b6df2..b5c5bc3afeb5c 100644 --- a/arch/csky/kernel/smp.c +++ b/arch/csky/kernel/smp.c @@ -22,6 +22,9 @@ #include <asm/sections.h> #include <asm/mmu_context.h> #include <asm/pgalloc.h> +#ifdef CONFIG_CPU_HAS_FPU +#include <abi/fpu.h> +#endif
struct ipi_data_struct { unsigned long bits ____cacheline_aligned;
From: Jeffery Miller jmiller@neverware.com
[ Upstream commit e42fe5b29ac07210297e75f36deefe54edbdbf80 ]
The Intel Compute Stick `STK1A32SC` can have a system vendor of "Intel(R) Client Systems". Broaden the Intel Compute Stick DMI checks so that they match "Intel Corporation" as well as "Intel(R) Client Systems".
This fixes an issue where the STK1A32SC compute sticks were still exposing a battery with the existing blacklist entry.
Signed-off-by: Jeffery Miller jmiller@neverware.com Reviewed-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Sebastian Reichel sebastian.reichel@collabora.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/power/supply/axp288_fuel_gauge.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/power/supply/axp288_fuel_gauge.c b/drivers/power/supply/axp288_fuel_gauge.c index e1bc4e6e6f30e..f40fa0e63b6e5 100644 --- a/drivers/power/supply/axp288_fuel_gauge.c +++ b/drivers/power/supply/axp288_fuel_gauge.c @@ -706,14 +706,14 @@ static const struct dmi_system_id axp288_fuel_gauge_blacklist[] = { { /* Intel Cherry Trail Compute Stick, Windows version */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), + DMI_MATCH(DMI_SYS_VENDOR, "Intel"), DMI_MATCH(DMI_PRODUCT_NAME, "STK1AW32SC"), }, }, { /* Intel Cherry Trail Compute Stick, version without an OS */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), + DMI_MATCH(DMI_SYS_VENDOR, "Intel"), DMI_MATCH(DMI_PRODUCT_NAME, "STK1A32SC"), }, },
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit f84afbdd3a9e5e10633695677b95422572f920dc ]
The "cmd" comes from the user and it can be up to 255. It it's more than the number of bits in long, it results out of bounds read when we check test_bit(cmd, &cmd_mask). The highest valid value for "cmd" is ND_CMD_CALL (10) so I added a compare against that.
Fixes: 62232e45f4a2 ("libnvdimm: control (ioctl) messages for nvdimm_bus and nvdimm devices") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Link: https://lore.kernel.org/r/20200225162055.amtosfy7m35aivxg@kili.mountain Signed-off-by: Dan Williams dan.j.williams@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvdimm/bus.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c index d47412dcdf38d..5e5c6aafc070b 100644 --- a/drivers/nvdimm/bus.c +++ b/drivers/nvdimm/bus.c @@ -1010,8 +1010,10 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm, return -EFAULT; }
- if (!desc || (desc->out_num + desc->in_num == 0) || - !test_bit(cmd, &cmd_mask)) + if (!desc || + (desc->out_num + desc->in_num == 0) || + cmd > ND_CMD_CALL || + !test_bit(cmd, &cmd_mask)) return -ENOTTY;
/* fail write commands (when read-only) */
From: Adrian Huang ahuang12@lenovo.com
[ Upstream commit c20f36534666e37858a14e591114d93cc1be0d34 ]
The SPA of the GCR3 table root pointer[51:31] masks 20 bits. However, this requires 21 bits (Please see the AMD IOMMU specification). This leads to the potential failure when the bit 51 of SPA of the GCR3 table root pointer is 1'.
Signed-off-by: Adrian Huang ahuang12@lenovo.com Fixes: 52815b75682e2 ("iommu/amd: Add support for IOMMUv2 domain mode") Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iommu/amd_iommu_types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h index daeabd98c60e2..0679896b9e2e1 100644 --- a/drivers/iommu/amd_iommu_types.h +++ b/drivers/iommu/amd_iommu_types.h @@ -348,7 +348,7 @@
#define DTE_GCR3_VAL_A(x) (((x) >> 12) & 0x00007ULL) #define DTE_GCR3_VAL_B(x) (((x) >> 15) & 0x0ffffULL) -#define DTE_GCR3_VAL_C(x) (((x) >> 31) & 0xfffffULL) +#define DTE_GCR3_VAL_C(x) (((x) >> 31) & 0x1fffffULL)
#define DTE_GCR3_INDEX_A 0 #define DTE_GCR3_INDEX_B 1
From: Chao Yu yuchao0@huawei.com
[ Upstream commit dc5a941223edd803f476a153abd950cc3a83c3e1 ]
There is a race condition that we may miss to wait for all node pages writeback, fix it.
- fsync() - shrink - f2fs_do_sync_file - __write_node_page - set_page_writeback(page#0) : remove DIRTY/TOWRITE flag - f2fs_fsync_node_pages : won't find page #0 as TOWRITE flag was removeD - f2fs_wait_on_node_pages_writeback : wont' wait page #0 writeback as it was not in fsync_node_list list. - f2fs_add_fsync_node_entry
Fixes: 50fa53eccf9f ("f2fs: fix to avoid broken of dnode block list") Signed-off-by: Chao Yu yuchao0@huawei.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/node.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 8b66bc4c004b6..f14401a77d601 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -1562,15 +1562,16 @@ static int __write_node_page(struct page *page, bool atomic, bool *submitted, if (atomic && !test_opt(sbi, NOBARRIER)) fio.op_flags |= REQ_PREFLUSH | REQ_FUA;
- set_page_writeback(page); - ClearPageError(page); - + /* should add to global list before clearing PAGECACHE status */ if (f2fs_in_warm_node_list(sbi, page)) { seq = f2fs_add_fsync_node_entry(sbi, page); if (seq_id) *seq_id = seq; }
+ set_page_writeback(page); + ClearPageError(page); + fio.old_blkaddr = ni.blk_addr; f2fs_do_write_node_page(nid, &fio); set_node_addr(sbi, &ni, fio.new_blkaddr, is_fsync_dnode(page));
From: Ben Skeggs bskeggs@redhat.com
[ Upstream commit 028a12f5aa829b4ba6ac011530b815eda4960e89 ]
Certain boards with GP107/GP108 chipsets hang (often, but randomly) for unknown reasons during GR initialisation.
The first tell-tale symptom of this issue is:
nouveau 0000:01:00.0: bus: MMIO read of 00000000 FAULT at 409800 [ TIMEOUT ]
appearing in dmesg, likely followed by many other failures being logged.
Karol found this WAR for the issue a while back, but efforts to isolate the root cause and proper fix have not yielded success so far. I've modified the original patch to include a few more details, limit it to GP107/GP108 by default, and added a config option to override this choice.
Signed-off-by: Ben Skeggs bskeggs@redhat.com Reviewed-by: Karol Herbst kherbst@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+)
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index c578deb5867a8..c71606a45d1de 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -1988,8 +1988,34 @@ gf100_gr_init_(struct nvkm_gr *base) { struct gf100_gr *gr = gf100_gr(base); struct nvkm_subdev *subdev = &base->engine.subdev; + struct nvkm_device *device = subdev->device; + bool reset = device->chipset == 0x137 || device->chipset == 0x138; u32 ret;
+ /* On certain GP107/GP108 boards, we trigger a weird issue where + * GR will stop responding to PRI accesses after we've asked the + * SEC2 RTOS to boot the GR falcons. This happens with far more + * frequency when cold-booting a board (ie. returning from D3). + * + * The root cause for this is not known and has proven difficult + * to isolate, with many avenues being dead-ends. + * + * A workaround was discovered by Karol, whereby putting GR into + * reset for an extended period right before initialisation + * prevents the problem from occuring. + * + * XXX: As RM does not require any such workaround, this is more + * of a hack than a true fix. + */ + reset = nvkm_boolopt(device->cfgopt, "NvGrResetWar", reset); + if (reset) { + nvkm_mask(device, 0x000200, 0x00001000, 0x00000000); + nvkm_rd32(device, 0x000200); + msleep(50); + nvkm_mask(device, 0x000200, 0x00001000, 0x00001000); + nvkm_rd32(device, 0x000200); + } + nvkm_pmu_pgob(gr->base.engine.subdev.device->pmu, false);
ret = nvkm_falcon_get(gr->fecs.falcon, subdev);
From: Florian Fainelli f.fainelli@gmail.com
commit d0802dc411f469569a537283b6f3833af47aece9 upstream.
Commit f949a12fd697 ("net: dsa: bcm_sf2: fix buffer overflow doing set_rxnfc") tried to fix the some user controlled buffer overflows in bcm_sf2_cfp_rule_set() and bcm_sf2_cfp_rule_del() but the fix was using CFP_NUM_RULES, which while it is correct not to overflow the bitmaps, is not representative of what the device actually supports. Correct that by using bcm_sf2_cfp_rule_size() instead.
The latter subtracts the number of rules by 1, so change the checks from greater than or equal to greater than accordingly.
Fixes: f949a12fd697 ("net: dsa: bcm_sf2: fix buffer overflow doing set_rxnfc") Signed-off-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/net/dsa/bcm_sf2_cfp.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
--- a/drivers/net/dsa/bcm_sf2_cfp.c +++ b/drivers/net/dsa/bcm_sf2_cfp.c @@ -882,17 +882,14 @@ static int bcm_sf2_cfp_rule_set(struct d fs->m_ext.data[1])) return -EINVAL;
- if (fs->location != RX_CLS_LOC_ANY && fs->location >= CFP_NUM_RULES) + if (fs->location != RX_CLS_LOC_ANY && + fs->location > bcm_sf2_cfp_rule_size(priv)) return -EINVAL;
if (fs->location != RX_CLS_LOC_ANY && test_bit(fs->location, priv->cfp.used)) return -EBUSY;
- if (fs->location != RX_CLS_LOC_ANY && - fs->location > bcm_sf2_cfp_rule_size(priv)) - return -EINVAL; - ret = bcm_sf2_cfp_rule_cmp(priv, port, fs); if (ret == 0) return -EEXIST; @@ -973,7 +970,7 @@ static int bcm_sf2_cfp_rule_del(struct b struct cfp_rule *rule; int ret;
- if (loc >= CFP_NUM_RULES) + if (loc > bcm_sf2_cfp_rule_size(priv)) return -EINVAL;
/* Refuse deleting unused rules, and those that are not unique since
From: Grygorii Strashko grygorii.strashko@ti.com
commit 9bb50ed7470944238ec8e30a94ef096caf9056ee upstream.
The commit 2e05ea5cdc1a ("dma-mapping: implement dma_map_single_attrs using dma_map_page_attrs") removed "dma_debug_page" enum, but missed to update type2name string table. This causes incorrect displaying of dma allocation type. Fix it by removing "page" string from type2name string table and switch to use named initializers.
Before (dma_alloc_coherent()): k3-ringacc 4b800000.ringacc: scather-gather idx 2208 P=d1140000 N=d114 D=d1140000 L=40 DMA_BIDIRECTIONAL dma map error check not applicable k3-ringacc 4b800000.ringacc: scather-gather idx 2216 P=d1150000 N=d115 D=d1150000 L=40 DMA_BIDIRECTIONAL dma map error check not applicable
After: k3-ringacc 4b800000.ringacc: coherent idx 2208 P=d1140000 N=d114 D=d1140000 L=40 DMA_BIDIRECTIONAL dma map error check not applicable k3-ringacc 4b800000.ringacc: coherent idx 2216 P=d1150000 N=d115 D=d1150000 L=40 DMA_BIDIRECTIONAL dma map error check not applicable
Fixes: 2e05ea5cdc1a ("dma-mapping: implement dma_map_single_attrs using dma_map_page_attrs") Signed-off-by: Grygorii Strashko grygorii.strashko@ti.com Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- kernel/dma/debug.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
--- a/kernel/dma/debug.c +++ b/kernel/dma/debug.c @@ -137,9 +137,12 @@ static const char *const maperr2str[] = [MAP_ERR_CHECKED] = "dma map error checked", };
-static const char *type2name[5] = { "single", "page", - "scather-gather", "coherent", - "resource" }; +static const char *type2name[] = { + [dma_debug_single] = "single", + [dma_debug_sg] = "scather-gather", + [dma_debug_coherent] = "coherent", + [dma_debug_resource] = "resource", +};
static const char *dir2name[4] = { "DMA_BIDIRECTIONAL", "DMA_TO_DEVICE", "DMA_FROM_DEVICE", "DMA_NONE" };
From: Dan Carpenter dan.carpenter@oracle.com
commit d3d19d6fc5736a798b118971935ce274f7deaa82 upstream.
The "fix" struct has a 2 byte hole after ->ywrapstep and the "fix = info->fix;" assignment doesn't necessarily clear it. It depends on the compiler. The solution is just to replace the assignment with an memcpy().
Fixes: 1f5e31d7e55a ("fbmem: don't call copy_from/to_user() with mutex held") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Cc: Andrew Morton akpm@linux-foundation.org Cc: Arnd Bergmann arnd@arndb.de Cc: "Eric W. Biederman" ebiederm@xmission.com Cc: Andrea Righi righi.andrea@gmail.com Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: Sam Ravnborg sam@ravnborg.org Cc: Maarten Lankhorst maarten.lankhorst@linux.intel.com Cc: Daniel Thompson daniel.thompson@linaro.org Cc: Peter Rosin peda@axentia.se Cc: Jani Nikula jani.nikula@intel.com Cc: Gerd Hoffmann kraxel@redhat.com Signed-off-by: Bartlomiej Zolnierkiewicz b.zolnierkie@samsung.com Link: https://patchwork.freedesktop.org/patch/msgid/20200113100132.ixpaymordi24n3a... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/video/fbdev/core/fbmem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -1110,7 +1110,7 @@ static long do_fb_ioctl(struct fb_info * break; case FBIOGET_FSCREENINFO: lock_fb_info(info); - fix = info->fix; + memcpy(&fix, &info->fix, sizeof(fix)); if (info->flags & FBINFO_HIDE_SMEM_START) fix.smem_start = 0; unlock_fb_info(info);
From: Jernej Skrabec jernej.skrabec@siol.net
commit da180322582bd9db07f29e6d4a2d170afde0703f upstream.
As it can be seen from DE2 manual, clock range is 0x10000.
Fix it.
Signed-off-by: Jernej Skrabec jernej.skrabec@siol.net Fixes: 73f122c82775 ("ARM: dts: sun8i: a83t: Add display pipeline") Fixes: 05a43a262d03 ("ARM: dts: sun8i: r40: Add HDMI pipeline") Fixes: 21b299209330 ("ARM: sun8i: v3s: add device nodes for DE2 display pipeline") Fixes: d8c6f1f0295c ("ARM: sun8i: h3/h5: add DE2 CCU device node for H3") [wens@csie.org: added fixes tags] Signed-off-by: Chen-Yu Tsai wens@csie.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/arm/boot/dts/sun8i-a83t.dtsi | 2 +- arch/arm/boot/dts/sun8i-r40.dtsi | 2 +- arch/arm/boot/dts/sun8i-v3s.dtsi | 2 +- arch/arm/boot/dts/sunxi-h3-h5.dtsi | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-)
--- a/arch/arm/boot/dts/sun8i-a83t.dtsi +++ b/arch/arm/boot/dts/sun8i-a83t.dtsi @@ -313,7 +313,7 @@
display_clocks: clock@1000000 { compatible = "allwinner,sun8i-a83t-de2-clk"; - reg = <0x01000000 0x100000>; + reg = <0x01000000 0x10000>; clocks = <&ccu CLK_BUS_DE>, <&ccu CLK_PLL_DE>; clock-names = "bus", --- a/arch/arm/boot/dts/sun8i-r40.dtsi +++ b/arch/arm/boot/dts/sun8i-r40.dtsi @@ -118,7 +118,7 @@ display_clocks: clock@1000000 { compatible = "allwinner,sun8i-r40-de2-clk", "allwinner,sun8i-h3-de2-clk"; - reg = <0x01000000 0x100000>; + reg = <0x01000000 0x10000>; clocks = <&ccu CLK_BUS_DE>, <&ccu CLK_DE>; clock-names = "bus", --- a/arch/arm/boot/dts/sun8i-v3s.dtsi +++ b/arch/arm/boot/dts/sun8i-v3s.dtsi @@ -105,7 +105,7 @@
display_clocks: clock@1000000 { compatible = "allwinner,sun8i-v3s-de2-clk"; - reg = <0x01000000 0x100000>; + reg = <0x01000000 0x10000>; clocks = <&ccu CLK_BUS_DE>, <&ccu CLK_DE>; clock-names = "bus", --- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi +++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi @@ -113,7 +113,7 @@
display_clocks: clock@1000000 { /* compatible is in per SoC .dtsi file */ - reg = <0x01000000 0x100000>; + reg = <0x01000000 0x10000>; clocks = <&ccu CLK_BUS_DE>, <&ccu CLK_DE>; clock-names = "bus",
From: Maxime Roussin-Bélanger maxime.roussinbelanger@gmail.com
commit 328b50e9a0ad1fe8accdf8c19923deebab5e0c01 upstream.
The chip is configured in 24 bit mode. The values read from it must always be treated as is. This fixes the issue by replacing the previous 16 bits value by a 24 bits buffer.
This changes affects the value output by previous version of the driver, since the least significant byte was missing. The upper half of 16 bit values previously output are now the upper half of a 24 bit value.
Fixes: e01e7eaf37d8 ("iio: light: introduce si1133")
Reported-by: Simon Goyette simon.goyette@gmail.com Co-authored-by: Guillaume Champagne champagne.guillaume.c@gmail.com Signed-off-by: Maxime Roussin-Bélanger maxime.roussinbelanger@gmail.com Signed-off-by: Guillaume Champagne champagne.guillaume.c@gmail.com Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/iio/light/si1133.c | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-)
--- a/drivers/iio/light/si1133.c +++ b/drivers/iio/light/si1133.c @@ -102,6 +102,9 @@ #define SI1133_INPUT_FRACTION_LOW 15 #define SI1133_LUX_OUTPUT_FRACTION 12 #define SI1133_LUX_BUFFER_SIZE 9 +#define SI1133_MEASURE_BUFFER_SIZE 3 + +#define SI1133_SIGN_BIT_INDEX 23
static const int si1133_scale_available[] = { 1, 2, 4, 8, 16, 32, 64, 128}; @@ -234,13 +237,13 @@ static const struct si1133_lux_coeff lux } };
-static int si1133_calculate_polynomial_inner(u32 input, u8 fraction, u16 mag, +static int si1133_calculate_polynomial_inner(s32 input, u8 fraction, u16 mag, s8 shift) { return ((input << fraction) / mag) << shift; }
-static int si1133_calculate_output(u32 x, u32 y, u8 x_order, u8 y_order, +static int si1133_calculate_output(s32 x, s32 y, u8 x_order, u8 y_order, u8 input_fraction, s8 sign, const struct si1133_coeff *coeffs) { @@ -276,7 +279,7 @@ static int si1133_calculate_output(u32 x * The algorithm is from: * https://siliconlabs.github.io/Gecko_SDK_Doc/efm32zg/html/si1133_8c_source.ht... */ -static int si1133_calc_polynomial(u32 x, u32 y, u8 input_fraction, u8 num_coeff, +static int si1133_calc_polynomial(s32 x, s32 y, u8 input_fraction, u8 num_coeff, const struct si1133_coeff *coeffs) { u8 x_order, y_order; @@ -614,7 +617,7 @@ static int si1133_measure(struct si1133_ { int err;
- __be16 resp; + u8 buffer[SI1133_MEASURE_BUFFER_SIZE];
err = si1133_set_adcmux(data, 0, chan->channel); if (err) @@ -625,12 +628,13 @@ static int si1133_measure(struct si1133_ if (err) return err;
- err = si1133_bulk_read(data, SI1133_REG_HOSTOUT(0), sizeof(resp), - (u8 *)&resp); + err = si1133_bulk_read(data, SI1133_REG_HOSTOUT(0), sizeof(buffer), + buffer); if (err) return err;
- *val = be16_to_cpu(resp); + *val = sign_extend32((buffer[0] << 16) | (buffer[1] << 8) | buffer[2], + SI1133_SIGN_BIT_INDEX);
return err; } @@ -704,9 +708,9 @@ static int si1133_get_lux(struct si1133_ { int err; int lux; - u32 high_vis; - u32 low_vis; - u32 ir; + s32 high_vis; + s32 low_vis; + s32 ir; u8 buffer[SI1133_LUX_BUFFER_SIZE];
/* Activate lux channels */ @@ -719,9 +723,16 @@ static int si1133_get_lux(struct si1133_ if (err) return err;
- high_vis = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2]; - low_vis = (buffer[3] << 16) | (buffer[4] << 8) | buffer[5]; - ir = (buffer[6] << 16) | (buffer[7] << 8) | buffer[8]; + high_vis = + sign_extend32((buffer[0] << 16) | (buffer[1] << 8) | buffer[2], + SI1133_SIGN_BIT_INDEX); + + low_vis = + sign_extend32((buffer[3] << 16) | (buffer[4] << 8) | buffer[5], + SI1133_SIGN_BIT_INDEX); + + ir = sign_extend32((buffer[6] << 16) | (buffer[7] << 8) | buffer[8], + SI1133_SIGN_BIT_INDEX);
if (high_vis > SI1133_ADC_THRESHOLD || ir > SI1133_ADC_THRESHOLD) lux = si1133_calc_polynomial(high_vis, ir,
From: Nathan Chancellor natechancellor@gmail.com
commit 93166f5f2e4dc593cff8ca77ef828ac6f148b0f3 upstream.
Clang warns:
../drivers/video/fbdev/core/fbmem.c:665:3: warning: misleading indentation; statement is not part of the previous 'else' [-Wmisleading-indentation] if (fb_logo.depth > 4 && depth > 4) { ^ ../drivers/video/fbdev/core/fbmem.c:661:2: note: previous statement is here else ^ ../drivers/video/fbdev/core/fbmem.c:1075:3: warning: misleading indentation; statement is not part of the previous 'if' [-Wmisleading-indentation] return ret; ^ ../drivers/video/fbdev/core/fbmem.c:1072:2: note: previous statement is here if (!ret) ^ 2 warnings generated.
This warning occurs because there are spaces before the tabs on these lines. Normalize the indentation in these functions so that it is consistent with the Linux kernel coding style and clang no longer warns.
Fixes: 1692b37c99d5 ("fbdev: Fix logo if logo depth is less than framebuffer depth") Link: https://github.com/ClangBuiltLinux/linux/issues/825 Signed-off-by: Nathan Chancellor natechancellor@gmail.com Reviewed-by: Nick Desaulniers ndesaulniers@google.com Signed-off-by: Bartlomiej Zolnierkiewicz b.zolnierkie@samsung.com Link: https://patchwork.freedesktop.org/patch/msgid/20191218030025.10064-1-natecha... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/video/fbdev/core/fbmem.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-)
--- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -662,20 +662,20 @@ int fb_prepare_logo(struct fb_info *info fb_logo.depth = 1;
- if (fb_logo.depth > 4 && depth > 4) { - switch (info->fix.visual) { - case FB_VISUAL_TRUECOLOR: - fb_logo.needs_truepalette = 1; - break; - case FB_VISUAL_DIRECTCOLOR: - fb_logo.needs_directpalette = 1; - fb_logo.needs_cmapreset = 1; - break; - case FB_VISUAL_PSEUDOCOLOR: - fb_logo.needs_cmapreset = 1; - break; - } - } + if (fb_logo.depth > 4 && depth > 4) { + switch (info->fix.visual) { + case FB_VISUAL_TRUECOLOR: + fb_logo.needs_truepalette = 1; + break; + case FB_VISUAL_DIRECTCOLOR: + fb_logo.needs_directpalette = 1; + fb_logo.needs_cmapreset = 1; + break; + case FB_VISUAL_PSEUDOCOLOR: + fb_logo.needs_cmapreset = 1; + break; + } + }
height = fb_logo.logo->height; if (fb_center_logo) @@ -1060,19 +1060,19 @@ fb_blank(struct fb_info *info, int blank struct fb_event event; int ret = -EINVAL;
- if (blank > FB_BLANK_POWERDOWN) - blank = FB_BLANK_POWERDOWN; + if (blank > FB_BLANK_POWERDOWN) + blank = FB_BLANK_POWERDOWN;
event.info = info; event.data = ␣
if (info->fbops->fb_blank) - ret = info->fbops->fb_blank(blank, info); + ret = info->fbops->fb_blank(blank, info);
if (!ret) fb_notifier_call_chain(FB_EVENT_BLANK, &event);
- return ret; + return ret; } EXPORT_SYMBOL(fb_blank);
From: Stephen Rothwell sfr@canb.auug.org.au
commit 3670664b5da555a2a481449b3baafff113b0ac35 upstream.
ev_byte_channel_send() assumes that its third argument is a 16 byte array. Some places where it is called it may not be (or we can't easily tell if it is). Newer compilers have started producing warnings about this, so make sure we actually pass a 16 byte array.
There may be more elegant solutions to this, but the driver is quite old and hasn't been updated in many years.
The warnings (from a powerpc allyesconfig build) are:
In file included from include/linux/byteorder/big_endian.h:5, from arch/powerpc/include/uapi/asm/byteorder.h:14, from include/asm-generic/bitops/le.h:6, from arch/powerpc/include/asm/bitops.h:250, from include/linux/bitops.h:29, from include/linux/kernel.h:12, from include/asm-generic/bug.h:19, from arch/powerpc/include/asm/bug.h:109, from include/linux/bug.h:5, from include/linux/mmdebug.h:5, from include/linux/gfp.h:5, from include/linux/slab.h:15, from drivers/tty/ehv_bytechan.c:24: drivers/tty/ehv_bytechan.c: In function ‘ehv_bc_udbg_putc’: arch/powerpc/include/asm/epapr_hcalls.h:298:20: warning: array subscript 1 is outside array bounds of ‘const char[1]’ [-Warray-bounds] 298 | r6 = be32_to_cpu(p[1]); include/uapi/linux/byteorder/big_endian.h:40:51: note: in definition of macro ‘__be32_to_cpu’ 40 | #define __be32_to_cpu(x) ((__force __u32)(__be32)(x)) | ^ arch/powerpc/include/asm/epapr_hcalls.h:298:7: note: in expansion of macro ‘be32_to_cpu’ 298 | r6 = be32_to_cpu(p[1]); | ^~~~~~~~~~~ drivers/tty/ehv_bytechan.c:166:13: note: while referencing ‘data’ 166 | static void ehv_bc_udbg_putc(char c) | ^~~~~~~~~~~~~~~~
Fixes: dcd83aaff1c8 ("tty/powerpc: introduce the ePAPR embedded hypervisor byte channel driver") Signed-off-by: Stephen Rothwell sfr@canb.auug.org.au Tested-by: Laurentiu Tudor laurentiu.tudor@nxp.com [mpe: Trim warnings from change log] Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20200109183912.5fcb52aa@canb.auug.org.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/tty/ehv_bytechan.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-)
--- a/drivers/tty/ehv_bytechan.c +++ b/drivers/tty/ehv_bytechan.c @@ -136,6 +136,21 @@ static int find_console_handle(void) return 1; }
+static unsigned int local_ev_byte_channel_send(unsigned int handle, + unsigned int *count, + const char *p) +{ + char buffer[EV_BYTE_CHANNEL_MAX_BYTES]; + unsigned int c = *count; + + if (c < sizeof(buffer)) { + memcpy(buffer, p, c); + memset(&buffer[c], 0, sizeof(buffer) - c); + p = buffer; + } + return ev_byte_channel_send(handle, count, p); +} + /*************************** EARLY CONSOLE DRIVER ***************************/
#ifdef CONFIG_PPC_EARLY_DEBUG_EHV_BC @@ -154,7 +169,7 @@ static void byte_channel_spin_send(const
do { count = 1; - ret = ev_byte_channel_send(CONFIG_PPC_EARLY_DEBUG_EHV_BC_HANDLE, + ret = local_ev_byte_channel_send(CONFIG_PPC_EARLY_DEBUG_EHV_BC_HANDLE, &count, &data); } while (ret == EV_EAGAIN); } @@ -221,7 +236,7 @@ static int ehv_bc_console_byte_channel_s while (count) { len = min_t(unsigned int, count, EV_BYTE_CHANNEL_MAX_BYTES); do { - ret = ev_byte_channel_send(handle, &len, s); + ret = local_ev_byte_channel_send(handle, &len, s); } while (ret == EV_EAGAIN); count -= len; s += len; @@ -401,7 +416,7 @@ static void ehv_bc_tx_dequeue(struct ehv CIRC_CNT_TO_END(bc->head, bc->tail, BUF_SIZE), EV_BYTE_CHANNEL_MAX_BYTES);
- ret = ev_byte_channel_send(bc->handle, &len, bc->buf + bc->tail); + ret = local_ev_byte_channel_send(bc->handle, &len, bc->buf + bc->tail);
/* 'len' is valid only if the return code is 0 or EV_EAGAIN */ if (!ret || (ret == EV_EAGAIN))
From: Paul E. McKenney paulmck@kernel.org
commit 80c503e0e68fbe271680ab48f0fe29bc034b01b7 upstream.
The __torture_print_stats() function in locktorture.c carefully initializes local variable "min" to statp[0].n_lock_acquired, but then compares it to statp[i].n_lock_fail. Given that the .n_lock_fail field should normally be zero, and given the initialization, it seems reasonable to display the maximum and minimum number acquisitions instead of miscomputing the maximum and minimum number of failures. This commit therefore switches from failures to acquisitions.
And this turns out to be not only a day-zero bug, but entirely my own fault. I hate it when that happens!
Fixes: 0af3fe1efa53 ("locktorture: Add a lock-torture kernel module") Reported-by: Will Deacon will@kernel.org Signed-off-by: Paul E. McKenney paulmck@kernel.org Acked-by: Will Deacon will@kernel.org Cc: Davidlohr Bueso dave@stgolabs.net Cc: Josh Triplett josh@joshtriplett.org Cc: Peter Zijlstra peterz@infradead.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- kernel/locking/locktorture.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
--- a/kernel/locking/locktorture.c +++ b/kernel/locking/locktorture.c @@ -697,10 +697,10 @@ static void __torture_print_stats(char * if (statp[i].n_lock_fail) fail = true; sum += statp[i].n_lock_acquired; - if (max < statp[i].n_lock_fail) - max = statp[i].n_lock_fail; - if (min > statp[i].n_lock_fail) - min = statp[i].n_lock_fail; + if (max < statp[i].n_lock_acquired) + max = statp[i].n_lock_acquired; + if (min > statp[i].n_lock_acquired) + min = statp[i].n_lock_acquired; } page += sprintf(page, "%s: Total: %lld Max/Min: %ld/%ld %s Fail: %d %s\n",
From: Christophe Kerello christophe.kerello@st.com
commit 009264605cdf1b12962c3a46f75818d05452e890 upstream.
This patch releases the resources allocated in nanddev_init function.
Fixes: a7ab085d7c16 ("mtd: rawnand: Initialize the nand_device object") Signed-off-by: Christophe Kerello christophe.kerello@st.com Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/1579767768-32295-1-git-send-email-christop... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/mtd/nand/raw/nand_base.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -5907,6 +5907,8 @@ void nand_cleanup(struct nand_chip *chip chip->ecc.algo == NAND_ECC_BCH) nand_bch_free((struct nand_bch_control *)chip->ecc.priv);
+ nanddev_cleanup(&chip->base); + /* Free bad block table memory */ kfree(chip->bbt); kfree(chip->data_buf);
From: Frieder Schrempf frieder.schrempf@kontron.de
commit 621a7b780bd8b7054647d53d5071961f2c9e0873 upstream.
When writing the bad block marker to the OOB area the access mode should be set to MTD_OPS_RAW as it is done for reading the marker. Currently this only works because req.mode is initialized to MTD_OPS_PLACE_OOB (0) and spinand_write_to_cache_op() checks for req.mode != MTD_OPS_AUTO_OOB.
Fix this by explicitly setting req.mode to MTD_OPS_RAW.
Fixes: 7529df465248 ("mtd: nand: Add core infrastructure to support SPI NANDs") Signed-off-by: Frieder Schrempf frieder.schrempf@kontron.de Reviewed-by: Boris Brezillon boris.brezillon@collabora.com Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/20200218100432.32433-3-frieder.schrempf@ko... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/mtd/nand/spi/core.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c @@ -609,6 +609,7 @@ static int spinand_markbad(struct nand_d .ooboffs = 0, .ooblen = sizeof(marker), .oobbuf.out = marker, + .mode = MTD_OPS_RAW, }; int ret;
From: Jonathan Neuschäfer j.neuschaefer@gmx.net
commit fb2511247dc4061fd122d0195838278a4a0b7b59 upstream.
cmdlinepart.c has been moved to drivers/mtd/parsers/.
Fixes: a3f12a35c91d ("mtd: parsers: Move CMDLINE parser") Signed-off-by: Jonathan Neuschäfer j.neuschaefer@gmx.net Signed-off-by: Jonathan Corbet corbet@lwn.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- Documentation/admin-guide/kernel-parameters.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -2741,7 +2741,7 @@ <name>,<region-number>[,<base>,<size>,<buswidth>,<altbuswidth>]
mtdparts= [MTD] - See drivers/mtd/cmdlinepart.c. + See drivers/mtd/parsers/cmdlinepart.c
multitce=off [PPC] This parameter disables the use of the pSeries firmware feature for updating multiple TCE entries
From: Dan Carpenter dan.carpenter@oracle.com
commit 4da0ea71ea934af18db4c63396ba2af1a679ef02 upstream.
This function is only called from lpddr_probe(). We free "lpddr" both here and in the caller, so it's a double free. The best place to free "lpddr" is in lpddr_probe() so let's delete this one.
Fixes: 8dc004395d5e ("[MTD] LPDDR qinfo probing.") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/20200228092554.o57igp3nqhyvf66t@kili.mount... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/mtd/lpddr/lpddr_cmds.c | 1 - 1 file changed, 1 deletion(-)
--- a/drivers/mtd/lpddr/lpddr_cmds.c +++ b/drivers/mtd/lpddr/lpddr_cmds.c @@ -68,7 +68,6 @@ struct mtd_info *lpddr_cmdset(struct map shared = kmalloc_array(lpddr->numchips, sizeof(struct flchip_shared), GFP_KERNEL); if (!shared) { - kfree(lpddr); kfree(mtd); return NULL; }
From: Wen Yang wenyang@linux.alibaba.com
commit 49c64df880570034308e4a9a49c4bc95cf8cdb33 upstream.
The variable 'name' is released multiple times in the error path, which may cause double free issues. This problem is avoided by adding a goto label to release the memory uniformly. And this change also makes the code a bit more cleaner.
Fixes: 4f678a58d335 ("mtd: fix memory leaks in phram_setup") Signed-off-by: Wen Yang wenyang@linux.alibaba.com Cc: Joern Engel joern@lazybastard.org Cc: Miquel Raynal miquel.raynal@bootlin.com Cc: Richard Weinberger richard@nod.at Cc: Vignesh Raghavendra vigneshr@ti.com Cc: linux-mtd@lists.infradead.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/20200318153156.25612-1-wenyang@linux.aliba... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/mtd/devices/phram.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
--- a/drivers/mtd/devices/phram.c +++ b/drivers/mtd/devices/phram.c @@ -243,22 +243,25 @@ static int phram_setup(const char *val)
ret = parse_num64(&start, token[1]); if (ret) { - kfree(name); parse_err("illegal start address\n"); + goto error; }
ret = parse_num64(&len, token[2]); if (ret) { - kfree(name); parse_err("illegal device length\n"); + goto error; }
ret = register_device(name, start, len); - if (!ret) - pr_info("%s device: %#llx at %#llx\n", name, len, start); - else - kfree(name); + if (ret) + goto error;
+ pr_info("%s device: %#llx at %#llx\n", name, len, start); + return 0; + +error: + kfree(name); return ret; }
From: Waiman Long longman@redhat.com
commit d3ec10aa95819bff18a0d936b18884c7816d0914 upstream.
A lockdep circular locking dependency report was seen when running a keyutils test:
[12537.027242] ====================================================== [12537.059309] WARNING: possible circular locking dependency detected [12537.088148] 4.18.0-147.7.1.el8_1.x86_64+debug #1 Tainted: G OE --------- - - [12537.125253] ------------------------------------------------------ [12537.153189] keyctl/25598 is trying to acquire lock: [12537.175087] 000000007c39f96c (&mm->mmap_sem){++++}, at: __might_fault+0xc4/0x1b0 [12537.208365] [12537.208365] but task is already holding lock: [12537.234507] 000000003de5b58d (&type->lock_class){++++}, at: keyctl_read_key+0x15a/0x220 [12537.270476] [12537.270476] which lock already depends on the new lock. [12537.270476] [12537.307209] [12537.307209] the existing dependency chain (in reverse order) is: [12537.340754] [12537.340754] -> #3 (&type->lock_class){++++}: [12537.367434] down_write+0x4d/0x110 [12537.385202] __key_link_begin+0x87/0x280 [12537.405232] request_key_and_link+0x483/0xf70 [12537.427221] request_key+0x3c/0x80 [12537.444839] dns_query+0x1db/0x5a5 [dns_resolver] [12537.468445] dns_resolve_server_name_to_ip+0x1e1/0x4d0 [cifs] [12537.496731] cifs_reconnect+0xe04/0x2500 [cifs] [12537.519418] cifs_readv_from_socket+0x461/0x690 [cifs] [12537.546263] cifs_read_from_socket+0xa0/0xe0 [cifs] [12537.573551] cifs_demultiplex_thread+0x311/0x2db0 [cifs] [12537.601045] kthread+0x30c/0x3d0 [12537.617906] ret_from_fork+0x3a/0x50 [12537.636225] [12537.636225] -> #2 (root_key_user.cons_lock){+.+.}: [12537.664525] __mutex_lock+0x105/0x11f0 [12537.683734] request_key_and_link+0x35a/0xf70 [12537.705640] request_key+0x3c/0x80 [12537.723304] dns_query+0x1db/0x5a5 [dns_resolver] [12537.746773] dns_resolve_server_name_to_ip+0x1e1/0x4d0 [cifs] [12537.775607] cifs_reconnect+0xe04/0x2500 [cifs] [12537.798322] cifs_readv_from_socket+0x461/0x690 [cifs] [12537.823369] cifs_read_from_socket+0xa0/0xe0 [cifs] [12537.847262] cifs_demultiplex_thread+0x311/0x2db0 [cifs] [12537.873477] kthread+0x30c/0x3d0 [12537.890281] ret_from_fork+0x3a/0x50 [12537.908649] [12537.908649] -> #1 (&tcp_ses->srv_mutex){+.+.}: [12537.935225] __mutex_lock+0x105/0x11f0 [12537.954450] cifs_call_async+0x102/0x7f0 [cifs] [12537.977250] smb2_async_readv+0x6c3/0xc90 [cifs] [12538.000659] cifs_readpages+0x120a/0x1e50 [cifs] [12538.023920] read_pages+0xf5/0x560 [12538.041583] __do_page_cache_readahead+0x41d/0x4b0 [12538.067047] ondemand_readahead+0x44c/0xc10 [12538.092069] filemap_fault+0xec1/0x1830 [12538.111637] __do_fault+0x82/0x260 [12538.129216] do_fault+0x419/0xfb0 [12538.146390] __handle_mm_fault+0x862/0xdf0 [12538.167408] handle_mm_fault+0x154/0x550 [12538.187401] __do_page_fault+0x42f/0xa60 [12538.207395] do_page_fault+0x38/0x5e0 [12538.225777] page_fault+0x1e/0x30 [12538.243010] [12538.243010] -> #0 (&mm->mmap_sem){++++}: [12538.267875] lock_acquire+0x14c/0x420 [12538.286848] __might_fault+0x119/0x1b0 [12538.306006] keyring_read_iterator+0x7e/0x170 [12538.327936] assoc_array_subtree_iterate+0x97/0x280 [12538.352154] keyring_read+0xe9/0x110 [12538.370558] keyctl_read_key+0x1b9/0x220 [12538.391470] do_syscall_64+0xa5/0x4b0 [12538.410511] entry_SYSCALL_64_after_hwframe+0x6a/0xdf [12538.435535] [12538.435535] other info that might help us debug this: [12538.435535] [12538.472829] Chain exists of: [12538.472829] &mm->mmap_sem --> root_key_user.cons_lock --> &type->lock_class [12538.472829] [12538.524820] Possible unsafe locking scenario: [12538.524820] [12538.551431] CPU0 CPU1 [12538.572654] ---- ---- [12538.595865] lock(&type->lock_class); [12538.613737] lock(root_key_user.cons_lock); [12538.644234] lock(&type->lock_class); [12538.672410] lock(&mm->mmap_sem); [12538.687758] [12538.687758] *** DEADLOCK *** [12538.687758] [12538.714455] 1 lock held by keyctl/25598: [12538.732097] #0: 000000003de5b58d (&type->lock_class){++++}, at: keyctl_read_key+0x15a/0x220 [12538.770573] [12538.770573] stack backtrace: [12538.790136] CPU: 2 PID: 25598 Comm: keyctl Kdump: loaded Tainted: G [12538.844855] Hardware name: HP ProLiant DL360 Gen9/ProLiant DL360 Gen9, BIOS P89 12/27/2015 [12538.881963] Call Trace: [12538.892897] dump_stack+0x9a/0xf0 [12538.907908] print_circular_bug.isra.25.cold.50+0x1bc/0x279 [12538.932891] ? save_trace+0xd6/0x250 [12538.948979] check_prev_add.constprop.32+0xc36/0x14f0 [12538.971643] ? keyring_compare_object+0x104/0x190 [12538.992738] ? check_usage+0x550/0x550 [12539.009845] ? sched_clock+0x5/0x10 [12539.025484] ? sched_clock_cpu+0x18/0x1e0 [12539.043555] __lock_acquire+0x1f12/0x38d0 [12539.061551] ? trace_hardirqs_on+0x10/0x10 [12539.080554] lock_acquire+0x14c/0x420 [12539.100330] ? __might_fault+0xc4/0x1b0 [12539.119079] __might_fault+0x119/0x1b0 [12539.135869] ? __might_fault+0xc4/0x1b0 [12539.153234] keyring_read_iterator+0x7e/0x170 [12539.172787] ? keyring_read+0x110/0x110 [12539.190059] assoc_array_subtree_iterate+0x97/0x280 [12539.211526] keyring_read+0xe9/0x110 [12539.227561] ? keyring_gc_check_iterator+0xc0/0xc0 [12539.249076] keyctl_read_key+0x1b9/0x220 [12539.266660] do_syscall_64+0xa5/0x4b0 [12539.283091] entry_SYSCALL_64_after_hwframe+0x6a/0xdf
One way to prevent this deadlock scenario from happening is to not allow writing to userspace while holding the key semaphore. Instead, an internal buffer is allocated for getting the keys out from the read method first before copying them out to userspace without holding the lock.
That requires taking out the __user modifier from all the relevant read methods as well as additional changes to not use any userspace write helpers. That is,
1) The put_user() call is replaced by a direct copy. 2) The copy_to_user() call is replaced by memcpy(). 3) All the fault handling code is removed.
Compiling on a x86-64 system, the size of the rxrpc_read() function is reduced from 3795 bytes to 2384 bytes with this patch.
Fixes: ^1da177e4c3f4 ("Linux-2.6.12-rc2") Reviewed-by: Jarkko Sakkinen jarkko.sakkinen@linux.intel.com Signed-off-by: Waiman Long longman@redhat.com Signed-off-by: David Howells dhowells@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- include/keys/big_key-type.h | 2 include/keys/user-type.h | 3 - include/linux/key-type.h | 2 net/dns_resolver/dns_key.c | 2 net/rxrpc/key.c | 27 +++-------- security/keys/big_key.c | 11 +--- security/keys/encrypted-keys/encrypted.c | 7 +- security/keys/keyctl.c | 73 ++++++++++++++++++++++++------- security/keys/keyring.c | 6 -- security/keys/request_key_auth.c | 7 +- security/keys/trusted.c | 14 ----- security/keys/user_defined.c | 5 -- 12 files changed, 85 insertions(+), 74 deletions(-)
--- a/include/keys/big_key-type.h +++ b/include/keys/big_key-type.h @@ -17,6 +17,6 @@ extern void big_key_free_preparse(struct extern void big_key_revoke(struct key *key); extern void big_key_destroy(struct key *key); extern void big_key_describe(const struct key *big_key, struct seq_file *m); -extern long big_key_read(const struct key *key, char __user *buffer, size_t buflen); +extern long big_key_read(const struct key *key, char *buffer, size_t buflen);
#endif /* _KEYS_BIG_KEY_TYPE_H */ --- a/include/keys/user-type.h +++ b/include/keys/user-type.h @@ -41,8 +41,7 @@ extern int user_update(struct key *key, extern void user_revoke(struct key *key); extern void user_destroy(struct key *key); extern void user_describe(const struct key *user, struct seq_file *m); -extern long user_read(const struct key *key, - char __user *buffer, size_t buflen); +extern long user_read(const struct key *key, char *buffer, size_t buflen);
static inline const struct user_key_payload *user_key_payload_rcu(const struct key *key) { --- a/include/linux/key-type.h +++ b/include/linux/key-type.h @@ -127,7 +127,7 @@ struct key_type { * much is copied into the buffer * - shouldn't do the copy if the buffer is NULL */ - long (*read)(const struct key *key, char __user *buffer, size_t buflen); + long (*read)(const struct key *key, char *buffer, size_t buflen);
/* handle request_key() for this type instead of invoking * /sbin/request-key (optional) --- a/net/dns_resolver/dns_key.c +++ b/net/dns_resolver/dns_key.c @@ -302,7 +302,7 @@ static void dns_resolver_describe(const * - the key's semaphore is read-locked */ static long dns_resolver_read(const struct key *key, - char __user *buffer, size_t buflen) + char *buffer, size_t buflen) { int err = PTR_ERR(key->payload.data[dns_key_error]);
--- a/net/rxrpc/key.c +++ b/net/rxrpc/key.c @@ -31,7 +31,7 @@ static void rxrpc_free_preparse_s(struct static void rxrpc_destroy(struct key *); static void rxrpc_destroy_s(struct key *); static void rxrpc_describe(const struct key *, struct seq_file *); -static long rxrpc_read(const struct key *, char __user *, size_t); +static long rxrpc_read(const struct key *, char *, size_t);
/* * rxrpc defined keys take an arbitrary string as the description and an @@ -1042,12 +1042,12 @@ EXPORT_SYMBOL(rxrpc_get_null_key); * - this returns the result in XDR form */ static long rxrpc_read(const struct key *key, - char __user *buffer, size_t buflen) + char *buffer, size_t buflen) { const struct rxrpc_key_token *token; const struct krb5_principal *princ; size_t size; - __be32 __user *xdr, *oldxdr; + __be32 *xdr, *oldxdr; u32 cnlen, toksize, ntoks, tok, zero; u16 toksizes[AFSTOKEN_MAX]; int loop; @@ -1124,30 +1124,25 @@ static long rxrpc_read(const struct key if (!buffer || buflen < size) return size;
- xdr = (__be32 __user *) buffer; + xdr = (__be32 *)buffer; zero = 0; #define ENCODE(x) \ do { \ - __be32 y = htonl(x); \ - if (put_user(y, xdr++) < 0) \ - goto fault; \ + *xdr++ = htonl(x); \ } while(0) #define ENCODE_DATA(l, s) \ do { \ u32 _l = (l); \ ENCODE(l); \ - if (copy_to_user(xdr, (s), _l) != 0) \ - goto fault; \ - if (_l & 3 && \ - copy_to_user((u8 __user *)xdr + _l, &zero, 4 - (_l & 3)) != 0) \ - goto fault; \ + memcpy(xdr, (s), _l); \ + if (_l & 3) \ + memcpy((u8 *)xdr + _l, &zero, 4 - (_l & 3)); \ xdr += (_l + 3) >> 2; \ } while(0) #define ENCODE64(x) \ do { \ __be64 y = cpu_to_be64(x); \ - if (copy_to_user(xdr, &y, 8) != 0) \ - goto fault; \ + memcpy(xdr, &y, 8); \ xdr += 8 >> 2; \ } while(0) #define ENCODE_STR(s) \ @@ -1238,8 +1233,4 @@ static long rxrpc_read(const struct key ASSERTCMP((char __user *) xdr - buffer, ==, size); _leave(" = %zu", size); return size; - -fault: - _leave(" = -EFAULT"); - return -EFAULT; } --- a/security/keys/big_key.c +++ b/security/keys/big_key.c @@ -352,7 +352,7 @@ void big_key_describe(const struct key * * read the key data * - the key's semaphore is read-locked */ -long big_key_read(const struct key *key, char __user *buffer, size_t buflen) +long big_key_read(const struct key *key, char *buffer, size_t buflen) { size_t datalen = (size_t)key->payload.data[big_key_len]; long ret; @@ -391,9 +391,8 @@ long big_key_read(const struct key *key,
ret = datalen;
- /* copy decrypted data to user */ - if (copy_to_user(buffer, buf->virt, datalen) != 0) - ret = -EFAULT; + /* copy out decrypted data */ + memcpy(buffer, buf->virt, datalen);
err_fput: fput(file); @@ -401,9 +400,7 @@ error: big_key_free_buffer(buf); } else { ret = datalen; - if (copy_to_user(buffer, key->payload.data[big_key_data], - datalen) != 0) - ret = -EFAULT; + memcpy(buffer, key->payload.data[big_key_data], datalen); }
return ret; --- a/security/keys/encrypted-keys/encrypted.c +++ b/security/keys/encrypted-keys/encrypted.c @@ -902,14 +902,14 @@ out: }
/* - * encrypted_read - format and copy the encrypted data to userspace + * encrypted_read - format and copy out the encrypted data * * The resulting datablob format is: * <master-key name> <decrypted data length> <encrypted iv> <encrypted data> * * On success, return to userspace the encrypted key datablob size. */ -static long encrypted_read(const struct key *key, char __user *buffer, +static long encrypted_read(const struct key *key, char *buffer, size_t buflen) { struct encrypted_key_payload *epayload; @@ -957,8 +957,7 @@ static long encrypted_read(const struct key_put(mkey); memzero_explicit(derived_key, sizeof(derived_key));
- if (copy_to_user(buffer, ascii_buf, asciiblob_len) != 0) - ret = -EFAULT; + memcpy(buffer, ascii_buf, asciiblob_len); kzfree(ascii_buf);
return asciiblob_len; --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c @@ -798,6 +798,21 @@ error: }
/* + * Call the read method + */ +static long __keyctl_read_key(struct key *key, char *buffer, size_t buflen) +{ + long ret; + + down_read(&key->sem); + ret = key_validate(key); + if (ret == 0) + ret = key->type->read(key, buffer, buflen); + up_read(&key->sem); + return ret; +} + +/* * Read a key's payload. * * The key must either grant the caller Read permission, or it must grant the @@ -812,26 +827,27 @@ long keyctl_read_key(key_serial_t keyid, struct key *key; key_ref_t key_ref; long ret; + char *key_data;
/* find the key first */ key_ref = lookup_user_key(keyid, 0, 0); if (IS_ERR(key_ref)) { ret = -ENOKEY; - goto error; + goto out; }
key = key_ref_to_ptr(key_ref);
ret = key_read_state(key); if (ret < 0) - goto error2; /* Negatively instantiated */ + goto key_put_out; /* Negatively instantiated */
/* see if we can read it directly */ ret = key_permission(key_ref, KEY_NEED_READ); if (ret == 0) goto can_read_key; if (ret != -EACCES) - goto error2; + goto key_put_out;
/* we can't; see if it's searchable from this process's keyrings * - we automatically take account of the fact that it may be @@ -839,26 +855,51 @@ long keyctl_read_key(key_serial_t keyid, */ if (!is_key_possessed(key_ref)) { ret = -EACCES; - goto error2; + goto key_put_out; }
/* the key is probably readable - now try to read it */ can_read_key: - ret = -EOPNOTSUPP; - if (key->type->read) { - /* Read the data with the semaphore held (since we might sleep) - * to protect against the key being updated or revoked. - */ - down_read(&key->sem); - ret = key_validate(key); - if (ret == 0) - ret = key->type->read(key, buffer, buflen); - up_read(&key->sem); + if (!key->type->read) { + ret = -EOPNOTSUPP; + goto key_put_out; + } + + if (!buffer || !buflen) { + /* Get the key length from the read method */ + ret = __keyctl_read_key(key, NULL, 0); + goto key_put_out; + } + + /* + * Read the data with the semaphore held (since we might sleep) + * to protect against the key being updated or revoked. + * + * Allocating a temporary buffer to hold the keys before + * transferring them to user buffer to avoid potential + * deadlock involving page fault and mmap_sem. + */ + key_data = kmalloc(buflen, GFP_KERNEL); + + if (!key_data) { + ret = -ENOMEM; + goto key_put_out; + } + ret = __keyctl_read_key(key, key_data, buflen); + + /* + * Read methods will just return the required length without + * any copying if the provided length isn't large enough. + */ + if (ret > 0 && ret <= buflen) { + if (copy_to_user(buffer, key_data, ret)) + ret = -EFAULT; } + kzfree(key_data);
-error2: +key_put_out: key_put(key); -error: +out: return ret; }
--- a/security/keys/keyring.c +++ b/security/keys/keyring.c @@ -459,7 +459,6 @@ static int keyring_read_iterator(const v { struct keyring_read_iterator_context *ctx = data; const struct key *key = keyring_ptr_to_key(object); - int ret;
kenter("{%s,%d},,{%zu/%zu}", key->type->name, key->serial, ctx->count, ctx->buflen); @@ -467,10 +466,7 @@ static int keyring_read_iterator(const v if (ctx->count >= ctx->buflen) return 1;
- ret = put_user(key->serial, ctx->buffer); - if (ret < 0) - return ret; - ctx->buffer++; + *ctx->buffer++ = key->serial; ctx->count += sizeof(key->serial); return 0; } --- a/security/keys/request_key_auth.c +++ b/security/keys/request_key_auth.c @@ -22,7 +22,7 @@ static int request_key_auth_instantiate( static void request_key_auth_describe(const struct key *, struct seq_file *); static void request_key_auth_revoke(struct key *); static void request_key_auth_destroy(struct key *); -static long request_key_auth_read(const struct key *, char __user *, size_t); +static long request_key_auth_read(const struct key *, char *, size_t);
/* * The request-key authorisation key type definition. @@ -80,7 +80,7 @@ static void request_key_auth_describe(co * - the key's semaphore is read-locked */ static long request_key_auth_read(const struct key *key, - char __user *buffer, size_t buflen) + char *buffer, size_t buflen) { struct request_key_auth *rka = dereference_key_locked(key); size_t datalen; @@ -97,8 +97,7 @@ static long request_key_auth_read(const if (buflen > datalen) buflen = datalen;
- if (copy_to_user(buffer, rka->callout_info, buflen) != 0) - ret = -EFAULT; + memcpy(buffer, rka->callout_info, buflen); }
return ret; --- a/security/keys/trusted.c +++ b/security/keys/trusted.c @@ -1144,11 +1144,10 @@ out: * trusted_read - copy the sealed blob data to userspace in hex. * On success, return to userspace the trusted key datablob size. */ -static long trusted_read(const struct key *key, char __user *buffer, +static long trusted_read(const struct key *key, char *buffer, size_t buflen) { const struct trusted_key_payload *p; - char *ascii_buf; char *bufp; int i;
@@ -1157,18 +1156,9 @@ static long trusted_read(const struct ke return -EINVAL;
if (buffer && buflen >= 2 * p->blob_len) { - ascii_buf = kmalloc_array(2, p->blob_len, GFP_KERNEL); - if (!ascii_buf) - return -ENOMEM; - - bufp = ascii_buf; + bufp = buffer; for (i = 0; i < p->blob_len; i++) bufp = hex_byte_pack(bufp, p->blob[i]); - if (copy_to_user(buffer, ascii_buf, 2 * p->blob_len) != 0) { - kzfree(ascii_buf); - return -EFAULT; - } - kzfree(ascii_buf); } return 2 * p->blob_len; } --- a/security/keys/user_defined.c +++ b/security/keys/user_defined.c @@ -168,7 +168,7 @@ EXPORT_SYMBOL_GPL(user_describe); * read the key data * - the key's semaphore is read-locked */ -long user_read(const struct key *key, char __user *buffer, size_t buflen) +long user_read(const struct key *key, char *buffer, size_t buflen) { const struct user_key_payload *upayload; long ret; @@ -181,8 +181,7 @@ long user_read(const struct key *key, ch if (buflen > upayload->datalen) buflen = upayload->datalen;
- if (copy_to_user(buffer, upayload->data, buflen) != 0) - ret = -EFAULT; + memcpy(buffer, upayload->data, buflen); }
return ret;
From: Daniel Borkmann daniel@iogearbox.net Date: Tue, 21 Apr 2020 15:01:49 +0200
[ no upstream commit ]
See the glory details in 100605035e15 ("bpf: Verifier, do_refine_retval_range may clamp umin to 0 incorrectly") for why 849fa50662fb ("bpf/verifier: refine retval R0 state for bpf_get_stack helper") is buggy. The whole series however is not suitable for stable since it adds significant amount [0] of verifier complexity in order to add 32bit subreg tracking. Something simpler is needed.
Unfortunately, reverting 849fa50662fb ("bpf/verifier: refine retval R0 state for bpf_get_stack helper") or just cherry-picking 100605035e15 ("bpf: Verifier, do_refine_retval_range may clamp umin to 0 incorrectly") is not an option since it will break existing tracing programs badly (at least those that are using bpf_get_stack() and bpf_probe_read_str() helpers). Not fixing it in stable is also not an option since on 4.19 kernels an error will cause a soft-lockup due to hitting dead-code sanitized branch since we don't hard-wire such branches in old kernels yet. But even then for 5.x 849fa50662fb ("bpf/verifier: refine retval R0 state for bpf_get_stack helper") would cause wrong bounds on the verifier simluation when an error is hit.
In one of the earlier iterations of mentioned patch series for upstream there was the concern that just using smax_value in do_refine_retval_range() would nuke bounds by subsequent <<32 >>32 shifts before the comparison against 0 [1] which eventually led to the 32bit subreg tracking in the first place. While I initially went for implementing the idea [1] to pattern match the two shift operations, it turned out to be more complex than actually needed, meaning, we could simply treat do_refine_retval_range() similarly to how we branch off verification for conditionals or under speculation, that is, pushing a new reg state to the stack for later verification. This means, instead of verifying the current path with the ret_reg in [S32MIN, msize_max_value] interval where later bounds would get nuked, we split this into two: i) for the success case where ret_reg can be in [0, msize_max_value], and ii) for the error case with ret_reg known to be in interval [S32MIN, -1]. Latter will preserve the bounds during these shift patterns and can match reg < 0 test. test_progs also succeed with this approach.
[0] https://lore.kernel.org/bpf/158507130343.15666.8018068546764556975.stgit@joh... [1] https://lore.kernel.org/bpf/158015334199.28573.4940395881683556537.stgit@joh...
Fixes: 849fa50662fb ("bpf/verifier: refine retval R0 state for bpf_get_stack helper") Reported-by: Lorenzo Fontana fontanalorenz@gmail.com Reported-by: Leonardo Di Donato leodidonato@gmail.com Reported-by: John Fastabend john.fastabend@gmail.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Acked-by: Alexei Starovoitov ast@kernel.org Acked-by: John Fastabend john.fastabend@gmail.com Tested-by: John Fastabend john.fastabend@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/bpf/verifier.c | 45 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 11 deletions(-)
--- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -201,8 +201,7 @@ struct bpf_call_arg_meta { bool pkt_access; int regno; int access_size; - s64 msize_smax_value; - u64 msize_umax_value; + u64 msize_max_value; int ref_obj_id; int func_id; }; @@ -3377,8 +3376,7 @@ static int check_func_arg(struct bpf_ver /* remember the mem_size which may be used later * to refine return values. */ - meta->msize_smax_value = reg->smax_value; - meta->msize_umax_value = reg->umax_value; + meta->msize_max_value = reg->umax_value;
/* The register is SCALAR_VALUE; the access check * happens using its boundaries. @@ -3866,21 +3864,44 @@ static int prepare_func_exit(struct bpf_ return 0; }
-static void do_refine_retval_range(struct bpf_reg_state *regs, int ret_type, - int func_id, - struct bpf_call_arg_meta *meta) +static int do_refine_retval_range(struct bpf_verifier_env *env, + struct bpf_reg_state *regs, int ret_type, + int func_id, struct bpf_call_arg_meta *meta) { struct bpf_reg_state *ret_reg = ®s[BPF_REG_0]; + struct bpf_reg_state tmp_reg = *ret_reg; + bool ret;
if (ret_type != RET_INTEGER || (func_id != BPF_FUNC_get_stack && func_id != BPF_FUNC_probe_read_str)) - return; + return 0; + + /* Error case where ret is in interval [S32MIN, -1]. */ + ret_reg->smin_value = S32_MIN; + ret_reg->smax_value = -1;
- ret_reg->smax_value = meta->msize_smax_value; - ret_reg->umax_value = meta->msize_umax_value; __reg_deduce_bounds(ret_reg); __reg_bound_offset(ret_reg); + __update_reg_bounds(ret_reg); + + ret = push_stack(env, env->insn_idx + 1, env->insn_idx, false); + if (!ret) + return -EFAULT; + + *ret_reg = tmp_reg; + + /* Success case where ret is in range [0, msize_max_value]. */ + ret_reg->smin_value = 0; + ret_reg->smax_value = meta->msize_max_value; + ret_reg->umin_value = ret_reg->smin_value; + ret_reg->umax_value = ret_reg->smax_value; + + __reg_deduce_bounds(ret_reg); + __reg_bound_offset(ret_reg); + __update_reg_bounds(ret_reg); + + return 0; }
static int @@ -4112,7 +4133,9 @@ static int check_helper_call(struct bpf_ regs[BPF_REG_0].ref_obj_id = id; }
- do_refine_retval_range(regs, fn->ret_type, func_id, &meta); + err = do_refine_retval_range(env, regs, fn->ret_type, func_id, &meta); + if (err) + return err;
err = check_map_func_compatibility(env, meta.map_ptr, func_id); if (err)
From: John Fastabend john.fastabend@gmail.com
commit 9ac26e9973bac5716a2a542e32f380c84db2b88c upstream.
With current ALU32 subreg handling and retval refine fix from last patches we see an expected failure in test_verifier. With verbose verifier state being printed at each step for clarity we have the following relavent lines [I omit register states that are not necessarily useful to see failure cause],
#101/p bpf_get_stack return R0 within range FAIL Failed to load prog 'Success'! [..] 14: (85) call bpf_get_stack#67 R0_w=map_value(id=0,off=0,ks=8,vs=48,imm=0) R3_w=inv48 15: R0=inv(id=0,smax_value=48,var32_off=(0x0; 0xffffffff)) 15: (b7) r1 = 0 16: R0=inv(id=0,smax_value=48,var32_off=(0x0; 0xffffffff)) R1_w=inv0 16: (bf) r8 = r0 17: R0=inv(id=0,smax_value=48,var32_off=(0x0; 0xffffffff)) R1_w=inv0 R8_w=inv(id=0,smax_value=48,var32_off=(0x0; 0xffffffff)) 17: (67) r8 <<= 32 18: R0=inv(id=0,smax_value=48,var32_off=(0x0; 0xffffffff)) R1_w=inv0 R8_w=inv(id=0,smax_value=9223372032559808512, umax_value=18446744069414584320, var_off=(0x0; 0xffffffff00000000), s32_min_value=0, s32_max_value=0, u32_max_value=0, var32_off=(0x0; 0x0)) 18: (c7) r8 s>>= 32 19 R0=inv(id=0,smax_value=48,var32_off=(0x0; 0xffffffff)) R1_w=inv0 R8_w=inv(id=0,smin_value=-2147483648, smax_value=2147483647, var32_off=(0x0; 0xffffffff)) 19: (cd) if r1 s< r8 goto pc+16 R0=inv(id=0,smax_value=48,var32_off=(0x0; 0xffffffff)) R1_w=inv0 R8_w=inv(id=0,smin_value=-2147483648, smax_value=0, var32_off=(0x0; 0xffffffff)) 20: R0=inv(id=0,smax_value=48,var32_off=(0x0; 0xffffffff)) R1_w=inv0 R8_w=inv(id=0,smin_value=-2147483648, smax_value=0, R9=inv48 20: (1f) r9 -= r8 21: (bf) r2 = r7 22: R2_w=map_value(id=0,off=0,ks=8,vs=48,imm=0) 22: (0f) r2 += r8 value -2147483648 makes map_value pointer be out of bounds
After call bpf_get_stack() on line 14 and some moves we have at line 16 an r8 bound with max_value 48 but an unknown min value. This is to be expected bpf_get_stack call can only return a max of the input size but is free to return any negative error in the 32-bit register space. The C helper is returning an int so will use lower 32-bits.
Lines 17 and 18 clear the top 32 bits with a left/right shift but use ARSH so we still have worst case min bound before line 19 of -2147483648. At this point the signed check 'r1 s< r8' meant to protect the addition on line 22 where dst reg is a map_value pointer may very well return true with a large negative number. Then the final line 22 will detect this as an invalid operation and fail the program. What we want to do is proceed only if r8 is positive non-error. So change 'r1 s< r8' to 'r1 s> r8' so that we jump if r8 is negative.
Next we will throw an error because we access past the end of the map value. The map value size is 48 and sizeof(struct test_val) is 48 so we walk off the end of the map value on the second call to get bpf_get_stack(). Fix this by changing sizeof(struct test_val) to 24 by using 'sizeof(struct test_val) / 2'. After this everything passes as expected.
Signed-off-by: John Fastabend john.fastabend@gmail.com Signed-off-by: Alexei Starovoitov ast@kernel.org Signed-off-by: Daniel Borkmann daniel@iogearbox.net Link: https://lore.kernel.org/bpf/158560426019.10843.3285429543232025187.stgit@joh... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- tools/testing/selftests/bpf/verifier/bpf_get_stack.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
--- a/tools/testing/selftests/bpf/verifier/bpf_get_stack.c +++ b/tools/testing/selftests/bpf/verifier/bpf_get_stack.c @@ -9,17 +9,17 @@ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 28), BPF_MOV64_REG(BPF_REG_7, BPF_REG_0), - BPF_MOV64_IMM(BPF_REG_9, sizeof(struct test_val)), + BPF_MOV64_IMM(BPF_REG_9, sizeof(struct test_val)/2), BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), BPF_MOV64_REG(BPF_REG_2, BPF_REG_7), - BPF_MOV64_IMM(BPF_REG_3, sizeof(struct test_val)), + BPF_MOV64_IMM(BPF_REG_3, sizeof(struct test_val)/2), BPF_MOV64_IMM(BPF_REG_4, 256), BPF_EMIT_CALL(BPF_FUNC_get_stack), BPF_MOV64_IMM(BPF_REG_1, 0), BPF_MOV64_REG(BPF_REG_8, BPF_REG_0), BPF_ALU64_IMM(BPF_LSH, BPF_REG_8, 32), BPF_ALU64_IMM(BPF_ARSH, BPF_REG_8, 32), - BPF_JMP_REG(BPF_JSLT, BPF_REG_1, BPF_REG_8, 16), + BPF_JMP_REG(BPF_JSGT, BPF_REG_1, BPF_REG_8, 16), BPF_ALU64_REG(BPF_SUB, BPF_REG_9, BPF_REG_8), BPF_MOV64_REG(BPF_REG_2, BPF_REG_7), BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_8), @@ -29,7 +29,7 @@ BPF_MOV64_REG(BPF_REG_3, BPF_REG_2), BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_1), BPF_MOV64_REG(BPF_REG_1, BPF_REG_7), - BPF_MOV64_IMM(BPF_REG_5, sizeof(struct test_val)), + BPF_MOV64_IMM(BPF_REG_5, sizeof(struct test_val)/2), BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_5), BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 4), BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
From: John Fastabend john.fastabend@gmail.com
commit d2db08c7a14e0b5eed6132baf258b80622e041a9 upstream.
Before this series the verifier would clamp return bounds of bpf_get_stack() to [0, X] and this led the verifier to believe that a JMP_JSLT 0 would be false and so would prune that path.
The result is anything hidden behind that JSLT would be unverified. Add a test to catch this case by hiding an goto pc-1 behind the check which will cause an infinite loop if not rejected.
Signed-off-by: John Fastabend john.fastabend@gmail.com Signed-off-by: Alexei Starovoitov ast@kernel.org Link: https://lore.kernel.org/bpf/158560423908.10843.11783152347709008373.stgit@jo... Signed-off-by: Daniel Borkmann daniel@iogearbox.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- tools/testing/selftests/bpf/prog_tests/get_stack_raw_tp.c | 5 ++ tools/testing/selftests/bpf/progs/test_get_stack_rawtp_err.c | 26 +++++++++++ 2 files changed, 31 insertions(+)
--- a/tools/testing/selftests/bpf/prog_tests/get_stack_raw_tp.c +++ b/tools/testing/selftests/bpf/prog_tests/get_stack_raw_tp.c @@ -82,6 +82,7 @@ static void get_stack_print_output(void void test_get_stack_raw_tp(void) { const char *file = "./test_get_stack_rawtp.o"; + const char *file_err = "./test_get_stack_rawtp_err.o"; const char *prog_name = "raw_tracepoint/sys_enter"; int i, err, prog_fd, exp_cnt = MAX_CNT_RAWTP; struct perf_buffer_opts pb_opts = {}; @@ -93,6 +94,10 @@ void test_get_stack_raw_tp(void) struct bpf_map *map; cpu_set_t cpu_set;
+ err = bpf_prog_load(file_err, BPF_PROG_TYPE_RAW_TRACEPOINT, &obj, &prog_fd); + if (CHECK(err >= 0, "prog_load raw tp", "err %d errno %d\n", err, errno)) + return; + err = bpf_prog_load(file, BPF_PROG_TYPE_RAW_TRACEPOINT, &obj, &prog_fd); if (CHECK(err, "prog_load raw tp", "err %d errno %d\n", err, errno)) return; --- /dev/null +++ b/tools/testing/selftests/bpf/progs/test_get_stack_rawtp_err.c @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <linux/bpf.h> +#include <bpf/bpf_helpers.h> + +#define MAX_STACK_RAWTP 10 + +SEC("raw_tracepoint/sys_enter") +int bpf_prog2(void *ctx) +{ + __u64 stack[MAX_STACK_RAWTP]; + int error; + + /* set all the flags which should return -EINVAL */ + error = bpf_get_stack(ctx, stack, 0, -1); + if (error < 0) + goto loop; + + return error; +loop: + while (1) { + error++; + } +} + +char _license[] SEC("license") = "GPL";
From: Daniel Borkmann daniel@iogearbox.net
[ no upstream commit ]
Switch the comparison, so that is_branch_taken() will recognize that below branch is never taken:
[...] 17: [...] R1_w=inv0 [...] R8_w=inv(id=0,smin_value=-2147483648,smax_value=-1,umin_value=18446744071562067968,var_off=(0xffffffff80000000; 0x7fffffff)) [...] 17: (67) r8 <<= 32 18: [...] R8_w=inv(id=0,smax_value=-4294967296,umin_value=9223372036854775808,umax_value=18446744069414584320,var_off=(0x8000000000000000; 0x7fffffff00000000)) [...] 18: (c7) r8 s>>= 32 19: [...] R8_w=inv(id=0,smin_value=-2147483648,smax_value=-1,umin_value=18446744071562067968,var_off=(0xffffffff80000000; 0x7fffffff)) [...] 19: (6d) if r1 s> r8 goto pc+16 [...] R1_w=inv0 [...] R8_w=inv(id=0,smin_value=-2147483648,smax_value=-1,umin_value=18446744071562067968,var_off=(0xffffffff80000000; 0x7fffffff)) [...] [...]
Currently we check for is_branch_taken() only if either K is source, or source is a scalar value that is const. For upstream it would be good to extend this properly to check whether dst is const and src not.
For the sake of the test_verifier, it is probably not needed here:
# ./test_verifier 101 #101/p bpf_get_stack return R0 within range OK Summary: 1 PASSED, 0 SKIPPED, 0 FAILED
I haven't seen this issue in test_progs* though, they are passing fine:
# ./test_progs-no_alu32 -t get_stack Switching to flavor 'no_alu32' subdirectory... #20 get_stack_raw_tp:OK Summary: 1/0 PASSED, 0 SKIPPED, 0 FAILED
# ./test_progs -t get_stack #20 get_stack_raw_tp:OK Summary: 1/0 PASSED, 0 SKIPPED, 0 FAILED
Signed-off-by: Daniel Borkmann daniel@iogearbox.net Acked-by: Alexei Starovoitov ast@kernel.org Acked-by: John Fastabend john.fastabend@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- tools/testing/selftests/bpf/verifier/bpf_get_stack.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/tools/testing/selftests/bpf/verifier/bpf_get_stack.c +++ b/tools/testing/selftests/bpf/verifier/bpf_get_stack.c @@ -19,7 +19,7 @@ BPF_MOV64_REG(BPF_REG_8, BPF_REG_0), BPF_ALU64_IMM(BPF_LSH, BPF_REG_8, 32), BPF_ALU64_IMM(BPF_ARSH, BPF_REG_8, 32), - BPF_JMP_REG(BPF_JSGT, BPF_REG_1, BPF_REG_8, 16), + BPF_JMP_REG(BPF_JSLT, BPF_REG_8, BPF_REG_1, 16), BPF_ALU64_REG(BPF_SUB, BPF_REG_9, BPF_REG_8), BPF_MOV64_REG(BPF_REG_2, BPF_REG_7), BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_8),
On Wed, Apr 22, 2020 at 11:56:01AM +0200, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.4.35 release. There are 118 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 Fri, 24 Apr 2020 09:48:23 +0000. Anything received after that time might be too late.
Build results: total: 157 pass: 157 fail: 0 Qemu test results: total: 427 pass: 427 fail: 0
Guenter
On Wed, 22 Apr 2020 at 15:53, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 5.4.35 release. There are 118 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 Fri, 24 Apr 2020 09:48:23 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.4.35-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.4.y and the diffstat can be found below.
thanks,
greg k-h
Results from Linaro’s test farm. No regressions on arm64, arm, x86_64, and i386.
Summary ------------------------------------------------------------------------
kernel: 5.4.35-rc1 git repo: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git git branch: linux-5.4.y git commit: 186764443bf32f12e07093aaff52dd4a25231781 git describe: v5.4.34-119-g186764443bf3 Test details: https://qa-reports.linaro.org/lkft/linux-stable-rc-5.4-oe/build/v5.4.34-119-...
No regressions (compared to build v5.4.34)
No fixes (compared to build v5.4.34)
Ran 37179 total tests in the following environments and test suites.
Environments -------------- - dragonboard-410c - hi6220-hikey - i386 - juno-r2 - juno-r2-compat - juno-r2-kasan - nxp-ls2088 - qemu_arm - qemu_arm64 - qemu_i386 - qemu_x86_64 - x15 - x86 - x86-kasan
Test Suites ----------- * build * install-android-platform-tools-r2600 * install-android-platform-tools-r2800 * kselftest * kselftest/drivers * kselftest/filesystems * kselftest/net * kselftest/networking * linux-log-parser * ltp-cap_bounds-tests * ltp-commands-tests * ltp-cpuhotplug-tests * ltp-crypto-tests * ltp-dio-tests * ltp-fcntl-locktests-tests * ltp-filecaps-tests * ltp-fs_bind-tests * ltp-fs_perms_simple-tests * ltp-fsx-tests * ltp-io-tests * ltp-math-tests * ltp-nptl-tests * ltp-pty-tests * ltp-securebits-tests * perf * kvm-unit-tests * libgpiod * ltp-cve-tests * ltp-hugetlb-tests * ltp-ipc-tests * ltp-mm-tests * ltp-sched-tests * ltp-syscalls-tests * network-basic-tests * libhugetlbfs * ltp-containers-tests * ltp-fs-tests * ltp-open-posix-tests * v4l2-compliance * spectre-meltdown-checker-test * kselftest-vsyscall-mode-native * kselftest-vsyscall-mode-native/drivers * kselftest-vsyscall-mode-native/filesystems * kselftest-vsyscall-mode-native/net * kselftest-vsyscall-mode-native/networking * kselftest-vsyscall-mode-none * kselftest-vsyscall-mode-none/drivers * kselftest-vsyscall-mode-none/filesystems * kselftest-vsyscall-mode-none/net * kselftest-vsyscall-mode-none/networking
On 22/04/2020 10:56, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.4.35 release. There are 118 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 Fri, 24 Apr 2020 09:48:23 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.4.35-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.4.y and the diffstat can be found below.
thanks,
greg k-h
All tests are passing for Tegra
Test results for stable-v5.4: 13 builds: 13 pass, 0 fail 24 boots: 24 pass, 0 fail 40 tests: 40 pass, 0 fail
Linux version: 5.4.35-rc1-g186764443bf3 Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000, tegra194-p2972-0000, tegra20-ventana, tegra210-p2371-2180, tegra210-p3450-0000, tegra30-cardhu-a04
Cheers Jon
On 4/22/20 3:56 AM, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.4.35 release. There are 118 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 Fri, 24 Apr 2020 09:48:23 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.4.35-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.4.y and the diffstat can be found below.
thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks, -- Shuah
linux-stable-mirror@lists.linaro.org