7.2.4-rc1 review
Subsystems (2)
Greg Kroah-Hartman
maintainercover 7.2.4-rc1 review
This is the start of the stable review cycle for the 7.2.4 release. There are 713 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 Sun, 06 Sep 2026 04:56:59 +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/v7.x/stable-review/patch-7.2.4-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-7.2.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 7.2.4-rc1
Tzung-Bi Shih <[email protected]>
platform/chrome: sensorhub: Fix dropped timestamp events and log spam
Rafael J. Wysocki <[email protected]>
ACPI: scan: Do not combine resources that overlap completely
Injae Ryou <[email protected]>
selftests/mm: fix on-fault-limit false failure under sudo-rs
Zhan Xusheng <[email protected]>
udf: Fix i_lenExtents truncation on 32-bit kernels
Thomas Gleixner <[email protected]>
timer: Keep debugobjects state consistent in migrate_timer_list()
Thomas Weißschuh (Schneider Electric) <[email protected]>
timekeeping: Check the return value of tk_get_aux_ts64 in __do_adjtimex()
Bradley Morgan <[email protected]>
taskstats: fix cpumask parsing cutting off the last character
Jann Horn <[email protected]>
smack: fix cred UAF in smack_file_send_sigiotask()
Bradley Morgan <[email protected]>
signal: avoid shared siginfo namespace rewrites
Helge Deller <[email protected]>
sticon/parisc: Detect default STI graphics card for console output
Oleg Nesterov <[email protected]>
sysctl: move the "cad_pid" entry from pid_table[] to kern_reboot_table[]
Myeonghun Pak <[email protected]>
tpm: tpm_i2c_nuvoton: disable IRQ on wait timeout
Xu Rao <[email protected]>
zloop: truncate finished zones to zone capacity
Zi Yan <[email protected]>
xarray: honor XA_FLAGS_ACCOUNT in xas_split_alloc()
Maoyi Xie <[email protected]>
w1: ds28e17: reject an oversize length on an I2C block read
Chengfeng Ye <[email protected]>
vsock/virtio: flush works in dependency order
Laxman Acharya Padhya <[email protected]>
wifi: mt76: mt7996: validate default EEPROM firmware size
Felix Fietkau <[email protected]>
wifi: mt76: mt7996: fix TX DMA mapping leak for AddBA req frames
Bryam Vargas <[email protected]>
wifi: mt76: mt7996: bound the device EEPROM address before the EFUSE copy
Devin Wittmayer <[email protected]>
wifi: mt76: mt7925: cancel mlo_pm_work on stop
Bryam Vargas <[email protected]>
wifi: mt76: mt7915: bound the device EEPROM address before the EFUSE copy
Runyu Xiao <[email protected]>
wifi: mt76: mt7615: avoid waiting for mac work under the mt76 mutex
Yuhang.chen <[email protected]>
wifi: rtw89: pci: add .shutdown callback to stop rfkill polling on reboot
Dawei Feng <[email protected]>
wifi: rtw88: pci: fix resource leak on failed NAPI setup
Abdun Nihaal <[email protected]>
wifi: rtw88: Fix potential memory leak in rtw_txq_push_skb()
Abdun Nihaal <[email protected]>
wifi: rtlwifi: rtl8192du: Fix possible memory leak in rtl92du_init_sw_vars()
Runyu Xiao <[email protected]>
wifi: rtlwifi: rtl8192du: check QoS TID before indexing tids
Stanislaw Gruszka <[email protected]>
wifi: rtl818x: initialize eeprom_93cx6 struct to zero
Fabio Estevam <[email protected]>
wifi: mwifiex: Detach sync cmd buffer on interrupted wait
Breno Leitao <[email protected]>
mm/kmemleak: report RCU-tasks quiescent states during the scan
Breno Leitao <[email protected]>
mm/kmemleak: stop the task stack scan early when interrupted
Thorsten Blum <[email protected]>
crypto: atmel-ecc - avoid stale fallback key after set_secret failure
Thorsten Blum <[email protected]>
crypto: atmel-ecc - clean up and improve ECDH comments
Vinicius Costa Gomes <[email protected]>
crypto: iaa - unmap dst before software fallback on decompress
Xiang Mei <[email protected]>
fuse: copy request headers via a stack buffer for io-uring
Joanne Koong <[email protected]>
fuse: decouple fuse_ring creation from ent registration
Fan Wu <[email protected]>
wifi: rtl8xxxu: fix use-after-free from rx_urb_wq on stop
Dawei Feng <[email protected]>
wifi: iwlwifi: dvm: fix memory leak in iwl_op_mode_dvm_start()
Abdun Nihaal <[email protected]>
wifi: brcmfmac: Fix memory leak in brcmf_sdio_read_control()
Claudiu Beznea <[email protected]>
i3c: renesas: Perform Dynamic Address Assignment on resume
Claudiu Beznea <[email protected]>
i3c: renesas: Restore STDBR and EXTBR registers on resume
Claudiu Beznea <[email protected]>
i3c: renesas: Reset the controller on resume
Claudiu Beznea <[email protected]>
i3c: renesas: Reconfigure the DATBAS register on re-attach
Claudiu Beznea <[email protected]>
i3c: renesas: Follow the reset deassert order used in probe
Claudiu Beznea <[email protected]>
i3c: renesas: Clean DATBAS register on detach
Claudiu Beznea <[email protected]>
i3c: renesas: Check that the transfer is valid before accessing it
Adrian Hunter <[email protected]>
i3c: master: Fix potential UAF in i3c_device_uevent()
Maoyi Xie <[email protected]>
i3c: master: svc: bound IBI payload to the requested max_payload_len
Adrian Hunter <[email protected]>
i3c: master: Fix info leak and UAF in device unregister path
Runyu Xiao <[email protected]>
i3c: master: adi: initialize the lock before enabling interrupts
Adrian Hunter <[email protected]>
i3c: Fix unlocked dereference of dev->desc in i3c_device_get_supported_xfer_mode()
Jianyun Gao <[email protected]>
dm-pcache: fix use-after-free and invalid seg operations in kset_replay()
Jianyun Gao <[email protected]>
dm-pcache: fix implicit u8 truncation of gc_percent in message handler
Bryam Vargas <[email protected]>
dm-pcache: only hand out initialized cache segments
Bryam Vargas <[email protected]>
dm-pcache: detect a cycle in the last-kset chain during replay
Bryam Vargas <[email protected]>
dm-pcache: clamp the tail kset read to the segment data region
Bryam Vargas <[email protected]>
dm-pcache: bound the persisted tail-position offset
Bryam Vargas <[email protected]>
dm-pcache: validate on-media seg_num against the cache device size
Bryam Vargas <[email protected]>
dm-pcache: validate kset key_num and intra-segment bounds
Bryam Vargas <[email protected]>
dm-pcache: validate geometry fields from on-disk cache_info
Haotian Zhang <[email protected]>
dm-switch: use WRITE_ONCE() in switch_region_table_write()
Mikulas Patocka <[email protected]>
dm-stats: fix a crash if allocation of per-cpu data fails
Nathan Chancellor <[email protected]>
arch_numa: avoid false positive fortify warning in setup_node_to_cpumask_map()
Eliot Courtney <[email protected]>
rust: num: reject Bounded::shr overshifts at build time
Zhang Heng <[email protected]>
ALSA: hda/realtek: Fix Lenovo Yoga Slim 7 14AKP10 quirk ordering
Denis Batishchev <[email protected]>
ALSA: hda/realtek: Enable micmute LED on HP EliteBook 6 G1a p/n: AD3Q9ET#UUG
Ajrat Makhmutov <[email protected]>
ALSA: hda/realtek: Enable headset mic on F+ FLAPTOP r
Eckhart Mohr <[email protected]>
ALSA: hda/realtek: Add quirk for TongFang XxAF5xxx
Takashi Iwai <[email protected]>
ALSA: virmidi: Check card index validity at probe
Takashi Iwai <[email protected]>
ALSA: serial-u16550: Check card index validity at probe
Takashi Iwai <[email protected]>
ALSA: portman2x4: Check card index validity at probe
Runyu Xiao <[email protected]>
ALSA: pcxhr: initialize mutexes before requesting threaded IRQ
Takashi Iwai <[email protected]>
ALSA: mts64: Check card index validity at probe
Takashi Iwai <[email protected]>
ALSA: mpu401: Check card index validity at probe
Xu Rao <[email protected]>
ALSA: hda/ext: preserve PPLCCTL bits when clearing reset
Baul Lee <[email protected]>
ALSA: FCP: do not copy out an uninitialised init response
Baul Lee <[email protected]>
ALSA: bcd2000: clear the URB pointers on disconnect
Takashi Iwai <[email protected]>
ALSA: aloop: Check card index validity at probe
Baul Lee <[email protected]>
ALSA: 6fire: bound the MIDI event length from the device
Abdun Nihaal <[email protected]>
mfd: sm501: Fix potential memory leaks during remove
Ali Ahmet Memis <[email protected]>
mfd: qnap-mcu: keep the reply buffer alive past a command timeout
Thomas Richard <[email protected]>
mfd: cgbc: Fix teardown ordering in cgbc_remove()
Can Peng <[email protected]>
hwrng: stm32 - Fix runtime PM cleanup on registration failure
Zhiling Zou <[email protected]>
seg6: reset IP6CB after IPv6 decapsulation
Norbert Szetei <[email protected]>
net: skbuff: don't touch shared zerocopy state in skb_tx_error()
Breno Leitao <[email protected]>
net: fix spurious TX timeout after dev_activate()
Zhiling Zou <[email protected]>
net: cap advertised IP tunnel headroom
Bryam Vargas <[email protected]>
net/smc: unregister the connection before draining the rx tasklet
Hidayath Khan <[email protected]>
net/smc: stop killed, freed and out_of_sync sharing a byte
Yehyeong Lee <[email protected]>
net/smc: fix use-after-free of the LLC qentry in smc_llc_srv_add_link()
Hidayath Khan <[email protected]>
net/smc: fix use-after-free in smc_rx_pipe_buf_release()
Hidayath Khan <[email protected]>
net/smc: fix socket refcount leak in smc_switch_conns()
Bryam Vargas <[email protected]>
net/smc: do not dereference an unset send buffer on the SMC-D teardown path
Yehyeong Lee <[email protected]>
net/smc: carry oversized SMC-Rv2 LLC messages in the queue entry
Yehyeong Lee <[email protected]>
net/smc: bound the peer rkey counts in SMC-Rv2 LLC messages
Glenn Judd <[email protected]>
net/mlx5e: do not HW-GRO coalesce small frames
Koichiro Den <[email protected]>
net: ntb_netdev: Count packets dropped on RX refill failure
Koichiro Den <[email protected]>
net: ntb_netdev: Avoid double-accounting netif_rx() drops
Koichiro Den <[email protected]>
net: ntb_netdev: Fix TX busy and drop handling
Koichiro Den <[email protected]>
NTB: ntb_transport: Reject oversized TX buffers
Koichiro Den <[email protected]>
NTB: ntb_transport: Fail TX enqueue when the QP link is down
Koichiro Den <[email protected]>
NTB: ntb_transport: Recycle TX entries before client callbacks
Fan Ye <[email protected]>
net: thunderbolt: Mark the connection down when bringing it up fails
Fan Ye <[email protected]>
net: thunderbolt: Release the Rx HopID that was handed out on mismatch
Xuanqiang Luo <[email protected]>
net: ravb: serialize PTP clock teardown
Xuanqiang Luo <[email protected]>
net: ravb: avoid dereferencing an invalid PTP clock
Christian Marangi <[email protected]>
net: phylink: correctly validate returned PCS in phylink_inband_caps
Ruoyu Wang <[email protected]>
net: openvswitch: fix nf_connlabels leak in ovs_ct_init
Ilya Maximets <[email protected]>
net: openvswitch: fix flow mask use-after-free on flow deletion
Aldo Ariel Panzardo <[email protected]>
net: mctp: hold a reference to the route device in mctp_route_lookup()
Zihan Xi <[email protected]>
net: l2tp: do not propagate multicast notification errors
Jorijn van der Graaf <[email protected]>
net: ipa: fix stalled modem TX queue after runtime resume
Runyu Xiao <[email protected]>
net: ibm: emac: mal: fix NAPI locking
Joe Damato <[email protected]>
net: bnxt: ring the doorbell when SW USO exits early
Ahmad Fatoum <[email protected]>
net: dsa: realtek: use gpiod_set_value_cansleep for reset GPIO
Asim Viladi Oglu Manizada <[email protected]>
net: tun: bound receive headroom
Fabio Porcedda <[email protected]>
net: usb: qmi_wwan: add Telit Cinterion FE990D50 composition
Aleksandr Khromov <[email protected]>
slip: fix use-after-free in sl_sync()
Weiming Shi <[email protected]>
xdp: fix zero-copy frame layout
Alexandra Winter <[email protected]>
net/iucv: filter frames in afiucv_hs_rcv() by ingress device
Corey Minyard <[email protected]>
ipmi:msghandler: Cancel work cleanly on an error
Seiji Nishikawa <[email protected]>
ipmi: si: Fix NULL pointer dereference after failed registration
Yuho Choi <[email protected]>
ipmi: Remove all sysfs files on registration failure
Yousef Alhouseen <[email protected]>
ipmi: ipmb: validate write message length
Kuan-Wei Chiu <[email protected]>
interconnect: Fix use after free in icc_get() and of_icc_get_by_index()
Laxman Acharya Padhya <[email protected]>
io_uring/query: cap user size passed to copy_struct_to_user
Hui Su <[email protected]>
io_uring/waitid: avoid siginfo copy during ring teardown
Hui Su <[email protected]>
io_uring/waitid: honor task_work cancellation
Muhammad Bilal <[email protected]>
platform/x86: hp-bioscfg: warn on element type mismatch instead of failing
Muhammad Bilal <[email protected]>
platform/x86: hp-bioscfg: pass validated element count to package parsers
Muhammad Bilal <[email protected]>
platform/x86: hp-bioscfg: fix ORD_LIST_ELEMENTS never being parsed
Muhammad Bilal <[email protected]>
platform/x86: hp-bioscfg: fix off-by-one write in hp_get_string_from_buffer()
Muhammad Bilal <[email protected]>
platform/x86: hp-bioscfg: fix new_password_store() overwriting current_password
Muhammad Bilal <[email protected]>
platform/x86: hp-bioscfg: fix heap OOB read on empty password write
Muhammad Bilal <[email protected]>
platform/x86: hp-bioscfg: fix heap OOB read in sk_store() and kek_store()
Muhammad Bilal <[email protected]>
platform/x86: hp-bioscfg: bound ordered-list parsing by the package count
Muhammad Bilal <[email protected]>
platform/x86: hp-bioscfg: advance elem past consumed array elements
Muhammad Bilal <[email protected]>
platform/x86: hp-bioscfg: accept reduced ACPI packages from older HP BIOS
Mario Limonciello <[email protected]>
platform/x86/amd/pmc: Fix msg_port restoration in amd_stb_debugfs_open_v2()
Mario Limonciello <[email protected]>
platform/x86/amd/pmc: Fix LPS0 and debugfs leaks when STB init fails
Mario Limonciello <[email protected]>
platform/x86/amd/pmc: Propagate SMU errors and validate S2D address
Mario Limonciello <[email protected]>
platform/x86/amd/pmc: Restore msg_port on amd_stb_s2d_init() error paths
Bryam Vargas <[email protected]>
platform/chrome: sensorhub: Bound the EC-reported sensor number
Thorsten Blum <[email protected]>
platform/x86: think-lmi: Fix current password length check
Thorsten Blum <[email protected]>
platform/x86: think-lmi: Free system certificate signatures
Thorsten Blum <[email protected]>
platform/x86: think-lmi: Fix certificate thumbprint sysfs output
Hilgad Montelo <[email protected]>
platform/x86: panasonic-laptop: Fix sentinel write past pcc->sinf[]
Julian Haarmann <[email protected]>
platform/x86: lenovo/ymc: Only match lower byte in WMI lid switch query response
Ma Ke <[email protected]>
platform/x86: ishtp_eclite: Fix ACPI device reference leak in probe error path
Abdun Nihaal <[email protected]>
platform/x86: int1092: Fix potential memory leak in sar_probe()
Krishna Chomal <[email protected]>
platform/x86: hp-wmi: Add support for OMEN MAX 16-ak0xxx (8DD6)
Srinivas Pandruvada <[email protected]>
platform/x86: ISST: Return error during profile addition
Srinivas Pandruvada <[email protected]>
platform/x86: ISST: Validate parameter for frequency and priority
Srinivas Pandruvada <[email protected]>
platform/x86: ISST: Validate parameter for core power state
Srinivas Pandruvada <[email protected]>
platform/x86: ISST: Validate max level for set feature
Srinivas Pandruvada <[email protected]>
platform/x86: ISST: Validate logical CPU id and clos id
Srinivas Pandruvada <[email protected]>
platform/x86: ISST: Use PP level enable mask
Srinivas Pandruvada <[email protected]>
platform/x86: ISST: Just allow 2 bits for SST feature enable
Srinivas Pandruvada <[email protected]>
platform/x86: ISST: Add a NULL check for sst_inst[]
Fan Wu <[email protected]>
mmc: via-sdmmc: stop card-detect handling on probe failure
Fan Wu <[email protected]>
mmc: via-sdmmc: cancel card-detect work on remove
HyeongJun An <[email protected]>
platform/x86: ISST: Validate socket ID in clos_assoc ioctl
HyeongJun An <[email protected]>
platform/x86: ISST: Validate level in perf mask ioctls
HyeongJun An <[email protected]>
platform/x86: dell-wmi-sysman: Don't hex dump attribute security buffer
Peiyang He <[email protected]>
iommufd: Fix UAF in selftest IOPF reporting
Shuai Xue <[email protected]>
iommufd: Release current IOAS on xa_store() failure
Shuai Xue <[email protected]>
iommufd: Avoid locking internal accesses during unmap
Shuai Xue <[email protected]>
iommupt: Return zero for invalid iova_to_phys() ranges
Kevin Tian <[email protected]>
iommu/vt-d: Force requesting ACS when tboot is enabled
Kevin Tian <[email protected]>
iommu/vt-d: Fix no_iommu to disable platform opt-in
Peiyang He <[email protected]>
iommu: Fix dev_iommu memory leak when device_add fails in iommu_mock_device_add
Shameer Kolothum <[email protected]>
iommu/arm-smmu-v3: Manage teardown with devm
Robin Murphy <[email protected]>
iommu/arm-smmu-v3: Add HAFT support for SVA
Nicolin Chen <[email protected]>
iommu/tegra241-cmdqv: Reject a vSID wider than the SID_MATCH field
Shuai Xue <[email protected]>
iommu/sva: Set handle->dev before the SVA handle is visible
Weimin Xiong <[email protected]>
iommu/msm: Unwind probe state on registration failure
Shuai Xue <[email protected]>
iommu/amd: Put PCI device after handling PPR faults
Krzysztof Wilczyński <[email protected]>
PCI/proc: Warn on writes to kernel-exclusive config space regions
Krzysztof Wilczyński <[email protected]>
PCI/proc: Use file_ns_capable() when checking config space read access
Krzysztof Wilczyński <[email protected]>
PCI/proc: Avoid spurious runtime PM wakeup on config space accesses
Farhan Ali <[email protected]>
PCI/MSI: Enable memory decoding before restoring MSI-X messages
Darshit Shah <[email protected]>
PCI/DPC: Allow DPC on all Downstream Ports when OS controls AER
Max Lee <[email protected]>
PCI/ASPM: Avoid L0s for Realtek RTS525A
Lukas Wunner <[email protected]>
PCI/AER: Fix mapping of errors to agent & layer
Lukas Wunner <[email protected]>
PCI/AER: Emit TLP Log only for unmasked errors
Krzysztof Wilczyński <[email protected]>
PCI/sysfs: Avoid spurious runtime PM wakeup on config space accesses
Krzysztof Wilczyński <[email protected]>
PCI/sysfs: Fix read byte order in pci_read_legacy_io()
Tim Harvey <[email protected]>
PCI: Add ACS quirk for Pericom PI7C9X2G608 switches [12d8:2608]
Ali Tariq <[email protected]>
PCI: plda: Fix IRQ domain leaks in the error paths of plda_init_interrupts()
Ali Tariq <[email protected]>
PCI: plda: Fix use-after-free of event IRQs during teardown
Ali Tariq <[email protected]>
PCI: starfive: Fix resource leaks on error paths in host_init()
Ronald Claveau <[email protected]>
PCI: meson: Fix GPIO state while requesting PERST#
Mohamad Raizudeen <[email protected]>
PCI: Fix 32-bit config write in Intel PCH Root Port MPC ACS quirk
Naman Jain <[email protected]>
PCI: hv: Set irq_retrigger callback for the Hyper-V PCI MSI irqchip
Stefan Haberland <[email protected]>
s390/dasd: Propagate partial completion length across ERP recovery
Stefan Haberland <[email protected]>
s390/dasd: Guard sysfs discipline callbacks against unallocated private data
Stefan Haberland <[email protected]>
s390/dasd: Do not complete a failed ESE read as successful
Karl Mehltretter <[email protected]>
s390/percpu: Fix MVIY_PERCPU() with older binutils
Thomas Richter <[email protected]>
s390/cpum_cf: Handle CPU hotplug via prepare/dead callbacks
Jianing Li <[email protected]>
power: supply: max17040: synchronize work cancellation on suspend
Jianing Li <[email protected]>
power: supply: max17040: drop incorrect I2C functionality check
Jianing Li <[email protected]>
power: supply: max17040: propagate register read errors
Fan Wu <[email protected]>
power: supply: ucs1002: fix use-after-free on remove
Maoyi Xie <[email protected]>
power: supply: twl4030_charger: cancel workers via devm
Fan Wu <[email protected]>
power: supply: rt9455: quiesce delayed work before teardown
HyeongJun An <[email protected]>
power: supply: qcom_battmgr: terminate the strings from firmware
Fan Wu <[email protected]>
power: supply: qcom_battmgr: fix use-after-free
Xu Rao <[email protected]>
power: supply: pf1550: enable charging when battery profile exists
Fan Wu <[email protected]>
power: supply: lp8788-charger: fix use-after-free on remove
Fan Wu <[email protected]>
power: supply: lp8727: fix use-after-free in lp8727_release_irq()
Jameson Thies <[email protected]>
power: supply: cros_usbpd: Limit port counts to EC_USB_PD_MAX_PORTS
Bryam Vargas <[email protected]>
power: supply: cros_usbpd-charger: bound the EC-reported port count
Fan Wu <[email protected]>
power: supply: charger-manager: register regulators before exposing sysfs
Ma Ke <[email protected]>
power: supply: bq25890: Fix power_supply reference leak
Fan Wu <[email protected]>
power: supply: bq256xx: drain usb_work before freeing the charger
Fan Wu <[email protected]>
power: supply: bq24257: fix use-after-free on remove
Jun Yang <[email protected]>
sctp: fix stream->outcnt underflow on duplicate RECONF responses
Jun Yang <[email protected]>
sctp: distinguish sequence zero from wildcard in reconf lookup
Weiming Shi <[email protected]>
sctp: fix NULL deref on untransmitted RECONF completion
Hyunwoo Kim <[email protected]>
sctp: drop a chunk if its transport was removed
Hyunwoo Kim <[email protected]>
sctp: stop processing a packet once its association is deleted
Yehyeong Lee <[email protected]>
nvme-tcp: reject a read that transferred too few bytes
Yehyeong Lee <[email protected]>
nvme-tcp: fix host memory disclosure on R2T for a read command
Yehyeong Lee <[email protected]>
nvme-tcp: do not accept C2HData based on blk_rq_payload_bytes() alone
Myeonghun Pak <[email protected]>
nvme-pci: disable controller on admin queue IRQ setup failure
Yehyeong Lee <[email protected]>
nvme: zero the discard fallback page
Ewan D. Milne <[email protected]>
nvme: nvme-fc: Fix nvme_fc_create_hw_io_queues() queue deletion in error path
Oscar Ou <[email protected]>
lockd: fix swapped arguments in nlmsvc_match_ip()
Shuangpeng Bai <[email protected]>
lockd: fix NULL dereference on lockowner allocation failure
Olga Kornievskaia <[email protected]>
lockd: fix NLMv4 GRANTED_MSG handling
Michael Bommarito <[email protected]>
lockd: pin next file across nlm_inspect_file lock-drop
Yifei Gao <[email protected]>
ipmi: Fix use-after-free of cmd_rcvr in _ipmi_destroy_user()
Ruoyu Wang <[email protected]>
i2c: mxs: fix DMA channel leak on probe error
Cong Nguyen <[email protected]>
hwmon: (max6621) fix temperature clamp range
Cong Nguyen <[email protected]>
hwmon: (max6621) fix negative temperature offset and crit readings
Alexander Graf <[email protected]>
dma-contiguous: fix truncation of numa_cma / cma_pernuma sizes >= 2G
Jorijn van der Graaf <[email protected]>
ASoC: codecs: aw88261: only check PLL and clock state at power-up
Christopher Tolang <[email protected]>
ASoC: amd: yc: Add DMI entry for MSI Thin A15 B7UC
Karl Mehltretter <[email protected]>
arm64: proton-pack: Restore the nospectre_bhb command-line option
Karl Mehltretter <[email protected]>
arm64: compat: Fix decrementing LDM/STM alignment emulation
HyeongJun An <[email protected]>
ALSA: ump: Fix corrupted data bytes at MIDI 1.0 SysEx to UMP conversion
Norbert Szetei <[email protected]>
openvswitch: only skb_tx_error() a packet we are about to drop
Yuqi Xu <[email protected]>
openvswitch: Fix CT limit teardown use-after-free
Ali Ahmet Memis <[email protected]>
openrisc: fix arbitrary kernel memory access via or1k_atomic syscall
Zhan Xusheng <[email protected]>
ocfs2: fix readdir position truncation on 32-bit kernels
Matthias Goergens <[email protected]>
ocfs2: fix cached cluster count after suballocator reclaim
Joseph Qi <[email protected]>
ocfs2: cluster: fix o2hb_dependent_users leak on pin failure
Joseph Qi <[email protected]>
ocfs2: cluster: avoid lock order inversion in o2hb_region_pin() from drop_item
Joseph Qi <[email protected]>
ocfs2: cluster: don't sleep while holding o2hb_live_lock in o2hb_region_pin()
Doruk Tan Ozturk <[email protected]>
ocfs2: validate directory-index entry counts when reading metadata
Ibrahim Hashimov <[email protected]>
ocfs2: validate rl_used against rl_count in refcount block validator
Bryam Vargas <[email protected]>
ocfs2: validate lengths in dlm_mig_lockres_handler
Bryam Vargas <[email protected]>
ocfs2: bound namelen in dlm_migrate_request_handler
Dmitry Antipov <[email protected]>
ocfs2: always run deallocs on copy-on-write completion
Zhiling Zou <[email protected]>
orangefs: skip leading spaces before parsing client debug masks
Yifei Gao <[email protected]>
orangefs: fix double-free of trailer_buf on readdir copy failure
Shibo Zhu <[email protected]>
PM: sleep: Unblock runtime PM when device prepare fails
Ivan Immanuel Shaji <[email protected]>
ring-buffer: Stop remote reader update when page swap fails
Vincent Donnefort <[email protected]>
ring-buffer: Make cpu_buffer::free_page a buffer_data_read_page
Vincent Donnefort <[email protected]>
ring-buffer: Hold cpu_buffer::lock when resizing a subbuf
Vincent Donnefort <[email protected]>
ring-buffer: Free cpu_buffer::free_page with subbuf_order
Vincent Donnefort <[email protected]>
ring-buffer: Fix subbuf resize race with ring_buffer_alloc_read_page()
Kathiravan Thirumoorthy <[email protected]>
regulator: qcom-refgen: correct the regulator type to CURRENT
WenTao Liang <[email protected]>
regulator: max8998_pmic_dt_parse_pdata: of_node_put on reg_np after ownership transferred to rdata
WenTao Liang <[email protected]>
regulator: as3722_get_regulator_dt_data: fix premature of_node_put leaving dangling of_node pointer
Yuhang Pan <[email protected]>
RDMA/uverbs: Guard legacy bundles without method_elm
Jason Gunthorpe <[email protected]>
RDMA/uverbs: Add UVERBS_ATTR_UHW to UVERBS_METHOD_REG_MR
Norbert Szetei <[email protected]>
RDMA/ucma: Lock the handler in ucma_write_cm_event()
Norbert Szetei <[email protected]>
RDMA/ucma: Lock the handler in ucma_set_ib_path()
Abhijit Gangurde <[email protected]>
RDMA/ionic: Embed counter driver data in rdma_counter allocation
Brett Creeley <[email protected]>
RDMA/ionic: Cap eq_count to the eth driver's interrupt vector budget
Fan Wu <[email protected]>
RDMA/cxgb4: Cancel reg_work before freeing device on remove
Vaibhav Nagare <[email protected]>
qede: Fix NULL pointer dereference in TPA fragment processing
Abdifatah Suruur <[email protected]>
ptp: vmclock: prevent read-only mappings from becoming writable
Johan Hovold <[email protected]>
remoteproc: scp: Fix device reference leak on failed lookup
Nam Cao <[email protected]>
riscv: unaligned: stop using kthread for check_vector_unaligned_access()
Peixin Xie <[email protected]>
riscv: acpi: Handle LPI architectural context loss flags
Guidong Han <[email protected]>
RISC-V: KVM: Fix PMU event info array size overflow
Aurelien Jarno <[email protected]>
riscv: dts: spacemit: k1-orangepi-rv2: fix maximum CPU core voltage
Aurelien Jarno <[email protected]>
riscv: dts: spacemit: k1-orangepi-r2s: fix maximum CPU core voltage
Aurelien Jarno <[email protected]>
riscv: dts: spacemit: k1-musepi-pro: fix maximum CPU core voltage
Aurelien Jarno <[email protected]>
riscv: dts: spacemit: k1-milkv-jupiter: fix maximum CPU core voltage
Aurelien Jarno <[email protected]>
riscv: dts: spacemit: k1-bananapi-f3: fix maximum CPU core voltage
Fabio Estevam <[email protected]>
arm64: dts: rockchip: Fix rk3588s-roc-pc audio description
Fabio Estevam <[email protected]>
arm64: dts: rockchip: Fix rk3399-roc-pc-plus analog audio
Jakob Unterwurzacher <[email protected]>
arm64: dts: rockchip: fix emmc reset polarity on px30-cobra
Quentin Schulz <[email protected]>
arm64: dts: rockchip: fix eMMC reset polarity on PX30 Ringneck
Quentin Schulz <[email protected]>
arm64: dts: rockchip: fix eMMC reset polarity on PP-1516
Michael Scott <[email protected]>
arm64: dts: qcom: x1-dell-thena: mark l12b and l15b always-on
Krzysztof Kozlowski <[email protected]>
arm64: dts: qcom: sm6115-pro1x: Correct touchscreen GPIO flags
Jianping Li <[email protected]>
arm64: dts: qcom: kodiak: avoid EFI overlap for ADSP remote heap
Oren Klopfer <[email protected]>
Revert "arm64: dts: rockchip: Further describe the WiFi for the Pinephone Pro"
Chunkai Deng <[email protected]>
rpmsg: glink: smem: order FIFO read after availability check
Linkai Gong <[email protected]>
scsi: fnic: Use GFP_ATOMIC for VLAN alloc under spinlock
Petr Vaganov <[email protected]>
scsi: core: Fill in DMA padding bytes in scsi_alloc_sgtables()
Tejun Heo <[email protected]>
sched_ext: Keep kick_sync waiting on the rq's own CPU
Tejun Heo <[email protected]>
sched_ext: Fix scx_bpf_dsq_reenq___compat kfunc extern prototype
Tao Cui <[email protected]>
sched_ext: Don't BUG_ON a destroyed DSQ in process_deferred_reenq_users
Tejun Heo <[email protected]>
sched_ext: Fix inverted ops.core_sched_before() invocation
fangqiurong <[email protected]>
sched_ext: Fix exit_task leak on fork failure during enable
fangqiurong <[email protected]>
sched_ext: Fix scx_bpf_dsq_move_to_local___v2 compat detection
Tejun Heo <[email protected]>
sched_ext: Count rq lock releases in rq->scx.lock_drop_seq
Tejun Heo <[email protected]>
sched_ext: Fix rq->core_pick corruption under core scheduling
Tejun Heo <[email protected]>
sched_ext: Fix this_rq() assumptions in dispatch kfuncs
Tejun Heo <[email protected]>
sched_ext: Replace SCX_RQ_BAL_KEEP with a dispatch verdict return
Tejun Heo <[email protected]>
sched/core: Make core-sched flips wait for in-flight selections
Tejun Heo <[email protected]>
sched/core: Handle pick_task() releasing the rq lock
Cong Nguyen <[email protected]>
media: staging/ipu7: fix async notifier UAF on probe error path
Hao-Qun Huang <[email protected]>
staging: media: tegra-video: vi: fix probe failure on skipped last port
Hao-Qun Huang <[email protected]>
staging: media: tegra-video: fix of_node_put() on VIP parse errors
Wentao Guan <[email protected]>
wifi: mt76: mt7925: cancel pending mlo_pm_work
Doruk Tan Ozturk <[email protected]>
wifi: ath6kl: clamp assoc request/response lengths before subtracting IE offsets
David Lee <[email protected]>
udf: reject VAT indexes equal to the entry count
Chuck Lever <[email protected]>
svcrdma: Validate Read chunk positions before reconstruction
Chuck Lever <[email protected]>
svcrdma: Use svc_xprt_put to free listener on create failure
Chris Mason <[email protected]>
svcrdma: Reject Write/Reply chunks with segcount 0
Chuck Lever <[email protected]>
svcrdma: Reject Read lists that exceed the page budget
Chuck Lever <[email protected]>
svcrdma: Reject oversized Read segments at decode time
Chuck Lever <[email protected]>
svcrdma: Reject inline replies that overflow the pull-up buffer
Chuck Lever <[email protected]>
svcrdma: Reject connection when transport allocation fails
Chris Mason <[email protected]>
svcrdma: Fix unmatched rn_unregister on failed accept
Chris Mason <[email protected]>
svcrdma: Fix pcl_for_each_segment for empty chunks
Chris Mason <[email protected]>
svcrdma: Fix offset arithmetic in read_chunk_range
Chuck Lever <[email protected]>
svcrdma: Clear sc_cm_id when ADDR_CHANGE replacement fails
Chuck Lever <[email protected]>
svcrdma: Reorder rpcrdma_rn_unregister before rdma_destroy_id
Jérémy Jean <[email protected]>
SUNRPC: wait for in-flight client TLS handshake callback
Chuck Lever <[email protected]>
SUNRPC: Reject short RFC 4121 MIC tokens in gss_krb5_verify_mic_v2
Chuck Lever <[email protected]>
SUNRPC: Reject krb5 v2 wrap tokens with oversized ec field
Chris Mason <[email protected]>
SUNRPC: reject duplicate CREDS_VALUE options
Chris Mason <[email protected]>
sunrpc: init gssp_lock before publishing proc entry
Chris Mason <[email protected]>
SUNRPC: harden gss_unwrap_resp_priv length checks
Chris Mason <[email protected]>
SUNRPC: harden gss_krb5_unwrap_v2 against short tokens
Chris Mason <[email protected]>
SUNRPC: Guard svcauth_gss_release() dispatch on rq_auth_stat
Luxiao Xu <[email protected]>
sunrpc: fix use-after-free in __rpc_clnt_handle_event and __rpc_clnt_remove_pipedir
Chris Mason <[email protected]>
SUNRPC: fix gssx_dec_option_array error path bugs
Jeff Layton <[email protected]>
sunrpc: defer rq_argp and rq_resp free until after RCU grace period
Chuck Lever <[email protected]>
SUNRPC: close backchannel before destroying callback service
Chuck Lever <[email protected]>
SUNRPC: Check svc pool percpu counter allocation
Jeff Layton <[email protected]>
SUNRPC: always drain cache_cleaner before destroying a cache_detail
Ameer Hamza <[email protected]>
SUNRPC: Restore NUMA_NO_NODE for svc thread allocations in global mode
Jeff Layton <[email protected]>
sunrpc: route to a populated pool in svc_pool_for_cpu()
Chris Mason <[email protected]>
SUNRPC: svcauth_gss: enforce krb5 token minimum length
Chris Mason <[email protected]>
SUNRPC: Zero rpc_gss_wire_cred at svcauth_gss_decode_credbody() entry
Chris Mason <[email protected]>
SUNRPC: xdr_buf_trim: clamp buf->len to avoid underflow
Felix Gu <[email protected]>
phy: fsl-imx8mq-usb: fix typec switch leak on probe error path
Jiacheng Yu <[email protected]>
params: fix charp corruption on allocation failure
Dave Airlie <[email protected]>
nouveau/gem: reserve the bo in the info ioctl around the vma lookup
Stanislaw Gruszka <[email protected]>
module/kallsyms: fix nextval for data symbol lookup
Harshit Varu <[email protected]>
mptcp: fix uninitialized local_id in syncookie MP_JOIN reconstruction
Qing Ming <[email protected]>
mpls: reload header after pskb_may_pull()
Thiébaud Weksteen <[email protected]>
module: validate string table section types
Coly Li <[email protected]>
md: do overflow check for sb->bblog_shift in super_1_load()
Yunye Zhao <[email protected]>
md/raid10: fix still_degraded being inverted in raid10_sync_request()
Anup Vishwakarma <[email protected]>
mailbox: qcom-ipcc: fix duplicate channel allocation across holes
Bryam Vargas <[email protected]>
libnvdimm/labels: Prevent integer overflow in __nd_label_validate()
Günther Noack <[email protected]>
landlock: Require LANDLOCK_ACCESS_FS_MAKE_REG for whiteout creation
Yuyang Huang <[email protected]>
ipv6: use RCU iterator to dump route exceptions
Andrea Mayer <[email protected]>
ipv6: rpl: fix NULL dereference of idev in ipv6_rpl_srh_rcv()
Zhiling Zou <[email protected]>
ip6_gre: fix hardware header length for NBMA tunnels
Zhiling Zou <[email protected]>
ip6_tunnel: use skb_cow_head() in ip6_tnl_xmit()
Zhiling Zou <[email protected]>
ip: orphan prefetched skbs before multicast forwarding
Anton Danilov <[email protected]>
ipip: fix skb leak in collect_md mode when metadata_dst allocation fails
Max Kellermann <[email protected]>
jbd2: check need_resched() when skipping busy checkpoint buffers
Max Kellermann <[email protected]>
jbd2: bound shrinker scans by examined checkpoint buffers
Pratyush Yadav (Google) <[email protected]>
kho: fix size calculation in kho_preserved_memory_reserve()
Hui Su <[email protected]>
kasan: fix cache shrink race with CPU hotplug
Ibrahim Abdelkader <[email protected]>
Bluetooth: hci_sync: Clear HCI_CMD_PENDING when dropping the last request
Guangshuo Li <[email protected]>
Bluetooth: hci_intel: fix usage_count leak when autosuspend_delay is negative
Guangshuo Li <[email protected]>
Bluetooth: hci_h5: fix usage_count leak when autosuspend_delay is negative
Valentin Kindschi <[email protected]>
Bluetooth: hci_event: clear HCI_LE_ADV only on a created connection
Xin Chen <[email protected]>
Bluetooth: hci_core: use skb_get() instead of skb_clone() for req_skb
Valentin Kindschi <[email protected]>
Bluetooth: hci_conn: re-enable advertising only for peripheral role
Chengfeng Ye <[email protected]>
Bluetooth: RFCOMM: serialize security confirmation handling
Hang Nan <[email protected]>
Bluetooth: ISO: fix use-after-free of listener socket in iso_conn_ready
Gongwei Li <[email protected]>
Bluetooth: hci_uart: Fix false success return in hci_uart_setup()
Guangshuo Li <[email protected]>
Bluetooth: hci_bcm: fix usage_count leak when autosuspend_delay is negative
Lorenzo Stoakes (ARM) <[email protected]>
Bluetooth: hci_bcm4377: Ignore reserved PHY in ext adv reports on BCM4378
Terry Bowman <[email protected]>
cxl/ras: Fix cxl_rch_get_aer_severity() wrong severity register
Alison Schofield <[email protected]>
cxl/pmem: Format the nvdimm serial number as unsigned decimal
Dave Jiang <[email protected]>
cxl/mce: Make the MCE notifier per-region
Zhenhao Wan <[email protected]>
cxl/features: bound fwctl command payload to the input buffer
Hui Su <[email protected]>
cpufreq: schedutil: Fix rate limit overflow
Haoxiang Li <[email protected]>
cpufreq: apple-soc: Fix OPP table cleanup
Kuan-Wei Chiu <[email protected]>
coresight: etm3x: Fix cntr_val_show() to match cntr_val_store() behavior
Bryam Vargas <[email protected]>
dm array: reject an array block whose value size is not the caller's
Bryam Vargas <[email protected]>
dm array: validate array block headers on read
Ilya Krutskih <[email protected]>
dm raid1: reserve space for NUL-terminator in build_constructor_string()
liyouhong <[email protected]>
dm-era: fix shadowed superblock leak on take-snap failure
Mikulas Patocka <[email protected]>
dm-io: report non-retryable errors separatedly
Keith Busch <[email protected]>
dm-io: clone the source bio instead of copying its biovec
Jérémy Jean <[email protected]>
bpf: Harden bloom filter sizing and indexing on 32-bit kernels
Jia Zhu <[email protected]>
buffer: avoid tail commit walk for uptodate folios
Daniel Borkmann <[email protected]>
bpf: Disable preemption in __bpf_get_stack
Vineet Gupta <[email protected]>
bpf, x86: Fix per-CPU address resolution into an extended register
Joe Damato <[email protected]>
bnxt_en: Write doorbell when linearizing skb fails
Jiangshan Yi <[email protected]>
bnx2x: fix double free in bnx2x_init_firmware() error path
HyeongJun An <[email protected]>
Bluetooth: eir: Fix OOB read in eir_get_service_data()
Junjie Cao <[email protected]>
Bluetooth: btusb: limit RTL8761B BROKEN_EXT_SCAN quirk to 0bda:a728
Christoph Zwerschke <[email protected]>
Bluetooth: btusb: Add ASUS USB-BT600 for Realtek 8761CU
Christoph Zwerschke <[email protected]>
Bluetooth: btusb: Add ASUS USB-BT540 for Realtek 8761CU
胡连勤 <[email protected]>
block: set QUEUE_FLAG_DYING unconditionally in blk_mark_disk_dead()
Keith Busch <[email protected]>
block: validate user space vectors during extraction
Junjie Cao <[email protected]>
backlight: aw99706: Honor the core blank state in update_status()
Junjie Cao <[email protected]>
backlight: aw99706: Fix DT property names to match binding
Hongyan Xu <[email protected]>
auxdisplay: charlcd: cancel backlight work on registration failure
Niklas Cassel <[email protected]>
ata: libata-scsi: fix DSM TRIM for sector sizes larger than 2048 bytes
Ethan Nelson-Moore <[email protected]>
ARM: 9477/1: Disable broken eBPF JIT on the Risc PC
Matt Turner <[email protected]>
alpha: marvel: Fix lock ordering in init_io7_irqs()
Matt Turner <[email protected]>
alpha: marvel: Fix irq_set_status_flags to use correct IRQ number
Krzysztof Wilczyński <[email protected]>
alpha/PCI: Fix I/O port accessor argument order in pci_legacy_write()
Rafael J. Wysocki <[email protected]>
ACPI: TAD: Add locking around AML evaluations
Rafael J. Wysocki <[email protected]>
ACPI: scan: Avoid registering platform devices with resource overlaps
Anirudh Prasad <[email protected]>
ACPI: pfr_update: fix stack buffer overflow in query_capability()
Christian Loehle <[email protected]>
ACPI: CPPC: Skip desired_perf read in cppc_get_perf()
Christian Loehle <[email protected]>
ACPI: CPPC: Reject desired_perf reads on _CPC revision 4+
TanZheng <[email protected]>
ACPI: APEI: GHES: fix ARM section length accounting after header
Nirmoy Das <[email protected]>
ACPI: APEI: Fix ERST timeout unit conversion
Terry Bowman <[email protected]>
acpi/apei/ghes: Use raw_spinlock_t for CXL CPER work locks
ZhaoJinming <[email protected]>
accel/rocket: Fix error path handling in rocket_job_run()
Shuvam Pandey <[email protected]>
accel/rocket: initialize job domain before cleanup paths
Muhammad Bilal <[email protected]>
accel/rocket: fix NULL dereference and integer overflow in rocket_job_push()
Guillaume Morin <[email protected]>
hugetlb: only adjust reservation during unmapping if mapcount is 0
Ivaylo Dimitrov <[email protected]>
hsi: omap_ssi_core: fix missing DMA mask setup for SSI controller device
Youngjae Kwon <[email protected]>
fsnotify: Fix stale object mask after concurrent mark updates
Tien Sung Ang <[email protected]>
fpga: stratix10-soc: Fix SVC mailbox handling during reconfiguration
Marek Czernohous <[email protected]>
forcedeth: fix off-by-one when saving/restoring non-PCI config space
Randy Dunlap <[email protected]>
fonts: fixup font.h kernel-doc warnings
Myeonghun Pak <[email protected]>
fbdev: uvesafb: unregister connector callback on init failure
Hui Su <[email protected]>
fbdev: ssd1307fb: defer I2C transfers from damage callbacks
Florian Fuchs <[email protected]>
fbdev: pvr2fb: correct user pointer annotation and sentinel initializer
Runyu Xiao <[email protected]>
fbdev: omapfb: panel-dsi-cm: initialize lock before registering display
Yemu Lu <[email protected]>
fat: restore original value when fat_ent_write failed
Chengfeng Ye <[email protected]>
fanotify: fix use-after-free of file range info
Jan Kara <[email protected]>
ext2: Fix lost inode updates for IS_SYNC inodes
Nikhil Gurudasani <[email protected]>
erofs: skip sufficiently large global buffers when resizing
Jinjie Ruan <[email protected]>
entry: Fix seccomp bypass after ptrace with TSYNC
Ard Biesheuvel <[email protected]>
efivarfs: Rate limit statfs() handler
Yichong Chen <[email protected]>
ecryptfs: show filename encryption options
Yichong Chen <[email protected]>
ecryptfs: release message context on send failure
Yichong Chen <[email protected]>
ecryptfs: reject too-small tag 70 packets
HanQuan <[email protected]>
ecryptfs: reject oversized encrypted_key_size in parse_tag_3_packet
Yichong Chen <[email protected]>
ecryptfs: pass packet set buffer size to parser
Yichong Chen <[email protected]>
ecryptfs: hold msg ctx list lock when cleaning daemon queue
Yichong Chen <[email protected]>
ecryptfs: fix tag 11 packet exact-fit size check
Pengpeng Hou <[email protected]>
eCryptfs: bound the packet-length peek to the user buffer
Hongling Zeng <[email protected]>
ntfs: verify run length exceeding volume boundary
Hongling Zeng <[email protected]>
ntfs: validate non-resident attribute offsets
Hyunchul Lee <[email protected]>
ntfs: reject invalid MFT LCNs from boot sector
Hyunchul Lee <[email protected]>
ntfs: reject invalid empty mapping pairs
Bryam Vargas <[email protected]>
ntfs: bound the free-cluster bitmap scan to the volume
Konstantin Komarov <[email protected]>
fs/ntfs3: bound page_lcns[] index by the log record
Samuel Page <[email protected]>
fs/ntfs3: fix info-leak on partial LZNT decompress in ni_read_frame()
Xiang Mei <[email protected]>
fs/ntfs3: validate dirty page table on log replay
Deepanshu Kartikey <[email protected]>
eventfs: Initialize ei->children and ei->list in init_ei()
Guangshuo Li <[email protected]>
HID: intel-thc-hid: intel-quickspi: fix autosuspend cleanup during teardown
Guangshuo Li <[email protected]>
HID: intel-thc-hid: intel-quicki2c: fix autosuspend cleanup during teardown
HyeongJun An <[email protected]>
HID: intel-thc-hid: intel-quickspi: bound GET_REPORT response to the caller buffer
HyeongJun An <[email protected]>
HID: intel-thc-hid: intel-quickspi: validate report size before copy
Jiangshan Yi <[email protected]>
HID: mcp2221: validate report size in mcp2221_raw_event()
Jiangshan Yi <[email protected]>
HID: mcp2221: clear rxbuf after I2C/SMBus transfer completes
Jiangshan Yi <[email protected]>
HID: mcp2221: stop device IO before hid_hw_stop
Baul Lee <[email protected]>
HID: universal-pidff: stop the device when force-feedback init fails
Doruk Tan Ozturk <[email protected]>
HID: sony: fix UAF of ghl_poke_timer / ghl_urb at driver unbind
Haoxiang Li <[email protected]>
HID: sensor: custom: Fix field sysfs group cleanup on failure
Xu Rao <[email protected]>
HID: roccat: free buffered reports when destroying device
Ibrahim Hashimov <[email protected]>
HID: picolcd: clamp eeprom debugfs read to bytes actually received
Stuart Hayhurst <[email protected]>
HID: corsair-void: Check size of status and firmware events before reading them
Andre Eikmeyer <[email protected]>
HID: apple: preserve keyboard backlight across T2 resume
Bryam Vargas <[email protected]>
smb: client: restore the data_offset bound in is_valid_oplock_break()
Bryam Vargas <[email protected]>
smb: client: reject a tree connect response whose byte count is too small
Fredric Cover <[email protected]>
smb: client: harden DFS cache against invalid target hints
Frank Sorenson <[email protected]>
smb: client: fix use-before-check of ReparseDataLength in reparse_buf_ptr()
Frank Sorenson <[email protected]>
smb: client: fix OOB read/write from unvalidated DataOffset in coalesce_t2()
Frank Sorenson <[email protected]>
smb: client: fix copy-paste error in WSL EA length accounting for $LXDEV
Frank Sorenson <[email protected]>
smb: client: fix ALIGN() overflow in symlink_data() error context loop
Aldo Ariel Panzardo <[email protected]>
ksmbd: only rebind the reopened file's own oplock on durable reconnect
Fredric Cover <[email protected]>
smb: client: clear ce->tgthint in free_tgts()
Frank Sorenson <[email protected]>
smb: client: fix UAF and buffer leak in cifs_check_trans2() for malformed secondary T2
Jiangshan Yi <[email protected]>
smb: client: clear setuid/setgid bit on write with cifsacl/modefromsid/posix extensions
Frank Sorenson <[email protected]>
cifs: use cifs_invalidate_cache() in cifs_do_truncate() for O_TRUNC
Frank Sorenson <[email protected]>
cifs: fix loff_t underflow in cifs_remap_file_range() when len == 0
Frank Sorenson <[email protected]>
cifs: clear tcon after cifsFileInfo_put() in cifs_file_set_size()
Frank Sorenson <[email protected]>
cifs: call pagecache_isize_extended() in cifs_setsize() when extending
Frank Sorenson <[email protected]>
cifs: add cifs_resize_file_locked() to guard fscache_resize_cookie() under i_rwsem
Jérémy Jean <[email protected]>
audit: avoid dropping live tree ref on fsnotify rule autoremove
Qu Wenruo <[email protected]>
btrfs: do not overwrite NODATASUM flag when removing NODATACOW flag
Shuangpeng Bai <[email protected]>
btrfs: fix extent map leak in NOCOW direct I/O write
Guanghui Yang <[email protected]>
btrfs: drop recovered reloc root refs on recovery failure
Matthew Brown <[email protected]>
ceph: fix leaked inode reference on writeback abort at umount
Max Kellermann <[email protected]>
ceph: do not repeat ceph_trim_dentries() if no progress possible
Michael Bommarito <[email protected]>
ceph: cap delegated inode count in ceph_parse_deleg_inos()
Michael Bommarito <[email protected]>
ceph: bound xattr value length in __build_xattrs()
Michael Bommarito <[email protected]>
ceph: bound num_export_targets array for mds info v2/v3
Michael Bommarito <[email protected]>
ceph: bound MDSCapAuth path and fs_name decode in handle_session()
Michael Bommarito <[email protected]>
ceph: bound copied dentry name length in NFS export get_name
Jérémy Jean <[email protected]>
ceph: reject export_targets ranks >= CEPH_MAX_MDS in mdsmap decode
Max Kellermann <[email protected]>
ceph: force a cap message when a deferred revoke can't be acked immediately
Xiubo Li <[email protected]>
ceph: fix UAF in check_new_map() on session freed during unlock
Xiubo Li <[email protected]>
ceph: fix UAF in __kick_flushing_caps() on cf entry freed during unlock
Jérémy Jean <[email protected]>
libceph: reject buckets with mismatched CRUSH ids
Michael Bommarito <[email protected]>
libceph: validate OSD extent maps before cursor advance
Jeff Layton <[email protected]>
nfsd: use test_and_clear_bit for somebody_reclaimed to prevent lost update
Chuck Lever <[email protected]>
NFSD: Prevent client use-after-free during NFSv4.0 revoked-state cleanup
Chuck Lever <[email protected]>
NFSD: Prevent client use-after-free during delegation revoke
Chuck Lever <[email protected]>
NFSD: Prevent client use-after-free during admin state revocation
Chuck Lever <[email protected]>
NFSD: Prevent post-shutdown use-after-free in unlock_filesystem
Chuck Lever <[email protected]>
NFSD: Prevent lock owner use-after-free during client teardown
Jeff Layton <[email protected]>
nfsd: revoke copy-notify stateids before dropping their reference
Jeff Layton <[email protected]>
nfsd: release OPEN-decoded posix ACLs via op_release
Jeff Layton <[email protected]>
nfsd: reject reclaim LOCK after RECLAIM_COMPLETE
Robbie Ko <[email protected]>
nfsd: reject out-of-range useconds in NFSv2 SETATTR/CREATE
Robbie Ko <[email protected]>
nfsd: reject out-of-range nseconds in NFSv3 SETATTR and create ops
Jeff Layton <[email protected]>
nfsd: close shrinker/GC/fsnotify vs per-net shutdown race in filecache
Jeff Layton <[email protected]>
nfsd: move nfsd_debugfs_init() after nfsd4_init_slabs() in init_nfsd()
Jeff Layton <[email protected]>
nfsd: initialize DRC hash table before registering shrinker
Jeff Layton <[email protected]>
nfsd: initialize copy-notify stateid before publishing it
Chris Mason <[email protected]>
nfsd: hold rcu across localio cmpxchg retry
Chris Mason <[email protected]>
nfsd: gate nfs3 setacl by argp->mask
Chuck Lever <[email protected]>
nfsd: gate nfs2 setacl by argp->mask
Jeff Layton <[email protected]>
nfsd: fix XDR padding calculation in ff_encode_getdeviceinfo
Jeff Layton <[email protected]>
nfsd: fix XDR length calculation in nfsd4_ff_encode_layoutget
Jeff Layton <[email protected]>
nfsd: fix version mismatch loops in nfsd_acl_init_request()
Jeff Layton <[email protected]>
nfsd: fix UAF in async copy cancel and shutdown
Jeff Layton <[email protected]>
nfsd: fix stale s2s_cp_stateids IDR entry for async COPY
Jeff Layton <[email protected]>
nfsd: fix reply size estimate for GET_DIR_DELEGATION
Jeff Layton <[email protected]>
nfsd: fix refcount leak in nfsd_file_lru_add on insertion failure
NeilBrown <[email protected]>
nfsd: fix possible fh_compose of wrong dentry in nfsd4_create_file()
Chris Mason <[email protected]>
nfsd: fix partial-write detection in nfsd_direct_write
Nikol Kuklev <[email protected]>
nfsd: fix null dereference in nfsd4_setattr for deleg timestamp attrs
Jeff Layton <[email protected]>
nfsd: fix nfsd_file leak on inter-server COPY setup failure
Jeff Layton <[email protected]>
nfsd: fix netlink dumpit error handling for rpc_status_get
Jeff Layton <[email protected]>
nfsd: fix layout fence worker double-reference race
Jeff Layton <[email protected]>
nfsd: fix FL_SLEEP being set unconditionally for all LOCK types
Jeff Layton <[email protected]>
nfsd: fix fcache_disposal UAF by inlining dispose state into nfsd_net
Jeff Layton <[email protected]>
nfsd: fix dentry ref leak on V4ROOT export filehandle lookup
Chris Mason <[email protected]>
nfsd: fix cpntf publish race in nfs4_init_cp_state
Jeff Layton <[email protected]>
nfsd: fix clock domain mismatch in clients_still_reclaiming()
Jeff Layton <[email protected]>
nfsd: fix BUG_ON in nfsd4_alloc_layout_stateid on racing delegation revoke
NeilBrown <[email protected]>
nfsd: ensure nfsd_file_do_acquire() does not use a non-opened file
Jeff Layton <[email protected]>
nfsd: drop the stateid, not the stateowner, on seqid_op replay retry
Jeff Layton <[email protected]>
nfsd: don't free session slots that are still in use
Jeff Layton <[email protected]>
nfsd: defer vfree of compound ops to fix rpc_status UAF
Jeff Layton <[email protected]>
nfsd: defer setting NFSD4_CALLBACK_RUNNING in deleg_reaper
Jeff Layton <[email protected]>
nfsd: dedup nfs4_client_to_reclaim inserts
Chris Mason <[email protected]>
nfsd: convert nfsd_net boolean flags to unsigned long flags word
Jeff Layton <[email protected]>
nfsd: clear opcnt on compound arg release to prevent OOB read
Jeff Layton <[email protected]>
nfsd: clear CALLBACK_RUNNING on failed delegation recall queue
Jeff Layton <[email protected]>
nfsd: check nfsd4_acl_to_attr() return value in nfsd4_create()
Jeff Layton <[email protected]>
nfsd: check client ownership when cancelling a copy-notify stateid
Chris Mason <[email protected]>
nfsd: cap decoded POSIX ACL count to bound sort cost
Jeff Layton <[email protected]>
nfsd: block non-SAVEFH ops after FOREIGN PUTFH to prevent NULL deref
Jeff Layton <[email protected]>
nfsd: add missing read barrier to rpc_status_get dumpit seqcount retry
Jeff Layton <[email protected]>
nfsd: add filehandle match check to nfsd4_delegreturn()
Jeff Layton <[email protected]>
nfsd: add fh_want_write() for early-verified SETATTR in nfsd_proc_setattr()
Jeff Layton <[email protected]>
nfsd: widen nfsd_genl_rqstp address fields to sockaddr_storage
Jeff Layton <[email protected]>
nfsd: validate symlink target length in NFSv4 CREATE
Jeff Layton <[email protected]>
nfsd: validate sockaddr length per family in listener_set
Jeff Layton <[email protected]>
nfsd: validate nseconds in TIME_DELEG decode paths
Chris Mason <[email protected]>
nfsd: size fh_verify server sockaddr slot by xpt_locallen
Zhenghang Xiao <[email protected]>
nfsd: set SC_STATUS_FREED in nfsd4_drop_revoked_stid for delegations
Chuck Lever <[email protected]>
nfsd: sample writeback error cursor before async COPY loop
Jeff Layton <[email protected]>
nfsd: return NFS4ERR_NOTSUPP for unsupported netloc4 types
Jeff Layton <[email protected]>
nfsd: restore rq_status_counter to even on all nfsd_dispatch() exit paths
Chuck Lever <[email protected]>
nfsd: Reset write verifier when async COPY writeback fails
Chris Mason <[email protected]>
nfsd: release path refs on follow_down() error
Jeff Layton <[email protected]>
nfsd: RCU-protect cl_cb_session to fix use-after-free on session teardown
Jeff Layton <[email protected]>
lockd, nfsd: RCU-protect nlmsvc_ops dispatch
Tim Menninger <[email protected]>
pNFS: Fix EBUSY check in pnfs_layout_need_return
Junrui Luo <[email protected]>
NFSv4.1: fix layout segment leak on the pnfs_layout_process() forget path
Chris Mason <[email protected]>
nfsd: guard nfsd_serv deref in nfsd_file_net_dispose
Mike Snitzer <[email protected]>
NFSD: remove flawed WARN_ON_ONCE from nfsd_mode_check
Michael Bommarito <[email protected]>
NFSD: restart ssc_expire_umount walk after dropping nfsd_ssc_lock
Scott Mayhew <[email protected]>
NFSD: fix up error returned by write_threads()
Chuck Lever <[email protected]>
NFSD: Fix off-by-one in DRC bucket pruning limit
Chuck Lever <[email protected]>
NFSD: Encode only the status in NFS-ACL v2 GETACL error replies
Chuck Lever <[email protected]>
NFSD: check truncate permission under inode lock
Nate Prodromou <[email protected]>
NFS: fix delegation_hash_table leak when nfs4_server_common_setup() fails
Chris Mason <[email protected]>
NFS/localio: fix ref leak on nfs_uuid_add_file failure
Longlong Xia <[email protected]>
zsmalloc: account for handle size in class lookup
Sergey Senozhatsky <[email protected]>
zram: validate deflate params
Sergey Senozhatsky <[email protected]>
zram: set default primary compressor in zram_destroy_comps()
Longlong Xia <[email protected]>
zram: fix out-of-bounds access in writeback_store()
Longlong Xia <[email protected]>
zram: fix out-of-bounds access in read_block_state()
Ibrahim Hashimov <[email protected]>
ubifs: fix out-of-bounds read in signature length check
Jason Yang <[email protected]>
phy: rockchip-samsung-dcphy: fix out-of-range max_register
Krzysztof Wilczyński <[email protected]>
PCI/sysfs: Fix out-of-bounds read in pci_write_legacy_io()
Abdurrahman Hussain <[email protected]>
of: fix out-of-bounds read in of_alias_scan() stem parser
Ryusuke Konishi <[email protected]>
nilfs2: fix slab-out-of-bounds in nilfs_direct_propagate after truncation
Junrui Luo <[email protected]>
media: vicodec: fix out-of-bounds write in FWHT encoder
Weigang He <[email protected]>
media: cec: stm32: prevent out-of-bounds write on RX overflow
Vincent Mailhol <[email protected]>
lib/ucs2_string.c: fix out-of-bounds read in ucs2_strnlen()
Karl Mehltretter <[email protected]>
KVM: arm64: GICv2: Don't WARN on out-of-range GICV_DIR INTID
Claudiu Beznea <[email protected]>
i3c: renesas: Fix out-of-bounds access for newdevs mask
Xingrui Li <[email protected]>
HID: sensor-hub: Fix out-of-bounds write in sensor_hub_get_feature
Daisuke Matsuda <[email protected]>
fpga: altera-cvp: Avoid out-of-bounds read in trailing byte write
Terry Bowman <[email protected]>
cxl/ras: Fix cxl_rch_get_aer_info() out-of-bounds AER register read
Neill Kapron <[email protected]>
usb: gadget: f_fs: Prevent deadlock during ep0 read loop
Jeffin Philip <[email protected]>
usb: gadget: uvc: fix dangling pointers in uvc_function_bind() and uvc_function_unbind()
Jeffin Philip <[email protected]>
usb: gadget: uvc: Fix null pointer dereference in uvcg_video_init()
Yun Zhou <[email protected]>
usb: gadget: f_tcm: fix deadlock in usbg_make_tpg()
Joshua Crofts <[email protected]>
usb: gadget: midi2: remove default configfs groups on teardown
Myeonghun Pak <[email protected]>
usb: gadget: snps_udc_plat: clean up PHY on probe deferral
Sonali Pradhan <[email protected]>
usb: gadget: u_audio: Fix use-after-free on sound card disconnect
Huang Wei <[email protected]>
usb: typec: ucsi: use UCSI_TIMEOUT_MS for sync command completion
Fan Wu <[email protected]>
usb: typec: thunderbolt: Disable work before freeing tbt on remove
Xu Yang <[email protected]>
usb: typec: tcpci: pass correct rx_type to tcpm_pd_receive()
Xu Rao <[email protected]>
usb: typec: hd3ss3220: fix VBUS regulator error message
Johan Hovold <[email protected]>
USB: phy: fsl-usb: fix missing static keywords
Fan Wu <[email protected]>
usb: gadget: at91_udc: drain polled-VBUS timer/work before udc is freed
Pei Xiao <[email protected]>
usb: dwc3: gadget: Fix use-after-free in dwc3_gadget_free_endpoints due to race condition
Francesco Lavra <[email protected]>
usb: dwc2: gadget: Exit partial power down state when changing USB pull-up
Hao-Qun Huang <[email protected]>
staging: greybus: hid: fix SET_REPORT return value
Karl Mehltretter <[email protected]>
serial: imx: serialize imx_uart_ports[] lifetime
Hans Verkuil <[email protected]>
Revert "media: v4l2-dev: fix error handling in __video_register_device()"
James Kim <[email protected]>
rapidio: mport_cdev: fix use-after-free in dma_req_free()
Bartosz Golaszewski <[email protected]>
powerpc/powermac: fix OF node refcount
Bryam Vargas <[email protected]>
misc: nsm: bound the device-reported response length
Xu Yang <[email protected]>
device property: fix infinite loop in fwnode_for_each_child_node()
Chun-Yi Lee <[email protected]>
debugfs: Fix lockdown check for mmap_prepare
Prasanna Kumar T S M <[email protected]>
cdx: Fix double free when sysfs file creation fails
Hui Su <[email protected]>
tracing: Fix use-after-free with same-name named triggers
Deepanshu Kartikey <[email protected]>
tracing: Fix use-after-free in trace_pipe read on sub-buffer order change
Ivan Immanuel Shaji <[email protected]>
tracing: Fix retry exhaustion in simple ring buffer reader swap
Vincent Donnefort <[email protected]>
tracing: Fix logged instance name on creation failure
Hui Su <[email protected]>
tracing: Fix crash passing ERR_PTR to kthread_stop()
Jérémy Jean <[email protected]>
tracing/user_events: Clear copied tracing state before fork duplication
Sanman Pradhan <[email protected]>
hwtracing: hisi_ptt: Propagate DMA reset timeout in trace_start()
Roger Pau Monne <[email protected]>
x86/xen: fix init of balloon stats again
Kiryl Shutsemau (Meta) <[email protected]>
x86/tdx: Fix zero-extension for 32-bit port I/O
Kiryl Shutsemau (Meta) <[email protected]>
x86/tdx: Fix off-by-one in port I/O handling
Kiryl Shutsemau (Meta) <[email protected]>
x86/insn-eval: Move assign_register() out of KVM as insn_assign_reg()
Yao Zi <[email protected]>
x86/locking: Use sfence for wmb() if SSE is available
Joy H.J. Lee <[email protected]>
tools/compiler: match glibc 2.42 definition of __attribute_const__
Ridong Chen <[email protected]>
mm: vmscan: fix node reclaim ignoring swappiness parameter
Johannes Weiner <[email protected]>
mm: page_alloc: fix non-movable reclaim storm in defrag_mode
Vlastimil Babka (SUSE) <[email protected]>
mm: page_alloc: move capture_control to the page allocator
Johannes Weiner <[email protected]>
mm: page_alloc: __GFP_FS lockdep annotation for direct compaction
Johannes Weiner <[email protected]>
mm: mempolicy: fix automatic numa balancing for shmem
Guopeng Zhang <[email protected]>
mm: memcontrol: update state_local when flushing NMI stats
Guopeng Zhang <[email protected]>
mm: memcg: stop reclaim when a limit update is superseded
Guopeng Zhang <[email protected]>
mm: memcg-v1: fix memsw and TCP failcnt accounting
Guopeng Zhang <[email protected]>
mm: memcg-v1: fix wrong linux-mm list address in deprecation warnings
Johannes Weiner <[email protected]>
mm: compaction: support non-movable compaction for pageblock requests
Hao Jia <[email protected]>
mm/zswap: fix global shrinker when memory cgroup is disabled
Breno Leitao <[email protected]>
mm/vmscan: report RCU-tasks quiescent states in shrink_lruvec()
Artem Lytkin <[email protected]>
mm/vmalloc: make vm_struct.nr_pages an unsigned long
Shengming Hu <[email protected]>
mm/slub: prevent pfmemalloc objects from entering the barn
Li Xiasong <[email protected]>
mm/slub: fix missing debugfs entries for caches created before sysfs init
Dev Jain <[email protected]>
mm/rmap: use huge_ptep_get() in try_to_migrate_one()
Dev Jain <[email protected]>
mm/rmap: use huge_ptep_get() in try_to_unmap_one()
Hyunwoo Kim <[email protected]>
mm/pagewalk: fix stale walk->action escaping walk_pmd_range()
Dev Jain <[email protected]>
mm/page_vma_mapped: use huge_ptep_get() for hugetlb
Ye Liu <[email protected]>
mm/page_owner: use memcg_data snapshot to avoid TOCTOU in print_page_owner_memcg()
Alexander Graf <[email protected]>
mm/mm_init: deferred_grow_zone(): fix out-of-range first_deferred_pfn
Arvind Yadav <[email protected]>
mm/migrate_device: clear stale mapping after freeing swapcache
Dev Jain <[email protected]>
mm/migrate: use huge_ptep_get() in remove_migration_pte()
Breno Leitao <[email protected]>
mm/migrate: report RCU-tasks quiescent states in migrate_pages_batch()
Kairui Song <[email protected]>
mm/mglru: fix and remove redundant unevictable folio handling
Usama Arif <[email protected]>
mm/mempolicy: skip non-present PMDs when queueing folios
Usama Arif <[email protected]>
mm/madvise: skip device-private PMDs in cold and pageout walks
Breno Leitao <[email protected]>
mm/kmemleak: avoid soft lockup when scanning task stacks
Muchun Song <[email protected]>
mm/hugetlb_vmemmap: fix __hugetlb_vmemmap_optimize_folios()
Muchun Song <[email protected]>
mm/hugetlb: initialize gigantic bootmem hugepage struct pages earlier
Muchun Song <[email protected]>
mm/hugetlb: fix boot panic with CONFIG_DEBUG_VM and HVO bootmem pages
Zi Yan <[email protected]>
mm/huge_memory: use folio's memcg inside __folio_split()
Usama Arif <[email protected]>
mm/huge_memory: skip device-private PMDs in madvise_free_huge_pmd
David Hildenbrand (Arm) <[email protected]>
mm/gup: fix always draining LRU caches in collect_longterm_unpinnable_folios()
Breno Leitao <[email protected]>
mm, swap: ratelimit bad swap entry reports
Youngjun Park <[email protected]>
mm, swap: don't free a hibernation slot that is in the swap cache
Jordan R Abrahams-Whitehead <[email protected]>
include/linux/list.h: mark list_add and __list_add as __always_inline
Hyunwoo Kim <[email protected]>
apparmor: fix out-of-bounds write when null terminating a label vec
Jann Horn <[email protected]>
apparmor: fix cred UAF caused by begin_current_label_crit_section()
Chengfeng Ye <[email protected]>
KEYS: trusted: Fix TPM teardown ordering
Miguel Ojeda <[email protected]>
kbuild: rust: keep Rust objects out of Clang LTO with inline helpers
Miguel Ojeda <[email protected]>
kbuild: rust: preserve unreachable traps with inline helpers
Gary Guo <[email protected]>
rust: cfi: disable function merging if CFI is enabled
Younes Akhouayri <[email protected]>
rust: num: restrict bool conversion to unsigned Bounded
Miguel Ojeda <[email protected]>
objtool/rust: add one more noreturn Rust function
Nikolai Grlica <[email protected]>
rust: kernel: list: fix incorrect pop_back example comment
Miguel Ojeda <[email protected]>
rust: kbuild: disambiguate zerocopy_derive for rusttest
Danilo Krummrich <[email protected]>
rust: devres: ensure revocation is complete before device finishes unbinding
Danilo Krummrich <[email protected]>
rust: devres: fix race between concurrent revokers
Younes Akhouayri <[email protected]>
rust: dma: return zero for Coherent reads past EOF
Miguel Ojeda <[email protected]>
rust: rust_is_available: warn for `bindgen` < 0.72.1 && libclang >= 22
FUJITA Tomonori <[email protected]>
rust: bug: prevent dead_code warning from warn_on!'s flags constant
FUJITA Tomonori <[email protected]>
rust: bug: fix warn_on macro build error on UML
FUJITA Tomonori <[email protected]>
rust: bug: skip arch-specific asm in testlib builds
Antoni Boucher <[email protected]>
rust: kbuild: disambiguate zerocopy for rusttest
Miguel Ojeda <[email protected]>
objtool/rust: add one more noreturn Rust function for Rust 1.99.0
Jérémy Jean <[email protected]>
timers/itimer: Zero-init old itimerval before copy to userspace
Ke Sun <[email protected]>
rust: fmt: fix {:p} printing stack addresses
Gaurav Batra <[email protected]>
powerpc/pseries/iommu: switch to Default DMA window during kdump
Chen Linxuan <[email protected]>
pidfd: hold exec_update_lock around namespace ioctl
Vivek Parikh <[email protected]>
ovl: fix double end_creating() on the casefold-mismatch path
Baokun Li <[email protected]>
fs: fix user path of nested backing files
Felix Yan <[email protected]>
clocksource/drivers/timer-sun4i: Advertise a real minimum delta
WenTao Liang <[email protected]>
clocksource/drivers/nxp-pit: Fix IRQ leak on cpuhp_setup_state error path
Matt Turner <[email protected]>
alpha: don't leak hardware-fabricated FP exception bits to user space
FUJITA Tomonori <[email protected]>
rust: time: fix as_micros_ceil() rounding near i64::MAX
Christoph Hellwig <[email protected]>
iomap: don't free integrity payload that doesn't exist
Matt Turner <[email protected]>
alpha: fix ieee_swcr_to_fpcr setting FPCR_DNOD unconditionally
Fangzhi Zuo <[email protected]>
drm/amd/display: Prune per-tile Timing from Apple Studio Display Primary Tile
Jerry Zuo <[email protected]>
drm/amd/display: hide Apple Studio Display secondary tile
Vincent Donnefort <[email protected]>
ring-buffer: Fix subbuf resize race with ring buffer readers
Boris Burkov <[email protected]>
btrfs: write-protect folios during data writeback
Jon Hunter <[email protected]>
ASoC: tegra: Sort MBDRC register defaults
Jon Hunter <[email protected]>
ASoC: tegra: Sort ADMAIF register defaults
Jon Hunter <[email protected]>
ASoC: tegra: Fix the MIXER enable default value
Jon Hunter <[email protected]>
ASoC: tegra: Fix the I2S enable default value
Peter Ujfalusi <[email protected]>
ASoC: tegra210_mixer: sort the register default table
Peter Ujfalusi <[email protected]>
ASoC: tegra210_i2s: sort the Tegra264 register default table
Peter Ujfalusi <[email protected]>
ASoC: tegra210_i2s: sort the register default table
Fangzhi Zuo <[email protected]>
drm/amd/display: Skip Update HDCP Config In Transition State
-------------
Diffstat:
Documentation/ABI/testing/sysfs-bus-nvdimm | 3 +- Documentation/admin-guide/blockdev/zoned_loop.rst | 9 +- Makefile | 17 +- arch/alpha/include/uapi/asm/fpu.h | 8 +- arch/alpha/kernel/pci-sysfs.c | 6 +- arch/alpha/kernel/sys_marvel.c | 25 +- arch/alpha/kernel/traps.c | 6 +- arch/alpha/math-emu/math.c | 88 ++++- arch/arm/Kconfig | 2 +- arch/arm64/boot/dts/qcom/kodiak.dtsi | 9 +- arch/arm64/boot/dts/qcom/sm6115-fxtec-pro1x.dts | 2 +- arch/arm64/boot/dts/qcom/x1-dell-thena.dtsi | 2 + arch/arm64/boot/dts/rockchip/px30-cobra.dtsi | 2 +- arch/arm64/boot/dts/rockchip/px30-pp1516.dtsi | 2 +- arch/arm64/boot/dts/rockchip/px30-ringneck.dtsi | 2 +- .../boot/dts/rockchip/rk3399-pinephone-pro.dts | 18 - .../arm64/boot/dts/rockchip/rk3399-roc-pc-plus.dts | 12 + arch/arm64/boot/dts/rockchip/rk3588s-roc-pc.dts | 23 +- arch/arm64/kernel/compat_alignment.c | 4 +- arch/arm64/kernel/proton-pack.c | 9 +- arch/arm64/kvm/vgic/vgic-v2.c | 3 +- arch/openrisc/kernel/entry.S | 43 ++- arch/powerpc/kernel/pci-common.c | 9 +- arch/powerpc/platforms/powermac/low_i2c.c | 2 +- arch/powerpc/platforms/pseries/iommu.c | 23 +- arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts | 4 +- arch/riscv/boot/dts/spacemit/k1-milkv-jupiter.dts | 4 +- arch/riscv/boot/dts/spacemit/k1-musepi-pro.dts | 4 +- arch/riscv/boot/dts/spacemit/k1-orangepi-r2s.dts | 4 +- arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts | 4 +- arch/riscv/include/asm/acpi.h | 19 + arch/riscv/kernel/unaligned_access_speed.c | 19 +- arch/riscv/kvm/vcpu_pmu.c | 14 +- arch/s390/include/asm/percpu.h | 4 +- arch/s390/kernel/perf_cpum_cf.c | 221 ++++++++---- arch/x86/coco/tdx/tdx.c | 10 +- arch/x86/include/asm/barrier.h | 2 +- arch/x86/include/asm/insn-eval.h | 36 ++ arch/x86/kvm/emulate.c | 26 +- arch/x86/net/bpf_jit_comp.c | 2 +- block/bio.c | 56 ++- block/blk-map.c | 2 +- block/fops.c | 2 +- block/genhd.c | 1 + drivers/accel/rocket/rocket_job.c | 32 +- drivers/acpi/acpi_platform.c | 45 ++- drivers/acpi/acpi_tad.c | 46 ++- drivers/acpi/apei/erst.c | 2 +- drivers/acpi/apei/ghes.c | 52 ++- drivers/acpi/cppc_acpi.c | 24 +- drivers/acpi/pfr_update.c | 45 +-- drivers/ata/libata-scsi.c | 28 +- drivers/auxdisplay/charlcd.c | 21 +- drivers/base/arch_numa.c | 12 + drivers/base/power/main.c | 1 + drivers/base/property.c | 19 +- drivers/block/zloop.c | 3 +- drivers/block/zram/backend_deflate.c | 10 +- drivers/block/zram/zram_drv.c | 14 +- drivers/bluetooth/btrtl.c | 13 - drivers/bluetooth/btusb.c | 14 + drivers/bluetooth/hci_bcm.c | 1 + drivers/bluetooth/hci_bcm4377.c | 1 + drivers/bluetooth/hci_h5.c | 4 +- drivers/bluetooth/hci_intel.c | 1 + drivers/bluetooth/hci_ldisc.c | 2 +- drivers/bluetooth/hci_serdev.c | 2 +- drivers/cdx/cdx.c | 7 +- drivers/char/hw_random/stm32-rng.c | 10 +- drivers/char/ipmi/ipmb_dev_int.c | 5 +- drivers/char/ipmi/ipmi_msghandler.c | 4 + drivers/char/tpm/tpm_i2c_nuvoton.c | 6 +- drivers/clocksource/timer-nxp-pit.c | 4 +- drivers/clocksource/timer-sun4i.c | 2 +- drivers/cpufreq/apple-soc-cpufreq.c | 36 +- drivers/cpufreq/cppc_cpufreq.c | 2 +- drivers/crypto/atmel-ecc.c | 46 +-- drivers/crypto/intel/iaa/iaa_crypto_main.c | 27 +- drivers/cxl/core/features.c | 8 +- drivers/cxl/core/mbox.c | 8 - drivers/cxl/core/mce.c | 27 +- drivers/cxl/core/pmem.c | 10 +- drivers/cxl/core/ras.c | 1 - drivers/cxl/core/ras_rch.c | 27 +- drivers/cxl/core/region.c | 43 +-- drivers/cxl/cxl.h | 11 +- drivers/cxl/cxlmem.h | 2 - drivers/cxl/pci.c | 1 - drivers/cxl/pmem.c | 2 +- drivers/fpga/altera-cvp.c | 10 +- drivers/fpga/stratix10-soc.c | 21 +- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 79 ++++ .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c | 28 +- .../drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 11 + drivers/gpu/drm/amd/display/dc/dc_types.h | 1 + drivers/gpu/drm/nouveau/nouveau_gem.c | 11 +- drivers/hid/hid-apple.c | 18 +- drivers/hid/hid-corsair-void.c | 17 + drivers/hid/hid-mcp2221.c | 17 +- drivers/hid/hid-picolcd_debugfs.c | 9 + drivers/hid/hid-roccat.c | 13 +- drivers/hid/hid-sensor-custom.c | 9 +- drivers/hid/hid-sensor-hub.c | 46 ++- drivers/hid/hid-sony.c | 4 +- drivers/hid/hid-universal-pidff.c | 4 +- .../intel-thc-hid/intel-quicki2c/pci-quicki2c.c | 1 + .../intel-thc-hid/intel-quickspi/pci-quickspi.c | 10 +- .../intel-thc-hid/intel-quickspi/quickspi-dev.h | 1 + .../intel-thc-hid/intel-quickspi/quickspi-hid.c | 2 +- .../intel-quickspi/quickspi-protocol.c | 19 +- .../intel-quickspi/quickspi-protocol.h | 2 +- drivers/hsi/controllers/omap_ssi_core.c | 6 + drivers/hwmon/max6621.c | 8 +- .../hwtracing/coresight/coresight-etm3x-sysfs.c | 15 +- drivers/hwtracing/ptt/hisi_ptt.c | 20 +- drivers/i2c/busses/i2c-mxs.c | 5 +- drivers/i3c/device.c | 2 +- drivers/i3c/internals.h | 5 + drivers/i3c/master.c | 18 +- drivers/i3c/master/adi-i3c-master.c | 15 +- drivers/i3c/master/renesas-i3c.c | 142 +++++--- drivers/i3c/master/svc-i3c-master.c | 10 +- drivers/infiniband/core/ib_core_uverbs.c | 3 + drivers/infiniband/core/ucma.c | 14 +- drivers/infiniband/core/uverbs_main.c | 1 + drivers/infiniband/core/uverbs_std_types_mr.c | 6 +- drivers/infiniband/hw/cxgb4/device.c | 6 + drivers/infiniband/hw/ionic/ionic_hw_stats.c | 95 +++-- drivers/infiniband/hw/ionic/ionic_ibdev.h | 11 +- drivers/infiniband/hw/ionic/ionic_lif_cfg.c | 2 +- drivers/interconnect/core.c | 7 +- drivers/iommu/amd/ppr.c | 3 +- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c | 24 +- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 65 +++- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 3 + drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c | 8 +- drivers/iommu/generic_pt/iommu_pt.h | 2 +- drivers/iommu/intel/dmar.c | 15 +- drivers/iommu/intel/iommu.c | 8 +- drivers/iommu/intel/iommu.h | 2 + drivers/iommu/iommu-sva.c | 2 +- drivers/iommu/iommu.c | 2 +- drivers/iommu/iommufd/device.c | 4 +- drivers/iommu/iommufd/ioas.c | 2 + drivers/iommu/iommufd/selftest.c | 31 +- drivers/iommu/msm_iommu.c | 10 +- drivers/mailbox/qcom-ipcc.c | 17 +- drivers/md/dm-bufio.c | 10 +- drivers/md/dm-era-target.c | 5 + drivers/md/dm-integrity.c | 32 +- drivers/md/dm-io.c | 96 +++-- drivers/md/dm-kcopyd.c | 10 +- drivers/md/dm-log-userspace-base.c | 1 + drivers/md/dm-log.c | 4 +- drivers/md/dm-pcache/cache.c | 18 + drivers/md/dm-pcache/cache.h | 21 ++ drivers/md/dm-pcache/cache_dev.c | 22 +- drivers/md/dm-pcache/cache_gc.c | 10 +- drivers/md/dm-pcache/cache_key.c | 32 +- drivers/md/dm-pcache/cache_segment.c | 12 +- drivers/md/dm-pcache/cache_writeback.c | 10 +- drivers/md/dm-pcache/dm_pcache.c | 4 +- drivers/md/dm-raid1.c | 26 +- drivers/md/dm-snap-persistent.c | 4 +- drivers/md/dm-stats.c | 6 +- drivers/md/dm-switch.c | 2 +- drivers/md/dm-verity-target.c | 2 +- drivers/md/dm-writecache.c | 14 +- drivers/md/md.c | 7 + drivers/md/persistent-data/dm-array.c | 53 ++- drivers/md/raid10.c | 2 +- drivers/media/cec/platform/stm32/stm32-cec.c | 3 +- drivers/media/test-drivers/vicodec/vicodec-core.c | 4 +- drivers/media/v4l2-core/v4l2-dev.c | 14 +- drivers/mfd/cgbc-core.c | 4 +- drivers/mfd/qnap-mcu.c | 13 +- drivers/mfd/sm501.c | 2 + drivers/misc/nsm.c | 2 +- drivers/mmc/host/via-sdmmc.c | 12 +- drivers/net/dsa/realtek/rtl83xx.c | 4 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 3 + drivers/net/ethernet/broadcom/bnxt/bnxt.c | 17 +- drivers/net/ethernet/broadcom/bnxt/bnxt_gso.c | 4 +- drivers/net/ethernet/ibm/emac/mal.c | 13 +- drivers/net/ethernet/mellanox/mlx5/core/en_rx.c | 5 + drivers/net/ethernet/nvidia/forcedeth.c | 4 +- drivers/net/ethernet/qlogic/qede/qede.h | 8 +- drivers/net/ethernet/qlogic/qede/qede_fp.c | 1 + drivers/net/ethernet/renesas/ravb.h | 3 + drivers/net/ethernet/renesas/ravb_main.c | 9 +- drivers/net/ethernet/renesas/ravb_ptp.c | 44 ++- drivers/net/ipa/ipa_modem.c | 18 +- drivers/net/ntb_netdev.c | 38 +- drivers/net/phy/phylink.c | 2 +- drivers/net/slip/slip.c | 11 +- drivers/net/thunderbolt/main.c | 12 + drivers/net/tun.c | 21 +- drivers/net/usb/qmi_wwan.c | 1 + drivers/net/wireless/ath/ath6kl/cfg80211.c | 5 + .../wireless/broadcom/brcm80211/brcmfmac/sdio.c | 3 +- drivers/net/wireless/intel/iwlwifi/dvm/main.c | 4 +- drivers/net/wireless/marvell/mwifiex/sta_ioctl.c | 12 + drivers/net/wireless/mediatek/mt76/mt7615/main.c | 5 +- drivers/net/wireless/mediatek/mt76/mt7915/mcu.c | 11 +- drivers/net/wireless/mediatek/mt76/mt7925/mac.c | 1 + drivers/net/wireless/mediatek/mt76/mt7925/main.c | 12 +- drivers/net/wireless/mediatek/mt76/mt7925/pci.c | 2 + drivers/net/wireless/mediatek/mt76/mt7925/usb.c | 1 + drivers/net/wireless/mediatek/mt76/mt7996/eeprom.c | 6 + drivers/net/wireless/mediatek/mt76/mt7996/mac.c | 26 +- drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 9 +- drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c | 2 +- drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c | 2 +- drivers/net/wireless/realtek/rtl8xxxu/core.c | 19 +- .../net/wireless/realtek/rtlwifi/rtl8192du/sw.c | 12 +- .../net/wireless/realtek/rtlwifi/rtl8192du/trx.c | 3 +- drivers/net/wireless/realtek/rtw88/pci.c | 4 +- drivers/net/wireless/realtek/rtw88/tx.c | 1 + drivers/net/wireless/realtek/rtw89/core.h | 1 + drivers/net/wireless/realtek/rtw89/mac80211.c | 3 +- drivers/net/wireless/realtek/rtw89/pci.c | 13 + drivers/net/wireless/realtek/rtw89/pci.h | 1 + drivers/net/wireless/realtek/rtw89/rtw8851be.c | 1 + drivers/net/wireless/realtek/rtw89/rtw8852ae.c | 1 + drivers/net/wireless/realtek/rtw89/rtw8852be.c | 1 + drivers/net/wireless/realtek/rtw89/rtw8852bte.c | 1 + drivers/net/wireless/realtek/rtw89/rtw8852ce.c | 1 + drivers/net/wireless/realtek/rtw89/rtw8922ae.c | 1 + drivers/net/wireless/realtek/rtw89/rtw8922de.c | 1 + drivers/ntb/ntb_transport.c | 38 +- drivers/nvdimm/label.c | 2 +- drivers/nvme/host/core.c | 2 +- drivers/nvme/host/fc.c | 2 +- drivers/nvme/host/pci.c | 1 + drivers/nvme/host/tcp.c | 45 ++- drivers/of/base.c | 2 +- drivers/pci/controller/dwc/pci-meson.c | 2 +- drivers/pci/controller/pci-hyperv.c | 1 + drivers/pci/controller/plda/pcie-plda-host.c | 52 ++- drivers/pci/controller/plda/pcie-starfive.c | 13 +- drivers/pci/msi/msi.c | 10 + drivers/pci/pci-sysfs.c | 42 ++- drivers/pci/pcie/aer.c | 29 +- drivers/pci/pcie/portdrv.c | 2 +- drivers/pci/proc.c | 16 +- drivers/pci/quirks.c | 9 +- drivers/phy/freescale/phy-fsl-imx8mq-usb.c | 21 +- drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c | 2 +- drivers/platform/chrome/cros_ec_sensorhub_ring.c | 19 +- drivers/platform/x86/amd/pmc/mp1_stb.c | 66 ++-- drivers/platform/x86/amd/pmc/pmc.c | 6 +- .../x86/dell/dell-wmi-sysman/biosattr-interface.c | 1 - drivers/platform/x86/hp/hp-bioscfg/bioscfg.c | 18 +- drivers/platform/x86/hp/hp-bioscfg/bioscfg.h | 8 + .../platform/x86/hp/hp-bioscfg/enum-attributes.c | 15 +- .../platform/x86/hp/hp-bioscfg/int-attributes.c | 6 +- .../x86/hp/hp-bioscfg/order-list-attributes.c | 14 +- .../x86/hp/hp-bioscfg/passwdobj-attributes.c | 14 +- .../platform/x86/hp/hp-bioscfg/spmobj-attributes.c | 4 +- .../platform/x86/hp/hp-bioscfg/string-attributes.c | 6 +- drivers/platform/x86/hp/hp-wmi.c | 4 + drivers/platform/x86/intel/int1092/intel_sar.c | 32 +- drivers/platform/x86/intel/ishtp_eclite.c | 5 +- .../x86/intel/speed_select_if/isst_tpmi_core.c | 80 ++++- drivers/platform/x86/lenovo/think-lmi.c | 19 +- drivers/platform/x86/lenovo/ymc.c | 8 +- drivers/platform/x86/panasonic-laptop.c | 11 +- drivers/power/supply/bq24257_charger.c | 16 +- drivers/power/supply/bq256xx_charger.c | 29 +- drivers/power/supply/bq25890_charger.c | 12 + drivers/power/supply/charger-manager.c | 54 ++- drivers/power/supply/cros_usbpd-charger.c | 17 +- drivers/power/supply/lp8727_charger.c | 4 +- drivers/power/supply/lp8788-charger.c | 2 +- drivers/power/supply/max17040_battery.c | 32 +- drivers/power/supply/pf1550-charger.c | 2 +- drivers/power/supply/qcom_battmgr.c | 9 +- drivers/power/supply/rt9455_charger.c | 21 +- drivers/power/supply/twl4030_charger.c | 12 +- drivers/power/supply/ucs1002_power.c | 6 +- drivers/ptp/ptp_vmclock.c | 6 + drivers/rapidio/devices/rio_mport_cdev.c | 10 +- drivers/regulator/as3722-regulator.c | 1 - drivers/regulator/max8998.c | 1 - drivers/regulator/qcom-refgen-regulator.c | 4 +- drivers/remoteproc/mtk_scp.c | 9 +- drivers/rpmsg/qcom_glink_smem.c | 7 + drivers/s390/block/dasd.c | 6 +- drivers/s390/block/dasd_eckd.c | 40 ++- drivers/s390/block/dasd_erp.c | 3 + drivers/scsi/fnic/fip.c | 2 +- drivers/scsi/scsi_lib.c | 2 + drivers/staging/greybus/hid.c | 2 +- drivers/staging/media/ipu7/ipu7-isys.c | 1 + drivers/staging/media/tegra-video/vi.c | 9 +- drivers/staging/media/tegra-video/vip.c | 10 +- drivers/tty/serial/imx.c | 20 +- drivers/usb/dwc2/gadget.c | 11 +- drivers/usb/dwc3/gadget.c | 1 + drivers/usb/gadget/function/f_fs.c | 14 +- drivers/usb/gadget/function/f_midi2.c | 2 + drivers/usb/gadget/function/f_tcm.c | 23 +- drivers/usb/gadget/function/f_uvc.c | 7 +- drivers/usb/gadget/function/u_audio.c | 24 +- drivers/usb/gadget/function/uvc_video.c | 2 +- drivers/usb/gadget/udc/at91_udc.c | 20 +- drivers/usb/gadget/udc/snps_udc_plat.c | 5 +- drivers/usb/phy/phy-fsl-usb.c | 52 +-- drivers/usb/phy/phy-fsl-usb.h | 6 +- drivers/usb/typec/altmodes/thunderbolt.c | 2 + drivers/usb/typec/hd3ss3220.c | 2 +- drivers/usb/typec/tcpm/tcpci.c | 12 +- drivers/usb/typec/ucsi/ucsi.c | 3 +- drivers/video/backlight/aw99706.c | 10 +- .../fbdev/omap2/omapfb/displays/panel-dsi-cm.c | 4 +- drivers/video/fbdev/pvr2fb.c | 4 +- drivers/video/fbdev/ssd1307fb.c | 72 +++- drivers/video/fbdev/uvesafb.c | 2 + drivers/video/sticore.c | 22 +- drivers/w1/slaves/w1_ds28e17.c | 8 + drivers/xen/balloon.c | 29 +- fs/backing-file.c | 2 +- fs/btrfs/direct-io.c | 19 +- fs/btrfs/extent_io.c | 31 ++ fs/btrfs/extent_io.h | 5 + fs/btrfs/inode.c | 23 +- fs/btrfs/ioctl.c | 23 +- fs/btrfs/relocation.c | 31 +- fs/buffer.c | 3 + fs/ceph/addr.c | 11 + fs/ceph/caps.c | 74 +++- fs/ceph/dir.c | 10 +- fs/ceph/export.c | 26 +- fs/ceph/mds_client.c | 73 +++- fs/ceph/mds_client.h | 1 + fs/ceph/mdsmap.c | 11 +- fs/ceph/super.h | 14 + fs/ceph/xattr.c | 1 + fs/debugfs/file.c | 3 +- fs/ecryptfs/crypto.c | 2 +- fs/ecryptfs/ecryptfs_kernel.h | 3 +- fs/ecryptfs/keystore.c | 45 ++- fs/ecryptfs/messaging.c | 11 +- fs/ecryptfs/miscdev.c | 5 +- fs/ecryptfs/super.c | 7 + fs/efivarfs/super.c | 30 +- fs/erofs/zutil.c | 2 + fs/ext2/inode.c | 7 +- fs/ext2/xattr.c | 4 +- fs/fat/misc.c | 4 + fs/fuse/dev.c | 8 +- fs/fuse/dev.h | 2 +- fs/fuse/dev_uring.c | 38 +- fs/fuse/dev_uring_i.h | 5 + fs/fuse/inode.c | 4 +- fs/iomap/bio.c | 2 +- fs/iomap/direct-io.c | 1 + fs/jbd2/checkpoint.c | 28 +- fs/lockd/clntproc.c | 3 + fs/lockd/lockd.h | 2 +- fs/lockd/svc.c | 4 +- fs/lockd/svc4proc.c | 7 +- fs/lockd/svcproc.c | 4 +- fs/lockd/svcsubs.c | 107 ++++-- fs/nfs/callback.c | 4 +- fs/nfs/nfs4client.c | 17 +- fs/nfs/pnfs.c | 3 +- fs/nfs_common/nfslocalio.c | 16 +- fs/nfsd/filecache.c | 143 ++++---- fs/nfsd/flexfilelayoutxdr.c | 20 +- fs/nfsd/localio.c | 8 +- fs/nfsd/lockd.c | 6 +- fs/nfsd/netns.h | 35 +- fs/nfsd/nfs2acl.c | 52 +-- fs/nfsd/nfs3acl.c | 17 +- fs/nfsd/nfs3proc.c | 40 +++ fs/nfsd/nfs4callback.c | 113 +++++- fs/nfsd/nfs4layouts.c | 39 +- fs/nfsd/nfs4proc.c | 225 ++++++++---- fs/nfsd/nfs4recover.c | 48 ++- fs/nfsd/nfs4state.c | 399 ++++++++++++++++----- fs/nfsd/nfs4xdr.c | 40 ++- fs/nfsd/nfscache.c | 6 +- fs/nfsd/nfsctl.c | 156 ++++++-- fs/nfsd/nfsfh.c | 12 +- fs/nfsd/nfsproc.c | 7 + fs/nfsd/nfssvc.c | 49 ++- fs/nfsd/nfsxdr.c | 32 +- fs/nfsd/state.h | 4 +- fs/nfsd/trace.h | 18 +- fs/nfsd/vfs.c | 39 +- fs/nilfs2/bmap.c | 2 +- fs/nilfs2/bmap.h | 2 +- fs/nilfs2/btree.c | 39 +- fs/nilfs2/direct.c | 4 +- fs/notify/fanotify/fanotify.c | 3 +- fs/notify/fanotify/fanotify.h | 6 +- fs/notify/fanotify/fanotify_user.c | 17 +- fs/notify/inotify/inotify_user.c | 15 +- fs/ntfs/attrib.c | 24 +- fs/ntfs/lcnalloc.c | 7 +- fs/ntfs/runlist.c | 48 +++ fs/ntfs/super.c | 12 +- fs/ntfs3/frecord.c | 9 + fs/ntfs3/fslog.c | 34 ++ fs/ocfs2/cluster/heartbeat.c | 150 ++++++-- fs/ocfs2/cluster/nodemanager.c | 6 + fs/ocfs2/cluster/nodemanager.h | 1 + fs/ocfs2/dir.c | 47 ++- fs/ocfs2/dlm/dlmmaster.c | 6 + fs/ocfs2/dlm/dlmrecovery.c | 9 + fs/ocfs2/refcounttree.c | 47 ++- fs/ocfs2/suballoc.c | 2 +- fs/ocfs2/xattr.c | 5 +- fs/orangefs/devorangefs-req.c | 1 + fs/orangefs/orangefs-debugfs.c | 1 + fs/overlayfs/dir.c | 1 - fs/pidfs.c | 43 ++- fs/smb/client/cifsfs.c | 15 +- fs/smb/client/cifsfs.h | 1 + fs/smb/client/cifssmb.c | 6 + fs/smb/client/dfs_cache.c | 33 +- fs/smb/client/file.c | 1 + fs/smb/client/inode.c | 56 ++- fs/smb/client/smb1misc.c | 3 +- fs/smb/client/smb1ops.c | 2 +- fs/smb/client/smb1transport.c | 35 +- fs/smb/client/smb2file.c | 5 +- fs/smb/client/smb2inode.c | 6 +- fs/smb/client/smb2ops.c | 9 +- fs/smb/client/trace.h | 3 +- fs/smb/server/vfs_cache.c | 2 +- fs/tracefs/event_inode.c | 7 +- fs/ubifs/auth.c | 2 +- fs/udf/inode.c | 2 +- fs/udf/partition.c | 2 +- include/linux/bio.h | 2 +- include/linux/compaction.h | 3 +- include/linux/dm-io.h | 6 +- include/linux/entry-common.h | 3 + include/linux/font.h | 4 +- include/linux/hugetlb.h | 7 + include/linux/list.h | 15 +- include/linux/lockd/bind.h | 12 +- include/linux/sunrpc/bc_xprt.h | 5 + include/linux/sunrpc/svc_rdma_pcl.h | 2 +- include/linux/uio.h | 10 +- include/linux/usb/tcpci.h | 1 + include/linux/vmalloc.h | 2 +- include/net/ip_tunnels.h | 11 +- include/net/sctp/structs.h | 2 +- include/uapi/linux/landlock.h | 1 + io_uring/query.c | 3 + io_uring/waitid.c | 33 +- kernel/auditfilter.c | 6 +- kernel/bpf/bloom_filter.c | 19 +- kernel/bpf/stackmap.c | 3 + kernel/dma/contiguous.c | 16 +- kernel/liveupdate/kexec_handover.c | 2 +- kernel/module/kallsyms.c | 24 +- kernel/module/main.c | 14 +- kernel/params.c | 14 +- kernel/pid.c | 31 -- kernel/reboot.c | 29 ++ kernel/sched/core.c | 49 ++- kernel/sched/cpufreq_schedutil.c | 15 +- kernel/sched/ext/ext.c | 342 +++++++++++++----- kernel/sched/sched.h | 5 +- kernel/signal.c | 4 + kernel/taskstats.c | 3 +- kernel/time/itimer.c | 2 +- kernel/time/timekeeping.c | 8 +- kernel/time/timer.c | 1 + kernel/trace/ring_buffer.c | 202 +++++++---- kernel/trace/simple_ring_buffer.c | 4 +- kernel/trace/trace.c | 6 +- kernel/trace/trace_events.c | 2 + kernel/trace/trace_events_hist.c | 4 +- kernel/trace/trace_events_user.c | 3 + lib/iov_iter.c | 9 +- lib/ucs2_string.c | 2 +- lib/xarray.c | 3 + mm/compaction.c | 98 ++--- mm/gup.c | 10 +- mm/huge_memory.c | 24 +- mm/hugetlb.c | 38 +- mm/hugetlb_vmemmap.c | 23 +- mm/internal.h | 10 +- mm/kasan/quarantine.c | 7 +- mm/kmemleak.c | 77 ++-- mm/madvise.c | 4 +- mm/memcontrol-v1.c | 6 +- mm/memcontrol.c | 13 + mm/mempolicy.c | 29 +- mm/migrate.c | 8 +- mm/migrate_device.c | 13 + mm/mm_init.c | 10 +- mm/page_alloc.c | 76 +++- mm/page_owner.c | 10 +- mm/page_vma_mapped.c | 8 +- mm/pagewalk.c | 6 +- mm/rmap.c | 31 +- mm/slub.c | 80 +++-- mm/sparse-vmemmap.c | 4 +- mm/swapfile.c | 15 +- mm/vmalloc.c | 58 ++- mm/vmscan.c | 40 +-- mm/zsmalloc.c | 11 +- mm/zswap.c | 13 +- net/bluetooth/eir.c | 3 +- net/bluetooth/hci_conn.c | 3 +- net/bluetooth/hci_core.c | 2 +- net/bluetooth/hci_event.c | 7 +- net/bluetooth/hci_sync.c | 2 + net/bluetooth/iso.c | 8 + net/bluetooth/rfcomm/core.c | 8 +- net/ceph/osd_client.c | 30 ++ net/ceph/osdmap.c | 2 + net/core/skbuff.c | 5 +- net/core/xdp.c | 4 +- net/ipv4/ip_tunnel.c | 2 +- net/ipv4/ipip.c | 2 +- net/ipv4/ipmr.c | 3 + net/ipv6/exthdrs.c | 26 +- net/ipv6/ip6_gre.c | 14 +- net/ipv6/ip6_input.c | 1 + net/ipv6/ip6_tunnel.c | 22 +- net/ipv6/route.c | 2 +- net/ipv6/seg6_local.c | 9 + net/ipv6/sit.c | 2 +- net/iucv/af_iucv.c | 2 + net/l2tp/l2tp_netlink.c | 16 +- net/mctp/route.c | 19 +- net/mpls/af_mpls.c | 2 + net/mptcp/syncookies.c | 1 + net/openvswitch/conntrack.c | 128 ++++--- net/openvswitch/conntrack.h | 6 +- net/openvswitch/datapath.c | 60 ++-- net/openvswitch/datapath.h | 8 +- net/sched/sch_generic.c | 2 +- net/sctp/inqueue.c | 7 +- net/sctp/sm_sideeffect.c | 4 + net/sctp/stream.c | 48 ++- net/smc/af_smc.c | 3 +- net/smc/smc.h | 6 +- net/smc/smc_core.c | 27 +- net/smc/smc_llc.c | 122 +++++-- net/smc/smc_rx.c | 11 +- net/smc/smc_tx.h | 6 +- net/smc/smc_wr.c | 6 +- net/sunrpc/auth_gss/auth_gss.c | 6 +- net/sunrpc/auth_gss/gss_krb5_unseal.c | 3 + net/sunrpc/auth_gss/gss_krb5_wrap.c | 13 +- net/sunrpc/auth_gss/gss_rpc_upcall.c | 6 - net/sunrpc/auth_gss/gss_rpc_upcall.h | 1 - net/sunrpc/auth_gss/gss_rpc_xdr.c | 15 +- net/sunrpc/auth_gss/svcauth_gss.c | 8 +- net/sunrpc/backchannel_rqst.c | 38 +- net/sunrpc/cache.c | 7 +- net/sunrpc/clnt.c | 22 +- net/sunrpc/sunrpc_syms.c | 1 + net/sunrpc/svc.c | 93 ++++- net/sunrpc/xdr.c | 2 +- net/sunrpc/xprtrdma/ib_client.c | 24 +- net/sunrpc/xprtrdma/svc_rdma_pcl.c | 2 +- net/sunrpc/xprtrdma/svc_rdma_recvfrom.c | 21 +- net/sunrpc/xprtrdma/svc_rdma_rw.c | 52 ++- net/sunrpc/xprtrdma/svc_rdma_sendto.c | 47 ++- net/sunrpc/xprtrdma/svc_rdma_transport.c | 69 +++- net/sunrpc/xprtsock.c | 12 +- net/vmw_vsock/virtio_transport.c | 2 +- rust/Makefile | 6 +- rust/kernel/bug.rs | 34 +- rust/kernel/devres.rs | 25 +- rust/kernel/dma.rs | 6 +- rust/kernel/fmt.rs | 9 +- rust/kernel/list.rs | 2 +- rust/kernel/num/bounded.rs | 31 +- rust/kernel/time.rs | 17 +- scripts/Makefile.build | 3 +- scripts/rust_is_available.sh | 14 + scripts/rust_is_available_bindgen_libclang_22.h | 5 + scripts/rust_is_available_test.py | 30 +- security/apparmor/include/cred.h | 6 +- security/apparmor/include/label.h | 6 +- security/apparmor/include/task.h | 15 +- security/apparmor/task.c | 27 ++ security/keys/trusted-keys/trusted_tpm1.c | 2 +- security/landlock/errata/abi-1.h | 23 ++ security/landlock/fs.c | 41 ++- security/smack/smack_lsm.c | 2 +- sound/core/ump_convert.c | 1 + sound/drivers/aloop.c | 6 + sound/drivers/mpu401/mpu401.c | 6 + sound/drivers/mts64.c | 6 + sound/drivers/portman2x4.c | 6 + sound/drivers/serial-u16550.c | 6 + sound/drivers/virmidi.c | 6 + sound/hda/codecs/realtek/alc269.c | 7 +- sound/hda/codecs/realtek/alc662.c | 1 + sound/hda/core/ext/stream.c | 4 +- sound/pci/pcxhr/pcxhr.c | 14 +- sound/soc/amd/yc/acp6x-mach.c | 7 + sound/soc/codecs/aw88261.c | 6 +- sound/soc/codecs/aw88261.h | 6 - sound/soc/tegra/tegra210_admaif.c | 210 +++++++---- sound/soc/tegra/tegra210_i2s.c | 24 +- sound/soc/tegra/tegra210_i2s.h | 1 + sound/soc/tegra/tegra210_mbdrc.c | 42 +-- sound/soc/tegra/tegra210_mixer.c | 10 +- sound/usb/6fire/comm.c | 9 +- sound/usb/bcd2000/bcd2000.c | 11 +- sound/usb/fcp.c | 4 +- tools/include/linux/compiler.h | 2 +- tools/objtool/check.c | 2 + tools/sched_ext/include/scx/compat.bpf.h | 12 +- tools/sched_ext/include/scx/enum_defs.autogen.h | 1 - tools/sched_ext/include/scx/enums.autogen.bpf.h | 3 - tools/sched_ext/include/scx/enums.autogen.h | 1 - tools/sched_ext/scx_qmap.bpf.c | 2 +- tools/testing/selftests/mm/run_vmtests.sh | 2 +- 621 files changed, 7838 insertions(+), 3129 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/713 drm/amd/display: Skip Update HDCP Config In Transition State
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fangzhi Zuo <[email protected]>
[ Upstream commit d5164580a99477dcfe15cea101b153b1e63f1535 ]
Transition state does not have a valid dm_stream_ctx that should skip configuring HDCP routine. The routine is valid to go through only when a valid stream is created.
--- .../amd/display/amdgpu_dm/amdgpu_dm_hdcp.c | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c +20 -8
@@ -535,15 +535,27 @@ static bool enable_assr(void *handle, struct dc_link *link)static void update_config (void *handle,struct cp_psp_stream_config *config) {struct hdcp_workqueue *hdcp_work = handle; -struct amdgpu_dm_connector *aconnector = config->dm_stream_ctx; -int link_index = aconnector->dc_link->link_index; -unsigned int conn_index = aconnector->base.index; -struct mod_hdcp_display *display = &hdcp_work[link_index].display; -struct mod_hdcp_link *link = &hdcp_work[link_index].link; -struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index]; +struct amdgpu_dm_connector *aconnector; +const struct dc *dc; +int link_index; +unsigned int conn_index; +struct mod_hdcp_display *display; +struct mod_hdcp_link *link; +struct hdcp_workqueue *hdcp_w;struct dc_sink *sink =NULL ;bool link_is_hdcp14 = false; -const struct dc *dc = aconnector->dc_link->dc; + + aconnector = config->dm_stream_ctx; +if (!aconnector || !aconnector->dc_link) +return ; + + link_index = aconnector->dc_link->link_index; + display = &hdcp_work[link_index].display; + link = &hdcp_work[link_index].link; + hdcp_w = &hdcp_work[link_index]; + + conn_index = aconnector->base.index; + dc = aconnector->dc_link->dc;if (config->dpms_off) {hdcp_remove_display (hdcp_work, link_index, aconnector);
@@ -581,7 +593,7 @@ static void update_config(void *handle, struct cp_psp_stream_config *config) link->dp.mst_enabled = config->mst_enabled; link->dp.dp2_enabled = config->dp2_enabled; link->dp.usb4_enabled = config->usb4_enabled; -if (aconnector->dc_sink->sink_signal ==SIGNAL_TYPE_HDMI_FRL ) +if (sink && sink->sink_signal ==SIGNAL_TYPE_HDMI_FRL ) link->hdmi.frl_enabled = config->frl_enabled; display->adjust.disable =MOD_HDCP_DISPLAY_DISABLE_AUTHENTICATION ; link->adjust.auth_delay =2 ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 2/713 ASoC: tegra210_i2s: sort the register default table
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Ujfalusi <[email protected]>
[ Upstream commit 597273563d90d03fda852a29c3a76c41a22bf6ac ]
reg_defaults must be sorted by ascending register address, as regcache_lookup_reg() locates entries in it with bsearch(). See commit fd80df352ba1 ("regcache: Add support for sorting defaults arrays").
TEGRA210_I2S_ENABLE (0x80) is listed after TEGRA210_I2S_CG (0x88) and TEGRA210_I2S_TIMING (0xa4), so both it and TEGRA210_I2S_TIMING are unreachable. regcache_reg_needs_sync() then cannot compare them against their default and reports that a sync is needed, so they are written to the device on every regcache_sync() even when they were never touched.
Sort the table by register address.
--- sound/soc/tegra/tegra210_i2s.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/soc/tegra/tegra210_i2s.c +1 -1
@@ -23,9 +23,9 @@ static const struct reg_default tegra210_i2s_reg_defaults[] = { { TEGRA210_I2S_RX_CIF_CTRL, 0x00007700 }, { TEGRA210_I2S_TX_INT_MASK, 0x00000003 }, { TEGRA210_I2S_TX_CIF_CTRL, 0x00007700 }, + { TEGRA210_I2S_ENABLE, 0x1 }, { TEGRA210_I2S_CG, 0x1 }, { TEGRA210_I2S_TIMING, 0x0000001f }, - { TEGRA210_I2S_ENABLE, 0x1 },/* * Below update does not have any effect on Tegra186 and Tegra194. * On Tegra210, I2S4 has "i2s4a" and "i2s4b" pins and below update
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 3/713 ASoC: tegra210_i2s: sort the Tegra264 register default table
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Ujfalusi <[email protected]>
[ Upstream commit 82da8df388004af4540e930ab3de2ce5787207e7 ]
reg_defaults must be sorted by ascending register address, as regcache_lookup_reg() locates entries in it with bsearch(). See commit fd80df352ba1 ("regcache: Add support for sorting defaults arrays").
TEGRA264_I2S_ENABLE (0x100), TEGRA264_I2S_RX_FIFO_WR_ACCESS_MODE (0x30) and TEGRA264_I2S_TX_FIFO_RD_ACCESS_MODE (0xb0) are listed at the end of the table, after TEGRA264_I2S_TIMING (0x130), which leaves 4 of the 9 entries unreachable. regcache_reg_needs_sync() then cannot compare them against their default and reports that a sync is needed, so they are written to the device on every regcache_sync() even when they were never touched.
Sort the table by register address.
--- sound/soc/tegra/tegra210_i2s.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
sound/soc/tegra/tegra210_i2s.c +3 -3
@@ -38,13 +38,13 @@ static const struct reg_default tegra210_i2s_reg_defaults[] = {static const struct reg_default tegra264_i2s_reg_defaults[] = { {TEGRA210_I2S_RX_INT_MASK ,0x00000003 }, {TEGRA210_I2S_RX_CIF_CTRL ,0x00003f00 }, + {TEGRA264_I2S_RX_FIFO_WR_ACCESS_MODE ,0x1 }, {TEGRA264_I2S_TX_INT_MASK ,0x00000003 }, {TEGRA264_I2S_TX_CIF_CTRL ,0x00003f00 }, + {TEGRA264_I2S_TX_FIFO_RD_ACCESS_MODE ,0x1 }, + {TEGRA264_I2S_ENABLE ,0x1 }, {TEGRA264_I2S_CG ,0x1 }, {TEGRA264_I2S_TIMING ,0x0000001f }, - {TEGRA264_I2S_ENABLE ,0x1 }, - {TEGRA264_I2S_RX_FIFO_WR_ACCESS_MODE ,0x1 }, - {TEGRA264_I2S_TX_FIFO_RD_ACCESS_MODE ,0x1 }, }; static void tegra210_i2s_set_slot_ctrl(struct tegra210_i2s *i2s,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 4/713 ASoC: tegra210_mixer: sort the register default table
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Ujfalusi <[email protected]>
[ Upstream commit f70bc276fc7f712ff5c8e995d5050558a3198df2 ]
reg_defaults must be sorted by ascending register address, as regcache_lookup_reg() locates entries in it with bsearch(). See commit fd80df352ba1 ("regcache: Add support for sorting defaults arrays").
TEGRA210_MIXER_ENABLE (0x400) is the last entry of the table, after TEGRA210_MIXER_PEAKM_RAM_CTRL (0x434), which makes it unreachable. regcache_reg_needs_sync() then cannot compare it against its default and reports that a sync is needed, so it is written to the device on every regcache_sync() even when it was never touched.
Sort the table by register address.
--- sound/soc/tegra/tegra210_mixer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/soc/tegra/tegra210_mixer.c +1 -1
@@ -57,10 +57,10 @@ static const struct reg_default tegra210_mixer_reg_defaults[] = {MIXER_TX_REG_DEFAULTS (3 ),MIXER_TX_REG_DEFAULTS (4 ), + { TEGRA210_MIXER_ENABLE, 0x1 }, { TEGRA210_MIXER_CG, 0x00000001}, { TEGRA210_MIXER_GAIN_CFG_RAM_CTRL, 0x00004000}, { TEGRA210_MIXER_PEAKM_RAM_CTRL, 0x00004000}, - { TEGRA210_MIXER_ENABLE, 0x1 }, };/* Default gain parameters */
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 5/713 ASoC: tegra: Fix the I2S enable default value
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jon Hunter <[email protected]>
[ Upstream commit 53dd1c1de851280c71385f49a24715e5615c926c ]
Commit 4b05ccb17f92 ("regcache: Sort the local copy of an unsorted reg_defaults array") exposed an issue in the Tegra I2S driver where the register default for the TEGRA210_I2S_ENABLE is specified as 1, but the hardware default is actually 0. After this commit was added the I2S driver is no longer working and so fix this by correcting the default value for this register and explicitly configuring the I2S_ENABLE register when runtime resuming the I2S device.
The I2S_ENABLE register offset is different on Tegra264 devices than other Tegra devices and so add a 'enable_reg' variable to the SoC data structure to specify the offset for different SoC devices.
--- sound/soc/tegra/tegra210_i2s.c | 20 +++++++++++++++++--- sound/soc/tegra/tegra210_i2s.h | 1 + 2 files changed, 18 insertions(+), 3 deletions(-)
sound/soc/tegra/tegra210_i2s.c +17 -3
@@ -23,7 +23,7 @@ static const struct reg_default tegra210_i2s_reg_defaults[] = { { TEGRA210_I2S_RX_CIF_CTRL, 0x00007700 }, { TEGRA210_I2S_TX_INT_MASK, 0x00000003 }, { TEGRA210_I2S_TX_CIF_CTRL, 0x00007700 }, - { TEGRA210_I2S_ENABLE, 0x1 }, + { TEGRA210_I2S_ENABLE, 0x0 }, { TEGRA210_I2S_CG, 0x1 }, { TEGRA210_I2S_TIMING, 0x0000001f },/*
@@ -42,7 +42,7 @@ static const struct reg_default tegra264_i2s_reg_defaults[] = { { TEGRA264_I2S_TX_INT_MASK, 0x00000003 }, { TEGRA264_I2S_TX_CIF_CTRL, 0x00003f00 }, { TEGRA264_I2S_TX_FIFO_RD_ACCESS_MODE, 0x1 }, - { TEGRA264_I2S_ENABLE, 0x1 }, + { TEGRA264_I2S_ENABLE, 0x0 }, { TEGRA264_I2S_CG, 0x1 }, { TEGRA264_I2S_TIMING, 0x0000001f }, };
@@ -201,9 +201,21 @@ static int tegra210_i2s_runtime_resume(struct device *dev) }regcache_cache_only (i2s->regmap, false); -regcache_sync (i2s->regmap); + err =regcache_sync (i2s->regmap); +if (err) + goto err; + + err =regmap_write (i2s->regmap, i2s->soc_data->enable_reg,I2S_EN ); +if (err) + goto err;return 0 ; + +err: +regcache_cache_only (i2s->regmap, true); +clk_disable_unprepare (i2s->clk_i2s); + +return err; } static void tegra210_i2s_set_data_offset(struct tegra210_i2s *i2s,
@@ -1133,6 +1145,7 @@ static const struct tegra_i2s_soc_data soc_data_tegra210 = { .regmap_conf = &tegra210_regmap_conf, .i2s_cmpnt = &tegra210_i2s_cmpnt, .max_ch = TEGRA210_I2S_MAX_CHANNEL, + .enable_reg = TEGRA210_I2S_ENABLE, .tx_offset = TEGRA210_I2S_TX_OFFSET, .i2s_ctrl_offset = TEGRA210_I2S_CTRL_OFFSET, .fsync_width_mask = I2S_CTRL_FSYNC_WIDTH_MASK,
@@ -1144,6 +1157,7 @@ static const struct tegra_i2s_soc_data soc_data_tegra264 = { .regmap_conf = &tegra264_regmap_conf, .i2s_cmpnt = &tegra264_i2s_cmpnt, .max_ch = TEGRA264_I2S_MAX_CHANNEL, + .enable_reg = TEGRA264_I2S_ENABLE, .tx_offset = TEGRA264_I2S_TX_OFFSET, .i2s_ctrl_offset = TEGRA264_I2S_CTRL_OFFSET, .fsync_width_mask = TEGRA264_I2S_CTRL_FSYNC_WIDTH_MASK,
sound/soc/tegra/tegra210_i2s.h +1 -0
@@ -150,6 +150,7 @@ struct tegra_i2s_soc_data {const struct regmap_config *regmap_conf;const struct snd_soc_component_driver *i2s_cmpnt;unsigned int max_ch; +unsigned int enable_reg;unsigned int tx_offset;unsigned int i2s_ctrl_offset;unsigned int fsync_width_mask;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 6/713 ASoC: tegra: Fix the MIXER enable default value
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jon Hunter <[email protected]>
[ Upstream commit 5442b8093a2f94ecd4696b3875194be09e2676c5 ]
Commit 4b05ccb17f92 ("regcache: Sort the local copy of an unsorted reg_defaults array") exposed an issue in the Tegra MIXER driver where the register default for the TEGRA210_MIXER_ENABLE is specified as 1, but the hardware default is actually 0. After this commit was added the MIXER driver is no longer working and so fix this by correcting the default value for this register and explicitly configuring the MIXER_ENABLE register when runtime resuming the MIXER device.
--- sound/soc/tegra/tegra210_mixer.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
sound/soc/tegra/tegra210_mixer.c +7 -3
@@ -57,7 +57,7 @@ static const struct reg_default tegra210_mixer_reg_defaults[] = {MIXER_TX_REG_DEFAULTS (3 ),MIXER_TX_REG_DEFAULTS (4 ), - { TEGRA210_MIXER_ENABLE, 0x1 }, + { TEGRA210_MIXER_ENABLE, 0x0 }, { TEGRA210_MIXER_CG, 0x00000001}, { TEGRA210_MIXER_GAIN_CFG_RAM_CTRL, 0x00004000}, { TEGRA210_MIXER_PEAKM_RAM_CTRL, 0x00004000},
@@ -86,11 +86,15 @@ static int tegra210_mixer_runtime_suspend(struct device *dev)static int tegra210_mixer_runtime_resume (struct device *dev) {struct tegra210_mixer *mixer =dev_get_drvdata (dev); +int err;regcache_cache_only (mixer->regmap, false); -regcache_sync (mixer->regmap); + err =regcache_sync (mixer->regmap); +if (err) +return err; -return 0 ; +return regmap_write (mixer->regmap,TEGRA210_MIXER_ENABLE , +TEGRA210_MIXER_EN ); } static int tegra210_mixer_write_ram(struct tegra210_mixer *mixer,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 7/713 ASoC: tegra: Sort ADMAIF register defaults
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jon Hunter <[email protected]>
[ Upstream commit 18d48bfd1bc178da7cfc7a1be3eaa1c8cb10f05c ]
Commit 4b05ccb17f92 ("regcache: Sort the local copy of an unsorted reg_defaults array") exposed an issue in the Tegra ADMAIF driver and now the following warning is observed:
tegra210-admaif 290f000.admaif: Driver needs fixing: Unsorted
reg_defaults, sorting the copy
This warning occurs because register defaults in the structures tegra186_admaif_reg_defaults and tegra264_admaif_reg_defaults are not specified in ascending order which is required by regmap. Fix this by sorting the register defaults according to their address. Note that in order to do this it is necessary to split the macro ADMAIF_REG_DEFAULTS into separate RX and TX macros to the RX and TX registers.
--- sound/soc/tegra/tegra210_admaif.c | 208 ++++++++++++++++++++---------- 1 file changed, 138 insertions(+), 70 deletions(-)
sound/soc/tegra/tegra210_admaif.c +138 -70
@@ -26,94 +26,162 @@#define CH_RX_REG (reg, id) CH_REG(admaif->soc_data->rx_base, reg, id) -#define REG_DEFAULTS (id, rx_ctrl, tx_ctrl, tx_base, rx_base, cif_ctrl) \ +#define RX_REG_DEFAULTS (id, rx_ctrl, rx_base, cif_ctrl) \ { CH_REG(rx_base, TEGRA_ADMAIF_RX_INT_MASK, id), 0x00000001 }, \ { CH_REG(rx_base, TEGRA_ADMAIF_CH_ACIF_RX_CTRL, id), cif_ctrl }, \ - { CH_REG(rx_base, TEGRA_ADMAIF_RX_FIFO_CTRL, id), rx_ctrl }, \ + { CH_REG(rx_base, TEGRA_ADMAIF_RX_FIFO_CTRL, id), rx_ctrl } + +#define TX_REG_DEFAULTS (id, tx_ctrl, tx_base, cif_ctrl) \ { CH_REG(tx_base, TEGRA_ADMAIF_TX_INT_MASK, id), 0x00000001 }, \ { CH_REG(tx_base, TEGRA_ADMAIF_CH_ACIF_TX_CTRL, id), cif_ctrl }, \ { CH_REG(tx_base, TEGRA_ADMAIF_TX_FIFO_CTRL, id), tx_ctrl } -#define ADMAIF_REG_DEFAULTS (id, chip) \ - REG_DEFAULTS((id) - 1, \ +#define ADMAIF_RX_REG_DEFAULTS (id, chip) \ + RX_REG_DEFAULTS((id) - 1, \ chip ## _ADMAIF_RX ## id ## _FIFO_CTRL_REG_DEFAULT, \ + chip ## _ADMAIF_RX_BASE, \ + chip ## _ADMAIF_CIF_REG_DEFAULT) + +#define ADMAIF_TX_REG_DEFAULTS (id, chip) \ + TX_REG_DEFAULTS((id) - 1, \ chip ## _ADMAIF_TX ## id ## _FIFO_CTRL_REG_DEFAULT, \ chip ## _ADMAIF_TX_BASE, \ - chip ## _ADMAIF_RX_BASE, \ chip ## _ADMAIF_CIF_REG_DEFAULT)static const struct reg_default tegra186_admaif_reg_defaults[] = { - {(TEGRA_ADMAIF_GLOBAL_CG_0 +TEGRA186_ADMAIF_GLOBAL_BASE ),0x00000003 }, -ADMAIF_REG_DEFAULTS (1 ,TEGRA186 ), -ADMAIF_REG_DEFAULTS (2 ,TEGRA186 ), -ADMAIF_REG_DEFAULTS (3 ,TEGRA186 ), -ADMAIF_REG_DEFAULTS (4 ,TEGRA186 ), -ADMAIF_REG_DEFAULTS (5 ,TEGRA186 ), -ADMAIF_REG_DEFAULTS (6 ,TEGRA186 ), -ADMAIF_REG_DEFAULTS (7 ,TEGRA186 ), -ADMAIF_REG_DEFAULTS (8 ,TEGRA186 ), -ADMAIF_REG_DEFAULTS (9 ,TEGRA186 ), -ADMAIF_REG_DEFAULTS (10 ,TEGRA186 ), -ADMAIF_REG_DEFAULTS (11 ,TEGRA186 ), -ADMAIF_REG_DEFAULTS (12 ,TEGRA186 ), -ADMAIF_REG_DEFAULTS (13 ,TEGRA186 ), -ADMAIF_REG_DEFAULTS (14 ,TEGRA186 ), -ADMAIF_REG_DEFAULTS (15 ,TEGRA186 ), -ADMAIF_REG_DEFAULTS (16 ,TEGRA186 ), -ADMAIF_REG_DEFAULTS (17 ,TEGRA186 ), -ADMAIF_REG_DEFAULTS (18 ,TEGRA186 ), -ADMAIF_REG_DEFAULTS (19 ,TEGRA186 ), -ADMAIF_REG_DEFAULTS (20 ,TEGRA186 ) +ADMAIF_RX_REG_DEFAULTS (1 ,TEGRA186 ), +ADMAIF_RX_REG_DEFAULTS (2 ,TEGRA186 ), +ADMAIF_RX_REG_DEFAULTS (3 ,TEGRA186 ), +ADMAIF_RX_REG_DEFAULTS (4 ,TEGRA186 ), +ADMAIF_RX_REG_DEFAULTS (5 ,TEGRA186 ), +ADMAIF_RX_REG_DEFAULTS (6 ,TEGRA186 ), +ADMAIF_RX_REG_DEFAULTS (7 ,TEGRA186 ), +ADMAIF_RX_REG_DEFAULTS (8 ,TEGRA186 ), +ADMAIF_RX_REG_DEFAULTS (9 ,TEGRA186 ), +ADMAIF_RX_REG_DEFAULTS (10 ,TEGRA186 ), +ADMAIF_RX_REG_DEFAULTS (11 ,TEGRA186 ), +ADMAIF_RX_REG_DEFAULTS (12 ,TEGRA186 ), +ADMAIF_RX_REG_DEFAULTS (13 ,TEGRA186 ), +ADMAIF_RX_REG_DEFAULTS (14 ,TEGRA186 ), +ADMAIF_RX_REG_DEFAULTS (15 ,TEGRA186 ), +ADMAIF_RX_REG_DEFAULTS (16 ,TEGRA186 ), +ADMAIF_RX_REG_DEFAULTS (17 ,TEGRA186 ), +ADMAIF_RX_REG_DEFAULTS (18 ,TEGRA186 ), +ADMAIF_RX_REG_DEFAULTS (19 ,TEGRA186 ), +ADMAIF_RX_REG_DEFAULTS (20 ,TEGRA186 ), +ADMAIF_TX_REG_DEFAULTS (1 ,TEGRA186 ), +ADMAIF_TX_REG_DEFAULTS (2 ,TEGRA186 ), +ADMAIF_TX_REG_DEFAULTS (3 ,TEGRA186 ), +ADMAIF_TX_REG_DEFAULTS (4 ,TEGRA186 ), +ADMAIF_TX_REG_DEFAULTS (5 ,TEGRA186 ), +ADMAIF_TX_REG_DEFAULTS (6 ,TEGRA186 ), +ADMAIF_TX_REG_DEFAULTS (7 ,TEGRA186 ), +ADMAIF_TX_REG_DEFAULTS (8 ,TEGRA186 ), +ADMAIF_TX_REG_DEFAULTS (9 ,TEGRA186 ), +ADMAIF_TX_REG_DEFAULTS (10 ,TEGRA186 ), +ADMAIF_TX_REG_DEFAULTS (11 ,TEGRA186 ), +ADMAIF_TX_REG_DEFAULTS (12 ,TEGRA186 ), +ADMAIF_TX_REG_DEFAULTS (13 ,TEGRA186 ), +ADMAIF_TX_REG_DEFAULTS (14 ,TEGRA186 ), +ADMAIF_TX_REG_DEFAULTS (15 ,TEGRA186 ), +ADMAIF_TX_REG_DEFAULTS (16 ,TEGRA186 ), +ADMAIF_TX_REG_DEFAULTS (17 ,TEGRA186 ), +ADMAIF_TX_REG_DEFAULTS (18 ,TEGRA186 ), +ADMAIF_TX_REG_DEFAULTS (19 ,TEGRA186 ), +ADMAIF_TX_REG_DEFAULTS (20 ,TEGRA186 ), + {(TEGRA_ADMAIF_GLOBAL_CG_0 +TEGRA186_ADMAIF_GLOBAL_BASE ),0x00000003 } };static const struct reg_default tegra210_admaif_reg_defaults[] = { - {(TEGRA_ADMAIF_GLOBAL_CG_0 +TEGRA210_ADMAIF_GLOBAL_BASE ),0x00000003 }, -ADMAIF_REG_DEFAULTS (1 ,TEGRA210 ), -ADMAIF_REG_DEFAULTS (2 ,TEGRA210 ), -ADMAIF_REG_DEFAULTS (3 ,TEGRA210 ), -ADMAIF_REG_DEFAULTS (4 ,TEGRA210 ), -ADMAIF_REG_DEFAULTS (5 ,TEGRA210 ), -ADMAIF_REG_DEFAULTS (6 ,TEGRA210 ), -ADMAIF_REG_DEFAULTS (7 ,TEGRA210 ), -ADMAIF_REG_DEFAULTS (8 ,TEGRA210 ), -ADMAIF_REG_DEFAULTS (9 ,TEGRA210 ), -ADMAIF_REG_DEFAULTS (10 ,TEGRA210 ) +ADMAIF_RX_REG_DEFAULTS (1 ,TEGRA210 ), +ADMAIF_RX_REG_DEFAULTS (2 ,TEGRA210 ), +ADMAIF_RX_REG_DEFAULTS (3 ,TEGRA210 ), +ADMAIF_RX_REG_DEFAULTS (4 ,TEGRA210 ), +ADMAIF_RX_REG_DEFAULTS (5 ,TEGRA210 ), +ADMAIF_RX_REG_DEFAULTS (6 ,TEGRA210 ), +ADMAIF_RX_REG_DEFAULTS (7 ,TEGRA210 ), +ADMAIF_RX_REG_DEFAULTS (8 ,TEGRA210 ), +ADMAIF_RX_REG_DEFAULTS (9 ,TEGRA210 ), +ADMAIF_RX_REG_DEFAULTS (10 ,TEGRA210 ), +ADMAIF_TX_REG_DEFAULTS (1 ,TEGRA210 ), +ADMAIF_TX_REG_DEFAULTS (2 ,TEGRA210 ), +ADMAIF_TX_REG_DEFAULTS (3 ,TEGRA210 ), +ADMAIF_TX_REG_DEFAULTS (4 ,TEGRA210 ), +ADMAIF_TX_REG_DEFAULTS (5 ,TEGRA210 ), +ADMAIF_TX_REG_DEFAULTS (6 ,TEGRA210 ), +ADMAIF_TX_REG_DEFAULTS (7 ,TEGRA210 ), +ADMAIF_TX_REG_DEFAULTS (8 ,TEGRA210 ), +ADMAIF_TX_REG_DEFAULTS (9 ,TEGRA210 ), +ADMAIF_TX_REG_DEFAULTS (10 ,TEGRA210 ), + {(TEGRA_ADMAIF_GLOBAL_CG_0 +TEGRA210_ADMAIF_GLOBAL_BASE ),0x00000003 } };static const struct reg_default tegra264_admaif_reg_defaults[] = { - {(TEGRA_ADMAIF_GLOBAL_CG_0 +TEGRA264_ADMAIF_GLOBAL_BASE ),0x00000003 }, -ADMAIF_REG_DEFAULTS (1 ,TEGRA264 ), -ADMAIF_REG_DEFAULTS (2 ,TEGRA264 ), -ADMAIF_REG_DEFAULTS (3 ,TEGRA264 ), -ADMAIF_REG_DEFAULTS (4 ,TEGRA264 ), -ADMAIF_REG_DEFAULTS (5 ,TEGRA264 ), -ADMAIF_REG_DEFAULTS (6 ,TEGRA264 ), -ADMAIF_REG_DEFAULTS (7 ,TEGRA264 ), -ADMAIF_REG_DEFAULTS (8 ,TEGRA264 ), -ADMAIF_REG_DEFAULTS (9 ,TEGRA264 ), -ADMAIF_REG_DEFAULTS (10 ,TEGRA264 ), -ADMAIF_REG_DEFAULTS (11 ,TEGRA264 ), -ADMAIF_REG_DEFAULTS (12 ,TEGRA264 ), -ADMAIF_REG_DEFAULTS (13 ,TEGRA264 ), -ADMAIF_REG_DEFAULTS (14 ,TEGRA264 ), -ADMAIF_REG_DEFAULTS (15 ,TEGRA264 ), -ADMAIF_REG_DEFAULTS (16 ,TEGRA264 ), -ADMAIF_REG_DEFAULTS (17 ,TEGRA264 ), -ADMAIF_REG_DEFAULTS (18 ,TEGRA264 ), -ADMAIF_REG_DEFAULTS (19 ,TEGRA264 ), -ADMAIF_REG_DEFAULTS (20 ,TEGRA264 ), -ADMAIF_REG_DEFAULTS (21 ,TEGRA264 ), -ADMAIF_REG_DEFAULTS (22 ,TEGRA264 ), -ADMAIF_REG_DEFAULTS (23 ,TEGRA264 ), -ADMAIF_REG_DEFAULTS (24 ,TEGRA264 ), -ADMAIF_REG_DEFAULTS (25 ,TEGRA264 ), -ADMAIF_REG_DEFAULTS (26 ,TEGRA264 ), -ADMAIF_REG_DEFAULTS (27 ,TEGRA264 ), -ADMAIF_REG_DEFAULTS (28 ,TEGRA264 ), -ADMAIF_REG_DEFAULTS (29 ,TEGRA264 ), -ADMAIF_REG_DEFAULTS (30 ,TEGRA264 ), -ADMAIF_REG_DEFAULTS (31 ,TEGRA264 ), -ADMAIF_REG_DEFAULTS (32 ,TEGRA264 ) +ADMAIF_RX_REG_DEFAULTS (1 ,TEGRA264 ), +ADMAIF_RX_REG_DEFAULTS (2 ,TEGRA264 ), +ADMAIF_RX_REG_DEFAULTS (3 ,TEGRA264 ), +ADMAIF_RX_REG_DEFAULTS (4 ,TEGRA264 ), +ADMAIF_RX_REG_DEFAULTS (5 ,TEGRA264 ), +ADMAIF_RX_REG_DEFAULTS (6 ,TEGRA264 ), +ADMAIF_RX_REG_DEFAULTS (7 ,TEGRA264 ), +ADMAIF_RX_REG_DEFAULTS (8 ,TEGRA264 ), +ADMAIF_RX_REG_DEFAULTS (9 ,TEGRA264 ), +ADMAIF_RX_REG_DEFAULTS (10 ,TEGRA264 ), +ADMAIF_RX_REG_DEFAULTS (11 ,TEGRA264 ), +ADMAIF_RX_REG_DEFAULTS (12 ,TEGRA264 ), +ADMAIF_RX_REG_DEFAULTS (13 ,TEGRA264 ), +ADMAIF_RX_REG_DEFAULTS (14 ,TEGRA264 ), +ADMAIF_RX_REG_DEFAULTS (15 ,TEGRA264 ), +ADMAIF_RX_REG_DEFAULTS (16 ,TEGRA264 ), +ADMAIF_RX_REG_DEFAULTS (17 ,TEGRA264 ), +ADMAIF_RX_REG_DEFAULTS (18 ,TEGRA264 ), +ADMAIF_RX_REG_DEFAULTS (19 ,TEGRA264 ), +ADMAIF_RX_REG_DEFAULTS (20 ,TEGRA264 ), +ADMAIF_RX_REG_DEFAULTS (21 ,TEGRA264 ), +ADMAIF_RX_REG_DEFAULTS (22 ,TEGRA264 ), +ADMAIF_RX_REG_DEFAULTS (23 ,TEGRA264 ), +ADMAIF_RX_REG_DEFAULTS (24 ,TEGRA264 ), +ADMAIF_RX_REG_DEFAULTS (25 ,TEGRA264 ), +ADMAIF_RX_REG_DEFAULTS (26 ,TEGRA264 ), +ADMAIF_RX_REG_DEFAULTS (27 ,TEGRA264 ), +ADMAIF_RX_REG_DEFAULTS (28 ,TEGRA264 ), +ADMAIF_RX_REG_DEFAULTS (29 ,TEGRA264 ), +ADMAIF_RX_REG_DEFAULTS (30 ,TEGRA264 ), +ADMAIF_RX_REG_DEFAULTS (31 ,TEGRA264 ), +ADMAIF_RX_REG_DEFAULTS (32 ,TEGRA264 ), +ADMAIF_TX_REG_DEFAULTS (1 ,TEGRA264 ), +ADMAIF_TX_REG_DEFAULTS (2 ,TEGRA264 ), +ADMAIF_TX_REG_DEFAULTS (3 ,TEGRA264 ), +ADMAIF_TX_REG_DEFAULTS (4 ,TEGRA264 ), +ADMAIF_TX_REG_DEFAULTS (5 ,TEGRA264 ), +ADMAIF_TX_REG_DEFAULTS (6 ,TEGRA264 ), +ADMAIF_TX_REG_DEFAULTS (7 ,TEGRA264 ), +ADMAIF_TX_REG_DEFAULTS (8 ,TEGRA264 ), +ADMAIF_TX_REG_DEFAULTS (9 ,TEGRA264 ), +ADMAIF_TX_REG_DEFAULTS (10 ,TEGRA264 ), +ADMAIF_TX_REG_DEFAULTS (11 ,TEGRA264 ), +ADMAIF_TX_REG_DEFAULTS (12 ,TEGRA264 ), +ADMAIF_TX_REG_DEFAULTS (13 ,TEGRA264 ), +ADMAIF_TX_REG_DEFAULTS (14 ,TEGRA264 ), +ADMAIF_TX_REG_DEFAULTS (15 ,TEGRA264 ), +ADMAIF_TX_REG_DEFAULTS (16 ,TEGRA264 ), +ADMAIF_TX_REG_DEFAULTS (17 ,TEGRA264 ), +ADMAIF_TX_REG_DEFAULTS (18 ,TEGRA264 ), +ADMAIF_TX_REG_DEFAULTS (19 ,TEGRA264 ), +ADMAIF_TX_REG_DEFAULTS (20 ,TEGRA264 ), +ADMAIF_TX_REG_DEFAULTS (21 ,TEGRA264 ), +ADMAIF_TX_REG_DEFAULTS (22 ,TEGRA264 ), +ADMAIF_TX_REG_DEFAULTS (23 ,TEGRA264 ), +ADMAIF_TX_REG_DEFAULTS (24 ,TEGRA264 ), +ADMAIF_TX_REG_DEFAULTS (25 ,TEGRA264 ), +ADMAIF_TX_REG_DEFAULTS (26 ,TEGRA264 ), +ADMAIF_TX_REG_DEFAULTS (27 ,TEGRA264 ), +ADMAIF_TX_REG_DEFAULTS (28 ,TEGRA264 ), +ADMAIF_TX_REG_DEFAULTS (29 ,TEGRA264 ), +ADMAIF_TX_REG_DEFAULTS (30 ,TEGRA264 ), +ADMAIF_TX_REG_DEFAULTS (31 ,TEGRA264 ), +ADMAIF_TX_REG_DEFAULTS (32 ,TEGRA264 ), + {(TEGRA_ADMAIF_GLOBAL_CG_0 +TEGRA264_ADMAIF_GLOBAL_BASE ),0x00000003 } };static bool tegra_admaif_wr_reg (struct device *dev,unsigned int reg)
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 8/713 ASoC: tegra: Sort MBDRC register defaults
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jon Hunter <[email protected]>
[ Upstream commit abb5bed6f48d54d3b82724a430fd462579ecd876 ]
Commit 4b05ccb17f92 ("regcache: Sort the local copy of an unsorted reg_defaults array") exposed an issue with the Tegra MBDRC driver and now the following warning is observed:
tegra210-ope 2908000.processing-engine: Driver needs fixing: Unsorted
reg_defaults, sorting the copy
This warning occurs because register defaults in the structure tegra210_mbdrc_reg_defaults are not specified in ascending order which is required by regmap. Fix this by sorting the register defaults according to their address. Note that in order to do this it is necessary to replace the macro MBDRC_FILTER_REG_DEFAULTS with a per register macro MBDRC_FILTER_PARAM_REG_DEFAULTS.
--- sound/soc/tegra/tegra210_mbdrc.c | 42 ++++++++++++++++---------------- 1 file changed, 21 insertions(+), 21 deletions(-)
sound/soc/tegra/tegra210_mbdrc.c +21 -21
@@ -20,33 +20,33 @@#define MBDRC_FILTER_REG (reg, id) \ ((reg) + ((id) * TEGRA210_MBDRC_FILTER_PARAM_STRIDE)) -#define MBDRC_FILTER_REG_DEFAULTS (id) \ - { MBDRC_FILTER_REG(TEGRA210_MBDRC_IIR_CFG, id), 0x00000005}, \ - { MBDRC_FILTER_REG(TEGRA210_MBDRC_IN_ATTACK, id), 0x3e48590c}, \ - { MBDRC_FILTER_REG(TEGRA210_MBDRC_IN_RELEASE, id), 0x08414e9f}, \ - { MBDRC_FILTER_REG(TEGRA210_MBDRC_FAST_ATTACK, id), 0x7fffffff}, \ - { MBDRC_FILTER_REG(TEGRA210_MBDRC_IN_THRESHOLD, id), 0x06145082}, \ - { MBDRC_FILTER_REG(TEGRA210_MBDRC_OUT_THRESHOLD, id), 0x060d379b}, \ - { MBDRC_FILTER_REG(TEGRA210_MBDRC_RATIO_1ST, id), 0x0000a000}, \ - { MBDRC_FILTER_REG(TEGRA210_MBDRC_RATIO_2ND, id), 0x00002000}, \ - { MBDRC_FILTER_REG(TEGRA210_MBDRC_RATIO_3RD, id), 0x00000b33}, \ - { MBDRC_FILTER_REG(TEGRA210_MBDRC_RATIO_4TH, id), 0x00000800}, \ - { MBDRC_FILTER_REG(TEGRA210_MBDRC_RATIO_5TH, id), 0x0000019a}, \ - { MBDRC_FILTER_REG(TEGRA210_MBDRC_MAKEUP_GAIN, id), 0x00000002}, \ - { MBDRC_FILTER_REG(TEGRA210_MBDRC_INIT_GAIN, id), 0x00066666}, \ - { MBDRC_FILTER_REG(TEGRA210_MBDRC_GAIN_ATTACK, id), 0x00d9ba0e}, \ - { MBDRC_FILTER_REG(TEGRA210_MBDRC_GAIN_RELEASE, id), 0x3e48590c}, \ - { MBDRC_FILTER_REG(TEGRA210_MBDRC_FAST_RELEASE, id), 0x7ffff26a}, \ - { MBDRC_FILTER_REG(TEGRA210_MBDRC_CFG_RAM_CTRL, id), 0x4000} +#define MBDRC_FILTER_PARAM_REG_DEFAULTS (reg, val) \ + { MBDRC_FILTER_REG(reg, 0), val}, \ + { MBDRC_FILTER_REG(reg, 1), val}, \ + { MBDRC_FILTER_REG(reg, 2), val}static const struct reg_default tegra210_mbdrc_reg_defaults[] = { {TEGRA210_MBDRC_CFG ,0x0030de51 }, {TEGRA210_MBDRC_CHANNEL_MASK ,0x00000003 }, {TEGRA210_MBDRC_FAST_FACTOR ,0x30000800 }, -MBDRC_FILTER_REG_DEFAULTS (0 ), -MBDRC_FILTER_REG_DEFAULTS (1 ), -MBDRC_FILTER_REG_DEFAULTS (2 ), +MBDRC_FILTER_PARAM_REG_DEFAULTS (TEGRA210_MBDRC_IIR_CFG ,0x00000005 ), +MBDRC_FILTER_PARAM_REG_DEFAULTS (TEGRA210_MBDRC_IN_ATTACK ,0x3e48590c ), +MBDRC_FILTER_PARAM_REG_DEFAULTS (TEGRA210_MBDRC_IN_RELEASE ,0x08414e9f ), +MBDRC_FILTER_PARAM_REG_DEFAULTS (TEGRA210_MBDRC_FAST_ATTACK ,0x7fffffff ), +MBDRC_FILTER_PARAM_REG_DEFAULTS (TEGRA210_MBDRC_IN_THRESHOLD ,0x06145082 ), +MBDRC_FILTER_PARAM_REG_DEFAULTS (TEGRA210_MBDRC_OUT_THRESHOLD ,0x060d379b ), +MBDRC_FILTER_PARAM_REG_DEFAULTS (TEGRA210_MBDRC_RATIO_1ST ,0x0000a000 ), +MBDRC_FILTER_PARAM_REG_DEFAULTS (TEGRA210_MBDRC_RATIO_2ND ,0x00002000 ), +MBDRC_FILTER_PARAM_REG_DEFAULTS (TEGRA210_MBDRC_RATIO_3RD ,0x00000b33 ), +MBDRC_FILTER_PARAM_REG_DEFAULTS (TEGRA210_MBDRC_RATIO_4TH ,0x00000800 ), +MBDRC_FILTER_PARAM_REG_DEFAULTS (TEGRA210_MBDRC_RATIO_5TH ,0x0000019a ), +MBDRC_FILTER_PARAM_REG_DEFAULTS (TEGRA210_MBDRC_MAKEUP_GAIN ,0x00000002 ), +MBDRC_FILTER_PARAM_REG_DEFAULTS (TEGRA210_MBDRC_INIT_GAIN ,0x00066666 ), +MBDRC_FILTER_PARAM_REG_DEFAULTS (TEGRA210_MBDRC_GAIN_ATTACK ,0x00d9ba0e ), +MBDRC_FILTER_PARAM_REG_DEFAULTS (TEGRA210_MBDRC_GAIN_RELEASE ,0x3e48590c ), +MBDRC_FILTER_PARAM_REG_DEFAULTS (TEGRA210_MBDRC_FAST_RELEASE ,0x7ffff26a ), +MBDRC_FILTER_PARAM_REG_DEFAULTS (TEGRA210_MBDRC_CFG_RAM_CTRL ,0x4000 ), };/* Default MBDRC parameters */
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 9/713 btrfs: write-protect folios during data writeback
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Boris Burkov <[email protected]>
commit 5376c9db45368eb210b4d71104ac00a59dc8b6e0 upstream.
commit 095be159f3eb ("btrfs: unify folio dirty flag clearing") replaced the folio_clear_dirty_for_io() call in extent_write_cache_pages() with a plain folio_test_dirty() check. Besides clearing the dirty flag, folio_clear_dirty_for_io() also calls folio_mkclean(), which write-protects the shared mmap PTEs mapping the folio. Note that we still do call folio_clear_dirty_for_io() later in submit_one_sector() when we clear dirty on the last sector of the folio (the only sector for non-subpage cases). But we lost this early call in extent_write_cache_pages().
Without the extra write-protection, a process with the file mmap-ed can modify a sector while it is being used by writeback in a way that expects a stable folio (checksumming, compressing, copying, etc...) without faulting, which manifests as a handful of concrete bugs.
1. For large folios or subpage sectorsize, it is possible to submit a bio which does not cover the whole folio. When this happens, we will have a bio in flight for a folio that we have *not* called folio_clear_dirty_for_io() on. If a task with an existing mmap-ed PTE writes (without faulting..) in this window, it can result in corruptions. If the write arrives while the checksumming or writing itself is underway, this can result in an invalid checksum and later corruption reports on read. If the write arrives after checksumming/writing is done but before the last sector dirty is cleared, then the write is present in page cache but doesn't affect the dirty tracking and will be lost when the folio is fully finished being submitted and the dirty bit is cleared. This results in losing the write even if fsync() is called.
2. For zoned submissions which are done in batch separate from the main extent_writepage() loop, we also risk csum violations for those submissions. Zoned writes are clamped to max_zone_append_size and are not aligned with folios, so a submission can span two folios. The first folio being processed in extent_write_cache_pages() will call extent_write_locked_range() which will submit the partial range of the next folio, while the rest of that folio could still be dirty. So clearing dirty on the submitted sectors doesn't call folio_clear_dirty_for_io() and we have the same issue. Since extent_write_cache_pages() skips these batch submitted folios (they are already marked for writeback from submission by the preceding folio), we must add the extra write protection in lock_delalloc_folios().
3. For inline extents this will subtly risk losing writes that happen after/while we copy the inline extent but before we clear dirty on the folio.
4. For folios spanning EOF, mmap could tamper with the zeroed bytes past EOF and cause them to be persisted where future faults would improperly see them instead of zeros.
5. Finally, for compressed extents, we risk modifying the folios while we
work on compressing them which will result in corrupted compressed data.
Specifically, in run_delalloc_compressed() we queue up work to docompress_file_range() in BTRFS_COMPRESSION_CHUNK_SIZE (512K) chunks which
will call btrfs_folio_clamp_clear_dirty() on the range. For non-subpage,
this will always clear the whole folio, safely. For subpage, we risk a
partial clear here as well. In particular, imagine a 2M folio broken up
into 512K chunks of work which might start compression work on one chunk
before all the chunks compress_file_range() workers have gotten far
enough to finish clearing all the dirty bitmaps of the folio and getting
to folio_clear_dirty_for_io(). Large folios on the edges of submission
ranges are similarly at risk to be only partly cleared.
This particular gap was introduced by a second patch in the same series:
commit a4ef54dbb576 ("btrfs: make extent_range_clear_dirty_for_io() to handle sector size < page size cases")
We cannot simply restore the call to folio_clear_dirty_for_io() because
that also drops the dirty flag off the folio which violates invariants
introduced for large folios by
commit 334509ce9d07 ("btrfs: use dirty flag to check if an ordered extent needs to be truncated") and results in failing to invalidate clean folios past i_size, resulting
in deadlocks.
Therefore, to fix it, leave the existing semantics w.r.t. the folio's dirty flag (to preserve the correct invalidate behavior) but ensure that the other aspect of folio_clear_dirty_for_io(), folio_mkclean(), is run on the folio when we lock it for writeback.
Finally, to help prevent similar regressions in the future, add a debug warning that triggers at the known corruption sites if we have failed to write protect the folio.
--- fs/btrfs/extent_io.c | 31 +++++++++++++++++++++++++++++++ fs/btrfs/extent_io.h | 5 +++++ fs/btrfs/inode.c | 23 +++++++++++++++++------ 3 files changed, 53 insertions(+), 6 deletions(-)
fs/btrfs/extent_io.c +31 -0
@@ -6,6 +6,7 @@#include <linux/mm.h> #include <linux/pagemap.h> #include <linux/page-flags.h> +#include <linux/rmap.h> #include <linux/sched/mm.h> #include <linux/spinlock.h> #include <linux/blkdev.h>
@@ -299,6 +300,25 @@ static noinline void unlock_delalloc_folio(const struct inode *inode, PAGE_UNLOCK); } +#ifdef CONFIG_BTRFS_DEBUG +/* +* Writeback must write-protect a folio when locking it for IO, before +* anything consumes its data (zeroing, inline copy, compression, +* checksumming). If this fails, then an mmap writer would be able to +* modify the data concurrently while we need it to be stable. +*/ +void btrfs_check_folio_write_protected (struct folio *folio) +{ +if (folio_mkclean (folio)) { +const struct btrfs_inode *inode =BTRFS_I (folio->mapping->host); + +DEBUG_WARN ("writable mmap PTEs, root %llu ino %llu pos %llu order %u" , +btrfs_root_id (inode->root),btrfs_ino (inode),folio_pos (folio), +folio_order (folio)); + } +} +#endif + static noinline int lock_delalloc_folios(struct inode *inode,struct folio *locked_folio,u64 start,u64 end)
@@ -332,6 +352,8 @@ static noinline int lock_delalloc_folios(struct inode *inode,folio_unlock (folio); goto out; } +/* Locked for writeback; revoke writable mmap PTEs before using the data. */ +folio_mkclean (folio); range_start =max_t (u64,folio_pos (folio), start); range_len =min_t (u64,folio_next_pos (folio), end +1 ) - range_start;btrfs_folio_set_lock (fs_info, folio, range_start, range_len);
@@ -1893,6 +1915,13 @@ static noinline_for_stack int extent_writepage_io(struct btrfs_inode *inode,ASSERT (end <= folio_end,"start=%llu len=%u folio_start=%llu folio_size=%zu" , start, len, folio_start,folio_size (folio)); +/* +* We are about to checksum and write out the data, so it must not be +* mmap writeable, or we could corrupt the data and end up with invalid +* checksums. +*/ +btrfs_check_folio_write_protected (folio); +/* Truncate the submit bitmap to the current range. */ if (start > folio_start) bitmap_clear(bio_ctrl->submit_bitmap, 0,
@@ -2703,6 +2732,8 @@ static int extent_write_cache_pages(struct address_space *mapping,continue ; } +/* Locked for writeback; revoke writable mmap PTEs before using the data. */ +folio_mkclean (folio); ret =extent_writepage (folio, bio_ctrl);if (ret <0 ) { done = true;
fs/btrfs/extent_io.h +5 -0
@@ -255,6 +255,11 @@ bool try_release_extent_mapping(struct folio *folio, gfp_t mask);int try_release_extent_buffer (struct folio *folio);int btrfs_read_folio (struct file *file,struct folio *folio); +#ifdef CONFIG_BTRFS_DEBUG +void btrfs_check_folio_write_protected (struct folio *folio); +#else +static inline void btrfs_check_folio_write_protected (struct folio *folio) { } +#endif void extent_write_locked_range (struct inode *inode,const struct folio *locked_folio,u64 start,u64 end,struct writeback_control *wbc,bool pages_dirty);
fs/btrfs/inode.c +17 -6
@@ -775,19 +775,28 @@ static inline void inode_should_defrag(struct btrfs_inode *inode,static int extent_range_clear_dirty_for_io (struct btrfs_inode *inode,u64 start,u64 end) { +pgoff_t index = start >>PAGE_SHIFT ;const pgoff_t end_index = end >>PAGE_SHIFT ;struct folio *folio;int ret =0 ; -for (pgoff_t index = start >>PAGE_SHIFT ; index <= end_index; index++) { +while (index <= end_index) { folio =filemap_get_folio (inode->vfs_inode.i_mapping, index);if (IS_ERR (folio)) {if (!ret) ret =PTR_ERR (folio); + index++;continue ; } +/* +* We are about to compress the folio, so it must not be mmap +* writeable or we could corrupt the data as we attempt to +* compress it. +*/ +btrfs_check_folio_write_protected (folio);btrfs_folio_clamp_clear_dirty (inode->root->fs_info, folio, start, end +1 - start); + index =folio_next_index (folio);folio_put (folio); }return ret;
@@ -877,11 +886,6 @@ static void compress_file_range(struct btrfs_work *work)inode_should_defrag (inode, start, end, end - start +1 ,SZ_16K ); -/* -* We need to call clear_page_dirty_for_io on each page in the range. -* Otherwise applications with the file mmap'd can wander in and change -* the page contents while we are compressing them. -*/ ret =extent_range_clear_dirty_for_io (inode, start, end);/*
@@ -2317,6 +2321,13 @@ static int run_delalloc_inline(struct btrfs_inode *inode, struct folio *locked_fint ret;ASSERT (folio_pos (locked_folio) ==0 ); +/* +* If an mmap writer could modify the folio while we copy it into an +* inline extent we might see only part of their modification then +* wrongly mark it clean again after copying, losing that write. So the +* folio must be write protected here. +*/ +btrfs_check_folio_write_protected (locked_folio);if (btrfs_inode_can_compress (inode) &&inode_need_compress (inode,0 , blocksize, true)) {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 10/713 ring-buffer: Fix subbuf resize race with ring buffer readers
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vincent Donnefort <[email protected]>
[ Upstream commit 8a5f63637890f03177146efddaba5ec7a1b4d61f ]
trace_buffer subbuf_size is read lockless in ring_buffer_read_page() and ring_buffer_read_start(), while it can simultaneously be resized with ring_buffer_subbuf_order_set().
Instead of trace_buffer::subbuf_size, use bpage::order in ring_buffer_read_start() and ring_buffer_read_page().
In ring_buffer_read_start(), even with resize_disabled, there is still a possibility of a race with a buffer modification. Hold the trace_buffer mutex to synchronise with any pending ring buffer order modification.
trace_buffer::subbuf_size is now actually useless, remove it. Also, create accessors rb_subbuf_capacity() and rb_page_capacity() which return the actual size available for storing events, while rb_subbuf_size() returns the actual subbuf page-size.
--- kernel/trace/ring_buffer.c | 167 +++++++++++++++++++++++-------------- 1 file changed, 106 insertions(+), 61 deletions(-)
kernel/trace/ring_buffer.c +106 -61
@@ -391,6 +391,17 @@ static __always_inline unsigned int rb_page_size(struct buffer_page *bpage)return rb_data_page_size (bpage->page); } +/** +* rb_page_capacity - Get the capacity of a buffer page +* @bpage: The buffer page +* +* Return: The maximum size available for events in the given buffer page. +*/ +static __always_inline unsigned int rb_page_capacity(struct buffer_page *bpage) +{ +return (PAGE_SIZE << bpage->order) -BUF_PAGE_HDR_SIZE ; +} +static void free_buffer_page (struct buffer_page *bpage) {/* Range pages are not to be freed */
@@ -586,11 +597,42 @@ struct trace_buffer {struct ring_buffer_meta *meta; -unsigned int subbuf_size;unsigned int subbuf_order;unsigned int max_data_size; }; +static __always_inline unsigned int rb_subbuf_size(struct trace_buffer *buffer) +{ +return PAGE_SIZE << buffer->subbuf_order; +} + +/** +* rb_subbuf_capacity - Get the capacity of a subbuffer +* @buffer: A trace buffer +* +* Unsafe to use without holding trace_buffer::mutex or with resizing enabled. +* Consider rb_page_capacity() instead. +* +* Return: The maximum size available for events in a trace buffer subbuffer. +*/ +static __always_inline unsigned int rb_subbuf_capacity(struct trace_buffer *buffer) +{ +return rb_subbuf_size (buffer) -BUF_PAGE_HDR_SIZE ; +} + +/** +* rb_subbuf_start - Get the start address of a subbuffer +* @buffer: A trace buffer +* @addr: An address of an event on a subbuffer +* +* Return: The start of the subbuffer for where @addr sits +*/ +static __always_inline +unsigned long rb_subbuf_start (struct trace_buffer *buffer,unsigned long addr) +{ +return addr & ~((unsigned long )(rb_subbuf_size (buffer) -1 )); +} +struct ring_buffer_iter {struct ring_buffer_per_cpu *cpu_buffer;unsigned long head;
@@ -630,7 +672,7 @@ int ring_buffer_print_page_header(struct trace_buffer *buffer, struct trace_seqtrace_seq_printf (s,"\tfield: char data;\t" "offset:%u;\tsize:%u;\tsigned:%u;\n" , (unsigned int )offsetof(typeof (field ), data), - (unsigned int )(buffer ? buffer->subbuf_size : + (unsigned int )(buffer ?rb_subbuf_capacity (buffer) :PAGE_SIZE -BUF_PAGE_HDR_SIZE ), (unsigned int )is_signed_type (char));
@@ -1620,7 +1662,7 @@ rb_range_align_subbuf(unsigned long addr, int subbuf_size, int nr_subbufs)*/ static void *rb_range_meta (struct trace_buffer *buffer,int nr_pages,int cpu) { -int subbuf_size = buffer->subbuf_size +BUF_PAGE_HDR_SIZE ; +int subbuf_size =rb_subbuf_size (buffer);struct ring_buffer_cpu_meta *meta;struct ring_buffer_meta *bmeta;unsigned long ptr;
@@ -2432,8 +2474,8 @@ static int __rb_allocate_pages(struct ring_buffer_per_cpu *cpu_buffer, bpage->id = i +1 ; cpu_buffer->subbuf_ids[i +1 ] = bpage; }else { -int order = cpu_buffer->buffer->subbuf_order; - bpage->page =alloc_cpu_data (cpu_buffer->cpu, order); + bpage->page =alloc_cpu_data (cpu_buffer->cpu, + cpu_buffer->buffer->subbuf_order);if (!bpage->page) goto free_pages; }
@@ -2556,8 +2598,7 @@ rb_allocate_cpu_buffer(struct trace_buffer *buffer, long nr_pages, int cpu) bpage->range =1 ; cpu_buffer->subbuf_ids[0 ] = bpage; }else { -int order = cpu_buffer->buffer->subbuf_order; - bpage->page =alloc_cpu_data (cpu, order); + bpage->page =alloc_cpu_data (cpu, bpage->order);if (!bpage->page) goto fail_free_reader; }
@@ -2731,10 +2772,9 @@ static struct trace_buffer *alloc_buffer(unsigned long size, unsigned flags, buffer->subbuf_order = order; subbuf_size = (PAGE_SIZE << order); - buffer->subbuf_size = subbuf_size -BUF_PAGE_HDR_SIZE ;/* Max payload is buffer page size - header (8bytes) */ - buffer->max_data_size = buffer->subbuf_size - (sizeof (u32) *2 ); + buffer->max_data_size =rb_subbuf_capacity (buffer) - (sizeof (u32) *2 ); buffer->flags = flags; buffer->clock = trace_clock_local;
@@ -2818,9 +2858,8 @@ static struct trace_buffer *alloc_buffer(unsigned long size, unsigned flags,if (nr_pages <2 ) goto fail_free_buffers; }else { -/* need at least two pages */ - nr_pages =DIV_ROUND_UP (size, buffer->subbuf_size); + nr_pages =DIV_ROUND_UP (size,rb_subbuf_capacity (buffer));if (nr_pages <2 ) nr_pages =2 ; }
@@ -3203,7 +3242,7 @@ static void update_pages_handler(struct work_struct *work)* @size: the new size. * @cpu_id: the cpu buffer to resize * -* Minimum size is 2 * buffer->subbuf_size. +* Minimum size is 2 * rb_subbuf_capacity(buffer). * * Returns 0 on success and < 0 on failure. */
@@ -3225,12 +3264,6 @@ int ring_buffer_resize(struct trace_buffer *buffer, unsigned long size, !cpumask_test_cpu(cpu_id, buffer->cpumask))return 0 ; - nr_pages =DIV_ROUND_UP (size, buffer->subbuf_size); - -/* we need a minimum of two pages */ -if (nr_pages <2 ) - nr_pages =2 ; -/* * Keep CPUs from coming online while resizing to synchronize * with new per CPU buffers being created.
@@ -3241,6 +3274,12 @@ int ring_buffer_resize(struct trace_buffer *buffer, unsigned long size,mutex_lock (&buffer->mutex);atomic_inc (&buffer->resizing); + nr_pages =DIV_ROUND_UP (size,rb_subbuf_capacity (buffer)); + +/* we need a minimum of two pages */ +if (nr_pages <2 ) + nr_pages =2 ; +if (cpu_id ==RING_BUFFER_ALL_CPUS ) {/* * Don't succeed if resizing is disabled, as a reader might be
@@ -3513,7 +3552,7 @@ rb_event_index(struct ring_buffer_per_cpu *cpu_buffer, struct ring_buffer_event {unsigned long addr = (unsigned long )event; - addr &= (PAGE_SIZE << cpu_buffer->buffer->subbuf_order) -1 ; + addr &= (unsigned long )rb_subbuf_size (cpu_buffer->buffer) -1 ;return addr -BUF_PAGE_HDR_SIZE ; }
@@ -3755,8 +3794,8 @@ static inline void rb_reset_tail(struct ring_buffer_per_cpu *cpu_buffer, unsigned long tail, struct rb_event_info *info) { - unsigned long bsize = READ_ONCE(cpu_buffer->buffer->subbuf_size); struct buffer_page *tail_page = info->tail_page; +unsigned long bsize =rb_page_capacity (tail_page);struct ring_buffer_event *event;unsigned long length = info->length;
@@ -4101,8 +4140,7 @@ rb_try_to_discard(struct ring_buffer_per_cpu *cpu_buffer, new_index =rb_event_index (cpu_buffer, event); old_index = new_index +rb_event_ts_length (event); - addr = (unsigned long )event; - addr &= ~((PAGE_SIZE << cpu_buffer->buffer->subbuf_order) -1 ); + addr =rb_subbuf_start (cpu_buffer->buffer, (unsigned long )event); bpage =READ_ONCE (cpu_buffer->tail_page);
@@ -4767,7 +4805,7 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer, tail = write - info->length;/* See if we shot pass the end of this buffer page */ -if (unlikely (write > cpu_buffer->buffer->subbuf_size)) { +if (unlikely (write >rb_page_capacity (tail_page))) {check_buffer (cpu_buffer, info,CHECK_FULL_PAGE );return rb_move_tail (cpu_buffer, tail, info); }
@@ -5012,7 +5050,7 @@ rb_decrement_entry(struct ring_buffer_per_cpu *cpu_buffer,struct buffer_page *bpage = cpu_buffer->commit_page;struct buffer_page *start; - addr &= ~((PAGE_SIZE << cpu_buffer->buffer->subbuf_order) -1 ); + addr =rb_subbuf_start (cpu_buffer->buffer, addr);/* Do the likely case first */ if (likely (bpage->page == (void *)addr)) {
@@ -5799,7 +5837,6 @@ static struct buffer_page * __rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer) {int max_loops = cpu_buffer->ring_meta ? cpu_buffer->nr_pages :3 ; -unsigned long bsize =READ_ONCE (cpu_buffer->buffer->subbuf_size);struct buffer_page *reader =NULL ;unsigned long overwrite;unsigned long flags;
@@ -5947,7 +5984,7 @@ __rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer)#define USECS_WAIT 1000000for (nr_loops =0 ; nr_loops <USECS_WAIT ; nr_loops++) {/* If the write is past the end of page, a writer is still updating it */ -if (likely (!reader ||rb_page_write (reader) <= bsize)) +if (likely (!reader ||rb_page_write (reader) <=rb_page_capacity (reader)))break ;udelay (1 );
@@ -6380,36 +6417,44 @@ EXPORT_SYMBOL_GPL(ring_buffer_consume);struct ring_buffer_iter *ring_buffer_read_start (struct trace_buffer *buffer,int cpu,gfp_t flags) { + struct ring_buffer_iter *iter __free(kfree) = kzalloc_obj(*iter, flags);struct ring_buffer_per_cpu *cpu_buffer; -struct ring_buffer_iter *iter; - -if (!cpumask_test_cpu (cpu, buffer->cpumask)) -return NULL ; - iter =kzalloc_obj (*iter, flags);if (!iter)return NULL ; -/* Holds the entire event: data and meta data */ - iter->event_size = buffer->subbuf_size; - iter->event =kmalloc (iter->event_size, flags); -if (!iter->event) { -kfree (iter); +if (!cpumask_test_cpu (cpu, buffer->cpumask))return NULL ; - } cpu_buffer = buffer->buffers[cpu]; - iter->cpu_buffer = cpu_buffer; +/* +* Only KDB is using GFP_ATOMIC, for the others, lock the buffer to +* prevent concurrent resizing. +*/ +if (gfpflags_allow_blocking (flags)) +mutex_lock (&buffer->mutex);atomic_inc (&cpu_buffer->resize_disabled); +if (gfpflags_allow_blocking (flags)) +mutex_unlock (&buffer->mutex); + +/* Holds the entire event: data and meta data. */ + iter->event_size =rb_page_capacity (READ_ONCE (cpu_buffer->reader_page)); + iter->event =kmalloc (iter->event_size, flags); +if (!iter->event) { +atomic_dec (&cpu_buffer->resize_disabled); +return NULL ; + } + iter->cpu_buffer = cpu_buffer; +guard (raw_spinlock_irqsave)(&cpu_buffer->reader_lock);arch_spin_lock (&cpu_buffer->lock);rb_iter_reset (iter);arch_spin_unlock (&cpu_buffer->lock); -return iter; +return_ptr (iter); }EXPORT_SYMBOL_GPL (ring_buffer_read_start);
@@ -6463,7 +6508,7 @@ unsigned long ring_buffer_size(struct trace_buffer *buffer, int cpu)if (!cpumask_test_cpu (cpu, buffer->cpumask))return 0 ; -return buffer->subbuf_size * buffer->buffers[cpu]->nr_pages; +return rb_subbuf_capacity (buffer) * buffer->buffers[cpu]->nr_pages; }EXPORT_SYMBOL_GPL (ring_buffer_size);
@@ -7094,15 +7139,15 @@ int ring_buffer_read_page(struct trace_buffer *buffer,if (!data_page || !data_page->data)return -1 ; -if (data_page->order != buffer->subbuf_order) -return -1 ; - dpage = data_page->data;if (!dpage)return -1 ;guard (raw_spinlock_irqsave)(&cpu_buffer->reader_lock); +if (data_page->order != cpu_buffer->reader_page->order) +return -1 ; + reader =rb_get_reader_page (cpu_buffer);if (!reader)return -1 ;
@@ -7228,7 +7273,7 @@ int ring_buffer_read_page(struct trace_buffer *buffer,* missed events, then record it there. */ if (missed_events >0 && - buffer->subbuf_size - size >=sizeof (missed_events)) { +rb_page_capacity (reader) - size >=sizeof (missed_events)) {memcpy (&dpage->data[size], &missed_events,sizeof (missed_events));local_add (RB_MISSED_STORED , &dpage->commit);
@@ -7248,8 +7293,8 @@ int ring_buffer_read_page(struct trace_buffer *buffer,/* * This page may be off to user land. Zero it out here. */ -if (size < buffer->subbuf_size) -memset (&dpage->data[size],0 , buffer->subbuf_size - size); +if (size <rb_page_capacity (reader)) +memset (&dpage->data[size],0 ,rb_page_capacity (reader) - size);return read; }
@@ -7275,7 +7320,7 @@ EXPORT_SYMBOL_GPL(ring_buffer_read_page_data);*/ int ring_buffer_subbuf_size_get (struct trace_buffer *buffer) { -return buffer->subbuf_size +BUF_PAGE_HDR_SIZE ; +return rb_subbuf_size (buffer); }EXPORT_SYMBOL_GPL (ring_buffer_subbuf_size_get);
@@ -7320,7 +7365,8 @@ int ring_buffer_subbuf_order_set(struct trace_buffer *buffer, int order) {struct ring_buffer_per_cpu *cpu_buffer;struct buffer_page *bpage, *tmp; -int old_order, old_size; +unsigned int old_capacity; +int old_order;int nr_pages;int psize;int err;
@@ -7329,9 +7375,6 @@ int ring_buffer_subbuf_order_set(struct trace_buffer *buffer, int order)if (!buffer || order <0 )return -EINVAL ; -if (buffer->subbuf_order == order) -return 0 ; - psize = (1 << order) *PAGE_SIZE ;if (psize <=BUF_PAGE_HDR_SIZE )return -EINVAL ;
@@ -7340,18 +7383,21 @@ int ring_buffer_subbuf_order_set(struct trace_buffer *buffer, int order)if (psize >RB_WRITE_MASK +1 )return -EINVAL ; - old_order = buffer->subbuf_order; - old_size = buffer->subbuf_size; -/* prevent another thread from changing buffer sizes */ guard (mutex)(&buffer->mutex); + + old_order = buffer->subbuf_order; +if (old_order == order) +return 0 ; + + old_capacity =rb_subbuf_capacity (buffer); +atomic_inc (&buffer->record_disabled);/* Make sure all commits have finished */ synchronize_rcu (); buffer->subbuf_order = order; - buffer->subbuf_size = psize -BUF_PAGE_HDR_SIZE ;/* Make sure all new buffers are allocated, before deleting the old ones */ for_each_buffer_cpu (buffer, cpu) {
@@ -7367,8 +7413,8 @@ int ring_buffer_subbuf_order_set(struct trace_buffer *buffer, int order) }/* Update the number of pages to match the new size */ - nr_pages = old_size * buffer->buffers[cpu]->nr_pages; - nr_pages =DIV_ROUND_UP (nr_pages, buffer->subbuf_size); + nr_pages = old_capacity * buffer->buffers[cpu]->nr_pages; + nr_pages =DIV_ROUND_UP (nr_pages,rb_subbuf_capacity (buffer));/* we need a minimum of two pages */ if (nr_pages <2 )
@@ -7454,7 +7500,6 @@ int ring_buffer_subbuf_order_set(struct trace_buffer *buffer, int order) error: buffer->subbuf_order = old_order; - buffer->subbuf_size = old_size;atomic_dec (&buffer->record_disabled);
@@ -7532,7 +7577,7 @@ static void rb_setup_ids_meta_page(struct ring_buffer_per_cpu *cpu_buffer, meta->meta_struct_len =sizeof (*meta); meta->nr_subbufs = nr_subbufs; - meta->subbuf_size = cpu_buffer->buffer->subbuf_size +BUF_PAGE_HDR_SIZE ; + meta->subbuf_size =rb_subbuf_size (cpu_buffer->buffer); meta->meta_page_size = meta->subbuf_size;rb_update_meta_page (cpu_buffer);
@@ -7894,7 +7939,7 @@ int ring_buffer_map_get_reader(struct trace_buffer *buffer, int cpu)* missed events, then record it there. */ commit =rb_page_size (reader); -if (buffer->subbuf_size - commit >=sizeof (missed_events)) { +if (rb_subbuf_capacity (buffer) - commit >=sizeof (missed_events)) {memcpy (&dpage->data[commit], &missed_events,sizeof (missed_events));local_add (RB_MISSED_STORED , &dpage->commit);
@@ -7926,7 +7971,7 @@ int ring_buffer_map_get_reader(struct trace_buffer *buffer, int cpu) out:/* Some archs do not have data cache coherency between kernel and user-space */ flush_kernel_vmap_range (cpu_buffer->reader_page->page, - buffer->subbuf_size +BUF_PAGE_HDR_SIZE ); +rb_subbuf_size (buffer));rb_update_meta_page (cpu_buffer);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 11/713 drm/amd/display: hide Apple Studio Display secondary tile
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jerry Zuo <[email protected]>
[ Upstream commit 49521be4809d63fe3efb6bc68ee11cb1e1ef3d63 ]
The Apple Studio Display exposes a 2x1 tiled panel over two SST DP links. The primary tile advertises the full 5120x2880 mode (with DSC on the bandwidth-sufficient link) while the secondary carries a per-tile 2560x2880 timing on a link without sufficient bandwidth. Report the non-primary tile connector as disconnected during detect so compositors only see the primary DP link and configure a single 5K mode instead of driving both tiled streams independently.
Drive the behaviour from an EDID quirk: add a disable_second_tile panel patch that apply_edid_quirks() sets for the affected Apple Studio Display panel IDs (0xAE3A, 0xAE42, 0xAE46), and have detect() hide the secondary tile when the sink carries that quirk.
Adjust for lack of movement from amdgpu_dm.c to amdgpu_dm_connector.c
--- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 36 +++++++++++++++++++ .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 11 ++++++ drivers/gpu/drm/amd/display/dc/dc_types.h | 1 + 3 files changed, 48 insertions(+)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +36 -0
@@ -7846,6 +7846,39 @@ amdgpu_dm_connector_poll(struct amdgpu_dm_connector *aconnector, bool force)return status; } +/* +* Apple Studio Display exposes two SST DP links for a 2x1 tiled panel. +* The primary tile advertises the full 5120x2880 mode (with DSC on the +* bandwidth-sufficient link) while the secondary carries a per-tile +* 2560x2880 timing on a insufficient bandwidth link. Hide the secondary +* connector from userspace so compositors configure a single 5K stream +* on the primary link only. +*/ +static bool amdgpu_dm_hide_secondary_tile_from_userspace (struct drm_connector *connector) +{ +struct amdgpu_dm_connector *aconnector =to_amdgpu_dm_connector (connector); + +if (!aconnector->dc_sink) +return false; + +if (!aconnector->dc_sink->edid_caps.panel_patch.disable_second_tile) +return false; + +drm_edid_connector_update (connector, aconnector->drm_edid); + +if (!connector->has_tile) +return false; + +if (!connector->tile_h_loc && !connector->tile_v_loc) +return false; + +drm_dbg_kms (connector->dev, +"[CONNECTOR:%d:%s] hiding secondary Apple Studio Display tile from userspace\n" , + connector->base.id, connector->name); + +return true; +} +/** * amdgpu_dm_connector_detect() - Detect whether a DRM connector is connected to a display *
@@ -7889,6 +7922,9 @@ amdgpu_dm_connector_detect(struct drm_connector *connector, bool force) (!aconnector->dc_sink || aconnector->dc_sink->edid_caps.analog))return amdgpu_dm_connector_poll (aconnector, force); +if (amdgpu_dm_hide_secondary_tile_from_userspace (connector)) +return connector_status_disconnected; +return (aconnector->dc_sink ? connector_status_connected : connector_status_disconnected); }
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c +11 -0
@@ -134,6 +134,17 @@ static void apply_edid_quirks(struct dc_link *link, struct edid *edid,drm_dbg_driver (dev,"Skip PHY SSC reduction on panel id %X\n" , panel_id); link->wa_flags.skip_phy_ssc_reduction = true;break ; +/* +* Workaround for Apple Studio Display which exposes a 2x1 tiled panel +* over two SST DP links. Hide the secondary tile from userspace so +* compositors drive a single 5K stream on the primary link only. +*/ +case drm_edid_encode_panel_id ('A' ,'P' ,'P' ,0xAE3A ): +case drm_edid_encode_panel_id ('A' ,'P' ,'P' ,0xAE42 ): +case drm_edid_encode_panel_id ('A' ,'P' ,'P' ,0xAE46 ): +drm_dbg_driver (dev,"Hiding secondary tile on panel id %X\n" , panel_id); + edid_caps->panel_patch.disable_second_tile = true; +break ;default :return ; }
drivers/gpu/drm/amd/display/dc/dc_types.h +1 -0
@@ -187,6 +187,7 @@ struct dc_panel_patch {unsigned int skip_audio_sab_check;unsigned int mst_start_top_delay;unsigned int remove_sink_ext_caps; +bool disable_second_tile;unsigned int disable_colorimetry;uint8_t blankstream_before_otg_off;bool oled_optimize_display_on;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 12/713 drm/amd/display: Prune per-tile Timing from Apple Studio Display Primary Tile
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fangzhi Zuo <[email protected]>
[ Upstream commit 7a4dd08c3f921576c6a7524f60e4f0e4601835d2 ]
[why]
The Apple Studio Display primary tile advertises both the full 5120x2880 mode and the per-tile 2560x2880 timing. With the secondary tile already hidden from userspace, the stray 2560x2880 mode on the primary connector can still be picked by compositors, defeating the single 5K stream goal.
[how]
Prune the per-tile timing from the primary connector during get_modes:
when the sink carries the disable_second_tile quirk and the connector is the primary tile (tile_h_loc == 0 && tile_v_loc == 0), drop any probed mode matching the advertised tile size (tile_h_size x tile_v_size) so userspace only sees the full 5120x2880 mode.
Adjust for lack of movement from amdgpu_dm.c to amdgpu_dm_connector.c
--- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +43 -0
@@ -9116,6 +9116,47 @@ static void amdgpu_dm_connector_add_common_modes(struct drm_encoder *encoder, } } +/* +* The Apple Studio Display primary tile advertises both the full 5120x2880 +* mode and the per-tile 2560x2880 timing. As the secondary tile is hidden from +* userspace (see amdgpu_dm_hide_secondary_tile_from_userspace()), drop the +* per-tile timing from the primary connector so compositors only pick the full +* 5K mode. +*/ +static void amdgpu_dm_prune_primary_tile_modes (struct drm_connector *connector) +{ +struct amdgpu_dm_connector *aconnector =to_amdgpu_dm_connector (connector); +struct drm_display_mode *mode, *t; + +if (!aconnector->dc_sink) +return ; + +if (!aconnector->dc_sink->edid_caps.panel_patch.disable_second_tile) +return ; + +if (!connector->has_tile) +return ; + +/* Only prune the per-tile timing from the primary tile. */ +if (connector->tile_h_loc || connector->tile_v_loc) +return ; + +list_for_each_entry_safe (mode, t, &connector->probed_modes, head) { +if (mode->hdisplay != connector->tile_h_size || + mode->vdisplay != connector->tile_v_size) +continue ; + +drm_dbg_kms (connector->dev, +"[CONNECTOR:%d:%s] pruning per-tile %dx%d timing from primary Apple Studio Display tile\n" , + connector->base.id, connector->name, + mode->hdisplay, mode->vdisplay); + +list_del (&mode->head); +drm_mode_destroy (connector->dev, mode); + aconnector->num_modes--; + } +} +static void amdgpu_set_panel_orientation (struct drm_connector *connector) {struct drm_encoder *encoder;
@@ -9158,6 +9199,8 @@ static void amdgpu_dm_connector_ddc_get_modes(struct drm_connector *connector, amdgpu_dm_connector->num_modes =drm_edid_connector_add_modes (connector); +amdgpu_dm_prune_primary_tile_modes (connector); +/* sorting the probed modes before calling function * amdgpu_dm_get_native_mode() since EDID can have * more than one preferred mode. The modes that are
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 13/713 alpha: fix ieee_swcr_to_fpcr setting FPCR_DNOD unconditionally
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matt Turner <[email protected]>
commit 49672d026cc4773608e1222b69b29fd70f41336b upstream.
ieee_swcr_to_fpcr() converts the software IEEE trap-enable and status bits kept in thread_info.ieee_state into the hardware FPCR format. It contained:
fp |= (~sw & IEEE_TRAP_ENABLE_DNO) << 41;
FPCR_DNOD (bit 47) disables denormal operand traps: with it set the hardware handles a denormal operand itself, treating it as zero, instead of trapping for software completion. The intent was to set DNOD when the user has not asked for SIGFPE on denormal operands, but IEEE_TRAP_ENABLE_DNO is clear by default, so ieee_swcr_to_fpcr(0) always set DNOD.
Instructions built with the software completion suffix therefore never trapped on a denormal operand. The hardware silently substituted zero and produced wrong results, affecting every program compiled with -mieee and default FPU settings, glibc included.
Set FPCR_DNOD only when IEEE_MAP_DMZ is requested, which is exactly the case where flushing denormal inputs to zero is what the user asked for. DNOD then encodes MAP_DMZ, which ieee_fpcr_to_swcr() already recovers from FPCR_DNZ, so drop its attempt to recover IEEE_TRAP_ENABLE_DNO from DNOD; the DNO trap enable lives solely in ieee_state.
Both functions are in a uapi header, so the encoding change is visible to userspace, but nothing outside the kernel is known to depend on DNOD carrying the DNO trap enable, and the kernel is the only writer of the FPCR.
This must not be backported on its own. Re-enabling denormal operand traps exposes a second bug, fixed in the following patch: those traps usually find an exact result, and for an exact result the emulator did not write the FPCR back, leaving hardware-fabricated exception bits visible to user space. Taken alone this change would make spurious exception flags more common.
The bug predates the git history, so there is no commit to reference in a Fixes tag.
--- arch/alpha/include/uapi/asm/fpu.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
arch/alpha/include/uapi/asm/fpu.h +6 -2
@@ -101,7 +101,12 @@ ieee_swcr_to_fpcr(unsigned long sw) | IEEE_TRAP_ENABLE_OVF)) << 48; fp |= (~sw & (IEEE_TRAP_ENABLE_UNF |IEEE_TRAP_ENABLE_INE )) <<57 ; fp |= (sw &IEEE_MAP_UMZ ?FPCR_UNDZ |FPCR_UNFD :0 ); - fp |= (~sw &IEEE_TRAP_ENABLE_DNO ) <<41 ; +/* +* Disable denormal operand traps only when denormal inputs are to be +* flushed to zero. Otherwise they must keep trapping, so that /S +* instructions reach the kernel emulation handler. +*/ + fp |= (sw &IEEE_MAP_DMZ ?FPCR_DNOD :0 );return fp; }
@@ -116,7 +121,6 @@ ieee_fpcr_to_swcr(unsigned long fp) | IEEE_TRAP_ENABLE_OVF); sw |= (~fp >>57 ) & (IEEE_TRAP_ENABLE_UNF |IEEE_TRAP_ENABLE_INE ); sw |= (fp >>47 ) &IEEE_MAP_UMZ ; - sw |= (~fp >>41 ) &IEEE_TRAP_ENABLE_DNO ;return sw; }
Greg Kroah-Hartman
maintainerPATCH 14/713 iomap: dont free integrity payload that doesnt exist
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Hellwig <[email protected]>
commit 8a8685b32c0718cc7b2cb4d6202e5a5b8e0a8e2d upstream.
fs_bio_integrity_alloc might not allocate a bio integrity payload if PI verification is disabled on the block device. Check for that case before calling fs_bio_integrity_free in iomap_bio_read_folio_range_sync to avoid a NULL pointer dereferences.
Make the branch cover the PI verification as well - while fs_bio_integrity_verify works without an integrity payload, it requires one to actually do useful work.
--- fs/iomap/bio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/iomap/bio.c +1 -1
@@ -179,7 +179,7 @@ int iomap_bio_read_folio_range_sync(consif (srcmap->flags &IOMAP_F_INTEGRITY )fs_bio_integrity_alloc (&bio); error =submit_bio_wait (&bio); -if (srcmap->flags &IOMAP_F_INTEGRITY ) { +if (bio_integrity (&bio)) {if (!error) error =fs_bio_integrity_verify (&bio, sector, len);fs_bio_integrity_free (&bio);
Greg Kroah-Hartman
maintainerPATCH 15/713 rust: time: fix as_micros_ceil() rounding near i64::MAX
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: FUJITA Tomonori <[email protected]>
commit ec90dfcf05f02206c280bb59af660bbb3ae177d0 upstream.
The ceiling adjustment used saturating_add(NSEC_PER_USEC - 1) before dividing. Once the nanosecond value gets within NSEC_PER_USEC - 1 of i64::MAX the addition saturates to i64::MAX, which drops the ceiling bias and can yield a result one microsecond too small.
--- rust/kernel/time.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-)
rust/kernel/time.rs +10 -7
@@ -441,22 +441,25 @@ impl Delta {/// to the value in the [`Delta`]. #[inline] pub fn as_micros_ceil (self) ->i64 { +// Only positive values need to be rounded up: truncating division already +// rounds towards zero, i.e. up, for negative values. +// +// The usual `(nanos + d - 1) / d` is not used because the addition overflows +// once `nanos` exceeds `i64::MAX - (d - 1)`; saturating the addition instead +// would drop the rounding bias and return a result one unit too small. let n = self.as_nanos (); -let n =if n >=0 { - n.saturating_add (NSEC_PER_USEC -1 ) - }else { - n - }; + +let (n, add) =if n >0 { (n -1 ,1 ) }else { (n,0 ) };#[cfg( CONFIG_64BIT )] { - n /NSEC_PER_USEC + n /NSEC_PER_USEC + add }#[cfg(not( CONFIG_64BIT ))] // SAFETY: It is always safe to call `ktime_to_us()` with any value. unsafe { - bindings::ktime_to_us (n) + bindings::ktime_to_us (n) + add } }
Greg Kroah-Hartman
maintainerPATCH 16/713 alpha: dont leak hardware-fabricated FP exception bits to user space
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matt Turner <[email protected]>
commit bcfe3187412e342b4619efb92c945f073855ebc0 upstream.
On EV6 and later the hardware records exception status bits in the FPCR before delivering a software completion trap, and those bits can be wrong for the instruction that trapped. Converting a double that is exactly representable as a subnormal float sets FPCR_UNF even though the result is exact, and an underflow trap additionally sets FPCR_INE even when the emulated operation turns out to be exact.
alpha_fp_emul() only wrote the FPCR when soft-fp raised an exception, so whenever it determined that the instruction was exact the fabricated bits stayed in the FPCR and were reported to user space by fetestexcept().
Pass the exception summary register down from do_entArith() so the handler can tell which exceptions the hardware attributed to the trapping instruction, and always write the FPCR. Clear the exceptions that the trap reported but that soft-fp did not raise. EXC_SUM reports only the underflow or overflow when the hardware also set INE, so treat INE as a candidate in that case, and treat a trap with no reported exception as a denormal operand trap, for which the hardware can fabricate INE and UNF as well. Bits that software has already confirmed in ieee_state belong to this or an earlier instruction and are never cleared.
The imprecise path passes no summary. There the trap was taken somewhere in the trap shadow, so EXC_SUM is not attribution for the instruction being re-executed -- and only EV6, which traps precisely and so never takes that path, has fabricated bits to clear. For the same reason the clearing is guarded by implver(), matching swcr_update_status().
On an UP1500 (EV68) this takes the glibc math testsuite from 831 failures to 28, the remainder being unrelated to exception status.
This belongs with the preceding fix to ieee_swcr_to_fpcr(), and should not be backported without it -- nor it without this. That fix stops FPCR_DNOD being set unconditionally, so denormal operand traps start firing again. Those traps very often find an exact result, which is precisely the case where the old code left the FPCR unwritten and the fabricated bits visible. Applied alone it would make spurious exception flags more common, not less.
One case cannot be resolved here: an inexact instruction without the software completion suffix never traps, so its INE reaches the FPCR without being recorded anywhere else. Such a bit is indistinguishable from an INE the hardware fabricated for a trapping instruction, and is lost if an underflow or overflow trap with an exact result follows it. The FPCR is the only record of those instructions and it carries no attribution.
The bug predates the git history, so there is no commit to reference in a Fixes tag.
--- arch/alpha/kernel/traps.c | 6 +-- arch/alpha/math-emu/math.c | 88 +++++++++++++++++++++++++++++++++++++++------ 2 files changed, 80 insertions(+), 14 deletions(-)
arch/alpha/kernel/traps.c +3 -3
@@ -166,12 +166,12 @@ static long dummy_emul(void) { return 0;long (*alpha_fp_emul_imprecise)(struct pt_regs *regs,unsigned long writemask) = (void *)dummy_emul;EXPORT_SYMBOL_GPL (alpha_fp_emul_imprecise); -long (*alpha_fp_emul) (unsigned long pc) +long (*alpha_fp_emul) (unsigned long pc,unsigned long summary) = (void *)dummy_emul;EXPORT_SYMBOL_GPL (alpha_fp_emul);#else long alpha_fp_emul_imprecise (struct pt_regs *regs,unsigned long writemask); -long alpha_fp_emul (unsigned long pc); +long alpha_fp_emul (unsigned long pc,unsigned long summary);#endif asmlinkage void
@@ -185,7 +185,7 @@ do_entArith(unsigned long summary, unsigemulate the instruction. If the processor supports precise exceptions, we don't have to search. */ if (!amask (AMASK_PRECISE_TRAP )) - si_code =alpha_fp_emul (regs->pc -4 ); + si_code =alpha_fp_emul (regs->pc -4 , summary);else si_code =alpha_fp_emul_imprecise (regs, write_mask);if (si_code ==0 )
arch/alpha/math-emu/math.c +77 -11
125 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 17/713 clocksource/drivers/nxp-pit: Fix IRQ leak on cpuhp_setup_state error path
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: WenTao Liang <[email protected]>
commit 05520e035f8332c8e33f3011b5ca016fde61793d upstream.
When cpuhp_setup_state fails after pit_clockevent_per_cpu_init has successfully called request_irq, the error handling jumps directly to out_pit_clocksource_unregister without freeing the registered IRQ.
This leaks the IRQ line and, since kfree(pit) follows, leaves a dangling pointer registered as the interrupt handler's dev_id, potentially leading to a use-after-free if the IRQ fires afterwards.
Fix it by calling pit_clockevent_per_cpu_exit to properly release the IRQ before falling through to the existing cleanup chain.
--- drivers/clocksource/timer-nxp-pit.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/clocksource/timer-nxp-pit.c +3 -1
@@ -328,8 +328,10 @@ static int pit_timer_init(struct device_if (pit_instances == max_pit_instances) { ret =cpuhp_setup_state (CPUHP_AP_ONLINE_DYN ,"PIT timer:starting" , pit_clockevent_starting_cpu,NULL ); -if (ret <0 ) +if (ret <0 ) { +pit_clockevent_per_cpu_exit (pit, pit_instances); goto out_pit_clocksource_unregister; + } }return 0 ;
Greg Kroah-Hartman
maintainerPATCH 18/713 clocksource/drivers/timer-sun4i: Advertise a real minimum delta
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Yan <[email protected]>
commit d21808328225ab8cee46885bf9a0dffcefbe630e upstream.
sun4i_clkevt_next_event() compensates for the timer stop/start synchronization delay by programming evt - TIMER_SYNC_TICKS into the hardware interval register. The clockevent device currently advertises TIMER_SYNC_TICKS as min_delta_ticks, so the clockevents core is allowed to call set_next_event() with evt == TIMER_SYNC_TICKS.
That programs a zero-tick interval. With oneshot/highres/nohz timer operation this can leave the next event stuck, which was observed as a boot hang on Allwinner D1 after the clockevents core started reusing forced minimum-delta events.
Advertise one extra tick instead, so the smallest event accepted by the core still programs at least one hardware tick after the synchronization compensation.
--- drivers/clocksource/timer-sun4i.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clocksource/timer-sun4i.c +1 -1
@@ -208,7 +208,7 @@ static int __init sun4i_timer_init(strucsun4i_timer_clear_interrupt (timer_of_base (&to));clockevents_config_and_register (&to.clkevt,timer_of_rate (&to), -TIMER_SYNC_TICKS ,0xffffffff ); +TIMER_SYNC_TICKS +1 ,0xffffffff );/* Enable timer0 interrupt */ val =readl (timer_of_base (&to) +TIMER_IRQ_EN_REG );
Greg Kroah-Hartman
maintainerPATCH 19/713 fs: fix user path of nested backing files
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baokun Li <[email protected]>
commit f2381b546e7e6a35c9fcee0d0ccb6c042a9aeb5d upstream.
backing_file_open() derives the path to be stored in the new backing file from user_file->f_path. This is incorrect when user_file itself is a backing file, which is the case for nested stacking filesystems, e.g. overlayfs mounts where the lowerdir of one overlayfs is the merged directory of another. Since commit def3ae83da02 ("fs: store real path instead of fake path in backing file f_path") the f_path of a backing file holds the real path of the intermediate layer, not the path that the user opened.
Commit 924577e4f6ca ("ovl: Fix nested backing file paths") fixed this for such configurations by passing file_user_path() from ovl_open_realfile(). However, commit 6af36aeb147a ("lsm: add backing_file LSM hooks") changed the first argument of backing_file_open() from the user path back to the user file and derived the path from user_file->f_path again, silently re-introducing the problem.
As a result, files mapped through a nested overlayfs show the wrong path in /proc/<pid>/maps and in perf/ftrace mmap records. For example, with two nested overlayfs mounts:
mkdir -p /ovl/{lower,upper,work,merged} /ovl/nested echo hello > /ovl/lower/foo
mount -t overlay overlay \ -o lowerdir=/ovl/lower,upperdir=/ovl/upper,workdir=/ovl/work \ /ovl/merged # at least two lowerdirs are needed when upperdir is nonexistent mount -t overlay overlay \ -o lowerdir=/ovl/merged:/ovl/lower /ovl/nested
mapping /ovl/nested/foo shows a disconnected path instead of the user path:
# readlink /proc/self/fd/3 /ovl/nested/foo # grep foo /proc/self/maps 7f6e2c100000-7f6e2c101000 r--s 00000000 00:24 15813027 /foo
The bogus path is derived from the f_path of the intermediate backing file, whose mount is a private clone that d_path() cannot resolve.
Fix this by using file_user_path(), which returns the outermost user-visible path for backing files and falls back to &user_file->f_path for regular files. This restores the behavior of commit 924577e4f6ca ("ovl: Fix nested backing file paths") for overlayfs and also fixes the same problem for the other backing_file_open() callers, fuse passthrough and erofs ishare, when their user file is itself a backing file.
backing_tmpfile_open() has the same pattern but is not affected: it is only called by ovl_create_tmpfile() for the upper layer, and another overlayfs is rejected as upperdir by the DCACHE_OP_REAL check in ovl_mount_dir_check(), so its user_file can never be a backing file.
--- fs/backing-file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/backing-file.c +1 -1
@@ -35,7 +35,7 @@ struct file *backing_file_open(const strconst struct path *real_path, const struct cred *cred) { - const struct path *user_path = &user_file->f_path; + const struct path *user_path = file_user_path(user_file);struct file *f;int error;
Greg Kroah-Hartman
maintainerPATCH 20/713 ovl: fix double end_creating() on the casefold-mismatch path
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vivek Parikh <[email protected]>
commit 077ab8985ee278c3d8618182d335b0f0cd919e16 upstream.
ovl_create_real() releases the new dentry twice when the casefold consistency check fails. The S_IFDIR branch calls end_creating() and sets err, then falls through to the common out: label which calls end_creating() on the same dentry again:
case S_IFDIR:
newdentry = ovl_do_mkdir(ofs, dir, newdentry, attr->mode);
err = PTR_ERR_OR_ZERO(newdentry);
if (!err && ofs->casefold != ovl_dentry_casefolded(newdentry)) {
pr_warn_ratelimited(...);
end_creating(newdentry); /* first */
err = -EINVAL;
}
break;
...
if (err)
goto out;
...
out:
if (err) {
end_creating(newdentry); /* second, same dentry */
return ERR_PTR(err);
}end_creating() is end_dirop(), which does inode_unlock() on the parent and dput() on the dentry, so the parent directory's i_rwsem is unlocked twice and the dentry is put twice. The second unlock releases a lock that is not held, which is what wedges every later creation under that parent, and the second dput() drops a reference that was never taken.
The branch was added by commit dfc7da402ccc ("ovl: Check for casefold consistency when creating new dentries") as a bare dput(), which already released the reference twice; commit fe497f0759e0 ("VFS: change vfs_mkdir() to unlock on failure.") converted both sites to end_creating(), adding the double unlock.
This is reachable by an unprivileged user. The casefold consistency of the layers is validated at mount time in ovl_parse_layer(), and again on every lookup in ovl_lookup_single(), but ofs->workdir is the internal "work" subdirectory created inside the user-supplied workdir, and that subdirectory is not re-checked. Marking it casefolded after the mount therefore makes every ovl_create_temp() inherit the wrong state - and that path reaches ovl_create_real() through ovl_start_creating_temp(), which uses start_creating() with a generated name and so never runs the lookup-time check.
unshare -Urm
mount -t tmpfs -o casefold=utf8-12.1.0 tmpfs mnt
mkdir -p mnt/lower/d mnt/upper mnt/work mnt/merged
mount -t overlay ovl -o lowerdir=mnt/lower,\
upperdir=mnt/upper,workdir=mnt/work mnt/merged
chattr +F mnt/work/work
mkdir mnt/merged/d/sub # directory copy-upoverlayfs: wrong inherited casefold (work/#5)
and the next copy-up blocks forever on the parent's i_rwsem:
mkdir D start_creating+0x65/0xb0
ovl_start_creating_temp+0xb0/0xe0 [overlay]
ovl_create_temp+0xa3/0x1d0 [overlay]
ovl_copy_up_one+0x1f1c/0x21c0 [overlay]
ovl_copy_up_flags+0xf5/0x140 [overlay]
ovl_create_object+0xb7/0x220 [overlay]
ovl_mkdir+0x23/0x40 [overlay]Drop the end_creating() from the branch and let out: own the cleanup, which is what every other error path in this function already does.
--- fs/overlayfs/dir.c | 1 - 1 file changed, 1 deletion(-)
fs/overlayfs/dir.c +0 -1
@@ -188,7 +188,6 @@ struct dentry *ovl_create_real(struct ovif (!err && ofs->casefold !=ovl_dentry_casefolded (newdentry)) {pr_warn_ratelimited ("wrong inherited casefold (%pd2)\n" , newdentry); -end_creating (newdentry); err = -EINVAL ; }break ;
Greg Kroah-Hartman
maintainerPATCH 21/713 pidfd: hold exec_update_lock around namespace ioctl
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen Linxuan <[email protected]>
commit 9688a46802939da28f00cb40e8129615d5d4af39 upstream.
The PIDFD_GET_*_NAMESPACE ioctls in pidfd_ioctl() perform a filesystem credentials ptrace access check before handing out a namespace file descriptor. The accompanying comment states that the code "mirrors nsfs behavior", but, unlike the corresponding procfs paths, it does so without holding the target task's exec_update_lock.
proc_ns_get_link() and proc_ns_readlink() both take exec_update_lock for reading around the ptrace check and the namespace lookup, so that the credentials used for the access decision match those of the task when its namespace is read. Without it, a caller can pass the check against the target's old credentials and then read the namespace after the target has execve()'d a setuid binary and committed new credentials -- accessing namespace information it should have been denied.
Hold exec_update_lock for reading around the ptrace check and the namespace lookup so that pidfd truly mirrors nsfs behavior, as the comment already claims. open_namespace() itself runs outside the lock: once a namespace reference is obtained it carries its own refcount and is opened with the caller's own credentials, so a concurrent execve() on the target can no longer affect the outcome.
--- fs/pidfs.c | 43 +++++++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 12 deletions(-)
fs/pidfs.c +31 -12
@@ -532,6 +532,7 @@ static long pidfd_ioctl(struct file *fil struct task_struct *task __free(put_task) = NULL; struct nsproxy *nsp __free(put_nsproxy) = NULL;struct ns_common *ns_common =NULL ; +int error;if (!pidfs_ioctl_valid (cmd))return -ENOIOCTLCMD ;
@@ -555,20 +556,33 @@ static long pidfd_ioctl(struct file *filif (arg)return -EINVAL ; +/* +* We're trying to open a file descriptor to the namespace so perform a +* filesystem cred ptrace check. Hold @task's exec_update_lock for the +* duration of the ptrace check and the namespace lookup so that the +* credentials used for the access decision match those of @task at the +* time its namespace is read, preventing a concurrent execve() from +* swapping the task's credentials in between the check and the use. We +* mirror nsfs behavior. +*/ + error =down_read_killable (&task->signal->exec_update_lock); +if (error) +return error; + +if (!ptrace_may_access (task,PTRACE_MODE_READ_FSCREDS )) { + error = -EACCES ; + goto out_unlock; + } + scoped_guard(task_lock, task) { nsp = task->nsproxy;if (nsp)get_nsproxy (nsp); } -if (!nsp) -return -ESRCH ;/* just pretend it didn't exist */ - -/* -* We're trying to open a file descriptor to the namespace so perform a -* filesystem cred ptrace check. Also, we mirror nsfs behavior. -*/ -if (!ptrace_may_access (task,PTRACE_MODE_READ_FSCREDS )) -return -EACCES ; +if (!nsp) { + error = -ESRCH ;/* just pretend it didn't exist */ + goto out_unlock; + }switch (cmd) {/* Namespaces that hang of nsproxy. */
@@ -650,11 +664,16 @@ static long pidfd_ioctl(struct file *fil#endif break ;default : -return -ENOIOCTLCMD ; + error = -ENOIOCTLCMD ; } -if (!ns_common) -return -EOPNOTSUPP ; +if (!error && !ns_common) + error = -EOPNOTSUPP ; + +out_unlock: +up_read (&task->signal->exec_update_lock); +if (error) +return error;/* open_namespace() unconditionally consumes the reference */ return open_namespace (ns_common);
Greg Kroah-Hartman
maintainerPATCH 22/713 powerpc/pseries/iommu: switch to Default DMA window during kdump
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gaurav Batra <[email protected]>
commit 1304643a1c20badbb91b86a5084dd76cb7620c05 upstream.
In PowerPC (pseries) a non-virtualized adapter will have 2 DMA windows - 2GB default and a larger Dynamic DMA Window (DDW). DDW is large enough to map total RAM to a device.
During normal functioning of OS, since RAM is pre-mapped, 2GB default window is not used. The only scenario it might get used is when buffers in pmemory are mapped to the device for DMA.
As of today, during kdump, during early device discovery, pci_dma_find() finds that the device has 2 DMA windows. It selects to use DDW. This is a kdump path and DMA window is needed for IO to the device.
Although commit 09a3c1e46142 ("powerpc/pseries/iommu: IOMMU table is not initialized for kdump over SR-IOV") fixed an issue during kdump with SR-IOV case, but this also made the kdump prefer DDW over the default DMA window when both are present (dedicated adapter case). Since the DDW is fully mapped by the previous kernel, iommu_table_clear() can free only KDUMP_MIN_TCE_ENTRIES (2048) TCEs for use by kdump kernel.
This is not enough when the dump device is NVMe over Fibre Channel. Because nvme-fc driver DMA-maps the cmds and resp IUs of every pre-allocated request and each such mapping consumes roughly:
32 (IO queues, one per cpus = nr_cpus) *
64 (queue_depth, blk-mq kdump limit) *
2 (cmd+resp) = 4096
This is already double of what we have without counting admin queues and lpfc driver's own allocations / mapping requirement. Hence this results into iommu_alloc failures like -
lpfc 0153:70:00.0: iommu_alloc failed,
tbl 0000000034ebcf5e vaddr 00000000d814df0b npages 1 lpfc 0153:70:00.0: FCP Op failed - cmdiu dma mapping failed. lpfc 0153:70:00.0: iommu_alloc failed,
tbl 0000000034ebcf5e vaddr 000000009779e4d2 npages 1 lpfc 0153:70:00.0: FCP Op failed - cmdiu dma mapping failed.
iommu_map_phys+0x1c4/0x1f0 (unreliable) dma_iommu_map_phys+0x54/0xa0 dma_map_phys+0x3f8/0x590 __nvme_fc_init_request+0x110/0x300 [nvme_fc] nvme_fc_init_request+0x60/0xb8 [nvme_fc] blk_mq_alloc_map_and_rqs+0x388/0x510 blk_mq_alloc_tag_set+0x2a4/0x5f0 nvme_alloc_io_tag_set+0xe0/0x1e0 [nvme_core] nvme_fc_connect_ctrl_work+0x85c/0xdac [nvme_fc] process_one_work+0x1e4/0x5a0 worker_thread+0x1ec/0x3e0
Increasing the number of free TCE entries in iommu_table_clear() will increase the probability of hitting EEH since there could still be some active IOs from the previous life of the kernel.
Hence this patch partially reverts the previous fixes commit and switches the kdump's default back to 2GB default DMA window instead of DDW window. This window will mostly be empty. Or, could be slightly used if buffers in pmemory were mapped for IO.
--- arch/powerpc/platforms/pseries/iommu.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-)
arch/powerpc/platforms/pseries/iommu.c +12 -11
@@ -812,18 +812,11 @@ static struct device_node *pci_dma_find(/* parse DMA window property. During normal system boot, only default * DMA window is passed in OF. But, for kdump, a dedicated adapter might -* have both default and DDW in FDT. In this scenario, DDW takes precedence -* over default window. +* have both default and DDW in FDT. In this scenario, default window +* takes precedence over DDW. For a dedicated adapter, default window will +* potentially have more unused TCEs. */ -if (ddw_win) { -struct dynamic_dma_window_prop *p; - - p = (struct dynamic_dma_window_prop *)ddw_prop; - prop->liobn = p->liobn; - prop->dma_base = p->dma_base; - prop->tce_shift = p->tce_shift; - prop->window_shift = p->window_shift; - }else if (default_win) { +if (default_win) {unsigned long offset, size, liobn;of_parse_dma_window (rdn, default_prop, &liobn, &offset, &size);
@@ -832,6 +825,14 @@ static struct device_node *pci_dma_find( prop->dma_base =cpu_to_be64 (offset); prop->tce_shift =cpu_to_be32 (IOMMU_PAGE_SHIFT_4K ); prop->window_shift =cpu_to_be32 (order_base_2 (size)); + }else { +struct dynamic_dma_window_prop *p; + + p = (struct dynamic_dma_window_prop *)ddw_prop; + prop->liobn = p->liobn; + prop->dma_base = p->dma_base; + prop->tce_shift = p->tce_shift; + prop->window_shift = p->window_shift; }return rdn;
Greg Kroah-Hartman
maintainerPATCH 23/713 rust: fmt: fix {:p} printing stack addresses
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ke Sun <[email protected]>
commit fb7d645176189d2b068d69861e230fa5aceb4922 upstream.
The impl_fmt_adapter_forward! macro forwards Pointer for Adapter<T> by destructuring self into a local t, causing {:p} to print the address of that temporary stack variable rather than the actual pointer.
Remove Pointer from the macro and provide a manual impl for Adapter<&T> that passes self.0 directly.
--- rust/kernel/fmt.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
rust/kernel/fmt.rs +8 -1
@@ -43,7 +43,14 @@ use core::fmt::{ UpperExp, UpperHex, // }; -impl_fmt_adapter_forward! (Debug ,LowerHex ,UpperHex ,Octal ,Binary ,Pointer ,LowerExp ,UpperExp ); +impl_fmt_adapter_forward! (Debug ,LowerHex ,UpperHex ,Octal ,Binary ,LowerExp ,UpperExp ); + +impl <T : ?Sized +Pointer >Pointer for Adapter <&T > { +#[inline] +fn fmt (&self, f: &mut Formatter <'_>) ->Result { +Pointer ::fmt (self.0 , f) + } +}/// A copy of [`core::fmt::Display`] that allows us to implement it for foreign types. ///
Greg Kroah-Hartman
maintainerPATCH 24/713 timers/itimer: Zero-init old itimerval before copy to userspace
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jérémy Jean <[email protected]>
commit 18c7d85864e554adc8fad1e8d2e9d2cb6c3911c8 upstream.
On native sparc64, struct __kernel_old_timeval contains a four-byte hole after tv_usec because tv_sec is 64-bit while __kernel_suseconds_t is 32-bit. put_itimerval() fills only the named fields in a stack-allocated __kernel_old_itimerval and copies the entire object to userspace, so getitimer() can expose the two padding holes.
Zero-initialize the aggregate before assigning the fields so implicit padding is deterministic before it crosses the user/kernel boundary.
--- kernel/time/itimer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/time/itimer.c +1 -1
@@ -100,7 +100,7 @@ static int do_getitimer(int which, strucstatic int put_itimerval (struct __kernel_old_itimerval __user *o,const struct itimerspec64 *i) { -struct __kernel_old_itimerval v; +struct __kernel_old_itimerval v = {}; v.it_interval.tv_sec = i->it_interval.tv_sec; v.it_interval.tv_usec = i->it_interval.tv_nsec /NSEC_PER_USEC ;
Greg Kroah-Hartman
maintainerPATCH 25/713 objtool/rust: add one more `noreturn` Rust function for Rust 1.99.0
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miguel Ojeda <[email protected]>
commit 16861ca3508e0deac70d3bcacb6dcf435b49d9ef upstream.
Starting with Rust 1.99.0 (expected 2026-10-01), objtool may report:
rust/kernel.o: warning: objtool: _R..._6kernel3str9parse_intaNtNtB2_7private12FromStrRadix14from_str_radix() falls through to next function _R..._6kernel3str9parse_intaNtNtB2_7private12FromStrRadix16from_u64_negated()
due to calls to the noreturn symbol:
core::num::from_ascii_bytes_radix_panic
The function was renamed from from_ascii_radix_panic [1], which is already in the list.
Thus add the new one to the list so that objtool knows it is actually noreturn.
See commit 56d680dd23c3 ("objtool/rust: list noreturn Rust functions") for more details.
--- tools/objtool/check.c | 1 + 1 file changed, 1 insertion(+)
tools/objtool/check.c +1 -0
@@ -194,6 +194,7 @@ static bool is_rust_noreturn(const struc*/ return str_ends_with (func->name,"_4core3num20from_str_radix_panic" ) ||str_ends_with (func->name,"_4core3num22from_ascii_radix_panic" ) || +str_ends_with (func->name,"_4core3num28from_ascii_bytes_radix_panic" ) ||str_ends_with (func->name,"_4core5sliceSp15copy_from_slice17len_mismatch_fail" ) ||str_ends_with (func->name,"_4core6option13expect_failed" ) || str_ends_with(func->name, "_4core6option13unwrap_failed") ||
Greg Kroah-Hartman
maintainerPATCH 26/713 rust: kbuild: disambiguate `zerocopy` for `rusttest`
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Antoni Boucher <[email protected]>
commit fe39a233ea52601d416a1d02e7f70049aae47016 upstream.
Starting with Rust 1.76.0, zerocopy was added as an (indirect) compiler dependency [1]. In turn, this meant that the rustc-dev component started including a precompiled zerocopy crate in the sysroot.
This makes rusttest fail because the compiler finds several candidates:
error[E0464]: multiple candidates for `rmeta` dependency `zerocopy` found
--> rust/kernel/prelude.rs:64:9
|
64 | pub use zerocopy::{
| ^^^^^^^^
|
= note: candidate #1: .../lib/rustlib/x86_64-unknown-linux-gnu/lib/libzerocopy-dfef4cb07ca752aa.rmeta
= note: candidate #2: ./rust/test/libzerocopy.rlibWe cannot use --sysroot=/dev/null for these, thus point to the dependency explicitly.
[ Investigated when it started happening, reworded to add that and to
follow our usual style and sent on behalf of Antoni, who found this during his work to support Rust for Linux with the GCC backend, i.e. with rustc_codegen_gcc. - Miguel ]
--- rust/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
rust/Makefile +1 -1
@@ -350,7 +350,7 @@ rusttestlib-pin_init: $(src)/pin-init/src/lib.rs rusttestlib-macros \ rusttestlib-kernel: private rustc_target_flags = --extern ffi \ --extern build_error --extern macros --extern pin_init \ --extern bindings --extern uapi \ - --extern zerocopy --extern zerocopy_derive + --extern zerocopy=$(objtree)/$(obj)/test/libzerocopy.rlib --extern zerocopy_derive rusttestlib-kernel: $(src)/kernel/lib.rs rusttestlib-bindings rusttestlib-uapi \ rusttestlib-build_error rusttestlib-pin_init $(obj)/$(libmacros_name) \ $(obj)/bindings.o rusttestlib-zerocopy rusttestlib-zerocopy_derive FORCE
Signature · 1 line
2.55.0
Greg Kroah-Hartman
maintainerPATCH 27/713 rust: bug: skip arch-specific asm in `testlib` builds
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: FUJITA Tomonori <[email protected]>
commit 5d9668f3930609ead91f39b059ef4fe53db04942 upstream.
Running make rusttest with ARCH= set to an architecture other than the host's fails, e.g. ARCH=arm64 on an x86_64 host:
error: invalid instruction mnemonic 'brk'
--> rust/kernel/bug.rs:63:17
|
63 | / concat!(
64 | | "/* {size} */",
65 | | include!(concat!(env!("OBJTREE"), "/rust/kernel/generated_arch_warn_asm.rs")),
66 | | include!(concat!(env!("OBJTREE"), "/rust/kernel/generated_arch_reachable_asm.rs")));
| |_______________________________________________________________________________________________________^
|
note: instantiated into assembly here
--> <inline asm>:1:115
|
1 | /* 8 */.pushsection __bug_table,"aw"; .align 2; 14470: .long 14471f - .;.short 2305;.align 2; .popsection; 14471:brk 0x800
| ^^^The reason is that rusttest builds the kernel crate as a host
library: it passes the CONFIG_* cfgs of the configured architecture, but not --target, so code generation happens for the host. warn_flags! then selects the arch-specific inline asm arm based on CONFIG_*, and the host assembler rejects it.
This does not happen with the current master because warn_on! has no user inside the kernel crate itself yet, but it will as soon as one is added.
--- rust/kernel/bug.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
rust/kernel/bug.rs +5 -1
@@ -8,6 +8,7 @@#[macro_export] #[doc(hidden)] +#[cfg(not(testlib))] #[cfg(all( CONFIG_BUG , not( CONFIG_UML ), not( CONFIG_LOONGARCH ), not( CONFIG_ARM )))] #[cfg( CONFIG_DEBUG_BUGVERBOSE )] macro_rules! warn_flags {
@@ -47,6 +48,7 @@ macro_rules! warn_flags {#[macro_export] #[doc(hidden)] +#[cfg(not(testlib))] #[cfg(all( CONFIG_BUG , not( CONFIG_UML ), not( CONFIG_LOONGARCH ), not( CONFIG_ARM )))] #[cfg(not( CONFIG_DEBUG_BUGVERBOSE ))] macro_rules! warn_flags {
@@ -73,6 +75,7 @@ macro_rules! warn_flags {#[macro_export] #[doc(hidden)] +#[cfg(not(testlib))] #[cfg(all( CONFIG_BUG , CONFIG_UML ))] macro_rules! warn_flags { ($file:expr, $flags:expr) => {
@@ -91,6 +94,7 @@ macro_rules! warn_flags {#[macro_export] #[doc(hidden)] +#[cfg(not(testlib))] #[cfg(all( CONFIG_BUG , any( CONFIG_LOONGARCH , CONFIG_ARM )))] macro_rules! warn_flags { ($file:expr, $flags:expr) => {
@@ -101,7 +105,7 @@ macro_rules! warn_flags {#[macro_export] #[doc(hidden)] -#[cfg(not( CONFIG_BUG ))] +#[cfg(any(testlib, not( CONFIG_BUG )))] macro_rules! warn_flags { ($file:expr, $flags:expr) => {}; }
Greg Kroah-Hartman
maintainerPATCH 28/713 rust: bug: fix warn_on macro build error on UML
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: FUJITA Tomonori <[email protected]>
commit 30a449e04a32033d8e4844fdb4938a0ebccfa37b upstream.
Callers that go through kernel::prelude have CStrExt in scope, but code inside the kernel crate imports explicitly and may not. Using warn_on! from such a module fails to build on UML, which is the only configuration where warn_flags! needs a C string pointer rather than an inline asm bug entry:
error[E0599]: no method named as_char_ptr found for reference &ffi::CStr in the current scope
--> linux/rust/kernel/bug.rs:83:49
|
83 | $crate::c_str!(::core::file!()).as_char_ptr(),
| ^^^^^^^^^^^
|
::: linux/rust/kernel/time.rs:427:9
|
427 | warn_on!(self.nanos < 0);
| ------------------------ in this macro invocation
| = help: items from traits can only be used if the trait is in scope
= note: this error originates in the macro $crate::warn_flags which comes from the expansion of the macro warn_on (in Nightly builds, run with -Z mac)
help: trait CStrExt which provides as_char_ptr is implemented but not in scope; perhaps you want to import it
--> linux/rust/kernel/time.rs:27:1
|
27 + use crate::str::CStrExt;
Call the method through its fully qualified path, which resolves without any import at the expansion site.
--- rust/kernel/bug.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
rust/kernel/bug.rs +1 -1
@@ -83,7 +83,7 @@ macro_rules! warn_flags {// with a valid null-terminated string. unsafe { $crate::bindings::warn_slowpath_fmt ( - $crate::c_str!(::core::file!()).as_char_ptr (), + $crate::str::CStrExt ::as_char_ptr ($crate::c_str!(::core::file!())),line! ()as $crate::ffi::c_int , $flagsas $crate::ffi::c_uint , ::core::ptr::null(),
Greg Kroah-Hartman
maintainerPATCH 29/713 rust: bug: prevent dead_code warning from warn_on!s flags constant
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: FUJITA Tomonori <[email protected]>
commit e66cfc29e0d06fec34c06bb40d4d281f595677b1 upstream.
Fix the following dead_code warning on some configurations in an atomic development branch:
warning: constant WARN_ON_FLAGS is never used
--> linux/rust/kernel/bug.rs:126:19
|
126 | const WARN_ON_FLAGS: u32 = $crate::bug::bugflag_taint($crate::bindings::TAINT_WARN);
| ^^^^^^^^^^^^^
|
::: linux/rust/kernel/sync/srcu.rs:106:12
|
106 | if crate::warn_on!(
| ____________-
107 | | // SAFETY: By the type invariants, `self` contains a valid and pinned `struct srcu_struct`
108 | | // and `srcu_readers_active()` only checks the active reader count.
109 | | unsafe { bindings::srcu_readers_active(ptr) }
110 | | ) {
| |_________- in this macro invocation
| = note: #[warn(dead_code)] (part of #[warn(unused)]) on by default
= note: this warning originates in the macro crate::warn_on (in Nightly builds, run with -Z macro-backtrace for more info)
The warn_on! macro always defines a WARN_ON_FLAGS constant and hands it to warn_flags!. On configurations where warn_flags! does not reference its flags argument (the LOONGARCH/ARM variant, which only calls WARN_ON(), and the !CONFIG_BUG no-op variant), the constant is left unused and triggers a dead_code warning.
warn_flags! is the macro that accepts (and here discards) the flags argument, so make it responsible for the argument it drops.
Also rename _COND_STR to COND_STR and consume $file for consistency.
--- rust/kernel/bug.rs | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-)
rust/kernel/bug.rs +22 -4
@@ -55,6 +55,10 @@ macro_rules! warn_flags { ($file:expr, $flags:expr) => {const FLAGS :u32 = $crate::bindings::BUGFLAG_WARNING | $flags; +if false { + _ = $file; + } +// SAFETY: // - `flags` and `size` are all compile-time constants, preventing // any invalid memory access.
@@ -79,6 +83,10 @@ macro_rules! warn_flags {#[cfg(all( CONFIG_BUG , CONFIG_UML ))] macro_rules! warn_flags { ($file:expr, $flags:expr) => { +if false { + _ = $file; + } +// SAFETY: It is always safe to call `warn_slowpath_fmt()` // with a valid null-terminated string. unsafe {
@@ -98,6 +106,11 @@ macro_rules! warn_flags {#[cfg(all( CONFIG_BUG , any( CONFIG_LOONGARCH , CONFIG_ARM )))] macro_rules! warn_flags { ($file:expr, $flags:expr) => { +if false { + _ = $file; + _ = $flags; + } +// SAFETY: It is always safe to call `WARN_ON()`. unsafe { $crate::bindings::WARN_ON (true ) } };
@@ -107,7 +120,12 @@ macro_rules! warn_flags {#[doc(hidden)] #[cfg(any(testlib, not( CONFIG_BUG )))] macro_rules! warn_flags { - ($file:expr, $flags:expr) => {}; + ($file:expr, $flags:expr) => { +if false { + _ = $file; + _ = $flags; + } + }; }#[doc(hidden)]
@@ -122,14 +140,14 @@ macro_rules! warn_on {let cond = $cond;#[cfg( CONFIG_DEBUG_BUGVERBOSE_DETAILED )] -const _COND_STR: &str =concat! ("[" ,stringify! ($cond),"] " ,file! ()); +const COND_STR : &str =concat! ("[" ,stringify! ($cond),"] " ,file! ());#[cfg(not( CONFIG_DEBUG_BUGVERBOSE_DETAILED ))] -const _COND_STR: &str =file! (); +const COND_STR : &str =file! ();if cond {const WARN_ON_FLAGS :u32 = $crate::bug::bugflag_taint ($crate::bindings::TAINT_WARN ); - $crate::warn_flags!(_COND_STR,WARN_ON_FLAGS ); + $crate::warn_flags!(COND_STR ,WARN_ON_FLAGS ); } cond }};
Greg Kroah-Hartman
maintainerPATCH 30/713 rust: rust_is_available: warn for `bindgen` < 0.72.1 && libclang >= 22
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miguel Ojeda <[email protected]>
commit dc01dfb37b34beeefcfe1c3055364d41a4070c7e upstream.
Starting with LLVM 22, clang_getTypeDeclaration() may return a forward declaration instead of the type definition. This made bindgen generate opaque types [1][2], which in turn made us fail with e.g.
error[E0609]: no field `__bindgen_anon_1` on type `bindings::kernel_param`
--> rust/kernel/module_param.rs:78:46
|
78 | let container = unsafe { &*((*param).__bindgen_anon_1.arg.cast::<SetOnce<T>>()) };
| ^^^^^^^^^^^^^^^^ unknown field
|
= note: available field is: `_address`This was fixed in bindgen 0.72.1 [3].
In order to clarify what is going on and avoid confusion [4][5], add a warning to rust_is_available.sh about it when the versions match, similar to past warnings like the one removed in:
commit ae64324ad5c1 ("rust: rust_is_available: remove warning for `bindgen` < 0.69.5 && libclang >= 19.1")In addition, even if the versions match, check if the issue appears to not reproduce with the given binaries, to avoid a warning in such a case.
Finally, include tests.
[ Nathan, in parallel, updated the instructions of the LLVM+Rust
kernel.org toolchains [6] so that --version is not passed to cargo for bindgen, and thus the latest bindgen is installed by default, which should help to avoid some of these situations.
Thanks!
- Miguel ]
--- scripts/rust_is_available.sh | 14 +++++++++++ scripts/rust_is_available_bindgen_libclang_22.h | 5 ++++ scripts/rust_is_available_test.py | 30 +++++++++++++++++++++++- 3 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 scripts/rust_is_available_bindgen_libclang_22.h
scripts/rust_is_available.sh +14 -0
@@ -208,6 +208,20 @@ if [ "$bindgen_libclang_cversion" -lt "$ exit 1 fi +if [ "$bindgen_libclang_cversion" -ge 2200000 ] && + [ "$rust_bindings_generator_cversion" -lt 7201 ]; then + # Distributions may have patched the issue. + if ! "$BINDGEN" $(dirname $0)/rust_is_available_bindgen_libclang_22.h | grep -q 'pub foo'; then + echo >&2 "***" + echo >&2 "*** Rust bindings generator '$BINDGEN' < 0.72.1 together with libclang >= 22" + echo >&2 "*** may not work due to a bug (https://github.com/rust-lang/rust-bindgen/pull/3278)." + echo >&2 "*** Your bindgen version: $rust_bindings_generator_version" + echo >&2 "*** Your libclang version: $bindgen_libclang_version" + echo >&2 "***" + warning=1 + fi +fi + # If the C compiler is Clang, then we can also check whether its version # matches the `libclang` version used by the Rust bindings generator. #
scripts/rust_is_available_bindgen_libclang_22.h new file +5 -0
@@ -0,0 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +struct S ; +struct S { +int foo; +};
scripts/rust_is_available_test.py +29 -1
@@ -54,16 +54,23 @@ else: """) @classmethod - def generate_bindgen(cls, version_stdout, libclang_stderr): + def generate_bindgen(cls, version_stdout, libclang_stderr, libclang_22_patched=False): if libclang_stderr is None: libclang_case = f"raise SystemExit({cls.bindgen_default_bindgen_libclang_failure_exit_code})" else: libclang_case = f"print({repr(libclang_stderr)}, file=sys.stderr)" + if libclang_22_patched: + libclang_22_case = "print('pub foo: ::std::os::raw::c_int,')" + else: + libclang_22_case = "pass" + return cls.generate_executable(f"""#!/usr/bin/env python3 import sys if "rust_is_available_bindgen_libclang.h" in " ".join(sys.argv): {libclang_case} +elif "rust_is_available_bindgen_libclang_22.h" in " ".join(sys.argv): + {libclang_22_case} else: print({repr(version_stdout)}) """)
@@ -248,6 +255,27 @@ else: result = self.run_script(self.Expected.FAILURE, { "BINDGEN": bindgen }) self.assertIn(f"libclang (used by the Rust bindings generator '{bindgen}') is too old.", result.stderr) + def test_bindgen_bad_libclang_22(self): + for (bindgen_version, libclang_version, expected_not_patched) in ( + ("0.71.1", "21.1.0", self.Expected.SUCCESS), + ("0.71.1", "22.0.0", self.Expected.SUCCESS_WITH_WARNINGS), + ("0.71.1", "22.1.0", self.Expected.SUCCESS_WITH_WARNINGS), + + ("0.72.0", "22.0.0", self.Expected.SUCCESS_WITH_WARNINGS), + + ("0.72.1", "22.0.0", self.Expected.SUCCESS), + ): + with self.subTest(bindgen_version=bindgen_version, libclang_version=libclang_version): + cc = self.generate_clang(f"clang version {libclang_version}") + libclang_stderr = f"scripts/rust_is_available_bindgen_libclang.h:2:9: warning: clang version {libclang_version} [-W#pragma-messages], err: false" + bindgen = self.generate_bindgen(f"bindgen {bindgen_version}", libclang_stderr) + result = self.run_script(expected_not_patched, { "BINDGEN": bindgen, "CC": cc }) + if expected_not_patched == self.Expected.SUCCESS_WITH_WARNINGS: + self.assertIn(f"Rust bindings generator '{bindgen}' < 0.72.1 together with libclang >= 22", result.stderr) + + bindgen = self.generate_bindgen(f"bindgen {bindgen_version}", libclang_stderr, libclang_22_patched=True) + result = self.run_script(self.Expected.SUCCESS, { "BINDGEN": bindgen, "CC": cc }) + def test_clang_matches_bindgen_libclang_different_bindgen(self): bindgen = self.generate_bindgen_libclang("scripts/rust_is_available_bindgen_libclang.h:2:9: warning: clang version 999.0.0 [-W#pragma-messages], err: false") result = self.run_script(self.Expected.SUCCESS_WITH_WARNINGS, { "BINDGEN": bindgen })
Greg Kroah-Hartman
maintainerPATCH 31/713 rust: dma: return zero for Coherent reads past EOF
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Younes Akhouayri <[email protected]>
commit 5391b147d9fd8d4736e28c629cda00fd37c2304a upstream.
Coherent<T>::write_to_slice() calculates a zero-byte copy when the file offset is beyond the allocation, but still calls UserSliceWriter::write_dma(). The latter rejects offsets beyond the allocation even when the copy length is zero, so a debugfs read past EOF returns -ERANGE.
Return before calling write_dma() when the offset is at or beyond the allocation, matching simple_read_from_buffer() EOF semantics.
--- rust/kernel/dma.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
rust/kernel/dma.rs +5 -1
@@ -1005,7 +1005,11 @@ impl<T: KnownSize + AsBytes + ?Sized> dereturn Ok (0 ); }; -let count = self.size ().saturating_sub (offset_val).min (writer.len ()); +if offset_val >= self.size () { +return Ok (0 ); + } + +let count = (self.size () - offset_val).min (writer.len ()); writer.write_dma (self, offset_val, count)?;
Greg Kroah-Hartman
maintainerPATCH 32/713 rust: devres: fix race between concurrent revokers
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Danilo Krummrich <[email protected]>
commit acc516dfa1972d31836b50abc0115216cd0fccc5 upstream.
There is a potential race condition when two paths try to revoke a Devres concurrently.
The driver core's devres_release_all() calls Revocable::revoke() via the release callback, while Devres::drop() calls revoke_nosync() on another CPU.
The revoker that does not claim the is_available swap returns immediately, but the revoker that did may still be executing drop_in_place() on the inner data. This can cause a use-after-free when the other revoker's caller proceeds to drop adjacent resources that drop_in_place() still references (e.g., Devres<DmaMappedSgt> racing with SGTable freeing the backing sg_table and pages).
Fix this by adding a Completion. The release callback signals the Completion after revoke() finishes, and Devres::drop() waits for it when it loses the is_available swap. This ensures the wrapped object is fully torn down before Devres::drop() returns.
--- rust/kernel/devres.rs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)
rust/kernel/devres.rs +16 -2
@@ -21,7 +21,8 @@ use crate::{ sync::{ aref::ARef, rcu, - Arc, // + Arc, + Completion, // }, types::{ ForeignOwnable,
@@ -37,6 +38,8 @@ struct Inner<T> { node: Opaque<bindings::devres_node>,#[pin] data: Revocable<T>, +#[pin] + revocation: Completion, }/// This abstraction is meant to be used by subsystems to containerize [`Device`] bound resources to
@@ -53,6 +56,10 @@ struct Inner<T> {/// After the [`Devres`] has been unbound it is not possible to access the encapsulated resource /// anymore. /// +/// When a [`Devres`] is dropped, it is guaranteed that `T` has been fully dropped by the time +/// [`Devres::drop`] returns, even if a concurrent revocation through the release callback is in +/// progress. +/// /// [`Devres`] users should make sure to simply free the corresponding backing resource in `T`'s /// [`Drop`] implementation. ///
@@ -218,6 +225,7 @@ impl<T: Send + 'static> Devres<T> { }; }), data <- Revocable::new(data), + revocation <- Completion::new(), }), GFP_KERNEL, )?;
@@ -255,7 +263,9 @@ impl<T: Send + 'static> Devres<T> {// SAFETY: `inner` is a valid `Inner<T>` pointer. let inner =unsafe { &*inner }; - inner.data.revoke (); +if inner.data.revoke () { + inner.revocation.complete_all (); + } }#[allow(clippy::missing_safety_doc)]
@@ -362,6 +372,10 @@ impl<T: Send + 'static> Drop for Devres<// this additional reference count. drop (unsafe {Arc ::from_raw (Arc ::as_ptr (&self.inner)) }); } + }else { +// The release callback is concurrently revoking; wait for it to finish +// `drop_in_place()` of the wrapped object before returning. + self.inner.revocation.wait_for_completion (); } } }
Greg Kroah-Hartman
maintainerPATCH 33/713 rust: devres: ensure revocation is complete before device finishes unbinding
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Danilo Krummrich <[email protected]>
commit a10639966fd72fff8f7fbf3c8e733307daabd38f upstream.
Now that the revocation Completion is in place, also address the symmetric case. When Devres::drop() wins the is_available swap and the devres callback loses, the callback returns to devres_release_all() without waiting. This means device unbinding can complete while Devres::drop() is still executing drop_in_place() on another CPU, which is a problem if T's destructor accesses device state.
Make the synchronization bidirectional. Whichever side performs drop_in_place() signals the Completion, and the other side waits.
This does not reintroduce the nested Devres deadlock fixed by commit ba268514ea14 ("rust: devres: fix race condition due to nesting"), because that deadlock was caused by drop waiting for the release callback to return (the old 'devm' Completion). Here, both sides only wait for drop_in_place() to finish, which completes within the current call chain. The Arc<Inner<T>> keeps the Inner allocation alive independently.
--- rust/kernel/devres.rs | 7 +++++++ 1 file changed, 7 insertions(+)
rust/kernel/devres.rs +7 -0
@@ -265,6 +265,11 @@ impl<T: Send + 'static> Devres<T> {if inner.data.revoke () { inner.revocation.complete_all (); + }else { +// Devres::drop() is concurrently revoking; wait for it to finish `drop_in_place()` +// before returning to `devres_release_all()`, ensuring `T` is fully torn down before +// the device finishes unbinding. + inner.revocation.wait_for_completion (); } }
@@ -365,6 +370,8 @@ impl<T: Send + 'static> Drop for Devres<// SAFETY: When `drop` runs, it is guaranteed that nobody is accessing the revocable data // anymore, hence it is safe not to wait for the grace period to finish. if unsafe { self.data ().revoke_nosync () } { + self.inner.revocation.complete_all (); +// We revoked `self.data` before devres did, hence try to remove it. if self.remove_node () {// SAFETY: In `Self::new` we have taken an additional reference count of `self.data`
Greg Kroah-Hartman
maintainerPATCH 34/713 rust: kbuild: disambiguate `zerocopy_derive` for `rusttest`
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miguel Ojeda <[email protected]>
commit 1b0bab4a873f1034c27573cfc613394cff7e0a5b upstream.
The rustc-dev components for Rust 1.82.0 through 1.87.0 include a precompiled zerocopy_derive procedural macro in the sysroot. This range includes Rust 1.85.0, our minimum supported version.
This makes rusttest fail because the compiler finds both the sysroot copy and the copy built in rust/test:
error[E0464]: multiple candidates for `dylib` dependency `zerocopy_derive` found
--> rust/kernel/prelude.rs:70:9
|
70 | pub use zerocopy_derive::{
| ^^^^^^^^^^^^^^^
|
= note: candidate #1: .../lib/rustlib/x86_64-unknown-linux-gnu/lib/libzerocopy_derive-54d2b38896fa6bc5.so
= note: candidate #2: .../rust/test/libzerocopy_derive.soCommit fe39a233ea52 ("rust: kbuild: disambiguate zerocopy for rusttest") fixed the equivalent ambiguity for zerocopy.
Thus point to the dependency explicitly in this case too.
--- rust/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
rust/Makefile +2 -1
@@ -350,7 +350,8 @@ rusttestlib-pin_init: $(src)/pin-init/src/lib.rs rusttestlib-macros \ rusttestlib-kernel: private rustc_target_flags = --extern ffi \ --extern build_error --extern macros --extern pin_init \ --extern bindings --extern uapi \ - --extern zerocopy=$(objtree)/$(obj)/test/libzerocopy.rlib --extern zerocopy_derive + --extern zerocopy=$(objtree)/$(obj)/test/libzerocopy.rlib \ + --extern zerocopy_derive=$(objtree)/$(obj)/test/$(libzerocopy_derive_name) rusttestlib-kernel: $(src)/kernel/lib.rs rusttestlib-bindings rusttestlib-uapi \ rusttestlib-build_error rusttestlib-pin_init $(obj)/$(libmacros_name) \ $(obj)/bindings.o rusttestlib-zerocopy rusttestlib-zerocopy_derive FORCE
Signature · 1 line
2.55.0
Greg Kroah-Hartman
maintainerPATCH 35/713 rust: kernel: list: fix incorrect pop_back example comment
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikolai Grlica <[email protected]>
commit a5c7d35e2fd3e24c411816c91f8f6cc78e652e0c upstream.
The example uses pop_back(), but the accompanying comment says pop_front(). Update the comment to match the example.
--- rust/kernel/list.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
rust/kernel/list.rs +1 -1
@@ -249,7 +249,7 @@ pub use self::arc_field::{/// assert_eq!(list.iter().count(), 3); /// } /// -/// // Pop the items from the list using `pop_front()` and verify the content. +/// // Pop the items from the list using `pop_back()` and verify the content. /// { /// assert_eq!(list.pop_back().ok_or(EINVAL)?.value.foo(), ("a", 15)); /// assert_eq!(list.pop_back().ok_or(EINVAL)?.value.foo(), ("a", 32));
Greg Kroah-Hartman
maintainerPATCH 36/713 objtool/rust: add one more `noreturn` Rust function
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miguel Ojeda <[email protected]>
commit 993f235c4af49d0e912cc28abe6d733531600237 upstream.
When the pointer formatting series [1] is applied and KUnit tests are enabled, objtool would report an error with any of our supported Rust versions. For instance, with Rust 1.97.1:
rust/kernel.o: error: objtool: _R..._4core3fmt7Pointer3fmtB7_() falls through to next function _R..._4core7convert5AsRefNtB5_4BStrE6as_ref()
Or, with Rust 1.85.0:
rust/kernel.o: error: objtool: _R..._4core3fmt7Pointer3fmtB7_()
falls through to next function _R..._4core3ffi5c_str4CStrENtNtBS_3fmt7Display3fmtB7_()
This happens due to calls to the noreturn symbol:
core::str::slice_error_fail
Thus add the mangled one to the list so that objtool knows it is actually noreturn.
See commit 56d680dd23c3 ("objtool/rust: list noreturn Rust functions") for more details.
[ While the series [1] mentioned above was not applied in a way
that triggered this, Gary found another case [2]:
I am seeing this function causing issue on my 1.85.1 -Os build, although the error message is different this time:
rust/kernel.o: warning: objtool: _R..._5range9RangeFromjEE5indexCsldbe0TGTmNx_6kernel+0x1d:
stack state mismatch: cfa1=4+8 cfa2=4+16
Disassembly shows that the function call before the warning location is a call to _4core3str16slice_error_fail, and objtool thought it can return (which will end up with a unbalanced stack if it does return).
Thus apply it. - Miguel ]
--- tools/objtool/check.c | 1 + 1 file changed, 1 insertion(+)
tools/objtool/check.c +1 -0
@@ -195,6 +195,7 @@ static bool is_rust_noreturn(const strucreturn str_ends_with (func->name,"_4core3num20from_str_radix_panic" ) ||str_ends_with (func->name,"_4core3num22from_ascii_radix_panic" ) ||str_ends_with (func->name,"_4core3num28from_ascii_bytes_radix_panic" ) || +str_ends_with (func->name,"_4core3str16slice_error_fail" ) ||str_ends_with (func->name,"_4core5sliceSp15copy_from_slice17len_mismatch_fail" ) ||str_ends_with (func->name,"_4core6option13expect_failed" ) || str_ends_with(func->name, "_4core6option13unwrap_failed") ||
Greg Kroah-Hartman
maintainerPATCH 37/713 rust: num: restrict bool conversion to unsigned Bounded
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Younes Akhouayri <[email protected]>
commit 7dd6343fc127935425a81a8f1989907996c2868d upstream.
From<bool> turns true into 1. A signed Bounded with N = 1 can hold only -1 and 0. The current implementation can therefore create a value that breaks Bounded's invariant. Deref relies on that invariant and calls unreachable_unchecked() when it is broken, so safe Rust can reach undefined behavior.
The other primitive conversions require the source and destination to have the same signedness. Treat bool as an unsigned one-bit value and allow conversions between bool and Bounded only when the backing integer type is unsigned.
--- rust/kernel/num/bounded.rs | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-)
rust/kernel/num/bounded.rs +21 -9
@@ -13,7 +13,10 @@ use core::{ };use kernel::{ - num::Integer , + num::{ +Integer , +Unsigned ,// + }, prelude::*,// };
@@ -174,13 +177,16 @@ fn fits_within<T: Integer>(value: T, num/// // `u8` (regardless of the passed value). /// // let _ = Bounded::<u32, 6>::from(10u8); /// -/// // Booleans can be converted into single-bit `Bounded`s. +/// // Booleans can be converted into unsigned `Bounded`s. /// /// let v = Bounded::<u64, 1>::from(false); /// assert_eq!(v.get(), 0); /// /// let v = Bounded::<u64, 1>::from(true); /// assert_eq!(v.get(), 1); +/// +/// // This does not build because `i8` is signed. +/// // let _ = Bounded::<i8, 2>::from(true); /// ``` /// /// Infallible conversions from a [`Bounded`] to a primitive integer are also supported, and
@@ -203,12 +209,16 @@ fn fits_within<T: Integer>(value: T, num/// let _v = Bounded::<u32, 10>::new::<10>(); /// // assert_eq!(u8::from(_v), 10); /// -/// // Single-bit `Bounded`s can be converted into a boolean. +/// // Unsigned single-bit `Bounded`s can be converted into a boolean. /// let v = Bounded::<u8, 1>::new::<1>(); /// assert_eq!(bool::from(v), true); /// /// let v = Bounded::<u8, 1>::new::<0>(); /// assert_eq!(bool::from(v), false); +/// +/// // This does not build because `i8` is signed. +/// // let v = Bounded::<i8, 1>::new::<-1>(); +/// // let _ = bool::from(v); /// ``` /// /// Fallible conversions from any primitive integer to any [`Bounded`] are also supported using the
@@ -1077,31 +1087,33 @@ impl_into_primitive!( i8 i16 i32 i64 isize ); -// Single-bit `Bounded`s can be converted from/to a boolean. +// Unsigned single-bit `Bounded`s can be converted to a boolean. impl <T >From <Bounded <T ,1 >>for bool where -T :Integer +Zeroable , +T :Integer <Signedness =Unsigned > +Zeroable , {fn from (value:Bounded <T ,1 >) ->Self { value.get () !=Zeroable ::zeroed () } } +// Booleans can be converted to unsigned `Bounded`s. +impl <T ,const N :u32 >From <bool >for Bounded <T ,N >where -T :Integer +From <bool >, +T :Integer <Signedness =Unsigned > +From <bool >, {fn from (value:bool ) ->Self { -// SAFETY: A boolean can be represented using a single bit, and thus fits within any -// integer type for any `N` > 0. +// SAFETY: A boolean is represented by `0` or `1`, so it fits within any valid unsigned +// `Bounded` width. unsafe {Self ::__new (T ::from (value)) } } }impl <T >Bounded <T ,1 >where -T :Integer +Zeroable , +T :Integer <Signedness =Unsigned > +Zeroable , {/// Converts this [`Bounded`] into a [`bool`]. ///
Greg Kroah-Hartman
maintainerPATCH 38/713 rust: cfi: disable function merging if CFI is enabled
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gary Guo <[email protected]>
commit 29b03d1de967a177176d12811d970cac7882afcf upstream.
In Rust doc tests, there is a dummy __module_firmware_test_init function generated by the example in module_firmware!'s documentation, which just returns zero. Many other documentation examples generate functions that produce zero. LKP test robot reports [1] a Flags::zeroed instance; my local reproduction has a Bounded::new::<0>.
LLVM's MergeFunctionsPass incorrectly merges functions with different KCFI types, causing __module_firmware_test_init to be merged into one of the zero-returning functions. As module init is invoked via an indirect function call, KCFI is checked and this produces a KCFI failure.
I've reported this bug to upstream LLVM [2]; in the meantime, disable function merging if CFI is enabled. No separate treatment is needed for CONFIG_RUST_INLINE_HELPERS, as Clang does not enable function merging by default.
[ LLVM already has a pending PR:
https://github.com/llvm/llvm-project/pull/217665
which solves the issue. In addition, I asked upstream Rust if the unstable -Zmerge-functions=disabled flag will remain around:
https://rust-lang.zulipchat.com/#narrow/channel/425075-rust-for-linux/topic/.60-Zmerge-functions.3Ddisabled.60/
and it does indeed look like that will be the case. - Miguel ]
--- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
Makefile +2 -1
@@ -1118,7 +1118,8 @@ endif ifdef CONFIG_RUST # Always pass -Zsanitizer-cfi-normalize-integers as CONFIG_RUST selects # CONFIG_CFI_ICALL_NORMALIZE_INTEGERS. - RUSTC_FLAGS_CFI := -Zsanitizer=kcfi -Zsanitizer-cfi-normalize-integers + # Disable function merging as LLVM incorrectly merges functions with different KCFI types. + RUSTC_FLAGS_CFI := -Zsanitizer=kcfi -Zsanitizer-cfi-normalize-integers -Zmerge-functions=disabled KBUILD_RUSTFLAGS += $(RUSTC_FLAGS_CFI) export RUSTC_FLAGS_CFI endif
Greg Kroah-Hartman
maintainerPATCH 39/713 kbuild: rust: preserve unreachable traps with inline helpers
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miguel Ojeda <[email protected]>
commit 0bff7711c19ba05ff3b686554c5a2d503c3e9797 upstream.
When CONFIG_RUST_INLINE_HELPERS is enabled, it is possible to hit objtool warnings like:
vmlinux.o: warning: objtool: _R..._4cmdq12CommandToGsp4init() falls through to next function _R..._4core5array4iter8IntoIterRShKj3_EEEBa_()
rustc normally emits traps for unreachable paths. However, under CONFIG_RUST_INLINE_HELPERS=y, rustc emits LLVM bitcode and Clang performs final code generation after the helper bitcode is linked, but Clang does not trap unreachable IR by default.
In turn, this means objtool follows compiler-generated impossible Rust enum paths through alignment padding into the next function, resulting in fallthrough warnings.
Thus pass the LLVM trap-unreachable option to the final Clang invocation and suppress traps immediately after noreturn calls, which objtool already recognizes as dead ends. The combination of both flags makes it match rustc's behavior.
Rust 1.85.0 (the minimum supported one) supports LLVM >= 18, and both flags are available in LLVM 18.
--- Makefile | 10 ++++++++++ rust/Makefile | 3 ++- scripts/Makefile.build | 3 ++- 3 files changed, 14 insertions(+), 2 deletions(-)
Makefile +10 -0
@@ -1083,6 +1083,16 @@ endif export CC_FLAGS_SCS endif +ifdef CONFIG_RUST_INLINE_HELPERS +# `rustc` normally emits traps for unreachable paths during code generation. +# With inline helpers, Clang performs code generation from the linked bitcode +# instead, so request the same behavior explicitly. Otherwise `objtool` may +# follow an impossible Rust path into the next function. +CC_FLAGS_RUST_INLINE_HELPERS := -mllvm -trap-unreachable \ + -mllvm -no-trap-after-noreturn +export CC_FLAGS_RUST_INLINE_HELPERS +endif + ifdef CONFIG_LTO_CLANG ifdef CONFIG_LTO_CLANG_FULL CC_FLAGS_LTO := -flto
rust/Makefile +2 -1
@@ -645,7 +645,8 @@ quiet_cmd_rustc_library = $(if $(skip_cl -Zunstable-options \ $(if $(link_helper),;$(LLVM_LINK) --internalize --suppress-warnings $(patsubst %.o,%.bc,$@) \ $(obj)/helpers/helpers$(if $(part-of-module),_module).bc -o $(patsubst %.o,%.m.bc,$@); \ - $(CC) $(CLANG_FLAGS) $(KBUILD_CFLAGS) -Wno-override-module -c $(patsubst %.o,%.m.bc,$@) -o $@ \ + $(CC) $(CLANG_FLAGS) $(KBUILD_CFLAGS) \ + $(CC_FLAGS_RUST_INLINE_HELPERS) -Wno-override-module -c $(patsubst %.o,%.m.bc,$@) -o $@ \ $(cmd_ld_single)) \ $(if $(rustc_objcopy),;$(OBJCOPY) $(rustc_objcopy) $@) \ $(cmd_objtool)
scripts/Makefile.build +2 -1
@@ -346,7 +346,8 @@ quiet_cmd_rustc_o_rs = $(RUSTC_OR_CLIPPY cmd_rustc_o_rs = $(rust_common_cmd) --emit=$(if $(CONFIG_RUST_INLINE_HELPERS),llvm-bc=$(patsubst %.o,%.bc,$@),obj=$@) $< \ $(if $(CONFIG_RUST_INLINE_HELPERS),;$(LLVM_LINK) --internalize --suppress-warnings $(patsubst %.o,%.bc,$@) \ $(objtree)/rust/helpers/helpers$(if $(part-of-module),_module).bc -o $(patsubst %.o,%.m.bc,$@); \ - $(CC) $(CLANG_FLAGS) $(KBUILD_CFLAGS) -Wno-override-module -c $(patsubst %.o,%.m.bc,$@) -o $@ \ + $(CC) $(CLANG_FLAGS) $(KBUILD_CFLAGS) \ + $(CC_FLAGS_RUST_INLINE_HELPERS) -Wno-override-module -c $(patsubst %.o,%.m.bc,$@) -o $@ \ $(cmd_ld_single)) \ $(cmd_objtool)
Greg Kroah-Hartman
maintainerPATCH 40/713 kbuild: rust: keep Rust objects out of Clang LTO with inline helpers
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miguel Ojeda <[email protected]>
commit 5febf432df1cfa5b25d99b54c32103fafbdd0eb9 upstream.
Under CONFIG_LTO_CLANG + CONFIG_RUST_INLINE_HELPERS, one may hit objtool errors such as:
vmlinux.o: error: objtool: _R..._3Gsp4boot+0xd6a:
can't find jump dest instruction at .text._R..._3Gsp4boot+0x1dfdThe reason is that in such builds, the Clang invocation that compiles the combined Rust plus helpers bitcode emits LLVM bitcode (again) -- the final code generation happens in the linker's LTO step, which the -mllvm trap options passed to Clang do not reach.
This, in turn, means that unreachable traps are missing, and the impossible paths do not merely fallthrough to the next symbol, but past the end of their own section, since LTO builds place each function in its own section.
Thus filter CC_FLAGS_LTO out of the Clang invocation, so that it always emits machine code directly, with the traps in place.
--- rust/Makefile | 2 +- scripts/Makefile.build | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
rust/Makefile +1 -1
@@ -645,7 +645,7 @@ quiet_cmd_rustc_library = $(if $(skip_cl -Zunstable-options \ $(if $(link_helper),;$(LLVM_LINK) --internalize --suppress-warnings $(patsubst %.o,%.bc,$@) \ $(obj)/helpers/helpers$(if $(part-of-module),_module).bc -o $(patsubst %.o,%.m.bc,$@); \ - $(CC) $(CLANG_FLAGS) $(KBUILD_CFLAGS) \ + $(CC) $(CLANG_FLAGS) $(filter-out $(CC_FLAGS_LTO),$(KBUILD_CFLAGS)) \ $(CC_FLAGS_RUST_INLINE_HELPERS) -Wno-override-module -c $(patsubst %.o,%.m.bc,$@) -o $@ \ $(cmd_ld_single)) \ $(if $(rustc_objcopy),;$(OBJCOPY) $(rustc_objcopy) $@) \
scripts/Makefile.build +1 -1
@@ -346,7 +346,7 @@ quiet_cmd_rustc_o_rs = $(RUSTC_OR_CLIPPY cmd_rustc_o_rs = $(rust_common_cmd) --emit=$(if $(CONFIG_RUST_INLINE_HELPERS),llvm-bc=$(patsubst %.o,%.bc,$@),obj=$@) $< \ $(if $(CONFIG_RUST_INLINE_HELPERS),;$(LLVM_LINK) --internalize --suppress-warnings $(patsubst %.o,%.bc,$@) \ $(objtree)/rust/helpers/helpers$(if $(part-of-module),_module).bc -o $(patsubst %.o,%.m.bc,$@); \ - $(CC) $(CLANG_FLAGS) $(KBUILD_CFLAGS) \ + $(CC) $(CLANG_FLAGS) $(filter-out $(CC_FLAGS_LTO),$(KBUILD_CFLAGS)) \ $(CC_FLAGS_RUST_INLINE_HELPERS) -Wno-override-module -c $(patsubst %.o,%.m.bc,$@) -o $@ \ $(cmd_ld_single)) \ $(cmd_objtool)
Greg Kroah-Hartman
maintainerPATCH 41/713 KEYS: trusted: Fix TPM teardown ordering
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chengfeng Ye <[email protected]>
commit 5e2d672280d97d83de43031d93761b12dadd7b8a upstream.
trusted_tpm_exit() drops the TPM chip reference and frees the digest array before unregistering the trusted key type. key_type_lookup() holds key_types_sem for reading until the key operation finishes, while unregister_key_type() takes it for writing. It therefore provides the synchronization point that must precede backend teardown.
The current order permits this interleaving:
CPU 0 CPU 1
trusted_tpm_exit() key_type_lookup("trusted")
put_device(&chip->dev) trusted_tpm_seal()
kfree(digests) pcrlock()
unregister_key_type() tpm_pcr_extend(..., digests)
CPU 1 can consequently dereference the freed digest array. The chip can also be released before callbacks stop using it.
KASAN reported:
BUG: KASAN: slab-use-after-free in tpm_pcr_extend+0x1f0/0x200
Read of size 2 at addr ffff88810872d000 by task poc/89
Call Trace:
tpm_pcr_extend+0x1f0/0x200
pcrlock+0x42/0x70 [trusted]
trusted_tpm_seal+0x1b6/0x570 [trusted]
trusted_instantiate+0x293/0x340 [trusted]
__key_instantiate_and_link+0xb2/0x2b0
__key_create_or_update+0x61e/0xb50
__do_sys_add_key+0x1b8/0x310
Allocated by task 88:
__kmalloc_noprof+0x1a7/0x490
do_one_initcall+0xa1/0x390
do_init_module+0x2df/0x840
Freed by task 90:
kfree+0x131/0x3c0
trusted_tpm_exit+0x59/0xa0 [trusted]
__do_sys_delete_module+0x346/0x510Move unregister_key_type() before releasing either resource. This stops new lookups and waits for in-flight key operations to finish before the backend state is destroyed.
--- security/keys/trusted-keys/trusted_tpm1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
security/keys/trusted-keys/trusted_tpm1.c +1 -1
@@ -987,9 +987,9 @@ err_put:static void trusted_tpm_exit (void ) {if (chip) { +unregister_key_type (&key_type_trusted);put_device (&chip->dev);kfree (digests); -unregister_key_type (&key_type_trusted); } }
Greg Kroah-Hartman
maintainerPATCH 42/713 apparmor: fix cred UAF caused by begin_current_label_crit_section()
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jann Horn <[email protected]>
commit 3f4ae5fab613dca01d6a2a8210dd832e009fcf47 upstream.
AppArmor's begin_current_label_crit_section() is a scary function called from lots of LSM hooks (in particular VFS/socket-related ones) that checks if the label referenced by the current creds is marked FLAG_STALE, and if so, attempts to use aa_replace_current_label() to replace the creds with an updated version that uses a new label.
The first problem with this is that it would directly lead to UAF of struct cred if anything in the kernel takes a pointer to the current creds and accesses these past a security hook invocation that replaces creds, like so:
``` const struct cred *cred = current_cred(); alloc_file_pseudo(...); uid_t uid = cred->euid; ```
I don't know if anything in the kernel actually does this, but I think it is very surprising that this pattern could lead to UAF.
The second problem is that things go wrong when aa_replace_current_label() runs with overridden credentials. aa_replace_current_label() bails out if current_cred() != current_real_cred() (mirroring the check in proc_pid_attr_write()), but this check can't actually reliably detect overridden credentials because the overridden creds can be the same as the objective creds.
So in approximately the following scenario, things go wrong:
1. task begins with <creds A> (as both objective and subjective creds), with refcount=2
2. task grabs an extra reference on <creds A> for overriding
3. task calls override_creds(<creds A>), which returns a pointer to the old subjective creds (<creds A>)
4. task enters AppArmor LSM hook
5. AppArmor checks that objective/subjective creds are equal
6. AppArmor replaces both cred pointers with <creds B> and drops 2 refs on <creds A>
7. task leaves AppArmor LSM hook
8. task calls revert_creds(<creds A>)
9. now task->cred is <creds A> while task->real_cred is <creds B>, but the task_struct logically holds two references to <creds B>
10. another task drops the extra reference on <creds A> that was used for overriding, refcount drops to 0
11. now task->real_cred points to freed creds
At this point, any access to current_cred() will be UAF.
I have a test case where I run aa-disable on a profile while a process using that profile is blocked on splice() from a FUSE passthrough file into a full pipe; after the profile update, the pipe becomes empty, splice() resumes, the credentials go out of sync, and a subsequent getuid() syscall results in a KASAN UAF splat.
To fix this, instead of directly replacing creds, do it via task_work that will run at the end of the current syscall. (The point in time at which the cred replacement happens should have no correctness impact; it is just a performance optimization to avoid unnecessarily touching the refcount of the new label.)
Note that AppArmor still performs direct cred replacements in the sb_pivotroot LSM hook after this change, and that direct cred replacements can still happen in VFS ->write() callbacks via proc_pid_attr_write().
There are two options for what to do with aa_dup_task_ctx(): Either explicitly reset new->label_replacement_pending after the entire aa_task_ctx has been copied, or switch to manually copying members over. I am switching to manually copying members over because that should make bugs more obvious.
--- security/apparmor/include/cred.h | 6 +----- security/apparmor/include/task.h | 15 +++++++++++---- security/apparmor/task.c | 27 +++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 9 deletions(-)
security/apparmor/include/cred.h +1 -5
@@ -222,13 +222,9 @@ static inline struct aa_label *begin_cur {struct aa_label *label =aa_current_raw_label (); -might_sleep (); -if (label_is_stale (label)) { label =aa_get_newest_label (label); -if (aa_replace_current_label (label) ==0 ) -/* task cred will keep the reference */ -aa_put_label (label); +aa_schedule_stale_label_replacement (); }return label;
security/apparmor/include/task.h +11 -4
@@ -21,15 +21,22 @@ static inline struct aa_task_ctx *task_c* @onexec: profile to transition to on next exec (MAY BE NULL) * @previous: profile the task may return to (MAY BE NULL) * @token: magic value the task must know for returning to @previous_profile +* @label_replacement_tw: for aa_schedule_stale_label_replacement() +* @label_replacement_pending: is @label_replacement_tw pending? +* +* When changing this, check if aa_dup_task_ctx() needs to be updated. */ struct aa_task_ctx {struct aa_label *nnp;struct aa_label *onexec;struct aa_label *previous;u64 token; +struct callback_head label_replacement_tw; +bool label_replacement_pending; };int aa_replace_current_label (struct aa_label *label); +void aa_schedule_stale_label_replacement (void );void aa_set_current_onexec (struct aa_label *label,bool stack);int aa_set_current_hat (struct aa_label *label,u64 token);int aa_restore_previous_label (u64 cookie);
@@ -56,10 +63,10 @@ static inline void aa_free_task_ctx(strustatic inline void aa_dup_task_ctx (struct aa_task_ctx *new,const struct aa_task_ctx *old) { - *new = *old; -aa_get_label (new->nnp); -aa_get_label (new->previous); -aa_get_label (new->onexec); + new->nnp =aa_get_label (old->nnp); + new->onexec =aa_get_label (old->onexec); + new->previous =aa_get_label (old->previous); + new->token = old->token; }/**
security/apparmor/task.c +27 -0
@@ -14,6 +14,7 @@#include <linux/gfp.h> #include <linux/ptrace.h> +#include <linux/task_work.h> #include "include/path.h" #include "include/audit.h"
@@ -89,6 +90,32 @@ int aa_replace_current_label(struct aa_lreturn 0 ; } +static void aa_replace_stale_label_tw_func (struct callback_head *tw) +{ +struct aa_task_ctx *ctx =task_ctx (current); +struct aa_label *label; + + ctx->label_replacement_pending = false; + label =aa_current_raw_label (); +if (!label_is_stale (label)) +return ; + label =aa_get_newest_label (label); +aa_replace_current_label (label); +aa_put_label (label); +} + +/* replace the current task's stale label on syscall return */ +void aa_schedule_stale_label_replacement (void ) +{ +struct aa_task_ctx *ctx =task_ctx (current); + +if (ctx->label_replacement_pending) +return ; +init_task_work (&ctx->label_replacement_tw, aa_replace_stale_label_tw_func); +if (task_work_add (current, &ctx->label_replacement_tw,TWA_RESUME ) ==0 ) + ctx->label_replacement_pending = true; +} +/** * aa_set_current_onexec - set the tasks change_profile to happen onexec
Greg Kroah-Hartman
maintainerPATCH 43/713 apparmor: fix out-of-bounds write when null terminating a label vec
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hyunwoo Kim <[email protected]>
commit 9f1e40193eef7f047e6b77cfb4b4cafdecd7a123 upstream.
aa_vec_unique() null terminates at vec[n - dups] when VEC_FLAG_TERMINATE is passed. If the components are all distinct no duplicates are dropped, dups is 0 and the terminator goes to vec[n], so the caller has to provide room for n + 1 entries.
aa_label_strn_parse() sets up its vector with vec_setup(profile, vec, len, gfp) and then calls aa_vec_unique(vec, len, VEC_FLAG_TERMINATE), but vec_setup() does not reserve the terminator entry. Up to LOCAL_VEC_ENTRIES it uses the local array of LOCAL_VEC_ENTRIES pointers, above that it allocates exactly len pointers. The terminator therefore lands one entry past the end of the local array when len is LOCAL_VEC_ENTRIES, and one entry past the end of the allocation when len is larger.
len comes from the number of "//&" separated components in the label name and label_count_strn_entries() does not bound it. An unprivileged task reaches the parse by writing to /proc/self/attr/apparmor/current or through lsm_set_self_attr(2), both of which go through do_setattr(), and the name is parsed before the change_profile permission is checked.
The query_label() path behind the securityfs .access file, which is mode 0666, performs no permission check at all. Every component has to resolve to a loaded profile, so a system with policy loaded is required.
The other two VEC_FLAG_TERMINATE users work on a label vec that aa_label_alloc() has already sized with "+ 1 for null terminator entry on vec". Reserve the same entry in vec_setup() and DEFINE_VEC(). Passing len + 1 from the caller instead would move len == LOCAL_VEC_ENTRIES out of the local array and into kzalloc().
--- security/apparmor/include/label.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
security/apparmor/include/label.h +3 -3
@@ -23,7 +23,7 @@ struct aa_ruleset;#define LOCAL_VEC_ENTRIES 8#define DEFINE_VEC (T ,V ) \ - struct aa_ ## T *(_ ## V ## _localtmp)[LOCAL_VEC_ENTRIES]; \ + struct aa_ ## T *(_ ## V ## _localtmp)[LOCAL_VEC_ENTRIES + 1]; \ struct aa_ ## T **(V)#define vec_setup (T ,V ,N ,GFP ) \
@@ -31,10 +31,10 @@ struct aa_ruleset;if ((N ) <=LOCAL_VEC_ENTRIES ) { \typeof (N) i; \ (V) = (_ ## V ## _localtmp); \ - for (i = 0; i < (N); i++) \ + for (i = 0; i <= (N); i++) \ (V)[i] = NULL; \ } else \ - (V) = kzalloc(sizeof(struct aa_ ## T *) * (N), (GFP)); \ + (V) = kzalloc_objs(struct aa_ ## T *, (N) + 1, (GFP)); \ (V) ? 0 : -ENOMEM; \ })
Greg Kroah-Hartman
maintainerPATCH 44/713 include/linux/list.h: mark list_add and __list_add as __always_inline
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jordan R Abrahams-Whitehead <[email protected]>
commit 2780860eddecba9ffe210bb9436eee3cf22bfcdd upstream.
This commit resolves an issue where modpost section verification fails due to section mismatches between list_add and its callers.
At present, list_add (and its internal __list_add) are called from both .text and .init code sections. Since inlining can vary per call site, list_add can be 4 different states:
list_add in text with arguments to non-.init.data values list_add in init with arguments to static .init.data values list_add in init with arguments to non-.init.data values list_add in text with arguments to static .init.data values
It is last instance that ends up causing the section mismatch caused by constant propagation of the address of static libs inside the dir_add as seen below (with the dir_list being defined statically in initramfs.c, resting in .init.data).
WARNING: modpost: vmlinux.o: section mismatch in reference: __list_add (section: .text.unlikely.) -> dir_list (section: .init.data)
Because of these section matching requirements, semantically, __list_add and list_add MUST be inlined. This will then ensure callers inside .init will receive a list_add that exists and refers to only .init data, and list_add code in .text sections will only refer to non-init data.
This issue manifests predominently in AutoFDO with clang, which is very hesitant to inline cold functions such as list_add even when marked inline. Marking them as __always_inline therefore matches the existing semantic constraints imposed by modpost's section mismatch checks.
--- include/linux/list.h | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
include/linux/list.h +11 -4
@@ -150,10 +150,13 @@ static inline bool __list_del_entry_vali* * This is only for internal list manipulation where we know * the prev/next entries already! +* +* Must be inlined to ensure it can be safely called +* with initdata arguments. */ -static inline void __list_add (struct list_head *new, -struct list_head *prev, -struct list_head *next) +static __always_inline void __list_add(struct list_head *new, +struct list_head *prev, +struct list_head *next) {if (!__list_add_valid (new, prev, next))return ;
@@ -171,8 +174,12 @@ static inline void __list_add(struct lis* * Insert a new entry after the specified head. * This is good for implementing stacks. +* +* Must be inlined to ensure it can be safely called +* with initdata arguments. */ -static inline void list_add (struct list_head *new,struct list_head *head) +static __always_inline void list_add(struct list_head *new, +struct list_head *head) {__list_add (new, head, head->next); }
Greg Kroah-Hartman
maintainerPATCH 45/713 mm, swap: dont free a hibernation slot that is in the swap cache
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Youngjun Park <[email protected]>
commit 10d9012e83efedde8718ceaa5053f836e0c8596c upstream.
A slot with a folio in the swap cache is freed when the folio leaves the cache, not when its count drops. swap_put_entries_cluster() follows that rule. swap_free_hibernation_slot() does not, it calls __swap_cluster_free_entries() whether or not a folio sits on the slot.
Cluster readahead can put one there. It walks a raw page_cluster sized window of offsets around the faulting entry, and a hibernation slot passes __swap_cache_add_check() because it is not a folio and its count is not zero. Freeing the slot then clears the entry under that folio.
The folio is now unreachable from the swap table, and the offset goes back to the allocator. The folio is still on the LRU though, so reclaim can pick it up later. It then takes the old offset out of folio->swap and overwrites the table entry there, which by then may belong to someone else.
This bug can trigger silent memory corruption, process crashes, or data instability across completely unrelated userspace applications - typically occurring when uswsusp is preparing the hibernation image.
I found this while working on giving hibernation slots their own marker in the swap table, which I had discussed with Kairui.
(https://lore.kernel.org/linux-mm/abp7aDgYLrxF3Me8@KASONG-MC4/) As far as I know there are no reports, so there is no Reported-by/Closes to add.
Check for a cached folio before freeing. The slot is then left in the ordinary state where only the swap cache holds it, and it is freed when the folio leaves the cache, either through the reclaim below or through normal reclaim later.
--- mm/swapfile.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
mm/swapfile.c +8 -1
@@ -2196,7 +2196,14 @@ void swap_free_hibernation_slot(swp_entr ci =swap_cluster_lock (si, offset);__swap_cluster_put_entry (ci, offset %SWAPFILE_CLUSTER ); -__swap_cluster_free_entries (si, ci, offset %SWAPFILE_CLUSTER ,1 ); +/* +* A slot with a folio in the swap cache is freed when the folio +* leaves the cache, the same rule swap_put_entries_cluster() follows. +* Readahead can put a folio here, and freeing the slot now would +* leave that folio with no entry behind it. +*/ +if (!swp_tb_is_folio (__swap_table_get (ci, offset %SWAPFILE_CLUSTER ))) +__swap_cluster_free_entries (si, ci, offset %SWAPFILE_CLUSTER ,1 );swap_cluster_unlock (ci);/* In theory readahead might add it to the swap cache by accident */
Greg Kroah-Hartman
maintainerPATCH 46/713 mm, swap: ratelimit bad swap entry reports
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao <[email protected]>
commit f9dc428249ed962a70acf301f01eae8578449161 upstream.
A corrupt page table hands the same bogus entry to get_swap_device() on every access to the mapping, and every rejection is logged. One machine logged 6185620 copies of the same line in a few hours.
swap_dup_entry_direct() prints the same message from the fork path, once per call: the WARN_ON_ONCE() guarding it warns once, the pr_err() inside does not.
Rate limit all three prints.
--- mm/swapfile.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
mm/swapfile.c +3 -3
@@ -1893,11 +1893,11 @@ struct swap_info_struct *get_swap_devicereturn si; bad_nofile: -pr_err ("%s: %s%08lx\n" , __func__, Bad_file, entry.val); +pr_err_ratelimited ("%s: %s%08lx\n" , __func__, Bad_file, entry.val); out:return NULL ; put_out: -pr_err ("%s: %s%08lx\n" , __func__, Bad_offset, entry.val); +pr_err_ratelimited ("%s: %s%08lx\n" , __func__, Bad_offset, entry.val);percpu_ref_put (&si->users);return NULL ; }
@@ -3871,7 +3871,7 @@ int swap_dup_entry_direct(swp_entry_t en si =swap_entry_to_info (entry);if (WARN_ON_ONCE (!si)) { -pr_err ("%s%08lx\n" , Bad_file, entry.val); +pr_err_ratelimited ("%s%08lx\n" , Bad_file, entry.val);return -EINVAL ; }
Greg Kroah-Hartman
maintainerPATCH 47/713 mm/gup: fix always draining LRU caches in collect_longterm_unpinnable_folios()
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand (Arm) <[email protected]>
commit 078e1a0fc41a42baaf113383b52dab8874c0b967 upstream.
folio_may_be_lru_cached() is currently only true for small folios, and for small folios FOLL_PIN adds GUP_PIN_COUNTING_BIAS references instead of 1 in try_grab_folio()/try_grab_folio_fast().
Consequently, our
folio_ref_count(folio) != folio_expected_ref_count(folio) + 1
check in collect_longterm_unpinnable_folios() will currently always identify "reference mismatch" and first drain the local LRU cache to then drain the LRU cache on all CPUs, as collect_longterm_unpinnable_folios() is really called after pinning the folios with FOLL_PIN.
Add a comment because the current code is not quite intuitive: we used to drain only to make sure the folio_isolate_lru() would succeed. But then we also started draining to make later migration more reliable.
We'll refactor that code soon a bit, to also make it usable in other context where we really want to remove any references from LRU caches.
Let's add CC stable, because having an easy way for excessive LRU cache draining on all CPUs does not sound right. In common scenarios we don't expect to ever have to drain.
--- mm/gup.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
mm/gup.c +8 -2
@@ -2273,6 +2273,7 @@ static unsigned long collect_longterm_unfor (folio =pofs_get_folio (pofs, i); folio; folio =pofs_next_folio (folio, pofs, &i)) { +const int pin_refs =folio_has_pincount (folio) ?1 :GUP_PIN_COUNTING_BIAS ;if (folio_is_longterm_pinnable (folio))continue ;
@@ -2287,15 +2288,20 @@ static unsigned long collect_longterm_uncontinue ; } +/* +* We drain not only to make the folio_isolate_lru() succeed, +* but also to remove any other folio references from LRU +* caches. +*/ if (drained ==0 &&folio_may_be_lru_cached (folio) &&folio_ref_count (folio) != -folio_expected_ref_count (folio) +1 ) { +folio_expected_ref_count (folio) + pin_refs) {lru_add_drain (); drained =1 ; }if (drained ==1 &&folio_may_be_lru_cached (folio) &&folio_ref_count (folio) != -folio_expected_ref_count (folio) +1 ) { +folio_expected_ref_count (folio) + pin_refs) {lru_add_drain_all (); drained =2 ; }
Greg Kroah-Hartman
maintainerPATCH 48/713 mm/huge_memory: skip device-private PMDs in madvise_free_huge_pmd
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Usama Arif <[email protected]>
commit ce579dcf730ce5ed8043a5eeea18a3e6706a97e5 upstream.
madvise_free_pte_range() checks pmd_trans_huge(*pmd) unlocked, then madvise_free_huge_pmd() takes pmd_trans_huge_lock(). pmd_is_huge() returns true for a device-private PMD, so orig_pmd can be device-private and enter the !pmd_present() branch.
Skip device-private PMDs in that non-present branch and continue to out before calling pmd_folio(). Downgrade the check to VM_WARN_ON_ONCE() so an unexpected PMD softleaf logs a warning rather than panicking. Drop the thp_migration_supported() guard: it expands to IS_ENABLED(CONFIG_ARCH_SUPPORTS_PMD_SOFTLEAF), and both pmd_is_migration_entry() and pmd_is_device_private_entry() already return false when that config is not selected, so the guard suppresses only the case where the warning would already be silent.
Potential trigger: an HMM-based GPU driver races with madvise(MADV_FREE):migrate_vma_pages() flips the PMD to a device-private entry between the caller's pmd_trans_huge() check and the callee's pmd_trans_huge_lock().
--- mm/huge_memory.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
mm/huge_memory.c +2 -2
@@ -2340,8 +2340,8 @@ bool madvise_free_huge_pmd(struct mmu_ga goto out;if (unlikely (!pmd_present (orig_pmd))) { -VM_BUG_ON (thp_migration_supported () && - !pmd_is_migration_entry (orig_pmd)); +VM_WARN_ON_ONCE (!pmd_is_migration_entry (orig_pmd) && + !pmd_is_device_private_entry (orig_pmd)); goto out; }
Greg Kroah-Hartman
maintainerPATCH 49/713 mm/huge_memory: use folios memcg inside __folio_split()
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zi Yan <[email protected]>
commit c299a2285d9d8bda4da024455de65e3d00de6f17 upstream.
Patch series "Honor XA_FLAGS_ACCOUNT in xas_split_alloc() and charge to folio's memcg", v3.
__GFP_ACCOUNT is needed for xarray node allocation accounting when XA_FLAGS_ACCOUNT is set. Commit 7b785645e8f13 ("mm: fix page cache convergence regression") fixed a workingset regression with it. xas_split_alloc() does not have it and needs to be fixed.
In addition, based on Sashiko's review[1] and Johannes' confirmation[2], to charge the right memcg, folio's memcg needs to be active during folio split. Add that before adding __GFP_ACCOUNT.
There is no workingset convergence regression related to missing __GFP_ACCOUNT in xas_split_alloc() and the impact to userspace should be minor.
This patch (of 2):
During a pagecache folio split, an xarray node allocation can happen and needs to charge at folio's memcg instead of folio split invoker's memcg, because for example folio split can happen during reclaim and reclaim's active memcg might not be folio's memcg. Switch to folio's memcg at the beginning and switch back afterwards.
--- mm/huge_memory.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-)
mm/huge_memory.c +16 -4
@@ -4027,34 +4027,42 @@ static int __folio_split(struct folio *fXA_STATE (xas, &folio->mapping->i_pages, folio->index);struct folio *end_folio =folio_next (folio);bool is_anon =folio_test_anon (folio); +struct mem_cgroup *memcg, *old_memcg;struct address_space *mapping =NULL ;struct anon_vma *anon_vma =NULL ;int old_order =folio_order (folio);struct folio *new_folio, *next;int nr_shmem_dropped =0 ;enum ttu_flags ttu_flags =0 ; -int ret;pgoff_t end =0 ; +int ret;VM_WARN_ON_ONCE_FOLIO (!folio_test_locked (folio), folio);VM_WARN_ON_ONCE_FOLIO (!folio_test_large (folio), folio);if (folio !=page_folio (split_at) || folio !=page_folio (lock_at)) { ret = -EINVAL ; - goto out; + goto out_no_memcg; }if (new_order >= old_order) { ret = -EINVAL ; - goto out; + goto out_no_memcg; } ret =folio_check_splittable (folio, new_order, split_type);if (ret) {VM_WARN_ONCE (ret == -EINVAL ,"Tried to split an unsplittable folio" ); - goto out; + goto out_no_memcg; } +/* +* switch to folio's memcg as xarray node allocation can happen and +* needs to charge to it. +*/ + memcg =get_mem_cgroup_from_folio (folio); + old_memcg =set_active_memcg (memcg); +if (is_anon) {/* * The caller does not necessarily hold an mmap_lock that would
@@ -4197,6 +4205,10 @@ out_unlock:if (mapping)i_mmap_unlock_read (mapping); out: +/* restore to caller's old_memcg */ +set_active_memcg (old_memcg); +mem_cgroup_put (memcg); +out_no_memcg:xas_destroy (&xas);if (is_pmd_order (old_order))count_vm_event (!ret ?THP_SPLIT_PAGE :THP_SPLIT_PAGE_FAILED );
Greg Kroah-Hartman
maintainerPATCH 50/713 mm/hugetlb: fix boot panic with CONFIG_DEBUG_VM and HVO bootmem pages
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Muchun Song <[email protected]>
commit c0caeceb0c3899dc42844d3979093b27d1434108 upstream.
Patch series "mm: Refactor bootmem gigantic hugepage allocation", v4.
This series is split out from the earlier larger series "mm: Generalize HVO for HugeTLB and device DAX" [1]. It collects the first 19 patches of that series as a standalone set of fixes and preparatory cleanups around bootmem HugeTLB handling, sparse initialization ordering, and related vmemmap setup.
The first patches fix a few bugs found while reviewing the existing code, including incorrect bootmem HVO handling, wrong vmemmap registration arguments, a powerpc compound-vmemmap tracking bug, and too-late initialization of gigantic bootmem HugeTLB struct pages.
The rest of the series reorders early memory initialization so the relevant zone state is available before sparse and HugeTLB boot-time setup runs, then simplifies the remaining bootmem gigantic hugepage allocation path and removes code made obsolete by that rework.
At a high level:
- patches [1-4] fix boot-time and arch-specific bugs
- patches [5-12] reorder and simplify sparse/mm/hugetlb early init
- patches [13-19] refactor bootmem gigantic hugepage allocation and remove obsolete helpers and state
This patch (of 19):
Commit 622026e87c40 ("mm/hugetlb: remove fake head pages") switched HVO to reuse per-zone shared tail pages from zone->vmemmap_tails[].
Those shared tail pages were initialized in hugetlb_vmemmap_init(), but bootmem HugeTLB folios are prepared earlier from gather_bootmem_prealloc(). With hugetlb_free_vmemmap=on, prep_and_add_bootmem_folios() can access pageblock flags on bootmem HugeTLB pages whose mirrored tail struct pages already point to the shared tail page. On CONFIG_DEBUG_VM kernels, get_pfnblock_bitmap_bitidx() then dereferences the still-uninitialized shared tail page and can panic during boot.
Initialize zone->vmemmap_tails[] from gather_bootmem_prealloc(), before bootmem HugeTLB folios are processed, and drop the later initialization from hugetlb_vmemmap_init().
This bug only affects CONFIG_DEBUG_VM kernels, where the relevant assertion is evaluated.
--- mm/hugetlb.c | 25 +++++++++++++++++++++++++ mm/hugetlb_vmemmap.c | 17 ----------------- mm/sparse-vmemmap.c | 2 +- 3 files changed, 26 insertions(+), 18 deletions(-)
mm/hugetlb.c +25 -0
@@ -3365,6 +3365,31 @@ static void __init gather_bootmem_prealloc(void) .max_threads = num_node_state(N_MEMORY), .numa_aware = true, }; +#ifdef CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP +struct zone *zone; + +for_each_zone (zone) { +for (int i =0 ; i <NR_VMEMMAP_TAILS ; i++) { +struct page *tail, *p; +unsigned int order; + + tail = zone->vmemmap_tails[i]; +if (!tail) +continue ; + + order = i +VMEMMAP_TAIL_MIN_ORDER ; + p =page_to_virt (tail); +/* +* prep_and_add_bootmem_folios() can access pageblock +* flags on bootmem HugeTLB pages, so initialize the +* shared tail struct pages here before bootmem folios +* start using them. +*/ +for (int j =0 ; j <PAGE_SIZE /sizeof (struct page ); j++) +init_compound_tail (p + j,NULL , order, zone); + } + } +#endif padata_do_multithreaded (&job); }
mm/hugetlb_vmemmap.c +0 -17
@@ -870,27 +870,10 @@ static const struct ctl_table hugetlb_vmemmap_sysctls[] = {static int __init hugetlb_vmemmap_init (void ) {const struct hstate *h; -struct zone *zone;/* HUGETLB_VMEMMAP_RESERVE_SIZE should cover all used struct pages */ BUILD_BUG_ON (__NR_USED_SUBPAGE >HUGETLB_VMEMMAP_RESERVE_PAGES ); -for_each_zone (zone) { -for (int i =0 ; i <NR_VMEMMAP_TAILS ; i++) { -struct page *tail, *p; -unsigned int order; - - tail = zone->vmemmap_tails[i]; -if (!tail) -continue ; - - order = i +VMEMMAP_TAIL_MIN_ORDER ; - p =page_to_virt (tail); -for (int j =0 ; j <PAGE_SIZE /sizeof (struct page ); j++) -init_compound_tail (p + j,NULL , order, zone); - } - } -for_each_hstate (h) {if (hugetlb_vmemmap_optimizable (h)) {register_sysctl_init ("vm" , hugetlb_vmemmap_sysctls);
mm/sparse-vmemmap.c +1 -1
@@ -342,7 +342,7 @@ static __meminit struct page *vmemmap_get_tail(unsigned int order, struct zone ** * Any initialization done here will be overwritten by memmap_init(). * -* hugetlb_vmemmap_init() will take care of initialization after +* gather_bootmem_prealloc() will take care of initialization after * memmap_init(). */
Signature · 1 line
2.55.0
Greg Kroah-Hartman
maintainerPATCH 51/713 mm/hugetlb: initialize gigantic bootmem hugepage struct pages earlier
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Muchun Song <[email protected]>
commit b1b7c045e808c761b1cc8c19b3040fadedda3fef upstream.
Gigantic bootmem HugeTLB pages are currently initialized from hugetlb_init(), but page_alloc_init_late() runs earlier and walks pageblocks to determine zone contiguity.
If a bootmem HugeTLB region is marked noinit, set_zone_contiguous() can observe still-uninitialized struct pages through __pageblock_pfn_to_page(). This may not trigger an immediate failure, but it can make set_zone_contiguous() compute the wrong zone contiguity state. If extra poisoned-page checks are added in this path, such as PF_POISONED_CHECK() in page_zone_id(), it can also trigger an early boot panic.
Initialize gigantic bootmem HugeTLB struct pages from page_alloc_init_late(), before zone contiguity is evaluated, so later page allocator setup only sees valid struct page state. This also makes the initialization order more natural, as struct pages should be initialized before later code inspects them.
--- include/linux/hugetlb.h | 5 +++++ mm/hugetlb.c | 5 ++--- mm/mm_init.c | 1 + mm/sparse-vmemmap.c | 4 ++-- 4 files changed, 10 insertions(+), 5 deletions(-)
include/linux/hugetlb.h +5 -0
@@ -171,6 +171,7 @@ extern int movable_gigantic_pages __readextern int sysctl_hugetlb_shm_group__read_mostly ;extern struct list_head huge_boot_pages[MAX_NUMNODES ]; +void hugetlb_bootmem_struct_page_init (void );void hugetlb_bootmem_alloc (void );extern nodemask_t hugetlb_bootmem_nodes;void hugetlb_bootmem_set_nodes (void );
@@ -1293,6 +1294,10 @@ static inline bool hugetlbfs_pagecache_pstatic inline void hugetlb_bootmem_alloc (void ) { } + +static inline void hugetlb_bootmem_struct_page_init (void ) +{ +}#endif /* CONFIG_HUGETLB_PAGE */ static inline spinlock_t *huge_pte_lock(struct hstate *h,
mm/hugetlb.c +2 -3
@@ -3353,7 +3353,7 @@ static void __init gather_bootmem_preallgather_bootmem_prealloc_node (nid); } -static void __init gather_bootmem_prealloc (void ) +void __init hugetlb_bootmem_struct_page_init (void ) {struct padata_mt_job job = { .thread_fn = gather_bootmem_prealloc_parallel,
@@ -3582,7 +3582,7 @@ static unsigned long __init hugetlb_page* - For gigantic pages, this is called early in the boot process and * pages are allocated from memblock allocated or something similar. * Gigantic pages are actually added to pools later with the routine -* gather_bootmem_prealloc. +* hugetlb_bootmem_struct_page_init. * - For non-gigantic pages, this is called later in the boot process after * all of mm is up and functional. Pages are allocated from buddy and * then added to hugetlb pools.
@@ -4152,7 +4152,6 @@ static int __init hugetlb_init(void) }hugetlb_init_hstates (); -gather_bootmem_prealloc ();report_hugepages ();hugetlb_sysfs_init ();
mm/mm_init.c +1 -0
@@ -2330,6 +2330,7 @@ void __init page_alloc_init_late(void)/* Reinit limits that are based on free pages after the kernel is up */ files_maxfiles_init ();#endif +hugetlb_bootmem_struct_page_init ();/* Accounting of total+free memory is stable at this point. */ mem_init_print_info ();
mm/sparse-vmemmap.c +2 -2
@@ -342,8 +342,8 @@ static __meminit struct page *vmemmap_ge* * Any initialization done here will be overwritten by memmap_init(). * -* gather_bootmem_prealloc() will take care of initialization after -* memmap_init(). +* hugetlb_bootmem_struct_page_init() will take care of initialization +* after memmap_init(). */ p =vmemmap_alloc_block_zero (PAGE_SIZE , node);
Greg Kroah-Hartman
maintainerPATCH 52/713 mm/hugetlb_vmemmap: fix __hugetlb_vmemmap_optimize_folios()
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Muchun Song <[email protected]>
commit 6e25c6a9c7eff141ecfc966ecdb7801db2a8810e upstream.
__hugetlb_vmemmap_optimize_folios() uses incorrect arguments when handling bootmem HugeTLB folios.
The section number passed to register_page_bootmem_memmap() is derived from the vmemmap virtual address of folio->page instead of the folio PFN, so the bootmem memmap metadata can be registered against the wrong section. The helper is also given HUGETLB_VMEMMAP_RESERVE_SIZE even though it expects a page count, not a size in bytes. In addition, the write-protect range is based on pages_per_huge_page(h), which does not cover the full HugeTLB vmemmap area and can leave part of the shared tail vmemmap mapping writable.
Fix the section lookup to use folio_pfn(folio), use HUGETLB_VMEMMAP_RESERVE_PAGES when registering the reserved memmap pages, and use hugetlb_vmemmap_size(h) for the write-protect range.
--- mm/hugetlb_vmemmap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
mm/hugetlb_vmemmap.c +3 -3
@@ -635,12 +635,12 @@ static void __hugetlb_vmemmap_optimize_f* mirrored tail page structs RO. */ spfn = (unsigned long )&folio->page; - epfn = spfn +pages_per_huge_page (h); + epfn = spfn +hugetlb_vmemmap_size (h);vmemmap_wrprotect_hvo (spfn, epfn,folio_nid (folio),HUGETLB_VMEMMAP_RESERVE_SIZE ); -register_page_bootmem_memmap (pfn_to_section_nr (spfn), +register_page_bootmem_memmap (pfn_to_section_nr (folio_pfn (folio)), &folio->page, -HUGETLB_VMEMMAP_RESERVE_SIZE ); +HUGETLB_VMEMMAP_RESERVE_PAGES );continue ; }
Greg Kroah-Hartman
maintainerPATCH 53/713 mm/kmemleak: avoid soft lockup when scanning task stacks
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao <[email protected]>
commit 5d10d4e19e6daa487f0cd0ea6cba472325de92f9 upstream.
Patch series "mm/kmemleak: avoid soft lockup when scanning task", v3.
kmemleak_scan() scans every task stack under one rcu_read_lock() with no reschedule point, which can trip the soft lockup watchdog on hosts with very many threads.
That prints the following message, depending on the workload+host configuration:
watchdog: BUG: soft lockup - CPU#35 stuck for 22s! [kmemleak:537]
scan_block
kmemleak_scan
kmemleak_scan_thread
kthreadPatch 1 walks the tasks with find_ge_pid() so the scan reschedules between tasks
Patches 2-3 let the scan loops stop early once a scan is interrupted.
This patch (of 3):
kmemleak_scan() walks every thread and scans its kernel stack under a single rcu_read_lock() with no reschedule point. On a host with very many threads -- amplified by KASAN/lockdep in debug builds -- this loop can hog a CPU long enough to trip the soft lockup watchdog:
watchdog: BUG: soft lockup - CPU#35 stuck for 22s! [kmemleak:537] scan_block kmemleak_scan kmemleak_scan_thread kthread
A cond_resched() cannot be added directly: the loop runs inside an RCU read-side critical section.
Walk the tasks one PID at a time with find_ge_pid(), taking the RCU read lock only to look up and pin each task. The stack is then scanned with no lock held, so cond_resched() runs between tasks and the scan stops early on scan_should_stop(). This follows the next_tgid()/task_seq_get_next() iteration pattern and keeps each RCU critical section short.
--- mm/kmemleak.c | 51 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 13 deletions(-)
mm/kmemleak.c +38 -13
@@ -1697,6 +1697,42 @@ unlock_put: }/* +* Scan all task kernel stacks, rescheduling between tasks. Each task is looked +* up and pinned within its own RCU read-side section, so no lock is held across +* the scan and the walk cannot trip the soft lockup watchdog. +*/ +static void kmemleak_scan_task_stacks (void ) +{ +struct pid *pid; +int nr =1 ; + +do { +struct task_struct *p =NULL ; + +rcu_read_lock (); + pid =find_ge_pid (nr, &init_pid_ns); +if (pid) { + nr =pid_nr (pid) +1 ; + p =pid_task (pid,PIDTYPE_PID ); +if (p) +get_task_struct (p); + } +rcu_read_unlock (); + +if (p) { +void *stack =try_get_task_stack (p); + +if (stack) { +scan_block (stack, stack +THREAD_SIZE ,NULL ); +put_task_stack (p); + } +put_task_struct (p); + } +cond_resched (); + }while (pid && !scan_should_stop ()); +} + +/* * Print one leak inline. The hex dump is gated on OBJECT_ALLOCATED so it * does not touch user memory that was freed concurrently; the rest of the * report (backtrace, comm, pid) is always emitted since the kmemleak_object
@@ -1885,19 +1921,8 @@ static void kmemleak_scan(void)/* * Scanning the task stacks (may introduce false negatives). */ -if (kmemleak_stack_scan) { -struct task_struct *p, *g; - -rcu_read_lock (); -for_each_process_thread (g, p) { -void *stack =try_get_task_stack (p); -if (stack) { -scan_block (stack, stack +THREAD_SIZE ,NULL ); -put_task_stack (p); - } - } -rcu_read_unlock (); - } +if (kmemleak_stack_scan) +kmemleak_scan_task_stacks ();/* * Scan the objects already referenced from the sections scanned
Greg Kroah-Hartman
maintainerPATCH 54/713 mm/madvise: skip device-private PMDs in cold and pageout walks
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Usama Arif <[email protected]>
commit d4b76d0b03cb49611312ecc4bcfb55ccdf0843e2 upstream.
madvise_cold_or_pageout_pte_range() takes pmd_trans_huge_lock(), whose pmd_is_huge() check returns true for a device-private PMD. The subsequent !pmd_present() branch has a VM_BUG_ON() asserting migration is the only allowed non-present case; a device-private PMD trips it.
Skip device-private PMDs in that non-present branch and continue to huge_unlock before calling pmd_folio(). Downgrade the check to VM_WARN_ON_ONCE() so an unexpected PMD softleaf logs a warning rather than panicking. Drop the thp_migration_supported() guard: it expands to IS_ENABLED(CONFIG_ARCH_SUPPORTS_PMD_SOFTLEAF), and both pmd_is_migration_entry() and pmd_is_device_private_entry() already return false when that config is not selected, so the guard suppresses only the case where the warning would already be silent.
Potential trigger: an HMM-based GPU driver races with madvise(MADV_COLD)/MADV_PAGEOUT: pmd_trans_huge(*pmd) reads true, then migrate_vma_pages() flips the PMD to a device-private entry before the PMD lock is acquired.
--- mm/madvise.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
mm/madvise.c +2 -2
@@ -388,8 +388,8 @@ static int madvise_cold_or_pageout_pte_range(pmd_t *pmd, goto huge_unlock;if (unlikely (!pmd_present (orig_pmd))) { -VM_BUG_ON (thp_migration_supported () && - !pmd_is_migration_entry (orig_pmd)); +VM_WARN_ON_ONCE (!pmd_is_migration_entry (orig_pmd) && + !pmd_is_device_private_entry (orig_pmd)); goto huge_unlock; }
Signature · 1 line
2.55.0
Greg Kroah-Hartman
maintainerPATCH 55/713 mm/mempolicy: skip non-present PMDs when queueing folios
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Usama Arif <[email protected]>
commit 2858b4027f491e6fdb8ee2d8923798b619bf2791 upstream.
Patch series "mm: handle device-private PMDs in walk callbacks", v3.
Since commit 368076f52ebe ("mm/huge_memory: add device-private THP support to PMD operations") a PMD may hold a device-private swap entry whenever an HMM-based GPU driver migrates an anonymous THP folio to device memory via migrate_vma_pages().
pmd_trans_huge_lock() succeeds for such PMDs (pmd_is_huge() returns true for any non-present, non-none huge PMD), so several MM walk callbacks that used to assume present THP or migration entry are now reachable with a device-private PMD. The results range from a VM_BUG_ON() firing on debug kernels, to an oops on a bogus vmemmap dereference, to silently isolating an unrelated live folio from LRU in the aliasing case.
This patch (of 3):
queue_folios_pmd() is called under pmd_trans_huge_lock(), whose pmd_is_huge() check returns true for any non-present, non-none PMD softleaf. Passing such a PMD to pmd_folio() treats the softleaf encoding as a hardware PFN and can return a bogus folio pointer.
Mirror queue_folios_pte_range(): handle non-present entries before looking up a folio. Keep migration entries counted as failures, but skip other non-present PMDs such as device-private entries.
Potential trigger: an HMM-based GPU driver migrates an anonymous THP folio to device memory via migrate_vma_pages(), leaving a device-private PMD. Userspace then calls mbind(), migrate_pages() or set_mempolicy_home_node() on that range.
--- mm/mempolicy.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
mm/mempolicy.c +5 -3
@@ -653,12 +653,14 @@ static void queue_folios_pmd(pmd_t *pmd, {struct folio *folio;struct queue_pages *qp = walk->private; +pmd_t pmdval =pmdp_get (pmd); -if (unlikely (pmd_is_migration_entry (*pmd))) { - qp->nr_failed++; +if (unlikely (!pmd_present (pmdval))) { +if (pmd_is_migration_entry (pmdval)) + qp->nr_failed++;return ; } - folio =pmd_folio (*pmd); + folio =pmd_folio (pmdval);if (is_huge_zero_folio (folio)) { walk->action =ACTION_CONTINUE ;return ;
Greg Kroah-Hartman
maintainerPATCH 56/713 mm/mglru: fix and remove redundant unevictable folio handling
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kairui Song <[email protected]>
commit f7e698e326b239a91ea15844817551921209e826 upstream.
sort_folio() has a shortcut for moving folios that are no longer evictable but are still sitting on a generation list. However, this shortcut is buggy. It does not follow the PG_lru usage convention, and it has a more serious issue.
Unevictable folios are not threaded on lists[LRU_UNEVICTABLE], so that folio->lru can be reused to hold folio->mlock_count (see the comment in lruvec_init()). Hence lruvec_add_folio() skips the list_add() for them, and every other place that turns a folio unevictable initialises mlock_count explicitly: lru_add() sets it to 0, __mlock_folio() and __mlock_new_folio() set it to !!folio_test_mlocked(folio). sort_folio() sets nothing, and the lru_gen_del_folio() right above it may have already poisoned folio->lru via list_del(), so mlock_count ends up aliasing LIST_POISON2, which reads as 0x122, i.e. 290. The result is user visible. On munlock, __munlock_folio() decrements that bogus count, finds it still non-zero and bails out before clearing PG_mlocked, so the folio remains unevictable and the Mlocked accounting stays inflated until the folio is freed.
The shortcut also touches the LRU flags in the wrong order. It calls lru_gen_del_folio() while PG_lru is still set, so a concurrent folio_test_clear_lru() (e.g. compaction, folio_isolate_lru()) can succeed on a folio that has already been taken off the generation list, which may lead to unexpected behavior.
So fix it by isolating them as common folios and letting the generic shrink path cull them. This matches the classical LRU behavior, and there should be no visible effect on the generic eviction or isolation behavior.
There is no performance concern either, such a folio goes through this once, and then it is off the generation lists for good.
--- mm/vmscan.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-)
mm/vmscan.c +5 -14
@@ -4573,7 +4573,6 @@ void lru_gen_reparent_memcg(struct mem_cstatic bool sort_folio (struct lruvec *lruvec,struct folio *folio,struct scan_control *sc,int tier_idx) { -bool success;int gen =folio_lru_gen (folio);int type =folio_is_file_lru (folio);int zone =folio_zonenum (folio);
@@ -4585,15 +4584,9 @@ static bool sort_folio(struct lruvec *lrVM_WARN_ON_ONCE_FOLIO (gen >=MAX_NR_GENS , folio); -/* unevictable */ -if (!folio_evictable (folio)) { - success =lru_gen_del_folio (lruvec, folio, true); -VM_WARN_ON_ONCE_FOLIO (!success, folio); -folio_set_unevictable (folio); -lruvec_add_folio (lruvec, folio); -__count_vm_events (UNEVICTABLE_PGCULLED , delta); -return true; - } +/* unevictable: let it through and the generic path will cull it */ +if (!folio_evictable (folio)) +return false;/* promoted */ if (gen !=lru_gen_from_seq (lrugen->min_seq[type])) {
@@ -4843,11 +4836,9 @@ retry:list_for_each_entry_safe_reverse (folio, next, &list, lru) {DEFINE_MIN_SEQ (lruvec); -if (!folio_evictable (folio)) { -list_del (&folio->lru); -folio_putback_lru (folio); +/* move_folios_to_lru() culls unevictable folios via folio_putback_lru() */ +if (!folio_evictable (folio))continue ; - }/* retry folios that may have missed folio_rotate_reclaimable() */ if (!skip_retry && !folio_test_active(folio) && !folio_mapped(folio) &&
Greg Kroah-Hartman
maintainerPATCH 57/713 mm/migrate: report RCU-tasks quiescent states in migrate_pages_batch()
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao <[email protected]>
commit efe8f86c0916f0f74eea74ae21a3b37f728c6bad upstream.
migrate_pages_batch() unmaps each folio before moving it, and every unmap runs the mmu_notifier invalidate callbacks. On KVM hosts try_to_migrate() ends up in kvm_mmu_notifier_invalidate_range_start() -> tdp_mmu_zap_leafs(), which is expensive, so unmapping a large batch keeps the CPU busy for a long time.
The loop already calls cond_resched(), but on PREEMPTION kernels that is a no-op, and involuntary preemption is not a Tasks-RCU quiescent state.
A long batch therefore never reports a quiescent state, and the migrating task (e.g. kcompactd) becomes a Tasks-RCU holdout, stalling the Tasks-RCU grace period for minutes, which is common at Meta fleet:
INFO: rcu_tasks detected stalls on tasks: 0000000055349ecc: .. nvcsw: 1157401/1157401 holdout: 1 idle_cpu: -1/56 task:kcompactd0 state:R running task Call Trace: tdp_mmu_zap_leafs tdp_mmu_next_root gfn_to_pfn_cache_invalidate_start kvm_mmu_notifier_invalidate_range_start __mmu_notifier_invalidate_range_start try_to_migrate_one try_to_migrate migrate_pages_batch migrate_pages compact_zone compact_node kcompactd kthread
Use cond_resched_tasks_rcu_qs() so a quiescent state is reported even when cond_resched() does nothing.
This has also been discussed at [1]
--- mm/migrate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/migrate.c +1 -1
@@ -1830,7 +1830,7 @@ static int migrate_pages_batch(struct li is_thp =folio_test_pmd_mappable (folio); nr_pages =folio_nr_pages (folio); -cond_resched (); +cond_resched_tasks_rcu_qs ();/* * The rare folio on the deferred split list should
Greg Kroah-Hartman
maintainerPATCH 58/713 mm/migrate: use huge_ptep_get() in remove_migration_pte()
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dev Jain <[email protected]>
commit ac1ec50d71b953524100ddc09057ee61a3dfaff3 upstream.
remove_migration_pte() converts migration entries back to present PTEs after folio migration completes. For hugetlb folios, page_vma_mapped_walk() returns the pte pointer to the hugetlb folio in pvmw.pte, but the code reads it with ptep_get().
On arches which provide their own huge_ptep_get() to dereference a huge pte pointer, accessing via ptep_get() would cause pte_pfn(), pte_present() etc to misbehave.
It is not clear whether this has a trivially visible effect to userspace.
Use huge_ptep_get() to dereference a huge pte pointer.
--- mm/migrate.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
mm/migrate.c +5 -1
@@ -371,7 +371,11 @@ static bool remove_migration_pte(struct continue; }#endif - old_pte =ptep_get (pvmw.pte); +if (folio_test_hugetlb (folio)) + old_pte =huge_ptep_get (vma->vm_mm, pvmw.address, + pvmw.pte); +else + old_pte =ptep_get (pvmw.pte);if (rmap_walk_arg->map_unused_to_zeropage &&try_to_map_unused_to_zeropage (&pvmw, folio, old_pte, idx))continue ;
Greg Kroah-Hartman
maintainerPATCH 59/713 mm/migrate_device: clear stale mapping after freeing swapcache
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arvind Yadav <[email protected]>
commit 34a00895d032a414830d41106a09329ae6c251b6 upstream.
__migrate_device_pages() reads the folio mapping before calling folio_free_swap(). When folio_free_swap() succeeds, the folio is removed from the swap cache, but the saved mapping still points to swap_space.
Passing the stale mapping to folio_migrate_mapping() makes it use the mapped-folio path for a folio that is no longer in swapcache. It can then operate on swap_space.i_pages with invalid reference accounting, eventually triggering a folio reference count BUG.
After a successful split, nr still contains the number of pages in the original large folio, although each resulting page is now a separate order-0 folio. Reset nr to 1 so each split folio is processed separately, including its own swapcache removal and mapping lookup.
Refresh the saved mapping after folio_free_swap() so the current folio state is used during migration.
--- mm/migrate_device.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
mm/migrate_device.c +13 -0
@@ -1183,6 +1183,13 @@ static void __migrate_device_pages(unsig MIGRATE_PFN_COMPOUND); goto next; } + +/* +* reset nr so that only first after-split folio +* is processed below +*/ +VM_WARN_ON_ONCE (folio_test_large (folio)); + nr =1 ; }else if ((src_pfns[i] &MIGRATE_PFN_MIGRATE ) && (dst_pfns[i] &MIGRATE_PFN_COMPOUND ) && !(src_pfns[i] &MIGRATE_PFN_COMPOUND )) {
@@ -1222,6 +1229,12 @@ static void __migrate_device_pages(unsig folio =page_folio (migrate_pfn_to_page (src_pfns[i+j])); newfolio =page_folio (migrate_pfn_to_page (dst_pfns[i+j])); +/* +* folio_free_swap() removed the folio from the swap +* cache. Refresh the saved mapping before migration. +*/ + mapping =folio_mapping (folio); + r =folio_migrate_mapping (mapping, newfolio, folio, extra_cnt);if (r) src_pfns[i+j] &= ~MIGRATE_PFN_MIGRATE ;
Greg Kroah-Hartman
maintainerPATCH 60/713 mm/mm_init: deferred_grow_zone(): fix out-of-range first_deferred_pfn
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Graf <[email protected]>
commit 97090500d776c3f6d08e857e3a0a7cf092999094 upstream.
With CONFIG_DEFERRED_STRUCT_PAGE_INIT enabled, deferred_grow_zone() initializes struct pages early in boot to satisfy an allocation.
With a large CMA reservation in place, the ranges deferred_init_memmap() finds may not add up to the allocation it was asked for, and the function ends up initializing the memory map of the entire zone and still falls short.
That is fine in itself: the function accounts for it and leaves the caller to decide whether it now has enough memory.
However, the update of pgdat->first_deferred_pfn that tracks where uninitialized memory map starts could overflow.
If the node's RAM end is not aligned on PAGES_PER_SECTION boundaries and some deferred struct pages were initialized, pgdat->first_deferred_pfn would point past the end of the node's memory.
deferred_init_memmap() later picks up from pgdat->first_deferred_pfn and hits a BUG_ON(), because it expects a pfn within its node.
For example, when running a kernel with CONFIG_DEFERRED_STRUCT_PAGE_INIT=y and CONFIG_CMA=y using the following qemu command line
qemu-system-x86_64 -enable-kvm -m 8032M -kernel bzImage \
-append "nokaslr cma=4768M@0x100000000"the kernel panics:
kernel BUG at mm/mm_init.c:2131!
CPU: 3 UID: 0 PID: 36 Comm: pgdatinit0 Not tainted 7.2.0-rc6 #1 RIP: 0010:deferred_init_memmap+0x1b8/0x1c0 RAX: 0000000000236000 R13: 0000000000238000 Call Trace: kthread+0xdf/0x120 ret_from_fork+0x187/0x250
Make sure that the update of pgdta->first_deferred_pfn does not overflow when the entire zone's (and therefore node's) memory map is initialized.
--- mm/mm_init.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
mm/mm_init.c +6 -3
@@ -2214,10 +2214,13 @@ bool __init deferred_grow_zone(struct zo }/* -* There were no pages to initialize and free which means the zone's -* memory map is completely initialized. +* The loop only tests spfn before entering an iteration, so on exit it +* may point up to a section past the end of the zone. When it does, +* the rest of the zone has already been handed to +* deferred_init_memmap_chunk() and nothing is left to initialize. */ - pgdat->first_deferred_pfn = nr_pages ? spfn :ULONG_MAX ; + pgdat->first_deferred_pfn = + spfn <zone_end_pfn (zone) ? spfn :ULONG_MAX ;pgdat_resize_unlock (pgdat, &flags);
Greg Kroah-Hartman
maintainerPATCH 61/713 mm/page_owner: use memcg_data snapshot to avoid TOCTOU in print_page_owner_memcg()
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ye Liu <[email protected]>
commit 90f095b816e25c6a9e4446d299bac5007fdcb3df upstream.
print_page_owner_memcg() reads page->memcg_data via READ_ONCE() at the start to guard against tail pages and NULL data. However, it later re-reads page->memcg_data locklessly in two places:
1: page_memcg_check(page)
2: PageMemcgKmem(page) (via folio_memcg_kmem(), which includes
VM_BUG_ON assertions for tail pages and MEMCG_DATA_OBJEXTS)
If the page is concurrently freed and reallocated as a THP tail page or slab page between these calls, the VM_BUG_ON assertions can trigger on CONFIG_DEBUG_VM=y builds, crashing the kernel.
Fix both TOCTOU issues by using the memcg_data snapshot throughout.
--- mm/page_owner.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
mm/page_owner.c +7 -3
@@ -513,6 +513,7 @@ static inline int print_page_owner_memcg {#ifdef CONFIG_MEMCG unsigned long memcg_data; +struct obj_cgroup *objcg;struct mem_cgroup *memcg;bool online;char name[80 ];
@@ -522,11 +523,14 @@ static inline int print_page_owner_memcgif (!memcg_data ||PageTail (page)) goto out_unlock; -if (memcg_data &MEMCG_DATA_OBJEXTS ) +if (memcg_data &MEMCG_DATA_OBJEXTS ) { ret +=scnprintf (kbuf + ret, count - ret,"Slab cache page\n" ); + goto out_unlock; + } - memcg =page_memcg_check (page); + objcg = (void *)(memcg_data & ~OBJEXTS_FLAGS_MASK ); + memcg = objcg ?obj_cgroup_memcg (objcg) :NULL ;if (!memcg) goto out_unlock;
@@ -534,7 +538,7 @@ static inline int print_page_owner_memcgcgroup_name (memcg->css.cgroup, name,sizeof (name)); ret +=scnprintf (kbuf + ret, count - ret,"Charged %sto %smemcg %s\n" , -PageMemcgKmem (page) ?"(via objcg) " :"" , + (memcg_data &MEMCG_DATA_KMEM ) ?"(via objcg) " :"" , online ?"" :"offline " , name); out_unlock:
Greg Kroah-Hartman
maintainerPATCH 62/713 mm/page_vma_mapped: use huge_ptep_get() for hugetlb
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dev Jain <[email protected]>
commit e87df0d5d6962bde50f55f6d02b779daa394f894 upstream.
check_pte() is the final validation step in page_vma_mapped_walk(). It reads pvmw->pte with ptep_get() to decide whether the entry maps the PFN range being walked. For hugetlb VMAs, that pointer refers to a hugetlb entry.
On arches which provide their own huge_ptep_get() to dereference a huge pte pointer, accessing via ptep_get() would cause pte_pfn(), pte_present() etc to misbehave.
It is not clear whether this has a trivially visible effect to userspace.
Use huge_ptep_get() to dereference a huge pte pointer.
--- mm/page_vma_mapped.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
mm/page_vma_mapped.c +7 -1
@@ -107,7 +107,13 @@ again:static bool check_pte (struct page_vma_mapped_walk *pvmw,unsigned long pte_nr) {unsigned long pfn; -pte_t ptent =ptep_get (pvmw->pte); +pte_t ptent; + +if (is_vm_hugetlb_page (pvmw->vma)) + ptent =huge_ptep_get (pvmw->vma->vm_mm, pvmw->address, + pvmw->pte); +else + ptent =ptep_get (pvmw->pte);if (pvmw->flags &PVMW_MIGRATION ) {const softleaf_t entry =softleaf_from_pte (ptent);
Greg Kroah-Hartman
maintainerPATCH 63/713 mm/pagewalk: fix stale walk->action escaping walk_pmd_range()
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hyunwoo Kim <[email protected]>
commit aedf2efd18977e0cef7eb963166e2b1fcc0aa321 upstream.
If ->pmd_entry() sets walk->action = ACTION_AGAIN, the pmd_none() check is retried. The PMD entry may be cleared at the point of retry.
In this case, if walk->ops->install_pte is not specified, the code continues to the next PMD entry in the range without resetting walk->action to ACTION_SUBTREE.
This leaves walk->action erroneously set to ACTION_AGAIN, which is incorrect.
This was incorrect but not problematic up until commit 3b89863c3fa4 ("mm/pagewalk: fix race between concurrent split and refault") which updated walk_pud_range() to check for walk->action == ACTION_AGAIN upon walk_pmd_range()'s return, causing the PUD walk to be retried.
In this case this results in duplicate walk callbacks being invoked, which is erroneous and will break any caller that is not idempotent with respect to this (and waste time for those which are). The result is an out-of-bounds write, triggered by a local fuzzer:
[ 2.272695] ================================================================== [ 2.273471] BUG: KASAN: slab-out-of-bounds in __mincore_unmapped_range+0x14f/0x190 [ 2.274302] Write of size 1 at addr ffff888008d9b000 by task poc/106 [ 2.274966] [ 2.275154] CPU: 0 UID: 1000 PID: 106 Comm: poc Not tainted 7.2.0-rc6-00429-ga7c7074b58d2 #55 PREEMPT(lazy) [ 2.275159] Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 [ 2.275164] Call Trace: [ 2.275170] <TASK> [ 2.275172] dump_stack_lvl+0x53/0x70 [ 2.275200] print_report+0xd0/0x630 [ 2.275210] ? __pfx__raw_spin_lock_irqsave+0x10/0x10 [ 2.275219] ? irqentry_exit+0xd2/0x670 [ 2.275224] ? irqentry_exit+0xd2/0x670 [ 2.275226] ? __virt_addr_valid+0xef/0x1a0 [ 2.275239] ? __mincore_unmapped_range+0x14f/0x190 [ 2.275242] kasan_report+0xce/0x100 [ 2.275245] ? __mincore_unmapped_range+0x14f/0x190 [ 2.275248] __mincore_unmapped_range+0x14f/0x190 [ 2.275252] mincore_unmapped_range+0x45/0x70 [ 2.275254] walk_pgd_range+0xafc/0xfc0 [ 2.275261] ? __pfx_walk_pgd_range+0x10/0x10 [ 2.275264] ? __update_load_avg_se+0x3d1/0x670 [ 2.275275] __walk_page_range+0xc0/0x310 [ 2.275278] ? __pfx_find_vma+0x10/0x10 [ 2.275281] ? finish_task_switch.isra.0+0x16d/0x4f0 [ 2.275290] walk_page_range_mm_unsafe+0x26f/0x3a0 [ 2.275293] ? __pfx_mtree_load+0x10/0x10 [ 2.275298] ? __pfx_walk_page_range_mm_unsafe+0x10/0x10 [ 2.275302] ? __free_frozen_pages+0x54d/0x7e0 [ 2.275308] __do_sys_mincore+0x132/0x380 [ 2.275311] do_syscall_64+0xf9/0x540 [ 2.275316] entry_SYSCALL_64_after_hwframe+0x77/0x7f [ 2.275322] RIP: 0033:0x422ccd [ 2.275326] Code: b3 66 2e 0f 1f 84 00 00 00 00 00 66 90 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 c7 c1 b8 ff ff ff f7 d8 64 89 01 48 [ 2.275329] RSP: 002b:00007fffffffec18 EFLAGS: 00000287 ORIG_RAX: 000000000000001b [ 2.275337] RAX: ffffffffffffffda RBX: 0000000000000066 RCX: 0000000000422ccd [ 2.275339] RDX: 00000000004d0940 RSI: 0000000001000000 RDI: 00007ffff4000000 [ 2.275340] RBP: 00000000004d0940 R08: 0000000000000100 R09: 0000000000000100 [ 2.275342] R10: 0000000000000100 R11: 0000000000000287 R12: 20c49ba5e353f7cf [ 2.275343] R13: 00000000004990d3 R14: 0000000000000000 R15: 0000000000000001 [ 2.275346] </TASK> [ 2.275347] [ 2.296904] The buggy address belongs to the object at ffff888008d9b000 [ 2.296904] which belongs to the cache sigqueue of size 80 [ 2.298151] The buggy address is located 0 bytes inside of [ 2.298151] allocated 80-byte region [ffff888008d9b000, ffff888008d9b050) [ 2.299408] [ 2.299601] The buggy address belongs to the physical page: [ 2.300191] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x8d9b [ 2.301001] flags: 0x100000000000000(node=0|zone=1) [ 2.301535] page_type: f5(slab) [ 2.301884] raw: 0100000000000000 ffff888107e46780 dead000000000122 0000000000000000 [ 2.302687] raw: 0000000000000000 0000000800240024 00000000f5000000 0000000000000000 [ 2.303489] page dumped because: kasan: bad access detected [ 2.304092] [ 2.304276] Memory state around the buggy address: [ 2.304801] ffff888008d9af00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 2.305567] ffff888008d9af80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 2.306340] >ffff888008d9b000: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 2.307115] ^ [ 2.307474] ffff888008d9b080: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 2.308237] ffff888008d9b100: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 2.308997] ==================================================================
A specific example of this breaking things is mincore which walks an internal cursor data structure a byte at a time on assumption that page table entry callbacks are called only once for each entry.
Fix the problem by resetting walk->action to ACTION_SUBTREE prior to the none check.
The pattern also exists in walk_pud_range() so fix it there too.
This issue was found through AI-based fuzzing.
--- mm/pagewalk.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
mm/pagewalk.c +2 -4
@@ -126,6 +126,7 @@ static int walk_pmd_range(pud_t *pud, un pmd =pmd_offset (pud, addr); do { again: + walk->action = ACTION_SUBTREE; next = pmd_addr_end(addr, end); if (pmd_none(*pmd)) { if (has_install)
@@ -138,8 +139,6 @@ again:continue ; } - walk->action =ACTION_SUBTREE ; -/* * This implies that each ->pmd_entry() handler * needs to know about pmd_trans_huge() pmds
@@ -196,6 +195,7 @@ static int walk_pud_range(p4d_t *p4d, un pud =pud_offset (p4d, addr); do { again: + walk->action = ACTION_SUBTREE; next = pud_addr_end(addr, end); if (pud_none(*pud)) { if (has_install)
@@ -208,8 +208,6 @@ static int walk_pud_range(p4d_t *p4d, uncontinue ; } - walk->action =ACTION_SUBTREE ; -if (ops->pud_entry) err = ops->pud_entry (pud, addr, next, walk);if (err)
Greg Kroah-Hartman
maintainerPATCH 64/713 mm/rmap: use huge_ptep_get() in try_to_unmap_one()
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dev Jain <[email protected]>
commit f5407e9b697c940e78b27ff63c6e14d8d171adc3 upstream.
Patch series "Fix incorrect access of hugetlb pte entries", v3.
There are various places which use ptep_get() to get the pte entry corresponding to a hugetlb folio. Some arches (like s390) have special handling to compute the pteval, so they provide huge_ptep_get(). Use this helper consistently.
Additionally, some code paths may provide huge_ptep_get with an unaligned address. This is a problem on arm64 (I checked other arches and it looks fine for them), which is fixed in patch 1. The fix is made to be
backport-friendly: the cleaner fix would be to perhaps pass the hstate to huge_ptep_get() - that is wider churn and we can do that later.
This patch (of 5):
try_to_unmap_one() handles hugetlb folios when memory failure needs to replace a poisoned hugetlb mapping with a hwpoison entry. In that case page_vma_mapped_walk() returns the pte pointer to the hugetlb folio in pvmw.pte, but the code reads it with ptep_get().
On arches which provide their own huge_ptep_get() to dereference a huge pte pointer, accessing via ptep_get() would cause pte_pfn(), pte_present() etc to misbehave.
It is not clear whether this has a trivially visible effect to userspace.
Just use huge_ptep_get() for dereferencing a huge pte pointer.
--- include/linux/hugetlb.h | 2 ++ mm/rmap.c | 16 ++++++++++------ 2 files changed, 12 insertions(+), 6 deletions(-)
include/linux/hugetlb.h +2 -0
@@ -1262,6 +1262,8 @@ static inline void hugetlb_count_sub(lon { } +pte_t huge_ptep_get (struct mm_struct *mm,unsigned long addr,pte_t *ptep); +static inline pte_t huge_ptep_clear_flush (struct vm_area_struct *vma,unsigned long addr,pte_t *ptep) {
mm/rmap.c +10 -6
@@ -2095,14 +2095,19 @@ static bool try_to_unmap_one(struct foli/* Unexpected PMD-mapped THP? */ VM_BUG_ON_FOLIO (!pvmw.pte, folio); -/* -* Handle PFN swap PTEs, such as device-exclusive ones, that -* actually map pages. -*/ - pteval =ptep_get (pvmw.pte); + address = pvmw.address; +if (folio_test_hugetlb (folio)) { + pteval =huge_ptep_get (mm, address, pvmw.pte); + }else { + pteval =ptep_get (pvmw.pte); + }if (likely (pte_present (pteval))) { pfn =pte_pfn (pteval); }else { +/* +* Handle PFN swap PTEs, such as device-exclusive ones, +* that actually map pages. +*/ const softleaf_t entry =softleaf_from_pte (pteval); pfn =softleaf_to_pfn (entry);
@@ -2110,7 +2115,6 @@ static bool try_to_unmap_one(struct foli } subpage =folio_page (folio, pfn -folio_pfn (folio)); - address = pvmw.address; anon_exclusive =folio_test_anon (folio) &&PageAnonExclusive (subpage);
Greg Kroah-Hartman
maintainerPATCH 65/713 mm/rmap: use huge_ptep_get() in try_to_migrate_one()
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dev Jain <[email protected]>
commit 9be12ffa78cd087d41086f937a156435d4e588e9 upstream.
try_to_migrate_one() is used by folio migration to replace a present mapping with a migration entry. For hugetlb folios, page_vma_mapped_walk() returns the pte pointer to the hugetlb folio in pvmw.pte, but the code reads the huge pte entry with ptep_get().
On arches which provide their own huge_ptep_get() to dereference a huge pte pointer, accessing via ptep_get() would cause pte_pfn(), pte_present() etc to misbehave.
It is not clear whether this has a trivially visible effect to userspace.
Use huge_ptep_get() to dereference a huge pte pointer.
Commit a98a2f0c8ce1 copied the bug from try_to_unmap_one into try_to_migrate_one.
--- mm/rmap.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
mm/rmap.c +9 -6
@@ -2505,14 +2505,18 @@ static bool try_to_migrate_one(struct fo/* Unexpected PMD-mapped THP? */ VM_BUG_ON_FOLIO (!pvmw.pte, folio); -/* -* Handle PFN swap PTEs, such as device-exclusive ones, that -* actually map pages. -*/ - pteval =ptep_get (pvmw.pte); + address = pvmw.address; +if (folio_test_hugetlb (folio)) + pteval =huge_ptep_get (mm, address, pvmw.pte); +else + pteval =ptep_get (pvmw.pte);if (likely (pte_present (pteval))) { pfn =pte_pfn (pteval); }else { +/* +* Handle PFN swap PTEs, such as device-exclusive ones, +* that actually map pages. +*/ const softleaf_t entry =softleaf_from_pte (pteval); pfn =softleaf_to_pfn (entry);
@@ -2520,7 +2524,6 @@ static bool try_to_migrate_one(struct fo } subpage =folio_page (folio, pfn -folio_pfn (folio)); - address = pvmw.address; anon_exclusive =folio_test_anon (folio) &&PageAnonExclusive (subpage);
Greg Kroah-Hartman
maintainerPATCH 66/713 mm/slub: fix missing debugfs entries for caches created before sysfs init
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Li Xiasong <[email protected]>
commit 7e98f856395618011c517f767fb80ac3fe90de2b upstream.
slab_debugfs_init() creates the slab debugfs root at device initcall time, while slab_sysfs_init() moves slab_state to FULL at late initcall time. SLAB_STORE_USER caches created in this window miss their debugfs entries because do_kmem_cache_create() skips debugfs_slab_add() when slab_state <= UP. This was observed with MPTCP's request_sock_subflow_v6 cache, whose slab debugfs directory was missing.
The affected window is:
slab_debugfs_init()
slab_debugfs_root = debugfs_create_dir(...)
list_for_each_entry(s, &slab_caches, list)
debugfs_slab_add(s)
kmem_cache_create(..., SLAB_STORE_USER, ...)
do_kmem_cache_create()
if (slab_state <= UP)
return without debugfs entries
slab_sysfs_init()
slab_state = FULL
Initialize the debugfs root and add debugfs entries while holding slab_mutex, walking slab_caches exactly once and handling both sysfs and debugfs entries in the same pass. This gives the sysfs and debugfs initialization an explicit order and prevents caches from being created between the debugfs scan and slab_state reaching FULL.
Gate the new slab_late_init() on either sysfs or debugfs being enabled, with the slab_kset creation and alias_list processing factored into helpers that have empty no-sysfs variants, as suggested by Vlastimil Babka. On slab_kset_init() failure, slab_state stays below FULL so kmem_cache_create() keeps taking the early-boot path, matching prior behavior.
Guard debugfs_slab_release() against an uninitialized debugfs root, since the root is now created later and a cache may be released before it exists.
--- mm/slub.c | 76 +++++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 48 insertions(+), 28 deletions(-)
mm/slub.c +48 -28
@@ -333,14 +333,20 @@ enum track_item { TRACK_ALLOC, TRACK_FRE#ifdef SLAB_SUPPORTS_SYSFS static int sysfs_slab_add (struct kmem_cache *); +static int __init slab_kset_init (void ); +static void __init slab_sysfs_process_aliases (void );#else static inline int sysfs_slab_add (struct kmem_cache *s) {return 0 ; } +static inline int slab_kset_init (void ) {return 0 ; } +static inline void slab_sysfs_process_aliases (void ) { }#endif #if defined(CONFIG_DEBUG_FS ) && defined(CONFIG_SLUB_DEBUG )static void debugfs_slab_add (struct kmem_cache *); +static void __init slab_debugfs_root_init (void );#else static inline void debugfs_slab_add (struct kmem_cache *s) { } +static inline void slab_debugfs_root_init (void ) { }#endif enum add_mode {
@@ -9734,28 +9740,20 @@ int sysfs_slab_alias(struct kmem_cache *return 0 ; } -static int __init slab_sysfs_init (void ) +static int __init slab_kset_init (void ) { -struct kmem_cache *s; -int err; - -mutex_lock (&slab_mutex); - slab_kset =kset_create_and_add ("slab" ,NULL , kernel_kobj);if (!slab_kset) { -mutex_unlock (&slab_mutex);pr_err ("Cannot register slab subsystem.\n" );return -ENOMEM ; } - slab_state =FULL ; +return 0 ; +} -list_for_each_entry (s, &slab_caches, list) { - err =sysfs_slab_add (s); -if (err) -pr_err ("SLUB: Unable to add boot slab %s to sysfs\n" , - s->name); - } +static void __init slab_sysfs_process_aliases (void ) +{ +int err;while (alias_list) {struct saved_alias *al = alias_list;
@@ -9767,12 +9765,41 @@ static int __init slab_sysfs_init(void) al->name); kfree(al); } +} +#endif /* SLAB_SUPPORTS_SYSFS */ + +#if defined(SLAB_SUPPORTS_SYSFS ) || \ + (defined(CONFIG_SLUB_DEBUG ) && defined(CONFIG_DEBUG_FS )) +static int __init slab_late_init (void ) +{ +struct kmem_cache *s; +int err; +mutex_lock (&slab_mutex); + + err =slab_kset_init (); +if (err) + goto out; + +slab_debugfs_root_init (); + slab_state =FULL ; + +list_for_each_entry (s, &slab_caches, list) { +if (sysfs_slab_add (s)) +pr_err ("SLUB: Unable to add boot slab %s to sysfs\n" , + s->name); + +if (s->flags &SLAB_STORE_USER ) +debugfs_slab_add (s); + } + +slab_sysfs_process_aliases (); +out:mutex_unlock (&slab_mutex); -return 0 ; +return err; } -late_initcall (slab_sysfs_init); -#endif /* SLAB_SUPPORTS_SYSFS */ +late_initcall (slab_late_init); +#endif #if defined(CONFIG_SLUB_DEBUG ) && defined(CONFIG_DEBUG_FS )static int slab_debugfs_show (struct seq_file *seq,void *v)
@@ -9964,23 +9991,16 @@ static void debugfs_slab_add(struct kmemvoid debugfs_slab_release (struct kmem_cache *s) { +if (unlikely (!slab_debugfs_root)) +return ; +debugfs_lookup_and_remove (s->name, slab_debugfs_root); } -static int __init slab_debugfs_init (void ) +static void __init slab_debugfs_root_init (void ) { -struct kmem_cache *s; - slab_debugfs_root =debugfs_create_dir ("slab" ,NULL ); - -list_for_each_entry (s, &slab_caches, list) -if (s->flags &SLAB_STORE_USER ) -debugfs_slab_add (s); - -return 0 ; - } -__initcall (slab_debugfs_init);#endif /* * The /proc/slabinfo ABI
Greg Kroah-Hartman
maintainerPATCH 67/713 mm/slub: prevent pfmemalloc objects from entering the barn
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shengming Hu <[email protected]>
commit 9338b189be6895e45cf6fcf819c55cd3c47e4a18 upstream.
kmem_cache_return_sheaf() may refill a partially consumed sheaf before placing it in the barn. Without an explicit restriction, this refill may draw objects from pfmemalloc slabs and consume emergency reserves.
Add __GFP_NOMEMALLOC so that returned sheaves are refilled only from non-pfmemalloc slabs. Also add __GFP_NOWARN, as suggested by Hao Li, because this refill is a best-effort attempt and failure is acceptable. If the refill fails, flush and free the sheaf instead.
--- mm/slub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/slub.c +1 -1
@@ -5153,7 +5153,7 @@ void kmem_cache_return_sheaf(struct kmem* simply flush and free it. */ if (!barn ||data_race (barn->nr_full) >=MAX_FULL_SHEAVES || -refill_sheaf (s, sheaf, gfp)) { +refill_sheaf (s, sheaf, gfp | __GFP_NOMEMALLOC | __GFP_NOWARN)) {sheaf_flush_unused (s, sheaf);free_empty_sheaf (s, sheaf);return ;
Greg Kroah-Hartman
maintainerPATCH 68/713 mm/vmalloc: make vm_struct.nr_pages an unsigned long
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Artem Lytkin <[email protected]>
commit 272b0d84b17f72f6396254dbaa6264f2f74a7997 upstream.
vm_struct::nr_pages is an unsigned int, and the file keeps deriving byte counts from it as nr_pages << PAGE_SHIFT. A shift is evaluated in the type of its promoted left operand, so those are 32-bit arithmetic and wrap at 4 GiB of bytes, which is 2^20 pages. Every site depends on a cast being remembered; vmap() has one, two recent commits did not. vread_iter() then computes a size of zero for a 4 GiB VM_ALLOC area and /proc/kcore returns it as zeros while reporting a successful read, which drgn, crash or gdb cannot tell from real memory, and the vrealloc() grow-in-place check declines a request that would have fit.
Widen the field so the class of bug goes away instead of one site at a time. Everything feeding or consuming it widens too:vm_area_alloc_pages() and its accumulators, nr_small_pages, new_nr_pages and old_nr_pages, the index range of vm_area_free_pages(), and three page indexes that were plain int. Five casts go. Two prints needed fixing as well, %u in vmalloc_dump_obj() and %d for the unsigned field in vmalloc_info_show().
No bug report behind this, I found it reading the code. The 4 GiB wrap needs only a machine with over 4 GiB of memory. Neither larger threshold is a practical concern: 2^32 pages, where the field itself truncates, is 16 TiB and beyond what hardware can populate, and 2^31, where the plain int indexes break, is 8 TiB and larger than anything in the tree asks for. The int *nr cursor in the mapping path is unchanged and is separate work. Users outside mm/vmalloc.c need no change either. Those handing the count to a narrower parameter cannot drive it near 2^31, and kho_preserve_vmalloc() stores it into a 32-bit ABI field that still receives the same low bits; above 2^32 pages the truncation just moves out of vm_struct into that store.
sizeof(struct vm_struct) on x86-64 stays 72 bytes with CONFIG_HAVE_ARCH_HUGE_VMALLOC=n and goes from 72 to 80 with it enabled, both inside the kmalloc-96 bucket it already comes from.
--- include/linux/vmalloc.h | 2 - mm/vmalloc.c | 60 +++++++++++++++++++++++------------------------- 2 files changed, 30 insertions(+), 32 deletions(-)
include/linux/vmalloc.h +1 -1
@@ -62,7 +62,7 @@ struct vm_struct {#ifdef CONFIG_HAVE_ARCH_HUGE_VMALLOC unsigned int page_order;#endif -unsigned int nr_pages; +unsigned long nr_pages;phys_addr_t phys_addr;const void *caller;unsigned long requested_size;
mm/vmalloc.c +29 -31
158 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 69/713 mm/vmscan: report RCU-tasks quiescent states in shrink_lruvec()
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao <[email protected]>
commit 25f52e81216884a7444bf07a606691feb09a94e3 upstream.
I am seeing some rcu_tasks stalls in the Meta fleet during reclaim.
INFO: rcu_tasks detected stalls on tasks: 0000000088620d09: .. nvcsw: 6735/6735 holdout: 1 idle_cpu: -1/8 task:GlobalCPUThread state:R running task pid:2552016 tgid:2524552 Call Trace: shrink_lruvec mem_cgroup_iter shrink_node do_try_to_free_pages try_to_free_pages __alloc_frozen_pages_noprof alloc_pages_noprof pte_alloc_one __pte_alloc handle_mm_fault
Nothing promises direct reclaim returns in bounded time, and the scan loop in shrink_lruvec() only calls cond_resched(), which is a no-op on PREEMPTION kernels. Involuntary preemption is not a Tasks-RCU quiescent state, so the reclaiming task never reports one and becomes a holdout.
Upgrade it to cond_resched_tasks_rcu_qs(), which reports a quiescent state even when cond_resched() does nothing.
PS: This has been discussed in [1]
--- mm/vmscan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/vmscan.c +1 -1
@@ -5918,7 +5918,7 @@ static void shrink_lruvec(struct lruvec } } -cond_resched (); +cond_resched_tasks_rcu_qs ();if (nr_reclaimed < nr_to_reclaim || proportional_reclaim)continue ;
Greg Kroah-Hartman
maintainerPATCH 70/713 mm/zswap: fix global shrinker when memory cgroup is disabled
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hao Jia <[email protected]>
commit dc8458f43fe964d8ade74c9b0fce54fe71d156de upstream.
Patch series "mm/zswap: Fixes and improves the zswap shrink", v4.
This series fixes and improves the zswap global shrinker (shrink_worker()): Patch 1: Fix missing global shrinker when memory cgroup is disabled. Patch 2: Extend shrink_memcg() to support batch writeback and thereby improving the writeback efficiency in the shrink_worker() and zswap_store() paths.
This patch (of 2):
Zswap writeback when the global pool limit is hit fails when memory cgroup is disabled. The pool remains full until it is organically drained by swapins or memory freeing, leading to zswap store failures and pages bypassing getting written directly to the backing swap device, causing LRU inversion (hotter pages with higher fault latency).
This happens because mem_cgroup_iter() always returns NULL when memory cgroups are disabled. As a result, the global shrinker shrink_worker() repeatedly takes empty walks. After MAX_RECLAIM_RETRIES failed attempts, the worker gives up without writing back any pages.
Therefore, when memory cgroup is disabled, fall through with the !memcg branch and shrink the root memcg directly.
With memcg disabled, shrink_memcg() only returns -ENOENT when the root LRU is empty, which means the total pages are already below thr. In the absence of heavy concurrent zswap stores, the loop then safely bails out via the zswap_total_pages() <= thr check; otherwise, it will resume shrinking the memcg after processing the reschedule check. For any other return value from shrink_memcg(), the loop is guaranteed to terminate, either after MAX_RECLAIM_RETRIES failures or once the threshold is met.
This is a potential performance regression for people using zswap without memcg that was introduced by the commit in "Fixes".
--- mm/zswap.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
mm/zswap.c +7 -6
@@ -1356,11 +1356,12 @@ static void shrink_worker(struct work_st }while (memcg && !mem_cgroup_tryget_online (memcg));spin_unlock (&zswap_shrink_lock); -if (!memcg) { -/* -* Continue shrinking without incrementing failures if -* we found candidate memcgs in the last tree walk. -*/ +/* +* A NULL memcg ends a full hierarchy pass (except when memcg is +* disabled, where it is always NULL: fall through to the root LRU). +* Count a failure only if the last pass found no candidates. +*/ +if (!memcg && !mem_cgroup_disabled ()) {if (!attempts && ++failures ==MAX_RECLAIM_RETRIES )break ;
@@ -1379,7 +1380,7 @@ static void shrink_worker(struct work_st* and failures. */ if (ret == -ENOENT ) -continue ; + goto resched; ++attempts;if (ret && ++failures ==MAX_RECLAIM_RETRIES )
Greg Kroah-Hartman
maintainerPATCH 71/713 mm: compaction: support non-movable compaction for pageblock requests
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Weiner <[email protected]>
commit 1b4b697a5743e624cc259d6c31a8d8716b796305 upstream.
While trying to fix a reclaim storm in defrag_mode, I noticed that non-movable direct compaction is extremely inefficient.
When searching for space to evacuate, compaction only allows blocks of the same type as the incoming request. This is to prevent migratetype pollution, where a small non-movable request frees space in a movable block and provokes the allocator to fall back and pollute it.
This protection is reasonable on one hand, but the downside is that it makes non-movable direct compaction nearly useless: if we get the type annotations right, by definition there aren't any movable pages inside the non-movable blocks it is allowed to scan.
With defrag_mode, the goal is the production of whole blocks, which are essentially type neutral: __rmqueue_claim() will convert them wholesale on alloc. This makes type mixing and pollution a non-issue.
Fix the pollution gates to take the requested order into account, and allow whole-block requests to scan blocks of other types.
The only exception is CMA blocks. That type is sticky and these blocks cannot be claimed to other types. Continue to be strict with them, and allow only explicit ALLOC_CMA requests and kcompactd to evacuate them.
--- mm/compaction.c | 46 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 7 deletions(-)
mm/compaction.c +39 -7
@@ -1381,12 +1381,44 @@ static bool suitable_migration_source(stif (pageblock_skip_persistent (page))return false; -if ((cc->mode !=MIGRATE_ASYNC ) || !cc->direct_compaction) +/* +* Background compaction produces blocks for the zone at +* large, with no particular allocation context. Allow all +* block types, including CMA. +*/ +if (!cc->direct_compaction)return true; block_mt =get_pageblock_migratetype (page); -if (cc->migratetype ==MIGRATE_MOVABLE ) +/* +* CMA pages can only be taken by ALLOC_CMA requests. For anybody +* else, vacating a CMA block consumes free pages the caller +* could have used, and produces free pages it cannot. +*/ +if (is_migrate_cma (block_mt) && !(cc->alloc_flags &ALLOC_CMA )) +return false; + +/* +* Per default, scans are restricted to blocks compatible with +* the request, to prevent cross-contamination. Once +* compaction priority escalates to synchronous scans, though, +* scan all blocks to try to make forward progress. For +* movable request, this likely helps little: there shouldn't +* be many migratable pages inside non-movable blocks besides +* allocator fallbacks. For non-movable requests, this helps a +* lot, as they can finally scan movable blocks. +*/ +if (cc->mode !=MIGRATE_ASYNC ) +return true; + +/* +* Prevent <pageblock_order unmovable/reclaimable requests from +* polluting movable blocks through fallbacks. Whole-block production +* (directly requested, or defrag_mode) is exempt as the allocator +* claims and converts these. +*/ +if (cc->migratetype ==MIGRATE_MOVABLE || cc->order >= pageblock_order)return is_migrate_movable (block_mt);else return block_mt == cc->migratetype;
@@ -1974,12 +2006,12 @@ static unsigned long fast_find_migrateblreturn pfn;/* -* Only allow kcompactd and direct requests for movable pages to -* quickly clear out a MOVABLE pageblock for allocation. This -* reduces the risk that a large movable pageblock is freed for -* an unmovable/reclaimable small allocation. +* Prevent <pageblock_order unmovable/reclaimable requests from +* polluting movable blocks through fallbacks. Whole-block production +* is exempt as the allocator claims and converts these. */ -if (cc->direct_compaction && cc->migratetype !=MIGRATE_MOVABLE ) +if (cc->direct_compaction && cc->migratetype !=MIGRATE_MOVABLE && + cc->order < pageblock_order)return pfn;/*
Greg Kroah-Hartman
maintainerPATCH 72/713 mm: memcg-v1: fix wrong linux-mm list address in deprecation warnings
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guopeng Zhang <[email protected]>
commit 45b1ec4887bdcc58af885540d9fefa8b67d17d57 upstream.
The deprecation warnings for memory.oom_control and memory.pressure_level use [email protected] instead of the linux-mm mailing list address. Remove the extra hyphen.
--- mm/memcontrol-v1.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
mm/memcontrol-v1.c +3 -3
@@ -1181,13 +1181,13 @@ static ssize_t memcg_write_event_control event->unregister_event = mem_cgroup_usage_unregister_event; }else if (!strcmp (name,"memory.oom_control" )) {pr_warn_once ("oom_control is deprecated and will be removed. " -"Please report your usecase to [email protected]" +"Please report your usecase to [email protected]" " if you depend on this functionality.\n" ); event->register_event = mem_cgroup_oom_register_event; event->unregister_event = mem_cgroup_oom_unregister_event; }else if (!strcmp (name,"memory.pressure_level" )) {pr_warn_once ("pressure_level is deprecated and will be removed. " -"Please report your usecase to [email protected] " +"Please report your usecase to [email protected] " "if you depend on this functionality.\n" ); event->register_event = vmpressure_register_event; event->unregister_event = vmpressure_unregister_event;
@@ -2040,7 +2040,7 @@ static int mem_cgroup_oom_control_write(struct mem_cgroup *memcg =mem_cgroup_from_css (css);pr_warn_once ("oom_control is deprecated and will be removed. " -"Please report your usecase to [email protected] if you " +"Please report your usecase to [email protected] if you " "depend on this functionality.\n" );/* cannot set to root cgroup and only 0 and 1 are allowed */
Greg Kroah-Hartman
maintainerPATCH 73/713 mm: memcg-v1: fix memsw and TCP failcnt accounting
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guopeng Zhang <[email protected]>
commit 92192e9c5ee07efc657d3654bc264081fb0aa01b upstream.
Commit 0e2759afcaf9 ("page_counter: track failcnt only for legacy cgroups") made failcnt accounting conditional on track_failcnt. It enabled the flag for memcg->memory, but not for memcg->memsw or memcg->tcpmem.
Consequently, memory.memsw.failcnt remains zero when the memory+swap limit is hit. memory.kmem.tcp.limit_in_bytes still sets memcg->tcpmem.max, but TCP charge failures are not reflected in memory.kmem.tcp.failcnt.
Enable failcnt accounting for both v1 counters.
To reproduce memory.memsw.failcnt:
CG=/sys/fs/cgroup/memory/memsw-test
LIMIT=33554432
mkdir "$CG"
echo "$LIMIT" > "$CG/memory.limit_in_bytes"
echo "$LIMIT" > "$CG/memory.memsw.limit_in_bytes"Start a child process in the cgroup and make it allocate and touch 96 MiB of memory, causing a memcg OOM.
cat "$CG/memory.memsw.failcnt"
Without the patch, memory.memsw.failcnt is 0. With the patch, memory.memsw.failcnt is greater than 0.
To reproduce memory.kmem.tcp.failcnt:
CG=/sys/fs/cgroup/memory/tcpmem-test
LIMIT=65536
mkdir "$CG"
echo "$LIMIT" > "$CG/memory.kmem.tcp.limit_in_bytes"Start a child process in the cgroup, create a TCP socket, and reserve 1 MiB of socket memory with SO_RESERVE_MEM. The reservation fails with ENOMEM.
cat "$CG/memory.kmem.tcp.failcnt"
Without the patch, memory.kmem.tcp.failcnt is 0. With the patch, memory.kmem.tcp.failcnt is greater than 0.
--- mm/memcontrol.c | 2 ++ 1 file changed, 2 insertions(+)
mm/memcontrol.c +2 -0
@@ -4180,9 +4180,11 @@ mem_cgroup_css_alloc(struct cgroup_subsypage_counter_init (&memcg->swap, &parent->swap, false);#ifdef CONFIG_MEMCG_V1 memcg->memory.track_failcnt = !memcg_on_dfl; + memcg->memsw.track_failcnt = !memcg_on_dfl;WRITE_ONCE (memcg->oom_kill_disable,READ_ONCE (parent->oom_kill_disable));page_counter_init (&memcg->kmem, &parent->kmem, false);page_counter_init (&memcg->tcpmem, &parent->tcpmem, false); + memcg->tcpmem.track_failcnt = !memcg_on_dfl;#endif }else {init_memcg_stats ();
Greg Kroah-Hartman
maintainerPATCH 74/713 mm: memcg: stop reclaim when a limit update is superseded
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guopeng Zhang <[email protected]>
commit 9477820c63cbf4d97114238f3d1ff10dfd6bee3f upstream.
kernfs serializes file operations only per open file, so separate open files can update the same memory.high or memory.max file concurrently. Both handlers store the new limit before synchronous reclaim, but continue to use the writer's local target in the reclaim loop. If another writer raises or removes the limit, the first writer can continue reclaiming toward a stale target.
For memory.max, this can leave the writer looping indefinitely once reclaim retries are exhausted. The OOM path sees sufficient margin under the current limit and returns true without killing, while the writer still compares usage against its stale target and records another OOM event.
Check the current limit at the start of each reclaim iteration and stop if it no longer matches the writer's target.
Reproducer:
Populate a cgroup with anonymous memory and disable swapping. Lower memory.max from one open file, then restore it to "max" through another open file after the new limit becomes visible.
Without the patch, the first writer remains blocked and repeatedly increments the OOM event counter. With the patch, it returns normally.
This was not motivated by a reported production workload. We found it through automated randomized testing for our cgroup observability work and reduced it to the reproducer above.
--- mm/memcontrol.c | 6 ++++++ 1 file changed, 6 insertions(+)
mm/memcontrol.c +6 -0
@@ -4790,6 +4790,9 @@ static ssize_t memory_high_write(structunsigned long nr_pages =page_counter_read (&memcg->memory);unsigned long reclaimed; +if (high !=READ_ONCE (memcg->memory.high)) +break ; +if (nr_pages <= high)break ;
@@ -4841,6 +4844,9 @@ static ssize_t memory_max_write(struct kfor (;;) {unsigned long nr_pages =page_counter_read (&memcg->memory); +if (max !=READ_ONCE (memcg->memory.max)) +break ; +if (nr_pages <= max)break ;
Greg Kroah-Hartman
maintainerPATCH 75/713 mm: memcontrol: update state_local when flushing NMI stats
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guopeng Zhang <[email protected]>
commit 72f522bbf473f03a77e83547b677dc1505c5d41a upstream.
flush_nmi_stats() updates state[] for kmem and slab counters but leaves the corresponding state_local[] counters unchanged. Local kmem and slab statistics therefore miss updates collected through the NMI-safe atomic path.
Update state_local[] together with state[].
--- mm/memcontrol.c | 5 +++++ 1 file changed, 5 insertions(+)
mm/memcontrol.c +5 -0
@@ -4440,6 +4440,7 @@ static void flush_nmi_stats(struct mem_cint index =memcg_stats_index (MEMCG_KMEM ); memcg->vmstats->state[index] += kmem; + memcg->vmstats->state_local[index] += kmem;if (parent) parent->vmstats->state_pending[index] += kmem; }
@@ -4457,9 +4458,11 @@ static void flush_nmi_stats(struct mem_cint index =memcg_stats_index (NR_SLAB_RECLAIMABLE_B ); lstats->state[index] += slab; + lstats->state_local[index] += slab;if (plstats) plstats->state_pending[index] += slab; memcg->vmstats->state[index] += slab; + memcg->vmstats->state_local[index] += slab;if (parent) parent->vmstats->state_pending[index] += slab; }
@@ -4468,9 +4471,11 @@ static void flush_nmi_stats(struct mem_cint index =memcg_stats_index (NR_SLAB_UNRECLAIMABLE_B ); lstats->state[index] += slab; + lstats->state_local[index] += slab;if (plstats) plstats->state_pending[index] += slab; memcg->vmstats->state[index] += slab; + memcg->vmstats->state_local[index] += slab;if (parent) parent->vmstats->state_pending[index] += slab; }
Greg Kroah-Hartman
maintainerPATCH 76/713 mm: mempolicy: fix automatic numa balancing for shmem
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Weiner <[email protected]>
commit d230991493b521eeff39f32434fddcbcdb109eb0 upstream.
Neha reports that mapped shmem aren't considered for NUMA balancing, noting convergence problems and bandwidth bottlenecking for cachelib based workloads on tiered memory systems.
Looking at the code and going through the git history, this doesn't actually seem intentional:
Commit fc3147245d19 ("mm: numa: Limit NUMA scanning to migrate-on-fault VMAs") added a vma_policy_mof() gate to task_numa_work() so VMAs whose policy lacks MPOL_F_MOF are skipped from NUMA balancing scans. The motivation was a real usecase: Oracle was pinning shared segments with mbind(MPOL_BIND) so trapping faults was both expensive and pointless.
The handling of NULL from vm_ops->get_policy, however, treated "user explicitly opted out" the same as "user never specified anything." For VMAs whose shared policy is absent - the common case for shmem - the scan was disabled too.
This issue is old. It probably hurts less in conventional NUMA. But it's very noticeable on tiered systems, where entire tmpfs workingsets can get stuck on lower-bandwidth memory.
Fix this by having vma_policy_mof() use __get_vma_policy() directly, and thereby handle the fallback to task policy (-> preferred_node_policy() has MPOL_F_MOF per default). Every other consumer of vm_ops->get_policy already handles it this way, the scan-eligibility check was the outlier.
This preserves Mel's intended fix: don't scan stuff the user explicitly pinned. But allow default policy vmas to participate in balancing.
--- mm/mempolicy.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-)
mm/mempolicy.c +6 -15
@@ -2059,24 +2059,15 @@ struct mempolicy *get_vma_policy(structbool vma_policy_mof (struct vm_area_struct *vma) {struct mempolicy *pol; +pgoff_t ilx; +bool mof; -if (vma->vm_ops && vma->vm_ops->get_policy) { -bool ret = false; -pgoff_t ilx;/* ignored here */ - - pol = vma->vm_ops->get_policy (vma, vma->vm_start, &ilx); -if (pol && (pol->flags &MPOL_F_MOF )) - ret = true; -mpol_cond_put (pol); - -return ret; - } - - pol = vma->vm_policy; + pol =__get_vma_policy (vma, vma->vm_start, &ilx);if (!pol) pol =get_task_policy (current); - -return pol->flags &MPOL_F_MOF ; + mof = pol->flags &MPOL_F_MOF ; +mpol_cond_put (pol); +return mof; }bool apply_policy_zone (struct mempolicy *policy,enum zone_type zone)
Greg Kroah-Hartman
maintainerPATCH 77/713 mm: page_alloc: __GFP_FS lockdep annotation for direct compaction
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Weiner <[email protected]>
commit 37864d0bf5a4d60da6109b9078cc78ef3fc81216 upstream.
Patch series "mm: fix reclaim storms in defrag_mode", v2.
As we deployed vm.defrag_mode=1 in Meta production, some workloads regressed with recurring pressure spikes and swap storms (which in turn triggered userspace OOM rules on pressure and swap utilization levels).
Tracing pinned this to non-movable requests spinning and reclaiming unproductively when kswapd/kcompactd are overwhelmed. Direct reclaim predominantly frees up pages in movable blocks, but those requests cannot use that space under defrag_mode rules; and it is unlikely to free up whole blocks incidentally for __rmqueue_claim() to work.
This series fixes it by making non-movable requests participate in pageblock production in the allocator slowpath - meaning, they will invoke direct reclaim and direct compaction with pageblock_order.
That requires some small-ish adjustments up front in the allocator and the compaction code: three prep patches and the fix last.
The series has been in production against one of the affected workloads for several weeks and restores the OOM kill rate to !defrag_mode baseline.
This patch (of 4):
A subsequent patch will have some order-0 allocations participate in compaction under defrag_mode, to stave off extfrag events.
Since this is a sprawling expansion of entry points, and compaction can enter filesystem paths, add lockdep annotations that catches __GFP_FS passing errors.
Direct reclaim has had this annotation for a while, and since reclaim and compaction are usually used in conjunction, this is unlikely to unearth old bugs. It's more about future proofing and peace of mind.
--- mm/page_alloc.c | 2 ++ 1 file changed, 2 insertions(+)
mm/page_alloc.c +2 -0
@@ -4152,12 +4152,14 @@ __alloc_pages_direct_compact(gfp_t gfp_mpsi_memstall_enter (&pflags);delayacct_compact_start (); +fs_reclaim_acquire (gfp_mask); noreclaim_flag =memalloc_noreclaim_save (); *compact_result =try_to_compact_pages (gfp_mask, order, alloc_flags, ac, prio, &page);memalloc_noreclaim_restore (noreclaim_flag); +fs_reclaim_release (gfp_mask);psi_memstall_leave (&pflags);delayacct_compact_end ();
Greg Kroah-Hartman
maintainerPATCH 78/713 mm: page_alloc: move capture_control to the page allocator
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vlastimil Babka (SUSE) <[email protected]>
commit aee220f565cce38f0efcff940ae2b44bdc495408 upstream.
The compaction capturing code assumes the allocation request order and compaction target order are the same. That won't be true once defrag_mode promotes sub-block allocations to pageblock-order compaction: compaction targets the larger order, while capture should remain at the original allocation order.
Move the capture_control to the page allocator and give it its own copies of what the page freeing path matches against - zone, migratetype and the allocation order - rather than reaching into compaction's live compact_control. __alloc_pages_direct_compact() fills in migratetype and order, and installs and hides current->capture_control around the whole compaction call; try_to_compact_pages() aims capc->zone at each zone while it is being compacted. compact_zone_order() no longer deals with capture at all.
Pass the capture_control through try_to_compact_pages() / compact_zone_order() in place of the bare struct page **.
No functional change.
--- include/linux/compaction.h | 3 +- mm/compaction.c | 50 ++++++++++++--------------------------------- mm/internal.h | 4 ++- mm/page_alloc.c | 45 ++++++++++++++++++++++++++++++++++------ 4 files changed, 57 insertions(+), 45 deletions(-)
include/linux/compaction.h +2 -1
@@ -58,6 +58,7 @@ enum compact_result { };struct alloc_context ;/* in mm/internal.h */ +struct capture_control ;/* in mm/internal.h */ /* * Number of free order-0 pages that should be available above given watermark
@@ -92,7 +93,7 @@ extern int fragmentation_index(struct zoextern enum compact_result try_to_compact_pages (gfp_t gfp_mask,unsigned int order,unsigned int alloc_flags,const struct alloc_context *ac,enum compact_priority prio, -struct page **page); +struct capture_control *capc);extern void reset_isolation_suitable (pg_data_t *pgdat);extern bool compaction_suitable (struct zone *zone,int order,unsigned long watermark,int highest_zoneidx);
mm/compaction.c +14 -36
82 lines not on this page · raw message
mm/internal.h +3 -1
@@ -1059,7 +1059,9 @@ struct compact_control {* immediately when one is created during the free path. */ struct capture_control { -struct compact_control *cc; +struct zone *zone; +int migratetype; +int order;struct page *page; };
mm/page_alloc.c +38 -7
78 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 79/713 mm: page_alloc: fix non-movable reclaim storm in defrag_mode
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Weiner <[email protected]>
commit 7e8756d7ad22655b935c384f123071aa9de07a27 upstream.
As we deployed defrag_mode into Meta production, pressure spikes and excessive swapping were observed on some workloads. Tracing confirmed that this is unmovable/reclaimable requests spinning in the allocator and direct reclaim, causing excessive amounts of swap.
The initial plan for defrag_mode was to rely on kswapd/kcompactd to produce blocks, and if those are overwhelmed under high pressure, let the allocator fall back (__rmqueue_steal()) after its retry loops. However, that retrying results in more reclaim on some of these workloads than we'd hoped, sometimes excessively so, spurred on by the !costly order conditions in should_reclaim_retry().
The storms are dependent on the request type. Reclaim will inevitably make room in existing movable blocks, since that's where the LRU pages live. So if movable requests retry on reclaim, they make progress.
When non-movable requests spin in reclaim that isn't productive. They cannot use the individually freed pages, and the process is unlikely to accidentally free whole blocks to meet the ALLOC_NOFRAGMENT bar. They spin and overreclaim excessively, which tanks performance and triggers userspace guards like swap exhaustion or pressure based OOM.
To fix this, send non-movable requests, regardless of order, into pageblock reclaim/compaction. This way, they help move things along to meet the ALLOC_NOFRAGMENT bar. After this patch, the reclaim storms and excess OOM rates are no longer observed in production.
The longer-term plan is still to have all requests, including the movable ones, help make blocks to spread the cost of defragmenting more evenly and fairly; combined with proper watermarking to reduce allocation latencies in the common case. However, doing this naively unearths scaling and concurrency limitations in compaction that need to be addressed first. Promoting just non-movables for now is the minimally viable bug fix for the above issue.
--- mm/compaction.c | 2 +- mm/internal.h | 6 ++++++ mm/page_alloc.c | 31 ++++++++++++++++++++++++++----- 3 files changed, 33 insertions(+), 6 deletions(-)
mm/compaction.c +1 -1
@@ -2825,7 +2825,7 @@ static enum compact_result compact_zone_/** * try_to_compact_pages - Direct compact to satisfy a high-order allocation * @gfp_mask: The GFP mask of the current allocation -* @order: The order of the current allocation +* @order: The order to try to make available * @alloc_flags: The allocation flags of the current allocation * @ac: The context of current allocation * @prio: Determines how hard direct compaction should try to succeed
mm/internal.h +6 -0
@@ -1061,6 +1061,12 @@ struct compact_control {struct capture_control {struct zone *zone;int migratetype; +/* +* Allocation request order. May differ from the compaction +* order: defrag_mode promotes sub-block allocations to +* pageblock-order compaction; capture still matches at the +* original allocation order so prep_new_page() is consistent. +*/ int order;struct page *page; };
mm/page_alloc.c +26 -5
@@ -4152,8 +4152,24 @@ __alloc_pages_direct_compact(gfp_t gfp_m .order = order, .page = NULL, }; +int compact_order = order; -if (!order) +/* +* If fallbacks are not permitted (defrag_mode), we either +* need to reclaim space in a block of matching type, or clear +* out an entire block to allow __rmqueue_claim() to convert. +* +* Reclaim by itself is primarily freeing space in movable +* blocks, since that's where the LRU pages live. So this +* works for movable requests, but not for others. +* +* For those, promote the order to help make blocks, instead +* of spinning in reclaim alone unproductively. +*/ +if ((alloc_flags &ALLOC_NOFRAGMENT ) && ac->migratetype !=MIGRATE_MOVABLE ) + compact_order =max (order, pageblock_order); + +if (!compact_order)return NULL ;psi_memstall_enter (&pflags);
@@ -4169,8 +4185,8 @@ __alloc_pages_direct_compact(gfp_t gfp_mbarrier ();WRITE_ONCE (current->capture_control, &capc); - *compact_result =try_to_compact_pages (gfp_mask, order, alloc_flags, ac, - prio, &capc); + *compact_result =try_to_compact_pages (gfp_mask, compact_order, + alloc_flags, ac, prio, &capc);/* * Make sure we hide capture control first before we read the captured
@@ -4215,7 +4231,7 @@ __alloc_pages_direct_compact(gfp_t gfp_mstruct zone *zone =page_zone (page); zone->compact_blockskip_flush = false; -compaction_defer_reset (zone, order, true); +compaction_defer_reset (zone, compact_order, true);count_vm_event (COMPACTSUCCESS );return page; }
@@ -4455,9 +4471,14 @@ __alloc_pages_direct_reclaim(gfp_t gfp_mstruct page *page =NULL ;unsigned long pflags;bool drained = false; +int reclaim_order = order; + +/* Match the slowpath compaction promotion in __alloc_pages_direct_compact */ +if ((alloc_flags &ALLOC_NOFRAGMENT ) && ac->migratetype !=MIGRATE_MOVABLE ) + reclaim_order =max (order, pageblock_order);psi_memstall_enter (&pflags); - *did_some_progress =__perform_reclaim (gfp_mask, order, ac); + *did_some_progress =__perform_reclaim (gfp_mask, reclaim_order, ac);if (unlikely (!(*did_some_progress))) goto out;
Greg Kroah-Hartman
maintainerPATCH 80/713 mm: vmscan: fix node reclaim ignoring swappiness parameter
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ridong Chen <[email protected]>
commit 8a905195850d383c0465ab5bdd3c91d94269b242 upstream.
sc_swappiness() had two separate definitions depending on CONFIG_MEMCG. The !CONFIG_MEMCG variant simply returned vm_swappiness, ignoring the proactive_swappiness value passed through scan_control. This caused the swappiness parameter written to /sys/devices/system/node/nodeX/reclaim to have no effect when CONFIG_MEMCG is disabled.
Fix this by consolidating sc_swappiness() into a single definition that checks sc->proactive_swappiness first, then falls back to mem_cgroup_swappiness() which already handles both CONFIG_MEMCG and !CONFIG_MEMCG.
Before fix (swappiness=max ignored, mostly file pages reclaimed):
# cat /proc/sys/vm/swappiness
60
# cat /proc/vmstat | grep pgsteal
pgsteal_kswapd 0
pgsteal_direct 0
pgsteal_khugepaged 0
pgsteal_proactive 1840
pgsteal_anon 25
pgsteal_file 1815
# echo "64M swappiness=max" > /sys/devices/system/node/node0/reclaim
# cat /proc/vmstat | grep pgsteal
pgsteal_kswapd 0
pgsteal_direct 0
pgsteal_khugepaged 0
pgsteal_proactive 18013
pgsteal_anon 337
pgsteal_file 17676After fix (swappiness=max honored, anon pages reclaimed as expected):
# cat /proc/vmstat | grep pgsteal
pgsteal_kswapd 0
pgsteal_direct 0
pgsteal_khugepaged 0
pgsteal_proactive 0
pgsteal_anon 0
pgsteal_file 0
# echo "64M swappiness=max" > /sys/devices/system/node/node0/reclaim
# cat /proc/vmstat | grep pgsteal
pgsteal_kswapd 0
pgsteal_direct 0
pgsteal_khugepaged 0
pgsteal_proactive 16283
pgsteal_anon 16283
pgsteal_file 0--- mm/vmscan.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-)
mm/vmscan.c +7 -12
@@ -198,6 +198,13 @@ struct scan_control {*/ int vm_swappiness =60 ; +static int sc_swappiness (struct scan_control *sc,struct mem_cgroup *memcg) +{ +if (sc->proactive && sc->proactive_swappiness) +return *sc->proactive_swappiness; +return mem_cgroup_swappiness (memcg); +} +#ifdef CONFIG_MEMCG /* Returns true for reclaim through cgroup limits or cgroup interfaces. */
@@ -238,13 +245,6 @@ static bool writeback_throttling_sane(st#endif return false; } - -static int sc_swappiness (struct scan_control *sc,struct mem_cgroup *memcg) -{ -if (sc->proactive && sc->proactive_swappiness) -return *sc->proactive_swappiness; -return mem_cgroup_swappiness (memcg); -}#else static bool cgroup_reclaim (struct scan_control *sc) {
@@ -260,11 +260,6 @@ static bool writeback_throttling_sane(st {return true; } - -static int sc_swappiness (struct scan_control *sc,struct mem_cgroup *memcg) -{ -return READ_ONCE (vm_swappiness); -}#endif static void set_task_reclaim_state(struct task_struct *task,
Greg Kroah-Hartman
maintainerPATCH 81/713 tools/compiler: match glibc 2.42 definition of __attribute_const__
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joy H.J. Lee <[email protected]>
commit 8700a4761beb219873956666cf91776a2c61e698 upstream.
glibc 2.42 added __attribute_const__ to sys/cdefs.h:
# define __attribute_const__ __attribute__ ((__const__))
GCC 15 warns when a macro is redefined to a different replacement list (-Wbuiltin-macro-redefined). Since host tool Makefiles (resolve_btfids, objtool) pass -Werror, this conflict becomes fatal.
The warning is suppressed on standard native builds because GCC treats /usr/include as a system header path (-isystem), and macro-redefinition warnings from system headers are silently suppressed by GCC. It fires when glibc headers are on a regular include path (-I) instead, which is the case in cross-compilation setups such as NixOS, where the sysroot's glibc is passed explicitly via -I rather than -isystem.
Per (C11 6.10.3), identical replacement lists are accepted silently. Match the glibc definition exactly, including the space before "((", so the redefinition is accepted without warning regardless of whether glibc headers are treated as system or non-system includes.
--- tools/include/linux/compiler.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/include/linux/compiler.h +1 -1
@@ -119,7 +119,7 @@#define __read_mostly#ifndef __attribute_const__ -# define __attribute_const__ +# define __attribute_const__ __attribute__ ((__const__))#endif #ifndef __maybe_unused
Greg Kroah-Hartman
maintainerPATCH 82/713 x86/locking: Use sfence for wmb() if SSE is available
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yao Zi <[email protected]>
commit d824ed1307680dd482f607b0e707c575f70668c4 upstream.
When adding cc clobber to wmb()'s definition, the alternative() condition to use sfence was incorrectly raised from X86_FEATURE_XMM to X86_FEATURE_XMM2.
Restore the correct constraint for potential better performance on machines without SSE2.
--- arch/x86/include/asm/barrier.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/include/asm/barrier.h +1 -1
@@ -17,7 +17,7 @@#define rmb () asm volatile(ALTERNATIVE("lock addl $0,-4(%%esp)", "lfence", \ X86_FEATURE_XMM2) ::: "memory", "cc")#define wmb () asm volatile(ALTERNATIVE("lock addl $0,-4(%%esp)", "sfence", \ - X86_FEATURE_XMM2) ::: "memory", "cc") + X86_FEATURE_XMM) ::: "memory", "cc")#else #define __mb () asm volatile("mfence":::"memory")#define __rmb () asm volatile("lfence":::"memory")
Greg Kroah-Hartman
maintainerPATCH 83/713 x86/insn-eval: Move assign_register() out of KVM as insn_assign_reg()
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kiryl Shutsemau (Meta) <[email protected]>
commit 1fe104b048d77d6cb25bd938e6a67450fb50e61d upstream.
KVM's instruction emulator has a small helper, assign_register(), that writes a value into a register following the x86 rules for writes to general-purpose registers: an 8- or 16-bit write leaves the rest of the register untouched, a 32-bit write zero-extends the result to 64 bits, and a 64-bit write replaces the whole register.
The TDX guest #VE handler needs the same logic for port I/O emulation to get 32-bit zero-extension right. Rather than add a third copy of the same switch, move the helper verbatim to <asm/insn-eval.h>, rename it to insn_assign_reg(), and route KVM's callers through it.
Add <asm/insn.h> to the header's includes so it builds standalone in callers that have not pulled it in transitively.
No functional change.
--- arch/x86/include/asm/insn-eval.h | 36 ++++++++++++++++++++++++++++++++++++ arch/x86/kvm/emulate.c | 26 ++++---------------------- 2 files changed, 40 insertions(+), 22 deletions(-)
arch/x86/include/asm/insn-eval.h +36 -0
@@ -9,6 +9,7 @@#include <linux/compiler.h> #include <linux/bug.h> #include <linux/err.h> +#include <asm/insn.h> #include <asm/ptrace.h> #define INSN_CODE_SEG_ADDR_SZ (params) ((params >> 4) & 0xf)
@@ -46,4 +47,39 @@ enum insn_mmio_type insn_decode_mmio(strbool insn_is_nop (struct insn *insn); +/* +* Write @val into *@reg following the x86 rules for writes to +* general-purpose registers (Intel SDM Vol. 1, "General-Purpose +* Registers in 64-Bit Mode"): an 8- or 16-bit write leaves the rest of +* the register untouched, a 32-bit write zero-extends the result into +* the upper 32 bits, and a 64-bit write replaces the whole register. +* +* @bytes is the width of the write, not a property of the instruction: +* an instruction that, say, sign-extends a 32-bit immediate into a +* 64-bit register does a 64-bit write here. +* +* @reg need not be 8-byte aligned: KVM's instruction emulator offsets +* the pointer by one byte to address the high-byte registers (AH, CH, +* DH, BH). Use narrow stores for the sub-word cases so the access +* width matches @bytes and the adjacent bytes are left alone. +*/ +static inline void insn_assign_reg (unsigned long *reg,u64 val,int bytes) +{ +switch (bytes) { +case 1 : + *(u8 *)reg = (u8 )val; +break ; +case 2 : + *(u16 *)reg = (u16 )val; +break ; +case 4 : +/* A 32-bit write zero-extends into the upper 32 bits. */ + *reg = (u32 )val; +break ; +case 8 : + *reg = val; +break ; + } +} +#endif /* _ASM_X86_INSN_EVAL_H */
arch/x86/kvm/emulate.c +4 -22
@@ -24,6 +24,7 @@#include "kvm_emulate.h" #include <linux/stringify.h> #include <asm/debugreg.h> +#include <asm/insn-eval.h> #include <asm/nospec-branch.h> #include <asm/ibt.h> #include <asm/text-patching.h>
@@ -439,25 +440,6 @@ static void assign_masked(ulong *dest, u *dest = (*dest & ~mask) | (src & mask); } -static void assign_register (unsigned long *reg,u64 val,int bytes) -{ -/* The 4-byte case *is* correct: in 64-bit mode we zero-extend. */ -switch (bytes) { -case 1 : - *(u8 *)reg = (u8 )val; -break ; -case 2 : - *(u16 *)reg = (u16 )val; -break ; -case 4 : - *reg = (u32 )val; -break ;/* 64b: zero-extend */ -case 8 : - *reg = val; -break ; - } -} -static inline unsigned long ad_mask (struct x86_emulate_ctxt *ctxt) {return (1UL << (ctxt->ad_bytes <<3 )) -1 ;
@@ -505,7 +487,7 @@ register_address_increment(struct x86_em {ulong *preg =reg_rmw (ctxt, reg); -assign_register (preg, *preg + inc, ctxt->ad_bytes); +insn_assign_reg (preg, *preg + inc, ctxt->ad_bytes); }static void rsp_increment (struct x86_emulate_ctxt *ctxt,int inc)
@@ -1767,7 +1749,7 @@ static int load_segment_descriptor(strucstatic void write_register_operand (struct operand *op) { -return assign_register (op->addr.reg, op->val, op->bytes); +return insn_assign_reg (op->addr.reg, op->val, op->bytes); }static int writeback (struct x86_emulate_ctxt *ctxt,struct operand *op)
@@ -2008,7 +1990,7 @@ static int em_popa(struct x86_emulate_ct rc =emulate_pop (ctxt, &val, ctxt->op_bytes);if (rc !=X86EMUL_CONTINUE )break ; -assign_register (reg_rmw (ctxt, reg), val, ctxt->op_bytes); +insn_assign_reg (reg_rmw (ctxt, reg), val, ctxt->op_bytes); --reg; }return rc;
Greg Kroah-Hartman
maintainerPATCH 84/713 x86/tdx: Fix off-by-one in port I/O handling
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kiryl Shutsemau (Meta) <[email protected]>
commit 0f63e656b1c679d32ac595de29d10c03efca6a25 upstream.
handle_in() and handle_out() in arch/x86/coco/tdx/tdx.c use:
u64 mask = GENMASK(BITS_PER_BYTE * size, 0);
GENMASK(h, l) includes bit h. For size=1 (INB), this produces GENMASK(8, 0) = 0x1FF (9 bits) instead of GENMASK(7, 0) = 0xFF (8 bits). The mask is one bit too wide for all I/O sizes.
Fix the mask calculation.
--- arch/x86/coco/tdx/tdx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/x86/coco/tdx/tdx.c +2 -2
@@ -694,7 +694,7 @@ static bool handle_in(struct pt_regs *re .r13 = PORT_READ, .r14 = port, }; -u64 mask =GENMASK (BITS_PER_BYTE * size,0 ); +u64 mask =GENMASK (BITS_PER_BYTE * size -1 ,0 );bool success;/*
@@ -714,7 +714,7 @@ static bool handle_in(struct pt_regs *restatic bool handle_out (struct pt_regs *regs,int size,int port) { -u64 mask =GENMASK (BITS_PER_BYTE * size,0 ); +u64 mask =GENMASK (BITS_PER_BYTE * size -1 ,0 );/* * Emulate the I/O write via hypercall. More info about ABI can be found
Greg Kroah-Hartman
maintainerPATCH 85/713 x86/tdx: Fix zero-extension for 32-bit port I/O
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kiryl Shutsemau (Meta) <[email protected]>
commit 941370fc93cc3474e26811f4d3b062903eefe2cf upstream.
According to x86 architecture rules, 32-bit operations zero-extend the result to 64 bits. The current implementation of handle_in() only masks the lower 32 bits, which preserves the upper 32 bits of RAX when a 32-bit port IN instruction is emulated.
Use insn_assign_reg() to write the result back into RAX with proper partial-register-write semantics: 1- and 2-byte forms leave the upper bits untouched, the 4-byte form zero-extends to the full register.
--- arch/x86/coco/tdx/tdx.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
arch/x86/coco/tdx/tdx.c +3 -5
@@ -694,8 +694,8 @@ static bool handle_in(struct pt_regs *re .r13 = PORT_READ, .r14 = port, }; -u64 mask =GENMASK (BITS_PER_BYTE * size -1 ,0 );bool success; +u64 val;/* * Emulate the I/O read via hypercall. More info about ABI can be found
@@ -703,11 +703,9 @@ static bool handle_in(struct pt_regs *re* "TDG.VP.VMCALL<Instruction.IO>". */ success = !__tdx_hypercall (&args); + val = success ? args.r11 :0 ; -/* Update part of the register affected by the emulated instruction */ - regs->ax &= ~mask; -if (success) - regs->ax |= args.r11 & mask; +insn_assign_reg (®s->ax, val, size);return success; }
Greg Kroah-Hartman
maintainerPATCH 86/713 x86/xen: fix init of balloon stats again
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Roger Pau Monne <[email protected]>
commit 5d00a11d484e7b31a358cd81afebccb4602dbe8c upstream.
The handling of extra memory regions done in balloon_add_regions() is not correct for PV guests, since the initial target is set to reflect the real memory the system has, not what's described on the memory map, which can be higher if memory != maxmem.
Introduce separate logic for addition vs subtraction in balloon_add_regions() and handle extra regions correctly by adding them to the total amount of pages, instead of subtracting from the current and target pages amounts.
In the common case PV domU/dom0 and PVH dom0 will use the addition path, since the initial target reflects the real assigned memory. HVM and PVH domUs use the subtraction path, since the target is set based on the amount of memory reported in the memory map, without accounting for released regions.
Message-ID: <[email protected]>
--- drivers/xen/balloon.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-)
drivers/xen/balloon.c +19 -10
@@ -679,7 +679,7 @@ void xen_free_ballooned_pages(unsigned i }EXPORT_SYMBOL (xen_free_ballooned_pages); -static int __init balloon_add_regions (void ) +static int __init balloon_add_regions (bool append) {unsigned long start_pfn, pages;unsigned long pfn, extra_pfn_end;
@@ -703,19 +703,26 @@ static int __init balloon_add_regions(voballoon_append (pfn_to_page (pfn));/* -* Extra regions are accounted for in the physmap, but need -* decreasing from current_pages and target_pages to balloon -* down the initial allocation, because they are already -* accounted for in total_pages. +* There are two different use-cases depending on how the +* initial memory target is fetched. For PVH dom0 and PV the +* target is usually set to reflect the domain assigned memory, +* and hence extra regions need adding. +* +* OTOH for HVM and PVH domU the target is set to the amount of +* RAM reported in the memory map, and hence extra regions need +* subtracting to reflect the real memory usage. */ pages = extra_pfn_end - start_pfn; -if (pages >= balloon_stats.current_pages || - pages >= balloon_stats.target_pages) { +if (append) { + balloon_stats.total_pages += pages; + }else if (pages >= balloon_stats.current_pages || + pages >= balloon_stats.target_pages) {WARN (1 ,"Extra pages underflow current target" );return -ERANGE ; + }else { + balloon_stats.current_pages -= pages; + balloon_stats.target_pages -= pages; } - balloon_stats.current_pages -= pages; - balloon_stats.target_pages -= pages; }return 0 ;
@@ -726,6 +733,7 @@ static int __init balloon_init(void)struct task_struct *task;long current_pages =0 ;domid_t domid =DOMID_SELF ; +bool append = true;int rc;if (!xen_domain ())
@@ -745,6 +753,7 @@ static int __init balloon_init(void) }else {if (xen_unpopulated_pages >=get_num_physpages ()) goto underflow; + append = false; current_pages =get_num_physpages () - xen_unpopulated_pages; }
@@ -767,7 +776,7 @@ static int __init balloon_init(void)register_sysctl_init ("xen/balloon" , balloon_table);#endif - rc =balloon_add_regions (); + rc =balloon_add_regions (append);if (rc)return rc;
Greg Kroah-Hartman
maintainerPATCH 87/713 hwtracing: hisi_ptt: Propagate DMA reset timeout in trace_start()
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sanman Pradhan <[email protected]>
commit 75d42d990335322852ed5f7ce324b701c0949d79 upstream.
hisi_ptt_wait_dma_reset_done() discards the return value of readl_poll_timeout_atomic(). If the DMA engine does not complete its reset within the timeout, hisi_ptt_trace_start() proceeds to start tracing regardless.
Return a bool from hisi_ptt_wait_dma_reset_done(), consistent with the other wait helpers in this driver. On timeout, log an error, de-assert the reset bit, and return -ETIMEDOUT. Move ctrl->started to the successful path so a failed start does not leave the trace marked as active.
--- drivers/hwtracing/ptt/hisi_ptt.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-)
drivers/hwtracing/ptt/hisi_ptt.c +13 -7
@@ -171,13 +171,13 @@ static bool hisi_ptt_wait_trace_hw_idle( HISI_PTT_WAIT_TRACE_TIMEOUT_US); } -static void hisi_ptt_wait_dma_reset_done (struct hisi_ptt *hisi_ptt) +static bool hisi_ptt_wait_dma_reset_done (struct hisi_ptt *hisi_ptt) {u32 val; -readl_poll_timeout_atomic (hisi_ptt->iobase +HISI_PTT_TRACE_WR_STS , - val, !val,HISI_PTT_RESET_POLL_INTERVAL_US , -HISI_PTT_RESET_TIMEOUT_US ); +return !readl_poll_timeout_atomic (hisi_ptt->iobase +HISI_PTT_TRACE_WR_STS , + val, !val,HISI_PTT_RESET_POLL_INTERVAL_US , +HISI_PTT_RESET_TIMEOUT_US ); }static void hisi_ptt_trace_end (struct hisi_ptt *hisi_ptt)
@@ -202,14 +202,18 @@ static int hisi_ptt_trace_start(struct hreturn -EBUSY ; } - ctrl->started = true; -/* Reset the DMA before start tracing */ val =readl (hisi_ptt->iobase +HISI_PTT_TRACE_CTRL ); val |=HISI_PTT_TRACE_CTRL_RST ;writel (val, hisi_ptt->iobase +HISI_PTT_TRACE_CTRL ); -hisi_ptt_wait_dma_reset_done (hisi_ptt); +if (!hisi_ptt_wait_dma_reset_done (hisi_ptt)) { +pci_err (hisi_ptt->pdev,"timed out waiting for DMA reset\n" ); + val =readl (hisi_ptt->iobase +HISI_PTT_TRACE_CTRL ); + val &= ~HISI_PTT_TRACE_CTRL_RST ; +writel (val, hisi_ptt->iobase +HISI_PTT_TRACE_CTRL ); +return -ETIMEDOUT ; + } val =readl (hisi_ptt->iobase +HISI_PTT_TRACE_CTRL ); val &= ~HISI_PTT_TRACE_CTRL_RST ;
@@ -234,6 +238,8 @@ static int hisi_ptt_trace_start(struct hif (!hisi_ptt->trace_ctrl.is_port) val |=HISI_PTT_TRACE_CTRL_FILTER_MODE ; + ctrl->started = true; +/* Start the Trace */ val |=HISI_PTT_TRACE_CTRL_EN ;writel (val, hisi_ptt->iobase +HISI_PTT_TRACE_CTRL );
Greg Kroah-Hartman
maintainerPATCH 88/713 tracing/user_events: Clear copied tracing state before fork duplication
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jérémy Jean <[email protected]>
commit 390f6bd8583d177029d9df4bea6667509e55a765 upstream.
dup_task_struct() copies user_event_mm from the parent into the child, without grabbing a reference to it. user_event_mm_dup() should replace it, but it leaves that copied pointer unmodified if user_event_mm_alloc() fails.
When the child exits, user_event_mm_remove() decrements a reference the child never owned, which ultimately frees user_event_mm, while the parent still as a stale pointer to it. This creates a UAF, which KASAN reports as:
BUG: KASAN: slab-use-after-free in
current_user_event_mm+0x51/0x1d0 Write of size 4 at addr
ffff888005010d30 by task init/44
Call Trace:
<TASK>
kasan_report+0xce/0x100
kasan_check_range+0x10f/0x1e0
current_user_event_mm+0x51/0x1d0
user_events_ioctl+0x82e/0x15c0
__x64_sys_ioctl+0x139/0x1c0
do_syscall_64+0xce/0x450
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Allocated by task 44:
__kasan_kmalloc+0x8f/0xa0
__kmalloc_cache_noprof+0x180/0x3a0
user_event_mm_alloc+0x3c/0x1f0
current_user_event_mm+0x88/0x1d0
Freed by task 42:
__kasan_slab_free+0x43/0x70
kfree+0x13a/0x390
process_one_work+0x696/0xf90
worker_thread+0x420/0xba0The fix simply clears the copied pointer before any possible failure. In case of failure, the child then has nothing to free.
--- kernel/trace/trace_events_user.c | 3 +++ 1 file changed, 3 insertions(+)
kernel/trace/trace_events_user.c +3 -0
@@ -868,6 +868,9 @@ void user_event_mm_dup(struct task_strucstruct user_event_mm *mm =user_event_mm_alloc (t);struct user_event_enabler *enabler; +/* On failure, do not free parent's copy */ + t->user_event_mm =NULL ; +if (!mm)return ;
Greg Kroah-Hartman
maintainerPATCH 89/713 tracing: Fix crash passing ERR_PTR to kthread_stop()
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hui Su <[email protected]>
commit 649bc7df3e5d7be6f7996a95084037dbf3cad1e5 upstream.
event_test_stuff() calls kthread_run() and unconditionally passes the returned task_struct pointer to kthread_stop(). kthread_run() returns an error pointer such as ERR_PTR(-ENOMEM) when kthread creation fails, for example under memory pressure during the boot-time event self-test. kthread_stop() then dereferences the invalid pointer, crashing the kernel.
Check the result of kthread_run() before passing it to kthread_stop(). Use WARN_ON() so that a failure to create the self-test thread does not go unnoticed, matching the ring-buffer self-test fix in commit 91542863abad ("ring-buffer: Fix crash passing ERR_PTR to kthread_stop()").
--- kernel/trace/trace_events.c | 2 ++ 1 file changed, 2 insertions(+)
kernel/trace/trace_events.c +2 -0
@@ -4901,6 +4901,8 @@ static __init void event_test_stuff(voidstruct task_struct *test_thread; test_thread =kthread_run (event_test_thread,NULL ,"test-events" ); +if (WARN_ON (IS_ERR (test_thread))) +return ;msleep (1 );kthread_stop (test_thread); }
Greg Kroah-Hartman
maintainerPATCH 90/713 tracing: Fix logged instance name on creation failure
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vincent Donnefort <[email protected]>
commit a9a01be2834a529cbd490ccbab02643f0c1735f2 upstream.
When boot instance creation fails, the kernel incorrectly logs "(null)" as the instance name because strsep() consumes curr_str entirely during parsing.
Print the properly parsed name variable instead. And while at it log the error code.
--- kernel/trace/trace.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
kernel/trace/trace.c +2 -1
@@ -9726,7 +9726,8 @@ __init static void enable_instances(void tr =trace_array_create_systems (name,NULL , addr, size);if (IS_ERR (tr)) { -pr_warn ("Tracing: Failed to create instance buffer %s\n" , curr_str); +pr_warn ("Tracing: Failed to create instance buffer '%s' (%ld)\n" , name, +PTR_ERR (tr));continue ; }
Greg Kroah-Hartman
maintainerPATCH 91/713 tracing: Fix retry exhaustion in simple ring buffer reader swap
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ivan Immanuel Shaji <[email protected]>
commit e0d3aed7b12cf37b74c7cc5265073d0263b49cde upstream.
simple_ring_buffer_swap_reader_page() starts with retry set to 8 and post-decrements it only after a failed link replacement. On the final attempt, a successful replacement leaves retry at zero, while a failed replacement leaves it at -1.
The current !retry test reverses both outcomes. It returns an error after a successful final replacement, leaving the link update complete but the reader bookkeeping unfinished. After a failed final replacement, it falls through and updates the head and reader pointers as though the replacement succeeded, which can corrupt the ring.
Treat only a negative counter as exhaustion and return the documented -EBUSY error.
--- kernel/trace/simple_ring_buffer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/trace/simple_ring_buffer.c +2 -2
@@ -160,8 +160,8 @@ int simple_ring_buffer_swap_reader_page( overrun = cpu_buffer->meta->overrun; }while (!simple_bpage_unset_head_link (last, reader,SIMPLE_RB_LINK_NORMAL ) && retry--); -if (!retry) -return -EINVAL ; +if (retry <0 ) +return -EBUSY ; cpu_buffer->head_page =simple_bpage_from_link (reader->link.next); cpu_buffer->head_page->link.prev = &reader->link;
Greg Kroah-Hartman
maintainerPATCH 92/713 tracing: Fix use-after-free in trace_pipe read on sub-buffer order change
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Deepanshu Kartikey <[email protected]>
commit 372f8534244d632ad5118e8a87a11291b01712d3 upstream.
Writing to buffer_subbuf_size_kb calls ring_buffer_subbuf_order_set(), which frees every sub-buffer of the ring buffer, including the reader page, and replaces them with newly allocated ones.
Readers of trace_pipe hold pointers into those pages. ring_buffer_peek() looks up an event under cpu_buffer->reader_lock but returns the event pointer after dropping the lock, and peek_next_entry() then calls ring_buffer_event_length() and ring_buffer_event_data() on it. If the sub-buffer order is changed in that window, the reader dereferences freed memory:
BUG: KASAN: use-after-free in ring_buffer_peek+0x3e0/0x430 Read of size 1 at addr ffff88802a4cf010 by task syz-executor989/6002
Freed by:
free_buffer_page kernel/trace/ring_buffer.c:398 [inline] ring_buffer_subbuf_order_set+0x1325/0x18e0 kernel/trace/ring_buffer.c:7444 buffer_subbuf_size_write+0x182/0x280 kernel/trace/trace.c:8221
Take trace_access_lock(RING_BUFFER_ALL_CPUS) around the order change. This is the lock trace_pipe readers already hold across their entire peek-and-print loop, so the swap can no longer race with a reader that is dereferencing a peeked event.
--- kernel/trace/trace.c | 3 +++ 1 file changed, 3 insertions(+)
kernel/trace/trace.c +3 -0
@@ -8214,6 +8214,8 @@ buffer_subbuf_size_write(struct file *fi/* Do not allow tracing while changing the order of the ring buffer */ tracing_stop_tr (tr); +trace_access_lock (RING_BUFFER_ALL_CPUS ); + old_order =ring_buffer_subbuf_order_get (tr->array_buffer.buffer);if (old_order == order) goto out;
@@ -8253,6 +8255,7 @@ buffer_subbuf_size_write(struct file *fi#endif (*ppos)++; out: +trace_access_unlock (RING_BUFFER_ALL_CPUS );if (ret) cnt = ret;tracing_start_tr (tr);
Greg Kroah-Hartman
maintainerPATCH 93/713 tracing: Fix use-after-free with same-name named triggers
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hui Su <[email protected]>
commit a7318172aa332a161fb9618286e64454c827f8fd upstream.
When two hist triggers on different events are registered with the same name=, the second one reuses the first as named_data. Both are added to tr->hist_vars by save_hist_vars() during event_hist_trigger_parse(), because save_hist_vars() is called before event_trigger_register() while the named reuse is only detected later, in hist_register_trigger().
In the named-data branch hist_register_trigger() then frees the second histogram's hist_data via destroy_hist_data(), but never removes its tr->hist_vars list entry, leaving a dangling pointer and leaking the trace_array reference it holds.
A later hist trigger that references a variable makes find_var_file() walk tr->hist_vars and dereference the freed hist_data. The bug is reproducible from userspace by writing three hist triggers to tracefs:
cd /sys/kernel/tracing
echo 'hist:keys=common_pid:x=common_pid:name=mh' > events/sched/sched_switch/trigger echo 'hist:keys=common_pid:x=common_pid:name=mh' > events/sched/sched_process_fork/trigger echo 'hist:keys=common_pid:vals=$x' > events/sched/sched_process_exit/trigger
The third write panics the kernel:
BUG: KASAN: slab-use-after-free in find_var_file.part.0+0x272/0x290
Read of size 8 at addr ffff888001f8a0e0 by task sh/1
CPU: 1 UID: 0 PID: 1 Comm: sh Tainted: G D N
Call Trace:
find_var_file.part.0
find_event_var
parse_atom
parse_expr
__create_val_field
event_hist_trigger_parse
trigger_process_regex
event_trigger_write
vfs_write
ksys_write
do_syscall_64
entry_SYSCALL_64_after_hwframe
Allocated by task 1:
event_hist_trigger_parse
Freed by task 1:
hist_register_trigger+0x618/0xa30
event_hist_trigger_parse
The buggy address belongs to freed 2048-byte region
Oops: general protection fault ... RIP: find_var_file.part.0
Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000bFix by removing the hist_data from tr->hist_vars and releasing the trace_array reference in the named-data branch of hist_register_trigger() before freeing the hist_data.
--- kernel/trace/trace_events_hist.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
kernel/trace/trace_events_hist.c +3 -1
@@ -6641,8 +6641,10 @@ static int hist_register_trigger(char *gtracing_set_filter_buffering (file->tr, true); } -if (named_data) +if (named_data) { +remove_hist_vars (hist_data);destroy_hist_data (hist_data); + } out:return ret; }
Greg Kroah-Hartman
maintainerPATCH 94/713 cdx: Fix double free when sysfs file creation fails
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Prasanna Kumar T S M <[email protected]>
commit 6f4acc3a3c300e174e3f586b97b04ed8f5948c36 upstream.
In cdx_create_res_attr(), if sysfs_create_bin_file() fails, the code frees res_attr but doesn't set cdx_dev->res_attr[num] to NULL. This leaves a dangling pointer in the array. Then cdx_destroy_res_attr() frees the already-freed memory. Fix the double free by initializing cdx_dev->res_attr[num] after sysfs_create_bin_file() completes.
--- drivers/cdx/cdx.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/cdx/cdx.c +5 -2
@@ -738,7 +738,6 @@ static int cdx_create_res_attr(struct cdsysfs_bin_attr_init (res_attr); - cdx_dev->res_attr[num] = res_attr;sprintf (res_attr_name,"resource%d" , num); res_attr->mmap = cdx_mmap_resource;
@@ -747,8 +746,12 @@ static int cdx_create_res_attr(struct cd res_attr->size =cdx_resource_len (cdx_dev, num); res_attr->private = (void *)(unsigned long )num; ret =sysfs_create_bin_file (&cdx_dev->dev.kobj, res_attr); -if (ret) +if (ret) {kfree (res_attr); +return ret; + } + + cdx_dev->res_attr[num] = res_attr;return ret; }
Greg Kroah-Hartman
maintainerPATCH 95/713 debugfs: Fix lockdown check for mmap_prepare
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chun-Yi Lee <[email protected]>
commit f81808de37338aac8e167f99bfae647b1b835c70 upstream.
Commit 651fdda8406d ("relay: update relay to use mmap_prepare") changed the mmap file operation to mmap_prepare for relayfs, but the lockdown check in debugfs was not updated accordingly.
This prevents debugfs from being locked down when the kernel is in integrity mode if a file uses mmap_prepare but not mmap.
Since the conversion to mmap_prepare across the kernel is not yet complete, update the lockdown check to look for both mmap and mmap_prepare to ensure comprehensive coverage.
--- fs/debugfs/file.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/debugfs/file.c +2 -1
@@ -273,7 +273,8 @@ static int debugfs_locked_down(struct in (!real_fops || (!real_fops->unlocked_ioctl && !real_fops->compat_ioctl && - !real_fops->mmap))) + !real_fops->mmap && + !real_fops->mmap_prepare))) return 0;if (security_locked_down (LOCKDOWN_DEBUGFS ))
Greg Kroah-Hartman
maintainerPATCH 96/713 device property: fix infinite loop in fwnode_for_each_child_node()
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xu Yang <[email protected]>
commit 1900692555826753adab8799a1a8d50bb1ee200c upstream.
When iterate over children of a fwnode that has a secondary fwnode, fwnode_get_next_child_node() can enter an infinite loop if the secondary fwnode has more than one child.
Parent Child
(Primary fwnode) FWa: {FWa1, FWa2, FWa3}
(Secondary fwnode) FWb: {FWb1, FWb2}In this case:
┌─> fwnode_get_next_child_node(FWa, FWa1) │ - fwnode_call_ptr_op(FWa, get_next_child_node, FWa1) returns FWa2 │ │ ... │ │ fwnode_get_next_child_node(FWa, FWa3) │ - fwnode_call_ptr_op(FWa, get_next_child_node, FWa3) returns NULL │ - fwnode_call_ptr_op(FWb, get_next_child_node, FWa3) returns FWb1 │ │ fwnode_get_next_child_node(FWa, FWb1) │ - fwnode_call_ptr_op(FWa, get_next_child_node, FWb1) returns FWa1 └────┘
This cause fwnode_for_each_child_node() to loop indefinitely, reapeatedly output {FWa1, FWa2, FWa3, FWb1, FWa1, ...}.
The root cause is that when the current child (FWb1) belongs to the secondary fwnode, calling get_next_child_node() on the parimary fwnode incorrectly returns the first child (FWa1) again instead of NULL.
Fix this by dynamically checking the parent fwnode of the current child before calling get_next_child_node(). This approach follows the pattern established in commit b5b41ab6b0c1 ("device property: Check fwnode->secondary in fwnode_graph_get_next_endpoint()").
--- drivers/base/property.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-)
drivers/base/property.c +16 -3
@@ -807,18 +807,31 @@ struct fwnode_handle * fwnode_get_next_child_node(const struct fwnode_handle *fwnode, struct fwnode_handle *child) { + const struct fwnode_handle *parent; + struct fwnode_handle *child_parent __free(fwnode_handle) = NULL;struct fwnode_handle *next; -if (IS_ERR_OR_NULL (fwnode)) +/* +* If this function is in a loop and the previous iteration returned +* an child from fwnode->secondary, then we need to use the secondary +* as parent rather than @fwnode. +*/ +if (child) { + child_parent =fwnode_get_parent (child); + parent = child_parent; + }else { + parent = fwnode; + } +if (IS_ERR_OR_NULL (parent))return NULL ;/* Try to find a child in primary fwnode */ - next =fwnode_call_ptr_op (fwnode, get_next_child_node, child); + next =fwnode_call_ptr_op (parent, get_next_child_node, child);if (next)return next;/* When no more children in primary, continue with secondary */ -return fwnode_call_ptr_op (fwnode->secondary, get_next_child_node, child); +return fwnode_get_next_child_node (parent->secondary,NULL ); }EXPORT_SYMBOL_GPL (fwnode_get_next_child_node);
Greg Kroah-Hartman
maintainerPATCH 97/713 misc: nsm: bound the device-reported response length
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bryam Vargas <[email protected]>
commit 808e530654a5354e6df78863a5d61e4d44e67235 upstream.
nsm_sendrecv_msg_locked() stores the virtqueue used-ring length reported by the NSM device into msg->resp.len without bounding it to the response buffer. A malicious or buggy backend can report a length larger than the response buffer; parse_resp_raw() then copies that many bytes out of the fixed buffer to user space, disclosing adjacent kernel heap (an out-of-bounds read). The request path already floors its length in fill_req_raw(); the response path lacks the symmetric check.
Clamp the stored length to the size of the response buffer. Well-behaved devices report no more than the posted buffer size, so conforming traffic is unaffected.
--- drivers/misc/nsm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/misc/nsm.c +1 -1
@@ -243,7 +243,7 @@ static int nsm_sendrecv_msg_locked(struc goto cleanup; } - msg->resp.len = len; + msg->resp.len = min_t(unsigned int, len, sizeof(msg->resp.data)); rc =0 ;
Greg Kroah-Hartman
maintainerPATCH 98/713 powerpc/powermac: fix OF node refcount
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bartosz Golaszewski <[email protected]>
commit bd0abfe6b013aeb2a1aebc5fbc7ceeb50355bda3 upstream.
Platform devices created with platform_device_alloc() call platform_device_release() when the last reference to the device's kobject is dropped. This function calls of_node_put() unconditionally. This works fine for devices created with platform_device_register_full() but users of the split approach (platform_device_alloc() + platform_device_add()) must bump the reference of the of_node they assign manually. Add the missing call to of_node_get().
--- arch/powerpc/platforms/powermac/low_i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/platforms/powermac/low_i2c.c +1 -1
@@ -1471,7 +1471,7 @@ static int __init pmac_i2c_create_platfoif (bus->platform_dev ==NULL )return -ENOMEM ; bus->platform_dev->dev.platform_data = bus; - bus->platform_dev->dev.of_node = bus->busnode; + bus->platform_dev->dev.of_node =of_node_get (bus->busnode);platform_device_add (bus->platform_dev); }
Greg Kroah-Hartman
maintainerPATCH 99/713 rapidio: mport_cdev: fix use-after-free in dma_req_free()
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: James Kim <[email protected]>
commit 5cbef379a94b161726c5f504598bf4791d45cedc upstream.
dma_req_free() acquires buf_mutex through req->map, drops the mapping reference with kref_put(), and then dereferences req->map again to unlock the mutex.
If kref_put() drops the last reference, mport_release_mapping() frees the mapping, and the subsequent mutex_unlock() dereferences a freed object. This is a use-after-free.
Fix this by caching map and md before kref_put(), clearing req->map while holding buf_mutex, and using the cached md for mutex unlocking.
The bug is reachable from userspace via the RapidIO mport character device interface.
--- drivers/rapidio/devices/rio_mport_cdev.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
drivers/rapidio/devices/rio_mport_cdev.c +7 -3
@@ -564,9 +564,13 @@ static void dma_req_free(struct kref *re }if (req->map) { -mutex_lock (&req->map->md->buf_mutex); -kref_put (&req->map->ref, mport_release_mapping); -mutex_unlock (&req->map->md->buf_mutex); +struct rio_mport_mapping *map = req->map; +struct mport_dev *md = map->md; + +mutex_lock (&md->buf_mutex); + req->map =NULL ; +kref_put (&map->ref, mport_release_mapping); +mutex_unlock (&md->buf_mutex); }kref_put (&priv->dma_ref, mport_release_dma);
Greg Kroah-Hartman
maintainerPATCH 100/713 Revert "media: v4l2-dev: fix error handling in __video_register_device()"
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans Verkuil <[email protected]>
commit e7600f5cee5de14065f950807931d6e6d40fb2d7 upstream.
This reverts commit 2a934fdb01db6458288fc9386d3d8ceba6dd551a.
The intentions of that patch were good, but it doesn't work.
The idea is that if device_register fails, you have to do a put_device to let the ref counter release resources.
However, the V4L2 API says that if video_register_device() fails, then you have to call video_device_release(), which kfree()s the video_device struct.
But the put_device() will already have freed the struct, so you end up in a double-free scenario.
There is not really a good way of fixing this without breaking video_register_device() into two parts, one that initializes everything, and one that does the actual device_register, and then converting all V4L2 drivers to this new model.
That is a massive job, and it is very unlikely that device_register will fail.
So rather than ending up in a double-free scenario, just revert this patch, and in that case we'll have a small memory leak. Which is a lot more robust.
--- drivers/media/v4l2-core/v4l2-dev.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
drivers/media/v4l2-core/v4l2-dev.c +7 -7
@@ -1071,25 +1071,25 @@ int __video_register_device(struct video vdev->dev.class = &video_class; vdev->dev.devt =MKDEV (VIDEO_MAJOR , vdev->minor); vdev->dev.parent = vdev->dev_parent; - vdev->dev.release = v4l2_device_release;dev_set_name (&vdev->dev,"%s%d" , name_base, vdev->num); - -/* Increase v4l2_device refcount */ -v4l2_device_get (vdev->v4l2_dev); -mutex_lock (&videodev_lock); ret =device_register (&vdev->dev);if (ret <0 ) {mutex_unlock (&videodev_lock);pr_err ("%s: device_register failed\n" , __func__); -put_device (&vdev->dev); -return ret; + goto cleanup; } +/* Register the release callback that will be called when the last +reference to the device goes away. */ + vdev->dev.release = v4l2_device_release;if (nr !=-1 && nr != vdev->num && warn_if_nr_in_use)pr_warn ("%s: requested %s%d, got %s\n" , __func__, name_base, nr,video_device_node_name (vdev)); +/* Increase v4l2_device refcount */ +v4l2_device_get (vdev->v4l2_dev); +/* Part 5: Register the entity. */ ret =video_register_media_controller (vdev);