5.16.13-rc1 review
Subsystems (4)
Greg Kroah-Hartman
maintainercover 5.16.13-rc1 review
This is the start of the stable review cycle for the 5.16.13 release. There are 186 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 09 Mar 2022 09:16:25 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.16.13-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.16.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 5.16.13-rc1
Like Xu <[email protected]>
KVM: x86/mmu: Passing up the error state of mmu_alloc_shadow_roots()
Heiko Carstens <[email protected]>
s390/ftrace: fix ftrace_caller/ftrace_regs_caller generation
Heiko Carstens <[email protected]>
s390/ftrace: fix arch_ftrace_get_regs implementation
Dexuan Cui <[email protected]>
x86/kvmclock: Fix Hyper-V Isolated VM's boot issue when vCPUs > 64
Yun Zhou <[email protected]>
proc: fix documentation and description of pagemap
Jiri Bohac <[email protected]>
Revert "xfrm: xfrm_state_mtu should return at least 1280 for ipv6"
Josef Bacik <[email protected]>
btrfs: do not start relocation until in progress drops are done
Filipe Manana <[email protected]>
btrfs: fallback to blocking mode when doing async dio over multiple extents
Filipe Manana <[email protected]>
btrfs: add missing run of delayed items after unlink during log replay
Sidong Yang <[email protected]>
btrfs: qgroup: fix deadlock between rescan worker and remove qgroup
Josef Bacik <[email protected]>
btrfs: do not WARN_ON() if we have PageError set
Qu Wenruo <[email protected]>
btrfs: subpage: fix a wrong check on subpage->writers
Omar Sandoval <[email protected]>
btrfs: fix relocation crash due to premature return from btrfs_commit_transaction()
Filipe Manana <[email protected]>
btrfs: fix lost prealloc extents beyond eof after full fsync
Randy Dunlap <[email protected]>
tracing: Fix return value of __setup handlers
Steven Rostedt (Google) <[email protected]>
tracing/histogram: Fix sorting on old "cpu" value
William Mahon <[email protected]>
HID: add mapping for KEY_ALL_APPLICATIONS
William Mahon <[email protected]>
HID: add mapping for KEY_DICTATE
David Gow <[email protected]>
Input: samsung-keypad - properly state IOMEM dependency
Hans de Goede <[email protected]>
Input: elan_i2c - fix regulator enable count imbalance after suspend/resume
Hans de Goede <[email protected]>
Input: elan_i2c - move regulator_[en|dis]able() out of elan_[en|dis]able_power()
Ong Boon Leong <[email protected]>
net: stmmac: perserve TX and RX coalesce value during XDP setup
Amit Cohen <[email protected]>
selftests: mlxsw: resource_scale: Fix return value
Vladimir Oltean <[email protected]>
net: dcb: disable softirqs in dcbnl_flush_dev()
Qiang Yu <[email protected]>
drm/amdgpu: fix suspend/resume hang regression
Jonathan Lemon <[email protected]>
ptp: ocp: Add ptp_ocp_adjtime_coarse for large adjustments
Jiasheng Jiang <[email protected]>
nl80211: Handle nla_memdup failures in handle_nan_filter
Ilya Lipnitskiy <[email protected]>
MIPS: ralink: mt7621: use bitwise NOT instead of logical
Sasha Neftin <[email protected]>
e1000e: Fix possible HW unit hang after an s0ix exit
Douglas Anderson <[email protected]>
drm/bridge: ti-sn65dsi86: Properly undo autosuspend
Vinay Belgaumkar <[email protected]>
drm/i915/guc/slpc: Correct the param count for unset param
Slawomir Laba <[email protected]>
iavf: Fix __IAVF_RESETTING state usage
Slawomir Laba <[email protected]>
iavf: Fix race in init state
Slawomir Laba <[email protected]>
iavf: Fix locking for VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS
Slawomir Laba <[email protected]>
iavf: Fix init state closure on remove
Slawomir Laba <[email protected]>
iavf: Add waiting so the port is initialized in remove
Slawomir Laba <[email protected]>
iavf: Rework mutexes for better synchronisation
Jedrzej Jagielski <[email protected]>
iavf: Add trace while removing device
Casper Andersson <[email protected]>
net: sparx5: Fix add vlan when invalid operation
Jia-Ju Bai <[email protected]>
net: chelsio: cxgb3: check the return value of pci_find_capability()
Sukadev Bhattiprolu <[email protected]>
ibmvnic: Allow queueing resets during probe
Sukadev Bhattiprolu <[email protected]>
ibmvnic: clear fop when retrying probe
Sukadev Bhattiprolu <[email protected]>
ibmvnic: init init_done_rc earlier
Dany Madden <[email protected]>
ibmvnic: Update driver return codes
Sukadev Bhattiprolu <[email protected]>
ibmvnic: complete init_done on transport events
Sukadev Bhattiprolu <[email protected]>
ibmvnic: define flush_reset_queue helper
Sukadev Bhattiprolu <[email protected]>
ibmvnic: initialize rc before completing wait
Vincent Whitchurch <[email protected]>
net: stmmac: only enable DMA interrupts when ready
Ong Boon Leong <[email protected]>
net: stmmac: enhance XDP ZC driver level switching performance
Vincent Mailhol <[email protected]>
can: etas_es58x: change opened_channel_cnt's type from atomic_t to u8
Luiz Augusto von Dentz <[email protected]>
Bluetooth: Fix bt_skb_sendmmsg not allocating partial chunks
Thierry Reding <[email protected]>
ARM: tegra: Move panels to AUX bus
Eric Dumazet <[email protected]>
netfilter: nf_tables: prefer kfree_rcu(ptr, rcu) variant
Laurent Pinchart <[email protected]>
soc: imx: gpcv2: Fix clock disabling imbalance in error path
Jiasheng Jiang <[email protected]>
soc: fsl: qe: Check of ioremap return value
Christophe JAILLET <[email protected]>
soc: fsl: guts: Add a missing memory allocation failure check
Christophe JAILLET <[email protected]>
soc: fsl: guts: Revert commit 3c0d64e867ed
Anthoine Bourgeois <[email protected]>
ARM: dts: Use 32KiHz oscillator on devkit8000
Anthoine Bourgeois <[email protected]>
ARM: dts: switch timer config to common devkit8000 devicetree
Chuanhong Guo <[email protected]>
MIPS: ralink: mt7621: do memory detection on KSEG1
Suravee Suthikulpanit <[email protected]>
iommu/amd: Fix I/O page table memory leak
Matthew Wilcox (Oracle) <[email protected]>
iommu/amd: Use put_pages_list
Robin Murphy <[email protected]>
iommu/amd: Simplify pagetable freeing
Adam Ford <[email protected]>
arm64: dts: imx8mm: Fix VPU Hanging
Peter Geis <[email protected]>
arm64: dts: rockchip: fix Quartz64-A ddr regulator voltage
Robin Murphy <[email protected]>
arm64: dts: juno: Remove GICv2m dma-range
Frank Wunderlich <[email protected]>
arm64: dts: rockchip: drop pclk_xpcs from gmac0 on rk3568
Peter Zijlstra <[email protected]>
sched: Fix yet more sched_fork() races
Heiko Carstens <[email protected]>
s390/extable: fix exception table sorting
Alexander Egorenkov <[email protected]>
s390/setup: preserve memory at OLDMEM_BASE and OLDMEM_SIZE
Hugh Dickins <[email protected]>
memfd: fix F_SEAL_WRITE after shmem huge page allocated
Sukadev Bhattiprolu <[email protected]>
ibmvnic: free reset-work-item when flushing
Sasha Neftin <[email protected]>
igc: igc_write_phy_reg_gpy: drop premature return
Samuel Holland <[email protected]>
pinctrl: sunxi: Use unique lockdep classes for IRQs
Amit Cohen <[email protected]>
selftests: mlxsw: tc_police_scale: Make test more robust
Mat Martineau <[email protected]>
mptcp: Correctly set DATA_FIN timeout when number of retransmits is large
Randy Dunlap <[email protected]>
ARM: 9182/1: mmu: fix returns from early_param() and __setup() functions
Randy Dunlap <[email protected]>
mips: setup: fix setnocoherentio() boolean setting
Russell King (Oracle) <[email protected]>
ARM: Fix kgdb breakpoint for Thumb2
Corinna Vinschen <[email protected]>
igc: igc_read_phy_reg_gpy: drop premature return
Brian Norris <[email protected]>
arm64: dts: rockchip: Switch RK3399-Gru DP to SPDIF output
Miaoqian Lin <[email protected]>
iommu/tegra-smmu: Fix missing put_device() call in tegra_smmu_find
Vincent Mailhol <[email protected]>
can: gs_usb: change active_channels's type from atomic_t to u8
Andy Shevchenko <[email protected]>
auxdisplay: lcd2s: Use proper API to free the instance of charlcd object
Andy Shevchenko <[email protected]>
auxdisplay: lcd2s: Fix memory leak in ->remove()
Fabio Estevam <[email protected]>
ASoC: cs4265: Fix the duplicated control name
Alyssa Ross <[email protected]>
firmware: arm_scmi: Remove space in MODULE_ALIAS name
Andy Shevchenko <[email protected]>
auxdisplay: lcd2s: Fix lcd2s_redefine_char() feature
Jann Horn <[email protected]>
efivars: Respect "block" flag in efivar_entry_set_safe()
Slawomir Laba <[email protected]>
iavf: Fix deadlock in iavf_reset_task
Maciej Fijalkowski <[email protected]>
ixgbe: xsk: change !netif_carrier_ok() handling in ixgbe_xmit_zc()
Zheyu Ma <[email protected]>
net: arcnet: com20020: Fix null-ptr-deref in com20020pci_probe()
Sukadev Bhattiprolu <[email protected]>
ibmvnic: register netdev after init of adapter
Randy Dunlap <[email protected]>
net: sxgbe: fix return value of __setup handler
Slawomir Laba <[email protected]>
iavf: Fix missing check for running netdev
Johannes Berg <[email protected]>
mac80211: treat some SAE auth steps as final
Randy Dunlap <[email protected]>
net: stmmac: fix return value of __setup handler
Nicolas Escande <[email protected]>
mac80211: fix forwarded mesh frames AC & queue selection
Svenning Sørensen <[email protected]>
net: dsa: microchip: fix bridging with more than two member ports
Mario Limonciello <[email protected]>
platform/x86: amd-pmc: Set QOS during suspend on CZN w/ timer wakeup
Filipe Manana <[email protected]>
btrfs: fix ENOSPC failure when attempting direct IO write into NOCOW range
D. Wythe <[email protected]>
net/smc: fix unexpected SMC_CLC_DECL_ERR_REGRMB error cause by server
D. Wythe <[email protected]>
net/smc: fix unexpected SMC_CLC_DECL_ERR_REGRMB error generated by client
D. Wythe <[email protected]>
net/smc: fix connection leak
Alex Elder <[email protected]>
net: ipa: add an interconnect dependency
Alex Elder <[email protected]>
net: ipa: fix a build dependency
Vladimir Oltean <[email protected]>
net: dcb: flush lingering app table entries for unregistered devices
[email protected] <[email protected]>
net: ipv6: ensure we call ipv6_mc_down() at most once
Sven Eckelmann <[email protected]>
batman-adv: Don't expect inter-netns unique iflink indices
Sven Eckelmann <[email protected]>
batman-adv: Request iflink once in batadv_get_real_netdevice
Sven Eckelmann <[email protected]>
batman-adv: Request iflink once in batadv-on-batadv check
Florian Westphal <[email protected]>
netfilter: nf_queue: handle socket prefetch
Florian Westphal <[email protected]>
netfilter: nf_queue: fix possible use-after-free
Florian Westphal <[email protected]>
netfilter: nf_queue: don't assume sk is full socket
lena wang <[email protected]>
net: fix up skbs delta_truesize in UDP GRO frag_list
Sasha Neftin <[email protected]>
e1000e: Correct NVM checksum verification flow
Leon Romanovsky <[email protected]>
xfrm: enforce validity of offload input flags
Antony Antony <[email protected]>
xfrm: fix the if_id check in changelink
Eric Dumazet <[email protected]>
bpf, sockmap: Do not ignore orig_len parameter
Eric Dumazet <[email protected]>
netfilter: fix use-after-free in __nf_register_net_hook()
Jiri Bohac <[email protected]>
xfrm: fix MTU regression
Daniel Borkmann <[email protected]>
mm: Consider __GFP_NOWARN flag for oversized kvmalloc() calls
Dave Jiang <[email protected]>
ntb: intel: fix port config status offset for SPR
Yu Kuai <[email protected]>
blktrace: fix use after free for struct blk_trace
Deren Wu <[email protected]>
mac80211: fix EAPoL rekey fail in 802.3 rx path
Nicolas Cavallari <[email protected]>
thermal: core: Fix TZ_GET_TRIP NULL pointer dereference
Marek Marczykowski-Górecki <[email protected]>
xen/netfront: destroy queues before real_num_tx_queues is zeroed
Leo (Hanghong) Ma <[email protected]>
drm/amd/display: Reduce dmesg error to a debug print
Ville Syrjälä <[email protected]>
drm/i915: s/JSP2/ICP2/ PCH
Lennert Buytenhek <[email protected]>
iommu/amd: Recover from event log overflow
Adrian Huang <[email protected]>
iommu/vt-d: Fix double list_add when enabling VMD in scalable mode
Marek Vasut <[email protected]>
ASoC: ops: Shift tested values in snd_soc_put_volsw() by +min
Randy Dunlap <[email protected]>
iwlwifi: mvm: check debugfs_dir ptr before use
Alexandre Ghiti <[email protected]>
riscv: Fix config KASAN && DEBUG_VIRTUAL
Alexandre Ghiti <[email protected]>
riscv: Fix config KASAN && SPARSEMEM && !SPARSE_VMEMMAP
Sunil V L <[email protected]>
riscv/efi_stub: Fix get_boot_hartid_from_fdt() return value
Kees Cook <[email protected]>
binfmt_elf: Avoid total_mapping_size for ET_EXEC
Eric W. Biederman <[email protected]>
ucounts: Fix systemd LimitNPROC with private users regression
Zhen Ni <[email protected]>
ALSA: intel_hdmi: Fix reference to PCM buffer address
Qu Wenruo <[email protected]>
btrfs: defrag: don't use merged extent map for their generation check
Qu Wenruo <[email protected]>
btrfs: defrag: bring back the old file extent search behavior
Eric Dumazet <[email protected]>
ipv6: fix skb drops in igmp6_event_query() and igmp6_event_report()
Steven Rostedt <[email protected]>
tracing: Add ustring operation to filtering string pointers
Qiang Yu <[email protected]>
drm/amdgpu: check vm ready by amdgpu_vm->evicting flag
Sergey Shtylyov <[email protected]>
ata: pata_hpt37x: fix PCI clock detection
Aaron Lewis <[email protected]>
KVM: x86: Add KVM_CAP_ENABLE_CAP to x86
Tadeusz Struk <[email protected]>
sched/fair: Fix fault in reweight_entity
Xin Yin <[email protected]>
ext4: fast commit may miss file actions
Xin Yin <[email protected]>
ext4: fast commit may not fallback for ineligible commit
Harshad Shirwadkar <[email protected]>
ext4: simplify updating of fast commit stats
Harshad Shirwadkar <[email protected]>
ext4: drop ineligible txn start stop APIs
James Morse <[email protected]>
KVM: arm64: Workaround Cortex-A510's single-step and PAC trap errata
Valentin Caron <[email protected]>
serial: stm32: prevent TDR register overwrite when sending x_char
Masami Hiramatsu <[email protected]>
arm64: Mark start_backtrace() notrace and NOKPROBE_SYMBOL
Steven Rostedt <[email protected]>
tracing: Add test for user space strings when filtering on string pointers
Christophe Vu-Brugier <[email protected]>
exfat: fix i_blocks for files truncated over 4 GiB
Christophe Vu-Brugier <[email protected]>
exfat: reuse exfat_inode_info variable instead of calling EXFAT_I()
Hangyu Hua <[email protected]>
usb: gadget: clear related members when goto fail
Hangyu Hua <[email protected]>
usb: gadget: don't release an existing dev->buf
Haimin Zhang <[email protected]>
block-map: add __GFP_ZERO flag for alloc_page in function bio_copy_kern
Daniele Palmas <[email protected]>
net: usb: cdc_mbim: avoid altsetting toggling for Telit FN990
Wolfram Sang <[email protected]>
i2c: qup: allow COMPILE_TEST
Wolfram Sang <[email protected]>
i2c: imx: allow COMPILE_TEST
Wolfram Sang <[email protected]>
i2c: cadence: allow COMPILE_TEST
Yongzhi Liu <[email protected]>
dmaengine: shdma: Fix runtime PM imbalance on error
Krzysztof Kozlowski <[email protected]>
selftests/ftrace: Do not trace do_softirq because of PREEMPT_RT
Evan Quan <[email protected]>
drm/amd/pm: correct UMD pstate clocks for Dimgrey Cavefish and Beige Goby
Sherry Yang <[email protected]>
selftests/seccomp: Fix seccomp failure by adding missing headers
Ronnie Sahlberg <[email protected]>
cifs: modefromsids must add an ACE for authenticated users
Basavaraj Natikar <[email protected]>
HID: amd_sfh: Add interrupt handler to process interrupts
Basavaraj Natikar <[email protected]>
HID: amd_sfh: Add functionality to clear interrupts
Basavaraj Natikar <[email protected]>
HID: amd_sfh: Handle amd_sfh work buffer in PM ops
Ronnie Sahlberg <[email protected]>
cifs: fix double free race when mount fails in cifs_get_root()
Ronnie Sahlberg <[email protected]>
cifs: do not use uninitialized data in the owner/group sid
Hangyu Hua <[email protected]>
tipc: fix a bit overflow in tipc_crypto_key_rcv()
Ming Lei <[email protected]>
block: loop:use kstatfs.f_bsize of backing file to set discard granularity
Marc Zyngier <[email protected]>
KVM: arm64: vgic: Read HW interrupt pending state from the HW
Filipe Manana <[email protected]>
btrfs: get rid of warning on transaction commit when using flushoncommit
José Expósito <[email protected]>
Input: clear BTN_RIGHT/MIDDLE on buttonpads
Oliver Barta <[email protected]>
regulator: core: fix false positive in regulator_late_cleanup()
Kai Vehmanen <[email protected]>
ASoC: rt5682: do not block workqueue if card is unbound
Kai Vehmanen <[email protected]>
ASoC: rt5668: do not block workqueue if card is unbound
Kai Vehmanen <[email protected]>
ASoC: rt5682s: do not block workqueue if card is unbound
Eric Anholt <[email protected]>
i2c: bcm2835: Avoid clock stretching timeouts
JaeMan Park <[email protected]>
mac80211_hwsim: initialize ieee80211_tx_info at hw_scan_work
Benjamin Beichler <[email protected]>
mac80211_hwsim: report NOACK frames in tx_status
-------------
Diffstat:
Documentation/admin-guide/mm/pagemap.rst | 2 +- Documentation/arm64/silicon-errata.rst | 2 + Documentation/trace/events.rst | 19 ++ Documentation/virt/kvm/api.rst | 2 +- Makefile | 4 +- arch/arm/boot/dts/omap3-devkit8000-common.dtsi | 18 ++ arch/arm/boot/dts/omap3-devkit8000.dts | 33 --- arch/arm/boot/dts/tegra124-nyan-big.dts | 15 +- arch/arm/boot/dts/tegra124-nyan-blaze.dts | 15 +- arch/arm/boot/dts/tegra124-venice2.dts | 14 +- arch/arm/kernel/kgdb.c | 36 ++- arch/arm/mm/mmu.c | 2 + arch/arm64/Kconfig | 16 ++ arch/arm64/boot/dts/arm/juno-base.dtsi | 3 +- arch/arm64/boot/dts/freescale/imx8mm.dtsi | 1 - arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi | 17 +- arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts | 2 - arch/arm64/boot/dts/rockchip/rk3568.dtsi | 6 +- arch/arm64/kernel/cpu_errata.c | 8 + arch/arm64/kernel/stacktrace.c | 3 +- arch/arm64/kvm/hyp/include/hyp/switch.h | 20 +- arch/arm64/kvm/vgic/vgic-mmio.c | 2 + arch/arm64/tools/cpucaps | 5 +- arch/mips/kernel/setup.c | 2 +- arch/mips/ralink/mt7621.c | 36 +-- arch/riscv/mm/Makefile | 3 + arch/riscv/mm/kasan_init.c | 3 +- arch/s390/include/asm/extable.h | 9 +- arch/s390/include/asm/ftrace.h | 10 +- arch/s390/include/asm/ptrace.h | 2 + arch/s390/kernel/ftrace.c | 37 ++- arch/s390/kernel/mcount.S | 9 + arch/s390/kernel/setup.c | 2 + arch/x86/kernel/kvmclock.c | 3 + arch/x86/kvm/mmu/mmu.c | 2 +- arch/x86/kvm/x86.c | 1 + block/blk-map.c | 2 +- drivers/ata/pata_hpt37x.c | 4 +- drivers/auxdisplay/lcd2s.c | 24 +- drivers/block/loop.c | 8 +- drivers/clocksource/timer-ti-dm-systimer.c | 3 +- drivers/dma/sh/shdma-base.c | 4 +- drivers/firmware/arm_scmi/driver.c | 2 +- drivers/firmware/efi/libstub/riscv-stub.c | 17 +- drivers/firmware/efi/vars.c | 5 +- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 10 +- drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 4 +- .../drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c | 26 ++- .../drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.h | 8 + drivers/gpu/drm/bridge/ti-sn65dsi86.c | 5 +- drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c | 2 +- drivers/gpu/drm/i915/intel_pch.c | 2 +- drivers/gpu/drm/i915/intel_pch.h | 2 +- drivers/hid/amd-sfh-hid/amd_sfh_pcie.c | 69 +++++- drivers/hid/amd-sfh-hid/amd_sfh_pcie.h | 2 + drivers/hid/hid-debug.c | 5 +- drivers/hid/hid-input.c | 3 + drivers/i2c/busses/Kconfig | 6 +- drivers/i2c/busses/i2c-bcm2835.c | 11 + drivers/input/input.c | 6 + drivers/input/keyboard/Kconfig | 2 +- drivers/input/mouse/elan_i2c_core.c | 64 ++---- drivers/iommu/amd/amd_iommu.h | 1 + drivers/iommu/amd/amd_iommu_types.h | 1 + drivers/iommu/amd/init.c | 10 + drivers/iommu/amd/io_pgtable.c | 120 ++++------ drivers/iommu/amd/iommu.c | 10 +- drivers/iommu/intel/iommu.c | 2 +- drivers/iommu/tegra-smmu.c | 4 +- drivers/net/arcnet/com20020-pci.c | 3 + drivers/net/can/usb/etas_es58x/es58x_core.c | 9 +- drivers/net/can/usb/etas_es58x/es58x_core.h | 8 +- drivers/net/can/usb/gs_usb.c | 10 +- drivers/net/dsa/microchip/ksz_common.c | 26 ++- drivers/net/ethernet/chelsio/cxgb3/t3_hw.c | 2 + drivers/net/ethernet/ibm/ibmvnic.c | 247 ++++++++++++++++----- drivers/net/ethernet/ibm/ibmvnic.h | 1 + drivers/net/ethernet/intel/e1000e/hw.h | 1 + drivers/net/ethernet/intel/e1000e/ich8lan.c | 8 +- drivers/net/ethernet/intel/e1000e/ich8lan.h | 1 + drivers/net/ethernet/intel/e1000e/netdev.c | 26 +++ drivers/net/ethernet/intel/iavf/iavf.h | 6 +- drivers/net/ethernet/intel/iavf/iavf_main.c | 152 ++++++++----- drivers/net/ethernet/intel/iavf/iavf_virtchnl.c | 14 +- drivers/net/ethernet/intel/igc/igc_phy.c | 4 - drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c | 6 +- .../net/ethernet/microchip/sparx5/sparx5_vlan.c | 20 +- drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c | 6 +- drivers/net/ethernet/stmicro/stmmac/stmmac.h | 4 +- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 170 +++++++++++++- drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c | 4 +- drivers/net/ipa/Kconfig | 2 + drivers/net/usb/cdc_mbim.c | 5 + drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c | 11 +- drivers/net/wireless/mac80211_hwsim.c | 13 ++ drivers/net/xen-netfront.c | 39 ++-- drivers/ntb/hw/intel/ntb_hw_gen4.c | 17 +- drivers/ntb/hw/intel/ntb_hw_gen4.h | 16 ++ drivers/pinctrl/sunxi/pinctrl-sunxi.c | 9 + drivers/platform/x86/amd-pmc.c | 34 ++- drivers/ptp/ptp_ocp.c | 25 ++- drivers/regulator/core.c | 13 +- drivers/soc/fsl/guts.c | 14 +- drivers/soc/fsl/qe/qe_io.c | 2 + drivers/soc/imx/gpcv2.c | 3 +- drivers/thermal/thermal_netlink.c | 5 +- drivers/tty/serial/stm32-usart.c | 12 + drivers/usb/gadget/legacy/inode.c | 10 +- fs/binfmt_elf.c | 25 ++- fs/btrfs/ctree.h | 10 + fs/btrfs/disk-io.c | 10 + fs/btrfs/extent-tree.c | 10 + fs/btrfs/extent_io.c | 16 +- fs/btrfs/extent_map.c | 2 + fs/btrfs/extent_map.h | 8 + fs/btrfs/inode.c | 170 ++++++++------ fs/btrfs/ioctl.c | 175 ++++++++++++++- fs/btrfs/qgroup.c | 9 +- fs/btrfs/relocation.c | 13 ++ fs/btrfs/root-tree.c | 15 ++ fs/btrfs/subpage.c | 2 +- fs/btrfs/transaction.c | 77 ++++++- fs/btrfs/transaction.h | 1 + fs/btrfs/tree-log.c | 61 ++++- fs/cifs/cifsacl.c | 9 +- fs/cifs/cifsfs.c | 1 + fs/exfat/file.c | 18 +- fs/exfat/inode.c | 13 +- fs/exfat/namei.c | 6 +- fs/exfat/super.c | 10 +- fs/ext4/ext4.h | 15 +- fs/ext4/extents.c | 6 +- fs/ext4/fast_commit.c | 218 ++++++++---------- fs/ext4/fast_commit.h | 27 +-- fs/ext4/inode.c | 4 +- fs/ext4/ioctl.c | 5 +- fs/ext4/namei.c | 4 +- fs/ext4/super.c | 3 +- fs/ext4/xattr.c | 6 +- fs/jbd2/commit.c | 2 +- fs/jbd2/journal.c | 2 +- fs/proc/task_mmu.c | 3 +- include/linux/jbd2.h | 2 +- include/linux/sched/task.h | 4 +- include/net/bluetooth/bluetooth.h | 3 +- include/net/ndisc.h | 4 +- include/net/netfilter/nf_queue.h | 2 +- include/net/xfrm.h | 1 - include/uapi/linux/input-event-codes.h | 4 +- include/uapi/linux/xfrm.h | 6 + kernel/fork.c | 13 +- kernel/sched/core.c | 23 +- kernel/trace/blktrace.c | 26 ++- kernel/trace/trace.c | 4 +- kernel/trace/trace_events_filter.c | 107 ++++++++- kernel/trace/trace_events_hist.c | 6 +- kernel/trace/trace_kprobe.c | 2 +- kernel/user_namespace.c | 14 +- mm/memfd.c | 40 +++- mm/util.c | 4 +- net/batman-adv/hard-interface.c | 29 ++- net/core/skbuff.c | 2 +- net/core/skmsg.c | 2 +- net/dcb/dcbnl.c | 44 ++++ net/ipv4/esp4.c | 2 +- net/ipv6/addrconf.c | 8 +- net/ipv6/esp6.c | 2 +- net/ipv6/ip6_output.c | 11 +- net/ipv6/mcast.c | 32 +-- net/mac80211/ieee80211_i.h | 2 +- net/mac80211/mlme.c | 16 +- net/mac80211/rx.c | 14 +- net/mptcp/protocol.c | 7 +- net/netfilter/core.c | 5 +- net/netfilter/nf_queue.c | 36 ++- net/netfilter/nf_tables_api.c | 4 +- net/netfilter/nfnetlink_queue.c | 12 +- net/smc/af_smc.c | 10 +- net/smc/smc_core.c | 5 +- net/tipc/crypto.c | 2 +- net/wireless/nl80211.c | 12 + net/xfrm/xfrm_device.c | 6 +- net/xfrm/xfrm_interface.c | 2 +- net/xfrm/xfrm_state.c | 14 +- sound/soc/codecs/cs4265.c | 3 +- sound/soc/codecs/rt5668.c | 12 +- sound/soc/codecs/rt5682.c | 12 +- sound/soc/codecs/rt5682s.c | 12 +- sound/soc/soc-ops.c | 4 +- sound/x86/intel_hdmi_audio.c | 2 +- .../drivers/net/mlxsw/spectrum/resource_scale.sh | 2 +- .../selftests/drivers/net/mlxsw/tc_police_scale.sh | 3 +- .../ftrace/test.d/ftrace/func_set_ftrace_file.tc | 2 +- tools/testing/selftests/seccomp/Makefile | 2 +- 194 files changed, 2383 insertions(+), 937 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/186 mac80211_hwsim: report NOACK frames in tx_status
From: Benjamin Beichler <[email protected]>
[ Upstream commit 42a79960ffa50bfe9e0bf5d6280be89bf563a5dd ]
Add IEEE80211_TX_STAT_NOACK_TRANSMITTED to tx_status flags to have proper statistics for non-acked frames.
--- drivers/net/wireless/mac80211_hwsim.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/net/wireless/mac80211_hwsim.c +4 -0
@@ -3770,6 +3770,10 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2, } txi->flags |=IEEE80211_TX_STAT_ACK ; } + +if (hwsim_flags &HWSIM_TX_CTL_NO_ACK ) + txi->flags |=IEEE80211_TX_STAT_NOACK_TRANSMITTED ; +ieee80211_tx_status_irqsafe (data2->hw, skb);return 0 ; out:
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 2/186 mac80211_hwsim: initialize ieee80211_tx_info at hw_scan_work
In reply to Greg Kroah-HartmanFrom: JaeMan Park <[email protected]>
[ Upstream commit cacfddf82baf1470e5741edeecb187260868f195 ]
In mac80211_hwsim, the probe_req frame is created and sent while scanning. It is sent with ieee80211_tx_info which is not initialized. Uninitialized ieee80211_tx_info can cause problems when using mac80211_hwsim with wmediumd. wmediumd checks the tx_rates field of ieee80211_tx_info and doesn't relay probe_req frame to other clients even if it is a broadcasting message.
Call ieee80211_tx_prepare_skb() to initialize ieee80211_tx_info for the probe_req that is created by hw_scan_work in mac80211_hwsim.
--- drivers/net/wireless/mac80211_hwsim.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/net/wireless/mac80211_hwsim.c +9 -0
@@ -2336,6 +2336,15 @@ static void hw_scan_work(struct work_struct *work)if (req->ie_len)skb_put_data (probe, req->ie, req->ie_len); +if (!ieee80211_tx_prepare_skb (hwsim->hw, + hwsim->hw_scan_vif, + probe, + hwsim->tmp_chan->band, +NULL )) { +kfree_skb (probe); +continue ; + } +local_bh_disable ();mac80211_hwsim_tx_frame (hwsim->hw, probe, hwsim->tmp_chan);
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 3/186 i2c: bcm2835: Avoid clock stretching timeouts
In reply to Greg Kroah-HartmanFrom: Eric Anholt <[email protected]>
[ Upstream commit 9495b9b31abe525ebd93da58de2c88b9f66d3a0e ]
The CLKT register contains at poweron 0x40, which at our typical 100kHz bus rate means .64ms. But there is no specified limit to how long devices should be able to stretch the clocks, so just disable the timeout. We still have a timeout wrapping the entire transfer.
--- drivers/i2c/busses/i2c-bcm2835.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
drivers/i2c/busses/i2c-bcm2835.c +11 -0
@@ -23,6 +23,11 @@#define BCM2835_I2C_FIFO 0x10#define BCM2835_I2C_DIV 0x14#define BCM2835_I2C_DEL 0x18 +/* +* 16-bit field for the number of SCL cycles to wait after rising SCL +* before deciding the slave is not responding. 0 disables the +* timeout detection. +*/ #define BCM2835_I2C_CLKT 0x1c#define BCM2835_I2C_C_READ BIT(0)
@@ -477,6 +482,12 @@ static int bcm2835_i2c_probe(struct platform_device *pdev) adap->dev.of_node = pdev->dev.of_node; adap->quirks =of_device_get_match_data (&pdev->dev); +/* +* Disable the hardware clock stretching timeout. SMBUS +* specifies a limit for how long the device can stretch the +* clock, but core I2C doesn't. +*/ +bcm2835_i2c_writel (i2c_dev,BCM2835_I2C_CLKT ,0 );bcm2835_i2c_writel (i2c_dev,BCM2835_I2C_C ,0 ); ret =i2c_add_adapter (adap);
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 4/186 ASoC: rt5682s: do not block workqueue if card is unbound
In reply to Greg Kroah-HartmanFrom: Kai Vehmanen <[email protected]>
[ Upstream commit d7b530fdc45e75a54914a194c4becd9672a4e24f ]
The current rt5682s_jack_detect_handler() assumes the component and card will always show up and implements an infinite usleep loop waiting for them to show up.
This does not hold true if a codec interrupt (or other event) occurs when the card is unbound. The codec driver's remove or shutdown functions cannot cancel the workqueue due to the wait loop. As a result, code can either end up blocking the workqueue, or hit a kernel oops when the card is freed.
Fix the issue by rescheduling the jack detect handler in case the card is not ready. In case card never shows up, the shutdown/remove/suspend calls can now cancel the detect task.
--- sound/soc/codecs/rt5682s.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
sound/soc/codecs/rt5682s.c +7 -5
@@ -824,11 +824,13 @@ static void rt5682s_jack_detect_handler(struct work_struct *work) container_of(work, struct rt5682s_priv, jack_detect_work.work);int val, btn_type; -while (!rt5682s->component) -usleep_range (10000 ,15000 ); - -while (!rt5682s->component->card->instantiated) -usleep_range (10000 ,15000 ); +if (!rt5682s->component || !rt5682s->component->card || + !rt5682s->component->card->instantiated) { +/* card not yet ready, try later */ +mod_delayed_work (system_power_efficient_wq, + &rt5682s->jack_detect_work,msecs_to_jiffies (15 )); +return ; + }mutex_lock (&rt5682s->jdet_mutex);mutex_lock (&rt5682s->calibrate_mutex);
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 5/186 ASoC: rt5668: do not block workqueue if card is unbound
In reply to Greg Kroah-HartmanFrom: Kai Vehmanen <[email protected]>
[ Upstream commit a6d78661dc903d90a327892bbc34268f3a5f4b9c ]
The current rt5668_jack_detect_handler() assumes the component and card will always show up and implements an infinite usleep loop waiting for them to show up.
This does not hold true if a codec interrupt (or other event) occurs when the card is unbound. The codec driver's remove or shutdown functions cannot cancel the workqueue due to the wait loop. As a result, code can either end up blocking the workqueue, or hit a kernel oops when the card is freed.
Fix the issue by rescheduling the jack detect handler in case the card is not ready. In case card never shows up, the shutdown/remove/suspend calls can now cancel the detect task.
--- sound/soc/codecs/rt5668.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
sound/soc/codecs/rt5668.c +7 -5
@@ -1022,11 +1022,13 @@ static void rt5668_jack_detect_handler(struct work_struct *work) container_of(work, struct rt5668_priv, jack_detect_work.work);int val, btn_type; -while (!rt5668->component) -usleep_range (10000 ,15000 ); - -while (!rt5668->component->card->instantiated) -usleep_range (10000 ,15000 ); +if (!rt5668->component || !rt5668->component->card || + !rt5668->component->card->instantiated) { +/* card not yet ready, try later */ +mod_delayed_work (system_power_efficient_wq, + &rt5668->jack_detect_work,msecs_to_jiffies (15 )); +return ; + }mutex_lock (&rt5668->calibrate_mutex);
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 6/186 ASoC: rt5682: do not block workqueue if card is unbound
In reply to Greg Kroah-HartmanFrom: Kai Vehmanen <[email protected]>
[ Upstream commit 4c33de0673ced9c7c37b3bbd9bfe0fda72340b2a ]
The current rt5682_jack_detect_handler() assumes the component and card will always show up and implements an infinite usleep loop waiting for them to show up.
This does not hold true if a codec interrupt (or other event) occurs when the card is unbound. The codec driver's remove or shutdown functions cannot cancel the workqueue due to the wait loop. As a result, code can either end up blocking the workqueue, or hit a kernel oops when the card is freed.
Fix the issue by rescheduling the jack detect handler in case the card is not ready. In case card never shows up, the shutdown/remove/suspend calls can now cancel the detect task.
--- sound/soc/codecs/rt5682.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
sound/soc/codecs/rt5682.c +7 -5
@@ -1092,11 +1092,13 @@ void rt5682_jack_detect_handler(struct work_struct *work)struct snd_soc_dapm_context *dapm;int val, btn_type; -while (!rt5682->component) -usleep_range (10000 ,15000 ); - -while (!rt5682->component->card->instantiated) -usleep_range (10000 ,15000 ); +if (!rt5682->component || !rt5682->component->card || + !rt5682->component->card->instantiated) { +/* card not yet ready, try later */ +mod_delayed_work (system_power_efficient_wq, + &rt5682->jack_detect_work,msecs_to_jiffies (15 )); +return ; + } dapm =snd_soc_component_get_dapm (rt5682->component);
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 7/186 regulator: core: fix false positive in regulator_late_cleanup()
In reply to Greg Kroah-HartmanFrom: Oliver Barta <[email protected]>
[ Upstream commit 4e2a354e3775870ca823f1fb29bbbffbe11059a6 ]
The check done by regulator_late_cleanup() to detect whether a regulator is on was inconsistent with the check done by _regulator_is_enabled(). While _regulator_is_enabled() takes the enable GPIO into account, regulator_late_cleanup() was not doing that.
This resulted in a false positive, e.g. when a GPIO-controlled fixed regulator was used, which was not enabled at boot time, e.g.
reg_disp_1v2: reg_disp_1v2 {
compatible = "regulator-fixed";
regulator-name = "display_1v2";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
gpio = <&tlmm 148 0>;
enable-active-high;
};Such regulator doesn't have an is_enabled() operation. Nevertheless it's state can be determined based on the enable GPIO. The check in regulator_late_cleanup() wrongly assumed that the regulator is on and tried to disable it.
--- drivers/regulator/core.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-)
drivers/regulator/core.c +3 -10
@@ -6014,9 +6014,8 @@ core_initcall(regulator_init);static int regulator_late_cleanup (struct device *dev,void *data) {struct regulator_dev *rdev =dev_to_rdev (dev); -const struct regulator_ops *ops = rdev->desc->ops;struct regulation_constraints *c = rdev->constraints; -int enabled, ret; +int ret;if (c && c->always_on)return 0 ;
@@ -6029,14 +6028,8 @@ static int regulator_late_cleanup(struct device *dev, void *data)if (rdev->use_count) goto unlock; -/* If we can't read the status assume it's always on. */ -if (ops->is_enabled) - enabled = ops->is_enabled (rdev); -else - enabled =1 ; - -/* But if reading the status failed, assume that it's off. */ -if (enabled <=0 ) +/* If reading the status failed, assume that it's off. */ +if (_regulator_is_enabled (rdev) <=0 ) goto unlock;if (have_full_constraints ()) {
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 8/186 Input: clear BTN_RIGHT/MIDDLE on buttonpads
In reply to Greg Kroah-HartmanFrom: José Expósito <[email protected]>
[ Upstream commit 37ef4c19b4c659926ce65a7ac709ceaefb211c40 ]
Buttonpads are expected to map the INPUT_PROP_BUTTONPAD property bit and the BTN_LEFT key bit.
As explained in the specification, where a device has a button type value of 0 (click-pad) or 1 (pressure-pad) there should not be discrete buttons:
https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/touchpad-windows-precision-touchpad-collection#device-capabilities-feature-report
However, some drivers map the BTN_RIGHT and/or BTN_MIDDLE key bits even though the device is a buttonpad and therefore does not have those buttons.
This behavior has forced userspace applications like libinput to implement different workarounds and quirks to detect buttonpads and offer to the user the right set of features and configuration options. For more information:
https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/726
In order to avoid this issue clear the BTN_RIGHT and BTN_MIDDLE key bits when the input device is register if the INPUT_PROP_BUTTONPAD property bit is set.
Notice that this change will not affect udev because it does not check for buttons. See systemd/src/udev/udev-builtin-input_id.c.
List of known affected hardware:
- Chuwi AeroBook Plus
- Chuwi Gemibook
- Framework Laptop
- GPD Win Max
- Huawei MateBook 2020
- Prestigio Smartbook 141 C2
- Purism Librem 14v1
- StarLite Mk II - AMI firmware - StarLite Mk II - Coreboot firmware - StarLite Mk III - AMI firmware - StarLite Mk III - Coreboot firmware
- StarLabTop Mk IV - AMI firmware
- StarLabTop Mk IV - Coreboot firmware
- StarBook Mk V
--- drivers/input/input.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/input/input.c +6 -0
@@ -2285,6 +2285,12 @@ int input_register_device(struct input_dev *dev)/* KEY_RESERVED is not supposed to be transmitted to userspace. */ __clear_bit (KEY_RESERVED , dev->keybit); +/* Buttonpads should not map BTN_RIGHT and/or BTN_MIDDLE. */ +if (test_bit (INPUT_PROP_BUTTONPAD , dev->propbit)) { +__clear_bit (BTN_RIGHT , dev->keybit); +__clear_bit (BTN_MIDDLE , dev->keybit); + } +/* Make sure that bitmasks not mentioned in dev->evbit are clean. */ input_cleanse_bitmasks (dev);
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 9/186 btrfs: get rid of warning on transaction commit when using flushoncommit
In reply to Greg Kroah-HartmanFrom: Filipe Manana <[email protected]>
[ Upstream commit a0f0cf8341e34e5d2265bfd3a7ad68342da1e2aa ]
When using the flushoncommit mount option, during almost every transaction commit we trigger a warning from __writeback_inodes_sb_nr():
$ cat fs/fs-writeback.c:
(...)
static void __writeback_inodes_sb_nr(struct super_block *sb, ...
{
(...)
WARN_ON(!rwsem_is_locked(&sb->s_umount));
(...)
}
(...)The trace produced in dmesg looks like the following:
[947.473890] WARNING: CPU: 5 PID: 930 at fs/fs-writeback.c:2610 __writeback_inodes_sb_nr+0x7e/0xb3 [947.481623] Modules linked in: nfsd nls_cp437 cifs asn1_decoder cifs_arc4 fscache cifs_md4 ipmi_ssif [947.489571] CPU: 5 PID: 930 Comm: btrfs-transacti Not tainted 95.16.3-srb-asrock-00001-g36437ad63879 #186 [947.497969] RIP: 0010:__writeback_inodes_sb_nr+0x7e/0xb3 [947.502097] Code: 24 10 4c 89 44 24 18 c6 (...) [947.519760] RSP: 0018:ffffc90000777e10 EFLAGS: 00010246 [947.523818] RAX: 0000000000000000 RBX: 0000000000963300 RCX: 0000000000000000 [947.529765] RDX: 0000000000000000 RSI: 000000000000fa51 RDI: ffffc90000777e50 [947.535740] RBP: ffff888101628a90 R08: ffff888100955800 R09: ffff888100956000 [947.541701] R10: 0000000000000002 R11: 0000000000000001 R12: ffff888100963488 [947.547645] R13: ffff888100963000 R14: ffff888112fb7200 R15: ffff888100963460 [947.553621] FS: 0000000000000000(0000) GS:ffff88841fd40000(0000) knlGS:0000000000000000 [947.560537] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [947.565122] CR2: 0000000008be50c4 CR3: 000000000220c000 CR4: 00000000001006e0 [947.571072] Call Trace: [947.572354] <TASK> [947.573266] btrfs_commit_transaction+0x1f1/0x998 [947.576785] ? start_transaction+0x3ab/0x44e [947.579867] ? schedule_timeout+0x8a/0xdd [947.582716] transaction_kthread+0xe9/0x156 [947.585721] ? btrfs_cleanup_transaction.isra.0+0x407/0x407 [947.590104] kthread+0x131/0x139 [947.592168] ? set_kthread_struct+0x32/0x32 [947.595174] ret_from_fork+0x22/0x30 [947.597561] </TASK> [947.598553] ---[ end trace 644721052755541c ]---
This is because we started using writeback_inodes_sb() to flush delalloc when committing a transaction (when using -o flushoncommit), in order to avoid deadlocks with filesystem freeze operations. This change was made by commit ce8ea7cc6eb313 ("btrfs: don't call btrfs_start_delalloc_roots in flushoncommit"). After that change we started producing that warning, and every now and then a user reports this since the warning happens too often, it spams dmesg/syslog, and a user is unsure if this reflects any problem that might compromise the filesystem's reliability.
We can not just lock the sb->s_umount semaphore before calling writeback_inodes_sb(), because that would at least deadlock with filesystem freezing, since at fs/super.c:freeze_super() sync_filesystem() is called while we are holding that semaphore in write mode, and that can trigger a transaction commit, resulting in a deadlock. It would also trigger the same type of deadlock in the unmount path. Possibly, it could also introduce some other locking dependencies that lockdep would report.
To fix this call try_to_writeback_inodes_sb() instead of writeback_inodes_sb(), because that will try to read lock sb->s_umount and then will only call writeback_inodes_sb() if it was able to lock it. This is fine because the cases where it can't read lock sb->s_umount are during a filesystem unmount or during a filesystem freeze - in those cases sb->s_umount is write locked and sync_filesystem() is called, which calls writeback_inodes_sb(). In other words, in all cases where we can't take a read lock on sb->s_umount, writeback is already being triggered elsewhere.
An alternative would be to call btrfs_start_delalloc_roots() with a number of pages different from LONG_MAX, for example matching the number of delalloc bytes we currently have, in which case we would end up starting all delalloc with filemap_fdatawrite_wbc() and not with an async flush via filemap_flush() - that is only possible after the rather recent commit e076ab2a2ca70a ("btrfs: shrink delalloc pages instead of full inodes"). However that creates a whole new can of worms due to new lock dependencies, which lockdep complains, like for example:
[ 8948.247280] ======================================================
[ 8948.247823] WARNING: possible circular locking dependency detected
[ 8948.248353] 5.17.0-rc1-btrfs-next-111 #1 Not tainted
[ 8948.248786] ------------------------------------------------------
[ 8948.249320] kworker/u16:18/933570 is trying to acquire lock:
[ 8948.249812] ffff9b3de1591690 (sb_internal#2){.+.+}-{0:0}, at: find_free_extent+0x141e/0x1590 [btrfs]
[ 8948.250638]
but task is already holding lock:
[ 8948.251140] ffff9b3e09c717d8 (&root->delalloc_mutex){+.+.}-{3:3}, at: start_delalloc_inodes+0x78/0x400 [btrfs]
[ 8948.252018]
which lock already depends on the new lock.[ 8948.252710]
the existing dependency chain (in reverse order) is:
[ 8948.253343]
-> #2 (&root->delalloc_mutex){+.+.}-{3:3}:
[ 8948.253950] __mutex_lock+0x90/0x900
[ 8948.254354] start_delalloc_inodes+0x78/0x400 [btrfs]
[ 8948.254859] btrfs_start_delalloc_roots+0x194/0x2a0 [btrfs]
[ 8948.255408] btrfs_commit_transaction+0x32f/0xc00 [btrfs]
[ 8948.255942] btrfs_mksubvol+0x380/0x570 [btrfs]
[ 8948.256406] btrfs_mksnapshot+0x81/0xb0 [btrfs]
[ 8948.256870] __btrfs_ioctl_snap_create+0x17f/0x190 [btrfs]
[ 8948.257413] btrfs_ioctl_snap_create_v2+0xbb/0x140 [btrfs]
[ 8948.257961] btrfs_ioctl+0x1196/0x3630 [btrfs]
[ 8948.258418] __x64_sys_ioctl+0x83/0xb0
[ 8948.258793] do_syscall_64+0x3b/0xc0
[ 8948.259146] entry_SYSCALL_64_after_hwframe+0x44/0xae
[ 8948.259709]
-> #1 (&fs_info->delalloc_root_mutex){+.+.}-{3:3}:
[ 8948.260330] __mutex_lock+0x90/0x900
[ 8948.260692] btrfs_start_delalloc_roots+0x97/0x2a0 [btrfs]
[ 8948.261234] btrfs_commit_transaction+0x32f/0xc00 [btrfs]
[ 8948.261766] btrfs_set_free_space_cache_v1_active+0x38/0x60 [btrfs]
[ 8948.262379] btrfs_start_pre_rw_mount+0x119/0x180 [btrfs]
[ 8948.262909] open_ctree+0x1511/0x171e [btrfs]
[ 8948.263359] btrfs_mount_root.cold+0x12/0xde [btrfs]
[ 8948.263863] legacy_get_tree+0x30/0x50
[ 8948.264242] vfs_get_tree+0x28/0xc0
[ 8948.264594] vfs_kern_mount.part.0+0x71/0xb0
[ 8948.265017] btrfs_mount+0x11d/0x3a0 [btrfs]
[ 8948.265462] legacy_get_tree+0x30/0x50
[ 8948.265851] vfs_get_tree+0x28/0xc0
[ 8948.266203] path_mount+0x2d4/0xbe0
[ 8948.266554] __x64_sys_mount+0x103/0x140
[ 8948.266940] do_syscall_64+0x3b/0xc0
[ 8948.267300] entry_SYSCALL_64_after_hwframe+0x44/0xae
[ 8948.267790]
-> #0 (sb_internal#2){.+.+}-{0:0}:
[ 8948.268322] __lock_acquire+0x12e8/0x2260
[ 8948.268733] lock_acquire+0xd7/0x310
[ 8948.269092] start_transaction+0x44c/0x6e0 [btrfs]
[ 8948.269591] find_free_extent+0x141e/0x1590 [btrfs]
[ 8948.270087] btrfs_reserve_extent+0x14b/0x280 [btrfs]
[ 8948.270588] cow_file_range+0x17e/0x490 [btrfs]
[ 8948.271051] btrfs_run_delalloc_range+0x345/0x7a0 [btrfs]
[ 8948.271586] writepage_delalloc+0xb5/0x170 [btrfs]
[ 8948.272071] __extent_writepage+0x156/0x3c0 [btrfs]
[ 8948.272579] extent_write_cache_pages+0x263/0x460 [btrfs]
[ 8948.273113] extent_writepages+0x76/0x130 [btrfs]
[ 8948.273573] do_writepages+0xd2/0x1c0
[ 8948.273942] filemap_fdatawrite_wbc+0x68/0x90
[ 8948.274371] start_delalloc_inodes+0x17f/0x400 [btrfs]
[ 8948.274876] btrfs_start_delalloc_roots+0x194/0x2a0 [btrfs]
[ 8948.275417] flush_space+0x1f2/0x630 [btrfs]
[ 8948.275863] btrfs_async_reclaim_data_space+0x108/0x1b0 [btrfs]
[ 8948.276438] process_one_work+0x252/0x5a0
[ 8948.276829] worker_thread+0x55/0x3b0
[ 8948.277189] kthread+0xf2/0x120
[ 8948.277506] ret_from_fork+0x22/0x30
[ 8948.277868]
other info that might help us debug this:[ 8948.278548] Chain exists of:
sb_internal#2 --> &fs_info->delalloc_root_mutex --> &root->delalloc_mutex[ 8948.279601] Possible unsafe locking scenario:
[ 8948.280102] CPU0 CPU1
[ 8948.280508] ---- ----
[ 8948.280915] lock(&root->delalloc_mutex);
[ 8948.281271] lock(&fs_info->delalloc_root_mutex);
[ 8948.281915] lock(&root->delalloc_mutex);
[ 8948.282487] lock(sb_internal#2);
[ 8948.282800]
*** DEADLOCK ***[ 8948.283333] 4 locks held by kworker/u16:18/933570:
[ 8948.283750] #0: ffff9b3dc00a9d48 ((wq_completion)events_unbound){+.+.}-{0:0}, at: process_one_work+0x1d2/0x5a0
[ 8948.284609] #1: ffffa90349dafe70 ((work_completion)(&fs_info->async_data_reclaim_work)){+.+.}-{0:0}, at: process_one_work+0x1d2/0x5a0
[ 8948.285637] #2: ffff9b3e14db5040 (&fs_info->delalloc_root_mutex){+.+.}-{3:3}, at: btrfs_start_delalloc_roots+0x97/0x2a0 [btrfs]
[ 8948.286674] #3: ffff9b3e09c717d8 (&root->delalloc_mutex){+.+.}-{3:3}, at: start_delalloc_inodes+0x78/0x400 [btrfs]
[ 8948.287596]
stack backtrace:
[ 8948.287975] CPU: 3 PID: 933570 Comm: kworker/u16:18 Not tainted 5.17.0-rc1-btrfs-next-111 #1
[ 8948.288677] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
[ 8948.289649] Workqueue: events_unbound btrfs_async_reclaim_data_space [btrfs]
[ 8948.290298] Call Trace:
[ 8948.290517] <TASK>
[ 8948.290700] dump_stack_lvl+0x59/0x73
[ 8948.291026] check_noncircular+0xf3/0x110
[ 8948.291375] ? start_transaction+0x228/0x6e0 [btrfs]
[ 8948.291826] __lock_acquire+0x12e8/0x2260
[ 8948.292241] lock_acquire+0xd7/0x310
[ 8948.292714] ? find_free_extent+0x141e/0x1590 [btrfs]
[ 8948.293241] ? lock_is_held_type+0xea/0x140
[ 8948.293601] start_transaction+0x44c/0x6e0 [btrfs]
[ 8948.294055] ? find_free_extent+0x141e/0x1590 [btrfs]
[ 8948.294518] find_free_extent+0x141e/0x1590 [btrfs]
[ 8948.294957] ? _raw_spin_unlock+0x29/0x40
[ 8948.295312] ? btrfs_get_alloc_profile+0x124/0x290 [btrfs]
[ 8948.295813] btrfs_reserve_extent+0x14b/0x280 [btrfs]
[ 8948.296270] cow_file_range+0x17e/0x490 [btrfs]
[ 8948.296691] btrfs_run_delalloc_range+0x345/0x7a0 [btrfs]
[ 8948.297175] ? find_lock_delalloc_range+0x247/0x270 [btrfs]
[ 8948.297678] writepage_delalloc+0xb5/0x170 [btrfs]
[ 8948.298123] __extent_writepage+0x156/0x3c0 [btrfs]
[ 8948.298570] extent_write_cache_pages+0x263/0x460 [btrfs]
[ 8948.299061] extent_writepages+0x76/0x130 [btrfs]
[ 8948.299495] do_writepages+0xd2/0x1c0
[ 8948.299817] ? sched_clock_cpu+0xd/0x110
[ 8948.300160] ? lock_release+0x155/0x4a0
[ 8948.300494] filemap_fdatawrite_wbc+0x68/0x90
[ 8948.300874] ? do_raw_spin_unlock+0x4b/0xa0
[ 8948.301243] start_delalloc_inodes+0x17f/0x400 [btrfs]
[ 8948.301706] ? lock_release+0x155/0x4a0
[ 8948.302055] btrfs_start_delalloc_roots+0x194/0x2a0 [btrfs]
[ 8948.302564] flush_space+0x1f2/0x630 [btrfs]
[ 8948.302970] btrfs_async_reclaim_data_space+0x108/0x1b0 [btrfs]
[ 8948.303510] process_one_work+0x252/0x5a0
[ 8948.303860] ? process_one_work+0x5a0/0x5a0
[ 8948.304221] worker_thread+0x55/0x3b0
[ 8948.304543] ? process_one_work+0x5a0/0x5a0
[ 8948.304904] kthread+0xf2/0x120
[ 8948.305184] ? kthread_complete_and_exit+0x20/0x20
[ 8948.305598] ret_from_fork+0x22/0x30
[ 8948.305921] </TASK>It all comes from the fact that btrfs_start_delalloc_roots() takes the delalloc_root_mutex, in the transaction commit path we are holding a read lock on one of the superblock's freeze semaphores (via sb_start_intwrite()), the async reclaim task can also do a call to btrfs_start_delalloc_roots(), which ends up triggering writeback with calls to filemap_fdatawrite_wbc(), resulting in extent allocation which in turn can call btrfs_start_transaction(), which will result in taking the freeze semaphore via sb_start_intwrite(), forming a nasty dependency on all those locks which can be taken in different orders by different code paths.
So just adopt the simple approach of calling try_to_writeback_inodes_sb() at btrfs_start_delalloc_flush().
--- fs/btrfs/transaction.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
fs/btrfs/transaction.c +10 -2
@@ -2013,16 +2013,24 @@ static void btrfs_cleanup_pending_block_groups(struct btrfs_trans_handle *trans)static inline int btrfs_start_delalloc_flush (struct btrfs_fs_info *fs_info) {/* -* We use writeback_inodes_sb here because if we used +* We use try_to_writeback_inodes_sb() here because if we used * btrfs_start_delalloc_roots we would deadlock with fs freeze. * Currently are holding the fs freeze lock, if we do an async flush * we'll do btrfs_join_transaction() and deadlock because we need to * wait for the fs freeze lock. Using the direct flushing we benefit * from already being in a transaction and our join_transaction doesn't * have to re-take the fs freeze lock. +* +* Note that try_to_writeback_inodes_sb() will only trigger writeback +* if it can read lock sb->s_umount. It will always be able to lock it, +* except when the filesystem is being unmounted or being frozen, but in +* those cases sync_filesystem() is called, which results in calling +* writeback_inodes_sb() while holding a write lock on sb->s_umount. +* Note that we don't call writeback_inodes_sb() directly, because it +* will emit a warning if sb->s_umount is not locked. */ if (btrfs_test_opt (fs_info,FLUSHONCOMMIT )) -writeback_inodes_sb (fs_info->sb,WB_REASON_SYNC ); +try_to_writeback_inodes_sb (fs_info->sb,WB_REASON_SYNC );return 0 ; }
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 10/186 KVM: arm64: vgic: Read HW interrupt pending state from the HW
In reply to Greg Kroah-HartmanFrom: Marc Zyngier <[email protected]>
[ Upstream commit 5bfa685e62e9ba93c303a9a8db646c7228b9b570 ]
It appears that a read access to GIC[DR]_I[CS]PENDRn doesn't always result in the pending interrupts being accurately reported if they are mapped to a HW interrupt. This is particularily visible when acking the timer interrupt and reading the GICR_ISPENDR1 register immediately after, for example (the interrupt appears as not-pending while it really is...).
This is because a HW interrupt has its 'active and pending state' kept in the *physical* distributor, and not in the virtual one, as mandated by the spec (this is what allows the direct deactivation). The virtual distributor only caries the pending and active *states* (note the plural, as these are two independent and non-overlapping states).
Fix it by reading the HW state back, either from the timer itself or from the distributor if necessary.
--- arch/arm64/kvm/vgic/vgic-mmio.c | 2 ++ 1 file changed, 2 insertions(+)
arch/arm64/kvm/vgic/vgic-mmio.c +2 -0
@@ -248,6 +248,8 @@ unsigned long vgic_mmio_read_pending(struct kvm_vcpu *vcpu,IRQCHIP_STATE_PENDING , &val);WARN_RATELIMIT (err,"IRQ %d" , irq->host_irq); + }else if (vgic_irq_is_mapped_level (irq)) { + val =vgic_get_phys_line_level (irq); }else { val =irq_is_pending (irq); }
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 11/186 block: loop:use kstatfs.f_bsize of backing file to set discard granularity
In reply to Greg Kroah-HartmanFrom: Ming Lei <[email protected]>
[ Upstream commit 06582bc86d7f48d35cd044098ca1e246e8c7c52e ]
If backing file's filesystem has implemented ->fallocate(), we think the loop device can support discard, then pass sb->s_blocksize as discard_granularity. However, some underlying FS, such as overlayfs, doesn't set sb->s_blocksize, and causes discard_granularity to be set as zero, then the warning in __blkdev_issue_discard() is triggered.
Christoph suggested to pass kstatfs.f_bsize as discard granularity, and this way is fine because kstatfs.f_bsize means 'Optimal transfer block size', which still matches with definition of discard granularity.
So fix the issue by setting discard_granularity as kstatfs.f_bsize if it is available, otherwise claims discard isn't supported.
--- drivers/block/loop.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/block/loop.c +7 -1
@@ -79,6 +79,7 @@#include <linux/ioprio.h> #include <linux/blk-cgroup.h> #include <linux/sched/mm.h> +#include <linux/statfs.h> #include "loop.h"
@@ -774,8 +775,13 @@ static void loop_config_discard(struct loop_device *lo) granularity =0 ; }else { +struct kstatfs sbuf; + max_discard_sectors =UINT_MAX >>9 ; - granularity = inode->i_sb->s_blocksize; +if (!vfs_statfs (&file->f_path, &sbuf)) + granularity = sbuf.f_bsize; +else + max_discard_sectors =0 ; }if (max_discard_sectors) {
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 12/186 tipc: fix a bit overflow in tipc_crypto_key_rcv()
In reply to Greg Kroah-HartmanFrom: Hangyu Hua <[email protected]>
[ Upstream commit 143de8d97d79316590475dc2a84513c63c863ddf ]
msg_data_sz return a 32bit value, but size is 16bit. This may lead to a bit overflow.
--- net/tipc/crypto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/tipc/crypto.c +1 -1
@@ -2287,7 +2287,7 @@ static bool tipc_crypto_key_rcv(struct tipc_crypto *rx, struct tipc_msg *hdr)struct tipc_crypto *tx =tipc_net (rx->net)->crypto_tx;struct tipc_aead_key *skey =NULL ;u16 key_gen =msg_key_gen (hdr); -u16 size =msg_data_sz (hdr); +u32 size =msg_data_sz (hdr);u8 *data =msg_data (hdr);unsigned int keylen;
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 13/186 cifs: do not use uninitialized data in the owner/group sid
In reply to Greg Kroah-HartmanFrom: Ronnie Sahlberg <[email protected]>
[ Upstream commit 26d3dadebbcbddfaf1d9caad42527a28a0ed28d8 ]
When idsfromsid is used we create a special SID for owner/group. This structure must be initialized or else the first 5 bytes of the Authority field of the SID will contain uninitialized data and thus not be a valid SID.
--- fs/cifs/cifsacl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/cifs/cifsacl.c +2 -2
@@ -1297,7 +1297,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,if (uid_valid (uid)) {/* chown */ uid_t id; - nowner_sid_ptr =kmalloc (sizeof (struct cifs_sid ), + nowner_sid_ptr =kzalloc (sizeof (struct cifs_sid ),GFP_KERNEL );if (!nowner_sid_ptr) { rc = -ENOMEM ;
@@ -1326,7 +1326,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, }if (gid_valid (gid)) {/* chgrp */ gid_t id; - ngroup_sid_ptr =kmalloc (sizeof (struct cifs_sid ), + ngroup_sid_ptr =kzalloc (sizeof (struct cifs_sid ),GFP_KERNEL );if (!ngroup_sid_ptr) { rc = -ENOMEM ;
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 14/186 cifs: fix double free race when mount fails in cifs_get_root()
In reply to Greg Kroah-HartmanFrom: Ronnie Sahlberg <[email protected]>
[ Upstream commit 3d6cc9898efdfb062efb74dc18cfc700e082f5d5 ]
When cifs_get_root() fails during cifs_smb3_do_mount() we call deactivate_locked_super() which eventually will call delayed_free() which will free the context.
In this situation we should not proceed to enter the out: section in cifs_smb3_do_mount() and free the same resources a second time.
[Thu Feb 10 12:59:06 2022] BUG: KASAN: use-after-free in rcu_cblist_dequeue+0x32/0x60 [Thu Feb 10 12:59:06 2022] Read of size 8 at addr ffff888364f4d110 by task swapper/1/0
[Thu Feb 10 12:59:06 2022] CPU: 1 PID: 0 Comm: swapper/1 Tainted: G OE 5.17.0-rc3+ #4 [Thu Feb 10 12:59:06 2022] Hardware name: Microsoft Corporation Virtual Machine/Virtual Machine, BIOS Hyper-V UEFI Release v4.0 12/17/2019 [Thu Feb 10 12:59:06 2022] Call Trace: [Thu Feb 10 12:59:06 2022] <IRQ> [Thu Feb 10 12:59:06 2022] dump_stack_lvl+0x5d/0x78 [Thu Feb 10 12:59:06 2022] print_address_description.constprop.0+0x24/0x150 [Thu Feb 10 12:59:06 2022] ? rcu_cblist_dequeue+0x32/0x60 [Thu Feb 10 12:59:06 2022] kasan_report.cold+0x7d/0x117 [Thu Feb 10 12:59:06 2022] ? rcu_cblist_dequeue+0x32/0x60 [Thu Feb 10 12:59:06 2022] __asan_load8+0x86/0xa0 [Thu Feb 10 12:59:06 2022] rcu_cblist_dequeue+0x32/0x60 [Thu Feb 10 12:59:06 2022] rcu_core+0x547/0xca0 [Thu Feb 10 12:59:06 2022] ? call_rcu+0x3c0/0x3c0 [Thu Feb 10 12:59:06 2022] ? __this_cpu_preempt_check+0x13/0x20 [Thu Feb 10 12:59:06 2022] ? lock_is_held_type+0xea/0x140 [Thu Feb 10 12:59:06 2022] rcu_core_si+0xe/0x10 [Thu Feb 10 12:59:06 2022] __do_softirq+0x1d4/0x67b [Thu Feb 10 12:59:06 2022] __irq_exit_rcu+0x100/0x150 [Thu Feb 10 12:59:06 2022] irq_exit_rcu+0xe/0x30 [Thu Feb 10 12:59:06 2022] sysvec_hyperv_stimer0+0x9d/0xc0 ... [Thu Feb 10 12:59:07 2022] Freed by task 58179: [Thu Feb 10 12:59:07 2022] kasan_save_stack+0x26/0x50 [Thu Feb 10 12:59:07 2022] kasan_set_track+0x25/0x30 [Thu Feb 10 12:59:07 2022] kasan_set_free_info+0x24/0x40 [Thu Feb 10 12:59:07 2022] ____kasan_slab_free+0x137/0x170 [Thu Feb 10 12:59:07 2022] __kasan_slab_free+0x12/0x20 [Thu Feb 10 12:59:07 2022] slab_free_freelist_hook+0xb3/0x1d0 [Thu Feb 10 12:59:07 2022] kfree+0xcd/0x520 [Thu Feb 10 12:59:07 2022] cifs_smb3_do_mount+0x149/0xbe0 [cifs] [Thu Feb 10 12:59:07 2022] smb3_get_tree+0x1a0/0x2e0 [cifs] [Thu Feb 10 12:59:07 2022] vfs_get_tree+0x52/0x140 [Thu Feb 10 12:59:07 2022] path_mount+0x635/0x10c0 [Thu Feb 10 12:59:07 2022] __x64_sys_mount+0x1bf/0x210 [Thu Feb 10 12:59:07 2022] do_syscall_64+0x5c/0xc0 [Thu Feb 10 12:59:07 2022] entry_SYSCALL_64_after_hwframe+0x44/0xae
[Thu Feb 10 12:59:07 2022] Last potentially related work creation: [Thu Feb 10 12:59:07 2022] kasan_save_stack+0x26/0x50 [Thu Feb 10 12:59:07 2022] __kasan_record_aux_stack+0xb6/0xc0 [Thu Feb 10 12:59:07 2022] kasan_record_aux_stack_noalloc+0xb/0x10 [Thu Feb 10 12:59:07 2022] call_rcu+0x76/0x3c0 [Thu Feb 10 12:59:07 2022] cifs_umount+0xce/0xe0 [cifs] [Thu Feb 10 12:59:07 2022] cifs_kill_sb+0xc8/0xe0 [cifs] [Thu Feb 10 12:59:07 2022] deactivate_locked_super+0x5d/0xd0 [Thu Feb 10 12:59:07 2022] cifs_smb3_do_mount+0xab9/0xbe0 [cifs] [Thu Feb 10 12:59:07 2022] smb3_get_tree+0x1a0/0x2e0 [cifs] [Thu Feb 10 12:59:07 2022] vfs_get_tree+0x52/0x140 [Thu Feb 10 12:59:07 2022] path_mount+0x635/0x10c0 [Thu Feb 10 12:59:07 2022] __x64_sys_mount+0x1bf/0x210 [Thu Feb 10 12:59:07 2022] do_syscall_64+0x5c/0xc0 [Thu Feb 10 12:59:07 2022] entry_SYSCALL_64_after_hwframe+0x44/0xae
--- fs/cifs/cifsfs.c | 1 + 1 file changed, 1 insertion(+)
fs/cifs/cifsfs.c +1 -0
@@ -908,6 +908,7 @@ cifs_smb3_do_mount(struct file_system_type *fs_type, out_super:deactivate_locked_super (sb); +return root; out:if (cifs_sb) {kfree (cifs_sb->prepath);
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 15/186 HID: amd_sfh: Handle amd_sfh work buffer in PM ops
In reply to Greg Kroah-HartmanFrom: Basavaraj Natikar <[email protected]>
[ Upstream commit 0cf74235f4403b760a37f77271d2ca3424001ff9 ]
Since in the current amd_sfh design the sensor data is periodically obtained in the form of poll data, during the suspend/resume cycle, scheduling a delayed work adds no value.
So, cancel the work and restart back during the suspend/resume cycle respectively.
--- drivers/hid/amd-sfh-hid/amd_sfh_pcie.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/hid/amd-sfh-hid/amd_sfh_pcie.c +4 -0
@@ -290,6 +290,8 @@ static int __maybe_unused amd_mp2_pci_resume(struct device *dev) } } +schedule_delayed_work (&cl_data->work_buffer,msecs_to_jiffies (AMD_SFH_IDLE_LOOP )); +return 0 ; }
@@ -312,6 +314,8 @@ static int __maybe_unused amd_mp2_pci_suspend(struct device *dev) } } +cancel_delayed_work_sync (&cl_data->work_buffer); +return 0 ; }
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 16/186 HID: amd_sfh: Add functionality to clear interrupts
In reply to Greg Kroah-HartmanFrom: Basavaraj Natikar <[email protected]>
[ Upstream commit fb75a3791a8032848c987db29b622878d8fe2b1c ]
Newer AMD platforms with SFH may generate interrupts on some events which are unwarranted. Until this is cleared the actual MP2 data processing maybe stalled in some cases.
Add a mechanism to clear the pending interrupts (if any) during the driver initialization and sensor command operations.
--- drivers/hid/amd-sfh-hid/amd_sfh_pcie.c | 25 ++++++++++++++++++++++++- drivers/hid/amd-sfh-hid/amd_sfh_pcie.h | 1 + 2 files changed, 25 insertions(+), 1 deletion(-)
drivers/hid/amd-sfh-hid/amd_sfh_pcie.c +24 -1
@@ -89,6 +89,20 @@ static void amd_stop_all_sensor_v2(struct amd_mp2_dev *privdata)writel (cmd_base.ul, privdata->mmio +AMD_C2P_MSG0 ); } +static void amd_sfh_clear_intr_v2 (struct amd_mp2_dev *privdata) +{ +if (readl (privdata->mmio +AMD_P2C_MSG (4 ))) { +writel (0 , privdata->mmio +AMD_P2C_MSG (4 )); +writel (0xf , privdata->mmio +AMD_P2C_MSG (5 )); + } +} + +static void amd_sfh_clear_intr (struct amd_mp2_dev *privdata) +{ +if (privdata->mp2_ops->clear_intr) + privdata->mp2_ops->clear_intr (privdata); +} +void amd_start_sensor (struct amd_mp2_dev *privdata,struct amd_mp2_sensor_info info) {union sfh_cmd_param cmd_param;
@@ -193,6 +207,7 @@ static void amd_mp2_pci_remove(void *privdata)struct amd_mp2_dev *mp2 = privdata;amd_sfh_hid_client_deinit (privdata); mp2->mp2_ops->stop_all (mp2); +amd_sfh_clear_intr (mp2); }static const struct amd_mp2_ops amd_sfh_ops_v2 = {
@@ -200,6 +215,7 @@ static const struct amd_mp2_ops amd_sfh_ops_v2 = { .stop = amd_stop_sensor_v2, .stop_all = amd_stop_all_sensor_v2, .response = amd_sfh_wait_response_v2, + .clear_intr = amd_sfh_clear_intr_v2, };static const struct amd_mp2_ops amd_sfh_ops = {
@@ -262,8 +278,13 @@ static int amd_mp2_pci_probe(struct pci_dev *pdev, const struct pci_device_id *imp2_select_ops (privdata); rc =amd_sfh_hid_client_init (privdata); -if (rc) +if (rc) { +amd_sfh_clear_intr (privdata); +dev_err (&pdev->dev,"amd_sfh_hid_client_init failed\n" );return rc; + } + +amd_sfh_clear_intr (privdata);return devm_add_action_or_reset (&pdev->dev, amd_mp2_pci_remove, privdata); }
@@ -291,6 +312,7 @@ static int __maybe_unused amd_mp2_pci_resume(struct device *dev) }schedule_delayed_work (&cl_data->work_buffer,msecs_to_jiffies (AMD_SFH_IDLE_LOOP )); +amd_sfh_clear_intr (mp2);return 0 ; }
@@ -315,6 +337,7 @@ static int __maybe_unused amd_mp2_pci_suspend(struct device *dev) }cancel_delayed_work_sync (&cl_data->work_buffer); +amd_sfh_clear_intr (mp2);return 0 ; }
drivers/hid/amd-sfh-hid/amd_sfh_pcie.h +1 -0
@@ -141,5 +141,6 @@ struct amd_mp2_ops {void (*stop)(struct amd_mp2_dev *privdata,u16 sensor_idx);void (*stop_all)(struct amd_mp2_dev *privdata);int (*response)(struct amd_mp2_dev *mp2,u8 sid,u32 sensor_sts); + void (*clear_intr)(struct amd_mp2_dev *privdata); };#endif
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 17/186 HID: amd_sfh: Add interrupt handler to process interrupts
In reply to Greg Kroah-HartmanFrom: Basavaraj Natikar <[email protected]>
[ Upstream commit 7f016b35ca7623c71b31facdde080e8ce171a697 ]
On newer AMD platforms with SFH, it is observed that random interrupts get generated on the SFH hardware and until this is cleared the firmware sensor processing is stalled, resulting in no data been received to driver side.
Add routines to handle these interrupts, so that firmware operations are not stalled.
--- drivers/hid/amd-sfh-hid/amd_sfh_pcie.c | 40 ++++++++++++++++++++++++++ drivers/hid/amd-sfh-hid/amd_sfh_pcie.h | 1 + 2 files changed, 41 insertions(+)
drivers/hid/amd-sfh-hid/amd_sfh_pcie.c +40 -0
@@ -103,6 +103,30 @@ static void amd_sfh_clear_intr(struct amd_mp2_dev *privdata) privdata->mp2_ops->clear_intr (privdata); } +static irqreturn_t amd_sfh_irq_handler (int irq,void *data) +{ +amd_sfh_clear_intr (data); + +return IRQ_HANDLED ; +} + +static int amd_sfh_irq_init_v2 (struct amd_mp2_dev *privdata) +{ +int rc; + +pci_intx (privdata->pdev, true); + + rc =devm_request_irq (&privdata->pdev->dev, privdata->pdev->irq, + amd_sfh_irq_handler,0 ,DRIVER_NAME , privdata); +if (rc) { +dev_err (&privdata->pdev->dev,"failed to request irq %d err=%d\n" , + privdata->pdev->irq, rc); +return rc; + } + +return 0 ; +} +void amd_start_sensor (struct amd_mp2_dev *privdata,struct amd_mp2_sensor_info info) {union sfh_cmd_param cmd_param;
@@ -207,6 +231,7 @@ static void amd_mp2_pci_remove(void *privdata)struct amd_mp2_dev *mp2 = privdata;amd_sfh_hid_client_deinit (privdata); mp2->mp2_ops->stop_all (mp2); +pci_intx (mp2->pdev, false);amd_sfh_clear_intr (mp2); }
@@ -216,6 +241,7 @@ static const struct amd_mp2_ops amd_sfh_ops_v2 = { .stop_all = amd_stop_all_sensor_v2, .response = amd_sfh_wait_response_v2, .clear_intr = amd_sfh_clear_intr_v2, + .init_intr = amd_sfh_irq_init_v2, };static const struct amd_mp2_ops amd_sfh_ops = {
@@ -241,6 +267,14 @@ static void mp2_select_ops(struct amd_mp2_dev *privdata) } } +static int amd_sfh_irq_init (struct amd_mp2_dev *privdata) +{ +if (privdata->mp2_ops->init_intr) +return privdata->mp2_ops->init_intr (privdata); + +return 0 ; +} +static int amd_mp2_pci_probe (struct pci_dev *pdev,const struct pci_device_id *id) {struct amd_mp2_dev *privdata;
@@ -277,6 +311,12 @@ static int amd_mp2_pci_probe(struct pci_dev *pdev, const struct pci_device_id *imp2_select_ops (privdata); + rc =amd_sfh_irq_init (privdata); +if (rc) { +dev_err (&pdev->dev,"amd_sfh_irq_init failed\n" ); +return rc; + } + rc =amd_sfh_hid_client_init (privdata);if (rc) {amd_sfh_clear_intr (privdata);
drivers/hid/amd-sfh-hid/amd_sfh_pcie.h +1 -0
@@ -142,5 +142,6 @@ struct amd_mp2_ops {void (*stop_all)(struct amd_mp2_dev *privdata);int (*response)(struct amd_mp2_dev *mp2,u8 sid,u32 sensor_sts);void (*clear_intr)(struct amd_mp2_dev *privdata); + int (*init_intr)(struct amd_mp2_dev *privdata); };#endif
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 18/186 cifs: modefromsids must add an ACE for authenticated users
In reply to Greg Kroah-HartmanFrom: Ronnie Sahlberg <[email protected]>
[ Upstream commit 0c6f4ebf8835d01866eb686d47578cde80097981 ]
When we create a file with modefromsids we set an ACL that has one ACE for the magic modefromsid as well as a second ACE that grants full access to all authenticated users.
When later we chante the mode on the file we strip away this, and other, ACE for authenticated users in set_chmod_dacl() and then just add back/update the modefromsid ACE.
Thus leaving the file with a single ACE that is for the mode and no ACE to grant any user any rights to access the file.
Fix this by always adding back also the modefromsid ACE so that we do not drop the rights to access the file.
--- fs/cifs/cifsacl.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
fs/cifs/cifsacl.c +4 -1
@@ -949,6 +949,9 @@ static void populate_new_aces(char *nacl_base, pnntace = (struct cifs_ace *) (nacl_base + nsize); nsize +=setup_special_mode_ACE (pnntace, nmode); num_aces++; + pnntace = (struct cifs_ace *) (nacl_base + nsize); + nsize +=setup_authusers_ACE (pnntace); + num_aces++; goto set_size; }
@@ -1613,7 +1616,7 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode, nsecdesclen = secdesclen;if (pnmode && *pnmode !=NO_CHANGE_64 ) {/* chmod */ if (mode_from_sid) - nsecdesclen +=sizeof (struct cifs_ace ); + nsecdesclen +=2 *sizeof (struct cifs_ace );else /* cifsacl */ nsecdesclen +=5 *sizeof (struct cifs_ace ); }else {/* chown */
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 19/186 selftests/seccomp: Fix seccomp failure by adding missing headers
In reply to Greg Kroah-HartmanFrom: Sherry Yang <[email protected]>
[ Upstream commit 21bffcb76ee2fbafc7d5946cef10abc9df5cfff7 ]
seccomp_bpf failed on tests 47 global.user_notification_filter_empty and 48 global.user_notification_filter_empty_threaded when it's tested on updated kernel but with old kernel headers. Because old kernel headers don't have definition of macro __NR_clone3 which is required for these two tests. Since under selftests/, we can install headers once for all tests (the default INSTALL_HDR_PATH is usr/include), fix it by adding usr/include to the list of directories to be searched. Use "-isystem" to indicate it's a system directory as the real kernel headers directories are.
--- tools/testing/selftests/seccomp/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/testing/selftests/seccomp/Makefile +1 -1
@@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 -CFLAGS += -Wl,-no-as-needed -Wall +CFLAGS += -Wl,-no-as-needed -Wall -isystem ../../../../usr/include/ LDFLAGS += -lpthread TEST_GEN_PROGS := seccomp_bpf seccomp_benchmark
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 20/186 drm/amd/pm: correct UMD pstate clocks for Dimgrey Cavefish and Beige Goby
In reply to Greg Kroah-HartmanFrom: Evan Quan <[email protected]>
[ Upstream commit 0136f5844b006e2286f873457c3fcba8c45a3735 ]
Correct the UMD pstate profiling clocks for Dimgrey Cavefish and Beige Goby.
--- .../amd/pm/swsmu/smu11/sienna_cichlid_ppt.c | 26 +++++++++++++++---- .../amd/pm/swsmu/smu11/sienna_cichlid_ppt.h | 8 ++++++ 2 files changed, 29 insertions(+), 5 deletions(-)
drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +21 -5
@@ -1261,21 +1261,37 @@ static int sienna_cichlid_populate_umd_state_clk(struct smu_context *smu) &dpm_context->dpm_tables.soc_table;struct smu_umd_pstate_table *pstate_table = &smu->pstate_table; +struct amdgpu_device *adev = smu->adev; pstate_table->gfxclk_pstate.min = gfx_table->min; pstate_table->gfxclk_pstate.peak = gfx_table->max; -if (gfx_table->max >=SIENNA_CICHLID_UMD_PSTATE_PROFILING_GFXCLK ) - pstate_table->gfxclk_pstate.standard =SIENNA_CICHLID_UMD_PSTATE_PROFILING_GFXCLK ; pstate_table->uclk_pstate.min = mem_table->min; pstate_table->uclk_pstate.peak = mem_table->max; -if (mem_table->max >=SIENNA_CICHLID_UMD_PSTATE_PROFILING_MEMCLK ) - pstate_table->uclk_pstate.standard =SIENNA_CICHLID_UMD_PSTATE_PROFILING_MEMCLK ; pstate_table->socclk_pstate.min = soc_table->min; pstate_table->socclk_pstate.peak = soc_table->max; -if (soc_table->max >=SIENNA_CICHLID_UMD_PSTATE_PROFILING_SOCCLK ) + +switch (adev->asic_type) { +case CHIP_SIENNA_CICHLID : +case CHIP_NAVY_FLOUNDER : + pstate_table->gfxclk_pstate.standard =SIENNA_CICHLID_UMD_PSTATE_PROFILING_GFXCLK ; + pstate_table->uclk_pstate.standard =SIENNA_CICHLID_UMD_PSTATE_PROFILING_MEMCLK ; pstate_table->socclk_pstate.standard =SIENNA_CICHLID_UMD_PSTATE_PROFILING_SOCCLK ; +break ; +case CHIP_DIMGREY_CAVEFISH : + pstate_table->gfxclk_pstate.standard =DIMGREY_CAVEFISH_UMD_PSTATE_PROFILING_GFXCLK ; + pstate_table->uclk_pstate.standard =DIMGREY_CAVEFISH_UMD_PSTATE_PROFILING_MEMCLK ; + pstate_table->socclk_pstate.standard =DIMGREY_CAVEFISH_UMD_PSTATE_PROFILING_SOCCLK ; +break ; +case CHIP_BEIGE_GOBY : + pstate_table->gfxclk_pstate.standard =BEIGE_GOBY_UMD_PSTATE_PROFILING_GFXCLK ; + pstate_table->uclk_pstate.standard =BEIGE_GOBY_UMD_PSTATE_PROFILING_MEMCLK ; + pstate_table->socclk_pstate.standard =BEIGE_GOBY_UMD_PSTATE_PROFILING_SOCCLK ; +break ; +default : +break ; + }return 0 ; }
drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.h +8 -0
@@ -33,6 +33,14 @@ typedef enum {#define SIENNA_CICHLID_UMD_PSTATE_PROFILING_SOCCLK 960#define SIENNA_CICHLID_UMD_PSTATE_PROFILING_MEMCLK 1000 +#define DIMGREY_CAVEFISH_UMD_PSTATE_PROFILING_GFXCLK 1950 +#define DIMGREY_CAVEFISH_UMD_PSTATE_PROFILING_SOCCLK 960 +#define DIMGREY_CAVEFISH_UMD_PSTATE_PROFILING_MEMCLK 676 + +#define BEIGE_GOBY_UMD_PSTATE_PROFILING_GFXCLK 2200 +#define BEIGE_GOBY_UMD_PSTATE_PROFILING_SOCCLK 960 +#define BEIGE_GOBY_UMD_PSTATE_PROFILING_MEMCLK 1000 +extern void sienna_cichlid_set_ppt_funcs (struct smu_context *smu);#endif
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 21/186 selftests/ftrace: Do not trace do_softirq because of PREEMPT_RT
In reply to Greg Kroah-HartmanFrom: Krzysztof Kozlowski <[email protected]>
[ Upstream commit 6fec1ab67f8d60704cc7de64abcfd389ab131542 ]
The PREEMPT_RT patchset does not use do_softirq() function thus trying to filter for do_softirq fails for such kernel:
echo do_softirq
ftracetest: 81: echo: echo: I/O error
Choose some other visible function for the test. The function does not have to be actually executed during the test, because it is only testing filter API interface.
--- .../selftests/ftrace/test.d/ftrace/func_set_ftrace_file.tc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/testing/selftests/ftrace/test.d/ftrace/func_set_ftrace_file.tc +1 -1
@@ -19,7 +19,7 @@ fail() { # mesg FILTER=set_ftrace_filter FUNC1="schedule" -FUNC2="do_softirq" +FUNC2="scheduler_tick" ALL_FUNCS="#### all functions enabled ####"
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 22/186 dmaengine: shdma: Fix runtime PM imbalance on error
In reply to Greg Kroah-HartmanFrom: Yongzhi Liu <[email protected]>
[ Upstream commit 455896c53d5b803733ddd84e1bf8a430644439b6 ]
pm_runtime_get_() increments the runtime PM usage counter even when it returns an error code, thus a matching decrement is needed on the error handling path to keep the counter balanced.
--- drivers/dma/sh/shdma-base.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/dma/sh/shdma-base.c +3 -1
@@ -115,8 +115,10 @@ static dma_cookie_t shdma_tx_submit(struct dma_async_tx_descriptor *tx) ret =pm_runtime_get (schan->dev);spin_unlock_irq (&schan->chan_lock); -if (ret <0 ) +if (ret <0 ) {dev_err (schan->dev,"%s(): GET = %d\n" , __func__, ret); +pm_runtime_put (schan->dev); + }pm_runtime_barrier (schan->dev);
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 23/186 i2c: cadence: allow COMPILE_TEST
In reply to Greg Kroah-HartmanFrom: Wolfram Sang <[email protected]>
[ Upstream commit 0b0dcb3882c8f08bdeafa03adb4487e104d26050 ]
Driver builds fine with COMPILE_TEST. Enable it for wider test coverage and easier maintenance.
--- drivers/i2c/busses/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/i2c/busses/Kconfig +1 -1
@@ -488,7 +488,7 @@ config I2C_BRCMSTB config I2C_CADENCE tristate "Cadence I2C Controller" - depends on ARCH_ZYNQ || ARM64 || XTENSA + depends on ARCH_ZYNQ || ARM64 || XTENSA || COMPILE_TEST help Say yes here to select Cadence I2C Host Controller. This controller is e.g. used by Xilinx Zynq.
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 24/186 i2c: imx: allow COMPILE_TEST
In reply to Greg Kroah-HartmanFrom: Wolfram Sang <[email protected]>
[ Upstream commit 2ce4462f2724d1b3cedccea441c6d18bb360629a ]
Driver builds fine with COMPILE_TEST. Enable it for wider test coverage and easier maintenance.
--- drivers/i2c/busses/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/i2c/busses/Kconfig +1 -1
@@ -680,7 +680,7 @@ config I2C_IMG config I2C_IMX tristate "IMX I2C interface" - depends on ARCH_MXC || ARCH_LAYERSCAPE || COLDFIRE + depends on ARCH_MXC || ARCH_LAYERSCAPE || COLDFIRE || COMPILE_TEST select I2C_SLAVE help Say Y here if you want to use the IIC bus controller on
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 25/186 i2c: qup: allow COMPILE_TEST
In reply to Greg Kroah-HartmanFrom: Wolfram Sang <[email protected]>
[ Upstream commit 5de717974005fcad2502281e9f82e139ca91f4bb ]
Driver builds fine with COMPILE_TEST. Enable it for wider test coverage and easier maintenance.
--- drivers/i2c/busses/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/i2c/busses/Kconfig +1 -1
@@ -935,7 +935,7 @@ config I2C_QCOM_GENI config I2C_QUP tristate "Qualcomm QUP based I2C controller" - depends on ARCH_QCOM + depends on ARCH_QCOM || COMPILE_TEST help If you say yes to this option, support will be included for the built-in I2C interface on the Qualcomm SoCs.
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 26/186 net: usb: cdc_mbim: avoid altsetting toggling for Telit FN990
In reply to Greg Kroah-HartmanFrom: Daniele Palmas <[email protected]>
[ Upstream commit 21e8a96377e6b6debae42164605bf9dcbe5720c5 ]
Add quirk CDC_MBIM_FLAG_AVOID_ALTSETTING_TOGGLE for Telit FN990 0x1071 composition in order to avoid bind error.
--- drivers/net/usb/cdc_mbim.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/net/usb/cdc_mbim.c +5 -0
@@ -659,6 +659,11 @@ static const struct usb_device_id mbim_devs[] = { .driver_info = (unsigned long)&cdc_mbim_info_avoid_altsetting_toggle, }, +/* Telit FN990 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x1bc7, 0x1071, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE), + .driver_info = (unsigned long )&cdc_mbim_info_avoid_altsetting_toggle, + }, + /* default entry */ { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE), .driver_info = (unsigned long)&cdc_mbim_info_zlp,
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 27/186 block-map: add __GFP_ZERO flag for alloc_page in function bio_copy_kern
In reply to Greg Kroah-HartmanFrom: Haimin Zhang <[email protected]>
[ Upstream commit cc8f7fe1f5eab010191aa4570f27641876fa1267 ]
Add __GFP_ZERO flag for alloc_page in function bio_copy_kern to initialize the buffer of a bio.
--- block/blk-map.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
block/blk-map.c +1 -1
@@ -446,7 +446,7 @@ static struct bio *bio_copy_kern(struct request_queue *q, void *data,if (bytes > len) bytes = len; - page =alloc_page (GFP_NOIO | gfp_mask); + page =alloc_page (GFP_NOIO | __GFP_ZERO | gfp_mask);if (!page) goto cleanup;
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 28/186 usb: gadget: dont release an existing dev->buf
In reply to Greg Kroah-HartmanFrom: Hangyu Hua <[email protected]>
commit 89f3594d0de58e8a57d92d497dea9fee3d4b9cda upstream.
dev->buf does not need to be released if it already exists before executing dev_config.
--- drivers/usb/gadget/legacy/inode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/usb/gadget/legacy/inode.c +2 -1
@@ -1826,8 +1826,9 @@ dev_config (struct file *fd, const charspin_lock_irq (&dev->lock); value = -EINVAL ;if (dev->buf) { +spin_unlock_irq (&dev->lock);kfree (kbuf); - goto fail; +return value; } dev->buf = kbuf;
Greg Kroah-Hartman
maintainerPATCH 29/186 usb: gadget: clear related members when goto fail
In reply to Greg Kroah-HartmanFrom: Hangyu Hua <[email protected]>
commit 501e38a5531efbd77d5c73c0ba838a889bfc1d74 upstream.
dev->config and dev->hs_config and dev->dev need to be cleaned if dev_config fails to avoid UAF.
--- drivers/usb/gadget/legacy/inode.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/usb/gadget/legacy/inode.c +5 -2
@@ -1875,8 +1875,8 @@ dev_config (struct file *fd, const char value =usb_gadget_probe_driver (&gadgetfs_driver);if (value !=0 ) { -kfree (dev->buf); - dev->buf =NULL ; +spin_lock_irq (&dev->lock); + goto fail; }else {/* at this point "good" hardware has for the first time * let the USB the host see us. alternatively, if users
@@ -1893,6 +1893,9 @@ dev_config (struct file *fd, const charreturn value; fail: + dev->config =NULL ; + dev->hs_config =NULL ; + dev->dev =NULL ;spin_unlock_irq (&dev->lock);pr_debug ("%s: %s fail %zd, %p\n" , shortname, __func__, value, dev);kfree (dev->buf);
Greg Kroah-Hartman
maintainerPATCH 30/186 exfat: reuse exfat_inode_info variable instead of calling EXFAT_I()
In reply to Greg Kroah-HartmanFrom: Christophe Vu-Brugier <[email protected]>
[ Upstream commit 7dee6f57d7f22a89dd214518c778aec448270d4c ]
Also add a local "struct exfat_inode_info *ei" variable to exfat_truncate() to simplify the code.
--- fs/exfat/file.c | 14 +++++++------- fs/exfat/inode.c | 9 ++++----- fs/exfat/namei.c | 6 +++--- fs/exfat/super.c | 6 +++--- 4 files changed, 17 insertions(+), 18 deletions(-)
fs/exfat/file.c +7 -7
@@ -110,8 +110,7 @@ int __exfat_truncate(struct inode *inode, loff_t new_size)exfat_set_volume_dirty (sb); num_clusters_new =EXFAT_B_TO_CLU_ROUND_UP (i_size_read (inode), sbi); - num_clusters_phys = -EXFAT_B_TO_CLU_ROUND_UP (EXFAT_I (inode)->i_size_ondisk, sbi); + num_clusters_phys =EXFAT_B_TO_CLU_ROUND_UP (ei->i_size_ondisk, sbi);exfat_chain_set (&clu, ei->start_clu, num_clusters_phys, ei->flags);
@@ -228,12 +227,13 @@ void exfat_truncate(struct inode *inode, loff_t size) {struct super_block *sb = inode->i_sb;struct exfat_sb_info *sbi =EXFAT_SB (sb); +struct exfat_inode_info *ei =EXFAT_I (inode);unsigned int blocksize =i_blocksize (inode);loff_t aligned_size;int err;mutex_lock (&sbi->s_lock); -if (EXFAT_I (inode)->start_clu ==0 ) { +if (ei->start_clu ==0 ) {/* * Empty start_clu != ~0 (not allocated) */
@@ -260,11 +260,11 @@ void exfat_truncate(struct inode *inode, loff_t size) aligned_size++; } -if (EXFAT_I (inode)->i_size_ondisk >i_size_read (inode)) -EXFAT_I (inode)->i_size_ondisk = aligned_size; +if (ei->i_size_ondisk >i_size_read (inode)) + ei->i_size_ondisk = aligned_size; -if (EXFAT_I (inode)->i_size_aligned >i_size_read (inode)) -EXFAT_I (inode)->i_size_aligned = aligned_size; +if (ei->i_size_aligned >i_size_read (inode)) + ei->i_size_aligned = aligned_size;mutex_unlock (&sbi->s_lock); }
fs/exfat/inode.c +4 -5
@@ -114,10 +114,9 @@ static int exfat_map_cluster(struct inode *inode, unsigned int clu_offset,unsigned int local_clu_offset = clu_offset;unsigned int num_to_be_allocated =0 , num_clusters =0 ; -if (EXFAT_I (inode)->i_size_ondisk >0 ) +if (ei->i_size_ondisk >0 ) num_clusters = -EXFAT_B_TO_CLU_ROUND_UP (EXFAT_I (inode)->i_size_ondisk, - sbi); +EXFAT_B_TO_CLU_ROUND_UP (ei->i_size_ondisk, sbi);if (clu_offset >= num_clusters) num_to_be_allocated = clu_offset - num_clusters +1 ;
@@ -416,10 +415,10 @@ static int exfat_write_end(struct file *file, struct address_space *mapping, err =generic_write_end (file, mapping, pos, len, copied, pagep, fsdata); -if (EXFAT_I (inode)->i_size_aligned <i_size_read (inode)) { +if (ei->i_size_aligned <i_size_read (inode)) {exfat_fs_error (inode->i_sb,"invalid size(size(%llu) > aligned(%llu)\n" , -i_size_read (inode),EXFAT_I (inode)->i_size_aligned); +i_size_read (inode), ei->i_size_aligned);return -EIO ; }
fs/exfat/namei.c +3 -3
@@ -395,9 +395,9 @@ static int exfat_find_empty_entry(struct inode *inode,/* directory inode should be updated in here */ i_size_write (inode, size); -EXFAT_I (inode)->i_size_ondisk += sbi->cluster_size; -EXFAT_I (inode)->i_size_aligned += sbi->cluster_size; -EXFAT_I (inode)->flags = p_dir->flags; + ei->i_size_ondisk += sbi->cluster_size; + ei->i_size_aligned += sbi->cluster_size; + ei->flags = p_dir->flags; inode->i_blocks +=1 << sbi->sect_per_clus_bits; }
fs/exfat/super.c +3 -3
@@ -366,9 +366,9 @@ static int exfat_read_root(struct inode *inode) inode->i_blocks = ((i_size_read (inode) + (sbi->cluster_size -1 )) & ~(sbi->cluster_size -1 )) >> inode->i_blkbits; -EXFAT_I (inode)->i_pos = ((loff_t )sbi->root_dir <<32 ) |0xffffffff ; -EXFAT_I (inode)->i_size_aligned =i_size_read (inode); -EXFAT_I (inode)->i_size_ondisk =i_size_read (inode); + ei->i_pos = ((loff_t )sbi->root_dir <<32 ) |0xffffffff ; + ei->i_size_aligned =i_size_read (inode); + ei->i_size_ondisk =i_size_read (inode);exfat_save_attr (inode,ATTR_SUBDIR ); inode->i_mtime = inode->i_atime = inode->i_ctime = ei->i_crtime =
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 31/186 exfat: fix i_blocks for files truncated over 4 GiB
In reply to Greg Kroah-HartmanFrom: Christophe Vu-Brugier <[email protected]>
[ Upstream commit 92fba084b79e6bc7b12fc118209f1922c1a2df56 ]
In exfat_truncate(), the computation of inode->i_blocks is wrong if the file is larger than 4 GiB because a 32-bit variable is used as a mask. This is fixed and simplified by using round_up().
Also fix the same buggy computation in exfat_read_root() and another (correct) one in exfat_fill_inode(). The latter was fixed another way last month but can be simplified by using round_up() as well. See:
commit 0c336d6e33f4 ("exfat: fix incorrect loading of i_blocks for
large files")
--- fs/exfat/file.c | 4 ++-- fs/exfat/inode.c | 4 ++-- fs/exfat/super.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-)
fs/exfat/file.c +2 -2
@@ -251,8 +251,8 @@ void exfat_truncate(struct inode *inode, loff_t size)else mark_inode_dirty (inode); - inode->i_blocks = ((i_size_read (inode) + (sbi->cluster_size -1 )) & - ~(sbi->cluster_size -1 )) >> inode->i_blkbits; + inode->i_blocks =round_up (i_size_read (inode), sbi->cluster_size) >> + inode->i_blkbits; write_size: aligned_size =i_size_read (inode);if (aligned_size & (blocksize -1 )) {
fs/exfat/inode.c +2 -2
@@ -602,8 +602,8 @@ static int exfat_fill_inode(struct inode *inode, struct exfat_dir_entry *info)exfat_save_attr (inode, info->attr); - inode->i_blocks = ((i_size_read (inode) + (sbi->cluster_size -1 )) & - ~((loff_t )sbi->cluster_size -1 )) >> inode->i_blkbits; + inode->i_blocks =round_up (i_size_read (inode), sbi->cluster_size) >> + inode->i_blkbits; inode->i_mtime = info->mtime; inode->i_ctime = info->mtime; ei->i_crtime = info->crtime;
fs/exfat/super.c +2 -2
@@ -364,8 +364,8 @@ static int exfat_read_root(struct inode *inode) inode->i_op = &exfat_dir_inode_operations; inode->i_fop = &exfat_dir_operations; - inode->i_blocks = ((i_size_read (inode) + (sbi->cluster_size -1 )) - & ~(sbi->cluster_size -1 )) >> inode->i_blkbits; + inode->i_blocks =round_up (i_size_read (inode), sbi->cluster_size) >> + inode->i_blkbits; ei->i_pos = ((loff_t )sbi->root_dir <<32 ) |0xffffffff ; ei->i_size_aligned =i_size_read (inode); ei->i_size_ondisk =i_size_read (inode);
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 32/186 tracing: Add test for user space strings when filtering on string pointers
In reply to Greg Kroah-HartmanFrom: Steven Rostedt <[email protected]>
[ Upstream commit 77360f9bbc7e5e2ab7a2c8b4c0244fbbfcfc6f62 ]
Pingfan reported that the following causes a fault:
echo "filename ~ \"cpu\"" > events/syscalls/sys_enter_openat/filter echo 1 > events/syscalls/sys_enter_at/enable
The reason is that trace event filter treats the user space pointer defined by "filename" as a normal pointer to compare against the "cpu" string. The following bug happened:
kvm-03-guest16 login: [72198.026181] BUG: unable to handle page fault for address: 00007fffaae8ef60 #PF: supervisor read access in kernel mode
#PF: error_code(0x0001) - permissions violation
PGD 80000001008b7067 P4D 80000001008b7067 PUD 2393f1067 PMD 2393ec067 PTE 8000000108f47867
Oops: 0001 [#1] PREEMPT SMP PTI
CPU: 1 PID: 1 Comm: systemd Kdump: loaded Not tainted 5.14.0-32.el9.x86_64 #1
Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011
RIP: 0010:strlen+0x0/0x20
Code: 48 89 f9 74 09 48 83 c1 01 80 39 00 75 f7 31 d2 44 0f b6 04 16 44 88 04 11
48 83 c2 01 45 84 c0 75 ee c3 0f 1f 80 00 00 00 00 <80> 3f 00 74 10 48 89 f8
48 83 c0 01 80 38 00 75 f7 48 29 f8 c3 31
RSP: 0018:ffffb5b900013e48 EFLAGS: 00010246
RAX: 0000000000000018 RBX: ffff8fc1c49ede00 RCX: 0000000000000000
RDX: 0000000000000020 RSI: ffff8fc1c02d601c RDI: 00007fffaae8ef60
RBP: 00007fffaae8ef60 R08: 0005034f4ddb8ea4 R09: 0000000000000000
R10: ffff8fc1c02d601c R11: 0000000000000000 R12: ffff8fc1c8a6e380
R13: 0000000000000000 R14: ffff8fc1c02d6010 R15: ffff8fc1c00453c0
FS: 00007fa86123db40(0000) GS:ffff8fc2ffd00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007fffaae8ef60 CR3: 0000000102880001 CR4: 00000000007706e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
PKRU: 55555554
Call Trace:
filter_pred_pchar+0x18/0x40
filter_match_preds+0x31/0x70
ftrace_syscall_enter+0x27a/0x2c0
syscall_trace_enter.constprop.0+0x1aa/0x1d0
do_syscall_64+0x16/0x90
entry_SYSCALL_64_after_hwframe+0x44/0xae
RIP: 0033:0x7fa861d88664The above happened because the kernel tried to access user space directly and triggered a "supervisor read access in kernel mode" fault. Worse yet, the memory could not even be loaded yet, and a SEGFAULT could happen as well. This could be true for kernel space accessing as well.
To be even more robust, test both kernel and user space strings. If the string fails to read, then simply have the filter fail.
Note, TASK_SIZE is used to determine if the pointer is user or kernel space and the appropriate strncpy_from_kernel/user_nofault() function is used to copy the memory. For some architectures, the compare to TASK_SIZE may always pick user space or kernel space. If it gets it wrong, the only thing is that the filter will fail to match. In the future, this needs to be fixed to have the event denote which should be used. But failing a filter is much better than panicing the machine, and that can be solved later.
--- Documentation/trace/events.rst | 10 +++++ kernel/trace/trace_events_filter.c | 66 ++++++++++++++++++++++++++++-- 2 files changed, 73 insertions(+), 3 deletions(-)
Documentation/trace/events.rst +10 -0
@@ -230,6 +230,16 @@ Currently the caret ('^') for an error always appears at the beginning of the filter string; the error message should still be useful though even without more accurate position info. +5.2.1 Filter limitations +------------------------ + +If a filter is placed on a string pointer ``(char *)`` that does not point +to a string on the ring buffer, but instead points to kernel or user space +memory, then, for safety reasons, at most 1024 bytes of the content is +copied onto a temporary buffer to do the compare. If the copy of the memory +faults (the pointer points to memory that should not be accessed), then the +string compare will be treated as not matching. + 5.3 Clearing filters --------------------
kernel/trace/trace_events_filter.c +63 -3
99 lines not on this page · raw message
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 33/186 arm64: Mark start_backtrace() notrace and NOKPROBE_SYMBOL
In reply to Greg Kroah-HartmanFrom: Masami Hiramatsu <[email protected]>
[ Upstream commit 1e0924bd09916fab795fc2a21ec1d148f24299fd ]
Mark the start_backtrace() as notrace and NOKPROBE_SYMBOL because this function is called from ftrace and lockdep to get the caller address via return_address(). The lockdep is used in kprobes, it should also be NOKPROBE_SYMBOL.
--- arch/arm64/kernel/stacktrace.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/arm64/kernel/stacktrace.c +2 -1
@@ -33,7 +33,7 @@*/ -void start_backtrace (struct stackframe *frame,unsigned long fp, +notrace void start_backtrace(struct stackframe *frame, unsigned long fp,unsigned long pc) { frame->fp = fp;
@@ -55,6 +55,7 @@ void start_backtrace(struct stackframe *frame, unsigned long fp, frame->prev_fp =0 ; frame->prev_type =STACK_TYPE_UNKNOWN ; } +NOKPROBE_SYMBOL (start_backtrace);/* * Unwind from one frame record (A) to the next frame record (B).
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 34/186 serial: stm32: prevent TDR register overwrite when sending x_char
In reply to Greg Kroah-HartmanFrom: Valentin Caron <[email protected]>
[ Upstream commit d3d079bde07e1b7deaeb57506dc0b86010121d17 ]
When sending x_char in stm32_usart_transmit_chars(), driver can overwrite the value of TDR register by the value of x_char. If this happens, the previous value that was present in TDR register will not be sent through uart.
This code checks if the previous value in TDR register is sent before writing the x_char value into register.
--- drivers/tty/serial/stm32-usart.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
drivers/tty/serial/stm32-usart.c +12 -0
@@ -520,10 +520,22 @@ static void stm32_usart_transmit_chars(struct uart_port *port)struct stm32_port *stm32_port =to_stm32_port (port);const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;struct circ_buf *xmit = &port->state->xmit; +u32 isr; +int ret;if (port->x_char) {if (stm32_port->tx_dma_busy)stm32_usart_clr_bits (port, ofs->cr3,USART_CR3_DMAT ); + +/* Check that TDR is empty before filling FIFO */ + ret = +readl_relaxed_poll_timeout_atomic (port->membase + ofs->isr, + isr, + (isr &USART_SR_TXE ), +10 ,1000 ); +if (ret) +dev_warn (port->dev,"1 character may be erased\n" ); +writel_relaxed (port->x_char, port->membase + ofs->tdr); port->x_char =0 ; port->icount.tx++;
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 35/186 KVM: arm64: Workaround Cortex-A510s single-step and PAC trap errata
In reply to Greg Kroah-HartmanFrom: James Morse <[email protected]>
[ Upstream commit 1dd498e5e26ad71e3e9130daf72cfb6a693fee03 ]
Cortex-A510's erratum #2077057 causes SPSR_EL2 to be corrupted when single-stepping authenticated ERET instructions. A single step is expected, but a pointer authentication trap is taken instead. The erratum causes SPSR_EL1 to be copied to SPSR_EL2, which could allow EL1 to cause a return to EL2 with a guest controlled ELR_EL2.
Because the conditions require an ERET into active-not-pending state, this is only a problem for the EL2 when EL2 is stepping EL1. In this case the previous SPSR_EL2 value is preserved in struct kvm_vcpu, and can be restored.
--- Documentation/arm64/silicon-errata.rst | 2 ++ arch/arm64/Kconfig | 16 ++++++++++++++++ arch/arm64/kernel/cpu_errata.c | 8 ++++++++ arch/arm64/kvm/hyp/include/hyp/switch.h | 20 +++++++++++++++++++- arch/arm64/tools/cpucaps | 5 +++-- 5 files changed, 48 insertions(+), 3 deletions(-)
Documentation/arm64/silicon-errata.rst +2 -0
@@ -100,6 +100,8 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A510 | #2051678 | ARM64_ERRATUM_2051678 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-A510 | #2077057 | ARM64_ERRATUM_2077057 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A710 | #2119858 | ARM64_ERRATUM_2119858 | +----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A710 | #2054223 | ARM64_ERRATUM_2054223 |
arch/arm64/Kconfig +16 -0
@@ -681,6 +681,22 @@ config ARM64_ERRATUM_2051678 If unsure, say Y. +config ARM64_ERRATUM_2077057 + bool "Cortex-A510: 2077057: workaround software-step corrupting SPSR_EL2" + help + This option adds the workaround for ARM Cortex-A510 erratum 2077057. + Affected Cortex-A510 may corrupt SPSR_EL2 when the a step exception is + expected, but a Pointer Authentication trap is taken instead. The + erratum causes SPSR_EL1 to be copied to SPSR_EL2, which could allow + EL1 to cause a return to EL2 with a guest controlled ELR_EL2. + + This can only happen when EL2 is stepping EL1. + + When these conditions occur, the SPSR_EL2 value is unchanged from the + previous guest entry, and can be restored from the in-memory copy. + + If unsure, say Y. + config ARM64_ERRATUM_2119858 bool "Cortex-A710/X2: 2119858: workaround TRBE overwriting trace data in FILL mode" default y
arch/arm64/kernel/cpu_errata.c +8 -0
@@ -600,6 +600,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = { CAP_MIDR_RANGE_LIST(trbe_write_out_of_range_cpus), },#endif +#ifdef CONFIG_ARM64_ERRATUM_2077057 + { + .desc = "ARM erratum 2077057", + .capability = ARM64_WORKAROUND_2077057, + .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM, + ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2), + }, +#endif #ifdef CONFIG_ARM64_ERRATUM_2064142 { .desc = "ARM erratum 2064142",
arch/arm64/kvm/hyp/include/hyp/switch.h +19 -1
@@ -424,6 +424,24 @@ static inline bool kvm_hyp_handle_exit(struct kvm_vcpu *vcpu, u64 *exit_code)return false; } +static inline void synchronize_vcpu_pstate (struct kvm_vcpu *vcpu,u64 *exit_code) +{ +/* +* Check for the conditions of Cortex-A510's #2077057. When these occur +* SPSR_EL2 can't be trusted, but isn't needed either as it is +* unchanged from the value in vcpu_gp_regs(vcpu)->pstate. +* Are we single-stepping the guest, and took a PAC exception from the +* active-not-pending state? +*/ +if (cpus_have_final_cap (ARM64_WORKAROUND_2077057 ) && + vcpu->guest_debug &KVM_GUESTDBG_SINGLESTEP && + *vcpu_cpsr (vcpu) &DBG_SPSR_SS && +ESR_ELx_EC (read_sysreg_el2 (SYS_ESR )) == ESR_ELx_EC_PAC) +write_sysreg_el2 (*vcpu_cpsr (vcpu),SYS_SPSR ); + + vcpu->arch.ctxt.regs.pstate =read_sysreg_el2 (SYS_SPSR ); +} +/* * Return true when we were able to fixup the guest exit and should return to * the guest, false when we should restore the host state and return to the
@@ -435,7 +453,7 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code)* Save PSTATE early so that we can evaluate the vcpu mode * early on. */ - vcpu->arch.ctxt.regs.pstate =read_sysreg_el2 (SYS_SPSR ); +synchronize_vcpu_pstate (vcpu, exit_code);/* * Check whether we want to repaint the state one way or
arch/arm64/tools/cpucaps +3 -2
@@ -55,9 +55,10 @@ WORKAROUND_1418040 WORKAROUND_1463225 WORKAROUND_1508412 WORKAROUND_1542419 -WORKAROUND_2064142 -WORKAROUND_2038923 WORKAROUND_1902691 +WORKAROUND_2038923 +WORKAROUND_2064142 +WORKAROUND_2077057 WORKAROUND_TRBE_OVERWRITE_FILL_MODE WORKAROUND_TSB_FLUSH_FAILURE WORKAROUND_TRBE_WRITE_OUT_OF_RANGE
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 36/186 ext4: drop ineligible txn start stop APIs
In reply to Greg Kroah-HartmanFrom: Harshad Shirwadkar <[email protected]>
[ Upstream commit 7bbbe241ec7ce0def9f71464c878fdbd2b0dcf37 ]
This patch drops ext4_fc_start_ineligible() and ext4_fc_stop_ineligible() APIs. Fast commit ineligible transactions should simply call ext4_fc_mark_ineligible() after starting the trasaction.
--- fs/ext4/ext4.h | 6 ++-- fs/ext4/extents.c | 6 ++-- fs/ext4/fast_commit.c | 79 ++++++++----------------------------------- fs/ext4/ioctl.c | 3 +- fs/ext4/super.c | 1 - 5 files changed, 20 insertions(+), 75 deletions(-)
fs/ext4/ext4.h +2 -4
@@ -1725,9 +1725,9 @@ struct ext4_sb_info {*/ struct work_struct s_error_work; -/* Ext4 fast commit stuff */ +/* Ext4 fast commit sub transaction ID */ atomic_t s_fc_subtid; -atomic_t s_fc_ineligible_updates; +/* * After commit starts, the main queue gets locked, and the further * updates get added in the staging queue.
@@ -2926,8 +2926,6 @@ void __ext4_fc_track_create(handle_t *handle, struct inode *inode,void ext4_fc_track_create (handle_t *handle,struct dentry *dentry);void ext4_fc_track_inode (handle_t *handle,struct inode *inode);void ext4_fc_mark_ineligible (struct super_block *sb,int reason); -void ext4_fc_start_ineligible (struct super_block *sb,int reason); -void ext4_fc_stop_ineligible (struct super_block *sb);void ext4_fc_start_update (struct inode *inode);void ext4_fc_stop_update (struct inode *inode);void ext4_fc_del (struct inode *inode);
fs/ext4/extents.c +2 -4
@@ -5342,7 +5342,7 @@ static int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) ret =PTR_ERR (handle); goto out_mmap; } -ext4_fc_start_ineligible (sb,EXT4_FC_REASON_FALLOC_RANGE ); +ext4_fc_mark_ineligible (sb,EXT4_FC_REASON_FALLOC_RANGE );down_write (&EXT4_I (inode)->i_data_sem);ext4_discard_preallocations (inode,0 );
@@ -5381,7 +5381,6 @@ static int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) out_stop:ext4_journal_stop (handle); -ext4_fc_stop_ineligible (sb); out_mmap:filemap_invalidate_unlock (mapping); out_mutex:
@@ -5483,7 +5482,7 @@ static int ext4_insert_range(struct inode *inode, loff_t offset, loff_t len) ret =PTR_ERR (handle); goto out_mmap; } -ext4_fc_start_ineligible (sb,EXT4_FC_REASON_FALLOC_RANGE ); +ext4_fc_mark_ineligible (sb,EXT4_FC_REASON_FALLOC_RANGE );/* Expand file to avoid data loss if there is error while shifting */ inode->i_size += len;
@@ -5558,7 +5557,6 @@ static int ext4_insert_range(struct inode *inode, loff_t offset, loff_t len) out_stop:ext4_journal_stop (handle); -ext4_fc_stop_ineligible (sb); out_mmap:filemap_invalidate_unlock (mapping); out_mutex:
fs/ext4/fast_commit.c +15 -64
116 lines not on this page · raw message
fs/ext4/ioctl.c +1 -2
@@ -169,7 +169,7 @@ static long swap_inode_boot_loader(struct super_block *sb, err = -EINVAL ; goto err_out; } -ext4_fc_start_ineligible (sb,EXT4_FC_REASON_SWAP_BOOT ); +ext4_fc_mark_ineligible (sb,EXT4_FC_REASON_SWAP_BOOT );/* Protect extent tree against block allocations via delalloc */ ext4_double_down_write_data_sem (inode, inode_bl);
@@ -252,7 +252,6 @@ static long swap_inode_boot_loader(struct super_block *sb, err_out1:ext4_journal_stop (handle); -ext4_fc_stop_ineligible (sb);ext4_double_up_write_data_sem (inode, inode_bl); err_out:
fs/ext4/super.c +0 -1
@@ -4620,7 +4620,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)/* Initialize fast commit stuff */ atomic_set (&sbi->s_fc_subtid,0 ); -atomic_set (&sbi->s_fc_ineligible_updates,0 );INIT_LIST_HEAD (&sbi->s_fc_q[FC_Q_MAIN ]);INIT_LIST_HEAD (&sbi->s_fc_q[FC_Q_STAGING ]);INIT_LIST_HEAD (&sbi->s_fc_dentry_q[FC_Q_MAIN ]);
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 37/186 ext4: simplify updating of fast commit stats
In reply to Greg Kroah-HartmanFrom: Harshad Shirwadkar <[email protected]>
[ Upstream commit 0915e464cb274648e1ef1663e1356e53ff400983 ]
Move fast commit stats updating logic to a separate function from ext4_fc_commit(). This significantly improves readability of ext4_fc_commit().
--- fs/ext4/ext4.h | 1 - fs/ext4/fast_commit.c | 99 +++++++++++++++++++++++-------------------- fs/ext4/fast_commit.h | 27 ++++++------ 3 files changed, 68 insertions(+), 59 deletions(-)
fs/ext4/ext4.h +0 -1
@@ -1747,7 +1747,6 @@ struct ext4_sb_info {spinlock_t s_fc_lock;struct buffer_head *s_fc_bh;struct ext4_fc_stats s_fc_stats; -u64 s_fc_avg_commit_time;#ifdef CONFIG_EXT4_DEBUG int s_fc_debug_max_replay;#endif
fs/ext4/fast_commit.c +54 -45
143 lines not on this page · raw message
fs/ext4/fast_commit.h +14 -13
@@ -71,21 +71,19 @@ struct ext4_fc_tail { };/* -* Fast commit reason codes +* Fast commit status codes +*/ +enum { +EXT4_FC_STATUS_OK =0 , +EXT4_FC_STATUS_INELIGIBLE , +EXT4_FC_STATUS_SKIPPED , +EXT4_FC_STATUS_FAILED , +}; + +/* +* Fast commit ineligiblity reasons: */ enum { -/* -* Commit status codes: -*/ -EXT4_FC_REASON_OK =0 , -EXT4_FC_REASON_INELIGIBLE , -EXT4_FC_REASON_ALREADY_COMMITTED , -EXT4_FC_REASON_FC_START_FAILED , -EXT4_FC_REASON_FC_FAILED , - -/* -* Fast commit ineligiblity reasons: -*/ EXT4_FC_REASON_XATTR =0 ,EXT4_FC_REASON_CROSS_RENAME ,EXT4_FC_REASON_JOURNAL_FLAG_CHANGE ,
@@ -117,7 +115,10 @@ struct ext4_fc_stats {unsigned int fc_ineligible_reason_count[EXT4_FC_REASON_MAX ];unsigned long fc_num_commits;unsigned long fc_ineligible_commits; +unsigned long fc_failed_commits; +unsigned long fc_skipped_commits;unsigned long fc_numblks; +u64 s_fc_avg_commit_time; };#define EXT4_FC_REPLAY_REALLOC_INCREMENT 4
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 38/186 ext4: fast commit may not fallback for ineligible commit
In reply to Greg Kroah-HartmanFrom: Xin Yin <[email protected]>
[ Upstream commit e85c81ba8859a4c839bcd69c5d83b32954133a5b ]
For the follow scenario:
1. jbd start commit transaction n
2. task A get new handle for transaction n+1
3. task A do some ineligible actions and mark FC_INELIGIBLE
4. jbd complete transaction n and clean FC_INELIGIBLE
5. task A call fsync
In this case fast commit will not fallback to full commit and transaction n+1 also not handled by jbd.
Make ext4_fc_mark_ineligible() also record transaction tid for latest ineligible case, when call ext4_fc_cleanup() check current transaction tid, if small than latest ineligible tid do not clear the EXT4_MF_FC_INELIGIBLE.
--- fs/ext4/ext4.h | 3 ++- fs/ext4/extents.c | 4 ++-- fs/ext4/fast_commit.c | 33 +++++++++++++++++++++++++-------- fs/ext4/inode.c | 4 ++-- fs/ext4/ioctl.c | 4 ++-- fs/ext4/namei.c | 4 ++-- fs/ext4/super.c | 1 + fs/ext4/xattr.c | 6 +++--- fs/jbd2/commit.c | 2 +- fs/jbd2/journal.c | 2 +- include/linux/jbd2.h | 2 +- 11 files changed, 42 insertions(+), 23 deletions(-)
fs/ext4/ext4.h +2 -1
@@ -1747,6 +1747,7 @@ struct ext4_sb_info {spinlock_t s_fc_lock;struct buffer_head *s_fc_bh;struct ext4_fc_stats s_fc_stats; +tid_t s_fc_ineligible_tid;#ifdef CONFIG_EXT4_DEBUG int s_fc_debug_max_replay;#endif
@@ -2924,7 +2925,7 @@ void __ext4_fc_track_create(handle_t *handle, struct inode *inode, struct dentry *dentry);void ext4_fc_track_create (handle_t *handle,struct dentry *dentry);void ext4_fc_track_inode (handle_t *handle,struct inode *inode); -void ext4_fc_mark_ineligible (struct super_block *sb,int reason); +void ext4_fc_mark_ineligible (struct super_block *sb,int reason,handle_t *handle);void ext4_fc_start_update (struct inode *inode);void ext4_fc_stop_update (struct inode *inode);void ext4_fc_del (struct inode *inode);
fs/ext4/extents.c +2 -2
@@ -5342,7 +5342,7 @@ static int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) ret =PTR_ERR (handle); goto out_mmap; } -ext4_fc_mark_ineligible (sb,EXT4_FC_REASON_FALLOC_RANGE ); +ext4_fc_mark_ineligible (sb,EXT4_FC_REASON_FALLOC_RANGE , handle);down_write (&EXT4_I (inode)->i_data_sem);ext4_discard_preallocations (inode,0 );
@@ -5482,7 +5482,7 @@ static int ext4_insert_range(struct inode *inode, loff_t offset, loff_t len) ret =PTR_ERR (handle); goto out_mmap; } -ext4_fc_mark_ineligible (sb,EXT4_FC_REASON_FALLOC_RANGE ); +ext4_fc_mark_ineligible (sb,EXT4_FC_REASON_FALLOC_RANGE , handle);/* Expand file to avoid data loss if there is error while shifting */ inode->i_size += len;
fs/ext4/fast_commit.c +25 -8
@@ -302,18 +302,32 @@ void ext4_fc_del(struct inode *inode) }/* -* Mark file system as fast commit ineligible. This means that next commit -* operation would result in a full jbd2 commit. +* Mark file system as fast commit ineligible, and record latest +* ineligible transaction tid. This means until the recorded +* transaction, commit operation would result in a full jbd2 commit. */ -void ext4_fc_mark_ineligible (struct super_block *sb,int reason) +void ext4_fc_mark_ineligible (struct super_block *sb,int reason,handle_t *handle) {struct ext4_sb_info *sbi =EXT4_SB (sb); +tid_t tid;if (!test_opt2 (sb,JOURNAL_FAST_COMMIT ) || (EXT4_SB (sb)->s_mount_state &EXT4_FC_REPLAY ))return ;ext4_set_mount_flag (sb,EXT4_MF_FC_INELIGIBLE ); +if (handle && !IS_ERR (handle)) + tid = handle->h_transaction->t_tid; +else { +read_lock (&sbi->s_journal->j_state_lock); + tid = sbi->s_journal->j_running_transaction ? + sbi->s_journal->j_running_transaction->t_tid :0 ; +read_unlock (&sbi->s_journal->j_state_lock); + } +spin_lock (&sbi->s_fc_lock); +if (sbi->s_fc_ineligible_tid < tid) + sbi->s_fc_ineligible_tid = tid; +spin_unlock (&sbi->s_fc_lock);WARN_ON (reason >=EXT4_FC_REASON_MAX ); sbi->s_fc_stats.fc_ineligible_reason_count[reason]++; }
@@ -389,7 +403,7 @@ static int __track_dentry_update(struct inode *inode, void *arg, bool update)mutex_unlock (&ei->i_fc_lock); node =kmem_cache_alloc (ext4_fc_dentry_cachep,GFP_NOFS );if (!node) { -ext4_fc_mark_ineligible (inode->i_sb,EXT4_FC_REASON_NOMEM ); +ext4_fc_mark_ineligible (inode->i_sb,EXT4_FC_REASON_NOMEM ,NULL );mutex_lock (&ei->i_fc_lock);return -ENOMEM ; }
@@ -402,7 +416,7 @@ static int __track_dentry_update(struct inode *inode, void *arg, bool update)if (!node->fcd_name.name) {kmem_cache_free (ext4_fc_dentry_cachep, node);ext4_fc_mark_ineligible (inode->i_sb, -EXT4_FC_REASON_NOMEM ); +EXT4_FC_REASON_NOMEM ,NULL );mutex_lock (&ei->i_fc_lock);return -ENOMEM ; }
@@ -504,7 +518,7 @@ void ext4_fc_track_inode(handle_t *handle, struct inode *inode)if (ext4_should_journal_data (inode)) {ext4_fc_mark_ineligible (inode->i_sb, -EXT4_FC_REASON_INODE_JOURNAL_DATA ); +EXT4_FC_REASON_INODE_JOURNAL_DATA , handle);return ; }
@@ -1182,7 +1196,7 @@ int ext4_fc_commit(journal_t *journal, tid_t commit_tid)* Fast commit cleanup routine. This is called after every fast commit and * full commit. full is true if we are called after a full commit. */ -static void ext4_fc_cleanup (journal_t *journal,int full) +static void ext4_fc_cleanup (journal_t *journal,int full,tid_t tid) {struct super_block *sb = journal->j_private;struct ext4_sb_info *sbi =EXT4_SB (sb);
@@ -1230,7 +1244,10 @@ static void ext4_fc_cleanup(journal_t *journal, int full) &sbi->s_fc_q[FC_Q_MAIN]);ext4_clear_mount_flag (sb,EXT4_MF_FC_COMMITTING ); -ext4_clear_mount_flag (sb,EXT4_MF_FC_INELIGIBLE ); +if (tid >= sbi->s_fc_ineligible_tid) { + sbi->s_fc_ineligible_tid =0 ; +ext4_clear_mount_flag (sb,EXT4_MF_FC_INELIGIBLE ); + }if (full) sbi->s_fc_bytes =0 ;
fs/ext4/inode.c +2 -2
@@ -337,7 +337,7 @@ void ext4_evict_inode(struct inode *inode)return ; no_delete:if (!list_empty (&EXT4_I (inode)->i_fc_list)) -ext4_fc_mark_ineligible (inode->i_sb,EXT4_FC_REASON_NOMEM ); +ext4_fc_mark_ineligible (inode->i_sb,EXT4_FC_REASON_NOMEM ,NULL );ext4_clear_inode (inode);/* We must guarantee clearing of inode... */ }
@@ -5983,7 +5983,7 @@ int ext4_change_inode_journal_flag(struct inode *inode, int val)return PTR_ERR (handle);ext4_fc_mark_ineligible (inode->i_sb, -EXT4_FC_REASON_JOURNAL_FLAG_CHANGE ); +EXT4_FC_REASON_JOURNAL_FLAG_CHANGE , handle); err =ext4_mark_inode_dirty (handle, inode);ext4_handle_sync (handle);ext4_journal_stop (handle);
fs/ext4/ioctl.c +2 -2
@@ -169,7 +169,7 @@ static long swap_inode_boot_loader(struct super_block *sb, err = -EINVAL ; goto err_out; } -ext4_fc_mark_ineligible (sb,EXT4_FC_REASON_SWAP_BOOT ); +ext4_fc_mark_ineligible (sb,EXT4_FC_REASON_SWAP_BOOT , handle);/* Protect extent tree against block allocations via delalloc */ ext4_double_down_write_data_sem (inode, inode_bl);
@@ -1075,7 +1075,7 @@ static long __ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) err =ext4_resize_fs (sb, n_blocks_count);if (EXT4_SB (sb)->s_journal) { -ext4_fc_mark_ineligible (sb,EXT4_FC_REASON_RESIZE ); +ext4_fc_mark_ineligible (sb,EXT4_FC_REASON_RESIZE ,NULL );jbd2_journal_lock_updates (EXT4_SB (sb)->s_journal); err2 =jbd2_journal_flush (EXT4_SB (sb)->s_journal,0 );jbd2_journal_unlock_updates (EXT4_SB (sb)->s_journal);
fs/ext4/namei.c +2 -2
@@ -3889,7 +3889,7 @@ static int ext4_rename(struct user_namespace *mnt_userns, struct inode *old_dir,* dirents in directories. */ ext4_fc_mark_ineligible (old.inode->i_sb, -EXT4_FC_REASON_RENAME_DIR ); +EXT4_FC_REASON_RENAME_DIR , handle); }else {if (new.inode)ext4_fc_track_unlink (handle, new.dentry);
@@ -4049,7 +4049,7 @@ static int ext4_cross_rename(struct inode *old_dir, struct dentry *old_dentry,if (unlikely (retval)) goto end_rename;ext4_fc_mark_ineligible (new.inode->i_sb, -EXT4_FC_REASON_CROSS_RENAME ); +EXT4_FC_REASON_CROSS_RENAME , handle);if (old.dir_bh) { retval =ext4_rename_dir_finish (handle, &old, new.dir->i_ino);if (retval)
fs/ext4/super.c +1 -0
@@ -4627,6 +4627,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) sbi->s_fc_bytes =0 ;ext4_clear_mount_flag (sb,EXT4_MF_FC_INELIGIBLE );ext4_clear_mount_flag (sb,EXT4_MF_FC_COMMITTING ); + sbi->s_fc_ineligible_tid =0 ;spin_lock_init (&sbi->s_fc_lock);memset (&sbi->s_fc_stats,0 ,sizeof (sbi->s_fc_stats)); sbi->s_fc_replay_state.fc_regions =NULL ;
fs/ext4/xattr.c +3 -3
@@ -2408,7 +2408,7 @@ ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,if (IS_SYNC (inode))ext4_handle_sync (handle); } -ext4_fc_mark_ineligible (inode->i_sb,EXT4_FC_REASON_XATTR ); +ext4_fc_mark_ineligible (inode->i_sb,EXT4_FC_REASON_XATTR , handle); cleanup:brelse (is.iloc.bh);
@@ -2486,7 +2486,7 @@ ext4_xattr_set(struct inode *inode, int name_index, const char *name,if (error ==0 ) error = error2; } -ext4_fc_mark_ineligible (inode->i_sb,EXT4_FC_REASON_XATTR ); +ext4_fc_mark_ineligible (inode->i_sb,EXT4_FC_REASON_XATTR ,NULL );return error; }
@@ -2920,7 +2920,7 @@ int ext4_xattr_delete_inode(handle_t *handle, struct inode *inode, error); goto cleanup; } -ext4_fc_mark_ineligible (inode->i_sb,EXT4_FC_REASON_XATTR ); +ext4_fc_mark_ineligible (inode->i_sb,EXT4_FC_REASON_XATTR , handle); } error =0 ; cleanup:
fs/jbd2/commit.c +1 -1
@@ -1170,7 +1170,7 @@ void jbd2_journal_commit_transaction(journal_t *journal)if (journal->j_commit_callback) journal->j_commit_callback (journal, commit_transaction);if (journal->j_fc_cleanup_callback) - journal->j_fc_cleanup_callback (journal,1 ); + journal->j_fc_cleanup_callback (journal,1 , commit_transaction->t_tid);trace_jbd2_end_commit (journal, commit_transaction); jbd_debug(1, "JBD2: commit %d complete, head %d\n",
fs/jbd2/journal.c +1 -1
@@ -769,7 +769,7 @@ EXPORT_SYMBOL(jbd2_fc_begin_commit);static int __jbd2_fc_end_commit (journal_t *journal,tid_t tid,bool fallback) {if (journal->j_fc_cleanup_callback) - journal->j_fc_cleanup_callback (journal,0 ); + journal->j_fc_cleanup_callback (journal,0 , tid);write_lock (&journal->j_state_lock); journal->j_flags &= ~JBD2_FAST_COMMIT_ONGOING ;if (fallback)
include/linux/jbd2.h +1 -1
@@ -1295,7 +1295,7 @@ struct journal_s* Clean-up after fast commit or full commit. JBD2 calls this function * after every commit operation. */ -void (*j_fc_cleanup_callback)(struct journal_s *journal,int ); +void (*j_fc_cleanup_callback)(struct journal_s *journal,int full,tid_t tid);/** * @j_fc_replay_callback:
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 39/186 ext4: fast commit may miss file actions
In reply to Greg Kroah-HartmanFrom: Xin Yin <[email protected]>
[ Upstream commit bdc8a53a6f2f0b1cb5f991440f2100732299eb93 ]
in the follow scenario:
1. jbd start transaction n
2. task A get new handle for transaction n+1
3. task A do some actions and add inode to FC_Q_MAIN fc_q
4. jbd complete transaction n and clear FC_Q_MAIN fc_q
5. task A call fsync
Fast commit will lost the file actions during a full commit.
we should also add updates to staging queue during a full commit. and in ext4_fc_cleanup(), when reset a inode's fc track range, check it's i_sync_tid, if it bigger than current transaction tid, do not rest it, or we will lost the track range.
And EXT4_MF_FC_COMMITTING is not needed anymore, so drop it.
--- fs/ext4/ext4.h | 5 +---- fs/ext4/fast_commit.c | 11 ++++++----- fs/ext4/super.c | 1 - 3 files changed, 7 insertions(+), 10 deletions(-)
fs/ext4/ext4.h +1 -4
@@ -1793,10 +1793,7 @@ static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino)enum {EXT4_MF_MNTDIR_SAMPLED ,EXT4_MF_FS_ABORTED ,/* Fatal error detected */ -EXT4_MF_FC_INELIGIBLE ,/* Fast commit ineligible */ -EXT4_MF_FC_COMMITTING /* File system underoing a fast -* commit. -*/ +EXT4_MF_FC_INELIGIBLE /* Fast commit ineligible */ };static inline void ext4_set_mount_flag (struct super_block *sb,int bit)
fs/ext4/fast_commit.c +6 -5
@@ -377,7 +377,8 @@ static int ext4_fc_track_template(spin_lock (&sbi->s_fc_lock);if (list_empty (&EXT4_I (inode)->i_fc_list))list_add_tail (&EXT4_I (inode)->i_fc_list, - (ext4_test_mount_flag (inode->i_sb,EXT4_MF_FC_COMMITTING )) ? + (sbi->s_journal->j_flags &JBD2_FULL_COMMIT_ONGOING || + sbi->s_journal->j_flags &JBD2_FAST_COMMIT_ONGOING ) ? &sbi->s_fc_q[FC_Q_STAGING ] : &sbi->s_fc_q[FC_Q_MAIN ]);spin_unlock (&sbi->s_fc_lock);
@@ -430,7 +431,8 @@ static int __track_dentry_update(struct inode *inode, void *arg, bool update) node->fcd_name.len = dentry->d_name.len;spin_lock (&sbi->s_fc_lock); -if (ext4_test_mount_flag (inode->i_sb,EXT4_MF_FC_COMMITTING )) +if (sbi->s_journal->j_flags &JBD2_FULL_COMMIT_ONGOING || + sbi->s_journal->j_flags &JBD2_FAST_COMMIT_ONGOING )list_add_tail (&node->fcd_list, &sbi->s_fc_dentry_q[FC_Q_STAGING ]);else
@@ -896,7 +898,6 @@ static int ext4_fc_submit_inode_data_all(journal_t *journal)int ret =0 ;spin_lock (&sbi->s_fc_lock); -ext4_set_mount_flag (sb,EXT4_MF_FC_COMMITTING );list_for_each_entry (ei, &sbi->s_fc_q[FC_Q_MAIN ], i_fc_list) {ext4_set_inode_state (&ei->vfs_inode,EXT4_STATE_FC_COMMITTING );while (atomic_read (&ei->i_fc_updates)) {
@@ -1214,7 +1215,8 @@ static void ext4_fc_cleanup(journal_t *journal, int full, tid_t tid)list_del_init (&iter->i_fc_list);ext4_clear_inode_state (&iter->vfs_inode,EXT4_STATE_FC_COMMITTING ); -ext4_fc_reset_inode (&iter->vfs_inode); +if (iter->i_sync_tid <= tid) +ext4_fc_reset_inode (&iter->vfs_inode);/* Make sure EXT4_STATE_FC_COMMITTING bit is clear */ smp_mb ();#if (BITS_PER_LONG <64 )
@@ -1243,7 +1245,6 @@ static void ext4_fc_cleanup(journal_t *journal, int full, tid_t tid)list_splice_init (&sbi->s_fc_q[FC_Q_STAGING ], &sbi->s_fc_q[FC_Q_MAIN ]); -ext4_clear_mount_flag (sb,EXT4_MF_FC_COMMITTING );if (tid >= sbi->s_fc_ineligible_tid) { sbi->s_fc_ineligible_tid =0 ;ext4_clear_mount_flag (sb,EXT4_MF_FC_INELIGIBLE );
fs/ext4/super.c +0 -1
@@ -4626,7 +4626,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)INIT_LIST_HEAD (&sbi->s_fc_dentry_q[FC_Q_STAGING ]); sbi->s_fc_bytes =0 ;ext4_clear_mount_flag (sb,EXT4_MF_FC_INELIGIBLE ); -ext4_clear_mount_flag (sb,EXT4_MF_FC_COMMITTING ); sbi->s_fc_ineligible_tid =0 ;spin_lock_init (&sbi->s_fc_lock);memset (&sbi->s_fc_stats,0 ,sizeof (sbi->s_fc_stats));
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 40/186 sched/fair: Fix fault in reweight_entity
In reply to Greg Kroah-HartmanFrom: Tadeusz Struk <[email protected]>
[ Upstream commit 13765de8148f71fa795e0a6607de37c49ea5915a ]
Syzbot found a GPF in reweight_entity. This has been bisected to commit 4ef0c5c6b5ba ("kernel/sched: Fix sched_fork() access an invalid sched_task_group")
There is a race between sched_post_fork() and setpriority(PRIO_PGRP) within a thread group that causes a null-ptr-deref in reweight_entity() in CFS. The scenario is that the main process spawns number of new threads, which then call setpriority(PRIO_PGRP, 0, -20), wait, and exit. For each of the new threads the copy_process() gets invoked, which adds the new task_struct and calls sched_post_fork() for it.
In the above scenario there is a possibility that setpriority(PRIO_PGRP) and set_one_prio() will be called for a thread in the group that is just being created by copy_process(), and for which the sched_post_fork() has not been executed yet. This will trigger a null pointer dereference in reweight_entity(), as it will try to access the run queue pointer, which hasn't been set.
Before the mentioned change the cfs_rq pointer for the task has been set in sched_fork(), which is called much earlier in copy_process(), before the new task is added to the thread_group. Now it is done in the sched_post_fork(), which is called after that. To fix the issue the remove the update_load param from the update_load param() function and call reweight_task() only if the task flag doesn't have the TASK_NEW flag set.
--- kernel/sched/core.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
kernel/sched/core.c +6 -5
@@ -1203,8 +1203,9 @@ int tg_nop(struct task_group *tg, void *data) }#endif -static void set_load_weight (struct task_struct *p,bool update_load) +static void set_load_weight (struct task_struct *p) { +bool update_load = !(READ_ONCE (p->__state) &TASK_NEW );int prio = p->static_prio -MAX_RT_PRIO ;struct load_weight *load = &p->se.load;
@@ -4392,7 +4393,7 @@ int sched_fork(unsigned long clone_flags, struct task_struct *p) p->static_prio =NICE_TO_PRIO (0 ); p->prio = p->normal_prio = p->static_prio; -set_load_weight (p, false); +set_load_weight (p);/* * We don't need the reset flag anymore after the fork. It has
@@ -6879,7 +6880,7 @@ void set_user_nice(struct task_struct *p, long nice)put_prev_task (rq, p); p->static_prio =NICE_TO_PRIO (nice); -set_load_weight (p, true); +set_load_weight (p); old_prio = p->prio; p->prio =effective_prio (p);
@@ -7170,7 +7171,7 @@ static void __setscheduler_params(struct task_struct *p,*/ p->rt_priority = attr->sched_priority; p->normal_prio =normal_prio (p); -set_load_weight (p, true); +set_load_weight (p); }/*
@@ -9409,7 +9410,7 @@ void __init sched_init(void)#endif } -set_load_weight (&init_task, false); +set_load_weight (&init_task);/* * The boot idle thread does lazy MMU switching as well:
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 41/186 KVM: x86: Add KVM_CAP_ENABLE_CAP to x86
In reply to Greg Kroah-HartmanFrom: Aaron Lewis <[email protected]>
[ Upstream commit 127770ac0d043435375ab86434f31a93efa88215 ]
Follow the precedent set by other architectures that support the VCPU ioctl, KVM_ENABLE_CAP, and advertise the VM extension, KVM_CAP_ENABLE_CAP. This way, userspace can ensure that KVM_ENABLE_CAP is available on a vcpu before using it.
Message-Id: <[email protected]>
--- Documentation/virt/kvm/api.rst | 2 +- arch/x86/kvm/x86.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-)
Documentation/virt/kvm/api.rst +1 -1
@@ -1391,7 +1391,7 @@ documentation when it pops into existence). ------------------- :Capability: KVM_CAP_ENABLE_CAP -:Architectures: mips, ppc, s390 +:Architectures: mips, ppc, s390, x86 :Type: vcpu ioctl :Parameters: struct kvm_enable_cap (in) :Returns: 0 on success; -1 on error
arch/x86/kvm/x86.c +1 -0
@@ -4163,6 +4163,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)case KVM_CAP_SREGS2 :case KVM_CAP_EXIT_ON_EMULATION_FAILURE :case KVM_CAP_VCPU_ATTRIBUTES : +case KVM_CAP_ENABLE_CAP : r =1 ;break ;case KVM_CAP_EXIT_HYPERCALL :
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 42/186 ata: pata_hpt37x: fix PCI clock detection
In reply to Greg Kroah-HartmanFrom: Sergey Shtylyov <[email protected]>
[ Upstream commit 5f6b0f2d037c8864f20ff15311c695f65eb09db5 ]
The f_CNT register (at the PCI config. address 0x78) is 16-bit, not 8-bit! The bug was there from the very start... :-(
--- drivers/ata/pata_hpt37x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/ata/pata_hpt37x.c +2 -2
@@ -964,14 +964,14 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)if ((freq >>12 ) !=0xABCDE ) {int i; -u8 sr; +u16 sr;u32 total =0 ;pr_warn ("BIOS has not set timing clocks\n" );/* This is the process the HPT371 BIOS is reported to use */ for (i =0 ; i <128 ; i++) { -pci_read_config_byte (dev,0x78 , &sr); +pci_read_config_word (dev,0x78 , &sr); total += sr &0x1FF ;udelay (15 ); }
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 43/186 drm/amdgpu: check vm ready by amdgpu_vm->evicting flag
In reply to Greg Kroah-HartmanFrom: Qiang Yu <[email protected]>
[ Upstream commit c1a66c3bc425ff93774fb2f6eefa67b83170dd7e ]
Workstation application ANSA/META v21.1.4 get this error dmesg when running CI test suite provided by ANSA/META:
[drm:amdgpu_gem_va_ioctl [amdgpu]] *ERROR* Couldn't update BO_VA (-16)
This is caused by:
1. create a 256MB buffer in invisible VRAM
2. CPU map the buffer and access it causes vm_fault and try to move it to visible VRAM
3. force visible VRAM space and traverse all VRAM bos to check if evicting this bo is valuable
4. when checking a VM bo (in invisible VRAM), amdgpu_vm_evictable() will set amdgpu_vm->evicting, but latter due to not in visible VRAM, won't really evict it so not add it to amdgpu_vm->evicted
5. before next CS to clear the amdgpu_vm->evicting, user VM ops ioctl will pass amdgpu_vm_ready() (check amdgpu_vm->evicted) but fail in amdgpu_vm_bo_update_mapping() (check amdgpu_vm->evicting) and get this error log
This error won't affect functionality as next CS will finish the waiting VM ops. But we'd better clear the error log by checking the amdgpu_vm->evicting flag in amdgpu_vm_ready() to stop calling amdgpu_vm_bo_update_mapping() later.
Another reason is amdgpu_vm->evicted list holds all BOs (both user buffer and page table), but only page table BOs' eviction prevent VM ops. amdgpu_vm->evicting flag is set only for page table BOs, so we should use evicting flag instead of evicted list in amdgpu_vm_ready().
The side effect of this change is: previously blocked VM op (user buffer in "evicted" list but no page table in it) gets done immediately.
v2: update commit comments.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +7 -2
@@ -768,11 +768,16 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,* Check if all VM PDs/PTs are ready for updates * * Returns: -* True if eviction list is empty. +* True if VM is not evicting. */ bool amdgpu_vm_ready (struct amdgpu_vm *vm) { -return list_empty (&vm->evicted); +bool ret; + +amdgpu_vm_eviction_lock (vm); + ret = !vm->evicting; +amdgpu_vm_eviction_unlock (vm); +return ret; }/**
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 44/186 tracing: Add ustring operation to filtering string pointers
In reply to Greg Kroah-HartmanFrom: Steven Rostedt <[email protected]>
[ Upstream commit f37c3bbc635994eda203a6da4ba0f9d05165a8d6 ]
Since referencing user space pointers is special, if the user wants to filter on a field that is a pointer to user space, then they need to specify it.
Add a ".ustring" attribute to the field name for filters to state that the field is pointing to user space such that the kernel can take the appropriate action to read that pointer.
--- Documentation/trace/events.rst | 9 ++++ kernel/trace/trace_events_filter.c | 81 +++++++++++++++++++++--------- 2 files changed, 66 insertions(+), 24 deletions(-)
Documentation/trace/events.rst +9 -0
@@ -198,6 +198,15 @@ The glob (~) accepts a wild card character (\*,?) and character classes prev_comm ~ "*sh*" prev_comm ~ "ba*sh" +If the field is a pointer that points into user space (for example +"filename" from sys_enter_openat), then you have to append ".ustring" to the +field name:: + + filename.ustring ~ "password" + +As the kernel will have to know how to retrieve the memory that the pointer +is at from user space. + 5.2 Setting filters -------------------
kernel/trace/trace_events_filter.c +57 -24
129 lines not on this page · raw message
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 45/186 ipv6: fix skb drops in igmp6_event_query() and igmp6_event_report()
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit 2d3916f3189172d5c69d33065c3c21119fe539fc ]
While investigating on why a synchronize_net() has been added recently in ipv6_mc_down(), I found that igmp6_event_query() and igmp6_event_report() might drop skbs in some cases.
Discussion about removing synchronize_net() from ipv6_mc_down() will happen in a different thread.
--- include/net/ndisc.h | 4 ++-- net/ipv6/mcast.c | 32 ++++++++++++-------------------- 2 files changed, 14 insertions(+), 22 deletions(-)
include/net/ndisc.h +2 -2
@@ -487,9 +487,9 @@ int igmp6_late_init(void);void igmp6_cleanup (void );void igmp6_late_cleanup (void ); -int igmp6_event_query (struct sk_buff *skb); +void igmp6_event_query (struct sk_buff *skb); -int igmp6_event_report (struct sk_buff *skb); +void igmp6_event_report (struct sk_buff *skb);#ifdef CONFIG_SYSCTL
net/ipv6/mcast.c +12 -20
@@ -1371,27 +1371,23 @@ static void mld_process_v2(struct inet6_dev *idev, struct mld2_query *mld, }/* called with rcu_read_lock() */ -int igmp6_event_query (struct sk_buff *skb) +void igmp6_event_query (struct sk_buff *skb) {struct inet6_dev *idev =__in6_dev_get (skb->dev); -if (!idev) -return -EINVAL ; - -if (idev->dead) { -kfree_skb (skb); -return -ENODEV ; - } +if (!idev || idev->dead) + goto out;spin_lock_bh (&idev->mc_query_lock);if (skb_queue_len (&idev->mc_query_queue) <MLD_MAX_SKBS ) {__skb_queue_tail (&idev->mc_query_queue, skb);if (!mod_delayed_work (mld_wq, &idev->mc_query_work,0 ))in6_dev_hold (idev); + skb =NULL ; }spin_unlock_bh (&idev->mc_query_lock); - -return 0 ; +out: +kfree_skb (skb); }static void __mld_query_work (struct sk_buff *skb)
@@ -1542,27 +1538,23 @@ static void mld_query_work(struct work_struct *work) }/* called with rcu_read_lock() */ -int igmp6_event_report (struct sk_buff *skb) +void igmp6_event_report (struct sk_buff *skb) {struct inet6_dev *idev =__in6_dev_get (skb->dev); -if (!idev) -return -EINVAL ; - -if (idev->dead) { -kfree_skb (skb); -return -ENODEV ; - } +if (!idev || idev->dead) + goto out;spin_lock_bh (&idev->mc_report_lock);if (skb_queue_len (&idev->mc_report_queue) <MLD_MAX_SKBS ) {__skb_queue_tail (&idev->mc_report_queue, skb);if (!mod_delayed_work (mld_wq, &idev->mc_report_work,0 ))in6_dev_hold (idev); + skb =NULL ; }spin_unlock_bh (&idev->mc_report_lock); - -return 0 ; +out: +kfree_skb (skb); }static void __mld_report_work (struct sk_buff *skb)
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 46/186 btrfs: defrag: bring back the old file extent search behavior
In reply to Greg Kroah-HartmanFrom: Qu Wenruo <[email protected]>
commit d5633b0dee02d7d25e93463a03709f11c71500e2 upstream.
For defrag, we don't really want to use btrfs_get_extent() to iterate all extent maps of an inode.
The reasons are:
- btrfs_get_extent() can merge extent maps
And the result em has the higher generation of the two, causing defrag to mark unnecessary part of such merged large extent map.
This in fact can result extra IO for autodefrag in v5.16+ kernels.
However this patch is not going to completely solve the problem, as one can still using read() to trigger extent map reading, and got them merged.
The completely solution for the extent map merging generation problem will come as an standalone fix.
- btrfs_get_extent() caches the extent map result Normally it's fine, but for defrag the target range may not get another read/write for a long long time.
Such cache would only increase the memory usage.
- btrfs_get_extent() doesn't skip older extent map
Unlike the old find_new_extent() which uses btrfs_search_forward() to skip the older subtree, thus it will pick up unnecessary extent maps.
This patch will fix the regression by introducing defrag_get_extent() to replace the btrfs_get_extent() call.
This helper will:
- Not cache the file extent we found
It will search the file extent and manually convert it to em.
- Use btrfs_search_forward() to skip entire ranges which is modified in the past
This should reduce the IO for autodefrag.
--- fs/btrfs/ioctl.c | 161 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 157 insertions(+), 4 deletions(-)
fs/btrfs/ioctl.c +157 -4
@@ -986,8 +986,155 @@ out:return ret; } +/* +* Defrag specific helper to get an extent map. +* +* Differences between this and btrfs_get_extent() are: +* +* - No extent_map will be added to inode->extent_tree +* To reduce memory usage in the long run. +* +* - Extra optimization to skip file extents older than @newer_than +* By using btrfs_search_forward() we can skip entire file ranges that +* have extents created in past transactions, because btrfs_search_forward() +* will not visit leaves and nodes with a generation smaller than given +* minimal generation threshold (@newer_than). +* +* Return valid em if we find a file extent matching the requirement. +* Return NULL if we can not find a file extent matching the requirement. +* +* Return ERR_PTR() for error. +*/ +static struct extent_map *defrag_get_extent (struct btrfs_inode *inode, +u64 start,u64 newer_than) +{ +struct btrfs_root *root = inode->root; +struct btrfs_file_extent_item *fi; +struct btrfs_path path = {0 }; +struct extent_map *em; +struct btrfs_key key; +u64 ino =btrfs_ino (inode); +int ret; + + em =alloc_extent_map (); +if (!em) { + ret = -ENOMEM ; + goto err; + } + + key.objectid = ino; + key.type =BTRFS_EXTENT_DATA_KEY ; + key.offset = start; + +if (newer_than) { + ret =btrfs_search_forward (root, &key, &path, newer_than); +if (ret <0 ) + goto err; +/* Can't find anything newer */ +if (ret >0 ) + goto not_found; + }else { + ret =btrfs_search_slot (NULL , root, &key, &path,0 ,0 ); +if (ret <0 ) + goto err; + } +if (path.slots[0 ] >=btrfs_header_nritems (path.nodes[0 ])) { +/* +* If btrfs_search_slot() makes path to point beyond nritems, +* we should not have an empty leaf, as this inode must at +* least have its INODE_ITEM. +*/ +ASSERT (btrfs_header_nritems (path.nodes[0 ])); + path.slots[0 ] =btrfs_header_nritems (path.nodes[0 ]) -1 ; + } +btrfs_item_key_to_cpu (path.nodes[0 ], &key, path.slots[0 ]); +/* Perfect match, no need to go one slot back */ +if (key.objectid == ino && key.type ==BTRFS_EXTENT_DATA_KEY && + key.offset == start) + goto iterate; + +/* We didn't find a perfect match, needs to go one slot back */ +if (path.slots[0 ] >0 ) { +btrfs_item_key_to_cpu (path.nodes[0 ], &key, path.slots[0 ]); +if (key.objectid == ino && key.type ==BTRFS_EXTENT_DATA_KEY ) + path.slots[0 ]--; + } + +iterate: +/* Iterate through the path to find a file extent covering @start */ +while (true) { +u64 extent_end; + +if (path.slots[0 ] >=btrfs_header_nritems (path.nodes[0 ])) + goto next; + +btrfs_item_key_to_cpu (path.nodes[0 ], &key, path.slots[0 ]); + +/* +* We may go one slot back to INODE_REF/XATTR item, then +* need to go forward until we reach an EXTENT_DATA. +* But we should still has the correct ino as key.objectid. +*/ +if (WARN_ON (key.objectid < ino) || key.type <BTRFS_EXTENT_DATA_KEY ) + goto next; + +/* It's beyond our target range, definitely not extent found */ +if (key.objectid > ino || key.type >BTRFS_EXTENT_DATA_KEY ) + goto not_found; + +/* +* | |<- File extent ->| +* \- start +* +* This means there is a hole between start and key.offset. +*/ +if (key.offset > start) { + em->start = start; + em->orig_start = start; + em->block_start =EXTENT_MAP_HOLE ; + em->len = key.offset - start; +break ; + } + + fi =btrfs_item_ptr (path.nodes[0 ], path.slots[0 ], + struct btrfs_file_extent_item); + extent_end =btrfs_file_extent_end (&path); + +/* +* |<- file extent ->| | +* \- start +* +* We haven't reached start, search next slot. +*/ +if (extent_end <= start) + goto next; + +/* Now this extent covers @start, convert it to em */ +btrfs_extent_item_to_extent_map (inode, &path, fi, false, em); +break ; +next: + ret =btrfs_next_item (root, &path); +if (ret <0 ) + goto err; +if (ret >0 ) + goto not_found; + } +btrfs_release_path (&path); +return em; + +not_found: +btrfs_release_path (&path); +free_extent_map (em); +return NULL ; + +err: +btrfs_release_path (&path); +free_extent_map (em); +return ERR_PTR (ret); +} +static struct extent_map *defrag_lookup_extent (struct inode *inode,u64 start, -bool locked) +u64 newer_than,bool locked) {struct extent_map_tree *em_tree = &BTRFS_I (inode)->extent_tree;struct extent_io_tree *io_tree = &BTRFS_I (inode)->io_tree;
@@ -1009,7 +1156,7 @@ static struct extent_map *defrag_lookup_/* get the big lock and read metadata off disk */ if (!locked)lock_extent_bits (io_tree, start, end, &cached); - em =btrfs_get_extent (BTRFS_I (inode),NULL ,0 , start, sectorsize); + em =defrag_get_extent (BTRFS_I (inode), start, newer_than);if (!locked)unlock_extent_cached (io_tree, start, end, &cached);
@@ -1037,7 +1184,12 @@ static bool defrag_check_next_extent(strif (em->start + em->len >=i_size_read (inode))return false; - next =defrag_lookup_extent (inode, em->start + em->len, locked); +/* +* We want to check if the next extent can be merged with the current +* one, which can be an extent created in a past generation, so we pass +* a minimum generation of 0 to defrag_lookup_extent(). +*/ + next =defrag_lookup_extent (inode, em->start + em->len,0 , locked);/* No more em or hole */ if (!next || next->block_start >=EXTENT_MAP_LAST_BYTE ) goto out;
@@ -1188,7 +1340,8 @@ static int defrag_collect_targets(structu64 range_len; last_is_target = false; - em =defrag_lookup_extent (&inode->vfs_inode, cur, locked); + em =defrag_lookup_extent (&inode->vfs_inode, cur, + newer_than, locked);if (!em)break ;
Greg Kroah-Hartman
maintainerPATCH 47/186 btrfs: defrag: dont use merged extent map for their generation check
In reply to Greg Kroah-HartmanFrom: Qu Wenruo <[email protected]>
commit 199257a78bb01341c3ba6e85bdcf3a2e6e452c6d upstream.
For extent maps, if they are not compressed extents and are adjacent by logical addresses and file offsets, they can be merged into one larger extent map.
Such merged extent map will have the higher generation of all the original ones.
But this brings a problem for autodefrag, as it relies on accurate extent_map::generation to determine if one extent should be defragged.
For merged extent maps, their higher generation can mark some older extents to be defragged while the original extent map doesn't meet the minimal generation threshold.
Thus this will cause extra IO.
So solve the problem, here we introduce a new flag, EXTENT_FLAG_MERGED, to indicate if the extent map is merged from one or more ems.
And for autodefrag, if we find a merged extent map, and its generation meets the generation requirement, we just don't use this one, and go back to defrag_get_extent() to read extent maps from subvolume trees.
This could cause more read IO, but should result less defrag data write, so in the long run it should be a win for autodefrag.
--- fs/btrfs/extent_map.c | 2 ++ fs/btrfs/extent_map.h | 8 ++++++++ fs/btrfs/ioctl.c | 14 ++++++++++++++ 3 files changed, 24 insertions(+)
fs/btrfs/extent_map.c +2 -0
@@ -261,6 +261,7 @@ static void try_merge_map(struct extent_ em->mod_len = (em->mod_len + em->mod_start) - merge->mod_start; em->mod_start = merge->mod_start; em->generation =max (em->generation, merge->generation); +set_bit (EXTENT_FLAG_MERGED , &em->flags);rb_erase_cached (&merge->rb_node, &tree->map);RB_CLEAR_NODE (&merge->rb_node);
@@ -278,6 +279,7 @@ static void try_merge_map(struct extent_RB_CLEAR_NODE (&merge->rb_node); em->mod_len = (merge->mod_start + merge->mod_len) - em->mod_start; em->generation =max (em->generation, merge->generation); +set_bit (EXTENT_FLAG_MERGED , &em->flags);free_extent_map (merge); } }
fs/btrfs/extent_map.h +8 -0
@@ -25,6 +25,8 @@ enum {EXTENT_FLAG_FILLING ,/* filesystem extent mapping type */ EXTENT_FLAG_FS_MAPPING , +/* This em is merged from two or more physically adjacent ems */ + EXTENT_FLAG_MERGED, }; struct extent_map {
@@ -40,6 +42,12 @@ struct extent_map {u64 ram_bytes;u64 block_start;u64 block_len; + +/* +* Generation of the extent map, for merged em it's the highest +* generation of all merged ems. +* For non-merged extents, it's from btrfs_file_extent_item::generation. +*/ u64 generation;unsigned long flags;/* Used for chunk mappings, flag EXTENT_FLAG_FS_MAPPING must be set */
fs/btrfs/ioctl.c +14 -0
@@ -1149,6 +1149,20 @@ static struct extent_map *defrag_lookup_ em =lookup_extent_mapping (em_tree, start, sectorsize);read_unlock (&em_tree->lock); +/* +* We can get a merged extent, in that case, we need to re-search +* tree to get the original em for defrag. +* +* If @newer_than is 0 or em::generation < newer_than, we can trust +* this em, as either we don't care about the generation, or the +* merged extent map will be rejected anyway. +*/ +if (em &&test_bit (EXTENT_FLAG_MERGED , &em->flags) && + newer_than && em->generation >= newer_than) { +free_extent_map (em); + em =NULL ; + } +if (!em) {struct extent_state *cached =NULL ;u64 end = start + sectorsize -1 ;
Greg Kroah-Hartman
maintainerPATCH 48/186 ALSA: intel_hdmi: Fix reference to PCM buffer address
In reply to Greg Kroah-HartmanFrom: Zhen Ni <[email protected]>
commit 0aa6b294b312d9710804679abd2c0c8ca52cc2bc upstream.
PCM buffers might be allocated dynamically when the buffer preallocation failed or a larger buffer is requested, and it's not guaranteed that substream->dma_buffer points to the actually used buffer. The driver needs to refer to substream->runtime->dma_addr instead for the buffer address.
--- sound/x86/intel_hdmi_audio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/x86/intel_hdmi_audio.c +1 -1
@@ -1261,7 +1261,7 @@ static int had_pcm_mmap(struct snd_pcm_s { vma->vm_page_prot =pgprot_noncached (vma->vm_page_prot);return remap_pfn_range (vma, vma->vm_start, - substream->dma_buffer.addr >>PAGE_SHIFT , + substream->runtime->dma_addr >>PAGE_SHIFT , vma->vm_end - vma->vm_start, vma->vm_page_prot); }
Greg Kroah-Hartman
maintainerPATCH 49/186 ucounts: Fix systemd LimitNPROC with private users regression
In reply to Greg Kroah-HartmanFrom: Eric W. Biederman <[email protected]>
commit 0ac983f512033cb7b5e210c9589768ad25b1e36b upstream.
Long story short recursively enforcing RLIMIT_NPROC when it is not enforced on the process that creates a new user namespace, causes currently working code to fail. There is no reason to enforce RLIMIT_NPROC recursively when we don't enforce it normally so update the code to detect this case.
I would like to simply use capable(CAP_SYS_RESOURCE) to detect when RLIMIT_NPROC is not enforced upon the caller. Unfortunately because RLIMIT_NPROC is charged and checked for enforcement based upon the real uid, using capable() which is euid based is inconsistent with reality. Come as close as possible to testing for capable(CAP_SYS_RESOURCE) by testing for when the real uid would match the conditions when CAP_SYS_RESOURCE would be present if the real uid was the effective uid.
--- kernel/user_namespace.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
kernel/user_namespace.c +13 -1
@@ -58,6 +58,18 @@ static void set_cred_user_ns(struct cred cred->user_ns = user_ns; } +static unsigned long enforced_nproc_rlimit (void ) +{ +unsigned long limit =RLIM_INFINITY ; + +/* Is RLIMIT_NPROC currently enforced? */ +if (!uid_eq (current_uid (),GLOBAL_ROOT_UID ) || + (current_user_ns () != &init_user_ns)) + limit =rlimit (RLIMIT_NPROC ); + +return limit; +} +/* * Create a new user namespace, deriving the creator from the user in the * passed credentials, and replacing that user with the new root user for the
@@ -122,7 +134,7 @@ int create_user_ns(struct cred *new)for (i =0 ; i <MAX_PER_NAMESPACE_UCOUNTS ; i++) { ns->ucount_max[i] =INT_MAX ; } -set_rlimit_ucount_max (ns,UCOUNT_RLIMIT_NPROC ,rlimit (RLIMIT_NPROC )); +set_rlimit_ucount_max (ns,UCOUNT_RLIMIT_NPROC ,enforced_nproc_rlimit ());set_rlimit_ucount_max (ns,UCOUNT_RLIMIT_MSGQUEUE ,rlimit (RLIMIT_MSGQUEUE ));set_rlimit_ucount_max (ns,UCOUNT_RLIMIT_SIGPENDING ,rlimit (RLIMIT_SIGPENDING ));set_rlimit_ucount_max (ns,UCOUNT_RLIMIT_MEMLOCK ,rlimit (RLIMIT_MEMLOCK ));
Greg Kroah-Hartman
maintainerPATCH 50/186 binfmt_elf: Avoid total_mapping_size for ET_EXEC
In reply to Greg Kroah-HartmanFrom: Kees Cook <[email protected]>
commit 439a8468242b313486e69b8cc3b45ddcfa898fbf upstream.
Partially revert commit 5f501d555653 ("binfmt_elf: reintroduce using MAP_FIXED_NOREPLACE"), which applied the ET_DYN "total_mapping_size" logic also to ET_EXEC.
At least ia64 has ET_EXEC PT_LOAD segments that are not virtual-address contiguous (but _are_ file-offset contiguous). This would result in a giant mapping attempting to cover the entire span, including the virtual address range hole, and well beyond the size of the ELF file itself, causing the kernel to refuse to load it. For example:
$ readelf -lW /usr/bin/gcc
...
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz ...
...
LOAD 0x000000 0x4000000000000000 0x4000000000000000 0x00b5a0 0x00b5a0 ...
LOAD 0x00b5a0 0x600000000000b5a0 0x600000000000b5a0 0x0005ac 0x000710 ...
...
^^^^^^^^ ^^^^^^^^^^^^^^^^^^ ^^^^^^^^ ^^^^^^^^File offset range : 0x000000-0x00bb4c
0x00bb4c bytes
Virtual address range : 0x4000000000000000-0x600000000000bcb0
0x200000000000bcb0 bytes
Remove the total_mapping_size logic for ET_EXEC, which reduces the ET_EXEC MAP_FIXED_NOREPLACE coverage to only the first PT_LOAD (better than nothing), and retains it for ET_DYN.
Ironically, this is the reverse of the problem that originally caused problems with MAP_FIXED_NOREPLACE: overlapping PT_LOAD segments. Future work could restore full coverage if load_elf_binary() were to perform mappings in a separate phase from the loading (where it could resolve both overlaps and holes).
--- fs/binfmt_elf.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-)
fs/binfmt_elf.c +18 -7
@@ -1135,14 +1135,25 @@ out_free_interp:* is then page aligned. */ load_bias =ELF_PAGESTART (load_bias - vaddr); - } -/* -* Calculate the entire size of the ELF mapping (total_size). -* (Note that load_addr_set is set to true later once the -* initial mapping is performed.) -*/ -if (!load_addr_set) { +/* +* Calculate the entire size of the ELF mapping +* (total_size), used for the initial mapping, +* due to load_addr_set which is set to true later +* once the initial mapping is performed. +* +* Note that this is only sensible when the LOAD +* segments are contiguous (or overlapping). If +* used for LOADs that are far apart, this would +* cause the holes between LOADs to be mapped, +* running the risk of having the mapping fail, +* as it would be larger than the ELF file itself. +* +* As a result, only ET_DYN does this, since +* some ET_EXEC (e.g. ia64) may have large virtual +* memory holes between LOADs. +* +*/ total_size =total_mapping_size (elf_phdata, elf_ex->e_phnum);if (!total_size) {
Greg Kroah-Hartman
maintainerPATCH 51/186 riscv/efi_stub: Fix get_boot_hartid_from_fdt() return value
In reply to Greg Kroah-HartmanFrom: Sunil V L <[email protected]>
commit dcf0c838854c86e1f41fb1934aea906845d69782 upstream.
The get_boot_hartid_from_fdt() function currently returns U32_MAX for failure case which is not correct because U32_MAX is a valid hartid value. This patch fixes the issue by returning error code.
--- drivers/firmware/efi/libstub/riscv-stub.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-)
drivers/firmware/efi/libstub/riscv-stub.c +10 -7
@@ -25,7 +25,7 @@ typedef void __noreturn (*jump_kernel_fustatic u32 hartid; -static u32 get_boot_hartid_from_fdt (void ) +static int get_boot_hartid_from_fdt (void ) {const void *fdt;int chosen_node, len;
@@ -33,23 +33,26 @@ static u32 get_boot_hartid_from_fdt(void fdt =get_efi_config_table (DEVICE_TREE_GUID );if (!fdt) -return U32_MAX ; +return -EINVAL ; chosen_node =fdt_path_offset (fdt,"/chosen" );if (chosen_node <0 ) -return U32_MAX ; +return -EINVAL ; prop =fdt_getprop ((void *)fdt, chosen_node,"boot-hartid" , &len);if (!prop || len !=sizeof (u32)) -return U32_MAX ; +return -EINVAL ; -return fdt32_to_cpu (*prop); + hartid =fdt32_to_cpu (*prop); +return 0 ; }efi_status_t check_platform_features (void ) { - hartid =get_boot_hartid_from_fdt (); -if (hartid ==U32_MAX ) { +int ret; + + ret =get_boot_hartid_from_fdt (); +if (ret) {efi_err ("/chosen/boot-hartid missing or invalid!\n" );return EFI_UNSUPPORTED ; }
Greg Kroah-Hartman
maintainerPATCH 52/186 riscv: Fix config KASAN && SPARSEMEM && !SPARSE_VMEMMAP
In reply to Greg Kroah-HartmanFrom: Alexandre Ghiti <[email protected]>
commit a3d328037846d013bb4c7f3777241e190e4c75e1 upstream.
In order to get the pfn of a struct page* when sparsemem is enabled without vmemmap, the mem_section structures need to be initialized which happens in sparse_init.
But kasan_early_init calls pfn_to_page way before sparse_init is called, which then tries to dereference a null mem_section pointer.
Fix this by removing the usage of this function in kasan_early_init.
--- arch/riscv/mm/kasan_init.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
arch/riscv/mm/kasan_init.c +1 -2
@@ -22,8 +22,7 @@ asmlinkage void __init kasan_early_init(for (i =0 ; i <PTRS_PER_PTE ; ++i)set_pte (kasan_early_shadow_pte + i, -mk_pte (virt_to_page (kasan_early_shadow_page), -PAGE_KERNEL )); +pfn_pte (virt_to_pfn (kasan_early_shadow_page),PAGE_KERNEL ));for (i =0 ; i <PTRS_PER_PMD ; ++i) set_pmd(kasan_early_shadow_pmd + i,
Greg Kroah-Hartman
maintainerPATCH 53/186 riscv: Fix config KASAN && DEBUG_VIRTUAL
In reply to Greg Kroah-HartmanFrom: Alexandre Ghiti <[email protected]>
commit c648c4bb7d02ceb53ee40172fdc4433b37cee9c6 upstream.
__virt_to_phys function is called very early in the boot process (ie kasan_early_init) so it should not be instrumented by KASAN otherwise it bugs.
Fix this by declaring phys_addr.c as non-kasan instrumentable.
--- arch/riscv/mm/Makefile | 3 +++ 1 file changed, 3 insertions(+)
arch/riscv/mm/Makefile +3 -0
@@ -24,6 +24,9 @@ obj-$(CONFIG_KASAN) += kasan_init.o ifdef CONFIG_KASAN KASAN_SANITIZE_kasan_init.o := n KASAN_SANITIZE_init.o := n +ifdef CONFIG_DEBUG_VIRTUAL +KASAN_SANITIZE_physaddr.o := n +endif endif obj-$(CONFIG_DEBUG_VIRTUAL) += physaddr.o
Greg Kroah-Hartman
maintainerPATCH 54/186 iwlwifi: mvm: check debugfs_dir ptr before use
In reply to Greg Kroah-HartmanFrom: Randy Dunlap <[email protected]>
commit 5a6248c0a22352f09ea041665d3bd3e18f6f872c upstream.
When "debugfs=off" is used on the kernel command line, iwiwifi's mvm module uses an invalid/unchecked debugfs_dir pointer and causes a BUG:
BUG: kernel NULL pointer dereference, address: 000000000000004f #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 0 P4D 0 Oops: 0000 [#1] PREEMPT SMP CPU: 1 PID: 503 Comm: modprobe Tainted: G W 5.17.0-rc5 #7 Hardware name: Dell Inc. Inspiron 15 5510/076F7Y, BIOS 2.4.1 11/05/2021 RIP: 0010:iwl_mvm_dbgfs_register+0x692/0x700 [iwlmvm] Code: 69 a0 be 80 01 00 00 48 c7 c7 50 73 6a a0 e8 95 cf ee e0 48 8b 83 b0 1e 00 00 48 c7 c2 54 73 6a a0 be 64 00 00 00 48 8d 7d 8c <48> 8b 48 50 e8 15 22 07 e1 48 8b 43 28 48 8d 55 8c 48 c7 c7 5f 73 RSP: 0018:ffffc90000a0ba68 EFLAGS: 00010246 RAX: ffffffffffffffff RBX: ffff88817d6e3328 RCX: ffff88817d6e3328 RDX: ffffffffa06a7354 RSI: 0000000000000064 RDI: ffffc90000a0ba6c RBP: ffffc90000a0bae0 R08: ffffffff824e4880 R09: ffffffffa069d620 R10: ffffc90000a0ba00 R11: ffffffffffffffff R12: 0000000000000000 R13: ffffc90000a0bb28 R14: ffff88817d6e3328 R15: ffff88817d6e3320 FS: 00007f64dd92d740(0000) GS:ffff88847f640000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000000000000004f CR3: 000000016fc79001 CR4: 0000000000770ee0 PKRU: 55555554 Call Trace: <TASK> ? iwl_mvm_mac_setup_register+0xbdc/0xda0 [iwlmvm] iwl_mvm_start_post_nvm+0x71/0x100 [iwlmvm] iwl_op_mode_mvm_start+0xab8/0xb30 [iwlmvm] _iwl_op_mode_start+0x6f/0xd0 [iwlwifi] iwl_opmode_register+0x6a/0xe0 [iwlwifi] ? 0xffffffffa0231000 iwl_mvm_init+0x35/0x1000 [iwlmvm] ? 0xffffffffa0231000 do_one_initcall+0x5a/0x1b0 ? kmem_cache_alloc+0x1e5/0x2f0 ? do_init_module+0x1e/0x220 do_init_module+0x48/0x220 load_module+0x2602/0x2bc0 ? __kernel_read+0x145/0x2e0 ? kernel_read_file+0x229/0x290 __do_sys_finit_module+0xc5/0x130 ? __do_sys_finit_module+0xc5/0x130 __x64_sys_finit_module+0x13/0x20 do_syscall_64+0x38/0x90 entry_SYSCALL_64_after_hwframe+0x44/0xae RIP: 0033:0x7f64dda564dd Code: 5b 41 5c c3 66 0f 1f 84 00 00 00 00 00 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 1b 29 0f 00 f7 d8 64 89 01 48 RSP: 002b:00007ffdba393f88 EFLAGS: 00000246 ORIG_RAX: 0000000000000139 RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f64dda564dd RDX: 0000000000000000 RSI: 00005575399e2ab2 RDI: 0000000000000001 RBP: 000055753a91c5e0 R08: 0000000000000000 R09: 0000000000000002 R10: 0000000000000001 R11: 0000000000000246 R12: 00005575399e2ab2 R13: 000055753a91ceb0 R14: 0000000000000000 R15: 000055753a923018 </TASK> Modules linked in: btintel(+) btmtk bluetooth vfat snd_hda_codec_hdmi fat snd_hda_codec_realtek snd_hda_codec_generic iwlmvm(+) snd_sof_pci_intel_tgl mac80211 snd_sof_intel_hda_common soundwire_intel soundwire_generic_allocation soundwire_cadence soundwire_bus snd_sof_intel_hda snd_sof_pci snd_sof snd_sof_xtensa_dsp snd_soc_hdac_hda snd_hda_ext_core snd_soc_acpi_intel_match snd_soc_acpi snd_soc_core btrfs snd_compress snd_hda_intel snd_intel_dspcfg snd_intel_sdw_acpi snd_hda_codec raid6_pq iwlwifi snd_hda_core snd_pcm snd_timer snd soundcore cfg80211 intel_ish_ipc(+) thunderbolt rfkill intel_ishtp ucsi_acpi wmi i2c_hid_acpi i2c_hid evdev CR2: 000000000000004f ---[ end trace 0000000000000000 ]---
Check the debugfs_dir pointer for an error before using it.
--- drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c +8 -3
@@ -5,6 +5,7 @@* Copyright (C) 2016-2017 Intel Deutschland GmbH */ #include <linux/vmalloc.h> +#include <linux/err.h> #include <linux/ieee80211.h> #include <linux/netdevice.h>
@@ -1849,7 +1850,6 @@ void iwl_mvm_sta_add_debugfs(struct ieeevoid iwl_mvm_dbgfs_register (struct iwl_mvm *mvm) {struct dentry *bcast_dir__maybe_unused ; -char buf[100 ];spin_lock_init (&mvm->drv_stats_lock);
@@ -1930,6 +1930,11 @@ void iwl_mvm_dbgfs_register(struct iwl_m* Create a symlink with mac80211. It will be removed when mac80211 * exists (before the opmode exists which removes the target.) */ -snprintf (buf,100 ,"../../%pd2" , mvm->debugfs_dir->d_parent); -debugfs_create_symlink ("iwlwifi" , mvm->hw->wiphy->debugfsdir, buf); +if (!IS_ERR (mvm->debugfs_dir)) { +char buf[100 ]; + +snprintf (buf,100 ,"../../%pd2" , mvm->debugfs_dir->d_parent); +debugfs_create_symlink ("iwlwifi" , mvm->hw->wiphy->debugfsdir, + buf); + } }
Greg Kroah-Hartman
maintainerPATCH 55/186 ASoC: ops: Shift tested values in snd_soc_put_volsw() by +min
In reply to Greg Kroah-HartmanFrom: Marek Vasut <[email protected]>
commit 9bdd10d57a8807dba0003af0325191f3cec0f11c upstream.
While the $val/$val2 values passed in from userspace are always >= 0 integers, the limits of the control can be signed integers and the $min can be non-zero and less than zero. To correctly validate $val/$val2 against platform_max, add the $min offset to val first.
--- sound/soc/soc-ops.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
sound/soc/soc-ops.c +2 -2
@@ -317,7 +317,7 @@ int snd_soc_put_volsw(struct snd_kcontro mask =BIT (sign_bit +1 ) -1 ; val = ucontrol->value.integer.value[0 ]; -if (mc->platform_max && val > mc->platform_max) +if (mc->platform_max && ((int )val + min) > mc->platform_max)return -EINVAL ;if (val > max - min)return -EINVAL ;
@@ -330,7 +330,7 @@ int snd_soc_put_volsw(struct snd_kcontro val = val << shift;if (snd_soc_volsw_is_stereo (mc)) { val2 = ucontrol->value.integer.value[1 ]; -if (mc->platform_max && val2 > mc->platform_max) +if (mc->platform_max && ((int )val2 + min) > mc->platform_max)return -EINVAL ;if (val2 > max - min)return -EINVAL ;
Greg Kroah-Hartman
maintainerPATCH 56/186 iommu/vt-d: Fix double list_add when enabling VMD in scalable mode
In reply to Greg Kroah-HartmanFrom: Adrian Huang <[email protected]>
commit b00833768e170a31af09268f7ab96aecfcca9623 upstream.
When enabling VMD and IOMMU scalable mode, the following kernel panic call trace/kernel log is shown in Eagle Stream platform (Sapphire Rapids CPU) during booting:
pci 0000:59:00.5: Adding to iommu group 42
...
vmd 0000:59:00.5: PCI host bridge to bus 10000:80 pci 10000:80:01.0: [8086:352a] type 01 class 0x060400 pci 10000:80:01.0: reg 0x10: [mem 0x00000000-0x0001ffff 64bit] pci 10000:80:01.0: enabling Extended Tags
pci 10000:80:01.0: PME# supported from D0 D3hot D3cold pci 10000:80:01.0: DMAR: Setup RID2PASID failed
pci 10000:80:01.0: Failed to add to iommu group 42: -16 pci 10000:80:03.0: [8086:352b] type 01 class 0x060400 pci 10000:80:03.0: reg 0x10: [mem 0x00000000-0x0001ffff 64bit] pci 10000:80:03.0: enabling Extended Tags
pci 10000:80:03.0: PME# supported from D0 D3hot D3cold
------------[ cut here ]------------
kernel BUG at lib/list_debug.c:29!
invalid opcode: 0000 [#1] PREEMPT SMP NOPTI
CPU: 0 PID: 7 Comm: kworker/0:1 Not tainted 5.17.0-rc3+ #7
Hardware name: Lenovo ThinkSystem SR650V3/SB27A86647, BIOS ESE101Y-1.00 01/13/2022
Workqueue: events work_for_cpu_fn
RIP: 0010:__list_add_valid.cold+0x26/0x3f
Code: 9a 4a ab ff 4c 89 c1 48 c7 c7 40 0c d9 9e e8 b9 b1 fe ff 0f
0b 48 89 f2 4c 89 c1 48 89 fe 48 c7 c7 f0 0c d9 9e e8 a2 b1
fe ff <0f> 0b 48 89 d1 4c 89 c6 4c 89 ca 48 c7 c7 98 0c d9
9e e8 8b b1 fe
RSP: 0000:ff5ad434865b3a40 EFLAGS: 00010246
RAX: 0000000000000058 RBX: ff4d61160b74b880 RCX: ff4d61255e1fffa8
RDX: 0000000000000000 RSI: 00000000fffeffff RDI: ffffffff9fd34f20
RBP: ff4d611d8e245c00 R08: 0000000000000000 R09: ff5ad434865b3888
R10: ff5ad434865b3880 R11: ff4d61257fdc6fe8 R12: ff4d61160b74b8a0
R13: ff4d61160b74b8a0 R14: ff4d611d8e245c10 R15: ff4d611d8001ba70
FS: 0000000000000000(0000) GS:ff4d611d5ea00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: ff4d611fa1401000 CR3: 0000000aa0210001 CR4: 0000000000771ef0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe07f0 DR7: 0000000000000400
PKRU: 55555554
Call Trace:
<TASK>
intel_pasid_alloc_table+0x9c/0x1d0
dmar_insert_one_dev_info+0x423/0x540
? device_to_iommu+0x12d/0x2f0
intel_iommu_attach_device+0x116/0x290
__iommu_attach_device+0x1a/0x90
iommu_group_add_device+0x190/0x2c0
__iommu_probe_device+0x13e/0x250
iommu_probe_device+0x24/0x150
iommu_bus_notifier+0x69/0x90
blocking_notifier_call_chain+0x5a/0x80
device_add+0x3db/0x7b0
? arch_memremap_can_ram_remap+0x19/0x50
? memremap+0x75/0x140
pci_device_add+0x193/0x1d0
pci_scan_single_device+0xb9/0xf0
pci_scan_slot+0x4c/0x110
pci_scan_child_bus_extend+0x3a/0x290
vmd_enable_domain.constprop.0+0x63e/0x820
vmd_probe+0x163/0x190
local_pci_probe+0x42/0x80
work_for_cpu_fn+0x13/0x20
process_one_work+0x1e2/0x3b0
worker_thread+0x1c4/0x3a0
? rescuer_thread+0x370/0x370
kthread+0xc7/0xf0
? kthread_complete_and_exit+0x20/0x20
ret_from_fork+0x1f/0x30
</TASK>
Modules linked in:
---[ end trace 0000000000000000 ]---
...
Kernel panic - not syncing: Fatal exception
Kernel Offset: 0x1ca00000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff)
---[ end Kernel panic - not syncing: Fatal exception ]---The following 'lspci' output shows devices '10000:80:*' are subdevices of the VMD device 0000:59:00.5:
$ lspci ... 0000:59:00.5 RAID bus controller: Intel Corporation Volume Management Device NVMe RAID Controller (rev 20) ... 10000:80:01.0 PCI bridge: Intel Corporation Device 352a (rev 03) 10000:80:03.0 PCI bridge: Intel Corporation Device 352b (rev 03) 10000:80:05.0 PCI bridge: Intel Corporation Device 352c (rev 03) 10000:80:07.0 PCI bridge: Intel Corporation Device 352d (rev 03) 10000:81:00.0 Non-Volatile memory controller: Intel Corporation NVMe Datacenter SSD [3DNAND, Beta Rock Controller] 10000:82:00.0 Non-Volatile memory controller: Intel Corporation NVMe Datacenter SSD [3DNAND, Beta Rock Controller]
The symptom 'list_add double add' is caused by the following failure message:
pci 10000:80:01.0: DMAR: Setup RID2PASID failed pci 10000:80:01.0: Failed to add to iommu group 42: -16 pci 10000:80:03.0: [8086:352b] type 01 class 0x060400
Device 10000:80:01.0 is the subdevice of the VMD device 0000:59:00.5, so invoking intel_pasid_alloc_table() gets the pasid_table of the VMD device 0000:59:00.5. Here is call path:
intel_pasid_alloc_table
pci_for_each_dma_alias
get_alias_pasid_table
search_pasid_table
pci_real_dma_dev() in pci_for_each_dma_alias() gets the real dma device which is the VMD device 0000:59:00.5. However, pte of the VMD device 0000:59:00.5 has been configured during this message "pci 0000:59:00.5:
Adding to iommu group 42". So, the status -EBUSY is returned when configuring pasid entry for device 10000:80:01.0.
It then invokes dmar_remove_one_dev_info() to release 'struct device_domain_info *' from iommu_devinfo_cache. But, the pasid table is not released because of the following statement in __dmar_remove_one_dev_info():
if (info->dev && !dev_is_real_dma_subdevice(info->dev)) {
...
intel_pasid_free_table(info->dev);
}The subsequent dmar_insert_one_dev_info() operation of device 10000:80:03.0 allocates 'struct device_domain_info *' from iommu_devinfo_cache. The allocated address is the same address that is released previously for device 10000:80:01.0. Finally, invoking device_attach_pasid_table() causes the issue.
git bisect points to the offending commit 474dd1c65064 ("iommu/vt-d:
Fix clearing real DMA device's scalable-mode context entries"), which releases the pasid table if the device is not the subdevice by checking the returned status of dev_is_real_dma_subdevice(). Reverting the offending commit can work around the issue.
The solution is to prevent from allocating pasid table if those devices are subdevices of the VMD device.
--- drivers/iommu/intel/iommu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iommu/intel/iommu.c +1 -1
@@ -2773,7 +2773,7 @@ static struct dmar_domain *dmar_insert_ospin_unlock_irqrestore (&device_domain_lock, flags);/* PASID table is mandatory for a PCI device in scalable mode. */ -if (dev &&dev_is_pci (dev) &&sm_supported (iommu)) { +if (sm_supported (iommu) && !dev_is_real_dma_subdevice (dev)) { ret =intel_pasid_alloc_table (dev);if (ret) {dev_err (dev,"PASID table allocation failed\n" );
Greg Kroah-Hartman
maintainerPATCH 57/186 iommu/amd: Recover from event log overflow
In reply to Greg Kroah-HartmanFrom: Lennert Buytenhek <[email protected]>
commit 5ce97f4ec5e0f8726a5dda1710727b1ee9badcac upstream.
The AMD IOMMU logs I/O page faults and such to a ring buffer in system memory, and this ring buffer can overflow. The AMD IOMMU spec has the following to say about the interrupt status bit that signals this overflow condition:
EventOverflow: Event log overflow. RW1C. Reset 0b. 1 = IOMMU event log overflow has occurred. This bit is set when a new event is to be written to the event log and there is no usable entry in the event log, causing the new event information to be discarded. An interrupt is generated when EventOverflow = 1b and MMIO Offset 0018h[EventIntEn] = 1b. No new event log entries are written while this bit is set. Software Note: To resume logging, clear EventOverflow (W1C), and write a 1 to MMIO Offset 0018h[EventLogEn].
The AMD IOMMU driver doesn't currently implement this recovery sequence, meaning that if a ring buffer overflow occurs, logging of EVT/PPR/GA events will cease entirely.
This patch implements the spec-mandated reset sequence, with the minor tweak that the hardware seems to want to have a 0 written to MMIO Offset 0018h[EventLogEn] first, before writing an 1 into this field, or the IOMMU won't actually resume logging events.
--- drivers/iommu/amd/amd_iommu.h | 1 + drivers/iommu/amd/amd_iommu_types.h | 1 + drivers/iommu/amd/init.c | 10 ++++++++++ drivers/iommu/amd/iommu.c | 10 ++++++++-- 4 files changed, 20 insertions(+), 2 deletions(-)
drivers/iommu/amd/amd_iommu.h +1 -0
@@ -14,6 +14,7 @@extern irqreturn_t amd_iommu_int_thread (int irq,void *data);extern irqreturn_t amd_iommu_int_handler (int irq,void *data);extern void amd_iommu_apply_erratum_63 (u16 devid); +extern void amd_iommu_restart_event_logging (struct amd_iommu *iommu);extern void amd_iommu_reset_cmd_buffer (struct amd_iommu *iommu);extern int amd_iommu_init_devices (void );extern void amd_iommu_uninit_devices (void );
drivers/iommu/amd/amd_iommu_types.h +1 -0
@@ -110,6 +110,7 @@#define PASID_MASK 0x0000ffff/* MMIO status bits */ +#define MMIO_STATUS_EVT_OVERFLOW_INT_MASK (1 << 0)#define MMIO_STATUS_EVT_INT_MASK (1 << 1)#define MMIO_STATUS_COM_WAIT_INT_MASK (1 << 2)#define MMIO_STATUS_PPR_INT_MASK (1 << 6)
drivers/iommu/amd/init.c +10 -0
@@ -658,6 +658,16 @@ static int __init alloc_command_buffer(s }/* +* This function restarts event logging in case the IOMMU experienced +* an event log buffer overflow. +*/ +void amd_iommu_restart_event_logging (struct amd_iommu *iommu) +{ +iommu_feature_disable (iommu,CONTROL_EVT_LOG_EN ); +iommu_feature_enable (iommu,CONTROL_EVT_LOG_EN ); +} + +/* * This function resets the command buffer if the IOMMU stopped fetching * commands from it. */
drivers/iommu/amd/iommu.c +8 -2
@@ -764,7 +764,8 @@ amd_iommu_set_pci_msi_domain(struct devi#endif /* !CONFIG_IRQ_REMAP */ #define AMD_IOMMU_INT_MASK \ - (MMIO_STATUS_EVT_INT_MASK | \ + (MMIO_STATUS_EVT_OVERFLOW_INT_MASK | \ + MMIO_STATUS_EVT_INT_MASK | \ MMIO_STATUS_PPR_INT_MASK | \ MMIO_STATUS_GALOG_INT_MASK)
@@ -774,7 +775,7 @@ irqreturn_t amd_iommu_int_thread(int irqu32 status =readl (iommu->mmio_base +MMIO_STATUS_OFFSET );while (status &AMD_IOMMU_INT_MASK ) { -/* Enable EVT and PPR and GA interrupts again */ +/* Enable interrupt sources again */ writel (AMD_IOMMU_INT_MASK , iommu->mmio_base +MMIO_STATUS_OFFSET );
@@ -795,6 +796,11 @@ irqreturn_t amd_iommu_int_thread(int irq }#endif +if (status &MMIO_STATUS_EVT_OVERFLOW_INT_MASK ) { +pr_info_ratelimited ("IOMMU event log overflow\n" ); +amd_iommu_restart_event_logging (iommu); + } +/* * Hardware bug: ERBT1312 * When re-enabling interrupt (by writing 1
Greg Kroah-Hartman
maintainerPATCH 58/186 drm/i915: s/JSP2/ICP2/ PCH
In reply to Greg Kroah-HartmanFrom: Ville Syrjälä <[email protected]>
commit 08783aa7693f55619859f4f63f384abf17cb58c5 upstream.
This JSP2 PCH actually seems to be some special Apple specific ICP variant rather than a JSP. Make it so. Or at least all the references to it seem to be some Apple ICL machines. Didn't manage to find these PCI IDs in any public chipset docs unfortunately.
The only thing we're losing here with this JSP->ICP change is Wa_14011294188, but based on the HSD that isn't actually needed on any ICP based design (including JSP), only TGP based stuff (including MCC) really need it. The documented w/a just never made that distinction because Windows didn't want to differentiate between JSP and MCC (not sure how they handle hpd/ddc/etc. then though...).
--- drivers/gpu/drm/i915/intel_pch.c | 2 +- drivers/gpu/drm/i915/intel_pch.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/i915/intel_pch.c +1 -1
@@ -108,6 +108,7 @@ intel_pch_type(const struct drm_i915_pri/* Comet Lake V PCH is based on KBP, which is SPT compatible */ return PCH_SPT ;case INTEL_PCH_ICP_DEVICE_ID_TYPE : +case INTEL_PCH_ICP2_DEVICE_ID_TYPE :drm_dbg_kms (&dev_priv->drm,"Found Ice Lake PCH\n" );drm_WARN_ON (&dev_priv->drm, !IS_ICELAKE (dev_priv));return PCH_ICP ;
@@ -123,7 +124,6 @@ intel_pch_type(const struct drm_i915_pri !IS_GEN9_BC(dev_priv));return PCH_TGP ;case INTEL_PCH_JSP_DEVICE_ID_TYPE : -case INTEL_PCH_JSP2_DEVICE_ID_TYPE :drm_dbg_kms (&dev_priv->drm,"Found Jasper Lake PCH\n" );drm_WARN_ON (&dev_priv->drm, !IS_JSL_EHL (dev_priv));return PCH_JSP ;
drivers/gpu/drm/i915/intel_pch.h +1 -1
@@ -50,11 +50,11 @@ enum intel_pch {#define INTEL_PCH_CMP2_DEVICE_ID_TYPE 0x0680#define INTEL_PCH_CMP_V_DEVICE_ID_TYPE 0xA380#define INTEL_PCH_ICP_DEVICE_ID_TYPE 0x3480 +#define INTEL_PCH_ICP2_DEVICE_ID_TYPE 0x3880#define INTEL_PCH_MCC_DEVICE_ID_TYPE 0x4B00#define INTEL_PCH_TGP_DEVICE_ID_TYPE 0xA080#define INTEL_PCH_TGP2_DEVICE_ID_TYPE 0x4380#define INTEL_PCH_JSP_DEVICE_ID_TYPE 0x4D80 -#define INTEL_PCH_JSP2_DEVICE_ID_TYPE 0x3880#define INTEL_PCH_ADP_DEVICE_ID_TYPE 0x7A80#define INTEL_PCH_ADP2_DEVICE_ID_TYPE 0x5180#define INTEL_PCH_P2X_DEVICE_ID_TYPE 0x7100
Greg Kroah-Hartman
maintainerPATCH 59/186 drm/amd/display: Reduce dmesg error to a debug print
In reply to Greg Kroah-HartmanFrom: Leo (Hanghong) Ma <[email protected]>
commit 1d925758ba1a5d2716a847903e2fd04efcbd9862 upstream.
[Why & How]
Dmesg errors are found on dcn3.1 during reset test, but it's not a really failure. So reduce it to a debug print.
--- drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +3 -1
@@ -4454,7 +4454,9 @@ bool dp_retrieve_lttpr_cap(struct dc_lin lttpr_dpcd_data, sizeof(lttpr_dpcd_data));if (status !=DC_OK ) { -dm_error ("%s: Read LTTPR caps data failed.\n" , __func__); +#if defined(CONFIG_DRM_AMD_DC_DCN ) +DC_LOG_DP2 ("%s: Read LTTPR caps data failed.\n" , __func__); +#endif return false; }
Greg Kroah-Hartman
maintainerPATCH 60/186 xen/netfront: destroy queues before real_num_tx_queues is zeroed
In reply to Greg Kroah-HartmanFrom: Marek Marczykowski-Górecki <[email protected]>
commit dcf4ff7a48e7598e6b10126cc02177abb8ae4f3f upstream.
xennet_destroy_queues() relies on info->netdev->real_num_tx_queues to delete queues. Since d7dac083414eb5bb99a6d2ed53dc2c1b405224e5 ("net-sysfs: update the queue counts in the unregistration path"), unregister_netdev() indirectly sets real_num_tx_queues to 0. Those two facts together means, that xennet_destroy_queues() called from xennet_remove() cannot do its job, because it's called after unregister_netdev(). This results in kfree-ing queues that are still linked in napi, which ultimately crashes:
BUG: kernel NULL pointer dereference, address: 0000000000000000
#PF: supervisor read access in kernel mode
#PF: error_code(0x0000) - not-present page
PGD 0 P4D 0
Oops: 0000 [#1] PREEMPT SMP PTI
CPU: 1 PID: 52 Comm: xenwatch Tainted: G W 5.16.10-1.32.fc32.qubes.x86_64+ #226
RIP: 0010:free_netdev+0xa3/0x1a0
Code: ff 48 89 df e8 2e e9 00 00 48 8b 43 50 48 8b 08 48 8d b8 a0 fe ff ff 48 8d a9 a0 fe ff ff 49 39 c4 75 26 eb 47 e8 ed c1 66 ff <48> 8b 85 60 01 00 00 48 8d 95 60 01 00 00 48 89 ef 48 2d 60 01 00
RSP: 0000:ffffc90000bcfd00 EFLAGS: 00010286
RAX: 0000000000000000 RBX: ffff88800edad000 RCX: 0000000000000000
RDX: 0000000000000001 RSI: ffffc90000bcfc30 RDI: 00000000ffffffff
RBP: fffffffffffffea0 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000001 R12: ffff88800edad050
R13: ffff8880065f8f88 R14: 0000000000000000 R15: ffff8880066c6680
FS: 0000000000000000(0000) GS:ffff8880f3300000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000000000000 CR3: 00000000e998c006 CR4: 00000000003706e0
Call Trace:
<TASK>
xennet_remove+0x13d/0x300 [xen_netfront]
xenbus_dev_remove+0x6d/0xf0
__device_release_driver+0x17a/0x240
device_release_driver+0x24/0x30
bus_remove_device+0xd8/0x140
device_del+0x18b/0x410
? _raw_spin_unlock+0x16/0x30
? klist_iter_exit+0x14/0x20
? xenbus_dev_request_and_reply+0x80/0x80
device_unregister+0x13/0x60
xenbus_dev_changed+0x18e/0x1f0
xenwatch_thread+0xc0/0x1a0
? do_wait_intr_irq+0xa0/0xa0
kthread+0x16b/0x190
? set_kthread_struct+0x40/0x40
ret_from_fork+0x22/0x30
</TASK>Fix this by calling xennet_destroy_queues() from xennet_uninit(), when real_num_tx_queues is still available. This ensures that queues are destroyed when real_num_tx_queues is set to 0, regardless of how unregister_netdev() was called.
Originally reported at
https://github.com/QubesOS/qubes-issues/issues/7257
--- drivers/net/xen-netfront.c | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-)
drivers/net/xen-netfront.c +23 -16
@@ -842,6 +842,28 @@ static int xennet_close(struct net_devicreturn 0 ; } +static void xennet_destroy_queues (struct netfront_info *info) +{ +unsigned int i; + +for (i =0 ; i < info->netdev->real_num_tx_queues; i++) { +struct netfront_queue *queue = &info->queues[i]; + +if (netif_running (info->netdev)) +napi_disable (&queue->napi); +netif_napi_del (&queue->napi); + } + +kfree (info->queues); + info->queues =NULL ; +} + +static void xennet_uninit (struct net_device *dev) +{ +struct netfront_info *np =netdev_priv (dev); +xennet_destroy_queues (np); +} +static void xennet_set_rx_rsp_cons (struct netfront_queue *queue,RING_IDX val) {unsigned long flags;
@@ -1611,6 +1633,7 @@ static int xennet_xdp(struct net_device }static const struct net_device_ops xennet_netdev_ops = { + .ndo_uninit = xennet_uninit, .ndo_open = xennet_open, .ndo_stop = xennet_close, .ndo_start_xmit = xennet_start_xmit,
@@ -2103,22 +2126,6 @@ error:return err; } -static void xennet_destroy_queues (struct netfront_info *info) -{ -unsigned int i; - -for (i =0 ; i < info->netdev->real_num_tx_queues; i++) { -struct netfront_queue *queue = &info->queues[i]; - -if (netif_running (info->netdev)) -napi_disable (&queue->napi); -netif_napi_del (&queue->napi); - } - -kfree (info->queues); - info->queues =NULL ; -} -static int xennet_create_page_pool (struct netfront_queue *queue)
Greg Kroah-Hartman
maintainerPATCH 61/186 thermal: core: Fix TZ_GET_TRIP NULL pointer dereference
In reply to Greg Kroah-HartmanFrom: Nicolas Cavallari <[email protected]>
commit 5838a14832d447990827d85e90afe17e6fb9c175 upstream.
Do not call get_trip_hyst() from thermal_genl_cmd_tz_get_trip() if the thermal zone does not define one.
--- drivers/thermal/thermal_netlink.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/thermal/thermal_netlink.c +3 -2
@@ -419,11 +419,12 @@ static int thermal_genl_cmd_tz_get_trip(for (i =0 ; i < tz->trips; i++) {enum thermal_trip_type type; -int temp, hyst; +int temp, hyst =0 ; tz->ops->get_trip_type (tz, i, &type); tz->ops->get_trip_temp (tz, i, &temp); - tz->ops->get_trip_hyst (tz, i, &hyst); +if (tz->ops->get_trip_hyst) + tz->ops->get_trip_hyst (tz, i, &hyst); if (nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_TRIP_ID, i) || nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_TRIP_TYPE, type) ||
Greg Kroah-Hartman
maintainerPATCH 62/186 mac80211: fix EAPoL rekey fail in 802.3 rx path
In reply to Greg Kroah-HartmanFrom: Deren Wu <[email protected]>
commit 610d086d6df0b15c3732a7b4a5b0f1c3e1b84d4c upstream.
mac80211 set capability NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211 to upper layer by default. That means we should pass EAPoL packets through nl80211 path only, and should not send the EAPoL skb to netdevice diretly. At the meanwhile, wpa_supplicant would not register sock to listen EAPoL skb on the netdevice.
However, there is no control_port_protocol handler in mac80211 for 802.3 RX packets, mac80211 driver would pass up the EAPoL rekey frame to netdevice and wpa_supplicant would be never interactive with this kind of packets, if SUPPORTS_RX_DECAP_OFFLOAD is enabled. This causes STA always rekey fail if EAPoL frame go through 802.3 path.
To avoid this problem, align the same process as 802.11 type to handle this frame before put it into network stack.
This also addresses a potential security issue in 802.3 RX mode that was previously fixed in commit a8c4d76a8dd4 ("mac80211: do not accept/forward invalid EAPOL frames").
--- net/mac80211/rx.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-)
net/mac80211/rx.c +3 -7
@@ -2602,7 +2602,8 @@ static void ieee80211_deliver_skb_to_loc* address, so that the authenticator (e.g. hostapd) will see * the frame, but bridge won't forward it anywhere else. Note * that due to earlier filtering, the only other address can -* be the PAE group address. +* be the PAE group address, unless the hardware allowed them +* through in 802.3 offloaded mode. */ if (unlikely (skb->protocol == sdata->control_port_protocol && !ether_addr_equal (ehdr->h_dest, sdata->vif.addr)))
@@ -4509,12 +4510,7 @@ static void ieee80211_rx_8023(struct iee/* deliver to local stack */ skb->protocol =eth_type_trans (skb, fast_rx->dev); -memset (skb->cb,0 ,sizeof (skb->cb)); -if (rx->list) -list_add_tail (&skb->list, rx->list); -else -netif_receive_skb (skb); - +ieee80211_deliver_skb_to_local_stack (skb, rx); } static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx,
Greg Kroah-Hartman
maintainerPATCH 63/186 blktrace: fix use after free for struct blk_trace
In reply to Greg Kroah-HartmanFrom: Yu Kuai <[email protected]>
commit 30939293262eb433c960c4532a0d59c4073b2b84 upstream.
When tracing the whole disk, 'dropped' and 'msg' will be created under 'q->debugfs_dir' and 'bt->dir' is NULL, thus blk_trace_free() won't remove those files. What's worse, the following UAF can be triggered because of accessing stale 'dropped' and 'msg':
==================================================================
BUG: KASAN: use-after-free in blk_dropped_read+0x89/0x100
Read of size 4 at addr ffff88816912f3d8 by task blktrace/1188
CPU: 27 PID: 1188 Comm: blktrace Not tainted 5.17.0-rc4-next-20220217+ #469
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS ?-20190727_073836-4
Call Trace:
<TASK>
dump_stack_lvl+0x34/0x44
print_address_description.constprop.0.cold+0xab/0x381
? blk_dropped_read+0x89/0x100
? blk_dropped_read+0x89/0x100
kasan_report.cold+0x83/0xdf
? blk_dropped_read+0x89/0x100
kasan_check_range+0x140/0x1b0
blk_dropped_read+0x89/0x100
? blk_create_buf_file_callback+0x20/0x20
? kmem_cache_free+0xa1/0x500
? do_sys_openat2+0x258/0x460
full_proxy_read+0x8f/0xc0
vfs_read+0xc6/0x260
ksys_read+0xb9/0x150
? vfs_write+0x3d0/0x3d0
? fpregs_assert_state_consistent+0x55/0x60
? exit_to_user_mode_prepare+0x39/0x1e0
do_syscall_64+0x35/0x80
entry_SYSCALL_64_after_hwframe+0x44/0xae
RIP: 0033:0x7fbc080d92fd
Code: ce 20 00 00 75 10 b8 00 00 00 00 0f 05 48 3d 01 f0 ff ff 73 31 c3 48 83 1
RSP: 002b:00007fbb95ff9cb0 EFLAGS: 00000293 ORIG_RAX: 0000000000000000
RAX: ffffffffffffffda RBX: 00007fbb95ff9dc0 RCX: 00007fbc080d92fd
RDX: 0000000000000100 RSI: 00007fbb95ff9cc0 RDI: 0000000000000045
RBP: 0000000000000045 R08: 0000000000406299 R09: 00000000fffffffd
R10: 000000000153afa0 R11: 0000000000000293 R12: 00007fbb780008c0
R13: 00007fbb78000938 R14: 0000000000608b30 R15: 00007fbb780029c8
</TASK>
Allocated by task 1050:
kasan_save_stack+0x1e/0x40
__kasan_kmalloc+0x81/0xa0
do_blk_trace_setup+0xcb/0x410
__blk_trace_setup+0xac/0x130
blk_trace_ioctl+0xe9/0x1c0
blkdev_ioctl+0xf1/0x390
__x64_sys_ioctl+0xa5/0xe0
do_syscall_64+0x35/0x80
entry_SYSCALL_64_after_hwframe+0x44/0xae
Freed by task 1050:
kasan_save_stack+0x1e/0x40
kasan_set_track+0x21/0x30
kasan_set_free_info+0x20/0x30
__kasan_slab_free+0x103/0x180
kfree+0x9a/0x4c0
__blk_trace_remove+0x53/0x70
blk_trace_ioctl+0x199/0x1c0
blkdev_common_ioctl+0x5e9/0xb30
blkdev_ioctl+0x1a5/0x390
__x64_sys_ioctl+0xa5/0xe0
do_syscall_64+0x35/0x80
entry_SYSCALL_64_after_hwframe+0x44/0xae
The buggy address belongs to the object at ffff88816912f380
which belongs to the cache kmalloc-96 of size 96
The buggy address is located 88 bytes inside of
96-byte region [ffff88816912f380, ffff88816912f3e0)
The buggy address belongs to the page:
page:000000009a1b4e7c refcount:1 mapcount:0 mapping:0000000000000000 index:0x0f
flags: 0x17ffffc0000200(slab|node=0|zone=2|lastcpupid=0x1fffff)
raw: 0017ffffc0000200 ffffea00044f1100 dead000000000002 ffff88810004c780
raw: 0000000000000000 0000000000200020 00000001ffffffff 0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff88816912f280: fa fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc
ffff88816912f300: fa fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc
>ffff88816912f380: fa fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc
^
ffff88816912f400: fa fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc
ffff88816912f480: fa fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc
==================================================================--- kernel/trace/blktrace.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-)
kernel/trace/blktrace.c +18 -8
@@ -310,10 +310,20 @@ record_it:local_irq_restore (flags); } -static void blk_trace_free (struct blk_trace *bt) +static void blk_trace_free (struct request_queue *q,struct blk_trace *bt) {relay_close (bt->rchan); -debugfs_remove (bt->dir); + +/* +* If 'bt->dir' is not set, then both 'dropped' and 'msg' are created +* under 'q->debugfs_dir', thus lookup and remove them. +*/ +if (!bt->dir) { +debugfs_remove (debugfs_lookup ("dropped" , q->debugfs_dir)); +debugfs_remove (debugfs_lookup ("msg" , q->debugfs_dir)); + }else { +debugfs_remove (bt->dir); + }free_percpu (bt->sequence);free_percpu (bt->msg_data);kfree (bt);
@@ -335,10 +345,10 @@ static void put_probe_ref(void)mutex_unlock (&blk_probe_mutex); } -static void blk_trace_cleanup (struct blk_trace *bt) +static void blk_trace_cleanup (struct request_queue *q,struct blk_trace *bt) {synchronize_rcu (); -blk_trace_free (bt); +blk_trace_free (q, bt);put_probe_ref (); }
@@ -352,7 +362,7 @@ static int __blk_trace_remove(struct reqreturn -EINVAL ;if (bt->trace_state != Blktrace_running) -blk_trace_cleanup (bt); +blk_trace_cleanup (q, bt);return 0 ; }
@@ -572,7 +582,7 @@ static int do_blk_trace_setup(struct req ret =0 ; err:if (ret) -blk_trace_free (bt); +blk_trace_free (q, bt);return ret; }
@@ -1616,7 +1626,7 @@ static int blk_trace_remove_queue(structput_probe_ref ();synchronize_rcu (); -blk_trace_free (bt); +blk_trace_free (q, bt);return 0 ; }
@@ -1647,7 +1657,7 @@ static int blk_trace_setup_queue(structreturn 0 ; free_bt: -blk_trace_free (bt); +blk_trace_free (q, bt);return ret; }
Greg Kroah-Hartman
maintainerPATCH 64/186 ntb: intel: fix port config status offset for SPR
In reply to Greg Kroah-HartmanFrom: Dave Jiang <[email protected]>
commit d5081bf5dcfb1cb83fb538708b0ac07a10a79cc4 upstream.
The field offset for port configuration status on SPR has been changed to bit 14 from ICX where it resides at bit 12. By chance link status detection continued to work on SPR. This is due to bit 12 being a configuration bit which is in sync with the status bit. Fix this by checking for a SPR device and checking correct status bit.
--- drivers/ntb/hw/intel/ntb_hw_gen4.c | 17 ++++++++++++++++- drivers/ntb/hw/intel/ntb_hw_gen4.h | 16 ++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-)
drivers/ntb/hw/intel/ntb_hw_gen4.c +16 -1
@@ -168,6 +168,18 @@ static enum ntb_topo gen4_ppd_topo(strucreturn NTB_TOPO_NONE ; } +static enum ntb_topo spr_ppd_topo (struct intel_ntb_dev *ndev,u32 ppd) +{ +switch (ppd &SPR_PPD_TOPO_MASK ) { +case SPR_PPD_TOPO_B2B_USD : +return NTB_TOPO_B2B_USD ; +case SPR_PPD_TOPO_B2B_DSD : +return NTB_TOPO_B2B_DSD ; + } + +return NTB_TOPO_NONE ; +} +int gen4_init_dev (struct intel_ntb_dev *ndev) {struct pci_dev *pdev = ndev->ntb.pdev;
@@ -183,7 +195,10 @@ int gen4_init_dev(struct intel_ntb_dev * } ppd1 =ioread32 (ndev->self_mmio +GEN4_PPD1_OFFSET ); - ndev->ntb.topo =gen4_ppd_topo (ndev, ppd1); +if (pdev_is_ICX (pdev)) + ndev->ntb.topo =gen4_ppd_topo (ndev, ppd1); +else if (pdev_is_SPR (pdev)) + ndev->ntb.topo =spr_ppd_topo (ndev, ppd1);dev_dbg (&pdev->dev,"ppd %#x topo %s\n" , ppd1,ntb_topo_string (ndev->ntb.topo));if (ndev->ntb.topo ==NTB_TOPO_NONE )
drivers/ntb/hw/intel/ntb_hw_gen4.h +16 -0
@@ -49,10 +49,14 @@#define GEN4_PPD_CLEAR_TRN 0x0001#define GEN4_PPD_LINKTRN 0x0008#define GEN4_PPD_CONN_MASK 0x0300 +#define SPR_PPD_CONN_MASK 0x0700#define GEN4_PPD_CONN_B2B 0x0200#define GEN4_PPD_DEV_MASK 0x1000#define GEN4_PPD_DEV_DSD 0x1000#define GEN4_PPD_DEV_USD 0x0000 +#define SPR_PPD_DEV_MASK 0x4000 +#define SPR_PPD_DEV_DSD 0x4000 +#define SPR_PPD_DEV_USD 0x0000#define GEN4_LINK_CTRL_LINK_DISABLE 0x0010#define GEN4_SLOTSTS 0xb05a
@@ -62,6 +66,10 @@#define GEN4_PPD_TOPO_B2B_USD (GEN4_PPD_CONN_B2B | GEN4_PPD_DEV_USD)#define GEN4_PPD_TOPO_B2B_DSD (GEN4_PPD_CONN_B2B | GEN4_PPD_DEV_DSD) +#define SPR_PPD_TOPO_MASK (SPR_PPD_CONN_MASK | SPR_PPD_DEV_MASK) +#define SPR_PPD_TOPO_B2B_USD (GEN4_PPD_CONN_B2B | SPR_PPD_DEV_USD) +#define SPR_PPD_TOPO_B2B_DSD (GEN4_PPD_CONN_B2B | SPR_PPD_DEV_DSD) +#define GEN4_DB_COUNT 32#define GEN4_DB_LINK 32#define GEN4_DB_LINK_BIT BIT_ULL(GEN4_DB_LINK)
@@ -111,5 +119,13 @@ static inline int pdev_is_ICX(struct pcireturn 1 ; return 0; } + +static inline int pdev_is_SPR (struct pci_dev *pdev) +{ +if (pdev_is_gen4 (pdev) && + pdev->revision >PCI_DEVICE_REVISION_ICX_MAX ) +return 1 ; +return 0 ; +}#endif
Greg Kroah-Hartman
maintainerPATCH 65/186 mm: Consider __GFP_NOWARN flag for oversized kvmalloc() calls
In reply to Greg Kroah-HartmanFrom: Daniel Borkmann <[email protected]>
commit 0708a0afe291bdfe1386d74d5ec1f0c27e8b9168 upstream.
syzkaller was recently triggering an oversized kvmalloc() warning via xdp_umem_create().
The triggered warning was added back in 7661809d493b ("mm: don't allow oversized kvmalloc() calls"). The rationale for the warning for huge kvmalloc sizes was as a reaction to a security bug where the size was more than UINT_MAX but not everything was prepared to handle unsigned long sizes.
Anyway, the AF_XDP related call trace from this syzkaller report was:
kvmalloc include/linux/mm.h:806 [inline] kvmalloc_array include/linux/mm.h:824 [inline] kvcalloc include/linux/mm.h:829 [inline] xdp_umem_pin_pages net/xdp/xdp_umem.c:102 [inline] xdp_umem_reg net/xdp/xdp_umem.c:219 [inline] xdp_umem_create+0x6a5/0xf00 net/xdp/xdp_umem.c:252 xsk_setsockopt+0x604/0x790 net/xdp/xsk.c:1068 __sys_setsockopt+0x1fd/0x4e0 net/socket.c:2176 __do_sys_setsockopt net/socket.c:2187 [inline] __se_sys_setsockopt net/socket.c:2184 [inline] __x64_sys_setsockopt+0xb5/0x150 net/socket.c:2184 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x44/0xae
Björn mentioned that requests for >2GB allocation can still be valid:
The structure that is being allocated is the page-pinning accounting. AF_XDP has an internal limit of U32_MAX pages, which is *a lot*, but still fewer than what memcg allows (PAGE_COUNTER_MAX is a LONG_MAX/ PAGE_SIZE on 64 bit systems). [...]
I could just change from U32_MAX to INT_MAX, but as I stated earlier that has a hacky feeling to it. [...] From my perspective, the code isn't broken, with the memcg limits in consideration. [...]
Linus says:
[...] Pretty much every time this has come up, the kernel warning has shown that yes, the code was broken and there really wasn't a reason for doing allocations that big.
Of course, some people would be perfectly fine with the allocation failing, they just don't want the warning. I didn't want __GFP_NOWARN to shut it up originally because I wanted people to see all those cases, but these days I think we can just say "yeah, people can shut it up explicitly by saying 'go ahead and fail this allocation, don't warn about it'".
So enough time has passed that by now I'd certainly be ok with [it].
Thus allow call-sites to silence such userspace triggered splats if the allocation requests have __GFP_NOWARN. For xdp_umem_pin_pages()'s call to kvcalloc() this is already the case, so nothing else needed there.
--- mm/util.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
mm/util.c +3 -1
@@ -594,8 +594,10 @@ void *kvmalloc_node(size_t size, gfp_t freturn ret;/* Don't even allow crazy sizes */ -if (WARN_ON_ONCE (size >INT_MAX )) +if (unlikely (size >INT_MAX )) { +WARN_ON_ONCE (!(flags & __GFP_NOWARN));return NULL ; + }return __vmalloc_node (size,1 , flags, node,__builtin_return_address (0 ));
Greg Kroah-Hartman
maintainerPATCH 66/186 xfrm: fix MTU regression
In reply to Greg Kroah-HartmanFrom: Jiri Bohac <[email protected]>
commit 6596a0229541270fb8d38d989f91b78838e5e9da upstream.
Commit 749439bfac6e1a2932c582e2699f91d329658196 ("ipv6: fix udpv6 sendmsg crash caused by too small MTU") breaks PMTU for xfrm.
A Packet Too Big ICMPv6 message received in response to an ESP packet will prevent all further communication through the tunnel if the reported MTU minus the ESP overhead is smaller than 1280.
E.g. in a case of a tunnel-mode ESP with sha256/aes the overhead is 92 bytes. Receiving a PTB with MTU of 1371 or less will result in all further packets in the tunnel dropped. A ping through the tunnel fails with "ping: sendmsg: Invalid argument".
Apparently the MTU on the xfrm route is smaller than 1280 and fails the check inside ip6_setup_cork() added by 749439bf.
We found this by debugging USGv6/ipv6ready failures. Failing tests are: "Phase-2 Interoperability Test Scenario IPsec" / 5.3.11 and 5.4.11 (Tunnel Mode: Fragmentation).
Commit b515d2637276a3810d6595e10ab02c13bfd0b63a ("xfrm:xfrm_state_mtu should return at least 1280 for ipv6") attempted to fix this but caused another regression in TCP MSS calculations and had to be reverted.
The patch below fixes the situation by dropping the MTU check and instead checking for the underflows described in the 749439bf commit message.
--- net/ipv6/ip6_output.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
net/ipv6/ip6_output.c +7 -4
@@ -1408,8 +1408,6 @@ static int ip6_setup_cork(struct sock *sif (np->frag_size) mtu = np->frag_size; } -if (mtu <IPV6_MIN_MTU ) -return -EINVAL ; cork->base.fragsize = mtu; cork->base.gso_size = ipc6->gso_size; cork->base.tx_flags =0 ;
@@ -1471,8 +1469,6 @@ static int __ip6_append_data(struct sock fragheaderlen =sizeof (struct ipv6hdr ) + rt->rt6i_nfheader_len + (opt ? opt->opt_nflen :0 ); - maxfraglen = ((mtu - fragheaderlen) & ~7 ) + fragheaderlen - -sizeof (struct frag_hdr ); headersize =sizeof (struct ipv6hdr ) + (opt ? opt->opt_flen + opt->opt_nflen : 0) +
@@ -1480,6 +1476,13 @@ static int __ip6_append_data(struct sock sizeof(struct frag_hdr) : 0) + rt->rt6i_nfheader_len; +if (mtu < fragheaderlen || + ((mtu - fragheaderlen) & ~7 ) + fragheaderlen <sizeof (struct frag_hdr )) + goto emsgsize; + + maxfraglen = ((mtu - fragheaderlen) & ~7 ) + fragheaderlen - +sizeof (struct frag_hdr ); +/* as per RFC 7112 section 5, the entire IPv6 Header Chain must fit * the first fragment */
Greg Kroah-Hartman
maintainerPATCH 67/186 netfilter: fix use-after-free in __nf_register_net_hook()
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
commit 56763f12b0f02706576a088e85ef856deacc98a0 upstream.
We must not dereference @new_hooks after nf_hook_mutex has been released, because other threads might have freed our allocated hooks already.
BUG: KASAN: use-after-free in nf_hook_entries_get_hook_ops include/linux/netfilter.h:130 [inline]
BUG: KASAN: use-after-free in hooks_validate net/netfilter/core.c:171 [inline]
BUG: KASAN: use-after-free in __nf_register_net_hook+0x77a/0x820 net/netfilter/core.c:438
Read of size 2 at addr ffff88801c1a8000 by task syz-executor237/4430
CPU: 1 PID: 4430 Comm: syz-executor237 Not tainted 5.17.0-rc5-syzkaller-00306-g2293be58d6a1 #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
Call Trace:
<TASK>
__dump_stack lib/dump_stack.c:88 [inline]
dump_stack_lvl+0xcd/0x134 lib/dump_stack.c:106
print_address_description.constprop.0.cold+0x8d/0x336 mm/kasan/report.c:255
__kasan_report mm/kasan/report.c:442 [inline]
kasan_report.cold+0x83/0xdf mm/kasan/report.c:459
nf_hook_entries_get_hook_ops include/linux/netfilter.h:130 [inline]
hooks_validate net/netfilter/core.c:171 [inline]
__nf_register_net_hook+0x77a/0x820 net/netfilter/core.c:438
nf_register_net_hook+0x114/0x170 net/netfilter/core.c:571
nf_register_net_hooks+0x59/0xc0 net/netfilter/core.c:587
nf_synproxy_ipv6_init+0x85/0xe0 net/netfilter/nf_synproxy_core.c:1218
synproxy_tg6_check+0x30d/0x560 net/ipv6/netfilter/ip6t_SYNPROXY.c:81
xt_check_target+0x26c/0x9e0 net/netfilter/x_tables.c:1038
check_target net/ipv6/netfilter/ip6_tables.c:530 [inline]
find_check_entry.constprop.0+0x7f1/0x9e0 net/ipv6/netfilter/ip6_tables.c:573
translate_table+0xc8b/0x1750 net/ipv6/netfilter/ip6_tables.c:735
do_replace net/ipv6/netfilter/ip6_tables.c:1153 [inline]
do_ip6t_set_ctl+0x56e/0xb90 net/ipv6/netfilter/ip6_tables.c:1639
nf_setsockopt+0x83/0xe0 net/netfilter/nf_sockopt.c:101
ipv6_setsockopt+0x122/0x180 net/ipv6/ipv6_sockglue.c:1024
rawv6_setsockopt+0xd3/0x6a0 net/ipv6/raw.c:1084
__sys_setsockopt+0x2db/0x610 net/socket.c:2180
__do_sys_setsockopt net/socket.c:2191 [inline]
__se_sys_setsockopt net/socket.c:2188 [inline]
__x64_sys_setsockopt+0xba/0x150 net/socket.c:2188
do_syscall_x64 arch/x86/entry/common.c:50 [inline]
do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80
entry_SYSCALL_64_after_hwframe+0x44/0xae
RIP: 0033:0x7f65a1ace7d9
Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 71 15 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007f65a1a7f308 EFLAGS: 00000246 ORIG_RAX: 0000000000000036
RAX: ffffffffffffffda RBX: 0000000000000006 RCX: 00007f65a1ace7d9
RDX: 0000000000000040 RSI: 0000000000000029 RDI: 0000000000000003
RBP: 00007f65a1b574c8 R08: 0000000000000001 R09: 0000000000000000
R10: 0000000020000000 R11: 0000000000000246 R12: 00007f65a1b55130
R13: 00007f65a1b574c0 R14: 00007f65a1b24090 R15: 0000000000022000
</TASK>
The buggy address belongs to the page:
page:ffffea0000706a00 refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x1c1a8
flags: 0xfff00000000000(node=0|zone=1|lastcpupid=0x7ff)
raw: 00fff00000000000 ffffea0001c1b108 ffffea000046dd08 0000000000000000
raw: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000
page dumped because: kasan: bad access detected
page_owner tracks the page as freed
page last allocated via order 2, migratetype Unmovable, gfp_mask 0x52dc0(GFP_KERNEL|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP|__GFP_ZERO), pid 4430, ts 1061781545818, free_ts 1061791488993
prep_new_page mm/page_alloc.c:2434 [inline]
get_page_from_freelist+0xa72/0x2f50 mm/page_alloc.c:4165
__alloc_pages+0x1b2/0x500 mm/page_alloc.c:5389
__alloc_pages_node include/linux/gfp.h:572 [inline]
alloc_pages_node include/linux/gfp.h:595 [inline]
kmalloc_large_node+0x62/0x130 mm/slub.c:4438
__kmalloc_node+0x35a/0x4a0 mm/slub.c:4454
kmalloc_node include/linux/slab.h:604 [inline]
kvmalloc_node+0x97/0x100 mm/util.c:580
kvmalloc include/linux/slab.h:731 [inline]
kvzalloc include/linux/slab.h:739 [inline]
allocate_hook_entries_size net/netfilter/core.c:61 [inline]
nf_hook_entries_grow+0x140/0x780 net/netfilter/core.c:128
__nf_register_net_hook+0x144/0x820 net/netfilter/core.c:429
nf_register_net_hook+0x114/0x170 net/netfilter/core.c:571
nf_register_net_hooks+0x59/0xc0 net/netfilter/core.c:587
nf_synproxy_ipv6_init+0x85/0xe0 net/netfilter/nf_synproxy_core.c:1218
synproxy_tg6_check+0x30d/0x560 net/ipv6/netfilter/ip6t_SYNPROXY.c:81
xt_check_target+0x26c/0x9e0 net/netfilter/x_tables.c:1038
check_target net/ipv6/netfilter/ip6_tables.c:530 [inline]
find_check_entry.constprop.0+0x7f1/0x9e0 net/ipv6/netfilter/ip6_tables.c:573
translate_table+0xc8b/0x1750 net/ipv6/netfilter/ip6_tables.c:735
do_replace net/ipv6/netfilter/ip6_tables.c:1153 [inline]
do_ip6t_set_ctl+0x56e/0xb90 net/ipv6/netfilter/ip6_tables.c:1639
nf_setsockopt+0x83/0xe0 net/netfilter/nf_sockopt.c:101
page last free stack trace:
reset_page_owner include/linux/page_owner.h:24 [inline]
free_pages_prepare mm/page_alloc.c:1352 [inline]
free_pcp_prepare+0x374/0x870 mm/page_alloc.c:1404
free_unref_page_prepare mm/page_alloc.c:3325 [inline]
free_unref_page+0x19/0x690 mm/page_alloc.c:3404
kvfree+0x42/0x50 mm/util.c:613
rcu_do_batch kernel/rcu/tree.c:2527 [inline]
rcu_core+0x7b1/0x1820 kernel/rcu/tree.c:2778
__do_softirq+0x29b/0x9c2 kernel/softirq.c:558
Memory state around the buggy address:
ffff88801c1a7f00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ffff88801c1a7f80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
>ffff88801c1a8000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
^
ffff88801c1a8080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ffff88801c1a8100: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff--- net/netfilter/core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
net/netfilter/core.c +3 -2
@@ -428,14 +428,15 @@ static int __nf_register_net_hook(struct p =nf_entry_dereference (*pp); new_hooks =nf_hook_entries_grow (p, reg); -if (!IS_ERR (new_hooks)) +if (!IS_ERR (new_hooks)) { +hooks_validate (new_hooks);rcu_assign_pointer (*pp, new_hooks); + }mutex_unlock (&nf_hook_mutex);if (IS_ERR (new_hooks))return PTR_ERR (new_hooks); -hooks_validate (new_hooks);#ifdef CONFIG_NETFILTER_INGRESS if (nf_ingress_hook (reg, pf))net_inc_ingress_queue ();
Greg Kroah-Hartman
maintainerPATCH 68/186 bpf, sockmap: Do not ignore orig_len parameter
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
commit 60ce37b03917e593d8e5d8bcc7ec820773daf81d upstream.
Currently, sk_psock_verdict_recv() returns skb->len
This is problematic because tcp_read_sock() might have passed orig_len < skb->len, due to the presence of TCP urgent data.
This causes an infinite loop from tcp_read_sock()
Followup patch will make tcp_read_sock() more robust vs bad actors.
--- net/core/skmsg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/core/skmsg.c +1 -1
@@ -1153,7 +1153,7 @@ static int sk_psock_verdict_recv(read_destruct sk_psock *psock;struct bpf_prog *prog;int ret = __SK_DROP; -int len = skb->len; +int len = orig_len;/* clone here so sk_eat_skb() in tcp_read_sock does not drop our data */ skb =skb_clone (skb,GFP_ATOMIC );
Greg Kroah-Hartman
maintainerPATCH 69/186 xfrm: fix the if_id check in changelink
In reply to Greg Kroah-HartmanFrom: Antony Antony <[email protected]>
commit 6d0d95a1c2b07270870e7be16575c513c29af3f1 upstream.
if_id will be always 0, because it was not yet initialized.
--- net/xfrm/xfrm_interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/xfrm/xfrm_interface.c +1 -1
@@ -673,12 +673,12 @@ static int xfrmi_changelink(struct net_dstruct net *net = xi->net;struct xfrm_if_parms p = {}; +xfrmi_netlink_parms (data, &p);if (!p.if_id) {NL_SET_ERR_MSG (extack,"if_id must be non zero" );return -EINVAL ; } -xfrmi_netlink_parms (data, &p); xi =xfrmi_locate (net, &p);if (!xi) { xi =netdev_priv (dev);
Greg Kroah-Hartman
maintainerPATCH 70/186 xfrm: enforce validity of offload input flags
In reply to Greg Kroah-HartmanFrom: Leon Romanovsky <[email protected]>
commit 7c76ecd9c99b6e9a771d813ab1aa7fa428b3ade1 upstream.
struct xfrm_user_offload has flags variable that received user input, but kernel didn't check if valid bits were provided. It caused a situation where not sanitized input was forwarded directly to the drivers.
For example, XFRM_OFFLOAD_IPV6 define that was exposed, was used by strongswan, but not implemented in the kernel at all.
As a solution, check and sanitize input flags to forward XFRM_OFFLOAD_INBOUND to the drivers.
--- include/uapi/linux/xfrm.h | 6 ++++++ net/xfrm/xfrm_device.c | 6 +++++- 2 files changed, 11 insertions(+), 1 deletion(-)
include/uapi/linux/xfrm.h +6 -0
@@ -511,6 +511,12 @@ struct xfrm_user_offload {int ifindex;__u8 flags; }; +/* This flag was exposed without any kernel code that supporting it. +* Unfortunately, strongswan has the code that uses sets this flag, +* which makes impossible to reuse this bit. +* +* So leave it here to make sure that it won't be reused by mistake. +*/ #define XFRM_OFFLOAD_IPV6 1#define XFRM_OFFLOAD_INBOUND 2
net/xfrm/xfrm_device.c +5 -1
@@ -223,6 +223,9 @@ int xfrm_dev_state_add(struct net *net,if (x->encap || x->tfcpad)return -EINVAL ; +if (xuo->flags & ~(XFRM_OFFLOAD_IPV6 |XFRM_OFFLOAD_INBOUND )) +return -EINVAL ; + dev =dev_get_by_index (net, xuo->ifindex);if (!dev) {if (!(xuo->flags &XFRM_OFFLOAD_INBOUND )) {
@@ -261,7 +264,8 @@ int xfrm_dev_state_add(struct net *net, xso->dev = dev; xso->real_dev = dev; xso->num_exthdrs =1 ; - xso->flags = xuo->flags; +/* Don't forward bit that is not implemented */ + xso->flags = xuo->flags & ~XFRM_OFFLOAD_IPV6 ; err = dev->xfrmdev_ops->xdo_dev_state_add (x);if (err) {
Greg Kroah-Hartman
maintainerPATCH 71/186 e1000e: Correct NVM checksum verification flow
In reply to Greg Kroah-HartmanFrom: Sasha Neftin <[email protected]>
commit ffd24fa2fcc76ecb2e61e7a4ef8588177bcb42a6 upstream.
Update MAC type check e1000_pch_tgp because for e1000_pch_cnp, NVM checksum update is still possible.
Emit a more detailed warning message.
Bugzilla: https://bugzilla.opensuse.org/show_bug.cgi?id=1191663
--- drivers/net/ethernet/intel/e1000e/ich8lan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/intel/e1000e/ich8lan.c +2 -2
@@ -4136,9 +4136,9 @@ static s32 e1000_validate_nvm_checksum_ireturn ret_val;if (!(data & valid_csum_mask)) { -e_dbg ("NVM Checksum Invalid\n" ); +e_dbg ("NVM Checksum valid bit not set\n" ); -if (hw->mac.type < e1000_pch_cnp) { +if (hw->mac.type < e1000_pch_tgp) { data |= valid_csum_mask; ret_val =e1000_write_nvm (hw, word,1 , &data);if (ret_val)
Greg Kroah-Hartman
maintainerPATCH 72/186 net: fix up skbs delta_truesize in UDP GRO frag_list
In reply to Greg Kroah-HartmanFrom: lena wang <[email protected]>
commit 224102de2ff105a2c05695e66a08f4b5b6b2d19c upstream.
The truesize for a UDP GRO packet is added by main skb and skbs in main skb's frag_list:skb_gro_receive_list
p->truesize += skb->truesize;
The commit 53475c5dd856 ("net: fix use-after-free when UDP GRO with shared fraglist") introduced a truesize increase for frag_list skbs. When uncloning skb, it will call pskb_expand_head and trusesize for frag_list skbs may increase. This can occur when allocators uses __netdev_alloc_skb and not jump into __alloc_skb. This flow does not use ksize(len) to calculate truesize while pskb_expand_head uses. skb_segment_list
err = skb_unclone(nskb, GFP_ATOMIC);pskb_expand_head
if (!skb->sk || skb->destructor == sock_edemux)
skb->truesize += size - osize;If we uses increased truesize adding as delta_truesize, it will be larger than before and even larger than previous total truesize value if skbs in frag_list are abundant. The main skb truesize will become smaller and even a minus value or a huge value for an unsigned int parameter. Then the following memory check will drop this abnormal skb.
To avoid this error we should use the original truesize to segment the main skb.
--- net/core/skbuff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/core/skbuff.c +1 -1
@@ -3854,6 +3854,7 @@ struct sk_buff *skb_segment_list(struct list_skb = list_skb->next; err =0 ; + delta_truesize += nskb->truesize;if (skb_shared (nskb)) { tmp =skb_clone (nskb,GFP_ATOMIC );if (tmp) {
@@ -3878,7 +3879,6 @@ struct sk_buff *skb_segment_list(struct tail = nskb; delta_len += nskb->len; - delta_truesize += nskb->truesize;skb_push (nskb, -skb_network_offset (nskb) + offset);
Greg Kroah-Hartman
maintainerPATCH 73/186 netfilter: nf_queue: dont assume sk is full socket
In reply to Greg Kroah-HartmanFrom: Florian Westphal <[email protected]>
commit 747670fd9a2d1b7774030dba65ca022ba442ce71 upstream.
There is no guarantee that state->sk refers to a full socket.
If refcount transitions to 0, sock_put calls sk_free which then ends up with garbage fields.
I'd like to thank Oleksandr Natalenko and Jiri Benc for considerable debug work and pointing out state->sk oddities.
--- net/netfilter/nf_queue.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
net/netfilter/nf_queue.c +10 -1
@@ -46,6 +46,15 @@ void nf_unregister_queue_handler(void) }EXPORT_SYMBOL (nf_unregister_queue_handler); +static void nf_queue_sock_put (struct sock *sk) +{ +#ifdef CONFIG_INET +sock_gen_put (sk); +#else +sock_put (sk); +#endif +} +static void nf_queue_entry_release_refs (struct nf_queue_entry *entry) {struct nf_hook_state *state = &entry->state;
@@ -54,7 +63,7 @@ static void nf_queue_entry_release_refs(dev_put (state->in);dev_put (state->out);if (state->sk) -sock_put (state->sk); +nf_queue_sock_put (state->sk);#if IS_ENABLED (CONFIG_BRIDGE_NETFILTER )dev_put (entry->physin);
Greg Kroah-Hartman
maintainerPATCH 74/186 netfilter: nf_queue: fix possible use-after-free
In reply to Greg Kroah-HartmanFrom: Florian Westphal <[email protected]>
commit c3873070247d9e3c7a6b0cf9bf9b45e8018427b1 upstream.
Eric Dumazet says:
The sock_hold() side seems suspect, because there is no guarantee that sk_refcnt is not already 0.
On failure, we cannot queue the packet and need to indicate an error. The packet will be dropped by the caller.
v2: split skb prefetch hunk into separate change
--- include/net/netfilter/nf_queue.h | 2 +- net/netfilter/nf_queue.c | 13 +++++++++---- net/netfilter/nfnetlink_queue.c | 12 +++++++++--- 3 files changed, 19 insertions(+), 8 deletions(-)
include/net/netfilter/nf_queue.h +1 -1
@@ -37,7 +37,7 @@ void nf_register_queue_handler(const strvoid nf_unregister_queue_handler (void );void nf_reinject (struct nf_queue_entry *entry,unsigned int verdict); -void nf_queue_entry_get_refs (struct nf_queue_entry *entry); +bool nf_queue_entry_get_refs (struct nf_queue_entry *entry);void nf_queue_entry_free (struct nf_queue_entry *entry);static inline void init_hashrandom (u32 *jhash_initval)
net/netfilter/nf_queue.c +9 -4
@@ -96,19 +96,21 @@ static void __nf_queue_entry_init_physde }/* Bump dev refs so they don't vanish while packet is out */ -void nf_queue_entry_get_refs (struct nf_queue_entry *entry) +bool nf_queue_entry_get_refs (struct nf_queue_entry *entry) {struct nf_hook_state *state = &entry->state; +if (state->sk && !refcount_inc_not_zero (&state->sk->sk_refcnt)) +return false; +dev_hold (state->in);dev_hold (state->out); -if (state->sk) -sock_hold (state->sk);#if IS_ENABLED (CONFIG_BRIDGE_NETFILTER )dev_hold (entry->physin);dev_hold (entry->physout);#endif +return true; }EXPORT_SYMBOL_GPL (nf_queue_entry_get_refs);
@@ -196,7 +198,10 @@ static int __nf_queue(struct sk_buff *sk__nf_queue_entry_init_physdevs (entry); -nf_queue_entry_get_refs (entry); +if (!nf_queue_entry_get_refs (entry)) { +kfree (entry); +return -ENOTCONN ; + }switch (entry->state.pf) {case AF_INET :
net/netfilter/nfnetlink_queue.c +9 -3
@@ -710,9 +710,15 @@ static struct nf_queue_entry * nf_queue_entry_dup(struct nf_queue_entry *e) {struct nf_queue_entry *entry =kmemdup (e, e->size,GFP_ATOMIC ); -if (entry) -nf_queue_entry_get_refs (entry); -return entry; + +if (!entry) +return NULL ; + +if (nf_queue_entry_get_refs (entry)) +return entry; + +kfree (entry); +return NULL ; }#if IS_ENABLED (CONFIG_BRIDGE_NETFILTER )
Greg Kroah-Hartman
maintainerPATCH 75/186 netfilter: nf_queue: handle socket prefetch
In reply to Greg Kroah-HartmanFrom: Florian Westphal <[email protected]>
commit 3b836da4081fa585cf6c392f62557496f2cb0efe upstream.
In case someone combines bpf socket assign and nf_queue, then we will queue an skb who references a struct sock that did not have its reference count incremented.
As we leave rcu protection, there is no guarantee that skb->sk is still valid.
For refcount-less skb->sk case, try to increment the reference count and then override the destructor.
In case of failure we have two choices: orphan the skb and 'delete' preselect or let nf_queue() drop the packet.
Do the latter, it should not happen during normal operation.
--- net/netfilter/nf_queue.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
net/netfilter/nf_queue.c +12 -0
@@ -180,6 +180,18 @@ static int __nf_queue(struct sk_buff *skbreak ; } +if (skb_sk_is_prefetched (skb)) { +struct sock *sk = skb->sk; + +if (!sk_is_refcounted (sk)) { +if (!refcount_inc_not_zero (&sk->sk_refcnt)) +return -ENOTCONN ; + +/* drop refcount on skb_orphan */ + skb->destructor = sock_edemux; + } + } + entry =kmalloc (sizeof (*entry) + route_key_size,GFP_ATOMIC );if (!entry)return -ENOMEM ;
Greg Kroah-Hartman
maintainerPATCH 76/186 batman-adv: Request iflink once in batadv-on-batadv check
In reply to Greg Kroah-HartmanFrom: Sven Eckelmann <[email protected]>
commit 690bb6fb64f5dc7437317153902573ecad67593d upstream.
There is no need to call dev_get_iflink multiple times for the same net_device in batadv_is_on_batman_iface. And since some of the .ndo_get_iflink callbacks are dynamic (for example via RCUs like in vxcan_get_iflink), it could easily happen that the returned values are not stable. The pre-checks before __dev_get_by_index are then of course bogus.
--- net/batman-adv/hard-interface.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
net/batman-adv/hard-interface.c +5 -4
@@ -149,22 +149,23 @@ static bool batadv_is_on_batman_iface(costruct net *net =dev_net (net_dev);struct net_device *parent_dev;struct net *parent_net; +int iflink;bool ret;/* check if this is a batman-adv mesh interface */ if (batadv_softif_is_valid (net_dev))return true; + iflink =dev_get_iflink (net_dev); +/* no more parents..stop recursion */ -if (dev_get_iflink (net_dev) ==0 || -dev_get_iflink (net_dev) == net_dev->ifindex) +if (iflink ==0 || iflink == net_dev->ifindex)return false; parent_net =batadv_getlink_net (net_dev, net);/* recurse over the parent device */ - parent_dev =__dev_get_by_index ((struct net *)parent_net, -dev_get_iflink (net_dev)); + parent_dev =__dev_get_by_index ((struct net *)parent_net, iflink);/* if we got a NULL parent_dev there is something broken.. */ if (!parent_dev) {pr_err ("Cannot find parent device\n" );
Greg Kroah-Hartman
maintainerPATCH 77/186 batman-adv: Request iflink once in batadv_get_real_netdevice
In reply to Greg Kroah-HartmanFrom: Sven Eckelmann <[email protected]>
commit 6116ba09423f7d140f0460be6a1644dceaad00da upstream.
There is no need to call dev_get_iflink multiple times for the same net_device in batadv_get_real_netdevice. And since some of the ndo_get_iflink callbacks are dynamic (for example via RCUs like in vxcan_get_iflink), it could easily happen that the returned values are not stable. The pre-checks before __dev_get_by_index are then of course bogus.
--- net/batman-adv/hard-interface.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
net/batman-adv/hard-interface.c +5 -4
@@ -215,14 +215,16 @@ static struct net_device *batadv_get_reastruct net_device *real_netdev =NULL ;struct net *real_net;struct net *net; -int ifindex; +int iflink;ASSERT_RTNL ();if (!netdev)return NULL ; -if (netdev->ifindex ==dev_get_iflink (netdev)) { + iflink =dev_get_iflink (netdev); + +if (netdev->ifindex == iflink) {dev_hold (netdev);return netdev; }
@@ -232,9 +234,8 @@ static struct net_device *batadv_get_rea goto out; net =dev_net (hard_iface->soft_iface); - ifindex =dev_get_iflink (netdev); real_net =batadv_getlink_net (netdev, net); - real_netdev =dev_get_by_index (real_net, ifindex); + real_netdev =dev_get_by_index (real_net, iflink); out:batadv_hardif_put (hard_iface);
Greg Kroah-Hartman
maintainerPATCH 78/186 batman-adv: Dont expect inter-netns unique iflink indices
In reply to Greg Kroah-HartmanFrom: Sven Eckelmann <[email protected]>
commit 6c1f41afc1dbe59d9d3c8bb0d80b749c119aa334 upstream.
The ifindex doesn't have to be unique for multiple network namespaces on the same machine.
$ ip netns add test1 $ ip -net test1 link add dummy1 type dummy $ ip netns add test2 $ ip -net test2 link add dummy2 type dummy
$ ip -net test1 link show dev dummy1
6: dummy1: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 96:81:55:1e:dd:85 brd ff:ff:ff:ff:ff:ff
$ ip -net test2 link show dev dummy2
6: dummy2: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 5a:3c:af:35:07:c3 brd ff:ff:ff:ff:ff:ffBut the batman-adv code to walk through the various layers of virtual interfaces uses this assumption because dev_get_iflink handles it internally and doesn't return the actual netns of the iflink. And dev_get_iflink only documents the situation where ifindex == iflink for physical devices.
But only checking for dev->netdev_ops->ndo_get_iflink is also not an option because ipoib_get_iflink implements it even when it sometimes returns an iflink != ifindex and sometimes iflink == ifindex. The caller must therefore make sure itself to check both netns and iflink + ifindex for equality. Only when they are equal, a "physical" interface was detected which should stop the traversal. On the other hand, vxcan_get_iflink can also return 0 in case there was currently no valid peer. In this case, it is still necessary to stop.
--- net/batman-adv/hard-interface.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-)
net/batman-adv/hard-interface.c +14 -5
@@ -157,13 +157,15 @@ static bool batadv_is_on_batman_iface(coreturn true; iflink =dev_get_iflink (net_dev); - -/* no more parents..stop recursion */ -if (iflink ==0 || iflink == net_dev->ifindex) +if (iflink ==0 )return false; parent_net =batadv_getlink_net (net_dev, net); +/* iflink to itself, most likely physical device */ +if (net == parent_net && iflink == net_dev->ifindex) +return false; +/* recurse over the parent device */ parent_dev =__dev_get_by_index ((struct net *)parent_net, iflink);/* if we got a NULL parent_dev there is something broken.. */
@@ -223,8 +225,7 @@ static struct net_device *batadv_get_reareturn NULL ; iflink =dev_get_iflink (netdev); - -if (netdev->ifindex == iflink) { +if (iflink ==0 ) {dev_hold (netdev);return netdev; }
@@ -235,6 +236,14 @@ static struct net_device *batadv_get_rea net =dev_net (hard_iface->soft_iface); real_net =batadv_getlink_net (netdev, net); + +/* iflink to itself, most likely physical device */ +if (net == real_net && netdev->ifindex == iflink) { + real_netdev = netdev; +dev_hold (real_netdev); + goto out; + } + real_netdev =dev_get_by_index (real_net, iflink); out:
Greg Kroah-Hartman
maintainerPATCH 79/186 net: ipv6: ensure we call ipv6_mc_down() at most once
In reply to Greg Kroah-HartmanFrom: [email protected] <[email protected]>
commit 9995b408f17ff8c7f11bc725c8aa225ba3a63b1c upstream.
There are two reasons for addrconf_notify() to be called with NETDEV_DOWN:
either the network device is actually going down, or IPv6 was disabled on the interface.
If either of them stays down while the other is toggled, we repeatedly call the code for NETDEV_DOWN, including ipv6_mc_down(), while never calling the corresponding ipv6_mc_up() in between. This will cause a new entry in idev->mc_tomb to be allocated for each multicast group the interface is subscribed to, which in turn leaks one struct ifmcaddr6 per nontrivial multicast group the interface is subscribed to.
The following reproducer will leak at least $n objects:
ip addr add ff2e::4242/32 dev eth0 autojoin sysctl -w net.ipv6.conf.eth0.disable_ipv6=1 for i in $(seq 1 $n); do
ip link set up eth0; ip link set down eth0
done
Joining groups with IPV6_ADD_MEMBERSHIP (unprivileged) or setting the sysctl net.ipv6.conf.eth0.forwarding to 1 (=> subscribing to ff02::2) can also be used to create a nontrivial idev->mc_list, which will the leak objects with the right up-down-sequence.
Based on both sources for NETDEV_DOWN events the interface IPv6 state should be considered:
- not ready if the network interface is not ready OR IPv6 is disabled for it
- ready if the network interface is ready AND IPv6 is enabled for it
The functions ipv6_mc_up() and ipv6_down() should only be run when this state changes.
Implement this by remembering when the IPv6 state is ready, and only run ipv6_mc_down() if it actually changed from ready to not ready.
The other direction (not ready -> ready) already works correctly, as:
- the interface notification triggered codepath for NETDEV_UP / NETDEV_CHANGE returns early if ipv6 is disabled, and
- the disable_ipv6=0 triggered codepath skips fully initializing the interface as long as addrconf_link_ready(dev) returns false
- calling ipv6_mc_up() repeatedly does not leak anything
--- net/ipv6/addrconf.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
net/ipv6/addrconf.c +6 -2
@@ -3732,6 +3732,7 @@ static int addrconf_ifdown(struct net_destruct inet6_dev *idev;struct inet6_ifaddr *ifa, *tmp;bool keep_addr = false; +bool was_ready;int state, i;ASSERT_RTNL ();
@@ -3797,7 +3798,10 @@ restart:addrconf_del_rs_timer (idev); -/* Step 2: clear flags for stateless addrconf */ +/* Step 2: clear flags for stateless addrconf, repeated down +* detection +*/ + was_ready = idev->if_flags &IF_READY ;if (!unregister) idev->if_flags &= ~(IF_RS_SENT |IF_RA_RCVD |IF_READY );
@@ -3871,7 +3875,7 @@ restart:if (unregister) {ipv6_ac_destroy_dev (idev);ipv6_mc_destroy_dev (idev); - }else { + }else if (was_ready) {ipv6_mc_down (idev); }
Greg Kroah-Hartman
maintainerPATCH 80/186 net: dcb: flush lingering app table entries for unregistered devices
In reply to Greg Kroah-HartmanFrom: Vladimir Oltean <[email protected]>
commit 91b0383fef06f20b847fa9e4f0e3054ead0b1a1b upstream.
If I'm not mistaken (and I don't think I am), the way in which the dcbnl_ops work is that drivers call dcb_ieee_setapp() and this populates the application table with dynamically allocated struct dcb_app_type entries that are kept in the module-global dcb_app_list.
However, nobody keeps exact track of these entries, and although dcb_ieee_delapp() is supposed to remove them, nobody does so when the interface goes away (example: driver unbinds from device). So the dcb_app_list will contain lingering entries with an ifindex that no longer matches any device in dcb_app_lookup().
Reclaim the lost memory by listening for the NETDEV_UNREGISTER event and flushing the app table entries of interfaces that are now gone.
In fact something like this used to be done as part of the initial commit (blamed below), but it was done in dcbnl_exit() -> dcb_flushapp(), essentially at module_exit time. That became dead code after commit 7a6b6f515f77 ("DCB: fix kconfig option") which essentially merged "tristate config DCB" and "bool config DCBNL" into a single "bool config DCB", so net/dcb/dcbnl.c could not be built as a module anymore.
Commit 36b9ad8084bd ("net/dcb: make dcbnl.c explicitly non-modular") recognized this and deleted dcbnl_exit() and dcb_flushapp() altogether, leaving us with the version we have today.
Since flushing application table entries can and should be done as soon as the netdevice disappears, fundamentally the commit that is to blame is the one that introduced the design of this API.
--- net/dcb/dcbnl.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+)
net/dcb/dcbnl.c +44 -0
@@ -2073,8 +2073,52 @@ u8 dcb_ieee_getapp_default_prio_mask(con }EXPORT_SYMBOL (dcb_ieee_getapp_default_prio_mask); +static void dcbnl_flush_dev (struct net_device *dev) +{ +struct dcb_app_type *itr, *tmp; + +spin_lock (&dcb_lock); + +list_for_each_entry_safe (itr, tmp, &dcb_app_list, list) { +if (itr->ifindex == dev->ifindex) { +list_del (&itr->list); +kfree (itr); + } + } + +spin_unlock (&dcb_lock); +} + +static int dcbnl_netdevice_event (struct notifier_block *nb, +unsigned long event,void *ptr) +{ +struct net_device *dev =netdev_notifier_info_to_dev (ptr); + +switch (event) { +case NETDEV_UNREGISTER : +if (!dev->dcbnl_ops) +return NOTIFY_DONE ; + +dcbnl_flush_dev (dev); + +return NOTIFY_OK ; +default : +return NOTIFY_DONE ; + } +} + +static struct notifier_block dcbnl_nb__read_mostly = { + .notifier_call = dcbnl_netdevice_event, +}; +static int __init dcbnl_init (void ) { +int err; + + err =register_netdevice_notifier (&dcbnl_nb); +if (err) +return err; +rtnl_register (PF_UNSPEC ,RTM_GETDCB , dcb_doit,NULL ,0 );rtnl_register (PF_UNSPEC ,RTM_SETDCB , dcb_doit,NULL ,0 );
Greg Kroah-Hartman
maintainerPATCH 81/186 net: ipa: fix a build dependency
In reply to Greg Kroah-HartmanFrom: Alex Elder <[email protected]>
commit caef14b7530c065fb85d54492768fa48fdb5093e upstream.
An IPA build problem arose in the linux-next tree the other day. The problem is that a recent commit adds a new dependency on some code, and the Kconfig file for IPA doesn't reflect that dependency. As a result, some configurations can fail to build (particularly when COMPILE_TEST is enabled).
The recent patch adds calls to qmp_get(), qmp_put(), and qmp_send(), and those are built based on the QCOM_AOSS_QMP config option. If that symbol is not defined, stubs are defined, so we just need to ensure QCOM_AOSS_QMP is compatible with QCOM_IPA, or it's not defined.
--- drivers/net/ipa/Kconfig | 1 + 1 file changed, 1 insertion(+)
drivers/net/ipa/Kconfig +1 -0
@@ -3,6 +3,7 @@ config QCOM_IPA depends on NET && QCOM_SMEM depends on ARCH_QCOM || COMPILE_TEST depends on QCOM_RPROC_COMMON || (QCOM_RPROC_COMMON=n && COMPILE_TEST) + depends on QCOM_AOSS_QMP || QCOM_AOSS_QMP=n select QCOM_MDT_LOADER if ARCH_QCOM select QCOM_SCM select QCOM_QMI_HELPERS
Greg Kroah-Hartman
maintainerPATCH 82/186 net: ipa: add an interconnect dependency
In reply to Greg Kroah-HartmanFrom: Alex Elder <[email protected]>
commit 1dba41c9d2e2dc94b543394974f63d55aa195bfe upstream.
In order to function, the IPA driver very clearly requires the interconnect framework to be enabled in the kernel configuration. State that dependency in the Kconfig file.
This became a problem when CONFIG_COMPILE_TEST support was added. Non-Qualcomm platforms won't necessarily enable CONFIG_INTERCONNECT.
--- drivers/net/ipa/Kconfig | 1 + 1 file changed, 1 insertion(+)
drivers/net/ipa/Kconfig +1 -0
@@ -2,6 +2,7 @@ config QCOM_IPA tristate "Qualcomm IPA support" depends on NET && QCOM_SMEM depends on ARCH_QCOM || COMPILE_TEST + depends on INTERCONNECT depends on QCOM_RPROC_COMMON || (QCOM_RPROC_COMMON=n && COMPILE_TEST) depends on QCOM_AOSS_QMP || QCOM_AOSS_QMP=n select QCOM_MDT_LOADER if ARCH_QCOM
Greg Kroah-Hartman
maintainerPATCH 83/186 net/smc: fix connection leak
In reply to Greg Kroah-HartmanFrom: D. Wythe <[email protected]>
commit 9f1c50cf39167ff71dc5953a3234f3f6eeb8fcb5 upstream.
There's a potential leak issue under following execution sequence :
smc_release smc_connect_work
if (sk->sk_state == SMC_INIT)
send_clc_confirim tcp_abort(); ... sk.sk_state = SMC_ACTIVE
smc_close_activeswitch(sk->sk_state) {
...
case SMC_ACTIVE:
smc_close_final() // then wait peer closed
Unfortunately, tcp_abort() may discard CLC CONFIRM messages that are still in the tcp send buffer, in which case our connection token cannot be delivered to the server side, which means that we cannot get a passive close message at all. Therefore, it is impossible for the to be disconnected at all.
This patch tries a very simple way to avoid this issue, once the state has changed to SMC_ACTIVE after tcp_abort(), we can actively abort the smc connection, considering that the state is SMC_INIT before tcp_abort(), abandoning the complete disconnection process should not cause too much problem.
In fact, this problem may exist as long as the CLC CONFIRM message is not received by the server. Whether a timer should be added after smc_close_final() needs to be discussed in the future. But even so, this patch provides a faster release for connection in above case, it should also be valuable.
--- net/smc/af_smc.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
net/smc/af_smc.c +8 -2
@@ -183,7 +183,7 @@ static int smc_release(struct socket *so {struct sock *sk = sock->sk;struct smc_sock *smc; -int rc =0 ; +int old_state, rc =0 ;if (!sk) goto out;
@@ -191,8 +191,10 @@ static int smc_release(struct socket *sosock_hold (sk);/* sock_put below */ smc =smc_sk (sk); + old_state = sk->sk_state; +/* cleanup for a dangling non-blocking connect */ -if (smc->connect_nonblock && sk->sk_state ==SMC_INIT ) +if (smc->connect_nonblock && old_state ==SMC_INIT )tcp_abort (smc->clcsock->sk,ECONNABORTED );if (cancel_work_sync (&smc->connect_work))
@@ -206,6 +208,10 @@ static int smc_release(struct socket *soelse lock_sock (sk); +if (old_state ==SMC_INIT && sk->sk_state ==SMC_ACTIVE && + !smc->use_fallback) +smc_close_active_abort (smc); + rc =__smc_release (smc);/* detach socket */
Greg Kroah-Hartman
maintainerPATCH 84/186 net/smc: fix unexpected SMC_CLC_DECL_ERR_REGRMB error generated by client
In reply to Greg Kroah-HartmanFrom: D. Wythe <[email protected]>
commit 0537f0a2151375dcf90c1bbfda6a0aaf57164e89 upstream.
The main reason for this unexpected SMC_CLC_DECL_ERR_REGRMB in client dues to following execution sequence:
Server Conn A: Server Conn B: Client Conn B:
smc_lgr_unregister_conn
smc_lgr_register_conn
smc_clc_send_accept ->
smc_rtoken_add
smcr_buf_unuse
-> Client Conn A:
smc_rtoken_deletesmc_lgr_unregister_conn() makes current link available to assigned to new incoming connection, while smcr_buf_unuse() has not executed yet, which means that smc_rtoken_add may fail because of insufficient rtoken_entry, reversing their execution order will avoid this problem.
--- net/smc/smc_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/smc/smc_core.c +1 -1
@@ -1132,8 +1132,8 @@ void smc_conn_free(struct smc_connectioncancel_work_sync (&conn->abort_work); }if (!list_empty (&lgr->list)) { -smc_lgr_unregister_conn (conn);smc_buf_unuse (conn, lgr);/* allow buffer reuse */ +smc_lgr_unregister_conn (conn); }if (!lgr->conns_num)
Greg Kroah-Hartman
maintainerPATCH 85/186 net/smc: fix unexpected SMC_CLC_DECL_ERR_REGRMB error cause by server
In reply to Greg Kroah-HartmanFrom: D. Wythe <[email protected]>
commit 4940a1fdf31c39f0806ac831cde333134862030b upstream.
The problem of SMC_CLC_DECL_ERR_REGRMB on the server is very clear. Based on the fact that whether a new SMC connection can be accepted or not depends on not only the limit of conn nums, but also the available entries of rtoken. Since the rtoken release is trigger by peer, while the conn nums is decrease by local, tons of thing can happen in this time difference.
This only thing that needs to be mentioned is that now all connection creations are completely protected by smc_server_lgr_pending lock, it's enough to check only the available entries in rtokens_used_mask.
--- net/smc/smc_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/smc/smc_core.c +2 -1
@@ -1783,7 +1783,8 @@ int smc_conn_create(struct smc_sock *smc (ini->smcd_version ==SMC_V2 || lgr->vlan_id == ini->vlan_id) && (role ==SMC_CLNT || ini->is_smcd || - lgr->conns_num < SMC_RMBS_PER_LGR_MAX)) { + (lgr->conns_num <SMC_RMBS_PER_LGR_MAX && + !bitmap_full(lgr->rtokens_used_mask, SMC_RMBS_PER_LGR_MAX)))) { /* link group found */ ini->first_contact_local = 0; conn->lgr = lgr;
Greg Kroah-Hartman
maintainerPATCH 86/186 btrfs: fix ENOSPC failure when attempting direct IO write into NOCOW range
In reply to Greg Kroah-HartmanFrom: Filipe Manana <[email protected]>
commit f0bfa76a11e93d0fe2c896fcb566568c5e8b5d3f upstream.
When doing a direct IO write against a file range that either has preallocated extents in that range or has regular extents and the file has the NOCOW attribute set, the write fails with -ENOSPC when all of the following conditions are met:
1) There are no data blocks groups with enough free space matching the size of the write;
2) There's not enough unallocated space for allocating a new data block group;
3) The extents in the target file range are not shared, neither through snapshots nor through reflinks.
This is wrong because a NOCOW write can be done in such case, and in fact it's possible to do it using a buffered IO write, since when failing to allocate data space, the buffered IO path checks if a NOCOW write is possible.
The failure in direct IO write path comes from the fact that early on, at btrfs_dio_iomap_begin(), we try to allocate data space for the write and if it that fails we return the error and stop - we never check if we can do NOCOW. But later, at btrfs_get_blocks_direct_write(), we check if we can do a NOCOW write into the range, or a subset of the range, and then release the previously reserved data space.
Fix this by doing the data reservation only if needed, when we must COW, at btrfs_get_blocks_direct_write() instead of doing it at btrfs_dio_iomap_begin(). This also simplifies a bit the logic and removes the inneficiency of doing unnecessary data reservations.
The following example test script reproduces the problem:
$ cat dio-nocow-enospc.sh #!/bin/bash
DEV=/dev/sdj
MNT=/mnt/sdj
# Use a small fixed size (1G) filesystem so that it's quick to fill # it up. # Make sure the mixed block groups feature is not enabled because we # later want to not have more space available for allocating data # extents but still have enough metadata space free for the file writes. mkfs.btrfs -f -b $((1024 * 1024 * 1024)) -O ^mixed-bg $DEV mount $DEV $MNT
# Create our test file with the NOCOW attribute set. touch $MNT/foobar
chattr +C $MNT/foobar
# Now fill in all unallocated space with data for our test file. # This will allocate a data block group that will be full and leave
# no (or a very small amount of) unallocated space in the device, so # that it will not be possible to allocate a new block group later. echo echo "Creating test file with initial data..." xfs_io -c "pwrite -S 0xab -b 1M 0 900M" $MNT/foobar
# Now try a direct IO write against file range [0, 10M[.
# This should succeed since this is a NOCOW file and an extent for the
# range was previously allocated. echo echo "Trying direct IO write over allocated space..." xfs_io -d -c "pwrite -S 0xcd -b 10M 0 10M" $MNT/foobar
umount $MNT
When running the test:
$ ./dio-nocow-enospc.sh (...)
Creating test file with initial data...
wrote 943718400/943718400 bytes at offset 0
900 MiB, 900 ops; 0:00:01.43 (625.526 MiB/sec and 625.5265 ops/sec)
Trying direct IO write over allocated space...
pwrite: No space left on device
A test case for fstests will follow, testing both this direct IO write scenario as well as the buffered IO write scenario to make it less likely to get future regressions on the buffered IO case.
--- fs/btrfs/inode.c | 142 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 78 insertions(+), 64 deletions(-)
fs/btrfs/inode.c +78 -64
@@ -61,8 +61,6 @@ struct btrfs_iget_args { };struct btrfs_dio_data { -u64 reserve; -loff_t length;ssize_t submitted;struct extent_changeset *data_reserved; };
@@ -7773,6 +7771,10 @@ static int btrfs_get_blocks_direct_write {struct btrfs_fs_info *fs_info =btrfs_sb (inode->i_sb);struct extent_map *em = *map; +int type; +u64 block_start, orig_start, orig_block_len, ram_bytes; +bool can_nocow = false; +bool space_reserved = false;int ret =0 ;/*
@@ -7787,9 +7789,6 @@ static int btrfs_get_blocks_direct_writeif (test_bit (EXTENT_FLAG_PREALLOC , &em->flags) || ((BTRFS_I (inode)->flags &BTRFS_INODE_NODATACOW ) && em->block_start !=EXTENT_MAP_HOLE )) { -int type; -u64 block_start, orig_start, orig_block_len, ram_bytes; -if (test_bit (EXTENT_FLAG_PREALLOC , &em->flags)) type =BTRFS_ORDERED_PREALLOC ;else
@@ -7799,53 +7798,92 @@ static int btrfs_get_blocks_direct_writeif (can_nocow_extent (inode, start, &len, &orig_start, &orig_block_len, &ram_bytes, false) ==1 && -btrfs_inc_nocow_writers (fs_info, block_start)) { -struct extent_map *em2; +btrfs_inc_nocow_writers (fs_info, block_start)) + can_nocow = true; + } - em2 =btrfs_create_dio_extent (BTRFS_I (inode), start, len, - orig_start, block_start, - len, orig_block_len, - ram_bytes, type); +if (can_nocow) { +struct extent_map *em2; + +/* We can NOCOW, so only need to reserve metadata space. */ + ret =btrfs_delalloc_reserve_metadata (BTRFS_I (inode), len); +if (ret <0 ) { +/* Our caller expects us to free the input extent map. */ +free_extent_map (em); + *map =NULL ;btrfs_dec_nocow_writers (fs_info, block_start); -if (type ==BTRFS_ORDERED_PREALLOC ) { -free_extent_map (em); - *map = em = em2; - } + goto out; + } + space_reserved = true; -if (em2 &&IS_ERR (em2)) { - ret =PTR_ERR (em2); - goto out; - } -/* -* For inode marked NODATACOW or extent marked PREALLOC, -* use the existing or preallocated extent, so does not -* need to adjust btrfs_space_info's bytes_may_use. -*/ -btrfs_free_reserved_data_space_noquota (fs_info, len); - goto skip_cow; + em2 =btrfs_create_dio_extent (BTRFS_I (inode), start, len, + orig_start, block_start, + len, orig_block_len, + ram_bytes, type); +btrfs_dec_nocow_writers (fs_info, block_start); +if (type ==BTRFS_ORDERED_PREALLOC ) { +free_extent_map (em); + *map = em = em2; } - } -/* this will cow the extent */ -free_extent_map (em); - *map = em =btrfs_new_extent_direct (BTRFS_I (inode), start, len); -if (IS_ERR (em)) { - ret =PTR_ERR (em); - goto out; +if (IS_ERR (em2)) { + ret =PTR_ERR (em2); + goto out; + } + }else { +const u64 prev_len = len; + +/* Our caller expects us to free the input extent map. */ +free_extent_map (em); + *map =NULL ; + +/* We have to COW, so need to reserve metadata and data space. */ + ret =btrfs_delalloc_reserve_space (BTRFS_I (inode), + &dio_data->data_reserved, + start, len); +if (ret <0 ) + goto out; + space_reserved = true; + + em =btrfs_new_extent_direct (BTRFS_I (inode), start, len); +if (IS_ERR (em)) { + ret =PTR_ERR (em); + goto out; + } + *map = em; + len =min (len, em->len - (start - em->start)); +if (len < prev_len) +btrfs_delalloc_release_space (BTRFS_I (inode), + dio_data->data_reserved, + start + len, prev_len - len, + true); } - len =min (len, em->len - (start - em->start)); +/* +* We have created our ordered extent, so we can now release our reservation +* for an outstanding extent. +*/ +btrfs_delalloc_release_extents (BTRFS_I (inode), len); -skip_cow:/* * Need to update the i_size under the extent lock so buffered * readers will get the updated i_size when we unlock. */ if (start + len >i_size_read (inode))i_size_write (inode, start + len); - - dio_data->reserve -= len; out: +if (ret && space_reserved) { +btrfs_delalloc_release_extents (BTRFS_I (inode), len); +if (can_nocow) { +btrfs_delalloc_release_metadata (BTRFS_I (inode), len, true); + }else { +btrfs_delalloc_release_space (BTRFS_I (inode), + dio_data->data_reserved, + start, len, true); +extent_changeset_free (dio_data->data_reserved); + dio_data->data_reserved =NULL ; + } + }return ret; }
@@ -7887,18 +7925,6 @@ static int btrfs_dio_iomap_begin(structif (!dio_data)return -ENOMEM ; - dio_data->length = length; -if (write) { - dio_data->reserve =round_up (length, fs_info->sectorsize); - ret =btrfs_delalloc_reserve_space (BTRFS_I (inode), - &dio_data->data_reserved, - start, dio_data->reserve); -if (ret) { -extent_changeset_free (dio_data->data_reserved); -kfree (dio_data); -return ret; - } - } iomap->private = dio_data;
@@ -7991,14 +8017,8 @@ unlock_err:unlock_extent_cached (&BTRFS_I (inode)->io_tree, lockstart, lockend, &cached_state); err: -if (dio_data) { -btrfs_delalloc_release_space (BTRFS_I (inode), - dio_data->data_reserved, start, - dio_data->reserve, true); -btrfs_delalloc_release_extents (BTRFS_I (inode), dio_data->reserve); -extent_changeset_free (dio_data->data_reserved); -kfree (dio_data); - } +kfree (dio_data); +return ret; }
@@ -8028,14 +8048,8 @@ static int btrfs_dio_iomap_end(struct in ret = -ENOTBLK ; } -if (write) { -if (dio_data->reserve) -btrfs_delalloc_release_space (BTRFS_I (inode), - dio_data->data_reserved, pos, - dio_data->reserve, true); -btrfs_delalloc_release_extents (BTRFS_I (inode), dio_data->length); +if (write)extent_changeset_free (dio_data->data_reserved); - } out:kfree (dio_data); iomap->private =NULL ;
Greg Kroah-Hartman
maintainerPATCH 87/186 platform/x86: amd-pmc: Set QOS during suspend on CZN w/ timer wakeup
In reply to Greg Kroah-HartmanFrom: Mario Limonciello <[email protected]>
commit 68af28426b3ca1bf9ba21c7d8bdd0ff639e5134c upstream.
commit 59348401ebed ("platform/x86: amd-pmc: Add special handling for timer based S0i3 wakeup") adds support for using another platform timer in lieu of the RTC which doesn't work properly on some systems. This path was validated and worked well before submission. During the 5.16-rc1 merge window other patches were merged that caused this to stop working properly.
When this feature was used with 5.16-rc1 or later some OEM laptops with the matching firmware requirements from that commit would shutdown instead of program a timer based wakeup.
This was bisected to commit 8d89835b0467 ("PM: suspend: Do not pause cpuidle in the suspend-to-idle path"). This wasn't supposed to cause any negative impacts and also tested well on both Intel and ARM platforms. However this changed the semantics of when CPUs are allowed to be in the deepest state. For the AMD systems in question it appears this causes a firmware crash for timer based wakeup.
It's hypothesized to be caused by the amd-pmc driver sending OS_HINT and all the CPUs going into a deep state while the timer is still being programmed. It's likely a firmware bug, but to avoid it don't allow setting CPUs into the deepest state while using CZN timer wakeup path.
If later it's discovered that this also occurs from "regular" suspends without a timer as well or on other silicon, this may be later expanded to run in the suspend path for more scenarios.
--- drivers/platform/x86/amd-pmc.c | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-)
drivers/platform/x86/amd-pmc.c +30 -4
@@ -21,6 +21,7 @@#include <linux/module.h> #include <linux/pci.h> #include <linux/platform_device.h> +#include <linux/pm_qos.h> #include <linux/rtc.h> #include <linux/suspend.h> #include <linux/seq_file.h>
@@ -79,6 +80,9 @@#define PMC_MSG_DELAY_MIN_US 50#define RESPONSE_REGISTER_LOOP_MAX 20000 +/* QoS request for letting CPUs in idle states, but not the deepest */ +#define AMD_PMC_MAX_IDLE_STATE_LATENCY 3 +#define SOC_SUBSYSTEM_IP_MAX 12#define DELAY_MIN_US 2000#define DELAY_MAX_US 3000
@@ -123,6 +127,7 @@ struct amd_pmc_dev {u8 rev;struct device *dev;struct mutex lock;/* generic mutex lock */ +struct pm_qos_request amd_pmc_pm_qos_req;#if IS_ENABLED (CONFIG_DEBUG_FS )struct dentry *dbgfs_dir;#endif /* CONFIG_DEBUG_FS */
@@ -459,6 +464,14 @@ static int amd_pmc_verify_czn_rtc(struct rc =rtc_alarm_irq_enable (rtc_device,0 );dev_dbg (pdev->dev,"wakeup timer programmed for %lld seconds\n" , duration); +/* +* Prevent CPUs from getting into deep idle states while sending OS_HINT +* which is otherwise generally safe to send when at least one of the CPUs +* is not in deep idle states. +*/ +cpu_latency_qos_update_request (&pdev->amd_pmc_pm_qos_req,AMD_PMC_MAX_IDLE_STATE_LATENCY ); +wake_up_all_idle_cpus (); +return rc; }
@@ -476,17 +489,24 @@ static int __maybe_unused amd_pmc_suspen/* Activate CZN specific RTC functionality */ if (pdev->cpu_id ==AMD_CPU_ID_CZN ) { rc =amd_pmc_verify_czn_rtc (pdev, &arg); -if (rc <0 ) -return rc; +if (rc) + goto fail; }/* Dump the IdleMask before we send hint to SMU */ amd_pmc_idlemask_read (pdev, dev,NULL ); msg =amd_pmc_get_os_hint (pdev); rc =amd_pmc_send_cmd (pdev, arg,NULL , msg,0 ); -if (rc) +if (rc) {dev_err (pdev->dev,"suspend failed\n" ); + goto fail; + } +return 0 ; +fail: +if (pdev->cpu_id ==AMD_CPU_ID_CZN ) +cpu_latency_qos_update_request (&pdev->amd_pmc_pm_qos_req, +PM_QOS_DEFAULT_VALUE );return rc; }
@@ -507,7 +527,12 @@ static int __maybe_unused amd_pmc_resume/* Dump the IdleMask to see the blockers */ amd_pmc_idlemask_read (pdev, dev,NULL ); -return 0 ; +/* Restore the QoS request back to defaults if it was set */ +if (pdev->cpu_id ==AMD_CPU_ID_CZN ) +cpu_latency_qos_update_request (&pdev->amd_pmc_pm_qos_req, +PM_QOS_DEFAULT_VALUE ); + +return rc; }static const struct dev_pm_ops amd_pmc_pm_ops = {
@@ -597,6 +622,7 @@ static int amd_pmc_probe(struct platformamd_pmc_get_smu_version (dev);platform_set_drvdata (pdev, dev);amd_pmc_dbgfs_register (dev); +cpu_latency_qos_add_request (&dev->amd_pmc_pm_qos_req,PM_QOS_DEFAULT_VALUE );return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 88/186 net: dsa: microchip: fix bridging with more than two member ports
In reply to Greg Kroah-HartmanFrom: Svenning Sørensen <[email protected]>
commit 3d00827a90db6f79abc7cdc553887f89a2e0a184 upstream.
Commit b3612ccdf284 ("net: dsa: microchip: implement multi-bridge support") plugged a packet leak between ports that were members of different bridges. Unfortunately, this broke another use case, namely that of more than two ports that are members of the same bridge.
After that commit, when a port is added to a bridge, hardware bridging between other member ports of that bridge will be cleared, preventing packet exchange between them.
Fix by ensuring that the Port VLAN Membership bitmap includes any existing ports in the bridge, not just the port being added.
--- drivers/net/dsa/microchip/ksz_common.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-)
drivers/net/dsa/microchip/ksz_common.c +23 -3
@@ -26,7 +26,7 @@ void ksz_update_port_member(struct ksz_dstruct dsa_switch *ds = dev->ds;u8 port_member =0 , cpu_port;const struct dsa_port *dp; -int i; +int i, j;if (!dsa_is_user_port (ds, port))return ;
@@ -45,13 +45,33 @@ void ksz_update_port_member(struct ksz_dcontinue ;if (!dp->bridge_dev || dp->bridge_dev != other_dp->bridge_dev)continue ; +if (other_p->stp_state !=BR_STATE_FORWARDING ) +continue ; -if (other_p->stp_state ==BR_STATE_FORWARDING && - p->stp_state ==BR_STATE_FORWARDING ) { +if (p->stp_state ==BR_STATE_FORWARDING ) { val |=BIT (port); port_member |=BIT (i); } +/* Retain port [i]'s relationship to other ports than [port] */ +for (j =0 ; j < ds->num_ports; j++) { +const struct dsa_port *third_dp; +struct ksz_port *third_p; + +if (j == i) +continue ; +if (j == port) +continue ; +if (!dsa_is_user_port (ds, j)) +continue ; + third_p = &dev->ports[j]; +if (third_p->stp_state !=BR_STATE_FORWARDING ) +continue ; + third_dp =dsa_to_port (ds, j); +if (third_dp->bridge_dev == dp->bridge_dev) + val |=BIT (j); + } + dev->dev_ops->cfg_port_member (dev, i, val | cpu_port); }
Greg Kroah-Hartman
maintainerPATCH 89/186 mac80211: fix forwarded mesh frames AC & queue selection
In reply to Greg Kroah-HartmanFrom: Nicolas Escande <[email protected]>
commit 859ae7018316daa4adbc496012dcbbb458d7e510 upstream.
There are two problems with the current code that have been highlighted with the AQL feature that is now enbaled by default.
First problem is in ieee80211_rx_h_mesh_fwding(), ieee80211_select_queue_80211() is used on received packets to choose the sending AC queue of the forwarding packet although this function should only be called on TX packet (it uses ieee80211_tx_info). This ends with forwarded mesh packets been sent on unrelated random AC queue. To fix that, AC queue can directly be infered from skb->priority which has been extracted from QOS info (see ieee80211_parse_qos()).
Second problem is the value of queue_mapping set on forwarded mesh frames via skb_set_queue_mapping() is not the AC of the packet but a hardware queue index. This may or may not work depending on AC to HW queue mapping which is driver specific.
Both of these issues lead to improper AC selection while forwarding mesh packets but more importantly due to improper airtime accounting (which is done on a per STA, per AC basis) caused traffic stall with the introduction of AQL.
--- net/mac80211/rx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
net/mac80211/rx.c +2 -2
@@ -2918,13 +2918,13 @@ ieee80211_rx_h_mesh_fwding(struct ieee80 ether_addr_equal(sdata->vif.addr, hdr->addr3))return RX_CONTINUE ; - ac =ieee80211_select_queue_80211 (sdata, skb, hdr); + ac = ieee802_1d_to_ac[skb->priority]; q = sdata->vif.hw_queue[ac];if (ieee80211_queue_stopped (&local->hw, q)) {IEEE80211_IFSTA_MESH_CTR_INC (ifmsh, dropped_frames_congestion);return RX_DROP_MONITOR ; } -skb_set_queue_mapping (skb, q); +skb_set_queue_mapping (skb, ac);if (!--mesh_hdr->ttl) {if (!is_multicast_ether_addr (hdr->addr1))
Greg Kroah-Hartman
maintainerPATCH 90/186 net: stmmac: fix return value of __setup handler
In reply to Greg Kroah-HartmanFrom: Randy Dunlap <[email protected]>
commit e01b042e580f1fbf4fd8da467442451da00c7a90 upstream.
__setup() handlers should return 1 on success, i.e., the parameter has been handled. A return of 0 causes the "option=value" string to be added to init's environment strings, polluting it.
--- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +3 -3
@@ -7353,7 +7353,7 @@ static int __init stmmac_cmdline_opt(chachar *opt;if (!str || !*str) -return -EINVAL ; +return 1 ;while ((opt =strsep (&str,"," )) !=NULL ) {if (!strncmp (opt,"debug:" ,6 )) {if (kstrtoint (opt +6 ,0 , &debug))
@@ -7384,11 +7384,11 @@ static int __init stmmac_cmdline_opt(cha goto err; } } -return 0 ; +return 1 ; err:pr_err ("%s: ERROR broken module parameter conversion" , __func__); -return -EINVAL ; +return 1 ; }__setup ("stmmaceth=" , stmmac_cmdline_opt);
Greg Kroah-Hartman
maintainerPATCH 91/186 mac80211: treat some SAE auth steps as final
In reply to Greg Kroah-HartmanFrom: Johannes Berg <[email protected]>
commit 94d9864cc86f572f881db9b842a78e9d075493ae upstream.
When we get anti-clogging token required (added by the commit mentioned below), or the other status codes added by the later commit 4e56cde15f7d ("mac80211: Handle special status codes in SAE commit") we currently just pretend (towards the internal state machine of authentication) that we didn't receive anything.
This has the undesirable consequence of retransmitting the prior frame, which is not expected, because the timer is still armed.
If we just disarm the timer at that point, it would result in the undesirable side effect of being in this state indefinitely if userspace crashes, or so.
So to fix this, reset the timer and set a new auth_data->waiting in order to have no more retransmissions, but to have the data destroyed when the timer actually fires, which will only happen if userspace didn't continue (i.e. crashed or abandoned it.)
--- net/mac80211/ieee80211_i.h | 2 +- net/mac80211/mlme.c | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-)
net/mac80211/ieee80211_i.h +1 -1
@@ -376,7 +376,7 @@ struct ieee80211_mgd_auth_data {u8 key[WLAN_KEY_LEN_WEP104 ];u8 key_len, key_idx; -bool done; +bool done, waiting;bool peer_confirmed;bool timeout_started;
net/mac80211/mlme.c +12 -4
@@ -37,6 +37,7 @@#define IEEE80211_AUTH_TIMEOUT_SAE (HZ * 2)#define IEEE80211_AUTH_MAX_TRIES 3#define IEEE80211_AUTH_WAIT_ASSOC (HZ * 5) +#define IEEE80211_AUTH_WAIT_SAE_RETRY (HZ * 2)#define IEEE80211_ASSOC_TIMEOUT (HZ / 5)#define IEEE80211_ASSOC_TIMEOUT_LONG (HZ / 2)#define IEEE80211_ASSOC_TIMEOUT_SHORT (HZ / 10)
@@ -3009,8 +3010,15 @@ static void ieee80211_rx_mgmt_auth(struc (status_code ==WLAN_STATUS_ANTI_CLOG_REQUIRED || (auth_transaction ==1 && (status_code ==WLAN_STATUS_SAE_HASH_TO_ELEMENT || - status_code == WLAN_STATUS_SAE_PK)))) + status_code == WLAN_STATUS_SAE_PK)))) { + /* waiting for userspace now */ + ifmgd->auth_data->waiting = true; + ifmgd->auth_data->timeout = + jiffies +IEEE80211_AUTH_WAIT_SAE_RETRY ; + ifmgd->auth_data->timeout_started = true; +run_again (sdata, ifmgd->auth_data->timeout); goto notify_driver; + }sdata_info (sdata,"%pM denied authentication (status %d)\n" , mgmt->sa, status_code);
@@ -4597,10 +4605,10 @@ void ieee80211_sta_work(struct ieee80211if (ifmgd->auth_data && ifmgd->auth_data->timeout_started &&time_after (jiffies, ifmgd->auth_data->timeout)) { -if (ifmgd->auth_data->done) { +if (ifmgd->auth_data->done || ifmgd->auth_data->waiting) {/* -* ok ... we waited for assoc but userspace didn't, -* so let's just kill the auth data +* ok ... we waited for assoc or continuation but +* userspace didn't do it, so kill the auth data */ ieee80211_destroy_auth_data (sdata, false); }else if (ieee80211_auth (sdata)) {
Greg Kroah-Hartman
maintainerPATCH 92/186 iavf: Fix missing check for running netdev
In reply to Greg Kroah-HartmanFrom: Slawomir Laba <[email protected]>
commit d2c0f45fcceb0995f208c441d9c9a453623f9ccf upstream.
The driver was queueing reset_task regardless of the netdev state.
Do not queue the reset task in iavf_change_mtu if netdev is not running.
--- drivers/net/ethernet/intel/iavf/iavf_main.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/net/ethernet/intel/iavf/iavf_main.c +5 -2
@@ -3436,8 +3436,11 @@ static int iavf_change_mtu(struct net_deiavf_notify_client_l2_params (&adapter->vsi); adapter->flags |=IAVF_FLAG_SERVICE_CLIENT_REQUESTED ; } - adapter->flags |=IAVF_FLAG_RESET_NEEDED ; -queue_work (iavf_wq, &adapter->reset_task); + +if (netif_running (netdev)) { + adapter->flags |=IAVF_FLAG_RESET_NEEDED ; +queue_work (iavf_wq, &adapter->reset_task); + }return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 93/186 net: sxgbe: fix return value of __setup handler
In reply to Greg Kroah-HartmanFrom: Randy Dunlap <[email protected]>
commit 50e06ddceeea263f57fe92baa677c638ecd65bb6 upstream.
__setup() handlers should return 1 on success, i.e., the parameter has been handled. A return of 0 causes the "option=value" string to be added to init's environment strings, polluting it.
--- drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c +3 -3
@@ -2285,18 +2285,18 @@ static int __init sxgbe_cmdline_opt(charchar *opt;if (!str || !*str) -return -EINVAL ; +return 1 ;while ((opt =strsep (&str,"," )) !=NULL ) {if (!strncmp (opt,"eee_timer:" ,10 )) {if (kstrtoint (opt +10 ,0 , &eee_timer)) goto err; } } -return 0 ; +return 1 ; err:pr_err ("%s: ERROR broken module parameter conversion\n" , __func__); -return -EINVAL ; +return 1 ; }__setup ("sxgbeeth=" , sxgbe_cmdline_opt);
Greg Kroah-Hartman
maintainerPATCH 94/186 ibmvnic: register netdev after init of adapter
In reply to Greg Kroah-HartmanFrom: Sukadev Bhattiprolu <[email protected]>
commit 570425f8c7c18b14fa8a2a58a0adb431968ad118 upstream.
Finish initializing the adapter before registering netdev so state is consistent.
--- drivers/net/ethernet/ibm/ibmvnic.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
drivers/net/ethernet/ibm/ibmvnic.c +8 -6
@@ -5811,12 +5811,6 @@ static int ibmvnic_probe(struct vio_dev goto ibmvnic_dev_file_err;netif_carrier_off (netdev); - rc =register_netdev (netdev); -if (rc) { -dev_err (&dev->dev,"failed to register netdev rc=%d\n" , rc); - goto ibmvnic_register_fail; - } -dev_info (&dev->dev,"ibmvnic registered\n" );if (init_success) { adapter->state =VNIC_PROBED ;
@@ -5829,6 +5823,14 @@ static int ibmvnic_probe(struct vio_dev adapter->wait_for_reset = false; adapter->last_reset_time = jiffies; + + rc =register_netdev (netdev); +if (rc) { +dev_err (&dev->dev,"failed to register netdev rc=%d\n" , rc); + goto ibmvnic_register_fail; + } +dev_info (&dev->dev,"ibmvnic registered\n" ); +return 0 ; ibmvnic_register_fail:
Greg Kroah-Hartman
maintainerPATCH 95/186 net: arcnet: com20020: Fix null-ptr-deref in com20020pci_probe()
In reply to Greg Kroah-HartmanFrom: Zheyu Ma <[email protected]>
commit bd6f1fd5d33dfe5d1b4f2502d3694a7cc13f166d upstream.
During driver initialization, the pointer of card info, i.e. the variable 'ci' is required. However, the definition of 'com20020pci_id_table' reveals that this field is empty for some devices, which will cause null pointer dereference when initializing these devices.
The following log reveals it:
[ 3.973806] KASAN: null-ptr-deref in range [0x0000000000000028-0x000000000000002f] [ 3.973819] RIP: 0010:com20020pci_probe+0x18d/0x13e0 [com20020_pci] [ 3.975181] Call Trace: [ 3.976208] local_pci_probe+0x13f/0x210 [ 3.977248] pci_device_probe+0x34c/0x6d0 [ 3.977255] ? pci_uevent+0x470/0x470 [ 3.978265] really_probe+0x24c/0x8d0 [ 3.978273] __driver_probe_device+0x1b3/0x280 [ 3.979288] driver_probe_device+0x50/0x370
Fix this by checking whether the 'ci' is a null pointer first.
--- drivers/net/arcnet/com20020-pci.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/arcnet/com20020-pci.c +3 -0
@@ -138,6 +138,9 @@ static int com20020pci_probe(struct pci_return -ENOMEM ; ci = (struct com20020_pci_card_info *)id->driver_data; +if (!ci) +return -EINVAL ; + priv->ci = ci; mm = &ci->misc_map;
Greg Kroah-Hartman
maintainerPATCH 96/186 ixgbe: xsk: change !netif_carrier_ok() handling in ixgbe_xmit_zc()
In reply to Greg Kroah-HartmanFrom: Maciej Fijalkowski <[email protected]>
commit 6c7273a266759d9d36f7c862149f248bcdeddc0f upstream.
Commit c685c69fba71 ("ixgbe: don't do any AF_XDP zero-copy transmit if netif is not OK") addressed the ring transient state when MEM_TYPE_XSK_BUFF_POOL was being configured which in turn caused the interface to through down/up. Maurice reported that when carrier is not ok and xsk_pool is present on ring pair, ksoftirqd will consume 100% CPU cycles due to the constant NAPI rescheduling as ixgbe_poll() states that there is still some work to be done.
To fix this, do not set work_done to false for a !netif_carrier_ok().
--- drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c +4 -2
@@ -390,12 +390,14 @@ static bool ixgbe_xmit_zc(struct ixgbe_ru32 cmd_type;while (budget-- >0 ) { -if (unlikely (!ixgbe_desc_unused (xdp_ring)) || - !netif_carrier_ok (xdp_ring->netdev)) { +if (unlikely (!ixgbe_desc_unused (xdp_ring))) { work_done = false;break ; } +if (!netif_carrier_ok (xdp_ring->netdev)) +break ; +if (!xsk_tx_peek_desc (pool, &desc))break ;
Greg Kroah-Hartman
maintainerPATCH 97/186 iavf: Fix deadlock in iavf_reset_task
In reply to Greg Kroah-HartmanFrom: Slawomir Laba <[email protected]>
commit e85ff9c631e1bf109ce8428848dfc8e8b0041f48 upstream.
There exists a missing mutex_unlock call on crit_lock in iavf_reset_task call path.
Unlock the crit_lock before returning from reset task.
--- drivers/net/ethernet/intel/iavf/iavf_main.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/intel/iavf/iavf_main.c +1 -0
@@ -2254,6 +2254,7 @@ static void iavf_reset_task(struct work_ reg_val);iavf_disable_vf (adapter);mutex_unlock (&adapter->client_lock); +mutex_unlock (&adapter->crit_lock);return ;/* Do not attempt to reinit. It's dead, Jim. */ }
Greg Kroah-Hartman
maintainerPATCH 98/186 efivars: Respect "block" flag in efivar_entry_set_safe()
In reply to Greg Kroah-HartmanFrom: Jann Horn <[email protected]>
commit 258dd902022cb10c83671176688074879517fd21 upstream.
When the "block" flag is false, the old code would sometimes still call check_var_size(), which wrongly tells ->query_variable_store() that it can block.
As far as I can tell, this can't really materialize as a bug at the moment, because ->query_variable_store only does something on X86 with generic EFI, and in that configuration we always take the efivar_entry_set_nonblocking() path.
--- drivers/firmware/efi/vars.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/firmware/efi/vars.c +4 -1
@@ -742,6 +742,7 @@ int efivar_entry_set_safe(efi_char16_t * {const struct efivar_operations *ops;efi_status_t status; +unsigned long varsize;if (!__efivars)return -EINVAL ;
@@ -764,15 +765,17 @@ int efivar_entry_set_safe(efi_char16_t *return efivar_entry_set_nonblocking (name, vendor, attributes, size, data); + varsize = size +ucs2_strsize (name,1024 );if (!block) {if (down_trylock (&efivars_lock))return -EBUSY ; + status =check_var_size_nonblocking (attributes, varsize); }else {if (down_interruptible (&efivars_lock))return -EINTR ; + status =check_var_size (attributes, varsize); } - status =check_var_size (attributes, size +ucs2_strsize (name,1024 ));if (status !=EFI_SUCCESS ) {up (&efivars_lock);return -ENOSPC ;
Greg Kroah-Hartman
maintainerPATCH 99/186 auxdisplay: lcd2s: Fix lcd2s_redefine_char() feature
In reply to Greg Kroah-HartmanFrom: Andy Shevchenko <[email protected]>
commit 4424c35ead667ba2e8de7ab8206da66453e6f728 upstream.
It seems that the lcd2s_redefine_char() has never been properly tested. The buffer is filled by DEF_CUSTOM_CHAR command followed by the character number (from 0 to 7), but immediately after that these bytes are rewritten by the decoded hex stream.
Fix the index to fill the buffer after the command and number.
--- drivers/auxdisplay/lcd2s.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/auxdisplay/lcd2s.c +1 -1
@@ -238,7 +238,7 @@ static int lcd2s_redefine_char(struct chif (buf[1 ] >7 )return 1 ; - i =0 ; + i =2 ; shift =0 ; value =0 ;while (*esc && i <LCD2S_CHARACTER_SIZE +2 ) {
Greg Kroah-Hartman
maintainerPATCH 100/186 firmware: arm_scmi: Remove space in MODULE_ALIAS name
In reply to Greg Kroah-HartmanFrom: Alyssa Ross <[email protected]>
commit 1ba603f56568c3b4c2542dfba07afa25f21dcff3 upstream.
modprobe can't handle spaces in aliases. Get rid of it to fix the issue.
--- drivers/firmware/arm_scmi/driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/firmware/arm_scmi/driver.c +1 -1
@@ -2112,7 +2112,7 @@ static void __exit scmi_driver_exit(void }module_exit (scmi_driver_exit); -MODULE_ALIAS ("platform: arm-scmi" ); +MODULE_ALIAS ("platform:arm-scmi" );MODULE_AUTHOR ("Sudeep Holla <[email protected]>" );MODULE_DESCRIPTION ("ARM SCMI protocol driver" );MODULE_LICENSE ("GPL v2" );
Greg Kroah-Hartman
maintainerPATCH 101/186 ASoC: cs4265: Fix the duplicated control name
In reply to Greg Kroah-HartmanFrom: Fabio Estevam <[email protected]>
commit c5487b9cdea5c1ede38a7ec94db0fc59963c8e86 upstream.
Currently, the following error messages are seen during boot:
asoc-simple-card sound: control 2:0:0:SPDIF Switch:0 is already present cs4265 1-004f: ASoC: failed to add widget SPDIF dapm kcontrol SPDIF Switch: -16
Quoting Mark Brown:
"The driver is just plain buggy, it defines both a regular SPIDF Switch control and a SND_SOC_DAPM_SWITCH() called SPDIF both of which will create an identically named control, it can never have loaded without error. One or both of those has to be renamed or they need to be merged into one thing."
Fix the duplicated control name by combining the two SPDIF controls here and move the register bits onto the DAPM widget and have DAPM control them.
--- sound/soc/codecs/cs4265.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
sound/soc/codecs/cs4265.c +1 -2
@@ -150,7 +150,6 @@ static const struct snd_kcontrol_new cs4SOC_SINGLE ("E to F Buffer Disable Switch" ,CS4265_SPDIF_CTL1 ,6 ,1 ,0 ),SOC_ENUM ("C Data Access" , cam_mode_enum), -SOC_SINGLE ("SPDIF Switch" ,CS4265_SPDIF_CTL2 ,5 ,1 ,1 ),SOC_SINGLE ("Validity Bit Control Switch" ,CS4265_SPDIF_CTL2 ,3 ,1 ,0 ), SOC_ENUM("SPDIF Mono/Stereo", spdif_mono_stereo_enum),
@@ -186,7 +185,7 @@ static const struct snd_soc_dapm_widgetSND_SOC_DAPM_SWITCH ("Loopback" ,SND_SOC_NOPM ,0 ,0 , &loopback_ctl), -SND_SOC_DAPM_SWITCH ("SPDIF" ,SND_SOC_NOPM ,0 ,0 , +SND_SOC_DAPM_SWITCH ("SPDIF" ,CS4265_SPDIF_CTL2 ,5 ,1 , &spdif_switch),SND_SOC_DAPM_SWITCH ("DAC" ,CS4265_PWRCTL ,1 ,1 , &dac_switch),
Greg Kroah-Hartman
maintainerPATCH 102/186 auxdisplay: lcd2s: Fix memory leak in ->remove()
In reply to Greg Kroah-HartmanFrom: Andy Shevchenko <[email protected]>
commit 898c0a15425a5bcaa8d44bd436eae5afd2483796 upstream.
Once allocated the struct lcd2s_data is never freed. Fix the memory leak by switching to devm_kzalloc().
--- drivers/auxdisplay/lcd2s.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-)
drivers/auxdisplay/lcd2s.c +7 -11
@@ -298,6 +298,10 @@ static int lcd2s_i2c_probe(struct i2c_cl I2C_FUNC_SMBUS_WRITE_BLOCK_DATA))return -EIO ; + lcd2s =devm_kzalloc (&i2c->dev,sizeof (*lcd2s),GFP_KERNEL ); +if (!lcd2s) +return -ENOMEM ; +/* Test, if the display is responding */ err =lcd2s_i2c_smbus_write_byte (i2c,LCD2S_CMD_DISPLAY_OFF );if (err <0 )
@@ -307,12 +311,6 @@ static int lcd2s_i2c_probe(struct i2c_clif (!lcd)return -ENOMEM ; - lcd2s =kzalloc (sizeof (struct lcd2s_data ),GFP_KERNEL ); -if (!lcd2s) { - err = -ENOMEM ; - goto fail1; - } - lcd->drvdata = lcd2s; lcd2s->i2c = i2c; lcd2s->charlcd = lcd;
@@ -321,24 +319,22 @@ static int lcd2s_i2c_probe(struct i2c_cl err =device_property_read_u32 (&i2c->dev,"display-height-chars" , &lcd->height);if (err) - goto fail2; + goto fail1; err =device_property_read_u32 (&i2c->dev,"display-width-chars" , &lcd->width);if (err) - goto fail2; + goto fail1; lcd->ops = &lcd2s_ops; err =charlcd_register (lcd2s->charlcd);if (err) - goto fail2; + goto fail1;i2c_set_clientdata (i2c, lcd2s);return 0 ; -fail2: -kfree (lcd2s); fail1:kfree (lcd);return err;
Greg Kroah-Hartman
maintainerPATCH 103/186 auxdisplay: lcd2s: Use proper API to free the instance of charlcd object
In reply to Greg Kroah-HartmanFrom: Andy Shevchenko <[email protected]>
commit 9ed331f8a0fb674f4f06edf05a1687bf755af27b upstream.
While it might work, the current approach is fragile in a few ways:
- whenever members in the structure are shuffled, the pointer will be wrong
- the resource freeing may include more than covered by kfree()
Fix this by using charlcd_free() call instead of kfree().
--- drivers/auxdisplay/lcd2s.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/auxdisplay/lcd2s.c +2 -2
@@ -336,7 +336,7 @@ static int lcd2s_i2c_probe(struct i2c_clreturn 0 ; fail1: -kfree (lcd); +charlcd_free (lcd2s->charlcd);return err; }
@@ -345,7 +345,7 @@ static int lcd2s_i2c_remove(struct i2c_cstruct lcd2s_data *lcd2s =i2c_get_clientdata (i2c);charlcd_unregister (lcd2s->charlcd); -kfree (lcd2s->charlcd); +charlcd_free (lcd2s->charlcd);return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 104/186 can: gs_usb: change active_channelss type from atomic_t to u8
In reply to Greg Kroah-HartmanFrom: Vincent Mailhol <[email protected]>
commit 035b0fcf02707d3c9c2890dc1484b11aa5335eb1 upstream.
The driver uses an atomic_t variable: gs_usb:active_channels to keep track of the number of opened channels in order to only allocate memory for the URBs when this count changes from zero to one.
However, the driver does not decrement the counter when an error occurs in gs_can_open(). This issue is fixed by changing the type from atomic_t to u8 and by simplifying the logic accordingly.
It is safe to use an u8 here because the network stack big kernel lock (a.k.a. rtnl_mutex) is being hold. For details, please refer to [1].
--- drivers/net/can/usb/gs_usb.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/net/can/usb/gs_usb.c +5 -5
@@ -191,8 +191,8 @@ struct gs_can {struct gs_usb {struct gs_can *canch[GS_MAX_INTF ];struct usb_anchor rx_submitted; -atomic_t active_channels;struct usb_device *udev; +u8 active_channels; };/* 'allocate' a tx context.
@@ -590,7 +590,7 @@ static int gs_can_open(struct net_deviceif (rc)return rc; -if (atomic_add_return (1 , &parent->active_channels) ==1 ) { +if (!parent->active_channels) {for (i =0 ; i <GS_MAX_RX_URBS ; i++) {struct urb *urb;u8 *buf;
@@ -691,6 +691,7 @@ static int gs_can_open(struct net_device dev->can.state =CAN_STATE_ERROR_ACTIVE ; + parent->active_channels++;if (!(dev->can.ctrlmode &CAN_CTRLMODE_LISTENONLY ))netif_start_queue (netdev);
@@ -706,7 +707,8 @@ static int gs_can_close(struct net_devicnetif_stop_queue (netdev);/* Stop polling */ -if (atomic_dec_and_test (&parent->active_channels)) + parent->active_channels--; +if (!parent->active_channels)usb_kill_anchored_urbs (&parent->rx_submitted);/* Stop sending URBs */
@@ -985,8 +987,6 @@ static int gs_usb_probe(struct usb_interinit_usb_anchor (&dev->rx_submitted); -atomic_set (&dev->active_channels,0 ); -usb_set_intfdata (intf, dev); dev->udev =interface_to_usbdev (intf);
Greg Kroah-Hartman
maintainerPATCH 105/186 iommu/tegra-smmu: Fix missing put_device() call in tegra_smmu_find
In reply to Greg Kroah-HartmanFrom: Miaoqian Lin <[email protected]>
commit 9826e393e4a8c3df474e7f9eacd3087266f74005 upstream.
The reference taken by 'of_find_device_by_node()' must be released when not needed anymore.
Add the corresponding 'put_device()' in the error handling path.
--- drivers/iommu/tegra-smmu.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/iommu/tegra-smmu.c +3 -1
@@ -808,8 +808,10 @@ static struct tegra_smmu *tegra_smmu_finreturn NULL ; mc =platform_get_drvdata (pdev); -if (!mc) +if (!mc) { +put_device (&pdev->dev);return NULL ; + }return mc->smmu; }
Greg Kroah-Hartman
maintainerPATCH 106/186 arm64: dts: rockchip: Switch RK3399-Gru DP to SPDIF output
In reply to Greg Kroah-HartmanFrom: Brian Norris <[email protected]>
commit b5fbaf7d779f5f02b7f75b080e7707222573be2a upstream.
Commit b18c6c3c7768 ("ASoC: rockchip: cdn-dp sound output use spdif") switched the platform to SPDIF, but we didn't fix up the device tree.
Drop the pinctrl settings, because the 'spdif_bus' pins are either:
* unused (on kevin, bob), so the settings is ~harmless
* used by a different function (on scarlet), which causes probe failures (!!)
--- arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi +12 -5
@@ -286,7 +286,7 @@ sound: sound { compatible = "rockchip,rk3399-gru-sound"; - rockchip,cpu = <&i2s0 &i2s2>; + rockchip,cpu = <&i2s0 &spdif>; }; };
@@ -437,10 +437,6 @@ ap_i2c_audio: &i2c8 { status = "okay"; }; -&i2s2 { - status = "okay"; -}; - &io_domains { status = "okay";
@@ -537,6 +533,17 @@ ap_i2c_audio: &i2c8 { vqmmc-supply = <&ppvar_sd_card_io>; }; +&spdif { + status = "okay"; + + /* + * SPDIF is routed internally to DP; we either don't use these pins, or + * mux them to something else. + */ + /delete-property/ pinctrl-0; + /delete-property/ pinctrl-names; +}; + &spi1 { status = "okay";
Greg Kroah-Hartman
maintainerPATCH 107/186 igc: igc_read_phy_reg_gpy: drop premature return
In reply to Greg Kroah-HartmanFrom: Corinna Vinschen <[email protected]>
commit fda2635466cd26ad237e1bc5d3f6a60f97ad09b6 upstream.
igc_read_phy_reg_gpy checks the return value from igc_read_phy_reg_mdic and if it's not 0, returns immediately. By doing this, it leaves the HW semaphore in the acquired state.
Drop this premature return statement, the function returns after releasing the semaphore immediately anyway.
--- drivers/net/ethernet/intel/igc/igc_phy.c | 2 -- 1 file changed, 2 deletions(-)
drivers/net/ethernet/intel/igc/igc_phy.c +0 -2
@@ -779,8 +779,6 @@ s32 igc_read_phy_reg_gpy(struct igc_hw *if (ret_val)return ret_val; ret_val =igc_read_phy_reg_mdic (hw, offset, data); -if (ret_val) -return ret_val; hw->phy.ops.release (hw); }else { ret_val = igc_read_xmdio_reg(hw, (u16)offset, dev_addr,
Greg Kroah-Hartman
maintainerPATCH 108/186 ARM: Fix kgdb breakpoint for Thumb2
In reply to Greg Kroah-HartmanFrom: Russell King (Oracle) <[email protected]>
commit d920eaa4c4559f59be7b4c2d26fa0a2e1aaa3da9 upstream.
The kgdb code needs to register an undef hook for the Thumb UDF instruction that will fault in order to be functional on Thumb2 platforms.
--- arch/arm/kernel/kgdb.c | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-)
arch/arm/kernel/kgdb.c +28 -8
@@ -154,22 +154,38 @@ static int kgdb_compiled_brk_fn(struct preturn 0 ; } -static struct undef_hook kgdb_brkpt_hook = { +static struct undef_hook kgdb_brkpt_arm_hook = { .instr_mask =0xffffffff , .instr_val =KGDB_BREAKINST , - .cpsr_mask =MODE_MASK , + .cpsr_mask =PSR_T_BIT |MODE_MASK , .cpsr_val =SVC_MODE , .fn = kgdb_brk_fn }; -static struct undef_hook kgdb_compiled_brkpt_hook = { +static struct undef_hook kgdb_brkpt_thumb_hook = { + .instr_mask =0xffff , + .instr_val =KGDB_BREAKINST &0xffff , + .cpsr_mask =PSR_T_BIT |MODE_MASK , + .cpsr_val =PSR_T_BIT |SVC_MODE , + .fn = kgdb_brk_fn +}; + +static struct undef_hook kgdb_compiled_brkpt_arm_hook = { .instr_mask =0xffffffff , .instr_val =KGDB_COMPILED_BREAK , - .cpsr_mask =MODE_MASK , + .cpsr_mask =PSR_T_BIT |MODE_MASK , .cpsr_val =SVC_MODE , .fn = kgdb_compiled_brk_fn }; +static struct undef_hook kgdb_compiled_brkpt_thumb_hook = { + .instr_mask =0xffff , + .instr_val =KGDB_COMPILED_BREAK &0xffff , + .cpsr_mask =PSR_T_BIT |MODE_MASK , + .cpsr_val =PSR_T_BIT |SVC_MODE , + .fn = kgdb_compiled_brk_fn +}; +static int __kgdb_notify (struct die_args *args,unsigned long cmd) {struct pt_regs *regs = args->regs;
@@ -210,8 +226,10 @@ int kgdb_arch_init(void)if (ret !=0 )return ret; -register_undef_hook (&kgdb_brkpt_hook); -register_undef_hook (&kgdb_compiled_brkpt_hook); +register_undef_hook (&kgdb_brkpt_arm_hook); +register_undef_hook (&kgdb_brkpt_thumb_hook); +register_undef_hook (&kgdb_compiled_brkpt_arm_hook); +register_undef_hook (&kgdb_compiled_brkpt_thumb_hook);return 0 ; }
@@ -224,8 +242,10 @@ int kgdb_arch_init(void)*/ void kgdb_arch_exit (void ) { -unregister_undef_hook (&kgdb_brkpt_hook); -unregister_undef_hook (&kgdb_compiled_brkpt_hook); +unregister_undef_hook (&kgdb_brkpt_arm_hook); +unregister_undef_hook (&kgdb_brkpt_thumb_hook); +unregister_undef_hook (&kgdb_compiled_brkpt_arm_hook); +unregister_undef_hook (&kgdb_compiled_brkpt_thumb_hook);unregister_die_notifier (&kgdb_notifier); }
Greg Kroah-Hartman
maintainerPATCH 109/186 mips: setup: fix setnocoherentio() boolean setting
In reply to Greg Kroah-HartmanFrom: Randy Dunlap <[email protected]>
commit 1e6ae0e46e32749b130f1823da30cea9aa2a59a0 upstream.
Correct a typo/pasto: setnocoherentio() should set dma_default_coherent to false, not true.
--- arch/mips/kernel/setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/mips/kernel/setup.c +1 -1
@@ -803,7 +803,7 @@ early_param("coherentio", setcoherentio)static int __init setnocoherentio (char *str) { - dma_default_coherent = true; + dma_default_coherent = false;pr_info ("Software DMA cache coherency (command line)\n" );return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 110/186 ARM: 9182/1: mmu: fix returns from early_param() and __setup() functions
In reply to Greg Kroah-HartmanFrom: Randy Dunlap <[email protected]>
commit 7b83299e5b9385943a857d59e15cba270df20d7e upstream.
early_param() handlers should return 0 on success. __setup() handlers should return 1 on success, i.e., the parameter has been handled. A return of 0 would cause the "option=value" string to be added to init's environment strings, polluting it.
../arch/arm/mm/mmu.c: In function 'test_early_cachepolicy':../arch/arm/mm/mmu.c:215:1: error: no return statement in function returning non-void [-Werror=return-type] ../arch/arm/mm/mmu.c: In function 'test_noalign_setup':../arch/arm/mm/mmu.c:221:1: error: no return statement in function returning non-void [-Werror=return-type]
--- arch/arm/mm/mmu.c | 2 ++ 1 file changed, 2 insertions(+)
arch/arm/mm/mmu.c +2 -0
@@ -212,12 +212,14 @@ early_param("ecc", early_ecc);static int __init early_cachepolicy (char *p) {pr_warn ("cachepolicy kernel parameter not supported without cp15\n" ); +return 0 ; }early_param ("cachepolicy" , early_cachepolicy);static int __init noalign_setup (char *__unused) {pr_warn ("noalign kernel parameter not supported without cp15\n" ); +return 1 ; }__setup ("noalign" , noalign_setup);
_______________________________________________
linux-arm-kernel mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Greg Kroah-Hartman
maintainerPATCH 111/186 mptcp: Correctly set DATA_FIN timeout when number of retransmits is large
In reply to Greg Kroah-HartmanFrom: Mat Martineau <[email protected]>
commit 877d11f0332cd2160e19e3313e262754c321fa36 upstream.
Syzkaller with UBSAN uncovered a scenario where a large number of DATA_FIN retransmits caused a shift-out-of-bounds in the DATA_FIN timeout calculation:
================================================================================
UBSAN: shift-out-of-bounds in net/mptcp/protocol.c:470:29 shift exponent 32 is too large for 32-bit type 'unsigned int' CPU: 1 PID: 13059 Comm: kworker/1:0 Not tainted 5.17.0-rc2-00630-g5fbf21c90c60 #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014 Workqueue: events mptcp_worker Call Trace: <TASK> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0xcd/0x134 lib/dump_stack.c:106 ubsan_epilogue+0xb/0x5a lib/ubsan.c:151 __ubsan_handle_shift_out_of_bounds.cold+0xb2/0x20e lib/ubsan.c:330 mptcp_set_datafin_timeout net/mptcp/protocol.c:470 [inline] __mptcp_retrans.cold+0x72/0x77 net/mptcp/protocol.c:2445 mptcp_worker+0x58a/0xa70 net/mptcp/protocol.c:2528 process_one_work+0x9df/0x16d0 kernel/workqueue.c:2307 worker_thread+0x95/0xe10 kernel/workqueue.c:2454 kthread+0x2f4/0x3b0 kernel/kthread.c:377 ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:295 </TASK> ================================================================================
This change limits the maximum timeout by limiting the size of the shift, which keeps all intermediate values in-bounds.
--- net/mptcp/protocol.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
net/mptcp/protocol.c +5 -2
@@ -464,9 +464,12 @@ static bool mptcp_pending_data_fin(strucstatic void mptcp_set_datafin_timeout (const struct sock *sk) {struct inet_connection_sock *icsk =inet_csk (sk); +u32 retransmits; -mptcp_sk (sk)->timer_ival =min (TCP_RTO_MAX , -TCP_RTO_MIN << icsk->icsk_retransmits); + retransmits =min_t (u32, icsk->icsk_retransmits, +ilog2 (TCP_RTO_MAX /TCP_RTO_MIN )); + +mptcp_sk (sk)->timer_ival =TCP_RTO_MIN << retransmits; }static void __mptcp_set_timeout (struct sock *sk,long tout)
Greg Kroah-Hartman
maintainerPATCH 112/186 selftests: mlxsw: tc_police_scale: Make test more robust
In reply to Greg Kroah-HartmanFrom: Amit Cohen <[email protected]>
commit dc9752075341e7beb653e37c6f4a3723074dc8bc upstream.
The test adds tc filters and checks how many of them were offloaded by grepping for 'in_hw'.
iproute2 commit f4cd4f127047 ("tc: add skip_hw and skip_sw to control action offload") added offload indication to tc actions, producing the following output:
$ tc filter show dev swp2 ingress
...
filter protocol ipv6 pref 1000 flower chain 0 handle 0x7c0
eth_type ipv6
dst_ip 2001:db8:1::7bf
skip_sw
in_hw in_hw_count 1
action order 1: police 0x7c0 rate 10Mbit burst 100Kb mtu 2Kb action drop overhead 0b
ref 1 bind 1
not_in_hw
used_hw_stats immediateThe current grep expression matches on both 'in_hw' and 'not_in_hw', resulting in incorrect results.
Fix that by using JSON output instead.
--- tools/testing/selftests/drivers/net/mlxsw/tc_police_scale.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
tools/testing/selftests/drivers/net/mlxsw/tc_police_scale.sh +2 -1
@@ -60,7 +60,8 @@ __tc_police_test() tc_police_rules_create $count $should_fail - offload_count=$(tc filter show dev $swp1 ingress | grep in_hw | wc -l) + offload_count=$(tc -j filter show dev $swp1 ingress | + jq "[.[] | select(.options.in_hw == true)] | length") ((offload_count == count)) check_err_fail $should_fail $? "tc police offload count" }
Greg Kroah-Hartman
maintainerPATCH 113/186 pinctrl: sunxi: Use unique lockdep classes for IRQs
In reply to Greg Kroah-HartmanFrom: Samuel Holland <[email protected]>
commit bac129dbc6560dfeb634c03f0c08b78024e71915 upstream.
This driver, like several others, uses a chained IRQ for each GPIO bank, and forwards .irq_set_wake to the GPIO bank's upstream IRQ. As a result, a call to irq_set_irq_wake() needs to lock both the upstream and downstream irq_desc's. Lockdep considers this to be a possible deadlock when the irq_desc's share lockdep classes, which they do by default:
============================================
WARNING: possible recursive locking detected 5.17.0-rc3-00394-gc849047c2473 #1 Not tainted
--------------------------------------------
init/307 is trying to acquire lock:
c2dfe27c (&irq_desc_lock_class){-.-.}-{2:2}, at: __irq_get_desc_lock+0x58/0xa0
but task is already holding lock:
c3c0ac7c (&irq_desc_lock_class){-.-.}-{2:2}, at: __irq_get_desc_lock+0x58/0xa0
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0
---- lock(&irq_desc_lock_class);
lock(&irq_desc_lock_class);
*** DEADLOCK ***
May be due to missing lock nesting notation
4 locks held by init/307:
#0: c1f29f18 (system_transition_mutex){+.+.}-{3:3}, at: __do_sys_reboot+0x90/0x23c #1: c20f7760 (&dev->mutex){....}-{3:3}, at: device_shutdown+0xf4/0x224 #2: c2e804d8 (&dev->mutex){....}-{3:3}, at: device_shutdown+0x104/0x224 #3: c3c0ac7c (&irq_desc_lock_class){-.-.}-{2:2}, at: __irq_get_desc_lock+0x58/0xa0
stack backtrace:
CPU: 0 PID: 307 Comm: init Not tainted 5.17.0-rc3-00394-gc849047c2473 #1
Hardware name: Allwinner sun8i Family
unwind_backtrace from show_stack+0x10/0x14
show_stack from dump_stack_lvl+0x68/0x90
dump_stack_lvl from __lock_acquire+0x1680/0x31a0
__lock_acquire from lock_acquire+0x148/0x3dc
lock_acquire from _raw_spin_lock_irqsave+0x50/0x6c
_raw_spin_lock_irqsave from __irq_get_desc_lock+0x58/0xa0
__irq_get_desc_lock from irq_set_irq_wake+0x2c/0x19c
irq_set_irq_wake from irq_set_irq_wake+0x13c/0x19c
[tail call from sunxi_pinctrl_irq_set_wake]
irq_set_irq_wake from gpio_keys_suspend+0x80/0x1a4
gpio_keys_suspend from gpio_keys_shutdown+0x10/0x2c
gpio_keys_shutdown from device_shutdown+0x180/0x224
device_shutdown from __do_sys_reboot+0x134/0x23c
__do_sys_reboot from ret_fast_syscall+0x0/0x1cHowever, this can never deadlock because the upstream and downstream IRQs are never the same (nor do they even involve the same irqchip).
Silence this erroneous lockdep splat by applying what appears to be the usual fix of moving the GPIO IRQs to separate lockdep classes.
--- drivers/pinctrl/sunxi/pinctrl-sunxi.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/pinctrl/sunxi/pinctrl-sunxi.c +9 -0
@@ -36,6 +36,13 @@#include "../core.h" #include "pinctrl-sunxi.h" +/* +* These lock classes tell lockdep that GPIO IRQs are in a different +* category than their parents, so it won't report false recursion. +*/ +static struct lock_class_key sunxi_pinctrl_irq_lock_class; +static struct lock_class_key sunxi_pinctrl_irq_request_class; +static struct irq_chip sunxi_pinctrl_edge_irq_chip;static struct irq_chip sunxi_pinctrl_level_irq_chip;
@@ -1551,6 +1558,8 @@ int sunxi_pinctrl_init_with_variant(strufor (i =0 ; i < (pctl->desc->irq_banks *IRQ_PER_BANK ); i++) {int irqno =irq_create_mapping (pctl->domain, i); +irq_set_lockdep_class (irqno, &sunxi_pinctrl_irq_lock_class, + &sunxi_pinctrl_irq_request_class);irq_set_chip_and_handler (irqno, &sunxi_pinctrl_edge_irq_chip, handle_edge_irq);irq_set_chip_data (irqno, pctl);
Greg Kroah-Hartman
maintainerPATCH 114/186 igc: igc_write_phy_reg_gpy: drop premature return
In reply to Greg Kroah-HartmanFrom: Sasha Neftin <[email protected]>
commit c4208653a327a09da1e9e7b10299709b6d9b17bf upstream.
Similar to "igc_read_phy_reg_gpy: drop premature return" patch. igc_write_phy_reg_gpy checks the return value from igc_write_phy_reg_mdic and if it's not 0, returns immediately. By doing this, it leaves the HW semaphore in the acquired state.
Drop this premature return statement, the function returns after releasing the semaphore immediately anyway.
--- drivers/net/ethernet/intel/igc/igc_phy.c | 2 -- 1 file changed, 2 deletions(-)
drivers/net/ethernet/intel/igc/igc_phy.c +0 -2
@@ -746,8 +746,6 @@ s32 igc_write_phy_reg_gpy(struct igc_hwif (ret_val)return ret_val; ret_val =igc_write_phy_reg_mdic (hw, offset, data); -if (ret_val) -return ret_val; hw->phy.ops.release (hw); }else { ret_val = igc_write_xmdio_reg(hw, (u16)offset, dev_addr,
Greg Kroah-Hartman
maintainerPATCH 115/186 ibmvnic: free reset-work-item when flushing
In reply to Greg Kroah-HartmanFrom: Sukadev Bhattiprolu <[email protected]>
commit 8d0657f39f487d904fca713e0bc39c2707382553 upstream.
Fix a tiny memory leak when flushing the reset work queue.
--- drivers/net/ethernet/ibm/ibmvnic.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/ethernet/ibm/ibmvnic.c +3 -1
@@ -2780,8 +2780,10 @@ static int ibmvnic_reset(struct ibmvnic_* flush reset queue and process this reset */ if (adapter->force_reset_recovery && !list_empty (&adapter->rwi_list)) { -list_for_each_safe (entry, tmp_entry, &adapter->rwi_list) +list_for_each_safe (entry, tmp_entry, &adapter->rwi_list) {list_del (entry); +kfree (list_entry(entry ,struct ibmvnic_rwi ,list )); + } } rwi->reset_reason = reason;list_add_tail (&rwi->list, &adapter->rwi_list);
Greg Kroah-Hartman
maintainerPATCH 116/186 memfd: fix F_SEAL_WRITE after shmem huge page allocated
In reply to Greg Kroah-HartmanFrom: Hugh Dickins <[email protected]>
commit f2b277c4d1c63a85127e8aa2588e9cc3bd21cb99 upstream.
Wangyong reports: after enabling tmpfs filesystem to support transparent hugepage with the following command:
echo always > /sys/kernel/mm/transparent_hugepage/shmem_enabled
the docker program tries to add F_SEAL_WRITE through the following command, but it fails unexpectedly with errno EBUSY:
fcntl(5, F_ADD_SEALS, F_SEAL_WRITE) = -1.
That is because memfd_tag_pins() and memfd_wait_for_pins() were never updated for shmem huge pages: checking page_mapcount() against page_count() is hopeless on THP subpages - they need to check total_mapcount() against page_count() on THP heads only.
Make memfd_tag_pins() (compared > 1) as strict as memfd_wait_for_pins() (compared != 1): either can be justified, but given the non-atomic total_mapcount() calculation, it is better now to be strict. Bear in mind that total_mapcount() itself scans all of the THP subpages, when choosing to take an XA_CHECK_SCHED latency break.
Also fix the unlikely xa_is_value() case in memfd_wait_for_pins(): if a page has been swapped out since memfd_tag_pins(), then its refcount must have fallen, and so it can safely be untagged.
--- mm/memfd.c | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-)
mm/memfd.c +28 -12
@@ -31,20 +31,28 @@static void memfd_tag_pins (struct xa_state *xas) {struct page *page; -unsigned int tagged =0 ; +int latency =0 ; +int cache_count;lru_add_drain ();xas_lock_irq (xas);xas_for_each (xas, page,ULONG_MAX ) { -if (xa_is_value (page)) -continue ; - page =find_subpage (page, xas->xa_index); -if (page_count (page) -page_mapcount (page) >1 ) + cache_count =1 ; +if (!xa_is_value (page) && +PageTransHuge (page) && !PageHuge (page)) + cache_count =HPAGE_PMD_NR ; + +if (!xa_is_value (page) && +page_count (page) -total_mapcount (page) != cache_count)xas_set_mark (xas,MEMFD_TAG_PINNED ); +if (cache_count !=1 ) +xas_set (xas, page->index + cache_count); -if (++tagged %XA_CHECK_SCHED ) + latency += cache_count; +if (latency <XA_CHECK_SCHED )continue ; + latency =0 ;xas_pause (xas);xas_unlock_irq (xas);
@@ -73,7 +81,8 @@ static int memfd_wait_for_pins(struct ad error =0 ;for (scan =0 ; scan <=LAST_SCAN ; scan++) { -unsigned int tagged =0 ; +int latency =0 ; +int cache_count;if (!xas_marked (&xas,MEMFD_TAG_PINNED ))break ;
@@ -87,10 +96,14 @@ static int memfd_wait_for_pins(struct adxas_lock_irq (&xas);xas_for_each_marked (&xas, page,ULONG_MAX ,MEMFD_TAG_PINNED ) {bool clear = true; -if (xa_is_value (page)) -continue ; - page =find_subpage (page, xas.xa_index); -if (page_count (page) -page_mapcount (page) !=1 ) { + + cache_count =1 ; +if (!xa_is_value (page) && +PageTransHuge (page) && !PageHuge (page)) + cache_count =HPAGE_PMD_NR ; + +if (!xa_is_value (page) && cache_count != +page_count (page) -total_mapcount (page)) {/* * On the last scan, we clean up all those tags * we inserted; but make a note that we still
@@ -103,8 +116,11 @@ static int memfd_wait_for_pins(struct ad }if (clear)xas_clear_mark (&xas,MEMFD_TAG_PINNED ); -if (++tagged %XA_CHECK_SCHED ) + + latency += cache_count; +if (latency <XA_CHECK_SCHED )continue ; + latency =0 ;xas_pause (&xas);xas_unlock_irq (&xas);
Greg Kroah-Hartman
maintainerPATCH 117/186 s390/setup: preserve memory at OLDMEM_BASE and OLDMEM_SIZE
In reply to Greg Kroah-HartmanFrom: Alexander Egorenkov <[email protected]>
commit 6b4b54c7ca347bcb4aa7a3cc01aa16e84ac7fbe4 upstream.
We need to preserve the values at OLDMEM_BASE and OLDMEM_SIZE which are used by zgetdump in case when kdump crashes. In that case zgetdump will attempt to read OLDMEM_BASE and OLDMEM_SIZE in order to find out where the memory range [0 - OLDMEM_SIZE] belonging to the production kernel is.
--- arch/s390/kernel/setup.c | 2 ++ 1 file changed, 2 insertions(+)
arch/s390/kernel/setup.c +2 -0
@@ -800,6 +800,8 @@ static void __init check_initrd(void)static void __init reserve_kernel (void ) {memblock_reserve (0 ,STARTUP_NORMAL_OFFSET ); +memblock_reserve (OLDMEM_BASE ,sizeof (unsigned long )); +memblock_reserve (OLDMEM_SIZE ,sizeof (unsigned long ));memblock_reserve (__amode31_base, __eamode31 - __samode31);memblock_reserve (__pa (sclp_early_sccb),EXT_SCCB_READ_SCP );memblock_reserve (__pa (_stext), _end - _stext);
Greg Kroah-Hartman
maintainerPATCH 118/186 s390/extable: fix exception table sorting
In reply to Greg Kroah-HartmanFrom: Heiko Carstens <[email protected]>
commit c194dad21025dfd043210912653baab823bdff67 upstream.
s390 has a swap_ex_entry_fixup function, however it is not being used since common code expects a swap_ex_entry_fixup define. If it is not defined the default implementation will be used. So fix this by adding a proper define.
However also the implementation of the function must be fixed, since a NULL value for handler has a special meaning and must not be adjusted.
Luckily all of this doesn't fix a real bug currently: the main extable is correctly sorted during build time, and for runtime sorting there is currently no case where the handler field is not NULL.
--- arch/s390/include/asm/extable.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
arch/s390/include/asm/extable.h +7 -2
@@ -69,8 +69,13 @@ static inline void swap_ex_entry_fixup(s { a->fixup = b->fixup + delta; b->fixup = tmp.fixup - delta; - a->handler = b->handler + delta; - b->handler = tmp.handler - delta; + a->handler = b->handler; +if (a->handler) + a->handler += delta; + b->handler = tmp.handler; +if (b->handler) + b->handler -= delta; } +#define swap_ex_entry_fixup swap_ex_entry_fixup#endif
Greg Kroah-Hartman
maintainerPATCH 119/186 sched: Fix yet more sched_fork() races
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit b1e8206582f9d680cff7d04828708c8b6ab32957 upstream.
Where commit 4ef0c5c6b5ba ("kernel/sched: Fix sched_fork() access an invalid sched_task_group") fixed a fork race vs cgroup, it opened up a race vs syscalls by not placing the task on the runqueue before it gets exposed through the pidhash.
Commit 13765de8148f ("sched/fair: Fix fault in reweight_entity") is trying to fix a single instance of this, instead fix the whole class of issues, effectively reverting this commit.
--- include/linux/sched/task.h | 4 ++-- kernel/fork.c | 13 ++++++++++++- kernel/sched/core.c | 34 +++++++++++++++++++++------------- 3 files changed, 35 insertions(+), 16 deletions(-)
include/linux/sched/task.h +2 -2
@@ -54,8 +54,8 @@ extern asmlinkage void schedule_tail(strextern void init_idle (struct task_struct *idle,int cpu);extern int sched_fork (unsigned long clone_flags,struct task_struct *p); -extern void sched_post_fork (struct task_struct *p, -struct kernel_clone_args *kargs); +extern void sched_cgroup_fork (struct task_struct *p,struct kernel_clone_args *kargs); +extern void sched_post_fork (struct task_struct *p);extern void sched_dead (struct task_struct *p);void __noreturn do_task_dead (void );
kernel/fork.c +12 -1
@@ -2294,6 +2294,17 @@ static __latent_entropy struct task_stru goto bad_fork_put_pidfd;/* +* Now that the cgroups are pinned, re-clone the parent cgroup and put +* the new task on the correct runqueue. All this *before* the task +* becomes visible. +* +* This isn't part of ->can_fork() because while the re-cloning is +* cgroup specific, it unconditionally needs to place the task on a +* runqueue. +*/ +sched_cgroup_fork (p, args); + +/* * From this point on we must avoid any synchronous user-space * communication until we take the tasklist-lock. In particular, we do * not want user-space to be able to predict the process start-time by
@@ -2402,7 +2413,7 @@ static __latent_entropy struct task_strufd_install (pidfd, pidfile);proc_fork_connector (p); -sched_post_fork (p, args); +sched_post_fork (p);cgroup_post_fork (p, args);perf_event_fork (p);
kernel/sched/core.c +21 -13
@@ -1203,9 +1203,8 @@ int tg_nop(struct task_group *tg, void * }#endif -static void set_load_weight (struct task_struct *p) +static void set_load_weight (struct task_struct *p,bool update_load) { -bool update_load = !(READ_ONCE (p->__state) &TASK_NEW );int prio = p->static_prio -MAX_RT_PRIO ;struct load_weight *load = &p->se.load;
@@ -4393,7 +4392,7 @@ int sched_fork(unsigned long clone_flags p->static_prio =NICE_TO_PRIO (0 ); p->prio = p->normal_prio = p->static_prio; -set_load_weight (p); +set_load_weight (p, false);/* * We don't need the reset flag anymore after the fork. It has
@@ -4411,6 +4410,7 @@ int sched_fork(unsigned long clone_flagsinit_entity_runnable_average (&p->se); +#ifdef CONFIG_SCHED_INFO if (likely (sched_info_on ()))memset (&p->sched_info,0 ,sizeof (p->sched_info));
@@ -4426,18 +4426,23 @@ int sched_fork(unsigned long clone_flagsreturn 0 ; } -void sched_post_fork (struct task_struct *p,struct kernel_clone_args *kargs) +void sched_cgroup_fork (struct task_struct *p,struct kernel_clone_args *kargs) {unsigned long flags; -#ifdef CONFIG_CGROUP_SCHED -struct task_group *tg; -#endif +/* +* Because we're not yet on the pid-hash, p->pi_lock isn't strictly +* required yet, but lockdep gets upset if rules are violated. +*/ raw_spin_lock_irqsave (&p->pi_lock, flags);#ifdef CONFIG_CGROUP_SCHED - tg =container_of (kargs->cset->subsys[cpu_cgrp_id], - struct task_group, css); - p->sched_task_group =autogroup_task_group (p, tg); +if (1 ) { +struct task_group *tg; + tg =container_of (kargs->cset->subsys[cpu_cgrp_id], + struct task_group, css); + tg =autogroup_task_group (p, tg); + p->sched_task_group = tg; + }#endif rseq_migrate (p);/*
@@ -4448,7 +4453,10 @@ void sched_post_fork(struct task_structif (p->sched_class->task_fork) p->sched_class->task_fork (p);raw_spin_unlock_irqrestore (&p->pi_lock, flags); +} +void sched_post_fork (struct task_struct *p) +{uclamp_post_fork (p); }
@@ -6880,7 +6888,7 @@ void set_user_nice(struct task_struct *pput_prev_task (rq, p); p->static_prio =NICE_TO_PRIO (nice); -set_load_weight (p); +set_load_weight (p, true); old_prio = p->prio; p->prio =effective_prio (p);
@@ -7171,7 +7179,7 @@ static void __setscheduler_params(struct*/ p->rt_priority = attr->sched_priority; p->normal_prio =normal_prio (p); -set_load_weight (p); +set_load_weight (p, true); }/*
@@ -9410,7 +9418,7 @@ void __init sched_init(void)#endif } -set_load_weight (&init_task); +set_load_weight (&init_task, false);/* * The boot idle thread does lazy MMU switching as well:
Greg Kroah-Hartman
maintainerPATCH 120/186 arm64: dts: rockchip: drop pclk_xpcs from gmac0 on rk3568
In reply to Greg Kroah-HartmanFrom: Frank Wunderlich <[email protected]>
[ Upstream commit 85a8bccfa945680dc561f06b65ea01341d2033fc ]
pclk_xpcs is not supported by mainline driver and breaks dtbs_check
following warnings occour, and many more
rk3568-evb1-v10.dt.yaml: ethernet@fe2a0000: clocks:
[[15, 386], [15, 389], [15, 389], [15, 184], [15, 180], [15, 181],
[15, 389], [15, 185], [15, 172]] is too long
From schema: Documentation/devicetree/bindings/net/snps,dwmac.yaml
rk3568-evb1-v10.dt.yaml: ethernet@fe2a0000: clock-names:
['stmmaceth', 'mac_clk_rx', 'mac_clk_tx', 'clk_mac_refout', 'aclk_mac',
'pclk_mac', 'clk_mac_speed', 'ptp_ref', 'pclk_xpcs'] is too long
From schema: Documentation/devicetree/bindings/net/snps,dwmac.yamlafter removing it, the clock and other warnings are gone.
pclk_xpcs on gmac is used to support QSGMII, but this requires a driver supporting it.
Once xpcs support is introduced, the clock can be added to the documentation and both controllers.
--- arch/arm64/boot/dts/rockchip/rk3568.dtsi | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
arch/arm64/boot/dts/rockchip/rk3568.dtsi +2 -4
@@ -32,13 +32,11 @@ clocks = <&cru SCLK_GMAC0>, <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0_RX_TX>, <&cru CLK_MAC0_REFOUT>, <&cru ACLK_GMAC0>, <&cru PCLK_GMAC0>, - <&cru SCLK_GMAC0_RX_TX>, <&cru CLK_GMAC0_PTP_REF>, - <&cru PCLK_XPCS>; + <&cru SCLK_GMAC0_RX_TX>, <&cru CLK_GMAC0_PTP_REF>; clock-names = "stmmaceth", "mac_clk_rx", "mac_clk_tx", "clk_mac_refout", "aclk_mac", "pclk_mac", - "clk_mac_speed", "ptp_ref", - "pclk_xpcs"; + "clk_mac_speed", "ptp_ref"; resets = <&cru SRST_A_GMAC0>; reset-names = "stmmaceth"; rockchip,grf = <&grf>;
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 121/186 arm64: dts: juno: Remove GICv2m dma-range
In reply to Greg Kroah-HartmanFrom: Robin Murphy <[email protected]>
[ Upstream commit 31eeb6b09f4053f32a30ce9fbcdfca31f713028d ]
Although it is painstakingly honest to describe all 3 PCI windows in "dma-ranges", it misses the the subtle distinction that the window for the GICv2m range is normally programmed for Device memory attributes rather than Normal Cacheable like the DRAM windows. Since MMU-401 only offers stage 2 translation, this means that when the PCI SMMU is enabled, accesses through that IPA range unexpectedly lose coherency if mapped as cacheable at the SMMU, due to the attribute combining rules. Since an extra 256KB is neither here nor there when we still have 10GB worth of usable address space, rather than attempting to describe and cope with this detail let's just remove the offending range. If the SMMU is not used then it makes no difference anyway.
--- arch/arm64/boot/dts/arm/juno-base.dtsi | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
arch/arm64/boot/dts/arm/juno-base.dtsi +1 -2
@@ -543,8 +543,7 @@ <0x02000000 0x00 0x50000000 0x00 0x50000000 0x0 0x08000000>, <0x42000000 0x40 0x00000000 0x40 0x00000000 0x1 0x00000000>; /* Standard AXI Translation entries as programmed by EDK2 */ - dma-ranges = <0x02000000 0x0 0x2c1c0000 0x0 0x2c1c0000 0x0 0x00040000>, - <0x02000000 0x0 0x80000000 0x0 0x80000000 0x0 0x80000000>, + dma-ranges = <0x02000000 0x0 0x80000000 0x0 0x80000000 0x0 0x80000000>, <0x43000000 0x8 0x00000000 0x8 0x00000000 0x2 0x00000000>; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 7>;
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 122/186 arm64: dts: rockchip: fix Quartz64-A ddr regulator voltage
In reply to Greg Kroah-HartmanFrom: Peter Geis <[email protected]>
[ Upstream commit ad02776cf8d083e28b1ca4d93d8b1949668c27cc ]
The Quartz64 Model A uses a voltage divider to ensure ddr voltage is within specification from the default regulator configuration. Adjusting this voltage is detrimental, and currently causes the ddr voltage to be about 0.8v.
Remove the min and max voltage setpoints for the ddr regulator.
--- arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts | 2 -- 1 file changed, 2 deletions(-)
arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts +0 -2
@@ -285,8 +285,6 @@ vcc_ddr: DCDC_REG3 { regulator-always-on; regulator-boot-on; - regulator-min-microvolt = <1100000>; - regulator-max-microvolt = <1100000>; regulator-initial-mode = <0x2>; regulator-name = "vcc_ddr"; regulator-state-mem {
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 123/186 arm64: dts: imx8mm: Fix VPU Hanging
In reply to Greg Kroah-HartmanFrom: Adam Ford <[email protected]>
[ Upstream commit ef3075d6638d3d5353a97fcc7bb0338fc85675f5 ]
The vpumix power domain has a reset assigned to it, however when used, it causes a system hang. Testing has shown that it does not appear to be needed anywhere.
--- arch/arm64/boot/dts/freescale/imx8mm.dtsi | 1 - 1 file changed, 1 deletion(-)
arch/arm64/boot/dts/freescale/imx8mm.dtsi +0 -1
@@ -681,7 +681,6 @@ clocks = <&clk IMX8MM_CLK_VPU_DEC_ROOT>; assigned-clocks = <&clk IMX8MM_CLK_VPU_BUS>; assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_800M>; - resets = <&src IMX8MQ_RESET_VPU_RESET>; }; pgc_vpu_g1: power-domain@7 {
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 124/186 iommu/amd: Simplify pagetable freeing
In reply to Greg Kroah-HartmanFrom: Robin Murphy <[email protected]>
[ Upstream commit 6b3106e9ba2de7320a71291cedcefdcf1195ad58 ]
For reasons unclear, pagetable freeing is an effectively recursive method implemented via an elaborate system of templated functions that turns out to account for 25% of the object file size. Implementing it using regular straightforward recursion makes the code simpler, and seems like a good thing to do before we work on it further. As part of that, also fix the types to avoid all the needless casting back and forth which just gets in the way.
--- drivers/iommu/amd/io_pgtable.c | 82 ++++++++++++++-------------------- 1 file changed, 34 insertions(+), 48 deletions(-)
drivers/iommu/amd/io_pgtable.c +34 -48
@@ -84,49 +84,45 @@ static void free_page_list(struct page *freelist) } } -static struct page *free_pt_page (unsigned long pt,struct page *freelist) +static struct page *free_pt_page (u64 *pt,struct page *freelist) { -struct page *p =virt_to_page ((void *)pt); +struct page *p =virt_to_page (pt); p->freelist = freelist;return p; } -#define DEFINE_FREE_PT_FN (LVL ,FN ) \ -static struct page *free_pt_##LVL (unsigned long __pt, struct page *freelist) \ -{ \ - unsigned long p; \ - u64 *pt; \ - int i; \ - \ - pt = (u64 *)__pt; \ - \ - for (i = 0; i < 512; ++i) { \ -/* PTE present? */ \ -if (!IOMMU_PTE_PRESENT (pt[i])) \ -continue ; \ - \ -/* Large PTE? */ \ -if (PM_PTE_LEVEL (pt[i]) ==0 || \ -PM_PTE_LEVEL (pt[i]) ==7 ) \ -continue ; \ - \ - p = (unsigned long )IOMMU_PTE_PAGE (pt[i]); \ - freelist =FN (p, freelist); \ - } \ - \ -return free_pt_page ((unsigned long )pt, freelist); \ -} +static struct page *free_pt_lvl (u64 *pt,struct page *freelist,int lvl) +{ +u64 *p; +int i; + +for (i =0 ; i <512 ; ++i) { +/* PTE present? */ +if (!IOMMU_PTE_PRESENT (pt[i])) +continue ; -DEFINE_FREE_PT_FN(l2, free_pt_page) -DEFINE_FREE_PT_FN(l3, free_pt_l2) -DEFINE_FREE_PT_FN(l4, free_pt_l3) -DEFINE_FREE_PT_FN(l5, free_pt_l4) -DEFINE_FREE_PT_FN(l6, free_pt_l5) +/* Large PTE? */ +if (PM_PTE_LEVEL (pt[i]) ==0 || +PM_PTE_LEVEL (pt[i]) ==7 ) +continue ; -static struct page *free_sub_pt (unsigned long root,int mode, -struct page *freelist) +/* +* Free the next level. No need to look at l1 tables here since +* they can only contain leaf PTEs; just free them directly. +*/ + p =IOMMU_PTE_PAGE (pt[i]); +if (lvl >2 ) + freelist =free_pt_lvl (p, freelist, lvl -1 ); +else + freelist =free_pt_page (p, freelist); + } + +return free_pt_page (pt, freelist); +} + +static struct page *free_sub_pt (u64 *root,int mode,struct page *freelist) {switch (mode) {case PAGE_MODE_NONE :
@@ -136,19 +132,11 @@ static struct page *free_sub_pt(unsigned long root, int mode, freelist =free_pt_page (root, freelist);break ;case PAGE_MODE_2_LEVEL : - freelist =free_pt_l2 (root, freelist); -break ;case PAGE_MODE_3_LEVEL : - freelist =free_pt_l3 (root, freelist); -break ;case PAGE_MODE_4_LEVEL : - freelist =free_pt_l4 (root, freelist); -break ;case PAGE_MODE_5_LEVEL : - freelist =free_pt_l5 (root, freelist); -break ;case PAGE_MODE_6_LEVEL : - freelist =free_pt_l6 (root, freelist); +free_pt_lvl (root, freelist, mode);break ;default :BUG ();
@@ -364,7 +352,7 @@ static u64 *fetch_pte(struct amd_io_pgtable *pgtable,static struct page *free_clear_pte (u64 *pte,u64 pteval,struct page *freelist) { -unsigned long pt; +u64 *pt;int mode;while (cmpxchg64 (pte, pteval,0 ) != pteval) {
@@ -375,7 +363,7 @@ static struct page *free_clear_pte(u64 *pte, u64 pteval, struct page *freelist)if (!IOMMU_PTE_PRESENT (pteval))return freelist; - pt = (unsigned long )IOMMU_PTE_PAGE (pteval); + pt =IOMMU_PTE_PAGE (pteval); mode =IOMMU_PTE_MODE (pteval);return free_sub_pt (pt, mode, freelist);
@@ -512,7 +500,6 @@ static void v1_free_pgtable(struct io_pgtable *iop) struct amd_io_pgtable *pgtable = container_of(iop, struct amd_io_pgtable, iop);struct protection_domain *dom;struct page *freelist =NULL ; -unsigned long root;if (pgtable->mode ==PAGE_MODE_NONE )return ;
@@ -529,8 +516,7 @@ static void v1_free_pgtable(struct io_pgtable *iop)BUG_ON (pgtable->mode <PAGE_MODE_NONE || pgtable->mode >PAGE_MODE_6_LEVEL ); - root = (unsigned long )pgtable->root; - freelist =free_sub_pt (root, pgtable->mode, freelist); + freelist =free_sub_pt (pgtable->root, pgtable->mode, freelist);free_page_list (freelist); }
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 125/186 iommu/amd: Use put_pages_list
In reply to Greg Kroah-HartmanFrom: Matthew Wilcox (Oracle) <[email protected]>
[ Upstream commit ce00eece6909c266da123fd147172d745a4f14a0 ]
page->freelist is for the use of slab. We already have the ability to free a list of pages in the core mm, but it requires the use of a list_head and for the pages to be chained together through page->lru. Switch the AMD IOMMU code over to using free_pages_list().
--- drivers/iommu/amd/io_pgtable.c | 50 ++++++++++++---------------------- 1 file changed, 18 insertions(+), 32 deletions(-)
drivers/iommu/amd/io_pgtable.c +18 -32
@@ -74,26 +74,14 @@ static u64 *first_pte_l7(u64 *pte, unsigned long *page_size,* ****************************************************************************/ -static void free_page_list (struct page *freelist) -{ -while (freelist !=NULL ) { -unsigned long p = (unsigned long )page_address (freelist); - - freelist = freelist->freelist; -free_page (p); - } -} - -static struct page *free_pt_page (u64 *pt,struct page *freelist) +static void free_pt_page (u64 *pt,struct list_head *freelist) {struct page *p =virt_to_page (pt); - p->freelist = freelist; - -return p; +list_add_tail (&p->lru, freelist); } -static struct page *free_pt_lvl (u64 *pt,struct page *freelist,int lvl) +static void free_pt_lvl (u64 *pt,struct list_head *freelist,int lvl) {u64 *p;int i;
@@ -114,22 +102,22 @@ static struct page *free_pt_lvl(u64 *pt, struct page *freelist, int lvl)*/ p =IOMMU_PTE_PAGE (pt[i]);if (lvl >2 ) - freelist =free_pt_lvl (p, freelist, lvl -1 ); +free_pt_lvl (p, freelist, lvl -1 );else - freelist =free_pt_page (p, freelist); +free_pt_page (p, freelist); } -return free_pt_page (pt, freelist); +free_pt_page (pt, freelist); } -static struct page *free_sub_pt (u64 *root,int mode,struct page *freelist) +static void free_sub_pt (u64 *root,int mode,struct list_head *freelist) {switch (mode) {case PAGE_MODE_NONE :case PAGE_MODE_7_LEVEL :break ;case PAGE_MODE_1_LEVEL : - freelist =free_pt_page (root, freelist); +free_pt_page (root, freelist);break ;case PAGE_MODE_2_LEVEL :case PAGE_MODE_3_LEVEL :
@@ -141,8 +129,6 @@ static struct page *free_sub_pt(u64 *root, int mode, struct page *freelist)default :BUG (); } - -return freelist; } void amd_iommu_domain_set_pgtable(struct protection_domain *domain,
@@ -350,7 +336,7 @@ static u64 *fetch_pte(struct amd_io_pgtable *pgtable,return pte; } -static struct page *free_clear_pte (u64 *pte,u64 pteval,struct page *freelist) +static void free_clear_pte (u64 *pte,u64 pteval,struct list_head *freelist) {u64 *pt;int mode;
@@ -361,12 +347,12 @@ static struct page *free_clear_pte(u64 *pte, u64 pteval, struct page *freelist) }if (!IOMMU_PTE_PRESENT (pteval)) -return freelist; +return ; pt =IOMMU_PTE_PAGE (pteval); mode =IOMMU_PTE_MODE (pteval); -return free_sub_pt (pt, mode, freelist); +free_sub_pt (pt, mode, freelist); }/*
@@ -380,7 +366,7 @@ static int iommu_v1_map_page(struct io_pgtable_ops *ops, unsigned long iova, phys_addr_t paddr, size_t size, int prot, gfp_t gfp) { struct protection_domain *dom = io_pgtable_ops_to_domain(ops); -struct page *freelist =NULL ; +LIST_HEAD (freelist);bool updated = false;u64 __pte, *pte;int ret, i, count;
@@ -400,9 +386,9 @@ static int iommu_v1_map_page(struct io_pgtable_ops *ops, unsigned long iova, goto out;for (i =0 ; i < count; ++i) - freelist =free_clear_pte (&pte[i], pte[i], freelist); +free_clear_pte (&pte[i], pte[i], &freelist); -if (freelist !=NULL ) +if (!list_empty (&freelist)) updated = true;if (count >1 ) {
@@ -437,7 +423,7 @@ static int iommu_v1_map_page(struct io_pgtable_ops *ops, unsigned long iova, }/* Everything flushed out, free pages now */ -free_page_list (freelist); +put_pages_list (&freelist);return ret; }
@@ -499,7 +485,7 @@ static void v1_free_pgtable(struct io_pgtable *iop) { struct amd_io_pgtable *pgtable = container_of(iop, struct amd_io_pgtable, iop);struct protection_domain *dom; -struct page *freelist =NULL ; +LIST_HEAD (freelist);if (pgtable->mode ==PAGE_MODE_NONE )return ;
@@ -516,9 +502,9 @@ static void v1_free_pgtable(struct io_pgtable *iop)BUG_ON (pgtable->mode <PAGE_MODE_NONE || pgtable->mode >PAGE_MODE_6_LEVEL ); - freelist =free_sub_pt (pgtable->root, pgtable->mode, freelist); +free_sub_pt (pgtable->root, pgtable->mode, &freelist); -free_page_list (freelist); +put_pages_list (&freelist); }static struct io_pgtable *v1_alloc_pgtable (struct io_pgtable_cfg *cfg,void *cookie)
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 126/186 iommu/amd: Fix I/O page table memory leak
In reply to Greg Kroah-HartmanFrom: Suravee Suthikulpanit <[email protected]>
[ Upstream commit 6b0b2d9a6a308bcd9300c2d83000a82812c56cea ]
The current logic updates the I/O page table mode for the domain before calling the logic to free memory used for the page table. This results in IOMMU page table memory leak, and can be observed when launching VM w/ pass-through devices.
Fix by freeing the memory used for page table before updating the mode.
--- drivers/iommu/amd/io_pgtable.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/iommu/amd/io_pgtable.c +6 -6
@@ -492,18 +492,18 @@ static void v1_free_pgtable(struct io_pgtable *iop) dom = container_of(pgtable, struct protection_domain, iop); -/* Update data structure */ -amd_iommu_domain_clr_pt_root (dom); - -/* Make changes visible to IOMMUs */ -amd_iommu_domain_update (dom); -/* Page-table is not visible to IOMMU anymore, so free it */ BUG_ON (pgtable->mode <PAGE_MODE_NONE || pgtable->mode >PAGE_MODE_6_LEVEL );free_sub_pt (pgtable->root, pgtable->mode, &freelist); +/* Update data structure */ +amd_iommu_domain_clr_pt_root (dom); + +/* Make changes visible to IOMMUs */ +amd_iommu_domain_update (dom); +put_pages_list (&freelist); }
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 127/186 MIPS: ralink: mt7621: do memory detection on KSEG1
In reply to Greg Kroah-HartmanFrom: Chuanhong Guo <[email protected]>
[ Upstream commit cc19db8b312a6c75645645f5cc1b45166b109006 ]
It's reported that current memory detection code occasionally detects larger memory under some bootloaders.
Current memory detection code tests whether address space wraps around on KSEG0, which is unreliable because it's cached.
Rewrite memory size detection to perform the same test on KSEG1 instead. While at it, this patch also does the following two things:
1. use a fixed pattern instead of a random function pointer as the magic value.
2. add an additional memory write and a second comparison as part of the test to prevent possible smaller memory detection result due to leftover values in memory.
--- arch/mips/ralink/mt7621.c | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-)
arch/mips/ralink/mt7621.c +23 -13
@@ -20,31 +20,41 @@#include "common.h" -static void *detect_magic__initdata = detect_memory_region; +#define MT7621_MEM_TEST_PATTERN 0xaa5555aa + +static u32 detect_magic__initdata ;phys_addr_t mips_cpc_default_phys_base (void ) {panic ("Cannot detect cpc address" ); } +static bool __init mt7621_addr_wraparound_test (phys_addr_t size) +{ +void *dm = (void *)KSEG1ADDR (&detect_magic); + +if (CPHYSADDR (dm + size) >=MT7621_LOWMEM_MAX_SIZE ) +return true; +__raw_writel (MT7621_MEM_TEST_PATTERN , dm); +if (__raw_readl (dm) !=__raw_readl (dm + size)) +return false; +__raw_writel (!MT7621_MEM_TEST_PATTERN , dm); +return __raw_readl (dm) ==__raw_readl (dm + size); +} +static void __init mt7621_memory_detect (void ) { -void *dm = &detect_magic;phys_addr_t size; -for (size =32 *SZ_1M ; size <256 *SZ_1M ; size <<=1 ) { -if (!__builtin_memcmp (dm, dm + size,sizeof (detect_magic))) -break ; +for (size =32 *SZ_1M ; size <=256 *SZ_1M ; size <<=1 ) { +if (mt7621_addr_wraparound_test (size)) { +memblock_add (MT7621_LOWMEM_BASE , size); +return ; + } } -if ((size ==256 *SZ_1M ) && - (CPHYSADDR (dm + size) <MT7621_LOWMEM_MAX_SIZE ) && -__builtin_memcmp (dm, dm + size,sizeof (detect_magic))) { -memblock_add (MT7621_LOWMEM_BASE ,MT7621_LOWMEM_MAX_SIZE ); -memblock_add (MT7621_HIGHMEM_BASE ,MT7621_HIGHMEM_SIZE ); - }else { -memblock_add (MT7621_LOWMEM_BASE , size); - } +memblock_add (MT7621_LOWMEM_BASE ,MT7621_LOWMEM_MAX_SIZE ); +memblock_add (MT7621_HIGHMEM_BASE ,MT7621_HIGHMEM_SIZE ); }void __init ralink_of_remap (void )
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 128/186 ARM: dts: switch timer config to common devkit8000 devicetree
In reply to Greg Kroah-HartmanFrom: Anthoine Bourgeois <[email protected]>
[ Upstream commit 64324ef337d0caa5798fa8fa3f6bbfbd3245868a ]
This patch allow lcd43 and lcd70 flavors to benefit from timer evolution.
--- .../arm/boot/dts/omap3-devkit8000-common.dtsi | 33 +++++++++++++++++++ arch/arm/boot/dts/omap3-devkit8000.dts | 33 ------------------- 2 files changed, 33 insertions(+), 33 deletions(-)
arch/arm/boot/dts/omap3-devkit8000-common.dtsi +33 -0
@@ -158,6 +158,39 @@ status = "disabled"; }; +/* Unusable as clocksource because of unreliable oscillator */ +&counter32k { + status = "disabled"; +}; + +/* Unusable as clockevent because if unreliable oscillator, allow to idle */ +&timer1_target { + /delete-property/ti,no-reset-on-init; + /delete-property/ti,no-idle; + timer@0 { + /delete-property/ti,timer-alwon; + }; +}; + +/* Preferred always-on timer for clocksource */ +&timer12_target { + ti,no-reset-on-init; + ti,no-idle; + timer@0 { + /* Always clocked by secure_32k_fck */ + }; +}; + +/* Preferred timer for clockevent */ +&timer2_target { + ti,no-reset-on-init; + ti,no-idle; + timer@0 { + assigned-clocks = <&gpt2_fck>; + assigned-clock-parents = <&sys_ck>; + }; +}; + &twl_gpio { ti,use-leds; /*
arch/arm/boot/dts/omap3-devkit8000.dts +0 -33
@@ -14,36 +14,3 @@ display2 = &tv0; }; }; - -/* Unusable as clocksource because of unreliable oscillator */ -&counter32k { - status = "disabled"; -}; - -/* Unusable as clockevent because if unreliable oscillator, allow to idle */ -&timer1_target { - /delete-property/ti,no-reset-on-init; - /delete-property/ti,no-idle; - timer@0 { - /delete-property/ti,timer-alwon; - }; -}; - -/* Preferred always-on timer for clocksource */ -&timer12_target { - ti,no-reset-on-init; - ti,no-idle; - timer@0 { - /* Always clocked by secure_32k_fck */ - }; -}; - -/* Preferred timer for clockevent */ -&timer2_target { - ti,no-reset-on-init; - ti,no-idle; - timer@0 { - assigned-clocks = <&gpt2_fck>; - assigned-clock-parents = <&sys_ck>; - }; -};
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 129/186 ARM: dts: Use 32KiHz oscillator on devkit8000
In reply to Greg Kroah-HartmanFrom: Anthoine Bourgeois <[email protected]>
[ Upstream commit 8840f5460a23759403f1f2860429dcbcc2f04a65 ]
Devkit8000 board seems to always used 32k_counter as clocksource. Restore this behavior.
If clocksource is back to 32k_counter, timer12 is now the clockevent source (as before) and timer2 is not longer needed here.
This commit fixes the same issue observed with commit 23885389dbbb ("ARM: dts: Fix timer regression for beagleboard revision c") when sleep is blocked until hitting keys over serial console.
--- arch/arm/boot/dts/omap3-devkit8000-common.dtsi | 17 +---------------- drivers/clocksource/timer-ti-dm-systimer.c | 3 +-- 2 files changed, 2 insertions(+), 18 deletions(-)
arch/arm/boot/dts/omap3-devkit8000-common.dtsi +1 -16
@@ -158,11 +158,6 @@ status = "disabled"; }; -/* Unusable as clocksource because of unreliable oscillator */ -&counter32k { - status = "disabled"; -}; - /* Unusable as clockevent because if unreliable oscillator, allow to idle */ &timer1_target { /delete-property/ti,no-reset-on-init;
@@ -172,7 +167,7 @@ }; }; -/* Preferred always-on timer for clocksource */ +/* Preferred timer for clockevent */ &timer12_target { ti,no-reset-on-init; ti,no-idle;
@@ -181,16 +176,6 @@ }; }; -/* Preferred timer for clockevent */ -&timer2_target { - ti,no-reset-on-init; - ti,no-idle; - timer@0 { - assigned-clocks = <&gpt2_fck>; - assigned-clock-parents = <&sys_ck>; - }; -}; - &twl_gpio { ti,use-leds; /*
drivers/clocksource/timer-ti-dm-systimer.c +1 -2
@@ -241,8 +241,7 @@ static void __init dmtimer_systimer_assign_alwon(void)bool quirk_unreliable_oscillator = false;/* Quirk unreliable 32 KiHz oscillator with incomplete dts */ -if (of_machine_is_compatible ("ti,omap3-beagle-ab4" ) || -of_machine_is_compatible ("timll,omap3-devkit8000" )) { +if (of_machine_is_compatible ("ti,omap3-beagle-ab4" )) { quirk_unreliable_oscillator = true; counter_32k = -ENODEV ; }
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 130/186 soc: fsl: guts: Revert commit 3c0d64e867ed
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit b113737cf12964a20cc3ba1ddabe6229099661c6 ]
This reverts commit 3c0d64e867ed
("soc: fsl: guts: reuse machine name from device tree").
A following patch will fix the missing memory allocation failure check instead.
--- drivers/soc/fsl/guts.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
drivers/soc/fsl/guts.c +3 -4
@@ -28,7 +28,6 @@ struct fsl_soc_die_attr {static struct guts *guts;static struct soc_device_attribute soc_dev_attr;static struct soc_device *soc_dev; -static struct device_node *root;/* SoC die attribute definition for QorIQ platform */
@@ -138,7 +137,7 @@ static u32 fsl_guts_get_svr(void)static int fsl_guts_probe (struct platform_device *pdev) { -struct device_node *np = pdev->dev.of_node; +struct device_node *root, *np = pdev->dev.of_node;struct device *dev = &pdev->dev;const struct fsl_soc_die_attr *soc_die;const char *machine;
@@ -159,8 +158,9 @@ static int fsl_guts_probe(struct platform_device *pdev) root =of_find_node_by_path ("/" );if (of_property_read_string (root,"model" , &machine))of_property_read_string_index (root,"compatible" ,0 , &machine); +of_node_put (root);if (machine) - soc_dev_attr.machine = machine; + soc_dev_attr.machine =devm_kstrdup (dev, machine,GFP_KERNEL ); svr =fsl_guts_get_svr (); soc_die =fsl_soc_die_match (svr, fsl_soc_die);
@@ -195,7 +195,6 @@ static int fsl_guts_probe(struct platform_device *pdev)static int fsl_guts_remove (struct platform_device *dev) {soc_device_unregister (soc_dev); -of_node_put (root);return 0 ; }
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 131/186 soc: fsl: guts: Add a missing memory allocation failure check
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit b9abe942cda43a1d46a0fd96efb54f1aa909f757 ]
If 'devm_kstrdup()' fails, we should return -ENOMEM.
While at it, move the 'of_node_put()' call in the error handling path and after the 'machine' has been copied.
Better safe than sorry.
Depends-on: fddacc7ff4dd ("soc: fsl: guts: Revert commit 3c0d64e867ed")
--- drivers/soc/fsl/guts.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/soc/fsl/guts.c +7 -2
@@ -158,9 +158,14 @@ static int fsl_guts_probe(struct platform_device *pdev) root =of_find_node_by_path ("/" );if (of_property_read_string (root,"model" , &machine))of_property_read_string_index (root,"compatible" ,0 , &machine); -of_node_put (root); -if (machine) +if (machine) { soc_dev_attr.machine =devm_kstrdup (dev, machine,GFP_KERNEL ); +if (!soc_dev_attr.machine) { +of_node_put (root); +return -ENOMEM ; + } + } +of_node_put (root); svr =fsl_guts_get_svr (); soc_die =fsl_soc_die_match (svr, fsl_soc_die);
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 132/186 soc: fsl: qe: Check of ioremap return value
In reply to Greg Kroah-HartmanFrom: Jiasheng Jiang <[email protected]>
[ Upstream commit a222fd8541394b36b13c89d1698d9530afd59a9c ]
As the possible failure of the ioremap(), the par_io could be NULL. Therefore it should be better to check it and return error in order to guarantee the success of the initiation.
But, I also notice that all the caller like mpc85xx_qe_par_io_init() in arch/powerpc/platforms/85xx/common.c don't check the return value of the par_io_init().
Actually, par_io_init() needs to check to handle the potential error. I will submit another patch to fix that.
Anyway, par_io_init() itsely should be fixed.
--- drivers/soc/fsl/qe/qe_io.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/soc/fsl/qe/qe_io.c +2 -0
@@ -35,6 +35,8 @@ int par_io_init(struct device_node *np)if (ret)return ret; par_io =ioremap (res.start,resource_size (&res)); +if (!par_io) +return -ENOMEM ;if (!of_property_read_u32 (np,"num-ports" , &num_ports)) num_par_io_ports = num_ports;
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 133/186 soc: imx: gpcv2: Fix clock disabling imbalance in error path
In reply to Greg Kroah-HartmanFrom: Laurent Pinchart <[email protected]>
[ Upstream commit fa231bef3b34f1670b240409c11e59a3ce095e6d ]
The imx_pgc_power_down() starts by enabling the domain clocks, and thus disables them in the error path. Commit 18c98573a4cf ("soc: imx: gpcv2:
add domain option to keep domain clocks enabled") made the clock enable conditional, but forgot to add the same condition to the error path. This can result in a clock enable/disable imbalance. Fix it.
--- drivers/soc/imx/gpcv2.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/soc/imx/gpcv2.c +2 -1
@@ -382,7 +382,8 @@ static int imx_pgc_power_down(struct generic_pm_domain *genpd)return 0 ; out_clk_disable: -clk_bulk_disable_unprepare (domain->num_clks, domain->clks); +if (!domain->keep_clocks) +clk_bulk_disable_unprepare (domain->num_clks, domain->clks);return ret; }
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 134/186 netfilter: nf_tables: prefer kfree_rcu(ptr, rcu) variant
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit ae089831ff28a115908b8d796f667c2dadef1637 ]
While kfree_rcu(ptr) _is_ supported, it has some limitations.
Given that 99.99% of kfree_rcu() users [1] use the legacy two parameters variant, and @catchall objects do have an rcu head, simply use it.
Choice of kfree_rcu(ptr) variant was probably not intentional.
[1] including calls from net/netfilter/nf_tables_api.c
--- net/netfilter/nf_tables_api.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
net/netfilter/nf_tables_api.c +2 -2
@@ -4486,7 +4486,7 @@ static void nft_set_catchall_destroy(const struct nft_ctx *ctx,list_for_each_entry_safe (catchall, next, &set->catchall_list, list) {list_del_rcu (&catchall->list);nft_set_elem_destroy (set, catchall->elem, true); -kfree_rcu (catchall); +kfree_rcu (catchall, rcu); } }
@@ -5653,7 +5653,7 @@ static void nft_setelem_catchall_remove(const struct net *net,list_for_each_entry_safe (catchall, next, &set->catchall_list, list) {if (catchall->elem == elem->priv) {list_del_rcu (&catchall->list); -kfree_rcu (catchall); +kfree_rcu (catchall, rcu);break ; } }
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 135/186 ARM: tegra: Move panels to AUX bus
In reply to Greg Kroah-HartmanFrom: Thierry Reding <[email protected]>
[ Upstream commit 8d3b01e0d4bb54368d73d0984466d72c2eeeac74 ]
Move the eDP panel on Venice 2 and Nyan boards into the corresponding AUX bus device tree node. This allows us to avoid a nasty circular dependency that would otherwise be created between the DPAUX and panel nodes via the DDC/I2C phandle.
--- arch/arm/boot/dts/tegra124-nyan-big.dts | 15 +++++++++------ arch/arm/boot/dts/tegra124-nyan-blaze.dts | 15 +++++++++------ arch/arm/boot/dts/tegra124-venice2.dts | 14 +++++++------- 3 files changed, 25 insertions(+), 19 deletions(-)
arch/arm/boot/dts/tegra124-nyan-big.dts +9 -6
@@ -13,12 +13,15 @@ "google,nyan-big-rev1", "google,nyan-big-rev0", "google,nyan-big", "google,nyan", "nvidia,tegra124"; - panel: panel { - compatible = "auo,b133xtn01"; - - power-supply = <&vdd_3v3_panel>; - backlight = <&backlight>; - ddc-i2c-bus = <&dpaux>; + host1x@50000000 { + dpaux@545c0000 { + aux-bus { + panel: panel { + compatible = "auo,b133xtn01"; + backlight = <&backlight>; + }; + }; + }; }; mmc@700b0400 { /* SD Card on this bus */
arch/arm/boot/dts/tegra124-nyan-blaze.dts +9 -6
@@ -15,12 +15,15 @@ "google,nyan-blaze-rev0", "google,nyan-blaze", "google,nyan", "nvidia,tegra124"; - panel: panel { - compatible = "samsung,ltn140at29-301"; - - power-supply = <&vdd_3v3_panel>; - backlight = <&backlight>; - ddc-i2c-bus = <&dpaux>; + host1x@50000000 { + dpaux@545c0000 { + aux-bus { + panel: panel { + compatible = "samsung,ltn140at29-301"; + backlight = <&backlight>; + }; + }; + }; }; sound {
arch/arm/boot/dts/tegra124-venice2.dts +7 -7
@@ -48,6 +48,13 @@ dpaux@545c0000 { vdd-supply = <&vdd_3v3_panel>; status = "okay"; + + aux-bus { + panel: panel { + compatible = "lg,lp129qe"; + backlight = <&backlight>; + }; + }; }; };
@@ -1079,13 +1086,6 @@ }; }; - panel: panel { - compatible = "lg,lp129qe"; - power-supply = <&vdd_3v3_panel>; - backlight = <&backlight>; - ddc-i2c-bus = <&dpaux>; - }; - vdd_mux: regulator@0 { compatible = "regulator-fixed"; regulator-name = "+VDD_MUX";
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 136/186 Bluetooth: Fix bt_skb_sendmmsg not allocating partial chunks
In reply to Greg Kroah-HartmanFrom: Luiz Augusto von Dentz <[email protected]>
[ Upstream commit 29fb608396d6a62c1b85acc421ad7a4399085b9f ]
Since bt_skb_sendmmsg can be used with the likes of SOCK_STREAM it shall return the partial chunks it could allocate instead of freeing everything as otherwise it can cause problems like bellow.
--- include/net/bluetooth/bluetooth.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
include/net/bluetooth/bluetooth.h +1 -2
@@ -497,8 +497,7 @@ static inline struct sk_buff *bt_skb_sendmmsg(struct sock *sk, tmp =bt_skb_sendmsg (sk, msg, len, mtu, headroom, tailroom);if (IS_ERR (tmp)) { -kfree_skb (skb); -return tmp; +return skb; } len -= tmp->len;
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 137/186 can: etas_es58x: change opened_channel_cnts type from atomic_t to u8
In reply to Greg Kroah-HartmanFrom: Vincent Mailhol <[email protected]>
[ Upstream commit f4896248e9025ff744b4147e6758274a1cb8cbae ]
The driver uses an atomic_t variable: struct es58x_device::opened_channel_cnt to keep track of the number of opened channels in order to only allocate memory for the URBs when this count changes from zero to one.
While the intent was to prevent race conditions, the choice of an atomic_t turns out to be a bad idea for several reasons:
- implementation is incorrect and fails to decrement opened_channel_cnt when the URB allocation fails as reported in [1].
- even if opened_channel_cnt were to be correctly decremented, atomic_t is insufficient to cover edge cases: there can be a race condition in which 1/ a first process fails to allocate URBs memory 2/ a second process enters es58x_open() before the first process does its cleanup and decrements opened_channed_cnt. In which case, the second process would successfully return despite the URBs memory not being allocated.
- actually, any kind of locking mechanism was useless here because it is redundant with the network stack big kernel lock (a.k.a. rtnl_lock) which is being hold by all the callers of net_device_ops:ndo_open() and net_device_ops:ndo_close(). c.f. the ASSERST_RTNL() calls in __dev_open() [2] and __dev_close_many() [3].
The atmomic_t is thus replaced by a simple u8 type and the logic to increment and decrement es58x_device:opened_channel_cnt is simplified accordingly fixing the bug reported in [1]. We do not check again for ASSERST_RTNL() as this is already done by the callers.
[1] https://lore.kernel.org/linux-can/20220201140351.GA2548@kili/T/#u
[2] https://elixir.bootlin.com/linux/v5.16/source/net/core/dev.c#L1463
[3] https://elixir.bootlin.com/linux/v5.16/source/net/core/dev.c#L1541
--- drivers/net/can/usb/etas_es58x/es58x_core.c | 9 +++++---- drivers/net/can/usb/etas_es58x/es58x_core.h | 8 +++++--- 2 files changed, 10 insertions(+), 7 deletions(-)
drivers/net/can/usb/etas_es58x/es58x_core.c +5 -4
@@ -1787,7 +1787,7 @@ static int es58x_open(struct net_device *netdev)struct es58x_device *es58x_dev =es58x_priv (netdev)->es58x_dev;int ret; -if (atomic_inc_return (&es58x_dev->opened_channel_cnt) ==1 ) { +if (!es58x_dev->opened_channel_cnt) { ret =es58x_alloc_rx_urbs (es58x_dev);if (ret)return ret;
@@ -1805,12 +1805,13 @@ static int es58x_open(struct net_device *netdev)if (ret) goto free_urbs; + es58x_dev->opened_channel_cnt++;netif_start_queue (netdev);return ret; free_urbs: -if (atomic_dec_and_test (&es58x_dev->opened_channel_cnt)) +if (!es58x_dev->opened_channel_cnt)es58x_free_urbs (es58x_dev);netdev_err (netdev,"%s: Could not open the network device: %pe\n" , __func__,ERR_PTR (ret));
@@ -1845,7 +1846,8 @@ static int es58x_stop(struct net_device *netdev)es58x_flush_pending_tx_msg (netdev); -if (atomic_dec_and_test (&es58x_dev->opened_channel_cnt)) + es58x_dev->opened_channel_cnt--; +if (!es58x_dev->opened_channel_cnt)es58x_free_urbs (es58x_dev);return 0 ;
@@ -2214,7 +2216,6 @@ static struct es58x_device *es58x_init_es58x_dev(struct usb_interface *intf,init_usb_anchor (&es58x_dev->tx_urbs_idle);init_usb_anchor (&es58x_dev->tx_urbs_busy);atomic_set (&es58x_dev->tx_urbs_idle_cnt,0 ); -atomic_set (&es58x_dev->opened_channel_cnt,0 );usb_set_intfdata (intf, es58x_dev); es58x_dev->rx_pipe = usb_rcvbulkpipe(es58x_dev->udev,
drivers/net/can/usb/etas_es58x/es58x_core.h +5 -3
@@ -373,8 +373,6 @@ struct es58x_operators {* queue wake/stop logic should prevent this URB from getting * empty. Please refer to es58x_get_tx_urb() for more details. * @tx_urbs_idle_cnt: number of urbs in @tx_urbs_idle. -* @opened_channel_cnt: number of channels opened (c.f. es58x_open() -* and es58x_stop()). * @ktime_req_ns: kernel timestamp when es58x_set_realtime_diff_ns() * was called. * @realtime_diff_ns: difference in nanoseconds between the clocks of
@@ -384,6 +382,10 @@ struct es58x_operators {* in RX branches. * @rx_max_packet_size: Maximum length of bulk-in URB. * @num_can_ch: Number of CAN channel (i.e. number of elements of @netdev). +* @opened_channel_cnt: number of channels opened. Free of race +* conditions because its two users (net_device_ops:ndo_open() +* and net_device_ops:ndo_close()) guarantee that the network +* stack big kernel lock (a.k.a. rtnl_mutex) is being hold. * @rx_cmd_buf_len: Length of @rx_cmd_buf. * @rx_cmd_buf: The device might split the URB commands in an * arbitrary amount of pieces. This buffer is used to concatenate
@@ -406,7 +408,6 @@ struct es58x_device {struct usb_anchor tx_urbs_busy;struct usb_anchor tx_urbs_idle;atomic_t tx_urbs_idle_cnt; -atomic_t opened_channel_cnt;u64 ktime_req_ns;s64 realtime_diff_ns;
@@ -415,6 +416,7 @@ struct es58x_device {u16 rx_max_packet_size;u8 num_can_ch; +u8 opened_channel_cnt;u16 rx_cmd_buf_len;union es58x_urb_cmd rx_cmd_buf;
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 138/186 net: stmmac: enhance XDP ZC driver level switching performance
In reply to Greg Kroah-HartmanFrom: Ong Boon Leong <[email protected]>
[ Upstream commit ac746c8520d9d056b6963ecca8ff1da9929d02f1 ]
The previous stmmac_xdp_set_prog() implementation uses stmmac_release() and stmmac_open() which tear down the PHY device and causes undesirable autonegotiation which causes a delay whenever AFXDP ZC is setup.
This patch introduces two new functions that just sufficiently tear down DMA descriptors, buffer, NAPI process, and IRQs and reestablish them accordingly in both stmmac_xdp_release() and stammac_xdp_open().
As the results of this enhancement, we get rid of transient state introduced by the link auto-negotiation:
$ ./xdpsock -i eth0 -t -z
sock0@eth0:0 txonly xdp-drv
pps pkts 1.00 rx 0 0 tx 634444 634560
sock0@eth0:0 txonly xdp-drv
pps pkts 1.00 rx 0 0 tx 632330 1267072
sock0@eth0:0 txonly xdp-drv
pps pkts 1.00 rx 0 0 tx 632438 1899584
sock0@eth0:0 txonly xdp-drv
pps pkts 1.00 rx 0 0 tx 632502 2532160
--- drivers/net/ethernet/stmicro/stmmac/stmmac.h | 4 +- .../net/ethernet/stmicro/stmmac/stmmac_main.c | 137 +++++++++++++++++- .../net/ethernet/stmicro/stmmac/stmmac_xdp.c | 4 +- 3 files changed, 139 insertions(+), 6 deletions(-)
drivers/net/ethernet/stmicro/stmmac/stmmac.h +2 -2
@@ -334,8 +334,8 @@ void stmmac_set_ethtool_ops(struct net_device *netdev);int stmmac_init_tstamp_counter (struct stmmac_priv *priv,u32 systime_flags);void stmmac_ptp_register (struct stmmac_priv *priv);void stmmac_ptp_unregister (struct stmmac_priv *priv); -int stmmac_open (struct net_device *dev); -int stmmac_release (struct net_device *dev); +int stmmac_xdp_open (struct net_device *dev); +void stmmac_xdp_release (struct net_device *dev);int stmmac_resume (struct device *dev);int stmmac_suspend (struct device *dev);int stmmac_dvr_remove (struct device *dev);
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +135 -2
155 lines not on this page · raw message
drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c +2 -2
@@ -119,7 +119,7 @@ int stmmac_xdp_set_prog(struct stmmac_priv *priv, struct bpf_prog *prog, need_update = !!priv->xdp_prog != !!prog;if (if_running && need_update) -stmmac_release (dev); +stmmac_xdp_release (dev); old_prog =xchg (&priv->xdp_prog, prog);if (old_prog)
@@ -129,7 +129,7 @@ int stmmac_xdp_set_prog(struct stmmac_priv *priv, struct bpf_prog *prog, priv->sph = priv->sph_cap && !stmmac_xdp_is_enabled (priv);if (if_running && need_update) -stmmac_open (dev); +stmmac_xdp_open (dev);return 0 ; }
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 139/186 net: stmmac: only enable DMA interrupts when ready
In reply to Greg Kroah-HartmanFrom: Vincent Whitchurch <[email protected]>
[ Upstream commit 087a7b944c5db409f7c1a68bf4896c56ba54eaff ]
In this driver's ->ndo_open() callback, it enables DMA interrupts, starts the DMA channels, then requests interrupts with request_irq(), and then finally enables napi.
If RX DMA interrupts are received before napi is enabled, no processing is done because napi_schedule_prep() will return false. If the network has a lot of broadcast/multicast traffic, then the RX ring could fill up completely before napi is enabled. When this happens, no further RX interrupts will be delivered, and the driver will fail to receive any packets.
Fix this by only enabling DMA interrupts after all other initialization is complete.
--- .../net/ethernet/stmicro/stmmac/stmmac_main.c | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-)
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +26 -2
@@ -2272,6 +2272,23 @@ static void stmmac_stop_tx_dma(struct stmmac_priv *priv, u32 chan)stmmac_stop_tx (priv, priv->ioaddr, chan); } +static void stmmac_enable_all_dma_irq (struct stmmac_priv *priv) +{ +u32 rx_channels_count = priv->plat->rx_queues_to_use; +u32 tx_channels_count = priv->plat->tx_queues_to_use; +u32 dma_csr_ch =max (rx_channels_count, tx_channels_count); +u32 chan; + +for (chan =0 ; chan < dma_csr_ch; chan++) { +struct stmmac_channel *ch = &priv->channel[chan]; +unsigned long flags; + +spin_lock_irqsave (&ch->lock, flags); +stmmac_enable_dma_irq (priv, priv->ioaddr, chan,1 ,1 ); +spin_unlock_irqrestore (&ch->lock, flags); + } +} +/** * stmmac_start_all_dma - start all RX and TX DMA channels * @priv: driver private structure
@@ -2911,8 +2928,10 @@ static int stmmac_init_dma_engine(struct stmmac_priv *priv)stmmac_axi (priv, priv->ioaddr, priv->plat->axi);/* DMA CSR Channel configuration */ -for (chan =0 ; chan < dma_csr_ch; chan++) +for (chan =0 ; chan < dma_csr_ch; chan++) {stmmac_init_chan (priv, priv->ioaddr, priv->plat->dma_cfg, chan); +stmmac_disable_dma_irq (priv, priv->ioaddr, chan,1 ,1 ); + }/* DMA RX Channel Configuration */ for (chan =0 ; chan < rx_channels_count; chan++) {
@@ -3768,6 +3787,7 @@ static int stmmac_open(struct net_device *dev)stmmac_enable_all_queues (priv);netif_tx_start_all_queues (priv->dev); +stmmac_enable_all_dma_irq (priv);return 0 ;
@@ -6531,8 +6551,10 @@ int stmmac_xdp_open(struct net_device *dev) }/* DMA CSR Channel configuration */ -for (chan =0 ; chan < dma_csr_ch; chan++) +for (chan =0 ; chan < dma_csr_ch; chan++) {stmmac_init_chan (priv, priv->ioaddr, priv->plat->dma_cfg, chan); +stmmac_disable_dma_irq (priv, priv->ioaddr, chan,1 ,1 ); + }/* Adjust Split header */ sph_en = (priv->hw->rx_csum >0 ) && priv->sph;
@@ -6592,6 +6614,7 @@ int stmmac_xdp_open(struct net_device *dev)stmmac_enable_all_queues (priv);netif_carrier_on (dev);netif_tx_start_all_queues (dev); +stmmac_enable_all_dma_irq (priv);return 0 ;
@@ -7470,6 +7493,7 @@ int stmmac_resume(struct device *dev)stmmac_restore_hw_vlan_rx_fltr (priv, ndev, priv->hw);stmmac_enable_all_queues (priv); +stmmac_enable_all_dma_irq (priv);mutex_unlock (&priv->lock);rtnl_unlock ();
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 140/186 ibmvnic: initialize rc before completing wait
In reply to Greg Kroah-HartmanFrom: Sukadev Bhattiprolu <[email protected]>
[ Upstream commit 765559b10ce514eb1576595834f23cdc92125fee ]
We should initialize ->init_done_rc before calling complete(). Otherwise the waiting thread may see ->init_done_rc as 0 before we have updated it and may assume that the CRQ was successful.
--- drivers/net/ethernet/ibm/ibmvnic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/ibm/ibmvnic.c +1 -1
@@ -5319,9 +5319,9 @@ static void ibmvnic_handle_crq(union ibmvnic_crq *crq, }if (!completion_done (&adapter->init_done)) { -complete (&adapter->init_done);if (!adapter->init_done_rc) adapter->init_done_rc = -EAGAIN ; +complete (&adapter->init_done); }break ;
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 141/186 ibmvnic: define flush_reset_queue helper
In reply to Greg Kroah-HartmanFrom: Sukadev Bhattiprolu <[email protected]>
[ Upstream commit 83da53f7e4bd86dca4b2edc1e2bb324fb3c033a1 ]
Define and use a helper to flush the reset queue.
--- drivers/net/ethernet/ibm/ibmvnic.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-)
drivers/net/ethernet/ibm/ibmvnic.c +16 -8
@@ -2731,12 +2731,23 @@ static void __ibmvnic_delayed_reset(struct work_struct *work)__ibmvnic_reset (&adapter->ibmvnic_reset); } +static void flush_reset_queue (struct ibmvnic_adapter *adapter) +{ +struct list_head *entry, *tmp_entry; + +if (!list_empty (&adapter->rwi_list)) { +list_for_each_safe (entry, tmp_entry, &adapter->rwi_list) { +list_del (entry); +kfree (list_entry(entry ,struct ibmvnic_rwi ,list )); + } + } +} +static int ibmvnic_reset (struct ibmvnic_adapter *adapter,enum ibmvnic_reset_reason reason) { -struct list_head *entry, *tmp_entry; -struct ibmvnic_rwi *rwi, *tmp;struct net_device *netdev = adapter->netdev; +struct ibmvnic_rwi *rwi, *tmp;unsigned long flags;int ret;
@@ -2779,12 +2790,9 @@ static int ibmvnic_reset(struct ibmvnic_adapter *adapter,/* if we just received a transport event, * flush reset queue and process this reset */ -if (adapter->force_reset_recovery && !list_empty (&adapter->rwi_list)) { -list_for_each_safe (entry, tmp_entry, &adapter->rwi_list) { -list_del (entry); -kfree (list_entry(entry ,struct ibmvnic_rwi ,list )); - } - } +if (adapter->force_reset_recovery) +flush_reset_queue (adapter); + rwi->reset_reason = reason;list_add_tail (&rwi->list, &adapter->rwi_list); netdev_dbg(adapter->netdev, "Scheduling reset (reason %s)\n",
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 142/186 ibmvnic: complete init_done on transport events
In reply to Greg Kroah-HartmanFrom: Sukadev Bhattiprolu <[email protected]>
[ Upstream commit 36491f2df9ad2501e5a4ec25d3d95d72bafd2781 ]
If we get a transport event, set the error and mark the init as complete so the attempt to send crq-init or login fail sooner rather than wait for the timeout.
--- drivers/net/ethernet/ibm/ibmvnic.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/net/ethernet/ibm/ibmvnic.c +7 -0
@@ -5352,6 +5352,13 @@ static void ibmvnic_handle_crq(union ibmvnic_crq *crq, adapter->fw_done_rc = -EIO ;complete (&adapter->fw_done); } + +/* if we got here during crq-init, retry crq-init */ +if (!completion_done (&adapter->init_done)) { + adapter->init_done_rc = -EAGAIN ; +complete (&adapter->init_done); + } +if (!completion_done (&adapter->stats_done))complete (&adapter->stats_done);if (test_bit (0 , &adapter->resetting))
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 143/186 ibmvnic: Update driver return codes
In reply to Greg Kroah-HartmanFrom: Dany Madden <[email protected]>
[ Upstream commit b6ee566cf3940883d67c0d142fae8d410e975f47 ]
Update return codes to be more informative.
--- drivers/net/ethernet/ibm/ibmvnic.c | 64 ++++++++++++++++-------------- 1 file changed, 34 insertions(+), 30 deletions(-)
drivers/net/ethernet/ibm/ibmvnic.c +34 -30
@@ -309,7 +309,7 @@ static int alloc_long_term_buff(struct ibmvnic_adapter *adapter,if (adapter->fw_done_rc) {dev_err (dev,"Couldn't map LTB, rc = %d\n" , adapter->fw_done_rc); - rc =-1 ; + rc = -EIO ; goto out; } rc =0 ;
@@ -541,13 +541,15 @@ static int init_stats_token(struct ibmvnic_adapter *adapter) {struct device *dev = &adapter->vdev->dev;dma_addr_t stok; +int rc; stok =dma_map_single (dev, &adapter->stats,sizeof (struct ibmvnic_statistics ),DMA_FROM_DEVICE ); -if (dma_mapping_error (dev, stok)) { -dev_err (dev,"Couldn't map stats buffer\n" ); -return -1 ; + rc =dma_mapping_error (dev, stok); +if (rc) { +dev_err (dev,"Couldn't map stats buffer, rc = %d\n" , rc); +return rc; } adapter->stats_token = stok;
@@ -656,7 +658,7 @@ static int init_rx_pools(struct net_device *netdev)u64 num_pools;u64 pool_size;/* # of buffers in one pool */ u64 buff_size; -int i, j; +int i, j, rc; pool_size = adapter->req_rx_add_entries_per_subcrq; num_pools = adapter->req_rx_queues;
@@ -675,7 +677,7 @@ static int init_rx_pools(struct net_device *netdev) GFP_KERNEL);if (!adapter->rx_pool) {dev_err (dev,"Failed to allocate rx pools\n" ); -return -1 ; +return -ENOMEM ; }/* Set num_active_rx_pools early. If we fail below after partial
@@ -698,6 +700,7 @@ static int init_rx_pools(struct net_device *netdev) GFP_KERNEL);if (!rx_pool->free_map) {dev_err (dev,"Couldn't alloc free_map %d\n" , i); + rc = -ENOMEM ; goto out_release; }
@@ -706,6 +709,7 @@ static int init_rx_pools(struct net_device *netdev) GFP_KERNEL);if (!rx_pool->rx_buff) {dev_err (dev,"Couldn't alloc rx buffers\n" ); + rc = -ENOMEM ; goto out_release; } }
@@ -719,8 +723,9 @@ static int init_rx_pools(struct net_device *netdev)dev_dbg (dev,"Updating LTB for rx pool %d [%d, %d]\n" , i, rx_pool->size, rx_pool->buff_size); -if (alloc_long_term_buff (adapter, &rx_pool->long_term_buff, - rx_pool->size * rx_pool->buff_size)) + rc =alloc_long_term_buff (adapter, &rx_pool->long_term_buff, + rx_pool->size * rx_pool->buff_size); +if (rc) goto out;for (j =0 ; j < rx_pool->size; ++j) {
@@ -757,7 +762,7 @@ static int init_rx_pools(struct net_device *netdev)/* We failed to allocate one or more LTBs or map them on the VIOS. * Hold onto the pools and any LTBs that we did allocate/map. */ -return -1 ; +return rc; }static void release_vpd_data (struct ibmvnic_adapter *adapter)
@@ -818,13 +823,13 @@ static int init_one_tx_pool(struct net_device *netdev,sizeof (struct ibmvnic_tx_buff ), GFP_KERNEL);if (!tx_pool->tx_buff) -return -1 ; +return -ENOMEM ; tx_pool->free_map =kcalloc (pool_size,sizeof (int ),GFP_KERNEL );if (!tx_pool->free_map) {kfree (tx_pool->tx_buff); tx_pool->tx_buff =NULL ; -return -1 ; +return -ENOMEM ; }for (i =0 ; i < pool_size; i++)
@@ -915,7 +920,7 @@ static int init_tx_pools(struct net_device *netdev) adapter->tx_pool =kcalloc (num_pools,sizeof (struct ibmvnic_tx_pool ),GFP_KERNEL );if (!adapter->tx_pool) -return -1 ; +return -ENOMEM ; adapter->tso_pool =kcalloc (num_pools,sizeof (struct ibmvnic_tx_pool ),GFP_KERNEL );
@@ -925,7 +930,7 @@ static int init_tx_pools(struct net_device *netdev)if (!adapter->tso_pool) {kfree (adapter->tx_pool); adapter->tx_pool =NULL ; -return -1 ; +return -ENOMEM ; }/* Set num_active_tx_pools early. If we fail below after partial
@@ -1114,7 +1119,7 @@ static int ibmvnic_login(struct net_device *netdev) retry = false;if (retry_count > retries) {netdev_warn (netdev,"Login attempts exceeded\n" ); -return -1 ; +return -EACCES ; } adapter->init_done_rc =0 ;
@@ -1155,25 +1160,26 @@ static int ibmvnic_login(struct net_device *netdev) timeout)) {netdev_warn (netdev,"Capabilities query timed out\n" ); -return -1 ; +return -ETIMEDOUT ; } rc =init_sub_crqs (adapter);if (rc) {netdev_warn (netdev,"SCRQ initialization failed\n" ); -return -1 ; +return rc; } rc =init_sub_crq_irqs (adapter);if (rc) {netdev_warn (netdev,"SCRQ irq initialization failed\n" ); -return -1 ; +return rc; } }else if (adapter->init_done_rc) { -netdev_warn (netdev,"Adapter login failed\n" ); -return -1 ; +netdev_warn (netdev,"Adapter login failed, init_done_rc = %d\n" , + adapter->init_done_rc); +return -EIO ; } }while (retry);
@@ -1232,7 +1238,7 @@ static int set_link_state(struct ibmvnic_adapter *adapter, u8 link_state)if (!wait_for_completion_timeout (&adapter->init_done, timeout)) {netdev_err (netdev,"timeout setting link state\n" ); -return -1 ; +return -ETIMEDOUT ; }if (adapter->init_done_rc ==PARTIALSUCCESS ) {
@@ -2293,7 +2299,7 @@ static int do_reset(struct ibmvnic_adapter *adapter,/* If someone else changed the adapter state * when we dropped the rtnl, fail the reset */ - rc =-1 ; + rc = -EAGAIN ; goto out; } adapter->state =VNIC_CLOSED ;
@@ -2335,10 +2341,8 @@ static int do_reset(struct ibmvnic_adapter *adapter, } rc =ibmvnic_reset_init (adapter, true); -if (rc) { - rc =IBMVNIC_INIT_FAILED ; +if (rc) goto out; - }/* If the adapter was in PROBE or DOWN state prior to the reset, * exit here.
@@ -3787,7 +3791,7 @@ static int init_sub_crqs(struct ibmvnic_adapter *adapter) allqueues =kcalloc (total_queues,sizeof (*allqueues),GFP_KERNEL );if (!allqueues) -return -1 ; +return -ENOMEM ;for (i =0 ; i < total_queues; i++) { allqueues[i] =init_sub_crq_queue (adapter);
@@ -3856,7 +3860,7 @@ static int init_sub_crqs(struct ibmvnic_adapter *adapter)for (i =0 ; i < registered_queues; i++)release_sub_crq_queue (adapter, allqueues[i],1 );kfree (allqueues); -return -1 ; +return -ENOMEM ; }static void send_request_cap (struct ibmvnic_adapter *adapter,int retry)
@@ -4235,7 +4239,7 @@ static int send_login(struct ibmvnic_adapter *adapter)if (!adapter->tx_scrq || !adapter->rx_scrq) {netdev_err (adapter->netdev,"RX or TX queues are not allocated, device login failed\n" ); -return -1 ; +return -ENOMEM ; }release_login_buffer (adapter);
@@ -4355,7 +4359,7 @@ static int send_login(struct ibmvnic_adapter *adapter)kfree (login_buffer); adapter->login_buf =NULL ; buf_alloc_failed: -return -1 ; +return -ENOMEM ; } static int send_request_map(struct ibmvnic_adapter *adapter, dma_addr_t addr,
@@ -5693,7 +5697,7 @@ static int ibmvnic_reset_init(struct ibmvnic_adapter *adapter, bool reset)if (!wait_for_completion_timeout (&adapter->init_done, timeout)) {dev_err (dev,"Initialization sequence timed out\n" ); -return -1 ; +return -ETIMEDOUT ; }if (adapter->init_done_rc) {
@@ -5704,7 +5708,7 @@ static int ibmvnic_reset_init(struct ibmvnic_adapter *adapter, bool reset)if (adapter->from_passive_init) { adapter->state =VNIC_OPEN ; adapter->from_passive_init = false; -return -1 ; +return -EINVAL ; } if (reset &&
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 144/186 ibmvnic: init init_done_rc earlier
In reply to Greg Kroah-HartmanFrom: Sukadev Bhattiprolu <[email protected]>
[ Upstream commit ae16bf15374d8b055e040ac6f3f1147ab1c9bb7d ]
We currently initialize the ->init_done completion/return code fields before issuing a CRQ_INIT command. But if we get a transport event soon after registering the CRQ the taskslet may already have recorded the completion and error code. If we initialize here, we might overwrite/ lose that and end up issuing the CRQ_INIT only to timeout later.
If that timeout happens during probe, we will leave the adapter in the DOWN state rather than retrying to register/init the CRQ.
Initialize the completion before registering the CRQ so we don't lose the notification.
--- drivers/net/ethernet/ibm/ibmvnic.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-)
drivers/net/ethernet/ibm/ibmvnic.c +21 -5
@@ -2212,6 +2212,19 @@ static const char *reset_reason_to_string(enum ibmvnic_reset_reason reason)return "UNKNOWN" ; } +/* +* Initialize the init_done completion and return code values. We +* can get a transport event just after registering the CRQ and the +* tasklet will use this to communicate the transport event. To ensure +* we don't miss the notification/error, initialize these _before_ +* regisering the CRQ. +*/ +static inline void reinit_init_done (struct ibmvnic_adapter *adapter) +{ +reinit_completion (&adapter->init_done); + adapter->init_done_rc =0 ; +} +/* * do_reset returns zero if we are able to keep processing reset events, or * non-zero if we hit a fatal error and must halt.
@@ -2318,6 +2331,8 @@ static int do_reset(struct ibmvnic_adapter *adapter,*/ adapter->state =VNIC_PROBED ; +reinit_init_done (adapter); +if (adapter->reset_reason ==VNIC_RESET_CHANGE_PARAM ) { rc =init_crq_queue (adapter); }else if (adapter->reset_reason ==VNIC_RESET_MOBILITY ) {
@@ -2461,7 +2476,8 @@ static int do_hard_reset(struct ibmvnic_adapter *adapter,*/ adapter->state =VNIC_PROBED ; -reinit_completion (&adapter->init_done); +reinit_init_done (adapter); + rc =init_crq_queue (adapter);if (rc) { netdev_err(adapter->netdev,
@@ -5685,10 +5701,6 @@ static int ibmvnic_reset_init(struct ibmvnic_adapter *adapter, bool reset) adapter->from_passive_init = false; -if (reset) -reinit_completion (&adapter->init_done); - - adapter->init_done_rc =0 ; rc =ibmvnic_send_crq_init (adapter);if (rc) {dev_err (dev,"Send crq init failed with error %d\n" , rc);
@@ -5702,12 +5714,14 @@ static int ibmvnic_reset_init(struct ibmvnic_adapter *adapter, bool reset)if (adapter->init_done_rc) {release_crq_queue (adapter); +dev_err (dev,"CRQ-init failed, %d\n" , adapter->init_done_rc);return adapter->init_done_rc; }if (adapter->from_passive_init) { adapter->state =VNIC_OPEN ; adapter->from_passive_init = false; +dev_err (dev,"CRQ-init failed, passive-init\n" );return -EINVAL ; }
@@ -5801,6 +5815,8 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id) init_success = false; do { + reinit_init_done(adapter); + rc = init_crq_queue(adapter); if (rc) { dev_err(&dev->dev, "Couldn't initialize crq. rc=%d\n",
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 145/186 ibmvnic: clear fop when retrying probe
In reply to Greg Kroah-HartmanFrom: Sukadev Bhattiprolu <[email protected]>
[ Upstream commit f628ad531b4f34fdba0984255b4a2850dd369513 ]
Clear ->failover_pending flag that may have been set in the previous pass of registering CRQ. If we don't clear, a subsequent ibmvnic_open() call would be misled into thinking a failover is pending and assuming that the reset worker thread would open the adapter. If this pass of registering the CRQ succeeds (i.e there is no transport event), there wouldn't be a reset worker thread.
This would leave the adapter unconfigured and require manual intervention to bring it up during boot.
--- drivers/net/ethernet/ibm/ibmvnic.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/net/ethernet/ibm/ibmvnic.c +5 -0
@@ -5817,6 +5817,11 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id) do { reinit_init_done(adapter); + /* clear any failovers we got in the previous pass + * since we are reinitializing the CRQ + */ + adapter->failover_pending = false; + rc = init_crq_queue(adapter); if (rc) { dev_err(&dev->dev, "Couldn't initialize crq. rc=%d\n",
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 146/186 ibmvnic: Allow queueing resets during probe
In reply to Greg Kroah-HartmanFrom: Sukadev Bhattiprolu <[email protected]>
[ Upstream commit fd98693cb0721317f27341951593712c580c36a1 ]
We currently don't allow queuing resets when adapter is in VNIC_PROBING state - instead we throw away the reset and return EBUSY. The reasoning is probably that during ibmvnic_probe() the ibmvnic_adapter itself is being initialized so performing a reset during this time can lead us to accessing fields in the ibmvnic_adapter that are not fully initialized. A review of the code shows that all the adapter state neede to process a reset is initialized before registering the CRQ so that should no longer be a concern.
Further the expectation is that if we do get a reset (transport event) during probe, the do..while() loop in ibmvnic_probe() will handle this by reinitializing the CRQ.
While that is true to some extent, it is possible that the reset might occur _after_ the CRQ is registered and CRQ_INIT message was exchanged but _before_ the adapter state is set to VNIC_PROBED. As mentioned above, such a reset will be thrown away. While the client assumes that the adapter is functional, the vnic server will wait for the client to reinit the adapter. This disconnect between the two leaves the adapter down needing manual intervention.
Because ibmvnic_probe() has other work to do after initializing the CRQ (such as registering the netdev at a minimum) and because the reset event can occur at any instant after the CRQ is initialized, there will always be a window between initializing the CRQ and considering the adapter ready for resets (ie state == PROBED).
So rather than discarding resets during this window, allow queueing them
- but only process them after the adapter is fully initialized.
To do this, introduce a new completion state ->probe_done and have the reset worker thread wait on this before processing resets.
This change brings up two new situations in or just after ibmvnic_probe(). First after one or more resets were queued, we encounter an error and decide to retry the initialization. At that point the queued resets are no longer relevant since we could be talking to a new vnic server. So we must purge/flush the queued resets before restarting the initialization. As a side note, since we are still in the probing stage and we have not registered the netdev, it will not be CHANGE_PARAM reset.
Second this change opens up a potential race between the worker thread in __ibmvnic_reset(), the tasklet and the ibmvnic_open() due to the following sequence of events:
1. Register CRQ
2. Get transport event before CRQ_INIT completes.
3. Tasklet schedules reset:
a) add rwi to list
b) schedule_work() to start worker thread which runs and waits for ->probe_done.
4. ibmvnic_probe() decides to retry, purges rwi_list
5. Re-register crq and this time rest of probe succeeds - register netdev and complete(->probe_done).
6. Worker thread resumes in __ibmvnic_reset() from 3b.
7. Worker thread sets ->resetting bit
8. ibmvnic_open() comes in, notices ->resetting bit, sets state to IBMVNIC_OPEN and returns early expecting worker thread to finish the open.
9. Worker thread finds rwi_list empty and returns without opening the interface.
If this happens, the ->ndo_open() call is effectively lost and the interface remains down. To address this, ensure that ->rwi_list is not empty before setting the ->resetting bit. See also comments in __ibmvnic_reset().
--- drivers/net/ethernet/ibm/ibmvnic.c | 107 ++++++++++++++++++++++++++--- drivers/net/ethernet/ibm/ibmvnic.h | 1 + 2 files changed, 98 insertions(+), 10 deletions(-)
drivers/net/ethernet/ibm/ibmvnic.c +97 -10
@@ -2618,23 +2618,82 @@ static int do_passive_init(struct ibmvnic_adapter *adapter)static void __ibmvnic_reset (struct work_struct *work) {struct ibmvnic_adapter *adapter; -bool saved_state = false; +unsigned int timeout =5000 ;struct ibmvnic_rwi *tmprwi; +bool saved_state = false;struct ibmvnic_rwi *rwi;unsigned long flags; -u32 reset_state; +struct device *dev; +bool need_reset;int num_fails =0 ; +u32 reset_state;int rc =0 ; adapter = container_of(work, struct ibmvnic_adapter, ibmvnic_reset); + dev = &adapter->vdev->dev; -if (test_and_set_bit_lock (0 , &adapter->resetting)) { +/* Wait for ibmvnic_probe() to complete. If probe is taking too long +* or if another reset is in progress, defer work for now. If probe +* eventually fails it will flush and terminate our work. +* +* Three possibilities here: +* 1. Adpater being removed - just return +* 2. Timed out on probe or another reset in progress - delay the work +* 3. Completed probe - perform any resets in queue +*/ +if (adapter->state ==VNIC_PROBING && + !wait_for_completion_timeout (&adapter->probe_done, timeout)) { +dev_err (dev,"Reset thread timed out on probe" );queue_delayed_work (system_long_wq, &adapter->ibmvnic_delayed_reset,IBMVNIC_RESET_DELAY );return ; } +/* adapter is done with probe (i.e state is never VNIC_PROBING now) */ +if (adapter->state ==VNIC_REMOVING ) +return ; + +/* ->rwi_list is stable now (no one else is removing entries) */ + +/* ibmvnic_probe() may have purged the reset queue after we were +* scheduled to process a reset so there maybe no resets to process. +* Before setting the ->resetting bit though, we have to make sure +* that there is infact a reset to process. Otherwise we may race +* with ibmvnic_open() and end up leaving the vnic down: +* +* __ibmvnic_reset() ibmvnic_open() +* ----------------- -------------- +* +* set ->resetting bit +* find ->resetting bit is set +* set ->state to IBMVNIC_OPEN (i.e +* assume reset will open device) +* return +* find reset queue empty +* return +* +* Neither performed vnic login/open and vnic stays down +* +* If we hold the lock and conditionally set the bit, either we +* or ibmvnic_open() will complete the open. +*/ + need_reset = false; +spin_lock (&adapter->rwi_lock); +if (!list_empty (&adapter->rwi_list)) { +if (test_and_set_bit_lock (0 , &adapter->resetting)) { +queue_delayed_work (system_long_wq, + &adapter->ibmvnic_delayed_reset, +IBMVNIC_RESET_DELAY ); + }else { + need_reset = true; + } + } +spin_unlock (&adapter->rwi_lock); + +if (!need_reset) +return ; + rwi =get_next_rwi (adapter);while (rwi) {spin_lock_irqsave (&adapter->state_lock, flags);
@@ -2786,13 +2845,6 @@ static int ibmvnic_reset(struct ibmvnic_adapter *adapter, goto err; } -if (adapter->state ==VNIC_PROBING ) { -netdev_warn (netdev,"Adapter reset during probe\n" ); - adapter->init_done_rc = -EAGAIN ; - ret =EAGAIN ; - goto err; - } -list_for_each_entry (tmp, &adapter->rwi_list, list) {if (tmp->reset_reason == reason) { netdev_dbg(netdev, "Skipping matching reset, reason=%s\n",
@@ -5761,6 +5813,7 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)struct ibmvnic_adapter *adapter;struct net_device *netdev;unsigned char *mac_addr_p; +unsigned long flags;bool init_success;int rc;
@@ -5805,6 +5858,7 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)spin_lock_init (&adapter->rwi_lock);spin_lock_init (&adapter->state_lock);mutex_init (&adapter->fw_lock); +init_completion (&adapter->probe_done);init_completion (&adapter->init_done);init_completion (&adapter->fw_done);init_completion (&adapter->reset_done);
@@ -5822,6 +5876,26 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)*/ adapter->failover_pending = false; +/* If we had already initialized CRQ, we may have one or +* more resets queued already. Discard those and release +* the CRQ before initializing the CRQ again. +*/ +release_crq_queue (adapter); + +/* Since we are still in PROBING state, __ibmvnic_reset() +* will not access the ->rwi_list and since we released CRQ, +* we won't get _new_ transport events. But there maybe an +* ongoing ibmvnic_reset() call. So serialize access to +* rwi_list. If we win the race, ibvmnic_reset() could add +* a reset after we purged but thats ok - we just may end +* up with an extra reset (i.e similar to having two or more +* resets in the queue at once). +* CHECK. +*/ +spin_lock_irqsave (&adapter->rwi_lock, flags); +flush_reset_queue (adapter); +spin_unlock_irqrestore (&adapter->rwi_lock, flags); + rc =init_crq_queue (adapter);if (rc) { dev_err(&dev->dev, "Couldn't initialize crq. rc=%d\n",
@@ -5873,6 +5947,8 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id) }dev_info (&dev->dev,"ibmvnic registered\n" ); +complete (&adapter->probe_done); +return 0 ; ibmvnic_register_fail:
@@ -5887,6 +5963,17 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id) ibmvnic_init_fail:release_sub_crqs (adapter,1 );release_crq_queue (adapter); + +/* cleanup worker thread after releasing CRQ so we don't get +* transport events (i.e new work items for the worker thread). +*/ + adapter->state =VNIC_REMOVING ; +complete (&adapter->probe_done); +flush_work (&adapter->ibmvnic_reset); +flush_delayed_work (&adapter->ibmvnic_delayed_reset); + +flush_reset_queue (adapter); +mutex_destroy (&adapter->fw_lock);free_netdev (netdev);
drivers/net/ethernet/ibm/ibmvnic.h +1 -0
@@ -933,6 +933,7 @@ struct ibmvnic_adapter {struct ibmvnic_tx_pool *tx_pool;struct ibmvnic_tx_pool *tso_pool; +struct completion probe_done;struct completion init_done;int init_done_rc;
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 147/186 net: chelsio: cxgb3: check the return value of pci_find_capability()
In reply to Greg Kroah-HartmanFrom: Jia-Ju Bai <[email protected]>
[ Upstream commit 767b9825ed1765894e569a3d698749d40d83762a ]
The function pci_find_capability() in t3_prep_adapter() can fail, so its return value should be checked.
--- drivers/net/ethernet/chelsio/cxgb3/t3_hw.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/ethernet/chelsio/cxgb3/t3_hw.c +2 -0
@@ -3613,6 +3613,8 @@ int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai, MAC_STATS_ACCUM_SECS : (MAC_STATS_ACCUM_SECS *10 ); adapter->params.pci.vpd_cap_addr =pci_find_capability (adapter->pdev,PCI_CAP_ID_VPD ); +if (!adapter->params.pci.vpd_cap_addr) +return -ENODEV ; ret =get_vpd_params (adapter, &adapter->params.vpd);if (ret <0 )return ret;
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 148/186 net: sparx5: Fix add vlan when invalid operation
In reply to Greg Kroah-HartmanFrom: Casper Andersson <[email protected]>
[ Upstream commit b3a34dc362c03215031b268fcc0b988e69490231 ]
Check if operation is valid before changing any settings in hardware. Otherwise it results in changes being made despite it not being a valid operation.
--- .../ethernet/microchip/sparx5/sparx5_vlan.c | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
drivers/net/ethernet/microchip/sparx5/sparx5_vlan.c +10 -10
@@ -58,16 +58,6 @@ int sparx5_vlan_vid_add(struct sparx5_port *port, u16 vid, bool pvid,struct sparx5 *sparx5 = port->sparx5;int ret; -/* Make the port a member of the VLAN */ -set_bit (port->portno, sparx5->vlan_mask[vid]); - ret =sparx5_vlant_set_mask (sparx5, vid); -if (ret) -return ret; - -/* Default ingress vlan classification */ -if (pvid) - port->pvid = vid; -/* Untagged egress vlan classification */ if (untagged && port->vid != vid) {if (port->vid) {
@@ -79,6 +69,16 @@ int sparx5_vlan_vid_add(struct sparx5_port *port, u16 vid, bool pvid, port->vid = vid; } +/* Make the port a member of the VLAN */ +set_bit (port->portno, sparx5->vlan_mask[vid]); + ret =sparx5_vlant_set_mask (sparx5, vid); +if (ret) +return ret; + +/* Default ingress vlan classification */ +if (pvid) + port->pvid = vid; +sparx5_vlan_port_apply (sparx5, port);return 0 ;
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 149/186 iavf: Add trace while removing device
In reply to Greg Kroah-HartmanFrom: Jedrzej Jagielski <[email protected]>
[ Upstream commit bdb9e5c7aec73a7b8b5acab37587b6de1203e68d ]
Add kernel trace that device was removed.
Currently there is no such information.
I.e. Host admin removes a PCI device from a VM,
than on VM shall be info about the event.
This patch adds info log to iavf_remove function.
--- drivers/net/ethernet/intel/iavf/iavf_main.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/intel/iavf/iavf_main.c +1 -0
@@ -4005,6 +4005,7 @@ static void iavf_remove(struct pci_dev *pdev)if (iavf_lock_timeout (&adapter->crit_lock,5000 ))dev_warn (&adapter->pdev->dev,"failed to acquire crit_lock in %s\n" , __FUNCTION__); +dev_info (&adapter->pdev->dev,"Removing device\n" );/* Shut down all the garbage mashers on the detention level */ iavf_change_state (adapter, __IAVF_REMOVE); adapter->aq_required =0 ;
Signature · 1 line
2.34.1