6.1.76-rc1 review
Subsystems (5)
Greg Kroah-Hartman
maintainercover 6.1.76-rc1 review
This is the start of the stable review cycle for the 6.1.76 release. There are 185 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, 31 Jan 2024 16:59:28 +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/v6.x/stable-review/patch-6.1.76-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-6.1.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 6.1.76-rc1
Randy Dunlap <[email protected]>
serial: core: fix kernel-doc for uart_port_unlock_irqrestore()
Richard Palethorpe <[email protected]>
x86/entry/ia32: Ensure s32 is sign extended to s64
Tim Chen <[email protected]>
tick/sched: Preserve number of idle sleeps across CPU hotplug events
Xi Ruoyao <[email protected]>
mips: Call lose_fpu(0) before initializing fcr31 in mips_set_personality_nan
Quanquan Cao <[email protected]>
cxl/region:Fix overflow issue in alloc_hpa()
Aleksander Jan Bajkowski <[email protected]>
MIPS: lantiq: register smp_ops on non-smp platforms
David Lechner <[email protected]>
spi: fix finalize message on error return
Kamal Dasu <[email protected]>
spi: bcm-qspi: fix SFDP BFPT read by usig mspi read
Hsin-Yi Wang <[email protected]>
drm/bridge: anx7625: Ensure bridge is suspended in disable()
Li Lingfeng <[email protected]>
block: Move checking GENHD_FL_NO_PART to bdev_add_partition()
Wenhua Lin <[email protected]>
gpio: eic-sprd: Clear interrupt after set the interrupt type
Fedor Pchelkin <[email protected]>
drm/exynos: gsc: minor fix for loop iteration in gsc_runtime_resume
Arnd Bergmann <[email protected]>
drm/exynos: fix accidental on-stack copy of exynos_drm_plane
Douglas Anderson <[email protected]>
drm/bridge: parade-ps8640: Make sure we drop the AUX mutex in the error case
Pin-yen Lin <[email protected]>
drm/bridge: parade-ps8640: Ensure bridge is suspended in .post_disable()
Tomi Valkeinen <[email protected]>
drm/bridge: sii902x: Fix audio codec unregistration
Tomi Valkeinen <[email protected]>
drm/bridge: sii902x: Fix probing race issue
Matti Vaittinen <[email protected]>
drm/bridge: sii902x: Use devm_regulator_bulk_get_enable()
Markus Niebel <[email protected]>
drm: panel-simple: add missing bus flags for Tianma tm070jvhg[30/33]
Douglas Anderson <[email protected]>
drm/bridge: parade-ps8640: Wait for HPD when doing an AUX transfer
Sasha Levin <[email protected]>
Revert "powerpc/64s: Increase default stack size to 32KB"
Hsin-Yi Wang <[email protected]>
drm/panel-edp: drm/panel-edp: Fix AUO B116XAK01 name and timing
Naohiro Aota <[email protected]>
btrfs: zoned: optimize hint byte for zoned allocator
Naohiro Aota <[email protected]>
btrfs: zoned: factor out prepare_allocation_zoned()
Hugo Villeneuve <[email protected]>
serial: sc16is7xx: fix unconditional activation of THRI interrupt
Thomas Gleixner <[email protected]>
serial: sc16is7xx: Use port lock wrappers
Thomas Gleixner <[email protected]>
serial: core: Provide port lock wrappers
Jordan Rife <[email protected]>
dlm: use kernel_connect() and kernel_bind()
Johan Hovold <[email protected]>
ARM: dts: qcom: sdx55: fix USB SS wakeup
Johan Hovold <[email protected]>
ARM: dts: qcom: sdx55: fix USB DP/DM HS PHY interrupts
Johan Hovold <[email protected]>
ARM: dts: qcom: sdx55: fix pdc '#interrupt-cells'
Paul Cercueil <[email protected]>
ARM: dts: samsung: exynos4210-i9100: Unconditionally enable LDO12
Johan Hovold <[email protected]>
ARM: dts: qcom: sdx55: fix USB wakeup interrupt types
Lukas Schauer <[email protected]>
pipe: wakeup wr_wait after setting max_usage
Max Kellermann <[email protected]>
fs/pipe: move check to pipe_has_watch_queue()
Ricardo Neri <[email protected]>
thermal: intel: hfi: Add syscore callbacks for system-wide PM
Ricardo Neri <[email protected]>
thermal: intel: hfi: Disable an HFI instance when all its CPUs go offline
Ricardo Neri <[email protected]>
thermal: intel: hfi: Refactor enabling code into helper functions
Rafael J. Wysocki <[email protected]>
PM: sleep: Fix possible deadlocks in core system-wide PM code
Li zeming <[email protected]>
PM: core: Remove unnecessary (void *) conversions
Manivannan Sadhasivam <[email protected]>
bus: mhi: ep: Do not allocate event ring element on stack
Bingbu Cao <[email protected]>
media: ov13b10: Enable runtime PM before registering async sub-device
Arec Kao <[email protected]>
media: ov13b10: Support device probe in non-zero ACPI D state
Gao Xiang <[email protected]>
erofs: fix lz4 inplace decompression
Gao Xiang <[email protected]>
erofs: get rid of the remaining kmap_atomic()
Ma Jun <[email protected]>
drm/amdgpu/pm: Fix the power source flag error
Nicholas Kazlauskas <[email protected]>
drm/amd/display: Port DENTIST hang and TDR fixes to OTG disable W/A
Dan Carpenter <[email protected]>
drm/bridge: nxp-ptn3460: simplify some error checking
Nathan Chancellor <[email protected]>
platform/x86: intel-uncore-freq: Fix types in sysfs callbacks
Mario Limonciello <[email protected]>
drm/amd/display: Disable PSR-SU on Parade 0803 TCON again
Tomi Valkeinen <[email protected]>
drm/tidss: Fix atomic_flush check
Dan Carpenter <[email protected]>
drm/bridge: nxp-ptn3460: fix i2c_master_send() error checking
Ville Syrjälä <[email protected]>
drm: Don't unref the same fb many times by mistake due to deadlock handling
Rafael J. Wysocki <[email protected]>
cpufreq: intel_pstate: Refine computation of P-state for given frequency
Mario Limonciello <[email protected]>
gpiolib: acpi: Ignore touchpad wakeup on GPD G1619-04
Dave Chinner <[email protected]>
xfs: read only mounts with fsopen mount API are busted
Cristian Marussi <[email protected]>
firmware: arm_scmi: Check mailbox/SMT channel for consistency
Lin Ma <[email protected]>
ksmbd: fix global oob in ksmbd_nl_policy
Shin'ichiro Kawasaki <[email protected]>
platform/x86: p2sb: Allow p2sb_bar() calls during PCI device probe
Florian Westphal <[email protected]>
netfilter: nf_tables: reject QUEUE/DROP verdict parameters
Pablo Neira Ayuso <[email protected]>
netfilter: nft_chain_filter: handle NETDEV_UNREGISTER for inet/ingress basechain
Michael Kelley <[email protected]>
hv_netvsc: Calculate correct ring size when PAGE_SIZE is not 4 Kbytes
Emmanuel Grumbach <[email protected]>
wifi: iwlwifi: fix a memory corruption
Bernd Edlinger <[email protected]>
exec: Fix error handling in begin_new_exec()
Ilya Dryomov <[email protected]>
rbd: don't move requests to the running list on errors
Omar Sandoval <[email protected]>
btrfs: don't abort filesystem when attempting to snapshot deleted subvolume
Qu Wenruo <[email protected]>
btrfs: defrag: reject unknown flags of btrfs_ioctl_defrag_range_args
David Sterba <[email protected]>
btrfs: don't warn if discard range is not aligned to sector
Chung-Chiang Cheng <[email protected]>
btrfs: tree-checker: fix inline ref size in error messages
Fedor Pchelkin <[email protected]>
btrfs: ref-verify: free ref cache before clearing mount opt
Omar Sandoval <[email protected]>
btrfs: avoid copying BTRFS_ROOT_SUBVOL_DEAD flag to snapshot of subvolume being deleted
Eric Dumazet <[email protected]>
nbd: always initialize struct msghdr completely
Shenwei Wang <[email protected]>
net: fec: fix the unhandled context fault from smmu
Zhipeng Lu <[email protected]>
fjes: fix memleaks in fjes_hw_setup
Jakub Kicinski <[email protected]>
selftests: netdevsim: fix the udp_tunnel_nic test
Jenishkumar Maheshbhai Patel <[email protected]>
net: mvpp2: clear BM pool before initialization
Bernd Edlinger <[email protected]>
net: stmmac: Wait a bit for the reset to take effect
Pablo Neira Ayuso <[email protected]>
netfilter: nf_tables: validate NFPROTO_* family
Florian Westphal <[email protected]>
netfilter: nf_tables: restrict anonymous set and map names to 16 bytes
Filipe Manana <[email protected]>
btrfs: fix race between reading a directory and adding entries to it
Filipe Manana <[email protected]>
btrfs: refresh dir last index during a rewinddir(3) call
Filipe Manana <[email protected]>
btrfs: set last dir index to the current last index when opening dir
Filipe Manana <[email protected]>
btrfs: fix infinite directory reads
Florian Westphal <[email protected]>
netfilter: nft_limit: reject configurations that cause integer overflow
Frederic Weisbecker <[email protected]>
rcu: Defer RCU kthreads wakeup when CPU is dying
Dinghao Liu <[email protected]>
net/mlx5e: fix a potential double-free in fs_any_create_groups
Zhipeng Lu <[email protected]>
net/mlx5e: fix a double-free in arfs_create_groups
Leon Romanovsky <[email protected]>
net/mlx5e: Allow software parsing when IPsec crypto is enabled
Rahul Rameshbabu <[email protected]>
net/mlx5: Use mlx5 device constant for selecting CQ period mode for ASO
Yevgeny Kliteynik <[email protected]>
net/mlx5: DR, Can't go to uplink vport on RX rule
Yevgeny Kliteynik <[email protected]>
net/mlx5: DR, Use the right GVMI number for drop action
Zhengchao Shao <[email protected]>
ipv6: init the accept_queue's spinlocks in inet6_create
Zhengchao Shao <[email protected]>
netlink: fix potential sleeping issue in mqueue_flush_file
Salvatore Dipietro <[email protected]>
tcp: Add memory barrier to tcp_push()
David Howells <[email protected]>
afs: Hide silly-rename files from userspace
Petr Pavlu <[email protected]>
tracing: Ensure visibility when inserting an element into tracing_map
Dan Carpenter <[email protected]>
netfs, fscache: Prevent Oops in fscache_put_cache()
Sharath Srinivasan <[email protected]>
net/rds: Fix UBSAN: array-index-out-of-bounds in rds_cmsg_recv
Horatiu Vultur <[email protected]>
net: micrel: Fix PTP frame parsing for lan8814
Yunjian Wang <[email protected]>
tun: add missing rx stats accounting in tun_xdp_act
Yunjian Wang <[email protected]>
tun: fix missing dropped counter in tun_xdp_act
Jakub Kicinski <[email protected]>
net: fix removing a namespace with conflicting altnames
Eric Dumazet <[email protected]>
udp: fix busy polling
Kuniyuki Iwashima <[email protected]>
llc: Drop support for ETH_P_TR_802_2.
Eric Dumazet <[email protected]>
llc: make llc_ui_sendmsg() more robust against bonding changes
Lin Ma <[email protected]>
vlan: skip nested type that is not IFLA_VLAN_QOS_MAPPING
Michael Chan <[email protected]>
bnxt_en: Wait for FLR to complete during probe
Zhengchao Shao <[email protected]>
tcp: make sure init the accept_queue's spinlocks once
Wen Gu <[email protected]>
net/smc: fix illegal rmb_desc access in SMC-D connection dump
Johannes Berg <[email protected]>
wifi: mac80211: fix potential sta-link leak
Wayne Lin <[email protected]>
drm/amd/display: pbn_div need be updated for hotplug event
Jonathan Gray <[email protected]>
Revert "drm/amd: Enable PCIe PME from D3"
Namjae Jeon <[email protected]>
ksmbd: Add missing set_freezable() for freezable kthread
Namjae Jeon <[email protected]>
ksmbd: send lease break notification on FILE_RENAME_INFORMATION
Namjae Jeon <[email protected]>
ksmbd: don't increment epoch if current state and request state are same
Namjae Jeon <[email protected]>
ksmbd: fix potential circular locking issue in smb2_set_ea()
Namjae Jeon <[email protected]>
ksmbd: set v2 lease version on lease upgrade
Charan Teja Kalla <[email protected]>
mm: page_alloc: unreserve highatomic page blocks before oom
Huacai Chen <[email protected]>
LoongArch/smp: Call rcutree_report_cpu_starting() earlier
Hugo Villeneuve <[email protected]>
serial: sc16is7xx: improve do/while loop in sc16is7xx_irq()
Hugo Villeneuve <[email protected]>
serial: sc16is7xx: remove obsolete loop in sc16is7xx_port_irq()
Hugo Villeneuve <[email protected]>
serial: sc16is7xx: fix invalid sc16is7xx_lines bitfield in case of probe error
Hugo Villeneuve <[email protected]>
serial: sc16is7xx: convert from _raw_ to _noinc_ regmap functions for FIFO
Hugo Villeneuve <[email protected]>
serial: sc16is7xx: change EFR lock to operate on each channels
Hugo Villeneuve <[email protected]>
serial: sc16is7xx: remove unused line structure member
Hugo Villeneuve <[email protected]>
serial: sc16is7xx: remove global regmap from struct sc16is7xx_port
Hugo Villeneuve <[email protected]>
serial: sc16is7xx: remove wasteful static buffer in sc16is7xx_regmap_name()
Hugo Villeneuve <[email protected]>
serial: sc16is7xx: improve regmap debugfs by using one regmap per port
Al Viro <[email protected]>
rename(): fix the locking of subdirectories
Charan Teja Kalla <[email protected]>
mm/sparsemem: fix race in accessing memory_section->usage
Steven Rostedt (Google) <[email protected]>
mm/rmap: fix misplaced parenthesis of a likely()
Zhihao Cheng <[email protected]>
ubifs: ubifs_symlink: Fix memleak of inode->i_link in error path
Dave Airlie <[email protected]>
nouveau/vmm: don't set addr on the fail path to avoid warning
Mario Limonciello <[email protected]>
rtc: Extend timeout for waiting for UIP to clear to 1s
Mario Limonciello <[email protected]>
rtc: Add support for configuring the UIP timeout for RTC reads
Mario Limonciello <[email protected]>
rtc: mc146818-lib: Adjust failure return code for mc146818_get_time()
Mario Limonciello <[email protected]>
rtc: Adjust failure return code for cmos_set_alarm()
Mario Limonciello <[email protected]>
rtc: cmos: Use ACPI alarm for non-Intel x86 systems too
Rob Herring <[email protected]>
arm64: Rename ARM64_WORKAROUND_2966298
Zheng Wang <[email protected]>
media: mtk-jpeg: Fix use after free bug due to error path handling in mtk_jpeg_dec_device_run
Andy Shevchenko <[email protected]>
mmc: mmc_spi: remove custom DMA mapped buffers
Avri Altman <[email protected]>
mmc: core: Use mrq.sbc in close-ended ffu
Michael Grzeschik <[email protected]>
media: videobuf2-dma-sg: fix vmap callback
Vegard Nossum <[email protected]>
scripts/get_abi: fix source path leak
Vegard Nossum <[email protected]>
docs: kernel_abi.py: fix command injection
Alfred Piccioni <[email protected]>
lsm: new security_file_ioctl_compat() hook
Johan Hovold <[email protected]>
arm64: dts: qcom: sm8150: fix USB DP/DM HS PHY interrupts
Johan Hovold <[email protected]>
arm64: dts: qcom: sdm845: fix USB DP/DM HS PHY interrupts
Johan Hovold <[email protected]>
arm64: dts: qcom: sc7280: fix usb_1 wakeup interrupt types
Johan Hovold <[email protected]>
arm64: dts: qcom: sm8150: fix USB wakeup interrupt types
Johan Hovold <[email protected]>
arm64: dts: qcom: sdm845: fix USB wakeup interrupt types
Johan Hovold <[email protected]>
arm64: dts: qcom: sc7180: fix USB wakeup interrupt types
Bart Van Assche <[email protected]>
scsi: ufs: core: Remove the ufshcd_hba_exit() call from ufshcd_async_scan()
Amelie Delaunay <[email protected]>
dmaengine: fix NULL pointer in channel unregistration function
Marcelo Schmitt <[email protected]>
iio: adc: ad7091r: Enable internal vref if external vref is not supplied
Rafael J. Wysocki <[email protected]>
async: Introduce async_schedule_dev_nocall()
Rafael J. Wysocki <[email protected]>
async: Split async_schedule_node_domain()
Helge Deller <[email protected]>
parisc/power: Fix power soft-off button emulation on qemu
Helge Deller <[email protected]>
parisc/firmware: Fix F-extend for PDC addresses
Bhaumik Bhatt <[email protected]>
bus: mhi: host: Add spinlock to protect WP access when queueing TREs
Qiang Yu <[email protected]>
bus: mhi: host: Drop chan lock before queuing buffers
Krishna chaitanya chundru <[email protected]>
bus: mhi: host: Add alignment check for event ring read pointer
Serge Semin <[email protected]>
mips: Fix max_mapnr being uninitialized on early stages
Tony Krowiak <[email protected]>
s390/vfio-ap: let on_scan_complete() callback filter matrix and update guest's APCB
Tony Krowiak <[email protected]>
s390/vfio-ap: loop over the shadow APCB when filtering guest's AP configuration
Tony Krowiak <[email protected]>
s390/vfio-ap: always filter entire AP matrix
Bingbu Cao <[email protected]>
media: ov9734: Enable runtime PM before registering async sub-device
Xiaolei Wang <[email protected]>
rpmsg: virtio: Free driver_override when rpmsg_remove()
Bingbu Cao <[email protected]>
media: imx355: Enable runtime PM before registering async sub-device
Christian Marangi <[email protected]>
PM / devfreq: Fix buffer overflow in trans_stat_show
Anthony Krowiak <[email protected]>
s390/vfio-ap: unpin pages on gisc registration failure
Herbert Xu <[email protected]>
crypto: s390/aes - Fix buffer overread in CTR mode
Herbert Xu <[email protected]>
hwrng: core - Fix page fault dead lock on mmap-ed hwrng
Hongchen Zhang <[email protected]>
PM: hibernate: Enforce ordering during image compression/decompression
Herbert Xu <[email protected]>
crypto: api - Disallow identical driver names
David Disseldorp <[email protected]>
btrfs: sysfs: validate scrub_speed_max value
Viresh Kumar <[email protected]>
OPP: Pass rounded rate to _set_opp()
Josef Bacik <[email protected]>
arm64: properly install vmlinuz.efi
Suraj Jitindar Singh <[email protected]>
ext4: allow for the last group to be marked as trimmed
Marcelo Schmitt <[email protected]>
iio: adc: ad7091r: Allow users to configure device events
Marcelo Schmitt <[email protected]>
iio: adc: ad7091r: Set alert bit in config register
Sean Christopherson <[email protected]>
Revert "nSVM: Check for reserved encodings of TLB_CONTROL in nested VMCB"
Wesley Cheng <[email protected]>
usb: dwc3: gadget: Handle EP0 request dequeuing properly
Wesley Cheng <[email protected]>
usb: dwc3: gadget: Queue PM runtime idle on disconnect event
Wesley Cheng <[email protected]>
usb: dwc3: gadget: Refactor EP0 forced stall/restart into a separate API
-------------
Diffstat:
Documentation/ABI/testing/sysfs-class-devfreq | 3 + Documentation/admin-guide/abi-obsolete.rst | 2 +- Documentation/admin-guide/abi-removed.rst | 2 +- Documentation/admin-guide/abi-stable.rst | 2 +- Documentation/admin-guide/abi-testing.rst | 2 +- Documentation/filesystems/directory-locking.rst | 29 +- Documentation/filesystems/locking.rst | 5 +- Documentation/filesystems/porting.rst | 18 + Documentation/sphinx/kernel_abi.py | 56 +-- Makefile | 4 +- arch/alpha/kernel/rtc.c | 2 +- arch/arm/boot/dts/exynos4210-i9100.dts | 8 + arch/arm/boot/dts/qcom-sdx55.dtsi | 10 +- arch/arm64/Kconfig | 4 + arch/arm64/boot/dts/qcom/sc7180.dtsi | 4 +- arch/arm64/boot/dts/qcom/sc7280.dtsi | 4 +- arch/arm64/boot/dts/qcom/sdm845.dtsi | 16 +- arch/arm64/boot/dts/qcom/sm8150.dtsi | 16 +- arch/arm64/boot/install.sh | 3 +- arch/arm64/kernel/cpu_errata.c | 4 +- arch/arm64/kernel/entry.S | 2 +- arch/arm64/tools/cpucaps | 2 +- arch/loongarch/kernel/smp.c | 3 +- arch/mips/kernel/elf.c | 6 + arch/mips/lantiq/prom.c | 7 +- arch/mips/mm/init.c | 12 +- arch/parisc/kernel/firmware.c | 4 +- arch/powerpc/Kconfig | 1 - arch/s390/crypto/aes_s390.c | 4 +- arch/s390/crypto/paes_s390.c | 4 +- arch/x86/include/asm/syscall_wrapper.h | 25 +- arch/x86/kernel/hpet.c | 2 +- arch/x86/kernel/rtc.c | 2 +- arch/x86/kvm/svm/nested.c | 14 - block/ioctl.c | 2 - block/partitions/core.c | 5 + crypto/algapi.c | 1 + drivers/base/power/main.c | 160 ++++----- drivers/base/power/trace.c | 2 +- drivers/block/nbd.c | 6 +- drivers/block/rbd.c | 22 +- drivers/bus/mhi/ep/main.c | 68 +++- drivers/bus/mhi/host/main.c | 29 +- drivers/char/hw_random/core.c | 34 +- drivers/cpufreq/intel_pstate.c | 55 +-- drivers/cxl/core/region.c | 4 +- drivers/devfreq/devfreq.c | 57 ++- drivers/dma/dmaengine.c | 3 + drivers/firmware/arm_scmi/common.h | 1 + drivers/firmware/arm_scmi/mailbox.c | 14 + drivers/firmware/arm_scmi/shmem.c | 6 + drivers/gpio/gpio-eic-sprd.c | 32 +- drivers/gpio/gpiolib-acpi.c | 14 + drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 2 - drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 +- .../amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c | 21 +- .../drm/amd/display/modules/power/power_helpers.c | 2 + drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 13 +- drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c | 2 + drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c | 2 + drivers/gpu/drm/bridge/analogix/anx7625.c | 7 +- drivers/gpu/drm/bridge/analogix/anx7625.h | 2 + drivers/gpu/drm/bridge/nxp-ptn3460.c | 6 +- drivers/gpu/drm/bridge/parade-ps8640.c | 23 ++ drivers/gpu/drm/bridge/sii902x.c | 68 ++-- drivers/gpu/drm/drm_plane.c | 1 + drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 4 +- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 4 +- drivers/gpu/drm/exynos/exynos_drm_gsc.c | 2 +- drivers/gpu/drm/nouveau/nouveau_vmm.c | 3 + drivers/gpu/drm/panel/panel-edp.c | 4 +- drivers/gpu/drm/panel/panel-simple.c | 2 + drivers/gpu/drm/tidss/tidss_crtc.c | 10 +- drivers/iio/adc/ad7091r-base.c | 169 +++++++++ drivers/iio/adc/ad7091r-base.h | 8 + drivers/iio/adc/ad7091r5.c | 28 +- drivers/media/common/videobuf2/videobuf2-dma-sg.c | 10 +- drivers/media/i2c/imx355.c | 12 +- drivers/media/i2c/ov13b10.c | 86 +++-- drivers/media/i2c/ov9734.c | 19 +- .../media/platform/mediatek/jpeg/mtk_jpeg_core.c | 6 +- drivers/mmc/core/block.c | 46 ++- drivers/mmc/host/mmc_spi.c | 186 +--------- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 5 + drivers/net/ethernet/freescale/fec_main.c | 2 + drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 27 +- .../mellanox/mlx5/core/en/fs_tt_redirect.c | 1 + .../net/ethernet/mellanox/mlx5/core/en/params.c | 4 +- drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c | 26 +- drivers/net/ethernet/mellanox/mlx5/core/lib/aso.c | 2 +- .../mellanox/mlx5/core/steering/dr_action.c | 17 +- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 3 + drivers/net/fjes/fjes_hw.c | 37 +- drivers/net/hyperv/netvsc_drv.c | 4 +- drivers/net/phy/micrel.c | 11 + drivers/net/tun.c | 10 +- drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c | 2 +- drivers/opp/core.c | 6 +- drivers/parisc/power.c | 2 +- .../uncore-frequency/uncore-frequency-common.c | 64 ++-- .../uncore-frequency/uncore-frequency-common.h | 20 +- drivers/platform/x86/p2sb.c | 180 +++++++--- drivers/rpmsg/virtio_rpmsg_bus.c | 1 + drivers/rtc/rtc-cmos.c | 28 +- drivers/rtc/rtc-mc146818-lib.c | 39 ++- drivers/s390/crypto/vfio_ap_ops.c | 72 ++-- drivers/spi/spi-bcm-qspi.c | 4 +- drivers/spi/spi.c | 4 + drivers/thermal/intel/intel_hfi.c | 106 ++++-- drivers/tty/serial/sc16is7xx.c | 389 +++++++++++---------- drivers/ufs/core/ufshcd.c | 7 +- drivers/usb/dwc3/gadget.c | 70 ++-- fs/afs/dir.c | 8 + fs/btrfs/ctree.h | 1 + fs/btrfs/delayed-inode.c | 5 +- fs/btrfs/delayed-inode.h | 1 + fs/btrfs/extent-tree.c | 53 ++- fs/btrfs/inode.c | 172 +++++---- fs/btrfs/ioctl.c | 7 + fs/btrfs/ref-verify.c | 6 +- fs/btrfs/sysfs.c | 4 + fs/btrfs/tree-checker.c | 2 +- fs/dlm/lowcomms.c | 14 +- fs/erofs/decompressor.c | 49 +-- fs/exec.c | 3 + fs/ext4/mballoc.c | 15 +- fs/fscache/cache.c | 3 +- fs/ioctl.c | 3 +- fs/namei.c | 60 ++-- fs/pipe.c | 19 +- fs/smb/server/connection.c | 1 + fs/smb/server/ksmbd_netlink.h | 3 +- fs/smb/server/oplock.c | 16 +- fs/smb/server/smb2pdu.c | 8 +- fs/smb/server/transport_ipc.c | 4 +- fs/ubifs/dir.c | 2 + fs/xfs/xfs_super.c | 27 +- include/linux/async.h | 2 + include/linux/lsm_hook_defs.h | 2 + include/linux/mc146818rtc.h | 3 +- include/linux/mmzone.h | 14 +- include/linux/pipe_fs_i.h | 16 + include/linux/rmap.h | 4 +- include/linux/security.h | 9 + include/linux/serial_core.h | 79 +++++ include/linux/skmsg.h | 6 - include/linux/syscalls.h | 1 + include/net/inet_connection_sock.h | 8 + include/net/inet_sock.h | 5 - include/net/llc_pdu.h | 6 +- include/net/sock.h | 18 +- include/uapi/linux/btrfs.h | 3 + kernel/async.c | 85 +++-- kernel/power/swap.c | 38 +- kernel/rcu/tree.c | 34 +- kernel/rcu/tree_exp.h | 3 +- kernel/time/tick-sched.c | 5 + kernel/trace/tracing_map.c | 7 +- mm/page_alloc.c | 16 +- mm/sparse.c | 17 +- net/8021q/vlan_netlink.c | 4 + net/core/dev.c | 9 + net/core/dev.h | 3 + net/core/request_sock.c | 3 - net/core/sock.c | 11 +- net/ipv4/af_inet.c | 3 + net/ipv4/inet_connection_sock.c | 4 + net/ipv4/tcp.c | 1 + net/ipv6/af_inet6.c | 3 + net/llc/af_llc.c | 24 +- net/llc/llc_core.c | 7 - net/mac80211/sta_info.c | 5 +- net/netfilter/nf_tables_api.c | 20 +- net/netfilter/nft_chain_filter.c | 11 +- net/netfilter/nft_compat.c | 12 + net/netfilter/nft_flow_offload.c | 5 + net/netfilter/nft_limit.c | 23 +- net/netfilter/nft_nat.c | 5 + net/netfilter/nft_rt.c | 5 + net/netfilter/nft_socket.c | 5 + net/netfilter/nft_synproxy.c | 7 +- net/netfilter/nft_tproxy.c | 5 + net/netfilter/nft_xfrm.c | 5 + net/netlink/af_netlink.c | 2 +- net/rds/af_rds.c | 2 +- net/smc/smc_diag.c | 2 +- scripts/get_abi.pl | 2 +- security/security.c | 18 + security/selinux/hooks.c | 28 ++ security/smack/smack_lsm.c | 1 + security/tomoyo/tomoyo.c | 1 + .../drivers/net/netdevsim/udp_tunnel_nic.sh | 9 + 192 files changed, 2418 insertions(+), 1385 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/185 usb: dwc3: gadget: Refactor EP0 forced stall/restart into a separate API
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wesley Cheng <[email protected]>
[ Upstream commit 8f40fc0808137c157dd408d2632e63bfca2aecdb ]
Several sequences utilize the same routine for forcing the control endpoint back into the SETUP phase. This is required, because those operations need to ensure that EP0 is back in the default state.
Stable-dep-of: 3c7af52c7616 ("usb: dwc3: gadget: Queue PM runtime idle on disconnect event")
--- drivers/usb/dwc3/gadget.c | 53 ++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 32 deletions(-)
drivers/usb/dwc3/gadget.c +21 -32
@@ -139,6 +139,24 @@ int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state)return -ETIMEDOUT ; } +static void dwc3_ep0_reset_state (struct dwc3 *dwc) +{ +unsigned int dir; + +if (dwc->ep0state !=EP0_SETUP_PHASE ) { + dir = !!dwc->ep0_expect_in; +if (dwc->ep0state ==EP0_DATA_PHASE ) +dwc3_ep0_end_control_data (dwc, dwc->eps[dir]); +else +dwc3_ep0_end_control_data (dwc, dwc->eps[!dir]); + + dwc->eps[0 ]->trb_enqueue =0 ; + dwc->eps[1 ]->trb_enqueue =0 ; + +dwc3_ep0_stall_and_restart (dwc); + } +} +/** * dwc3_ep_inc_trb - increment a trb index. * @index: Pointer to the TRB index to increment.
@@ -2552,16 +2570,9 @@ static int dwc3_gadget_soft_disconnect(struct dwc3 *dwc) ret =wait_for_completion_timeout (&dwc->ep0_in_setup,msecs_to_jiffies (DWC3_PULL_UP_TIMEOUT ));if (ret ==0 ) { -unsigned int dir; -dev_warn (dwc->dev,"wait for SETUP phase timed out\n" );spin_lock_irqsave (&dwc->lock, flags); - dir = !!dwc->ep0_expect_in; -if (dwc->ep0state ==EP0_DATA_PHASE ) -dwc3_ep0_end_control_data (dwc, dwc->eps[dir]); -else -dwc3_ep0_end_control_data (dwc, dwc->eps[!dir]); -dwc3_ep0_stall_and_restart (dwc); +dwc3_ep0_reset_state (dwc);spin_unlock_irqrestore (&dwc->lock, flags); } }
@@ -3848,16 +3859,7 @@ static void dwc3_gadget_disconnect_interrupt(struct dwc3 *dwc) dwc->setup_packet_pending = false;usb_gadget_set_state (dwc->gadget,USB_STATE_NOTATTACHED ); -if (dwc->ep0state !=EP0_SETUP_PHASE ) { -unsigned int dir; - - dir = !!dwc->ep0_expect_in; -if (dwc->ep0state ==EP0_DATA_PHASE ) -dwc3_ep0_end_control_data (dwc, dwc->eps[dir]); -else -dwc3_ep0_end_control_data (dwc, dwc->eps[!dir]); -dwc3_ep0_stall_and_restart (dwc); - } +dwc3_ep0_reset_state (dwc); }static void dwc3_gadget_reset_interrupt (struct dwc3 *dwc)
@@ -3913,20 +3915,7 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc)* phase. So ensure that EP0 is in setup phase by issuing a stall * and restart if EP0 is not in setup phase. */ -if (dwc->ep0state !=EP0_SETUP_PHASE ) { -unsigned int dir; - - dir = !!dwc->ep0_expect_in; -if (dwc->ep0state ==EP0_DATA_PHASE ) -dwc3_ep0_end_control_data (dwc, dwc->eps[dir]); -else -dwc3_ep0_end_control_data (dwc, dwc->eps[!dir]); - - dwc->eps[0 ]->trb_enqueue =0 ; - dwc->eps[1 ]->trb_enqueue =0 ; - -dwc3_ep0_stall_and_restart (dwc); - } +dwc3_ep0_reset_state (dwc);/* * In the Synopsis DesignWare Cores USB3 Databook Rev. 3.30a
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 2/185 usb: dwc3: gadget: Queue PM runtime idle on disconnect event
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wesley Cheng <[email protected]>
[ Upstream commit 3c7af52c7616c3aa6dacd2336ec748d4a65df8f4 ]
There is a scenario where DWC3 runtime suspend is blocked due to the dwc->connected flag still being true while PM usage_count is zero after DWC3 giveback is completed and the USB gadget session is being terminated. This leads to a case where nothing schedules a PM runtime idle for the device.
The exact condition is seen with the following sequence:
1. USB bus reset is issued by the host
2. Shortly after, or concurrently, a USB PD DR SWAP request is received
(sink->source)
3. USB bus reset event handler runs and issues
dwc3_stop_active_transfers(), and pending transfer are stopped
4. DWC3 usage_count decremented to 0, and runtime idle occurs while
dwc->connected == true, returns -EBUSY 5. DWC3 disconnect event seen, dwc->connected set to false due to DR swap handling
6. No runtime idle after this point
Address this by issuing an asynchronous PM runtime idle call after the disconnect event is completed, as it modifies the dwc->connected flag, which is what blocks the initial runtime idle.
--- drivers/usb/dwc3/gadget.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/usb/dwc3/gadget.c +7 -0
@@ -3860,6 +3860,13 @@ static void dwc3_gadget_disconnect_interrupt(struct dwc3 *dwc)usb_gadget_set_state (dwc->gadget,USB_STATE_NOTATTACHED );dwc3_ep0_reset_state (dwc); + +/* +* Request PM idle to address condition where usage count is +* already decremented to zero, but waiting for the disconnect +* interrupt to set dwc->connected to FALSE. +*/ +pm_request_idle (dwc->dev); }static void dwc3_gadget_reset_interrupt (struct dwc3 *dwc)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 3/185 usb: dwc3: gadget: Handle EP0 request dequeuing properly
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wesley Cheng <[email protected]>
[ Upstream commit 730e12fbec53ab59dd807d981a204258a4cfb29a ]
Current EP0 dequeue path will share the same as other EPs. However, there are some special considerations that need to be made for EP0 transfers:
- EP0 transfers never transition into the started_list
- EP0 only has one active request at a time
In case there is a vendor specific control message for a function over USB FFS, then there is no guarantee on the timeline which the DATA/STATUS stage is responded to. While this occurs, any attempt to end transfers on non-control EPs will end up having the DWC3_EP_DELAY_STOP flag set, and defer issuing of the end transfer command. If the USB FFS application decides to timeout the control transfer, or if USB FFS AIO path exits, the USB FFS driver will issue a call to usb_ep_dequeue() for the ep0 request.
In case of the AIO exit path, the AIO FS blocks until all pending USB requests utilizing the AIO path is completed. However, since the dequeue of ep0 req does not happen properly, all non-control EPs with the DWC3_EP_DELAY_STOP flag set will not be handled, and the AIO exit path will be stuck waiting for the USB FFS data endpoints to receive a completion callback.
Fix is to utilize dwc3_ep0_reset_state() in the dequeue API to ensure EP0 is brought back to the SETUP state, and ensures that any deferred end transfer commands are handled. This also will end any active transfers on EP0, compared to the previous implementation which directly called giveback only.
--- drivers/usb/dwc3/gadget.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
drivers/usb/dwc3/gadget.c +11 -1
@@ -2093,7 +2093,17 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,list_for_each_entry (r, &dep->pending_list, list) {if (r == req) { -dwc3_gadget_giveback (dep, req, -ECONNRESET ); +/* +* Explicitly check for EP0/1 as dequeue for those +* EPs need to be handled differently. Control EP +* only deals with one USB req, and giveback will +* occur during dwc3_ep0_stall_and_restart(). EP0 +* requests are never added to started_list. +*/ +if (dep->number >1 ) +dwc3_gadget_giveback (dep, req, -ECONNRESET ); +else +dwc3_ep0_reset_state (dwc); goto out; } }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 4/185 Revert "nSVM: Check for reserved encodings of TLB_CONTROL in nested VMCB"
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <[email protected]>
[ Upstream commit a484755ab2526ebdbe042397cdd6e427eb4b1a68 ]
Revert KVM's made-up consistency check on SVM's TLB control. The APM says that unsupported encodings are reserved, but the APM doesn't state that VMRUN checks for a supported encoding. Unless something is called out in "Canonicalization and Consistency Checks" or listed as MBZ (Must Be Zero), AMD behavior is typically to let software shoot itself in the foot.
This reverts commit 174a921b6975ef959dd82ee9e8844067a62e3ec1.
--- arch/x86/kvm/svm/nested.c | 14 -------------- 1 file changed, 14 deletions(-)
arch/x86/kvm/svm/nested.c +0 -14
@@ -239,18 +239,6 @@ static bool nested_svm_check_bitmap_pa(struct kvm_vcpu *vcpu, u64 pa, u32 size)kvm_vcpu_is_legal_gpa (vcpu, addr + size -1 ); } -static bool nested_svm_check_tlb_ctl (struct kvm_vcpu *vcpu,u8 tlb_ctl) -{ -/* Nested FLUSHBYASID is not supported yet. */ -switch (tlb_ctl) { -case TLB_CONTROL_DO_NOTHING : -case TLB_CONTROL_FLUSH_ALL_ASID : -return true; -default : -return false; - } -} -static bool __nested_vmcb_check_controls (struct kvm_vcpu *vcpu,struct vmcb_ctrl_area_cached *control) {
@@ -270,8 +258,6 @@ static bool __nested_vmcb_check_controls(struct kvm_vcpu *vcpu, IOPM_SIZE)))return false; -if (CC (!nested_svm_check_tlb_ctl (vcpu, control->tlb_ctl))) -return false;return true; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 5/185 iio: adc: ad7091r: Set alert bit in config register
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marcelo Schmitt <[email protected]>
[ Upstream commit 149694f5e79b0c7a36ceb76e7c0d590db8f151c1 ]
The ad7091r-base driver sets up an interrupt handler for firing events when inputs are either above or below a certain threshold. However, for the interrupt signal to come from the device it must be configured to enable the ALERT/BUSY/GPO pin to be used as ALERT, which was not being done until now.
Enable interrupt signals on the ALERT/BUSY/GPO pin by setting the proper bit in the configuration register.
Stable-dep-of: 020e71c7ffc2 ("iio: adc: ad7091r: Allow users to configure device events")
--- drivers/iio/adc/ad7091r-base.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/iio/adc/ad7091r-base.c +6 -0
@@ -28,6 +28,7 @@#define AD7091R_REG_RESULT_CONV_RESULT (x) ((x) & 0xfff)/* AD7091R_REG_CONF */ +#define AD7091R_REG_CONF_ALERT_EN BIT(4)#define AD7091R_REG_CONF_AUTO BIT(8)#define AD7091R_REG_CONF_CMD BIT(10)
@@ -232,6 +233,11 @@ int ad7091r_probe(struct device *dev, const char *name, iio_dev->channels = chip_info->channels;if (irq) { + ret =regmap_update_bits (st->map,AD7091R_REG_CONF , +AD7091R_REG_CONF_ALERT_EN ,BIT (4 )); +if (ret) +return ret; + ret =devm_request_threaded_irq (dev, irq,NULL , ad7091r_event_handler,IRQF_TRIGGER_FALLING |IRQF_ONESHOT , name, iio_dev);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 6/185 iio: adc: ad7091r: Allow users to configure device events
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marcelo Schmitt <[email protected]>
[ Upstream commit 020e71c7ffc25dfe29ed9be6c2d39af7bd7f661f ]
AD7091R-5 devices are supported by the ad7091r-5 driver together with the ad7091r-base driver. Those drivers declared iio events for notifying user space when ADC readings fall bellow the thresholds of low limit registers or above the values set in high limit registers. However, to configure iio events and their thresholds, a set of callback functions must be implemented and those were not present until now. The consequence of trying to configure ad7091r-5 events without the proper callback functions was a null pointer dereference in the kernel because the pointers to the callback functions were not set.
Implement event configuration callbacks allowing users to read/write event thresholds and enable/disable event generation.
Since the event spec structs are generic to AD7091R devices, also move those from the ad7091r-5 driver the base driver so they can be reused when support for ad7091r-2/-4/-8 be added.
--- drivers/iio/adc/ad7091r-base.c | 156 +++++++++++++++++++++++++++++++++ drivers/iio/adc/ad7091r-base.h | 6 ++ drivers/iio/adc/ad7091r5.c | 28 +----- 3 files changed, 166 insertions(+), 24 deletions(-)
drivers/iio/adc/ad7091r-base.c +156 -0
@@ -6,6 +6,7 @@*/ #include <linux/bitops.h> +#include <linux/bitfield.h> #include <linux/iio/events.h> #include <linux/iio/iio.h> #include <linux/interrupt.h>
@@ -50,6 +51,27 @@ struct ad7091r_state {struct mutex lock;/*lock to prevent concurent reads */ }; +const struct iio_event_spec ad7091r_events[] = { + { + .type =IIO_EV_TYPE_THRESH , + .dir =IIO_EV_DIR_RISING , + .mask_separate =BIT (IIO_EV_INFO_VALUE ) | +BIT (IIO_EV_INFO_ENABLE ), + }, + { + .type =IIO_EV_TYPE_THRESH , + .dir =IIO_EV_DIR_FALLING , + .mask_separate =BIT (IIO_EV_INFO_VALUE ) | +BIT (IIO_EV_INFO_ENABLE ), + }, + { + .type =IIO_EV_TYPE_THRESH , + .dir =IIO_EV_DIR_EITHER , + .mask_separate =BIT (IIO_EV_INFO_HYSTERESIS ), + }, +}; +EXPORT_SYMBOL_NS_GPL (ad7091r_events,IIO_AD7091R ); +static int ad7091r_set_mode (struct ad7091r_state *st,enum ad7091r_mode mode) {int ret, conf;
@@ -169,8 +191,142 @@ static int ad7091r_read_raw(struct iio_dev *iio_dev,return ret; } +static int ad7091r_read_event_config (struct iio_dev *indio_dev, +const struct iio_chan_spec *chan, +enum iio_event_type type, +enum iio_event_direction dir) +{ +struct ad7091r_state *st =iio_priv (indio_dev); +int val, ret; + +switch (dir) { +case IIO_EV_DIR_RISING : + ret =regmap_read (st->map, +AD7091R_REG_CH_HIGH_LIMIT (chan->channel), + &val); +if (ret) +return ret; +return val !=AD7091R_HIGH_LIMIT ; +case IIO_EV_DIR_FALLING : + ret =regmap_read (st->map, +AD7091R_REG_CH_LOW_LIMIT (chan->channel), + &val); +if (ret) +return ret; +return val !=AD7091R_LOW_LIMIT ; +default : +return -EINVAL ; + } +} + +static int ad7091r_write_event_config (struct iio_dev *indio_dev, +const struct iio_chan_spec *chan, +enum iio_event_type type, +enum iio_event_direction dir,int state) +{ +struct ad7091r_state *st =iio_priv (indio_dev); + +if (state) { +return regmap_set_bits (st->map,AD7091R_REG_CONF , +AD7091R_REG_CONF_ALERT_EN ); + }else { +/* +* Set thresholds either to 0 or to 2^12 - 1 as appropriate to +* prevent alerts and thus disable event generation. +*/ +switch (dir) { +case IIO_EV_DIR_RISING : +return regmap_write (st->map, +AD7091R_REG_CH_HIGH_LIMIT (chan->channel), +AD7091R_HIGH_LIMIT ); +case IIO_EV_DIR_FALLING : +return regmap_write (st->map, +AD7091R_REG_CH_LOW_LIMIT (chan->channel), +AD7091R_LOW_LIMIT ); +default : +return -EINVAL ; + } + } +} + +static int ad7091r_read_event_value (struct iio_dev *indio_dev, +const struct iio_chan_spec *chan, +enum iio_event_type type, +enum iio_event_direction dir, +enum iio_event_info info,int *val,int *val2) +{ +struct ad7091r_state *st =iio_priv (indio_dev); +int ret; + +switch (info) { +case IIO_EV_INFO_VALUE : +switch (dir) { +case IIO_EV_DIR_RISING : + ret =regmap_read (st->map, +AD7091R_REG_CH_HIGH_LIMIT (chan->channel), + val); +if (ret) +return ret; +return IIO_VAL_INT ; +case IIO_EV_DIR_FALLING : + ret =regmap_read (st->map, +AD7091R_REG_CH_LOW_LIMIT (chan->channel), + val); +if (ret) +return ret; +return IIO_VAL_INT ; +default : +return -EINVAL ; + } +case IIO_EV_INFO_HYSTERESIS : + ret =regmap_read (st->map, +AD7091R_REG_CH_HYSTERESIS (chan->channel), + val); +if (ret) +return ret; +return IIO_VAL_INT ; +default : +return -EINVAL ; + } +} + +static int ad7091r_write_event_value (struct iio_dev *indio_dev, +const struct iio_chan_spec *chan, +enum iio_event_type type, +enum iio_event_direction dir, +enum iio_event_info info,int val,int val2) +{ +struct ad7091r_state *st =iio_priv (indio_dev); + +switch (info) { +case IIO_EV_INFO_VALUE : +switch (dir) { +case IIO_EV_DIR_RISING : +return regmap_write (st->map, +AD7091R_REG_CH_HIGH_LIMIT (chan->channel), + val); +case IIO_EV_DIR_FALLING : +return regmap_write (st->map, +AD7091R_REG_CH_LOW_LIMIT (chan->channel), + val); +default : +return -EINVAL ; + } +case IIO_EV_INFO_HYSTERESIS : +return regmap_write (st->map, +AD7091R_REG_CH_HYSTERESIS (chan->channel), + val); +default : +return -EINVAL ; + } +} +static const struct iio_info ad7091r_info = { .read_raw = ad7091r_read_raw, + .read_event_config = &ad7091r_read_event_config, + .write_event_config = &ad7091r_write_event_config, + .read_event_value = &ad7091r_read_event_value, + .write_event_value = &ad7091r_write_event_value, };static irqreturn_t ad7091r_event_handler (int irq,void *private)
drivers/iio/adc/ad7091r-base.h +6 -0
@@ -8,6 +8,10 @@#ifndef __DRIVERS_IIO_ADC_AD7091R_BASE_H__#define __DRIVERS_IIO_ADC_AD7091R_BASE_H__ +/* AD7091R_REG_CH_LIMIT */ +#define AD7091R_HIGH_LIMIT 0xFFF +#define AD7091R_LOW_LIMIT 0x0 +struct device ;struct ad7091r_state ;
@@ -17,6 +21,8 @@ struct ad7091r_chip_info {unsigned int vref_mV; }; +extern const struct iio_event_spec ad7091r_events[3 ]; +extern const struct regmap_config ad7091r_regmap_config; int ad7091r_probe(struct device *dev, const char *name,
drivers/iio/adc/ad7091r5.c +4 -24
@@ -12,26 +12,6 @@#include "ad7091r-base.h" -static const struct iio_event_spec ad7091r5_events[] = { - { - .type =IIO_EV_TYPE_THRESH , - .dir =IIO_EV_DIR_RISING , - .mask_separate =BIT (IIO_EV_INFO_VALUE ) | -BIT (IIO_EV_INFO_ENABLE ), - }, - { - .type =IIO_EV_TYPE_THRESH , - .dir =IIO_EV_DIR_FALLING , - .mask_separate =BIT (IIO_EV_INFO_VALUE ) | -BIT (IIO_EV_INFO_ENABLE ), - }, - { - .type =IIO_EV_TYPE_THRESH , - .dir =IIO_EV_DIR_EITHER , - .mask_separate =BIT (IIO_EV_INFO_HYSTERESIS ), - }, -}; -#define AD7091R_CHANNEL (idx, bits, ev, num_ev) { \ .type = IIO_VOLTAGE, \ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
@@ -44,10 +24,10 @@ static const struct iio_event_spec ad7091r5_events[] = { .scan_type.realbits = bits, \ }static const struct iio_chan_spec ad7091r5_channels_irq[] = { -AD7091R_CHANNEL (0 ,12 , ad7091r5_events,ARRAY_SIZE (ad7091r5_events)), -AD7091R_CHANNEL (1 ,12 , ad7091r5_events,ARRAY_SIZE (ad7091r5_events)), -AD7091R_CHANNEL (2 ,12 , ad7091r5_events,ARRAY_SIZE (ad7091r5_events)), -AD7091R_CHANNEL (3 ,12 , ad7091r5_events,ARRAY_SIZE (ad7091r5_events)), +AD7091R_CHANNEL (0 ,12 , ad7091r_events,ARRAY_SIZE (ad7091r_events)), +AD7091R_CHANNEL (1 ,12 , ad7091r_events,ARRAY_SIZE (ad7091r_events)), +AD7091R_CHANNEL (2 ,12 , ad7091r_events,ARRAY_SIZE (ad7091r_events)), +AD7091R_CHANNEL (3 ,12 , ad7091r_events,ARRAY_SIZE (ad7091r_events)), };static const struct iio_chan_spec ad7091r5_channels_noirq[] = {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 7/185 ext4: allow for the last group to be marked as trimmed
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Suraj Jitindar Singh <[email protected]>
commit 7c784d624819acbeefb0018bac89e632467cca5a upstream.
The ext4 filesystem tracks the trim status of blocks at the group level. When an entire group has been trimmed then it is marked as such and subsequent trim invocations with the same minimum trim size will not be attempted on that group unless it is marked as able to be trimmed again such as when a block is freed.
Currently the last group can't be marked as trimmed due to incorrect logic in ext4_last_grp_cluster(). ext4_last_grp_cluster() is supposed to return the zero based index of the last cluster in a group. This is then used by ext4_try_to_trim_range() to determine if the trim operation spans the entire group and as such if the trim status of the group should be recorded.
ext4_last_grp_cluster() takes a 0 based group index, thus the valid values for grp are 0..(ext4_get_groups_count - 1). Any group index less than (ext4_get_groups_count - 1) is not the last group and must have EXT4_CLUSTERS_PER_GROUP(sb) clusters. For the last group we need to calculate the number of clusters based on the number of blocks in the group. Finally subtract 1 from the number of clusters as zero based indexing is expected. Rearrange the function slightly to make it clear what we are calculating and returning.
Reproducer:
// Create file system where the last group has fewer blocks than // blocks per group
$ mkfs.ext4 -b 4096 -g 8192 /dev/nvme0n1 8191 $ mount /dev/nvme0n1 /mnt
Before Patch:
$ fstrim -v /mnt /mnt: 25.9 MiB (27156480 bytes) trimmed // Group not marked as trimmed so second invocation still discards blocks $ fstrim -v /mnt /mnt: 25.9 MiB (27156480 bytes) trimmed
After Patch:
fstrim -v /mnt
/mnt: 25.9 MiB (27156480 bytes) trimmed
// Group marked as trimmed so second invocation DOESN'T discard any blocks fstrim -v /mnt
/mnt: 0 B (0 bytes) trimmed
--- fs/ext4/mballoc.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
fs/ext4/mballoc.c +10 -5
@@ -6421,11 +6421,16 @@ __acquires(bitlock)static ext4_grpblk_t ext4_last_grp_cluster (struct super_block *sb,ext4_group_t grp) { -if (grp <ext4_get_groups_count (sb)) -return EXT4_CLUSTERS_PER_GROUP (sb) -1 ; -return (ext4_blocks_count (EXT4_SB (sb)->s_es) - -ext4_group_first_block_no (sb, grp) -1 ) >> -EXT4_CLUSTER_BITS (sb); +unsigned long nr_clusters_in_group; + +if (grp < (ext4_get_groups_count (sb) -1 )) + nr_clusters_in_group =EXT4_CLUSTERS_PER_GROUP (sb); +else + nr_clusters_in_group = (ext4_blocks_count (EXT4_SB (sb)->s_es) - +ext4_group_first_block_no (sb, grp)) + >>EXT4_CLUSTER_BITS (sb); + +return nr_clusters_in_group -1 ; }static bool ext4_trim_interrupted (void )
Greg Kroah-Hartman
maintainerPATCH 8/185 arm64: properly install vmlinuz.efi
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <[email protected]>
commit 7b21ed7d119dc06b0ed2ba3e406a02cafe3a8d03 upstream.
If you select CONFIG_EFI_ZBOOT, we will generate vmlinuz.efi, and then when we go to install the kernel we'll install the vmlinux instead because install.sh only recognizes Image.gz as wanting the compressed install image. With CONFIG_EFI_ZBOOT we don't get the proper kernel installed, which means it doesn't boot, which makes for a very confused and subsequently angry kernel developer.
Fix this by properly installing our compressed kernel if we've enabled CONFIG_EFI_ZBOOT.
--- arch/arm64/boot/install.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/arm64/boot/install.sh +2 -1
@@ -17,7 +17,8 @@ # $3 - kernel map file # $4 - default install path (blank if root directory) -if [ "$(basename $2)" = "Image.gz" ]; then +if [ "$(basename $2)" = "Image.gz" ] || [ "$(basename $2)" = "vmlinuz.efi" ] +then # Compressed install echo "Installing compressed kernel" base=vmlinuz
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 9/185 OPP: Pass rounded rate to _set_opp()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Viresh Kumar <[email protected]>
commit 7269c250db1b89cda72ca419b7bd5e37997309d6 upstream.
The OPP core finds the eventual frequency to set with the help of clk_round_rate() and the same was earlier getting passed to _set_opp() and that's what would get configured.
The commit 1efae8d2e777 ("OPP: Make dev_pm_opp_set_opp() independent of frequency") mistakenly changed that. Fix it.
--- drivers/opp/core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/opp/core.c +3 -3
@@ -1226,12 +1226,12 @@ int dev_pm_opp_set_rate(struct device *d* value of the frequency. In such a case, do not abort but * configure the hardware to the desired frequency forcefully. */ - forced = opp_table->rate_clk_single != target_freq; + forced = opp_table->rate_clk_single != freq; } - ret =_set_opp (dev, opp_table, opp, &target_freq, forced); + ret =_set_opp (dev, opp_table, opp, &freq, forced); -if (target_freq) +if (freq)dev_pm_opp_put (opp); put_opp_table:
Greg Kroah-Hartman
maintainerPATCH 10/185 btrfs: sysfs: validate scrub_speed_max value
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Disseldorp <[email protected]>
commit 2b0122aaa800b021e36027d7f29e206f87c761d6 upstream.
The value set as scrub_speed_max accepts size with suffixes (k/m/g/t/p/e) but we should still validate it for trailing characters, similar to what we do with chunk_size_store.
--- fs/btrfs/sysfs.c | 4 ++++ 1 file changed, 4 insertions(+)
fs/btrfs/sysfs.c +4 -0
@@ -1704,6 +1704,10 @@ static ssize_t btrfs_devinfo_scrub_speedunsigned long long limit; limit =memparse (buf, &endptr); +/* There could be trailing '\n', also catch any typos after the value. */ + endptr =skip_spaces (endptr); +if (*endptr !=0 ) +return -EINVAL ;WRITE_ONCE (device->scrub_speed_max, limit);return len; }
Greg Kroah-Hartman
maintainerPATCH 11/185 crypto: api - Disallow identical driver names
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Herbert Xu <[email protected]>
commit 27016f75f5ed47e2d8e0ca75a8ff1f40bc1a5e27 upstream.
Disallow registration of two algorithms with identical driver names.
--- crypto/algapi.c | 1 + 1 file changed, 1 insertion(+)
crypto/algapi.c +1 -0
@@ -290,6 +290,7 @@ static struct crypto_larval *__crypto_re }if (!strcmp (q->cra_driver_name, alg->cra_name) || + !strcmp (q->cra_driver_name, alg->cra_driver_name) || !strcmp (q->cra_name, alg->cra_driver_name)) goto err; }
Greg Kroah-Hartman
maintainerPATCH 12/185 PM: hibernate: Enforce ordering during image compression/decompression
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hongchen Zhang <[email protected]>
commit 71cd7e80cfde548959952eac7063aeaea1f2e1c6 upstream.
An S4 (suspend to disk) test on the LoongArch 3A6000 platform sometimes fails with the following error messaged in the dmesg log:
Invalid LZO compressed length
That happens because when compressing/decompressing the image, the synchronization between the control thread and the compress/decompress/crc thread is based on a relaxed ordering interface, which is unreliable, and the following situation may occur:
CPU 0 CPU 1save_image_lzo lzo_compress_threadfn
atomic_set(&d->stop, 1);
atomic_read(&data[thr].stop)
data[thr].cmp = data[thr].cmp_len;
WRITE data[thr].cmp_len
Then CPU0 gets a stale cmp_len and writes it to disk. During resume from S4, wrong cmp_len is loaded.
To maintain data consistency between the two threads, use the acquire/release variants of atomic set and read operations.
--- kernel/power/swap.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-)
kernel/power/swap.c +19 -19
@@ -605,11 +605,11 @@ static int crc32_threadfn(void *data)unsigned i;while (1 ) { -wait_event (d->go,atomic_read (&d->ready) || +wait_event (d->go,atomic_read_acquire (&d->ready) ||kthread_should_stop ());if (kthread_should_stop ()) { d->thr =NULL ; -atomic_set (&d->stop,1 ); +atomic_set_release (&d->stop,1 );wake_up (&d->done);break ; }
@@ -618,7 +618,7 @@ static int crc32_threadfn(void *data)for (i =0 ; i < d->run_threads; i++) *d->crc32 =crc32_le (*d->crc32, d->unc[i], *d->unc_len[i]); -atomic_set (&d->stop,1 ); +atomic_set_release (&d->stop,1 );wake_up (&d->done); }return 0 ;
@@ -648,12 +648,12 @@ static int lzo_compress_threadfn(void *dstruct cmp_data *d = data;while (1 ) { -wait_event (d->go,atomic_read (&d->ready) || +wait_event (d->go,atomic_read_acquire (&d->ready) ||kthread_should_stop ());if (kthread_should_stop ()) { d->thr =NULL ; d->ret =-1 ; -atomic_set (&d->stop,1 ); +atomic_set_release (&d->stop,1 );wake_up (&d->done);break ; }
@@ -662,7 +662,7 @@ static int lzo_compress_threadfn(void *d d->ret =lzo1x_1_compress (d->unc, d->unc_len, d->cmp +LZO_HEADER , &d->cmp_len, d->wrk); -atomic_set (&d->stop,1 ); +atomic_set_release (&d->stop,1 );wake_up (&d->done); }return 0 ;
@@ -797,7 +797,7 @@ static int save_image_lzo(struct swap_ma data[thr].unc_len = off; -atomic_set (&data[thr].ready,1 ); +atomic_set_release (&data[thr].ready,1 );wake_up (&data[thr].go); }
@@ -805,12 +805,12 @@ static int save_image_lzo(struct swap_mabreak ; crc->run_threads = thr; -atomic_set (&crc->ready,1 ); +atomic_set_release (&crc->ready,1 );wake_up (&crc->go);for (run_threads = thr, thr =0 ; thr < run_threads; thr++) {wait_event (data[thr].done, -atomic_read (&data[thr].stop)); +atomic_read_acquire (&data[thr].stop));atomic_set (&data[thr].stop,0 ); ret = data[thr].ret;
@@ -849,7 +849,7 @@ static int save_image_lzo(struct swap_ma } } -wait_event (crc->done,atomic_read (&crc->stop)); +wait_event (crc->done,atomic_read_acquire (&crc->stop));atomic_set (&crc->stop,0 ); }
@@ -1131,12 +1131,12 @@ static int lzo_decompress_threadfn(voidstruct dec_data *d = data;while (1 ) { -wait_event (d->go,atomic_read (&d->ready) || +wait_event (d->go,atomic_read_acquire (&d->ready) ||kthread_should_stop ());if (kthread_should_stop ()) { d->thr =NULL ; d->ret =-1 ; -atomic_set (&d->stop,1 ); +atomic_set_release (&d->stop,1 );wake_up (&d->done);break ; }
@@ -1149,7 +1149,7 @@ static int lzo_decompress_threadfn(voidflush_icache_range ((unsigned long )d->unc, (unsigned long )d->unc + d->unc_len); -atomic_set (&d->stop,1 ); +atomic_set_release (&d->stop,1 );wake_up (&d->done); }return 0 ;
@@ -1334,7 +1334,7 @@ static int load_image_lzo(struct swap_ma }if (crc->run_threads) { -wait_event (crc->done,atomic_read (&crc->stop)); +wait_event (crc->done,atomic_read_acquire (&crc->stop));atomic_set (&crc->stop,0 ); crc->run_threads =0 ; }
@@ -1370,7 +1370,7 @@ static int load_image_lzo(struct swap_ma pg =0 ; } -atomic_set (&data[thr].ready,1 ); +atomic_set_release (&data[thr].ready,1 );wake_up (&data[thr].go); }
@@ -1389,7 +1389,7 @@ static int load_image_lzo(struct swap_mafor (run_threads = thr, thr =0 ; thr < run_threads; thr++) {wait_event (data[thr].done, -atomic_read (&data[thr].stop)); +atomic_read_acquire (&data[thr].stop));atomic_set (&data[thr].stop,0 ); ret = data[thr].ret;
@@ -1420,7 +1420,7 @@ static int load_image_lzo(struct swap_ma ret =snapshot_write_next (snapshot);if (ret <=0 ) { crc->run_threads = thr +1 ; -atomic_set (&crc->ready,1 ); +atomic_set_release (&crc->ready,1 );wake_up (&crc->go); goto out_finish; }
@@ -1428,13 +1428,13 @@ static int load_image_lzo(struct swap_ma } crc->run_threads = thr; -atomic_set (&crc->ready,1 ); +atomic_set_release (&crc->ready,1 );wake_up (&crc->go); } out_finish:if (crc->run_threads) { -wait_event (crc->done,atomic_read (&crc->stop)); +wait_event (crc->done,atomic_read_acquire (&crc->stop));atomic_set (&crc->stop,0 ); } stop =ktime_get ();
Greg Kroah-Hartman
maintainerPATCH 13/185 hwrng: core - Fix page fault dead lock on mmap-ed hwrng
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Herbert Xu <[email protected]>
commit 78aafb3884f6bc6636efcc1760c891c8500b9922 upstream.
There is a dead-lock in the hwrng device read path. This triggers when the user reads from /dev/hwrng into memory also mmap-ed from /dev/hwrng. The resulting page fault triggers a recursive read which then dead-locks.
Fix this by using a stack buffer when calling copy_to_user.
--- drivers/char/hw_random/core.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-)
drivers/char/hw_random/core.c +21 -13
@@ -24,10 +24,13 @@#include <linux/random.h> #include <linux/sched.h> #include <linux/slab.h> +#include <linux/string.h> #include <linux/uaccess.h> #define RNG_MODULE_NAME "hw_random" +#define RNG_BUFFER_SIZE (SMP_CACHE_BYTES < 32 ? 32 : SMP_CACHE_BYTES) +static struct hwrng *current_rng;/* the current rng has been explicitly chosen by user via sysfs */ static int cur_rng_set_by_user;
@@ -59,7 +62,7 @@ static inline int rng_get_data(struct hwstatic size_t rng_buffer_size (void ) { -return SMP_CACHE_BYTES <32 ?32 :SMP_CACHE_BYTES ; +return RNG_BUFFER_SIZE ; }static void add_early_randomness (struct hwrng *rng)
@@ -211,6 +214,7 @@ static inline int rng_get_data(struct hwstatic ssize_t rng_dev_read (struct file *filp,char __user *buf,size_t size,loff_t *offp) { +u8 buffer[RNG_BUFFER_SIZE ];ssize_t ret =0 ;int err =0 ;int bytes_read, len;
@@ -238,34 +242,37 @@ static ssize_t rng_dev_read(struct fileif (bytes_read <0 ) { err = bytes_read; goto out_unlock_reading; + }else if (bytes_read ==0 && + (filp->f_flags &O_NONBLOCK )) { + err = -EAGAIN ; + goto out_unlock_reading; } + data_avail = bytes_read; } -if (!data_avail) { -if (filp->f_flags &O_NONBLOCK ) { - err = -EAGAIN ; - goto out_unlock_reading; - } - }else { - len = data_avail; + len = data_avail; +if (len) {if (len > size) len = size; data_avail -= len; -if (copy_to_user (buf + ret, rng_buffer + data_avail, - len)) { +memcpy (buffer, rng_buffer + data_avail, len); + } +mutex_unlock (&reading_mutex); +put_rng (rng); + +if (len) { +if (copy_to_user (buf + ret, buffer, len)) { err = -EFAULT ; - goto out_unlock_reading; + goto out; } size -= len; ret += len; } -mutex_unlock (&reading_mutex); -put_rng (rng);if (need_resched ())schedule_timeout_interruptible (1 );
@@ -276,6 +283,7 @@ static ssize_t rng_dev_read(struct file } } out: +memzero_explicit (buffer,sizeof (buffer));return ret ? : err; out_unlock_reading:
Greg Kroah-Hartman
maintainerPATCH 14/185 crypto: s390/aes - Fix buffer overread in CTR mode
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Herbert Xu <[email protected]>
commit d07f951903fa9922c375b8ab1ce81b18a0034e3b upstream.
When processing the last block, the s390 ctr code will always read a whole block, even if there isn't a whole block of data left. Fix this by using the actual length left and copy it into a buffer first for processing.
--- arch/s390/crypto/aes_s390.c | 4 +++- arch/s390/crypto/paes_s390.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-)
arch/s390/crypto/aes_s390.c +3 -1
@@ -601,7 +601,9 @@ static int ctr_aes_crypt(struct skcipher* final block may be < AES_BLOCK_SIZE, copy only nbytes */ if (nbytes) { -cpacf_kmctr (sctx->fc, sctx->key, buf, walk.src.virt.addr, +memset (buf,0 ,AES_BLOCK_SIZE ); +memcpy (buf, walk.src.virt.addr, nbytes); +cpacf_kmctr (sctx->fc, sctx->key, buf, buf,AES_BLOCK_SIZE , walk.iv);memcpy (walk.dst.virt.addr, buf, nbytes);crypto_inc (walk.iv,AES_BLOCK_SIZE );
arch/s390/crypto/paes_s390.c +3 -1
@@ -688,9 +688,11 @@ static int ctr_paes_crypt(struct skciphe* final block may be < AES_BLOCK_SIZE, copy only nbytes */ if (nbytes) { +memset (buf,0 ,AES_BLOCK_SIZE ); +memcpy (buf, walk.src.virt.addr, nbytes);while (1 ) {if (cpacf_kmctr (ctx->fc, ¶m, buf, - walk.src.virt.addr,AES_BLOCK_SIZE , + buf,AES_BLOCK_SIZE , walk.iv) ==AES_BLOCK_SIZE )break ;if (__paes_convert_key (ctx))
Greg Kroah-Hartman
maintainerPATCH 15/185 s390/vfio-ap: unpin pages on gisc registration failure
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Anthony Krowiak <[email protected]>
commit 7b2d039da622daa9ba259ac6f38701d542b237c3 upstream.
In the vfio_ap_irq_enable function, after the page containing the notification indicator byte (NIB) is pinned, the function attempts to register the guest ISC. If registration fails, the function sets the status response code and returns without unpinning the page containing the NIB. In order to avoid a memory leak, the NIB should be unpinned before returning from the vfio_ap_irq_enable function.
--- drivers/s390/crypto/vfio_ap_ops.c | 1 + 1 file changed, 1 insertion(+)
drivers/s390/crypto/vfio_ap_ops.c +1 -0
@@ -425,6 +425,7 @@ static struct ap_queue_status vfio_ap_irVFIO_AP_DBF_WARN ("%s: gisc registration failed: nisc=%d, isc=%d, apqn=%#04x\n" , __func__, nisc, isc, q->apqn); +vfio_unpin_pages (&q->matrix_mdev->vdev, nib,1 ); status.response_code =AP_RESPONSE_INVALID_GISA ;return status; }
Greg Kroah-Hartman
maintainerPATCH 16/185 PM / devfreq: Fix buffer overflow in trans_stat_show
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Marangi <[email protected]>
commit 08e23d05fa6dc4fc13da0ccf09defdd4bbc92ff4 upstream.
Fix buffer overflow in trans_stat_show().
Convert simple snprintf to the more secure scnprintf with size of PAGE_SIZE.
Add condition checking if we are exceeding PAGE_SIZE and exit early from loop. Also add at the end a warning that we exceeded PAGE_SIZE and that stats is disabled.
Return -EFBIG in the case where we don't have enough space to write the full transition table.
Also document in the ABI that this function can return -EFBIG error.
--- Documentation/ABI/testing/sysfs-class-devfreq | 3 + drivers/devfreq/devfreq.c | 59 +++++++++++++++++--------- 2 files changed, 43 insertions(+), 19 deletions(-)
Documentation/ABI/testing/sysfs-class-devfreq +3 -0
@@ -52,6 +52,9 @@ Description: echo 0 > /sys/class/devfreq/.../trans_stat + If the transition table is bigger than PAGE_SIZE, reading + this will return an -EFBIG error. + What: /sys/class/devfreq/.../available_frequencies Date: October 2012 Contact: Nishanth Menon <[email protected]>
drivers/devfreq/devfreq.c +40 -19
85 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 17/185 media: imx355: Enable runtime PM before registering async sub-device
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bingbu Cao <[email protected]>
commit efa5fe19c0a9199f49e36e1f5242ed5c88da617d upstream.
As the sensor device maybe accessible right after its async sub-device is registered, such as ipu-bridge will try to power up sensor by sensor's client device's runtime PM from the async notifier callback, if runtime PM is not enabled, it will fail.
So runtime PM should be ready before its async sub-device is registered and accessible by others.
--- drivers/media/i2c/imx355.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
drivers/media/i2c/imx355.c +7 -5
@@ -1784,10 +1784,6 @@ static int imx355_probe(struct i2c_clien goto error_handler_free; } - ret =v4l2_async_register_subdev_sensor (&imx355->sd); -if (ret <0 ) - goto error_media_entity; -/* * Device is already turned on by i2c-core with ACPI domain PM. * Enable runtime PM and turn off the device.
@@ -1796,9 +1792,15 @@ static int imx355_probe(struct i2c_clienpm_runtime_enable (&client->dev);pm_runtime_idle (&client->dev); + ret =v4l2_async_register_subdev_sensor (&imx355->sd); +if (ret <0 ) + goto error_media_entity_runtime_pm; +return 0 ; -error_media_entity: +error_media_entity_runtime_pm: +pm_runtime_disable (&client->dev); +pm_runtime_set_suspended (&client->dev);media_entity_cleanup (&imx355->sd.entity); error_handler_free:
Greg Kroah-Hartman
maintainerPATCH 18/185 rpmsg: virtio: Free driver_override when rpmsg_remove()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiaolei Wang <[email protected]>
commit d5362c37e1f8a40096452fc201c30e705750e687 upstream.
Free driver_override when rpmsg_remove(), otherwise the following memory leak will occur:
unreferenced object 0xffff0000d55d7080 (size 128):
comm "kworker/u8:2", pid 56, jiffies 4294893188 (age 214.272s) hex dump (first 32 bytes):
72 70 6d 73 67 5f 6e 73 00 00 00 00 00 00 00 00 rpmsg_ns........
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<000000009c94c9c1>] __kmem_cache_alloc_node+0x1f8/0x320
[<000000002300d89b>] __kmalloc_node_track_caller+0x44/0x70
[<00000000228a60c3>] kstrndup+0x4c/0x90
[<0000000077158695>] driver_set_override+0xd0/0x164
[<000000003e9c4ea5>] rpmsg_register_device_override+0x98/0x170
[<000000001c0c89a8>] rpmsg_ns_register_device+0x24/0x30
[<000000008bbf8fa2>] rpmsg_probe+0x2e0/0x3ec
[<00000000e65a68df>] virtio_dev_probe+0x1c0/0x280
[<00000000443331cc>] really_probe+0xbc/0x2dc
[<00000000391064b1>] __driver_probe_device+0x78/0xe0
[<00000000a41c9a5b>] driver_probe_device+0xd8/0x160
[<000000009c3bd5df>] __device_attach_driver+0xb8/0x140
[<0000000043cd7614>] bus_for_each_drv+0x7c/0xd4
[<000000003b929a36>] __device_attach+0x9c/0x19c
[<00000000a94e0ba8>] device_initial_probe+0x14/0x20
[<000000003c999637>] bus_probe_device+0xa0/0xac--- drivers/rpmsg/virtio_rpmsg_bus.c | 1 + 1 file changed, 1 insertion(+)
drivers/rpmsg/virtio_rpmsg_bus.c +1 -0
@@ -378,6 +378,7 @@ static void virtio_rpmsg_release_device(struct rpmsg_device *rpdev =to_rpmsg_device (dev);struct virtio_rpmsg_channel *vch =to_virtio_rpmsg_channel (rpdev); +kfree (rpdev->driver_override);kfree (vch); }
Greg Kroah-Hartman
maintainerPATCH 19/185 media: ov9734: Enable runtime PM before registering async sub-device
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bingbu Cao <[email protected]>
commit e242e9c144050ed120cf666642ba96b7c4462a4c upstream.
As the sensor device maybe accessible right after its async sub-device is registered, such as ipu-bridge will try to power up sensor by sensor's client device's runtime PM from the async notifier callback, if runtime PM is not enabled, it will fail.
So runtime PM should be ready before its async sub-device is registered and accessible by others.
--- drivers/media/i2c/ov9734.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-)
drivers/media/i2c/ov9734.c +11 -8
@@ -939,6 +939,7 @@ static void ov9734_remove(struct i2c_climedia_entity_cleanup (&sd->entity);v4l2_ctrl_handler_free (sd->ctrl_handler);pm_runtime_disable (&client->dev); +pm_runtime_set_suspended (&client->dev);mutex_destroy (&ov9734->mutex); }
@@ -984,13 +985,6 @@ static int ov9734_probe(struct i2c_clien goto probe_error_v4l2_ctrl_handler_free; } - ret =v4l2_async_register_subdev_sensor (&ov9734->sd); -if (ret <0 ) { -dev_err (&client->dev,"failed to register V4L2 subdev: %d" , - ret); - goto probe_error_media_entity_cleanup; - } -/* * Device is already turned on by i2c-core with ACPI domain PM. * Enable runtime PM and turn off the device.
@@ -999,9 +993,18 @@ static int ov9734_probe(struct i2c_clienpm_runtime_enable (&client->dev);pm_runtime_idle (&client->dev); + ret =v4l2_async_register_subdev_sensor (&ov9734->sd); +if (ret <0 ) { +dev_err (&client->dev,"failed to register V4L2 subdev: %d" , + ret); + goto probe_error_media_entity_cleanup_pm; + } +return 0 ; -probe_error_media_entity_cleanup: +probe_error_media_entity_cleanup_pm: +pm_runtime_disable (&client->dev); +pm_runtime_set_suspended (&client->dev);media_entity_cleanup (&ov9734->sd.entity); probe_error_v4l2_ctrl_handler_free:
Greg Kroah-Hartman
maintainerPATCH 20/185 s390/vfio-ap: always filter entire AP matrix
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tony Krowiak <[email protected]>
commit 850fb7fa8c684a4c6bf0e4b6978f4ddcc5d43d11 upstream.
The vfio_ap_mdev_filter_matrix function is called whenever a new adapter or domain is assigned to the mdev. The purpose of the function is to update the guest's AP configuration by filtering the matrix of adapters and domains assigned to the mdev. When an adapter or domain is assigned, only the APQNs associated with the APID of the new adapter or APQI of the new domain are inspected. If an APQN does not reference a queue device bound to the vfio_ap device driver, then it's APID will be filtered from the mdev's matrix when updating the guest's AP configuration.
Inspecting only the APID of the new adapter or APQI of the new domain will result in passing AP queues through to a guest that are not bound to the vfio_ap device driver under certain circumstances. Consider the following:
guest's AP configuration (all also assigned to the mdev's matrix):
14.0004
14.0005
14.0006
16.0004
16.0005
16.0006
unassign domain 4
unbind queue 16.0005
assign domain 4
When domain 4 is re-assigned, since only domain 4 will be inspected, the APQNs that will be examined will be:
14.0004
16.0004
Since both of those APQNs reference queue devices that are bound to the vfio_ap device driver, nothing will get filtered from the mdev's matrix when updating the guest's AP configuration. Consequently, queue 16.0005 will get passed through despite not being bound to the driver. This violates the linux device model requirement that a guest shall only be given access to devices bound to the device driver facilitating their pass-through.
To resolve this problem, every adapter and domain assigned to the mdev will be inspected when filtering the mdev's matrix.
--- drivers/s390/crypto/vfio_ap_ops.c | 57 +++++++++++--------------------------- 1 file changed, 17 insertions(+), 40 deletions(-)
drivers/s390/crypto/vfio_ap_ops.c +17 -40
@@ -639,8 +639,7 @@ static bool vfio_ap_mdev_filter_cdoms(st* Return: a boolean value indicating whether the KVM guest's APCB was changed * by the filtering or not. */ -static bool vfio_ap_mdev_filter_matrix (unsigned long *apm,unsigned long *aqm, -struct ap_matrix_mdev *matrix_mdev) +static bool vfio_ap_mdev_filter_matrix (struct ap_matrix_mdev *matrix_mdev) {unsigned long apid, apqi, apqn;DECLARE_BITMAP (prev_shadow_apm,AP_DEVICES );
@@ -661,8 +660,8 @@ static bool vfio_ap_mdev_filter_matrix(ubitmap_and (matrix_mdev->shadow_apcb.aqm, matrix_mdev->matrix.aqm, (unsigned long *)matrix_dev->info.aqm,AP_DOMAINS ); -for_each_set_bit_inv (apid, apm,AP_DEVICES ) { -for_each_set_bit_inv (apqi, aqm,AP_DOMAINS ) { +for_each_set_bit_inv (apid, matrix_mdev->matrix.apm,AP_DEVICES ) { +for_each_set_bit_inv (apqi, matrix_mdev->matrix.aqm,AP_DOMAINS ) {/* * If the APQN is not bound to the vfio_ap device * driver, then we can't assign it to the guest's
@@ -931,7 +930,6 @@ static ssize_t assign_adapter_store(stru {int ret;unsigned long apid; -DECLARE_BITMAP (apm_delta,AP_DEVICES );struct ap_matrix_mdev *matrix_mdev =dev_get_drvdata (dev);mutex_lock (&ap_perms_mutex);
@@ -960,11 +958,8 @@ static ssize_t assign_adapter_store(stru }vfio_ap_mdev_link_adapter (matrix_mdev, apid); -memset (apm_delta,0 ,sizeof (apm_delta)); -set_bit_inv (apid, apm_delta); -if (vfio_ap_mdev_filter_matrix (apm_delta, - matrix_mdev->matrix.aqm, matrix_mdev)) +if (vfio_ap_mdev_filter_matrix (matrix_mdev))vfio_ap_mdev_update_guest_apcb (matrix_mdev); ret = count;
@@ -1140,7 +1135,6 @@ static ssize_t assign_domain_store(struc {int ret;unsigned long apqi; -DECLARE_BITMAP (aqm_delta,AP_DOMAINS );struct ap_matrix_mdev *matrix_mdev =dev_get_drvdata (dev);mutex_lock (&ap_perms_mutex);
@@ -1169,11 +1163,8 @@ static ssize_t assign_domain_store(struc }vfio_ap_mdev_link_domain (matrix_mdev, apqi); -memset (aqm_delta,0 ,sizeof (aqm_delta)); -set_bit_inv (apqi, aqm_delta); -if (vfio_ap_mdev_filter_matrix (matrix_mdev->matrix.apm, aqm_delta, - matrix_mdev)) +if (vfio_ap_mdev_filter_matrix (matrix_mdev))vfio_ap_mdev_update_guest_apcb (matrix_mdev); ret = count;
@@ -1859,9 +1850,7 @@ int vfio_ap_mdev_probe_queue(struct ap_dif (matrix_mdev) {vfio_ap_mdev_link_queue (matrix_mdev, q); -if (vfio_ap_mdev_filter_matrix (matrix_mdev->matrix.apm, - matrix_mdev->matrix.aqm, - matrix_mdev)) +if (vfio_ap_mdev_filter_matrix (matrix_mdev))vfio_ap_mdev_update_guest_apcb (matrix_mdev); }dev_set_drvdata (&apdev->device, q);
@@ -2212,34 +2201,22 @@ void vfio_ap_on_cfg_changed(struct ap_costatic void vfio_ap_mdev_hot_plug_cfg (struct ap_matrix_mdev *matrix_mdev) { -bool do_hotplug = false; -int filter_domains =0 ; -int filter_adapters =0 ; -DECLARE_BITMAP (apm,AP_DEVICES ); -DECLARE_BITMAP (aqm,AP_DOMAINS ); +bool filter_domains, filter_adapters, filter_cdoms, do_hotplug = false;mutex_lock (&matrix_mdev->kvm->lock);mutex_lock (&matrix_dev->mdevs_lock); - filter_adapters =bitmap_and (apm, matrix_mdev->matrix.apm, - matrix_mdev->apm_add,AP_DEVICES ); - filter_domains =bitmap_and (aqm, matrix_mdev->matrix.aqm, - matrix_mdev->aqm_add,AP_DOMAINS ); - -if (filter_adapters && filter_domains) - do_hotplug |=vfio_ap_mdev_filter_matrix (apm, aqm, matrix_mdev); -else if (filter_adapters) - do_hotplug |= -vfio_ap_mdev_filter_matrix (apm, - matrix_mdev->shadow_apcb.aqm, - matrix_mdev); -else - do_hotplug |= -vfio_ap_mdev_filter_matrix (matrix_mdev->shadow_apcb.apm, - aqm, matrix_mdev); + filter_adapters =bitmap_intersects (matrix_mdev->matrix.apm, + matrix_mdev->apm_add,AP_DEVICES ); + filter_domains =bitmap_intersects (matrix_mdev->matrix.aqm, + matrix_mdev->aqm_add,AP_DOMAINS ); + filter_cdoms =bitmap_intersects (matrix_mdev->matrix.adm, + matrix_mdev->adm_add,AP_DOMAINS ); + +if (filter_adapters || filter_domains) + do_hotplug =vfio_ap_mdev_filter_matrix (matrix_mdev); -if (bitmap_intersects (matrix_mdev->matrix.adm, matrix_mdev->adm_add, -AP_DOMAINS )) +if (filter_cdoms) do_hotplug |=vfio_ap_mdev_filter_cdoms (matrix_mdev);if (do_hotplug)
Greg Kroah-Hartman
maintainerPATCH 21/185 s390/vfio-ap: loop over the shadow APCB when filtering guests AP configuration
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tony Krowiak <[email protected]>
commit 16fb78cbf56e42b8efb2682a4444ab59e32e7959 upstream.
While filtering the mdev matrix, it doesn't make sense - and will have unexpected results - to filter an APID from the matrix if the APID or one of the associated APQIs is not in the host's AP configuration. There are two reasons for this:
1. An adapter or domain that is not in the host's AP configuration can be assigned to the matrix; this is known as over-provisioning. Queue devices, however, are only created for adapters and domains in the host's AP configuration, so there will be no queues associated with an over-provisioned adapter or domain to filter.
2. The adapter or domain may have been externally removed from the host's configuration via an SE or HMC attached to a DPM enabled LPAR. In this case, the vfio_ap device driver would have been notified by the AP bus via the on_config_changed callback and the adapter or domain would have already been filtered.
Since the matrix_mdev->shadow_apcb.apm and matrix_mdev->shadow_apcb.aqm are copied from the mdev matrix sans the APIDs and APQIs not in the host's AP configuration, let's loop over those bitmaps instead of those assigned to the matrix.
--- drivers/s390/crypto/vfio_ap_ops.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/s390/crypto/vfio_ap_ops.c +3 -2
@@ -660,8 +660,9 @@ static bool vfio_ap_mdev_filter_matrix(sbitmap_and (matrix_mdev->shadow_apcb.aqm, matrix_mdev->matrix.aqm, (unsigned long *)matrix_dev->info.aqm,AP_DOMAINS ); -for_each_set_bit_inv (apid, matrix_mdev->matrix.apm,AP_DEVICES ) { -for_each_set_bit_inv (apqi, matrix_mdev->matrix.aqm,AP_DOMAINS ) { +for_each_set_bit_inv (apid, matrix_mdev->shadow_apcb.apm,AP_DEVICES ) { +for_each_set_bit_inv (apqi, matrix_mdev->shadow_apcb.aqm, +AP_DOMAINS ) {/* * If the APQN is not bound to the vfio_ap device * driver, then we can't assign it to the guest's
Greg Kroah-Hartman
maintainerPATCH 22/185 s390/vfio-ap: let on_scan_complete() callback filter matrix and update guests APCB
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tony Krowiak <[email protected]>
commit 774d10196e648e2c0b78da817f631edfb3dfa557 upstream.
When adapters and/or domains are added to the host's AP configuration, this may result in multiple queue devices getting created and probed by the vfio_ap device driver. For each queue device probed, the matrix of adapters and domains assigned to a matrix mdev will be filtered to update the guest's APCB. If any adapters or domains get added to or removed from the APCB, the guest's AP configuration will be dynamically updated (i.e., hot plug/unplug). To dynamically update the guest's configuration, its VCPUs must be taken out of SIE for the period of time it takes to make the update. This is disruptive to the guest's operation and if there are many queues probed due to a change in the host's AP configuration, this could be troublesome. The problem is exacerbated by the fact that the 'on_scan_complete' callback also filters the mdev's matrix and updates the guest's AP configuration.
In order to reduce the potential amount of disruption to the guest that may result from a change to the host's AP configuration, let's bypass the filtering of the matrix and updating of the guest's AP configuration in the probe callback - if due to a host config change - and defer it until the 'on_scan_complete' callback is invoked after the AP bus finishes its device scan operation. This way the filtering and updating will be performed only once regardless of the number of queues added.
--- drivers/s390/crypto/vfio_ap_ops.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
drivers/s390/crypto/vfio_ap_ops.c +13 -0
@@ -1851,9 +1851,22 @@ int vfio_ap_mdev_probe_queue(struct ap_dif (matrix_mdev) {vfio_ap_mdev_link_queue (matrix_mdev, q); +/* +* If we're in the process of handling the adding of adapters or +* domains to the host's AP configuration, then let the +* vfio_ap device driver's on_scan_complete callback filter the +* matrix and update the guest's AP configuration after all of +* the new queue devices are probed. +*/ +if (!bitmap_empty (matrix_mdev->apm_add,AP_DEVICES ) || + !bitmap_empty (matrix_mdev->aqm_add,AP_DOMAINS )) + goto done; +if (vfio_ap_mdev_filter_matrix (matrix_mdev))vfio_ap_mdev_update_guest_apcb (matrix_mdev); } + +done:dev_set_drvdata (&apdev->device, q);release_update_locks_for_mdev (matrix_mdev);
Greg Kroah-Hartman
maintainerPATCH 23/185 mips: Fix max_mapnr being uninitialized on early stages
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Serge Semin <[email protected]>
commit e1a9ae45736989c972a8d1c151bc390678ae6205 upstream.
max_mapnr variable is utilized in the pfn_valid() method in order to determine the upper PFN space boundary. Having it uninitialized effectively makes any PFN passed to that method invalid. That in its turn causes the kernel mm-subsystem occasion malfunctions even after the max_mapnr variable is actually properly updated. For instance, pfn_valid() is called in the init_unavailable_range() method in the framework of the calls-chain on MIPS:setup_arch()
+-> paging_init()
+-> free_area_init()
+-> memmap_init()
+-> memmap_init_zone_range()
+-> init_unavailable_range()Since pfn_valid() always returns "false" value before max_mapnr is initialized in the mem_init() method, any flatmem page-holes will be left in the poisoned/uninitialized state including the IO-memory pages. Thus any further attempts to map/remap the IO-memory by using MMU may fail. In particular it happened in my case on attempt to map the SRAM region. The kernel bootup procedure just crashed on the unhandled unaligned access bug raised in the __update_cache() method:
Quoted 11 lines
Unhandled kernel unaligned access[#1]:
CPU: 0 PID: 1 Comm: swapper/0 Not tainted 6.7.0-rc1-XXX-dirty #2056 ... Call Trace: [<8011ef9c>] __update_cache+0x88/0x1bc [<80385944>] ioremap_page_range+0x110/0x2a4 [<80126948>] ioremap_prot+0x17c/0x1f4 [<80711b80>] __devm_ioremap+0x8c/0x120 [<80711e0c>] __devm_ioremap_resource+0xf4/0x218 [<808bf244>] sram_probe+0x4f4/0x930 [<80889d20>] platform_probe+0x68/0xec
Quoted 1 line
...
Let's fix the problem by initializing the max_mapnr variable as soon as the required data is available. In particular it can be done right in the paging_init() method before free_area_init() is called since all the PFN zone boundaries have already been calculated by that time.
--- arch/mips/mm/init.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-)
arch/mips/mm/init.c +5 -7
@@ -417,7 +417,12 @@ void __init paging_init(void) (highend_pfn - max_low_pfn) << (PAGE_SHIFT - 10)); max_zone_pfns[ZONE_HIGHMEM] = max_low_pfn; } + + max_mapnr = highend_pfn ? highend_pfn : max_low_pfn; +#else + max_mapnr = max_low_pfn;#endif + high_memory = (void *)__va (max_low_pfn <<PAGE_SHIFT );free_area_init (max_zone_pfns); }
@@ -453,13 +458,6 @@ void __init mem_init(void)*/ BUILD_BUG_ON (IS_ENABLED (CONFIG_32BIT ) && (_PFN_SHIFT >PAGE_SHIFT )); -#ifdef CONFIG_HIGHMEM - max_mapnr = highend_pfn ? highend_pfn : max_low_pfn; -#else - max_mapnr = max_low_pfn; -#endif - high_memory = (void *)__va (max_low_pfn <<PAGE_SHIFT ); -maar_init ();memblock_free_all ();setup_zero_pages ();/* Setup zeroed pages. */
Greg Kroah-Hartman
maintainerPATCH 24/185 bus: mhi: host: Add alignment check for event ring read pointer
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krishna chaitanya chundru <[email protected]>
commit eff9704f5332a13b08fbdbe0f84059c9e7051d5f upstream.
Though we do check the event ring read pointer by "is_valid_ring_ptr" to make sure it is in the buffer range, but there is another risk the pointer may be not aligned. Since we are expecting event ring elements are 128 bits(struct mhi_ring_element) aligned, an unaligned read pointer could lead to multiple issues like DoS or ring buffer memory corruption.
So add a alignment check for event ring read pointer.
--- drivers/bus/mhi/host/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/bus/mhi/host/main.c +2 -1
@@ -268,7 +268,8 @@ static void mhi_del_ring_element(structstatic bool is_valid_ring_ptr (struct mhi_ring *ring,dma_addr_t addr) { -return addr >= ring->iommu_base && addr < ring->iommu_base + ring->len; +return addr >= ring->iommu_base && addr < ring->iommu_base + ring->len && + !(addr & (sizeof (struct mhi_ring_element ) -1 )); }int mhi_destroy_device (struct device *dev,void *data)
Greg Kroah-Hartman
maintainerPATCH 25/185 bus: mhi: host: Drop chan lock before queuing buffers
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qiang Yu <[email protected]>
commit 01bd694ac2f682fb8017e16148b928482bc8fa4b upstream.
Ensure read and write locks for the channel are not taken in succession by dropping the read lock from parse_xfer_event() such that a callback given to client can potentially queue buffers and acquire the write lock in that process. Any queueing of buffers should be done without channel read lock acquired as it can result in multiple locks and a soft lockup.
--- drivers/bus/mhi/host/main.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/bus/mhi/host/main.c +4 -0
@@ -643,6 +643,8 @@ static int parse_xfer_event(struct mhi_cmhi_del_ring_element (mhi_cntrl, tre_ring); local_rp = tre_ring->rp; +read_unlock_bh (&mhi_chan->lock); +/* notify client */ mhi_chan->xfer_cb (mhi_chan->mhi_dev, &result);
@@ -668,6 +670,8 @@ static int parse_xfer_event(struct mhi_ckfree (buf_info->cb_buf); } } + +read_lock_bh (&mhi_chan->lock); }break ; }/* CC_EOT */
Greg Kroah-Hartman
maintainerPATCH 26/185 bus: mhi: host: Add spinlock to protect WP access when queueing TREs
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bhaumik Bhatt <[email protected]>
commit b89b6a863dd53bc70d8e52d50f9cfaef8ef5e9c9 upstream.
Protect WP accesses such that multiple threads queueing buffers for incoming data do not race.
Meanwhile, if CONFIG_TRACE_IRQFLAGS is enabled, irq will be enabled once __local_bh_enable_ip is called as part of write_unlock_bh. Hence, let's take irqsave lock after TRE is generated to avoid running write_unlock_bh when irqsave lock is held.
--- drivers/bus/mhi/host/main.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-)
drivers/bus/mhi/host/main.c +13 -9
@@ -1124,17 +1124,15 @@ static int mhi_queue(struct mhi_device *if (unlikely (MHI_PM_IN_ERROR_STATE (mhi_cntrl->pm_state)))return -EIO ; -read_lock_irqsave (&mhi_cntrl->pm_lock, flags); - ret =mhi_is_ring_full (mhi_cntrl, tre_ring); -if (unlikely (ret)) { - ret = -EAGAIN ; - goto exit_unlock; - } +if (unlikely (ret)) +return -EAGAIN ; ret =mhi_gen_tre (mhi_cntrl, mhi_chan, buf_info, mflags);if (unlikely (ret)) - goto exit_unlock; +return ret; + +read_lock_irqsave (&mhi_cntrl->pm_lock, flags);/* Packet is queued, take a usage ref to exit M3 if necessary * for host->device buffer, balanced put is done on buffer completion
@@ -1154,7 +1152,6 @@ static int mhi_queue(struct mhi_device *if (dir ==DMA_FROM_DEVICE ) mhi_cntrl->runtime_put (mhi_cntrl); -exit_unlock:read_unlock_irqrestore (&mhi_cntrl->pm_lock, flags);return ret;
@@ -1206,6 +1203,9 @@ int mhi_gen_tre(struct mhi_controller *mint eot, eob, chain, bei;int ret; +/* Protect accesses for reading and incrementing WP */ +write_lock_bh (&mhi_chan->lock); + buf_ring = &mhi_chan->buf_ring; tre_ring = &mhi_chan->tre_ring;
@@ -1223,8 +1223,10 @@ int mhi_gen_tre(struct mhi_controller *mif (!info->pre_mapped) { ret = mhi_cntrl->map_single (mhi_cntrl, buf_info); -if (ret) +if (ret) { +write_unlock_bh (&mhi_chan->lock);return ret; + } } eob = !!(flags &MHI_EOB );
@@ -1241,6 +1243,8 @@ int mhi_gen_tre(struct mhi_controller *mmhi_add_ring_element (mhi_cntrl, tre_ring);mhi_add_ring_element (mhi_cntrl, buf_ring); +write_unlock_bh (&mhi_chan->lock); +return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 27/185 parisc/firmware: Fix F-extend for PDC addresses
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Helge Deller <[email protected]>
commit 735ae74f73e55c191d48689bd11ff4a06ea0508f upstream.
When running with narrow firmware (64-bit kernel using a 32-bit firmware), extend PDC addresses into the 0xfffffff0.00000000 region instead of the 0xf0f0f0f0.00000000 region.
This fixes the power button on the C3700 machine in qemu (64-bit CPU with 32-bit firmware), and my assumption is that the previous code was really never used (because most 64-bit machines have a 64-bit firmware), or it just worked on very old machines because they may only decode 40-bit of virtual addresses.
--- arch/parisc/kernel/firmware.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/parisc/kernel/firmware.c +2 -2
@@ -123,10 +123,10 @@ static unsigned long f_extend(unsigned l#ifdef CONFIG_64BIT if (unlikely (parisc_narrow_firmware)) {if ((address &0xff000000 ) ==0xf0000000 ) -return 0xf0f0f0f000000000UL | (u32 )address; +return (0xfffffff0UL <<32 ) | (u32 )address;if ((address &0xf0000000 ) ==0xf0000000 ) -return 0xffffffff00000000UL | (u32 )address; +return (0xffffffffUL <<32 ) | (u32 )address; }#endif return address;
Greg Kroah-Hartman
maintainerPATCH 28/185 parisc/power: Fix power soft-off button emulation on qemu
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Helge Deller <[email protected]>
commit 6472036581f947109b20664121db1d143e916f0b upstream.
Make sure to start the kthread to check the power button on qemu as well if the power button address was provided.
This fixes the qemu built-in system_powerdown runtime command.
--- drivers/parisc/power.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/parisc/power.c +1 -1
@@ -238,7 +238,7 @@ static int __init power_init(void)if (running_on_qemu && soft_power_reg)register_sys_off_handler (SYS_OFF_MODE_POWER_OFF ,SYS_OFF_PRIO_DEFAULT , qemu_power_off, (void *)soft_power_reg); -else +if (!running_on_qemu || soft_power_reg) power_task =kthread_run (kpowerswd, (void *)soft_power_reg,KTHREAD_NAME );if (IS_ERR (power_task)) {
Greg Kroah-Hartman
maintainerPATCH 29/185 async: Split async_schedule_node_domain()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rafael J. Wysocki <[email protected]>
commit 6aa09a5bccd8e224d917afdb4c278fc66aacde4d upstream.
In preparation for subsequent changes, split async_schedule_node_domain() in two pieces so as to allow the bottom part of it to be called from a somewhat different code path.
No functional impact.
--- kernel/async.c | 56 ++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 22 deletions(-)
kernel/async.c +34 -22
@@ -145,6 +145,39 @@ static void async_run_entry_fn(struct wowake_up (&async_done); } +static async_cookie_t __async_schedule_node_domain (async_func_t func, +void *data,int node, +struct async_domain *domain, +struct async_entry *entry) +{ +async_cookie_t newcookie; +unsigned long flags; + +INIT_LIST_HEAD (&entry->domain_list); +INIT_LIST_HEAD (&entry->global_list); +INIT_WORK (&entry->work, async_run_entry_fn); + entry->func = func; + entry->data = data; + entry->domain = domain; + +spin_lock_irqsave (&async_lock, flags); + +/* allocate cookie and queue */ + newcookie = entry->cookie = next_cookie++; + +list_add_tail (&entry->domain_list, &domain->pending); +if (domain->registered) +list_add_tail (&entry->global_list, &async_global_pending); + +atomic_inc (&entry_count); +spin_unlock_irqrestore (&async_lock, flags); + +/* schedule for execution */ +queue_work_node (node, system_unbound_wq, &entry->work); + +return newcookie; +} +/** * async_schedule_node_domain - NUMA specific version of async_schedule_domain * @func: function to execute asynchronously
@@ -186,29 +219,8 @@ async_cookie_t async_schedule_node_domaifunc (data, newcookie);return newcookie; } -INIT_LIST_HEAD (&entry->domain_list); -INIT_LIST_HEAD (&entry->global_list); -INIT_WORK (&entry->work, async_run_entry_fn); - entry->func = func; - entry->data = data; - entry->domain = domain; - -spin_lock_irqsave (&async_lock, flags); -/* allocate cookie and queue */ - newcookie = entry->cookie = next_cookie++; - -list_add_tail (&entry->domain_list, &domain->pending); -if (domain->registered) -list_add_tail (&entry->global_list, &async_global_pending); - -atomic_inc (&entry_count); -spin_unlock_irqrestore (&async_lock, flags); - -/* schedule for execution */ -queue_work_node (node, system_unbound_wq, &entry->work); - -return newcookie; +return __async_schedule_node_domain (func, data, node, domain, entry); }EXPORT_SYMBOL_GPL (async_schedule_node_domain);
Greg Kroah-Hartman
maintainerPATCH 30/185 async: Introduce async_schedule_dev_nocall()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rafael J. Wysocki <[email protected]>
commit 7d4b5d7a37bdd63a5a3371b988744b060d5bb86f upstream.
In preparation for subsequent changes, introduce a specialized variant of async_schedule_dev() that will not invoke the argument function synchronously when it cannot be scheduled for asynchronous execution.
The new function, async_schedule_dev_nocall(), will be used for fixing possible deadlocks in the system-wide power management core code.
--- include/linux/async.h | 2 ++ kernel/async.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+)
include/linux/async.h +2 -0
@@ -90,6 +90,8 @@ async_schedule_dev(async_func_t func, streturn async_schedule_node (func, dev,dev_to_node (dev)); } +bool async_schedule_dev_nocall (async_func_t func,struct device *dev); +/** * async_schedule_dev_domain - A device specific version of async_schedule_domain * @func: function to execute asynchronously
kernel/async.c +29 -0
@@ -244,6 +244,35 @@ async_cookie_t async_schedule_node(asyncEXPORT_SYMBOL_GPL (async_schedule_node);/** +* async_schedule_dev_nocall - A simplified variant of async_schedule_dev() +* @func: function to execute asynchronously +* @dev: device argument to be passed to function +* +* @dev is used as both the argument for the function and to provide NUMA +* context for where to run the function. +* +* If the asynchronous execution of @func is scheduled successfully, return +* true. Otherwise, do nothing and return false, unlike async_schedule_dev() +* that will run the function synchronously then. +*/ +bool async_schedule_dev_nocall (async_func_t func,struct device *dev) +{ +struct async_entry *entry; + + entry =kzalloc (sizeof (struct async_entry ),GFP_KERNEL ); + +/* Give up if there is no memory or too much work. */ +if (!entry ||atomic_read (&entry_count) >MAX_WORK ) { +kfree (entry); +return false; + } + +__async_schedule_node_domain (func, dev,dev_to_node (dev), + &async_dfl_domain, entry); +return true; +} + +/** * async_synchronize_full - synchronize all asynchronous function calls * * This function waits until all asynchronous function calls have been done.
Greg Kroah-Hartman
maintainerPATCH 31/185 iio: adc: ad7091r: Enable internal vref if external vref is not supplied
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marcelo Schmitt <[email protected]>
[ Upstream commit e71c5c89bcb165a02df35325aa13d1ee40112401 ]
The ADC needs a voltage reference to work correctly.
Users can provide an external voltage reference or use the chip internal reference to operate the ADC.
The availability of an in chip reference for the ADC saves the user from having to supply an external voltage reference, which makes the external reference an optional property as described in the device tree documentation.
Though, to use the internal reference, it must be enabled by writing to the configuration register.
Enable AD7091R internal voltage reference if no external vref is supplied.
--- drivers/iio/adc/ad7091r-base.c | 7 +++++++ drivers/iio/adc/ad7091r-base.h | 2 ++ 2 files changed, 9 insertions(+)
drivers/iio/adc/ad7091r-base.c +7 -0
@@ -405,7 +405,14 @@ int ad7091r_probe(struct device *dev, const char *name,if (IS_ERR (st->vref)) {if (PTR_ERR (st->vref) == -EPROBE_DEFER )return -EPROBE_DEFER ; + st->vref =NULL ; +/* Enable internal vref */ + ret =regmap_set_bits (st->map,AD7091R_REG_CONF , +AD7091R_REG_CONF_INT_VREF ); +if (ret) +return dev_err_probe (st->dev, ret, +"Error on enable internal reference\n" ); }else { ret =regulator_enable (st->vref);if (ret)
drivers/iio/adc/ad7091r-base.h +2 -0
@@ -8,6 +8,8 @@#ifndef __DRIVERS_IIO_ADC_AD7091R_BASE_H__#define __DRIVERS_IIO_ADC_AD7091R_BASE_H__ +#define AD7091R_REG_CONF_INT_VREF BIT(0) +/* AD7091R_REG_CH_LIMIT */ #define AD7091R_HIGH_LIMIT 0xFFF#define AD7091R_LOW_LIMIT 0x0
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 32/185 dmaengine: fix NULL pointer in channel unregistration function
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amelie Delaunay <[email protected]>
[ Upstream commit f5c24d94512f1b288262beda4d3dcb9629222fc7 ]
__dma_async_device_channel_register() can fail. In case of failure, chan->local is freed (with free_percpu()), and chan->local is nullified. When dma_async_device_unregister() is called (because of managed API or intentionally by DMA controller driver), channels are unconditionally unregistered, leading to this NULL pointer:
[ 1.318693] Unable to handle kernel NULL pointer dereference at virtual address 00000000000000d0 [...] [ 1.484499] Call trace: [ 1.486930] device_del+0x40/0x394 [ 1.490314] device_unregister+0x20/0x7c [ 1.494220] __dma_async_device_channel_unregister+0x68/0xc0
Look at dma_async_device_register() function error path, channel device unregistration is done only if chan->local is not NULL.
Then add the same condition at the beginning of __dma_async_device_channel_unregister() function, to avoid NULL pointer issue whatever the API used to reach this function.
--- drivers/dma/dmaengine.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/dma/dmaengine.c +3 -0
@@ -1103,6 +1103,9 @@ EXPORT_SYMBOL_GPL(dma_async_device_channel_register);static void __dma_async_device_channel_unregister (struct dma_device *device,struct dma_chan *chan) { +if (chan->local ==NULL ) +return ; +WARN_ONCE (!device->device_release && chan->client_count,"%s called while %d clients hold a reference\n" , __func__, chan->client_count);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 33/185 scsi: ufs: core: Remove the ufshcd_hba_exit() call from ufshcd_async_scan()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche <[email protected]>
[ Upstream commit ee36710912b2075c417100a8acc642c9c6496501 ]
Calling ufshcd_hba_exit() from a function that is called asynchronously from ufshcd_init() is wrong because this triggers multiple race conditions. Instead of calling ufshcd_hba_exit(), log an error message.
--- drivers/ufs/core/ufshcd.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
drivers/ufs/core/ufshcd.c +2 -5
@@ -8333,12 +8333,9 @@ static void ufshcd_async_scan(void *data, async_cookie_t cookie) out:pm_runtime_put_sync (hba->dev); -/* -* If we failed to initialize the device or the device is not -* present, turn off the power/clocks etc. -*/ +if (ret) -ufshcd_hba_exit (hba); +dev_err (hba->dev,"%s failed: %d\n" , __func__, ret); }static const struct attribute_group *ufshcd_driver_groups[] = {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 34/185 arm64: dts: qcom: sc7180: fix USB wakeup interrupt types
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit 9b956999bf725fd62613f719c3178fdbee6e5f47 upstream.
The DP/DM wakeup interrupts are edge triggered and which edge to trigger on depends on use-case and whether a Low speed or Full/High speed device is connected.
--- arch/arm64/boot/dts/qcom/sc7180.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/qcom/sc7180.dtsi +2 -2
@@ -2769,8 +2769,8 @@ interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>, <&pdc 6 IRQ_TYPE_LEVEL_HIGH>, - <&pdc 8 IRQ_TYPE_LEVEL_HIGH>, - <&pdc 9 IRQ_TYPE_LEVEL_HIGH>; + <&pdc 8 IRQ_TYPE_EDGE_BOTH>, + <&pdc 9 IRQ_TYPE_EDGE_BOTH>; interrupt-names = "hs_phy_irq", "ss_phy_irq", "dm_hs_phy_irq", "dp_hs_phy_irq";
Greg Kroah-Hartman
maintainerPATCH 35/185 arm64: dts: qcom: sdm845: fix USB wakeup interrupt types
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit 84ad9ac8d9ca29033d589e79a991866b38e23b85 upstream.
The DP/DM wakeup interrupts are edge triggered and which edge to trigger on depends on use-case and whether a Low speed or Full/High speed device is connected.
--- arch/arm64/boot/dts/qcom/sdm845.dtsi | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
arch/arm64/boot/dts/qcom/sdm845.dtsi +4 -4
@@ -4050,8 +4050,8 @@ interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 486 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 488 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 489 IRQ_TYPE_LEVEL_HIGH>; + <GIC_SPI 488 IRQ_TYPE_EDGE_BOTH>, + <GIC_SPI 489 IRQ_TYPE_EDGE_BOTH>; interrupt-names = "hs_phy_irq", "ss_phy_irq", "dm_hs_phy_irq", "dp_hs_phy_irq";
@@ -4101,8 +4101,8 @@ interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 487 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 490 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 491 IRQ_TYPE_LEVEL_HIGH>; + <GIC_SPI 490 IRQ_TYPE_EDGE_BOTH>, + <GIC_SPI 491 IRQ_TYPE_EDGE_BOTH>; interrupt-names = "hs_phy_irq", "ss_phy_irq", "dm_hs_phy_irq", "dp_hs_phy_irq";
Greg Kroah-Hartman
maintainerPATCH 36/185 arm64: dts: qcom: sm8150: fix USB wakeup interrupt types
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit 54524b6987d1fffe64cbf3dded1b2fa6b903edf9 upstream.
The DP/DM wakeup interrupts are edge triggered and which edge to trigger on depends on use-case and whether a Low speed or Full/High speed device is connected.
--- arch/arm64/boot/dts/qcom/sm8150.dtsi | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
arch/arm64/boot/dts/qcom/sm8150.dtsi +4 -4
@@ -3630,8 +3630,8 @@ interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 486 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 488 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 489 IRQ_TYPE_LEVEL_HIGH>; + <GIC_SPI 488 IRQ_TYPE_EDGE_BOTH>, + <GIC_SPI 489 IRQ_TYPE_EDGE_BOTH>; interrupt-names = "hs_phy_irq", "ss_phy_irq", "dm_hs_phy_irq", "dp_hs_phy_irq";
@@ -3679,8 +3679,8 @@ interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 487 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 490 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 491 IRQ_TYPE_LEVEL_HIGH>; + <GIC_SPI 490 IRQ_TYPE_EDGE_BOTH>, + <GIC_SPI 491 IRQ_TYPE_EDGE_BOTH>; interrupt-names = "hs_phy_irq", "ss_phy_irq", "dm_hs_phy_irq", "dp_hs_phy_irq";
Greg Kroah-Hartman
maintainerPATCH 37/185 arm64: dts: qcom: sc7280: fix usb_1 wakeup interrupt types
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit c34199d967a946e55381404fa949382691737521 upstream.
A recent cleanup reordering the usb_1 wakeup interrupts inadvertently switched the DP and SuperSpeed interrupt trigger types.
--- arch/arm64/boot/dts/qcom/sc7280.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/qcom/sc7280.dtsi +2 -2
@@ -3664,9 +3664,9 @@ assigned-clock-rates = <19200000>, <200000000>; interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>, - <&pdc 14 IRQ_TYPE_LEVEL_HIGH>, + <&pdc 14 IRQ_TYPE_EDGE_BOTH>, <&pdc 15 IRQ_TYPE_EDGE_BOTH>, - <&pdc 17 IRQ_TYPE_EDGE_BOTH>; + <&pdc 17 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "hs_phy_irq", "dp_hs_phy_irq", "dm_hs_phy_irq",
Greg Kroah-Hartman
maintainerPATCH 38/185 arm64: dts: qcom: sdm845: fix USB DP/DM HS PHY interrupts
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit 204f9ed4bad6293933179517624143b8f412347c upstream.
The USB DP/DM HS PHY interrupts need to be provided by the PDC interrupt controller in order to be able to wake the system up from low-power states and to be able to detect disconnect events, which requires triggering on falling edges.
A recent commit updated the trigger type but failed to change the interrupt provider as required. This leads to the current Linux driver failing to probe instead of printing an error during suspend and USB wakeup not working as intended.
--- arch/arm64/boot/dts/qcom/sdm845.dtsi | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
arch/arm64/boot/dts/qcom/sdm845.dtsi +8 -8
@@ -4048,10 +4048,10 @@ <&gcc GCC_USB30_PRIM_MASTER_CLK>; assigned-clock-rates = <19200000>, <150000000>; - interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 486 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 488 IRQ_TYPE_EDGE_BOTH>, - <GIC_SPI 489 IRQ_TYPE_EDGE_BOTH>; + interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>, + <&intc GIC_SPI 486 IRQ_TYPE_LEVEL_HIGH>, + <&pdc_intc 8 IRQ_TYPE_EDGE_BOTH>, + <&pdc_intc 9 IRQ_TYPE_EDGE_BOTH>; interrupt-names = "hs_phy_irq", "ss_phy_irq", "dm_hs_phy_irq", "dp_hs_phy_irq";
@@ -4099,10 +4099,10 @@ <&gcc GCC_USB30_SEC_MASTER_CLK>; assigned-clock-rates = <19200000>, <150000000>; - interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 487 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 490 IRQ_TYPE_EDGE_BOTH>, - <GIC_SPI 491 IRQ_TYPE_EDGE_BOTH>; + interrupts-extended = <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>, + <&intc GIC_SPI 487 IRQ_TYPE_LEVEL_HIGH>, + <&pdc_intc 10 IRQ_TYPE_EDGE_BOTH>, + <&pdc_intc 11 IRQ_TYPE_EDGE_BOTH>; interrupt-names = "hs_phy_irq", "ss_phy_irq", "dm_hs_phy_irq", "dp_hs_phy_irq";
Greg Kroah-Hartman
maintainerPATCH 39/185 arm64: dts: qcom: sm8150: fix USB DP/DM HS PHY interrupts
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit 134de5e831775e8b178db9b131c1d3769a766982 upstream.
The USB DP/DM HS PHY interrupts need to be provided by the PDC interrupt controller in order to be able to wake the system up from low-power states and to be able to detect disconnect events, which requires triggering on falling edges.
A recent commit updated the trigger type but failed to change the interrupt provider as required. This leads to the current Linux driver failing to probe instead of printing an error during suspend and USB wakeup not working as intended.
--- arch/arm64/boot/dts/qcom/sm8150.dtsi | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
arch/arm64/boot/dts/qcom/sm8150.dtsi +8 -8
@@ -3628,10 +3628,10 @@ <&gcc GCC_USB30_PRIM_MASTER_CLK>; assigned-clock-rates = <19200000>, <200000000>; - interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 486 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 488 IRQ_TYPE_EDGE_BOTH>, - <GIC_SPI 489 IRQ_TYPE_EDGE_BOTH>; + interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>, + <&intc GIC_SPI 486 IRQ_TYPE_LEVEL_HIGH>, + <&pdc 8 IRQ_TYPE_EDGE_BOTH>, + <&pdc 9 IRQ_TYPE_EDGE_BOTH>; interrupt-names = "hs_phy_irq", "ss_phy_irq", "dm_hs_phy_irq", "dp_hs_phy_irq";
@@ -3677,10 +3677,10 @@ <&gcc GCC_USB30_SEC_MASTER_CLK>; assigned-clock-rates = <19200000>, <200000000>; - interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 487 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 490 IRQ_TYPE_EDGE_BOTH>, - <GIC_SPI 491 IRQ_TYPE_EDGE_BOTH>; + interrupts-extended = <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>, + <&intc GIC_SPI 487 IRQ_TYPE_LEVEL_HIGH>, + <&pdc 10 IRQ_TYPE_EDGE_BOTH>, + <&pdc 11 IRQ_TYPE_EDGE_BOTH>; interrupt-names = "hs_phy_irq", "ss_phy_irq", "dm_hs_phy_irq", "dp_hs_phy_irq";
Greg Kroah-Hartman
maintainerPATCH 40/185 lsm: new security_file_ioctl_compat() hook
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alfred Piccioni <[email protected]>
commit f1bb47a31dff6d4b34fb14e99850860ee74bb003 upstream.
Some ioctl commands do not require ioctl permission, but are routed to other permissions such as FILE_GETATTR or FILE_SETATTR. This routing is done by comparing the ioctl cmd to a set of 64-bit flags (FS_IOC_*).
However, if a 32-bit process is running on a 64-bit kernel, it emits 32-bit flags (FS_IOC32_*) for certain ioctl operations. These flags are being checked erroneously, which leads to these ioctl operations being routed to the ioctl permission, rather than the correct file permissions.
This was also noted in a RED-PEN finding from a while back - "/* RED-PEN how should LSM module know it's handling 32bit? */".
This patch introduces a new hook, security_file_ioctl_compat(), that is called from the compat ioctl syscall. All current LSMs have been changed to support this hook.
Reviewing the three places where we are currently using security_file_ioctl(), it appears that only SELinux needs a dedicated compat change; TOMOYO and SMACK appear to be functional without any change.
--- fs/ioctl.c | 3 +-- include/linux/lsm_hook_defs.h | 2 ++ include/linux/security.h | 9 +++++++++ security/security.c | 18 ++++++++++++++++++ security/selinux/hooks.c | 28 ++++++++++++++++++++++++++++ security/smack/smack_lsm.c | 1 + security/tomoyo/tomoyo.c | 1 + 7 files changed, 60 insertions(+), 2 deletions(-)
fs/ioctl.c +1 -2
@@ -916,8 +916,7 @@ COMPAT_SYSCALL_DEFINE3(ioctl, unsigned iif (!f.file)return -EBADF ; -/* RED-PEN how should LSM module know it's handling 32bit? */ - error =security_file_ioctl (f.file, cmd, arg); + error =security_file_ioctl_compat (f.file, cmd, arg);if (error) goto out;
include/linux/lsm_hook_defs.h +2 -0
@@ -165,6 +165,8 @@ LSM_HOOK(int, 0, file_alloc_security, st LSM_HOOK(void, LSM_RET_VOID, file_free_security, struct file *file) LSM_HOOK(int, 0, file_ioctl, struct file *file, unsigned int cmd, unsigned long arg) +LSM_HOOK(int, 0, file_ioctl_compat, struct file *file, unsigned int cmd, + unsigned long arg) LSM_HOOK(int, 0, mmap_addr, unsigned long addr) LSM_HOOK(int, 0, mmap_file, struct file *file, unsigned long reqprot, unsigned long prot, unsigned long flags)
include/linux/security.h +9 -0
@@ -385,6 +385,8 @@ int security_file_permission(struct fileint security_file_alloc (struct file *file);void security_file_free (struct file *file);int security_file_ioctl (struct file *file,unsigned int cmd,unsigned long arg); +int security_file_ioctl_compat (struct file *file,unsigned int cmd, +unsigned long arg);int security_mmap_file (struct file *file,unsigned long prot,unsigned long flags);int security_mmap_addr (unsigned long addr);
@@ -968,6 +970,13 @@ static inline int security_file_ioctl(st {return 0 ; } + +static inline int security_file_ioctl_compat (struct file *file, +unsigned int cmd, +unsigned long arg) +{ +return 0 ; +}static inline int security_mmap_file (struct file *file,unsigned long prot,unsigned long flags)
security/security.c +18 -0
@@ -1569,6 +1569,24 @@ int security_file_ioctl(struct file *fil }EXPORT_SYMBOL_GPL (security_file_ioctl); +/** +* security_file_ioctl_compat() - Check if an ioctl is allowed in compat mode +* @file: associated file +* @cmd: ioctl cmd +* @arg: ioctl arguments +* +* Compat version of security_file_ioctl() that correctly handles 32-bit +* processes running on 64-bit kernels. +* +* Return: Returns 0 if permission is granted. +*/ +int security_file_ioctl_compat (struct file *file,unsigned int cmd, +unsigned long arg) +{ +return call_int_hook (file_ioctl_compat,0 , file, cmd, arg); +} +EXPORT_SYMBOL_GPL (security_file_ioctl_compat); +static inline unsigned long mmap_prot (struct file *file,unsigned long prot) {/*
security/selinux/hooks.c +28 -0
@@ -3718,6 +3718,33 @@ static int selinux_file_ioctl(struct filreturn error; } +static int selinux_file_ioctl_compat (struct file *file,unsigned int cmd, +unsigned long arg) +{ +/* +* If we are in a 64-bit kernel running 32-bit userspace, we need to +* make sure we don't compare 32-bit flags to 64-bit flags. +*/ +switch (cmd) { +case FS_IOC32_GETFLAGS : + cmd =FS_IOC_GETFLAGS ; +break ; +case FS_IOC32_SETFLAGS : + cmd =FS_IOC_SETFLAGS ; +break ; +case FS_IOC32_GETVERSION : + cmd =FS_IOC_GETVERSION ; +break ; +case FS_IOC32_SETVERSION : + cmd =FS_IOC_SETVERSION ; +break ; +default : +break ; + } + +return selinux_file_ioctl (file, cmd, arg); +} +static int default_noexec__ro_after_init ;static int file_map_prot_check (struct file *file,unsigned long prot,int shared)
@@ -7135,6 +7162,7 @@ static struct security_hook_list selinuxLSM_HOOK_INIT (file_permission, selinux_file_permission),LSM_HOOK_INIT (file_alloc_security, selinux_file_alloc_security),LSM_HOOK_INIT (file_ioctl, selinux_file_ioctl), +LSM_HOOK_INIT (file_ioctl_compat, selinux_file_ioctl_compat),LSM_HOOK_INIT (mmap_file, selinux_mmap_file),LSM_HOOK_INIT (mmap_addr, selinux_mmap_addr), LSM_HOOK_INIT(file_mprotect, selinux_file_mprotect),
security/smack/smack_lsm.c +1 -0
@@ -4905,6 +4905,7 @@ static struct security_hook_list smack_hLSM_HOOK_INIT (file_alloc_security, smack_file_alloc_security),LSM_HOOK_INIT (file_ioctl, smack_file_ioctl), +LSM_HOOK_INIT (file_ioctl_compat, smack_file_ioctl),LSM_HOOK_INIT (file_lock, smack_file_lock),LSM_HOOK_INIT (file_fcntl, smack_file_fcntl), LSM_HOOK_INIT(mmap_file, smack_mmap_file),
security/tomoyo/tomoyo.c +1 -0
@@ -555,6 +555,7 @@ static struct security_hook_list tomoyo_LSM_HOOK_INIT (path_rename, tomoyo_path_rename),LSM_HOOK_INIT (inode_getattr, tomoyo_inode_getattr),LSM_HOOK_INIT (file_ioctl, tomoyo_file_ioctl), +LSM_HOOK_INIT (file_ioctl_compat, tomoyo_file_ioctl),LSM_HOOK_INIT (path_chmod, tomoyo_path_chmod),LSM_HOOK_INIT (path_chown, tomoyo_path_chown), LSM_HOOK_INIT(path_chroot, tomoyo_path_chroot),
Greg Kroah-Hartman
maintainerPATCH 41/185 docs: kernel_abi.py: fix command injection
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vegard Nossum <[email protected]>
commit 3231dd5862779c2e15633c96133a53205ad660ce upstream.
The kernel-abi directive passes its argument straight to the shell. This is unfortunate and unnecessary.
Let's always use paths relative to $srctree/Documentation/ and use subprocess.check_call() instead of subprocess.Popen(shell=True).
This also makes the code shorter.
--- Documentation/admin-guide/abi-obsolete.rst | 2 - Documentation/admin-guide/abi-removed.rst | 2 - Documentation/admin-guide/abi-stable.rst | 2 - Documentation/admin-guide/abi-testing.rst | 2 - Documentation/sphinx/kernel_abi.py | 56 +++++------------------------ 5 files changed, 14 insertions(+), 50 deletions(-)
Documentation/admin-guide/abi-obsolete.rst +1 -1
@@ -7,5 +7,5 @@ marked to be removed at some later point The description of the interface will document the reason why it is obsolete and when it can be expected to be removed. -.. kernel-abi:: $srctree/Documentation/ABI/obsolete +.. kernel-abi:: ABI/obsolete :rst:
Documentation/admin-guide/abi-removed.rst +1 -1
@@ -1,5 +1,5 @@ ABI removed symbols =================== -.. kernel-abi:: $srctree/Documentation/ABI/removed +.. kernel-abi:: ABI/removed :rst:
Documentation/admin-guide/abi-stable.rst +1 -1
@@ -10,5 +10,5 @@ for at least 2 years. Most interfaces (like syscalls) are expected to never change and always be available. -.. kernel-abi:: $srctree/Documentation/ABI/stable +.. kernel-abi:: ABI/stable :rst:
Documentation/admin-guide/abi-testing.rst +1 -1
@@ -16,5 +16,5 @@ Programs that use these interfaces are s name to the description of these interfaces, so that the kernel developers can easily notify them if any changes occur. -.. kernel-abi:: $srctree/Documentation/ABI/testing +.. kernel-abi:: ABI/testing :rst:
Documentation/sphinx/kernel_abi.py +10 -46
78 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 42/185 scripts/get_abi: fix source path leak
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vegard Nossum <[email protected]>
commit 5889d6ede53bc17252f79c142387e007224aa554 upstream.
The code currently leaks the absolute path of the ABI files into the rendered documentation.
There exists code to prevent this, but it is not effective when an absolute path is passed, which it is when $srctree is used.
I consider this to be a minimal, stop-gap fix; a better fix would strip off the actual prefix instead of hacking it off with a regex.
--- scripts/get_abi.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
scripts/get_abi.pl +1 -1
@@ -98,7 +98,7 @@ sub parse_abi { $name =~ s,.*/,,; my $fn = $file; - $fn =~ s,Documentation/ABI/,,; + $fn =~ s,.*Documentation/ABI/,,; my $nametag = "File $fn"; $data{$nametag}->{what} = "File $name";
Greg Kroah-Hartman
maintainerPATCH 43/185 media: videobuf2-dma-sg: fix vmap callback
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Grzeschik <[email protected]>
commit 608ca5a60ee47b48fec210aeb7a795a64eb5dcee upstream.
For dmabuf import users to be able to use the vaddr from another videobuf2-dma-sg source, the exporter needs to set a proper vaddr on vb2_dma_sg_dmabuf_ops_vmap callback. This patch adds vmap on map if buf->vaddr was not set.
--- drivers/media/common/videobuf2/videobuf2-dma-sg.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
drivers/media/common/videobuf2/videobuf2-dma-sg.c +8 -2
@@ -494,9 +494,15 @@ vb2_dma_sg_dmabuf_ops_end_cpu_access(strstatic int vb2_dma_sg_dmabuf_ops_vmap (struct dma_buf *dbuf,struct iosys_map *map) { -struct vb2_dma_sg_buf *buf = dbuf->priv; +struct vb2_dma_sg_buf *buf; +void *vaddr; -iosys_map_set_vaddr (map, buf->vaddr); + buf = dbuf->priv; + vaddr =vb2_dma_sg_vaddr (buf->vb, buf); +if (!vaddr) +return -EINVAL ; + +iosys_map_set_vaddr (map, vaddr);return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 44/185 mmc: core: Use mrq.sbc in close-ended ffu
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Avri Altman <[email protected]>
commit 4d0c8d0aef6355660b6775d57ccd5d4ea2e15802 upstream.
Field Firmware Update (ffu) may use close-ended or open ended sequence. Each such sequence is comprised of a write commands enclosed between 2 switch commands - to and from ffu mode. So for the close-ended case, it will be: cmd6->cmd23-cmd25-cmd6.
Some host controllers however, get confused when multi-block rw is sent without sbc, and may generate auto-cmd12 which breaks the ffu sequence. I encountered this issue while testing fwupd (github.com/fwupd/fwupd) on HP Chromebook x2, a qualcomm based QC-7c, code name - strongbad.
Instead of a quirk, or hooking the request function of the msm ops, it would be better to fix the ioctl handling and make it use mrq.sbc instead of issuing SET_BLOCK_COUNT separately.
--- drivers/mmc/core/block.c | 46 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-)
drivers/mmc/core/block.c +43 -3
@@ -402,6 +402,10 @@ struct mmc_blk_ioc_data {struct mmc_ioc_cmd ic;unsigned char *buf;u64 buf_bytes; +unsigned int flags; +#define MMC_BLK_IOC_DROP BIT(0)/* drop this mrq */ +#define MMC_BLK_IOC_SBC BIT(1)/* use mrq.sbc */ +struct mmc_rpmb_data *rpmb; };
@@ -467,7 +471,7 @@ static int mmc_blk_ioctl_copy_to_user(st }static int __mmc_blk_ioctl_cmd (struct mmc_card *card,struct mmc_blk_data *md, -struct mmc_blk_ioc_data *idata) +struct mmc_blk_ioc_data **idatas,int i) {struct mmc_command cmd = {}, sbc = {};struct mmc_data data = {};
@@ -477,10 +481,18 @@ static int __mmc_blk_ioctl_cmd(struct mmunsigned int busy_timeout_ms;int err;unsigned int target_part; +struct mmc_blk_ioc_data *idata = idatas[i]; +struct mmc_blk_ioc_data *prev_idata =NULL ;if (!card || !md || !idata)return -EINVAL ; +if (idata->flags &MMC_BLK_IOC_DROP ) +return 0 ; + +if (idata->flags &MMC_BLK_IOC_SBC ) + prev_idata = idatas[i -1 ]; +/* * The RPMB accesses comes in from the character device, so we * need to target these explicitly. Else we just target the
@@ -547,7 +559,7 @@ static int __mmc_blk_ioctl_cmd(struct mmreturn err; } -if (idata->rpmb) { +if (idata->rpmb || prev_idata) { sbc.opcode =MMC_SET_BLOCK_COUNT ;/* * We don't do any blockcount validation because the max size
@@ -555,6 +567,8 @@ static int __mmc_blk_ioctl_cmd(struct mm* 'Reliable Write' bit here. */ sbc.arg = data.blocks | (idata->ic.write_flag &BIT (31 )); +if (prev_idata) + sbc.arg = prev_idata->ic.arg; sbc.flags =MMC_RSP_R1 |MMC_CMD_AC ; mrq.sbc = &sbc; }
@@ -572,6 +586,15 @@ static int __mmc_blk_ioctl_cmd(struct mmmmc_wait_for_req (card->host, &mrq);memcpy (&idata->ic.response, cmd.resp,sizeof (cmd.resp)); +if (prev_idata) { +memcpy (&prev_idata->ic.response, sbc.resp,sizeof (sbc.resp)); +if (sbc.error) { +dev_err (mmc_dev (card->host),"%s: sbc error %d\n" , + __func__, sbc.error); +return sbc.error; + } + } +if (cmd.error) {dev_err (mmc_dev (card->host),"%s: cmd error %d\n" , __func__, cmd.error);
@@ -1057,6 +1080,20 @@ static inline void mmc_blk_reset_success md->reset_done &= ~type; } +static void mmc_blk_check_sbc (struct mmc_queue_req *mq_rq) +{ +struct mmc_blk_ioc_data **idata = mq_rq->drv_op_data; +int i; + +for (i =1 ; i < mq_rq->ioc_count; i++) { +if (idata[i -1 ]->ic.opcode ==MMC_SET_BLOCK_COUNT && +mmc_op_multi (idata[i]->ic.opcode)) { + idata[i -1 ]->flags |=MMC_BLK_IOC_DROP ; + idata[i]->flags |=MMC_BLK_IOC_SBC ; + } + } +} +/* * The non-block commands come back from the block layer after it queued it and * processed it with all other requests and then they get issued in this
@@ -1084,11 +1121,14 @@ static void mmc_blk_issue_drv_op(structif (ret)break ; } + +mmc_blk_check_sbc (mq_rq); + fallthrough;case MMC_DRV_OP_IOCTL_RPMB : idata = mq_rq->drv_op_data;for (i =0 , ret =0 ; i < mq_rq->ioc_count; i++) { - ret =__mmc_blk_ioctl_cmd (card, md, idata[i]); + ret =__mmc_blk_ioctl_cmd (card, md, idata, i);if (ret)break ; }
Greg Kroah-Hartman
maintainerPATCH 45/185 mmc: mmc_spi: remove custom DMA mapped buffers
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <[email protected]>
commit 84a6be7db9050dd2601c9870f65eab9a665d2d5d upstream.
There is no need to duplicate what SPI core or individual controller drivers already do, i.e. mapping the buffers for DMA capable transfers.
Note, that the code, besides its redundancy, was buggy: strictly speaking there is no guarantee, while it's true for those which can use this code (see below), that the SPI host controller _is_ the device which does DMA.
Also see the Link tags below.
Additional notes. Currently only two SPI host controller drivers may use premapped (by the user) DMA buffers:
- drivers/spi/spi-au1550.c
- drivers/spi/spi-fsl-spi.c
Both of them have DMA mapping support code. I don't expect that SPI host controller code is worse than what has been done in mmc_spi. Hence I do not expect any regressions here. Otherwise, I'm pretty much sure these regressions have to be fixed in the respective drivers, and not here.
That said, remove all related pieces of DMA mapping code from mmc_spi.
--- drivers/mmc/host/mmc_spi.c | 186 +-------------------------------------------- 1 file changed, 5 insertions(+), 181 deletions(-)
drivers/mmc/host/mmc_spi.c +5 -181
@@ -15,7 +15,7 @@#include <linux/slab.h> #include <linux/module.h> #include <linux/bio.h> -#include <linux/dma-mapping.h> +#include <linux/dma-direction.h> #include <linux/crc7.h> #include <linux/crc-itu-t.h> #include <linux/scatterlist.h>
@@ -119,19 +119,14 @@ struct mmc_spi_host {struct spi_transfer status;struct spi_message readback; -/* underlying DMA-aware controller, or null */ -struct device *dma_dev; -/* buffer used for commands and for message "overhead" */ struct scratch *data; -dma_addr_t data_dma;/* Specs say to write ones most of the time, even when the card * has no need to read its input data; and many cards won't care. * This is our source of those ones. */ void *ones; -dma_addr_t ones_dma; };
@@ -147,11 +142,8 @@ static inline int mmc_cs_off(struct mmc_return spi_setup (host->spi); } -static int -mmc_spi_readbytes (struct mmc_spi_host *host,unsigned len) +static int mmc_spi_readbytes (struct mmc_spi_host *host,unsigned int len) { -int status; -if (len >sizeof (*host->data)) {WARN_ON (1 );return -EIO ;
@@ -159,19 +151,7 @@ mmc_spi_readbytes(struct mmc_spi_host *h host->status.len = len; -if (host->dma_dev) -dma_sync_single_for_device (host->dma_dev, - host->data_dma,sizeof (*host->data), -DMA_FROM_DEVICE ); - - status =spi_sync_locked (host->spi, &host->readback); - -if (host->dma_dev) -dma_sync_single_for_cpu (host->dma_dev, - host->data_dma,sizeof (*host->data), -DMA_FROM_DEVICE ); - -return status; +return spi_sync_locked (host->spi, &host->readback); } static int mmc_spi_skip(struct mmc_spi_host *host, unsigned long timeout,
@@ -506,23 +486,11 @@ mmc_spi_command_send(struct mmc_spi_host t = &host->t;memset (t,0 ,sizeof (*t)); t->tx_buf = t->rx_buf = data->status; - t->tx_dma = t->rx_dma = host->data_dma; t->len = cp - data->status; t->cs_change =1 ;spi_message_add_tail (t, &host->m); -if (host->dma_dev) { - host->m.is_dma_mapped =1 ; -dma_sync_single_for_device (host->dma_dev, - host->data_dma,sizeof (*host->data), -DMA_BIDIRECTIONAL ); - } status =spi_sync_locked (host->spi, &host->m); - -if (host->dma_dev) -dma_sync_single_for_cpu (host->dma_dev, - host->data_dma,sizeof (*host->data), -DMA_BIDIRECTIONAL );if (status <0 ) {dev_dbg (&host->spi->dev," ... write returned %d\n" , status); cmd->error = status;
@@ -540,9 +508,6 @@ mmc_spi_command_send(struct mmc_spi_host* We always provide TX data for data and CRC. The MMC/SD protocol * requires us to write ones; but Linux defaults to writing zeroes; * so we explicitly initialize it to all ones on RX paths. -* -* We also handle DMA mapping, so the underlying SPI controller does -* not need to (re)do it for each message. */ static void mmc_spi_setup_data_message(
@@ -552,11 +517,8 @@ mmc_spi_setup_data_message( {struct spi_transfer *t;struct scratch *scratch = host->data; -dma_addr_t dma = host->data_dma;spi_message_init (&host->m); -if (dma) - host->m.is_dma_mapped =1 ;/* for reads, readblock() skips 0xff bytes before finding * the token; for writes, this transfer issues that token.
@@ -570,8 +532,6 @@ mmc_spi_setup_data_message(else scratch->data_token =SPI_TOKEN_SINGLE ; t->tx_buf = &scratch->data_token; -if (dma) - t->tx_dma = dma + offsetof(struct scratch , data_token);spi_message_add_tail (t, &host->m); }
@@ -581,7 +541,6 @@ mmc_spi_setup_data_message( t = &host->t;memset (t,0 ,sizeof (*t)); t->tx_buf = host->ones; - t->tx_dma = host->ones_dma;/* length and actual buffer info are written later */ spi_message_add_tail (t, &host->m);
@@ -591,14 +550,9 @@ mmc_spi_setup_data_message(if (direction ==DMA_TO_DEVICE ) {/* the actual CRC may get written later */ t->tx_buf = &scratch->crc_val; -if (dma) - t->tx_dma = dma + offsetof(struct scratch , crc_val); }else { t->tx_buf = host->ones; - t->tx_dma = host->ones_dma; t->rx_buf = &scratch->crc_val; -if (dma) - t->rx_dma = dma + offsetof(struct scratch , crc_val); }spi_message_add_tail (t, &host->m);
@@ -621,10 +575,7 @@ mmc_spi_setup_data_message(memset (t,0 ,sizeof (*t)); t->len = (direction ==DMA_TO_DEVICE ) ?sizeof (scratch->status) :1 ; t->tx_buf = host->ones; - t->tx_dma = host->ones_dma; t->rx_buf = scratch->status; -if (dma) - t->rx_dma = dma + offsetof(struct scratch , status); t->cs_change =1 ;spi_message_add_tail (t, &host->m); }
@@ -653,23 +604,13 @@ mmc_spi_writeblock(struct mmc_spi_host *if (host->mmc->use_spi_crc) scratch->crc_val =cpu_to_be16 (crc_itu_t (0 , t->tx_buf, t->len)); -if (host->dma_dev) -dma_sync_single_for_device (host->dma_dev, - host->data_dma,sizeof (*scratch), -DMA_BIDIRECTIONAL ); status =spi_sync_locked (spi, &host->m); -if (status !=0 ) {dev_dbg (&spi->dev,"write error (%d)\n" , status);return status; } -if (host->dma_dev) -dma_sync_single_for_cpu (host->dma_dev, - host->data_dma,sizeof (*scratch), -DMA_BIDIRECTIONAL ); -/* * Get the transmission data-response reply. It must follow * immediately after the data block we transferred. This reply
@@ -718,8 +659,6 @@ mmc_spi_writeblock(struct mmc_spi_host * } t->tx_buf += t->len; -if (host->dma_dev) - t->tx_dma += t->len;/* Return when not busy. If we didn't collect that status yet, * we'll need some more I/O.
@@ -783,30 +722,12 @@ mmc_spi_readblock(struct mmc_spi_host *h } leftover = status <<1 ; -if (host->dma_dev) { -dma_sync_single_for_device (host->dma_dev, - host->data_dma,sizeof (*scratch), -DMA_BIDIRECTIONAL ); -dma_sync_single_for_device (host->dma_dev, - t->rx_dma, t->len, -DMA_FROM_DEVICE ); - } - status =spi_sync_locked (spi, &host->m);if (status <0 ) {dev_dbg (&spi->dev,"read error %d\n" , status);return status; } -if (host->dma_dev) { -dma_sync_single_for_cpu (host->dma_dev, - host->data_dma,sizeof (*scratch), -DMA_BIDIRECTIONAL ); -dma_sync_single_for_cpu (host->dma_dev, - t->rx_dma, t->len, -DMA_FROM_DEVICE ); - } -if (bitshift) {/* Walk through the data and the crc and do * all the magic to get byte-aligned data.
@@ -841,8 +762,6 @@ mmc_spi_readblock(struct mmc_spi_host *h } t->rx_buf += t->len; -if (host->dma_dev) - t->rx_dma += t->len;return 0 ; }
@@ -857,7 +776,6 @@ mmc_spi_data_do(struct mmc_spi_host *hos struct mmc_data *data, u32 blk_size) {struct spi_device *spi = host->spi; -struct device *dma_dev = host->dma_dev;struct spi_transfer *t;enum dma_data_direction direction =mmc_get_dma_dir (data);struct scatterlist *sg;
@@ -884,31 +802,8 @@ mmc_spi_data_do(struct mmc_spi_host *hos*/ for_each_sg (data->sg, sg, data->sg_len, n_sg) {int status =0 ; -dma_addr_t dma_addr =0 ;void *kmap_addr;unsigned length = sg->length; -enum dma_data_direction dir = direction; - -/* set up dma mapping for controller drivers that might -* use DMA ... though they may fall back to PIO -*/ -if (dma_dev) { -/* never invalidate whole *shared* pages ... */ -if ((sg->offset !=0 || length !=PAGE_SIZE ) - && dir ==DMA_FROM_DEVICE ) - dir =DMA_BIDIRECTIONAL ; - - dma_addr =dma_map_page (dma_dev,sg_page (sg),0 , -PAGE_SIZE , dir); -if (dma_mapping_error (dma_dev, dma_addr)) { - data->error = -EFAULT ; -break ; - } -if (direction ==DMA_TO_DEVICE ) - t->tx_dma = dma_addr + sg->offset; -else - t->rx_dma = dma_addr + sg->offset; - }/* allow pio too; we don't allow highmem */ kmap_addr =kmap (sg_page (sg));
@@ -941,8 +836,6 @@ mmc_spi_data_do(struct mmc_spi_host *hosif (direction ==DMA_FROM_DEVICE )flush_dcache_page (sg_page (sg));kunmap (sg_page (sg)); -if (dma_dev) -dma_unmap_page (dma_dev, dma_addr,PAGE_SIZE , dir);if (status <0 ) { data->error = status;
@@ -977,21 +870,9 @@ mmc_spi_data_do(struct mmc_spi_host *hos scratch->status[0 ] =SPI_TOKEN_STOP_TRAN ; host->early_status.tx_buf = host->early_status.rx_buf; - host->early_status.tx_dma = host->early_status.rx_dma; host->early_status.len = statlen; -if (host->dma_dev) -dma_sync_single_for_device (host->dma_dev, - host->data_dma,sizeof (*scratch), -DMA_BIDIRECTIONAL ); - tmp =spi_sync_locked (spi, &host->m); - -if (host->dma_dev) -dma_sync_single_for_cpu (host->dma_dev, - host->data_dma,sizeof (*scratch), -DMA_BIDIRECTIONAL ); -if (tmp <0 ) {if (!data->error) data->error = tmp;
@@ -1265,52 +1146,6 @@ mmc_spi_detect_irq(int irq, void *mmc)return IRQ_HANDLED ; } -#ifdef CONFIG_HAS_DMA -static int mmc_spi_dma_alloc (struct mmc_spi_host *host) -{ -struct spi_device *spi = host->spi; -struct device *dev; - -if (!spi->master->dev.parent->dma_mask) -return 0 ; - - dev = spi->master->dev.parent; - - host->ones_dma =dma_map_single (dev, host->ones,MMC_SPI_BLOCKSIZE , -DMA_TO_DEVICE ); -if (dma_mapping_error (dev, host->ones_dma)) -return -ENOMEM ; - - host->data_dma =dma_map_single (dev, host->data,sizeof (*host->data), -DMA_BIDIRECTIONAL ); -if (dma_mapping_error (dev, host->data_dma)) { -dma_unmap_single (dev, host->ones_dma,MMC_SPI_BLOCKSIZE , -DMA_TO_DEVICE ); -return -ENOMEM ; - } - -dma_sync_single_for_cpu (dev, host->data_dma,sizeof (*host->data), -DMA_BIDIRECTIONAL ); - - host->dma_dev = dev; -return 0 ; -} - -static void mmc_spi_dma_free (struct mmc_spi_host *host) -{ -if (!host->dma_dev) -return ; - -dma_unmap_single (host->dma_dev, host->ones_dma,MMC_SPI_BLOCKSIZE , -DMA_TO_DEVICE ); -dma_unmap_single (host->dma_dev, host->data_dma,sizeof (*host->data), -DMA_BIDIRECTIONAL ); -} -#else -static inline int mmc_spi_dma_alloc (struct mmc_spi_host *host) {return 0 ; } -static inline void mmc_spi_dma_free (struct mmc_spi_host *host) {} -#endif -static int mmc_spi_probe (struct spi_device *spi) {void *ones;
@@ -1402,24 +1237,17 @@ static int mmc_spi_probe(struct spi_devi host->powerup_msecs =250 ; } -/* preallocate dma buffers */ +/* Preallocate buffers */ host->data =kmalloc (sizeof (*host->data),GFP_KERNEL );if (!host->data) goto fail_nobuf1; - status =mmc_spi_dma_alloc (host); -if (status) - goto fail_dma; -/* setup message for status/busy readback */ spi_message_init (&host->readback); - host->readback.is_dma_mapped = (host->dma_dev !=NULL );spi_message_add_tail (&host->status, &host->readback); host->status.tx_buf = host->ones; - host->status.tx_dma = host->ones_dma; host->status.rx_buf = &host->data->status; - host->status.rx_dma = host->data_dma + offsetof(struct scratch , status); host->status.cs_change =1 ;/* register card detect irq */
@@ -1464,9 +1292,8 @@ static int mmc_spi_probe(struct spi_deviif (!status) has_ro = true; - dev_info(&spi->dev, "SD/MMC host %s%s%s%s%s\n", + dev_info(&spi->dev, "SD/MMC host %s%s%s%s\n", dev_name(&mmc->class_dev), - host->dma_dev ? "" : ", no DMA", has_ro ? "" : ", no WP", (host->pdata && host->pdata->setpower) ? "" : ", no poweroff",
@@ -1477,8 +1304,6 @@ static int mmc_spi_probe(struct spi_devi fail_gpiod_request:mmc_remove_host (mmc); fail_glue_init: -mmc_spi_dma_free (host); -fail_dma:kfree (host->data); fail_nobuf1:mmc_spi_put_pdata (spi);
@@ -1500,7 +1325,6 @@ static void mmc_spi_remove(struct spi_demmc_remove_host (mmc); -mmc_spi_dma_free (host);kfree (host->data);kfree (host->ones);
Greg Kroah-Hartman
maintainerPATCH 46/185 media: mtk-jpeg: Fix use after free bug due to error path handling in mtk_jpeg_dec_device_run
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zheng Wang <[email protected]>
commit 206c857dd17d4d026de85866f1b5f0969f2a109e upstream.
In mtk_jpeg_probe, &jpeg->job_timeout_work is bound with mtk_jpeg_job_timeout_work.
In mtk_jpeg_dec_device_run, if error happens in mtk_jpeg_set_dec_dst, it will finally start the worker while mark the job as finished by invoking v4l2_m2m_job_finish.
There are two methods to trigger the bug. If we remove the module, it which will call mtk_jpeg_remove to make cleanup. The possible sequence is as follows, which will cause a use-after-free bug.
CPU0 CPU1mtk_jpeg_dec_... |
start worker |
|mtk_jpeg_job_timeout_work
mtk_jpeg_remove |
v4l2_m2m_release |
kfree(m2m_dev); |
|
| v4l2_m2m_get_curr_priv
| m2m_dev->curr_ctx //useIf we close the file descriptor, which will call mtk_jpeg_release, it will have a similar sequence.
Fix this bug by starting timeout worker only if started jpegdec worker successfully. Then v4l2_m2m_job_finish will only be called in either mtk_jpeg_job_timeout_work or mtk_jpeg_dec_device_run.
--- drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c +3 -3
@@ -974,13 +974,13 @@ static void mtk_jpeg_dec_device_run(voidif (ret <0 ) goto dec_end; -schedule_delayed_work (&jpeg->job_timeout_work, -msecs_to_jiffies (MTK_JPEG_HW_TIMEOUT_MSEC )); -mtk_jpeg_set_dec_src (ctx, &src_buf->vb2_buf, &bs);if (mtk_jpeg_set_dec_dst (ctx, &jpeg_src_buf->dec_param, &dst_buf->vb2_buf, &fb)) goto dec_end; +schedule_delayed_work (&jpeg->job_timeout_work, +msecs_to_jiffies (MTK_JPEG_HW_TIMEOUT_MSEC )); +spin_lock_irqsave (&jpeg->hw_lock, flags);mtk_jpeg_dec_reset (jpeg->reg_base); mtk_jpeg_dec_set_config(jpeg->reg_base,
Greg Kroah-Hartman
maintainerPATCH 47/185 arm64: Rename ARM64_WORKAROUND_2966298
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rob Herring <[email protected]>
commit 546b7cde9b1dd36089649101b75266564600ffe5 upstream.
In preparation to apply ARM64_WORKAROUND_2966298 for multiple errata, rename the kconfig and capability. No functional change.
--- arch/arm64/Kconfig | 4 ++++ arch/arm64/kernel/cpu_errata.c | 4 ++-- arch/arm64/kernel/entry.S | 2 +- arch/arm64/tools/cpucaps | 2 +- 4 files changed, 8 insertions(+), 4 deletions(-)
arch/arm64/Kconfig +4 -0
@@ -983,8 +983,12 @@ config ARM64_ERRATUM_2457168 If unsure, say Y. +config ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD + bool + config ARM64_ERRATUM_2966298 bool "Cortex-A520: 2966298: workaround for speculatively executed unprivileged load" + select ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD default y help This option adds the workaround for ARM Cortex-A520 erratum 2966298.
arch/arm64/kernel/cpu_errata.c +2 -2
@@ -723,10 +723,10 @@ const struct arm64_cpu_capabilities arm6 .cpu_enable = cpu_clear_bf16_from_user_emulation, },#endif -#ifdef CONFIG_ARM64_ERRATUM_2966298 +#ifdef CONFIG_ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD { .desc = "ARM erratum 2966298", - .capability = ARM64_WORKAROUND_2966298, + .capability = ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD, /* Cortex-A520 r0p0 - r0p1 */ ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A520, 0, 0, 1), },
arch/arm64/kernel/entry.S +1 -1
@@ -419,7 +419,7 @@ alternative_else_nop_endif ldp x28, x29, [sp, #16 * 14] .if \el == 0 -alternative_if ARM64_WORKAROUND_2966298 +alternative_if ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD tlbi vale1, xzr dsb nsh alternative_else_nop_endif
arch/arm64/tools/cpucaps +1 -1
@@ -71,7 +71,6 @@ WORKAROUND_2064142 WORKAROUND_2077057 WORKAROUND_2457168 WORKAROUND_2658417 -WORKAROUND_2966298 WORKAROUND_AMPERE_AC03_CPU_38 WORKAROUND_TRBE_OVERWRITE_FILL_MODE WORKAROUND_TSB_FLUSH_FAILURE
@@ -87,3 +86,4 @@ WORKAROUND_NVIDIA_CARMEL_CNP WORKAROUND_QCOM_FALKOR_E1003 WORKAROUND_REPEAT_TLBI WORKAROUND_SPECULATIVE_AT +WORKAROUND_SPECULATIVE_UNPRIV_LOAD
Greg Kroah-Hartman
maintainerPATCH 48/185 rtc: cmos: Use ACPI alarm for non-Intel x86 systems too
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello <[email protected]>
commit 3d762e21d56370a43478b55e604b4a83dd85aafc upstream.
Intel systems > 2015 have been configured to use ACPI alarm instead of HPET to avoid s2idle issues.
Having HPET programmed for wakeup causes problems on AMD systems with s2idle as well.
One particular case is that the systemd "SuspendThenHibernate" feature doesn't work properly on the Framework 13" AMD model. Switching to using ACPI alarm fixes the issue.
Adjust the quirk to apply to AMD/Hygon systems from 2021 onwards. This matches what has been tested and is specifically to avoid potential risk to older systems.
--- drivers/rtc/rtc-cmos.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
drivers/rtc/rtc-cmos.c +12 -6
@@ -818,18 +818,24 @@ static void rtc_wake_off(struct device *dev) }#ifdef CONFIG_X86 -/* Enable use_acpi_alarm mode for Intel platforms no earlier than 2015 */ static void use_acpi_alarm_quirks (void ) { -if (boot_cpu_data.x86_vendor !=X86_VENDOR_INTEL ) +switch (boot_cpu_data.x86_vendor) { +case X86_VENDOR_INTEL : +if (dmi_get_bios_year () <2015 ) +return ; +break ; +case X86_VENDOR_AMD : +case X86_VENDOR_HYGON : +if (dmi_get_bios_year () <2021 ) +return ; +break ; +default :return ; - + }if (!is_hpet_enabled ())return ; -if (dmi_get_bios_year () <2015 ) -return ; - use_acpi_alarm = true; }#else
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 49/185 rtc: Adjust failure return code for cmos_set_alarm()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello <[email protected]>
commit 1311a8f0d4b23f58bbababa13623aa40b8ad4e0c upstream.
When mc146818_avoid_UIP() fails to return a valid value, this is because UIP didn't clear in the timeout period. Adjust the return code in this case to -ETIMEDOUT.
--- drivers/rtc/rtc-cmos.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/rtc/rtc-cmos.c +2 -2
@@ -292,7 +292,7 @@ static int cmos_read_alarm(struct device/* This not only a rtc_op, but also called directly */ if (!is_valid_irq (cmos->irq)) -return -EIO ; +return -ETIMEDOUT ;/* Basic alarms only support hour, minute, and seconds fields. * Some also support day and month, for alarms up to a year in
@@ -557,7 +557,7 @@ static int cmos_set_alarm(struct device* Use mc146818_avoid_UIP() to avoid this. */ if (!mc146818_avoid_UIP (cmos_set_alarm_callback, &p)) -return -EIO ; +return -ETIMEDOUT ; cmos->alarm_expires =rtc_tm_to_time64 (&t->time);
Greg Kroah-Hartman
maintainerPATCH 50/185 rtc: mc146818-lib: Adjust failure return code for mc146818_get_time()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello <[email protected]>
commit af838635a3eb9b1bc0d98599c101ebca98f31311 upstream.
mc146818_get_time() calls mc146818_avoid_UIP() to avoid fetching the time while RTC update is in progress (UIP). When this fails, the return code is -EIO, but actually there was no IO failure.
The reason for the return from mc146818_avoid_UIP() is that the UIP wasn't cleared in the time period. Adjust the return code to -ETIMEDOUT to match the behavior.
--- drivers/rtc/rtc-mc146818-lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/rtc/rtc-mc146818-lib.c +1 -1
@@ -138,7 +138,7 @@ int mc146818_get_time(struct rtc_time *tif (!mc146818_avoid_UIP (mc146818_get_time_callback, &p)) {memset (time,0 ,sizeof (*time)); -return -EIO ; +return -ETIMEDOUT ; }if (!(p.ctrl &RTC_DM_BINARY ) ||RTC_ALWAYS_BCD )
Greg Kroah-Hartman
maintainerPATCH 51/185 rtc: Add support for configuring the UIP timeout for RTC reads
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello <[email protected]>
commit 120931db07b49252aba2073096b595482d71857c upstream.
The UIP timeout is hardcoded to 10ms for all RTC reads, but in some contexts this might not be enough time. Add a timeout parameter to mc146818_get_time() and mc146818_get_time_callback().
If UIP timeout is configured by caller to be >=100 ms and a call takes this long, log a warning.
Make all callers use 10ms to ensure no functional changes.
--- arch/alpha/kernel/rtc.c | 2 +- arch/x86/kernel/hpet.c | 2 +- arch/x86/kernel/rtc.c | 2 +- drivers/base/power/trace.c | 2 +- drivers/rtc/rtc-cmos.c | 6 +++--- drivers/rtc/rtc-mc146818-lib.c | 37 +++++++++++++++++++++++++++++-------- include/linux/mc146818rtc.h | 3 ++- 7 files changed, 38 insertions(+), 16 deletions(-)
arch/alpha/kernel/rtc.c +1 -1
@@ -80,7 +80,7 @@ init_rtc_epoch(void)static int alpha_rtc_read_time (struct device *dev,struct rtc_time *tm) { -int ret =mc146818_get_time (tm); +int ret =mc146818_get_time (tm,10 );if (ret <0 ) {dev_err_ratelimited (dev,"unable to read current time\n" );
arch/x86/kernel/hpet.c +1 -1
@@ -1436,7 +1436,7 @@ irqreturn_t hpet_rtc_interrupt(int irq,memset (&curr_time,0 ,sizeof (struct rtc_time ));if (hpet_rtc_flags & (RTC_UIE |RTC_AIE )) { -if (unlikely (mc146818_get_time (&curr_time) <0 )) { +if (unlikely (mc146818_get_time (&curr_time,10 ) <0 )) {pr_err_ratelimited ("unable to read current time from RTC\n" );return IRQ_HANDLED ; }
arch/x86/kernel/rtc.c +1 -1
@@ -67,7 +67,7 @@ void mach_get_cmos_time(struct timespec6return ; } -if (mc146818_get_time (&tm)) { +if (mc146818_get_time (&tm,10 )) {pr_err ("Unable to read current time from RTC\n" ); now->tv_sec = now->tv_nsec =0 ;return ;
drivers/base/power/trace.c +1 -1
@@ -120,7 +120,7 @@ static unsigned int read_magic_time(voidstruct rtc_time time;unsigned int val; -if (mc146818_get_time (&time) <0 ) { +if (mc146818_get_time (&time,10 ) <0 ) {pr_err ("Unable to read current time from RTC\n" );return 0 ; }
drivers/rtc/rtc-cmos.c +3 -3
@@ -231,7 +231,7 @@ static int cmos_read_time(struct deviceif (!pm_trace_rtc_valid ())return -EIO ; - ret =mc146818_get_time (t); + ret =mc146818_get_time (t,10 );if (ret <0 ) {dev_err_ratelimited (dev,"unable to read current time\n" );return ret;
@@ -307,7 +307,7 @@ static int cmos_read_alarm(struct device* * Use the mc146818_avoid_UIP() function to avoid this. */ -if (!mc146818_avoid_UIP (cmos_read_alarm_callback, &p)) +if (!mc146818_avoid_UIP (cmos_read_alarm_callback,10 , &p))return -EIO ;if (!(p.rtc_control &RTC_DM_BINARY ) ||RTC_ALWAYS_BCD ) {
@@ -556,7 +556,7 @@ static int cmos_set_alarm(struct device* * Use mc146818_avoid_UIP() to avoid this. */ -if (!mc146818_avoid_UIP (cmos_set_alarm_callback, &p)) +if (!mc146818_avoid_UIP (cmos_set_alarm_callback,10 , &p))return -ETIMEDOUT ; cmos->alarm_expires =rtc_tm_to_time64 (&t->time);
drivers/rtc/rtc-mc146818-lib.c +29 -8
@@ -8,26 +8,31 @@#include <linux/acpi.h> #endif +#define UIP_RECHECK_DELAY 100/* usec */ +#define UIP_RECHECK_DELAY_MS (USEC_PER_MSEC / UIP_RECHECK_DELAY) +#define UIP_RECHECK_LOOPS_MS (x) (x / UIP_RECHECK_DELAY_MS) +/* * Execute a function while the UIP (Update-in-progress) bit of the RTC is -* unset. +* unset. The timeout is configurable by the caller in ms. * * Warning: callback may be executed more then once. */ bool mc146818_avoid_UIP (void (*callback)(unsigned char seconds,void *param), +int timeout,void *param) {int i;unsigned long flags;unsigned char seconds; -for (i =0 ; i <100 ; i++) { +for (i =0 ;UIP_RECHECK_LOOPS_MS (i) < timeout; i++) {spin_lock_irqsave (&rtc_lock, flags);/* * Check whether there is an update in progress during which the * readout is unspecified. The maximum update time is ~2ms. Poll -* every 100 usec for completion. +* for completion. * * Store the second value before checking UIP so a long lasting * NMI which happens to hit after the UIP check cannot make
@@ -37,7 +42,7 @@ bool mc146818_avoid_UIP(void (*callback)if (CMOS_READ (RTC_FREQ_SELECT ) &RTC_UIP ) {spin_unlock_irqrestore (&rtc_lock, flags); -udelay (100 ); +udelay (UIP_RECHECK_DELAY );continue ; }
@@ -56,7 +61,7 @@ bool mc146818_avoid_UIP(void (*callback)*/ if (CMOS_READ (RTC_FREQ_SELECT ) &RTC_UIP ) {spin_unlock_irqrestore (&rtc_lock, flags); -udelay (100 ); +udelay (UIP_RECHECK_DELAY );continue ; }
@@ -72,6 +77,10 @@ bool mc146818_avoid_UIP(void (*callback) }spin_unlock_irqrestore (&rtc_lock, flags); +if (UIP_RECHECK_LOOPS_MS (i) >=100 ) +pr_warn ("Reading current time from RTC took around %li ms\n" , +UIP_RECHECK_LOOPS_MS (i)); +return true; }return false;
@@ -84,7 +93,7 @@ EXPORT_SYMBOL_GPL(mc146818_avoid_UIP);*/ bool mc146818_does_rtc_work (void ) { -return mc146818_avoid_UIP (NULL ,NULL ); +return mc146818_avoid_UIP (NULL ,10 ,NULL ); }EXPORT_SYMBOL_GPL (mc146818_does_rtc_work);
@@ -130,13 +139,25 @@ static void mc146818_get_time_callback(u p->ctrl =CMOS_READ (RTC_CONTROL ); } -int mc146818_get_time (struct rtc_time *time) +/** +* mc146818_get_time - Get the current time from the RTC +* @time: pointer to struct rtc_time to store the current time +* @timeout: timeout value in ms +* +* This function reads the current time from the RTC and stores it in the +* provided struct rtc_time. The timeout parameter specifies the maximum +* time to wait for the RTC to become ready. +* +* Return: 0 on success, -ETIMEDOUT if the RTC did not become ready within +* the specified timeout, or another error code if an error occurred. +*/ +int mc146818_get_time (struct rtc_time *time,int timeout) {struct mc146818_get_time_callback_param p = { .time = time }; -if (!mc146818_avoid_UIP (mc146818_get_time_callback, &p)) { +if (!mc146818_avoid_UIP (mc146818_get_time_callback, timeout, &p)) {memset (time,0 ,sizeof (*time));return -ETIMEDOUT ; }
include/linux/mc146818rtc.h +2 -1
@@ -126,10 +126,11 @@ struct cmos_rtc_board_info {#endif /* ARCH_RTC_LOCATION */ bool mc146818_does_rtc_work (void ); -int mc146818_get_time (struct rtc_time *time); +int mc146818_get_time (struct rtc_time *time,int timeout);int mc146818_set_time (struct rtc_time *time);bool mc146818_avoid_UIP (void (*callback)(unsigned char seconds,void *param), +int timeout,void *param);#endif /* _MC146818RTC_H */
Greg Kroah-Hartman
maintainerPATCH 52/185 rtc: Extend timeout for waiting for UIP to clear to 1s
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello <[email protected]>
commit cef9ecc8e938dd48a560f7dd9be1246359248d20 upstream.
Specs don't say anything about UIP being cleared within 10ms. They only say that UIP won't occur for another 244uS. If a long NMI occurs while UIP is still updating it might not be possible to get valid data in 10ms.
This has been observed in the wild that around s2idle some calls can take up to 480ms before UIP is clear.
Adjust callers from outside an interrupt context to wait for up to a 1s instead of 10ms.
--- arch/x86/kernel/rtc.c | 2 +- drivers/base/power/trace.c | 2 +- drivers/rtc/rtc-cmos.c | 2 +- drivers/rtc/rtc-mc146818-lib.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-)
arch/x86/kernel/rtc.c +1 -1
@@ -67,7 +67,7 @@ void mach_get_cmos_time(struct timespec64 *now)return ; } -if (mc146818_get_time (&tm,10 )) { +if (mc146818_get_time (&tm,1000 )) {pr_err ("Unable to read current time from RTC\n" ); now->tv_sec = now->tv_nsec =0 ;return ;
drivers/base/power/trace.c +1 -1
@@ -120,7 +120,7 @@ static unsigned int read_magic_time(void)struct rtc_time time;unsigned int val; -if (mc146818_get_time (&time,10 ) <0 ) { +if (mc146818_get_time (&time,1000 ) <0 ) {pr_err ("Unable to read current time from RTC\n" );return 0 ; }
drivers/rtc/rtc-cmos.c +1 -1
@@ -231,7 +231,7 @@ static int cmos_read_time(struct device *dev, struct rtc_time *t)if (!pm_trace_rtc_valid ())return -EIO ; - ret =mc146818_get_time (t,10 ); + ret =mc146818_get_time (t,1000 );if (ret <0 ) {dev_err_ratelimited (dev,"unable to read current time\n" );return ret;
drivers/rtc/rtc-mc146818-lib.c +1 -1
@@ -93,7 +93,7 @@ EXPORT_SYMBOL_GPL(mc146818_avoid_UIP);*/ bool mc146818_does_rtc_work (void ) { -return mc146818_avoid_UIP (NULL ,10 ,NULL ); +return mc146818_avoid_UIP (NULL ,1000 ,NULL ); }EXPORT_SYMBOL_GPL (mc146818_does_rtc_work);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 53/185 nouveau/vmm: dont set addr on the fail path to avoid warning
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Airlie <[email protected]>
commit cacea81390fd8c8c85404e5eb2adeb83d87a912e upstream.
nvif_vmm_put gets called if addr is set, but if the allocation fails we don't need to call put, otherwise we get a warning like
[523232.435671] ------------[ cut here ]------------ [523232.435674] WARNING: CPU: 8 PID: 1505697 at drivers/gpu/drm/nouveau/nvif/vmm.c:68 nvif_vmm_put+0x72/0x80 [nouveau] [523232.435795] Modules linked in: uinput rfcomm snd_seq_dummy snd_hrtimer nf_conntrack_netbios_ns nf_conntrack_broadcast nft_fib_inet nft_fib_ipv4 nft_fib_ipv6 nft_fib nft_reject_inet nf_reject_ipv4 nf_reject_ipv6 nft_reject nft_ct nft_chain_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 ip_set nf_tables nfnetlink qrtr bnep sunrpc binfmt_misc intel_rapl_msr intel_rapl_common intel_uncore_frequency intel_uncore_frequency_common isst_if_common iwlmvm nfit libnvdimm vfat fat x86_pkg_temp_thermal intel_powerclamp mac80211 snd_soc_avs snd_soc_hda_codec coretemp snd_hda_ext_core snd_soc_core snd_hda_codec_realtek kvm_intel snd_hda_codec_hdmi snd_compress snd_hda_codec_generic ac97_bus snd_pcm_dmaengine snd_hda_intel libarc4 snd_intel_dspcfg snd_intel_sdw_acpi snd_hda_codec kvm iwlwifi snd_hda_core btusb snd_hwdep btrtl snd_seq btintel irqbypass btbcm rapl snd_seq_device eeepc_wmi btmtk intel_cstate iTCO_wdt cfg80211 snd_pcm asus_wmi bluetooth intel_pmc_bxt iTCO_vendor_support snd_timer ledtrig_audio pktcdvd snd mei_me [523232.435828] sparse_keymap intel_uncore i2c_i801 platform_profile wmi_bmof mei pcspkr ioatdma soundcore i2c_smbus rfkill idma64 dca joydev acpi_tad loop zram nouveau drm_ttm_helper ttm video drm_exec drm_gpuvm gpu_sched crct10dif_pclmul i2c_algo_bit nvme crc32_pclmul crc32c_intel drm_display_helper polyval_clmulni nvme_core polyval_generic e1000e mxm_wmi cec ghash_clmulni_intel r8169 sha512_ssse3 nvme_common wmi pinctrl_sunrisepoint uas usb_storage ip6_tables ip_tables fuse [523232.435849] CPU: 8 PID: 1505697 Comm: gnome-shell Tainted: G W 6.6.0-rc7-nvk-uapi+ #12 [523232.435851] Hardware name: System manufacturer System Product Name/ROG STRIX X299-E GAMING II, BIOS 1301 09/24/2021 [523232.435852] RIP: 0010:nvif_vmm_put+0x72/0x80 [nouveau] [523232.435934] Code: 00 00 48 89 e2 be 02 00 00 00 48 c7 04 24 00 00 00 00 48 89 44 24 08 e8 fc bf ff ff 85 c0 75 0a 48 c7 43 08 00 00 00 00 eb b3 <0f> 0b eb f2 e8 f5 c9 b2 e6 0f 1f 44 00 00 90 90 90 90 90 90 90 90 [523232.435936] RSP: 0018:ffffc900077ffbd8 EFLAGS: 00010282 [523232.435937] RAX: 00000000fffffffe RBX: ffffc900077ffc00 RCX: 0000000000000010 [523232.435938] RDX: 0000000000000010 RSI: ffffc900077ffb38 RDI: ffffc900077ffbd8 [523232.435940] RBP: ffff888e1c4f2140 R08: 0000000000000000 R09: 0000000000000000 [523232.435940] R10: 0000000000000000 R11: 0000000000000000 R12: ffff888503811800 [523232.435941] R13: ffffc900077ffca0 R14: ffff888e1c4f2140 R15: ffff88810317e1e0 [523232.435942] FS: 00007f933a769640(0000) GS:ffff88905fa00000(0000) knlGS:0000000000000000 [523232.435943] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [523232.435944] CR2: 00007f930bef7000 CR3: 00000005d0322001 CR4: 00000000003706e0 [523232.435945] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [523232.435946] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [523232.435964] Call Trace: [523232.435965] <TASK> [523232.435966] ? nvif_vmm_put+0x72/0x80 [nouveau] [523232.436051] ? __warn+0x81/0x130 [523232.436055] ? nvif_vmm_put+0x72/0x80 [nouveau] [523232.436138] ? report_bug+0x171/0x1a0 [523232.436142] ? handle_bug+0x3c/0x80 [523232.436144] ? exc_invalid_op+0x17/0x70 [523232.436145] ? asm_exc_invalid_op+0x1a/0x20 [523232.436149] ? nvif_vmm_put+0x72/0x80 [nouveau] [523232.436230] ? nvif_vmm_put+0x64/0x80 [nouveau] [523232.436342] nouveau_vma_del+0x80/0xd0 [nouveau] [523232.436506] nouveau_vma_new+0x1a0/0x210 [nouveau] [523232.436671] nouveau_gem_object_open+0x1d0/0x1f0 [nouveau] [523232.436835] drm_gem_handle_create_tail+0xd1/0x180 [523232.436840] drm_prime_fd_to_handle_ioctl+0x12e/0x200 [523232.436844] ? __pfx_drm_prime_fd_to_handle_ioctl+0x10/0x10 [523232.436847] drm_ioctl_kernel+0xd3/0x180 [523232.436849] drm_ioctl+0x26d/0x4b0 [523232.436851] ? __pfx_drm_prime_fd_to_handle_ioctl+0x10/0x10 [523232.436855] nouveau_drm_ioctl+0x5a/0xb0 [nouveau] [523232.437032] __x64_sys_ioctl+0x94/0xd0 [523232.437036] do_syscall_64+0x5d/0x90 [523232.437040] ? syscall_exit_to_user_mode+0x2b/0x40 [523232.437044] ? do_syscall_64+0x6c/0x90 [523232.437046] entry_SYSCALL_64_after_hwframe+0x6e/0xd8
--- drivers/gpu/drm/nouveau/nouveau_vmm.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/nouveau/nouveau_vmm.c +3 -0
@@ -108,6 +108,9 @@ nouveau_vma_new(struct nouveau_bo *nvbo, }else { ret =nvif_vmm_get (&vmm->vmm,PTES , false, mem->mem.page,0 , mem->mem.size, &tmp); +if (ret) + goto done; + vma->addr = tmp.addr; }
Greg Kroah-Hartman
maintainerPATCH 54/185 ubifs: ubifs_symlink: Fix memleak of inode->i_link in error path
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhihao Cheng <[email protected]>
commit 1e022216dcd248326a5bb95609d12a6815bca4e2 upstream.
For error handling path in ubifs_symlink(), inode will be marked as bad first, then iput() is invoked. If inode->i_link is initialized by fscrypt_encrypt_symlink() in encryption scenario, inode->i_link won't be freed by callchain ubifs_free_inode -> fscrypt_free_inode in error handling path, because make_bad_inode() has changed 'inode->i_mode' as 'S_IFREG'.
Following kmemleak is easy to be reproduced by injecting error in ubifs_jnl_update() when doing symlink in encryption scenario:
unreferenced object 0xffff888103da3d98 (size 8):
comm "ln", pid 1692, jiffies 4294914701 (age 12.045s) backtrace:
kmemdup+0x32/0x70 __fscrypt_encrypt_symlink+0xed/0x1c0 ubifs_symlink+0x210/0x300 [ubifs] vfs_symlink+0x216/0x360 do_symlinkat+0x11a/0x190 do_syscall_64+0x3b/0xe0
There are two ways fixing it:
1. Remove make_bad_inode() in error handling path. We can do that because ubifs_evict_inode() will do same processes for good symlink inode and bad symlink inode, for inode->i_nlink checking is before is_bad_inode().
2. Free inode->i_link before marking inode bad.
Method 2 is picked, it has less influence, personally, I think.
--- fs/ubifs/dir.c | 2 ++ 1 file changed, 2 insertions(+)
fs/ubifs/dir.c +2 -0
@@ -1226,6 +1226,8 @@ out_cancel: dir_ui->ui_size = dir->i_size;mutex_unlock (&dir_ui->ui_mutex); out_inode: +/* Free inode->i_link before inode is marked as bad. */ +fscrypt_free_inode (inode);make_bad_inode (inode);iput (inode); out_fname:
Greg Kroah-Hartman
maintainerPATCH 55/185 mm/rmap: fix misplaced parenthesis of a likely()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt (Google) <[email protected]>
commit f67f8d4a8c1e1ebc85a6cbdb9a7266f14863461c upstream.
Running my yearly branch profiler to see where likely/unlikely annotation may be added or removed, I discovered this:
correct incorrect % Function File Line
------- --------- - -------- ---- ----
0 457918 100 page_try_dup_anon_rmap rmap.h 264
[..]
458021 0 0 page_try_dup_anon_rmap rmap.h 265
I thought it was interesting that line 264 of rmap.h had a 100% incorrect annotation, but the line directly below it was 100% correct. Looking at the code:
if (likely(!is_device_private_page(page) && unlikely(page_needs_cow_for_dma(vma, page))))
It didn't make sense. The "likely()" was around the entire if statement (not just the "!is_device_private_page(page)"), which also included the "unlikely()" portion of that if condition.
If the unlikely portion is unlikely to be true, that would make the entire if condition unlikely to be true, so it made no sense at all to say the entire if condition is true.
What is more likely to be likely is just the first part of the if statement before the && operation. It's likely to be a misplaced parenthesis. And after making the if condition broken into a likely() && unlikely(), both now appear to be correct!
--- include/linux/rmap.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
include/linux/rmap.h +2 -2
@@ -250,8 +250,8 @@ static inline int page_try_dup_anon_rmap* guarantee the pinned page won't be randomly replaced in the * future on write faults. */ -if (likely (!is_device_private_page (page) && -unlikely (page_needs_cow_for_dma (vma, page)))) +if (likely (!is_device_private_page (page)) && +unlikely (page_needs_cow_for_dma (vma, page)))return -EBUSY ;ClearPageAnonExclusive (page);
Greg Kroah-Hartman
maintainerPATCH 56/185 mm/sparsemem: fix race in accessing memory_section->usage
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Charan Teja Kalla <[email protected]>
commit 5ec8e8ea8b7783fab150cf86404fc38cb4db8800 upstream.
The below race is observed on a PFN which falls into the device memory region with the system memory configuration where PFN's are such that [ZONE_NORMAL ZONE_DEVICE ZONE_NORMAL]. Since normal zone start and end pfn contains the device memory PFN's as well, the compaction triggered will try on the device memory PFN's too though they end up in NOP(because pfn_to_online_page() returns NULL for ZONE_DEVICE memory sections). When from other core, the section mappings are being removed for the ZONE_DEVICE region, that the PFN in question belongs to, on which compaction is currently being operated is resulting into the kernel crash with CONFIG_SPASEMEM_VMEMAP enabled. The crash logs can be seen at [1].
compact_zone() memunmap_pages
------------- ---------------__pageblock_pfn_to_page
......
(a)pfn_valid():
valid_section()//return true
(b)__remove_pages()->
sparse_remove_section()->
section_deactivate():
[Free the array ms->usage and set
ms->usage = NULL]
pfn_section_valid()
[Access ms->usage which
is NULL]NOTE: From the above it can be said that the race is reduced to between the pfn_valid()/pfn_section_valid() and the section deactivate with SPASEMEM_VMEMAP enabled.
The commit b943f045a9af("mm/sparse: fix kernel crash with pfn_section_valid check") tried to address the same problem by clearing the SECTION_HAS_MEM_MAP with the expectation of valid_section() returns false thus ms->usage is not accessed.
Fix this issue by the below steps:
a) Clear SECTION_HAS_MEM_MAP before freeing the ->usage.
b) RCU protected read side critical section will either return NULL when SECTION_HAS_MEM_MAP is cleared or can successfully access ->usage.
c) Free the ->usage with kfree_rcu() and set ms->usage = NULL. No attempt will be made to access ->usage after this as the SECTION_HAS_MEM_MAP is cleared thus valid_section() return false.
Thanks to David/Pavan for their inputs on this patch.
[1] https://lore.kernel.org/linux-mm/[email protected]/
On Snapdragon SoC, with the mentioned memory configuration of PFN's as [ZONE_NORMAL ZONE_DEVICE ZONE_NORMAL], we are able to see bunch of issues daily while testing on a device farm.
For this particular issue below is the log. Though the below log is not directly pointing to the pfn_section_valid(){ ms->usage;}, when we loaded this dump on T32 lauterbach tool, it is pointing.
[ 540.578056] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000 [ 540.578068] Mem abort info: [ 540.578070] ESR = 0x0000000096000005 [ 540.578073] EC = 0x25: DABT (current EL), IL = 32 bits [ 540.578077] SET = 0, FnV = 0 [ 540.578080] EA = 0, S1PTW = 0 [ 540.578082] FSC = 0x05: level 1 translation fault [ 540.578085] Data abort info: [ 540.578086] ISV = 0, ISS = 0x00000005 [ 540.578088] CM = 0, WnR = 0 [ 540.579431] pstate: 82400005 (Nzcv daif +PAN -UAO +TCO -DIT -SSBSBTYPE=--) [ 540.579436] pc : __pageblock_pfn_to_page+0x6c/0x14c [ 540.579454] lr : compact_zone+0x994/0x1058 [ 540.579460] sp : ffffffc03579b510 [ 540.579463] x29: ffffffc03579b510 x28: 0000000000235800 x27:000000000000000c [ 540.579470] x26: 0000000000235c00 x25: 0000000000000068 x24:ffffffc03579b640 [ 540.579477] x23: 0000000000000001 x22: ffffffc03579b660 x21:0000000000000000 [ 540.579483] x20: 0000000000235bff x19: ffffffdebf7e3940 x18:ffffffdebf66d140 [ 540.579489] x17: 00000000739ba063 x16: 00000000739ba063 x15:00000000009f4bff [ 540.579495] x14: 0000008000000000 x13: 0000000000000000 x12:0000000000000001 [ 540.579501] x11: 0000000000000000 x10: 0000000000000000 x9 :ffffff897d2cd440 [ 540.579507] x8 : 0000000000000000 x7 : 0000000000000000 x6 :ffffffc03579b5b4 [ 540.579512] x5 : 0000000000027f25 x4 : ffffffc03579b5b8 x3 :0000000000000001 [ 540.579518] x2 : ffffffdebf7e3940 x1 : 0000000000235c00 x0 :0000000000235800 [ 540.579524] Call trace: [ 540.579527] __pageblock_pfn_to_page+0x6c/0x14c [ 540.579533] compact_zone+0x994/0x1058 [ 540.579536] try_to_compact_pages+0x128/0x378 [ 540.579540] __alloc_pages_direct_compact+0x80/0x2b0 [ 540.579544] __alloc_pages_slowpath+0x5c0/0xe10 [ 540.579547] __alloc_pages+0x250/0x2d0 [ 540.579550] __iommu_dma_alloc_noncontiguous+0x13c/0x3fc [ 540.579561] iommu_dma_alloc+0xa0/0x320 [ 540.579565] dma_alloc_attrs+0xd4/0x108
--- include/linux/mmzone.h | 14 +++++++++++--- mm/sparse.c | 17 +++++++++-------- 2 files changed, 20 insertions(+), 11 deletions(-)
include/linux/mmzone.h +11 -3
@@ -1622,6 +1622,7 @@ static inline unsigned long section_nr_t#define SUBSECTION_ALIGN_DOWN (pfn) ((pfn) & PAGE_SUBSECTION_MASK)struct mem_section_usage { +struct rcu_head rcu;#ifdef CONFIG_SPARSEMEM_VMEMMAP DECLARE_BITMAP(subsection_map, SUBSECTIONS_PER_SECTION);#endif
@@ -1815,7 +1816,7 @@ static inline int pfn_section_valid(stru {int idx =subsection_map_index (pfn); -return test_bit (idx, ms->usage->subsection_map); +return test_bit (idx,READ_ONCE (ms->usage)->subsection_map); }#else static inline int pfn_section_valid (struct mem_section *ms,unsigned long pfn)
@@ -1839,6 +1840,7 @@ static inline int pfn_section_valid(strustatic inline int pfn_valid (unsigned long pfn) {struct mem_section *ms; +int ret;/* * Ensure the upper PAGE_SHIFT bits are clear in the
@@ -1852,13 +1854,19 @@ static inline int pfn_valid(unsigned lonif (pfn_to_section_nr (pfn) >=NR_MEM_SECTIONS )return 0 ; ms =__pfn_to_section (pfn); -if (!valid_section (ms)) +rcu_read_lock (); +if (!valid_section (ms)) { +rcu_read_unlock ();return 0 ; + }/* * Traditionally early sections always returned pfn_valid() for * the entire section-sized span. */ - return early_section(ms) || pfn_section_valid(ms, pfn); + ret =early_section (ms) ||pfn_section_valid (ms, pfn); +rcu_read_unlock (); + + return ret; }#endif
mm/sparse.c +9 -8
@@ -793,6 +793,13 @@ static void section_deactivate(unsignedunsigned long section_nr =pfn_to_section_nr (pfn);/* +* Mark the section invalid so that valid_section() +* return false. This prevents code from dereferencing +* ms->usage array. +*/ + ms->section_mem_map &= ~SECTION_HAS_MEM_MAP ; + +/* * When removing an early section, the usage map is kept (as the * usage maps of other sections fall into the same page). It * will be re-used when re-adding the section - which is then no
@@ -800,16 +807,10 @@ static void section_deactivate(unsigned* was allocated during boot. */ if (!PageReserved (virt_to_page (ms->usage))) { -kfree (ms->usage); - ms->usage =NULL ; +kfree_rcu (ms->usage, rcu); +WRITE_ONCE (ms->usage,NULL ); } memmap =sparse_decode_mem_map (ms->section_mem_map, section_nr); -/* -* Mark the section invalid so that valid_section() -* return false. This prevents code from dereferencing -* ms->usage array. -*/ - ms->section_mem_map &= ~SECTION_HAS_MEM_MAP ; }/*
Greg Kroah-Hartman
maintainerPATCH 57/185 rename(): fix the locking of subdirectories
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <[email protected]>
commit 22e111ed6c83dcde3037fc81176012721bc34c0b upstream.
We should never lock two subdirectories without having taken
->s_vfs_rename_mutex; inode pointer order or not, the "order" proposed in 28eceeda130f "fs: Lock moved directories" is not transitive, with the usual consequences.
The rationale for locking renamed subdirectory in all cases was
the possibility of race between rename modifying .. in a subdirectory to reflect the new parent and another thread modifying the same subdirectory. For a lot of filesystems that's not a problem, but for some it can lead to trouble (e.g. the case when short directory contents is kept in the inode, but creating a file in it might push it across the size limit and copy its contents into separate data block(s)).
However, we need that only in case when the parent does change -
otherwise ->rename() doesn't need to do anything with .. entry in the first place. Some instances are lazy and do a tautological update anyway, but it's really not hard to avoid.
Amended locking rules for rename():
find the parent(s) of source and target
if source and target have the same parent
lock the common parent
else
lock ->s_vfs_rename_mutex
lock both parents, in ancestor-first order; if neither is an ancestor of another, lock the parent of source first.
find the source and target.
if source and target have the same parent
if operation is an overwriting rename of a subdirectory
lock the target subdirectory
else
if source is a subdirectory
lock the source
if target is a subdirectory
lock the target
lock non-directories involved, in inode pointer order if both source and target are such.
That way we are guaranteed that parents are locked (for obvious reasons), that any renamed non-directory is locked (nfsd relies upon that), that any victim is locked (emptiness check needs that, among other things) and subdirectory that changes parent is locked (needed to protect the update of .. entries). We are also guaranteed that any operation locking more than one directory either takes ->s_vfs_rename_mutex or locks a parent followed by its child.
--- Documentation/filesystems/directory-locking.rst | 29 ++++++----- Documentation/filesystems/locking.rst | 5 +- Documentation/filesystems/porting.rst | 18 +++++++ fs/namei.c | 60 ++++++++++++++---------- 4 files changed, 74 insertions(+), 38 deletions(-)
Documentation/filesystems/directory-locking.rst +15 -14
@@ -22,13 +22,16 @@ exclusive. 3) object removal. Locking rules: caller locks parent, finds victim, locks victim and calls the method. Locks are exclusive. -4) rename() that is _not_ cross-directory. Locking rules: caller locks the -parent and finds source and target. We lock both (provided they exist). If we -need to lock two inodes of different type (dir vs non-dir), we lock directory -first. If we need to lock two inodes of the same type, lock them in inode -pointer order. Then call the method. All locks are exclusive. -NB: we might get away with locking the source (and target in exchange -case) shared. +4) rename() that is _not_ cross-directory. Locking rules: caller locks +the parent and finds source and target. Then we decide which of the +source and target need to be locked. Source needs to be locked if it's a +non-directory; target - if it's a non-directory or about to be removed. +Take the locks that need to be taken, in inode pointer order if need +to take both (that can happen only when both source and target are +non-directories - the source because it wouldn't be locked otherwise +and the target because mixing directory and non-directory is allowed +only with RENAME_EXCHANGE, and that won't be removing the target). +After the locks had been taken, call the method. All locks are exclusive. 5) link creation. Locking rules:
@@ -44,20 +47,17 @@ rules: * lock the filesystem * lock parents in "ancestors first" order. If one is not ancestor of - the other, lock them in inode pointer order. + the other, lock the parent of source first. * find source and target. * if old parent is equal to or is a descendent of target fail with -ENOTEMPTY * if new parent is equal to or is a descendent of source fail with -ELOOP - * Lock both the source and the target provided they exist. If we - need to lock two inodes of different type (dir vs non-dir), we lock - the directory first. If we need to lock two inodes of the same type, - lock them in inode pointer order. + * Lock subdirectories involved (source before target). + * Lock non-directories involved, in inode pointer order. * call the method. -All ->i_rwsem are taken exclusive. Again, we might get away with locking -the source (and target in exchange case) shared. +All ->i_rwsem are taken exclusive. The rules above obviously guarantee that all directories that are going to be read, modified or removed by method will be locked by caller.
@@ -67,6 +67,7 @@ If no directory is its own ancestor, the Proof: +[XXX: will be updated once we are done massaging the lock_rename()] First of all, at any moment we have a linear ordering of the objects - A < B iff (A is an ancestor of B) or (B is not an ancestor of A and ptr(A) < ptr(B)).
Documentation/filesystems/locking.rst +4 -1
@@ -99,7 +99,7 @@ symlink: exclusive mkdir: exclusive unlink: exclusive (both) rmdir: exclusive (both)(see below) -rename: exclusive (all) (see below) +rename: exclusive (both parents, some children) (see below) readlink: no get_link: no setattr: exclusive
@@ -119,6 +119,9 @@ fileattr_set: exclusive Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_rwsem exclusive on victim. cross-directory ->rename() has (per-superblock) ->s_vfs_rename_sem. + ->unlink() and ->rename() have ->i_rwsem exclusive on all non-directories + involved. + ->rename() has ->i_rwsem exclusive on any subdirectory that changes parent. See Documentation/filesystems/directory-locking.rst for more detailed discussion of the locking scheme for directory operations.
Documentation/filesystems/porting.rst +18 -0
@@ -943,3 +943,21 @@ file pointer instead of struct dentry po changed to simplify callers. The passed file is in a non-open state and on success must be opened before returning (e.g. by calling finish_open_simple()). + +--- + +**mandatory** + +If ->rename() update of .. on cross-directory move needs an exclusion with +directory modifications, do *not* lock the subdirectory in question in your +->rename() - it's done by the caller now [that item should've been added in +28eceeda130f "fs: Lock moved directories"]. + +--- + +**mandatory** + +On same-directory ->rename() the (tautological) update of .. is not protected +by any locks; just don't do it if the old parent is the same as the new one. +We really can't lock two subdirectories in same-directory rename - not without +deadlocks.
fs/namei.c +37 -23
97 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 58/185 serial: sc16is7xx: improve regmap debugfs by using one regmap per port
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hugo Villeneuve <[email protected]>
commit 3837a0379533aabb9e4483677077479f7c6aa910 upstream.
With this current driver regmap implementation, it is hard to make sense of the register addresses displayed using the regmap debugfs interface, because they do not correspond to the actual register addresses documented in the datasheet. For example, register 1 is displayed as registers 04 thru 07:
$ cat /sys/kernel/debug/regmap/spi0.0/registers 04: 10 -> Port 0, register offset 1 05: 10 -> Port 1, register offset 1 06: 00 -> Port 2, register offset 1 -> invalid 07: 00 -> port 3, register offset 1 -> invalid ...
The reason is that bits 0 and 1 of the register address correspond to the channel (port) bits, so the register address itself starts at bit 2, and we must 'mentally' shift each register address by 2 bits to get its real address/offset.
Also, only channels 0 and 1 are supported by the chip, so channel mask combinations of 10b and 11b are invalid, and the display of these registers is useless.
This patch adds a separate regmap configuration for each port, similar to what is done in the max310x driver, so that register addresses displayed match the register addresses in the chip datasheet. Also, each port now has its own debugfs entry.
Example with new regmap implementation:
$ cat /sys/kernel/debug/regmap/spi0.0-port0/registers 1: 10 2: 01 3: 00 ...
$ cat /sys/kernel/debug/regmap/spi0.0-port1/registers 1: 10 2: 01 3: 00
As an added bonus, this also simplifies some operations (read/write/modify) because it is no longer necessary to manually shift register addresses.
--- drivers/tty/serial/sc16is7xx.c | 143 +++++++++++++++++++++++------------------ 1 file changed, 81 insertions(+), 62 deletions(-)
drivers/tty/serial/sc16is7xx.c +81 -62
@@ -301,8 +301,8 @@/* Misc definitions */ +#define SC16IS7XX_SPI_READ_BIT BIT(7)#define SC16IS7XX_FIFO_SIZE (64) -#define SC16IS7XX_REG_SHIFT 2#define SC16IS7XX_GPIOS_PER_BANK 4struct sc16is7xx_devtype {
@@ -324,6 +324,7 @@ struct sc16is7xx_one_config {struct sc16is7xx_one {struct uart_port port;u8 line; +struct regmap *regmap;struct kthread_work tx_work;struct kthread_work reg_work;struct kthread_delayed_work ms_work;
@@ -362,48 +363,37 @@ static void sc16is7xx_stop_tx(struct uar#define to_sc16is7xx_port (p,e) ((container_of((p), struct sc16is7xx_port, e)))#define to_sc16is7xx_one (p,e) ((container_of((p), struct sc16is7xx_one, e))) -static int sc16is7xx_line (struct uart_port *port) -{ -struct sc16is7xx_one *one =to_sc16is7xx_one (port, port); - -return one->line; -} -static u8 sc16is7xx_port_read (struct uart_port *port,u8 reg) { -struct sc16is7xx_port *s =dev_get_drvdata (port->dev); +struct sc16is7xx_one *one =to_sc16is7xx_one (port, port);unsigned int val =0 ; -const u8 line =sc16is7xx_line (port); -regmap_read (s->regmap, (reg <<SC16IS7XX_REG_SHIFT ) | line, &val); +regmap_read (one->regmap, reg, &val);return val; }static void sc16is7xx_port_write (struct uart_port *port,u8 reg,u8 val) { -struct sc16is7xx_port *s =dev_get_drvdata (port->dev); -const u8 line =sc16is7xx_line (port); +struct sc16is7xx_one *one =to_sc16is7xx_one (port, port); -regmap_write (s->regmap, (reg <<SC16IS7XX_REG_SHIFT ) | line, val); +regmap_write (one->regmap, reg, val); }static void sc16is7xx_fifo_read (struct uart_port *port,unsigned int rxlen) {struct sc16is7xx_port *s =dev_get_drvdata (port->dev); -const u8 line =sc16is7xx_line (port); -u8 addr = (SC16IS7XX_RHR_REG <<SC16IS7XX_REG_SHIFT ) | line; +struct sc16is7xx_one *one =to_sc16is7xx_one (port, port); -regcache_cache_bypass (s->regmap, true); -regmap_raw_read (s->regmap, addr, s->buf, rxlen); -regcache_cache_bypass (s->regmap, false); +regcache_cache_bypass (one->regmap, true); +regmap_raw_read (one->regmap,SC16IS7XX_RHR_REG , s->buf, rxlen); +regcache_cache_bypass (one->regmap, false); }static void sc16is7xx_fifo_write (struct uart_port *port,u8 to_send) {struct sc16is7xx_port *s =dev_get_drvdata (port->dev); -const u8 line =sc16is7xx_line (port); -u8 addr = (SC16IS7XX_THR_REG <<SC16IS7XX_REG_SHIFT ) | line; +struct sc16is7xx_one *one =to_sc16is7xx_one (port, port);/* * Don't send zero-length data, at least on SPI it confuses the chip
@@ -412,19 +402,17 @@ static void sc16is7xx_fifo_write(structif (unlikely (!to_send))return ; -regcache_cache_bypass (s->regmap, true); -regmap_raw_write (s->regmap, addr, s->buf, to_send); -regcache_cache_bypass (s->regmap, false); +regcache_cache_bypass (one->regmap, true); +regmap_raw_write (one->regmap,SC16IS7XX_THR_REG , s->buf, to_send); +regcache_cache_bypass (one->regmap, false); }static void sc16is7xx_port_update (struct uart_port *port,u8 reg,u8 mask,u8 val) { -struct sc16is7xx_port *s =dev_get_drvdata (port->dev); -const u8 line =sc16is7xx_line (port); +struct sc16is7xx_one *one =to_sc16is7xx_one (port, port); -regmap_update_bits (s->regmap, (reg <<SC16IS7XX_REG_SHIFT ) | line, - mask, val); +regmap_update_bits (one->regmap, reg, mask, val); }static int sc16is7xx_alloc_line (void )
@@ -479,7 +467,7 @@ static const struct sc16is7xx_devtype scstatic bool sc16is7xx_regmap_volatile (struct device *dev,unsigned int reg) { -switch (reg >>SC16IS7XX_REG_SHIFT ) { +switch (reg) {case SC16IS7XX_RHR_REG :case SC16IS7XX_IIR_REG :case SC16IS7XX_LSR_REG :
@@ -498,7 +486,7 @@ static bool sc16is7xx_regmap_volatile(ststatic bool sc16is7xx_regmap_precious (struct device *dev,unsigned int reg) { -switch (reg >>SC16IS7XX_REG_SHIFT ) { +switch (reg) {case SC16IS7XX_RHR_REG :return true;default :
@@ -511,6 +499,7 @@ static bool sc16is7xx_regmap_precious(ststatic int sc16is7xx_set_baud (struct uart_port *port,int baud) {struct sc16is7xx_port *s =dev_get_drvdata (port->dev); +struct sc16is7xx_one *one =to_sc16is7xx_one (port, port);u8 lcr;u8 prescaler =0 ;unsigned long clk = port->uartclk, div = clk /16 / baud;
@@ -542,12 +531,12 @@ static int sc16is7xx_set_baud(struct uar SC16IS7XX_LCR_CONF_MODE_B);/* Enable enhanced features */ -regcache_cache_bypass (s->regmap, true); +regcache_cache_bypass (one->regmap, true);sc16is7xx_port_update (port,SC16IS7XX_EFR_REG ,SC16IS7XX_EFR_ENABLE_BIT ,SC16IS7XX_EFR_ENABLE_BIT ); -regcache_cache_bypass (s->regmap, false); +regcache_cache_bypass (one->regmap, false);/* Put LCR back to the normal mode */ sc16is7xx_port_write (port,SC16IS7XX_LCR_REG , lcr);
@@ -563,10 +552,10 @@ static int sc16is7xx_set_baud(struct uar SC16IS7XX_LCR_CONF_MODE_A);/* Write the new divisor */ -regcache_cache_bypass (s->regmap, true); +regcache_cache_bypass (one->regmap, true);sc16is7xx_port_write (port,SC16IS7XX_DLH_REG , div /256 );sc16is7xx_port_write (port,SC16IS7XX_DLL_REG , div %256 ); -regcache_cache_bypass (s->regmap, false); +regcache_cache_bypass (one->regmap, false);/* Put LCR back to the normal mode */ sc16is7xx_port_write (port,SC16IS7XX_LCR_REG , lcr);
@@ -1094,7 +1083,7 @@ static void sc16is7xx_set_termios(struct SC16IS7XX_LCR_CONF_MODE_B);/* Configure flow control */ -regcache_cache_bypass (s->regmap, true); +regcache_cache_bypass (one->regmap, true);sc16is7xx_port_write (port,SC16IS7XX_XON1_REG , termios->c_cc[VSTART ]);sc16is7xx_port_write (port,SC16IS7XX_XOFF1_REG , termios->c_cc[VSTOP ]);
@@ -1113,7 +1102,7 @@ static void sc16is7xx_set_termios(structSC16IS7XX_EFR_REG ,SC16IS7XX_EFR_FLOWCTRL_BITS , flow); -regcache_cache_bypass (s->regmap, false); +regcache_cache_bypass (one->regmap, false);/* Update LCR register */ sc16is7xx_port_write (port,SC16IS7XX_LCR_REG , lcr);
@@ -1164,7 +1153,6 @@ static int sc16is7xx_config_rs485(structstatic int sc16is7xx_startup (struct uart_port *port) {struct sc16is7xx_one *one =to_sc16is7xx_one (port, port); -struct sc16is7xx_port *s =dev_get_drvdata (port->dev);unsigned int val;unsigned long flags;
@@ -1181,7 +1169,7 @@ static int sc16is7xx_startup(struct uartsc16is7xx_port_write (port,SC16IS7XX_LCR_REG ,SC16IS7XX_LCR_CONF_MODE_B ); -regcache_cache_bypass (s->regmap, true); +regcache_cache_bypass (one->regmap, true);/* Enable write access to enhanced features and internal clock div */ sc16is7xx_port_update(port, SC16IS7XX_EFR_REG,
@@ -1199,7 +1187,7 @@ static int sc16is7xx_startup(struct uartSC16IS7XX_TCR_RX_RESUME (24 ) | SC16IS7XX_TCR_RX_HALT(48)); -regcache_cache_bypass (s->regmap, false); +regcache_cache_bypass (one->regmap, false);/* Now, initialize the UART */ sc16is7xx_port_write (port,SC16IS7XX_LCR_REG ,SC16IS7XX_LCR_WORD_LEN_8 );
@@ -1457,7 +1445,7 @@ static int sc16is7xx_setup_mctrl_ports(sif (s->mctrl_mask)regmap_update_bits ( s->regmap, -SC16IS7XX_IOCONTROL_REG <<SC16IS7XX_REG_SHIFT , +SC16IS7XX_IOCONTROL_REG ,SC16IS7XX_IOCONTROL_MODEM_A_BIT |SC16IS7XX_IOCONTROL_MODEM_B_BIT , s->mctrl_mask);
@@ -1472,7 +1460,7 @@ static const struct serial_rs485 sc16is7static int sc16is7xx_probe (struct device *dev,const struct sc16is7xx_devtype *devtype, -struct regmap *regmap,int irq) +struct regmap *regmaps[],int irq) {unsigned long freq =0 , *pfreq =dev_get_platdata (dev);unsigned int val;
@@ -1480,16 +1468,16 @@ static int sc16is7xx_probe(struct deviceint i, ret;struct sc16is7xx_port *s; -if (IS_ERR (regmap)) -return PTR_ERR (regmap); +for (i =0 ; i < devtype->nr_uart; i++) +if (IS_ERR (regmaps[i])) +return PTR_ERR (regmaps[i]);/* * This device does not have an identification register that would * tell us if we are really connected to the correct device. * The best we can do is to check if communication is at all possible. */ - ret =regmap_read (regmap, -SC16IS7XX_LSR_REG <<SC16IS7XX_REG_SHIFT , &val); + ret =regmap_read (regmaps[0 ],SC16IS7XX_LSR_REG , &val);if (ret <0 )return -EPROBE_DEFER ;
@@ -1523,7 +1511,7 @@ static int sc16is7xx_probe(struct devicereturn -EINVAL ; } - s->regmap = regmap; + s->regmap = regmaps[0 ]; s->devtype = devtype;dev_set_drvdata (dev, s);mutex_init (&s->efr_lock);
@@ -1538,8 +1526,8 @@ static int sc16is7xx_probe(struct devicesched_set_fifo (s->kworker_task);/* reset device, purging any pending irq / data */ -regmap_write (s->regmap,SC16IS7XX_IOCONTROL_REG <<SC16IS7XX_REG_SHIFT , -SC16IS7XX_IOCONTROL_SRESET_BIT ); +regmap_write (s->regmap,SC16IS7XX_IOCONTROL_REG , +SC16IS7XX_IOCONTROL_SRESET_BIT );for (i =0 ; i < devtype->nr_uart; ++i) { s->p[i].line = i;
@@ -1563,6 +1551,7 @@ static int sc16is7xx_probe(struct device s->p[i].port.ops = &sc16is7xx_ops; s->p[i].old_mctrl =0 ; s->p[i].port.line =sc16is7xx_alloc_line (); + s->p[i].regmap = regmaps[i];if (s->p[i].port.line >=SC16IS7XX_MAX_DEVS ) { ret = -ENOMEM ;
@@ -1591,13 +1580,13 @@ static int sc16is7xx_probe(struct devicesc16is7xx_port_write (&s->p[i].port,SC16IS7XX_LCR_REG ,SC16IS7XX_LCR_CONF_MODE_B ); -regcache_cache_bypass (s->regmap, true); +regcache_cache_bypass (regmaps[i], true);/* Enable write access to enhanced features */ sc16is7xx_port_write (&s->p[i].port,SC16IS7XX_EFR_REG ,SC16IS7XX_EFR_ENABLE_BIT ); -regcache_cache_bypass (s->regmap, false); +regcache_cache_bypass (regmaps[i], false);/* Restore access to general registers */ sc16is7xx_port_write (&s->p[i].port,SC16IS7XX_LCR_REG ,0x00 );
@@ -1700,19 +1689,36 @@ static const struct of_device_id __maybeMODULE_DEVICE_TABLE (of, sc16is7xx_dt_ids);static struct regmap_config regcfg = { - .reg_bits =7 , - .pad_bits =1 , + .reg_bits =5 , + .pad_bits =3 , .val_bits =8 , .cache_type =REGCACHE_RBTREE , .volatile_reg = sc16is7xx_regmap_volatile, .precious_reg = sc16is7xx_regmap_precious, + .max_register =SC16IS7XX_EFCR_REG , }; +static const char *sc16is7xx_regmap_name (unsigned int port_id) +{ +static char buf[6 ]; + +snprintf (buf,sizeof (buf),"port%d" , port_id); + +return buf; +} + +static unsigned int sc16is7xx_regmap_port_mask (unsigned int port_id) +{ +/* CH1,CH0 are at bits 2:1. */ +return port_id <<1 ; +} +#ifdef CONFIG_SERIAL_SC16IS7XX_SPI static int sc16is7xx_spi_probe (struct spi_device *spi) {const struct sc16is7xx_devtype *devtype; -struct regmap *regmap; +struct regmap *regmaps[2 ]; +unsigned int i;int ret;/* Setup SPI bus */
@@ -1737,11 +1743,20 @@ static int sc16is7xx_spi_probe(struct sp devtype = (struct sc16is7xx_devtype *)id_entry->driver_data; } - regcfg.max_register = (0xf <<SC16IS7XX_REG_SHIFT ) | - (devtype->nr_uart -1 ); - regmap =devm_regmap_init_spi (spi, ®cfg); +for (i =0 ; i < devtype->nr_uart; i++) { + regcfg.name =sc16is7xx_regmap_name (i); +/* +* If read_flag_mask is 0, the regmap code sets it to a default +* of 0x80. Since we specify our own mask, we must add the READ +* bit ourselves: +*/ + regcfg.read_flag_mask =sc16is7xx_regmap_port_mask (i) | +SC16IS7XX_SPI_READ_BIT ; + regcfg.write_flag_mask =sc16is7xx_regmap_port_mask (i); + regmaps[i] =devm_regmap_init_spi (spi, ®cfg); + } -return sc16is7xx_probe (&spi->dev, devtype, regmap, spi->irq); +return sc16is7xx_probe (&spi->dev, devtype, regmaps, spi->irq); }static void sc16is7xx_spi_remove (struct spi_device *spi)
@@ -1780,7 +1795,8 @@ static int sc16is7xx_i2c_probe(struct i2 const struct i2c_device_id *id) {const struct sc16is7xx_devtype *devtype; -struct regmap *regmap; +struct regmap *regmaps[2 ]; +unsigned int i;if (i2c->dev.of_node) { devtype =device_get_match_data (&i2c->dev);
@@ -1790,11 +1806,14 @@ static int sc16is7xx_i2c_probe(struct i2 devtype = (struct sc16is7xx_devtype *)id->driver_data; } - regcfg.max_register = (0xf <<SC16IS7XX_REG_SHIFT ) | - (devtype->nr_uart -1 ); - regmap =devm_regmap_init_i2c (i2c, ®cfg); +for (i =0 ; i < devtype->nr_uart; i++) { + regcfg.name =sc16is7xx_regmap_name (i); + regcfg.read_flag_mask =sc16is7xx_regmap_port_mask (i); + regcfg.write_flag_mask =sc16is7xx_regmap_port_mask (i); + regmaps[i] =devm_regmap_init_i2c (i2c, ®cfg); + } -return sc16is7xx_probe (&i2c->dev, devtype, regmap, i2c->irq); +return sc16is7xx_probe (&i2c->dev, devtype, regmaps, i2c->irq); }static void sc16is7xx_i2c_remove (struct i2c_client *client)
Greg Kroah-Hartman
maintainerPATCH 59/185 serial: sc16is7xx: remove wasteful static buffer in sc16is7xx_regmap_name()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hugo Villeneuve <[email protected]>
commit 6bcab3c8acc88e265c570dea969fd04f137c8a4c upstream.
Using a static buffer inside sc16is7xx_regmap_name() was a convenient and simple way to set the regmap name without having to allocate and free a buffer each time it is called. The drawback is that the static buffer wastes memory for nothing once regmap is fully initialized.
Remove static buffer and use constant strings instead.
This also avoids a truncation warning when using "%d" or "%u" in snprintf which was flagged by kernel test robot.
--- drivers/tty/serial/sc16is7xx.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
drivers/tty/serial/sc16is7xx.c +8 -6
@@ -1698,13 +1698,15 @@ static struct regmap_config regcfg = { .max_register = SC16IS7XX_EFCR_REG, }; -static const char *sc16is7xx_regmap_name (unsigned int port_id) +static const char *sc16is7xx_regmap_name (u8 port_id) { -static char buf[6 ]; - -snprintf (buf,sizeof (buf),"port%d" , port_id); - -return buf; +switch (port_id) { +case 0 :return "port0" ; +case 1 :return "port1" ; +default : +WARN_ON (true); +return NULL ; + } }static unsigned int sc16is7xx_regmap_port_mask (unsigned int port_id)
Greg Kroah-Hartman
maintainerPATCH 60/185 serial: sc16is7xx: remove global regmap from struct sc16is7xx_port
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hugo Villeneuve <[email protected]>
commit f6959c5217bd799bcb770b95d3c09b3244e175c6 upstream.
Remove global struct regmap so that it is more obvious that this regmap is to be used only in the probe function.
Also add a comment to that effect in probe function.
--- drivers/tty/serial/sc16is7xx.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
drivers/tty/serial/sc16is7xx.c +9 -6
@@ -335,7 +335,6 @@ struct sc16is7xx_one {struct sc16is7xx_port {const struct sc16is7xx_devtype *devtype; -struct regmap *regmap;struct clk *clk;#ifdef CONFIG_GPIOLIB struct gpio_chip gpio;
@@ -1415,7 +1414,8 @@ static int sc16is7xx_setup_gpio_chip(str/* * Configure ports designated to operate as modem control lines. */ -static int sc16is7xx_setup_mctrl_ports (struct sc16is7xx_port *s) +static int sc16is7xx_setup_mctrl_ports (struct sc16is7xx_port *s, +struct regmap *regmap) {int i;int ret;
@@ -1444,7 +1444,7 @@ static int sc16is7xx_setup_mctrl_ports(sif (s->mctrl_mask)regmap_update_bits ( - s->regmap, + regmap,SC16IS7XX_IOCONTROL_REG ,SC16IS7XX_IOCONTROL_MODEM_A_BIT |SC16IS7XX_IOCONTROL_MODEM_B_BIT , s->mctrl_mask);
@@ -1476,6 +1476,10 @@ static int sc16is7xx_probe(struct device* This device does not have an identification register that would * tell us if we are really connected to the correct device. * The best we can do is to check if communication is at all possible. +* +* Note: regmap[0] is used in the probe function to access registers +* common to all channels/ports, as it is guaranteed to be present on +* all variants. */ ret =regmap_read (regmaps[0 ],SC16IS7XX_LSR_REG , &val);if (ret <0 )
@@ -1511,7 +1515,6 @@ static int sc16is7xx_probe(struct devicereturn -EINVAL ; } - s->regmap = regmaps[0 ]; s->devtype = devtype;dev_set_drvdata (dev, s);mutex_init (&s->efr_lock);
@@ -1526,7 +1529,7 @@ static int sc16is7xx_probe(struct devicesched_set_fifo (s->kworker_task);/* reset device, purging any pending irq / data */ -regmap_write (s->regmap,SC16IS7XX_IOCONTROL_REG , +regmap_write (regmaps[0 ],SC16IS7XX_IOCONTROL_REG ,SC16IS7XX_IOCONTROL_SRESET_BIT );for (i =0 ; i < devtype->nr_uart; ++i) {
@@ -1606,7 +1609,7 @@ static int sc16is7xx_probe(struct device s->p[u].irda_mode = true; } - ret =sc16is7xx_setup_mctrl_ports (s); + ret =sc16is7xx_setup_mctrl_ports (s, regmaps[0 ]);if (ret) goto out_ports;
Greg Kroah-Hartman
maintainerPATCH 61/185 serial: sc16is7xx: remove unused line structure member
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hugo Villeneuve <[email protected]>
commit 41a308cbedb2a68a6831f0f2e992e296c4b8aff0 upstream.
Now that the driver has been converted to use one regmap per port, the line structure member is no longer used, so remove it.
--- drivers/tty/serial/sc16is7xx.c | 2 -- 1 file changed, 2 deletions(-)
drivers/tty/serial/sc16is7xx.c +0 -2
@@ -323,7 +323,6 @@ struct sc16is7xx_one_config {struct sc16is7xx_one {struct uart_port port; -u8 line;struct regmap *regmap;struct kthread_work tx_work;struct kthread_work reg_work;
@@ -1533,7 +1532,6 @@ static int sc16is7xx_probe(struct device SC16IS7XX_IOCONTROL_SRESET_BIT);for (i =0 ; i < devtype->nr_uart; ++i) { - s->p[i].line = i;/* Initialize port data */ s->p[i].port.dev = dev; s->p[i].port.irq = irq;
Greg Kroah-Hartman
maintainerPATCH 62/185 serial: sc16is7xx: change EFR lock to operate on each channels
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hugo Villeneuve <[email protected]>
commit 4409df5866b7ff7686ba27e449ca97a92ee063c9 upstream.
Now that the driver has been converted to use one regmap per port, change efr locking to operate on a channel basis instead of on the whole IC.
--- drivers/tty/serial/sc16is7xx.c | 49 +++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 23 deletions(-)
drivers/tty/serial/sc16is7xx.c +26 -23
@@ -324,6 +324,7 @@ struct sc16is7xx_one_config {struct sc16is7xx_one {struct uart_port port;struct regmap *regmap; +struct mutex efr_lock;/* EFR registers access */ struct kthread_work tx_work;struct kthread_work reg_work;struct kthread_delayed_work ms_work;
@@ -343,7 +344,6 @@ struct sc16is7xx_port {unsigned char buf[SC16IS7XX_FIFO_SIZE ];struct kthread_worker kworker;struct task_struct *kworker_task; -struct mutex efr_lock;struct sc16is7xx_one p[]; };
@@ -496,7 +496,6 @@ static bool sc16is7xx_regmap_precious(ststatic int sc16is7xx_set_baud (struct uart_port *port,int baud) { -struct sc16is7xx_port *s =dev_get_drvdata (port->dev);struct sc16is7xx_one *one =to_sc16is7xx_one (port, port);u8 lcr;u8 prescaler =0 ;
@@ -520,7 +519,7 @@ static int sc16is7xx_set_baud(struct uar* because the bulk of the interrupt processing is run as a workqueue * job in thread context. */ -mutex_lock (&s->efr_lock); +mutex_lock (&one->efr_lock); lcr =sc16is7xx_port_read (port,SC16IS7XX_LCR_REG );
@@ -539,7 +538,7 @@ static int sc16is7xx_set_baud(struct uar/* Put LCR back to the normal mode */ sc16is7xx_port_write (port,SC16IS7XX_LCR_REG , lcr); -mutex_unlock (&s->efr_lock); +mutex_unlock (&one->efr_lock); sc16is7xx_port_update(port, SC16IS7XX_MCR_REG, SC16IS7XX_MCR_CLKSEL_BIT,
@@ -709,11 +708,10 @@ static unsigned int sc16is7xx_get_hwmctrstatic void sc16is7xx_update_mlines (struct sc16is7xx_one *one) {struct uart_port *port = &one->port; -struct sc16is7xx_port *s =dev_get_drvdata (port->dev);unsigned long flags;unsigned int status, changed; -lockdep_assert_held_once (&s->efr_lock); +lockdep_assert_held_once (&one->efr_lock); status =sc16is7xx_get_hwmctrl (port); changed = status ^ one->old_mctrl;
@@ -739,15 +737,20 @@ static void sc16is7xx_update_mlines(strustatic bool sc16is7xx_port_irq (struct sc16is7xx_port *s,int portno) { +bool rc = true;struct uart_port *port = &s->p[portno].port; +struct sc16is7xx_one *one =to_sc16is7xx_one (port, port); + +mutex_lock (&one->efr_lock); do { unsigned int iir, rxlen; - struct sc16is7xx_one *one = to_sc16is7xx_one(port, port); iir = sc16is7xx_port_read(port, SC16IS7XX_IIR_REG); - if (iir & SC16IS7XX_IIR_NO_INT_BIT) - return false; + if (iir & SC16IS7XX_IIR_NO_INT_BIT) { + rc = false; + goto out_port_irq; + } iir &= SC16IS7XX_IIR_ID_MASK;
@@ -787,15 +790,17 @@ static bool sc16is7xx_port_irq(struct scbreak ; } }while (0 ); -return true; + +out_port_irq: +mutex_unlock (&one->efr_lock); + +return rc; }static irqreturn_t sc16is7xx_irq (int irq,void *dev_id) {struct sc16is7xx_port *s = (struct sc16is7xx_port *)dev_id; -mutex_lock (&s->efr_lock); -while (1 ) {bool keep_polling = false;int i;
@@ -806,24 +811,22 @@ static irqreturn_t sc16is7xx_irq(int irqbreak ; } -mutex_unlock (&s->efr_lock); -return IRQ_HANDLED ; }static void sc16is7xx_tx_proc (struct kthread_work *ws) {struct uart_port *port = &(to_sc16is7xx_one (ws, tx_work)->port); -struct sc16is7xx_port *s =dev_get_drvdata (port->dev); +struct sc16is7xx_one *one =to_sc16is7xx_one (port, port);unsigned long flags;if ((port->rs485.flags &SER_RS485_ENABLED ) && (port->rs485.delay_rts_before_send >0 ))msleep (port->rs485.delay_rts_before_send); -mutex_lock (&s->efr_lock); +mutex_lock (&one->efr_lock);sc16is7xx_handle_tx (port); -mutex_unlock (&s->efr_lock); +mutex_unlock (&one->efr_lock);spin_lock_irqsave (&port->lock, flags);sc16is7xx_ier_set (port,SC16IS7XX_IER_THRI_BIT );
@@ -930,9 +933,9 @@ static void sc16is7xx_ms_proc(struct kthstruct sc16is7xx_port *s =dev_get_drvdata (one->port.dev);if (one->port.state) { -mutex_lock (&s->efr_lock); +mutex_lock (&one->efr_lock);sc16is7xx_update_mlines (one); -mutex_unlock (&s->efr_lock); +mutex_unlock (&one->efr_lock);kthread_queue_delayed_work (&s->kworker, &one->ms_work,HZ ); }
@@ -1016,7 +1019,6 @@ static void sc16is7xx_set_termios(structstruct ktermios *termios, const struct ktermios *old) { - struct sc16is7xx_port *s = dev_get_drvdata(port->dev); struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);unsigned int lcr, flow =0 ;int baud;
@@ -1075,7 +1077,7 @@ static void sc16is7xx_set_termios(struct port->ignore_status_mask |=SC16IS7XX_LSR_BRK_ERROR_MASK ;/* As above, claim the mutex while accessing the EFR. */ -mutex_lock (&s->efr_lock); +mutex_lock (&one->efr_lock);sc16is7xx_port_write (port,SC16IS7XX_LCR_REG ,SC16IS7XX_LCR_CONF_MODE_B );
@@ -1105,7 +1107,7 @@ static void sc16is7xx_set_termios(struct/* Update LCR register */ sc16is7xx_port_write (port,SC16IS7XX_LCR_REG , lcr); -mutex_unlock (&s->efr_lock); +mutex_unlock (&one->efr_lock);/* Get baud rate generator configuration */ baud = uart_get_baud_rate(port, termios, old,
@@ -1516,7 +1518,6 @@ static int sc16is7xx_probe(struct device s->devtype = devtype;dev_set_drvdata (dev, s); -mutex_init (&s->efr_lock);kthread_init_worker (&s->kworker); s->kworker_task = kthread_run(kthread_worker_fn, &s->kworker,
@@ -1559,6 +1560,8 @@ static int sc16is7xx_probe(struct device goto out_ports; } +mutex_init (&s->p[i].efr_lock); + ret =uart_get_rs485_mode (&s->p[i].port);if (ret) goto out_ports;
Greg Kroah-Hartman
maintainerPATCH 63/185 serial: sc16is7xx: convert from _raw_ to _noinc_ regmap functions for FIFO
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hugo Villeneuve <[email protected]>
commit dbf4ab821804df071c8b566d9813083125e6d97b upstream.
The SC16IS7XX IC supports a burst mode to access the FIFOs where the initial register address is sent ($00), followed by all the FIFO data without having to resend the register address each time. In this mode, the IC doesn't increment the register address for each R/W byte.
The regmap_raw_read() and regmap_raw_write() are functions which can perform IO over multiple registers. They are currently used to read/write from/to the FIFO, and although they operate correctly in this burst mode on the SPI bus, they would corrupt the regmap cache if it was not disabled manually. The reason is that when the R/W size is more than 1 byte, these functions assume that the register address is incremented and handle the cache accordingly.
Convert FIFO R/W functions to use the regmap _noinc_ versions in order to remove the manual cache control which was a workaround when using the _raw_ versions. FIFO registers are properly declared as volatile so cache will not be used/updated for FIFO accesses.
--- drivers/tty/serial/sc16is7xx.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-)
drivers/tty/serial/sc16is7xx.c +11 -6
@@ -383,9 +383,7 @@ static void sc16is7xx_fifo_read(struct ustruct sc16is7xx_port *s =dev_get_drvdata (port->dev);struct sc16is7xx_one *one =to_sc16is7xx_one (port, port); -regcache_cache_bypass (one->regmap, true); -regmap_raw_read (one->regmap,SC16IS7XX_RHR_REG , s->buf, rxlen); -regcache_cache_bypass (one->regmap, false); +regmap_noinc_read (one->regmap,SC16IS7XX_RHR_REG , s->buf, rxlen); }static void sc16is7xx_fifo_write (struct uart_port *port,u8 to_send)
@@ -400,9 +398,7 @@ static void sc16is7xx_fifo_write(structif (unlikely (!to_send))return ; -regcache_cache_bypass (one->regmap, true); -regmap_raw_write (one->regmap,SC16IS7XX_THR_REG , s->buf, to_send); -regcache_cache_bypass (one->regmap, false); +regmap_noinc_write (one->regmap,SC16IS7XX_THR_REG , s->buf, to_send); } static void sc16is7xx_port_update(struct uart_port *port, u8 reg,
@@ -494,6 +490,11 @@ static bool sc16is7xx_regmap_precious(streturn false; } +static bool sc16is7xx_regmap_noinc (struct device *dev,unsigned int reg) +{ +return reg ==SC16IS7XX_RHR_REG ; +} +static int sc16is7xx_set_baud (struct uart_port *port,int baud) {struct sc16is7xx_one *one =to_sc16is7xx_one (port, port);
@@ -1699,6 +1700,10 @@ static struct regmap_config regcfg = { .cache_type = REGCACHE_RBTREE, .volatile_reg = sc16is7xx_regmap_volatile, .precious_reg = sc16is7xx_regmap_precious, + .writeable_noinc_reg = sc16is7xx_regmap_noinc, + .readable_noinc_reg = sc16is7xx_regmap_noinc, + .max_raw_read = SC16IS7XX_FIFO_SIZE, + .max_raw_write = SC16IS7XX_FIFO_SIZE, .max_register = SC16IS7XX_EFCR_REG, };
Greg Kroah-Hartman
maintainerPATCH 64/185 serial: sc16is7xx: fix invalid sc16is7xx_lines bitfield in case of probe error
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hugo Villeneuve <[email protected]>
commit 8a1060ce974919f2a79807527ad82ac39336eda2 upstream.
If an error occurs during probing, the sc16is7xx_lines bitfield may be left in a state that doesn't represent the correct state of lines allocation.
For example, in a system with two SC16 devices, if an error occurs only during probing of channel (port) B of the second device, sc16is7xx_lines final state will be 00001011b instead of the expected 00000011b.
This is caused in part because of the "i--" in the for/loop located in the out_ports: error path.
Fix this by checking the return value of uart_add_one_port() and set line allocation bit only if this was successful. This allows the refactor of the obfuscated for(i--...) loop in the error path, and properly call uart_remove_one_port() only when needed, and properly unset line allocation bits.
Also use same mechanism in remove() when calling uart_remove_one_port().
--- drivers/tty/serial/sc16is7xx.c | 44 ++++++++++++++++------------------------- 1 file changed, 18 insertions(+), 26 deletions(-)
drivers/tty/serial/sc16is7xx.c +18 -26
@@ -409,19 +409,6 @@ static void sc16is7xx_port_update(structregmap_update_bits (one->regmap, reg, mask, val); } -static int sc16is7xx_alloc_line (void ) -{ -int i; - -BUILD_BUG_ON (SC16IS7XX_MAX_DEVS >BITS_PER_LONG ); - -for (i =0 ; i <SC16IS7XX_MAX_DEVS ; i++) -if (!test_and_set_bit (i, &sc16is7xx_lines)) -break ; - -return i; -} -static void sc16is7xx_power (struct uart_port *port,int on) { sc16is7xx_port_update(port, SC16IS7XX_IER_REG,
@@ -1534,6 +1521,13 @@ static int sc16is7xx_probe(struct device SC16IS7XX_IOCONTROL_SRESET_BIT);for (i =0 ; i < devtype->nr_uart; ++i) { + s->p[i].port.line =find_first_zero_bit (&sc16is7xx_lines, +SC16IS7XX_MAX_DEVS ); +if (s->p[i].port.line >=SC16IS7XX_MAX_DEVS ) { + ret = -ERANGE ; + goto out_ports; + } +/* Initialize port data */ s->p[i].port.dev = dev; s->p[i].port.irq = irq;
@@ -1553,14 +1547,8 @@ static int sc16is7xx_probe(struct device s->p[i].port.rs485_supported = sc16is7xx_rs485_supported; s->p[i].port.ops = &sc16is7xx_ops; s->p[i].old_mctrl =0 ; - s->p[i].port.line =sc16is7xx_alloc_line (); s->p[i].regmap = regmaps[i]; -if (s->p[i].port.line >=SC16IS7XX_MAX_DEVS ) { - ret = -ENOMEM ; - goto out_ports; - } -mutex_init (&s->p[i].efr_lock); ret =uart_get_rs485_mode (&s->p[i].port);
@@ -1578,8 +1566,13 @@ static int sc16is7xx_probe(struct devicekthread_init_work (&s->p[i].tx_work, sc16is7xx_tx_proc);kthread_init_work (&s->p[i].reg_work, sc16is7xx_reg_proc);kthread_init_delayed_work (&s->p[i].ms_work, sc16is7xx_ms_proc); +/* Register port */ -uart_add_one_port (&sc16is7xx_uart, &s->p[i].port); + ret =uart_add_one_port (&sc16is7xx_uart, &s->p[i].port); +if (ret) + goto out_ports; + +set_bit (s->p[i].port.line, &sc16is7xx_lines);/* Enable EFR */ sc16is7xx_port_write(&s->p[i].port, SC16IS7XX_LCR_REG,
@@ -1646,10 +1639,9 @@ static int sc16is7xx_probe(struct device#endif out_ports: -for (i--; i >=0 ; i--) { -uart_remove_one_port (&sc16is7xx_uart, &s->p[i].port); -clear_bit (s->p[i].port.line, &sc16is7xx_lines); - } +for (i =0 ; i < devtype->nr_uart; i++) +if (test_and_clear_bit (s->p[i].port.line, &sc16is7xx_lines)) +uart_remove_one_port (&sc16is7xx_uart, &s->p[i].port);kthread_stop (s->kworker_task);
@@ -1671,8 +1663,8 @@ static void sc16is7xx_remove(struct devifor (i =0 ; i < s->devtype->nr_uart; i++) {kthread_cancel_delayed_work_sync (&s->p[i].ms_work); -uart_remove_one_port (&sc16is7xx_uart, &s->p[i].port); -clear_bit (s->p[i].port.line, &sc16is7xx_lines); +if (test_and_clear_bit (s->p[i].port.line, &sc16is7xx_lines)) +uart_remove_one_port (&sc16is7xx_uart, &s->p[i].port);sc16is7xx_power (&s->p[i].port,0 ); }
Greg Kroah-Hartman
maintainerPATCH 65/185 serial: sc16is7xx: remove obsolete loop in sc16is7xx_port_irq()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hugo Villeneuve <[email protected]>
commit ed647256e8f226241ecff7baaecdb8632ffc7ec1 upstream.
Commit 834449872105 ("sc16is7xx: Fix for multi-channel stall") changed sc16is7xx_port_irq() from looping multiple times when there was still interrupts to serve. It simply changed the do {} while(1) loop to a do {} while(0) loop, which makes the loop itself now obsolete.
Clean the code by removing this obsolete do {} while(0) loop.
--- drivers/tty/serial/sc16is7xx.c | 89 +++++++++++++++++++---------------------- 1 file changed, 43 insertions(+), 46 deletions(-)
drivers/tty/serial/sc16is7xx.c +43 -46
@@ -726,58 +726,55 @@ static void sc16is7xx_update_mlines(strustatic bool sc16is7xx_port_irq (struct sc16is7xx_port *s,int portno) {bool rc = true; +unsigned int iir, rxlen;struct uart_port *port = &s->p[portno].port;struct sc16is7xx_one *one =to_sc16is7xx_one (port, port);mutex_lock (&one->efr_lock); -do { -unsigned int iir, rxlen; - - iir =sc16is7xx_port_read (port,SC16IS7XX_IIR_REG ); -if (iir &SC16IS7XX_IIR_NO_INT_BIT ) { - rc = false; - goto out_port_irq; - } - - iir &=SC16IS7XX_IIR_ID_MASK ; - -switch (iir) { -case SC16IS7XX_IIR_RDI_SRC : -case SC16IS7XX_IIR_RLSE_SRC : -case SC16IS7XX_IIR_RTOI_SRC : -case SC16IS7XX_IIR_XOFFI_SRC : - rxlen =sc16is7xx_port_read (port,SC16IS7XX_RXLVL_REG ); - -/* -* There is a silicon bug that makes the chip report a -* time-out interrupt but no data in the FIFO. This is -* described in errata section 18.1.4. -* -* When this happens, read one byte from the FIFO to -* clear the interrupt. -*/ -if (iir ==SC16IS7XX_IIR_RTOI_SRC && !rxlen) - rxlen =1 ; - -if (rxlen) -sc16is7xx_handle_rx (port, rxlen, iir); -break ; + iir =sc16is7xx_port_read (port,SC16IS7XX_IIR_REG ); +if (iir &SC16IS7XX_IIR_NO_INT_BIT ) { + rc = false; + goto out_port_irq; + } + + iir &=SC16IS7XX_IIR_ID_MASK ; + +switch (iir) { +case SC16IS7XX_IIR_RDI_SRC : +case SC16IS7XX_IIR_RLSE_SRC : +case SC16IS7XX_IIR_RTOI_SRC : +case SC16IS7XX_IIR_XOFFI_SRC : + rxlen =sc16is7xx_port_read (port,SC16IS7XX_RXLVL_REG ); + +/* +* There is a silicon bug that makes the chip report a +* time-out interrupt but no data in the FIFO. This is +* described in errata section 18.1.4. +* +* When this happens, read one byte from the FIFO to +* clear the interrupt. +*/ +if (iir ==SC16IS7XX_IIR_RTOI_SRC && !rxlen) + rxlen =1 ; + +if (rxlen) +sc16is7xx_handle_rx (port, rxlen, iir); +break ;/* CTSRTS interrupt comes only when CTS goes inactive */ -case SC16IS7XX_IIR_CTSRTS_SRC : -case SC16IS7XX_IIR_MSI_SRC : -sc16is7xx_update_mlines (one); -break ; -case SC16IS7XX_IIR_THRI_SRC : -sc16is7xx_handle_tx (port); -break ; -default : -dev_err_ratelimited (port->dev, -"ttySC%i: Unexpected interrupt: %x" , - port->line, iir); -break ; - } - }while (0 ); +case SC16IS7XX_IIR_CTSRTS_SRC : +case SC16IS7XX_IIR_MSI_SRC : +sc16is7xx_update_mlines (one); +break ; +case SC16IS7XX_IIR_THRI_SRC : +sc16is7xx_handle_tx (port); +break ; +default : +dev_err_ratelimited (port->dev, +"ttySC%i: Unexpected interrupt: %x" , + port->line, iir); +break ; + } out_port_irq:mutex_unlock (&one->efr_lock);
Greg Kroah-Hartman
maintainerPATCH 66/185 serial: sc16is7xx: improve do/while loop in sc16is7xx_irq()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hugo Villeneuve <[email protected]>
commit d5078509c8b06c5c472a60232815e41af81c6446 upstream.
Simplify and improve readability by replacing while(1) loop with do {} while, and by using the keep_polling variable as the exit condition, making it more explicit.
--- drivers/tty/serial/sc16is7xx.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
drivers/tty/serial/sc16is7xx.c +6 -5
@@ -784,17 +784,18 @@ out_port_irq:static irqreturn_t sc16is7xx_irq (int irq,void *dev_id) { +bool keep_polling; +struct sc16is7xx_port *s = (struct sc16is7xx_port *)dev_id; -while (1 ) { -bool keep_polling = false; +do {int i; + keep_polling = false; +for (i =0 ; i < s->devtype->nr_uart; ++i) keep_polling |=sc16is7xx_port_irq (s, i); -if (!keep_polling) -break ; - } + }while (keep_polling);return IRQ_HANDLED ; }
Greg Kroah-Hartman
maintainerPATCH 67/185 LoongArch/smp: Call rcutree_report_cpu_starting() earlier
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Huacai Chen <[email protected]>
commit a2ccf46333d7b2cf9658f0d82ac74097c1542fae upstream.
rcutree_report_cpu_starting() must be called before cpu_probe() to avoid the following lockdep splat that triggered by calling __alloc_pages() when CONFIG_PROVE_RCU_LIST=y:
=============================
WARNING: suspicious RCU usage
6.6.0+ #980 Not tainted
-----------------------------
kernel/locking/lockdep.c:3761 RCU-list traversed in non-reader section!! other info that might help us debug this:
RCU used illegally from offline CPU!
rcu_scheduler_active = 1, debug_locks = 1
1 lock held by swapper/1/0:
#0: 900000000c82ef98 (&pcp->lock){+.+.}-{2:2}, at: get_page_from_freelist+0x894/0x1790
CPU: 1 PID: 0 Comm: swapper/1 Not tainted 6.6.0+ #980
Stack : 0000000000000001 9000000004f79508 9000000004893670 9000000100310000
90000001003137d0 0000000000000000 90000001003137d8 9000000004f79508
0000000000000000 0000000000000001 0000000000000000 90000000048a3384
203a656d616e2065 ca43677b3687e616 90000001002c3480 0000000000000008
000000000000009d 0000000000000000 0000000000000001 80000000ffffe0b8
000000000000000d 0000000000000033 0000000007ec0000 13bbf50562dad831
9000000005140748 0000000000000000 9000000004f79508 0000000000000004
0000000000000000 9000000005140748 90000001002bad40 0000000000000000
90000001002ba400 0000000000000000 9000000003573ec8 0000000000000000
00000000000000b0 0000000000000004 0000000000000000 0000000000070000
...
Call Trace:
[<9000000003573ec8>] show_stack+0x38/0x150
[<9000000004893670>] dump_stack_lvl+0x74/0xa8
[<900000000360d2bc>] lockdep_rcu_suspicious+0x14c/0x190
[<900000000361235c>] __lock_acquire+0xd0c/0x2740
[<90000000036146f4>] lock_acquire+0x104/0x2c0
[<90000000048a955c>] _raw_spin_lock_irqsave+0x5c/0x90
[<900000000381cd5c>] rmqueue_bulk+0x6c/0x950
[<900000000381fc0c>] get_page_from_freelist+0xd4c/0x1790
[<9000000003821c6c>] __alloc_pages+0x1bc/0x3e0
[<9000000003583b40>] tlb_init+0x150/0x2a0
[<90000000035742a0>] per_cpu_trap_init+0xf0/0x110
[<90000000035712fc>] cpu_probe+0x3dc/0x7a0
[<900000000357ed20>] start_secondary+0x40/0xb0
[<9000000004897138>] smpboot_entry+0x54/0x58raw_smp_processor_id() is required in order to avoid calling into lockdep before RCU has declared the CPU to be watched for readers.
See also commit 29368e093921 ("x86/smpboot: Move rcu_cpu_starting() earlier"), commit de5d9dae150c ("s390/smp: move rcu_cpu_starting() earlier") and commit 99f070b62322 ("powerpc/smp: Call rcu_cpu_starting() earlier").
--- arch/loongarch/kernel/smp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/loongarch/kernel/smp.c +2 -1
@@ -471,8 +471,9 @@ asmlinkage void start_secondary(void)unsigned int cpu;sync_counter (); - cpu =smp_processor_id (); + cpu =raw_smp_processor_id ();set_my_cpu_offset (per_cpu_offset (cpu)); +rcu_cpu_starting (cpu);cpu_probe ();constant_clockevent_init ();
Greg Kroah-Hartman
maintainerPATCH 68/185 mm: page_alloc: unreserve highatomic page blocks before oom
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Charan Teja Kalla <[email protected]>
commit ac3f3b0a55518056bc80ed32a41931c99e1f7d81 upstream.
__alloc_pages_direct_reclaim() is called from slowpath allocation where high atomic reserves can be unreserved after there is a progress in reclaim and yet no suitable page is found. Later should_reclaim_retry() gets called from slow path allocation to decide if the reclaim needs to be retried before OOM kill path is taken.
should_reclaim_retry() checks the available(reclaimable + free pages) memory against the min wmark levels of a zone and returns:
a) true, if it is above the min wmark so that slow path allocation will do the reclaim retries.
b) false, thus slowpath allocation takes oom kill path.
should_reclaim_retry() can also unreserves the high atomic reserves **but only after all the reclaim retries are exhausted.**
In a case where there are almost none reclaimable memory and free pages contains mostly the high atomic reserves but allocation context can't use these high atomic reserves, makes the available memory below min wmark levels hence false is returned from should_reclaim_retry() leading the allocation request to take OOM kill path. This can turn into a early oom kill if high atomic reserves are holding lot of free memory and unreserving of them is not attempted.
(early)OOM is encountered on a VM with the below state:
[ 295.998653] Normal free:7728kB boost:0kB min:804kB low:1004kB
high:1204kB reserved_highatomic:8192KB active_anon:4kB inactive_anon:0kB active_file:24kB inactive_file:24kB unevictable:1220kB writepending:0kB present:70732kB managed:49224kB mlocked:0kB bounce:0kB free_pcp:688kB local_pcp:492kB free_cma:0kB
[ 295.998656] lowmem_reserve[]: 0 32 [ 295.998659] Normal: 508*4kB (UMEH) 241*8kB (UMEH) 143*16kB (UMEH)
33*32kB (UH) 7*64kB (UH) 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 7752kB
Per above log, the free memory of ~7MB exist in the high atomic reserves is not freed up before falling back to oom kill path.
Fix it by trying to unreserve the high atomic reserves in should_reclaim_retry() before __alloc_pages_direct_reclaim() can fallback to oom kill path.
--- mm/page_alloc.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
mm/page_alloc.c +8 -8
@@ -4921,14 +4921,9 @@ should_reclaim_retry(gfp_t gfp_mask, unselse (*no_progress_loops)++; -/* -* Make sure we converge to OOM if we cannot make any progress -* several times in the row. -*/ -if (*no_progress_loops >MAX_RECLAIM_RETRIES ) { -/* Before OOM, exhaust highatomic_reserve */ -return unreserve_highatomic_pageblock (ac, true); - } +if (*no_progress_loops >MAX_RECLAIM_RETRIES ) + goto out; +/* * Keep reclaiming pages while there is a chance this will lead
@@ -4971,6 +4966,11 @@ should_reclaim_retry(gfp_t gfp_mask, unsschedule_timeout_uninterruptible (1 ); elsecond_resched (); +out: +/* Before OOM, exhaust highatomic_reserve */ +if (!ret) +return unreserve_highatomic_pageblock (ac, true); +return ret; }
Greg Kroah-Hartman
maintainerPATCH 69/185 ksmbd: set v2 lease version on lease upgrade
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <[email protected]>
[ Upstream commit bb05367a66a9990d2c561282f5620bb1dbe40c28 ]
If file opened with v2 lease is upgraded with v1 lease, smb server should response v2 lease create context to client.
This patch fix smb2.lease.v2_epoch2 test failure.
This test case assumes the following scenario:
1. smb2 create with v2 lease(R, LEASE1 key)
2. smb server return smb2 create response with v2 lease context(R,
LEASE1 key, epoch + 1)
3. smb2 create with v1 lease(RH, LEASE1 key)
4. smb server return smb2 create response with v2 lease context(RH,
LEASE1 key, epoch + 2)
i.e. If same client(same lease key) try to open a file that is being opened with v2 lease with v1 lease, smb server should return v2 lease.
--- fs/smb/server/oplock.c | 1 + 1 file changed, 1 insertion(+)
fs/smb/server/oplock.c +1 -0
@@ -1036,6 +1036,7 @@ static void copy_lease(struct oplock_inf lease2->duration = lease1->duration; lease2->flags = lease1->flags; lease2->epoch = lease1->epoch++; + lease2->version = lease1->version; }static int add_lease_global_list (struct oplock_info *opinfo)
Greg Kroah-Hartman
maintainerPATCH 70/185 ksmbd: fix potential circular locking issue in smb2_set_ea()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <[email protected]>
[ Upstream commit 6fc0a265e1b932e5e97a038f99e29400a93baad0 ]
smb2_set_ea() can be called in parent inode lock range. So add get_write argument to smb2_set_ea() not to call nested mnt_want_write().
--- fs/smb/server/smb2pdu.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
fs/smb/server/smb2pdu.c +4 -3
@@ -2321,11 +2321,12 @@ out:* @eabuf: set info command buffer * @buf_len: set info command buffer length * @path: dentry path for get ea +* @get_write: get write access to a mount * * Return: 0 on success, otherwise error */ static int smb2_set_ea (struct smb2_ea_info *eabuf,unsigned int buf_len, -const struct path *path) +const struct path *path,bool get_write) {struct user_namespace *user_ns =mnt_user_ns (path->mnt);char *attr_name =NULL , *value;
@@ -3013,7 +3014,7 @@ int smb2_open(struct ksmbd_work *work) rc =smb2_set_ea (&ea_buf->ea,le32_to_cpu (ea_buf->ccontext.DataLength), - &path); + &path, false);if (rc == -EOPNOTSUPP ) rc =0 ;else if (rc)
@@ -5990,7 +5991,7 @@ static int smb2_set_info_file(struct ksmreturn -EINVAL ;return smb2_set_ea ((struct smb2_ea_info *)req->Buffer, - buf_len, &fp->filp->f_path); + buf_len, &fp->filp->f_path, true); }case FILE_POSITION_INFORMATION : {
Greg Kroah-Hartman
maintainerPATCH 71/185 ksmbd: dont increment epoch if current state and request state are same
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <[email protected]>
[ Upstream commit b6e9a44e99603fe10e1d78901fdd97681a539612 ]
If existing lease state and request state are same, don't increment epoch in create context.
--- fs/smb/server/oplock.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
fs/smb/server/oplock.c +6 -3
@@ -105,7 +105,7 @@ static int alloc_lease(struct oplock_inf lease->is_dir = lctx->is_dir;memcpy (lease->parent_lease_key, lctx->parent_lease_key,SMB2_LEASE_KEY_SIZE ); lease->version = lctx->version; - lease->epoch =le16_to_cpu (lctx->epoch); + lease->epoch =le16_to_cpu (lctx->epoch) +1 ;INIT_LIST_HEAD (&opinfo->lease_entry); opinfo->o_lease = lease;
@@ -541,6 +541,9 @@ static struct oplock_info *same_client_hcontinue ; } +if (lctx->req_state != lease->state) + lease->epoch++; +/* upgrading lease */ if ((atomic_read (&ci->op_count) +atomic_read (&ci->sop_count)) ==1 ) {
@@ -1035,7 +1038,7 @@ static void copy_lease(struct oplock_inf SMB2_LEASE_KEY_SIZE); lease2->duration = lease1->duration; lease2->flags = lease1->flags; - lease2->epoch = lease1->epoch++; + lease2->epoch = lease1->epoch; lease2->version = lease1->version; }
@@ -1454,7 +1457,7 @@ void create_lease_buf(u8 *rbuf, struct lmemcpy (buf->lcontext.LeaseKey, lease->lease_key,SMB2_LEASE_KEY_SIZE ); buf->lcontext.LeaseFlags = lease->flags; - buf->lcontext.Epoch =cpu_to_le16 (++lease->epoch); + buf->lcontext.Epoch =cpu_to_le16 (lease->epoch); buf->lcontext.LeaseState = lease->state;memcpy (buf->lcontext.ParentLeaseKey, lease->parent_lease_key,SMB2_LEASE_KEY_SIZE );
Greg Kroah-Hartman
maintainerPATCH 72/185 ksmbd: send lease break notification on FILE_RENAME_INFORMATION
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <[email protected]>
[ Upstream commit 3fc74c65b367476874da5fe6f633398674b78e5a ]
Send lease break notification on FILE_RENAME_INFORMATION request. This patch fix smb2.lease.v2_epoch2 test failure.
--- fs/smb/server/oplock.c | 12 +++++++----- fs/smb/server/smb2pdu.c | 1 + 2 files changed, 8 insertions(+), 5 deletions(-)
fs/smb/server/oplock.c +7 -5
@@ -541,14 +541,12 @@ static struct oplock_info *same_client_hcontinue ; } -if (lctx->req_state != lease->state) - lease->epoch++; -/* upgrading lease */ if ((atomic_read (&ci->op_count) +atomic_read (&ci->sop_count)) ==1 ) {if (lease->state !=SMB2_LEASE_NONE_LE && lease->state == (lctx->req_state & lease->state)) { + lease->epoch++; lease->state |= lctx->req_state;if (lctx->req_state &SMB2_LEASE_WRITE_CACHING_LE )
@@ -559,13 +557,17 @@ static struct oplock_info *same_client_h atomic_read(&ci->sop_count)) > 1) {if (lctx->req_state == (SMB2_LEASE_READ_CACHING_LE | -SMB2_LEASE_HANDLE_CACHING_LE )) +SMB2_LEASE_HANDLE_CACHING_LE )) { + lease->epoch++; lease->state = lctx->req_state; + } }if (lctx->req_state && lease->state == -SMB2_LEASE_NONE_LE ) +SMB2_LEASE_NONE_LE ) { + lease->epoch++;lease_none_upgrade (opinfo, lctx->req_state); + } }read_lock (&ci->m_lock); }
fs/smb/server/smb2pdu.c +1 -0
@@ -5579,6 +5579,7 @@ static int smb2_rename(struct ksmbd_workif (!file_info->ReplaceIfExists) flags =RENAME_NOREPLACE ; +smb_break_all_levII_oplock (work, fp,0 ); rc =ksmbd_vfs_rename (work, &fp->filp->f_path, new_name, flags); out:kfree (new_name);
Greg Kroah-Hartman
maintainerPATCH 73/185 ksmbd: Add missing set_freezable() for freezable kthread
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <[email protected]>
From: Kevin Hao <[email protected]>
[ Upstream commit 8fb7b723924cc9306bc161f45496497aec733904 ]
The kernel thread function ksmbd_conn_handler_loop() invokes the try_to_freeze() in its loop. But all the kernel threads are non-freezable by default. So if we want to make a kernel thread to be freezable, we have to invoke set_freezable() explicitly.
--- fs/smb/server/connection.c | 1 + 1 file changed, 1 insertion(+)
fs/smb/server/connection.c +1 -0
@@ -284,6 +284,7 @@ int ksmbd_conn_handler_loop(void *p) goto out; conn->last_active = jiffies; +set_freezable ();while (ksmbd_conn_alive (conn)) {if (try_to_freeze ())continue ;
Greg Kroah-Hartman
maintainerPATCH 74/185 Revert "drm/amd: Enable PCIe PME from D3"
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonathan Gray <[email protected]>
This reverts commit 0c8d252d0a20a412ec30859afef6393aecfdd3cd.
duplicated a change made in 6.1.66c6088429630048661e480ed28590e69a48c102d6
--- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 2 -- 1 file changed, 2 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +0 -2
@@ -2202,8 +2202,6 @@ retry_init:pci_wake_from_d3 (pdev, TRUE); -pci_wake_from_d3 (pdev, TRUE); -/* * For runpm implemented via BACO, PMFW will handle the * timing for BACO in and out:
Greg Kroah-Hartman
maintainerPATCH 75/185 drm/amd/display: pbn_div need be updated for hotplug event
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wayne Lin <[email protected]>
commit 9cdef4f720376ef0fb0febce1ed2377c19e531f9 upstream.
link_rate sometime will be changed when DP MST connector hotplug, so pbn_div also need be updated; otherwise, it will mismatch with link_rate, causes no output in external monitor.
This is a backport to 6.7 and older.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +1 -2
@@ -6677,8 +6677,7 @@ static int dm_encoder_helper_atomic_checif (IS_ERR (mst_state))return PTR_ERR (mst_state); -if (!mst_state->pbn_div) - mst_state->pbn_div =dm_mst_get_pbn_divider (aconnector->mst_port->dc_link); + mst_state->pbn_div =dm_mst_get_pbn_divider (aconnector->mst_port->dc_link);if (!state->duplicated) {int max_bpc = conn_state->max_requested_bpc;
Greg Kroah-Hartman
maintainerPATCH 76/185 wifi: mac80211: fix potential sta-link leak
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <[email protected]>
[ Upstream commit b01a74b3ca6fd51b62c67733ba7c3280fa6c5d26 ]
When a station is allocated, links are added but not set to valid yet (e.g. during connection to an AP MLD), we might remove the station without ever marking links valid, and leak them. Fix that.
--- net/mac80211/sta_info.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
net/mac80211/sta_info.c +4 -1
@@ -396,7 +396,10 @@ void sta_info_free(struct ieee80211_local *local, struct sta_info *sta)int i;for (i =0 ; i <ARRAY_SIZE (sta->link); i++) { -if (!(sta->sta.valid_links &BIT (i))) +struct link_sta_info *link_sta; + + link_sta =rcu_access_pointer (sta->link[i]); +if (!link_sta)continue ;sta_remove_link (sta, i, false);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 77/185 net/smc: fix illegal rmb_desc access in SMC-D connection dump
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wen Gu <[email protected]>
[ Upstream commit dbc153fd3c142909e564bb256da087e13fbf239c ]
A crash was found when dumping SMC-D connections. It can be reproduced by following steps:
- run nginx/wrk test:
smc_run nginx
smc_run wrk -t 16 -c 1000 -d <duration> -H 'Connection: Close' <URL>
- continuously dump SMC-D connections in parallel:
watch -n 1 'smcss -D'
BUG: kernel NULL pointer dereference, address: 0000000000000030 CPU: 2 PID: 7204 Comm: smcss Kdump: loaded Tainted: G E 6.7.0+ #55 RIP: 0010:__smc_diag_dump.constprop.0+0x5e5/0x620 [smc_diag] Call Trace: <TASK> ? __die+0x24/0x70 ? page_fault_oops+0x66/0x150 ? exc_page_fault+0x69/0x140 ? asm_exc_page_fault+0x26/0x30 ? __smc_diag_dump.constprop.0+0x5e5/0x620 [smc_diag] ? __kmalloc_node_track_caller+0x35d/0x430 ? __alloc_skb+0x77/0x170 smc_diag_dump_proto+0xd0/0xf0 [smc_diag] smc_diag_dump+0x26/0x60 [smc_diag] netlink_dump+0x19f/0x320 __netlink_dump_start+0x1dc/0x300 smc_diag_handler_dump+0x6a/0x80 [smc_diag] ? __pfx_smc_diag_dump+0x10/0x10 [smc_diag] sock_diag_rcv_msg+0x121/0x140 ? __pfx_sock_diag_rcv_msg+0x10/0x10 netlink_rcv_skb+0x5a/0x110 sock_diag_rcv+0x28/0x40 netlink_unicast+0x22a/0x330 netlink_sendmsg+0x1f8/0x420 __sock_sendmsg+0xb0/0xc0 ____sys_sendmsg+0x24e/0x300 ? copy_msghdr_from_user+0x62/0x80 ___sys_sendmsg+0x7c/0xd0 ? __do_fault+0x34/0x160 ? do_read_fault+0x5f/0x100 ? do_fault+0xb0/0x110 ? __handle_mm_fault+0x2b0/0x6c0 __sys_sendmsg+0x4d/0x80 do_syscall_64+0x69/0x180 entry_SYSCALL_64_after_hwframe+0x6e/0x76
It is possible that the connection is in process of being established when we dump it. Assumed that the connection has been registered in a link group by smc_conn_create() but the rmb_desc has not yet been initialized by smc_buf_create(), thus causing the illegal access to conn->rmb_desc. So fix it by checking before dump.
--- net/smc/smc_diag.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/smc/smc_diag.c +1 -1
@@ -163,7 +163,7 @@ static int __smc_diag_dump(struct sock *sk, struct sk_buff *skb, }if (smc_conn_lgr_valid (&smc->conn) && smc->conn.lgr->is_smcd && (req->diag_ext & (1 << (SMC_DIAG_DMBINFO -1 ))) && - !list_empty (&smc->conn.lgr->list)) { + !list_empty (&smc->conn.lgr->list) && smc->conn.rmb_desc) {struct smc_connection *conn = &smc->conn;struct smcd_diag_dmbinfo dinfo;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 78/185 tcp: make sure init the accept_queues spinlocks once
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhengchao Shao <[email protected]>
[ Upstream commit 198bc90e0e734e5f98c3d2833e8390cac3df61b2 ]
When I run syz's reproduction C program locally, it causes the following issue:
pvqspinlock: lock 0xffff9d181cd5c660 has corrupted value 0x0!
WARNING: CPU: 19 PID: 21160 at __pv_queued_spin_unlock_slowpath (kernel/locking/qspinlock_paravirt.h:508) Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011 RIP: 0010:__pv_queued_spin_unlock_slowpath (kernel/locking/qspinlock_paravirt.h:508) Code: 73 56 3a ff 90 c3 cc cc cc cc 8b 05 bb 1f 48 01 85 c0 74 05 c3 cc cc cc cc 8b 17 48 89 fe 48 c7 c7 30 20 ce 8f e8 ad 56 42 ff <0f> 0b c3 cc cc cc cc 0f 0b 0f 1f 40 00 90 90 90 90 90 90 90 90 90 RSP: 0018:ffffa8d200604cb8 EFLAGS: 00010282 RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffff9d1ef60e0908 RDX: 00000000ffffffd8 RSI: 0000000000000027 RDI: ffff9d1ef60e0900 RBP: ffff9d181cd5c280 R08: 0000000000000000 R09: 00000000ffff7fff R10: ffffa8d200604b68 R11: ffffffff907dcdc8 R12: 0000000000000000 R13: ffff9d181cd5c660 R14: ffff9d1813a3f330 R15: 0000000000001000 FS: 00007fa110184640(0000) GS:ffff9d1ef60c0000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000020000000 CR3: 000000011f65e000 CR4: 00000000000006f0 Call Trace: <IRQ> _raw_spin_unlock (kernel/locking/spinlock.c:186) inet_csk_reqsk_queue_add (net/ipv4/inet_connection_sock.c:1321) inet_csk_complete_hashdance (net/ipv4/inet_connection_sock.c:1358) tcp_check_req (net/ipv4/tcp_minisocks.c:868) tcp_v4_rcv (net/ipv4/tcp_ipv4.c:2260) ip_protocol_deliver_rcu (net/ipv4/ip_input.c:205) ip_local_deliver_finish (net/ipv4/ip_input.c:234) __netif_receive_skb_one_core (net/core/dev.c:5529) process_backlog (./include/linux/rcupdate.h:779) __napi_poll (net/core/dev.c:6533) net_rx_action (net/core/dev.c:6604) __do_softirq (./arch/x86/include/asm/jump_label.h:27) do_softirq (kernel/softirq.c:454 kernel/softirq.c:441) </IRQ> <TASK> __local_bh_enable_ip (kernel/softirq.c:381) __dev_queue_xmit (net/core/dev.c:4374) ip_finish_output2 (./include/net/neighbour.h:540 net/ipv4/ip_output.c:235) __ip_queue_xmit (net/ipv4/ip_output.c:535) __tcp_transmit_skb (net/ipv4/tcp_output.c:1462) tcp_rcv_synsent_state_process (net/ipv4/tcp_input.c:6469) tcp_rcv_state_process (net/ipv4/tcp_input.c:6657) tcp_v4_do_rcv (net/ipv4/tcp_ipv4.c:1929) __release_sock (./include/net/sock.h:1121 net/core/sock.c:2968) release_sock (net/core/sock.c:3536) inet_wait_for_connect (net/ipv4/af_inet.c:609) __inet_stream_connect (net/ipv4/af_inet.c:702) inet_stream_connect (net/ipv4/af_inet.c:748) __sys_connect (./include/linux/file.h:45 net/socket.c:2064) __x64_sys_connect (net/socket.c:2073 net/socket.c:2070 net/socket.c:2070) do_syscall_64 (arch/x86/entry/common.c:51 arch/x86/entry/common.c:82) entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:129) RIP: 0033:0x7fa10ff05a3d 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 ab a3 0e 00 f7 d8 64 89 01 48 RSP: 002b:00007fa110183de8 EFLAGS: 00000202 ORIG_RAX: 000000000000002a RAX: ffffffffffffffda RBX: 0000000020000054 RCX: 00007fa10ff05a3d RDX: 000000000000001c RSI: 0000000020000040 RDI: 0000000000000003 RBP: 00007fa110183e20 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000202 R12: 00007fa110184640 R13: 0000000000000000 R14: 00007fa10fe8b060 R15: 00007fff73e23b20 </TASK>
The issue triggering process is analyzed as follows:
Thread A Thread Btcp_v4_rcv //receive ack TCP packet inet_shutdown
tcp_check_req tcp_disconnect //disconnect sock
... tcp_set_state(sk, TCP_CLOSE)
inet_csk_complete_hashdance ...
inet_csk_reqsk_queue_add inet_listen //start listen
spin_lock(&queue->rskq_lock) inet_csk_listen_start
... reqsk_queue_alloc
... spin_lock_init
spin_unlock(&queue->rskq_lock) //warningWhen the socket receives the ACK packet during the three-way handshake, it will hold spinlock. And then the user actively shutdowns the socket and listens to the socket immediately, the spinlock will be initialized. When the socket is going to release the spinlock, a warning is generated. Also the same issue to fastopenq.lock.
Move init spinlock to inet_create and inet_accept to make sure init the accept_queue's spinlocks once.
--- include/net/inet_connection_sock.h | 8 ++++++++ net/core/request_sock.c | 3 --- net/ipv4/af_inet.c | 3 +++ net/ipv4/inet_connection_sock.c | 4 ++++ 4 files changed, 15 insertions(+), 3 deletions(-)
include/net/inet_connection_sock.h +8 -0
@@ -346,4 +346,12 @@ static inline bool inet_csk_has_ulp(struct sock *sk) return inet_sk(sk)->is_icsk && !!inet_csk(sk)->icsk_ulp_ops; } +static inline void inet_init_csk_locks (struct sock *sk) +{ +struct inet_connection_sock *icsk =inet_csk (sk); + +spin_lock_init (&icsk->icsk_accept_queue.rskq_lock); +spin_lock_init (&icsk->icsk_accept_queue.fastopenq.lock); +} +#endif /* _INET_CONNECTION_SOCK_H */
net/core/request_sock.c +0 -3
@@ -33,9 +33,6 @@void reqsk_queue_alloc (struct request_sock_queue *queue) { -spin_lock_init (&queue->rskq_lock); - -spin_lock_init (&queue->fastopenq.lock); queue->fastopenq.rskq_rst_head =NULL ; queue->fastopenq.rskq_rst_tail =NULL ; queue->fastopenq.qlen =0 ;
net/ipv4/af_inet.c +3 -0
@@ -324,6 +324,9 @@ static int inet_create(struct net *net, struct socket *sock, int protocol,if (INET_PROTOSW_REUSE & answer_flags) sk->sk_reuse =SK_CAN_REUSE ; +if (INET_PROTOSW_ICSK & answer_flags) +inet_init_csk_locks (sk); + inet =inet_sk (sk); inet->is_icsk = (INET_PROTOSW_ICSK & answer_flags) !=0 ;
net/ipv4/inet_connection_sock.c +4 -0
@@ -727,6 +727,10 @@ struct sock *inet_csk_accept(struct sock *sk, int flags, int *err, bool kern) }if (req)reqsk_put (req); + +if (newsk) +inet_init_csk_locks (newsk); +return newsk; out_err: newsk =NULL ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 79/185 bnxt_en: Wait for FLR to complete during probe
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Chan <[email protected]>
[ Upstream commit 3c1069fa42872f95cf3c6fedf80723d391e12d57 ]
The first message to firmware may fail if the device is undergoing FLR. The driver has some recovery logic for this failure scenario but we must wait 100 msec for FLR to complete before proceeding. Otherwise the recovery will always fail.
--- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/net/ethernet/broadcom/bnxt/bnxt.c +5 -0
@@ -12269,6 +12269,11 @@ static int bnxt_fw_init_one_p1(struct bnxt *bp) bp->fw_cap =0 ; rc =bnxt_hwrm_ver_get (bp); +/* FW may be unresponsive after FLR. FLR must complete within 100 msec +* so wait before continuing with recovery. +*/ +if (rc) +msleep (100 );bnxt_try_map_fw_health_reg (bp);if (rc) { rc =bnxt_try_recover_fw (bp);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 80/185 vlan: skip nested type that is not IFLA_VLAN_QOS_MAPPING
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lin Ma <[email protected]>
[ Upstream commit 6c21660fe221a15c789dee2bc2fd95516bc5aeaf ]
In the vlan_changelink function, a loop is used to parse the nested attributes IFLA_VLAN_EGRESS_QOS and IFLA_VLAN_INGRESS_QOS in order to obtain the struct ifla_vlan_qos_mapping. These two nested attributes are checked in the vlan_validate_qos_map function, which calls nla_validate_nested_deprecated with the vlan_map_policy.
However, this deprecated validator applies a LIBERAL strictness, allowing the presence of an attribute with the type IFLA_VLAN_QOS_UNSPEC. Consequently, the loop in vlan_changelink may parse an attribute of type IFLA_VLAN_QOS_UNSPEC and believe it carries a payload of struct ifla_vlan_qos_mapping, which is not necessarily true.
To address this issue and ensure compatibility, this patch introduces two type checks that skip attributes whose type is not IFLA_VLAN_QOS_MAPPING.
--- net/8021q/vlan_netlink.c | 4 ++++ 1 file changed, 4 insertions(+)
net/8021q/vlan_netlink.c +4 -0
@@ -118,12 +118,16 @@ static int vlan_changelink(struct net_device *dev, struct nlattr *tb[], }if (data[IFLA_VLAN_INGRESS_QOS ]) {nla_for_each_nested (attr, data[IFLA_VLAN_INGRESS_QOS ], rem) { +if (nla_type (attr) !=IFLA_VLAN_QOS_MAPPING ) +continue ; m =nla_data (attr);vlan_dev_set_ingress_priority (dev, m->to, m->from); } }if (data[IFLA_VLAN_EGRESS_QOS ]) {nla_for_each_nested (attr, data[IFLA_VLAN_EGRESS_QOS ], rem) { +if (nla_type (attr) !=IFLA_VLAN_QOS_MAPPING ) +continue ; m =nla_data (attr); err =vlan_dev_set_egress_priority (dev, m->from, m->to);if (err)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 81/185 llc: make llc_ui_sendmsg() more robust against bonding changes
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit dad555c816a50c6a6a8a86be1f9177673918c647 ]
syzbot was able to trick llc_ui_sendmsg(), allocating an skb with no headroom, but subsequently trying to push 14 bytes of Ethernet header [1]
Like some others, llc_ui_sendmsg() releases the socket lock before calling sock_alloc_send_skb().
Then it acquires it again, but does not redo all the sanity checks that were performed.
This fix:
- Uses LL_RESERVED_SPACE() to reserve space.
- Check all conditions again after socket lock is held again.
- Do not account Ethernet header for mtu limitation.
[1]
skbuff: skb_under_panic: text:ffff800088baa334 len:1514 put:14 head:ffff0000c9c37000 data:ffff0000c9c36ff2 tail:0x5dc end:0x6c0 dev:bond0
kernel BUG at net/core/skbuff.c:193 !
Internal error: Oops - BUG: 00000000f2000800 [#1] PREEMPT SMP Modules linked in: CPU: 0 PID: 6875 Comm: syz-executor.0 Not tainted 6.7.0-rc8-syzkaller-00101-g0802e17d9aca-dirty #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 11/17/2023 pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : skb_panic net/core/skbuff.c:189 [inline] pc : skb_under_panic+0x13c/0x140 net/core/skbuff.c:203 lr : skb_panic net/core/skbuff.c:189 [inline] lr : skb_under_panic+0x13c/0x140 net/core/skbuff.c:203
sp : ffff800096f97000
x29: ffff800096f97010 x28: ffff80008cc8d668 x27: dfff800000000000
x26: ffff0000cb970c90 x25: 00000000000005dc x24: ffff0000c9c36ff2
x23: ffff0000c9c37000 x22: 00000000000005ea x21: 00000000000006c0
x20: 000000000000000e x19: ffff800088baa334 x18: 1fffe000368261ce
x17: ffff80008e4ed000 x16: ffff80008a8310f8 x15: 0000000000000001
x14: 1ffff00012df2d58 x13: 0000000000000000 x12: 0000000000000000
x11: 0000000000000001 x10: 0000000000ff0100 x9 : e28a51f1087e8400 x8 : e28a51f1087e8400 x7 : ffff80008028f8d0 x6 : 0000000000000000 x5 : 0000000000000001 x4 : 0000000000000001 x3 : ffff800082b78714 x2 : 0000000000000001 x1 : 0000000100000000 x0 : 0000000000000089
Call trace: skb_panic net/core/skbuff.c:189 [inline] skb_under_panic+0x13c/0x140 net/core/skbuff.c:203 skb_push+0xf0/0x108 net/core/skbuff.c:2451 eth_header+0x44/0x1f8 net/ethernet/eth.c:83 dev_hard_header include/linux/netdevice.h:3188 [inline] llc_mac_hdr_init+0x110/0x17c net/llc/llc_output.c:33 llc_sap_action_send_xid_c+0x170/0x344 net/llc/llc_s_ac.c:85 llc_exec_sap_trans_actions net/llc/llc_sap.c:153 [inline] llc_sap_next_state net/llc/llc_sap.c:182 [inline] llc_sap_state_process+0x1ec/0x774 net/llc/llc_sap.c:209 llc_build_and_send_xid_pkt+0x12c/0x1c0 net/llc/llc_sap.c:270 llc_ui_sendmsg+0x7bc/0xb1c net/llc/af_llc.c:997 sock_sendmsg_nosec net/socket.c:730 [inline] __sock_sendmsg net/socket.c:745 [inline] sock_sendmsg+0x194/0x274 net/socket.c:767 splice_to_socket+0x7cc/0xd58 fs/splice.c:881 do_splice_from fs/splice.c:933 [inline] direct_splice_actor+0xe4/0x1c0 fs/splice.c:1142 splice_direct_to_actor+0x2a0/0x7e4 fs/splice.c:1088 do_splice_direct+0x20c/0x348 fs/splice.c:1194 do_sendfile+0x4bc/0xc70 fs/read_write.c:1254 __do_sys_sendfile64 fs/read_write.c:1322 [inline] __se_sys_sendfile64 fs/read_write.c:1308 [inline] __arm64_sys_sendfile64+0x160/0x3b4 fs/read_write.c:1308 __invoke_syscall arch/arm64/kernel/syscall.c:37 [inline] invoke_syscall+0x98/0x2b8 arch/arm64/kernel/syscall.c:51 el0_svc_common+0x130/0x23c arch/arm64/kernel/syscall.c:136 do_el0_svc+0x48/0x58 arch/arm64/kernel/syscall.c:155 el0_svc+0x54/0x158 arch/arm64/kernel/entry-common.c:678 el0t_64_sync_handler+0x84/0xfc arch/arm64/kernel/entry-common.c:696 el0t_64_sync+0x190/0x194 arch/arm64/kernel/entry.S:595 Code: aa1803e6 aa1903e7 a90023f5 94792f6a (d4210000)
--- net/llc/af_llc.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-)
net/llc/af_llc.c +16 -8
@@ -928,14 +928,15 @@ static int llc_ui_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,*/ static int llc_ui_sendmsg (struct socket *sock,struct msghdr *msg,size_t len) { + DECLARE_SOCKADDR(struct sockaddr_llc *, addr, msg->msg_name);struct sock *sk = sock->sk;struct llc_sock *llc =llc_sk (sk); - DECLARE_SOCKADDR(struct sockaddr_llc *, addr, msg->msg_name);int flags = msg->msg_flags;int noblock = flags &MSG_DONTWAIT ; +int rc = -EINVAL , copied =0 , hdrlen, hh_len;struct sk_buff *skb =NULL ; +struct net_device *dev;size_t size =0 ; -int rc = -EINVAL , copied =0 , hdrlen;dprintk ("%s: sending from %02X to %02X\n" , __func__, llc->laddr.lsap, llc->daddr.lsap);
@@ -955,22 +956,29 @@ static int llc_ui_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)if (rc) goto out; } - hdrlen = llc->dev->hard_header_len +llc_ui_header_len (sk, addr); + dev = llc->dev; + hh_len =LL_RESERVED_SPACE (dev); + hdrlen =llc_ui_header_len (sk, addr); size = hdrlen + len; -if (size > llc->dev->mtu) - size = llc->dev->mtu; + size =min_t (size_t, size,READ_ONCE (dev->mtu)); copied = size - hdrlen; rc = -EINVAL ;if (copied <0 ) goto out;release_sock (sk); - skb =sock_alloc_send_skb (sk, size, noblock, &rc); + skb =sock_alloc_send_skb (sk, hh_len + size, noblock, &rc);lock_sock (sk);if (!skb) goto out; - skb->dev = llc->dev; +if (sock_flag (sk,SOCK_ZAPPED ) || + llc->dev != dev || + hdrlen !=llc_ui_header_len (sk, addr) || + hh_len !=LL_RESERVED_SPACE (dev) || + size >READ_ONCE (dev->mtu)) + goto out; + skb->dev = dev; skb->protocol =llc_proto_type (addr->sllc_arphrd); -skb_reserve (skb, hdrlen); +skb_reserve (skb, hh_len + hdrlen); rc =memcpy_from_msg (skb_put (skb, copied), msg, copied);if (rc) goto out;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 82/185 llc: Drop support for ETH_P_TR_802_2.
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
[ Upstream commit e3f9bed9bee261e3347131764e42aeedf1ffea61 ]
syzbot reported an uninit-value bug below. [0]
llc supports ETH_P_802_2 (0x0004) and used to support ETH_P_TR_802_2 (0x0011), and syzbot abused the latter to trigger the bug.
write$tun(r0, &(0x7f0000000040)={@val={0x0, 0x11}, @val, @mpls={[], @llc={@snap={0xaa, 0x1, ')', "90e5dd"}}}}, 0x16)
llc_conn_handler() initialises local variables {saddr,daddr}.mac based on skb in llc_pdu_decode_sa()/llc_pdu_decode_da() and passes them to __llc_lookup().
However, the initialisation is done only when skb->protocol is htons(ETH_P_802_2), otherwise, __llc_lookup_established() and __llc_lookup_listener() will read garbage.
The missing initialisation existed prior to commit 211ed865108e ("net: delete all instances of special processing for token ring").
It removed the part to kick out the token ring stuff but forgot to close the door allowing ETH_P_TR_802_2 packets to sneak into llc_rcv().
Let's remove llc_tr_packet_type and complete the deprecation.
[0]:
BUG: KMSAN: uninit-value in __llc_lookup_established+0xe9d/0xf90 __llc_lookup_established+0xe9d/0xf90 __llc_lookup net/llc/llc_conn.c:611 [inline] llc_conn_handler+0x4bd/0x1360 net/llc/llc_conn.c:791 llc_rcv+0xfbb/0x14a0 net/llc/llc_input.c:206 __netif_receive_skb_one_core net/core/dev.c:5527 [inline] __netif_receive_skb+0x1a6/0x5a0 net/core/dev.c:5641 netif_receive_skb_internal net/core/dev.c:5727 [inline] netif_receive_skb+0x58/0x660 net/core/dev.c:5786 tun_rx_batched+0x3ee/0x980 drivers/net/tun.c:1555 tun_get_user+0x53af/0x66d0 drivers/net/tun.c:2002 tun_chr_write_iter+0x3af/0x5d0 drivers/net/tun.c:2048 call_write_iter include/linux/fs.h:2020 [inline] new_sync_write fs/read_write.c:491 [inline] vfs_write+0x8ef/0x1490 fs/read_write.c:584 ksys_write+0x20f/0x4c0 fs/read_write.c:637 __do_sys_write fs/read_write.c:649 [inline] __se_sys_write fs/read_write.c:646 [inline] __x64_sys_write+0x93/0xd0 fs/read_write.c:646 do_syscall_x64 arch/x86/entry/common.c:51 [inline] do_syscall_64+0x44/0x110 arch/x86/entry/common.c:82 entry_SYSCALL_64_after_hwframe+0x63/0x6b
Local variable daddr created at:
llc_conn_handler+0x53/0x1360 net/llc/llc_conn.c:783 llc_rcv+0xfbb/0x14a0 net/llc/llc_input.c:206 CPU: 1 PID: 5004 Comm: syz-executor994 Not tainted 6.6.0-syzkaller-14500-g1c41041124bd #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/09/2023
--- include/net/llc_pdu.h | 6 ++---- net/llc/llc_core.c | 7 ------- 2 files changed, 2 insertions(+), 11 deletions(-)
include/net/llc_pdu.h +2 -4
@@ -262,8 +262,7 @@ static inline void llc_pdu_header_init(struct sk_buff *skb, u8 type,*/ static inline void llc_pdu_decode_sa (struct sk_buff *skb,u8 *sa) { -if (skb->protocol ==htons (ETH_P_802_2 )) -memcpy (sa,eth_hdr (skb)->h_source,ETH_ALEN ); +memcpy (sa,eth_hdr (skb)->h_source,ETH_ALEN ); }/**
@@ -275,8 +274,7 @@ static inline void llc_pdu_decode_sa(struct sk_buff *skb, u8 *sa)*/ static inline void llc_pdu_decode_da (struct sk_buff *skb,u8 *da) { -if (skb->protocol ==htons (ETH_P_802_2 )) -memcpy (da,eth_hdr (skb)->h_dest,ETH_ALEN ); +memcpy (da,eth_hdr (skb)->h_dest,ETH_ALEN ); }/**
net/llc/llc_core.c +0 -7
@@ -135,22 +135,15 @@ static struct packet_type llc_packet_type __read_mostly = { .func = llc_rcv, }; -static struct packet_type llc_tr_packet_type__read_mostly = { - .type =cpu_to_be16 (ETH_P_TR_802_2 ), - .func = llc_rcv, -}; -static int __init llc_init (void ) {dev_add_pack (&llc_packet_type); -dev_add_pack (&llc_tr_packet_type);return 0 ; } static void __exit llc_exit(void) {dev_remove_pack (&llc_packet_type); -dev_remove_pack (&llc_tr_packet_type); }module_init (llc_init);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 83/185 udp: fix busy polling
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit a54d51fb2dfb846aedf3751af501e9688db447f5 ]
Generic sk_busy_loop_end() only looks at sk->sk_receive_queue for presence of packets.
Problem is that for UDP sockets after blamed commit, some packets could be present in another queue: udp_sk(sk)->reader_queue
In some cases, a busy poller could spin until timeout expiration, even if some packets are available in udp_sk(sk)->reader_queue.
v3: - make sk_busy_loop_end() nicer (Willem)
v2: - add a READ_ONCE(sk->sk_family) in sk_is_inet() to avoid KCSAN splats.
- add a sk_is_inet() check in sk_is_udp() (Willem feedback)
- add a sk_is_inet() check in sk_is_tcp().
--- include/linux/skmsg.h | 6 ------ include/net/inet_sock.h | 5 ----- include/net/sock.h | 18 +++++++++++++++++- net/core/sock.c | 11 +++++++++-- 4 files changed, 26 insertions(+), 14 deletions(-)
include/linux/skmsg.h +0 -6
@@ -500,12 +500,6 @@ static inline bool sk_psock_strp_enabled(struct sk_psock *psock)return !!psock->saved_data_ready; } -static inline bool sk_is_udp (const struct sock *sk) -{ -return sk->sk_type ==SOCK_DGRAM && - sk->sk_protocol ==IPPROTO_UDP ; -} -#if IS_ENABLED (CONFIG_NET_SOCK_MSG )#define BPF_F_STRPARSER (1UL << 1)
include/net/inet_sock.h +0 -5
@@ -270,11 +270,6 @@ struct inet_sock {#define IP_CMSG_CHECKSUM BIT(7)#define IP_CMSG_RECVFRAGSIZE BIT(8) -static inline bool sk_is_inet (struct sock *sk) -{ -return sk->sk_family ==AF_INET || sk->sk_family ==AF_INET6 ; -} -/** * sk_to_full_sk - Access to a full socket * @sk: pointer to a socket
include/net/sock.h +17 -1
@@ -2824,9 +2824,25 @@ static inline void skb_setup_tx_timestamp(struct sk_buff *skb, __u16 tsflags) &skb_shinfo(skb)->tskey); } +static inline bool sk_is_inet (const struct sock *sk) +{ +int family =READ_ONCE (sk->sk_family); + +return family ==AF_INET || family ==AF_INET6 ; +} +static inline bool sk_is_tcp (const struct sock *sk) { -return sk->sk_type ==SOCK_STREAM && sk->sk_protocol ==IPPROTO_TCP ; +return sk_is_inet (sk) && + sk->sk_type ==SOCK_STREAM && + sk->sk_protocol ==IPPROTO_TCP ; +} + +static inline bool sk_is_udp (const struct sock *sk) +{ +return sk_is_inet (sk) && + sk->sk_type ==SOCK_DGRAM && + sk->sk_protocol ==IPPROTO_UDP ; }static inline bool sk_is_stream_unix (const struct sock *sk)
net/core/sock.c +9 -2
@@ -107,6 +107,7 @@#include <linux/interrupt.h> #include <linux/poll.h> #include <linux/tcp.h> +#include <linux/udp.h> #include <linux/init.h> #include <linux/highmem.h> #include <linux/user_namespace.h>
@@ -4109,8 +4110,14 @@ bool sk_busy_loop_end(void *p, unsigned long start_time) {struct sock *sk = p; -return !skb_queue_empty_lockless (&sk->sk_receive_queue) || -sk_busy_loop_timeout (sk, start_time); +if (!skb_queue_empty_lockless (&sk->sk_receive_queue)) +return true; + +if (sk_is_udp (sk) && + !skb_queue_empty_lockless (&udp_sk (sk)->reader_queue)) +return true; + +return sk_busy_loop_timeout (sk, start_time); }EXPORT_SYMBOL (sk_busy_loop_end);#endif /* CONFIG_NET_RX_BUSY_POLL */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 84/185 net: fix removing a namespace with conflicting altnames
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Kicinski <[email protected]>
[ Upstream commit d09486a04f5da0a812c26217213b89a3b1acf836 ]
Mark reports a BUG() when a net namespace is removed.
kernel BUG at net/core/dev.c:11520!
Physical interfaces moved outside of init_net get "refunded" to init_net when that namespace disappears. The main interface name may get overwritten in the process if it would have conflicted. We need to also discard all conflicting altnames. Recent fixes addressed ensuring that altnames get moved with the main interface, which surfaced this problem.
--- net/core/dev.c | 9 +++++++++ net/core/dev.h | 3 +++ 2 files changed, 12 insertions(+)
net/core/dev.c +9 -0
@@ -11323,6 +11323,7 @@ static struct pernet_operations __net_initdata netdev_net_ops = { static void __net_exit default_device_exit_net(struct net *net) { +struct netdev_name_node *name_node, *tmp;struct net_device *dev, *aux;/* * Push all migratable network devices back to the
@@ -11345,6 +11346,14 @@ static void __net_exit default_device_exit_net(struct net *net)snprintf (fb_name,IFNAMSIZ ,"dev%d" , dev->ifindex);if (netdev_name_in_use (&init_net, fb_name))snprintf (fb_name,IFNAMSIZ ,"dev%%d" ); + +netdev_for_each_altname_safe (dev, name_node, tmp) +if (netdev_name_in_use (&init_net, name_node->name)) { +netdev_name_node_del (name_node); +synchronize_rcu (); +__netdev_name_node_alt_destroy (name_node); + } + err =dev_change_net_namespace (dev, &init_net, fb_name);if (err) { pr_emerg("%s: failed to move %s to init_net: %d\n",
net/core/dev.h +3 -0
@@ -63,6 +63,9 @@ int dev_change_name(struct net_device *dev, const char *newname);#define netdev_for_each_altname (dev, namenode) \ list_for_each_entry((namenode), &(dev)->name_node->list, list) +#define netdev_for_each_altname_safe (dev, namenode, next) \ + list_for_each_entry_safe((namenode), (next), &(dev)->name_node->list, \ + list)int netdev_name_node_alt_create (struct net_device *dev,const char *name);int netdev_name_node_alt_destroy (struct net_device *dev,const char *name);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 85/185 tun: fix missing dropped counter in tun_xdp_act
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yunjian Wang <[email protected]>
[ Upstream commit 5744ba05e7c4bff8fec133dd0f9e51ddffba92f5 ]
The commit 8ae1aff0b331 ("tuntap: split out XDP logic") includes dropped counter for XDP_DROP, XDP_ABORTED, and invalid XDP actions. Unfortunately, that commit missed the dropped counter when error occurs during XDP_TX and XDP_REDIRECT actions. This patch fixes this issue.
--- drivers/net/tun.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/net/tun.c +6 -2
@@ -1622,13 +1622,17 @@ static int tun_xdp_act(struct tun_struct *tun, struct bpf_prog *xdp_prog,switch (act) {case XDP_REDIRECT : err =xdp_do_redirect (tun->dev, xdp, xdp_prog); -if (err) +if (err) { +dev_core_stats_rx_dropped_inc (tun->dev);return err; + }break ;case XDP_TX : err =tun_xdp_tx (tun->dev, xdp); -if (err <0 ) +if (err <0 ) { +dev_core_stats_rx_dropped_inc (tun->dev);return err; + }break ;case XDP_PASS :break ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 86/185 tun: add missing rx stats accounting in tun_xdp_act
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yunjian Wang <[email protected]>
[ Upstream commit f1084c427f55d573fcd5688d9ba7b31b78019716 ]
The TUN can be used as vhost-net backend, and it is necessary to count the packets transmitted from TUN to vhost-net/virtio-net. However, there are some places in the receive path that were not taken into account when using XDP. It would be beneficial to also include new accounting for successfully received bytes using dev_sw_netstats_rx_add.
--- drivers/net/tun.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/tun.c +2 -0
@@ -1626,6 +1626,7 @@ static int tun_xdp_act(struct tun_struct *tun, struct bpf_prog *xdp_prog,dev_core_stats_rx_dropped_inc (tun->dev);return err; } +dev_sw_netstats_rx_add (tun->dev, xdp->data_end - xdp->data);break ;case XDP_TX : err =tun_xdp_tx (tun->dev, xdp);
@@ -1633,6 +1634,7 @@ static int tun_xdp_act(struct tun_struct *tun, struct bpf_prog *xdp_prog,dev_core_stats_rx_dropped_inc (tun->dev);return err; } +dev_sw_netstats_rx_add (tun->dev, xdp->data_end - xdp->data);break ;case XDP_PASS :break ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 87/185 net: micrel: Fix PTP frame parsing for lan8814
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Horatiu Vultur <[email protected]>
[ Upstream commit aaf632f7ab6dec57bc9329a438f94504fe8034b9 ]
The HW has the capability to check each frame if it is a PTP frame, which domain it is, which ptp frame type it is, different ip address in the frame. And if one of these checks fail then the frame is not timestamp. Most of these checks were disabled except checking the field minorVersionPTP inside the PTP header. Meaning that once a partner sends a frame compliant to 8021AS which has minorVersionPTP set to 1, then the frame was not timestamp because the HW expected by default a value of 0 in minorVersionPTP. This is exactly the same issue as on lan8841. Fix this issue by removing this check so the userspace can decide on this.
--- drivers/net/phy/micrel.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
drivers/net/phy/micrel.c +11 -0
@@ -120,6 +120,11 @@*/ #define LAN8814_1PPM_FORMAT 17179 +#define PTP_RX_VERSION 0x0248 +#define PTP_TX_VERSION 0x0288 +#define PTP_MAX_VERSION (x) (((x) & GENMASK(7, 0)) << 8) +#define PTP_MIN_VERSION (x) ((x) & GENMASK(7, 0)) +#define PTP_RX_MOD 0x024F#define PTP_RX_MOD_BAD_UDPV4_CHKSUM_FORCE_FCS_DIS_ BIT(3)#define PTP_RX_TIMESTAMP_EN 0x024D
@@ -2922,6 +2927,12 @@ static void lan8814_ptp_init(struct phy_device *phydev)lanphy_write_page_reg (phydev,5 ,PTP_TX_PARSE_IP_ADDR_EN ,0 );lanphy_write_page_reg (phydev,5 ,PTP_RX_PARSE_IP_ADDR_EN ,0 ); +/* Disable checking for minorVersionPTP field */ +lanphy_write_page_reg (phydev,5 ,PTP_RX_VERSION , +PTP_MAX_VERSION (0xff ) |PTP_MIN_VERSION (0x0 )); +lanphy_write_page_reg (phydev,5 ,PTP_TX_VERSION , +PTP_MAX_VERSION (0xff ) |PTP_MIN_VERSION (0x0 )); +skb_queue_head_init (&ptp_priv->tx_queue);skb_queue_head_init (&ptp_priv->rx_queue);INIT_LIST_HEAD (&ptp_priv->rx_ts_list);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 88/185 net/rds: Fix UBSAN: array-index-out-of-bounds in rds_cmsg_recv
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sharath Srinivasan <[email protected]>
[ Upstream commit 13e788deb7348cc88df34bed736c3b3b9927ea52 ]
Syzcaller UBSAN crash occurs in rds_cmsg_recv(),
which reads inc->i_rx_lat_trace[j + 1] with index 4 (3 + 1), but with array size of 4 (RDS_RX_MAX_TRACES).
Here 'j' is assigned from rs->rs_rx_trace[i] and in-turn from trace.rx_trace_pos[i] in rds_recv_track_latency(),
with both arrays sized 3 (RDS_MSG_RX_DGRAM_TRACE_MAX). So fix the off-by-one bounds check in rds_recv_track_latency() to prevent a potential crash in rds_cmsg_recv().
Found by syzcaller:
=================================================================
UBSAN: array-index-out-of-bounds in net/rds/recv.c:585:39 index 4 is out of range for type 'u64 [4]' CPU: 1 PID: 8058 Comm: syz-executor228 Not tainted 6.6.0-gd2f51b3516da #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014 Call Trace: <TASK> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0x136/0x150 lib/dump_stack.c:106 ubsan_epilogue lib/ubsan.c:217 [inline] __ubsan_handle_out_of_bounds+0xd5/0x130 lib/ubsan.c:348 rds_cmsg_recv+0x60d/0x700 net/rds/recv.c:585 rds_recvmsg+0x3fb/0x1610 net/rds/recv.c:716 sock_recvmsg_nosec net/socket.c:1044 [inline] sock_recvmsg+0xe2/0x160 net/socket.c:1066 __sys_recvfrom+0x1b6/0x2f0 net/socket.c:2246 __do_sys_recvfrom net/socket.c:2264 [inline] __se_sys_recvfrom net/socket.c:2260 [inline] __x64_sys_recvfrom+0xe0/0x1b0 net/socket.c:2260 do_syscall_x64 arch/x86/entry/common.c:51 [inline] do_syscall_64+0x40/0x110 arch/x86/entry/common.c:82 entry_SYSCALL_64_after_hwframe+0x63/0x6b ==================================================================
--- net/rds/af_rds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/rds/af_rds.c +1 -1
@@ -419,7 +419,7 @@ static int rds_recv_track_latency(struct rds_sock *rs, sockptr_t optval, rs->rs_rx_traces = trace.rx_traces;for (i =0 ; i < rs->rs_rx_traces; i++) { -if (trace.rx_trace_pos[i] >RDS_MSG_RX_DGRAM_TRACE_MAX ) { +if (trace.rx_trace_pos[i] >=RDS_MSG_RX_DGRAM_TRACE_MAX ) { rs->rs_rx_traces =0 ;return -EFAULT ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 89/185 netfs, fscache: Prevent Oops in fscache_put_cache()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
[ Upstream commit 3be0b3ed1d76c6703b9ee482b55f7e01c369cc68 ]
This function dereferences "cache" and then checks if it's IS_ERR_OR_NULL(). Check first, then dereference.
--- fs/fscache/cache.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/fscache/cache.c +2 -1
@@ -179,13 +179,14 @@ EXPORT_SYMBOL(fscache_acquire_cache);void fscache_put_cache (struct fscache_cache *cache,enum fscache_cache_trace where) { -unsigned int debug_id = cache->debug_id; +unsigned int debug_id;bool zero;int ref;if (IS_ERR_OR_NULL (cache))return ; + debug_id = cache->debug_id; zero =__refcount_dec_and_test (&cache->ref, &ref);trace_fscache_cache (debug_id, ref -1 , where);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 90/185 tracing: Ensure visibility when inserting an element into tracing_map
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Petr Pavlu <[email protected]>
[ Upstream commit 2b44760609e9eaafc9d234a6883d042fc21132a7 ]
Running the following two commands in parallel on a multi-processor AArch64 machine can sporadically produce an unexpected warning about duplicate histogram entries:
$ while true; do
echo hist:key=id.syscall:val=hitcount > \
/sys/kernel/debug/tracing/events/raw_syscalls/sys_enter/trigger
cat /sys/kernel/debug/tracing/events/raw_syscalls/sys_enter/hist
sleep 0.001
done
$ stress-ng --sysbadaddr $(nproc)The warning looks as follows:
[ 2911.172474] ------------[ cut here ]------------ [ 2911.173111] Duplicates detected: 1 [ 2911.173574] WARNING: CPU: 2 PID: 12247 at kernel/trace/tracing_map.c:983 tracing_map_sort_entries+0x3e0/0x408 [ 2911.174702] Modules linked in: iscsi_ibft(E) iscsi_boot_sysfs(E) rfkill(E) af_packet(E) nls_iso8859_1(E) nls_cp437(E) vfat(E) fat(E) ena(E) tiny_power_button(E) qemu_fw_cfg(E) button(E) fuse(E) efi_pstore(E) ip_tables(E) x_tables(E) xfs(E) libcrc32c(E) aes_ce_blk(E) aes_ce_cipher(E) crct10dif_ce(E) polyval_ce(E) polyval_generic(E) ghash_ce(E) gf128mul(E) sm4_ce_gcm(E) sm4_ce_ccm(E) sm4_ce(E) sm4_ce_cipher(E) sm4(E) sm3_ce(E) sm3(E) sha3_ce(E) sha512_ce(E) sha512_arm64(E) sha2_ce(E) sha256_arm64(E) nvme(E) sha1_ce(E) nvme_core(E) nvme_auth(E) t10_pi(E) sg(E) scsi_mod(E) scsi_common(E) efivarfs(E) [ 2911.174738] Unloaded tainted modules: cppc_cpufreq(E):1 [ 2911.180985] CPU: 2 PID: 12247 Comm: cat Kdump: loaded Tainted: G E 6.7.0-default #2 1b58bbb22c97e4399dc09f92d309344f69c44a01 [ 2911.182398] Hardware name: Amazon EC2 c7g.8xlarge/, BIOS 1.0 11/1/2018 [ 2911.183208] pstate: 61400005 (nZCv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--) [ 2911.184038] pc : tracing_map_sort_entries+0x3e0/0x408 [ 2911.184667] lr : tracing_map_sort_entries+0x3e0/0x408 [ 2911.185310] sp : ffff8000a1513900 [ 2911.185750] x29: ffff8000a1513900 x28: ffff0003f272fe80 x27: 0000000000000001 [ 2911.186600] x26: ffff0003f272fe80 x25: 0000000000000030 x24: 0000000000000008 [ 2911.187458] x23: ffff0003c5788000 x22: ffff0003c16710c8 x21: ffff80008017f180 [ 2911.188310] x20: ffff80008017f000 x19: ffff80008017f180 x18: ffffffffffffffff [ 2911.189160] x17: 0000000000000000 x16: 0000000000000000 x15: ffff8000a15134b8 [ 2911.190015] x14: 0000000000000000 x13: 205d373432323154 x12: 5b5d313131333731 [ 2911.190844] x11: 00000000fffeffff x10: 00000000fffeffff x9 : ffffd1b78274a13c [ 2911.191716] x8 : 000000000017ffe8 x7 : c0000000fffeffff x6 : 000000000057ffa8 [ 2911.192554] x5 : ffff0012f6c24ec0 x4 : 0000000000000000 x3 : ffff2e5b72b5d000 [ 2911.193404] x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff0003ff254480 [ 2911.194259] Call trace: [ 2911.194626] tracing_map_sort_entries+0x3e0/0x408 [ 2911.195220] hist_show+0x124/0x800 [ 2911.195692] seq_read_iter+0x1d4/0x4e8 [ 2911.196193] seq_read+0xe8/0x138 [ 2911.196638] vfs_read+0xc8/0x300 [ 2911.197078] ksys_read+0x70/0x108 [ 2911.197534] __arm64_sys_read+0x24/0x38 [ 2911.198046] invoke_syscall+0x78/0x108 [ 2911.198553] el0_svc_common.constprop.0+0xd0/0xf8 [ 2911.199157] do_el0_svc+0x28/0x40 [ 2911.199613] el0_svc+0x40/0x178 [ 2911.200048] el0t_64_sync_handler+0x13c/0x158 [ 2911.200621] el0t_64_sync+0x1a8/0x1b0 [ 2911.201115] ---[ end trace 0000000000000000 ]---
The problem appears to be caused by CPU reordering of writes issued from __tracing_map_insert().
The check for the presence of an element with a given key in this function is:
val = READ_ONCE(entry->val);
if (val && keys_match(key, val->key, map->key_size)) ...
The write of a new entry is:
elt = get_free_elt(map);
memcpy(elt->key, key, map->key_size);
entry->val = elt;
The "memcpy(elt->key, key, map->key_size);" and "entry->val = elt;" stores may become visible in the reversed order on another CPU. This second CPU might then incorrectly determine that a new key doesn't match an already present val->key and subsequently insert a new element, resulting in a duplicate.
Fix the problem by adding a write barrier between "memcpy(elt->key, key, map->key_size);" and "entry->val = elt;", and for good measure, also use WRITE_ONCE(entry->val, elt) for publishing the element. The sequence pairs with the mentioned "READ_ONCE(entry->val);" and the "val->key" check which has an address dependency.
The barrier is placed on a path executed when adding an element for a new key. Subsequent updates targeting the same key remain unaffected.
Quoted 1 line
From the user's perspective, the issue was introduced by commit
c193707dde77 ("tracing: Remove code which merges duplicates"), which followed commit cbf4100efb8f ("tracing: Add support to detect and avoid duplicates"). The previous code operated differently; it inherently expected potential races which result in duplicates but merged them later when they occurred.
--- kernel/trace/tracing_map.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
kernel/trace/tracing_map.c +6 -1
@@ -574,7 +574,12 @@ __tracing_map_insert(struct tracing_map *map, void *key, bool lookup_only) }memcpy (elt->key, key, map->key_size); - entry->val = elt; +/* +* Ensure the initialization is visible and +* publish the elt. +*/ +smp_wmb (); +WRITE_ONCE (entry->val, elt);atomic64_inc (&map->hits);return entry->val;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 91/185 afs: Hide silly-rename files from userspace
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <[email protected]>
[ Upstream commit 57e9d49c54528c49b8bffe6d99d782ea051ea534 ]
There appears to be a race between silly-rename files being created/removed and various userspace tools iterating over the contents of a directory, leading to such errors as:
find: './kernel/.tmp_cpio_dir/include/dt-bindings/reset/.__afs2080': No such file or directory
tar: ./include/linux/greybus/.__afs3C95: File removed before we read it
when building a kernel.
Fix afs_readdir() so that it doesn't return .__afsXXXX silly-rename files to userspace. This doesn't stop them being looked up directly by name as we need to be able to look them up from within the kernel as part of the silly-rename algorithm.
--- fs/afs/dir.c | 8 ++++++++ 1 file changed, 8 insertions(+)
fs/afs/dir.c +8 -0
@@ -473,6 +473,14 @@ static int afs_dir_iterate_block(struct afs_vnode *dvnode,continue ; } +/* Don't expose silly rename entries to userspace. */ +if (nlen >6 && + dire->u.name[0 ] =='.' && + ctx->actor != afs_lookup_filldir && + ctx->actor != afs_lookup_one_filldir && +memcmp (dire->u.name,".__afs" ,6 ) ==0 ) +continue ; +/* found the next entry */ if (!dir_emit(ctx, dire->u.name, nlen, ntohl(dire->u.vnode),
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 92/185 tcp: Add memory barrier to tcp_push()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Salvatore Dipietro <[email protected]>
[ Upstream commit 7267e8dcad6b2f9fce05a6a06335d7040acbc2b6 ]
On CPUs with weak memory models, reads and updates performed by tcp_push to the sk variables can get reordered leaving the socket throttled when it should not. The tasklet running tcp_wfree() may also not observe the memory updates in time and will skip flushing any packets throttled by tcp_push(), delaying the sending. This can pathologically cause 40ms extra latency due to bad interactions with delayed acks.
Adding a memory barrier in tcp_push removes the bug, similarly to the previous commit bf06200e732d ("tcp: tsq: fix nonagle handling"). smp_mb__after_atomic() is used to not incur in unnecessary overhead on x86 since not affected.
Patch has been tested using an AWS c7g.2xlarge instance with Ubuntu 22.04 and Apache Tomcat 9.0.83 running the basic servlet below:
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HelloWorldServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
OutputStreamWriter osw = new OutputStreamWriter(response.getOutputStream(),"UTF-8");
String s = "a".repeat(3096);
osw.write(s,0,s.length());
osw.flush();
}
}Load was applied using wrk2 (https://github.com/kinvolk/wrk2) from an AWS c6i.8xlarge instance. Before the patch an additional 40ms latency from P99.99+ values is observed while, with the patch, the extra latency disappears.
No patch and tcp_autocorking=1
./wrk -t32 -c128 -d40s --latency -R10000 http://172.31.60.173:8080/hello/hello
...
50.000% 0.91ms 75.000% 1.13ms 90.000% 1.46ms 99.000% 1.74ms 99.900% 1.89ms 99.990% 41.95ms <<< 40+ ms extra latency 99.999% 48.32ms 100.000% 48.96ms
With patch and tcp_autocorking=1
./wrk -t32 -c128 -d40s --latency -R10000 http://172.31.60.173:8080/hello/hello
...
50.000% 0.90ms 75.000% 1.13ms 90.000% 1.45ms 99.000% 1.72ms 99.900% 1.83ms 99.990% 2.11ms <<< no 40+ ms extra latency 99.999% 2.53ms 100.000% 2.62ms
Patch has been also tested on x86 (m7i.2xlarge instance) which it is not affected by this issue and the patch doesn't introduce any additional delay.
--- net/ipv4/tcp.c | 1 + 1 file changed, 1 insertion(+)
net/ipv4/tcp.c +1 -0
@@ -718,6 +718,7 @@ void tcp_push(struct sock *sk, int flags, int mss_now,if (!test_bit (TSQ_THROTTLED , &sk->sk_tsq_flags)) {NET_INC_STATS (sock_net (sk),LINUX_MIB_TCPAUTOCORKING );set_bit (TSQ_THROTTLED , &sk->sk_tsq_flags); +smp_mb__after_atomic (); }/* It is possible TX completion already happened * before we set TSQ_THROTTLED.
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 93/185 netlink: fix potential sleeping issue in mqueue_flush_file
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhengchao Shao <[email protected]>
[ Upstream commit 234ec0b6034b16869d45128b8cd2dc6ffe596f04 ]
I analyze the potential sleeping issue of the following processes:
Thread A Thread B ... netlink_create //ref = 1 do_mq_notify ... sock = netlink_getsockbyfilp ... //ref = 2 info->notify_sock = sock; ... ... netlink_sendmsg
... skb = netlink_alloc_large_skb //skb->head is vmalloced
... netlink_unicast
... sk = netlink_getsockbyportid //ref = 3
... netlink_sendskb
... __netlink_sendskb
... skb_queue_tail //put skb to sk_receive_queue
... sock_put //ref = 2
... ...
... netlink_release
... deferred_put_nlk_sk //ref = 1mqueue_flush_file
spin_lock
remove_notification
netlink_sendskb
sock_put //ref = 0
sk_free
...
__sk_destruct
netlink_sock_destruct
skb_queue_purge //get skb from sk_receive_queue
...
__skb_queue_purge_reason
kfree_skb_reason
__kfree_skb
...
skb_release_all
skb_release_head_state
netlink_skb_destructor
vfree(skb->head) //sleeping while holding spinlockIn netlink_sendmsg, if the memory pointed to by skb->head is allocated by vmalloc, and is put to sk_receive_queue queue, also the skb is not freed. When the mqueue executes flush, the sleeping bug will occur. Use vfree_atomic instead of vfree in netlink_skb_destructor to solve the issue.
--- net/netlink/af_netlink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/netlink/af_netlink.c +1 -1
@@ -374,7 +374,7 @@ static void netlink_skb_destructor(struct sk_buff *skb)if (is_vmalloc_addr (skb->head)) {if (!skb->cloned || !atomic_dec_return (&(skb_shinfo (skb)->dataref))) -vfree (skb->head); +vfree_atomic (skb->head); skb->head =NULL ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 94/185 ipv6: init the accept_queues spinlocks in inet6_create
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhengchao Shao <[email protected]>
[ Upstream commit 435e202d645c197dcfd39d7372eb2a56529b6640 ]
In commit 198bc90e0e73("tcp: make sure init the accept_queue's spinlocks once"), the spinlocks of accept_queue are initialized only when socket is created in the inet4 scenario. The locks are not initialized when socket is created in the inet6 scenario. The kernel reports the following error:
INFO: trying to register non-static key.
The code is fine but needs lockdep annotation, or maybe
you didn't initialize this object before use?
turning off the locking correctness validator.
Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011 Call Trace: <TASK> dump_stack_lvl (lib/dump_stack.c:107) register_lock_class (kernel/locking/lockdep.c:1289) __lock_acquire (kernel/locking/lockdep.c:5015) lock_acquire.part.0 (kernel/locking/lockdep.c:5756) _raw_spin_lock_bh (kernel/locking/spinlock.c:178) inet_csk_listen_stop (net/ipv4/inet_connection_sock.c:1386) tcp_disconnect (net/ipv4/tcp.c:2981) inet_shutdown (net/ipv4/af_inet.c:935) __sys_shutdown (./include/linux/file.h:32 net/socket.c:2438) __x64_sys_shutdown (net/socket.c:2445) do_syscall_64 (arch/x86/entry/common.c:52) entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:129) RIP: 0033:0x7f52ecd05a3d 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 ab a3 0e 00 f7 d8 64 89 01 48
RSP: 002b:00007f52ecf5dde8 EFLAGS: 00000293 ORIG_RAX: 0000000000000030
RAX: ffffffffffffffda RBX: 00007f52ecf5e640 RCX: 00007f52ecd05a3d
RDX: 00007f52ecc8b188 RSI: 0000000000000000 RDI: 0000000000000004
RBP: 00007f52ecf5de20 R08: 00007ffdae45c69f R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000293 R12: 00007f52ecf5e640
R13: 0000000000000000 R14: 00007f52ecc8b060 R15: 00007ffdae45c6e0
--- net/ipv6/af_inet6.c | 3 +++ 1 file changed, 3 insertions(+)
net/ipv6/af_inet6.c +3 -0
@@ -199,6 +199,9 @@ static int inet6_create(struct net *net, struct socket *sock, int protocol,if (INET_PROTOSW_REUSE & answer_flags) sk->sk_reuse =SK_CAN_REUSE ; +if (INET_PROTOSW_ICSK & answer_flags) +inet_init_csk_locks (sk); + inet =inet_sk (sk); inet->is_icsk = (INET_PROTOSW_ICSK & answer_flags) !=0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 95/185 net/mlx5: DR, Use the right GVMI number for drop action
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yevgeny Kliteynik <[email protected]>
[ Upstream commit 5665954293f13642f9c052ead83c1e9d8cff186f ]
When FW provides ICM addresses for drop RX/TX, the provided capability is 64 bits that contain its GVMI as well as the ICM address itself. In case of TX DROP this GVMI is different from the GVMI that the domain is operating on.
This patch fixes the action to use these GVMI IDs, as provided by FW.
--- drivers/net/ethernet/mellanox/mlx5/core/steering/dr_action.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_action.c +1 -0
@@ -673,6 +673,7 @@ int mlx5dr_actions_build_ste_arr(struct mlx5dr_matcher *matcher,switch (action_type) {case DR_ACTION_TYP_DROP : attr.final_icm_addr = nic_dmn->drop_icm_addr; + attr.hit_gvmi = nic_dmn->drop_icm_addr >>48 ;break ;case DR_ACTION_TYP_FT : dest_action = action;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 96/185 net/mlx5: DR, Cant go to uplink vport on RX rule
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yevgeny Kliteynik <[email protected]>
[ Upstream commit 5b2a2523eeea5f03d39a9d1ff1bad2e9f8eb98d2 ]
Go-To-Vport action on RX is not allowed when the vport is uplink. In such case, the packet should be dropped.
--- .../mellanox/mlx5/core/steering/dr_action.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_action.c +11 -5
@@ -762,11 +762,17 @@ int mlx5dr_actions_build_ste_arr(struct mlx5dr_matcher *matcher, action->sampler->tx_icm_addr;break ;case DR_ACTION_TYP_VPORT : - attr.hit_gvmi = action->vport->caps->vhca_gvmi; - dest_action = action; - attr.final_icm_addr = rx_rule ? - action->vport->caps->icm_address_rx : - action->vport->caps->icm_address_tx; +if (unlikely (rx_rule && action->vport->caps->num ==MLX5_VPORT_UPLINK )) { +/* can't go to uplink on RX rule - dropping instead */ + attr.final_icm_addr = nic_dmn->drop_icm_addr; + attr.hit_gvmi = nic_dmn->drop_icm_addr >>48 ; + }else { + attr.hit_gvmi = action->vport->caps->vhca_gvmi; + dest_action = action; + attr.final_icm_addr = rx_rule ? + action->vport->caps->icm_address_rx : + action->vport->caps->icm_address_tx; + }break ;case DR_ACTION_TYP_POP_VLAN : if (!rx_rule && !(dmn->ste_ctx->actions_caps &
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 97/185 net/mlx5: Use mlx5 device constant for selecting CQ period mode for ASO
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rahul Rameshbabu <[email protected]>
[ Upstream commit 20cbf8cbb827094197f3b17db60d71449415db1e ]
mlx5 devices have specific constants for choosing the CQ period mode. These constants do not have to match the constants used by the kernel software API for DIM period mode selection.
--- drivers/net/ethernet/mellanox/mlx5/core/lib/aso.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlx5/core/lib/aso.c +1 -1
@@ -98,7 +98,7 @@ static int create_aso_cq(struct mlx5_aso_cq *cq, void *cqc_data)mlx5_fill_page_frag_array (&cq->wq_ctrl.buf, (__be64 *)MLX5_ADDR_OF (create_cq_in, in, pas)); -MLX5_SET (cqc, cqc, cq_period_mode,DIM_CQ_PERIOD_MODE_START_FROM_EQE ); +MLX5_SET (cqc, cqc, cq_period_mode,MLX5_CQ_PERIOD_MODE_START_FROM_EQE );MLX5_SET (cqc, cqc, c_eqn_or_apu_element, eqn);MLX5_SET (cqc, cqc, uar_page, mdev->priv.uar->index); MLX5_SET(cqc, cqc, log_page_size, cq->wq_ctrl.buf.page_shift -
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 98/185 net/mlx5e: Allow software parsing when IPsec crypto is enabled
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Leon Romanovsky <[email protected]>
[ Upstream commit 20f5468a7988dedd94a57ba8acd65ebda6a59723 ]
All ConnectX devices have software parsing capability enabled, but it is more correct to set allow_swp only if capability exists, which for IPsec means that crypto offload is supported.
--- drivers/net/ethernet/mellanox/mlx5/core/en/params.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en/params.c +2 -2
@@ -990,8 +990,8 @@ void mlx5e_build_sq_param(struct mlx5_core_dev *mdev,void *wq =MLX5_ADDR_OF (sqc, sqc, wq);bool allow_swp; - allow_swp = -mlx5_geneve_tx_allowed (mdev) || !!mlx5_ipsec_device_caps (mdev); + allow_swp =mlx5_geneve_tx_allowed (mdev) || + (mlx5_ipsec_device_caps (mdev) &MLX5_IPSEC_CAP_CRYPTO );mlx5e_build_sq_param_common (mdev, param);MLX5_SET (wq, wq, log_wq_sz, params->log_sq_size);MLX5_SET (sqc, sqc, allow_swp, allow_swp);
Signature · 1 line
2.43.0
Re: [PATCH 6.1 098/185] net/mlx5e: Allow software parsing when IPsec crypto is enabled
Hi Greg,
Quoted 25 lines · Greg Kroah-Hartman
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Leon Romanovsky <[email protected]>
[ Upstream commit
20f5468a7988dedd94a57ba8acd65ebda6a59723]All ConnectX devices have software parsing capability enabled, but it is more correct to set
allow_swponly if capability exists, which for IPsec means that crypto offload is supported.Fixes 2451da081a34 ("net/mlx5: Unify device IPsec capabilities check")Signed-off-by Leon Romanovsky <[email protected]>Signed-off-by Saeed Mahameed <[email protected]>Signed-off-by Sasha Levin <[email protected]>--- drivers/net/ethernet/mellanox/mlx5/core/en/params.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)drivers/net/ethernet/mellanox/mlx5/core/en/params.c +0
-0
drivers/net/ethernet/mellanox/mlx5/core/en/params.c void mlx5e_build_sq_param(struct mlx5_core_dev *mdev, · line 997
Quoted 10 lines
drivers/net/ethernet/mellanox/mlx5/core/en/params.c +2
-2@@ -990,8 +990,8 @@ void mlx5e_build_sq_param(struct mlx5_core_dev *mdev,void *wq =MLX5_ADDR_OF (sqc, sqc, wq);bool allow_swp; - allow_swp = -mlx5_geneve_tx_allowed (mdev) || !!mlx5_ipsec_device_caps (mdev); + allow_swp =mlx5_geneve_tx_allowed (mdev) || + (mlx5_ipsec_device_caps (mdev) &MLX5_IPSEC_CAP_CRYPTO );mlx5e_build_sq_param_common (mdev, param);MLX5_SET (wq, wq, log_wq_sz, params->log_sq_size);MLX5_SET (sqc, sqc, allow_swp, allow_swp);
When compiling 6.1.76-rc1 this commit causes the following build failure:
drivers/net/ethernet/mellanox/mlx5/core/en/params.c: In function ‘mlx5e_build_sq_param’:drivers/net/ethernet/mellanox/mlx5/core/en/params.c:994:53: error: ‘MLX5_IPSEC_CAP_CRYPTO’ undeclared (first use in this function)
994 | (mlx5_ipsec_device_caps(mdev) & MLX5_IPSEC_CAP_CRYPTO);
| ^~~~~~~~~~~~~~~~~~~~~drivers/net/ethernet/mellanox/mlx5/core/en/params.c:994:53: note: each undeclared identifier is reported only once for each function it appears in
Attached the used config.
Regards,
Salvatore
Re: [PATCH 6.1 098/185] net/mlx5e: Allow software parsing when IPsec crypto is enabled
Hi,
Quoted 42 lines · Salvatore Bonaccorso
Hi Greg,
Quoted 25 lines · Greg Kroah-Hartman
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Leon Romanovsky <[email protected]>
[ Upstream commit
20f5468a7988dedd94a57ba8acd65ebda6a59723]All ConnectX devices have software parsing capability enabled, but it is more correct to set
allow_swponly if capability exists, which for IPsec means that crypto offload is supported.Fixes 2451da081a34 ("net/mlx5: Unify device IPsec capabilities check")Signed-off-by Leon Romanovsky <[email protected]>Signed-off-by Saeed Mahameed <[email protected]>Signed-off-by Sasha Levin <[email protected]>--- drivers/net/ethernet/mellanox/mlx5/core/en/params.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)drivers/net/ethernet/mellanox/mlx5/core/en/params.c +0
-0drivers/net/ethernet/mellanox/mlx5/core/en/params.c void mlx5e_build_sq_param(struct mlx5_core_dev *mdev, · line 997
Quoted 10 lines
drivers/net/ethernet/mellanox/mlx5/core/en/params.c +2
-2@@ -990,8 +990,8 @@ void mlx5e_build_sq_param(struct mlx5_core_dev *mdev,void *wq =MLX5_ADDR_OF (sqc, sqc, wq);bool allow_swp; - allow_swp = -mlx5_geneve_tx_allowed (mdev) || !!mlx5_ipsec_device_caps (mdev); + allow_swp =mlx5_geneve_tx_allowed (mdev) || + (mlx5_ipsec_device_caps (mdev) &MLX5_IPSEC_CAP_CRYPTO );mlx5e_build_sq_param_common (mdev, param);MLX5_SET (wq, wq, log_wq_sz, params->log_sq_size);MLX5_SET (sqc, sqc, allow_swp, allow_swp);When compiling 6.1.76-rc1 this commit causes the following build failure:
Quoted 7 lines
drivers/net/ethernet/mellanox/mlx5/core/en/params.c: In function ‘mlx5e_build_sq_param’:drivers/net/ethernet/mellanox/mlx5/core/en/params.c:994:53: error: ‘MLX5_IPSEC_CAP_CRYPTO’ undeclared (first use in this function)994 | (mlx5_ipsec_device_caps(mdev) & MLX5_IPSEC_CAP_CRYPTO); | ^~~~~~~~~~~~~~~~~~~~~
drivers/net/ethernet/mellanox/mlx5/core/en/params.c:994:53: note: each undeclared identifier is reported only once for each function it appears inAttached the used config.
Mailserver from [email protected], [email protected] rejected the message due to the attached test.config.xz . Resending this here again without attachment so that might reach Leon and Saeed as well.
Regards,
Salvatore
Greg Kroah-Hartman
maintainerRe: [PATCH 6.1 098/185] net/mlx5e: Allow software parsing when IPsec crypto is enabled
Quoted 51 lines · Salvatore Bonaccorso
Hi,
Quoted 48 lines · Salvatore Bonaccorso
Hi Greg,
Quoted 25 lines · Greg Kroah-Hartman
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Leon Romanovsky <[email protected]>
[ Upstream commit
20f5468a7988dedd94a57ba8acd65ebda6a59723]All ConnectX devices have software parsing capability enabled, but it is more correct to set
allow_swponly if capability exists, which for IPsec means that crypto offload is supported.Fixes 2451da081a34 ("net/mlx5: Unify device IPsec capabilities check")Signed-off-by Leon Romanovsky <[email protected]>Signed-off-by Saeed Mahameed <[email protected]>Signed-off-by Sasha Levin <[email protected]>--- drivers/net/ethernet/mellanox/mlx5/core/en/params.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)drivers/net/ethernet/mellanox/mlx5/core/en/params.c +0
-0drivers/net/ethernet/mellanox/mlx5/core/en/params.c void mlx5e_build_sq_param(struct mlx5_core_dev *mdev, · line 997
Quoted 10 lines
drivers/net/ethernet/mellanox/mlx5/core/en/params.c +2
-2@@ -990,8 +990,8 @@ void mlx5e_build_sq_param(struct mlx5_core_dev *mdev,void *wq =MLX5_ADDR_OF (sqc, sqc, wq);bool allow_swp; - allow_swp = -mlx5_geneve_tx_allowed (mdev) || !!mlx5_ipsec_device_caps (mdev); + allow_swp =mlx5_geneve_tx_allowed (mdev) || + (mlx5_ipsec_device_caps (mdev) &MLX5_IPSEC_CAP_CRYPTO );mlx5e_build_sq_param_common (mdev, param);MLX5_SET (wq, wq, log_wq_sz, params->log_sq_size);MLX5_SET (sqc, sqc, allow_swp, allow_swp);When compiling 6.1.76-rc1 this commit causes the following build failure:
drivers/net/ethernet/mellanox/mlx5/core/en/params.c: In function ‘mlx5e_build_sq_param’:drivers/net/ethernet/mellanox/mlx5/core/en/params.c:994:53: error: ‘MLX5_IPSEC_CAP_CRYPTO’ undeclared (first use in this function)994 | (mlx5_ipsec_device_caps(mdev) & MLX5_IPSEC_CAP_CRYPTO); | ^~~~~~~~~~~~~~~~~~~~~
drivers/net/ethernet/mellanox/mlx5/core/en/params.c:994:53: note: each undeclared identifier is reported only once for each function it appears in
Quoted 5 lines
Quoted 1 line
Attached the used config.
Mailserver from [email protected], [email protected] rejected the message due to the attached test.config.xz . Resending this here again without attachment so that might reach Leon and Saeed as well.
This works for me, I don't know why it's failing elsewhere. I'd like to drop it but I really don't want to unless we can figure it out.
greg k-h
Re: [PATCH 6.1 098/185] net/mlx5e: Allow software parsing when IPsec crypto is enabled
Hi Greg,
Quoted 52 lines · Greg Kroah-Hartman
Quoted 51 lines · Salvatore Bonaccorso
Hi,
Quoted 48 lines · Salvatore Bonaccorso
Hi Greg,
Quoted 25 lines · Greg Kroah-Hartman
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Leon Romanovsky <[email protected]>
[ Upstream commit
20f5468a7988dedd94a57ba8acd65ebda6a59723]All ConnectX devices have software parsing capability enabled, but it is more correct to set
allow_swponly if capability exists, which for IPsec means that crypto offload is supported.Fixes 2451da081a34 ("net/mlx5: Unify device IPsec capabilities check")Signed-off-by Leon Romanovsky <[email protected]>Signed-off-by Saeed Mahameed <[email protected]>Signed-off-by Sasha Levin <[email protected]>--- drivers/net/ethernet/mellanox/mlx5/core/en/params.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)drivers/net/ethernet/mellanox/mlx5/core/en/params.c +0
-0drivers/net/ethernet/mellanox/mlx5/core/en/params.c void mlx5e_build_sq_param(struct mlx5_core_dev *mdev, · line 997
Quoted 10 lines
drivers/net/ethernet/mellanox/mlx5/core/en/params.c +2
-2@@ -990,8 +990,8 @@ void mlx5e_build_sq_param(struct mlx5_core_dev *mdev,void *wq =MLX5_ADDR_OF (sqc, sqc, wq);bool allow_swp; - allow_swp = -mlx5_geneve_tx_allowed (mdev) || !!mlx5_ipsec_device_caps (mdev); + allow_swp =mlx5_geneve_tx_allowed (mdev) || + (mlx5_ipsec_device_caps (mdev) &MLX5_IPSEC_CAP_CRYPTO );mlx5e_build_sq_param_common (mdev, param);MLX5_SET (wq, wq, log_wq_sz, params->log_sq_size);MLX5_SET (sqc, sqc, allow_swp, allow_swp);When compiling 6.1.76-rc1 this commit causes the following build failure:
drivers/net/ethernet/mellanox/mlx5/core/en/params.c: In function ‘mlx5e_build_sq_param’:drivers/net/ethernet/mellanox/mlx5/core/en/params.c:994:53: error: ‘MLX5_IPSEC_CAP_CRYPTO’ undeclared (first use in this function)994 | (mlx5_ipsec_device_caps(mdev) & MLX5_IPSEC_CAP_CRYPTO); | ^~~~~~~~~~~~~~~~~~~~~
drivers/net/ethernet/mellanox/mlx5/core/en/params.c:994:53: note: each undeclared identifier is reported only once for each function it appears in
Quoted 8 lines
Quoted 5 lines
Quoted 1 line
Attached the used config.
Mailserver from [email protected], [email protected] rejected the message due to the attached test.config.xz . Resending this here again without attachment so that might reach Leon and Saeed as well.
This works for me, I don't know why it's failing elsewhere. I'd like to drop it but I really don't want to unless we can figure it out.
There is an explanation and a proposed fix by Florian Fainelli
<[email protected]> in https://lore.kernel.org/stable/[email protected]/
Hope this helps!
Regards,
Salvatore
Greg Kroah-Hartman
maintainerRe: [PATCH 6.1 098/185] net/mlx5e: Allow software parsing when IPsec crypto is enabled
Quoted 61 lines · Salvatore Bonaccorso
Hi Greg,
Quoted 58 lines · Greg Kroah-Hartman
Quoted 56 lines · Salvatore Bonaccorso
Hi,
Quoted 42 lines · Salvatore Bonaccorso
Hi Greg,
Quoted 25 lines · Greg Kroah-Hartman
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Leon Romanovsky <[email protected]>
[ Upstream commit
20f5468a7988dedd94a57ba8acd65ebda6a59723]All ConnectX devices have software parsing capability enabled, but it is more correct to set
allow_swponly if capability exists, which for IPsec means that crypto offload is supported.Fixes 2451da081a34 ("net/mlx5: Unify device IPsec capabilities check")Signed-off-by Leon Romanovsky <[email protected]>Signed-off-by Saeed Mahameed <[email protected]>Signed-off-by Sasha Levin <[email protected]>--- drivers/net/ethernet/mellanox/mlx5/core/en/params.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)drivers/net/ethernet/mellanox/mlx5/core/en/params.c +0
-0drivers/net/ethernet/mellanox/mlx5/core/en/params.c void mlx5e_build_sq_param(struct mlx5_core_dev *mdev, · line 997
Quoted 10 lines
drivers/net/ethernet/mellanox/mlx5/core/en/params.c +2
-2@@ -990,8 +990,8 @@ void mlx5e_build_sq_param(struct mlx5_core_dev *mdev,void *wq =MLX5_ADDR_OF (sqc, sqc, wq);bool allow_swp; - allow_swp = -mlx5_geneve_tx_allowed (mdev) || !!mlx5_ipsec_device_caps (mdev); + allow_swp =mlx5_geneve_tx_allowed (mdev) || + (mlx5_ipsec_device_caps (mdev) &MLX5_IPSEC_CAP_CRYPTO );mlx5e_build_sq_param_common (mdev, param);MLX5_SET (wq, wq, log_wq_sz, params->log_sq_size);MLX5_SET (sqc, sqc, allow_swp, allow_swp);When compiling 6.1.76-rc1 this commit causes the following build failure:
Quoted 7 lines
drivers/net/ethernet/mellanox/mlx5/core/en/params.c: In function ‘mlx5e_build_sq_param’:drivers/net/ethernet/mellanox/mlx5/core/en/params.c:994:53: error: ‘MLX5_IPSEC_CAP_CRYPTO’ undeclared (first use in this function)994 | (mlx5_ipsec_device_caps(mdev) & MLX5_IPSEC_CAP_CRYPTO); | ^~~~~~~~~~~~~~~~~~~~~
drivers/net/ethernet/mellanox/mlx5/core/en/params.c:994:53: note: each undeclared identifier is reported only once for each function it appears inAttached the used config.
Mailserver from [email protected], [email protected] rejected the message due to the attached test.config.xz . Resending this here again without attachment so that might reach Leon and Saeed as well.
Quoted 7 lines
Quoted 2 lines
This works for me, I don't know why it's failing elsewhere. I'd like to drop it but I really don't want to unless we can figure it out.
There is an explanation and a proposed fix by Florian Fainelli
<[email protected]> in https://lore.kernel.org/stable/[email protected]/Hope this helps!
Yup, that looks good, I'll push out a new -rc2 with it, thanks!
greg k-h
Greg Kroah-Hartman
maintainerPATCH 99/185 net/mlx5e: fix a double-free in arfs_create_groups
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhipeng Lu <[email protected]>
[ Upstream commit 3c6d5189246f590e4e1f167991558bdb72a4738b ]
When in allocated by kvzalloc fails, arfs_create_groups will free ft->g and return an error. However, arfs_create_table, the only caller of arfs_create_groups, will hold this error and call to mlx5e_destroy_flow_table, in which the ft->g will be freed again.
--- .../net/ethernet/mellanox/mlx5/core/en_arfs.c | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c +15 -11
@@ -255,11 +255,13 @@ static int arfs_create_groups(struct mlx5e_flow_table *ft, ft->g =kcalloc (MLX5E_ARFS_NUM_GROUPS ,sizeof (*ft->g),GFP_KERNEL ); - in =kvzalloc (inlen,GFP_KERNEL ); -if (!in || !ft->g) { -kfree (ft->g); -kvfree (in); +if (!ft->g)return -ENOMEM ; + + in =kvzalloc (inlen,GFP_KERNEL ); +if (!in) { + err = -ENOMEM ; + goto err_free_g; } mc =MLX5_ADDR_OF (create_flow_group_in, in, match_criteria);
@@ -279,7 +281,7 @@ static int arfs_create_groups(struct mlx5e_flow_table *ft,break ;default : err = -EINVAL ; - goto out; + goto err_free_in; }switch (type) {
@@ -301,7 +303,7 @@ static int arfs_create_groups(struct mlx5e_flow_table *ft,break ;default : err = -EINVAL ; - goto out; + goto err_free_in; }MLX5_SET_CFG (in, match_criteria_enable,MLX5_MATCH_OUTER_HEADERS );
@@ -310,7 +312,7 @@ static int arfs_create_groups(struct mlx5e_flow_table *ft,MLX5_SET_CFG (in, end_flow_index, ix -1 ); ft->g[ft->num_groups] =mlx5_create_flow_group (ft->t, in);if (IS_ERR (ft->g[ft->num_groups])) - goto err; + goto err_clean_group; ft->num_groups++;memset (in,0 , inlen);
@@ -319,18 +321,20 @@ static int arfs_create_groups(struct mlx5e_flow_table *ft,MLX5_SET_CFG (in, end_flow_index, ix -1 ); ft->g[ft->num_groups] =mlx5_create_flow_group (ft->t, in);if (IS_ERR (ft->g[ft->num_groups])) - goto err; + goto err_clean_group; ft->num_groups++;kvfree (in);return 0 ; -err: +err_clean_group: err =PTR_ERR (ft->g[ft->num_groups]); ft->g[ft->num_groups] =NULL ; -out: +err_free_in:kvfree (in); - +err_free_g: +kfree (ft->g); + ft->g =NULL ;return err; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 100/185 net/mlx5e: fix a potential double-free in fs_any_create_groups
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dinghao Liu <[email protected]>
[ Upstream commit aef855df7e1bbd5aa4484851561211500b22707e ]
When kcalloc() for ft->g succeeds but kvzalloc() for in fails, fs_any_create_groups() will free ft->g. However, its caller fs_any_create_table() will free ft->g again through calling mlx5e_destroy_flow_table(), which will lead to a double-free. Fix this by setting ft->g to NULL in fs_any_create_groups().
--- drivers/net/ethernet/mellanox/mlx5/core/en/fs_tt_redirect.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/mellanox/mlx5/core/en/fs_tt_redirect.c +1 -0
@@ -436,6 +436,7 @@ static int fs_any_create_groups(struct mlx5e_flow_table *ft) in =kvzalloc (inlen,GFP_KERNEL );if (!in || !ft->g) {kfree (ft->g); + ft->g =NULL ;kvfree (in);return -ENOMEM ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 101/185 rcu: Defer RCU kthreads wakeup when CPU is dying
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frederic Weisbecker <[email protected]>
[ Upstream commit e787644caf7628ad3269c1fbd321c3255cf51710 ]
When the CPU goes idle for the last time during the CPU down hotplug process, RCU reports a final quiescent state for the current CPU. If this quiescent state propagates up to the top, some tasks may then be woken up to complete the grace period: the main grace period kthread and/or the expedited main workqueue (or kworker).
If those kthreads have a SCHED_FIFO policy, the wake up can indirectly arm the RT bandwith timer to the local offline CPU. Since this happens after hrtimers have been migrated at CPUHP_AP_HRTIMERS_DYING stage, the timer gets ignored. Therefore if the RCU kthreads are waiting for RT bandwidth to be available, they may never be actually scheduled.
This triggers TREE03 rcutorture hangs:
rcu: INFO: rcu_preempt self-detected stall on CPU rcu: 4-...!: (1 GPs behind) idle=9874/1/0x4000000000000000 softirq=0/0 fqs=20 rcuc=21071 jiffies(starved) rcu: (t=21035 jiffies g=938281 q=40787 ncpus=6) rcu: rcu_preempt kthread starved for 20964 jiffies! g938281 f0x0 RCU_GP_WAIT_FQS(5) ->state=0x0 ->cpu=0 rcu: Unless rcu_preempt kthread gets sufficient CPU time, OOM is now expected behavior. rcu: RCU grace-period kthread stack dump: task:rcu_preempt state:R running task stack:14896 pid:14 tgid:14 ppid:2 flags:0x00004000 Call Trace: <TASK> __schedule+0x2eb/0xa80 schedule+0x1f/0x90 schedule_timeout+0x163/0x270 ? __pfx_process_timeout+0x10/0x10 rcu_gp_fqs_loop+0x37c/0x5b0 ? __pfx_rcu_gp_kthread+0x10/0x10 rcu_gp_kthread+0x17c/0x200 kthread+0xde/0x110 ? __pfx_kthread+0x10/0x10 ret_from_fork+0x2b/0x40 ? __pfx_kthread+0x10/0x10 ret_from_fork_asm+0x1b/0x30 </TASK>
The situation can't be solved with just unpinning the timer. The hrtimer infrastructure and the nohz heuristics involved in finding the best remote target for an unpinned timer would then also need to handle enqueues from an offline CPU in the most horrendous way.
So fix this on the RCU side instead and defer the wake up to an online CPU if it's too late for the local one.
--- kernel/rcu/tree.c | 34 +++++++++++++++++++++++++++++++++- kernel/rcu/tree_exp.h | 3 +-- 2 files changed, 34 insertions(+), 3 deletions(-)
kernel/rcu/tree.c +33 -1
@@ -1051,6 +1051,38 @@ static bool rcu_future_gp_cleanup(struct rcu_node *rnp)return needmore; } +static void swake_up_one_online_ipi (void *arg) +{ +struct swait_queue_head *wqh = arg; + +swake_up_one (wqh); +} + +static void swake_up_one_online (struct swait_queue_head *wqh) +{ +int cpu =get_cpu (); + +/* +* If called from rcutree_report_cpu_starting(), wake up +* is dangerous that late in the CPU-down hotplug process. The +* scheduler might queue an ignored hrtimer. Defer the wake up +* to an online CPU instead. +*/ +if (unlikely (cpu_is_offline (cpu))) { +int target; + + target =cpumask_any_and (housekeeping_cpumask (HK_TYPE_RCU ), + cpu_online_mask); + +smp_call_function_single (target, swake_up_one_online_ipi, + wqh,0 ); +put_cpu (); + }else { +put_cpu (); +swake_up_one (wqh); + } +} +/* * Awaken the grace-period kthread. Don't do a self-awaken (unless in an * interrupt or softirq handler, in which case we just might immediately
@@ -1075,7 +1107,7 @@ static void rcu_gp_kthread_wake(void)return ;WRITE_ONCE (rcu_state.gp_wake_time, jiffies);WRITE_ONCE (rcu_state.gp_wake_seq,READ_ONCE (rcu_state.gp_seq)); -swake_up_one (&rcu_state.gp_wq); +swake_up_one_online (&rcu_state.gp_wq); }/*
kernel/rcu/tree_exp.h +1 -2
@@ -172,7 +172,6 @@ static bool sync_rcu_exp_done_unlocked(struct rcu_node *rnp)return ret; } -/* * Report the exit from RCU read-side critical section for the last task * that queued itself during or before the current expedited preemptible-RCU
@@ -200,7 +199,7 @@ static void __rcu_report_exp_rnp(struct rcu_node *rnp,raw_spin_unlock_irqrestore_rcu_node (rnp, flags);if (wake) {smp_mb ();/* EGP done before wake_up(). */ -swake_up_one (&rcu_state.expedited_wq); +swake_up_one_online (&rcu_state.expedited_wq); }break ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 102/185 netfilter: nft_limit: reject configurations that cause integer overflow
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal <[email protected]>
[ Upstream commit c9d9eb9c53d37cdebbad56b91e40baf42d5a97aa ]
Reject bogus configs where internal token counter wraps around. This only occurs with very very large requests, such as 17gbyte/s.
Its better to reject this rather than having incorrect ratelimit.
--- net/netfilter/nft_limit.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-)
net/netfilter/nft_limit.c +16 -7
@@ -58,17 +58,19 @@ static inline bool nft_limit_eval(struct nft_limit_priv *priv, u64 cost)static int nft_limit_init (struct nft_limit_priv *priv,const struct nlattr *const tb[],bool pkts) { +u64 unit, tokens, rate_with_burst;bool invert = false; -u64 unit, tokens;if (tb[NFTA_LIMIT_RATE ] ==NULL || tb[NFTA_LIMIT_UNIT ] ==NULL )return -EINVAL ; priv->rate =be64_to_cpu (nla_get_be64 (tb[NFTA_LIMIT_RATE ])); +if (priv->rate ==0 ) +return -EINVAL ; + unit =be64_to_cpu (nla_get_be64 (tb[NFTA_LIMIT_UNIT ])); - priv->nsecs = unit *NSEC_PER_SEC ; -if (priv->rate ==0 || priv->nsecs < unit) +if (check_mul_overflow (unit,NSEC_PER_SEC , &priv->nsecs))return -EOVERFLOW ;if (tb[NFTA_LIMIT_BURST ])
@@ -77,18 +79,25 @@ static int nft_limit_init(struct nft_limit_priv *priv,if (pkts && priv->burst ==0 ) priv->burst =NFT_LIMIT_PKT_BURST_DEFAULT ; -if (priv->rate + priv->burst < priv->rate) +if (check_add_overflow (priv->rate, priv->burst, &rate_with_burst))return -EOVERFLOW ;if (pkts) { - tokens =div64_u64 (priv->nsecs, priv->rate) * priv->burst; +u64 tmp =div64_u64 (priv->nsecs, priv->rate); + +if (check_mul_overflow (tmp, priv->burst, &tokens)) +return -EOVERFLOW ; }else { +u64 tmp; +/* The token bucket size limits the number of tokens can be * accumulated. tokens_max specifies the bucket size. * tokens_max = unit * (rate + burst) / rate. */ - tokens =div64_u64 (priv->nsecs * (priv->rate + priv->burst), - priv->rate); +if (check_mul_overflow (priv->nsecs, rate_with_burst, &tmp)) +return -EOVERFLOW ; + + tokens =div64_u64 (tmp, priv->rate); }if (tb[NFTA_LIMIT_FLAGS ]) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 103/185 btrfs: fix infinite directory reads
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
commit 9b378f6ad48cfa195ed868db9123c09ee7ec5ea2 upstream.
The readdir implementation currently processes always up to the last index it finds. This however can result in an infinite loop if the directory has a large number of entries such that they won't all fit in the given buffer passed to the readdir callback, that is, dir_emit() returns a non-zero value. Because in that case readdir() will be called again and if in the meanwhile new directory entries were added and we still can't put all the remaining entries in the buffer, we keep repeating this over and over.
The following C program and test script reproduce the problem:
$ cat /mnt/readdir_prog.c #include <sys/types.h> #include <dirent.h> #include <stdio.h>
int main(int argc, char *argv[])
{
DIR *dir = opendir(".");
struct dirent *dd; while ((dd = readdir(dir))) {
printf("%s\n", dd->d_name);
rename(dd->d_name, "TEMPFILE");
rename("TEMPFILE", dd->d_name);
}
closedir(dir);}
$ gcc -o /mnt/readdir_prog /mnt/readdir_prog.c
$ cat test.sh #!/bin/bash
DEV=/dev/sdi
MNT=/mnt/sdi
mkfs.btrfs -f $DEV &> /dev/null
#mkfs.xfs -f $DEV &> /dev/null
#mkfs.ext4 -F $DEV &> /dev/null
mount $DEV $MNT
mkdir $MNT/testdir
for ((i = 1; i <= 2000; i++)); do
echo -n > $MNT/testdir/file_$i
done
cd $MNT/testdir
/mnt/readdir_prog
cd /mnt
umount $MNT
This behaviour is surprising to applications and it's unlike ext4, xfs, tmpfs, vfat and other filesystems, which always finish. In this case where new entries were added due to renames, some file names may be reported more than once, but this varies according to each filesystem - for example ext4 never reported the same file more than once while xfs reports the first 13 file names twice.
So change our readdir implementation to track the last index number when opendir() is called and then make readdir() never process beyond that index number. This gives the same behaviour as ext4.
--- fs/btrfs/ctree.h | 1 fs/btrfs/delayed-inode.c | 5 + fs/btrfs/delayed-inode.h | 1 fs/btrfs/inode.c | 131 ++++++++++++++++++++++++++++------------------- 4 files changed, 84 insertions(+), 54 deletions(-)
fs/btrfs/ctree.h +1 -0
@@ -1552,6 +1552,7 @@ struct btrfs_drop_extents_args {struct btrfs_file_private {void *filldir_buf; +u64 last_index; };
fs/btrfs/delayed-inode.c +3 -2
@@ -1665,6 +1665,7 @@ int btrfs_inode_delayed_dir_index_count( }bool btrfs_readdir_get_delayed_items (struct inode *inode, +u64 last_index,struct list_head *ins_list,struct list_head *del_list) {
@@ -1684,14 +1685,14 @@ bool btrfs_readdir_get_delayed_items(strmutex_lock (&delayed_node->mutex); item =__btrfs_first_delayed_insertion_item (delayed_node); -while (item) { +while (item && item->index <= last_index) {refcount_inc (&item->refs);list_add_tail (&item->readdir_list, ins_list); item =__btrfs_next_delayed_item (item); } item =__btrfs_first_delayed_deletion_item (delayed_node); -while (item) { +while (item && item->index <= last_index) {refcount_inc (&item->refs);list_add_tail (&item->readdir_list, del_list); item =__btrfs_next_delayed_item (item);
fs/btrfs/delayed-inode.h +1 -0
@@ -148,6 +148,7 @@ void btrfs_destroy_delayed_inodes(struct/* Used for readdir() */ bool btrfs_readdir_get_delayed_items (struct inode *inode, +u64 last_index,struct list_head *ins_list,struct list_head *del_list); void btrfs_readdir_put_delayed_items(struct inode *inode,
fs/btrfs/inode.c +79 -52
165 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 104/185 btrfs: set last dir index to the current last index when opening dir
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
commit 357950361cbc6d54fb68ed878265c647384684ae upstream.
When opening a directory for reading it, we set the last index where we stop iteration to the value in struct btrfs_inode::index_cnt. That value does not match the index of the most recently added directory entry but it's instead the index number that will be assigned the next directory entry.
This means that if after the call to opendir(3) new directory entries are added, a readdir(3) call will return the first new directory entry. This is fine because POSIX says the following [1]:
"If a file is removed from or added to the directory after the most
recent call to opendir() or rewinddir(), whether a subsequent call to readdir() returns an entry for that file is unspecified."
For example for the test script from commit 9b378f6ad48c ("btrfs: fix infinite directory reads"), where we have 2000 files in a directory, ext4 doesn't return any new directory entry after opendir(3), while xfs returns the first 13 new directory entries added after the opendir(3) call.
If we move to a shorter example with an empty directory when opendir(3) is called, and 2 files added to the directory after the opendir(3) call, then readdir(3) on btrfs will return the first file, ext4 and xfs return the 2 files (but in a different order). A test program for this, reported by Ian Johnson, is the following:
#include <dirent.h>
#include <stdio.h>
int main(void) {
DIR *dir = opendir("test"); FILE *file;
file = fopen("test/1", "w");
fwrite("1", 1, 1, file);
fclose(file);
file = fopen("test/2", "w");
fwrite("2", 1, 1, file);
fclose(file);
struct dirent *entry;
while ((entry = readdir(dir))) {
printf("%s\n", entry->d_name);
}
closedir(dir);
return 0;}
To make this less odd, change the behaviour to never return new entries that were added after the opendir(3) call. This is done by setting the last_index field of the struct btrfs_file_private attached to the directory's file handle with a value matching btrfs_inode::index_cnt minus 1, since that value always matches the index of the next new directory entry and not the index of the most recently added entry.
[1] https://pubs.opengroup.org/onlinepubs/007904875/functions/readdir_r.html
--- fs/btrfs/inode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/btrfs/inode.c +2 -1
@@ -6011,7 +6011,8 @@ static int btrfs_get_dir_last_index(stru } } - *index = dir->index_cnt; +/* index_cnt is the index number of next new entry, so decrement it. */ + *index = dir->index_cnt -1 ;return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 105/185 btrfs: refresh dir last index during a rewinddir(3) call
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
commit e60aa5da14d01fed8411202dbe4adf6c44bd2a57 upstream.
When opening a directory we find what's the index of its last entry and then store it in the directory's file handle private data (struct btrfs_file_private::last_index), so that in the case new directory entries are added to a directory after an opendir(3) call we don't end up in an infinite loop (see commit 9b378f6ad48c ("btrfs: fix infinite directory reads")) when calling readdir(3).
However once rewinddir(3) is called, POSIX states [1] that any new directory entries added after the previous opendir(3) call, must be returned by subsequent calls to readdir(3):
"The rewinddir() function shall reset the position of the directory
stream to which dirp refers to the beginning of the directory. It shall also cause the directory stream to refer to the current state of the corresponding directory, as a call to opendir() would have done."
We currently don't refresh the last_index field of the struct btrfs_file_private associated to the directory, so after a rewinddir(3) we are not returning any new entries added after the opendir(3) call.
Fix this by finding the current last index of the directory when llseek is called against the directory.
This can be reproduced by the following C program provided by Ian Johnson:
#include <dirent.h>
#include <stdio.h>
int main(void) {
DIR *dir = opendir("test"); FILE *file;
file = fopen("test/1", "w");
fwrite("1", 1, 1, file);
fclose(file);
file = fopen("test/2", "w");
fwrite("2", 1, 1, file);
fclose(file);
rewinddir(dir);
struct dirent *entry;
while ((entry = readdir(dir))) {
printf("%s\n", entry->d_name);
}
closedir(dir);
return 0;}
--- fs/btrfs/inode.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
fs/btrfs/inode.c +14 -1
@@ -6049,6 +6049,19 @@ static int btrfs_opendir(struct inode *ireturn 0 ; } +static loff_t btrfs_dir_llseek (struct file *file,loff_t offset,int whence) +{ +struct btrfs_file_private *private = file->private_data; +int ret; + + ret =btrfs_get_dir_last_index (BTRFS_I (file_inode (file)), + &private->last_index); +if (ret) +return ret; + +return generic_file_llseek (file, offset, whence); +} +struct dir_entry {u64 ino;u64 offset;
@@ -11429,7 +11442,7 @@ static const struct inode_operations btr };static const struct file_operations btrfs_dir_file_operations = { - .llseek = generic_file_llseek, + .llseek = btrfs_dir_llseek, .read = generic_read_dir, .iterate_shared = btrfs_real_readdir, .open = btrfs_opendir,
Greg Kroah-Hartman
maintainerPATCH 106/185 btrfs: fix race between reading a directory and adding entries to it
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
commit 8e7f82deb0c0386a03b62e30082574347f8b57d5 upstream.
When opening a directory (opendir(3)) or rewinding it (rewinddir(3)), we are not holding the directory's inode locked, and this can result in later attempting to add two entries to the directory with the same index number, resulting in a transaction abort, with -EEXIST (-17), when inserting the second delayed dir index. This results in a trace like the following:
Sep 11 22:34:59 myhostname kernel: BTRFS error (device dm-3): err add delayed dir index item(name: cockroach-stderr.log) into the insertion tree of the delayed node(root id: 5, inode id: 4539217, errno: -17) Sep 11 22:34:59 myhostname kernel: ------------[ cut here ]------------ Sep 11 22:34:59 myhostname kernel: kernel BUG at fs/btrfs/delayed-inode.c:1504! Sep 11 22:34:59 myhostname kernel: invalid opcode: 0000 [#1] PREEMPT SMP NOPTI Sep 11 22:34:59 myhostname kernel: CPU: 0 PID: 7159 Comm: cockroach Not tainted 6.4.15-200.fc38.x86_64 #1 Sep 11 22:34:59 myhostname kernel: Hardware name: ASUS ESC500 G3/P9D WS, BIOS 2402 06/27/2018 Sep 11 22:34:59 myhostname kernel: RIP: 0010:btrfs_insert_delayed_dir_index+0x1da/0x260 Sep 11 22:34:59 myhostname kernel: Code: eb dd 48 (...) Sep 11 22:34:59 myhostname kernel: RSP: 0000:ffffa9980e0fbb28 EFLAGS: 00010282 Sep 11 22:34:59 myhostname kernel: RAX: 0000000000000000 RBX: ffff8b10b8f4a3c0 RCX: 0000000000000000 Sep 11 22:34:59 myhostname kernel: RDX: 0000000000000000 RSI: ffff8b177ec21540 RDI: ffff8b177ec21540 Sep 11 22:34:59 myhostname kernel: RBP: ffff8b110cf80888 R08: 0000000000000000 R09: ffffa9980e0fb938 Sep 11 22:34:59 myhostname kernel: R10: 0000000000000003 R11: ffffffff86146508 R12: 0000000000000014 Sep 11 22:34:59 myhostname kernel: R13: ffff8b1131ae5b40 R14: ffff8b10b8f4a418 R15: 00000000ffffffef Sep 11 22:34:59 myhostname kernel: FS: 00007fb14a7fe6c0(0000) GS:ffff8b177ec00000(0000) knlGS:0000000000000000 Sep 11 22:34:59 myhostname kernel: CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 Sep 11 22:34:59 myhostname kernel: CR2: 000000c00143d000 CR3: 00000001b3b4e002 CR4: 00000000001706f0 Sep 11 22:34:59 myhostname kernel: Call Trace: Sep 11 22:34:59 myhostname kernel: <TASK> Sep 11 22:34:59 myhostname kernel: ? die+0x36/0x90 Sep 11 22:34:59 myhostname kernel: ? do_trap+0xda/0x100 Sep 11 22:34:59 myhostname kernel: ? btrfs_insert_delayed_dir_index+0x1da/0x260 Sep 11 22:34:59 myhostname kernel: ? do_error_trap+0x6a/0x90 Sep 11 22:34:59 myhostname kernel: ? btrfs_insert_delayed_dir_index+0x1da/0x260 Sep 11 22:34:59 myhostname kernel: ? exc_invalid_op+0x50/0x70 Sep 11 22:34:59 myhostname kernel: ? btrfs_insert_delayed_dir_index+0x1da/0x260 Sep 11 22:34:59 myhostname kernel: ? asm_exc_invalid_op+0x1a/0x20 Sep 11 22:34:59 myhostname kernel: ? btrfs_insert_delayed_dir_index+0x1da/0x260 Sep 11 22:34:59 myhostname kernel: ? btrfs_insert_delayed_dir_index+0x1da/0x260 Sep 11 22:34:59 myhostname kernel: btrfs_insert_dir_item+0x200/0x280 Sep 11 22:34:59 myhostname kernel: btrfs_add_link+0xab/0x4f0 Sep 11 22:34:59 myhostname kernel: ? ktime_get_real_ts64+0x47/0xe0 Sep 11 22:34:59 myhostname kernel: btrfs_create_new_inode+0x7cd/0xa80 Sep 11 22:34:59 myhostname kernel: btrfs_symlink+0x190/0x4d0 Sep 11 22:34:59 myhostname kernel: ? schedule+0x5e/0xd0 Sep 11 22:34:59 myhostname kernel: ? __d_lookup+0x7e/0xc0 Sep 11 22:34:59 myhostname kernel: vfs_symlink+0x148/0x1e0 Sep 11 22:34:59 myhostname kernel: do_symlinkat+0x130/0x140 Sep 11 22:34:59 myhostname kernel: __x64_sys_symlinkat+0x3d/0x50 Sep 11 22:34:59 myhostname kernel: do_syscall_64+0x5d/0x90 Sep 11 22:34:59 myhostname kernel: ? syscall_exit_to_user_mode+0x2b/0x40 Sep 11 22:34:59 myhostname kernel: ? do_syscall_64+0x6c/0x90 Sep 11 22:34:59 myhostname kernel: entry_SYSCALL_64_after_hwframe+0x72/0xdc
The race leading to the problem happens like this:
1) Directory inode X is loaded into memory, its ->index_cnt field is initialized to (u64)-1 (at btrfs_alloc_inode());
2) Task A is adding a new file to directory X, holding its vfs inode lock, and calls btrfs_set_inode_index() to get an index number for the entry.
Because the inode's index_cnt field is set to (u64)-1 it calls btrfs_inode_delayed_dir_index_count() which fails because no dir index entries were added yet to the delayed inode and then it calls btrfs_set_inode_index_count(). This functions finds the last dir index key and then sets index_cnt to that index value + 1. It found that the last index key has an offset of 100. However before it assigns a value of 101 to index_cnt...
3) Task B calls opendir(3), ending up at btrfs_opendir(), where the VFS lock for inode X is not taken, so it calls btrfs_get_dir_last_index() and sees index_cnt still with a value of (u64)-1. Because of that it calls btrfs_inode_delayed_dir_index_count() which fails since no dir index entries were added to the delayed inode yet, and then it also calls btrfs_set_inode_index_count(). This also finds that the last index key has an offset of 100, and before it assigns the value 101 to the index_cnt field of inode X...
4) Task A assigns a value of 101 to index_cnt. And then the code flow goes to btrfs_set_inode_index() where it increments index_cnt from 101 to 102. Task A then creates a delayed dir index entry with a sequence number of 101 and adds it to the delayed inode;
5) Task B assigns 101 to the index_cnt field of inode X;
6) At some later point when someone tries to add a new entry to the directory, btrfs_set_inode_index() will return 101 again and shortly after an attempt to add another delayed dir index key with index number 101 will fail with -EEXIST resulting in a transaction abort.
Fix this by locking the inode at btrfs_get_dir_last_index(), which is only only used when opening a directory or attempting to lseek on it.
--- fs/btrfs/inode.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
fs/btrfs/inode.c +7 -4
@@ -6000,21 +6000,24 @@ out:static int btrfs_get_dir_last_index (struct btrfs_inode *dir,u64 *index) { -if (dir->index_cnt == (u64)-1 ) { -int ret; +int ret =0 ; +btrfs_inode_lock (&dir->vfs_inode,0 ); +if (dir->index_cnt == (u64)-1 ) { ret =btrfs_inode_delayed_dir_index_count (dir);if (ret) { ret =btrfs_set_inode_index_count (dir);if (ret) -return ret; + goto out; } }/* index_cnt is the index number of next new entry, so decrement it. */ *index = dir->index_cnt -1 ; +out: +btrfs_inode_unlock (&dir->vfs_inode,0 ); -return 0 ; +return ret; }/*
Greg Kroah-Hartman
maintainerPATCH 107/185 netfilter: nf_tables: restrict anonymous set and map names to 16 bytes
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal <[email protected]>
[ Upstream commit b462579b2b86a8f5230543cadd3a4836be27baf7 ]
nftables has two types of sets/maps, one where userspace defines the name, and anonymous sets/maps, where userspace defines a template name.
For the latter, kernel requires presence of exactly one "%d". nftables uses "__set%d" and "__map%d" for this. The kernel will expand the format specifier and replaces it with the smallest unused number.
As-is, userspace could define a template name that allows to move the set name past the 256 bytes upperlimit (post-expansion).
I don't see how this could be a problem, but I would prefer if userspace cannot do this, so add a limit of 16 bytes for the '%d' template name.
16 bytes is the old total upper limit for set names that existed when nf_tables was merged initially.
--- net/netfilter/nf_tables_api.c | 4 ++++ 1 file changed, 4 insertions(+)
net/netfilter/nf_tables_api.c +4 -0
@@ -24,6 +24,7 @@#include <net/sock.h> #define NFT_MODULE_AUTOLOAD_LIMIT (MODULE_NAME_LEN - sizeof("nft-expr-255-")) +#define NFT_SET_MAX_ANONLEN 16unsigned int nf_tables_net_id__read_mostly ;
@@ -4127,6 +4128,9 @@ static int nf_tables_set_alloc_name(struct nft_ctx *ctx, struct nft_set *set,if (p[1 ] !='d' ||strchr (p +2 ,'%' ))return -EINVAL ; +if (strnlen (name,NFT_SET_MAX_ANONLEN ) >=NFT_SET_MAX_ANONLEN ) +return -EINVAL ; + inuse = (unsigned long *)get_zeroed_page (GFP_KERNEL );if (inuse ==NULL )return -ENOMEM ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 108/185 netfilter: nf_tables: validate NFPROTO_* family
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pablo Neira Ayuso <[email protected]>
[ Upstream commit d0009effa8862c20a13af4cb7475d9771b905693 ]
Several expressions explicitly refer to NF_INET_* hook definitions from expr->ops->validate, however, family is not validated.
Bail out with EOPNOTSUPP in case they are used from unsupported families.
--- net/netfilter/nft_compat.c | 12 ++++++++++++ net/netfilter/nft_flow_offload.c | 5 +++++ net/netfilter/nft_nat.c | 5 +++++ net/netfilter/nft_rt.c | 5 +++++ net/netfilter/nft_socket.c | 5 +++++ net/netfilter/nft_synproxy.c | 7 +++++-- net/netfilter/nft_tproxy.c | 5 +++++ net/netfilter/nft_xfrm.c | 5 +++++ 8 files changed, 47 insertions(+), 2 deletions(-)
net/netfilter/nft_compat.c +12 -0
@@ -349,6 +349,12 @@ static int nft_target_validate(const struct nft_ctx *ctx,unsigned int hook_mask =0 ;int ret; +if (ctx->family !=NFPROTO_IPV4 && + ctx->family !=NFPROTO_IPV6 && + ctx->family !=NFPROTO_BRIDGE && + ctx->family !=NFPROTO_ARP ) +return -EOPNOTSUPP ; +if (nft_is_base_chain (ctx->chain)) {const struct nft_base_chain *basechain =nft_base_chain (ctx->chain);
@@ -592,6 +598,12 @@ static int nft_match_validate(const struct nft_ctx *ctx,unsigned int hook_mask =0 ;int ret; +if (ctx->family !=NFPROTO_IPV4 && + ctx->family !=NFPROTO_IPV6 && + ctx->family !=NFPROTO_BRIDGE && + ctx->family !=NFPROTO_ARP ) +return -EOPNOTSUPP ; +if (nft_is_base_chain (ctx->chain)) {const struct nft_base_chain *basechain =nft_base_chain (ctx->chain);
net/netfilter/nft_flow_offload.c +5 -0
@@ -380,6 +380,11 @@ static int nft_flow_offload_validate(const struct nft_ctx *ctx, {unsigned int hook_mask = (1 <<NF_INET_FORWARD ); +if (ctx->family !=NFPROTO_IPV4 && + ctx->family !=NFPROTO_IPV6 && + ctx->family !=NFPROTO_INET ) +return -EOPNOTSUPP ; +return nft_chain_validate_hooks (ctx->chain, hook_mask); }
net/netfilter/nft_nat.c +5 -0
@@ -142,6 +142,11 @@ static int nft_nat_validate(const struct nft_ctx *ctx,struct nft_nat *priv =nft_expr_priv (expr);int err; +if (ctx->family !=NFPROTO_IPV4 && + ctx->family !=NFPROTO_IPV6 && + ctx->family !=NFPROTO_INET ) +return -EOPNOTSUPP ; + err =nft_chain_validate_dependency (ctx->chain,NFT_CHAIN_T_NAT );if (err <0 )return err;
net/netfilter/nft_rt.c +5 -0
@@ -166,6 +166,11 @@ static int nft_rt_validate(const struct nft_ctx *ctx, const struct nft_expr *expconst struct nft_rt *priv =nft_expr_priv (expr);unsigned int hooks; +if (ctx->family !=NFPROTO_IPV4 && + ctx->family !=NFPROTO_IPV6 && + ctx->family !=NFPROTO_INET ) +return -EOPNOTSUPP ; +switch (priv->key) {case NFT_RT_NEXTHOP4 :case NFT_RT_NEXTHOP6 :
net/netfilter/nft_socket.c +5 -0
@@ -242,6 +242,11 @@ static int nft_socket_validate(const struct nft_ctx *ctx,const struct nft_expr *expr, const struct nft_data **data) { + if (ctx->family != NFPROTO_IPV4 && + ctx->family != NFPROTO_IPV6 && + ctx->family != NFPROTO_INET) + return -EOPNOTSUPP; + return nft_chain_validate_hooks(ctx->chain, (1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_IN) |
net/netfilter/nft_synproxy.c +5 -2
@@ -186,7 +186,6 @@ static int nft_synproxy_do_init(const struct nft_ctx *ctx,break ;#endif case NFPROTO_INET : -case NFPROTO_BRIDGE : err =nf_synproxy_ipv4_init (snet, ctx->net);if (err) goto nf_ct_failure;
@@ -219,7 +218,6 @@ static void nft_synproxy_do_destroy(const struct nft_ctx *ctx)break ;#endif case NFPROTO_INET : -case NFPROTO_BRIDGE :nf_synproxy_ipv4_fini (snet, ctx->net);nf_synproxy_ipv6_fini (snet, ctx->net);break ;
@@ -253,6 +251,11 @@ static int nft_synproxy_validate(const struct nft_ctx *ctx,const struct nft_expr *expr, const struct nft_data **data) { + if (ctx->family != NFPROTO_IPV4 && + ctx->family != NFPROTO_IPV6 && + ctx->family != NFPROTO_INET) + return -EOPNOTSUPP; + return nft_chain_validate_hooks(ctx->chain, (1 << NF_INET_LOCAL_IN) | (1 << NF_INET_FORWARD)); }
net/netfilter/nft_tproxy.c +5 -0
@@ -316,6 +316,11 @@ static int nft_tproxy_validate(const struct nft_ctx *ctx,const struct nft_expr *expr, const struct nft_data **data) { + if (ctx->family != NFPROTO_IPV4 && + ctx->family != NFPROTO_IPV6 && + ctx->family != NFPROTO_INET) + return -EOPNOTSUPP; + return nft_chain_validate_hooks(ctx->chain, 1 << NF_INET_PRE_ROUTING); }
net/netfilter/nft_xfrm.c +5 -0
@@ -235,6 +235,11 @@ static int nft_xfrm_validate(const struct nft_ctx *ctx, const struct nft_expr *econst struct nft_xfrm *priv =nft_expr_priv (expr);unsigned int hooks; +if (ctx->family !=NFPROTO_IPV4 && + ctx->family !=NFPROTO_IPV6 && + ctx->family !=NFPROTO_INET ) +return -EOPNOTSUPP ; +switch (priv->dir) {case XFRM_POLICY_IN : hooks = (1 << NF_INET_FORWARD) |
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 109/185 net: stmmac: Wait a bit for the reset to take effect
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernd Edlinger <[email protected]>
[ Upstream commit a5f5eee282a0aae80227697e1d9c811b1726d31d ]
otherwise the synopsys_id value may be read out wrong, because the GMAC_VERSION register might still be in reset state, for at least 1 us after the reset is de-asserted.
Add a wait for 10 us before continuing to be on the safe side.
Quoted 1 line
From what have you got that delay value?
Just try and error, with very old linux versions and old gcc versions the synopsys_id was read out correctly most of the time (but not always), with recent linux versions and recnet gcc versions it was read out wrongly most of the time, but again not always.
I don't have access to the VHDL code in question, so I cannot tell why it takes so long to get the correct values, I also do not have more than a few hardware samples, so I cannot tell how long this timeout must be in worst case.
Experimentally I can tell that the register is read several times as zero immediately after the reset is de-asserted, also adding several no-ops is not enough, adding a printk is enough, also udelay(1) seems to be enough but I tried that not very often, and I have not access to many hardware samples to be 100% sure about the necessary delay. And since the udelay here is only executed once per device instance, it seems acceptable to delay the boot for 10 us.
BTW: my hardware's synopsys id is 0x37.
--- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +3 -0
@@ -7166,6 +7166,9 @@ int stmmac_dvr_probe(struct device *device,dev_err (priv->device,"unable to bring out of ahb reset: %pe\n" ,ERR_PTR (ret)); +/* Wait a bit for the reset to take effect */ +udelay (10 ); +/* Init MAC and get the capabilities */ ret =stmmac_hw_init (priv);if (ret)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 110/185 net: mvpp2: clear BM pool before initialization
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jenishkumar Maheshbhai Patel <[email protected]>
[ Upstream commit 9f538b415db862e74b8c5d3abbccfc1b2b6caa38 ]
Register value persist after booting the kernel using kexec which results in kernel panic. Thus clear the BM pool registers before initialisation to fix the issue.
--- .../net/ethernet/marvell/mvpp2/mvpp2_main.c | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-)
drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +26 -1
@@ -614,12 +614,38 @@ static void mvpp23_bm_set_8pool_mode(struct mvpp2 *priv)mvpp2_write (priv,MVPP22_BM_POOL_BASE_ADDR_HIGH_REG , val); } +/* Cleanup pool before actual initialization in the OS */ +static void mvpp2_bm_pool_cleanup (struct mvpp2 *priv,int pool_id) +{ +unsigned int thread =mvpp2_cpu_to_thread (priv,get_cpu ()); +u32 val; +int i; + +/* Drain the BM from all possible residues left by firmware */ +for (i =0 ; i <MVPP2_BM_POOL_SIZE_MAX ; i++) +mvpp2_thread_read (priv, thread,MVPP2_BM_PHY_ALLOC_REG (pool_id)); + +put_cpu (); + +/* Stop the BM pool */ + val =mvpp2_read (priv,MVPP2_BM_POOL_CTRL_REG (pool_id)); + val |=MVPP2_BM_STOP_MASK ; +mvpp2_write (priv,MVPP2_BM_POOL_CTRL_REG (pool_id), val); +} +static int mvpp2_bm_init (struct device *dev,struct mvpp2 *priv) {enum dma_data_direction dma_dir =DMA_FROM_DEVICE ;int i, err, poolnum =MVPP2_BM_POOLS_NUM ;struct mvpp2_port *port; +if (priv->percpu_pools) + poolnum =mvpp2_get_nrxqs (priv) *2 ; + +/* Clean up the pool state in case it contains stale state */ +for (i =0 ; i < poolnum; i++) +mvpp2_bm_pool_cleanup (priv, i); +if (priv->percpu_pools) {for (i =0 ; i < priv->port_count; i++) { port = priv->port_list[i];
@@ -629,7 +655,6 @@ static int mvpp2_bm_init(struct device *dev, struct mvpp2 *priv) } } - poolnum =mvpp2_get_nrxqs (priv) *2 ;for (i =0 ; i < poolnum; i++) {/* the pool in use */ int pn = i / (poolnum /2 );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 111/185 selftests: netdevsim: fix the udp_tunnel_nic test
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Kicinski <[email protected]>
[ Upstream commit 0879020a7817e7ce636372c016b4528f541c9f4d ]
This test is missing a whole bunch of checks for interface renaming and one ifup. Presumably it was only used on a system with renaming disabled and NetworkManager running.
--- .../selftests/drivers/net/netdevsim/udp_tunnel_nic.sh | 9 +++++++++ 1 file changed, 9 insertions(+)
tools/testing/selftests/drivers/net/netdevsim/udp_tunnel_nic.sh +9 -0
@@ -269,6 +269,7 @@ for port in 0 1; do echo 1 > $NSIM_DEV_SYS/new_port fi NSIM_NETDEV=`get_netdev_name old_netdevs` + ifconfig $NSIM_NETDEV up msg="new NIC device created" exp0=( 0 0 0 0 )
@@ -430,6 +431,7 @@ for port in 0 1; do fi echo $port > $NSIM_DEV_SYS/new_port + NSIM_NETDEV=`get_netdev_name old_netdevs` ifconfig $NSIM_NETDEV up overflow_table0 "overflow NIC table"
@@ -487,6 +489,7 @@ for port in 0 1; do fi echo $port > $NSIM_DEV_SYS/new_port + NSIM_NETDEV=`get_netdev_name old_netdevs` ifconfig $NSIM_NETDEV up overflow_table0 "overflow NIC table"
@@ -543,6 +546,7 @@ for port in 0 1; do fi echo $port > $NSIM_DEV_SYS/new_port + NSIM_NETDEV=`get_netdev_name old_netdevs` ifconfig $NSIM_NETDEV up overflow_table0 "destroy NIC"
@@ -572,6 +576,7 @@ for port in 0 1; do fi echo $port > $NSIM_DEV_SYS/new_port + NSIM_NETDEV=`get_netdev_name old_netdevs` ifconfig $NSIM_NETDEV up msg="create VxLANs v6"
@@ -632,6 +637,7 @@ for port in 0 1; do fi echo $port > $NSIM_DEV_SYS/new_port + NSIM_NETDEV=`get_netdev_name old_netdevs` ifconfig $NSIM_NETDEV up echo 110 > $NSIM_DEV_DFS/ports/$port/udp_ports_inject_error
@@ -687,6 +693,7 @@ for port in 0 1; do fi echo $port > $NSIM_DEV_SYS/new_port + NSIM_NETDEV=`get_netdev_name old_netdevs` ifconfig $NSIM_NETDEV up msg="create VxLANs v6"
@@ -746,6 +753,7 @@ for port in 0 1; do fi echo $port > $NSIM_DEV_SYS/new_port + NSIM_NETDEV=`get_netdev_name old_netdevs` ifconfig $NSIM_NETDEV up msg="create VxLANs v6"
@@ -876,6 +884,7 @@ msg="re-add a port" echo 2 > $NSIM_DEV_SYS/del_port echo 2 > $NSIM_DEV_SYS/new_port +NSIM_NETDEV=`get_netdev_name old_netdevs` check_tables msg="replace VxLAN in overflow table"
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 112/185 fjes: fix memleaks in fjes_hw_setup
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhipeng Lu <[email protected]>
[ Upstream commit f6cc4b6a3ae53df425771000e9c9540cce9b7bb1 ]
In fjes_hw_setup, it allocates several memory and delay the deallocation to the fjes_hw_exit in fjes_probe through the following call chain:
fjes_probe
|-> fjes_hw_init
|-> fjes_hw_setup
|-> fjes_hw_exit
However, when fjes_hw_setup fails, fjes_hw_exit won't be called and thus all the resources allocated in fjes_hw_setup will be leaked. In this patch, we free those resources in fjes_hw_setup and prevents such leaks.
--- drivers/net/fjes/fjes_hw.c | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-)
drivers/net/fjes/fjes_hw.c +30 -7
@@ -221,21 +221,25 @@ static int fjes_hw_setup(struct fjes_hw *hw) mem_size =FJES_DEV_REQ_BUF_SIZE (hw->max_epid); hw->hw_info.req_buf =kzalloc (mem_size,GFP_KERNEL ); -if (!(hw->hw_info.req_buf)) -return -ENOMEM ; +if (!(hw->hw_info.req_buf)) { + result = -ENOMEM ; + goto free_ep_info; + } hw->hw_info.req_buf_size = mem_size; mem_size =FJES_DEV_RES_BUF_SIZE (hw->max_epid); hw->hw_info.res_buf =kzalloc (mem_size,GFP_KERNEL ); -if (!(hw->hw_info.res_buf)) -return -ENOMEM ; +if (!(hw->hw_info.res_buf)) { + result = -ENOMEM ; + goto free_req_buf; + } hw->hw_info.res_buf_size = mem_size; result =fjes_hw_alloc_shared_status_region (hw);if (result) -return result; + goto free_res_buf; hw->hw_info.buffer_share_bit =0 ; hw->hw_info.buffer_unshare_reserve_bit =0 ;
@@ -246,11 +250,11 @@ static int fjes_hw_setup(struct fjes_hw *hw) result =fjes_hw_alloc_epbuf (&buf_pair->tx);if (result) -return result; + goto free_epbuf; result =fjes_hw_alloc_epbuf (&buf_pair->rx);if (result) -return result; + goto free_epbuf;spin_lock_irqsave (&hw->rx_status_lock, flags); fjes_hw_setup_epbuf(&buf_pair->tx, mac,
@@ -273,6 +277,25 @@ static int fjes_hw_setup(struct fjes_hw *hw)fjes_hw_init_command_registers (hw, ¶m);return 0 ; + +free_epbuf: +for (epidx =0 ; epidx < hw->max_epid ; epidx++) { +if (epidx == hw->my_epid) +continue ; +fjes_hw_free_epbuf (&hw->ep_shm_info[epidx].tx); +fjes_hw_free_epbuf (&hw->ep_shm_info[epidx].rx); + } +fjes_hw_free_shared_status_region (hw); +free_res_buf: +kfree (hw->hw_info.res_buf); + hw->hw_info.res_buf =NULL ; +free_req_buf: +kfree (hw->hw_info.req_buf); + hw->hw_info.req_buf =NULL ; +free_ep_info: +kfree (hw->ep_shm_info); + hw->ep_shm_info =NULL ; +return result; }static void fjes_hw_cleanup (struct fjes_hw *hw)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 113/185 net: fec: fix the unhandled context fault from smmu
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shenwei Wang <[email protected]>
[ Upstream commit 5e344807735023cd3a67c37a1852b849caa42620 ]
When repeatedly changing the interface link speed using the command below:
ethtool -s eth0 speed 100 duplex full
ethtool -s eth0 speed 1000 duplex full
The following errors may sometimes be reported by the ARM SMMU driver:
[ 5395.035364] fec 5b040000.ethernet eth0: Link is Down [ 5395.039255] arm-smmu 51400000.iommu: Unhandled context fault: fsr=0x402, iova=0x00000000, fsynr=0x100001, cbfrsynra=0x852, cb=2 [ 5398.108460] fec 5b040000.ethernet eth0: Link is Up - 100Mbps/Full -
flow control off
It is identified that the FEC driver does not properly stop the TX queue during the link speed transitions, and this results in the invalid virtual I/O address translations from the SMMU and causes the context faults.
--- drivers/net/ethernet/freescale/fec_main.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/ethernet/freescale/fec_main.c +2 -0
@@ -1917,6 +1917,7 @@ static void fec_enet_adjust_link(struct net_device *ndev)/* if any of the above changed restart the FEC */ if (status_change) { +netif_stop_queue (ndev);napi_disable (&fep->napi);netif_tx_lock_bh (ndev);fec_restart (ndev);
@@ -1926,6 +1927,7 @@ static void fec_enet_adjust_link(struct net_device *ndev) } }else {if (fep->link) { +netif_stop_queue (ndev);napi_disable (&fep->napi);netif_tx_lock_bh (ndev);fec_stop (ndev);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 114/185 nbd: always initialize struct msghdr completely
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
commit 78fbb92af27d0982634116c7a31065f24d092826 upstream.
syzbot complains that msg->msg_get_inq value can be uninitialized [1]
struct msghdr got many new fields recently, we should always make sure their values is zero by default.
[1]
BUG: KMSAN: uninit-value in tcp_recvmsg+0x686/0xac0 net/ipv4/tcp.c:2571 tcp_recvmsg+0x686/0xac0 net/ipv4/tcp.c:2571 inet_recvmsg+0x131/0x580 net/ipv4/af_inet.c:879 sock_recvmsg_nosec net/socket.c:1044 [inline] sock_recvmsg+0x12b/0x1e0 net/socket.c:1066 __sock_xmit+0x236/0x5c0 drivers/block/nbd.c:538 nbd_read_reply drivers/block/nbd.c:732 [inline] recv_work+0x262/0x3100 drivers/block/nbd.c:863 process_one_work kernel/workqueue.c:2627 [inline] process_scheduled_works+0x104e/0x1e70 kernel/workqueue.c:2700 worker_thread+0xf45/0x1490 kernel/workqueue.c:2781 kthread+0x3ed/0x540 kernel/kthread.c:388 ret_from_fork+0x66/0x80 arch/x86/kernel/process.c:147 ret_from_fork_asm+0x11/0x20 arch/x86/entry/entry_64.S:242
Local variable msg created at:
__sock_xmit+0x4c/0x5c0 drivers/block/nbd.c:513 nbd_read_reply drivers/block/nbd.c:732 [inline] recv_work+0x262/0x3100 drivers/block/nbd.c:863 CPU: 1 PID: 7465 Comm: kworker/u5:1 Not tainted 6.7.0-rc7-syzkaller-00041-gf016f7547aee #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 11/17/2023 Workqueue: nbd5-recv recv_work
--- drivers/block/nbd.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)
drivers/block/nbd.c +1 -5
@@ -494,7 +494,7 @@ static int __sock_xmit(struct nbd_device struct iov_iter *iter, int msg_flags, int *sent) { int result; -struct msghdr msg; +struct msghdr msg = { };unsigned int noreclaim_flag;if (unlikely (!sock)) {
@@ -509,10 +509,6 @@ static int __sock_xmit(struct nbd_device noreclaim_flag =memalloc_noreclaim_save (); do { sock->sk->sk_allocation = GFP_NOIO | __GFP_MEMALLOC; - msg.msg_name = NULL; - msg.msg_namelen = 0; - msg.msg_control = NULL; - msg.msg_controllen = 0; msg.msg_flags = msg_flags | MSG_NOSIGNAL; if (send)
Greg Kroah-Hartman
maintainerPATCH 115/185 btrfs: avoid copying BTRFS_ROOT_SUBVOL_DEAD flag to snapshot of subvolume being deleted
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Omar Sandoval <[email protected]>
commit 3324d0547861b16cf436d54abba7052e0c8aa9de upstream.
Sweet Tea spotted a race between subvolume deletion and snapshotting that can result in the root item for the snapshot having the BTRFS_ROOT_SUBVOL_DEAD flag set. The race is:
Thread 1 | Thread 2
----------------------------------------------|----------
btrfs_delete_subvolume |
btrfs_set_root_flags(BTRFS_ROOT_SUBVOL_DEAD)|
|btrfs_mksubvol
| down_read(subvol_sem)
| create_snapshot
| ...
| create_pending_snapshot
| copy root item from source
down_write(subvol_sem) |This flag is only checked in send and swap activate, which this would cause to fail mysteriously.
create_snapshot() now checks the root refs to reject a deleted subvolume, so we can fix this by locking subvol_sem earlier so that the BTRFS_ROOT_SUBVOL_DEAD flag and the root refs are updated atomically.
--- fs/btrfs/inode.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-)
fs/btrfs/inode.c +13 -9
@@ -4689,6 +4689,8 @@ int btrfs_delete_subvolume(struct inodeu64 root_flags;int ret; +down_write (&fs_info->subvol_sem); +/* * Don't allow to delete a subvolume with send in progress. This is * inside the inode lock so the error handling that has to drop the bit
@@ -4700,25 +4702,25 @@ int btrfs_delete_subvolume(struct inodebtrfs_warn (fs_info,"attempt to delete subvolume %llu during send" , dest->root_key.objectid); -return -EPERM ; + ret = -EPERM ; + goto out_up_write; }if (atomic_read (&dest->nr_swapfiles)) {spin_unlock (&dest->root_item_lock);btrfs_warn (fs_info,"attempt to delete subvolume %llu with active swapfile" , root->root_key.objectid); -return -EPERM ; + ret = -EPERM ; + goto out_up_write; } root_flags =btrfs_root_flags (&dest->root_item);btrfs_set_root_flags (&dest->root_item, root_flags |BTRFS_ROOT_SUBVOL_DEAD );spin_unlock (&dest->root_item_lock); -down_write (&fs_info->subvol_sem); - ret =may_destroy_subvol (dest);if (ret) - goto out_up_write; + goto out_undead;btrfs_init_block_rsv (&block_rsv,BTRFS_BLOCK_RSV_TEMP );/*
@@ -4728,7 +4730,7 @@ int btrfs_delete_subvolume(struct inode*/ ret =btrfs_subvolume_reserve_metadata (root, &block_rsv,5 , true);if (ret) - goto out_up_write; + goto out_undead; trans =btrfs_start_transaction (root,0 );if (IS_ERR (trans)) {
@@ -4794,15 +4796,17 @@ out_end_trans: inode->i_flags |=S_DEAD ; out_release:btrfs_subvolume_release_metadata (root, &block_rsv); -out_up_write: -up_write (&fs_info->subvol_sem); +out_undead:if (ret) {spin_lock (&dest->root_item_lock); root_flags =btrfs_root_flags (&dest->root_item);btrfs_set_root_flags (&dest->root_item, root_flags & ~BTRFS_ROOT_SUBVOL_DEAD );spin_unlock (&dest->root_item_lock); - }else { + } +out_up_write: +up_write (&fs_info->subvol_sem); +if (!ret) {d_invalidate (dentry);btrfs_prune_dentries (dest);ASSERT (dest->send_in_progress ==0 );
Greg Kroah-Hartman
maintainerPATCH 116/185 btrfs: ref-verify: free ref cache before clearing mount opt
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fedor Pchelkin <[email protected]>
commit f03e274a8b29d1d1c1bbd7f764766cb5ca537ab7 upstream.
As clearing REF_VERIFY mount option indicates there were some errors in a ref-verify process, a ref cache is not relevant anymore and should be freed.
btrfs_free_ref_cache() requires REF_VERIFY option being set so call it just before clearing the mount option.
Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
--- fs/btrfs/ref-verify.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
fs/btrfs/ref-verify.c +4 -2
@@ -883,8 +883,10 @@ int btrfs_ref_tree_mod(struct btrfs_fs_i out_unlock:spin_unlock (&fs_info->ref_verify_lock); out: -if (ret) +if (ret) { +btrfs_free_ref_cache (fs_info);btrfs_clear_opt (fs_info->mount_opt,REF_VERIFY ); + }return ret; }
@@ -1015,8 +1017,8 @@ int btrfs_build_ref_tree(struct btrfs_fs } }if (ret) { -btrfs_clear_opt (fs_info->mount_opt,REF_VERIFY );btrfs_free_ref_cache (fs_info); +btrfs_clear_opt (fs_info->mount_opt,REF_VERIFY ); }btrfs_free_path (path);return ret;
Greg Kroah-Hartman
maintainerPATCH 117/185 btrfs: tree-checker: fix inline ref size in error messages
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chung-Chiang Cheng <[email protected]>
commit f398e70dd69e6ceea71463a5380e6118f219197e upstream.
The error message should accurately reflect the size rather than the type.
--- fs/btrfs/tree-checker.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/btrfs/tree-checker.c +1 -1
@@ -1399,7 +1399,7 @@ static int check_extent_item(struct exteif (unlikely (ptr +btrfs_extent_inline_ref_size (inline_type) > end)) {extent_err (leaf, slot,"inline ref item overflows extent item, ptr %lu iref size %u end %lu" , - ptr, inline_type, end); + ptr,btrfs_extent_inline_ref_size (inline_type), end);return -EUCLEAN ; }
Greg Kroah-Hartman
maintainerPATCH 118/185 btrfs: dont warn if discard range is not aligned to sector
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Sterba <[email protected]>
commit a208b3f132b48e1f94f620024e66fea635925877 upstream.
There's a warning in btrfs_issue_discard() when the range is not aligned to 512 bytes, originally added in 4d89d377bbb0 ("btrfs:btrfs_issue_discard ensure offset/length are aligned to sector boundaries"). We can't do sub-sector writes anyway so the adjustment is the only thing that we can do and the warning is unnecessary.
--- fs/btrfs/extent-tree.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/btrfs/extent-tree.c +2 -1
@@ -1209,7 +1209,8 @@ static int btrfs_issue_discard(struct blu64 bytes_left, end;u64 aligned_start =ALIGN (start,1 <<9 ); -if (WARN_ON (start != aligned_start)) { +/* Adjust the range to be aligned to 512B sectors if necessary. */ +if (start != aligned_start) { len -= aligned_start - start; len =round_down (len,1 <<9 ); start = aligned_start;
Greg Kroah-Hartman
maintainerPATCH 119/185 btrfs: defrag: reject unknown flags of btrfs_ioctl_defrag_range_args
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qu Wenruo <[email protected]>
commit 173431b274a9a54fc10b273b46e67f46bcf62d2e upstream.
Add extra sanity check for btrfs_ioctl_defrag_range_args::flags.
This is not really to enhance fuzzing tests, but as a preparation for future expansion on btrfs_ioctl_defrag_range_args.
In the future we're going to add new members, allowing more fine tuning for btrfs defrag. Without the -ENONOTSUPP error, there would be no way to detect if the kernel supports those new defrag features.
--- fs/btrfs/ioctl.c | 4 ++++ include/uapi/linux/btrfs.h | 3 +++ 2 files changed, 7 insertions(+)
fs/btrfs/ioctl.c +4 -0
@@ -3500,6 +3500,10 @@ static int btrfs_ioctl_defrag(struct fil ret = -EFAULT ; goto out; } +if (range.flags & ~BTRFS_DEFRAG_RANGE_FLAGS_SUPP ) { + ret = -EOPNOTSUPP ; + goto out; + }/* compression requires us to start the IO */ if ((range.flags &BTRFS_DEFRAG_RANGE_COMPRESS )) { range.flags |=BTRFS_DEFRAG_RANGE_START_IO ;
include/uapi/linux/btrfs.h +3 -0
@@ -585,6 +585,9 @@ struct btrfs_ioctl_clone_range_args {*/ #define BTRFS_DEFRAG_RANGE_COMPRESS 1#define BTRFS_DEFRAG_RANGE_START_IO 2 +#define BTRFS_DEFRAG_RANGE_FLAGS_SUPP (BTRFS_DEFRAG_RANGE_COMPRESS | \ + BTRFS_DEFRAG_RANGE_START_IO) +struct btrfs_ioctl_defrag_range_args {/* start of the defrag operation */ __u64 start;
Greg Kroah-Hartman
maintainerPATCH 120/185 btrfs: dont abort filesystem when attempting to snapshot deleted subvolume
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Omar Sandoval <[email protected]>
commit 7081929ab2572920e94d70be3d332e5c9f97095a upstream.
If the source file descriptor to the snapshot ioctl refers to a deleted subvolume, we get the following abort:
BTRFS: Transaction aborted (error -2)
WARNING: CPU: 0 PID: 833 at fs/btrfs/transaction.c:1875 create_pending_snapshot+0x1040/0x1190 [btrfs] Modules linked in: pata_acpi btrfs ata_piix libata scsi_mod virtio_net blake2b_generic xor net_failover virtio_rng failover scsi_common rng_core raid6_pq libcrc32c CPU: 0 PID: 833 Comm: t_snapshot_dele Not tainted 6.7.0-rc6 #2 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-1.fc39 04/01/2014 RIP: 0010:create_pending_snapshot+0x1040/0x1190 [btrfs] RSP: 0018:ffffa09c01337af8 EFLAGS: 00010282 RAX: 0000000000000000 RBX: ffff9982053e7c78 RCX: 0000000000000027 RDX: ffff99827dc20848 RSI: 0000000000000001 RDI: ffff99827dc20840 RBP: ffffa09c01337c00 R08: 0000000000000000 R09: ffffa09c01337998 R10: 0000000000000003 R11: ffffffffb96da248 R12: fffffffffffffffe R13: ffff99820535bb28 R14: ffff99820b7bd000 R15: ffff99820381ea80 FS: 00007fe20aadabc0(0000) GS:ffff99827dc00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000559a120b502f CR3: 00000000055b6000 CR4: 00000000000006f0 Call Trace: <TASK> ? create_pending_snapshot+0x1040/0x1190 [btrfs] ? __warn+0x81/0x130 ? create_pending_snapshot+0x1040/0x1190 [btrfs] ? report_bug+0x171/0x1a0 ? handle_bug+0x3a/0x70 ? exc_invalid_op+0x17/0x70 ? asm_exc_invalid_op+0x1a/0x20 ? create_pending_snapshot+0x1040/0x1190 [btrfs] ? create_pending_snapshot+0x1040/0x1190 [btrfs] create_pending_snapshots+0x92/0xc0 [btrfs] btrfs_commit_transaction+0x66b/0xf40 [btrfs] btrfs_mksubvol+0x301/0x4d0 [btrfs] btrfs_mksnapshot+0x80/0xb0 [btrfs] __btrfs_ioctl_snap_create+0x1c2/0x1d0 [btrfs] btrfs_ioctl_snap_create_v2+0xc4/0x150 [btrfs] btrfs_ioctl+0x8a6/0x2650 [btrfs] ? kmem_cache_free+0x22/0x340 ? do_sys_openat2+0x97/0xe0 __x64_sys_ioctl+0x97/0xd0 do_syscall_64+0x46/0xf0 entry_SYSCALL_64_after_hwframe+0x6e/0x76 RIP: 0033:0x7fe20abe83af RSP: 002b:00007ffe6eff1360 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 0000000000000004 RCX: 00007fe20abe83af RDX: 00007ffe6eff23c0 RSI: 0000000050009417 RDI: 0000000000000003 RBP: 0000000000000003 R08: 0000000000000000 R09: 00007fe20ad16cd0 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 00007ffe6eff13c0 R14: 00007fe20ad45000 R15: 0000559a120b6d58 </TASK> ---[ end trace 0000000000000000 ]--- BTRFS: error (device vdc: state A) in create_pending_snapshot:1875: errno=-2 No such entry BTRFS info (device vdc: state EA): forced readonly BTRFS warning (device vdc: state EA): Skipping commit of aborted transaction. BTRFS: error (device vdc: state EA) in cleanup_transaction:2055: errno=-2 No such entry
This happens because create_pending_snapshot() initializes the new root item as a copy of the source root item. This includes the refs field, which is 0 for a deleted subvolume. The call to btrfs_insert_root() therefore inserts a root with refs == 0. btrfs_get_new_fs_root() then finds the root and returns -ENOENT if refs == 0, which causes create_pending_snapshot() to abort.
Fix it by checking the source root's refs before attempting the snapshot, but after locking subvol_sem to avoid racing with deletion.
--- fs/btrfs/ioctl.c | 3 +++ 1 file changed, 3 insertions(+)
fs/btrfs/ioctl.c +3 -0
@@ -780,6 +780,9 @@ static int create_snapshot(struct btrfs_return -EOPNOTSUPP ; } +if (btrfs_root_refs (&root->root_item) ==0 ) +return -ENOENT ; +if (!test_bit (BTRFS_ROOT_SHAREABLE , &root->state))return -EINVAL ;
Greg Kroah-Hartman
maintainerPATCH 121/185 rbd: dont move requests to the running list on errors
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilya Dryomov <[email protected]>
commit ded080c86b3f99683774af0441a58fc2e3d60cae upstream.
The running list is supposed to contain requests that are pinning the exclusive lock, i.e. those that must be flushed before exclusive lock is released. When wake_lock_waiters() is called to handle an error, requests on the acquiring list are failed with that error and no flushing takes place. Briefly moving them to the running list is not only pointless but also harmful: if exclusive lock gets acquired before all of their state machines are scheduled and go through rbd_lock_del_request(), we trigger
rbd_assert(list_empty(&rbd_dev->running_list));
in rbd_try_acquire_lock().
--- drivers/block/rbd.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-)
drivers/block/rbd.c +14 -8
@@ -3453,14 +3453,15 @@ static bool rbd_lock_add_request(structstatic void rbd_lock_del_request (struct rbd_img_request *img_req) {struct rbd_device *rbd_dev = img_req->rbd_dev; -bool need_wakeup; +bool need_wakeup = false;lockdep_assert_held (&rbd_dev->lock_rwsem);spin_lock (&rbd_dev->lock_lists_lock); -rbd_assert (!list_empty (&img_req->lock_item)); -list_del_init (&img_req->lock_item); - need_wakeup = (rbd_dev->lock_state ==RBD_LOCK_STATE_RELEASING && -list_empty (&rbd_dev->running_list)); +if (!list_empty (&img_req->lock_item)) { +list_del_init (&img_req->lock_item); + need_wakeup = (rbd_dev->lock_state ==RBD_LOCK_STATE_RELEASING && +list_empty (&rbd_dev->running_list)); + }spin_unlock (&rbd_dev->lock_lists_lock);if (need_wakeup)complete (&rbd_dev->releasing_wait);
@@ -3843,14 +3844,19 @@ static void wake_lock_waiters(struct rbdreturn ; } -list_for_each_entry (img_req, &rbd_dev->acquiring_list, lock_item) { +while (!list_empty (&rbd_dev->acquiring_list)) { + img_req =list_first_entry (&rbd_dev->acquiring_list, + struct rbd_img_request, lock_item);mutex_lock (&img_req->state_mutex);rbd_assert (img_req->state ==RBD_IMG_EXCLUSIVE_LOCK ); +if (!result) +list_move_tail (&img_req->lock_item, + &rbd_dev->running_list); +else +list_del_init (&img_req->lock_item);rbd_img_schedule (img_req, result);mutex_unlock (&img_req->state_mutex); } - -list_splice_tail_init (&rbd_dev->acquiring_list, &rbd_dev->running_list); } static bool locker_equal(const struct ceph_locker *lhs,
Greg Kroah-Hartman
maintainerPATCH 122/185 exec: Fix error handling in begin_new_exec()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernd Edlinger <[email protected]>
commit 84c39ec57d409e803a9bb6e4e85daf1243e0e80b upstream.
If get_unused_fd_flags() fails, the error handling is incomplete because bprm->cred is already set to NULL, and therefore free_bprm will not unlock the cred_guard_mutex. Note there are two error conditions which end up here, one before and one after bprm->cred is cleared.
--- fs/exec.c | 3 +++ 1 file changed, 3 insertions(+)
fs/exec.c +3 -0
@@ -1410,6 +1410,9 @@ int begin_new_exec(struct linux_binprm * out_unlock:up_write (&me->signal->exec_update_lock); +if (!bprm->cred) +mutex_unlock (&me->signal->cred_guard_mutex); + out:return retval; }
Greg Kroah-Hartman
maintainerPATCH 123/185 wifi: iwlwifi: fix a memory corruption
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Emmanuel Grumbach <[email protected]>
commit cf4a0d840ecc72fcf16198d5e9c505ab7d5a5e4d upstream.
iwl_fw_ini_trigger_tlv::data is a pointer to a __le32, which means that if we copy to iwl_fw_ini_trigger_tlv::data + offset while offset is in bytes, we'll write past the buffer.
--- drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c +1 -1
@@ -1082,7 +1082,7 @@ static int iwl_dbg_tlv_override_trig_nod node_trig = (void *)node_tlv->data; } -memcpy (node_trig->data + offset, trig->data, trig_data_len); +memcpy ((u8 *)node_trig->data + offset, trig->data, trig_data_len); node_tlv->length =cpu_to_le32 (size);if (policy &IWL_FW_INI_APPLY_POLICY_OVERRIDE_CFG ) {
Greg Kroah-Hartman
maintainerPATCH 124/185 hv_netvsc: Calculate correct ring size when PAGE_SIZE is not 4 Kbytes
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Kelley <[email protected]>
commit 6941f67ad37d5465b75b9ffc498fcf6897a3c00e upstream.
Current code in netvsc_drv_init() incorrectly assumes that PAGE_SIZE is 4 Kbytes, which is wrong on ARM64 with 16K or 64K page size. As a result, the default VMBus ring buffer size on ARM64 with 64K page size is 8 Mbytes instead of the expected 512 Kbytes. While this doesn't break anything, a typical VM with 8 vCPUs and 8 netvsc channels wastes 120 Mbytes (8 channels * 2 ring buffers/channel * 7.5 Mbytes/ring buffer).
Unfortunately, the module parameter specifying the ring buffer size is in units of 4 Kbyte pages. Ideally, it should be in units that are independent of PAGE_SIZE, but backwards compatibility prevents changing that now.
Fix this by having netvsc_drv_init() hardcode 4096 instead of using PAGE_SIZE when calculating the ring buffer size in bytes. Also use the VMBUS_RING_SIZE macro to ensure proper alignment when running with page size larger than 4K.
--- drivers/net/hyperv/netvsc_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/hyperv/netvsc_drv.c +2 -2
@@ -44,7 +44,7 @@static unsigned int ring_size__ro_after_init =128 ;module_param (ring_size, uint,0444 ); -MODULE_PARM_DESC (ring_size,"Ring buffer size (# of pages)" ); +MODULE_PARM_DESC (ring_size,"Ring buffer size (# of 4K pages)" );unsigned int netvsc_ring_bytes__ro_after_init ; static const u32 default_msg = NETIF_MSG_DRV | NETIF_MSG_PROBE |
@@ -2801,7 +2801,7 @@ static int __init netvsc_drv_init(void)pr_info ("Increased ring_size to %u (min allowed)\n" , ring_size); } - netvsc_ring_bytes = ring_size *PAGE_SIZE ; + netvsc_ring_bytes =VMBUS_RING_SIZE (ring_size *4096 );register_netdevice_notifier (&netvsc_netdev_notifier);
Greg Kroah-Hartman
maintainerPATCH 125/185 netfilter: nft_chain_filter: handle NETDEV_UNREGISTER for inet/ingress basechain
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pablo Neira Ayuso <[email protected]>
commit 01acb2e8666a6529697141a6017edbf206921913 upstream.
Remove netdevice from inet/ingress basechain in case NETDEV_UNREGISTER event is reported, otherwise a stale reference to netdevice remains in the hook list.
--- net/netfilter/nft_chain_filter.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
net/netfilter/nft_chain_filter.c +9 -2
@@ -357,9 +357,10 @@ static int nf_tables_netdev_event(struct unsigned long event, void *ptr) { struct net_device *dev = netdev_notifier_info_to_dev(ptr); +struct nft_base_chain *basechain;struct nftables_pernet *nft_net; -struct nft_table *table;struct nft_chain *chain, *nr; +struct nft_table *table;struct nft_ctx ctx = { .net =dev_net (dev), };
@@ -371,7 +372,8 @@ static int nf_tables_netdev_event(struct nft_net =nft_pernet (ctx.net);mutex_lock (&nft_net->commit_mutex);list_for_each_entry (table, &nft_net->tables, list) { -if (table->family !=NFPROTO_NETDEV ) +if (table->family !=NFPROTO_NETDEV && + table->family !=NFPROTO_INET )continue ; ctx.family = table->family;
@@ -380,6 +382,11 @@ static int nf_tables_netdev_event(structif (!nft_is_base_chain (chain))continue ; + basechain =nft_base_chain (chain); +if (table->family ==NFPROTO_INET && + basechain->ops.hooknum !=NF_INET_INGRESS ) +continue ; + ctx.chain = chain;nft_netdev_event (event, dev, &ctx); }
Greg Kroah-Hartman
maintainerPATCH 126/185 netfilter: nf_tables: reject QUEUE/DROP verdict parameters
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal <[email protected]>
commit f342de4e2f33e0e39165d8639387aa6c19dff660 upstream.
This reverts commit e0abdadcc6e1.
core.c:nf_hook_slow assumes that the upper 16 bits of NF_DROP verdicts contain a valid errno, i.e. -EPERM, -EHOSTUNREACH or similar, or 0.
Due to the reverted commit, its possible to provide a positive value, e.g. NF_ACCEPT (1), which results in use-after-free.
Its not clear to me why this commit was made.
NF_QUEUE is not used by nftables; "queue" rules in nftables will result in use of "nft_queue" expression.
If we later need to allow specifiying errno values from userspace (do not know why), this has to call NF_DROP_GETERR and check that "err <= 0" holds true.
--- net/netfilter/nf_tables_api.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-)
net/netfilter/nf_tables_api.c +6 -10
@@ -10448,16 +10448,10 @@ static int nft_verdict_init(const struct data->verdict.code =ntohl (nla_get_be32 (tb[NFTA_VERDICT_CODE ]));switch (data->verdict.code) { -default : -switch (data->verdict.code &NF_VERDICT_MASK ) { -case NF_ACCEPT : -case NF_DROP : -case NF_QUEUE : -break ; -default : -return -EINVAL ; - } - fallthrough; +case NF_ACCEPT : +case NF_DROP : +case NF_QUEUE : +break ;case NFT_CONTINUE :case NFT_BREAK :case NFT_RETURN :
@@ -10492,6 +10486,8 @@ static int nft_verdict_init(const struct data->verdict.chain = chain;break ; +default : +return -EINVAL ; } desc->len =sizeof (data->verdict);
Greg Kroah-Hartman
maintainerPATCH 127/185 platform/x86: p2sb: Allow p2sb_bar() calls during PCI device probe
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shin'ichiro Kawasaki <[email protected]>
commit 5913320eb0b3ec88158cfcb0fa5e996bf4ef681b upstream.
p2sb_bar() unhides P2SB device to get resources from the device. It guards the operation by locking pci_rescan_remove_lock so that parallel rescans do not find the P2SB device. However, this lock causes deadlock when PCI bus rescan is triggered by /sys/bus/pci/rescan. The rescan locks pci_rescan_remove_lock and probes PCI devices. When PCI devices call p2sb_bar() during probe, it locks pci_rescan_remove_lock again. Hence the deadlock.
To avoid the deadlock, do not lock pci_rescan_remove_lock in p2sb_bar(). Instead, do the lock at fs_initcall. Introduce p2sb_cache_resources() for fs_initcall which gets and caches the P2SB resources. At p2sb_bar(), refer the cache and return to the caller.
Before operating the device at P2SB DEVFN for resource cache, check that its device class is PCI_CLASS_MEMORY_OTHER 0x0580 that PCH specifications define. This avoids unexpected operation to other devices at the same DEVFN.
Tested-by Klara Modin <[email protected]>
--- drivers/platform/x86/p2sb.c | 180 ++++++++++++++++++++++++++++-------- 1 file changed, 139 insertions(+), 41 deletions(-)
drivers/platform/x86/p2sb.c +139 -41
@@ -26,6 +26,21 @@ static const struct x86_cpu_id p2sb_cpu_ids[] = { {} }; +/* +* Cache BAR0 of P2SB device functions 0 to 7. +* TODO: The constant 8 is the number of functions that PCI specification +* defines. Same definitions exist tree-wide. Unify this definition and +* the other definitions then move to include/uapi/linux/pci.h. +*/ +#define NR_P2SB_RES_CACHE 8 + +struct p2sb_res_cache { +u32 bus_dev_id; +struct resource res; +}; + +static struct p2sb_res_cache p2sb_resources[NR_P2SB_RES_CACHE ]; +static int p2sb_get_devfn (unsigned int *devfn) {unsigned int fn =P2SB_DEVFN_DEFAULT ;
@@ -39,8 +54,16 @@ static int p2sb_get_devfn(unsigned int *devfn)return 0 ; } +static bool p2sb_valid_resource (struct resource *res) +{ +if (res->flags) +return true; + +return false; +} +/* Copy resource from the first BAR of the device in question */ -static int p2sb_read_bar0 (struct pci_dev *pdev,struct resource *mem) +static void p2sb_read_bar0 (struct pci_dev *pdev,struct resource *mem) {struct resource *bar0 = &pdev->resource[0 ];
@@ -56,49 +79,66 @@ static int p2sb_read_bar0(struct pci_dev *pdev, struct resource *mem) mem->end = bar0->end; mem->flags = bar0->flags; mem->desc = bar0->desc; - -return 0 ; } -static int p2sb_scan_and_read (struct pci_bus *bus,unsigned int devfn,struct resource *mem) +static void p2sb_scan_and_cache_devfn (struct pci_bus *bus,unsigned int devfn) { +struct p2sb_res_cache *cache = &p2sb_resources[PCI_FUNC (devfn)];struct pci_dev *pdev; -int ret; pdev =pci_scan_single_device (bus, devfn);if (!pdev) -return -ENODEV ; +return ; - ret =p2sb_read_bar0 (pdev, mem); +p2sb_read_bar0 (pdev, &cache->res); + cache->bus_dev_id = bus->dev.id;pci_stop_and_remove_bus_device (pdev); -return ret; } -/** -* p2sb_bar - Get Primary to Sideband (P2SB) bridge device BAR -* @bus: PCI bus to communicate with -* @devfn: PCI slot and function to communicate with -* @mem: memory resource to be filled in -* -* The BIOS prevents the P2SB device from being enumerated by the PCI -* subsystem, so we need to unhide and hide it back to lookup the BAR. -* -* if @bus is NULL, the bus 0 in domain 0 will be used. -* If @devfn is 0, it will be replaced by devfn of the P2SB device. -* -* Caller must provide a valid pointer to @mem. -* -* Locking is handled by pci_rescan_remove_lock mutex. -* -* Return: -* 0 on success or appropriate errno value on error. -*/ -int p2sb_bar (struct pci_bus *bus,unsigned int devfn,struct resource *mem) +static int p2sb_scan_and_cache (struct pci_bus *bus,unsigned int devfn) +{ +unsigned int slot, fn; + +if (PCI_FUNC (devfn) ==0 ) { +/* +* When function number of the P2SB device is zero, scan it and +* other function numbers, and if devices are available, cache +* their BAR0s. +*/ + slot =PCI_SLOT (devfn); +for (fn =0 ; fn <NR_P2SB_RES_CACHE ; fn++) +p2sb_scan_and_cache_devfn (bus,PCI_DEVFN (slot, fn)); + }else { +/* Scan the P2SB device and cache its BAR0 */ +p2sb_scan_and_cache_devfn (bus, devfn); + } + +if (!p2sb_valid_resource (&p2sb_resources[PCI_FUNC (devfn)].res)) +return -ENOENT ; + +return 0 ; +} + +static struct pci_bus *p2sb_get_bus (struct pci_bus *bus) +{ +static struct pci_bus *p2sb_bus; + + bus = bus ?: p2sb_bus; +if (bus) +return bus; + +/* Assume P2SB is on the bus 0 in domain 0 */ + p2sb_bus =pci_find_bus (0 ,0 ); +return p2sb_bus; +} + +static int p2sb_cache_resources (void ) { -struct pci_dev *pdev_p2sb;unsigned int devfn_p2sb;u32 value =P2SBC_HIDE ; +struct pci_bus *bus; +u16 class;int ret;/* Get devfn for P2SB device itself */
@@ -106,8 +146,17 @@ int p2sb_bar(struct pci_bus *bus, unsigned int devfn, struct resource *mem)if (ret)return ret; -/* if @bus is NULL, use bus 0 in domain 0 */ - bus = bus ?:pci_find_bus (0 ,0 ); + bus =p2sb_get_bus (NULL ); +if (!bus) +return -ENODEV ; + +/* +* When a device with same devfn exists and its device class is not +* PCI_CLASS_MEMORY_OTHER for P2SB, do not touch it. +*/ +pci_bus_read_config_word (bus, devfn_p2sb,PCI_CLASS_DEVICE , &class); +if (!PCI_POSSIBLE_ERROR (class) && class !=PCI_CLASS_MEMORY_OTHER ) +return -ENODEV ;/* * Prevent concurrent PCI bus scan from seeing the P2SB device and
@@ -115,17 +164,16 @@ int p2sb_bar(struct pci_bus *bus, unsigned int devfn, struct resource *mem)*/ pci_lock_rescan_remove (); -/* Unhide the P2SB device, if needed */ +/* +* The BIOS prevents the P2SB device from being enumerated by the PCI +* subsystem, so we need to unhide and hide it back to lookup the BAR. +* Unhide the P2SB device here, if needed. +*/ pci_bus_read_config_dword (bus, devfn_p2sb,P2SBC , &value);if (value &P2SBC_HIDE )pci_bus_write_config_dword (bus, devfn_p2sb,P2SBC ,0 ); - pdev_p2sb =pci_scan_single_device (bus, devfn_p2sb); -if (devfn) - ret =p2sb_scan_and_read (bus, devfn, mem); -else - ret =p2sb_read_bar0 (pdev_p2sb, mem); -pci_stop_and_remove_bus_device (pdev_p2sb); + ret =p2sb_scan_and_cache (bus, devfn_p2sb);/* Hide the P2SB device, if it was hidden */ if (value &P2SBC_HIDE )
@@ -133,12 +181,62 @@ int p2sb_bar(struct pci_bus *bus, unsigned int devfn, struct resource *mem)pci_unlock_rescan_remove (); -if (ret) -return ret; +return ret; +} + +/** +* p2sb_bar - Get Primary to Sideband (P2SB) bridge device BAR +* @bus: PCI bus to communicate with +* @devfn: PCI slot and function to communicate with +* @mem: memory resource to be filled in +* +* If @bus is NULL, the bus 0 in domain 0 will be used. +* If @devfn is 0, it will be replaced by devfn of the P2SB device. +* +* Caller must provide a valid pointer to @mem. +* +* Return: +* 0 on success or appropriate errno value on error. +*/ +int p2sb_bar (struct pci_bus *bus,unsigned int devfn,struct resource *mem) +{ +struct p2sb_res_cache *cache; +int ret; + + bus =p2sb_get_bus (bus); +if (!bus) +return -ENODEV ; + +if (!devfn) { + ret =p2sb_get_devfn (&devfn); +if (ret) +return ret; + } -if (mem->flags ==0 ) + cache = &p2sb_resources[PCI_FUNC (devfn)]; +if (cache->bus_dev_id != bus->dev.id)return -ENODEV ; +if (!p2sb_valid_resource (&cache->res)) +return -ENOENT ; + +memcpy (mem, &cache->res,sizeof (*mem));return 0 ; }EXPORT_SYMBOL_GPL (p2sb_bar); + +static int __init p2sb_fs_init (void ) +{ +p2sb_cache_resources (); +return 0 ; +} + +/* +* pci_rescan_remove_lock to avoid access to unhidden P2SB devices can +* not be locked in sysfs pci bus rescan path because of deadlock. To +* avoid the deadlock, access to P2SB devices with the lock at an early +* step in kernel initialization and cache required resources. This +* should happen after subsys_initcall which initializes PCI subsystem +* and before device_initcall which requires P2SB resources. +*/ +fs_initcall (p2sb_fs_init);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 128/185 ksmbd: fix global oob in ksmbd_nl_policy
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lin Ma <[email protected]>
commit ebeae8adf89d9a82359f6659b1663d09beec2faa upstream.
Similar to a reported issue (check the commit b33fb5b801c6 ("net:
qualcomm: rmnet: fix global oob in rmnet_policy"), my local fuzzer finds another global out-of-bounds read for policy ksmbd_nl_policy. See bug trace below:
==================================================================
BUG: KASAN: global-out-of-bounds in validate_nla lib/nlattr.c:386 [inline]
BUG: KASAN: global-out-of-bounds in __nla_validate_parse+0x24af/0x2750 lib/nlattr.c:600
Read of size 1 at addr ffffffff8f24b100 by task syz-executor.1/62810
CPU: 0 PID: 62810 Comm: syz-executor.1 Tainted: G N 6.1.0 #3
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014
Call Trace:
<TASK>
__dump_stack lib/dump_stack.c:88 [inline]
dump_stack_lvl+0x8b/0xb3 lib/dump_stack.c:106
print_address_description mm/kasan/report.c:284 [inline]
print_report+0x172/0x475 mm/kasan/report.c:395
kasan_report+0xbb/0x1c0 mm/kasan/report.c:495
validate_nla lib/nlattr.c:386 [inline]
__nla_validate_parse+0x24af/0x2750 lib/nlattr.c:600
__nla_parse+0x3e/0x50 lib/nlattr.c:697
__nlmsg_parse include/net/netlink.h:748 [inline]
genl_family_rcv_msg_attrs_parse.constprop.0+0x1b0/0x290 net/netlink/genetlink.c:565
genl_family_rcv_msg_doit+0xda/0x330 net/netlink/genetlink.c:734
genl_family_rcv_msg net/netlink/genetlink.c:833 [inline]
genl_rcv_msg+0x441/0x780 net/netlink/genetlink.c:850
netlink_rcv_skb+0x14f/0x410 net/netlink/af_netlink.c:2540
genl_rcv+0x24/0x40 net/netlink/genetlink.c:861
netlink_unicast_kernel net/netlink/af_netlink.c:1319 [inline]
netlink_unicast+0x54e/0x800 net/netlink/af_netlink.c:1345
netlink_sendmsg+0x930/0xe50 net/netlink/af_netlink.c:1921
sock_sendmsg_nosec net/socket.c:714 [inline]
sock_sendmsg+0x154/0x190 net/socket.c:734
____sys_sendmsg+0x6df/0x840 net/socket.c:2482
___sys_sendmsg+0x110/0x1b0 net/socket.c:2536
__sys_sendmsg+0xf3/0x1c0 net/socket.c:2565
do_syscall_x64 arch/x86/entry/common.c:50 [inline]
do_syscall_64+0x3b/0x90 arch/x86/entry/common.c:80
entry_SYSCALL_64_after_hwframe+0x63/0xcd
RIP: 0033:0x7fdd66a8f359
Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 f1 19 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:00007fdd65e00168 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
RAX: ffffffffffffffda RBX: 00007fdd66bbcf80 RCX: 00007fdd66a8f359
RDX: 0000000000000000 RSI: 0000000020000500 RDI: 0000000000000003
RBP: 00007fdd66ada493 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007ffc84b81aff R14: 00007fdd65e00300 R15: 0000000000022000
</TASK>
The buggy address belongs to the variable:
ksmbd_nl_policy+0x100/0xa80
The buggy address belongs to the physical page:
page:0000000034f47940 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x1ccc4b
flags: 0x200000000001000(reserved|node=0|zone=2)
raw: 0200000000001000 ffffea00073312c8 ffffea00073312c8 0000000000000000
raw: 0000000000000000 0000000000000000 00000001ffffffff 0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffffffff8f24b000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
ffffffff8f24b080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>ffffffff8f24b100: f9 f9 f9 f9 00 00 f9 f9 f9 f9 f9 f9 00 00 07 f9
^
ffffffff8f24b180: f9 f9 f9 f9 00 05 f9 f9 f9 f9 f9 f9 00 00 00 05
ffffffff8f24b200: f9 f9 f9 f9 00 00 03 f9 f9 f9 f9 f9 00 00 04 f9
==================================================================To fix it, add a placeholder named __KSMBD_EVENT_MAX and let KSMBD_EVENT_MAX to be its original value - 1 according to what other netlink families do. Also change two sites that refer the KSMBD_EVENT_MAX to correct value.
--- fs/smb/server/ksmbd_netlink.h | 3 ++- fs/smb/server/transport_ipc.c | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-)
fs/smb/server/ksmbd_netlink.h +2 -1
@@ -304,7 +304,8 @@ enum ksmbd_event {KSMBD_EVENT_SPNEGO_AUTHEN_REQUEST ,KSMBD_EVENT_SPNEGO_AUTHEN_RESPONSE =15 , - KSMBD_EVENT_MAX + __KSMBD_EVENT_MAX, + KSMBD_EVENT_MAX = __KSMBD_EVENT_MAX - 1 };/*
fs/smb/server/transport_ipc.c +2 -2
@@ -74,7 +74,7 @@ static int handle_unsupported_event(strustatic int handle_generic_event (struct sk_buff *skb,struct genl_info *info);static int ksmbd_ipc_heartbeat_request (void ); -static const struct nla_policy ksmbd_nl_policy[KSMBD_EVENT_MAX ] = { +static const struct nla_policy ksmbd_nl_policy[KSMBD_EVENT_MAX +1 ] = { [KSMBD_EVENT_UNSPEC ] = { .len =0 , },
@@ -403,7 +403,7 @@ static int handle_generic_event(struct sreturn -EPERM ;#endif -if (type >=KSMBD_EVENT_MAX ) { +if (type >KSMBD_EVENT_MAX ) {WARN_ON (1 );return -EINVAL ; }
Greg Kroah-Hartman
maintainerPATCH 129/185 firmware: arm_scmi: Check mailbox/SMT channel for consistency
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cristian Marussi <[email protected]>
commit 437a310b22244d4e0b78665c3042e5d1c0f45306 upstream.
On reception of a completion interrupt the shared memory area is accessed to retrieve the message header at first and then, if the message sequence number identifies a transaction which is still pending, the related payload is fetched too.
When an SCMI command times out the channel ownership remains with the platform until eventually a late reply is received and, as a consequence, any further transmission attempt remains pending, waiting for the channel to be relinquished by the platform.
Once that late reply is received the channel ownership is given back to the agent and any pending request is then allowed to proceed and overwrite the SMT area of the just delivered late reply; then the wait for the reply to the new request starts.
It has been observed that the spurious IRQ related to the late reply can be wrongly associated with the freshly enqueued request: when that happens the SCMI stack in-flight lookup procedure is fooled by the fact that the message header now present in the SMT area is related to the new pending transaction, even though the real reply has still to arrive.
This race-condition on the A2P channel can be detected by looking at the channel status bits: a genuine reply from the platform will have set the channel free bit before triggering the completion IRQ.
Add a consistency check to validate such condition in the A2P ISR.
--- drivers/firmware/arm_scmi/common.h | 1 + drivers/firmware/arm_scmi/mailbox.c | 14 ++++++++++++++ drivers/firmware/arm_scmi/shmem.c | 6 ++++++ 3 files changed, 21 insertions(+)
drivers/firmware/arm_scmi/common.h +1 -0
@@ -244,6 +244,7 @@ void shmem_fetch_notification(struct scmvoid shmem_clear_channel (struct scmi_shared_mem __iomem *shmem);bool shmem_poll_done (struct scmi_shared_mem __iomem *shmem,struct scmi_xfer *xfer); +bool shmem_channel_free (struct scmi_shared_mem __iomem *shmem);/* declarations for message passing transports */ struct scmi_msg_payld ;
drivers/firmware/arm_scmi/mailbox.c +14 -0
@@ -43,6 +43,20 @@ static void rx_callback(struct mbox_clie {struct scmi_mailbox *smbox =client_to_scmi_mailbox (cl); +/* +* An A2P IRQ is NOT valid when received while the platform still has +* the ownership of the channel, because the platform at first releases +* the SMT channel and then sends the completion interrupt. +* +* This addresses a possible race condition in which a spurious IRQ from +* a previous timed-out reply which arrived late could be wrongly +* associated with the next pending transaction. +*/ +if (cl->knows_txdone && !shmem_channel_free (smbox->shmem)) { +dev_warn (smbox->cinfo->dev,"Ignoring spurious A2P IRQ !\n" ); +return ; + } +scmi_rx_callback (smbox->cinfo,shmem_read_header (smbox->shmem),NULL ); }
drivers/firmware/arm_scmi/shmem.c +6 -0
@@ -122,3 +122,9 @@ bool shmem_poll_done(struct scmi_shared_ (SCMI_SHMEM_CHAN_STAT_CHANNEL_ERROR |SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE ); } + +bool shmem_channel_free (struct scmi_shared_mem __iomem *shmem) +{ +return (ioread32 (&shmem->channel_status) & +SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE ); +}