6.16.8-rc1 review
Greg Kroah-Hartman
maintainercover 6.16.8-rc1 review
This is the start of the stable review cycle for the 6.16.8 release. There are 189 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri, 19 Sep 2025 12:32:53 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.16.8-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.16.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 6.16.8-rc1
Johan Hovold <[email protected]>
phy: ti-pipe3: fix device leak at unbind
Johan Hovold <[email protected]>
phy: ti: omap-usb2: fix device leak at unbind
Johan Hovold <[email protected]>
phy: tegra: xusb: fix device and OF node leak at probe
Stephan Gerhold <[email protected]>
phy: qcom: qmp-pcie: Fix PHY initialization when powered down by firmware
Miaoqian Lin <[email protected]>
dmaengine: dw: dmamux: Fix device reference leak in rzn1_dmamux_route_allocate
Stephan Gerhold <[email protected]>
dmaengine: qcom: bam_dma: Fix DT error handling for num-channels/ees
Takashi Iwai <[email protected]>
usb: gadget: midi2: Fix MIDI2 IN EP max packet size
Takashi Iwai <[email protected]>
usb: gadget: midi2: Fix missing UMP group attributes initialization
RD Babiera <[email protected]>
usb: typec: tcpm: properly deliver cable vdms to altmode drivers
Alan Stern <[email protected]>
USB: gadget: dummy-hcd: Fix locking bug in RT-enabled kernels
Mathias Nyman <[email protected]>
xhci: fix memory leak regression when freeing xhci vdev devices depth first
Mathias Nyman <[email protected]>
xhci: dbc: Fix full DbC transfer ring after several reconnects
Mathias Nyman <[email protected]>
xhci: dbc: decouple endpoint allocation from initialization
Yuezhang Mo <[email protected]>
erofs: fix runtime warning on truncate_folio_batch_exceptionals()
Andreas Kemnade <[email protected]>
regulator: sy7636a: fix lifecycle of power good gpio
Anders Roxell <[email protected]>
dmaengine: ti: edma: Fix memory allocation size for queue_priority_map
Gao Xiang <[email protected]>
erofs: fix invalid algorithm for encoded extents
Gao Xiang <[email protected]>
erofs: unify meta buffers in z_erofs_fill_inode()
Gao Xiang <[email protected]>
erofs: remove need_kmap in erofs_read_metabuf()
Gao Xiang <[email protected]>
erofs: get rid of {get,put}_page() for ztailpacking data
Dan Carpenter <[email protected]>
dmaengine: idxd: Fix double free in idxd_setup_wqs()
Yi Sun <[email protected]>
dmaengine: idxd: Fix refcount underflow on module unload
Yi Sun <[email protected]>
dmaengine: idxd: Remove improper idxd_free
Pengyu Luo <[email protected]>
phy: qualcomm: phy-qcom-eusb2-repeater: fix override properties
Hangbin Liu <[email protected]>
hsr: hold rcu and dev lock for hsr_get_port_ndev
Hangbin Liu <[email protected]>
hsr: use hsr_for_each_port_rtnl in hsr_port_get_hsr
Hangbin Liu <[email protected]>
hsr: use rtnl lock when iterating over ports
Florian Westphal <[email protected]>
netfilter: nf_tables: restart set lookup on base_seq change
Florian Westphal <[email protected]>
netfilter: nf_tables: make nft_set_do_lookup available unconditionally
Florian Westphal <[email protected]>
netfilter: nf_tables: place base_seq in struct net
Phil Sutter <[email protected]>
netfilter: nf_tables: Reintroduce shortened deletion notifications
Florian Westphal <[email protected]>
netfilter: nft_set_rbtree: continue traversal if element is inactive
Florian Westphal <[email protected]>
netfilter: nft_set_pipapo: don't check genbit from packetpath lookups
Florian Westphal <[email protected]>
netfilter: nft_set_pipapo: don't return bogus extension pointer
Florian Westphal <[email protected]>
netfilter: nft_set_pipapo: merge pipapo_get/lookup
Florian Westphal <[email protected]>
netfilter: nft_set: remove one argument from lookup and update functions
Florian Westphal <[email protected]>
netfilter: nft_set_pipapo: remove unused arguments
Florian Westphal <[email protected]>
netfilter: nft_set_bitmap: fix lockdep splat due to missing annotation
Anssi Hannula <[email protected]>
can: xilinx_can: xcan_write_frame(): fix use-after-free of transmitted SKB
Tetsuo Handa <[email protected]>
can: j1939: j1939_local_ecu_get(): undo increment when j1939_local_ecu_get() fails
Tetsuo Handa <[email protected]>
can: j1939: j1939_sk_bind(): call j1939_priv_put() immediately when j1939_local_ecu_get() failed
Tetsuo Handa <[email protected]>
can: j1939: implement NETDEV_UNREGISTER notification handler
Davide Caratti <[email protected]>
selftests: can: enable CONFIG_CAN_VCAN as a module
Stanislav Fomichev <[email protected]>
macsec: sync features on RTM_NEWLINK
Carolina Jubran <[email protected]>
net: dev_ioctl: take ops lock in hwtstamp lower paths
Alex Deucher <[email protected]>
drm/amd/display: use udelay rather than fsleep
Michal Wajdeczko <[email protected]>
drm/xe/configfs: Don't touch survivability_mode on fini
Michal Schmidt <[email protected]>
i40e: fix IRQ freeing in i40e_vsi_request_irq_msix error path
Kohei Enju <[email protected]>
igb: fix link test skipping when interface is admin down
Tianyu Xu <[email protected]>
igb: Fix NULL pointer dereference in ethtool loopback test
Alex Tran <[email protected]>
docs: networking: can: change bcm_msg_head frames member to support flexible array
Antoine Tenart <[email protected]>
tunnels: reset the GSO metadata before reusing the skb
Petr Machata <[email protected]>
net: bridge: Bounce invalid boolopts
Jonas Gorski <[email protected]>
net: dsa: b53: fix ageing time for BCM53101
Alok Tiwari <[email protected]>
genetlink: fix genl_bind() invoking bind() after -EPERM
Klaus Kudielka <[email protected]>
PCI: mvebu: Fix use of for_each_of_range() iterator
Miaoqing Pan <[email protected]>
wifi: ath12k: fix WMI TLV header misalignment
Sriram R <[email protected]>
wifi: ath12k: Add support to enqueue management frame at MLD level
Sarika Sharma <[email protected]>
wifi: ath12k: add link support for multi-link in arsta
Miaoqing Pan <[email protected]>
wifi: ath12k: Fix missing station power save configuration
Vladimir Oltean <[email protected]>
net: phy: transfer phy_config_inband() locking responsibility to phylink
Vladimir Oltean <[email protected]>
net: phylink: add lock for serializing concurrent pl->phydev writes with resolver
Stefan Wahren <[email protected]>
net: fec: Fix possible NPD in fec_enet_phy_reset_after_clk_enable()
Chia-I Wu <[email protected]>
drm/panthor: validate group queue count
Christophe JAILLET <[email protected]>
mtd: rawnand: nuvoton: Fix an error handling path in ma35_nand_chips_init()
Fabio Porcedda <[email protected]>
USB: serial: option: add Telit Cinterion LE910C4-WWX new compositions
Fabio Porcedda <[email protected]>
USB: serial: option: add Telit Cinterion FN990A w/audio compositions
Krzysztof Kozlowski <[email protected]>
dt-bindings: serial: brcm,bcm7271-uart: Constrain clocks
Hugo Villeneuve <[email protected]>
serial: sc16is7xx: fix bug in flow control levels init
Fabian Vogt <[email protected]>
tty: hvc_console: Call hvc_kick in hvc_write unconditionally
Paolo Abeni <[email protected]>
Revert "net: usb: asix: ax88772: drop phylink use in PM to avoid MDIO runtime PM wakeups"
Antheas Kapenekakis <[email protected]>
Input: xpad - add support for Flydigi Apex 5
Christoffer Sandberg <[email protected]>
Input: i8042 - add TUXEDO InfinityBook Pro Gen10 AMD to i8042 quirk table
Jeff LaBundy <[email protected]>
Input: iqs7222 - avoid enabling unused interrupts
K Prateek Nayak <[email protected]>
x86/cpu/topology: Always try cpu_parse_topology_ext() on AMD/Hygon
Reinette Chatre <[email protected]>
fs/resctrl: Eliminate false positive lockdep warning when reading SNC counters
Xiongfeng Wang <[email protected]>
hrtimers: Unconditionally update target CPU base after offline timer migration
Pratap Nirujogi <[email protected]>
drm/amd/amdgpu: Declare isp firmware binary file
Mario Limonciello (AMD) <[email protected]>
drm/amd/display: Drop dm_prepare_suspend() and dm_complete()
Mario Limonciello <[email protected]>
drm/amd/display: Destroy cached state in complete() callback
Quanmin Yan <[email protected]>
mm/damon/reclaim: avoid divide-by-zero in damon_reclaim_apply_parameters()
Stanislav Fort <[email protected]>
mm/damon/sysfs: fix use-after-free in state_show()
Santhosh Kumar K <[email protected]>
mtd: spinand: winbond: Fix oob_layout for W25N01JW
Miquel Raynal <[email protected]>
mtd: spinand: winbond: Enable high-speed modes on w25n0xjw
Miquel Raynal <[email protected]>
mtd: spinand: Add a ->configure_chip() hook
Max Kellermann <[email protected]>
ceph: fix crash after fscrypt_encrypt_pagecache_blocks() error
Max Kellermann <[email protected]>
ceph: always call ceph_shift_unused_folios_left()
Alex Markuze <[email protected]>
ceph: fix race condition where r_parent becomes stale before sending message
Alex Markuze <[email protected]>
ceph: fix race condition validating r_parent before applying state
Ilya Dryomov <[email protected]>
libceph: fix invalid accesses to ceph_connection_v1_info
Chen Ridong <[email protected]>
kernfs: Fix UAF in polling when open file is released
Qu Wenruo <[email protected]>
btrfs: fix corruption reading compressed range when block size is smaller than page size
Boris Burkov <[email protected]>
btrfs: use readahead_expand() on compressed extents
Fangzhi Zuo <[email protected]>
drm/amd/display: Disable DPCD Probe Quirk
Imre Deak <[email protected]>
drm/dp: Add an EDID quirk for the DPCD register access probe
Imre Deak <[email protected]>
drm/edid: Add support for quirks visible to DRM core and drivers
Imre Deak <[email protected]>
drm/edid: Define the quirks in an enum list
Geoffrey McRae <[email protected]>
drm/amd/display: remove oem i2c adapter on finish
Ovidiu Bunea <[email protected]>
drm/amd/display: Correct sequences and delays for DCN35 PG & RCG
David Rosca <[email protected]>
drm/amdgpu/vcn4: Fix IB parsing with multiple engine info packages
David Rosca <[email protected]>
drm/amdgpu/vcn: Allow limiting ctx to instance 0 for AV1 at any time
Alex Deucher <[email protected]>
drm/amdgpu: fix a memory leak in fence cleanup when unloading
Thomas Hellström <[email protected]>
drm/xe: Block exec and rebind worker while evicting for suspend / hibernate
Thomas Hellström <[email protected]>
drm/xe: Allow the pm notifier to continue on failure
Thomas Hellström <[email protected]>
drm/xe: Attempt to bring bos back to VRAM after eviction
Jani Nikula <[email protected]>
drm/i915/power: fix size for for_each_set_bit() in abox iteration
Johan Hovold <[email protected]>
drm/mediatek: fix potential OF node use-after-free
Quanmin Yan <[email protected]>
mm/damon/lru_sort: avoid divide-by-zero in damon_lru_sort_apply_parameters()
Sang-Heon Jeon <[email protected]>
mm/damon/core: set quota->charged_from to jiffies at first charge window
Kyle Meyer <[email protected]>
mm/memory-failure: fix redundant updates for already poisoned pages
Miaohe Lin <[email protected]>
mm/memory-failure: fix VM_BUG_ON_PAGE(PagePoisoned(page)) when unpoison memory
Uladzislau Rezki (Sony) <[email protected]>
mm/vmalloc, mm/kasan: respect gfp mask in kasan_populate_vmalloc()
Wei Yang <[email protected]>
mm/khugepaged: fix the address passed to notifier on testing young
Jeongjun Park <[email protected]>
mm/hugetlb: add missing hugetlb_lock in __unmap_hugepage_range()
Miklos Szeredi <[email protected]>
fuse: prevent overflow in copy_file_range return value
Miklos Szeredi <[email protected]>
fuse: check if copy_file_range() returns larger than requested size
Amir Goldstein <[email protected]>
fuse: do not allow mapping a non-regular backing file
Christophe Kerello <[email protected]>
mtd: rawnand: stm32_fmc2: fix ECC overwrite
Christophe Kerello <[email protected]>
mtd: rawnand: stm32_fmc2: avoid overlapping mappings on ECC buffer
Alexander Sverdlin <[email protected]>
mtd: nand: raw: atmel: Respect tAR, tCLR in read setup timing
Paulo Alcantara <[email protected]>
smb: client: fix data loss due to broken rename(2)
Paulo Alcantara <[email protected]>
smb: client: fix compound alignment with encryption
Breno Leitao <[email protected]>
s390: kexec: initialize kexec_buf struct
Johannes Berg <[email protected]>
wifi: iwlwifi: fix 130/1030 configs
Rafael J. Wysocki <[email protected]>
PM: hibernate: Restrict GFP mask in hibernation_snapshot()
Rafael J. Wysocki <[email protected]>
PM: EM: Add function for registering a PD without capacity update
Oleksij Rempel <[email protected]>
net: usb: asix: ax88772: drop phylink use in PM to avoid MDIO runtime PM wakeups
Jiawen Wu <[email protected]>
net: libwx: fix to enable RSS
Jonas Jelonek <[email protected]>
i2c: rtl9300: remove broken SMBus Quick operation support
Jonas Jelonek <[email protected]>
i2c: rtl9300: ensure data length is within supported range
Chiasheng Lee <[email protected]>
i2c: i801: Hide Intel Birch Stream SoC TCO WDT
Omar Sandoval <[email protected]>
btrfs: fix subvolume deletion lockup caused by inodes xarray race
Boris Burkov <[email protected]>
btrfs: fix squota compressed stats leak
Mark Tinguely <[email protected]>
ocfs2: fix recursive semaphore deadlock in fiemap call
Matthieu Baerts (NGI0) <[email protected]>
netlink: specs: mptcp: fix if-idx attribute type
Matthieu Baerts (NGI0) <[email protected]>
doc: mptcp: net.mptcp.pm_type is deprecated
Krister Johansen <[email protected]>
mptcp: sockopt: make sync_socket_options propagate SOCK_KEEPOPEN
Breno Leitao <[email protected]>
arm64: kexec: initialize kexec_buf struct in load_other_segments()
Nathan Chancellor <[email protected]>
compiler-clang.h: define __SANITIZE_*__ macros only when undefined
Trond Myklebust <[email protected]>
Revert "SUNRPC: Don't allow waiting for exiting tasks"
Jonas Jelonek <[email protected]>
i2c: rtl9300: fix channel number bound check
Salah Triki <[email protected]>
EDAC/altera: Delete an inappropriate dma_free_coherent() call
wangzijie <[email protected]>
proc: fix type confusion in pde_set_flags()
Kuniyuki Iwashima <[email protected]>
tcp_bpf: Call sk_msg_free() when tcp_bpf_send_verdict() fails to allocate psock->cork.
Peilin Ye <[email protected]>
bpf: Tell memcg to use allow_spinning=false path in bpf_timer_init()
KaFai Wan <[email protected]>
bpf: Allow fall back to interpreter for programs with stack size <= 512
Kumar Kartikeya Dwivedi <[email protected]>
rqspinlock: Choose trylock fallback for NMI waiters
Maciej Fijalkowski <[email protected]>
xsk: Fix immature cq descriptor production
Daniel Borkmann <[email protected]>
bpf: Fix out-of-bounds dynptr write in bpf_crypto_crypt
Mario Limonciello (AMD) <[email protected]>
cpufreq/amd-pstate: Fix a regression leading to EPP 0 after resume
Thomas Richter <[email protected]>
s390/cpum_cf: Deny all sampling events by counter PMU
Thomas Richter <[email protected]>
s390/pai: Deny all events not handled by this PMU
Gautham R. Shenoy <[email protected]>
cpufreq/amd-pstate: Fix setting of CPPC.min_perf in active mode for performance governor
Jesper Dangaard Brouer <[email protected]>
bpf, cpumap: Disable page_pool direct xdp_return need larger scope
Pu Lehui <[email protected]>
tracing: Silence warning when chunk allocation fails in trace_pid_write
Jonathan Curley <[email protected]>
NFSv4/flexfiles: Fix layout merge mirror check.
Trond Myklebust <[email protected]>
NFS: nfs_invalidate_folio() must observe the offset and size arguments
Trond Myklebust <[email protected]>
NFSv4.2: Serialise O_DIRECT i/o and copy range
Trond Myklebust <[email protected]>
NFSv4.2: Serialise O_DIRECT i/o and clone range
Trond Myklebust <[email protected]>
NFSv4.2: Serialise O_DIRECT i/o and fallocate()
Trond Myklebust <[email protected]>
NFS: Serialise O_DIRECT i/o and truncate()
Wang Liang <[email protected]>
tracing/osnoise: Fix null-ptr-deref in bitmap_parselist()
Vladimir Riabchun <[email protected]>
ftrace/samples: Fix function size computation
Scott Mayhew <[email protected]>
nfs/localio: restore creds before releasing pageio data
Luo Gengkun <[email protected]>
tracing: Fix tracing_marker may trigger page fault during preempt_disable
Trond Myklebust <[email protected]>
NFSv4: Clear the NFS_CAP_XATTR flag if not supported by the server
Trond Myklebust <[email protected]>
NFSv4: Clear NFS_CAP_OPEN_XOR and NFS_CAP_DELEGTIME if not supported
Trond Myklebust <[email protected]>
NFSv4: Clear the NFS_CAP_FS_LOCATIONS flag if it is not set
Guenter Roeck <[email protected]>
trace/fgraph: Fix error handling
Xiao Ni <[email protected]>
md: keep recovery_cp in mdp_superblock_s
Trond Myklebust <[email protected]>
NFSv4: Don't clear capabilities that won't be reset
Justin Worrell <[email protected]>
SUNRPC: call xs_sock_process_cmsg for all cmsg
Tigran Mkrtchyan <[email protected]>
flexfiles/pNFS: fix NULL checks on result of ff_layout_choose_ds_for_read
Alex Deucher <[email protected]>
Revert "drm/amdgpu: Add more checks to PSP mailbox"
Luiz Augusto von Dentz <[email protected]>
Bluetooth: ISO: Fix getname not returning broadcast fields
Luiz Augusto von Dentz <[email protected]>
Bluetooth: hci_conn: Fix running bis_cleanup for hci_conn->type PA_LINK
Lu Baolu <[email protected]>
iommu/vt-d: Make iotlb_sync_map a static property of dmar_domain
Jason Gunthorpe <[email protected]>
iommu/vt-d: Split paging_domain_compatible()
Jason Gunthorpe <[email protected]>
iommu/vt-d: Create unique domain ops for each stage
Jason Gunthorpe <[email protected]>
iommu/vt-d: Split intel_iommu_domain_alloc_paging_flags()
Luiz Augusto von Dentz <[email protected]>
Bluetooth: hci_conn: Fix not cleaning up Broadcaster/Broadcast Source
Dan Carpenter <[email protected]>
irqchip/mvebu-gicp: Fix an IS_ERR() vs NULL check in probe()
Kan Liang <[email protected]>
perf: Fix the POLL_HUP delivery breakage
Baochen Qiang <[email protected]>
dma-debug: don't enforce dma mapping check on noncoherent allocations
Amir Goldstein <[email protected]>
fhandle: use more consistent rules for decoding file handle from userns
Edward Adam Davis <[email protected]>
fuse: Block access to folio overlimit
Christian Brauner <[email protected]>
coredump: don't pointlessly check and spew warnings
Christoph Hellwig <[email protected]>
block: don't silently ignore metadata for sync read/write
Christoph Hellwig <[email protected]>
fs: add a FMODE_ flag to indicate IOCB_HAS_METADATA availability
-------------
Diffstat:
.../bindings/serial/brcm,bcm7271-uart.yaml | 2 +- Documentation/netlink/specs/mptcp_pm.yaml | 2 +- Documentation/networking/can.rst | 2 +- Documentation/networking/mptcp.rst | 8 +- Makefile | 4 +- arch/arm64/kernel/machine_kexec_file.c | 2 +- arch/s390/kernel/kexec_elf.c | 2 +- arch/s390/kernel/kexec_image.c | 2 +- arch/s390/kernel/machine_kexec_file.c | 6 +- arch/s390/kernel/perf_cpum_cf.c | 4 +- arch/s390/kernel/perf_pai_crypto.c | 4 +- arch/s390/kernel/perf_pai_ext.c | 2 +- arch/x86/kernel/cpu/topology_amd.c | 25 +- block/fops.c | 13 +- drivers/cpufreq/amd-pstate.c | 19 +- drivers/cpufreq/intel_pstate.c | 4 +- drivers/dma/dw/rzn1-dmamux.c | 15 +- drivers/dma/idxd/init.c | 39 +-- drivers/dma/qcom/bam_dma.c | 8 +- drivers/dma/ti/edma.c | 4 +- drivers/edac/altera_edac.c | 1 - drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 4 - drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h | 11 - drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 2 - drivers/gpu/drm/amd/amdgpu/isp_v4_1_1.c | 2 + drivers/gpu/drm/amd/amdgpu/psp_v10_0.c | 4 +- drivers/gpu/drm/amd/amdgpu/psp_v11_0.c | 31 +-- drivers/gpu/drm/amd/amdgpu/psp_v11_0_8.c | 25 +- drivers/gpu/drm/amd/amdgpu/psp_v12_0.c | 18 +- drivers/gpu/drm/amd/amdgpu/psp_v13_0.c | 25 +- drivers/gpu/drm/amd/amdgpu/psp_v13_0_4.c | 25 +- drivers/gpu/drm/amd/amdgpu/psp_v14_0.c | 25 +- drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c | 12 +- drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c | 60 +++-- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 106 +++++---- .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 1 + drivers/gpu/drm/amd/display/dc/dc.h | 1 + .../gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c | 74 +++--- .../drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c | 2 +- .../drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c | 115 ++------- .../gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c | 3 - .../drm/amd/display/dc/hwss/dcn351/dcn351_init.c | 3 - drivers/gpu/drm/amd/display/dc/inc/hw/pg_cntl.h | 1 + .../drm/amd/display/dc/pg/dcn35/dcn35_pg_cntl.c | 78 +++--- drivers/gpu/drm/display/drm_dp_helper.c | 42 +++- drivers/gpu/drm/drm_edid.c | 232 +++++++++--------- drivers/gpu/drm/i915/display/intel_display_power.c | 6 +- drivers/gpu/drm/mediatek/mtk_drm_drv.c | 11 +- drivers/gpu/drm/panthor/panthor_drv.c | 2 +- drivers/gpu/drm/xe/tests/xe_bo.c | 2 +- drivers/gpu/drm/xe/tests/xe_dma_buf.c | 10 +- drivers/gpu/drm/xe/xe_bo.c | 16 +- drivers/gpu/drm/xe/xe_bo.h | 2 +- drivers/gpu/drm/xe/xe_device_types.h | 6 + drivers/gpu/drm/xe/xe_dma_buf.c | 2 +- drivers/gpu/drm/xe/xe_exec.c | 9 + drivers/gpu/drm/xe/xe_pm.c | 42 +++- drivers/gpu/drm/xe/xe_survivability_mode.c | 3 +- drivers/gpu/drm/xe/xe_vm.c | 42 +++- drivers/gpu/drm/xe/xe_vm.h | 2 + drivers/gpu/drm/xe/xe_vm_types.h | 5 + drivers/i2c/busses/i2c-i801.c | 2 +- drivers/i2c/busses/i2c-rtl9300.c | 22 +- drivers/input/joystick/xpad.c | 2 + drivers/input/misc/iqs7222.c | 3 + drivers/input/serio/i8042-acpipnpio.h | 14 ++ drivers/iommu/intel/cache.c | 5 +- drivers/iommu/intel/iommu.c | 263 ++++++++++++++------- drivers/iommu/intel/iommu.h | 12 + drivers/iommu/intel/nested.c | 4 +- drivers/iommu/intel/svm.c | 1 - drivers/irqchip/irq-mvebu-gicp.c | 2 +- drivers/md/md.c | 6 +- drivers/mtd/nand/raw/atmel/nand-controller.c | 16 +- .../mtd/nand/raw/nuvoton-ma35d1-nand-controller.c | 4 +- drivers/mtd/nand/raw/stm32_fmc2_nand.c | 46 ++-- drivers/mtd/nand/spi/core.c | 18 +- drivers/mtd/nand/spi/winbond.c | 80 ++++++- drivers/net/can/xilinx_can.c | 16 +- drivers/net/dsa/b53/b53_common.c | 17 +- drivers/net/ethernet/freescale/fec_main.c | 3 +- drivers/net/ethernet/intel/i40e/i40e_main.c | 2 +- drivers/net/ethernet/intel/igb/igb_ethtool.c | 5 +- drivers/net/ethernet/intel/igb/igb_main.c | 3 +- drivers/net/ethernet/ti/icssg/icssg_prueth.c | 20 +- drivers/net/ethernet/wangxun/libwx/wx_hw.c | 4 - drivers/net/macsec.c | 1 + drivers/net/phy/phy.c | 12 +- drivers/net/phy/phylink.c | 28 ++- drivers/net/wireless/ath/ath12k/core.h | 1 + drivers/net/wireless/ath/ath12k/dp_mon.c | 22 +- drivers/net/wireless/ath/ath12k/dp_rx.c | 11 +- drivers/net/wireless/ath/ath12k/hw.c | 55 +++++ drivers/net/wireless/ath/ath12k/hw.h | 2 + drivers/net/wireless/ath/ath12k/mac.c | 127 +++++----- drivers/net/wireless/ath/ath12k/peer.c | 2 +- drivers/net/wireless/ath/ath12k/peer.h | 28 +++ drivers/net/wireless/ath/ath12k/wmi.c | 58 ++++- drivers/net/wireless/ath/ath12k/wmi.h | 16 +- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 26 +- drivers/pci/controller/pci-mvebu.c | 21 +- drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c | 4 +- drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 25 +- drivers/phy/tegra/xusb-tegra210.c | 6 +- drivers/phy/ti/phy-omap-usb2.c | 13 + drivers/phy/ti/phy-ti-pipe3.c | 13 + drivers/regulator/sy7636a-regulator.c | 7 +- drivers/tty/hvc/hvc_console.c | 6 +- drivers/tty/serial/sc16is7xx.c | 14 +- drivers/usb/gadget/function/f_midi2.c | 11 +- drivers/usb/gadget/udc/dummy_hcd.c | 8 +- drivers/usb/host/xhci-dbgcap.c | 94 +++++--- drivers/usb/host/xhci-mem.c | 2 +- drivers/usb/serial/option.c | 17 ++ drivers/usb/typec/tcpm/tcpm.c | 12 +- fs/btrfs/extent_io.c | 73 +++++- fs/btrfs/inode.c | 12 +- fs/btrfs/qgroup.c | 6 +- fs/ceph/addr.c | 9 +- fs/ceph/debugfs.c | 14 +- fs/ceph/dir.c | 17 +- fs/ceph/file.c | 24 +- fs/ceph/inode.c | 88 +++++-- fs/ceph/mds_client.c | 172 ++++++++------ fs/ceph/mds_client.h | 18 +- fs/coredump.c | 4 + fs/erofs/data.c | 8 +- fs/erofs/fileio.c | 2 +- fs/erofs/fscache.c | 2 +- fs/erofs/inode.c | 8 +- fs/erofs/internal.h | 2 +- fs/erofs/super.c | 16 +- fs/erofs/zdata.c | 17 +- fs/erofs/zmap.c | 98 ++++---- fs/exec.c | 2 +- fs/fhandle.c | 8 + fs/fuse/dev.c | 2 +- fs/fuse/file.c | 5 +- fs/fuse/passthrough.c | 5 + fs/kernfs/file.c | 58 +++-- fs/nfs/client.c | 2 + fs/nfs/file.c | 7 +- fs/nfs/flexfilelayout/flexfilelayout.c | 21 +- fs/nfs/inode.c | 4 +- fs/nfs/internal.h | 10 + fs/nfs/io.c | 13 +- fs/nfs/localio.c | 12 +- fs/nfs/nfs42proc.c | 2 + fs/nfs/nfs4file.c | 2 + fs/nfs/nfs4proc.c | 7 +- fs/nfs/write.c | 1 + fs/ocfs2/extent_map.c | 10 +- fs/proc/generic.c | 3 +- fs/resctrl/ctrlmondata.c | 2 +- fs/resctrl/internal.h | 4 +- fs/resctrl/monitor.c | 6 +- fs/smb/client/cifsglob.h | 13 +- fs/smb/client/file.c | 18 +- fs/smb/client/inode.c | 86 +++++-- fs/smb/client/smb2glob.h | 3 +- fs/smb/client/smb2inode.c | 204 ++++++++++++---- fs/smb/client/smb2ops.c | 32 ++- fs/smb/client/smb2proto.h | 3 + fs/smb/client/trace.h | 9 +- include/drm/display/drm_dp_helper.h | 6 + include/drm/drm_connector.h | 4 +- include/drm/drm_edid.h | 8 + include/linux/compiler-clang.h | 31 ++- include/linux/energy_model.h | 10 + include/linux/fs.h | 3 +- include/linux/kasan.h | 6 +- include/linux/mtd/spinand.h | 8 + include/net/netfilter/nf_tables.h | 11 +- include/net/netfilter/nf_tables_core.h | 49 ++-- include/net/netns/nftables.h | 1 + include/uapi/linux/raid/md_p.h | 2 +- io_uring/rw.c | 3 + kernel/bpf/Makefile | 1 + kernel/bpf/core.c | 16 +- kernel/bpf/cpumap.c | 4 +- kernel/bpf/crypto.c | 2 +- kernel/bpf/helpers.c | 7 +- kernel/bpf/rqspinlock.c | 2 +- kernel/dma/debug.c | 48 +++- kernel/dma/debug.h | 20 ++ kernel/dma/mapping.c | 4 +- kernel/events/core.c | 1 + kernel/power/energy_model.c | 29 ++- kernel/power/hibernate.c | 1 + kernel/time/hrtimer.c | 11 +- kernel/trace/fgraph.c | 3 +- kernel/trace/trace.c | 10 +- kernel/trace/trace_osnoise.c | 3 + mm/damon/core.c | 4 + mm/damon/lru_sort.c | 5 + mm/damon/reclaim.c | 5 + mm/damon/sysfs.c | 14 +- mm/hugetlb.c | 9 +- mm/kasan/shadow.c | 31 ++- mm/khugepaged.c | 4 +- mm/memory-failure.c | 20 +- mm/vmalloc.c | 8 +- net/bluetooth/hci_conn.c | 14 +- net/bluetooth/hci_event.c | 7 +- net/bluetooth/iso.c | 2 +- net/bridge/br.c | 7 + net/can/j1939/bus.c | 5 +- net/can/j1939/j1939-priv.h | 1 + net/can/j1939/main.c | 3 + net/can/j1939/socket.c | 52 ++++ net/ceph/messenger.c | 7 +- net/core/dev_ioctl.c | 22 +- net/hsr/hsr_device.c | 28 ++- net/hsr/hsr_main.c | 4 +- net/hsr/hsr_main.h | 3 + net/ipv4/ip_tunnel_core.c | 6 + net/ipv4/tcp_bpf.c | 5 +- net/mptcp/sockopt.c | 11 +- net/netfilter/nf_tables_api.c | 123 ++++++---- net/netfilter/nft_dynset.c | 5 +- net/netfilter/nft_lookup.c | 67 ++++-- net/netfilter/nft_objref.c | 5 +- net/netfilter/nft_set_bitmap.c | 14 +- net/netfilter/nft_set_hash.c | 54 ++--- net/netfilter/nft_set_pipapo.c | 211 ++++++----------- net/netfilter/nft_set_pipapo_avx2.c | 29 +-- net/netfilter/nft_set_rbtree.c | 46 ++-- net/netlink/genetlink.c | 3 + net/sunrpc/sched.c | 2 - net/sunrpc/xprtsock.c | 6 +- net/xdp/xsk.c | 113 +++++++-- net/xdp/xsk_queue.h | 12 + samples/ftrace/ftrace-direct-modify.c | 2 +- tools/testing/selftests/net/can/config | 3 + 234 files changed, 3151 insertions(+), 1711 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/189 fs: add a FMODE_ flag to indicate IOCB_HAS_METADATA availability
6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Hellwig <[email protected]>
[ Upstream commit d072148a8631f102de60ed5a3a827e85d09d24f0 ]
Currently the kernel will happily route io_uring requests with metadata to file operations that don't support it. Add a FMODE_ flag to guard that.
--- block/fops.c | 3 +++ include/linux/fs.h | 3 ++- io_uring/rw.c | 3 +++ 3 files changed, 8 insertions(+), 1 deletion(-)
block/fops.c +3 -0
@@ -7,6 +7,7 @@#include <linux/init.h> #include <linux/mm.h> #include <linux/blkdev.h> +#include <linux/blk-integrity.h> #include <linux/buffer_head.h> #include <linux/mpage.h> #include <linux/uio.h>
@@ -672,6 +673,8 @@ static int blkdev_open(struct inode *inode, struct file *filp)if (bdev_can_atomic_write (bdev)) filp->f_mode |=FMODE_CAN_ATOMIC_WRITE ; +if (blk_get_integrity (bdev->bd_disk)) + filp->f_mode |=FMODE_HAS_METADATA ; ret =bdev_open (bdev, mode, filp->private_data,NULL , filp);if (ret)
include/linux/fs.h +2 -1
@@ -149,7 +149,8 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset,/* Expect random access pattern */ #define FMODE_RANDOM ((__force fmode_t)(1 << 12)) -/* FMODE_* bit 13 */ +/* Supports IOCB_HAS_METADATA */ +#define FMODE_HAS_METADATA ((__force fmode_t)(1 << 13))/* File is opened with O_PATH; almost nothing can be done with it */ #define FMODE_PATH ((__force fmode_t)(1 << 14))
io_uring/rw.c +3 -0
@@ -886,6 +886,9 @@ static int io_rw_init_file(struct io_kiocb *req, fmode_t mode, int rw_type)if (req->flags &REQ_F_HAS_METADATA ) {struct io_async_rw *io = req->async_data; +if (!(file->f_mode &FMODE_HAS_METADATA )) +return -EINVAL ; +/* * We have a union of meta fields with wpq used for buffered-io * in io_async_rw, so fail it here.
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 2/189 block: dont silently ignore metadata for sync read/write
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Hellwig <[email protected]>
[ Upstream commit 2729a60bbfb9215997f25372ebe9b7964f038296 ]
The block fops don't try to handle metadata for synchronous requests, probably because the completion handler looks at dio->iocb which is not valid for synchronous requests.
But silently ignoring metadata (or warning in case of __blkdev_direct_IO_simple) is a really bad idea as that can cause silent data corruption if a user ever shows up.
Instead simply handle metadata for synchronous requests as the completion handler can simply check for bio_integrity() as the block layer default integrity will already be freed at this point, and thus bio_integrity() will only return true for user mapped integrity.
--- block/fops.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
block/fops.c +5 -5
@@ -55,7 +55,6 @@ static ssize_t __blkdev_direct_IO_simple(struct kiocb *iocb,struct bio bio;ssize_t ret; -WARN_ON_ONCE (iocb->ki_flags &IOCB_HAS_METADATA );if (nr_pages <=DIO_INLINE_BIO_VECS ) vecs = inline_vecs;else {
@@ -132,7 +131,7 @@ static void blkdev_bio_end_io(struct bio *bio)if (bio->bi_status && !dio->bio.bi_status) dio->bio.bi_status = bio->bi_status; -if (!is_sync && (dio->iocb->ki_flags &IOCB_HAS_METADATA )) +if (bio_integrity (bio))bio_integrity_unmap_user (bio);if (atomic_dec_and_test (&dio->ref)) {
@@ -234,7 +233,7 @@ static ssize_t __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, } bio->bi_opf |=REQ_NOWAIT ; } -if (!is_sync && (iocb->ki_flags &IOCB_HAS_METADATA )) { +if (iocb->ki_flags &IOCB_HAS_METADATA ) { ret =bio_integrity_map_iter (bio, iocb->private);if (unlikely (ret)) goto fail;
@@ -302,7 +301,7 @@ static void blkdev_bio_end_io_async(struct bio *bio) ret =blk_status_to_errno (bio->bi_status); } -if (iocb->ki_flags &IOCB_HAS_METADATA ) +if (bio_integrity (bio))bio_integrity_unmap_user (bio); iocb->ki_complete (iocb, ret);
@@ -423,7 +422,8 @@ static ssize_t blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter) } nr_pages =bio_iov_vecs_to_alloc (iter,BIO_MAX_VECS +1 ); -if (likely (nr_pages <=BIO_MAX_VECS )) { +if (likely (nr_pages <=BIO_MAX_VECS && + !(iocb->ki_flags &IOCB_HAS_METADATA ))) {if (is_sync_kiocb (iocb))return __blkdev_direct_IO_simple (iocb, iter, bdev, nr_pages);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 3/189 coredump: dont pointlessly check and spew warnings
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <[email protected]>
[ Upstream commit be1e0283021ec73c2eb92839db9a471a068709d9 ]
When a write happens it doesn't make sense to check perform checks on the input. Skip them.
Whether a fixes tag is licensed is a bit of a gray area here but I'll add one for the socket validation part I added recently.
--- fs/coredump.c | 4 ++++ fs/exec.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-)
fs/coredump.c +4 -0
@@ -1263,11 +1263,15 @@ static int proc_dostring_coredump(const struct ctl_table *table, int write,ssize_t retval;char old_core_pattern[CORENAME_MAX_SIZE ]; +if (write) +return proc_dostring (table, write, buffer, lenp, ppos); + retval =strscpy (old_core_pattern, core_pattern,CORENAME_MAX_SIZE ); error =proc_dostring (table, write, buffer, lenp, ppos);if (error)return error; +if (!check_coredump_socket ()) {strscpy (core_pattern, old_core_pattern, retval +1 );return -EINVAL ;
fs/exec.c +1 -1
@@ -2048,7 +2048,7 @@ static int proc_dointvec_minmax_coredump(const struct ctl_table *table, int writ {int error =proc_dointvec_minmax (table, write, buffer, lenp, ppos); -if (!error) +if (!error && !write)validate_coredump_safety ();return error; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 4/189 fuse: Block access to folio overlimit
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Edward Adam Davis <[email protected]>
[ Upstream commit 9d81ba6d49a7457784f0b6a71046818b86ec7e44 ]
syz reported a slab-out-of-bounds Write in fuse_dev_do_write.
When the number of bytes to be retrieved is truncated to the upper limit by fc->max_pages and there is an offset, the oob is triggered.
Add a loop termination condition to prevent overruns.
--- fs/fuse/dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/fuse/dev.c +1 -1
@@ -1893,7 +1893,7 @@ static int fuse_retrieve(struct fuse_mount *fm, struct inode *inode, index = outarg->offset >>PAGE_SHIFT ; -while (num) { +while (num && ap->num_folios < num_pages) {struct folio *folio;unsigned int folio_offset;unsigned int nr_bytes;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 5/189 fhandle: use more consistent rules for decoding file handle from userns
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amir Goldstein <[email protected]>
[ Upstream commit bb585591ebf00fb1f6a1fdd1ea96b5848bd9112d ]
Commit 620c266f39493 ("fhandle: relax open_by_handle_at() permission checks") relaxed the coditions for decoding a file handle from non init userns.
The conditions are that that decoded dentry is accessible from the user provided mountfd (or to fs root) and that all the ancestors along the path have a valid id mapping in the userns.
These conditions are intentionally more strict than the condition that the decoded dentry should be "lookable" by path from the mountfd.
For example, the path /home/amir/dir/subdir is lookable by path from unpriv userns of user amir, because /home perms is 755, but the owner of /home does not have a valid id mapping in unpriv userns of user amir.
The current code did not check that the decoded dentry itself has a valid id mapping in the userns. There is no security risk in that, because that final open still performs the needed permission checks, but this is inconsistent with the checks performed on the ancestors, so the behavior can be a bit confusing.
Add the check for the decoded dentry itself, so that the entire path, including the last component has a valid id mapping in the userns.
--- fs/fhandle.c | 8 ++++++++ 1 file changed, 8 insertions(+)
fs/fhandle.c +8 -0
@@ -202,6 +202,14 @@ static int vfs_dentry_acceptable(void *context, struct dentry *dentry)if (!ctx->flags)return 1 ; +/* +* Verify that the decoded dentry itself has a valid id mapping. +* In case the decoded dentry is the mountfd root itself, this +* verifies that the mountfd inode itself has a valid id mapping. +*/ +if (!privileged_wrt_inode_uidgid (user_ns, idmap,d_inode (dentry))) +return 0 ; +/* * It's racy as we're not taking rename_lock but we're able to ignore * permissions and we just need an approximation whether we were able
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 6/189 dma-debug: dont enforce dma mapping check on noncoherent allocations
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baochen Qiang <[email protected]>
[ Upstream commit 7e2368a21741e2db542330b32aa6fdd8908e7cff ]
As discussed in [1], there is no need to enforce dma mapping check on noncoherent allocations, a simple test on the returned CPU address is good enough.
Add a new pair of debug helpers and use them for noncoherent alloc/free to fix this issue.
--- kernel/dma/debug.c | 48 +++++++++++++++++++++++++++++++++++++++++++- kernel/dma/debug.h | 20 ++++++++++++++++++ kernel/dma/mapping.c | 4 ++-- 3 files changed, 69 insertions(+), 3 deletions(-)
kernel/dma/debug.c +47 -1
@@ -39,6 +39,7 @@ enum { dma_debug_sg, dma_debug_coherent, dma_debug_resource, + dma_debug_noncoherent, }; enum map_err_types {
@@ -141,6 +142,7 @@ static const char *type2name[] = { [dma_debug_sg] = "scatter-gather", [dma_debug_coherent] = "coherent", [dma_debug_resource] = "resource", + [dma_debug_noncoherent] = "noncoherent", };static const char *dir2name[] = {
@@ -993,7 +995,8 @@ static void check_unmap(struct dma_debug_entry *ref)"[mapped as %s] [unmapped as %s]\n" , ref->dev_addr, ref->size, type2name[entry->type], type2name[ref->type]); - }else if (entry->type == dma_debug_coherent && + }else if ((entry->type == dma_debug_coherent || + entry->type == dma_debug_noncoherent) && ref->paddr != entry->paddr) {err_printk (ref->dev, entry,"device driver frees " "DMA memory with different CPU address "
@@ -1581,6 +1584,49 @@ void debug_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, } } +void debug_dma_alloc_pages (struct device *dev,struct page *page, +size_t size,int direction, +dma_addr_t dma_addr, +unsigned long attrs) +{ +struct dma_debug_entry *entry; + +if (unlikely (dma_debug_disabled ())) +return ; + + entry =dma_entry_alloc (); +if (!entry) +return ; + + entry->type = dma_debug_noncoherent; + entry->dev = dev; + entry->paddr =page_to_phys (page); + entry->size = size; + entry->dev_addr = dma_addr; + entry->direction = direction; + +add_dma_entry (entry, attrs); +} + +void debug_dma_free_pages (struct device *dev,struct page *page, +size_t size,int direction, +dma_addr_t dma_addr) +{ +struct dma_debug_entry ref = { + .type = dma_debug_noncoherent, + .dev = dev, + .paddr =page_to_phys (page), + .dev_addr = dma_addr, + .size = size, + .direction = direction, + }; + +if (unlikely (dma_debug_disabled ())) +return ; + +check_unmap (&ref); +} +static int __init dma_debug_driver_setup (char *str) {int i;
kernel/dma/debug.h +20 -0
@@ -54,6 +54,13 @@ extern void debug_dma_sync_sg_for_cpu(struct device *dev,extern void debug_dma_sync_sg_for_device (struct device *dev,struct scatterlist *sg,int nelems,int direction); +extern void debug_dma_alloc_pages (struct device *dev,struct page *page, +size_t size,int direction, +dma_addr_t dma_addr, +unsigned long attrs); +extern void debug_dma_free_pages (struct device *dev,struct page *page, +size_t size,int direction, +dma_addr_t dma_addr);#else /* CONFIG_DMA_API_DEBUG */ static inline void debug_dma_map_page(struct device *dev, struct page *page, size_t offset, size_t size,
@@ -126,5 +133,18 @@ static inline void debug_dma_sync_sg_for_device(struct device *dev, int nelems, int direction) { } + +static inline void debug_dma_alloc_pages (struct device *dev,struct page *page, +size_t size,int direction, +dma_addr_t dma_addr, +unsigned long attrs) +{ +} + +static inline void debug_dma_free_pages (struct device *dev,struct page *page, +size_t size,int direction, +dma_addr_t dma_addr) +{ +}#endif /* CONFIG_DMA_API_DEBUG */ #endif /* _KERNEL_DMA_DEBUG_H */
kernel/dma/mapping.c +2 -2
@@ -712,7 +712,7 @@ struct page *dma_alloc_pages(struct device *dev, size_t size,if (page) {trace_dma_alloc_pages (dev,page_to_virt (page), *dma_handle, size, dir, gfp,0 ); -debug_dma_map_page (dev, page,0 , size, dir, *dma_handle,0 ); +debug_dma_alloc_pages (dev, page, size, dir, *dma_handle,0 ); }else {trace_dma_alloc_pages (dev,NULL ,0 , size, dir, gfp,0 ); }
@@ -738,7 +738,7 @@ void dma_free_pages(struct device *dev, size_t size, struct page *page, dma_addr_t dma_handle, enum dma_data_direction dir) { trace_dma_free_pages(dev, page_to_virt(page), dma_handle, size, dir, 0); -debug_dma_unmap_page (dev, dma_handle, size, dir); +debug_dma_free_pages (dev, page, size, dir, dma_handle);__dma_free_pages (dev, size, page, dma_handle, dir); }EXPORT_SYMBOL_GPL (dma_free_pages);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 7/189 perf: Fix the POLL_HUP delivery breakage
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kan Liang <[email protected]>
[ Upstream commit 18dbcbfabfffc4a5d3ea10290c5ad27f22b0d240 ]
The event_limit can be set by the PERF_EVENT_IOC_REFRESH to limit the number of events. When the event_limit reaches 0, the POLL_HUP signal should be sent. But it's missed.
The corresponding counter should be stopped when the event_limit reaches
0. It was implemented in the ARCH-specific code. However, since the commit 9734e25fbf5a ("perf: Fix the throttle logic for a group"), all the ARCH-specific code has been moved to the generic code. The code to handle the event_limit was lost.
Add the event->pmu->stop(event, 0); back.
--- kernel/events/core.c | 1 + 1 file changed, 1 insertion(+)
kernel/events/core.c +1 -0
@@ -10330,6 +10330,7 @@ static int __perf_event_overflow(struct perf_event *event, ret =1 ; event->pending_kill =POLL_HUP ;perf_event_disable_inatomic (event); + event->pmu->stop (event,0 ); }if (event->attr.sigtrap) {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 8/189 irqchip/mvebu-gicp: Fix an IS_ERR() vs NULL check in probe()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
[ Upstream commit c8bb0f00a4886b24d933ffaabcdc09bf9a370dca ]
ioremap() never returns error pointers, it returns NULL on error. Fix the check to match.
--- drivers/irqchip/irq-mvebu-gicp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/irqchip/irq-mvebu-gicp.c +1 -1
@@ -238,7 +238,7 @@ static int mvebu_gicp_probe(struct platform_device *pdev) } base =ioremap (gicp->res->start,resource_size (gicp->res)); -if (IS_ERR (base)) { +if (!base) {dev_err (&pdev->dev,"ioremap() failed. Unable to clear pending interrupts.\n" ); }else {for (i =0 ; i <64 ; i++)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 9/189 Bluetooth: hci_conn: Fix not cleaning up Broadcaster/Broadcast Source
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luiz Augusto von Dentz <[email protected]>
[ Upstream commit 3ba486c5f3ce2c22ffd29c0103404cdbe21912b3 ]
This fixes Broadcaster/Broadcast Source not sending HCI_OP_LE_TERM_BIG because HCI_CONN_PER_ADV where not being set.
--- net/bluetooth/hci_conn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/bluetooth/hci_conn.c +1 -1
@@ -2274,7 +2274,7 @@ struct hci_conn *hci_connect_bis(struct hci_dev *hdev, bdaddr_t *dst,* the start periodic advertising and create BIG commands have * been queued */ -hci_conn_hash_list_state (hdev, bis_mark_per_adv,PA_LINK , +hci_conn_hash_list_state (hdev, bis_mark_per_adv,BIS_LINK ,BT_BOUND , &data);/* Queue start periodic advertising and create BIG */
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 10/189 iommu/vt-d: Split intel_iommu_domain_alloc_paging_flags()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Gunthorpe <[email protected]>
[ Upstream commit b9434ba97c44f5744ea537adfd1f9f3fe102681c ]
Create stage specific functions that check the stage specific conditions if each stage can be supported.
Have intel_iommu_domain_alloc_paging_flags() call both stages in sequence until one does not return EOPNOTSUPP and prefer to use the first stage if available and suitable for the requested flags.
Move second stage only operations like nested_parent and dirty_tracking into the second stage function for clarity.
Move initialization of the iommu_domain members into paging_domain_alloc().
Drop initialization of domain->owner as the callers all do it.
Stable-dep-of: cee686775f9c ("iommu/vt-d: Make iotlb_sync_map a static property of dmar_domain")
--- drivers/iommu/intel/iommu.c | 100 +++++++++++++++++++++--------------- 1 file changed, 58 insertions(+), 42 deletions(-)
drivers/iommu/intel/iommu.c +58 -42
@@ -3299,10 +3299,15 @@ static struct dmar_domain *paging_domain_alloc(struct device *dev, bool first_stspin_lock_init (&domain->lock);spin_lock_init (&domain->cache_lock);xa_init (&domain->iommu_array); +INIT_LIST_HEAD (&domain->s1_domains); +spin_lock_init (&domain->s1_lock); domain->nid =dev_to_node (dev); domain->use_first_level = first_stage; + domain->domain.type =IOMMU_DOMAIN_UNMANAGED ; + domain->domain.ops = intel_iommu_ops.default_domain_ops; +/* calculate the address width */ addr_width =agaw_to_width (iommu->agaw);if (addr_width >cap_mgaw (iommu->cap))
@@ -3344,62 +3349,73 @@ static struct dmar_domain *paging_domain_alloc(struct device *dev, bool first_st }static struct iommu_domain * -intel_iommu_domain_alloc_paging_flags (struct device *dev,u32 flags, -const struct iommu_user_data *user_data) +intel_iommu_domain_alloc_first_stage (struct device *dev, +struct intel_iommu *iommu,u32 flags) +{ +struct dmar_domain *dmar_domain; + +if (flags & ~IOMMU_HWPT_ALLOC_PASID ) +return ERR_PTR (-EOPNOTSUPP ); + +/* Only SL is available in legacy mode */ +if (!sm_supported (iommu) || !ecap_flts (iommu->ecap)) +return ERR_PTR (-EOPNOTSUPP ); + + dmar_domain =paging_domain_alloc (dev, true); +if (IS_ERR (dmar_domain)) +return ERR_CAST (dmar_domain); +return &dmar_domain->domain; +} + +static struct iommu_domain * +intel_iommu_domain_alloc_second_stage (struct device *dev, +struct intel_iommu *iommu,u32 flags) { -struct device_domain_info *info =dev_iommu_priv_get (dev); -bool dirty_tracking = flags &IOMMU_HWPT_ALLOC_DIRTY_TRACKING ; -bool nested_parent = flags &IOMMU_HWPT_ALLOC_NEST_PARENT ; -struct intel_iommu *iommu = info->iommu;struct dmar_domain *dmar_domain; -struct iommu_domain *domain; -bool first_stage;if (flags & (~(IOMMU_HWPT_ALLOC_NEST_PARENT |IOMMU_HWPT_ALLOC_DIRTY_TRACKING |IOMMU_HWPT_ALLOC_PASID )))return ERR_PTR (-EOPNOTSUPP ); -if (nested_parent && !nested_supported (iommu)) -return ERR_PTR (-EOPNOTSUPP ); -if (user_data || (dirty_tracking && !ssads_supported (iommu))) + +if (((flags &IOMMU_HWPT_ALLOC_NEST_PARENT ) && + !nested_supported (iommu)) || + ((flags &IOMMU_HWPT_ALLOC_DIRTY_TRACKING ) && + !ssads_supported (iommu)))return ERR_PTR (-EOPNOTSUPP ); -/* -* Always allocate the guest compatible page table unless -* IOMMU_HWPT_ALLOC_NEST_PARENT or IOMMU_HWPT_ALLOC_DIRTY_TRACKING -* is specified. -*/ -if (nested_parent || dirty_tracking) { -if (!sm_supported (iommu) || !ecap_slts (iommu->ecap)) -return ERR_PTR (-EOPNOTSUPP ); - first_stage = false; - }else { - first_stage =first_level_by_default (iommu); - } +/* Legacy mode always supports second stage */ +if (sm_supported (iommu) && !ecap_slts (iommu->ecap)) +return ERR_PTR (-EOPNOTSUPP ); - dmar_domain =paging_domain_alloc (dev, first_stage); + dmar_domain =paging_domain_alloc (dev, false);if (IS_ERR (dmar_domain))return ERR_CAST (dmar_domain); - domain = &dmar_domain->domain; - domain->type =IOMMU_DOMAIN_UNMANAGED ; - domain->owner = &intel_iommu_ops; - domain->ops = intel_iommu_ops.default_domain_ops; - -if (nested_parent) { - dmar_domain->nested_parent = true; -INIT_LIST_HEAD (&dmar_domain->s1_domains); -spin_lock_init (&dmar_domain->s1_lock); - } -if (dirty_tracking) { -if (dmar_domain->use_first_level) { -iommu_domain_free (domain); -return ERR_PTR (-EOPNOTSUPP ); - } - domain->dirty_ops = &intel_dirty_ops; - } + dmar_domain->nested_parent = flags &IOMMU_HWPT_ALLOC_NEST_PARENT ; -return domain; +if (flags &IOMMU_HWPT_ALLOC_DIRTY_TRACKING ) + dmar_domain->domain.dirty_ops = &intel_dirty_ops; + +return &dmar_domain->domain; +} + +static struct iommu_domain * +intel_iommu_domain_alloc_paging_flags (struct device *dev,u32 flags, +const struct iommu_user_data *user_data) +{ +struct device_domain_info *info =dev_iommu_priv_get (dev); +struct intel_iommu *iommu = info->iommu; +struct iommu_domain *domain; + +if (user_data) +return ERR_PTR (-EOPNOTSUPP ); + +/* Prefer first stage if possible by default. */ + domain =intel_iommu_domain_alloc_first_stage (dev, iommu, flags); +if (domain !=ERR_PTR (-EOPNOTSUPP )) +return domain; +return intel_iommu_domain_alloc_second_stage (dev, iommu, flags); }static void intel_iommu_domain_free (struct iommu_domain *domain)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 11/189 iommu/vt-d: Create unique domain ops for each stage
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Gunthorpe <[email protected]>
[ Upstream commit b33125296b5047115469b8a3b74c0fdbf4976548 ]
Use the domain ops pointer to tell what kind of domain it is instead of the internal use_first_level indication. This also protects against wrongly using a SVA/nested/IDENTITY/BLOCKED domain type in places they should not be.
The only remaining uses of use_first_level outside the paging domain are in paging_domain_compatible() and intel_iommu_enforce_cache_coherency().
Thus, remove the useless sets of use_first_level in intel_svm_domain_alloc() and intel_iommu_domain_alloc_nested(). None of the unique ops for these domain types ever reference it on their call chains.
Add a WARN_ON() check in domain_context_mapping_one() as it only works with second stage.
This is preparation for iommupt which will have different ops for each of the stages.
Stable-dep-of: cee686775f9c ("iommu/vt-d: Make iotlb_sync_map a static property of dmar_domain")
--- drivers/iommu/intel/cache.c | 5 +-- drivers/iommu/intel/iommu.c | 60 +++++++++++++++++++++++++----------- drivers/iommu/intel/iommu.h | 12 ++++++++ drivers/iommu/intel/nested.c | 4 +-- drivers/iommu/intel/svm.c | 1 - 5 files changed, 58 insertions(+), 24 deletions(-)
drivers/iommu/intel/cache.c +3 -2
@@ -370,7 +370,7 @@ static void cache_tag_flush_iotlb(struct dmar_domain *domain, struct cache_tag *struct intel_iommu *iommu = tag->iommu;u64 type =DMA_TLB_PSI_FLUSH ; -if (domain->use_first_level) { +if (intel_domain_is_fs_paging (domain)) {qi_batch_add_piotlb (iommu, tag->domain_id, tag->pasid, addr, pages, ih, domain->qi_batch);return ;
@@ -529,7 +529,8 @@ void cache_tag_flush_range_np(struct dmar_domain *domain, unsigned long start,qi_batch_flush_descs (iommu, domain->qi_batch); iommu = tag->iommu; -if (!cap_caching_mode (iommu->cap) || domain->use_first_level) { +if (!cap_caching_mode (iommu->cap) || +intel_domain_is_fs_paging (domain)) {iommu_flush_write_buffer (iommu);continue ; }
drivers/iommu/intel/iommu.c +42 -18
122 lines not on this page · raw message
drivers/iommu/intel/iommu.h +12 -0
@@ -1381,6 +1381,18 @@ struct context_entry *iommu_context_addr(struct intel_iommu *iommu, u8 bus, u8 devfn, int alloc);extern const struct iommu_ops intel_iommu_ops; +extern const struct iommu_domain_ops intel_fs_paging_domain_ops; +extern const struct iommu_domain_ops intel_ss_paging_domain_ops; + +static inline bool intel_domain_is_fs_paging (struct dmar_domain *domain) +{ +return domain->domain.ops == &intel_fs_paging_domain_ops; +} + +static inline bool intel_domain_is_ss_paging (struct dmar_domain *domain) +{ +return domain->domain.ops == &intel_ss_paging_domain_ops; +}#ifdef CONFIG_INTEL_IOMMU extern int intel_iommu_sm;
drivers/iommu/intel/nested.c +1 -3
@@ -216,8 +216,7 @@ intel_iommu_domain_alloc_nested(struct device *dev, struct iommu_domain *parent,/* Must be nested domain */ if (user_data->type !=IOMMU_HWPT_DATA_VTD_S1 )return ERR_PTR (-EOPNOTSUPP ); -if (parent->ops != intel_iommu_ops.default_domain_ops || - !s2_domain->nested_parent) +if (!intel_domain_is_ss_paging (s2_domain) || !s2_domain->nested_parent)return ERR_PTR (-EINVAL ); ret = iommu_copy_struct_from_user(&vtd, user_data,
@@ -229,7 +228,6 @@ intel_iommu_domain_alloc_nested(struct device *dev, struct iommu_domain *parent,if (!domain)return ERR_PTR (-ENOMEM ); - domain->use_first_level = true; domain->s2_domain = s2_domain; domain->s1_cfg = vtd; domain->domain.ops = &intel_nested_domain_ops;
drivers/iommu/intel/svm.c +0 -1
@@ -214,7 +214,6 @@ struct iommu_domain *intel_svm_domain_alloc(struct device *dev,return ERR_PTR (-ENOMEM ); domain->domain.ops = &intel_svm_domain_ops; - domain->use_first_level = true;INIT_LIST_HEAD (&domain->dev_pasids);INIT_LIST_HEAD (&domain->cache_tags);spin_lock_init (&domain->cache_lock);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 12/189 iommu/vt-d: Split paging_domain_compatible()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Gunthorpe <[email protected]>
[ Upstream commit 85cfaacc99377a63e47412eeef66eff77197acea ]
Make First/Second stage specific functions that follow the same pattern in intel_iommu_domain_alloc_first/second_stage() for computing EOPNOTSUPP. This makes the code easier to understand as if we couldn't create a domain with the parameters for this IOMMU instance then we certainly are not compatible with it.
Check superpage support directly against the per-stage cap bits and the pgsize_bitmap.
Add a note that the force_snooping is read without locking. The locking needs to cover the compatible check and the add of the device to the list.
Stable-dep-of: cee686775f9c ("iommu/vt-d: Make iotlb_sync_map a static property of dmar_domain")
--- drivers/iommu/intel/iommu.c | 66 ++++++++++++++++++++++++++++++------- 1 file changed, 54 insertions(+), 12 deletions(-)
drivers/iommu/intel/iommu.c +54 -12
@@ -3434,33 +3434,75 @@ static void intel_iommu_domain_free(struct iommu_domain *domain)domain_exit (dmar_domain); } +static int paging_domain_compatible_first_stage (struct dmar_domain *dmar_domain, +struct intel_iommu *iommu) +{ +if (WARN_ON (dmar_domain->domain.dirty_ops || + dmar_domain->nested_parent)) +return -EINVAL ; + +/* Only SL is available in legacy mode */ +if (!sm_supported (iommu) || !ecap_flts (iommu->ecap)) +return -EINVAL ; + +/* Same page size support */ +if (!cap_fl1gp_support (iommu->cap) && + (dmar_domain->domain.pgsize_bitmap &SZ_1G )) +return -EINVAL ; +return 0 ; +} + +static int +paging_domain_compatible_second_stage (struct dmar_domain *dmar_domain, +struct intel_iommu *iommu) +{ +unsigned int sslps =cap_super_page_val (iommu->cap); + +if (dmar_domain->domain.dirty_ops && !ssads_supported (iommu)) +return -EINVAL ; +if (dmar_domain->nested_parent && !nested_supported (iommu)) +return -EINVAL ; + +/* Legacy mode always supports second stage */ +if (sm_supported (iommu) && !ecap_slts (iommu->ecap)) +return -EINVAL ; + +/* Same page size support */ +if (!(sslps &BIT (0 )) && (dmar_domain->domain.pgsize_bitmap &SZ_2M )) +return -EINVAL ; +if (!(sslps &BIT (1 )) && (dmar_domain->domain.pgsize_bitmap &SZ_1G )) +return -EINVAL ; +return 0 ; +} +int paging_domain_compatible (struct iommu_domain *domain,struct device *dev) {struct device_domain_info *info =dev_iommu_priv_get (dev);struct dmar_domain *dmar_domain =to_dmar_domain (domain);struct intel_iommu *iommu = info->iommu; +int ret = -EINVAL ;int addr_width; -if (WARN_ON_ONCE (!(domain->type & __IOMMU_DOMAIN_PAGING))) -return -EPERM ; +if (intel_domain_is_fs_paging (dmar_domain)) + ret =paging_domain_compatible_first_stage (dmar_domain, iommu); +else if (intel_domain_is_ss_paging (dmar_domain)) + ret =paging_domain_compatible_second_stage (dmar_domain, iommu); +else if (WARN_ON (true)) + ret = -EINVAL ; +if (ret) +return ret; +/* +* FIXME this is locked wrong, it needs to be under the +* dmar_domain->lock +*/ if (dmar_domain->force_snooping && !ecap_sc_support (iommu->ecap))return -EINVAL ; -if (domain->dirty_ops && !ssads_supported (iommu)) -return -EINVAL ; -if (dmar_domain->iommu_coherency !=iommu_paging_structure_coherency (iommu))return -EINVAL ; -if (dmar_domain->iommu_superpage != -iommu_superpage_capability (iommu, dmar_domain->use_first_level)) -return -EINVAL ; - -if (dmar_domain->use_first_level && - (!sm_supported (iommu) || !ecap_flts (iommu->ecap))) -return -EINVAL ;/* check if this iommu agaw is sufficient for max mapped address */ addr_width =agaw_to_width (iommu->agaw);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 13/189 iommu/vt-d: Make iotlb_sync_map a static property of dmar_domain
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lu Baolu <[email protected]>
[ Upstream commit cee686775f9cd4eae31f3c1f7ec24b2048082667 ]
Commit 12724ce3fe1a ("iommu/vt-d: Optimize iotlb_sync_map for non-caching/non-RWBF modes") dynamically set iotlb_sync_map. This causes synchronization issues due to lack of locking on map and attach paths, racing iommufd userspace operations.
Invalidation changes must precede device attachment to ensure all flushes complete before hardware walks page tables, preventing coherence issues.
Make domain->iotlb_sync_map static, set once during domain allocation. If an IOMMU requires iotlb_sync_map but the domain lacks it, attach is rejected. This won't reduce domain sharing: RWBF and shadowing page table caching are legacy uses with legacy hardware. Mixed configs (some IOMMUs in caching mode, others not) are unlikely in real-world scenarios.
--- drivers/iommu/intel/iommu.c | 43 +++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 14 deletions(-)
drivers/iommu/intel/iommu.c +29 -14
@@ -57,6 +57,8 @@static void __init check_tylersburg_isoch (void );static int rwbf_quirk; +#define rwbf_required (iommu) (rwbf_quirk || cap_rwbf((iommu)->cap)) +/* * set to 1 to panic kernel if can't successfully enable VT-d * (used when kernel is launched w/ TXT)
@@ -1798,18 +1800,6 @@ static int domain_setup_first_level(struct intel_iommu *iommu, (pgd_t *)pgd, flags, old); } -static bool domain_need_iotlb_sync_map (struct dmar_domain *domain, -struct intel_iommu *iommu) -{ -if (cap_caching_mode (iommu->cap) &&intel_domain_is_ss_paging (domain)) -return true; - -if (rwbf_quirk ||cap_rwbf (iommu->cap)) -return true; - -return false; -} -static int dmar_domain_attach_device (struct dmar_domain *domain,struct device *dev) {
@@ -1849,8 +1839,6 @@ static int dmar_domain_attach_device(struct dmar_domain *domain,if (ret) goto out_block_translation; - domain->iotlb_sync_map |=domain_need_iotlb_sync_map (domain, iommu); -return 0 ; out_block_translation:
@@ -3370,6 +3358,14 @@ intel_iommu_domain_alloc_first_stage(struct device *dev,return ERR_CAST (dmar_domain); dmar_domain->domain.ops = &intel_fs_paging_domain_ops; +/* +* iotlb sync for map is only needed for legacy implementations that +* explicitly require flushing internal write buffers to ensure memory +* coherence. +*/ +if (rwbf_required (iommu)) + dmar_domain->iotlb_sync_map = true; +return &dmar_domain->domain; }
@@ -3404,6 +3400,14 @@ intel_iommu_domain_alloc_second_stage(struct device *dev,if (flags &IOMMU_HWPT_ALLOC_DIRTY_TRACKING ) dmar_domain->domain.dirty_ops = &intel_dirty_ops; +/* +* Besides the internal write buffer flush, the caching mode used for +* legacy nested translation (which utilizes shadowing page tables) +* also requires iotlb sync on map. +*/ +if (rwbf_required (iommu) ||cap_caching_mode (iommu->cap)) + dmar_domain->iotlb_sync_map = true; +return &dmar_domain->domain; }
@@ -3449,6 +3453,11 @@ static int paging_domain_compatible_first_stage(struct dmar_domain *dmar_domain,if (!cap_fl1gp_support (iommu->cap) && (dmar_domain->domain.pgsize_bitmap &SZ_1G ))return -EINVAL ; + +/* iotlb sync on map requirement */ +if ((rwbf_required (iommu)) && !dmar_domain->iotlb_sync_map) +return -EINVAL ; +return 0 ; }
@@ -3472,6 +3481,12 @@ paging_domain_compatible_second_stage(struct dmar_domain *dmar_domain,return -EINVAL ;if (!(sslps &BIT (1 )) && (dmar_domain->domain.pgsize_bitmap &SZ_1G ))return -EINVAL ; + +/* iotlb sync on map requirement */ +if ((rwbf_required (iommu) ||cap_caching_mode (iommu->cap)) && + !dmar_domain->iotlb_sync_map) +return -EINVAL ; +return 0 ; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 14/189 Bluetooth: hci_conn: Fix running bis_cleanup for hci_conn->type PA_LINK
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luiz Augusto von Dentz <[email protected]>
[ Upstream commit d36349ea73d805bb72cbc24ab90cb1da4ad5c379 ]
Connections with type of PA_LINK shall be considered temporary just to track the lifetime of PA Sync setup, once the BIG Sync is established and connection are created with BIS_LINK the existing PA_LINK connection shall not longer use bis_cleanup otherwise it terminates the PA Sync when that shall be left to BIS_LINK connection to do it.
--- net/bluetooth/hci_conn.c | 12 +++++++++++- net/bluetooth/hci_event.c | 7 ++++++- 2 files changed, 17 insertions(+), 2 deletions(-)
net/bluetooth/hci_conn.c +11 -1
@@ -829,7 +829,17 @@ static void bis_cleanup(struct hci_conn *conn)/* Check if ISO connection is a BIS and terminate advertising * set and BIG if there are no other connections using it. */ - bis =hci_conn_hash_lookup_big (hdev, conn->iso_qos.bcast.big); + bis =hci_conn_hash_lookup_big_state (hdev, + conn->iso_qos.bcast.big, +BT_CONNECTED , +HCI_ROLE_MASTER ); +if (bis) +return ; + + bis =hci_conn_hash_lookup_big_state (hdev, + conn->iso_qos.bcast.big, +BT_CONNECT , +HCI_ROLE_MASTER );if (bis)return ;
net/bluetooth/hci_event.c +6 -1
@@ -6973,9 +6973,14 @@ static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data,continue ; } -if (ev->status !=0x42 ) +if (ev->status !=0x42 ) {/* Mark PA sync as established */ set_bit (HCI_CONN_PA_SYNC , &bis->flags); +/* Reset cleanup callback of PA Sync so it doesn't +* terminate the sync when deleting the connection. +*/ + conn->cleanup =NULL ; + } bis->sync_handle = conn->sync_handle; bis->iso_qos.bcast.big = ev->handle;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 15/189 Bluetooth: ISO: Fix getname not returning broadcast fields
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luiz Augusto von Dentz <[email protected]>
[ Upstream commit aee29c18a38d479c2f058c9b6a39b0527cf81d10 ]
getname shall return iso_bc fields for both BIS_LINK and PA_LINK since the likes of bluetoothd do use the getpeername to retrieve the SID both when enumerating the broadcasters and when synchronizing.
--- net/bluetooth/iso.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/bluetooth/iso.c +1 -1
@@ -1347,7 +1347,7 @@ static int iso_sock_getname(struct socket *sock, struct sockaddr *addr,bacpy (&sa->iso_bdaddr, &iso_pi (sk)->dst); sa->iso_bdaddr_type =iso_pi (sk)->dst_type; -if (hcon && hcon->type ==BIS_LINK ) { +if (hcon && (hcon->type ==BIS_LINK || hcon->type ==PA_LINK )) { sa->iso_bc->bc_sid =iso_pi (sk)->bc_sid; sa->iso_bc->bc_num_bis =iso_pi (sk)->bc_num_bis; memcpy(sa->iso_bc->bc_bis, iso_pi(sk)->bc_bis,
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 16/189 Revert "drm/amdgpu: Add more checks to PSP mailbox"
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
This reverts commit 165a69a87d6bde85cac2c051fa6da611ca4524f6 which is commit 8345a71fc54b28e4d13a759c45ce2664d8540d28 upstream.
This commit is not applicable for stable kernels and results in the driver failing to load on some chips on kernel 6.16.x. Revert from 6.16.x.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 4 ---- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h | 11 ----------- drivers/gpu/drm/amd/amdgpu/psp_v10_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/psp_v11_0.c | 31 ++++++++++++------------------- drivers/gpu/drm/amd/amdgpu/psp_v11_0_8.c | 25 ++++++++++--------------- drivers/gpu/drm/amd/amdgpu/psp_v12_0.c | 18 +++++++----------- drivers/gpu/drm/amd/amdgpu/psp_v13_0.c | 25 ++++++++++--------------- drivers/gpu/drm/amd/amdgpu/psp_v13_0_4.c | 25 ++++++++++--------------- drivers/gpu/drm/amd/amdgpu/psp_v14_0.c | 25 ++++++++++--------------- 9 files changed, 61 insertions(+), 107 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +0 -4
@@ -596,10 +596,6 @@ int psp_wait_for(struct psp_context *pspudelay (1 ); } -dev_err (adev->dev, -"psp reg (0x%x) wait timed out, mask: %x, read: %x exp: %x" , - reg_index, mask, val, reg_val); -return -ETIME ; }
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h +0 -11
@@ -51,17 +51,6 @@#define C2PMSG_CMD_SPI_GET_ROM_IMAGE_ADDR_HI 0x10#define C2PMSG_CMD_SPI_GET_FLASH_IMAGE 0x11 -/* Command register bit 31 set to indicate readiness */ -#define MBOX_TOS_READY_FLAG (GFX_FLAG_RESPONSE) -#define MBOX_TOS_READY_MASK (GFX_CMD_RESPONSE_MASK | GFX_CMD_STATUS_MASK) - -/* Values to check for a successful GFX_CMD response wait. Check against -* both status bits and response state - helps to detect a command failure -* or other unexpected cases like a device drop reading all 0xFFs -*/ -#define MBOX_TOS_RESP_FLAG (GFX_FLAG_RESPONSE) -#define MBOX_TOS_RESP_MASK (GFX_CMD_RESPONSE_MASK | GFX_CMD_STATUS_MASK) -extern const struct attribute_group amdgpu_flash_attr_group;enum psp_shared_mem_size {
drivers/gpu/drm/amd/amdgpu/psp_v10_0.c +2 -2
@@ -94,7 +94,7 @@ static int psp_v10_0_ring_create(struct/* Wait for response flag (bit 31) in C2PMSG_64 */ ret =psp_wait_for (psp,SOC15_REG_OFFSET (MP0 ,0 , mmMP0_SMN_C2PMSG_64), -MBOX_TOS_RESP_FLAG ,MBOX_TOS_RESP_MASK , false); +0x80000000 ,0x8000FFFF , false);return ret; }
@@ -115,7 +115,7 @@ static int psp_v10_0_ring_stop(struct ps/* Wait for response flag (bit 31) in C2PMSG_64 */ ret =psp_wait_for (psp,SOC15_REG_OFFSET (MP0 ,0 , mmMP0_SMN_C2PMSG_64), -MBOX_TOS_RESP_FLAG ,MBOX_TOS_RESP_MASK , false); +0x80000000 ,0x80000000 , false);return ret; }
drivers/gpu/drm/amd/amdgpu/psp_v11_0.c +12 -19
@@ -277,13 +277,11 @@ static int psp_v11_0_ring_stop(struct ps/* Wait for response flag (bit 31) */ if (amdgpu_sriov_vf (adev)) - ret =psp_wait_for ( - psp,SOC15_REG_OFFSET (MP0 ,0 , mmMP0_SMN_C2PMSG_101), -MBOX_TOS_RESP_FLAG ,MBOX_TOS_RESP_MASK , false); + ret =psp_wait_for (psp,SOC15_REG_OFFSET (MP0 ,0 , mmMP0_SMN_C2PMSG_101), +0x80000000 ,0x80000000 , false);else - ret =psp_wait_for ( - psp,SOC15_REG_OFFSET (MP0 ,0 , mmMP0_SMN_C2PMSG_64), -MBOX_TOS_RESP_FLAG ,MBOX_TOS_RESP_MASK , false); + ret =psp_wait_for (psp,SOC15_REG_OFFSET (MP0 ,0 , mmMP0_SMN_C2PMSG_64), +0x80000000 ,0x80000000 , false);return ret; }
@@ -319,15 +317,13 @@ static int psp_v11_0_ring_create(structmdelay (20 );/* Wait for response flag (bit 31) in C2PMSG_101 */ - ret =psp_wait_for ( - psp,SOC15_REG_OFFSET (MP0 ,0 , mmMP0_SMN_C2PMSG_101), -MBOX_TOS_RESP_FLAG ,MBOX_TOS_RESP_MASK , false); + ret =psp_wait_for (psp,SOC15_REG_OFFSET (MP0 ,0 , mmMP0_SMN_C2PMSG_101), +0x80000000 ,0x8000FFFF , false); }else {/* Wait for sOS ready for ring creation */ - ret =psp_wait_for ( - psp,SOC15_REG_OFFSET (MP0 ,0 , mmMP0_SMN_C2PMSG_64), -MBOX_TOS_READY_FLAG ,MBOX_TOS_READY_MASK , false); + ret =psp_wait_for (psp,SOC15_REG_OFFSET (MP0 ,0 , mmMP0_SMN_C2PMSG_64), +0x80000000 ,0x80000000 , false);if (ret) {DRM_ERROR ("Failed to wait for sOS ready for ring creation\n" );return ret;
@@ -351,9 +347,8 @@ static int psp_v11_0_ring_create(structmdelay (20 );/* Wait for response flag (bit 31) in C2PMSG_64 */ - ret =psp_wait_for ( - psp,SOC15_REG_OFFSET (MP0 ,0 , mmMP0_SMN_C2PMSG_64), -MBOX_TOS_RESP_FLAG ,MBOX_TOS_RESP_MASK , false); + ret =psp_wait_for (psp,SOC15_REG_OFFSET (MP0 ,0 , mmMP0_SMN_C2PMSG_64), +0x80000000 ,0x8000FFFF , false); }return ret;
@@ -386,8 +381,7 @@ static int psp_v11_0_mode1_reset(struct offset =SOC15_REG_OFFSET (MP0 ,0 , mmMP0_SMN_C2PMSG_64); - ret =psp_wait_for (psp, offset,MBOX_TOS_READY_FLAG , -MBOX_TOS_READY_MASK , false); + ret =psp_wait_for (psp, offset,0x80000000 ,0x8000FFFF , false);if (ret) {DRM_INFO ("psp is not working correctly before mode1 reset!\n" );
@@ -401,8 +395,7 @@ static int psp_v11_0_mode1_reset(struct offset =SOC15_REG_OFFSET (MP0 ,0 , mmMP0_SMN_C2PMSG_33); - ret =psp_wait_for (psp, offset,MBOX_TOS_RESP_FLAG ,MBOX_TOS_RESP_MASK , - false); + ret =psp_wait_for (psp, offset,0x80000000 ,0x80000000 , false);if (ret) {DRM_INFO ("psp mode 1 reset failed!\n" );
drivers/gpu/drm/amd/amdgpu/psp_v11_0_8.c +10 -15
@@ -41,9 +41,8 @@ static int psp_v11_0_8_ring_stop(struct/* there might be handshake issue with hardware which needs delay */ mdelay (20 );/* Wait for response flag (bit 31) */ - ret =psp_wait_for ( - psp,SOC15_REG_OFFSET (MP0 ,0 , mmMP0_SMN_C2PMSG_101), -MBOX_TOS_RESP_FLAG ,MBOX_TOS_RESP_MASK , false); + ret =psp_wait_for (psp,SOC15_REG_OFFSET (MP0 ,0 , mmMP0_SMN_C2PMSG_101), +0x80000000 ,0x80000000 , false); }else {/* Write the ring destroy command*/ WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_64,
@@ -51,9 +50,8 @@ static int psp_v11_0_8_ring_stop(struct/* there might be handshake issue with hardware which needs delay */ mdelay (20 );/* Wait for response flag (bit 31) */ - ret =psp_wait_for ( - psp,SOC15_REG_OFFSET (MP0 ,0 , mmMP0_SMN_C2PMSG_64), -MBOX_TOS_RESP_FLAG ,MBOX_TOS_RESP_MASK , false); + ret =psp_wait_for (psp,SOC15_REG_OFFSET (MP0 ,0 , mmMP0_SMN_C2PMSG_64), +0x80000000 ,0x80000000 , false); }return ret;
@@ -89,15 +87,13 @@ static int psp_v11_0_8_ring_create(strucmdelay (20 );/* Wait for response flag (bit 31) in C2PMSG_101 */ - ret =psp_wait_for ( - psp,SOC15_REG_OFFSET (MP0 ,0 , mmMP0_SMN_C2PMSG_101), -MBOX_TOS_RESP_FLAG ,MBOX_TOS_RESP_MASK , false); + ret =psp_wait_for (psp,SOC15_REG_OFFSET (MP0 ,0 , mmMP0_SMN_C2PMSG_101), +0x80000000 ,0x8000FFFF , false); }else {/* Wait for sOS ready for ring creation */ - ret =psp_wait_for ( - psp,SOC15_REG_OFFSET (MP0 ,0 , mmMP0_SMN_C2PMSG_64), -MBOX_TOS_READY_FLAG ,MBOX_TOS_READY_MASK , false); + ret =psp_wait_for (psp,SOC15_REG_OFFSET (MP0 ,0 , mmMP0_SMN_C2PMSG_64), +0x80000000 ,0x80000000 , false);if (ret) {DRM_ERROR ("Failed to wait for trust OS ready for ring creation\n" );return ret;
@@ -121,9 +117,8 @@ static int psp_v11_0_8_ring_create(strucmdelay (20 );/* Wait for response flag (bit 31) in C2PMSG_64 */ - ret =psp_wait_for ( - psp,SOC15_REG_OFFSET (MP0 ,0 , mmMP0_SMN_C2PMSG_64), -MBOX_TOS_RESP_FLAG ,MBOX_TOS_RESP_MASK , false); + ret =psp_wait_for (psp,SOC15_REG_OFFSET (MP0 ,0 , mmMP0_SMN_C2PMSG_64), +0x80000000 ,0x8000FFFF , false); }return ret;
drivers/gpu/drm/amd/amdgpu/psp_v12_0.c +7 -11
@@ -163,7 +163,7 @@ static int psp_v12_0_ring_create(struct/* Wait for response flag (bit 31) in C2PMSG_64 */ ret =psp_wait_for (psp,SOC15_REG_OFFSET (MP0 ,0 , mmMP0_SMN_C2PMSG_64), -MBOX_TOS_RESP_FLAG ,MBOX_TOS_RESP_MASK , false); +0x80000000 ,0x8000FFFF , false);return ret; }
@@ -184,13 +184,11 @@ static int psp_v12_0_ring_stop(struct ps/* Wait for response flag (bit 31) */ if (amdgpu_sriov_vf (adev)) - ret =psp_wait_for ( - psp,SOC15_REG_OFFSET (MP0 ,0 , mmMP0_SMN_C2PMSG_101), -MBOX_TOS_RESP_FLAG ,MBOX_TOS_RESP_MASK , false); + ret =psp_wait_for (psp,SOC15_REG_OFFSET (MP0 ,0 , mmMP0_SMN_C2PMSG_101), +0x80000000 ,0x80000000 , false);else - ret =psp_wait_for ( - psp,SOC15_REG_OFFSET (MP0 ,0 , mmMP0_SMN_C2PMSG_64), -MBOX_TOS_RESP_FLAG ,MBOX_TOS_RESP_MASK , false); + ret =psp_wait_for (psp,SOC15_REG_OFFSET (MP0 ,0 , mmMP0_SMN_C2PMSG_64), +0x80000000 ,0x80000000 , false);return ret; }
@@ -221,8 +219,7 @@ static int psp_v12_0_mode1_reset(struct offset =SOC15_REG_OFFSET (MP0 ,0 , mmMP0_SMN_C2PMSG_64); - ret =psp_wait_for (psp, offset,MBOX_TOS_READY_FLAG , -MBOX_TOS_READY_MASK , false); + ret =psp_wait_for (psp, offset,0x80000000 ,0x8000FFFF , false);if (ret) {DRM_INFO ("psp is not working correctly before mode1 reset!\n" );
@@ -236,8 +233,7 @@ static int psp_v12_0_mode1_reset(struct offset =SOC15_REG_OFFSET (MP0 ,0 , mmMP0_SMN_C2PMSG_33); - ret =psp_wait_for (psp, offset,MBOX_TOS_RESP_FLAG ,MBOX_TOS_RESP_MASK , - false); + ret =psp_wait_for (psp, offset,0x80000000 ,0x80000000 , false);if (ret) {DRM_INFO ("psp mode 1 reset failed!\n" );
drivers/gpu/drm/amd/amdgpu/psp_v13_0.c +10 -15
@@ -384,9 +384,8 @@ static int psp_v13_0_ring_stop(struct ps/* there might be handshake issue with hardware which needs delay */ mdelay (20 );/* Wait for response flag (bit 31) */ - ret =psp_wait_for ( - psp,SOC15_REG_OFFSET (MP0 ,0 , regMP0_SMN_C2PMSG_101), -MBOX_TOS_RESP_FLAG ,MBOX_TOS_RESP_MASK , false); + ret =psp_wait_for (psp,SOC15_REG_OFFSET (MP0 ,0 , regMP0_SMN_C2PMSG_101), +0x80000000 ,0x80000000 , false); }else {/* Write the ring destroy command*/ WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_64,
@@ -394,9 +393,8 @@ static int psp_v13_0_ring_stop(struct ps/* there might be handshake issue with hardware which needs delay */ mdelay (20 );/* Wait for response flag (bit 31) */ - ret =psp_wait_for ( - psp,SOC15_REG_OFFSET (MP0 ,0 , regMP0_SMN_C2PMSG_64), -MBOX_TOS_RESP_FLAG ,MBOX_TOS_RESP_MASK , false); + ret =psp_wait_for (psp,SOC15_REG_OFFSET (MP0 ,0 , regMP0_SMN_C2PMSG_64), +0x80000000 ,0x80000000 , false); }return ret;
@@ -432,15 +430,13 @@ static int psp_v13_0_ring_create(structmdelay (20 );/* Wait for response flag (bit 31) in C2PMSG_101 */ - ret =psp_wait_for ( - psp,SOC15_REG_OFFSET (MP0 ,0 , regMP0_SMN_C2PMSG_101), -MBOX_TOS_RESP_FLAG ,MBOX_TOS_RESP_MASK , false); + ret =psp_wait_for (psp,SOC15_REG_OFFSET (MP0 ,0 , regMP0_SMN_C2PMSG_101), +0x80000000 ,0x8000FFFF , false); }else {/* Wait for sOS ready for ring creation */ - ret =psp_wait_for ( - psp,SOC15_REG_OFFSET (MP0 ,0 , regMP0_SMN_C2PMSG_64), -MBOX_TOS_READY_FLAG ,MBOX_TOS_READY_MASK , false); + ret =psp_wait_for (psp,SOC15_REG_OFFSET (MP0 ,0 , regMP0_SMN_C2PMSG_64), +0x80000000 ,0x80000000 , false);if (ret) {DRM_ERROR ("Failed to wait for trust OS ready for ring creation\n" );return ret;
@@ -464,9 +460,8 @@ static int psp_v13_0_ring_create(structmdelay (20 );/* Wait for response flag (bit 31) in C2PMSG_64 */ - ret =psp_wait_for ( - psp,SOC15_REG_OFFSET (MP0 ,0 , regMP0_SMN_C2PMSG_64), -MBOX_TOS_RESP_FLAG ,MBOX_TOS_RESP_MASK , false); + ret =psp_wait_for (psp,SOC15_REG_OFFSET (MP0 ,0 , regMP0_SMN_C2PMSG_64), +0x80000000 ,0x8000FFFF , false); }return ret;
drivers/gpu/drm/amd/amdgpu/psp_v13_0_4.c +10 -15
@@ -204,9 +204,8 @@ static int psp_v13_0_4_ring_stop(struct/* there might be handshake issue with hardware which needs delay */ mdelay (20 );/* Wait for response flag (bit 31) */ - ret =psp_wait_for ( - psp,SOC15_REG_OFFSET (MP0 ,0 , regMP0_SMN_C2PMSG_101), -MBOX_TOS_RESP_FLAG ,MBOX_TOS_RESP_MASK , false); + ret =psp_wait_for (psp,SOC15_REG_OFFSET (MP0 ,0 , regMP0_SMN_C2PMSG_101), +0x80000000 ,0x80000000 , false); }else {/* Write the ring destroy command*/ WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_64,
@@ -214,9 +213,8 @@ static int psp_v13_0_4_ring_stop(struct/* there might be handshake issue with hardware which needs delay */ mdelay (20 );/* Wait for response flag (bit 31) */ - ret =psp_wait_for ( - psp,SOC15_REG_OFFSET (MP0 ,0 , regMP0_SMN_C2PMSG_64), -MBOX_TOS_RESP_FLAG ,MBOX_TOS_RESP_MASK , false); + ret =psp_wait_for (psp,SOC15_REG_OFFSET (MP0 ,0 , regMP0_SMN_C2PMSG_64), +0x80000000 ,0x80000000 , false); }return ret;
@@ -252,15 +250,13 @@ static int psp_v13_0_4_ring_create(strucmdelay (20 );/* Wait for response flag (bit 31) in C2PMSG_101 */ - ret =psp_wait_for ( - psp,SOC15_REG_OFFSET (MP0 ,0 , regMP0_SMN_C2PMSG_101), -MBOX_TOS_RESP_FLAG ,MBOX_TOS_RESP_MASK , false); + ret =psp_wait_for (psp,SOC15_REG_OFFSET (MP0 ,0 , regMP0_SMN_C2PMSG_101), +0x80000000 ,0x8000FFFF , false); }else {/* Wait for sOS ready for ring creation */ - ret =psp_wait_for ( - psp,SOC15_REG_OFFSET (MP0 ,0 , regMP0_SMN_C2PMSG_64), -MBOX_TOS_READY_FLAG ,MBOX_TOS_READY_MASK , false); + ret =psp_wait_for (psp,SOC15_REG_OFFSET (MP0 ,0 , regMP0_SMN_C2PMSG_64), +0x80000000 ,0x80000000 , false);if (ret) {DRM_ERROR ("Failed to wait for trust OS ready for ring creation\n" );return ret;
@@ -284,9 +280,8 @@ static int psp_v13_0_4_ring_create(strucmdelay (20 );/* Wait for response flag (bit 31) in C2PMSG_64 */ - ret =psp_wait_for ( - psp,SOC15_REG_OFFSET (MP0 ,0 , regMP0_SMN_C2PMSG_64), -MBOX_TOS_RESP_FLAG ,MBOX_TOS_RESP_MASK , false); + ret =psp_wait_for (psp,SOC15_REG_OFFSET (MP0 ,0 , regMP0_SMN_C2PMSG_64), +0x80000000 ,0x8000FFFF , false); }return ret;
drivers/gpu/drm/amd/amdgpu/psp_v14_0.c +10 -15
@@ -250,9 +250,8 @@ static int psp_v14_0_ring_stop(struct ps/* there might be handshake issue with hardware which needs delay */ mdelay (20 );/* Wait for response flag (bit 31) */ - ret =psp_wait_for ( - psp,SOC15_REG_OFFSET (MP0 ,0 , regMPASP_SMN_C2PMSG_101), -MBOX_TOS_RESP_FLAG ,MBOX_TOS_RESP_MASK , false); + ret =psp_wait_for (psp,SOC15_REG_OFFSET (MP0 ,0 , regMPASP_SMN_C2PMSG_101), +0x80000000 ,0x80000000 , false); }else {/* Write the ring destroy command*/ WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_64,
@@ -260,9 +259,8 @@ static int psp_v14_0_ring_stop(struct ps/* there might be handshake issue with hardware which needs delay */ mdelay (20 );/* Wait for response flag (bit 31) */ - ret =psp_wait_for ( - psp,SOC15_REG_OFFSET (MP0 ,0 , regMPASP_SMN_C2PMSG_64), -MBOX_TOS_RESP_FLAG ,MBOX_TOS_RESP_MASK , false); + ret =psp_wait_for (psp,SOC15_REG_OFFSET (MP0 ,0 , regMPASP_SMN_C2PMSG_64), +0x80000000 ,0x80000000 , false); }return ret;
@@ -298,15 +296,13 @@ static int psp_v14_0_ring_create(structmdelay (20 );/* Wait for response flag (bit 31) in C2PMSG_101 */ - ret =psp_wait_for ( - psp,SOC15_REG_OFFSET (MP0 ,0 , regMPASP_SMN_C2PMSG_101), -MBOX_TOS_RESP_FLAG ,MBOX_TOS_RESP_MASK , false); + ret =psp_wait_for (psp,SOC15_REG_OFFSET (MP0 ,0 , regMPASP_SMN_C2PMSG_101), +0x80000000 ,0x8000FFFF , false); }else {/* Wait for sOS ready for ring creation */ - ret =psp_wait_for ( - psp,SOC15_REG_OFFSET (MP0 ,0 , regMPASP_SMN_C2PMSG_64), -MBOX_TOS_READY_FLAG ,MBOX_TOS_READY_MASK , false); + ret =psp_wait_for (psp,SOC15_REG_OFFSET (MP0 ,0 , regMPASP_SMN_C2PMSG_64), +0x80000000 ,0x80000000 , false);if (ret) {DRM_ERROR ("Failed to wait for trust OS ready for ring creation\n" );return ret;
@@ -330,9 +326,8 @@ static int psp_v14_0_ring_create(structmdelay (20 );/* Wait for response flag (bit 31) in C2PMSG_64 */ - ret =psp_wait_for ( - psp,SOC15_REG_OFFSET (MP0 ,0 , regMPASP_SMN_C2PMSG_64), -MBOX_TOS_RESP_FLAG ,MBOX_TOS_RESP_MASK , false); + ret =psp_wait_for (psp,SOC15_REG_OFFSET (MP0 ,0 , regMPASP_SMN_C2PMSG_64), +0x80000000 ,0x8000FFFF , false); }return ret;
Greg Kroah-Hartman
maintainerPATCH 17/189 flexfiles/pNFS: fix NULL checks on result of ff_layout_choose_ds_for_read
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tigran Mkrtchyan <[email protected]>
[ Upstream commit 5a46d2339a5ae268ede53a221f20433d8ea4f2f9 ]
Recent commit f06bedfa62d5 ("pNFS/flexfiles: don't attempt pnfs on fatal DS errors") has changed the error return type of ff_layout_choose_ds_for_read() from NULL to an error pointer. However, not all code paths have been updated to match the change. Thus, some non-NULL checks will accept error pointers as a valid return value.
--- fs/nfs/flexfilelayout/flexfilelayout.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-)
fs/nfs/flexfilelayout/flexfilelayout.c +12 -7
@@ -773,8 +773,11 @@ ff_layout_choose_ds_for_read(struct pnfs_layout_segment *lseg,continue ;if (check_device && -nfs4_test_deviceid_unavailable (&mirror->mirror_ds->id_node)) +nfs4_test_deviceid_unavailable (&mirror->mirror_ds->id_node)) { +// reinitialize the error state in case if this is the last iteration + ds =ERR_PTR (-EINVAL );continue ; + } *best_idx = idx;break ;
@@ -804,7 +807,7 @@ ff_layout_choose_best_ds_for_read(struct pnfs_layout_segment *lseg,struct nfs4_pnfs_ds *ds; ds =ff_layout_choose_valid_ds_for_read (lseg, start_idx, best_idx); -if (ds) +if (!IS_ERR (ds))return ds;return ff_layout_choose_any_ds_for_read (lseg, start_idx, best_idx); }
@@ -818,7 +821,7 @@ ff_layout_get_ds_for_read(struct nfs_pageio_descriptor *pgio, ds =ff_layout_choose_best_ds_for_read (lseg, pgio->pg_mirror_idx, best_idx); -if (ds || !pgio->pg_mirror_idx) +if (!IS_ERR (ds) || !pgio->pg_mirror_idx)return ds;return ff_layout_choose_best_ds_for_read (lseg,0 , best_idx); }
@@ -868,7 +871,7 @@ ff_layout_pg_init_read(struct nfs_pageio_descriptor *pgio, req->wb_nio =0 ; ds =ff_layout_get_ds_for_read (pgio, &ds_idx); -if (!ds) { +if (IS_ERR (ds)) {if (!ff_layout_no_fallback_to_mds (pgio->pg_lseg)) goto out_mds;pnfs_generic_pg_cleanup (pgio);
@@ -1072,11 +1075,13 @@ static void ff_layout_resend_pnfs_read(struct nfs_pgio_header *hdr) {u32 idx = hdr->pgio_mirror_idx +1 ;u32 new_idx =0 ; +struct nfs4_pnfs_ds *ds; -if (ff_layout_choose_any_ds_for_read (hdr->lseg, idx, &new_idx)) -ff_layout_send_layouterror (hdr->lseg); -else + ds =ff_layout_choose_any_ds_for_read (hdr->lseg, idx, &new_idx); +if (IS_ERR (ds))pnfs_error_mark_layout_for_return (hdr->inode, hdr->lseg); +else +ff_layout_send_layouterror (hdr->lseg);pnfs_read_resend_pnfs (hdr, new_idx); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 18/189 SUNRPC: call xs_sock_process_cmsg for all cmsg
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Justin Worrell <[email protected]>
[ Upstream commit 9559d2fffd4f9b892165eed48198a0e5cb8504e6 ]
xs_sock_recv_cmsg was failing to call xs_sock_process_cmsg for any cmsg type other than TLS_RECORD_TYPE_ALERT (TLS_RECORD_TYPE_DATA, and other values not handled.) Based on my reading of the previous commit (cc5d5908: sunrpc: fix client side handling of tls alerts), it looks like only iov_iter_revert should be conditional on TLS_RECORD_TYPE_ALERT (but that other cmsg types should still call xs_sock_process_cmsg). On my machine, I was unable to connect (over mtls) to an NFS share hosted on FreeBSD. With this patch applied, I am able to mount the share again.
--- net/sunrpc/xprtsock.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
net/sunrpc/xprtsock.c +3 -3
@@ -407,9 +407,9 @@ xs_sock_recv_cmsg(struct socket *sock, unsigned int *msg_flags, int flags)iov_iter_kvec (&msg.msg_iter,ITER_DEST , &alert_kvec,1 , alert_kvec.iov_len); ret =sock_recvmsg (sock, &msg, flags); -if (ret >0 && -tls_get_record_type (sock->sk, &u.cmsg) ==TLS_RECORD_TYPE_ALERT ) { -iov_iter_revert (&msg.msg_iter, ret); +if (ret >0 ) { +if (tls_get_record_type (sock->sk, &u.cmsg) ==TLS_RECORD_TYPE_ALERT ) +iov_iter_revert (&msg.msg_iter, ret); ret =xs_sock_process_cmsg (sock, &msg, msg_flags, &u.cmsg, -EAGAIN ); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 19/189 NFSv4: Dont clear capabilities that wont be reset
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <[email protected]>
[ Upstream commit 31f1a960ad1a14def94fa0b8c25d62b4c032813f ]
Don't clear the capabilities that are not going to get reset by the call to _nfs4_server_capabilities().
--- fs/nfs/nfs4proc.c | 1 - 1 file changed, 1 deletion(-)
fs/nfs/nfs4proc.c +0 -1
@@ -4082,7 +4082,6 @@ int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle) };int err; -nfs_server_set_init_caps (server); do { err = nfs4_handle_exception(server, _nfs4_server_capabilities(server, fhandle),
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 20/189 md: keep recovery_cp in mdp_superblock_s
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiao Ni <[email protected]>
[ Upstream commit c27973211ffcdf0a092eec265d5993e64b89adaf ]
commit 907a99c314a5 ("md: rename recovery_cp to resync_offset") replaces recovery_cp with resync_offset in mdp_superblock_s which is in md_p.h. md_p.h is used in userspace too. So mdadm building fails because of this. This patch revert this change.
--- drivers/md/md.c | 6 +++--- include/uapi/linux/raid/md_p.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-)
drivers/md/md.c +3 -3
@@ -1406,7 +1406,7 @@ static int super_90_validate(struct mddev *mddev, struct md_rdev *freshest, struelse {if (sb->events_hi == sb->cp_events_hi && sb->events_lo == sb->cp_events_lo) { - mddev->resync_offset = sb->resync_offset; + mddev->resync_offset = sb->recovery_cp; }else mddev->resync_offset =0 ; }
@@ -1534,13 +1534,13 @@ static void super_90_sync(struct mddev *mddev, struct md_rdev *rdev) mddev->minor_version = sb->minor_version;if (mddev->in_sync) { - sb->resync_offset = mddev->resync_offset; + sb->recovery_cp = mddev->resync_offset; sb->cp_events_hi = (mddev->events>>32 ); sb->cp_events_lo = (u32 )mddev->events;if (mddev->resync_offset == MaxSector) sb->state = (1 <<MD_SB_CLEAN ); }else - sb->resync_offset =0 ; + sb->recovery_cp =0 ; sb->layout = mddev->layout; sb->chunk_size = mddev->chunk_sectors <<9 ;
include/uapi/linux/raid/md_p.h +1 -1
@@ -173,7 +173,7 @@ typedef struct mdp_superblock_s {#else #error unspecified endianness#endif -__u32 resync_offset;/* 11 resync checkpoint sector count */ +__u32 recovery_cp;/* 11 resync checkpoint sector count */ /* There are only valid for minor_version > 90 */ __u64 reshape_position;/* 12,13 next address in array-space for reshape */ __u32 new_level;/* 14 new level we are reshaping to */
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 21/189 trace/fgraph: Fix error handling
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <[email protected]>
[ Upstream commit ab1396af7595e7d49a3850481b24d7fe7cbdfd31 ]
Commit edede7a6dcd7 ("trace/fgraph: Fix the warning caused by missing unregister notifier") added a call to unregister the PM notifier if register_ftrace_graph() failed. It does so unconditionally. However, the PM notifier is only registered with the first call to register_ftrace_graph(). If the first registration was successful and a subsequent registration failed, the notifier is now unregistered even if ftrace graphs are still registered.
Fix the problem by only unregistering the PM notifier during error handling if there are no active fgraph registrations.
--- kernel/trace/fgraph.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
kernel/trace/fgraph.c +2 -1
@@ -1393,7 +1393,8 @@ int register_ftrace_graph(struct fgraph_ops *gops) ftrace_graph_active--; gops->saved_func =NULL ;fgraph_lru_release_index (i); -unregister_pm_notifier (&ftrace_suspend_notifier); +if (!ftrace_graph_active) +unregister_pm_notifier (&ftrace_suspend_notifier); }return ret; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 22/189 NFSv4: Clear the NFS_CAP_FS_LOCATIONS flag if it is not set
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <[email protected]>
[ Upstream commit dd5a8621b886b02f8341c5d4ea68eb2c552ebd3e ]
_nfs4_server_capabilities() is expected to clear any flags that are not supported by the server.
--- fs/nfs/nfs4proc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
fs/nfs/nfs4proc.c +3 -2
@@ -4007,8 +4007,9 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f res.attr_bitmask[2 ]; }memcpy (server->attr_bitmask, res.attr_bitmask,sizeof (server->attr_bitmask)); - server->caps &= ~(NFS_CAP_ACLS |NFS_CAP_HARDLINKS | -NFS_CAP_SYMLINKS |NFS_CAP_SECURITY_LABEL ); + server->caps &= + ~(NFS_CAP_ACLS |NFS_CAP_HARDLINKS |NFS_CAP_SYMLINKS | +NFS_CAP_SECURITY_LABEL |NFS_CAP_FS_LOCATIONS ); server->fattr_valid =NFS_ATTR_FATTR_V4 ;if (res.attr_bitmask[0 ] &FATTR4_WORD0_ACL && res.acl_bitmask &ACL4_SUPPORT_ALLOW_ACL )
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 23/189 NFSv4: Clear NFS_CAP_OPEN_XOR and NFS_CAP_DELEGTIME if not supported
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <[email protected]>
[ Upstream commit b3ac33436030bce37ecb3dcae581ecfaad28078c ]
_nfs4_server_capabilities() should clear capabilities that are not supported by the server.
--- fs/nfs/nfs4proc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/nfs/nfs4proc.c +2 -1
@@ -4009,7 +4009,8 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fmemcpy (server->attr_bitmask, res.attr_bitmask,sizeof (server->attr_bitmask)); server->caps &= ~(NFS_CAP_ACLS |NFS_CAP_HARDLINKS |NFS_CAP_SYMLINKS | -NFS_CAP_SECURITY_LABEL |NFS_CAP_FS_LOCATIONS ); +NFS_CAP_SECURITY_LABEL |NFS_CAP_FS_LOCATIONS | +NFS_CAP_OPEN_XOR |NFS_CAP_DELEGTIME ); server->fattr_valid =NFS_ATTR_FATTR_V4 ;if (res.attr_bitmask[0 ] &FATTR4_WORD0_ACL && res.acl_bitmask &ACL4_SUPPORT_ALLOW_ACL )
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 24/189 NFSv4: Clear the NFS_CAP_XATTR flag if not supported by the server
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <[email protected]>
[ Upstream commit 4fb2b677fc1f70ee642c0beecc3cabf226ef5707 ]
nfs_server_set_fsinfo() shouldn't assume that NFS_CAP_XATTR is unset on entry to the function.
--- fs/nfs/client.c | 2 ++ 1 file changed, 2 insertions(+)
fs/nfs/client.c +2 -0
@@ -890,6 +890,8 @@ static void nfs_server_set_fsinfo(struct nfs_server *server,if (fsinfo->xattr_support) server->caps |=NFS_CAP_XATTR ; +else + server->caps &= ~NFS_CAP_XATTR ;#endif }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 25/189 tracing: Fix tracing_marker may trigger page fault during preempt_disable
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luo Gengkun <[email protected]>
[ Upstream commit 3d62ab32df065e4a7797204a918f6489ddb8a237 ]
Both tracing_mark_write and tracing_mark_raw_write call __copy_from_user_inatomic during preempt_disable. But in some case, __copy_from_user_inatomic may trigger page fault, and will call schedule() subtly. And if a task is migrated to other cpu, the following warning will be trigger:
if (RB_WARN_ON(cpu_buffer,
!local_read(&cpu_buffer->committing)))An example can illustrate this issue:
process flow CPU
---------------------------------------------------------------------
tracing_mark_raw_write(): cpu:0
...
ring_buffer_lock_reserve(): cpu:0
...
cpu = raw_smp_processor_id() cpu:0
cpu_buffer = buffer->buffers[cpu] cpu:0
...
...
__copy_from_user_inatomic(): cpu:0
...
# page fault
do_mem_abort(): cpu:0
...
# Call schedule
schedule() cpu:0
...
# the task schedule to cpu1
__buffer_unlock_commit(): cpu:1
...
ring_buffer_unlock_commit(): cpu:1
...
cpu = raw_smp_processor_id() cpu:1
cpu_buffer = buffer->buffers[cpu] cpu:1As shown above, the process will acquire cpuid twice and the return values are not the same.
To fix this problem using copy_from_user_nofault instead of __copy_from_user_inatomic, as the former performs 'access_ok' before copying.
--- kernel/trace/trace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/trace/trace.c +2 -2
@@ -7264,7 +7264,7 @@ static ssize_t write_marker_to_buffer(struct trace_array *tr, const char __user entry =ring_buffer_event_data (event); entry->ip = ip; - len =__copy_from_user_inatomic (&entry->buf, ubuf, cnt); + len =copy_from_user_nofault (&entry->buf, ubuf, cnt);if (len) {memcpy (&entry->buf,FAULTED_STR ,FAULTED_SIZE ); cnt =FAULTED_SIZE ;
@@ -7361,7 +7361,7 @@ static ssize_t write_raw_marker_to_buffer(struct trace_array *tr, entry =ring_buffer_event_data (event); - len =__copy_from_user_inatomic (&entry->id, ubuf, cnt); + len =copy_from_user_nofault (&entry->id, ubuf, cnt);if (len) { entry->id =-1 ;memcpy (&entry->buf,FAULTED_STR ,FAULTED_SIZE );
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 26/189 nfs/localio: restore creds before releasing pageio data
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Scott Mayhew <[email protected]>
[ Upstream commit 992203a1fba51b025c60ec0c8b0d9223343dea95 ]
Otherwise if the nfsd filecache code releases the nfsd_file immediately, it can trigger the BUG_ON(cred == current->cred) in __put_cred() when it puts the nfsd_file->nf_file->f-cred.
--- fs/nfs/localio.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
fs/nfs/localio.c +7 -5
@@ -453,12 +453,13 @@ static void nfs_local_call_read(struct work_struct *work)nfs_local_iter_init (&iter, iocb,READ ); status = filp->f_op->read_iter (&iocb->kiocb, &iter); + +revert_creds (save_cred); +if (status != -EIOCBQUEUED ) {nfs_local_read_done (iocb, status);nfs_local_pgio_release (iocb); } - -revert_creds (save_cred); } static int
@@ -649,14 +650,15 @@ static void nfs_local_call_write(struct work_struct *work)file_start_write (filp); status = filp->f_op->write_iter (&iocb->kiocb, &iter);file_end_write (filp); + +revert_creds (save_cred); + current->flags = old_flags; +if (status != -EIOCBQUEUED ) {nfs_local_write_done (iocb, status);nfs_local_vfs_getattr (iocb);nfs_local_pgio_release (iocb); } - -revert_creds (save_cred); - current->flags = old_flags; } static int
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 27/189 ftrace/samples: Fix function size computation
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vladimir Riabchun <[email protected]>
[ Upstream commit 80d03a40837a9b26750a25122b906c052cc846c9 ]
In my_tramp1 function .size directive was placed above ASM_RET instruction, leading to a wrong function size.
--- samples/ftrace/ftrace-direct-modify.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
samples/ftrace/ftrace-direct-modify.c +1 -1
@@ -75,8 +75,8 @@ asm (CALL_DEPTH_ACCOUNT " call my_direct_func1\n" " leave\n" -" .size my_tramp1, .-my_tramp1\n" ASM_RET +" .size my_tramp1, .-my_tramp1\n" " .type my_tramp2, @function\n" " .globl my_tramp2\n"
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 28/189 tracing/osnoise: Fix null-ptr-deref in bitmap_parselist()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wang Liang <[email protected]>
[ Upstream commit c1628c00c4351dd0727ef7f670694f68d9e663d8 ]
A crash was observed with the following output:
BUG: kernel NULL pointer dereference, address: 0000000000000010 Oops: Oops: 0000 [#1] SMP NOPTI CPU: 2 UID: 0 PID: 92 Comm: osnoise_cpus Not tainted 6.17.0-rc4-00201-gd69eb204c255 #138 PREEMPT(voluntary) RIP: 0010:bitmap_parselist+0x53/0x3e0 Call Trace: <TASK> osnoise_cpus_write+0x7a/0x190 vfs_write+0xf8/0x410 ? do_sys_openat2+0x88/0xd0 ksys_write+0x60/0xd0 do_syscall_64+0xa4/0x260 entry_SYSCALL_64_after_hwframe+0x77/0x7f </TASK>
This issue can be reproduced by below code:
fd=open("/sys/kernel/debug/tracing/osnoise/cpus", O_WRONLY); write(fd, "0-2", 0);
When user pass 'count=0' to osnoise_cpus_write(), kmalloc() will return ZERO_SIZE_PTR (16) and cpulist_parse() treat it as a normal value, which trigger the null pointer dereference. Add check for the parameter 'count'.
--- kernel/trace/trace_osnoise.c | 3 +++ 1 file changed, 3 insertions(+)
kernel/trace/trace_osnoise.c +3 -0
@@ -2322,6 +2322,9 @@ osnoise_cpus_write(struct file *filp, const char __user *ubuf, size_t count,int running, err; char *buf __free(kfree) = NULL; +if (count <1 ) +return 0 ; + buf =kmalloc (count,GFP_KERNEL );if (!buf)return -ENOMEM ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 29/189 NFS: Serialise O_DIRECT i/o and truncate()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <[email protected]>
[ Upstream commit 9eb90f435415c7da4800974ed943e39b5578ee7f ]
Ensure that all O_DIRECT reads and writes are complete, and prevent the initiation of new i/o until the setattr operation that will truncate the file is complete.
--- fs/nfs/inode.c | 4 +++- fs/nfs/internal.h | 10 ++++++++++ fs/nfs/io.c | 13 ++----------- 3 files changed, 15 insertions(+), 12 deletions(-)
fs/nfs/inode.c +3 -1
@@ -761,8 +761,10 @@ nfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,trace_nfs_setattr_enter (inode);/* Write all dirty data */ -if (S_ISREG (inode->i_mode)) +if (S_ISREG (inode->i_mode)) { +nfs_file_block_o_direct (NFS_I (inode));nfs_sync_inode (inode); + } fattr =nfs_alloc_fattr_with_label (NFS_SERVER (inode));if (fattr ==NULL ) {
fs/nfs/internal.h +10 -0
@@ -531,6 +531,16 @@ static inline bool nfs_file_io_is_buffered(struct nfs_inode *nfsi)return test_bit (NFS_INO_ODIRECT , &nfsi->flags) ==0 ; } +/* Must be called with exclusively locked inode->i_rwsem */ +static inline void nfs_file_block_o_direct (struct nfs_inode *nfsi) +{ +if (test_bit (NFS_INO_ODIRECT , &nfsi->flags)) { +clear_bit (NFS_INO_ODIRECT , &nfsi->flags); +inode_dio_wait (&nfsi->vfs_inode); + } +} + +/* namespace.c */ #define NFS_PATH_CANONICAL 1 extern char *nfs_path(char **p, struct dentry *dentry,
fs/nfs/io.c +2 -11
@@ -14,15 +14,6 @@#include "internal.h" -/* Call with exclusively locked inode->i_rwsem */ -static void nfs_block_o_direct (struct nfs_inode *nfsi,struct inode *inode) -{ -if (test_bit (NFS_INO_ODIRECT , &nfsi->flags)) { -clear_bit (NFS_INO_ODIRECT , &nfsi->flags); -inode_dio_wait (inode); - } -} -/** * nfs_start_io_read - declare the file is being used for buffered reads * @inode: file inode
@@ -57,7 +48,7 @@ nfs_start_io_read(struct inode *inode) err =down_write_killable (&inode->i_rwsem);if (err)return err; -nfs_block_o_direct (nfsi, inode); +nfs_file_block_o_direct (nfsi);downgrade_write (&inode->i_rwsem);return 0 ;
@@ -90,7 +81,7 @@ nfs_start_io_write(struct inode *inode) err =down_write_killable (&inode->i_rwsem);if (!err) -nfs_block_o_direct (NFS_I (inode), inode); +nfs_file_block_o_direct (NFS_I (inode));return err; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 30/189 NFSv4.2: Serialise O_DIRECT i/o and fallocate()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <[email protected]>
[ Upstream commit b93128f29733af5d427a335978a19884c2c230e2 ]
Ensure that all O_DIRECT reads and writes complete before calling fallocate so that we don't race w.r.t. attribute updates.
--- fs/nfs/nfs42proc.c | 1 + 1 file changed, 1 insertion(+)
fs/nfs/nfs42proc.c +1 -0
@@ -114,6 +114,7 @@ static int nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep, exception.inode = inode; exception.state = lock->open_context->state; +nfs_file_block_o_direct (NFS_I (inode)); err =nfs_sync_inode (inode);if (err) goto out;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 31/189 NFSv4.2: Serialise O_DIRECT i/o and clone range
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <[email protected]>
[ Upstream commit c80ebeba1198eac8811ab0dba36ecc13d51e4438 ]
Ensure that all O_DIRECT reads and writes complete before cloning a file range, so that both the source and destination are up to date.
--- fs/nfs/nfs4file.c | 2 ++ 1 file changed, 2 insertions(+)
fs/nfs/nfs4file.c +2 -0
@@ -291,9 +291,11 @@ static loff_t nfs42_remap_file_range(struct file *src_file, loff_t src_off,/* flush all pending writes on both src and dst so that server * has the latest data */ +nfs_file_block_o_direct (NFS_I (src_inode)); ret =nfs_sync_inode (src_inode);if (ret) goto out_unlock; +nfs_file_block_o_direct (NFS_I (dst_inode)); ret =nfs_sync_inode (dst_inode);if (ret) goto out_unlock;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 32/189 NFSv4.2: Serialise O_DIRECT i/o and copy range
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <[email protected]>
[ Upstream commit ca247c89900ae90207f4d321e260cd93b7c7d104 ]
Ensure that all O_DIRECT reads and writes complete before copying a file range, so that the destination is up to date.
--- fs/nfs/nfs42proc.c | 1 + 1 file changed, 1 insertion(+)
fs/nfs/nfs42proc.c +1 -0
@@ -431,6 +431,7 @@ static ssize_t _nfs42_proc_copy(struct file *src,return status; } +nfs_file_block_o_direct (NFS_I (dst_inode)); status =nfs_sync_inode (dst_inode);if (status)return status;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 33/189 NFS: nfs_invalidate_folio() must observe the offset and size arguments
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <[email protected]>
[ Upstream commit b7b8574225e9d2b5f1fb5483886ab797892f43b5 ]
If we're truncating part of the folio, then we need to write out the data on the part that is not covered by the cancellation.
--- fs/nfs/file.c | 7 ++++--- fs/nfs/write.c | 1 + 2 files changed, 5 insertions(+), 3 deletions(-)
fs/nfs/file.c +4 -3
@@ -437,10 +437,11 @@ static void nfs_invalidate_folio(struct folio *folio, size_t offset,dfprintk (PAGECACHE ,"NFS: invalidate_folio(%lu, %zu, %zu)\n" , folio->index, offset, length); -if (offset !=0 || length <folio_size (folio)) -return ;/* Cancel any unstarted writes on this page */ -nfs_wb_folio_cancel (inode, folio); +if (offset !=0 || length <folio_size (folio)) +nfs_wb_folio (inode, folio); +else +nfs_wb_folio_cancel (inode, folio);folio_wait_private_2 (folio);/* [DEPRECATED] */ trace_nfs_invalidate_folio (inode,folio_pos (folio) + offset, length); }
fs/nfs/write.c +1 -0
@@ -2045,6 +2045,7 @@ int nfs_wb_folio_cancel(struct inode *inode, struct folio *folio)* release it */ nfs_inode_remove_request (req);nfs_unlock_and_release_request (req); +folio_cancel_dirty (folio); }return ret;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 34/189 NFSv4/flexfiles: Fix layout merge mirror check.
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonathan Curley <[email protected]>
[ Upstream commit dd2fa82473453661d12723c46c9f43d9876a7efd ]
Typo in ff_lseg_match_mirrors makes the diff ineffective. This results in merge happening all the time. Merge happening all the time is problematic because it marks lsegs invalid. Marking lsegs invalid causes all outstanding IO to get restarted with EAGAIN and connections to get closed.
Closing connections constantly triggers race conditions in the RDMA implementation...
--- fs/nfs/flexfilelayout/flexfilelayout.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/nfs/flexfilelayout/flexfilelayout.c +1 -1
@@ -293,7 +293,7 @@ ff_lseg_match_mirrors(struct pnfs_layout_segment *l1, struct pnfs_layout_segment *l2) {const struct nfs4_ff_layout_segment *fl1 =FF_LAYOUT_LSEG (l1); -const struct nfs4_ff_layout_segment *fl2 =FF_LAYOUT_LSEG (l1); +const struct nfs4_ff_layout_segment *fl2 =FF_LAYOUT_LSEG (l2);u32 i;if (fl1->mirror_array_cnt != fl2->mirror_array_cnt)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 35/189 tracing: Silence warning when chunk allocation fails in trace_pid_write
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pu Lehui <[email protected]>
[ Upstream commit cd4453c5e983cf1fd5757e9acb915adb1e4602b6 ]
Syzkaller trigger a fault injection warning:
WARNING: CPU: 1 PID: 12326 at tracepoint_add_func+0xbfc/0xeb0 Modules linked in: CPU: 1 UID: 0 PID: 12326 Comm: syz.6.10325 Tainted: G U 6.14.0-rc5-syzkaller #0 Tainted: [U]=USER Hardware name: Google Compute Engine/Google Compute Engine RIP: 0010:tracepoint_add_func+0xbfc/0xeb0 kernel/tracepoint.c:294 Code: 09 fe ff 90 0f 0b 90 0f b6 74 24 43 31 ff 41 bc ea ff ff ff RSP: 0018:ffffc9000414fb48 EFLAGS: 00010283 RAX: 00000000000012a1 RBX: ffffffff8e240ae0 RCX: ffffc90014b78000 RDX: 0000000000080000 RSI: ffffffff81bbd78b RDI: 0000000000000001 RBP: 0000000000000000 R08: 0000000000000001 R09: 0000000000000000 R10: 0000000000000001 R11: 0000000000000001 R12: ffffffffffffffef R13: 0000000000000000 R14: dffffc0000000000 R15: ffffffff81c264f0 FS: 00007f27217f66c0(0000) GS:ffff8880b8700000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000001b2e80dff8 CR3: 00000000268f8000 CR4: 00000000003526f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> tracepoint_probe_register_prio+0xc0/0x110 kernel/tracepoint.c:464 register_trace_prio_sched_switch include/trace/events/sched.h:222 [inline] register_pid_events kernel/trace/trace_events.c:2354 [inline] event_pid_write.isra.0+0x439/0x7a0 kernel/trace/trace_events.c:2425 vfs_write+0x24c/0x1150 fs/read_write.c:677 ksys_write+0x12b/0x250 fs/read_write.c:731 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xcd/0x250 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f
We can reproduce the warning by following the steps below:
1. echo 8 >> set_event_notrace_pid. Let tr->filtered_pids owns one pid and register sched_switch tracepoint.
2. echo ' ' >> set_event_pid, and perform fault injection during chunk allocation of trace_pid_list_alloc. Let pid_list with no pid and
assign to tr->filtered_pids.
3. echo ' ' >> set_event_pid. Let pid_list is NULL and assign to tr->filtered_pids.
4. echo 9 >> set_event_pid, will trigger the double register sched_switch tracepoint warning.
The reason is that syzkaller injects a fault into the chunk allocation in trace_pid_list_alloc, causing a failure in trace_pid_list_set, which may trigger double register of the same tracepoint. This only occurs when the system is about to crash, but to suppress this warning, let's add failure handling logic to trace_pid_list_set.
--- kernel/trace/trace.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
kernel/trace/trace.c +5 -1
@@ -846,7 +846,10 @@ int trace_pid_write(struct trace_pid_list *filtered_pids,/* copy the current bits to the new max */ ret =trace_pid_list_first (filtered_pids, &pid);while (!ret) { -trace_pid_list_set (pid_list, pid); + ret =trace_pid_list_set (pid_list, pid); +if (ret <0 ) + goto out; + ret =trace_pid_list_next (filtered_pids, pid +1 , &pid); nr_pids++; }
@@ -883,6 +886,7 @@ int trace_pid_write(struct trace_pid_list *filtered_pids,trace_parser_clear (&parser); ret =0 ; } + out:trace_parser_put (&parser);if (ret <0 ) {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 36/189 bpf, cpumap: Disable page_pool direct xdp_return need larger scope
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jesper Dangaard Brouer <[email protected]>
[ Upstream commit 2b986b9e917bc88f81aa1ed386af63b26c983f1d ]
When running an XDP bpf_prog on the remote CPU in cpumap code then we must disable the direct return optimization that xdp_return can perform for mem_type page_pool. This optimization assumes code is still executing under RX-NAPI of the original receiving CPU, which isn't true on this remote CPU.
The cpumap code already disabled this via helpers xdp_set_return_frame_no_direct() and xdp_clear_return_frame_no_direct(), but the scope didn't include xdp_do_flush().
When doing XDP_REDIRECT towards e.g devmap this causes the function bq_xmit_all() to run with direct return optimization enabled. This can lead to hard to find bugs. The issue only happens when bq_xmit_all() cannot ndo_xdp_xmit all frames and them frees them via xdp_return_frame_rx_napi().
Fix by expanding scope to include xdp_do_flush(). This was found by Dragos Tatulea.
--- kernel/bpf/cpumap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/bpf/cpumap.c +2 -2
@@ -186,7 +186,6 @@ static int cpu_map_bpf_prog_run_xdp(struct bpf_cpu_map_entry *rcpu,struct xdp_buff xdp;int i, nframes =0 ; -xdp_set_return_frame_no_direct (); xdp.rxq = &rxq;for (i =0 ; i < n; i++) {
@@ -231,7 +230,6 @@ static int cpu_map_bpf_prog_run_xdp(struct bpf_cpu_map_entry *rcpu, } } -xdp_clear_return_frame_no_direct (); stats->pass += nframes;return nframes;
@@ -255,6 +253,7 @@ static void cpu_map_bpf_prog_run(struct bpf_cpu_map_entry *rcpu, void **frames,rcu_read_lock (); bpf_net_ctx =bpf_net_ctx_set (&__bpf_net_ctx); +xdp_set_return_frame_no_direct (); ret->xdp_n =cpu_map_bpf_prog_run_xdp (rcpu, frames, ret->xdp_n, stats);if (unlikely (ret->skb_n))
@@ -264,6 +263,7 @@ static void cpu_map_bpf_prog_run(struct bpf_cpu_map_entry *rcpu, void **frames,if (stats->redirect)xdp_do_flush (); +xdp_clear_return_frame_no_direct ();bpf_net_ctx_clear (bpf_net_ctx);rcu_read_unlock ();
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 37/189 cpufreq/amd-pstate: Fix setting of CPPC.min_perf in active mode for performance governor
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gautham R. Shenoy <[email protected]>
[ Upstream commit 220abf77e7c2835cc63ea8cd7158cf83952640af ]
In the "active" mode of the amd-pstate driver with performance governor, the CPPC.min_perf is expected to be the nominal_perf.
However after commit a9b9b4c2a4cd ("cpufreq/amd-pstate: Drop min and max cached frequencies"), this is not the case when the governor is switched from performance to powersave and back to performance, and the CPPC.min_perf will be equal to the scaling_min_freq that was set for the powersave governor.
This is because prior to commit a9b9b4c2a4cd ("cpufreq/amd-pstate:
Drop min and max cached frequencies"), amd_pstate_epp_update_limit() would unconditionally call amd_pstate_update_min_max_limit() and the latter function would enforce the CPPC.min_perf constraint when the governor is performance.
However, after the aforementioned commit, amd_pstate_update_min_max_limit() is called by amd_pstate_epp_update_limit() only when either the scaling_{min/max}_freq is different from the cached value of cpudata->{min/max}_limit_freq, which wouldn't have changed on a governor transition from powersave to performance, thus missing out on enforcing the CPPC.min_perf constraint for the performance governor.
Fix this by invoking amd_pstate_epp_udpate_limit() not only when the {min/max} limits have changed from the cached values, but also when the policy itself has changed.
--- drivers/cpufreq/amd-pstate.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/cpufreq/amd-pstate.c +6 -4
@@ -1547,13 +1547,15 @@ static void amd_pstate_epp_cpu_exit(struct cpufreq_policy *policy)pr_debug ("CPU %d exiting\n" , policy->cpu); } -static int amd_pstate_epp_update_limit (struct cpufreq_policy *policy) +static int amd_pstate_epp_update_limit (struct cpufreq_policy *policy,bool policy_change) {struct amd_cpudata *cpudata = policy->driver_data;union perf_cached perf;u8 epp; -if (policy->min != cpudata->min_limit_freq || policy->max != cpudata->max_limit_freq) +if (policy_change || + policy->min != cpudata->min_limit_freq || + policy->max != cpudata->max_limit_freq)amd_pstate_update_min_max_limit (policy);if (cpudata->policy ==CPUFREQ_POLICY_PERFORMANCE )
@@ -1577,7 +1579,7 @@ static int amd_pstate_epp_set_policy(struct cpufreq_policy *policy) cpudata->policy = policy->policy; - ret =amd_pstate_epp_update_limit (policy); + ret =amd_pstate_epp_update_limit (policy, true);if (ret)return ret;
@@ -1651,7 +1653,7 @@ static int amd_pstate_epp_resume(struct cpufreq_policy *policy)int ret;/* enable amd pstate from suspend state*/ - ret =amd_pstate_epp_update_limit (policy); + ret =amd_pstate_epp_update_limit (policy, false);if (ret)return ret;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 38/189 s390/pai: Deny all events not handled by this PMU
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Richter <[email protected]>
[ Upstream commit 85941afd2c404247e583c827fae0a45da1c1d92c ]
Each PAI PMU device driver returns -EINVAL when an event is out of its accepted range. This return value aborts the search for an alternative PMU device driver to handle this event.
Change the return value to -ENOENT. This return value is used to try other PMUs instead. This makes the PMUs more robust when the sequence of PMU device driver initialization changes (at boot time) or by using modules.
--- arch/s390/kernel/perf_pai_crypto.c | 4 ++-- arch/s390/kernel/perf_pai_ext.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-)
arch/s390/kernel/perf_pai_crypto.c +2 -2
@@ -286,10 +286,10 @@ static int paicrypt_event_init(struct perf_event *event)/* PAI crypto PMU registered as PERF_TYPE_RAW, check event type */ if (a->type !=PERF_TYPE_RAW && event->pmu->type != a->type)return -ENOENT ; -/* PAI crypto event must be in valid range */ +/* PAI crypto event must be in valid range, try others if not */ if (a->config <PAI_CRYPTO_BASE || a->config >PAI_CRYPTO_BASE + paicrypt_cnt) -return -EINVAL ; +return -ENOENT ;/* Allow only CRYPTO_ALL for sampling */ if (a->sample_period && a->config !=PAI_CRYPTO_BASE )return -EINVAL ;
arch/s390/kernel/perf_pai_ext.c +1 -1
@@ -266,7 +266,7 @@ static int paiext_event_valid(struct perf_event *event) event->hw.config_base = offsetof(struct paiext_cb , acc);return 0 ; } -return -EINVAL ; +return -ENOENT ; }/* Might be called on different CPU than the one the event is intended for. */
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 39/189 s390/cpum_cf: Deny all sampling events by counter PMU
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Richter <[email protected]>
[ Upstream commit ce971233242b5391d99442271f3ca096fb49818d ]
Deny all sampling event by the CPUMF counter facility device driver and return -ENOENT. This return value is used to try other PMUs. Up to now events for type PERF_TYPE_HARDWARE were not tested for sampling and returned later on -EOPNOTSUPP. This ends the search for alternative PMUs. Change that behavior and try other PMUs instead.
--- arch/s390/kernel/perf_cpum_cf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/s390/kernel/perf_cpum_cf.c +2 -2
@@ -761,8 +761,6 @@ static int __hw_perf_event_init(struct perf_event *event, unsigned int type)break ;case PERF_TYPE_HARDWARE : -if (is_sampling_event (event))/* No sampling support */ -return -ENOENT ; ev = attr->config;if (!attr->exclude_user && attr->exclude_kernel) {/*
@@ -860,6 +858,8 @@ static int cpumf_pmu_event_init(struct perf_event *event)unsigned int type = event->attr.type;int err = -ENOENT ; +if (is_sampling_event (event))/* No sampling support */ +return err;if (type ==PERF_TYPE_HARDWARE || type ==PERF_TYPE_RAW ) err =__hw_perf_event_init (event, type);else if (event->pmu->type == type)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 40/189 cpufreq/amd-pstate: Fix a regression leading to EPP 0 after resume
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello (AMD) <[email protected]>
[ Upstream commit ba3319e5905710abe495b11a1aaf03ebb51d62e2 ]
During the suspend sequence the cached CPPC request is destroyed with the expectation that it's restored during resume. This assumption broke when the separate cache EPP variable was removed, and then it was broken again by commit 608a76b65288 ("cpufreq/amd-pstate: Add support for the "Requested CPU Min frequency" BIOS option") which explicitly set it to zero during suspend.
Remove the invalidation and set the value during the suspend call to update limits so that the cached variable can be used to restore on resume.
--- drivers/cpufreq/amd-pstate.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/cpufreq/amd-pstate.c +5 -4
@@ -1621,13 +1621,14 @@ static int amd_pstate_suspend(struct cpufreq_policy *policy)* min_perf value across kexec reboots. If this CPU is just resumed back without kexec, * the limits, epp and desired perf will get reset to the cached values in cpudata struct */ - ret =amd_pstate_update_perf (policy, perf.bios_min_perf,0U ,0U ,0U , false); + ret =amd_pstate_update_perf (policy, perf.bios_min_perf, +FIELD_GET (AMD_CPPC_DES_PERF_MASK , cpudata->cppc_req_cached), +FIELD_GET (AMD_CPPC_MAX_PERF_MASK , cpudata->cppc_req_cached), +FIELD_GET (AMD_CPPC_EPP_PERF_MASK , cpudata->cppc_req_cached), + false);if (ret)return ret; -/* invalidate to ensure it's rewritten during resume */ - cpudata->cppc_req_cached =0 ; -/* set this flag to avoid setting core offline*/ cpudata->suspended = true;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 41/189 bpf: Fix out-of-bounds dynptr write in bpf_crypto_crypt
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Borkmann <[email protected]>
[ Upstream commit f9bb6ffa7f5ad0f8ee0f53fc4a10655872ee4a14 ]
Stanislav reported that in bpf_crypto_crypt() the destination dynptr's size is not validated to be at least as large as the source dynptr's size before calling into the crypto backend with 'len = src_len'. This can result in an OOB write when the destination is smaller than the source.
Concretely, in mentioned function, psrc and pdst are both linear buffers fetched from each dynptr:
psrc = __bpf_dynptr_data(src, src_len);
[...]
pdst = __bpf_dynptr_data_rw(dst, dst_len);
[...]
err = decrypt ?
ctx->type->decrypt(ctx->tfm, psrc, pdst, src_len, piv) :
ctx->type->encrypt(ctx->tfm, psrc, pdst, src_len, piv);The crypto backend expects pdst to be large enough with a src_len length that can be written. Add an additional src_len > dst_len check and bail out if it's the case. Note that these kfuncs are accessible under root privileges only.
--- kernel/bpf/crypto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/bpf/crypto.c +1 -1
@@ -278,7 +278,7 @@ static int bpf_crypto_crypt(const struct bpf_crypto_ctx *ctx, siv_len = siv ?__bpf_dynptr_size (siv) :0 ; src_len =__bpf_dynptr_size (src); dst_len =__bpf_dynptr_size (dst); -if (!src_len || !dst_len) +if (!src_len || !dst_len || src_len > dst_len)return -EINVAL ;if (siv_len != ctx->siv_len)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 42/189 xsk: Fix immature cq descriptor production
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maciej Fijalkowski <[email protected]>
[ Upstream commit 30f241fcf52aaaef7ac16e66530faa11be78a865 ]
Eryk reported an issue that I have put under Closes: tag, related to umem addrs being prematurely produced onto pool's completion queue. Let us make the skb's destructor responsible for producing all addrs that given skb used.
Commit from fixes tag introduced the buggy behavior, it was not broken from day 1, but rather when xsk multi-buffer got introduced.
In order to mitigate performance impact as much as possible, mimic the linear and frag parts within skb by storing the first address from XSK descriptor at sk_buff::destructor_arg. For fragments, store them at ::cb via list. The nodes that will go onto list will be allocated via kmem_cache. xsk_destruct_skb() will consume address stored at ::destructor_arg and optionally go through list from ::cb, if count of descriptors associated with this particular skb is bigger than 1.
Previous approach where whole array for storing UMEM addresses from XSK descriptors was pre-allocated during first fragment processing yielded too big performance regression for 64b traffic. In current approach impact is much reduced on my tests and for jumbo frames I observed traffic being slower by at most 9%.
Magnus suggested to have this way of processing special cased for XDP_SHARED_UMEM, so we would identify this during bind and set different hooks for 'backpressure mechanism' on CQ and for skb destructor, but given that results looked promising on my side I decided to have a single data path for XSK generic Tx. I suppose other auxiliary stuff would have to land as well in order to make it work.
--- net/xdp/xsk.c | 113 ++++++++++++++++++++++++++++++++++++++------ net/xdp/xsk_queue.h | 12 +++++ 2 files changed, 111 insertions(+), 14 deletions(-)
net/xdp/xsk.c +99 -14
@@ -36,6 +36,20 @@#define TX_BATCH_SIZE 32#define MAX_PER_SOCKET_BUDGET (TX_BATCH_SIZE) +struct xsk_addr_node { +u64 addr; +struct list_head addr_node; +}; + +struct xsk_addr_head { +u32 num_descs; +struct list_head addrs_list; +}; + +static struct kmem_cache *xsk_tx_generic_cache; + +#define XSKCB (skb) ((struct xsk_addr_head *)((skb)->cb)) +void xsk_set_rx_need_wakeup (struct xsk_buff_pool *pool) {if (pool->cached_need_wakeup &XDP_WAKEUP_RX )
@@ -528,24 +542,43 @@ static int xsk_wakeup(struct xdp_sock *xs, u8 flags)return dev->netdev_ops->ndo_xsk_wakeup (dev, xs->queue_id, flags); } -static int xsk_cq_reserve_addr_locked (struct xsk_buff_pool *pool,u64 addr) +static int xsk_cq_reserve_locked (struct xsk_buff_pool *pool) {unsigned long flags;int ret;spin_lock_irqsave (&pool->cq_lock, flags); - ret =xskq_prod_reserve_addr (pool->cq, addr); + ret =xskq_prod_reserve (pool->cq);spin_unlock_irqrestore (&pool->cq_lock, flags);return ret; } -static void xsk_cq_submit_locked (struct xsk_buff_pool *pool,u32 n) +static void xsk_cq_submit_addr_locked (struct xsk_buff_pool *pool, +struct sk_buff *skb) { +struct xsk_addr_node *pos, *tmp; +u32 descs_processed =0 ;unsigned long flags; +u32 idx;spin_lock_irqsave (&pool->cq_lock, flags); -xskq_prod_submit_n (pool->cq, n); + idx =xskq_get_prod (pool->cq); + +xskq_prod_write_addr (pool->cq, idx, + (u64 )(uintptr_t )skb_shinfo (skb)->destructor_arg); + descs_processed++; + +if (unlikely (XSKCB (skb)->num_descs >1 )) { +list_for_each_entry_safe (pos, tmp, &XSKCB (skb)->addrs_list, addr_node) { +xskq_prod_write_addr (pool->cq, idx + descs_processed, + pos->addr); + descs_processed++; +list_del (&pos->addr_node); +kmem_cache_free (xsk_tx_generic_cache, pos); + } + } +xskq_prod_submit_n (pool->cq, descs_processed);spin_unlock_irqrestore (&pool->cq_lock, flags); }
@@ -558,9 +591,14 @@ static void xsk_cq_cancel_locked(struct xsk_buff_pool *pool, u32 n)spin_unlock_irqrestore (&pool->cq_lock, flags); } +static void xsk_inc_num_desc (struct sk_buff *skb) +{ +XSKCB (skb)->num_descs++; +} +static u32 xsk_get_num_desc (struct sk_buff *skb) { -return skb ? (long )skb_shinfo (skb)->destructor_arg :0 ; +return XSKCB (skb)->num_descs; }static void xsk_destruct_skb (struct sk_buff *skb)
@@ -572,23 +610,33 @@ static void xsk_destruct_skb(struct sk_buff *skb) *compl->tx_timestamp =ktime_get_tai_fast_ns (); } -xsk_cq_submit_locked (xdp_sk (skb->sk)->pool,xsk_get_num_desc (skb)); +xsk_cq_submit_addr_locked (xdp_sk (skb->sk)->pool, skb);sock_wfree (skb); } -static void xsk_set_destructor_arg (struct sk_buff *skb) +static void xsk_set_destructor_arg (struct sk_buff *skb,u64 addr) { -long num =xsk_get_num_desc (xdp_sk (skb->sk)->skb) +1 ; - -skb_shinfo (skb)->destructor_arg = (void *)num; +BUILD_BUG_ON (sizeof (struct xsk_addr_head ) >sizeof (skb->cb)); +INIT_LIST_HEAD (&XSKCB (skb)->addrs_list); +XSKCB (skb)->num_descs =0 ; +skb_shinfo (skb)->destructor_arg = (void *)(uintptr_t )addr; }static void xsk_consume_skb (struct sk_buff *skb) {struct xdp_sock *xs =xdp_sk (skb->sk); +u32 num_descs =xsk_get_num_desc (skb); +struct xsk_addr_node *pos, *tmp; + +if (unlikely (num_descs >1 )) { +list_for_each_entry_safe (pos, tmp, &XSKCB (skb)->addrs_list, addr_node) { +list_del (&pos->addr_node); +kmem_cache_free (xsk_tx_generic_cache, pos); + } + } skb->destructor = sock_wfree; -xsk_cq_cancel_locked (xs->pool,xsk_get_num_desc (skb)); +xsk_cq_cancel_locked (xs->pool, num_descs);/* Free skb without triggering the perf drop trace */ consume_skb (skb); xs->skb =NULL ;
@@ -605,6 +653,7 @@ static struct sk_buff *xsk_build_skb_zerocopy(struct xdp_sock *xs, {struct xsk_buff_pool *pool = xs->pool;u32 hr, len, ts, offset, copy, copied; +struct xsk_addr_node *xsk_addr;struct sk_buff *skb = xs->skb;struct page *page;void *buffer;
@@ -619,6 +668,19 @@ static struct sk_buff *xsk_build_skb_zerocopy(struct xdp_sock *xs,return ERR_PTR (err);skb_reserve (skb, hr); + +xsk_set_destructor_arg (skb, desc->addr); + }else { + xsk_addr =kmem_cache_zalloc (xsk_tx_generic_cache,GFP_KERNEL ); +if (!xsk_addr) +return ERR_PTR (-ENOMEM ); + +/* in case of -EOVERFLOW that could happen below, +* xsk_consume_skb() will release this node as whole skb +* would be dropped, which implies freeing all list elements +*/ + xsk_addr->addr = desc->addr; +list_add_tail (&xsk_addr->addr_node, &XSKCB (skb)->addrs_list); } addr = desc->addr;
@@ -690,8 +752,11 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs, err =skb_store_bits (skb,0 , buffer, len);if (unlikely (err)) goto free_err; + +xsk_set_destructor_arg (skb, desc->addr); }else {int nr_frags =skb_shinfo (skb)->nr_frags; +struct xsk_addr_node *xsk_addr;struct page *page;u8 *vaddr;
@@ -706,12 +771,22 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs, goto free_err; } + xsk_addr =kmem_cache_zalloc (xsk_tx_generic_cache,GFP_KERNEL ); +if (!xsk_addr) { +__free_page (page); + err = -ENOMEM ; + goto free_err; + } + vaddr =kmap_local_page (page);memcpy (vaddr, buffer, len);kunmap_local (vaddr);skb_add_rx_frag (skb, nr_frags, page,0 , len,PAGE_SIZE );refcount_add (PAGE_SIZE , &xs->sk.sk_wmem_alloc); + + xsk_addr->addr = desc->addr; +list_add_tail (&xsk_addr->addr_node, &XSKCB (skb)->addrs_list); }if (first_frag && desc->options &XDP_TX_METADATA ) {
@@ -755,7 +830,7 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs, skb->mark =READ_ONCE (xs->sk.sk_mark); skb->destructor = xsk_destruct_skb;xsk_tx_metadata_to_compl (meta, &skb_shinfo (skb)->xsk_meta); -xsk_set_destructor_arg (skb); +xsk_inc_num_desc (skb);return skb;
@@ -765,7 +840,7 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,if (err == -EOVERFLOW ) {/* Drop the packet */ -xsk_set_destructor_arg (xs->skb); +xsk_inc_num_desc (xs->skb);xsk_drop_skb (xs->skb);xskq_cons_release (xs->tx); }else {
@@ -807,7 +882,7 @@ static int __xsk_generic_xmit(struct sock *sk)* if there is space in it. This avoids having to implement * any buffering in the Tx path. */ - err =xsk_cq_reserve_addr_locked (xs->pool, desc.addr); + err =xsk_cq_reserve_locked (xs->pool);if (err) { err = -EAGAIN ; goto out;
@@ -1795,8 +1870,18 @@ static int __init xsk_init(void)if (err) goto out_pernet; + xsk_tx_generic_cache =kmem_cache_create ("xsk_generic_xmit_cache" , +sizeof (struct xsk_addr_node ), +0 ,SLAB_HWCACHE_ALIGN ,NULL ); +if (!xsk_tx_generic_cache) { + err = -ENOMEM ; + goto out_unreg_notif; + } +return 0 ; +out_unreg_notif: +unregister_netdevice_notifier (&xsk_netdev_notifier); out_pernet:unregister_pernet_subsys (&xsk_net_ops); out_sk:
net/xdp/xsk_queue.h +12 -0
@@ -344,6 +344,11 @@ static inline u32 xskq_cons_present_entries(struct xsk_queue *q)/* Functions for producers */ +static inline u32 xskq_get_prod (struct xsk_queue *q) +{ +return READ_ONCE (q->ring->producer); +} +static inline u32 xskq_prod_nb_free (struct xsk_queue *q,u32 max) {u32 free_entries = q->nentries - (q->cached_prod - q->cached_cons);
@@ -390,6 +395,13 @@ static inline int xskq_prod_reserve_addr(struct xsk_queue *q, u64 addr)return 0 ; } +static inline void xskq_prod_write_addr (struct xsk_queue *q,u32 idx,u64 addr) +{ +struct xdp_umem_ring *ring = (struct xdp_umem_ring *)q->ring; + + ring->desc[idx & q->ring_mask] = addr; +} +static inline void xskq_prod_write_addr_batch (struct xsk_queue *q,struct xdp_desc *descs,u32 nb_entries) {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 43/189 rqspinlock: Choose trylock fallback for NMI waiters
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kumar Kartikeya Dwivedi <[email protected]>
[ Upstream commit 0d80e7f951be1bdd08d328fd87694be0d6e8aaa8 ]
Currently, out of all 3 types of waiters in the rqspinlock slow path (i.e., pending bit waiter, wait queue head waiter, and wait queue non-head waiter), only the pending bit waiter and wait queue head waiters apply deadlock checks and a timeout on their waiting loop. The assumption here was that the wait queue head's forward progress would be sufficient to identify cases where the lock owner or pending bit waiter is stuck, and non-head waiters relying on the head waiter would prove to be sufficient for their own forward progress.
However, the head waiter itself can be preempted by a non-head waiter for the same lock (AA) or a different lock (ABBA) in a manner that impedes its forward progress. In such a case, non-head waiters not performing deadlock and timeout checks becomes insufficient, and the system can enter a state of lockup.
This is typically not a concern with non-NMI lock acquisitions, as lock holders which in run in different contexts (IRQ, non-IRQ) use "irqsave" variants of the lock APIs, which naturally excludes such lock holders from preempting one another on the same CPU.
It might seem likely that a similar case may occur for rqspinlock when programs are attached to contention tracepoints (begin, end), however, these tracepoints either precede the enqueue into the wait queue, or succeed it, therefore cannot be used to preempt a head waiter's waiting loop.
We must still be careful against nested kprobe and fentry programs that may attach to the middle of the head's waiting loop to stall forward progress and invoke another rqspinlock acquisition that proceeds as a non-head waiter. To this end, drop CC_FLAGS_FTRACE from the rqspinlock.o object file.
For now, this issue is resolved by falling back to a repeated trylock on the lock word from NMI context, while performing the deadlock checks to break out early in case forward progress is impossible, and use the timeout as a final fallback.
A more involved fix to terminate the queue when such a condition occurs will be made as a follow up. A selftest to stress this aspect of nested NMI/non-NMI locking attempts will be added in a subsequent patch to the bpf-next tree when this fix lands and trees are synchronized.
--- kernel/bpf/Makefile | 1 + kernel/bpf/rqspinlock.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-)
kernel/bpf/Makefile +1 -0
@@ -62,3 +62,4 @@ CFLAGS_REMOVE_bpf_lru_list.o = $(CC_FLAGS_FTRACE) CFLAGS_REMOVE_queue_stack_maps.o = $(CC_FLAGS_FTRACE) CFLAGS_REMOVE_lpm_trie.o = $(CC_FLAGS_FTRACE) CFLAGS_REMOVE_ringbuf.o = $(CC_FLAGS_FTRACE) +CFLAGS_REMOVE_rqspinlock.o = $(CC_FLAGS_FTRACE)
kernel/bpf/rqspinlock.c +1 -1
@@ -471,7 +471,7 @@ int __lockfunc resilient_queued_spin_lock_slowpath(rqspinlock_t *lock, u32 val)* any MCS node. This is not the most elegant solution, but is * simple enough. */ -if (unlikely (idx >= _Q_MAX_NODES)) { +if (unlikely (idx >= _Q_MAX_NODES ||in_nmi ())) {lockevent_inc (lock_no_node);RES_RESET_TIMEOUT (ts,RES_DEF_TIMEOUT );while (!queued_spin_trylock (lock)) {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 44/189 bpf: Allow fall back to interpreter for programs with stack size <= 512
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: KaFai Wan <[email protected]>
[ Upstream commit df0cb5cb50bd54d3cd4d0d83417ceec6a66404aa ]
OpenWRT users reported regression on ARMv6 devices after updating to latest HEAD, where tcpdump filter:
tcpdump "not ether host 3c37121a2b3c and not ether host 184ecbca2a3a \
and not ether host 14130b4d3f47 and not ether host f0f61cf440b7 \
and not ether host a84b4dedf471 and not ether host d022be17e1d7 \
and not ether host 5c497967208b and not ether host 706655784d5b"
fails with warning: "Kernel filter failed: No error information" when using config:
# CONFIG_BPF_JIT_ALWAYS_ON is not set CONFIG_BPF_JIT_DEFAULT_ON=y
The issue arises because commits:
1. "bpf: Fix array bounds error with may_goto" changed default runtime to __bpf_prog_ret0_warn when jit_requested = 1
2. "bpf: Avoid __bpf_prog_ret0_warn when jit fails" returns error when jit_requested = 1 but jit fails
This change restores interpreter fallback capability for BPF programs with stack size <= 512 bytes when jit fails.
--- kernel/bpf/core.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
kernel/bpf/core.c +9 -7
@@ -2354,8 +2354,7 @@ static unsigned int __bpf_prog_ret0_warn(const void *ctx, const struct bpf_insn *insn) {/* If this handler ever gets executed, then BPF_JIT_ALWAYS_ON -* is not working properly, or interpreter is being used when -* prog->jit_requested is not 0, so warn about it! +* is not working properly, so warn about it! */ WARN_ON_ONCE (1 );return 0 ;
@@ -2456,8 +2455,9 @@ static int bpf_check_tail_call(const struct bpf_prog *fp)return ret; } -static void bpf_prog_select_func (struct bpf_prog *fp) +static bool bpf_prog_select_interpreter (struct bpf_prog *fp) { +bool select_interpreter = false;#ifndef CONFIG_BPF_JIT_ALWAYS_ON u32 stack_depth =max_t (u32, fp->aux->stack_depth,1 );u32 idx = (round_up (stack_depth,32 ) /32 ) -1 ;
@@ -2466,15 +2466,16 @@ static void bpf_prog_select_func(struct bpf_prog *fp)* But for non-JITed programs, we don't need bpf_func, so no bounds * check needed. */ -if (!fp->jit_requested && - !WARN_ON_ONCE (idx >=ARRAY_SIZE (interpreters))) { +if (idx <ARRAY_SIZE (interpreters)) { fp->bpf_func = interpreters[idx]; + select_interpreter = true; }else { fp->bpf_func = __bpf_prog_ret0_warn; }#else fp->bpf_func = __bpf_prog_ret0_warn;#endif +return select_interpreter; }/**
@@ -2493,7 +2494,7 @@ struct bpf_prog *bpf_prog_select_runtime(struct bpf_prog *fp, int *err)/* In case of BPF to BPF calls, verifier did all the prep * work with regards to JITing, etc. */ -bool jit_needed = fp->jit_requested; +bool jit_needed = false;if (fp->bpf_func) goto finalize;
@@ -2502,7 +2503,8 @@ struct bpf_prog *bpf_prog_select_runtime(struct bpf_prog *fp, int *err) bpf_prog_has_kfunc_call(fp)) jit_needed = true; -bpf_prog_select_func (fp); +if (!bpf_prog_select_interpreter (fp)) + jit_needed = true;/* eBPF JITs can rewrite the program in case constant * blinding is active. However, in case of error during
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 45/189 bpf: Tell memcg to use allow_spinning=false path in bpf_timer_init()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peilin Ye <[email protected]>
[ Upstream commit 6d78b4473cdb08b74662355a9e8510bde09c511e ]
Currently, calling bpf_map_kmalloc_node() from __bpf_async_init() can cause various locking issues; see the following stack trace (edited for style) as one example:
...
[10.011566] do_raw_spin_lock.cold [10.011570] try_to_wake_up (5) double-acquiring the same [10.011575] kick_pool rq_lock, causing a hardlockup [10.011579] __queue_work [10.011582] queue_work_on [10.011585] kernfs_notify [10.011589] cgroup_file_notify [10.011593] try_charge_memcg (4) memcg accounting raises an [10.011597] obj_cgroup_charge_pages MEMCG_MAX event [10.011599] obj_cgroup_charge_account [10.011600] __memcg_slab_post_alloc_hook [10.011603] __kmalloc_node_noprof ... [10.011611] bpf_map_kmalloc_node [10.011612] __bpf_async_init [10.011615] bpf_timer_init (3) BPF calls bpf_timer_init() [10.011617] bpf_prog_xxxxxxxxxxxxxxxx_fcg_runnable [10.011619] bpf__sched_ext_ops_runnable [10.011620] enqueue_task_scx (2) BPF runs with rq_lock held [10.011622] enqueue_task [10.011626] ttwu_do_activate [10.011629] sched_ttwu_pending (1) grabs rq_lock
...
The above was reproduced on bpf-next (b338cf849ec8) by modifying ./tools/sched_ext/scx_flatcg.bpf.c to call bpf_timer_init() during ops.runnable(), and hacking the memcg accounting code a bit to make a bpf_timer_init() call more likely to raise an MEMCG_MAX event.
We have also run into other similar variants (both internally and on bpf-next), including double-acquiring cgroup_file_kn_lock, the same worker_pool::lock, etc.
As suggested by Shakeel, fix this by using __GFP_HIGH instead of GFP_ATOMIC in __bpf_async_init(), so that e.g. if try_charge_memcg() raises an MEMCG_MAX event, we call __memcg_memory_event() with @allow_spinning=false and avoid calling cgroup_file_notify() there.
Depends on mm patch
"memcg: skip cgroup_file_notify if spinning is not allowed":
https://lore.kernel.org/bpf/[email protected]/
v0 approach s/bpf_map_kmalloc_node/bpf_mem_alloc/
https://lore.kernel.org/bpf/[email protected]/
v1 approach:
https://lore.kernel.org/bpf/[email protected]/
--- kernel/bpf/helpers.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
kernel/bpf/helpers.c +5 -2
@@ -1277,8 +1277,11 @@ static int __bpf_async_init(struct bpf_async_kern *async, struct bpf_map *map, u goto out; } -/* allocate hrtimer via map_kmalloc to use memcg accounting */ - cb =bpf_map_kmalloc_node (map, size,GFP_ATOMIC , map->numa_node); +/* Allocate via bpf_map_kmalloc_node() for memcg accounting. Until +* kmalloc_nolock() is available, avoid locking issues by using +* __GFP_HIGH (GFP_ATOMIC & ~__GFP_RECLAIM). +*/ + cb =bpf_map_kmalloc_node (map, size, __GFP_HIGH, map->numa_node);if (!cb) { ret = -ENOMEM ; goto out;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 46/189 tcp_bpf: Call sk_msg_free() when tcp_bpf_send_verdict() fails to allocate psock->cork.
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
[ Upstream commit a3967baad4d533dc254c31e0d221e51c8d223d58 ]
syzbot reported the splat below. [0]
The repro does the following:
1. Load a sk_msg prog that calls bpf_msg_cork_bytes(msg, cork_bytes)
2. Attach the prog to a SOCKMAP
3. Add a socket to the SOCKMAP
4. Activate fault injection
5. Send data less than cork_bytes
At 5., the data is carried over to the next sendmsg() as it is smaller than the cork_bytes specified by bpf_msg_cork_bytes().
Then, tcp_bpf_send_verdict() tries to allocate psock->cork to hold the data, but this fails silently due to fault injection + __GFP_NOWARN.
If the allocation fails, we need to revert the sk->sk_forward_alloc change done by sk_msg_alloc().
Let's call sk_msg_free() when tcp_bpf_send_verdict fails to allocate psock->cork.
The "*copied" also needs to be updated such that a proper error can be returned to the caller, sendmsg. It fails to allocate psock->cork. Nothing has been corked so far, so this patch simply sets "*copied" to 0.
[0]:
WARNING: net/ipv4/af_inet.c:156 at inet_sock_destruct+0x623/0x730 net/ipv4/af_inet.c:156, CPU#1: syz-executor/5983 Modules linked in: CPU: 1 UID: 0 PID: 5983 Comm: syz-executor Not tainted syzkaller #0 PREEMPT(full) Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/12/2025 RIP: 0010:inet_sock_destruct+0x623/0x730 net/ipv4/af_inet.c:156 Code: 0f 0b 90 e9 62 fe ff ff e8 7a db b5 f7 90 0f 0b 90 e9 95 fe ff ff e8 6c db b5 f7 90 0f 0b 90 e9 bb fe ff ff e8 5e db b5 f7 90 <0f> 0b 90 e9 e1 fe ff ff 89 f9 80 e1 07 80 c1 03 38 c1 0f 8c 9f fc RSP: 0018:ffffc90000a08b48 EFLAGS: 00010246 RAX: ffffffff8a09d0b2 RBX: dffffc0000000000 RCX: ffff888024a23c80 RDX: 0000000000000100 RSI: 0000000000000fff RDI: 0000000000000000 RBP: 0000000000000fff R08: ffff88807e07c627 R09: 1ffff1100fc0f8c4 R10: dffffc0000000000 R11: ffffed100fc0f8c5 R12: ffff88807e07c380 R13: dffffc0000000000 R14: ffff88807e07c60c R15: 1ffff1100fc0f872 FS: 00005555604c4500(0000) GS:ffff888125af1000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00005555604df5c8 CR3: 0000000032b06000 CR4: 00000000003526f0 Call Trace: <IRQ> __sk_destruct+0x86/0x660 net/core/sock.c:2339 rcu_do_batch kernel/rcu/tree.c:2605 [inline] rcu_core+0xca8/0x1770 kernel/rcu/tree.c:2861 handle_softirqs+0x286/0x870 kernel/softirq.c:579 __do_softirq kernel/softirq.c:613 [inline] invoke_softirq kernel/softirq.c:453 [inline] __irq_exit_rcu+0xca/0x1f0 kernel/softirq.c:680 irq_exit_rcu+0x9/0x30 kernel/softirq.c:696 instr_sysvec_apic_timer_interrupt arch/x86/kernel/apic/apic.c:1052 [inline] sysvec_apic_timer_interrupt+0xa6/0xc0 arch/x86/kernel/apic/apic.c:1052 </IRQ>
--- net/ipv4/tcp_bpf.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
net/ipv4/tcp_bpf.c +4 -1
@@ -408,8 +408,11 @@ static int tcp_bpf_send_verdict(struct sock *sk, struct sk_psock *psock,if (!psock->cork) { psock->cork =kzalloc (sizeof (*psock->cork),GFP_ATOMIC | __GFP_NOWARN); -if (!psock->cork) +if (!psock->cork) { +sk_msg_free (sk, msg); + *copied =0 ;return -ENOMEM ; + } }memcpy (psock->cork, msg,sizeof (*msg));return 0 ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 47/189 proc: fix type confusion in pde_set_flags()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: wangzijie <[email protected]>
[ Upstream commit 0ce9398aa0830f15f92bbed73853f9861c3e74ff ]
Commit 2ce3d282bd50 ("proc: fix missing pde_set_flags() for net proc files") missed a key part in the definition of proc_dir_entry:
union {
const struct proc_ops *proc_ops;
const struct file_operations *proc_dir_ops;
};So dereference of ->proc_ops assumes it is a proc_ops structure results in type confusion and make NULL check for 'proc_ops' not work for proc dir.
Add !S_ISDIR(dp->mode) test before calling pde_set_flags() to fix it.
--- fs/proc/generic.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/proc/generic.c +2 -1
@@ -390,7 +390,8 @@ struct proc_dir_entry *proc_register(struct proc_dir_entry *dir,if (proc_alloc_inum (&dp->low_ino)) goto out_free_entry; -pde_set_flags (dp); +if (!S_ISDIR (dp->mode)) +pde_set_flags (dp);write_lock (&proc_subdir_lock); dp->parent = dir;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 48/189 EDAC/altera: Delete an inappropriate dma_free_coherent() call
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Salah Triki <[email protected]>
commit ff2a66d21fd2364ed9396d151115eec59612b200 upstream.
dma_free_coherent() must only be called if the corresponding dma_alloc_coherent() call has succeeded. Calling it when the allocation fails leads to undefined behavior.
Delete the wrong call.
[ bp: Massage commit message. ]
--- drivers/edac/altera_edac.c | 1 - 1 file changed, 1 deletion(-)
drivers/edac/altera_edac.c +0 -1
@@ -128,7 +128,6 @@ static ssize_t altr_sdr_mc_err_inject_wr ptemp =dma_alloc_coherent (mci->pdev,16 , &dma_handle,GFP_KERNEL );if (!ptemp) { -dma_free_coherent (mci->pdev,16 , ptemp, dma_handle);edac_printk (KERN_ERR ,EDAC_MC ,"Inject: Buffer Allocation error\n" );return -ENOMEM ;
Greg Kroah-Hartman
maintainerPATCH 49/189 i2c: rtl9300: fix channel number bound check
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Jelonek <[email protected]>
commit cd6c956fbc13156bcbcca084b46a8380caebc2a8 upstream.
Fix the current check for number of channels (child nodes in the device tree). Before, this was:
if (device_get_child_node_count(dev) >= RTL9300_I2C_MUX_NCHAN)
RTL9300_I2C_MUX_NCHAN gives the maximum number of channels so checking with '>=' isn't correct because it doesn't allow the last channel number. Thus, fix it to:
if (device_get_child_node_count(dev) > RTL9300_I2C_MUX_NCHAN)
Issue occured on a TP-Link TL-ST1008F v2.0 device (8 SFP+ ports) and fix is tested there.
--- drivers/i2c/busses/i2c-rtl9300.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/i2c/busses/i2c-rtl9300.c +1 -1
@@ -353,7 +353,7 @@ static int rtl9300_i2c_probe(struct platplatform_set_drvdata (pdev, i2c); -if (device_get_child_node_count (dev) >=RTL9300_I2C_MUX_NCHAN ) +if (device_get_child_node_count (dev) >RTL9300_I2C_MUX_NCHAN )return dev_err_probe (dev, -EINVAL ,"Too many channels\n" );device_for_each_child_node (dev, child) {
Greg Kroah-Hartman
maintainerPATCH 50/189 Revert "SUNRPC: Dont allow waiting for exiting tasks"
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <[email protected]>
commit 199cd9e8d14bc14bdbd1fa3031ce26dac9781507 upstream.
This reverts commit 14e41b16e8cb677bb440dca2edba8b041646c742.
This patch breaks the LTP acct02 test, so let's revert and look for a better solution.
--- net/sunrpc/sched.c | 2 -- 1 file changed, 2 deletions(-)
net/sunrpc/sched.c +0 -2
@@ -276,8 +276,6 @@ EXPORT_SYMBOL_GPL(rpc_destroy_wait_queuestatic int rpc_wait_bit_killable (struct wait_bit_key *key,int mode) { -if (unlikely (current->flags &PF_EXITING )) -return -EINTR ;schedule ();if (signal_pending_state (mode, current))return -ERESTARTSYS ;
Greg Kroah-Hartman
maintainerPATCH 51/189 compiler-clang.h: define __SANITIZE_*__ macros only when undefined
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nathan Chancellor <[email protected]>
commit 3fac212fe489aa0dbe8d80a42a7809840ca7b0f9 upstream.
Clang 22 recently added support for defining __SANITIZE__ macros similar to GCC [1], which causes warnings (or errors with CONFIG_WERROR=y or W=e) with the existing defines that the kernel creates to emulate this behavior with existing clang versions.
In file included from <built-in>:3:
In file included from include/linux/compiler_types.h:171:
include/linux/compiler-clang.h:37:9: error: '__SANITIZE_THREAD__' macro redefined [-Werror,-Wmacro-redefined]
37 | #define __SANITIZE_THREAD__
| ^
<built-in>:352:9: note: previous definition is here
352 | #define __SANITIZE_THREAD__ 1
| ^Refactor compiler-clang.h to only define the sanitizer macros when they are undefined and adjust the rest of the code to use these macros for checking if the sanitizers are enabled, clearing up the warnings and allowing the kernel to easily drop these defines when the minimum supported version of LLVM for building the kernel becomes 22.0.0 or newer.
--- include/linux/compiler-clang.h | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-)
include/linux/compiler-clang.h +24 -5
@@ -18,23 +18,42 @@#define KASAN_ABI_VERSION 5/* +* Clang 22 added preprocessor macros to match GCC, in hopes of eventually +* dropping __has_feature support for sanitizers: +* https://github.com/llvm/llvm-project/commit/568c23bbd3303518c5056d7f03444dae4fdc8a9c +* Create these macros for older versions of clang so that it is easy to clean +* up once the minimum supported version of LLVM for building the kernel always +* creates these macros. +* * Note: Checking __has_feature(*_sanitizer) is only true if the feature is * enabled. Therefore it is not required to additionally check defined(CONFIG_*) * to avoid adding redundant attributes in other configurations. */ +#if __has_feature (address_sanitizer) && !defined(__SANITIZE_ADDRESS__) +#define __SANITIZE_ADDRESS__ +#endif +#if __has_feature (hwaddress_sanitizer) && !defined(__SANITIZE_HWADDRESS__) +#define __SANITIZE_HWADDRESS__ +#endif +#if __has_feature (thread_sanitizer) && !defined(__SANITIZE_THREAD__) +#define __SANITIZE_THREAD__ +#endif -#if __has_feature (address_sanitizer) ||__has_feature (hwaddress_sanitizer) -/* Emulate GCC's __SANITIZE_ADDRESS__ flag */ +/* +* Treat __SANITIZE_HWADDRESS__ the same as __SANITIZE_ADDRESS__ in the kernel. +*/ +#ifdef __SANITIZE_HWADDRESS__#define __SANITIZE_ADDRESS__ +#endif + +#ifdef __SANITIZE_ADDRESS__#define __no_sanitize_address \ __attribute__((no_sanitize("address", "hwaddress")))#else #define __no_sanitize_address#endif -#if __has_feature (thread_sanitizer) -/* emulate gcc's __SANITIZE_THREAD__ flag */ -#define __SANITIZE_THREAD__ +#ifdef __SANITIZE_THREAD__#define __no_sanitize_thread \ __attribute__((no_sanitize("thread")))#else
Greg Kroah-Hartman
maintainerPATCH 52/189 arm64: kexec: initialize kexec_buf struct in load_other_segments()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao <[email protected]>
commit 04d3cd43700a2d0fe4bfb1012a8ec7f2e34a3507 upstream.
Patch series "kexec: Fix invalid field access".
The kexec_buf structure was previously declared without initialization. commit bf454ec31add ("kexec_file: allow to place kexec_buf randomly") added a field that is always read but not consistently populated by all architectures. This un-initialized field will contain garbage.
This is also triggering a UBSAN warning when the uninitialized data was accessed:
------------[ cut here ]------------ UBSAN: invalid-load in ./include/linux/kexec.h:210:10 load of value 252 is not a valid value for type '_Bool'
Zero-initializing kexec_buf at declaration ensures all fields are cleanly set, preventing future instances of uninitialized memory being used.
An initial fix was already landed for arm64[0], and this patchset fixes the problem on the remaining arm64 code and on riscv, as raised by Mark.
Discussions about this problem could be found at[1][2].
This patch (of 3):
The kexec_buf structure was previously declared without initialization. commit bf454ec31add ("kexec_file: allow to place kexec_buf randomly") added a field that is always read but not consistently populated by all architectures. This un-initialized field will contain garbage.
This is also triggering a UBSAN warning when the uninitialized data was accessed:
------------[ cut here ]------------ UBSAN: invalid-load in ./include/linux/kexec.h:210:10 load of value 252 is not a valid value for type '_Bool'
Zero-initializing kexec_buf at declaration ensures all fields are cleanly set, preventing future instances of uninitialized memory being used.
--- arch/arm64/kernel/machine_kexec_file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/kernel/machine_kexec_file.c +1 -1
@@ -94,7 +94,7 @@ int load_other_segments(struct kimage *image, char *initrd, unsigned long initrd_len, char *cmdline) { - struct kexec_buf kbuf; + struct kexec_buf kbuf = {};void *dtb =NULL ;unsigned long initrd_load_addr =0 , dtb_len, orig_segments = image->nr_segments;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 53/189 mptcp: sockopt: make sync_socket_options propagate SOCK_KEEPOPEN
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krister Johansen <[email protected]>
commit 648de37416b301f046f62f1b65715c7fa8ebaa67 upstream.
Users reported a scenario where MPTCP connections that were configured with SO_KEEPALIVE prior to connect would fail to enable their keepalives if MTPCP fell back to TCP mode.
After investigating, this affects keepalives for any connection where sync_socket_options is called on a socket that is in the closed or listening state. Joins are handled properly. For connects, sync_socket_options is called when the socket is still in the closed state. The tcp_set_keepalive() function does not act on sockets that are closed or listening, hence keepalive is not immediately enabled. Since the SO_KEEPOPEN flag is absent, it is not enabled later in the connect sequence via tcp_finish_connect. Setting the keepalive via sockopt after connect does work, but would not address any subsequently created flows.
Fortunately, the fix here is straight-forward: set SOCK_KEEPOPEN on the subflow when calling sync_socket_options.
The fix was valdidated both by using tcpdump to observe keepalive packets not being sent before the fix, and being sent after the fix. It was also possible to observe via ss that the keepalive timer was not enabled on these sockets before the fix, but was enabled afterwards.
--- net/mptcp/sockopt.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
net/mptcp/sockopt.c +5 -6
@@ -1508,13 +1508,12 @@ static void sync_socket_options(struct m {static const unsigned int tx_rx_locks =SOCK_RCVBUF_LOCK |SOCK_SNDBUF_LOCK ;struct sock *sk = (struct sock *)msk; +bool keep_open; -if (ssk->sk_prot->keepalive) { -if (sock_flag (sk,SOCK_KEEPOPEN )) - ssk->sk_prot->keepalive (ssk,1 ); -else - ssk->sk_prot->keepalive (ssk,0 ); - } + keep_open =sock_flag (sk,SOCK_KEEPOPEN ); +if (ssk->sk_prot->keepalive) + ssk->sk_prot->keepalive (ssk, keep_open); +sock_valbool_flag (ssk,SOCK_KEEPOPEN , keep_open); ssk->sk_priority = sk->sk_priority; ssk->sk_bound_dev_if = sk->sk_bound_dev_if;
Greg Kroah-Hartman
maintainerPATCH 54/189 doc: mptcp: net.mptcp.pm_type is deprecated
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthieu Baerts (NGI0) <[email protected]>
commit 6f021e95d0828edc8ed104a294594c2f9569383a upstream.
The net.mptcp.pm_type sysctl knob has been deprecated in v6.15, net.mptcp.path_manager should be used instead.
Adapt the section about path managers to suggest using the new sysctl knob instead of the deprecated one.
--- Documentation/networking/mptcp.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
Documentation/networking/mptcp.rst +4 -4
@@ -60,10 +60,10 @@ address announcements. Typically, it is and the server side that announces additional addresses via the ``ADD_ADDR`` and ``REMOVE_ADDR`` options. -Path managers are controlled by the ``net.mptcp.pm_type`` sysctl knob -- see -mptcp-sysctl.rst. There are two types: the in-kernel one (type ``0``) where the -same rules are applied for all the connections (see: ``ip mptcp``) ; and the -userspace one (type ``1``), controlled by a userspace daemon (i.e. `mptcpd +Path managers are controlled by the ``net.mptcp.path_manager`` sysctl knob -- +see mptcp-sysctl.rst. There are two types: the in-kernel one (``kernel``) where +the same rules are applied for all the connections (see: ``ip mptcp``) ; and the +userspace one (``userspace``), controlled by a userspace daemon (i.e. `mptcpd <https://mptcpd.mptcp.dev/>`_) where different rules can be applied for each connection. The path managers can be controlled via a Netlink API; see netlink_spec/mptcp_pm.rst.
Greg Kroah-Hartman
maintainerPATCH 55/189 netlink: specs: mptcp: fix if-idx attribute type
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthieu Baerts (NGI0) <[email protected]>
commit 7094b84863e5832cb1cd9c4b9d648904775b6bd9 upstream.
This attribute is used as a signed number in the code in pm_netlink.c:
nla_put_s32(skb, MPTCP_ATTR_IF_IDX, ssk->sk_bound_dev_if))
The specs should then reflect that. Note that other 'if-idx' attributes from the same .yaml file use a signed number as well.
--- Documentation/netlink/specs/mptcp_pm.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Documentation/netlink/specs/mptcp_pm.yaml +1 -1
@@ -256,7 +256,7 @@ attribute-sets: type: u32 - name: if-idx - type: u32 + type: s32 - name: reset-reason type: u32
Greg Kroah-Hartman
maintainerPATCH 56/189 ocfs2: fix recursive semaphore deadlock in fiemap call
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Tinguely <[email protected]>
commit 04100f775c2ea501927f508f17ad824ad1f23c8d upstream.
syzbot detected a OCFS2 hang due to a recursive semaphore on a FS_IOC_FIEMAP of the extent list on a specially crafted mmap file.
context_switch kernel/sched/core.c:5357 [inline] __schedule+0x1798/0x4cc0 kernel/sched/core.c:6961 __schedule_loop kernel/sched/core.c:7043 [inline] schedule+0x165/0x360 kernel/sched/core.c:7058 schedule_preempt_disabled+0x13/0x30 kernel/sched/core.c:7115 rwsem_down_write_slowpath+0x872/0xfe0 kernel/locking/rwsem.c:1185 __down_write_common kernel/locking/rwsem.c:1317 [inline] __down_write kernel/locking/rwsem.c:1326 [inline] down_write+0x1ab/0x1f0 kernel/locking/rwsem.c:1591 ocfs2_page_mkwrite+0x2ff/0xc40 fs/ocfs2/mmap.c:142 do_page_mkwrite+0x14d/0x310 mm/memory.c:3361 wp_page_shared mm/memory.c:3762 [inline] do_wp_page+0x268d/0x5800 mm/memory.c:3981 handle_pte_fault mm/memory.c:6068 [inline] __handle_mm_fault+0x1033/0x5440 mm/memory.c:6195 handle_mm_fault+0x40a/0x8e0 mm/memory.c:6364 do_user_addr_fault+0x764/0x1390 arch/x86/mm/fault.c:1387 handle_page_fault arch/x86/mm/fault.c:1476 [inline] exc_page_fault+0x76/0xf0 arch/x86/mm/fault.c:1532 asm_exc_page_fault+0x26/0x30 arch/x86/include/asm/idtentry.h:623 RIP: 0010:copy_user_generic arch/x86/include/asm/uaccess_64.h:126 [inline] RIP: 0010:raw_copy_to_user arch/x86/include/asm/uaccess_64.h:147 [inline] RIP: 0010:_inline_copy_to_user include/linux/uaccess.h:197 [inline] RIP: 0010:_copy_to_user+0x85/0xb0 lib/usercopy.c:26 Code: e8 00 bc f7 fc 4d 39 fc 72 3d 4d 39 ec 77 38 e8 91 b9 f7 fc 4c 89
f7 89 de e8 47 25 5b fd 0f 01 cb 4c 89 ff 48 89 d9 4c 89 f6 <f3> a4 0f 1f 00 48 89 cb 0f 01 ca 48 89 d8 5b 41 5c 41 5d 41 5e 41
RSP: 0018:ffffc9000403f950 EFLAGS: 00050256
RAX: ffffffff84c7f101 RBX: 0000000000000038 RCX: 0000000000000038
RDX: 0000000000000000 RSI: ffffc9000403f9e0 RDI: 0000200000000060
RBP: ffffc9000403fa90 R08: ffffc9000403fa17 R09: 1ffff92000807f42
R10: dffffc0000000000 R11: fffff52000807f43 R12: 0000200000000098
R13: 00007ffffffff000 R14: ffffc9000403f9e0 R15: 0000200000000060
copy_to_user include/linux/uaccess.h:225 [inline] fiemap_fill_next_extent+0x1c0/0x390 fs/ioctl.c:145 ocfs2_fiemap+0x888/0xc90 fs/ocfs2/extent_map.c:806 ioctl_fiemap fs/ioctl.c:220 [inline] do_vfs_ioctl+0x1173/0x1430 fs/ioctl.c:532 __do_sys_ioctl fs/ioctl.c:596 [inline] __se_sys_ioctl+0x82/0x170 fs/ioctl.c:584 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f5f13850fd9 RSP: 002b:00007ffe3b3518b8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 0000200000000000 RCX: 00007f5f13850fd9 RDX: 0000200000000040 RSI: 00000000c020660b RDI: 0000000000000004 RBP: 6165627472616568 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 00007ffe3b3518f0 R13: 00007ffe3b351b18 R14: 431bde82d7b634db R15: 00007f5f1389a03b
ocfs2_fiemap() takes a read lock of the ip_alloc_sem semaphore (since v2.6.22-527-g7307de80510a) and calls fiemap_fill_next_extent() to read the extent list of this running mmap executable. The user supplied buffer to hold the fiemap information page faults calling ocfs2_page_mkwrite() which will take a write lock (since v2.6.27-38-g00dc417fa3e7) of the same semaphore. This recursive semaphore will hold filesystem locks and causes a hang of the fileystem.
The ip_alloc_sem protects the inode extent list and size. Release the read semphore before calling fiemap_fill_next_extent() in ocfs2_fiemap() and ocfs2_fiemap_inline(). This does an unnecessary semaphore lock/unlock on the last extent but simplifies the error path.
--- fs/ocfs2/extent_map.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
fs/ocfs2/extent_map.c +9 -1
@@ -706,6 +706,8 @@ out:* it not only handles the fiemap for inlined files, but also deals * with the fast symlink, cause they have no difference for extent * mapping per se. +* +* Must be called with ip_alloc_sem semaphore held. */ static int ocfs2_fiemap_inline(struct inode *inode, struct buffer_head *di_bh, struct fiemap_extent_info *fieinfo,
@@ -717,6 +719,7 @@ static int ocfs2_fiemap_inline(struct inu64 phys;u32 flags =FIEMAP_EXTENT_DATA_INLINE |FIEMAP_EXTENT_LAST ;struct ocfs2_inode_info *oi =OCFS2_I (inode); +lockdep_assert_held_read (&oi->ip_alloc_sem); di = (struct ocfs2_dinode *)di_bh->b_data;if (ocfs2_inode_is_fast_symlink (inode))
@@ -732,8 +735,11 @@ static int ocfs2_fiemap_inline(struct in phys += offsetof(struct ocfs2_dinode , id2.i_data.id_data); +/* Release the ip_alloc_sem to prevent deadlock on page fault */ +up_read (&OCFS2_I (inode)->ip_alloc_sem); ret =fiemap_fill_next_extent (fieinfo,0 , phys, id_count, flags); +down_read (&OCFS2_I (inode)->ip_alloc_sem);if (ret <0 )return ret; }
@@ -802,9 +808,11 @@ int ocfs2_fiemap(struct inode *inode, st len_bytes = (u64 )le16_to_cpu (rec.e_leaf_clusters) << osb->s_clustersize_bits; phys_bytes =le64_to_cpu (rec.e_blkno) << osb->sb->s_blocksize_bits; virt_bytes = (u64 )le32_to_cpu (rec.e_cpos) << osb->s_clustersize_bits; - +/* Release the ip_alloc_sem to prevent deadlock on page fault */ +up_read (&OCFS2_I (inode)->ip_alloc_sem); ret =fiemap_fill_next_extent (fieinfo, virt_bytes, phys_bytes, len_bytes, fe_flags); +down_read (&OCFS2_I (inode)->ip_alloc_sem);if (ret)break ;
Greg Kroah-Hartman
maintainerPATCH 57/189 btrfs: fix squota compressed stats leak
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Boris Burkov <[email protected]>
commit de134cb54c3a67644ff95b1c9bffe545e752c912 upstream.
The following workload on a squota enabled fs:
btrfs subvol create mnt/subvol
# ensure subvol extents get accounted sync btrfs qgroup create 1/1 mnt btrfs qgroup assign mnt/subvol 1/1 mnt btrfs qgroup delete mnt/subvol
# make the cleaner thread run btrfs filesystem sync mnt sleep 1 btrfs filesystem sync mnt btrfs qgroup destroy 1/1 mnt
will fail with EBUSY. The reason is that 1/1 does the quick accounting when we assign subvol to it, gaining its exclusive usage as excl and excl_cmpr. But then when we delete subvol, the decrement happens via record_squota_delta() which does not update excl_cmpr, as squotas does not make any distinction between compressed and normal extents. Thus, we increment excl_cmpr but never decrement it, and are unable to delete 1/1. The two possible fixes are to make squota always mirror excl and excl_cmpr or to make the fast accounting separately track the plain and cmpr numbers. The latter felt cleaner to me so that is what I opted for.
--- fs/btrfs/qgroup.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
fs/btrfs/qgroup.c +4 -2
@@ -1483,6 +1483,7 @@ static int __qgroup_excl_accounting(strustruct btrfs_qgroup *qgroup;LIST_HEAD (qgroup_list);u64 num_bytes = src->excl; +u64 num_bytes_cmpr = src->excl_cmpr;int ret =0 ; qgroup =find_qgroup_rb (fs_info, ref_root);
@@ -1494,11 +1495,12 @@ static int __qgroup_excl_accounting(strustruct btrfs_qgroup_list *glist; qgroup->rfer += sign * num_bytes; - qgroup->rfer_cmpr += sign * num_bytes; + qgroup->rfer_cmpr += sign * num_bytes_cmpr;WARN_ON (sign <0 && qgroup->excl < num_bytes); +WARN_ON (sign <0 && qgroup->excl_cmpr < num_bytes_cmpr); qgroup->excl += sign * num_bytes; - qgroup->excl_cmpr += sign * num_bytes; + qgroup->excl_cmpr += sign * num_bytes_cmpr;if (sign >0 )qgroup_rsv_add_by_qgroup (fs_info, qgroup, src);
Greg Kroah-Hartman
maintainerPATCH 58/189 btrfs: fix subvolume deletion lockup caused by inodes xarray race
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Omar Sandoval <[email protected]>
commit f6a6c280059c4ddc23e12e3de1b01098e240036f upstream.
There is a race condition between inode eviction and inode caching that can cause a live struct btrfs_inode to be missing from the root->inodes xarray. Specifically, there is a window during evict() between the inode being unhashed and deleted from the xarray. If btrfs_iget() is called for the same inode in that window, it will be recreated and inserted into the xarray, but then eviction will delete the new entry, leaving nothing in the xarray:
Thread 1 Thread 2
---------------------------------------------------------------evict()
remove_inode_hash()
btrfs_iget_path()
btrfs_iget_locked() btrfs_read_locked_inode()
btrfs_add_inode_to_root()
destroy_inode()
btrfs_destroy_inode()
btrfs_del_inode_from_root()
__xa_eraseIn turn, this can cause issues for subvolume deletion. Specifically, if an inode is in this lost state, and all other inodes are evicted, then btrfs_del_inode_from_root() will call btrfs_add_dead_root() prematurely. If the lost inode has a delayed_node attached to it, then when btrfs_clean_one_deleted_snapshot() calls btrfs_kill_all_delayed_nodes(), it will loop forever because the delayed_nodes xarray will never become empty (unless memory pressure forces the inode out). We saw this manifest as soft lockups in production.
Fix it by only deleting the xarray entry if it matches the given inode (using __xa_cmpxchg()).
--- fs/btrfs/inode.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
fs/btrfs/inode.c +11 -1
@@ -5685,7 +5685,17 @@ static void btrfs_del_inode_from_root(stbool empty = false;xa_lock (&root->inodes); - entry =__xa_erase (&root->inodes,btrfs_ino (inode)); +/* +* This btrfs_inode is being freed and has already been unhashed at this +* point. It's possible that another btrfs_inode has already been +* allocated for the same inode and inserted itself into the root, so +* don't delete it in that case. +* +* Note that this shouldn't need to allocate memory, so the gfp flags +* don't really matter. +*/ + entry =__xa_cmpxchg (&root->inodes,btrfs_ino (inode), inode,NULL , +GFP_ATOMIC );if (entry == inode) empty =xa_empty (&root->inodes);xa_unlock (&root->inodes);
Greg Kroah-Hartman
maintainerPATCH 59/189 i2c: i801: Hide Intel Birch Stream SoC TCO WDT
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chiasheng Lee <[email protected]>
commit 664596bd98bb251dd417dfd3f9b615b661e1e44a upstream.
Hide the Intel Birch Stream SoC TCO WDT feature since it was removed.
On platforms with PCH TCO WDT, this redundant device might be rendering errors like this:
[ 28.144542] sysfs: cannot create duplicate filename '/bus/platform/devices/iTCO_wdt'
--- drivers/i2c/busses/i2c-i801.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/i2c/busses/i2c-i801.c +1 -1
@@ -1052,7 +1052,7 @@ static const struct pci_device_id i801_i { PCI_DEVICE_DATA(INTEL, METEOR_LAKE_P_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, { PCI_DEVICE_DATA(INTEL, METEOR_LAKE_SOC_S_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, { PCI_DEVICE_DATA(INTEL, METEOR_LAKE_PCH_S_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, - { PCI_DEVICE_DATA(INTEL, BIRCH_STREAM_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, + { PCI_DEVICE_DATA(INTEL, BIRCH_STREAM_SMBUS, FEATURES_ICH5) }, { PCI_DEVICE_DATA(INTEL, ARROW_LAKE_H_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, { PCI_DEVICE_DATA(INTEL, PANTHER_LAKE_H_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, { PCI_DEVICE_DATA(INTEL, PANTHER_LAKE_P_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) },
Greg Kroah-Hartman
maintainerPATCH 60/189 i2c: rtl9300: ensure data length is within supported range
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Jelonek <[email protected]>
commit 06418cb5a1a542a003fdb4ad8e76ea542d57cfba upstream.
Add an explicit check for the xfer length to 'rtl9300_i2c_config_xfer' to ensure the data length isn't within the supported range. In particular a data length of 0 is not supported by the hardware and causes unintended or destructive behaviour.
This limitation becomes obvious when looking at the register documentation [1]. 4 bits are reserved for DATA_WIDTH and the value of these 4 bits is used as N + 1, allowing a data length range of 1 <= len <= 16.
Affected by this is the SMBus Quick Operation which works with a data length of 0. Passing 0 as the length causes an underflow of the value due to:
(len - 1) & 0xf
and effectively specifying a transfer length of 16 via the registers. This causes a 16-byte write operation instead of a Quick Write. For example, on SFP modules without write-protected EEPROM this soft-bricks them by overwriting some initial bytes.
For completeness, also add a quirk for the zero length.
[1] https://svanheule.net/realtek/longan/register/i2c_mst1_ctrl2
--- drivers/i2c/busses/i2c-rtl9300.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/i2c/busses/i2c-rtl9300.c +4 -1
@@ -99,6 +99,9 @@ static int rtl9300_i2c_config_xfer(struc {u32 val, mask; +if (len <1 || len >16 ) +return -EINVAL ; + val = chan->bus_freq <<RTL9300_I2C_MST_CTRL2_SCL_FREQ_OFS ; mask =RTL9300_I2C_MST_CTRL2_SCL_FREQ_MASK ;
@@ -323,7 +326,7 @@ static const struct i2c_algorithm rtl930 };static struct i2c_adapter_quirks rtl9300_i2c_quirks = { - .flags =I2C_AQ_NO_CLK_STRETCH , + .flags =I2C_AQ_NO_CLK_STRETCH |I2C_AQ_NO_ZERO_LEN , .max_read_len =16 , .max_write_len =16 , };
Greg Kroah-Hartman
maintainerPATCH 61/189 i2c: rtl9300: remove broken SMBus Quick operation support
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Jelonek <[email protected]>
commit ede965fd555ac2536cf651893a998dbfd8e57b86 upstream.
Remove the SMBus Quick operation from this driver because it is not natively supported by the hardware and is wrongly implemented in the driver.
The I2C controllers in Realtek RTL9300 and RTL9310 are SMBus-compliant but there doesn't seem to be native support for the SMBus Quick operation. It is not explicitly mentioned in the documentation but looking at the registers which configure an SMBus transaction, one can see that the data length cannot be set to 0. This suggests that the hardware doesn't allow any SMBus message without data bytes (except for those it does on it's own, see SMBus Block Read).
The current implementation of SMBus Quick operation passes a length of 0 (which is actually invalid). Before the fix of a bug in a previous commit, this led to a read operation of 16 bytes from any register (the one of a former transaction or any other value.
This caused issues like soft-bricked SFP modules after a simple probe with i2cdetect which uses Quick by default. Running this with SFP modules whose EEPROM isn't write-protected, some of the initial bytes are overwritten because a 16-byte write operation is executed instead of a Quick Write. (This temporarily soft-bricked one of my DAC cables.)
Because SMBus Quick operation is obviously not supported on these controllers (because a length of 0 cannot be set, even when no register address is set), remove that instead of claiming there is support. There also shouldn't be any kind of emulated 'Quick' which just does another kind of operation in the background. Otherwise, specific issues occur in case of a 'Quick' Write which actually writes unknown data to an unknown register.
--- drivers/i2c/busses/i2c-rtl9300.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-)
drivers/i2c/busses/i2c-rtl9300.c +3 -12
@@ -225,15 +225,6 @@ static int rtl9300_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr, unsigned s }switch (size) { -case I2C_SMBUS_QUICK : - ret =rtl9300_i2c_config_xfer (i2c, chan, addr,0 ); -if (ret) - goto out_unlock; - ret =rtl9300_i2c_reg_addr_set (i2c,0 ,0 ); -if (ret) - goto out_unlock; -break ; -case I2C_SMBUS_BYTE :if (read_write ==I2C_SMBUS_WRITE ) { ret =rtl9300_i2c_config_xfer (i2c, chan, addr,0 );
@@ -315,9 +306,9 @@ static int rtl9300_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr, unsigned sstatic u32 rtl9300_i2c_func (struct i2c_adapter *a) { -return I2C_FUNC_SMBUS_QUICK |I2C_FUNC_SMBUS_BYTE | -I2C_FUNC_SMBUS_BYTE_DATA |I2C_FUNC_SMBUS_WORD_DATA | -I2C_FUNC_SMBUS_BLOCK_DATA ; +return I2C_FUNC_SMBUS_BYTE |I2C_FUNC_SMBUS_BYTE_DATA | +I2C_FUNC_SMBUS_WORD_DATA |I2C_FUNC_SMBUS_BLOCK_DATA | +I2C_FUNC_SMBUS_I2C_BLOCK ; }static const struct i2c_algorithm rtl9300_i2c_algo = {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 62/189 net: libwx: fix to enable RSS
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiawen Wu <[email protected]>
commit 157cf360c4a8751f7f511a71cc3a283b5d27f889 upstream.
Now when SRIOV is enabled, PF with multiple queues can only receive all packets on queue 0. This is caused by an incorrect flag judgement, which prevents RSS from being enabled.
In fact, RSS is supported for the functions when SRIOV is enabled. Remove the flag judgement to fix it.
--- drivers/net/ethernet/wangxun/libwx/wx_hw.c | 4 ---- 1 file changed, 4 deletions(-)
drivers/net/ethernet/wangxun/libwx/wx_hw.c +0 -4
@@ -2071,10 +2071,6 @@ static void wx_setup_mrqc(struct wx *wx) {u32 rss_field =0 ; -/* VT, and RSS do not coexist at the same time */ -if (test_bit (WX_FLAG_VMDQ_ENABLED , wx->flags)) -return ; -/* Disable indicating checksum in descriptor, enables RSS hash */ wr32m (wx,WX_PSR_CTL ,WX_PSR_CTL_PCSD ,WX_PSR_CTL_PCSD );
Greg Kroah-Hartman
maintainerPATCH 63/189 net: usb: asix: ax88772: drop phylink use in PM to avoid MDIO runtime PM wakeups
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oleksij Rempel <[email protected]>
commit 5537a4679403423e0b49c95b619983a4583d69c5 upstream.
Drop phylink_{suspend,resume}() from ax88772 PM callbacks.
MDIO bus accesses have their own runtime-PM handling and will try to wake the device if it is suspended. Such wake attempts must not happen from PM callbacks while the device PM lock is held. Since phylink {sus|re}sume may trigger MDIO, it must not be called in PM context.
No extra phylink PM handling is required for this driver:
- .ndo_open/.ndo_stop control the phylink start/stop lifecycle.
- ethtool/phylib entry points run in process context, not PM.
- phylink MAC ops program the MAC on link changes after resume.
--- drivers/net/usb/asix_devices.c | 13 ------------- 1 file changed, 13 deletions(-)
drivers/net/usb/asix_devices.c +0 -13
@@ -607,15 +607,8 @@ static const struct net_device_ops ax887static void ax88772_suspend (struct usbnet *dev) { -struct asix_common_private *priv = dev->driver_priv;u16 medium; -if (netif_running (dev->net)) { -rtnl_lock (); -phylink_suspend (priv->phylink, false); -rtnl_unlock (); - } -/* Stop MAC operation */ medium =asix_read_medium_status (dev,1 ); medium &= ~AX_MEDIUM_RE ;
@@ -644,12 +637,6 @@ static void ax88772_resume(struct usbnetfor (i =0 ; i <3 ; i++)if (!priv->reset (dev,1 ))break ; - -if (netif_running (dev->net)) { -rtnl_lock (); -phylink_resume (priv->phylink); -rtnl_unlock (); - } }static int asix_resume (struct usb_interface *intf)
Greg Kroah-Hartman
maintainerPATCH 64/189 PM: EM: Add function for registering a PD without capacity update
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rafael J. Wysocki <[email protected]>
commit e0423541477dfb684fbc6e6b5386054bc650f264 upstream.
The intel_pstate driver manages CPU capacity changes itself and it does not need an update of the capacity of all CPUs in the system to be carried out after registering a PD.
Moreover, in some configurations (for instance, an SMT-capable hybrid x86 system booted with nosmt in the kernel command line) the em_check_capacity_update() call at the end of em_dev_register_perf_domain() always fails and reschedules itself to run once again in 1 s, so effectively it runs in vain every 1 s forever.
To address this, introduce a new variant of em_dev_register_perf_domain(), called em_dev_register_pd_no_update(), that does not invoke em_check_capacity_update(), and make intel_pstate use it instead of the original.
--- drivers/cpufreq/intel_pstate.c | 4 ++-- include/linux/energy_model.h | 10 ++++++++++ kernel/power/energy_model.c | 29 +++++++++++++++++++++++++---- 3 files changed, 37 insertions(+), 6 deletions(-)
drivers/cpufreq/intel_pstate.c +2 -2
@@ -1034,8 +1034,8 @@ static bool hybrid_register_perf_domain(unsigned int cpu)if (!cpu_dev)return false; -if (em_dev_register_perf_domain (cpu_dev,HYBRID_EM_STATE_COUNT , &cb, -cpumask_of (cpu), false)) +if (em_dev_register_pd_no_update (cpu_dev,HYBRID_EM_STATE_COUNT , &cb, +cpumask_of (cpu), false))return false; cpudata->pd_registered = true;
include/linux/energy_model.h +10 -0
@@ -171,6 +171,9 @@ int em_dev_update_perf_domain(struct device *dev,int em_dev_register_perf_domain (struct device *dev,unsigned int nr_states,const struct em_data_callback *cb,const cpumask_t *cpus,bool microwatts); +int em_dev_register_pd_no_update (struct device *dev,unsigned int nr_states, +const struct em_data_callback *cb, +const cpumask_t *cpus,bool microwatts);void em_dev_unregister_perf_domain (struct device *dev);struct em_perf_table *em_table_alloc (struct em_perf_domain *pd);void em_table_free (struct em_perf_table *table);
@@ -350,6 +353,13 @@ int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states, {return -EINVAL ; } +static inline +int em_dev_register_pd_no_update (struct device *dev,unsigned int nr_states, +const struct em_data_callback *cb, +const cpumask_t *cpus,bool microwatts) +{ +return -EINVAL ; +}static inline void em_dev_unregister_perf_domain (struct device *dev) { }
kernel/power/energy_model.c +25 -4
@@ -552,6 +552,30 @@ EXPORT_SYMBOL_GPL(em_cpu_get);int em_dev_register_perf_domain (struct device *dev,unsigned int nr_states,const struct em_data_callback *cb,const cpumask_t *cpus,bool microwatts) +{ +int ret =em_dev_register_pd_no_update (dev, nr_states, cb, cpus, microwatts); + +if (_is_cpu_device (dev)) +em_check_capacity_update (); + +return ret; +} +EXPORT_SYMBOL_GPL (em_dev_register_perf_domain); + +/** +* em_dev_register_pd_no_update() - Register a perf domain for a device +* @dev : Device to register the PD for +* @nr_states : Number of performance states in the new PD +* @cb : Callback functions for populating the energy model +* @cpus : CPUs to include in the new PD (mandatory if @dev is a CPU device) +* @microwatts : Whether or not the power values in the EM will be in uW +* +* Like em_dev_register_perf_domain(), but does not trigger a CPU capacity +* update after registering the PD, even if @dev is a CPU device. +*/ +int em_dev_register_pd_no_update (struct device *dev,unsigned int nr_states, +const struct em_data_callback *cb, +const cpumask_t *cpus,bool microwatts) {struct em_perf_table *em_table;unsigned long cap, prev_cap =0 ;
@@ -636,12 +660,9 @@ int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states, unlock:mutex_unlock (&em_pd_mutex); -if (_is_cpu_device (dev)) -em_check_capacity_update (); -return ret; } -EXPORT_SYMBOL_GPL (em_dev_register_perf_domain); +EXPORT_SYMBOL_GPL (em_dev_register_pd_no_update);/** * em_dev_unregister_perf_domain() - Unregister Energy Model (EM) for a device
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 65/189 PM: hibernate: Restrict GFP mask in hibernation_snapshot()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rafael J. Wysocki <[email protected]>
commit 449c9c02537a146ac97ef962327a221e21c9cab3 upstream.
Commit 12ffc3b1513e ("PM: Restrict swap use to later in the suspend sequence") incorrectly removed a pm_restrict_gfp_mask() call from hibernation_snapshot(), so memory allocations involving swap are not prevented from being carried out in this code path any more which may lead to serious breakage.
The symptoms of such breakage have become visible after adding a shrink_shmem_memory() call to hibernation_snapshot() in commit 2640e819474f ("PM: hibernate: shrink shmem pages after dev_pm_ops.prepare()") which caused this problem to be much more likely to manifest itself.
However, since commit 2640e819474f was initially present in the DRM tree that did not include commit 12ffc3b1513e, the symptoms of this issue were not visible until merge commit 260f6f4fda93 ("Merge tag 'drm-next-2025-07-30' of https://gitlab.freedesktop.org/drm/kernel")
that exposed it through an entirely reasonable merge conflict resolution.
--- kernel/power/hibernate.c | 1 + 1 file changed, 1 insertion(+)
kernel/power/hibernate.c +1 -0
@@ -423,6 +423,7 @@ int hibernation_snapshot(int platform_mo }console_suspend_all (); +pm_restrict_gfp_mask (); error =dpm_suspend (PMSG_FREEZE );
Greg Kroah-Hartman
maintainerPATCH 66/189 wifi: iwlwifi: fix 130/1030 configs
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <[email protected]>
commit 2682e7a317504a9d81cbb397249d4299e84dfadd upstream.
The 130/1030 devices are really derivatives of 6030, with some small differences not pertaining to the MAC, so they must use the 6030 MAC config.
--- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-)
drivers/net/wireless/intel/iwlwifi/pcie/drv.c +13 -13
@@ -124,13 +124,13 @@ VISIBLE_IF_IWLWIFI_KUNIT const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x0082, 0x1304, iwl6005_mac_cfg)},/* low 5GHz active */ {IWL_PCI_DEVICE(0x0082, 0x1305, iwl6005_mac_cfg)},/* high 5GHz active */ -/* 6x30 Series */ - {IWL_PCI_DEVICE(0x008A, 0x5305, iwl1000_mac_cfg)}, - {IWL_PCI_DEVICE(0x008A, 0x5307, iwl1000_mac_cfg)}, - {IWL_PCI_DEVICE(0x008A, 0x5325, iwl1000_mac_cfg)}, - {IWL_PCI_DEVICE(0x008A, 0x5327, iwl1000_mac_cfg)}, - {IWL_PCI_DEVICE(0x008B, 0x5315, iwl1000_mac_cfg)}, - {IWL_PCI_DEVICE(0x008B, 0x5317, iwl1000_mac_cfg)}, +/* 1030/6x30 Series */ + {IWL_PCI_DEVICE(0x008A, 0x5305, iwl6030_mac_cfg)}, + {IWL_PCI_DEVICE(0x008A, 0x5307, iwl6030_mac_cfg)}, + {IWL_PCI_DEVICE(0x008A, 0x5325, iwl6030_mac_cfg)}, + {IWL_PCI_DEVICE(0x008A, 0x5327, iwl6030_mac_cfg)}, + {IWL_PCI_DEVICE(0x008B, 0x5315, iwl6030_mac_cfg)}, + {IWL_PCI_DEVICE(0x008B, 0x5317, iwl6030_mac_cfg)}, {IWL_PCI_DEVICE(0x0090, 0x5211, iwl6030_mac_cfg)}, {IWL_PCI_DEVICE(0x0090, 0x5215, iwl6030_mac_cfg)}, {IWL_PCI_DEVICE(0x0090, 0x5216, iwl6030_mac_cfg)},
@@ -181,12 +181,12 @@ VISIBLE_IF_IWLWIFI_KUNIT const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x08AE, 0x1027, iwl1000_mac_cfg)},/* 130 Series WiFi */ - {IWL_PCI_DEVICE(0x0896, 0x5005, iwl1000_mac_cfg)}, - {IWL_PCI_DEVICE(0x0896, 0x5007, iwl1000_mac_cfg)}, - {IWL_PCI_DEVICE(0x0897, 0x5015, iwl1000_mac_cfg)}, - {IWL_PCI_DEVICE(0x0897, 0x5017, iwl1000_mac_cfg)}, - {IWL_PCI_DEVICE(0x0896, 0x5025, iwl1000_mac_cfg)}, - {IWL_PCI_DEVICE(0x0896, 0x5027, iwl1000_mac_cfg)}, + {IWL_PCI_DEVICE(0x0896, 0x5005, iwl6030_mac_cfg)}, + {IWL_PCI_DEVICE(0x0896, 0x5007, iwl6030_mac_cfg)}, + {IWL_PCI_DEVICE(0x0897, 0x5015, iwl6030_mac_cfg)}, + {IWL_PCI_DEVICE(0x0897, 0x5017, iwl6030_mac_cfg)}, + {IWL_PCI_DEVICE(0x0896, 0x5025, iwl6030_mac_cfg)}, + {IWL_PCI_DEVICE(0x0896, 0x5027, iwl6030_mac_cfg)},/* 2x00 Series */ {IWL_PCI_DEVICE(0x0890, 0x4022, iwl2000_mac_cfg)},
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 67/189 s390: kexec: initialize kexec_buf struct
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao <[email protected]>
commit e67f0bd05519012eaabaae68618ffc4ed30ab680 upstream.
The kexec_buf structure was previously declared without initialization. commit bf454ec31add ("kexec_file: allow to place kexec_buf randomly") added a field that is always read but not consistently populated by all architectures. This un-initialized field will contain garbage.
This is also triggering a UBSAN warning when the uninitialized data was accessed:
------------[ cut here ]------------ UBSAN: invalid-load in ./include/linux/kexec.h:210:10 load of value 252 is not a valid value for type '_Bool'
Zero-initializing kexec_buf at declaration ensures all fields are cleanly set, preventing future instances of uninitialized memory being used.
--- arch/s390/kernel/kexec_elf.c | 2 +- arch/s390/kernel/kexec_image.c | 2 +- arch/s390/kernel/machine_kexec_file.c | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-)
arch/s390/kernel/kexec_elf.c +1 -1
@@ -16,7 +16,7 @@static int kexec_file_add_kernel_elf (struct kimage *image,struct s390_load_data *data) { -struct kexec_buf buf; +struct kexec_buf buf = {};const Elf_Ehdr *ehdr;const Elf_Phdr *phdr;Elf_Addr entry;
arch/s390/kernel/kexec_image.c +1 -1
@@ -16,7 +16,7 @@static int kexec_file_add_kernel_image (struct kimage *image,struct s390_load_data *data) { -struct kexec_buf buf; +struct kexec_buf buf = {}; buf.image = image;
arch/s390/kernel/machine_kexec_file.c +3 -3
@@ -129,7 +129,7 @@ static int kexec_file_update_purgatory(struct kimage *image,static int kexec_file_add_purgatory (struct kimage *image,struct s390_load_data *data) { -struct kexec_buf buf; +struct kexec_buf buf = {};int ret; buf.image = image;
@@ -152,7 +152,7 @@ static int kexec_file_add_purgatory(struct kimage *image,static int kexec_file_add_initrd (struct kimage *image,struct s390_load_data *data) { -struct kexec_buf buf; +struct kexec_buf buf = {};int ret; buf.image = image;
@@ -184,7 +184,7 @@ static int kexec_file_add_ipl_report(struct kimage *image, {__u32 *lc_ipl_parmblock_ptr;unsigned int len, ncerts; -struct kexec_buf buf; +struct kexec_buf buf = {};unsigned long addr;void *ptr, *end;int ret;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 68/189 smb: client: fix compound alignment with encryption
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paulo Alcantara <[email protected]>
commit 90f7c100d2dd99d5cd5be950d553edd2647e6cc8 upstream.
The encryption layer can't handle the padding iovs, so flatten the compound request into a single buffer with required padding to prevent the server from dropping the connection when finding unaligned compound requests.
--- fs/smb/client/smb2ops.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-)
fs/smb/client/smb2ops.c +25 -3
@@ -2640,13 +2640,35 @@ smb2_set_next_command(struct cifs_tcon * }/* SMB headers in a compound are 8 byte aligned. */ -if (!IS_ALIGNED (len,8 )) { - num_padding =8 - (len &7 ); +if (IS_ALIGNED (len,8 )) + goto out; + + num_padding =8 - (len &7 ); +if (smb3_encryption_required (tcon)) { +int i; + +/* +* Flatten request into a single buffer with required padding as +* the encryption layer can't handle the padding iovs. +*/ +for (i =1 ; i < rqst->rq_nvec; i++) { +memcpy (rqst->rq_iov[0 ].iov_base + + rqst->rq_iov[0 ].iov_len, + rqst->rq_iov[i].iov_base, + rqst->rq_iov[i].iov_len); + rqst->rq_iov[0 ].iov_len += rqst->rq_iov[i].iov_len; + } +memset (rqst->rq_iov[0 ].iov_base + rqst->rq_iov[0 ].iov_len, +0 , num_padding); + rqst->rq_iov[0 ].iov_len += num_padding; + rqst->rq_nvec =1 ; + }else { rqst->rq_iov[rqst->rq_nvec].iov_base = smb2_padding; rqst->rq_iov[rqst->rq_nvec].iov_len = num_padding; rqst->rq_nvec++; - len += num_padding; } + len += num_padding; +out: shdr->NextCommand =cpu_to_le32 (len); }
Greg Kroah-Hartman
maintainerPATCH 69/189 smb: client: fix data loss due to broken rename(2)
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paulo Alcantara <[email protected]>
commit c5ea3065586d790ea5193a679b85585173d59866 upstream.
Rename of open files in SMB2+ has been broken for a very long time, resulting in data loss as the CIFS client would fail the rename(2) call with -ENOENT and then removing the target file.
Fix this by implementing ->rename_pending_delete() for SMB2+, which will rename busy files to random filenames (e.g. silly rename) during unlink(2) or rename(2), and then marking them to delete-on-close.
Besides, introduce a FIND_WR_NO_PENDING_DELETE flag to prevent open(2) from reusing open handles that had been marked as delete pending. Handle it in cifs_get_readable_path() as well.
--- fs/smb/client/cifsglob.h | 13 ++ fs/smb/client/file.c | 18 +++- fs/smb/client/inode.c | 86 +++++++++++++++---- fs/smb/client/smb2glob.h | 3 fs/smb/client/smb2inode.c | 204 ++++++++++++++++++++++++++++++++++++---------- fs/smb/client/smb2ops.c | 4 fs/smb/client/smb2proto.h | 3 fs/smb/client/trace.h | 9 -- 8 files changed, 268 insertions(+), 72 deletions(-)
fs/smb/client/cifsglob.h +9 -4
@@ -87,7 +87,7 @@#define SMB_INTERFACE_POLL_INTERVAL 600/* maximum number of PDUs in one compound */ -#define MAX_COMPOUND 7 +#define MAX_COMPOUND 10/* * Default number of credits to keep available for SMB3.
@@ -1877,9 +1877,12 @@ static inline bool is_replayable_error(i/* cifs_get_writable_file() flags */ -#define FIND_WR_ANY 0 -#define FIND_WR_FSUID_ONLY 1 -#define FIND_WR_WITH_DELETE 2 +enum cifs_writable_file_flags { +FIND_WR_ANY =0U , +FIND_WR_FSUID_ONLY = (1U <<0 ), +FIND_WR_WITH_DELETE = (1U <<1 ), +FIND_WR_NO_PENDING_DELETE = (1U <<2 ), +};#define MID_FREE 0#define MID_REQUEST_ALLOCATED 1
@@ -2339,6 +2342,8 @@ struct smb2_compound_vars {struct kvec qi_iov;struct kvec io_iov[SMB2_IOCTL_IOV_SIZE ];struct kvec si_iov[SMB2_SET_INFO_IOV_SIZE ]; +struct kvec unlink_iov[SMB2_SET_INFO_IOV_SIZE ]; +struct kvec rename_iov[SMB2_SET_INFO_IOV_SIZE ];struct kvec close_iov;struct smb2_file_rename_info_hdr rename_info;struct smb2_file_link_info_hdr link_info;
fs/smb/client/file.c +17 -1
@@ -998,7 +998,10 @@ int cifs_open(struct inode *inode, struc/* Get the cached handle as SMB2 close is deferred */ if (OPEN_FMODE (file->f_flags) &FMODE_WRITE ) { - rc =cifs_get_writable_path (tcon, full_path,FIND_WR_FSUID_ONLY , &cfile); + rc =cifs_get_writable_path (tcon, full_path, +FIND_WR_FSUID_ONLY | +FIND_WR_NO_PENDING_DELETE , + &cfile); }else { rc =cifs_get_readable_path (tcon, full_path, &cfile); }
@@ -2530,6 +2533,9 @@ refind_writable:continue ;if (with_delete && !(open_file->fid.access &DELETE ))continue ; +if ((flags &FIND_WR_NO_PENDING_DELETE ) && + open_file->status_file_deleted) +continue ;if (OPEN_FMODE (open_file->f_flags) &FMODE_WRITE ) {if (!open_file->invalidHandle) {/* found a good writable file */
@@ -2647,6 +2653,16 @@ cifs_get_readable_path(struct cifs_tconspin_unlock (&tcon->open_file_lock);free_dentry_path (page); *ret_file =find_readable_file (cinode,0 ); +if (*ret_file) { +spin_lock (&cinode->open_file_lock); +if ((*ret_file)->status_file_deleted) { +spin_unlock (&cinode->open_file_lock); +cifsFileInfo_put (*ret_file); + *ret_file =NULL ; + }else { +spin_unlock (&cinode->open_file_lock); + } + }return *ret_file ?0 : -ENOENT ; }
fs/smb/client/inode.c +69 -17
148 lines not on this page · raw message
fs/smb/client/smb2glob.h +1 -2
@@ -30,10 +30,9 @@ enum smb2_compound_ops {SMB2_OP_QUERY_DIR ,SMB2_OP_MKDIR ,SMB2_OP_RENAME , -SMB2_OP_DELETE ,SMB2_OP_HARDLINK ,SMB2_OP_SET_EOF , -SMB2_OP_RMDIR , +SMB2_OP_UNLINK ,SMB2_OP_POSIX_QUERY_INFO ,SMB2_OP_SET_REPARSE , SMB2_OP_GET_REPARSE,
fs/smb/client/smb2inode.c +162 -42
261 lines not on this page · raw message
fs/smb/client/smb2ops.c +4 -0
@@ -5399,6 +5399,7 @@ struct smb_version_operations smb20_oper .llseek = smb3_llseek, .is_status_io_timeout = smb2_is_status_io_timeout, .is_network_name_deleted = smb2_is_network_name_deleted, + .rename_pending_delete = smb2_rename_pending_delete, };#endif /* CIFS_ALLOW_INSECURE_LEGACY */
@@ -5504,6 +5505,7 @@ struct smb_version_operations smb21_oper .llseek = smb3_llseek, .is_status_io_timeout = smb2_is_status_io_timeout, .is_network_name_deleted = smb2_is_network_name_deleted, + .rename_pending_delete = smb2_rename_pending_delete, };struct smb_version_operations smb30_operations = {
@@ -5620,6 +5622,7 @@ struct smb_version_operations smb30_oper .llseek = smb3_llseek, .is_status_io_timeout = smb2_is_status_io_timeout, .is_network_name_deleted = smb2_is_network_name_deleted, + .rename_pending_delete = smb2_rename_pending_delete, };struct smb_version_operations smb311_operations = {
@@ -5736,6 +5739,7 @@ struct smb_version_operations smb311_ope .llseek = smb3_llseek, .is_status_io_timeout = smb2_is_status_io_timeout, .is_network_name_deleted = smb2_is_network_name_deleted, + .rename_pending_delete = smb2_rename_pending_delete, };#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
fs/smb/client/smb2proto.h +3 -0
@@ -320,5 +320,8 @@ int smb2_create_reparse_symlink(const unint smb2_make_nfs_node (unsigned int xid,struct inode *inode,struct dentry *dentry,struct cifs_tcon *tcon,const char *full_path,umode_t mode,dev_t dev); +int smb2_rename_pending_delete (const char *full_path, +struct dentry *dentry, +const unsigned int xid);#endif /* _SMB2PROTO_H */
fs/smb/client/trace.h +3 -6
@@ -669,13 +669,12 @@ DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(queDEFINE_SMB3_INF_COMPOUND_ENTER_EVENT (posix_query_info_compound_enter);DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT (hardlink_enter);DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT (rename_enter); -DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT (rmdir_enter); +DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT (unlink_enter);DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT (set_eof_enter);DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT (set_info_compound_enter);DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT (set_reparse_compound_enter);DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT (get_reparse_compound_enter);DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT (query_wsl_ea_compound_enter); -DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT (delete_enter);DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT (mkdir_enter);DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT (tdis_enter);DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT (mknod_enter);
@@ -710,13 +709,12 @@ DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(querDEFINE_SMB3_INF_COMPOUND_DONE_EVENT (posix_query_info_compound_done);DEFINE_SMB3_INF_COMPOUND_DONE_EVENT (hardlink_done);DEFINE_SMB3_INF_COMPOUND_DONE_EVENT (rename_done); -DEFINE_SMB3_INF_COMPOUND_DONE_EVENT (rmdir_done); +DEFINE_SMB3_INF_COMPOUND_DONE_EVENT (unlink_done);DEFINE_SMB3_INF_COMPOUND_DONE_EVENT (set_eof_done);DEFINE_SMB3_INF_COMPOUND_DONE_EVENT (set_info_compound_done);DEFINE_SMB3_INF_COMPOUND_DONE_EVENT (set_reparse_compound_done);DEFINE_SMB3_INF_COMPOUND_DONE_EVENT (get_reparse_compound_done);DEFINE_SMB3_INF_COMPOUND_DONE_EVENT (query_wsl_ea_compound_done); -DEFINE_SMB3_INF_COMPOUND_DONE_EVENT (delete_done);DEFINE_SMB3_INF_COMPOUND_DONE_EVENT (mkdir_done);DEFINE_SMB3_INF_COMPOUND_DONE_EVENT (tdis_done);DEFINE_SMB3_INF_COMPOUND_DONE_EVENT (mknod_done);
@@ -756,14 +754,13 @@ DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(queryDEFINE_SMB3_INF_COMPOUND_ERR_EVENT (posix_query_info_compound_err);DEFINE_SMB3_INF_COMPOUND_ERR_EVENT (hardlink_err);DEFINE_SMB3_INF_COMPOUND_ERR_EVENT (rename_err); -DEFINE_SMB3_INF_COMPOUND_ERR_EVENT (rmdir_err); +DEFINE_SMB3_INF_COMPOUND_ERR_EVENT (unlink_err);DEFINE_SMB3_INF_COMPOUND_ERR_EVENT (set_eof_err);DEFINE_SMB3_INF_COMPOUND_ERR_EVENT (set_info_compound_err);DEFINE_SMB3_INF_COMPOUND_ERR_EVENT (set_reparse_compound_err);DEFINE_SMB3_INF_COMPOUND_ERR_EVENT (get_reparse_compound_err);DEFINE_SMB3_INF_COMPOUND_ERR_EVENT (query_wsl_ea_compound_err);DEFINE_SMB3_INF_COMPOUND_ERR_EVENT (mkdir_err); -DEFINE_SMB3_INF_COMPOUND_ERR_EVENT (delete_err);DEFINE_SMB3_INF_COMPOUND_ERR_EVENT (tdis_err);DEFINE_SMB3_INF_COMPOUND_ERR_EVENT (mknod_err);
Greg Kroah-Hartman
maintainerPATCH 70/189 mtd: nand: raw: atmel: Respect tAR, tCLR in read setup timing
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Sverdlin <[email protected]>
commit fd779eac2d659668be4d3dbdac0710afd5d6db12 upstream.
Having setup time 0 violates tAR, tCLR of some chips, for instance TOSHIBA TC58NVG2S3ETAI0 cannot be detected successfully (first ID byte being read duplicated, i.e. 98 98 dc 90 15 76 14 03 instead of 98 dc 90 15 76 ...).
Atmel Application Notes postulated 1 cycle NRD_SETUP without explanation [1], but it looks more appropriate to just calculate setup time properly.
--- drivers/mtd/nand/raw/atmel/nand-controller.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
drivers/mtd/nand/raw/atmel/nand-controller.c +13 -3
@@ -1378,13 +1378,23 @@ static int atmel_smc_nand_prepare_smcconreturn ret;/* +* Read setup timing depends on the operation done on the NAND: +* +* NRD_SETUP = max(tAR, tCLR) +*/ + timeps =max (conf->timings.sdr.tAR_min, conf->timings.sdr.tCLR_min); + ncycles =DIV_ROUND_UP (timeps, mckperiodps); + totalcycles += ncycles; + ret =atmel_smc_cs_conf_set_setup (smcconf,ATMEL_SMC_NRD_SHIFT , ncycles); +if (ret) +return ret; + +/* * The read cycle timing is directly matching tRC, but is also * dependent on the setup and hold timings we calculated earlier, * which gives: * -* NRD_CYCLE = max(tRC, NRD_PULSE + NRD_HOLD) -* -* NRD_SETUP is always 0. +* NRD_CYCLE = max(tRC, NRD_SETUP + NRD_PULSE + NRD_HOLD) */ ncycles =DIV_ROUND_UP (conf->timings.sdr.tRC_min, mckperiodps); ncycles =max (totalcycles, ncycles);
Greg Kroah-Hartman
maintainerPATCH 71/189 mtd: rawnand: stm32_fmc2: avoid overlapping mappings on ECC buffer
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christophe Kerello <[email protected]>
commit 513c40e59d5a414ab763a9c84797534b5e8c208d upstream.
Avoid below overlapping mappings by using a contiguous non-cacheable buffer.
[ 4.077708] DMA-API: stm32_fmc2_nfc 48810000.nand-controller: cacheline tracking EEXIST, overlapping mappings aren't supported [ 4.089103] WARNING: CPU: 1 PID: 44 at kernel/dma/debug.c:568 add_dma_entry+0x23c/0x300 [ 4.097071] Modules linked in: [ 4.100101] CPU: 1 PID: 44 Comm: kworker/u4:2 Not tainted 6.1.82 #1 [ 4.106346] Hardware name: STMicroelectronics STM32MP257F VALID1 SNOR / MB1704 (LPDDR4 Power discrete) + MB1703 + MB1708 (SNOR MB1730) (DT) [ 4.118824] Workqueue: events_unbound deferred_probe_work_func [ 4.124674] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 4.131624] pc : add_dma_entry+0x23c/0x300 [ 4.135658] lr : add_dma_entry+0x23c/0x300 [ 4.139792] sp : ffff800009dbb490 [ 4.143016] x29: ffff800009dbb4a0 x28: 0000000004008022 x27: ffff8000098a6000 [ 4.150174] x26: 0000000000000000 x25: ffff8000099e7000 x24: ffff8000099e7de8 [ 4.157231] x23: 00000000ffffffff x22: 0000000000000000 x21: ffff8000098a6a20 [ 4.164388] x20: ffff000080964180 x19: ffff800009819ba0 x18: 0000000000000006 [ 4.171545] x17: 6361727420656e69 x16: 6c6568636163203a x15: 72656c6c6f72746e [ 4.178602] x14: 6f632d646e616e2e x13: ffff800009832f58 x12: 00000000000004ec [ 4.185759] x11: 00000000000001a4 x10: ffff80000988af58 x9 : ffff800009832f58 [ 4.192916] x8 : 00000000ffffefff x7 : ffff80000988af58 x6 : 80000000fffff000 [ 4.199972] x5 : 000000000000bff4 x4 : 0000000000000000 x3 : 0000000000000000 [ 4.207128] x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff0000812d2c40 [ 4.214185] Call trace: [ 4.216605] add_dma_entry+0x23c/0x300 [ 4.220338] debug_dma_map_sg+0x198/0x350 [ 4.224373] __dma_map_sg_attrs+0xa0/0x110 [ 4.228411] dma_map_sg_attrs+0x10/0x2c [ 4.232247] stm32_fmc2_nfc_xfer.isra.0+0x1c8/0x3fc [ 4.237088] stm32_fmc2_nfc_seq_read_page+0xc8/0x174 [ 4.242127] nand_read_oob+0x1d4/0x8e0 [ 4.245861] mtd_read_oob_std+0x58/0x84 [ 4.249596] mtd_read_oob+0x90/0x150 [ 4.253231] mtd_read+0x68/0xac
--- drivers/mtd/nand/raw/stm32_fmc2_nand.c | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-)
drivers/mtd/nand/raw/stm32_fmc2_nand.c +9 -19
@@ -272,6 +272,7 @@ struct stm32_fmc2_nfc {struct sg_table dma_data_sg;struct sg_table dma_ecc_sg;u8 *ecc_buf; +dma_addr_t dma_ecc_addr;int dma_ecc_len;u32 tx_dma_max_burst;u32 rx_dma_max_burst;
@@ -902,17 +903,10 @@ static int stm32_fmc2_nfc_xfer(struct naif (!write_data && !raw) {/* Configure DMA ECC status */ - p = nfc->ecc_buf;for_each_sg (nfc->dma_ecc_sg.sgl, sg, eccsteps, s) { -sg_set_buf (sg, p, nfc->dma_ecc_len); - p += nfc->dma_ecc_len; - } - - ret =dma_map_sg (nfc->dev, nfc->dma_ecc_sg.sgl, - eccsteps, dma_data_dir); -if (!ret) { - ret = -EIO ; - goto err_unmap_data; +sg_dma_address (sg) = nfc->dma_ecc_addr + + s * nfc->dma_ecc_len; +sg_dma_len (sg) = nfc->dma_ecc_len; } desc_ecc = dmaengine_prep_slave_sg(nfc->dma_ecc_ch,
@@ -921,7 +915,7 @@ static int stm32_fmc2_nfc_xfer(struct na DMA_PREP_INTERRUPT);if (!desc_ecc) { ret = -ENOMEM ; - goto err_unmap_ecc; + goto err_unmap_data; }reinit_completion (&nfc->dma_ecc_complete);
@@ -929,7 +923,7 @@ static int stm32_fmc2_nfc_xfer(struct na desc_ecc->callback_param = &nfc->dma_ecc_complete; ret =dma_submit_error (dmaengine_submit (desc_ecc));if (ret) - goto err_unmap_ecc; + goto err_unmap_data;dma_async_issue_pending (nfc->dma_ecc_ch); }
@@ -949,7 +943,7 @@ static int stm32_fmc2_nfc_xfer(struct naif (!write_data && !raw)dmaengine_terminate_all (nfc->dma_ecc_ch); ret = -ETIMEDOUT ; - goto err_unmap_ecc; + goto err_unmap_data; }/* Wait DMA data transfer completion */
@@ -969,11 +963,6 @@ static int stm32_fmc2_nfc_xfer(struct na } } -err_unmap_ecc: -if (!write_data && !raw) -dma_unmap_sg (nfc->dev, nfc->dma_ecc_sg.sgl, - eccsteps, dma_data_dir); - err_unmap_data:dma_unmap_sg (nfc->dev, nfc->dma_data_sg.sgl, eccsteps, dma_data_dir);
@@ -1610,7 +1599,8 @@ static int stm32_fmc2_nfc_dma_setup(strureturn ret;/* Allocate a buffer to store ECC status registers */ - nfc->ecc_buf =devm_kzalloc (nfc->dev,FMC2_MAX_ECC_BUF_LEN ,GFP_KERNEL ); + nfc->ecc_buf =dmam_alloc_coherent (nfc->dev,FMC2_MAX_ECC_BUF_LEN , + &nfc->dma_ecc_addr,GFP_KERNEL );if (!nfc->ecc_buf)return -ENOMEM ;
Greg Kroah-Hartman
maintainerPATCH 72/189 mtd: rawnand: stm32_fmc2: fix ECC overwrite
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christophe Kerello <[email protected]>
commit 811c0da4542df3c065f6cb843ced68780e27bb44 upstream.
In case OOB write is requested during a data write, ECC is currently lost. Avoid this issue by only writing in the free spare area. This issue has been seen with a YAFFS2 file system.
--- drivers/mtd/nand/raw/stm32_fmc2_nand.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-)
drivers/mtd/nand/raw/stm32_fmc2_nand.c +15 -3
@@ -985,9 +985,21 @@ static int stm32_fmc2_nfc_seq_write(stru/* Write oob */ if (oob_required) { - ret =nand_change_write_column_op (chip, mtd->writesize, - chip->oob_poi, mtd->oobsize, - false); +unsigned int offset_in_page = mtd->writesize; +const void *buf = chip->oob_poi; +unsigned int len = mtd->oobsize; + +if (!raw) { +struct mtd_oob_region oob_free; + +mtd_ooblayout_free (mtd,0 , &oob_free); + offset_in_page += oob_free.offset; + buf += oob_free.offset; + len = oob_free.length; + } + + ret =nand_change_write_column_op (chip, offset_in_page, + buf, len, false);if (ret)return ret; }
Greg Kroah-Hartman
maintainerPATCH 73/189 fuse: do not allow mapping a non-regular backing file
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amir Goldstein <[email protected]>
commit e9c8da670e749f7dedc53e3af54a87b041918092 upstream.
We do not support passthrough operations other than read/write on regular file, so allowing non-regular backing files makes no sense.
--- fs/fuse/passthrough.c | 5 +++++ 1 file changed, 5 insertions(+)
fs/fuse/passthrough.c +5 -0
@@ -237,6 +237,11 @@ int fuse_backing_open(struct fuse_conn *if (!file) goto out; +/* read/write/splice/mmap passthrough only relevant for regular files */ + res =d_is_dir (file->f_path.dentry) ? -EISDIR : -EINVAL ; +if (!d_is_reg (file->f_path.dentry)) + goto out_fput; + backing_sb =file_inode (file)->i_sb; res = -ELOOP ;if (backing_sb->s_stack_depth >= fc->max_stack_depth)
Greg Kroah-Hartman
maintainerPATCH 74/189 fuse: check if copy_file_range() returns larger than requested size
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miklos Szeredi <[email protected]>
commit e5203209b3935041dac541bc5b37efb44220cc0b upstream.
Just like write(), copy_file_range() should check if the return value is less or equal to the requested number of bytes.
--- fs/fuse/file.c | 3 +++ 1 file changed, 3 insertions(+)
fs/fuse/file.c +3 -0
@@ -3079,6 +3079,9 @@ static ssize_t __fuse_copy_file_range(st fc->no_copy_file_range =1 ; err = -EOPNOTSUPP ; } +if (!err && outarg.size > len) + err = -EIO ; +if (err) goto out;
Greg Kroah-Hartman
maintainerPATCH 75/189 fuse: prevent overflow in copy_file_range return value
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miklos Szeredi <[email protected]>
commit 1e08938c3694f707bb165535df352ac97a8c75c9 upstream.
The FUSE protocol uses struct fuse_write_out to convey the return value of copy_file_range, which is restricted to uint32_t. But the COPY_FILE_RANGE interface supports a 64-bit size copies.
Currently the number of bytes copied is silently truncated to 32-bit, which may result in poor performance or even failure to copy in case of truncation to zero.
--- fs/fuse/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/fuse/file.c +1 -1
@@ -3013,7 +3013,7 @@ static ssize_t __fuse_copy_file_range(st .nodeid_out = ff_out->nodeid, .fh_out = ff_out->fh, .off_out = pos_out, - .len = len, + .len = min_t(size_t, len, UINT_MAX & PAGE_MASK), .flags = flags };struct fuse_write_out outarg;
Greg Kroah-Hartman
maintainerPATCH 76/189 mm/hugetlb: add missing hugetlb_lock in __unmap_hugepage_range()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeongjun Park <[email protected]>
commit 21cc2b5c5062a256ae9064442d37ebbc23f5aef7 upstream.
When restoring a reservation for an anonymous page, we need to check to freeing a surplus. However, __unmap_hugepage_range() causes data race because it reads h->surplus_huge_pages without the protection of hugetlb_lock.
And adjust_reservation is a boolean variable that indicates whether reservations for anonymous pages in each folio should be restored. Therefore, it should be initialized to false for each round of the loop. However, this variable is not initialized to false except when defining the current adjust_reservation variable.
This means that once adjust_reservation is set to true even once within the loop, reservations for anonymous pages will be restored unconditionally in all subsequent rounds, regardless of the folio's state.
To fix this, we need to add the missing hugetlb_lock, unlock the page_table_lock earlier so that we don't lock the hugetlb_lock inside the page_table_lock lock, and initialize adjust_reservation to false on each round within the loop.
--- mm/hugetlb.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
mm/hugetlb.c +6 -3
@@ -5855,7 +5855,7 @@ void __unmap_hugepage_range(struct mmu_gspinlock_t *ptl;struct hstate *h =hstate_vma (vma);unsigned long sz =huge_page_size (h); -bool adjust_reservation = false; +bool adjust_reservation;unsigned long last_addr_mask;bool force_flush = false;
@@ -5948,6 +5948,7 @@ void __unmap_hugepage_range(struct mmu_g sz);hugetlb_count_sub (pages_per_huge_page (h), mm);hugetlb_remove_rmap (folio); +spin_unlock (ptl);/* * Restore the reservation for anonymous page, otherwise the
@@ -5955,14 +5956,16 @@ void __unmap_hugepage_range(struct mmu_g* If there we are freeing a surplus, do not set the restore * reservation bit. */ + adjust_reservation = false; + +spin_lock_irq (&hugetlb_lock);if (!h->surplus_huge_pages &&__vma_private_lock (vma) &&folio_test_anon (folio)) {folio_set_hugetlb_restore_reserve (folio);/* Reservation to be adjusted after the spin lock */ adjust_reservation = true; } - -spin_unlock (ptl); +spin_unlock_irq (&hugetlb_lock);/* * Adjust the reservation for the region that will have the
Greg Kroah-Hartman
maintainerPATCH 77/189 mm/khugepaged: fix the address passed to notifier on testing young
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wei Yang <[email protected]>
commit 394bfac1c7f7b701c2c93834c5761b9c9ceeebcf upstream.
Commit 8ee53820edfd ("thp: mmu_notifier_test_young") introduced mmu_notifier_test_young(), but we are passing the wrong address. In xxx_scan_pmd(), the actual iteration address is "_address" not "address". We seem to misuse the variable on the very beginning.
Change it to the right one.
--- mm/khugepaged.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
mm/khugepaged.c +2 -2
@@ -1400,8 +1400,8 @@ static int hpage_collapse_scan_pmd(struc*/ if (cc->is_khugepaged && (pte_young (pteval) ||folio_test_young (folio) || -folio_test_referenced (folio) ||mmu_notifier_test_young (vma->vm_mm, - address))) +folio_test_referenced (folio) || +mmu_notifier_test_young (vma->vm_mm, _address))) referenced++; }if (!writable) {
Greg Kroah-Hartman
maintainerPATCH 78/189 mm/vmalloc, mm/kasan: respect gfp mask in kasan_populate_vmalloc()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Uladzislau Rezki (Sony) <[email protected]>
commit 79357cd06d41d0f5a11b17d7c86176e395d10ef2 upstream.
kasan_populate_vmalloc() and its helpers ignore the caller's gfp_mask and always allocate memory using the hardcoded GFP_KERNEL flag. This makes them inconsistent with vmalloc(), which was recently extended to support GFP_NOFS and GFP_NOIO allocations.
Page table allocations performed during shadow population also ignore the external gfp_mask. To preserve the intended semantics of GFP_NOFS and GFP_NOIO, wrap the apply_to_page_range() calls into the appropriate memalloc scope.
xfs calls vmalloc with GFP_NOFS, so this bug could lead to deadlock.
There was a report here
https://lkml.kernel.org/r/[email protected]
This patch:
- Extends kasan_populate_vmalloc() and helpers to take gfp_mask;
- Passes gfp_mask down to alloc_pages_bulk() and __get_free_page();
- Enforces GFP_NOFS/NOIO semantics with memalloc_*_save()/restore() around apply_to_page_range();
- Updates vmalloc.c and percpu allocator call sites accordingly.
--- include/linux/kasan.h | 6 +++--- mm/kasan/shadow.c | 31 ++++++++++++++++++++++++------- mm/vmalloc.c | 8 ++++---- 3 files changed, 31 insertions(+), 14 deletions(-)
include/linux/kasan.h +3 -3
@@ -562,7 +562,7 @@ static inline void kasan_init_hw_tags(vo#if defined(CONFIG_KASAN_GENERIC ) || defined(CONFIG_KASAN_SW_TAGS )void kasan_populate_early_vm_area_shadow (void *start,unsigned long size); -int kasan_populate_vmalloc (unsigned long addr,unsigned long size); +int kasan_populate_vmalloc (unsigned long addr,unsigned long size,gfp_t gfp_mask); void kasan_release_vmalloc(unsigned long start, unsigned long end, unsigned long free_region_start, unsigned long free_region_end,
@@ -574,7 +574,7 @@ static inline void kasan_populate_early_ unsigned long size) { }static inline int kasan_populate_vmalloc (unsigned long start, -unsigned long size) +unsigned long size,gfp_t gfp_mask) {return 0 ; }
@@ -610,7 +610,7 @@ static __always_inline void kasan_poisonstatic inline void kasan_populate_early_vm_area_shadow (void *start,unsigned long size) { }static inline int kasan_populate_vmalloc (unsigned long start, -unsigned long size) +unsigned long size,gfp_t gfp_mask) {return 0 ; }
mm/kasan/shadow.c +24 -7
@@ -335,13 +335,13 @@ static void ___free_pages_bulk(struct pa } } -static int ___alloc_pages_bulk (struct page **pages,int nr_pages) +static int ___alloc_pages_bulk (struct page **pages,int nr_pages,gfp_t gfp_mask) {unsigned long nr_populated, nr_total = nr_pages;struct page **page_array = pages;while (nr_pages) { - nr_populated =alloc_pages_bulk (GFP_KERNEL , nr_pages, pages); + nr_populated =alloc_pages_bulk (gfp_mask, nr_pages, pages);if (!nr_populated) {___free_pages_bulk (page_array, nr_total - nr_pages);return -ENOMEM ;
@@ -353,25 +353,42 @@ static int ___alloc_pages_bulk(struct pareturn 0 ; } -static int __kasan_populate_vmalloc (unsigned long start,unsigned long end) +static int __kasan_populate_vmalloc (unsigned long start,unsigned long end,gfp_t gfp_mask) {unsigned long nr_pages, nr_total =PFN_UP (end - start);struct vmalloc_populate_data data; +unsigned int flags;int ret =0 ; - data.pages = (struct page **)__get_free_page (GFP_KERNEL | __GFP_ZERO); + data.pages = (struct page **)__get_free_page (gfp_mask | __GFP_ZERO);if (!data.pages)return -ENOMEM ;while (nr_total) { nr_pages =min (nr_total,PAGE_SIZE /sizeof (data.pages[0 ])); - ret =___alloc_pages_bulk (data.pages, nr_pages); + ret =___alloc_pages_bulk (data.pages, nr_pages, gfp_mask);if (ret)break ; data.start = start; + +/* +* page tables allocations ignore external gfp mask, enforce it +* by the scope API +*/ +if ((gfp_mask & (__GFP_FS | __GFP_IO)) == __GFP_IO) + flags =memalloc_nofs_save (); +else if ((gfp_mask & (__GFP_FS | __GFP_IO)) ==0 ) + flags =memalloc_noio_save (); + ret =apply_to_page_range (&init_mm, start, nr_pages *PAGE_SIZE , kasan_populate_vmalloc_pte, &data); + +if ((gfp_mask & (__GFP_FS | __GFP_IO)) == __GFP_IO) +memalloc_nofs_restore (flags); +else if ((gfp_mask & (__GFP_FS | __GFP_IO)) ==0 ) +memalloc_noio_restore (flags); +___free_pages_bulk (data.pages, nr_pages);if (ret)break ;
@@ -385,7 +402,7 @@ static int __kasan_populate_vmalloc(unsireturn ret; } -int kasan_populate_vmalloc (unsigned long addr,unsigned long size) +int kasan_populate_vmalloc (unsigned long addr,unsigned long size,gfp_t gfp_mask) {unsigned long shadow_start, shadow_end;int ret;
@@ -414,7 +431,7 @@ int kasan_populate_vmalloc(unsigned long shadow_start =PAGE_ALIGN_DOWN (shadow_start); shadow_end =PAGE_ALIGN (shadow_end); - ret =__kasan_populate_vmalloc (shadow_start, shadow_end); + ret =__kasan_populate_vmalloc (shadow_start, shadow_end, gfp_mask);if (ret)return ret;
mm/vmalloc.c +4 -4
@@ -2026,6 +2026,8 @@ static struct vmap_area *alloc_vmap_areaif (unlikely (!vmap_initialized))return ERR_PTR (-EBUSY ); +/* Only reclaim behaviour flags are relevant. */ + gfp_mask = gfp_mask &GFP_RECLAIM_MASK ;might_sleep ();/*
@@ -2038,8 +2040,6 @@ static struct vmap_area *alloc_vmap_area*/ va =node_alloc (size, align, vstart, vend, &addr, &vn_id);if (!va) { - gfp_mask = gfp_mask &GFP_RECLAIM_MASK ; - va =kmem_cache_alloc_node (vmap_area_cachep, gfp_mask, node);if (unlikely (!va))return ERR_PTR (-ENOMEM );
@@ -2089,7 +2089,7 @@ retry:BUG_ON (va->va_start < vstart);BUG_ON (va->va_end > vend); - ret =kasan_populate_vmalloc (addr, size); + ret =kasan_populate_vmalloc (addr, size, gfp_mask);if (ret) {free_vmap_area (va);return ERR_PTR (ret);
@@ -4826,7 +4826,7 @@ retry:/* populate the kasan shadow space */ for (area =0 ; area < nr_vms; area++) { -if (kasan_populate_vmalloc (vas[area]->va_start, sizes[area])) +if (kasan_populate_vmalloc (vas[area]->va_start, sizes[area],GFP_KERNEL )) goto err_free_shadow; }
Greg Kroah-Hartman
maintainerPATCH 79/189 mm/memory-failure: fix VM_BUG_ON_PAGE(PagePoisoned(page)) when unpoison memory
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miaohe Lin <[email protected]>
commit d613f53c83ec47089c4e25859d5e8e0359f6f8da upstream.
When I did memory failure tests, below panic occurs:
page dumped because: VM_BUG_ON_PAGE(PagePoisoned(page)) kernel BUG at include/linux/page-flags.h:616! Oops: invalid opcode: 0000 [#1] PREEMPT SMP NOPTI CPU: 3 PID: 720 Comm: bash Not tainted 6.10.0-rc1-00195-g148743902568 #40 RIP: 0010:unpoison_memory+0x2f3/0x590 RSP: 0018:ffffa57fc8787d60 EFLAGS: 00000246 RAX: 0000000000000037 RBX: 0000000000000009 RCX: ffff9be25fcdc9c8 RDX: 0000000000000000 RSI: 0000000000000027 RDI: ffff9be25fcdc9c0 RBP: 0000000000300000 R08: ffffffffb4956f88 R09: 0000000000009ffb R10: 0000000000000284 R11: ffffffffb4926fa0 R12: ffffe6b00c000000 R13: ffff9bdb453dfd00 R14: 0000000000000000 R15: fffffffffffffffe FS: 00007f08f04e4740(0000) GS:ffff9be25fcc0000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000564787a30410 CR3: 000000010d4e2000 CR4: 00000000000006f0 Call Trace: <TASK> unpoison_memory+0x2f3/0x590 simple_attr_write_xsigned.constprop.0.isra.0+0xb3/0x110 debugfs_attr_write+0x42/0x60 full_proxy_write+0x5b/0x80 vfs_write+0xd5/0x540 ksys_write+0x64/0xe0 do_syscall_64+0xb9/0x1d0 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f08f0314887 RSP: 002b:00007ffece710078 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 RAX: ffffffffffffffda RBX: 0000000000000009 RCX: 00007f08f0314887 RDX: 0000000000000009 RSI: 0000564787a30410 RDI: 0000000000000001 RBP: 0000564787a30410 R08: 000000000000fefe R09: 000000007fffffff R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000009 R13: 00007f08f041b780 R14: 00007f08f0417600 R15: 00007f08f0416a00 </TASK> Modules linked in: hwpoison_inject ---[ end trace 0000000000000000 ]--- RIP: 0010:unpoison_memory+0x2f3/0x590 RSP: 0018:ffffa57fc8787d60 EFLAGS: 00000246 RAX: 0000000000000037 RBX: 0000000000000009 RCX: ffff9be25fcdc9c8 RDX: 0000000000000000 RSI: 0000000000000027 RDI: ffff9be25fcdc9c0 RBP: 0000000000300000 R08: ffffffffb4956f88 R09: 0000000000009ffb R10: 0000000000000284 R11: ffffffffb4926fa0 R12: ffffe6b00c000000 R13: ffff9bdb453dfd00 R14: 0000000000000000 R15: fffffffffffffffe FS: 00007f08f04e4740(0000) GS:ffff9be25fcc0000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000564787a30410 CR3: 000000010d4e2000 CR4: 00000000000006f0 Kernel panic - not syncing: Fatal exception Kernel Offset: 0x31c00000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff) ---[ end Kernel panic - not syncing: Fatal exception ]---
The root cause is that unpoison_memory() tries to check the PG_HWPoison flags of an uninitialized page. So VM_BUG_ON_PAGE(PagePoisoned(page)) is triggered. This can be reproduced by below steps:
1.Offline memory block:
echo offline > /sys/devices/system/memory/memory12/state
2.Get offlined memory pfn:
page-types -b n -rlN
3.Write pfn to unpoison-pfn
echo <pfn> > /sys/kernel/debug/hwpoison/unpoison-pfn
This scenario can be identified by pfn_to_online_page() returning NULL. And ZONE_DEVICE pages are never expected, so we can simply fail if pfn_to_online_page() == NULL to fix the bug.
--- mm/memory-failure.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
mm/memory-failure.c +3 -4
@@ -2576,10 +2576,9 @@ int unpoison_memory(unsigned long pfn) static DEFINE_RATELIMIT_STATE(unpoison_rs, DEFAULT_RATELIMIT_INTERVAL, DEFAULT_RATELIMIT_BURST); -if (!pfn_valid (pfn)) -return -ENXIO ; - - p =pfn_to_page (pfn); + p =pfn_to_online_page (pfn); +if (!p) +return -EIO ; folio =page_folio (p);mutex_lock (&mf_mutex);
Greg Kroah-Hartman
maintainerPATCH 80/189 mm/memory-failure: fix redundant updates for already poisoned pages
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kyle Meyer <[email protected]>
commit 3be306cccdccede13e3cefd0c14e430cc2b7c9c7 upstream.
Duplicate memory errors can be reported by multiple sources.
Passing an already poisoned page to action_result() causes issues:
* The amount of hardware corrupted memory is incorrectly updated.
* Per NUMA node MF stats are incorrectly updated.
* Redundant "already poisoned" messages are printed.
Avoid those issues by:
* Skipping hardware corrupted memory updates for already poisoned pages.
* Skipping per NUMA node MF stats updates for already poisoned pages.
* Dropping redundant "already poisoned" messages.
Make MF_MSG_ALREADY_POISONED consistent with other action_page_types and make calls to action_result() consistent for already poisoned normal pages and huge pages.
--- mm/memory-failure.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
mm/memory-failure.c +6 -7
@@ -950,7 +950,7 @@ static const char * const action_page_ty [MF_MSG_BUDDY] = "free buddy page", [MF_MSG_DAX] = "dax page", [MF_MSG_UNSPLIT_THP] = "unsplit thp", - [MF_MSG_ALREADY_POISONED] = "already poisoned", + [MF_MSG_ALREADY_POISONED] = "already poisoned page", [MF_MSG_UNKNOWN] = "unknown page", };
@@ -1343,9 +1343,10 @@ static int action_result(unsigned long p {trace_memory_failure_event (pfn, type, result); -num_poisoned_pages_inc (pfn); - -update_per_node_mf_stats (pfn, result); +if (type !=MF_MSG_ALREADY_POISONED ) { +num_poisoned_pages_inc (pfn); +update_per_node_mf_stats (pfn, result); + }pr_err ("%#lx: recovery action for %s: %s\n" , pfn, action_page_types[type], action_name[result]);
@@ -2088,12 +2089,11 @@ retry: *hugetlb =0 ;return 0 ; }else if (res == -EHWPOISON ) { -pr_err ("%#lx: already hardware poisoned\n" , pfn);if (flags &MF_ACTION_REQUIRED ) { folio =page_folio (p); res =kill_accessing_process (current,folio_pfn (folio), flags); -action_result (pfn,MF_MSG_ALREADY_POISONED ,MF_FAILED ); } +action_result (pfn,MF_MSG_ALREADY_POISONED ,MF_FAILED );return res; }else if (res == -EBUSY ) {if (!(flags &MF_NO_RETRY )) {
@@ -2279,7 +2279,6 @@ try_again: goto unlock_mutex;if (TestSetPageHWPoison (p)) { -pr_err ("%#lx: already hardware poisoned\n" , pfn); res = -EHWPOISON ;if (flags &MF_ACTION_REQUIRED ) res =kill_accessing_process (current, pfn, flags);
Greg Kroah-Hartman
maintainerPATCH 81/189 mm/damon/core: set quota->charged_from to jiffies at first charge window
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sang-Heon Jeon <[email protected]>
commit ce652aac9c90a96c6536681d17518efb1f660fb8 upstream.
Kernel initializes the "jiffies" timer as 5 minutes below zero, as shown in include/linux/jiffies.h
/*
* Have the 32 bit jiffies value wrap 5 minutes after boot
* so jiffies wrap bugs show up earlier.
*/
#define INITIAL_JIFFIES ((unsigned long)(unsigned int) (-300*HZ))
And jiffies comparison help functions cast unsigned value to signed to cover wraparound
#define time_after_eq(a,b) \
(typecheck(unsigned long, a) && \
typecheck(unsigned long, b) && \
((long)((a) - (b)) >= 0))
When quota->charged_from is initialized to 0, time_after_eq() can incorrectly return FALSE even after reset_interval has elapsed. This occurs when (jiffies - reset_interval) produces a value with MSB=1, which is interpreted as negative in signed arithmetic.
This issue primarily affects 32-bit systems because: On 64-bit systems:
MSB=1 values occur after ~292 million years from boot (assuming HZ=1000), almost impossible.
On 32-bit systems: MSB=1 values occur during the first 5 minutes after boot, and the second half of every jiffies wraparound cycle, starting from day 25 (assuming HZ=1000)
When above unexpected FALSE return from time_after_eq() occurs, the charging window will not reset. The user impact depends on esz value at that time.
If esz is 0, scheme ignores configured quotas and runs without any limits.
If esz is not 0, scheme stops working once the quota is exhausted. It remains until the charging window finally resets.
So, change quota->charged_from to jiffies at damos_adjust_quota() when it is considered as the first charge window. By this change, we can avoid unexpected FALSE return from time_after_eq()
--- mm/damon/core.c | 4 ++++ 1 file changed, 4 insertions(+)
mm/damon/core.c +4 -0
@@ -2050,6 +2050,10 @@ static void damos_adjust_quota(struct daif (!quota->ms && !quota->sz &&list_empty ("a->goals))return ; +/* First charge window */ +if (!quota->total_charged_sz && !quota->charged_from) + quota->charged_from = jiffies; +/* New charge window starts */ if (time_after_eq (jiffies, quota->charged_from +msecs_to_jiffies (quota->reset_interval))) {
Greg Kroah-Hartman
maintainerPATCH 82/189 mm/damon/lru_sort: avoid divide-by-zero in damon_lru_sort_apply_parameters()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Quanmin Yan <[email protected]>
commit 711f19dfd783ffb37ca4324388b9c4cb87e71363 upstream.
Patch series "mm/damon: avoid divide-by-zero in DAMON module's parameters application".
DAMON's RECLAIM and LRU_SORT modules perform no validation on user-configured parameters during application, which may lead to division-by-zero errors.
Avoid the divide-by-zero by adding validation checks when DAMON modules attempt to apply the parameters.
This patch (of 2):
During the calculation of 'hot_thres' and 'cold_thres', either 'sample_interval' or 'aggr_interval' is used as the divisor, which may lead to division-by-zero errors. Fix it by directly returning -EINVAL when such a case occurs. Additionally, since 'aggr_interval' is already required to be set no smaller than 'sample_interval' in damon_set_attrs(), only the case where 'sample_interval' is zero needs to be checked.
--- mm/damon/lru_sort.c | 5 +++++ 1 file changed, 5 insertions(+)
mm/damon/lru_sort.c +5 -0
@@ -198,6 +198,11 @@ static int damon_lru_sort_apply_parameteif (err)return err; +if (!damon_lru_sort_mon_attrs.sample_interval) { + err = -EINVAL ; + goto out; + } + err =damon_set_attrs (ctx, &damon_lru_sort_mon_attrs);if (err) goto out;
Greg Kroah-Hartman
maintainerPATCH 83/189 drm/mediatek: fix potential OF node use-after-free
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit 4de37a48b6b58faaded9eb765047cf0d8785ea18 upstream.
The for_each_child_of_node() helper drops the reference it takes to each node as it iterates over children and an explicit of_node_put() is only needed when exiting the loop early.
Drop the recently introduced bogus additional reference count decrement at each iteration that could potentially lead to a use-after-free.
--- drivers/gpu/drm/mediatek/mtk_drm_drv.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
drivers/gpu/drm/mediatek/mtk_drm_drv.c +5 -6
@@ -388,11 +388,11 @@ static bool mtk_drm_get_all_drm_priv(str of_id =of_match_node (mtk_drm_of_ids, node);if (!of_id) - goto next_put_node; +continue ; pdev =of_find_device_by_node (node);if (!pdev) - goto next_put_node; +continue ; drm_dev =device_find_child (&pdev->dev,NULL , mtk_drm_match);if (!drm_dev)
@@ -418,11 +418,10 @@ next_put_device_drm_dev: next_put_device_pdev_dev:put_device (&pdev->dev); -next_put_node: -of_node_put (node); - -if (cnt ==MAX_CRTC ) +if (cnt ==MAX_CRTC ) { +of_node_put (node);break ; + } }if (drm_priv->data->mmsys_dev_num == cnt) {
Greg Kroah-Hartman
maintainerPATCH 84/189 drm/i915/power: fix size for for_each_set_bit() in abox iteration
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jani Nikula <[email protected]>
commit cfa7b7659757f8d0fc4914429efa90d0d2577dd7 upstream.
for_each_set_bit() expects size to be in bits, not bytes. The abox mask iteration uses bytes, but it works by coincidence, because the local variable holding the mask is unsigned long, and the mask only ever has bit 2 as the highest bit. Using a smaller type could lead to subtle and very hard to track bugs.
--- drivers/gpu/drm/i915/display/intel_display_power.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/gpu/drm/i915/display/intel_display_power.c +3 -3
@@ -1169,7 +1169,7 @@ static void icl_mbus_init(struct intel_dif (DISPLAY_VER (display) ==12 ) abox_regs |=BIT (0 ); -for_each_set_bit (i, &abox_regs,sizeof (abox_regs)) +for_each_set_bit (i, &abox_regs,BITS_PER_TYPE (abox_regs))intel_de_rmw (display,MBUS_ABOX_CTL (i), mask, val); }
@@ -1630,11 +1630,11 @@ static void tgl_bw_buddy_init(struct intif (table[config].page_mask ==0 ) {drm_dbg_kms (display->drm,"Unknown memory configuration; disabling address buddy logic.\n" ); -for_each_set_bit (i, &abox_mask,sizeof (abox_mask)) +for_each_set_bit (i, &abox_mask,BITS_PER_TYPE (abox_mask))intel_de_write (display,BW_BUDDY_CTL (i),BW_BUDDY_DISABLE ); }else { -for_each_set_bit (i, &abox_mask,sizeof (abox_mask)) { +for_each_set_bit (i, &abox_mask,BITS_PER_TYPE (abox_mask)) {intel_de_write (display,BW_BUDDY_PAGE_MASK (i), table[config].page_mask);
Greg Kroah-Hartman
maintainerPATCH 85/189 drm/xe: Attempt to bring bos back to VRAM after eviction
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Hellström <[email protected]>
commit 5c87fee3c96ce898ad681552404a66c7605193c0 upstream.
VRAM+TT bos that are evicted from VRAM to TT may remain in TT also after a revalidation following eviction or suspend.
This manifests itself as applications becoming sluggish after buffer objects get evicted or after a resume from suspend or hibernation.
If the bo supports placement in both VRAM and TT, and we are on DGFX, mark the TT placement as fallback. This means that it is tried only after VRAM + eviction.
This flaw has probably been present since the xe module was upstreamed but use a Fixes: commit below where backporting is likely to be simple. For earlier versions we need to open- code the fallback algorithm in the driver.
v2:
- Remove check for dgfx. (Matthew Auld)
- Update the xe_dma_buf kunit test for the new strategy (CI)
- Allow dma-buf to pin in current placement (CI)
- Make xe_bo_validate() for pinned bos a NOP.
--- drivers/gpu/drm/xe/tests/xe_bo.c | 2 +- drivers/gpu/drm/xe/tests/xe_dma_buf.c | 10 +--------- drivers/gpu/drm/xe/xe_bo.c | 16 ++++++++++++---- drivers/gpu/drm/xe/xe_bo.h | 2 +- drivers/gpu/drm/xe/xe_dma_buf.c | 2 +- 5 files changed, 16 insertions(+), 16 deletions(-)
drivers/gpu/drm/xe/tests/xe_bo.c +1 -1
@@ -236,7 +236,7 @@ static int evict_test_run_tile(struct xe }xe_bo_lock (external, false); - err =xe_bo_pin_external (external); + err =xe_bo_pin_external (external, false);xe_bo_unlock (external);if (err) { KUNIT_FAIL(test, "external bo pin err=%pe\n",
drivers/gpu/drm/xe/tests/xe_dma_buf.c +1 -9
@@ -89,15 +89,7 @@ static void check_residency(struct kunitreturn ; } -/* -* If on different devices, the exporter is kept in system if -* possible, saving a migration step as the transfer is just -* likely as fast from system memory. -*/ -if (params->mem_mask &XE_BO_FLAG_SYSTEM ) -KUNIT_EXPECT_TRUE (test,xe_bo_is_mem_type (exported,XE_PL_TT )); -else -KUNIT_EXPECT_TRUE (test,xe_bo_is_mem_type (exported, mem_type)); +KUNIT_EXPECT_TRUE (test,xe_bo_is_mem_type (exported, mem_type));if (params->force_different_devices)KUNIT_EXPECT_TRUE (test,xe_bo_is_mem_type (imported,XE_PL_TT ));
drivers/gpu/drm/xe/xe_bo.c +12 -4
@@ -184,6 +184,8 @@ static void try_add_system(struct xe_dev bo->placements[*c] = (struct ttm_place ) { .mem_type =XE_PL_TT , + .flags = (bo_flags &XE_BO_FLAG_VRAM_MASK ) ? +TTM_PL_FLAG_FALLBACK :0 , }; *c +=1 ; }
@@ -2266,6 +2268,7 @@ uint64_t vram_region_gpu_offset(struct t/** * xe_bo_pin_external - pin an external BO * @bo: buffer object to be pinned +* @in_place: Pin in current placement, don't attempt to migrate. * * Pin an external (not tied to a VM, can be exported via dma-buf / prime FD) * BO. Unique call compared to xe_bo_pin as this function has it own set of
@@ -2273,7 +2276,7 @@ uint64_t vram_region_gpu_offset(struct t* * Returns 0 for success, negative error code otherwise. */ -int xe_bo_pin_external (struct xe_bo *bo) +int xe_bo_pin_external (struct xe_bo *bo,bool in_place) {struct xe_device *xe =xe_bo_device (bo);int err;
@@ -2282,9 +2285,11 @@ int xe_bo_pin_external(struct xe_bo *bo)xe_assert (xe,xe_bo_is_user (bo));if (!xe_bo_is_pinned (bo)) { - err =xe_bo_validate (bo,NULL , false); -if (err) -return err; +if (!in_place) { + err =xe_bo_validate (bo,NULL , false); +if (err) +return err; + }spin_lock (&xe->pinned.lock);list_add_tail (&bo->pinned_link, &xe->pinned.late.external);
@@ -2437,6 +2442,9 @@ int xe_bo_validate(struct xe_bo *bo, str };int ret; +if (xe_bo_is_pinned (bo)) +return 0 ; +if (vm) {lockdep_assert_held (&vm->lock);xe_vm_assert_held (vm);
drivers/gpu/drm/xe/xe_bo.h +1 -1
@@ -201,7 +201,7 @@ static inline void xe_bo_unlock_vm_held( } } -int xe_bo_pin_external (struct xe_bo *bo); +int xe_bo_pin_external (struct xe_bo *bo,bool in_place);int xe_bo_pin (struct xe_bo *bo);void xe_bo_unpin_external (struct xe_bo *bo);void xe_bo_unpin (struct xe_bo *bo);
drivers/gpu/drm/xe/xe_dma_buf.c +1 -1
@@ -72,7 +72,7 @@ static int xe_dma_buf_pin(struct dma_bufreturn ret; } - ret =xe_bo_pin_external (bo); + ret =xe_bo_pin_external (bo, true);xe_assert (xe, !ret);return 0 ;
Greg Kroah-Hartman
maintainerPATCH 86/189 drm/xe: Allow the pm notifier to continue on failure
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Hellström <[email protected]>
commit d84820309ed34cc412ce76ecfa9471dae7d7d144 upstream.
Its actions are opportunistic anyway and will be completed on device suspend.
Marking as a fix to simplify backporting of the fix that follows in the series.
v2:
- Keep the runtime pm reference over suspend / hibernate and document why. (Matt Auld, Rodrigo Vivi):
--- drivers/gpu/drm/xe/xe_pm.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-)
drivers/gpu/drm/xe/xe_pm.c +7 -10
@@ -296,17 +296,17 @@ static int xe_pm_notifier_callback(struccase PM_SUSPEND_PREPARE :xe_pm_runtime_get (xe); err =xe_bo_evict_all_user (xe); -if (err) { +if (err)drm_dbg (&xe->drm,"Notifier evict user failed (%d)\n" , err); -xe_pm_runtime_put (xe); -break ; - } err =xe_bo_notifier_prepare_all_pinned (xe); -if (err) { +if (err)drm_dbg (&xe->drm,"Notifier prepare pin failed (%d)\n" , err); -xe_pm_runtime_put (xe); - } +/* +* Keep the runtime pm reference until post hibernation / post suspend to +* avoid a runtime suspend interfering with evicted objects or backup +* allocations. +*/ break ;case PM_POST_HIBERNATION :case PM_POST_SUSPEND :
@@ -315,9 +315,6 @@ static int xe_pm_notifier_callback(strucbreak ; } -if (err) -return NOTIFY_BAD ; -return NOTIFY_DONE ; }
Greg Kroah-Hartman
maintainerPATCH 87/189 drm/xe: Block exec and rebind worker while evicting for suspend / hibernate
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Hellström <[email protected]>
commit eb5723a75104605b7d2207a7d598e314166fbef4 upstream.
When the xe pm_notifier evicts for suspend / hibernate, there might be racing tasks trying to re-validate again. This can lead to suspend taking excessive time or get stuck in a live-lock. This behaviour becomes much worse with the fix that actually makes re-validation bring back bos to VRAM rather than letting them remain in TT.
Prevent that by having exec and the rebind worker waiting for a completion that is set to block by the pm_notifier before suspend and is signaled by the pm_notifier after resume / wakeup.
It's probably still possible to craft malicious applications that block suspending. More work is pending to fix that.
v3:
- Avoid wait_for_completion() in the kernel worker since it could potentially cause work item flushes from freezable processes to wait forever. Instead terminate the rebind workers if needed and re-launch at resume. (Matt Auld)
v4:
- Fix some bad naming and leftover debug printouts.
- Fix kerneldoc.
- Use drmm_mutex_init() for the xe->rebind_resume_lock (Matt Auld).
- Rework the interface of xe_vm_rebind_resume_worker (Matt Auld).
--- drivers/gpu/drm/xe/xe_device_types.h | 6 +++++ drivers/gpu/drm/xe/xe_exec.c | 9 +++++++ drivers/gpu/drm/xe/xe_pm.c | 25 ++++++++++++++++++++ drivers/gpu/drm/xe/xe_vm.c | 42 ++++++++++++++++++++++++++++++++++- drivers/gpu/drm/xe/xe_vm.h | 2 + drivers/gpu/drm/xe/xe_vm_types.h | 5 ++++ 6 files changed, 88 insertions(+), 1 deletion(-)
drivers/gpu/drm/xe/xe_device_types.h +6 -0
@@ -529,6 +529,12 @@ struct xe_device {/** @pm_notifier: Our PM notifier to perform actions in response to various PM events. */ struct notifier_block pm_notifier; +/** @pm_block: Completion to block validating tasks on suspend / hibernate prepare */ +struct completion pm_block; +/** @rebind_resume_list: List of wq items to kick on resume. */ +struct list_head rebind_resume_list; +/** @rebind_resume_lock: Lock to protect the rebind_resume_list */ +struct mutex rebind_resume_lock;/** @pmt: Support the PMT driver callback interface */ struct {
drivers/gpu/drm/xe/xe_exec.c +9 -0
@@ -237,6 +237,15 @@ retry: goto err_unlock_list; } +/* +* It's OK to block interruptible here with the vm lock held, since +* on task freezing during suspend / hibernate, the call will +* return -ERESTARTSYS and the IOCTL will be rerun. +*/ + err =wait_for_completion_interruptible (&xe->pm_block); +if (err) + goto err_unlock_list; + vm_exec.vm = &vm->gpuvm; vm_exec.flags =DRM_EXEC_INTERRUPTIBLE_WAIT ;if (xe_vm_in_lr_mode (vm)) {
drivers/gpu/drm/xe/xe_pm.c +25 -0
@@ -23,6 +23,7 @@#include "xe_pcode.h" #include "xe_pxp.h" #include "xe_trace.h" +#include "xe_vm.h" #include "xe_wa.h" /**
@@ -285,6 +286,19 @@ static u32 vram_threshold_value(struct xreturn DEFAULT_VRAM_THRESHOLD ; } +static void xe_pm_wake_rebind_workers (struct xe_device *xe) +{ +struct xe_vm *vm, *next; + +mutex_lock (&xe->rebind_resume_lock); +list_for_each_entry_safe (vm, next, &xe->rebind_resume_list, + preempt.pm_activate_link) { +list_del_init (&vm->preempt.pm_activate_link); +xe_vm_resume_rebind_worker (vm); + } +mutex_unlock (&xe->rebind_resume_lock); +} +static int xe_pm_notifier_callback (struct notifier_block *nb,unsigned long action,void *data) {
@@ -294,6 +308,7 @@ static int xe_pm_notifier_callback(strucswitch (action) {case PM_HIBERNATION_PREPARE :case PM_SUSPEND_PREPARE : +reinit_completion (&xe->pm_block);xe_pm_runtime_get (xe); err =xe_bo_evict_all_user (xe);if (err)
@@ -310,6 +325,8 @@ static int xe_pm_notifier_callback(strucbreak ;case PM_POST_HIBERNATION :case PM_POST_SUSPEND : +complete_all (&xe->pm_block); +xe_pm_wake_rebind_workers (xe);xe_bo_notifier_unprepare_all_pinned (xe);xe_pm_runtime_put (xe);break ;
@@ -336,6 +353,14 @@ int xe_pm_init(struct xe_device *xe)if (err)return err; + err =drmm_mutex_init (&xe->drm, &xe->rebind_resume_lock); +if (err) + goto err_unregister; + +init_completion (&xe->pm_block); +complete_all (&xe->pm_block); +INIT_LIST_HEAD (&xe->rebind_resume_list); +/* For now suspend/resume is only allowed with GuC */ if (!xe_device_uc_enabled (xe))return 0 ;
drivers/gpu/drm/xe/xe_vm.c +41 -1
73 lines not on this page · raw message
drivers/gpu/drm/xe/xe_vm.h +2 -0
@@ -268,6 +268,8 @@ struct dma_fence *xe_vm_bind_kernel_bo(s struct xe_exec_queue *q, u64 addr, enum xe_cache_level cache_lvl); +void xe_vm_resume_rebind_worker (struct xe_vm *vm); +/** * xe_vm_resv() - Return's the vm's reservation object * @vm: The vm
drivers/gpu/drm/xe/xe_vm_types.h +5 -0
@@ -286,6 +286,11 @@ struct xe_vm {* BOs */ struct work_struct rebind_work; +/** +* @preempt.pm_activate_link: Link to list of rebind workers to be +* kicked on resume. +*/ +struct list_head pm_activate_link; } preempt;/** @um: unified memory state */
Greg Kroah-Hartman
maintainerPATCH 88/189 drm/amdgpu: fix a memory leak in fence cleanup when unloading
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit 7838fb5f119191403560eca2e23613380c0e425e upstream.
Commit b61badd20b44 ("drm/amdgpu: fix usage slab after free") reordered when amdgpu_fence_driver_sw_fini() was called after that patch, amdgpu_fence_driver_sw_fini() effectively became a no-op as the sched entities we never freed because the ring pointers were already set to NULL. Remove the NULL setting.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 2 -- 1 file changed, 2 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +0 -2
@@ -389,8 +389,6 @@ void amdgpu_ring_fini(struct amdgpu_ringdma_fence_put (ring->vmid_wait); ring->vmid_wait =NULL ; ring->me =0 ; - - ring->adev->rings[ring->idx] =NULL ; }/**
Greg Kroah-Hartman
maintainerPATCH 89/189 drm/amdgpu/vcn: Allow limiting ctx to instance 0 for AV1 at any time
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Rosca <[email protected]>
commit 3318f2d20ce48849855df5e190813826d0bc3653 upstream.
There is no reason to require this to happen on first submitted IB only. We need to wait for the queue to be idle, but it can be done at any time (including when there are multiple video sessions active).
--- drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c | 12 ++++++++---- drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c | 12 ++++++++---- 2 files changed, 16 insertions(+), 8 deletions(-)
drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c +8 -4
@@ -1875,15 +1875,19 @@ static int vcn_v3_0_limit_sched(struct a struct amdgpu_job *job) {struct drm_gpu_scheduler **scheds; - -/* The create msg must be in the first IB submitted */ -if (atomic_read (&job->base.entity->fence_seq)) -return -EINVAL ; +struct dma_fence *fence;/* if VCN0 is harvested, we can't support AV1 */ if (p->adev->vcn.harvest_config &AMDGPU_VCN_HARVEST_VCN0 )return -EINVAL ; +/* wait for all jobs to finish before switching to instance 0 */ + fence =amdgpu_ctx_get_fence (p->ctx, job->base.entity, ~0ull ); +if (fence) { +dma_fence_wait (fence, false); +dma_fence_put (fence); + } + scheds = p->adev->gpu_sched[AMDGPU_HW_IP_VCN_DEC ] [AMDGPU_RING_PRIO_DEFAULT ].sched;drm_sched_entity_modify_sched (job->base.entity, scheds,1 );
drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c +8 -4
@@ -1807,15 +1807,19 @@ static int vcn_v4_0_limit_sched(struct a struct amdgpu_job *job) {struct drm_gpu_scheduler **scheds; - -/* The create msg must be in the first IB submitted */ -if (atomic_read (&job->base.entity->fence_seq)) -return -EINVAL ; +struct dma_fence *fence;/* if VCN0 is harvested, we can't support AV1 */ if (p->adev->vcn.harvest_config &AMDGPU_VCN_HARVEST_VCN0 )return -EINVAL ; +/* wait for all jobs to finish before switching to instance 0 */ + fence =amdgpu_ctx_get_fence (p->ctx, job->base.entity, ~0ull ); +if (fence) { +dma_fence_wait (fence, false); +dma_fence_put (fence); + } + scheds = p->adev->gpu_sched[AMDGPU_HW_IP_VCN_ENC ] [AMDGPU_RING_PRIO_0 ].sched;drm_sched_entity_modify_sched (job->base.entity, scheds,1 );
Greg Kroah-Hartman
maintainerPATCH 90/189 drm/amdgpu/vcn4: Fix IB parsing with multiple engine info packages
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Rosca <[email protected]>
commit 2b10cb58d7a3fd621ec9b2ba765a092e562ef998 upstream.
There can be multiple engine info packages in one IB and the first one may be common engine, not decode/encode.
We need to parse the entire IB instead of stopping after finding first engine info.
--- drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c | 52 +++++++++++++--------------------- 1 file changed, 21 insertions(+), 31 deletions(-)
drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c +21 -31
@@ -1910,22 +1910,16 @@ out:#define RADEON_VCN_ENGINE_TYPE_ENCODE (0x00000002)#define RADEON_VCN_ENGINE_TYPE_DECODE (0x00000003) -#define RADEON_VCN_ENGINE_INFO (0x30000001) -#define RADEON_VCN_ENGINE_INFO_MAX_OFFSET 16 -#define RENCODE_ENCODE_STANDARD_AV1 2#define RENCODE_IB_PARAM_SESSION_INIT 0x00000003 -#define RENCODE_IB_PARAM_SESSION_INIT_MAX_OFFSET 64 -/* return the offset in ib if id is found, -1 otherwise -* to speed up the searching we only search upto max_offset -*/ -static int vcn_v4_0_enc_find_ib_param (struct amdgpu_ib *ib,uint32_t id,int max_offset) +/* return the offset in ib if id is found, -1 otherwise */ +static int vcn_v4_0_enc_find_ib_param (struct amdgpu_ib *ib,uint32_t id,int start) {int i; -for (i =0 ; i < ib->length_dw && i < max_offset && ib->ptr[i] >=8 ; i += ib->ptr[i]/4 ) { +for (i = start; i < ib->length_dw && ib->ptr[i] >=8 ; i += ib->ptr[i] /4 ) {if (ib->ptr[i +1 ] == id)return i; }
@@ -1940,33 +1934,29 @@ static int vcn_v4_0_ring_patch_cs_in_plastruct amdgpu_vcn_decode_buffer *decode_buffer;uint64_t addr;uint32_t val; -int idx; +int idx =0 , sidx;/* The first instance can decode anything */ if (!ring->me)return 0 ; -/* RADEON_VCN_ENGINE_INFO is at the top of ib block */ - idx =vcn_v4_0_enc_find_ib_param (ib,RADEON_VCN_ENGINE_INFO , -RADEON_VCN_ENGINE_INFO_MAX_OFFSET ); -if (idx <0 )/* engine info is missing */ -return 0 ; - - val =amdgpu_ib_get_value (ib, idx +2 );/* RADEON_VCN_ENGINE_TYPE */ -if (val ==RADEON_VCN_ENGINE_TYPE_DECODE ) { - decode_buffer = (struct amdgpu_vcn_decode_buffer *)&ib->ptr[idx +6 ]; - -if (!(decode_buffer->valid_buf_flag &0x1 )) -return 0 ; - - addr = ((u64 )decode_buffer->msg_buffer_address_hi) <<32 | - decode_buffer->msg_buffer_address_lo; -return vcn_v4_0_dec_msg (p, job, addr); - }else if (val ==RADEON_VCN_ENGINE_TYPE_ENCODE ) { - idx =vcn_v4_0_enc_find_ib_param (ib,RENCODE_IB_PARAM_SESSION_INIT , -RENCODE_IB_PARAM_SESSION_INIT_MAX_OFFSET ); -if (idx >=0 && ib->ptr[idx +2 ] ==RENCODE_ENCODE_STANDARD_AV1 ) -return vcn_v4_0_limit_sched (p, job); +while ((idx =vcn_v4_0_enc_find_ib_param (ib,RADEON_VCN_ENGINE_INFO , idx)) >=0 ) { + val =amdgpu_ib_get_value (ib, idx +2 );/* RADEON_VCN_ENGINE_TYPE */ +if (val ==RADEON_VCN_ENGINE_TYPE_DECODE ) { + decode_buffer = (struct amdgpu_vcn_decode_buffer *)&ib->ptr[idx +6 ]; + +if (!(decode_buffer->valid_buf_flag &0x1 )) +return 0 ; + + addr = ((u64 )decode_buffer->msg_buffer_address_hi) <<32 | + decode_buffer->msg_buffer_address_lo; +return vcn_v4_0_dec_msg (p, job, addr); + }else if (val ==RADEON_VCN_ENGINE_TYPE_ENCODE ) { + sidx =vcn_v4_0_enc_find_ib_param (ib,RENCODE_IB_PARAM_SESSION_INIT , idx); +if (sidx >=0 && ib->ptr[sidx +2 ] ==RENCODE_ENCODE_STANDARD_AV1 ) +return vcn_v4_0_limit_sched (p, job); + } + idx += ib->ptr[idx] /4 ; }return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 91/189 drm/amd/display: Correct sequences and delays for DCN35 PG & RCG
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ovidiu Bunea <[email protected]>
commit 70f0b051f82d0234ade2f6753f72a2610048db3b upstream.
[why]
The current PG & RCG programming in driver has some gaps and incorrect sequences.
[how]
Added delays after ungating clocks to allow ramp up, increased polling to allow more time for power up, and removed the incorrect sequences.
--- drivers/gpu/drm/amd/display/dc/dc.h | 1 drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c | 74 +++++---- drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c | 115 ++------------- drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c | 3 drivers/gpu/drm/amd/display/dc/hwss/dcn351/dcn351_init.c | 3 drivers/gpu/drm/amd/display/dc/inc/hw/pg_cntl.h | 1 drivers/gpu/drm/amd/display/dc/pg/dcn35/dcn35_pg_cntl.c | 78 ++++++---- 7 files changed, 111 insertions(+), 164 deletions(-)
drivers/gpu/drm/amd/display/dc/dc.h +1 -0
@@ -1095,6 +1095,7 @@ struct dc_debug_options {bool enable_hblank_borrow;bool force_subvp_df_throttle;uint32_t acpi_transition_bitmasks[MAX_PIPES ]; +bool enable_pg_cntl_debug_logs; };
drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c +39 -35
190 lines not on this page · raw message
drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c +20 -95
169 lines not on this page · raw message
drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c +0 -3
@@ -115,7 +115,6 @@ static const struct hw_sequencer_funcs d .exit_optimized_pwr_state = dcn21_exit_optimized_pwr_state, .update_visual_confirm_color = dcn10_update_visual_confirm_color, .apply_idle_power_optimizations = dcn35_apply_idle_power_optimizations, - .update_dsc_pg = dcn32_update_dsc_pg, .calc_blocks_to_gate = dcn35_calc_blocks_to_gate, .calc_blocks_to_ungate = dcn35_calc_blocks_to_ungate, .hw_block_power_up = dcn35_hw_block_power_up,
@@ -150,7 +149,6 @@ static const struct hwseq_private_funcs .plane_atomic_disable = dcn35_plane_atomic_disable,//.plane_atomic_disable = dcn20_plane_atomic_disable,/*todo*/ //.hubp_pg_control = dcn35_hubp_pg_control, - .enable_power_gating_plane = dcn35_enable_power_gating_plane, .dpp_root_clock_control = dcn35_dpp_root_clock_control, .dpstream_root_clock_control = dcn35_dpstream_root_clock_control, .physymclk_root_clock_control = dcn35_physymclk_root_clock_control,
@@ -165,7 +163,6 @@ static const struct hwseq_private_funcs .calculate_dccg_k1_k2_values = dcn32_calculate_dccg_k1_k2_values, .resync_fifo_dccg_dio = dcn314_resync_fifo_dccg_dio, .is_dp_dig_pixel_rate_div_policy = dcn35_is_dp_dig_pixel_rate_div_policy, - .dsc_pg_control = dcn35_dsc_pg_control, .dsc_pg_status = dcn32_dsc_pg_status, .enable_plane = dcn35_enable_plane, .wait_for_pipe_update_if_needed = dcn10_wait_for_pipe_update_if_needed,
drivers/gpu/drm/amd/display/dc/hwss/dcn351/dcn351_init.c +0 -3
@@ -114,7 +114,6 @@ static const struct hw_sequencer_funcs d .exit_optimized_pwr_state = dcn21_exit_optimized_pwr_state, .update_visual_confirm_color = dcn10_update_visual_confirm_color, .apply_idle_power_optimizations = dcn35_apply_idle_power_optimizations, - .update_dsc_pg = dcn32_update_dsc_pg, .calc_blocks_to_gate = dcn351_calc_blocks_to_gate, .calc_blocks_to_ungate = dcn351_calc_blocks_to_ungate, .hw_block_power_up = dcn351_hw_block_power_up,
@@ -145,7 +144,6 @@ static const struct hwseq_private_funcs .plane_atomic_disable = dcn35_plane_atomic_disable,//.plane_atomic_disable = dcn20_plane_atomic_disable,/*todo*/ //.hubp_pg_control = dcn35_hubp_pg_control, - .enable_power_gating_plane = dcn35_enable_power_gating_plane, .dpp_root_clock_control = dcn35_dpp_root_clock_control, .dpstream_root_clock_control = dcn35_dpstream_root_clock_control, .physymclk_root_clock_control = dcn35_physymclk_root_clock_control,
@@ -159,7 +157,6 @@ static const struct hwseq_private_funcs .setup_hpo_hw_control = dcn35_setup_hpo_hw_control, .calculate_dccg_k1_k2_values = dcn32_calculate_dccg_k1_k2_values, .is_dp_dig_pixel_rate_div_policy = dcn35_is_dp_dig_pixel_rate_div_policy, - .dsc_pg_control = dcn35_dsc_pg_control, .dsc_pg_status = dcn32_dsc_pg_status, .enable_plane = dcn35_enable_plane, .wait_for_pipe_update_if_needed = dcn10_wait_for_pipe_update_if_needed,
drivers/gpu/drm/amd/display/dc/inc/hw/pg_cntl.h +1 -0
@@ -47,6 +47,7 @@ struct pg_cntl_funcs {void (*optc_pg_control)(struct pg_cntl *pg_cntl,unsigned int optc_inst,bool power_on);void (*dwb_pg_control)(struct pg_cntl *pg_cntl,bool power_on);void (*init_pg_status)(struct pg_cntl *pg_cntl); + void (*print_pg_status)(struct pg_cntl *pg_cntl, const char *debug_func, const char *debug_log); };#endif //__DC_PG_CNTL_H__
drivers/gpu/drm/amd/display/dc/pg/dcn35/dcn35_pg_cntl.c +50 -28
152 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 92/189 drm/amd/display: remove oem i2c adapter on finish
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Geoffrey McRae <[email protected]>
commit 1dfd2864a1c4909147663e5a27c055f50f7c2796 upstream.
Fixes a bug where unbinding of the GPU would leave the oem i2c adapter registered resulting in a null pointer dereference when applications try to access the invalid device.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +12 -1
@@ -2910,6 +2910,17 @@ static int dm_oem_i2c_hw_init(struct amdreturn 0 ; } +static void dm_oem_i2c_hw_fini (struct amdgpu_device *adev) +{ +struct amdgpu_display_manager *dm = &adev->dm; + +if (dm->oem_i2c) { +i2c_del_adapter (&dm->oem_i2c->base); +kfree (dm->oem_i2c); + dm->oem_i2c =NULL ; + } +} +/** * dm_hw_init() - Initialize DC device * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
@@ -2960,7 +2971,7 @@ static int dm_hw_fini(struct amdgpu_ip_b {struct amdgpu_device *adev = ip_block->adev; -kfree (adev->dm.oem_i2c); +dm_oem_i2c_hw_fini (adev);amdgpu_dm_hpd_fini (adev);
Greg Kroah-Hartman
maintainerPATCH 93/189 drm/edid: Define the quirks in an enum list
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Imre Deak <[email protected]>
commit 5281cbe0b55a1ff9c6c29361540016873bdc506e upstream.
An enum list is better suited to define a quirk list, do that. This makes looking up a quirk more robust and also allows for separating quirks internal to the EDID parser and global quirks which can be queried outside of the EDID parser (added as a follow-up).
--- drivers/gpu/drm/drm_edid.c | 218 +++++++++++++++++++++++---------------------- 1 file changed, 112 insertions(+), 106 deletions(-)
drivers/gpu/drm/drm_edid.c +112 -106
@@ -66,34 +66,36 @@ static int oui(u8 first, u8 second, u8 t* on as many displays as possible). */ -/* First detailed mode wrong, use largest 60Hz mode */ -#define EDID_QUIRK_PREFER_LARGE_60 (1 << 0) -/* Reported 135MHz pixel clock is too high, needs adjustment */ -#define EDID_QUIRK_135_CLOCK_TOO_HIGH (1 << 1) -/* Prefer the largest mode at 75 Hz */ -#define EDID_QUIRK_PREFER_LARGE_75 (1 << 2) -/* Detail timing is in cm not mm */ -#define EDID_QUIRK_DETAILED_IN_CM (1 << 3) -/* Detailed timing descriptors have bogus size values, so just take the -* maximum size and use that. -*/ -#define EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE (1 << 4) -/* use +hsync +vsync for detailed mode */ -#define EDID_QUIRK_DETAILED_SYNC_PP (1 << 6) -/* Force reduced-blanking timings for detailed modes */ -#define EDID_QUIRK_FORCE_REDUCED_BLANKING (1 << 7) -/* Force 8bpc */ -#define EDID_QUIRK_FORCE_8BPC (1 << 8) -/* Force 12bpc */ -#define EDID_QUIRK_FORCE_12BPC (1 << 9) -/* Force 6bpc */ -#define EDID_QUIRK_FORCE_6BPC (1 << 10) -/* Force 10bpc */ -#define EDID_QUIRK_FORCE_10BPC (1 << 11) -/* Non desktop display (i.e. HMD) */ -#define EDID_QUIRK_NON_DESKTOP (1 << 12) -/* Cap the DSC target bitrate to 15bpp */ -#define EDID_QUIRK_CAP_DSC_15BPP (1 << 13) +enum drm_edid_internal_quirk { +/* First detailed mode wrong, use largest 60Hz mode */ +EDID_QUIRK_PREFER_LARGE_60 , +/* Reported 135MHz pixel clock is too high, needs adjustment */ +EDID_QUIRK_135_CLOCK_TOO_HIGH , +/* Prefer the largest mode at 75 Hz */ +EDID_QUIRK_PREFER_LARGE_75 , +/* Detail timing is in cm not mm */ +EDID_QUIRK_DETAILED_IN_CM , +/* Detailed timing descriptors have bogus size values, so just take the +* maximum size and use that. +*/ +EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE , +/* use +hsync +vsync for detailed mode */ +EDID_QUIRK_DETAILED_SYNC_PP , +/* Force reduced-blanking timings for detailed modes */ +EDID_QUIRK_FORCE_REDUCED_BLANKING , +/* Force 8bpc */ +EDID_QUIRK_FORCE_8BPC , +/* Force 12bpc */ +EDID_QUIRK_FORCE_12BPC , +/* Force 6bpc */ +EDID_QUIRK_FORCE_6BPC , +/* Force 10bpc */ +EDID_QUIRK_FORCE_10BPC , +/* Non desktop display (i.e. HMD) */ +EDID_QUIRK_NON_DESKTOP , +/* Cap the DSC target bitrate to 15bpp */ +EDID_QUIRK_CAP_DSC_15BPP , +};#define MICROSOFT_IEEE_OUI 0xca125c
@@ -128,124 +130,124 @@ static const struct edid_quirk {u32 quirks; } edid_quirk_list[] = {/* Acer AL1706 */ -EDID_QUIRK ('A' ,'C' ,'R' ,44358 ,EDID_QUIRK_PREFER_LARGE_60 ), +EDID_QUIRK ('A' ,'C' ,'R' ,44358 ,BIT (EDID_QUIRK_PREFER_LARGE_60 )),/* Acer F51 */ -EDID_QUIRK ('A' ,'P' ,'I' ,0x7602 ,EDID_QUIRK_PREFER_LARGE_60 ), +EDID_QUIRK ('A' ,'P' ,'I' ,0x7602 ,BIT (EDID_QUIRK_PREFER_LARGE_60 )),/* AEO model 0 reports 8 bpc, but is a 6 bpc panel */ -EDID_QUIRK ('A' ,'E' ,'O' ,0 ,EDID_QUIRK_FORCE_6BPC ), +EDID_QUIRK ('A' ,'E' ,'O' ,0 ,BIT (EDID_QUIRK_FORCE_6BPC )),/* BenQ GW2765 */ -EDID_QUIRK ('B' ,'N' ,'Q' ,0x78d6 ,EDID_QUIRK_FORCE_8BPC ), +EDID_QUIRK ('B' ,'N' ,'Q' ,0x78d6 ,BIT (EDID_QUIRK_FORCE_8BPC )),/* BOE model on HP Pavilion 15-n233sl reports 8 bpc, but is a 6 bpc panel */ -EDID_QUIRK ('B' ,'O' ,'E' ,0x78b ,EDID_QUIRK_FORCE_6BPC ), +EDID_QUIRK ('B' ,'O' ,'E' ,0x78b ,BIT (EDID_QUIRK_FORCE_6BPC )),/* CPT panel of Asus UX303LA reports 8 bpc, but is a 6 bpc panel */ -EDID_QUIRK ('C' ,'P' ,'T' ,0x17df ,EDID_QUIRK_FORCE_6BPC ), +EDID_QUIRK ('C' ,'P' ,'T' ,0x17df ,BIT (EDID_QUIRK_FORCE_6BPC )),/* SDC panel of Lenovo B50-80 reports 8 bpc, but is a 6 bpc panel */ -EDID_QUIRK ('S' ,'D' ,'C' ,0x3652 ,EDID_QUIRK_FORCE_6BPC ), +EDID_QUIRK ('S' ,'D' ,'C' ,0x3652 ,BIT (EDID_QUIRK_FORCE_6BPC )),/* BOE model 0x0771 reports 8 bpc, but is a 6 bpc panel */ -EDID_QUIRK ('B' ,'O' ,'E' ,0x0771 ,EDID_QUIRK_FORCE_6BPC ), +EDID_QUIRK ('B' ,'O' ,'E' ,0x0771 ,BIT (EDID_QUIRK_FORCE_6BPC )),/* Belinea 10 15 55 */ -EDID_QUIRK ('M' ,'A' ,'X' ,1516 ,EDID_QUIRK_PREFER_LARGE_60 ), -EDID_QUIRK ('M' ,'A' ,'X' ,0x77e ,EDID_QUIRK_PREFER_LARGE_60 ), +EDID_QUIRK ('M' ,'A' ,'X' ,1516 ,BIT (EDID_QUIRK_PREFER_LARGE_60 )), +EDID_QUIRK ('M' ,'A' ,'X' ,0x77e ,BIT (EDID_QUIRK_PREFER_LARGE_60 )),/* Envision Peripherals, Inc. EN-7100e */ -EDID_QUIRK ('E' ,'P' ,'I' ,59264 ,EDID_QUIRK_135_CLOCK_TOO_HIGH ), +EDID_QUIRK ('E' ,'P' ,'I' ,59264 ,BIT (EDID_QUIRK_135_CLOCK_TOO_HIGH )),/* Envision EN2028 */ -EDID_QUIRK ('E' ,'P' ,'I' ,8232 ,EDID_QUIRK_PREFER_LARGE_60 ), +EDID_QUIRK ('E' ,'P' ,'I' ,8232 ,BIT (EDID_QUIRK_PREFER_LARGE_60 )),/* Funai Electronics PM36B */ -EDID_QUIRK ('F' ,'C' ,'M' ,13600 ,EDID_QUIRK_PREFER_LARGE_75 | -EDID_QUIRK_DETAILED_IN_CM ), +EDID_QUIRK ('F' ,'C' ,'M' ,13600 ,BIT (EDID_QUIRK_PREFER_LARGE_75 ) | +BIT (EDID_QUIRK_DETAILED_IN_CM )),/* LG 27GP950 */ -EDID_QUIRK ('G' ,'S' ,'M' ,0x5bbf ,EDID_QUIRK_CAP_DSC_15BPP ), +EDID_QUIRK ('G' ,'S' ,'M' ,0x5bbf ,BIT (EDID_QUIRK_CAP_DSC_15BPP )),/* LG 27GN950 */ -EDID_QUIRK ('G' ,'S' ,'M' ,0x5b9a ,EDID_QUIRK_CAP_DSC_15BPP ), +EDID_QUIRK ('G' ,'S' ,'M' ,0x5b9a ,BIT (EDID_QUIRK_CAP_DSC_15BPP )),/* LGD panel of HP zBook 17 G2, eDP 10 bpc, but reports unknown bpc */ -EDID_QUIRK ('L' ,'G' ,'D' ,764 ,EDID_QUIRK_FORCE_10BPC ), +EDID_QUIRK ('L' ,'G' ,'D' ,764 ,BIT (EDID_QUIRK_FORCE_10BPC )),/* LG Philips LCD LP154W01-A5 */ -EDID_QUIRK ('L' ,'P' ,'L' ,0 ,EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE ), -EDID_QUIRK ('L' ,'P' ,'L' ,0x2a00 ,EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE ), +EDID_QUIRK ('L' ,'P' ,'L' ,0 ,BIT (EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE )), +EDID_QUIRK ('L' ,'P' ,'L' ,0x2a00 ,BIT (EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE )),/* Samsung SyncMaster 205BW. Note: irony */ -EDID_QUIRK ('S' ,'A' ,'M' ,541 ,EDID_QUIRK_DETAILED_SYNC_PP ), +EDID_QUIRK ('S' ,'A' ,'M' ,541 ,BIT (EDID_QUIRK_DETAILED_SYNC_PP )),/* Samsung SyncMaster 22[5-6]BW */ -EDID_QUIRK ('S' ,'A' ,'M' ,596 ,EDID_QUIRK_PREFER_LARGE_60 ), -EDID_QUIRK ('S' ,'A' ,'M' ,638 ,EDID_QUIRK_PREFER_LARGE_60 ), +EDID_QUIRK ('S' ,'A' ,'M' ,596 ,BIT (EDID_QUIRK_PREFER_LARGE_60 )), +EDID_QUIRK ('S' ,'A' ,'M' ,638 ,BIT (EDID_QUIRK_PREFER_LARGE_60 )),/* Sony PVM-2541A does up to 12 bpc, but only reports max 8 bpc */ -EDID_QUIRK ('S' ,'N' ,'Y' ,0x2541 ,EDID_QUIRK_FORCE_12BPC ), +EDID_QUIRK ('S' ,'N' ,'Y' ,0x2541 ,BIT (EDID_QUIRK_FORCE_12BPC )),/* ViewSonic VA2026w */ -EDID_QUIRK ('V' ,'S' ,'C' ,5020 ,EDID_QUIRK_FORCE_REDUCED_BLANKING ), +EDID_QUIRK ('V' ,'S' ,'C' ,5020 ,BIT (EDID_QUIRK_FORCE_REDUCED_BLANKING )),/* Medion MD 30217 PG */ -EDID_QUIRK ('M' ,'E' ,'D' ,0x7b8 ,EDID_QUIRK_PREFER_LARGE_75 ), +EDID_QUIRK ('M' ,'E' ,'D' ,0x7b8 ,BIT (EDID_QUIRK_PREFER_LARGE_75 )),/* Lenovo G50 */ -EDID_QUIRK ('S' ,'D' ,'C' ,18514 ,EDID_QUIRK_FORCE_6BPC ), +EDID_QUIRK ('S' ,'D' ,'C' ,18514 ,BIT (EDID_QUIRK_FORCE_6BPC )),/* Panel in Samsung NP700G7A-S01PL notebook reports 6bpc */ -EDID_QUIRK ('S' ,'E' ,'C' ,0xd033 ,EDID_QUIRK_FORCE_8BPC ), +EDID_QUIRK ('S' ,'E' ,'C' ,0xd033 ,BIT (EDID_QUIRK_FORCE_8BPC )),/* Rotel RSX-1058 forwards sink's EDID but only does HDMI 1.1*/ -EDID_QUIRK ('E' ,'T' ,'R' ,13896 ,EDID_QUIRK_FORCE_8BPC ), +EDID_QUIRK ('E' ,'T' ,'R' ,13896 ,BIT (EDID_QUIRK_FORCE_8BPC )),/* Valve Index Headset */ -EDID_QUIRK ('V' ,'L' ,'V' ,0x91a8 ,EDID_QUIRK_NON_DESKTOP ), -EDID_QUIRK ('V' ,'L' ,'V' ,0x91b0 ,EDID_QUIRK_NON_DESKTOP ), -EDID_QUIRK ('V' ,'L' ,'V' ,0x91b1 ,EDID_QUIRK_NON_DESKTOP ), -EDID_QUIRK ('V' ,'L' ,'V' ,0x91b2 ,EDID_QUIRK_NON_DESKTOP ), -EDID_QUIRK ('V' ,'L' ,'V' ,0x91b3 ,EDID_QUIRK_NON_DESKTOP ), -EDID_QUIRK ('V' ,'L' ,'V' ,0x91b4 ,EDID_QUIRK_NON_DESKTOP ), -EDID_QUIRK ('V' ,'L' ,'V' ,0x91b5 ,EDID_QUIRK_NON_DESKTOP ), -EDID_QUIRK ('V' ,'L' ,'V' ,0x91b6 ,EDID_QUIRK_NON_DESKTOP ), -EDID_QUIRK ('V' ,'L' ,'V' ,0x91b7 ,EDID_QUIRK_NON_DESKTOP ), -EDID_QUIRK ('V' ,'L' ,'V' ,0x91b8 ,EDID_QUIRK_NON_DESKTOP ), -EDID_QUIRK ('V' ,'L' ,'V' ,0x91b9 ,EDID_QUIRK_NON_DESKTOP ), -EDID_QUIRK ('V' ,'L' ,'V' ,0x91ba ,EDID_QUIRK_NON_DESKTOP ), -EDID_QUIRK ('V' ,'L' ,'V' ,0x91bb ,EDID_QUIRK_NON_DESKTOP ), -EDID_QUIRK ('V' ,'L' ,'V' ,0x91bc ,EDID_QUIRK_NON_DESKTOP ), -EDID_QUIRK ('V' ,'L' ,'V' ,0x91bd ,EDID_QUIRK_NON_DESKTOP ), -EDID_QUIRK ('V' ,'L' ,'V' ,0x91be ,EDID_QUIRK_NON_DESKTOP ), -EDID_QUIRK ('V' ,'L' ,'V' ,0x91bf ,EDID_QUIRK_NON_DESKTOP ), +EDID_QUIRK ('V' ,'L' ,'V' ,0x91a8 ,BIT (EDID_QUIRK_NON_DESKTOP )), +EDID_QUIRK ('V' ,'L' ,'V' ,0x91b0 ,BIT (EDID_QUIRK_NON_DESKTOP )), +EDID_QUIRK ('V' ,'L' ,'V' ,0x91b1 ,BIT (EDID_QUIRK_NON_DESKTOP )), +EDID_QUIRK ('V' ,'L' ,'V' ,0x91b2 ,BIT (EDID_QUIRK_NON_DESKTOP )), +EDID_QUIRK ('V' ,'L' ,'V' ,0x91b3 ,BIT (EDID_QUIRK_NON_DESKTOP )), +EDID_QUIRK ('V' ,'L' ,'V' ,0x91b4 ,BIT (EDID_QUIRK_NON_DESKTOP )), +EDID_QUIRK ('V' ,'L' ,'V' ,0x91b5 ,BIT (EDID_QUIRK_NON_DESKTOP )), +EDID_QUIRK ('V' ,'L' ,'V' ,0x91b6 ,BIT (EDID_QUIRK_NON_DESKTOP )), +EDID_QUIRK ('V' ,'L' ,'V' ,0x91b7 ,BIT (EDID_QUIRK_NON_DESKTOP )), +EDID_QUIRK ('V' ,'L' ,'V' ,0x91b8 ,BIT (EDID_QUIRK_NON_DESKTOP )), +EDID_QUIRK ('V' ,'L' ,'V' ,0x91b9 ,BIT (EDID_QUIRK_NON_DESKTOP )), +EDID_QUIRK ('V' ,'L' ,'V' ,0x91ba ,BIT (EDID_QUIRK_NON_DESKTOP )), +EDID_QUIRK ('V' ,'L' ,'V' ,0x91bb ,BIT (EDID_QUIRK_NON_DESKTOP )), +EDID_QUIRK ('V' ,'L' ,'V' ,0x91bc ,BIT (EDID_QUIRK_NON_DESKTOP )), +EDID_QUIRK ('V' ,'L' ,'V' ,0x91bd ,BIT (EDID_QUIRK_NON_DESKTOP )), +EDID_QUIRK ('V' ,'L' ,'V' ,0x91be ,BIT (EDID_QUIRK_NON_DESKTOP )), +EDID_QUIRK ('V' ,'L' ,'V' ,0x91bf ,BIT (EDID_QUIRK_NON_DESKTOP )),/* HTC Vive and Vive Pro VR Headsets */ -EDID_QUIRK ('H' ,'V' ,'R' ,0xaa01 ,EDID_QUIRK_NON_DESKTOP ), -EDID_QUIRK ('H' ,'V' ,'R' ,0xaa02 ,EDID_QUIRK_NON_DESKTOP ), +EDID_QUIRK ('H' ,'V' ,'R' ,0xaa01 ,BIT (EDID_QUIRK_NON_DESKTOP )), +EDID_QUIRK ('H' ,'V' ,'R' ,0xaa02 ,BIT (EDID_QUIRK_NON_DESKTOP )),/* Oculus Rift DK1, DK2, CV1 and Rift S VR Headsets */ -EDID_QUIRK ('O' ,'V' ,'R' ,0x0001 ,EDID_QUIRK_NON_DESKTOP ), -EDID_QUIRK ('O' ,'V' ,'R' ,0x0003 ,EDID_QUIRK_NON_DESKTOP ), -EDID_QUIRK ('O' ,'V' ,'R' ,0x0004 ,EDID_QUIRK_NON_DESKTOP ), -EDID_QUIRK ('O' ,'V' ,'R' ,0x0012 ,EDID_QUIRK_NON_DESKTOP ), +EDID_QUIRK ('O' ,'V' ,'R' ,0x0001 ,BIT (EDID_QUIRK_NON_DESKTOP )), +EDID_QUIRK ('O' ,'V' ,'R' ,0x0003 ,BIT (EDID_QUIRK_NON_DESKTOP )), +EDID_QUIRK ('O' ,'V' ,'R' ,0x0004 ,BIT (EDID_QUIRK_NON_DESKTOP )), +EDID_QUIRK ('O' ,'V' ,'R' ,0x0012 ,BIT (EDID_QUIRK_NON_DESKTOP )),/* Windows Mixed Reality Headsets */ -EDID_QUIRK ('A' ,'C' ,'R' ,0x7fce ,EDID_QUIRK_NON_DESKTOP ), -EDID_QUIRK ('L' ,'E' ,'N' ,0x0408 ,EDID_QUIRK_NON_DESKTOP ), -EDID_QUIRK ('F' ,'U' ,'J' ,0x1970 ,EDID_QUIRK_NON_DESKTOP ), -EDID_QUIRK ('D' ,'E' ,'L' ,0x7fce ,EDID_QUIRK_NON_DESKTOP ), -EDID_QUIRK ('S' ,'E' ,'C' ,0x144a ,EDID_QUIRK_NON_DESKTOP ), -EDID_QUIRK ('A' ,'U' ,'S' ,0xc102 ,EDID_QUIRK_NON_DESKTOP ), +EDID_QUIRK ('A' ,'C' ,'R' ,0x7fce ,BIT (EDID_QUIRK_NON_DESKTOP )), +EDID_QUIRK ('L' ,'E' ,'N' ,0x0408 ,BIT (EDID_QUIRK_NON_DESKTOP )), +EDID_QUIRK ('F' ,'U' ,'J' ,0x1970 ,BIT (EDID_QUIRK_NON_DESKTOP )), +EDID_QUIRK ('D' ,'E' ,'L' ,0x7fce ,BIT (EDID_QUIRK_NON_DESKTOP )), +EDID_QUIRK ('S' ,'E' ,'C' ,0x144a ,BIT (EDID_QUIRK_NON_DESKTOP )), +EDID_QUIRK ('A' ,'U' ,'S' ,0xc102 ,BIT (EDID_QUIRK_NON_DESKTOP )),/* Sony PlayStation VR Headset */ -EDID_QUIRK ('S' ,'N' ,'Y' ,0x0704 ,EDID_QUIRK_NON_DESKTOP ), +EDID_QUIRK ('S' ,'N' ,'Y' ,0x0704 ,BIT (EDID_QUIRK_NON_DESKTOP )),/* Sensics VR Headsets */ -EDID_QUIRK ('S' ,'E' ,'N' ,0x1019 ,EDID_QUIRK_NON_DESKTOP ), +EDID_QUIRK ('S' ,'E' ,'N' ,0x1019 ,BIT (EDID_QUIRK_NON_DESKTOP )),/* OSVR HDK and HDK2 VR Headsets */ -EDID_QUIRK ('S' ,'V' ,'R' ,0x1019 ,EDID_QUIRK_NON_DESKTOP ), - EDID_QUIRK('A', 'U', 'O', 0x1111, EDID_QUIRK_NON_DESKTOP), +EDID_QUIRK ('S' ,'V' ,'R' ,0x1019 ,BIT (EDID_QUIRK_NON_DESKTOP )), + EDID_QUIRK('A', 'U', 'O', 0x1111, BIT(EDID_QUIRK_NON_DESKTOP)), };/*
@@ -2951,6 +2953,12 @@ static u32 edid_get_quirks(const structreturn 0 ; } +static bool drm_edid_has_internal_quirk (struct drm_connector *connector, +enum drm_edid_internal_quirk quirk) +{ +return connector->display_info.quirks &BIT (quirk); +} +#define MODE_SIZE (m) ((m)->hdisplay * (m)->vdisplay)#define MODE_REFRESH_DIFF (c,t) (abs((c) - (t)))
@@ -2960,7 +2968,6 @@ static u32 edid_get_quirks(const struct*/ static void edid_fixup_preferred (struct drm_connector *connector) { -const struct drm_display_info *info = &connector->display_info;struct drm_display_mode *t, *cur_mode, *preferred_mode;int target_refresh =0 ;int cur_vrefresh, preferred_vrefresh;
@@ -2968,9 +2975,9 @@ static void edid_fixup_preferred(structif (list_empty (&connector->probed_modes))return ; -if (info->quirks &EDID_QUIRK_PREFER_LARGE_60 ) +if (drm_edid_has_internal_quirk (connector,EDID_QUIRK_PREFER_LARGE_60 )) target_refresh =60 ; -if (info->quirks &EDID_QUIRK_PREFER_LARGE_75 ) +if (drm_edid_has_internal_quirk (connector,EDID_QUIRK_PREFER_LARGE_75 )) target_refresh =75 ; preferred_mode = list_first_entry(&connector->probed_modes,
@@ -3474,7 +3481,6 @@ static struct drm_display_mode *drm_modeconst struct drm_edid *drm_edid, const struct detailed_timing *timing) { - const struct drm_display_info *info = &connector->display_info; struct drm_device *dev = connector->dev;struct drm_display_mode *mode;const struct detailed_pixel_timing *pt = &timing->data.pixel_data;
@@ -3508,7 +3514,7 @@ static struct drm_display_mode *drm_modereturn NULL ; } -if (info->quirks &EDID_QUIRK_FORCE_REDUCED_BLANKING ) { +if (drm_edid_has_internal_quirk (connector,EDID_QUIRK_FORCE_REDUCED_BLANKING )) { mode =drm_cvt_mode (dev, hactive, vactive,60 , true, false, false);if (!mode)return NULL ;
@@ -3520,7 +3526,7 @@ static struct drm_display_mode *drm_modeif (!mode)return NULL ; -if (info->quirks &EDID_QUIRK_135_CLOCK_TOO_HIGH ) +if (drm_edid_has_internal_quirk (connector,EDID_QUIRK_135_CLOCK_TOO_HIGH )) mode->clock =1088 *10 ;else mode->clock =le16_to_cpu (timing->pixel_clock) *10 ;
@@ -3551,7 +3557,7 @@ static struct drm_display_mode *drm_modedrm_mode_do_interlace_quirk (mode, pt); -if (info->quirks &EDID_QUIRK_DETAILED_SYNC_PP ) { +if (drm_edid_has_internal_quirk (connector,EDID_QUIRK_DETAILED_SYNC_PP )) { mode->flags |=DRM_MODE_FLAG_PHSYNC |DRM_MODE_FLAG_PVSYNC ; }else { mode->flags |= (pt->misc & DRM_EDID_PT_HSYNC_POSITIVE) ?
@@ -3564,12 +3570,12 @@ set_size: mode->width_mm = pt->width_mm_lo | (pt->width_height_mm_hi &0xf0 ) <<4 ; mode->height_mm = pt->height_mm_lo | (pt->width_height_mm_hi &0xf ) <<8 ; -if (info->quirks &EDID_QUIRK_DETAILED_IN_CM ) { +if (drm_edid_has_internal_quirk (connector,EDID_QUIRK_DETAILED_IN_CM )) { mode->width_mm *=10 ; mode->height_mm *=10 ; } -if (info->quirks &EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE ) { +if (drm_edid_has_internal_quirk (connector,EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE )) { mode->width_mm = drm_edid->edid->width_cm *10 ; mode->height_mm = drm_edid->edid->height_cm *10 ; }
@@ -6734,26 +6740,26 @@ static void update_display_info(struct ddrm_update_mso (connector, drm_edid); out: -if (info->quirks &EDID_QUIRK_NON_DESKTOP ) { +if (drm_edid_has_internal_quirk (connector,EDID_QUIRK_NON_DESKTOP )) {drm_dbg_kms (connector->dev,"[CONNECTOR:%d:%s] Non-desktop display%s\n" , connector->base.id, connector->name, info->non_desktop ?" (redundant quirk)" :"" ); info->non_desktop = true; } -if (info->quirks &EDID_QUIRK_CAP_DSC_15BPP ) +if (drm_edid_has_internal_quirk (connector,EDID_QUIRK_CAP_DSC_15BPP )) info->max_dsc_bpp =15 ; -if (info->quirks &EDID_QUIRK_FORCE_6BPC ) +if (drm_edid_has_internal_quirk (connector,EDID_QUIRK_FORCE_6BPC )) info->bpc =6 ; -if (info->quirks &EDID_QUIRK_FORCE_8BPC ) +if (drm_edid_has_internal_quirk (connector,EDID_QUIRK_FORCE_8BPC )) info->bpc =8 ; -if (info->quirks &EDID_QUIRK_FORCE_10BPC ) +if (drm_edid_has_internal_quirk (connector,EDID_QUIRK_FORCE_10BPC )) info->bpc =10 ; -if (info->quirks &EDID_QUIRK_FORCE_12BPC ) +if (drm_edid_has_internal_quirk (connector,EDID_QUIRK_FORCE_12BPC )) info->bpc =12 ;/* Depends on info->cea_rev set by drm_parse_cea_ext() above */
@@ -6918,7 +6924,6 @@ static int add_displayid_detailed_modes(static int _drm_edid_connector_add_modes (struct drm_connector *connector,const struct drm_edid *drm_edid) { -const struct drm_display_info *info = &connector->display_info;int num_modes =0 ;if (!drm_edid)
@@ -6948,7 +6953,8 @@ static int _drm_edid_connector_add_modesif (drm_edid->edid->features &DRM_EDID_FEATURE_CONTINUOUS_FREQ ) num_modes +=add_inferred_modes (connector, drm_edid); -if (info->quirks & (EDID_QUIRK_PREFER_LARGE_60 |EDID_QUIRK_PREFER_LARGE_75 )) +if (drm_edid_has_internal_quirk (connector,EDID_QUIRK_PREFER_LARGE_60 ) || +drm_edid_has_internal_quirk (connector,EDID_QUIRK_PREFER_LARGE_75 ))edid_fixup_preferred (connector);return num_modes;
Greg Kroah-Hartman
maintainerPATCH 94/189 drm/edid: Add support for quirks visible to DRM core and drivers
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Imre Deak <[email protected]>
commit 0b4aa85e8981198e23a68d50ee3c490ccd7f8311 upstream.
Add support for EDID based quirks which can be queried outside of the EDID parser iteself by DRM core and drivers. There are at least two such quirks applicable to all drivers: the DPCD register access probe quirk and the 128b/132b DPRX Lane Count Conversion quirk (see 3.5.2.16.3 in the v2.1a DP Standard). The latter quirk applies to panels with specific EDID panel names, support for defining a quirk this way will be added as a follow-up.
v2: Reset global_quirks in drm_reset_display_info().
v3: (Jani)
- Use one list for both the global and internal quirks.
- Drop change for panel name specific quirks.
- Add comment about the way quirks should be queried.
--- drivers/gpu/drm/drm_edid.c | 8 +++++++- include/drm/drm_connector.h | 4 +++- include/drm/drm_edid.h | 5 +++++ 3 files changed, 15 insertions(+), 2 deletions(-)
drivers/gpu/drm/drm_edid.c +7 -1
@@ -68,7 +68,7 @@ static int oui(u8 first, u8 second, u8 tenum drm_edid_internal_quirk {/* First detailed mode wrong, use largest 60Hz mode */ -EDID_QUIRK_PREFER_LARGE_60 , +EDID_QUIRK_PREFER_LARGE_60 =DRM_EDID_QUIRK_NUM ,/* Reported 135MHz pixel clock is too high, needs adjustment */ EDID_QUIRK_135_CLOCK_TOO_HIGH ,/* Prefer the largest mode at 75 Hz */
@@ -2959,6 +2959,12 @@ static bool drm_edid_has_internal_quirk(return connector->display_info.quirks &BIT (quirk); } +bool drm_edid_has_quirk (struct drm_connector *connector,enum drm_edid_quirk quirk) +{ +return connector->display_info.quirks &BIT (quirk); +} +EXPORT_SYMBOL (drm_edid_has_quirk); +#define MODE_SIZE (m) ((m)->hdisplay * (m)->vdisplay)#define MODE_REFRESH_DIFF (c,t) (abs((c) - (t)))
include/drm/drm_connector.h +3 -1
@@ -843,7 +843,9 @@ struct drm_display_info {int vics_len;/** -* @quirks: EDID based quirks. Internal to EDID parsing. +* @quirks: EDID based quirks. DRM core and drivers can query the +* @drm_edid_quirk quirks using drm_edid_has_quirk(), the rest of +* the quirks also tracked here are internal to EDID parsing. */ u32 quirks;
include/drm/drm_edid.h +5 -0
@@ -109,6 +109,10 @@ struct detailed_data_string {#define DRM_EDID_CVT_FLAGS_STANDARD_BLANKING (1 << 3)#define DRM_EDID_CVT_FLAGS_REDUCED_BLANKING (1 << 4) +enum drm_edid_quirk { +DRM_EDID_QUIRK_NUM , +}; +struct detailed_data_monitor_range {u8 min_vfreq;u8 max_vfreq;
@@ -476,5 +480,6 @@ void drm_edid_print_product_id(struct dru32 drm_edid_get_panel_id (const struct drm_edid *drm_edid);bool drm_edid_match (const struct drm_edid *drm_edid,const struct drm_edid_ident *ident); +bool drm_edid_has_quirk (struct drm_connector *connector,enum drm_edid_quirk quirk);#endif /* __DRM_EDID_H__ */
Greg Kroah-Hartman
maintainerPATCH 95/189 drm/dp: Add an EDID quirk for the DPCD register access probe
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Imre Deak <[email protected]>
commit b87ed522b3643f096ef183ed0ccf2d2b90ddd513 upstream.
Reading DPCD registers has side-effects and some of these can cause a problem for instance during link training. Based on this it's better to avoid the probing quirk done before each DPCD register read, limiting this to the monitor which requires it. Add an EDID quirk for this. Leave the quirk enabled by default, allowing it to be disabled after the monitor is detected.
v2: Fix lockdep wrt. drm_dp_aux::hw_mutex when calling
drm_dp_dpcd_set_probe_quirk() with a dependent lock already held.
v3: Add a helper for determining if DPCD probing is needed. (Jani) v4:
- s/drm_dp_dpcd_set_probe_quirk/drm_dp_dpcd_set_probe (Jani)
- Fix documentation of drm_dp_dpcd_set_probe().
- Add comment at the end of internal quirk entries.
--- drivers/gpu/drm/display/drm_dp_helper.c | 42 ++++++++++++++++++++++---------- drivers/gpu/drm/drm_edid.c | 8 ++++++ include/drm/display/drm_dp_helper.h | 6 ++++ include/drm/drm_edid.h | 3 ++ 4 files changed, 46 insertions(+), 13 deletions(-)
drivers/gpu/drm/display/drm_dp_helper.c +29 -13
@@ -692,6 +692,34 @@ void drm_dp_dpcd_set_powered(struct drm_EXPORT_SYMBOL (drm_dp_dpcd_set_powered);/** +* drm_dp_dpcd_set_probe() - Set whether a probing before DPCD access is done +* @aux: DisplayPort AUX channel +* @enable: Enable the probing if required +*/ +void drm_dp_dpcd_set_probe (struct drm_dp_aux *aux,bool enable) +{ +WRITE_ONCE (aux->dpcd_probe_disabled, !enable); +} +EXPORT_SYMBOL (drm_dp_dpcd_set_probe); + +static bool dpcd_access_needs_probe (struct drm_dp_aux *aux) +{ +/* +* HP ZR24w corrupts the first DPCD access after entering power save +* mode. Eg. on a read, the entire buffer will be filled with the same +* byte. Do a throw away read to avoid corrupting anything we care +* about. Afterwards things will work correctly until the monitor +* gets woken up and subsequently re-enters power save mode. +* +* The user pressing any button on the monitor is enough to wake it +* up, so there is no particularly good place to do the workaround. +* We just have to do it before any DPCD access and hope that the +* monitor doesn't power down exactly after the throw away read. +*/ +return !aux->is_remote && !READ_ONCE (aux->dpcd_probe_disabled); +} + +/** * drm_dp_dpcd_read() - read a series of bytes from the DPCD * @aux: DisplayPort AUX channel (SST or MST) * @offset: address of the (first) register to read
@@ -712,19 +740,7 @@ ssize_t drm_dp_dpcd_read(struct drm_dp_a {int ret; -/* -* HP ZR24w corrupts the first DPCD access after entering power save -* mode. Eg. on a read, the entire buffer will be filled with the same -* byte. Do a throw away read to avoid corrupting anything we care -* about. Afterwards things will work correctly until the monitor -* gets woken up and subsequently re-enters power save mode. -* -* The user pressing any button on the monitor is enough to wake it -* up, so there is no particularly good place to do the workaround. -* We just have to do it before any DPCD access and hope that the -* monitor doesn't power down exactly after the throw away read. -*/ -if (!aux->is_remote) { +if (dpcd_access_needs_probe (aux)) { ret =drm_dp_dpcd_probe (aux,DP_TRAINING_PATTERN_SET );if (ret <0 )return ret;
drivers/gpu/drm/drm_edid.c +8 -0
@@ -248,6 +248,14 @@ static const struct edid_quirk {/* OSVR HDK and HDK2 VR Headsets */ EDID_QUIRK ('S' ,'V' ,'R' ,0x1019 ,BIT (EDID_QUIRK_NON_DESKTOP )),EDID_QUIRK ('A' ,'U' ,'O' ,0x1111 ,BIT (EDID_QUIRK_NON_DESKTOP )), + +/* +* @drm_edid_internal_quirk entries end here, following with the +* @drm_edid_quirk entries. +*/ + +/* HP ZR24w DP AUX DPCD access requires probing to prevent corruption. */ + EDID_QUIRK('H', 'W', 'P', 0x2869, BIT(DRM_EDID_QUIRK_DP_DPCD_PROBE)), };/*
include/drm/display/drm_dp_helper.h +6 -0
@@ -523,10 +523,16 @@ struct drm_dp_aux {* @no_zero_sized: If the hw can't use zero sized transfers (NVIDIA) */ bool no_zero_sized; + +/** +* @dpcd_probe_disabled: If probing before a DPCD access is disabled. +*/ +bool dpcd_probe_disabled; };int drm_dp_dpcd_probe (struct drm_dp_aux *aux,unsigned int offset);void drm_dp_dpcd_set_powered (struct drm_dp_aux *aux,bool powered); +void drm_dp_dpcd_set_probe (struct drm_dp_aux *aux,bool enable);ssize_t drm_dp_dpcd_read (struct drm_dp_aux *aux,unsigned int offset,void *buffer,size_t size); ssize_t drm_dp_dpcd_write(struct drm_dp_aux *aux, unsigned int offset,
include/drm/drm_edid.h +3 -0
@@ -110,6 +110,9 @@ struct detailed_data_string {#define DRM_EDID_CVT_FLAGS_REDUCED_BLANKING (1 << 4)enum drm_edid_quirk { +/* Do a dummy read before DPCD accesses, to prevent corruption. */ +DRM_EDID_QUIRK_DP_DPCD_PROBE , +DRM_EDID_QUIRK_NUM , };
Greg Kroah-Hartman
maintainerPATCH 96/189 drm/amd/display: Disable DPCD Probe Quirk
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fangzhi Zuo <[email protected]>
commit f5c32370dba668c171c73684f489a3ea0b9503c5 upstream.
Disable dpcd probe quirk to native aux.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +1 -0
@@ -809,6 +809,7 @@ void amdgpu_dm_initialize_dp_connector(sdrm_dp_aux_init (&aconnector->dm_dp_aux.aux);drm_dp_cec_register_connector (&aconnector->dm_dp_aux.aux, &aconnector->base); +drm_dp_dpcd_set_probe (&aconnector->dm_dp_aux.aux, false);if (aconnector->base.connector_type == DRM_MODE_CONNECTOR_eDP)return ;
Greg Kroah-Hartman
maintainerPATCH 97/189 btrfs: use readahead_expand() on compressed extents
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Boris Burkov <[email protected]>
[ Upstream commit 9e9ff875e4174be939371667d2cc81244e31232f ]
We recently received a report of poor performance doing sequential buffered reads of a file with compressed extents. With bs=128k, a naive sequential dd ran as fast on a compressed file as on an uncompressed (1.2GB/s on my reproducing system) while with bs<32k, this performance tanked down to ~300MB/s.
i.e., slow:
dd if=some-compressed-file of=/dev/null bs=4k count=X
vs fast:
dd if=some-compressed-file of=/dev/null bs=128k count=Y
The cause of this slowness is overhead to do with looking up extent_maps to enable readahead pre-caching on compressed extents (add_ra_bio_pages()), as well as some overhead in the generic VFS readahead code we hit more in the slow case. Notably, the main difference between the two read sizes is that in the large sized request case, we call btrfs_readahead() relatively rarely while in the smaller request we call it for every compressed extent. So the fast case stays in the btrfs readahead loop:
while ((folio = readahead_folio(rac)) != NULL) btrfs_do_readpage(folio, &em_cached, &bio_ctrl, &prev_em_start);
where the slower one breaks out of that loop every time. This results in calling add_ra_bio_pages a lot, doing lots of extent_map lookups, extent_map locking, etc.
This happens because although add_ra_bio_pages() does add the appropriate un-compressed file pages to the cache, it does not communicate back to the ractl in any way. To solve this, we should be using readahead_expand() to signal to readahead to expand the readahead window.
This change passes the readahead_control into the btrfs_bio_ctrl and in the case of compressed reads sets the expansion to the size of the extent_map we already looked up anyway. It skips the subpage case as that one already doesn't do add_ra_bio_pages().
With this change, whether we use bs=4k or bs=128k, btrfs expands the readahead window up to the largest compressed extent we have seen so far (in the trivial example: 128k) and the call stacks of the two modes look identical. Notably, we barely call add_ra_bio_pages at all. And the performance becomes identical as well. So this change certainly "fixes" this performance problem.
Of course, it does seem to beg a few questions:
1. Will this waste too much page cache with a too large ra window?
2. Will this somehow cause bugs prevented by the more thoughtful checking in add_ra_bio_pages?
3. Should we delete add_ra_bio_pages?
My stabs at some answers:
1. Hard to say. See attempts at generic performance testing below. Is there a "readahead_shrink" we should be using? Should we expand more slowly, by half the remaining em size each time?
2. I don't think so. Since the new behavior is indistinguishable from reading the file with a larger read size passed in, I don't see why one would be safe but not the other.
3. Probably! I tested that and it was fine in fstests, and it seems like the pages would get re-used just as well in the readahead case. However, it is possible some reads that use page cache but not btrfs_readahead() could suffer. I will investigate this further as a follow up.
I tested the performance implications of this change in 3 ways (using compress-force=zstd:3 for compression):
Directly test the affected workload of small sequential reads on a compressed file (improved from ~250MB/s to ~1.2GB/s)
==========for-next==========
dd /mnt/lol/non-cmpr 4k
1048576+0 records in
1048576+0 records out
4294967296 bytes (4.3 GB, 4.0 GiB) copied, 6.02983 s, 712 MB/s dd /mnt/lol/non-cmpr 128k
32768+0 records in
32768+0 records out
4294967296 bytes (4.3 GB, 4.0 GiB) copied, 5.92403 s, 725 MB/s dd /mnt/lol/cmpr 4k
1048576+0 records in
1048576+0 records out
4294967296 bytes (4.3 GB, 4.0 GiB) copied, 17.8832 s, 240 MB/s dd /mnt/lol/cmpr 128k
32768+0 records in
32768+0 records out
4294967296 bytes (4.3 GB, 4.0 GiB) copied, 3.71001 s, 1.2 GB/s
==========ra-expand==========
dd /mnt/lol/non-cmpr 4k
1048576+0 records in
1048576+0 records out
4294967296 bytes (4.3 GB, 4.0 GiB) copied, 6.09001 s, 705 MB/s dd /mnt/lol/non-cmpr 128k
32768+0 records in
32768+0 records out
4294967296 bytes (4.3 GB, 4.0 GiB) copied, 6.07664 s, 707 MB/s dd /mnt/lol/cmpr 4k
1048576+0 records in
1048576+0 records out
4294967296 bytes (4.3 GB, 4.0 GiB) copied, 3.79531 s, 1.1 GB/s dd /mnt/lol/cmpr 128k
32768+0 records in
32768+0 records out
4294967296 bytes (4.3 GB, 4.0 GiB) copied, 3.69533 s, 1.2 GB/s
Built the linux kernel from clean (no change)
Ran fsperf. Mostly neutral results with some improvements and regressions here and there.
Stable-dep-of: 9786531399a6 ("btrfs: fix corruption reading compressed range when block size is smaller than page size")
--- fs/btrfs/extent_io.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-)
fs/btrfs/extent_io.c +34 -1
@@ -110,6 +110,7 @@ struct btrfs_bio_ctrl {* This is to avoid touching ranges covered by compression/inline. */ unsigned long submit_bitmap; +struct readahead_control *ractl; };static void submit_one_bio (struct btrfs_bio_ctrl *bio_ctrl)
@@ -882,6 +883,25 @@ static struct extent_map *get_extent_mapreturn em; } + +static void btrfs_readahead_expand (struct readahead_control *ractl, +const struct extent_map *em) +{ +const u64 ra_pos =readahead_pos (ractl); +const u64 ra_end = ra_pos +readahead_length (ractl); +const u64 em_end = em->start + em->ram_bytes; + +/* No expansion for holes and inline extents. */ +if (em->disk_bytenr >EXTENT_MAP_LAST_BYTE ) +return ; + +ASSERT (em_end >= ra_pos, +"extent_map %llu %llu ends before current readahead position %llu" , + em->start, em->len, ra_pos); +if (em_end > ra_end) +readahead_expand (ractl, ra_pos, em_end - ra_pos); +} +/* * basic readpage implementation. Locked extent state structs are inserted * into the tree that are removed when the IO is done (by the end_io
@@ -945,6 +965,16 @@ static int btrfs_do_readpage(struct foli compress_type =btrfs_extent_map_compression (em); +/* +* Only expand readahead for extents which are already creating +* the pages anyway in add_ra_bio_pages, which is compressed +* extents in the non subpage case. +*/ +if (bio_ctrl->ractl && + !btrfs_is_subpage (fs_info, folio) && + compress_type !=BTRFS_COMPRESS_NONE ) +btrfs_readahead_expand (bio_ctrl->ractl, em); +if (compress_type !=BTRFS_COMPRESS_NONE ) disk_bytenr = em->disk_bytenr;else
@@ -2550,7 +2580,10 @@ int btrfs_writepages(struct address_spacvoid btrfs_readahead (struct readahead_control *rac) { -struct btrfs_bio_ctrl bio_ctrl = { .opf =REQ_OP_READ |REQ_RAHEAD }; +struct btrfs_bio_ctrl bio_ctrl = { + .opf =REQ_OP_READ |REQ_RAHEAD , + .ractl = rac + };struct folio *folio;struct btrfs_inode *inode =BTRFS_I (rac->mapping->host);const u64 start =readahead_pos (rac);
Greg Kroah-Hartman
maintainerPATCH 98/189 btrfs: fix corruption reading compressed range when block size is smaller than page size
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qu Wenruo <[email protected]>
[ Upstream commit 9786531399a679fc2f4630d2c0a186205282ab2f ]
[BUG]
With 64K page size (aarch64 with 64K page size config) and 4K btrfs block size, the following workload can easily lead to a corrupted read:
mkfs.btrfs -f -s 4k $dev > /dev/null
mount -o compress $dev $mnt
xfs_io -f -c "pwrite -S 0xff 0 64k" $mnt/base > /dev/null echo "correct result:"
od -Ad -t x1 $mnt/base
xfs_io -f -c "reflink $mnt/base 32k 0 32k" \
-c "reflink $mnt/base 0 32k 32k" \
-c "pwrite -S 0xff 60k 4k" $mnt/new > /dev/null
echo "incorrect result:"
od -Ad -t x1 $mnt/new
umount $mnt
This shows the following result:
correct result:
0000000 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff *
0065536
incorrect result:
0000000 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff *
0032768 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 *
0061440 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff *
0065536
Notice the zero in the range [32K, 60K), which is incorrect.
[CAUSE]
With extra trace printk, it shows the following events during od:
(some unrelated info removed like CPU and context)
od-3457 btrfs_do_readpage: enter r/i=5/258 folio=0(65536) prev_em_start=0000000000000000
The "r/i" is indicating the root and inode number. In our case the file "new" is using ino 258 from fs tree (root 5).
Here notice the @prev_em_start pointer is NULL. This means the btrfs_do_readpage() is called from btrfs_read_folio(), not from btrfs_readahead().
od-3457 btrfs_do_readpage: r/i=5/258 folio=0(65536) cur=0 got em start=0 len=32768 od-3457 btrfs_do_readpage: r/i=5/258 folio=0(65536) cur=4096 got em start=0 len=32768 od-3457 btrfs_do_readpage: r/i=5/258 folio=0(65536) cur=8192 got em start=0 len=32768 od-3457 btrfs_do_readpage: r/i=5/258 folio=0(65536) cur=12288 got em start=0 len=32768 od-3457 btrfs_do_readpage: r/i=5/258 folio=0(65536) cur=16384 got em start=0 len=32768 od-3457 btrfs_do_readpage: r/i=5/258 folio=0(65536) cur=20480 got em start=0 len=32768 od-3457 btrfs_do_readpage: r/i=5/258 folio=0(65536) cur=24576 got em start=0 len=32768 od-3457 btrfs_do_readpage: r/i=5/258 folio=0(65536) cur=28672 got em start=0 len=32768
These above 32K blocks will be read from the first half of the compressed data extent.
od-3457 btrfs_do_readpage: r/i=5/258 folio=0(65536) cur=32768 got em start=32768 len=32768
Note here there is no btrfs_submit_compressed_read() call. Which is incorrect now.
Although both extent maps at 0 and 32K are pointing to the same compressed data, their offsets are different thus can not be merged into the same read.
So this means the compressed data read merge check is doing something wrong.
od-3457 btrfs_do_readpage: r/i=5/258 folio=0(65536) cur=36864 got em start=32768 len=32768 od-3457 btrfs_do_readpage: r/i=5/258 folio=0(65536) cur=40960 got em start=32768 len=32768 od-3457 btrfs_do_readpage: r/i=5/258 folio=0(65536) cur=45056 got em start=32768 len=32768 od-3457 btrfs_do_readpage: r/i=5/258 folio=0(65536) cur=49152 got em start=32768 len=32768 od-3457 btrfs_do_readpage: r/i=5/258 folio=0(65536) cur=53248 got em start=32768 len=32768 od-3457 btrfs_do_readpage: r/i=5/258 folio=0(65536) cur=57344 got em start=32768 len=32768 od-3457 btrfs_do_readpage: r/i=5/258 folio=0(65536) cur=61440 skip uptodate od-3457 btrfs_submit_compressed_read: cb orig_bio: file off=0 len=61440
The function btrfs_submit_compressed_read() is only called at the end of folio read. The compressed bio will only have an extent map of range [0, 32K), but the original bio passed in is for the whole 64K folio.
This will cause the decompression part to only fill the first 32K, leaving the rest untouched (aka, filled with zero).
This incorrect compressed read merge leads to the above data corruption.
There were similar problems that happened in the past, commit 808f80b46790 ("Btrfs: update fix for read corruption of compressed and shared extents") is doing pretty much the same fix for readahead.
But that's back to 2015, where btrfs still only supports bs (block size) == ps (page size) cases.
This means btrfs_do_readpage() only needs to handle a folio which contains exactly one block.
Only btrfs_readahead() can lead to a read covering multiple blocks. Thus only btrfs_readahead() passes a non-NULL @prev_em_start pointer.
With v5.15 kernel btrfs introduced bs < ps support. This breaks the above assumption that a folio can only contain one block.
Now btrfs_read_folio() can also read multiple blocks in one go. But btrfs_read_folio() doesn't pass a @prev_em_start pointer, thus the existing bio force submission check will never be triggered.
In theory, this can also happen for btrfs with large folios, but since large folio is still experimental, we don't need to bother it, thus only bs < ps support is affected for now.
[FIX]
Instead of passing @prev_em_start to do the proper compressed extent check, introduce one new member, btrfs_bio_ctrl::last_em_start, so that the existing bio force submission logic will always be triggered.
--- fs/btrfs/extent_io.c | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-)
fs/btrfs/extent_io.c +30 -10
@@ -111,6 +111,24 @@ struct btrfs_bio_ctrl {*/ unsigned long submit_bitmap;struct readahead_control *ractl; + +/* +* The start offset of the last used extent map by a read operation. +* +* This is for proper compressed read merge. +* U64_MAX means we are starting the read and have made no progress yet. +* +* The current btrfs_bio_is_contig() only uses disk_bytenr as +* the condition to check if the read can be merged with previous +* bio, which is not correct. E.g. two file extents pointing to the +* same extent but with different offset. +* +* So here we need to do extra checks to only merge reads that are +* covered by the same extent map. +* Just extent_map::start will be enough, as they are unique +* inside the same inode. +*/ +u64 last_em_start; };static void submit_one_bio (struct btrfs_bio_ctrl *bio_ctrl)
@@ -910,7 +928,7 @@ static void btrfs_readahead_expand(struc* return 0 on success, otherwise return error */ static int btrfs_do_readpage (struct folio *folio,struct extent_map **em_cached, -struct btrfs_bio_ctrl *bio_ctrl,u64 *prev_em_start) +struct btrfs_bio_ctrl *bio_ctrl) {struct inode *inode = folio->mapping->host;struct btrfs_fs_info *fs_info =inode_to_fs_info (inode);
@@ -1020,12 +1038,11 @@ static int btrfs_do_readpage(struct foli* non-optimal behavior (submitting 2 bios for the same extent). */ if (compress_type !=BTRFS_COMPRESS_NONE && - prev_em_start && *prev_em_start != (u64)-1 && - *prev_em_start != em->start) + bio_ctrl->last_em_start !=U64_MAX && + bio_ctrl->last_em_start != em->start) force_bio_submit = true; -if (prev_em_start) - *prev_em_start = em->start; + bio_ctrl->last_em_start = em->start;btrfs_free_extent_map (em); em =NULL ;
@@ -1239,12 +1256,15 @@ int btrfs_read_folio(struct file *file,const u64 start =folio_pos (folio);const u64 end = start +folio_size (folio) -1 ;struct extent_state *cached_state =NULL ; -struct btrfs_bio_ctrl bio_ctrl = { .opf =REQ_OP_READ }; +struct btrfs_bio_ctrl bio_ctrl = { + .opf =REQ_OP_READ , + .last_em_start =U64_MAX , + };struct extent_map *em_cached =NULL ;int ret;lock_extents_for_read (inode, start, end, &cached_state); - ret =btrfs_do_readpage (folio, &em_cached, &bio_ctrl,NULL ); + ret =btrfs_do_readpage (folio, &em_cached, &bio_ctrl);btrfs_unlock_extent (&inode->io_tree, start, end, &cached_state);btrfs_free_extent_map (em_cached);
@@ -2582,7 +2602,8 @@ void btrfs_readahead(struct readahead_co {struct btrfs_bio_ctrl bio_ctrl = { .opf =REQ_OP_READ |REQ_RAHEAD , - .ractl = rac + .ractl = rac, + .last_em_start =U64_MAX , };struct folio *folio;struct btrfs_inode *inode =BTRFS_I (rac->mapping->host);
@@ -2590,12 +2611,11 @@ void btrfs_readahead(struct readahead_coconst u64 end = start +readahead_length (rac) -1 ;struct extent_state *cached_state =NULL ;struct extent_map *em_cached =NULL ; -u64 prev_em_start = (u64)-1 ;lock_extents_for_read (inode, start, end, &cached_state);while ((folio =readahead_folio (rac)) !=NULL ) -btrfs_do_readpage (folio, &em_cached, &bio_ctrl, &prev_em_start); +btrfs_do_readpage (folio, &em_cached, &bio_ctrl);btrfs_unlock_extent (&inode->io_tree, start, end, &cached_state);
Greg Kroah-Hartman
maintainerPATCH 99/189 kernfs: Fix UAF in polling when open file is released
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen Ridong <[email protected]>
commit 3c9ba2777d6c86025e1ba4186dc5cd930e40ec5f upstream.
A use-after-free (UAF) vulnerability was identified in the PSI (Pressure Stall Information) monitoring mechanism:
BUG: KASAN: slab-use-after-free in psi_trigger_poll+0x3c/0x140 Read of size 8 at addr ffff3de3d50bd308 by task systemd/1 psi_trigger_poll+0x3c/0x140 cgroup_pressure_poll+0x70/0xa0 cgroup_file_poll+0x8c/0x100 kernfs_fop_poll+0x11c/0x1c0 ep_item_poll.isra.0+0x188/0x2c0 Allocated by task 1: cgroup_file_open+0x88/0x388 kernfs_fop_open+0x73c/0xaf0 do_dentry_open+0x5fc/0x1200 vfs_open+0xa0/0x3f0 do_open+0x7e8/0xd08 path_openat+0x2fc/0x6b0 do_filp_open+0x174/0x368 Freed by task 8462: cgroup_file_release+0x130/0x1f8 kernfs_drain_open_files+0x17c/0x440 kernfs_drain+0x2dc/0x360 kernfs_show+0x1b8/0x288 cgroup_file_show+0x150/0x268 cgroup_pressure_write+0x1dc/0x340 cgroup_file_write+0x274/0x548
Reproduction Steps:
1. Open test/cpu.pressure and establish epoll monitoring
2. Disable monitoring: echo 0 > test/cgroup.pressure
3. Re-enable monitoring: echo 1 > test/cgroup.pressure
The race condition occurs because:
1. When cgroup.pressure is disabled (echo 0 > cgroup.pressure), it:
- Releases PSI triggers via cgroup_file_release()
- Frees of->priv through kernfs_drain_open_files()
2. While epoll still holds reference to the file and continues polling
3. Re-enabling (echo 1 > cgroup.pressure) accesses freed of->priv
epolling disable/enable cgroup.pressure
fd=open(cpu.pressure)
while(1)
...epoll_waitkernfs_fop_pollkernfs_get_active = true echo 0 > cgroup.pressure
... cgroup_file_show
kernfs_show // inactive kn kernfs_drain_open_files cft->release(of); kfree(ctx); ... kernfs_get_active = false echo 1 > cgroup.pressure kernfs_show kernfs_activate_one(kn);
kernfs_fop_pollkernfs_get_active = truecgroup_file_pollpsi_trigger_poll
// UAF
...
end: close(fd)
To address this issue, introduce kernfs_get_active_of() for kernfs open files to obtain active references. This function will fail if the open file has been released. Replace kernfs_get_active() with kernfs_get_active_of() to prevent further operations on released file descriptors.
--- fs/kernfs/file.c | 58 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 20 deletions(-)
fs/kernfs/file.c +38 -20
@@ -70,6 +70,24 @@ static struct kernfs_open_node *of_on(st !list_empty(&of->list)); } +/* Get active reference to kernfs node for an open file */ +static struct kernfs_open_file *kernfs_get_active_of (struct kernfs_open_file *of) +{ +/* Skip if file was already released */ +if (unlikely (of->released)) +return NULL ; + +if (!kernfs_get_active (of->kn)) +return NULL ; + +return of; +} + +static void kernfs_put_active_of (struct kernfs_open_file *of) +{ +return kernfs_put_active (of->kn); +} +/** * kernfs_deref_open_node_locked - Get kernfs_open_node corresponding to @kn *
@@ -139,7 +157,7 @@ static void kernfs_seq_stop_active(strucif (ops->seq_stop) ops->seq_stop (sf, v); -kernfs_put_active (of->kn); +kernfs_put_active_of (of); }static void *kernfs_seq_start (struct seq_file *sf,loff_t *ppos)
@@ -152,7 +170,7 @@ static void *kernfs_seq_start(struct seq* the ops aren't called concurrently for the same open file. */ mutex_lock (&of->mutex); -if (!kernfs_get_active (of->kn)) +if (!kernfs_get_active_of (of))return ERR_PTR (-ENODEV ); ops =kernfs_ops (of->kn);
@@ -238,7 +256,7 @@ static ssize_t kernfs_file_read_iter(str* the ops aren't called concurrently for the same open file. */ mutex_lock (&of->mutex); -if (!kernfs_get_active (of->kn)) { +if (!kernfs_get_active_of (of)) { len = -ENODEV ;mutex_unlock (&of->mutex); goto out_free;
@@ -252,7 +270,7 @@ static ssize_t kernfs_file_read_iter(strelse len = -EINVAL ; -kernfs_put_active (of->kn); +kernfs_put_active_of (of);mutex_unlock (&of->mutex);if (len <0 )
@@ -323,7 +341,7 @@ static ssize_t kernfs_fop_write_iter(str* the ops aren't called concurrently for the same open file. */ mutex_lock (&of->mutex); -if (!kernfs_get_active (of->kn)) { +if (!kernfs_get_active_of (of)) {mutex_unlock (&of->mutex); len = -ENODEV ; goto out_free;
@@ -335,7 +353,7 @@ static ssize_t kernfs_fop_write_iter(strelse len = -EINVAL ; -kernfs_put_active (of->kn); +kernfs_put_active_of (of);mutex_unlock (&of->mutex);if (len >0 )
@@ -357,13 +375,13 @@ static void kernfs_vma_open(struct vm_arif (!of->vm_ops)return ; -if (!kernfs_get_active (of->kn)) +if (!kernfs_get_active_of (of))return ;if (of->vm_ops->open) of->vm_ops->open (vma); -kernfs_put_active (of->kn); +kernfs_put_active_of (of); }static vm_fault_t kernfs_vma_fault (struct vm_fault *vmf)
@@ -375,14 +393,14 @@ static vm_fault_t kernfs_vma_fault(strucif (!of->vm_ops)return VM_FAULT_SIGBUS ; -if (!kernfs_get_active (of->kn)) +if (!kernfs_get_active_of (of))return VM_FAULT_SIGBUS ; ret =VM_FAULT_SIGBUS ;if (of->vm_ops->fault) ret = of->vm_ops->fault (vmf); -kernfs_put_active (of->kn); +kernfs_put_active_of (of);return ret; }
@@ -395,7 +413,7 @@ static vm_fault_t kernfs_vma_page_mkwritif (!of->vm_ops)return VM_FAULT_SIGBUS ; -if (!kernfs_get_active (of->kn)) +if (!kernfs_get_active_of (of))return VM_FAULT_SIGBUS ; ret =0 ;
@@ -404,7 +422,7 @@ static vm_fault_t kernfs_vma_page_mkwritelse file_update_time (file); -kernfs_put_active (of->kn); +kernfs_put_active_of (of);return ret; }
@@ -418,14 +436,14 @@ static int kernfs_vma_access(struct vm_aif (!of->vm_ops)return -EINVAL ; -if (!kernfs_get_active (of->kn)) +if (!kernfs_get_active_of (of))return -EINVAL ; ret = -EINVAL ;if (of->vm_ops->access) ret = of->vm_ops->access (vma, addr, buf, len, write); -kernfs_put_active (of->kn); +kernfs_put_active_of (of);return ret; }
@@ -455,7 +473,7 @@ static int kernfs_fop_mmap(struct file *mutex_lock (&of->mutex); rc = -ENODEV ; -if (!kernfs_get_active (of->kn)) +if (!kernfs_get_active_of (of)) goto out_unlock; ops =kernfs_ops (of->kn);
@@ -490,7 +508,7 @@ static int kernfs_fop_mmap(struct file * } vma->vm_ops = &kernfs_vm_ops; out_put: -kernfs_put_active (of->kn); +kernfs_put_active_of (of); out_unlock:mutex_unlock (&of->mutex);
@@ -852,7 +870,7 @@ static __poll_t kernfs_fop_poll(struct fstruct kernfs_node *kn =kernfs_dentry_node (filp->f_path.dentry);__poll_t ret; -if (!kernfs_get_active (kn)) +if (!kernfs_get_active_of (of))return DEFAULT_POLLMASK |EPOLLERR |EPOLLPRI ;if (kn->attr.ops->poll)
@@ -860,7 +878,7 @@ static __poll_t kernfs_fop_poll(struct felse ret =kernfs_generic_poll (of, wait); -kernfs_put_active (kn); +kernfs_put_active_of (of);return ret; }
@@ -875,7 +893,7 @@ static loff_t kernfs_fop_llseek(struct f* the ops aren't called concurrently for the same open file. */ mutex_lock (&of->mutex); -if (!kernfs_get_active (of->kn)) { +if (!kernfs_get_active_of (of)) {mutex_unlock (&of->mutex);return -ENODEV ; }
@@ -886,7 +904,7 @@ static loff_t kernfs_fop_llseek(struct felse ret =generic_file_llseek (file, offset, whence); -kernfs_put_active (of->kn); +kernfs_put_active_of (of);mutex_unlock (&of->mutex);return ret; }
Greg Kroah-Hartman
maintainerPATCH 100/189 libceph: fix invalid accesses to ceph_connection_v1_info
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilya Dryomov <[email protected]>
commit cdbc9836c7afadad68f374791738f118263c5371 upstream.
There is a place where generic code in messenger.c is reading and another place where it is writing to con->v1 union member without checking that the union member is active (i.e. msgr1 is in use).
On 64-bit systems, con->v1.auth_retry overlaps with con->v2.out_iter, so such a read is almost guaranteed to return a bogus value instead of 0 when msgr2 is in use. This ends up being fairly benign because the side effect is just the invalidation of the authorizer and successive fetching of new tickets.
con->v1.connect_seq overlaps with con->v2.conn_bufs and the fact that it's being written to can cause more serious consequences, but luckily it's not something that happens often.
--- net/ceph/messenger.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
net/ceph/messenger.c +4 -3
@@ -1524,7 +1524,7 @@ static void con_fault_finish(struct ceph* in case we faulted due to authentication, invalidate our * current tickets so that we can get new ones. */ -if (con->v1.auth_retry) { +if (!ceph_msgr2 (from_msgr (con->msgr)) && con->v1.auth_retry) {dout ("auth_retry %d, invalidating\n" , con->v1.auth_retry);if (con->ops->invalidate_authorizer) con->ops->invalidate_authorizer (con);
@@ -1714,9 +1714,10 @@ static void clear_standby(struct ceph_co {/* come back from STANDBY? */ if (con->state ==CEPH_CON_S_STANDBY ) { -dout ("clear_standby %p and ++connect_seq\n" , con); +dout ("clear_standby %p\n" , con); con->state =CEPH_CON_S_PREOPEN ; - con->v1.connect_seq++; +if (!ceph_msgr2 (from_msgr (con->msgr))) + con->v1.connect_seq++;WARN_ON (ceph_con_flag_test (con,CEPH_CON_F_WRITE_PENDING ));WARN_ON (ceph_con_flag_test (con,CEPH_CON_F_KEEPALIVE_PENDING )); }
Greg Kroah-Hartman
maintainerPATCH 101/189 ceph: fix race condition validating r_parent before applying state
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Markuze <[email protected]>
commit 15f519e9f883b316d86e2bb6b767a023aafd9d83 upstream.
Add validation to ensure the cached parent directory inode matches the directory info in MDS replies. This prevents client-side race conditions where concurrent operations (e.g. rename) cause r_parent to become stale between request initiation and reply processing, which could lead to applying state changes to incorrect directory inodes.
[ idryomov: folded a kerneldoc fixup and a follow-up fix from Alex to
move CEPH_CAP_PIN reference when r_parent is updated:
When the parent directory lock is not held, req->r_parent can become stale and is updated to point to the correct inode. However, the associated CEPH_CAP_PIN reference was not being adjusted. The CEPH_CAP_PIN is a reference on an inode that is tracked for accounting purposes. Moving this pin is important to keep the accounting balanced. When the pin was not moved from the old parent to the new one, it created two problems: The reference on the old, stale parent was never released, causing a reference leak. A reference for the new parent was never acquired, creating the risk of a reference underflow later in ceph_mdsc_release_request(). This patch corrects the logic by releasing the pin from the old parent and acquiring it for the new parent when r_parent is switched. This ensures reference accounting stays balanced. ]
--- fs/ceph/debugfs.c | 14 +--- fs/ceph/dir.c | 17 ++--- fs/ceph/file.c | 24 ++----- fs/ceph/inode.c | 7 -- fs/ceph/mds_client.c | 172 +++++++++++++++++++++++++++++++-------------------- fs/ceph/mds_client.h | 18 ++++- 6 files changed, 145 insertions(+), 107 deletions(-)
fs/ceph/debugfs.c +6 -8
@@ -55,8 +55,6 @@ static int mdsc_show(struct seq_file *s,struct ceph_mds_client *mdsc = fsc->mdsc;struct ceph_mds_request *req;struct rb_node *rp; -int pathlen =0 ; -u64 pathbase;char *path;mutex_lock (&mdsc->mutex);
@@ -81,8 +79,8 @@ static int mdsc_show(struct seq_file *s,if (req->r_inode) {seq_printf (s," #%llx" ,ceph_ino (req->r_inode)); }else if (req->r_dentry) { - path =ceph_mdsc_build_path (mdsc, req->r_dentry, &pathlen, - &pathbase,0 ); +struct ceph_path_info path_info; + path =ceph_mdsc_build_path (mdsc, req->r_dentry, &path_info,0 );if (IS_ERR (path)) path =NULL ;spin_lock (&req->r_dentry->d_lock);
@@ -91,7 +89,7 @@ static int mdsc_show(struct seq_file *s, req->r_dentry, path ? path : "");spin_unlock (&req->r_dentry->d_lock); -ceph_mdsc_free_path (path, pathlen); +ceph_mdsc_free_path_info (&path_info); }else if (req->r_path1) {seq_printf (s," #%llx/%s" , req->r_ino1.ino, req->r_path1);
@@ -100,8 +98,8 @@ static int mdsc_show(struct seq_file *s, }if (req->r_old_dentry) { - path =ceph_mdsc_build_path (mdsc, req->r_old_dentry, &pathlen, - &pathbase,0 ); +struct ceph_path_info path_info; + path =ceph_mdsc_build_path (mdsc, req->r_old_dentry, &path_info,0 );if (IS_ERR (path)) path =NULL ;spin_lock (&req->r_old_dentry->d_lock);
@@ -111,7 +109,7 @@ static int mdsc_show(struct seq_file *s, req->r_old_dentry, path ? path : "");spin_unlock (&req->r_old_dentry->d_lock); -ceph_mdsc_free_path (path, pathlen); +ceph_mdsc_free_path_info (&path_info); }else if (req->r_path2 && req->r_op !=CEPH_MDS_OP_SYMLINK ) {if (req->r_ino2.ino) seq_printf(s, " #%llx/%s", req->r_ino2.ino,
fs/ceph/dir.c +7 -10
@@ -1272,10 +1272,8 @@ static void ceph_async_unlink_cb(struct/* If op failed, mark everyone involved for errors */ if (result) { -int pathlen =0 ; -u64 base =0 ; -char *path =ceph_mdsc_build_path (mdsc, dentry, &pathlen, - &base,0 ); +struct ceph_path_info path_info = {0 }; +char *path =ceph_mdsc_build_path (mdsc, dentry, &path_info,0 );/* mark error on parent + clear complete */ mapping_set_error (req->r_parent->i_mapping, result);
@@ -1289,8 +1287,8 @@ static void ceph_async_unlink_cb(structmapping_set_error (req->r_old_inode->i_mapping, result);pr_warn_client (cl,"failure path=(%llx)%s result=%d!\n" , - base,IS_ERR (path) ?"<<bad>>" : path, result); -ceph_mdsc_free_path (path, pathlen); + path_info.vino.ino,IS_ERR (path) ?"<<bad>>" : path, result); +ceph_mdsc_free_path_info (&path_info); } out:iput (req->r_old_inode);
@@ -1348,8 +1346,6 @@ static int ceph_unlink(struct inode *dirint err = -EROFS ;int op;char *path; -int pathlen; -u64 pathbase;if (ceph_snap (dir) ==CEPH_SNAPDIR ) {/* rmdir .snap/foo is RMSNAP */
@@ -1368,14 +1364,15 @@ static int ceph_unlink(struct inode *dirif (!dn) { try_async = false; }else { - path =ceph_mdsc_build_path (mdsc, dn, &pathlen, &pathbase,0 ); +struct ceph_path_info path_info; + path =ceph_mdsc_build_path (mdsc, dn, &path_info,0 );if (IS_ERR (path)) { try_async = false; err =0 ; }else { err =ceph_mds_check_access (mdsc, path,MAY_WRITE ); } -ceph_mdsc_free_path (path, pathlen); +ceph_mdsc_free_path_info (&path_info);dput (dn);/* For none EACCES cases will let the MDS do the mds auth check */
fs/ceph/file.c +10 -14
@@ -368,8 +368,6 @@ int ceph_open(struct inode *inode, strucint flags, fmode, wanted;struct dentry *dentry;char *path; -int pathlen; -u64 pathbase;bool do_sync = false;int mask =MAY_READ ;
@@ -399,14 +397,15 @@ int ceph_open(struct inode *inode, strucif (!dentry) { do_sync = true; }else { - path =ceph_mdsc_build_path (mdsc, dentry, &pathlen, &pathbase,0 ); +struct ceph_path_info path_info; + path =ceph_mdsc_build_path (mdsc, dentry, &path_info,0 );if (IS_ERR (path)) { do_sync = true; err =0 ; }else { err =ceph_mds_check_access (mdsc, path, mask); } -ceph_mdsc_free_path (path, pathlen); +ceph_mdsc_free_path_info (&path_info);dput (dentry);/* For none EACCES cases will let the MDS do the mds auth check */
@@ -614,15 +613,13 @@ static void ceph_async_create_cb(structmapping_set_error (req->r_parent->i_mapping, result);if (result) { -int pathlen =0 ; -u64 base =0 ; -char *path =ceph_mdsc_build_path (mdsc, req->r_dentry, &pathlen, - &base,0 ); +struct ceph_path_info path_info = {0 }; +char *path =ceph_mdsc_build_path (mdsc, req->r_dentry, &path_info,0 );pr_warn_client (cl,"async create failure path=(%llx)%s result=%d!\n" , - base,IS_ERR (path) ?"<<bad>>" : path, result); -ceph_mdsc_free_path (path, pathlen); + path_info.vino.ino,IS_ERR (path) ?"<<bad>>" : path, result); +ceph_mdsc_free_path_info (&path_info);ceph_dir_clear_complete (req->r_parent);if (!d_unhashed (dentry))
@@ -791,8 +788,6 @@ int ceph_atomic_open(struct inode *dir,int mask;int err;char *path; -int pathlen; -u64 pathbase; doutc(cl, "%p %llx.%llx dentry %p '%pd' %s flags %d mode 0%o\n", dir, ceph_vinop(dir), dentry, dentry,
@@ -814,7 +809,8 @@ int ceph_atomic_open(struct inode *dir,if (!dn) { try_async = false; }else { - path =ceph_mdsc_build_path (mdsc, dn, &pathlen, &pathbase,0 ); +struct ceph_path_info path_info; + path =ceph_mdsc_build_path (mdsc, dn, &path_info,0 );if (IS_ERR (path)) { try_async = false; err =0 ;
@@ -826,7 +822,7 @@ int ceph_atomic_open(struct inode *dir, mask |=MAY_WRITE ; err =ceph_mds_check_access (mdsc, path, mask); } -ceph_mdsc_free_path (path, pathlen); +ceph_mdsc_free_path_info (&path_info);dput (dn);/* For none EACCES cases will let the MDS do the mds auth check */
fs/ceph/inode.c +3 -4
@@ -2488,22 +2488,21 @@ int __ceph_setattr(struct mnt_idmap *idmint truncate_retry =20 ;/* The RMW will take around 50ms */ struct dentry *dentry;char *path; -int pathlen; -u64 pathbase;bool do_sync = false; dentry =d_find_alias (inode);if (!dentry) { do_sync = true; }else { - path =ceph_mdsc_build_path (mdsc, dentry, &pathlen, &pathbase,0 ); +struct ceph_path_info path_info; + path =ceph_mdsc_build_path (mdsc, dentry, &path_info,0 );if (IS_ERR (path)) { do_sync = true; err =0 ; }else { err =ceph_mds_check_access (mdsc, path,MAY_WRITE ); } -ceph_mdsc_free_path (path, pathlen); +ceph_mdsc_free_path_info (&path_info);dput (dentry);/* For none EACCES cases will let the MDS do the mds auth check */
fs/ceph/mds_client.c +105 -67
343 lines not on this page · raw message
fs/ceph/mds_client.h +14 -4
@@ -617,14 +617,24 @@ extern int ceph_mds_check_access(structextern void ceph_mdsc_pre_umount (struct ceph_mds_client *mdsc); -static inline void ceph_mdsc_free_path (char *path,int len) +/* +* Structure to group path-related output parameters for build_*_path functions +*/ +struct ceph_path_info { +const char *path; +int pathlen; +struct ceph_vino vino; +bool freepath; +}; + +static inline void ceph_mdsc_free_path_info (const struct ceph_path_info *path_info) { -if (!IS_ERR_OR_NULL (path)) -__putname (path - (PATH_MAX -1 - len)); +if (path_info && path_info->freepath && !IS_ERR_OR_NULL (path_info->path)) +__putname ((char *)path_info->path - (PATH_MAX -1 - path_info->pathlen)); }extern char *ceph_mdsc_build_path (struct ceph_mds_client *mdsc, -struct dentry *dentry,int *plen,u64 *base, +struct dentry *dentry,struct ceph_path_info *path_info,int for_wire);extern void __ceph_mdsc_drop_dentry_lease (struct dentry *dentry);
Greg Kroah-Hartman
maintainerPATCH 102/189 ceph: fix race condition where r_parent becomes stale before sending message
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Markuze <[email protected]>
commit bec324f33d1ed346394b2eee25bf6dbf3511f727 upstream.
When the parent directory's i_rwsem is not locked, req->r_parent may become stale due to concurrent operations (e.g. rename) between dentry lookup and message creation. Validate that r_parent matches the encoded parent inode and update to the correct inode if a mismatch is detected.
[ idryomov: folded a follow-up fix from Alex to drop extra reference
from ceph_get_reply_dir() in ceph_fill_trace():
ceph_get_reply_dir() may return a different, referenced inode when r_parent is stale and the parent directory lock is not held. ceph_fill_trace() used that inode but failed to drop the reference when it differed from req->r_parent, leaking an inode reference.
Keep the directory inode in a local variable and iput() it at function end if it does not match req->r_parent. ]
--- fs/ceph/inode.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 69 insertions(+), 12 deletions(-)
fs/ceph/inode.c +69 -12
@@ -55,6 +55,52 @@ static int ceph_set_ino_cb(struct inodereturn 0 ; } +/* +* Check if the parent inode matches the vino from directory reply info +*/ +static inline bool ceph_vino_matches_parent (struct inode *parent, +struct ceph_vino vino) +{ +return ceph_ino (parent) == vino.ino &&ceph_snap (parent) == vino.snap; +} + +/* +* Validate that the directory inode referenced by @req->r_parent matches the +* inode number and snapshot id contained in the reply's directory record. If +* they do not match – which can theoretically happen if the parent dentry was +* moved between the time the request was issued and the reply arrived – fall +* back to looking up the correct inode in the inode cache. +* +* A reference is *always* returned. Callers that receive a different inode +* than the original @parent are responsible for dropping the extra reference +* once the reply has been processed. +*/ +static struct inode *ceph_get_reply_dir (struct super_block *sb, +struct inode *parent, +struct ceph_mds_reply_info_parsed *rinfo) +{ +struct ceph_vino vino; + +if (unlikely (!rinfo->diri.in)) +return parent;/* nothing to compare against */ + +/* If we didn't have a cached parent inode to begin with, just bail out. */ +if (!parent) +return NULL ; + + vino.ino =le64_to_cpu (rinfo->diri.in->ino); + vino.snap =le64_to_cpu (rinfo->diri.in->snapid); + +if (likely (ceph_vino_matches_parent (parent, vino))) +return parent;/* matches – use the original reference */ + +/* Mismatch – this should be rare. Emit a WARN and obtain the correct inode. */ +WARN_ONCE (1 ,"ceph: reply dir mismatch (parent valid %llx.%llx reply %llx.%llx)\n" , +ceph_ino (parent),ceph_snap (parent), vino.ino, vino.snap); + +return ceph_get_inode (sb, vino,NULL ); +} +/** * ceph_new_inode - allocate a new inode in advance of an expected create * @dir: parent directory for new inode
@@ -1523,6 +1569,7 @@ int ceph_fill_trace(struct super_block *struct ceph_vino tvino, dvino;struct ceph_fs_client *fsc =ceph_sb_to_fs_client (sb);struct ceph_client *cl = fsc->client; +struct inode *parent_dir =NULL ;int err =0 ; doutc(cl, "%p is_dentry %d is_target %d\n", req,
@@ -1536,10 +1583,17 @@ int ceph_fill_trace(struct super_block * }if (rinfo->head->is_dentry) { -struct inode *dir = req->r_parent; - -if (dir) { - err =ceph_fill_inode (dir,NULL , &rinfo->diri, +/* +* r_parent may be stale, in cases when R_PARENT_LOCKED is not set, +* so we need to get the correct inode +*/ + parent_dir =ceph_get_reply_dir (sb, req->r_parent, rinfo); +if (unlikely (IS_ERR (parent_dir))) { + err =PTR_ERR (parent_dir); + goto done; + } +if (parent_dir) { + err =ceph_fill_inode (parent_dir,NULL , &rinfo->diri, rinfo->dirfrag, session,-1 , &req->r_caps_reservation);if (err <0 )
@@ -1548,14 +1602,14 @@ int ceph_fill_trace(struct super_block *WARN_ON_ONCE (1 ); } -if (dir && req->r_op ==CEPH_MDS_OP_LOOKUPNAME && +if (parent_dir && req->r_op ==CEPH_MDS_OP_LOOKUPNAME &&test_bit (CEPH_MDS_R_PARENT_LOCKED , &req->r_req_flags) && !test_bit (CEPH_MDS_R_ABORTED , &req->r_req_flags)) {bool is_nokey = false;struct qstr dname;struct dentry *dn, *parent;struct fscrypt_str oname =FSTR_INIT (NULL ,0 ); -struct ceph_fname fname = { .dir = dir, +struct ceph_fname fname = { .dir = parent_dir, .name = rinfo->dname, .ctext = rinfo->altname, .name_len = rinfo->dname_len,
@@ -1564,10 +1618,10 @@ int ceph_fill_trace(struct super_block *BUG_ON (!rinfo->head->is_target);BUG_ON (req->r_dentry); - parent =d_find_any_alias (dir); + parent =d_find_any_alias (parent_dir);BUG_ON (!parent); - err =ceph_fname_alloc_buffer (dir, &oname); + err =ceph_fname_alloc_buffer (parent_dir, &oname);if (err <0 ) {dput (parent); goto done;
@@ -1576,7 +1630,7 @@ int ceph_fill_trace(struct super_block * err =ceph_fname_to_usr (&fname,NULL , &oname, &is_nokey);if (err <0 ) {dput (parent); -ceph_fname_free_buffer (dir, &oname); +ceph_fname_free_buffer (parent_dir, &oname); goto done; } dname.name = oname.name;
@@ -1595,7 +1649,7 @@ retry_lookup: dname.len, dname.name, dn);if (!dn) {dput (parent); -ceph_fname_free_buffer (dir, &oname); +ceph_fname_free_buffer (parent_dir, &oname); err = -ENOMEM ; goto done; }
@@ -1610,12 +1664,12 @@ retry_lookup: ceph_snap(d_inode(dn)) != tvino.snap)) {doutc (cl," dn %p points to wrong inode %p\n" , dn,d_inode (dn)); -ceph_dir_clear_ordered (dir); +ceph_dir_clear_ordered (parent_dir);d_delete (dn);dput (dn); goto retry_lookup; } -ceph_fname_free_buffer (dir, &oname); +ceph_fname_free_buffer (parent_dir, &oname); req->r_dentry = dn;dput (parent);
@@ -1794,6 +1848,9 @@ retry_lookup: &dvino, ptvino); } done: +/* Drop extra ref from ceph_get_reply_dir() if it returned a new inode */ +if (unlikely (!IS_ERR_OR_NULL (parent_dir) && parent_dir != req->r_parent)) +iput (parent_dir);doutc (cl,"done err=%d\n" , err);return err; }
Greg Kroah-Hartman
maintainerPATCH 103/189 ceph: always call ceph_shift_unused_folios_left()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Max Kellermann <[email protected]>
commit cce7c15faaac79b532a07ed6ab8332280ad83762 upstream.
The function ceph_process_folio_batch() sets folio_batch entries to NULL, which is an illegal state. Before folio_batch_release() crashes due to this API violation, the function ceph_shift_unused_folios_left() is supposed to remove those NULLs from the array.
However, since commit ce80b76dd327 ("ceph: introduce ceph_process_folio_batch() method"), this shifting doesn't happen anymore because the "for" loop got moved to ceph_process_folio_batch(), and now the i variable that remains in ceph_writepages_start() doesn't get incremented anymore, making the shifting effectively unreachable much of the time.
Later, commit 1551ec61dc55 ("ceph: introduce ceph_submit_write() method") added more preconditions for doing the shift, replacing the i check (with something that is still just as broken):
- if ceph_process_folio_batch() fails, shifting never happens
- if ceph_move_dirty_page_in_page_array() was never called (because ceph_process_folio_batch() has returned early for some of various reasons), shifting never happens
- if processed_in_fbatch is zero (because ceph_process_folio_batch() has returned early for some of the reasons mentioned above or because ceph_move_dirty_page_in_page_array() has failed), shifting never happens
Since those two commits, any problem in ceph_process_folio_batch() could crash the kernel, e.g. this way:
BUG: kernel NULL pointer dereference, address: 0000000000000034 #PF: supervisor write access in kernel mode #PF: error_code(0x0002) - not-present page PGD 0 P4D 0 Oops: Oops: 0002 [#1] SMP NOPTI CPU: 172 UID: 0 PID: 2342707 Comm: kworker/u778:8 Not tainted 6.15.10-cm4all1-es #714 NONE Hardware name: Dell Inc. PowerEdge R7615/0G9DHV, BIOS 1.6.10 12/08/2023 Workqueue: writeback wb_workfn (flush-ceph-1) RIP: 0010:folios_put_refs+0x85/0x140 Code: 83 c5 01 39 e8 7e 76 48 63 c5 49 8b 5c c4 08 b8 01 00 00 00 4d 85 ed 74 05 41 8b 44 ad 00 48 8b 15 b0 > RSP: 0018:ffffb880af8db778 EFLAGS: 00010207 RAX: 0000000000000001 RBX: 0000000000000000 RCX: 0000000000000003 RDX: ffffe377cc3b0000 RSI: 0000000000000000 RDI: ffffb880af8db8c0 RBP: 0000000000000000 R08: 000000000000007d R09: 000000000102b86f R10: 0000000000000001 R11: 00000000000000ac R12: ffffb880af8db8c0 R13: 0000000000000000 R14: 0000000000000000 R15: ffff9bd262c97000 FS: 0000000000000000(0000) GS:ffff9c8efc303000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000034 CR3: 0000000160958004 CR4: 0000000000770ef0 PKRU: 55555554 Call Trace: <TASK> ceph_writepages_start+0xeb9/0x1410
The crash can be reproduced easily by changing the ceph_check_page_before_write() return value to -E2BIG.
(Interestingly, the crash happens only if huge_zero_folio has already been allocated; without huge_zero_folio, is_huge_zero_folio(NULL) returns true and folios_put_refs() skips NULL entries instead of dereferencing them. That makes reproducing the bug somewhat unreliable. See
https://lore.kernel.org/[email protected]
for a discussion of this detail.)
My suggestion is to move the ceph_shift_unused_folios_left() to right after ceph_process_folio_batch() to ensure it always gets called to fix up the illegal folio_batch state.
--- fs/ceph/addr.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
fs/ceph/addr.c +1 -2
@@ -1687,6 +1687,7 @@ get_more_pages: process_folio_batch: rc =ceph_process_folio_batch (mapping, wbc, &ceph_wbc); +ceph_shift_unused_folios_left (&ceph_wbc.fbatch);if (rc) goto release_folios;
@@ -1695,8 +1696,6 @@ process_folio_batch: goto release_folios;if (ceph_wbc.processed_in_fbatch) { -ceph_shift_unused_folios_left (&ceph_wbc.fbatch); -if (folio_batch_count (&ceph_wbc.fbatch) ==0 && ceph_wbc.locked_pages < ceph_wbc.max_pages) {doutc (cl,"reached end fbatch, trying for more\n" );
Greg Kroah-Hartman
maintainerPATCH 104/189 ceph: fix crash after fscrypt_encrypt_pagecache_blocks() error
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Max Kellermann <[email protected]>
commit 249e0a47cdb46bb9eae65511c569044bd8698d7d upstream.
The function move_dirty_folio_in_page_array() was created by commit ce80b76dd327 ("ceph: introduce ceph_process_folio_batch() method") by moving code from ceph_writepages_start() to this function.
This new function is supposed to return an error code which is checked by the caller (now ceph_process_folio_batch()), and on error, the caller invokes redirty_page_for_writepage() and then breaks from the loop.
However, the refactoring commit has gone wrong, and it by accident, it always returns 0 (= success) because it first NULLs the pointer and then returns PTR_ERR(NULL) which is always 0. This means errors are silently ignored, leaving NULL entries in the page array, which may later crash the kernel.
The simple solution is to call PTR_ERR() before clearing the pointer.
--- fs/ceph/addr.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
fs/ceph/addr.c +4 -2
@@ -1264,7 +1264,9 @@ static inline int move_dirty_folio_in_page_array(struct address_space *mapping,0 , gfp_flags);if (IS_ERR (pages[index])) { -if (PTR_ERR (pages[index]) == -EINVAL ) { +int err =PTR_ERR (pages[index]); + +if (err == -EINVAL ) {pr_err_client (cl,"inode->i_blkbits=%hhu\n" , inode->i_blkbits); }
@@ -1273,7 +1275,7 @@ static inline int move_dirty_folio_in_page_array(struct address_space *mapping,BUG_ON (ceph_wbc->locked_pages ==0 ); pages[index] =NULL ; -return PTR_ERR (pages[index]); +return err; } }else { pages[index] = &folio->page;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 105/189 mtd: spinand: Add a ->configure_chip() hook
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miquel Raynal <[email protected]>
[ Upstream commit da55809ebb45d1d80b7a388ffef841ed683e1a6f ]
There is already a manufacturer hook, which is manufacturer specific but not chip specific. We no longer have access to the actual NAND identity at this stage so let's add a per-chip configuration hook to align the chip configuration (if any) with the core's setting.
Stable-dep-of: 4550d33e1811 ("mtd: spinand: winbond: Fix oob_layout for W25N01JW")
--- drivers/mtd/nand/spi/core.c | 16 ++++++++++++++-- include/linux/mtd/spinand.h | 7 +++++++ 2 files changed, 21 insertions(+), 2 deletions(-)
drivers/mtd/nand/spi/core.c +14 -2
@@ -1253,8 +1253,19 @@ static int spinand_id_detect(struct spinstatic int spinand_manufacturer_init (struct spinand_device *spinand) { -if (spinand->manufacturer->ops->init) -return spinand->manufacturer->ops->init (spinand); +int ret; + +if (spinand->manufacturer->ops->init) { + ret = spinand->manufacturer->ops->init (spinand); +if (ret) +return ret; + } + +if (spinand->configure_chip) { + ret = spinand->configure_chip (spinand); +if (ret) +return ret; + }return 0 ; }
@@ -1349,6 +1360,7 @@ int spinand_match_and_init(struct spinan spinand->flags = table[i].flags; spinand->id.len =1 + table[i].devid.len; spinand->select_target = table[i].select_target; + spinand->configure_chip = table[i].configure_chip; spinand->set_cont_read = table[i].set_cont_read; spinand->fact_otp = &table[i].fact_otp; spinand->user_otp = &table[i].user_otp;
include/linux/mtd/spinand.h +7 -0
@@ -484,6 +484,7 @@ struct spinand_user_otp {* @op_variants.update_cache: variants of the update-cache operation * @select_target: function used to select a target/die. Required only for * multi-die chips +* @configure_chip: Align the chip configuration with the core settings * @set_cont_read: enable/disable continuous cached reads * @fact_otp: SPI NAND factory OTP info. * @user_otp: SPI NAND user OTP info.
@@ -507,6 +508,7 @@ struct spinand_info { } op_variants;int (*select_target)(struct spinand_device *spinand,unsigned int target); +int (*configure_chip)(struct spinand_device *spinand);int (*set_cont_read)(struct spinand_device *spinand,bool enable);struct spinand_fact_otp fact_otp;
@@ -539,6 +541,9 @@ struct spinand_info {#define SPINAND_SELECT_TARGET (__func) \ .select_target = __func +#define SPINAND_CONFIGURE_CHIP (__configure_chip) \ + .configure_chip = __configure_chip +#define SPINAND_CONT_READ (__set_cont_read) \ .set_cont_read = __set_cont_read
@@ -607,6 +612,7 @@ struct spinand_dirmap {* passed in spi_mem_op be DMA-able, so we can't based the bufs on * the stack * @manufacturer: SPI NAND manufacturer information +* @configure_chip: Align the chip configuration with the core settings * @cont_read_possible: Field filled by the core once the whole system * configuration is known to tell whether continuous reads are * suitable to use or not in general with this chip/configuration.
@@ -647,6 +653,7 @@ struct spinand_device {const struct spinand_manufacturer *manufacturer;void *priv; +int (*configure_chip)(struct spinand_device *spinand);bool cont_read_possible;int (*set_cont_read)(struct spinand_device *spinand,bool enable);
Greg Kroah-Hartman
maintainerPATCH 106/189 mtd: spinand: winbond: Enable high-speed modes on w25n0xjw
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miquel Raynal <[email protected]>
[ Upstream commit f1a91175faaab02a45d1ceb313a315a5bfeb5416 ]
w25n0xjw chips have a high-speed capability hidden in a configuration register. Once enabled, dual/quad SDR reads may be performed at a much higher frequency.
Implement the new ->configure_chip() hook for this purpose and configure the SR4 register accordingly.
Stable-dep-of: 4550d33e1811 ("mtd: spinand: winbond: Fix oob_layout for W25N01JW")
--- drivers/mtd/nand/spi/core.c | 2 - drivers/mtd/nand/spi/winbond.c | 45 +++++++++++++++++++++++++++++++++++++++-- include/linux/mtd/spinand.h | 1 3 files changed, 45 insertions(+), 3 deletions(-)
drivers/mtd/nand/spi/core.c +1 -1
@@ -20,7 +20,7 @@#include <linux/spi/spi.h> #include <linux/spi/spi-mem.h> -static int spinand_read_reg_op (struct spinand_device *spinand,u8 reg,u8 *val) +int spinand_read_reg_op (struct spinand_device *spinand,u8 reg,u8 *val) {struct spi_mem_op op =SPINAND_GET_FEATURE_1S_1S_1S_OP (reg, spinand->scratchbuf);
drivers/mtd/nand/spi/winbond.c +43 -2
79 lines not on this page · raw message
include/linux/mtd/spinand.h +1 -0
@@ -730,6 +730,7 @@ int spinand_match_and_init(struct spinan enum spinand_readid_method rdid_method);int spinand_upd_cfg (struct spinand_device *spinand,u8 mask,u8 val); +int spinand_read_reg_op (struct spinand_device *spinand,u8 reg,u8 *val);int spinand_write_reg_op (struct spinand_device *spinand,u8 reg,u8 val);int spinand_select_target (struct spinand_device *spinand,unsigned int target);
Greg Kroah-Hartman
maintainerPATCH 107/189 mtd: spinand: winbond: Fix oob_layout for W25N01JW
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Santhosh Kumar K <[email protected]>
[ Upstream commit 4550d33e18112a11a740424c4eec063cd58e918c ]
Fix the W25N01JW's oob_layout according to the datasheet [1]
--- drivers/mtd/nand/spi/winbond.c | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-)
drivers/mtd/nand/spi/winbond.c +36 -1
@@ -162,6 +162,36 @@ static const struct mtd_ooblayout_ops w2 .free = w25n02kv_ooblayout_free, }; +static int w25n01jw_ooblayout_ecc (struct mtd_info *mtd,int section, +struct mtd_oob_region *region) +{ +if (section >3 ) +return -ERANGE ; + + region->offset = (16 * section) +12 ; + region->length =4 ; + +return 0 ; +} + +static int w25n01jw_ooblayout_free (struct mtd_info *mtd,int section, +struct mtd_oob_region *region) +{ +if (section >3 ) +return -ERANGE ; + + region->offset = (16 * section); + region->length =12 ; + +/* Extract BBM */ +if (!section) { + region->offset +=2 ; + region->length -=2 ; + } + +return 0 ; +} +static int w35n01jw_ooblayout_ecc (struct mtd_info *mtd,int section,struct mtd_oob_region *region) {
@@ -192,6 +222,11 @@ static int w35n01jw_ooblayout_free(strucreturn 0 ; } +static const struct mtd_ooblayout_ops w25n01jw_ooblayout = { + .ecc = w25n01jw_ooblayout_ecc, + .free = w25n01jw_ooblayout_free, +}; +static const struct mtd_ooblayout_ops w35n01jw_ooblayout = { .ecc = w35n01jw_ooblayout_ecc, .free = w35n01jw_ooblayout_free,
@@ -307,7 +342,7 @@ static const struct spinand_info winbond &write_cache_variants, &update_cache_variants), 0, - SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL), + SPINAND_ECCINFO(&w25n01jw_ooblayout, NULL), SPINAND_CONFIGURE_CHIP(w25n0xjw_hs_cfg)), SPINAND_INFO("W25N01KV", /* 3.3V */ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xae, 0x21),
Greg Kroah-Hartman
maintainerPATCH 108/189 mm/damon/sysfs: fix use-after-free in state_show()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stanislav Fort <[email protected]>
commit 3260a3f0828e06f5f13fac69fb1999a6d60d9cff upstream.
state_show() reads kdamond->damon_ctx without holding damon_sysfs_lock. This allows a use-after-free race:
CPU 0 CPU 1
----- -----
state_show() damon_sysfs_turn_damon_on()
ctx = kdamond->damon_ctx; mutex_lock(&damon_sysfs_lock);
damon_destroy_ctx(kdamond->damon_ctx);
kdamond->damon_ctx = NULL;
mutex_unlock(&damon_sysfs_lock);damon_is_running(ctx); /* ctx is freed */mutex_lock(&ctx->kdamond_lock); /* UAF */
(The race can also occur with damon_sysfs_kdamonds_rm_dirs() and damon_sysfs_kdamond_release(), which free or replace the context under damon_sysfs_lock.)
Fix by taking damon_sysfs_lock before dereferencing the context, mirroring the locking used in pid_show().
The bug has existed since state_show() first accessed kdamond->damon_ctx.
--- mm/damon/sysfs.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
mm/damon/sysfs.c +9 -5
@@ -1243,14 +1243,18 @@ static ssize_t state_show(struct kobject {struct damon_sysfs_kdamond *kdamond =container_of (kobj, struct damon_sysfs_kdamond, kobj); -struct damon_ctx *ctx = kdamond->damon_ctx; -bool running; +struct damon_ctx *ctx; +bool running = false; -if (!ctx) - running = false; -else +if (!mutex_trylock (&damon_sysfs_lock)) +return -EBUSY ; + + ctx = kdamond->damon_ctx; +if (ctx) running =damon_sysfs_ctx_running (ctx); +mutex_unlock (&damon_sysfs_lock); +return sysfs_emit (buf,"%s\n" , running ? damon_sysfs_cmd_strs[DAMON_SYSFS_CMD_ON ] : damon_sysfs_cmd_strs[DAMON_SYSFS_CMD_OFF ]);
Greg Kroah-Hartman
maintainerPATCH 109/189 mm/damon/reclaim: avoid divide-by-zero in damon_reclaim_apply_parameters()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Quanmin Yan <[email protected]>
commit e6b543ca9806d7bced863f43020e016ee996c057 upstream.
When creating a new scheme of DAMON_RECLAIM, the calculation of 'min_age_region' uses 'aggr_interval' as the divisor, which may lead to division-by-zero errors. Fix it by directly returning -EINVAL when such a case occurs.
--- mm/damon/reclaim.c | 5 +++++ 1 file changed, 5 insertions(+)
mm/damon/reclaim.c +5 -0
@@ -194,6 +194,11 @@ static int damon_reclaim_apply_parameterif (err)return err; +if (!damon_reclaim_mon_attrs.aggr_interval) { + err = -EINVAL ; + goto out; + } + err =damon_set_attrs (ctx, &damon_reclaim_mon_attrs);if (err) goto out;
Greg Kroah-Hartman
maintainerPATCH 110/189 drm/amd/display: Destroy cached state in complete() callback
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello <[email protected]>
[ Upstream commit 45cc102f8e6520ac07637c7e09f61dcc3772e125 ]
[Why]
When the suspend sequence has been aborted after prepare() but before suspend() the resume() callback never gets called. The PM core will call complete() when this happens. As the state has been cached in prepare() it needs to be destroyed in complete() if it's still around.
[How]
Create a helper for destroying cached state and call it both in resume() and complete() callbacks. If resume has been called the state will be destroyed and it's a no-op for complete(). If resume hasn't been called (such as an aborted suspend) then destroy the state in complete().
Stable-dep-of: 60f71f0db7b1 ("drm/amd/display: Drop dm_prepare_suspend() and dm_complete()")
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 100 +++++++++++++--------- 1 file changed, 60 insertions(+), 40 deletions(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +60 -40
@@ -3084,6 +3084,64 @@ static int dm_cache_state(struct amdgpu_return adev->dm.cached_state ?0 : r; } +static void dm_destroy_cached_state (struct amdgpu_device *adev) +{ +struct amdgpu_display_manager *dm = &adev->dm; +struct drm_device *ddev =adev_to_drm (adev); +struct dm_plane_state *dm_new_plane_state; +struct drm_plane_state *new_plane_state; +struct dm_crtc_state *dm_new_crtc_state; +struct drm_crtc_state *new_crtc_state; +struct drm_plane *plane; +struct drm_crtc *crtc; +int i; + +if (!dm->cached_state) +return ; + +/* Force mode set in atomic commit */ +for_each_new_crtc_in_state (dm->cached_state, crtc, new_crtc_state, i) { + new_crtc_state->active_changed = true; + dm_new_crtc_state =to_dm_crtc_state (new_crtc_state); +reset_freesync_config_for_crtc (dm_new_crtc_state); + } + +/* +* atomic_check is expected to create the dc states. We need to release +* them here, since they were duplicated as part of the suspend +* procedure. +*/ +for_each_new_crtc_in_state (dm->cached_state, crtc, new_crtc_state, i) { + dm_new_crtc_state =to_dm_crtc_state (new_crtc_state); +if (dm_new_crtc_state->stream) { +WARN_ON (kref_read (&dm_new_crtc_state->stream->refcount) >1 ); +dc_stream_release (dm_new_crtc_state->stream); + dm_new_crtc_state->stream =NULL ; + } + dm_new_crtc_state->base.color_mgmt_changed = true; + } + +for_each_new_plane_in_state (dm->cached_state, plane, new_plane_state, i) { + dm_new_plane_state =to_dm_plane_state (new_plane_state); +if (dm_new_plane_state->dc_state) { +WARN_ON (kref_read (&dm_new_plane_state->dc_state->refcount) >1 ); +dc_plane_state_release (dm_new_plane_state->dc_state); + dm_new_plane_state->dc_state =NULL ; + } + } + +drm_atomic_helper_resume (ddev, dm->cached_state); + + dm->cached_state =NULL ; +} + +static void dm_complete (struct amdgpu_ip_block *ip_block) +{ +struct amdgpu_device *adev = ip_block->adev; + +dm_destroy_cached_state (adev); +} +static int dm_prepare_suspend (struct amdgpu_ip_block *ip_block) {struct amdgpu_device *adev = ip_block->adev;
@@ -3317,12 +3375,6 @@ static int dm_resume(struct amdgpu_ip_blstruct amdgpu_dm_connector *aconnector;struct drm_connector *connector;struct drm_connector_list_iter iter; -struct drm_crtc *crtc; -struct drm_crtc_state *new_crtc_state; -struct dm_crtc_state *dm_new_crtc_state; -struct drm_plane *plane; -struct drm_plane_state *new_plane_state; -struct dm_plane_state *dm_new_plane_state;struct dm_atomic_state *dm_state =to_dm_atomic_state (dm->atomic_obj.state);enum dc_connection_type new_connection_type = dc_connection_none;struct dc_state *dc_state;
@@ -3481,40 +3533,7 @@ static int dm_resume(struct amdgpu_ip_bl }drm_connector_list_iter_end (&iter); -/* Force mode set in atomic commit */ -for_each_new_crtc_in_state (dm->cached_state, crtc, new_crtc_state, i) { - new_crtc_state->active_changed = true; - dm_new_crtc_state =to_dm_crtc_state (new_crtc_state); -reset_freesync_config_for_crtc (dm_new_crtc_state); - } - -/* -* atomic_check is expected to create the dc states. We need to release -* them here, since they were duplicated as part of the suspend -* procedure. -*/ -for_each_new_crtc_in_state (dm->cached_state, crtc, new_crtc_state, i) { - dm_new_crtc_state =to_dm_crtc_state (new_crtc_state); -if (dm_new_crtc_state->stream) { -WARN_ON (kref_read (&dm_new_crtc_state->stream->refcount) >1 ); -dc_stream_release (dm_new_crtc_state->stream); - dm_new_crtc_state->stream =NULL ; - } - dm_new_crtc_state->base.color_mgmt_changed = true; - } - -for_each_new_plane_in_state (dm->cached_state, plane, new_plane_state, i) { - dm_new_plane_state =to_dm_plane_state (new_plane_state); -if (dm_new_plane_state->dc_state) { -WARN_ON (kref_read (&dm_new_plane_state->dc_state->refcount) >1 ); -dc_plane_state_release (dm_new_plane_state->dc_state); - dm_new_plane_state->dc_state =NULL ; - } - } - -drm_atomic_helper_resume (ddev, dm->cached_state); - - dm->cached_state =NULL ; +dm_destroy_cached_state (adev);/* Do mst topology probing after resuming cached state*/ drm_connector_list_iter_begin (ddev, &iter);
@@ -3563,6 +3582,7 @@ static const struct amd_ip_funcs amdgpu_ .prepare_suspend = dm_prepare_suspend, .suspend = dm_suspend, .resume = dm_resume, + .complete = dm_complete, .is_idle = dm_is_idle, .wait_for_idle = dm_wait_for_idle, .check_soft_reset = dm_check_soft_reset,
Greg Kroah-Hartman
maintainerPATCH 111/189 drm/amd/display: Drop dm_prepare_suspend() and dm_complete()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Mario Limonciello (AMD)" <[email protected]>
[ Upstream commit 60f71f0db7b12f303789ef59949e38ee5838ee8b ]
[Why]dm_prepare_suspend() was added in commit 50e0bae34fa6b ("drm/amd/display: Add and use new dm_prepare_suspend() callback") to allow display to turn off earlier in the suspend sequence.
This caused a regression that HDMI audio sometimes didn't work properly after resume unless audio was playing during suspend.
[How]
Drop dm_prepare_suspend() callback. All code in it will still run during dm_suspend(). Also drop unnecessary dm_complete() callback. dm_complete() was used for failed prepare and also for any case of successful resume. The code in it already runs in dm_resume().
This change will introduce more time that the display is turned on during suspend sequence. The compositor can turn it off sooner if desired.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 21 --------------------- 1 file changed, 21 deletions(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +0 -21
@@ -3135,25 +3135,6 @@ static void dm_destroy_cached_state(stru dm->cached_state =NULL ; } -static void dm_complete (struct amdgpu_ip_block *ip_block) -{ -struct amdgpu_device *adev = ip_block->adev; - -dm_destroy_cached_state (adev); -} - -static int dm_prepare_suspend (struct amdgpu_ip_block *ip_block) -{ -struct amdgpu_device *adev = ip_block->adev; - -if (amdgpu_in_reset (adev)) -return 0 ; - -WARN_ON (adev->dm.cached_state); - -return dm_cache_state (adev); -} -static int dm_suspend (struct amdgpu_ip_block *ip_block) {struct amdgpu_device *adev = ip_block->adev;
@@ -3579,10 +3560,8 @@ static const struct amd_ip_funcs amdgpu_ .early_fini = amdgpu_dm_early_fini, .hw_init = dm_hw_init, .hw_fini = dm_hw_fini, - .prepare_suspend = dm_prepare_suspend, .suspend = dm_suspend, .resume = dm_resume, - .complete = dm_complete, .is_idle = dm_is_idle, .wait_for_idle = dm_wait_for_idle, .check_soft_reset = dm_check_soft_reset,
Greg Kroah-Hartman
maintainerPATCH 112/189 drm/amd/amdgpu: Declare isp firmware binary file
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pratap Nirujogi <[email protected]>
commit 857ccfc19f9be1269716f3d681650c1bd149a656 upstream.
Declare isp firmware file isp_4_1_1.bin required by isp4.1.1 device.
--- drivers/gpu/drm/amd/amdgpu/isp_v4_1_1.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/amd/amdgpu/isp_v4_1_1.c +2 -0
@@ -29,6 +29,8 @@#include "amdgpu.h" #include "isp_v4_1_1.h" +MODULE_FIRMWARE ("amdgpu/isp_4_1_1.bin" ); +static const unsigned int isp_4_1_1_int_srcid[MAX_ISP411_INT_SRC ] = {ISP_4_1__SRCID__ISP_RINGBUFFER_WPT9 ,ISP_4_1__SRCID__ISP_RINGBUFFER_WPT10 ,
Greg Kroah-Hartman
maintainerPATCH 113/189 hrtimers: Unconditionally update target CPU base after offline timer migration
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiongfeng Wang <[email protected]>
commit e895f8e29119c8c966ea794af9e9100b10becb88 upstream.
When testing softirq based hrtimers on an ARM32 board, with high resolution mode and NOHZ inactive, softirq based hrtimers fail to expire after being moved away from an offline CPU:
CPU0 CPU1
hrtimer_start(..., HRTIMER_MODE_SOFT);
cpu_down(CPU1) ...
hrtimers_cpu_dying()
// Migrate timers to CPU0
smp_call_function_single(CPU0, returgger_next_event);
retrigger_next_event()
if (!highres && !nohz)
return;As retrigger_next_event() is a NOOP when both high resolution timers and NOHZ are inactive CPU0's hrtimer_cpu_base::softirq_expires_next is not updated and the migrated softirq timers never expire unless there is a softirq based hrtimer queued on CPU0 later.
Fix this by removing the hrtimer_hres_active() and tick_nohz_active() check in retrigger_next_event(), which enforces a full update of the CPU base. As this is not a fast path the extra cost does not matter.
[ tglx: Massaged change log ]
--- kernel/time/hrtimer.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-)
kernel/time/hrtimer.c +3 -8
@@ -787,10 +787,10 @@ static void retrigger_next_event(void *a* of the next expiring timer is enough. The return from the SMP * function call will take care of the reprogramming in case the * CPU was in a NOHZ idle sleep. +* +* In periodic low resolution mode, the next softirq expiration +* must also be updated. */ -if (!hrtimer_hres_active (base) && !tick_nohz_active) -return ; -raw_spin_lock (&base->lock);hrtimer_update_base (base);if (hrtimer_hres_active (base))
@@ -2295,11 +2295,6 @@ int hrtimers_cpu_dying(unsigned int dyin &new_base->clock_base[i]); } -/* -* The migration might have changed the first expiring softirq -* timer on this CPU. Update it. -*/ -__hrtimer_get_next_event (new_base,HRTIMER_ACTIVE_SOFT );/* Tell the other CPU to retrigger the next event */ smp_call_function_single (ncpu, retrigger_next_event,NULL ,0 );
Greg Kroah-Hartman
maintainerPATCH 114/189 fs/resctrl: Eliminate false positive lockdep warning when reading SNC counters
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Reinette Chatre <[email protected]>
commit d2e1b84c5141ff2ad465279acfc3cf943c960b78 upstream.
Running resctrl_tests on an SNC-2 system with lockdep debugging enabled triggers several warnings with following trace:
WARNING: CPU: 0 PID: 1914 at kernel/cpu.c:528 lockdep_assert_cpus_held ... Call Trace: __mon_event_count ? __lock_acquire ? __pfx___mon_event_count mon_event_count ? __pfx_smp_mon_event_count smp_mon_event_count smp_call_on_cpu_callback
get_cpu_cacheinfo_level() called from __mon_event_count() requires CPU hotplug lock to be held. The hotplug lock is indeed held during this time, as confirmed by the lockdep_assert_cpus_held() within mon_event_read() that calls mon_event_count() via IPI, but the lockdep tracking is not able to follow the IPI.
Fresh CPU cache information via get_cpu_cacheinfo_level() from __mon_event_count() was added to support the fix for the issue where resctrl inappropriately maintained links to L3 cache information that will be stale in the case when the associated CPU goes offline.
Keep the cacheinfo ID in struct rdt_mon_domain to ensure that resctrl does not maintain stale cache information while CPUs can go offline. Return to using a pointer to the L3 cache information (struct cacheinfo) in struct rmid_read, rmid_read::ci. Initialize rmid_read::ci before the IPI where it is used. CPU hotplug lock is held across rmid_read::ci initialization and use to ensure that it points to accurate cache information.
--- fs/resctrl/ctrlmondata.c | 2 +- fs/resctrl/internal.h | 4 ++-- fs/resctrl/monitor.c | 6 ++---- 3 files changed, 5 insertions(+), 7 deletions(-)
fs/resctrl/ctrlmondata.c +1 -1
@@ -625,11 +625,11 @@ int rdtgroup_mondata_show(struct seq_file *m, void *arg)*/ list_for_each_entry (d, &r->mon_domains, hdr.list) {if (d->ci_id == domid) { - rr.ci_id = d->ci_id; cpu =cpumask_any (&d->hdr.cpu_mask); ci =get_cpu_cacheinfo_level (cpu,RESCTRL_L3_CACHE );if (!ci)continue ; + rr.ci = ci;mon_event_read (&rr, r,NULL , rdtgrp, &ci->shared_cpu_map, evtid, false); goto checkresult;
fs/resctrl/internal.h +2 -2
@@ -98,7 +98,7 @@ struct mon_data {* domains in @r sharing L3 @ci.id * @evtid: Which monitor event to read. * @first: Initialize MBM counter when true. -* @ci_id: Cacheinfo id for L3. Only set when @d is NULL. Used when summing domains. +* @ci: Cacheinfo for L3. Only set when @d is NULL. Used when summing domains. * @err: Error encountered when reading counter. * @val: Returned value of event counter. If @rgrp is a parent resource group, * @val includes the sum of event counts from its child resource groups.
@@ -112,7 +112,7 @@ struct rmid_read {struct rdt_mon_domain *d;enum resctrl_event_id evtid;bool first; -unsigned int ci_id; +struct cacheinfo *ci;int err;u64 val;void *arch_mon_ctx;
fs/resctrl/monitor.c +2 -4
@@ -361,7 +361,6 @@ static int __mon_event_count(u32 closid, u32 rmid, struct rmid_read *rr) {int cpu =smp_processor_id ();struct rdt_mon_domain *d; -struct cacheinfo *ci;struct mbm_state *m;int err, ret;u64 tval =0 ;
@@ -389,8 +388,7 @@ static int __mon_event_count(u32 closid, u32 rmid, struct rmid_read *rr) }/* Summing domains that share a cache, must be on a CPU for that cache. */ - ci =get_cpu_cacheinfo_level (cpu,RESCTRL_L3_CACHE ); -if (!ci || ci->id != rr->ci_id) +if (!cpumask_test_cpu (cpu, &rr->ci->shared_cpu_map))return -EINVAL ;/*
@@ -402,7 +400,7 @@ static int __mon_event_count(u32 closid, u32 rmid, struct rmid_read *rr)*/ ret = -EINVAL ;list_for_each_entry (d, &rr->r->mon_domains, hdr.list) { -if (d->ci_id != rr->ci_id) +if (d->ci_id != rr->ci->id)continue ; err =resctrl_arch_rmid_read (rr->r, d, closid, rmid, rr->evtid, &tval, rr->arch_mon_ctx);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 115/189 x86/cpu/topology: Always try cpu_parse_topology_ext() on AMD/Hygon
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: K Prateek Nayak <[email protected]>
commit cba4262a19afae21665ee242b3404bcede5a94d7 upstream.
Support for parsing the topology on AMD/Hygon processors using CPUID leaf 0xb was added in
3986a0a805e6 ("x86/CPU/AMD: Derive CPU topology from CPUID function 0xB when available").
In an effort to keep all the topology parsing bits in one place, this commit also introduced a pseudo dependency on the TOPOEXT feature to parse the CPUID leaf 0xb.
The TOPOEXT feature (CPUID 0x80000001 ECX[22]) advertises the support for Cache Properties leaf 0x8000001d and the CPUID leaf 0x8000001e EAX for "Extended APIC ID" however support for 0xb was introduced alongside the x2APIC support not only on AMD [1], but also historically on x86 [2].
Similar to 0xb, the support for extended CPU topology leaf 0x80000026 too does not depend on the TOPOEXT feature.
The support for these leaves is expected to be confirmed by ensuring
leaf <= {extended_}cpuid_level
and then parsing the level 0 of the respective leaf to confirm EBX[15:0] (LogProcAtThisLevel) is non-zero as stated in the definition of "CPUID_Fn0000000B_EAX_x00 [Extended Topology Enumeration] (Core::X86::Cpuid::ExtTopEnumEax0)" in Processor Programming Reference (PPR) for AMD Family 19h Model 01h Rev B1 Vol1 [3] Sec. 2.1.15.1 "CPUID Instruction Functions".
This has not been a problem on baremetal platforms since support for TOPOEXT (Fam 0x15 and later) predates the support for CPUID leaf 0xb (Fam 0x17[Zen2] and later), however, for AMD guests on QEMU, the "x2apic" feature can be enabled independent of the "topoext" feature where QEMU expects topology and the initial APICID to be parsed using the CPUID leaf 0xb (especially when number of cores > 255) which is populated independent of the "topoext" feature flag.
Unconditionally call cpu_parse_topology_ext() on AMD and Hygon processors to first parse the topology using the XTOPOLOGY leaves (0x80000026 / 0xb) before using the TOPOEXT leaf (0x8000001e).
While at it, break down the single large comment in parse_topology_amd() to better highlight the purpose of each CPUID leaf.
--- arch/x86/kernel/cpu/topology_amd.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-)
arch/x86/kernel/cpu/topology_amd.c +14 -11
@@ -175,27 +175,30 @@ static void topoext_fixup(struct topo_scstatic void parse_topology_amd (struct topo_scan *tscan) { -bool has_topoext = false; -/* -* If the extended topology leaf 0x8000_001e is available -* try to get SMT, CORE, TILE, and DIE shifts from extended +* Try to get SMT, CORE, TILE, and DIE shifts from extended * CPUID leaf 0x8000_0026 on supported processors first. If * extended CPUID leaf 0x8000_0026 is not supported, try to -* get SMT and CORE shift from leaf 0xb first, then try to -* get the CORE shift from leaf 0x8000_0008. +* get SMT and CORE shift from leaf 0xb. If either leaf is +* available, cpu_parse_topology_ext() will return true. */ -if (cpu_feature_enabled (X86_FEATURE_TOPOEXT )) - has_topoext =cpu_parse_topology_ext (tscan); +bool has_xtopology =cpu_parse_topology_ext (tscan);if (cpu_feature_enabled (X86_FEATURE_AMD_HTR_CORES )) tscan->c->topo.cpu_type =cpuid_ebx (0x80000026 ); -if (!has_topoext && !parse_8000_0008 (tscan)) +/* +* If XTOPOLOGY leaves (0x26/0xb) are not available, try to +* get the CORE shift from leaf 0x8000_0008 first. +*/ +if (!has_xtopology && !parse_8000_0008 (tscan))return ; -/* Prefer leaf 0x8000001e if available */ -if (parse_8000_001e (tscan, has_topoext)) +/* +* Prefer leaf 0x8000001e if available to get the SMT shift and +* the initial APIC ID if XTOPOLOGY leaves are not available. +*/ +if (parse_8000_001e (tscan, has_xtopology))return ;/* Try the NODEID MSR */
Greg Kroah-Hartman
maintainerPATCH 116/189 Input: iqs7222 - avoid enabling unused interrupts
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeff LaBundy <[email protected]>
commit c9ddc41cdd522f2db5d492eda3df8994d928be34 upstream.
If a proximity event node is defined so as to specify the wake-up properties of the touch surface, the proximity event interrupt is enabled unconditionally. This may result in unwanted interrupts.
Solve this problem by enabling the interrupt only if the event is mapped to a key or switch code.
--- drivers/input/misc/iqs7222.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/input/misc/iqs7222.c +3 -0
@@ -2427,6 +2427,9 @@ static int iqs7222_parse_chan(struct iqsif (error)return error; +if (!iqs7222->kp_type[chan_index][i]) +continue ; +if (!dev_desc->event_offset)continue ;
Greg Kroah-Hartman
maintainerPATCH 117/189 Input: i8042 - add TUXEDO InfinityBook Pro Gen10 AMD to i8042 quirk table
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoffer Sandberg <[email protected]>
commit 1939a9fcb80353dd8b111aa1e79c691afbde08b4 upstream.
Occasionally wakes up from suspend with missing input on the internal keyboard. Setting the quirks appears to fix the issue for this device as well.
--- drivers/input/serio/i8042-acpipnpio.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
drivers/input/serio/i8042-acpipnpio.h +14 -0
@@ -1155,6 +1155,20 @@ static const struct dmi_system_id i8042_ .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) }, + { + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "XxHP4NAx"), + }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | + SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) + }, + { + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "XxKK4NAx_XxSP4NAx"), + }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | + SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) + }, /* * A lot of modern Clevo barebones have touchpad and/or keyboard issues * after suspend fixable with the forcenorestore quirk.
Greg Kroah-Hartman
maintainerPATCH 118/189 Input: xpad - add support for Flydigi Apex 5
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Antheas Kapenekakis <[email protected]>
commit 47ddf62b43eced739b56422cd55e86b9b4bb7dac upstream.
Add Flydigi Apex 5 to the list of recognized controllers.
--- drivers/input/joystick/xpad.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/input/joystick/xpad.c +2 -0
@@ -422,6 +422,7 @@ static const struct xpad_device { { 0x3537, 0x1010, "GameSir G7 SE", 0, XTYPE_XBOXONE }, { 0x366c, 0x0005, "ByoWave Proteus Controller", MAP_SHARE_BUTTON, XTYPE_XBOXONE, FLAG_DELAY_INIT }, { 0x3767, 0x0101, "Fanatec Speedster 3 Forceshock Wheel", 0, XTYPE_XBOX }, + { 0x37d7, 0x2501, "Flydigi Apex 5", 0, XTYPE_XBOX360 }, { 0x413d, 0x2104, "Black Shark Green Ghost Gamepad", 0, XTYPE_XBOX360 }, { 0xffff, 0xffff, "Chinese-made Xbox Controller", 0, XTYPE_XBOX }, { 0x0000, 0x0000, "Generic X-Box pad", 0, XTYPE_UNKNOWN }
@@ -578,6 +579,7 @@ static const struct usb_device_id xpad_tXPAD_XBOX360_VENDOR (0x3537 ),/* GameSir Controllers */ XPAD_XBOXONE_VENDOR (0x3537 ),/* GameSir Controllers */ XPAD_XBOXONE_VENDOR (0x366c ),/* ByoWave controllers */ +XPAD_XBOX360_VENDOR (0x37d7 ),/* Flydigi Controllers */ XPAD_XBOX360_VENDOR(0x413d), /* Black Shark Green Ghost Controller */ { } };
Greg Kroah-Hartman
maintainerPATCH 119/189 Revert "net: usb: asix: ax88772: drop phylink use in PM to avoid MDIO runtime PM wakeups"
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Abeni <[email protected]>
commit 63a796558bc22ec699e4193d5c75534757ddf2e6 upstream.
This reverts commit 5537a4679403 ("net: usb: asix: ax88772: drop phylink use in PM to avoid MDIO runtime PM wakeups"), it breaks operation of asix ethernet usb dongle after system suspend-resume cycle.
--- drivers/net/usb/asix_devices.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
drivers/net/usb/asix_devices.c +13 -0
@@ -607,8 +607,15 @@ static const struct net_device_ops ax887static void ax88772_suspend (struct usbnet *dev) { +struct asix_common_private *priv = dev->driver_priv;u16 medium; +if (netif_running (dev->net)) { +rtnl_lock (); +phylink_suspend (priv->phylink, false); +rtnl_unlock (); + } +/* Stop MAC operation */ medium =asix_read_medium_status (dev,1 ); medium &= ~AX_MEDIUM_RE ;
@@ -637,6 +644,12 @@ static void ax88772_resume(struct usbnetfor (i =0 ; i <3 ; i++)if (!priv->reset (dev,1 ))break ; + +if (netif_running (dev->net)) { +rtnl_lock (); +phylink_resume (priv->phylink); +rtnl_unlock (); + } }static int asix_resume (struct usb_interface *intf)
Greg Kroah-Hartman
maintainerPATCH 120/189 tty: hvc_console: Call hvc_kick in hvc_write unconditionally
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fabian Vogt <[email protected]>
commit cfd956dcb101aa3d25bac321fae923323a47c607 upstream.
After hvc_write completes, call hvc_kick also in the case the output buffer has been drained, to ensure tty_wakeup gets called.
This fixes that functions which wait for a drained buffer got stuck occasionally.
--- drivers/tty/hvc/hvc_console.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/tty/hvc/hvc_console.c +3 -3
@@ -543,10 +543,10 @@ static ssize_t hvc_write(struct tty_stru }/* -* Racy, but harmless, kick thread if there is still pending data. +* Kick thread to flush if there's still pending data +* or to wakeup the write queue. */ -if (hp->n_outbuf) -hvc_kick (); +hvc_kick ();return written; }
Greg Kroah-Hartman
maintainerPATCH 121/189 serial: sc16is7xx: fix bug in flow control levels init
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hugo Villeneuve <[email protected]>
commit 535fd4c98452c87537a40610abba45daf5761ec6 upstream.
When trying to set MCR[2], XON1 is incorrectly accessed instead. And when writing to the TCR register to configure flow control levels, we are incorrectly writing to the MSR register. The default value of $00 is then used for TCR, which means that selectable trigger levels in FCR are used in place of TCR.
TCR/TLR access requires EFR[4] (enable enhanced functions) and MCR[2] to be set. EFR[4] is already set in probe().
MCR access requires LCR[7] to be zero.
Since LCR is set to $BF when trying to set MCR[2], XON1 is incorrectly accessed instead because MCR shares the same address space as XON1.
Since MCR[2] is unmodified and still zero, when writing to TCR we are in fact writing to MSR because TCR/TLR registers share the same address space as MSR/SPR.
Fix by first removing useless reconfiguration of EFR[4] (enable enhanced functions), as it is already enabled in sc16is7xx_probe() since commit 43c51bb573aa ("sc16is7xx: make sure device is in suspend once probed"). Now LCR is $00, which means that MCR access is enabled.
Also remove regcache_cache_bypass() calls since we no longer access the enhanced registers set, and TCR is already declared as volatile (in fact by declaring MSR as volatile, which shares the same address).
Finally disable access to TCR/TLR registers after modifying them by clearing MCR[2].
Note: the comment about "... and internal clock div" is wrong and can be
ignored/removed as access to internal clock div registers (DLL/DLH) is permitted only when LCR[7] is logic 1, not when enhanced features is enabled. And DLL/DLH access is not needed in sc16is7xx_startup().
--- drivers/tty/serial/sc16is7xx.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-)
drivers/tty/serial/sc16is7xx.c +2 -12
@@ -1177,17 +1177,6 @@ static int sc16is7xx_startup(struct uartsc16is7xx_port_write (port,SC16IS7XX_FCR_REG ,SC16IS7XX_FCR_FIFO_BIT ); -/* Enable EFR */ -sc16is7xx_port_write (port,SC16IS7XX_LCR_REG , -SC16IS7XX_LCR_CONF_MODE_B ); - -regcache_cache_bypass (one->regmap, true); - -/* Enable write access to enhanced features and internal clock div */ -sc16is7xx_port_update (port,SC16IS7XX_EFR_REG , -SC16IS7XX_EFR_ENABLE_BIT , -SC16IS7XX_EFR_ENABLE_BIT ); -/* Enable TCR/TLR */ sc16is7xx_port_update(port, SC16IS7XX_MCR_REG, SC16IS7XX_MCR_TCRTLR_BIT,
@@ -1199,7 +1188,8 @@ static int sc16is7xx_startup(struct uartSC16IS7XX_TCR_RX_RESUME (24 ) | SC16IS7XX_TCR_RX_HALT(48)); -regcache_cache_bypass (one->regmap, false); +/* Disable TCR/TLR access */ +sc16is7xx_port_update (port,SC16IS7XX_MCR_REG ,SC16IS7XX_MCR_TCRTLR_BIT ,0 );/* Now, initialize the UART */ sc16is7xx_port_write (port,SC16IS7XX_LCR_REG ,SC16IS7XX_LCR_WORD_LEN_8 );
Greg Kroah-Hartman
maintainerPATCH 122/189 dt-bindings: serial: brcm,bcm7271-uart: Constrain clocks
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski <[email protected]>
commit ee047e1d85d73496541c54bd4f432c9464e13e65 upstream.
Lists should have fixed constraints, because binding must be specific in respect to hardware, thus add missing constraints to number of clocks.
--- Documentation/devicetree/bindings/serial/brcm,bcm7271-uart.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Documentation/devicetree/bindings/serial/brcm,bcm7271-uart.yaml +1 -1
@@ -41,7 +41,7 @@ properties: - const: dma_intr2 clocks: - minItems: 1 + maxItems: 1 clock-names: const: sw_baud
Greg Kroah-Hartman
maintainerPATCH 123/189 USB: serial: option: add Telit Cinterion FN990A w/audio compositions
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fabio Porcedda <[email protected]>
commit cba70aff623b104085ab5613fedd21f6ea19095a upstream.
Add the following Telit Cinterion FN990A w/audio compositions:
0x1077: tty (diag) + adb + rmnet + audio + tty (AT/NMEA) + tty (AT) + tty (AT) + tty (AT)
T: Bus=01 Lev=01 Prnt=01 Port=09 Cnt=01 Dev#= 8 Spd=480 MxCh= 0 D: Ver= 2.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=1bc7 ProdID=1077 Rev=05.04 S: Manufacturer=Telit Wireless Solutions S: Product=FN990 S: SerialNumber=67e04c35 C: #Ifs=10 Cfg#= 1 Atr=e0 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none) E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=50 Driver=qmi_wwan E: Ad=0f(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=83(I) Atr=03(Int.) MxPS= 8 Ivl=32ms E: Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 3 Alt= 0 #EPs= 0 Cls=01(audio) Sub=01 Prot=20 Driver=snd-usb-audio I: If#= 4 Alt= 1 #EPs= 1 Cls=01(audio) Sub=02 Prot=20 Driver=snd-usb-audio E: Ad=03(O) Atr=0d(Isoc) MxPS= 68 Ivl=1ms I: If#= 5 Alt= 1 #EPs= 1 Cls=01(audio) Sub=02 Prot=20 Driver=snd-usb-audio E: Ad=84(I) Atr=0d(Isoc) MxPS= 68 Ivl=1ms I: If#= 6 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=60 Driver=option E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=86(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 7 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=88(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 8 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=89(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=8a(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 9 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=8b(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=8c(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
0x1078: tty (diag) + adb + MBIM + audio + tty (AT/NMEA) + tty (AT) + tty (AT) + tty (AT)
T: Bus=01 Lev=01 Prnt=01 Port=09 Cnt=01 Dev#= 21 Spd=480 MxCh= 0 D: Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=1bc7 ProdID=1078 Rev=05.04 S: Manufacturer=Telit Wireless Solutions S: Product=FN990 S: SerialNumber=67e04c35 C: #Ifs=11 Cfg#= 1 Atr=e0 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none) E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#=10 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=8b(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=8c(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 2 Alt= 0 #EPs= 1 Cls=02(commc) Sub=0e Prot=00 Driver=cdc_mbim E: Ad=83(I) Atr=03(Int.) MxPS= 64 Ivl=32ms I: If#= 3 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim E: Ad=0f(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 4 Alt= 0 #EPs= 0 Cls=01(audio) Sub=01 Prot=20 Driver=snd-usb-audio I: If#= 5 Alt= 0 #EPs= 0 Cls=01(audio) Sub=02 Prot=20 Driver=snd-usb-audio I: If#= 6 Alt= 1 #EPs= 1 Cls=01(audio) Sub=02 Prot=20 Driver=snd-usb-audio E: Ad=84(I) Atr=0d(Isoc) MxPS= 68 Ivl=1ms I: If#= 7 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=60 Driver=option E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=86(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 8 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=88(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 9 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=89(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=8a(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
0x1079: RNDIS + tty (diag) + adb + audio + tty (AT/NMEA) + tty (AT) + tty (AT) + tty (AT)
T: Bus=01 Lev=01 Prnt=01 Port=09 Cnt=01 Dev#= 23 Spd=480 MxCh= 0 D: Ver= 2.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=1bc7 ProdID=1079 Rev=05.04 S: Manufacturer=Telit Wireless Solutions S: Product=FN990 S: SerialNumber=67e04c35 C: #Ifs=11 Cfg#= 1 Atr=e0 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 1 Cls=ef(misc ) Sub=04 Prot=01 Driver=rndis_host E: Ad=81(I) Atr=03(Int.) MxPS= 8 Ivl=32ms I: If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=rndis_host E: Ad=0f(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#=10 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=8b(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=8c(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none) E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 4 Alt= 0 #EPs= 0 Cls=01(audio) Sub=01 Prot=20 Driver=snd-usb-audio I: If#= 5 Alt= 0 #EPs= 0 Cls=01(audio) Sub=02 Prot=20 Driver=snd-usb-audio I: If#= 6 Alt= 1 #EPs= 1 Cls=01(audio) Sub=02 Prot=20 Driver=snd-usb-audio E: Ad=84(I) Atr=0d(Isoc) MxPS= 68 Ivl=1ms I: If#= 7 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=60 Driver=option E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=86(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 8 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=88(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 9 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=89(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=8a(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
--- drivers/usb/serial/option.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/usb/serial/option.c +6 -0
@@ -1369,6 +1369,12 @@ static const struct usb_device_id option .driver_info = NCTRL(0) | RSVD(1) }, { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1075, 0xff), /* Telit FN990A (PCIe) */ .driver_info = RSVD(0) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1077, 0xff), /* Telit FN990A (rmnet + audio) */ + .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1078, 0xff), /* Telit FN990A (MBIM + audio) */ + .driver_info = NCTRL(0) | RSVD(1) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1079, 0xff), /* Telit FN990A (RNDIS + audio) */ + .driver_info = NCTRL(2) | RSVD(3) }, { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1080, 0xff), /* Telit FE990A (rmnet) */ .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) }, { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1081, 0xff), /* Telit FE990A (MBIM) */
Greg Kroah-Hartman
maintainerPATCH 124/189 USB: serial: option: add Telit Cinterion LE910C4-WWX new compositions
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fabio Porcedda <[email protected]>
commit a5a261bea9bf8444300d1067b4a73bedee5b5227 upstream.
Add the following Telit Cinterion LE910C4-WWX new compositions:
0x1034: tty (AT) + tty (AT) + rmnet
T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 8 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=1bc7 ProdID=1034 Rev=00.00 S: Manufacturer=Telit S: Product=LE910C4-WWX S: SerialNumber=93f617e7 C: #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=81(I) Atr=03(Int.) MxPS= 64 Ivl=2ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=fe Prot=ff Driver=option E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=83(I) Atr=03(Int.) MxPS= 64 Ivl=2ms E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qmi_wwan E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=85(I) Atr=03(Int.) MxPS= 64 Ivl=2ms E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
0x1036: tty (AT) + tty (AT)
T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 10 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=1bc7 ProdID=1036 Rev=00.00 S: Manufacturer=Telit S: Product=LE910C4-WWX S: SerialNumber=93f617e7 C: #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=81(I) Atr=03(Int.) MxPS= 64 Ivl=2ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=fe Prot=ff Driver=option E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=83(I) Atr=03(Int.) MxPS= 64 Ivl=2ms E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
0x1037: tty (diag) + tty (Telit custom) + tty (AT) + tty (AT) + rmnet
T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 15 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=1bc7 ProdID=1037 Rev=00.00 S: Manufacturer=Telit S: Product=LE910C4-WWX S: SerialNumber=93f617e7 C: #Ifs= 5 Cfg#= 1 Atr=e0 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=83(I) Atr=03(Int.) MxPS= 64 Ivl=2ms E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=fe Prot=ff Driver=option E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=85(I) Atr=03(Int.) MxPS= 64 Ivl=2ms E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qmi_wwan E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=87(I) Atr=03(Int.) MxPS= 64 Ivl=2ms E: Ad=88(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
0x1038: tty (Telit custom) + tty (AT) + tty (AT) + rmnet
T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 9 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=1bc7 ProdID=1038 Rev=00.00 S: Manufacturer=Telit S: Product=LE910C4-WWX S: SerialNumber=93f617e7 C: #Ifs= 4 Cfg#= 1 Atr=e0 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=82(I) Atr=03(Int.) MxPS= 64 Ivl=2ms E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=fe Prot=ff Driver=option E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=84(I) Atr=03(Int.) MxPS= 64 Ivl=2ms E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qmi_wwan E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=86(I) Atr=03(Int.) MxPS= 64 Ivl=2ms E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
0x103b: tty (diag) + tty (Telit custom) + tty (AT) + tty (AT)
T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 10 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=1bc7 ProdID=103b Rev=00.00 S: Manufacturer=Telit S: Product=LE910C4-WWX S: SerialNumber=93f617e7 C: #Ifs= 4 Cfg#= 1 Atr=e0 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=83(I) Atr=03(Int.) MxPS= 64 Ivl=2ms E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=fe Prot=ff Driver=option E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=85(I) Atr=03(Int.) MxPS= 64 Ivl=2ms E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
0x103c: tty (Telit custom) + tty (AT) + tty (AT)
T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 11 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=1bc7 ProdID=103c Rev=00.00 S: Manufacturer=Telit S: Product=LE910C4-WWX S: SerialNumber=93f617e7 C: #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=82(I) Atr=03(Int.) MxPS= 64 Ivl=2ms E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=fe Prot=ff Driver=option E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=84(I) Atr=03(Int.) MxPS= 64 Ivl=2ms E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
--- drivers/usb/serial/option.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
drivers/usb/serial/option.c +11 -0
@@ -1322,7 +1322,18 @@ static const struct usb_device_id option .driver_info = NCTRL(0) | RSVD(3) }, { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1033, 0xff), /* Telit LE910C1-EUX (ECM) */ .driver_info = NCTRL(0) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1034, 0xff), /* Telit LE910C4-WWX (rmnet) */ + .driver_info = RSVD(2) }, { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1035, 0xff) }, /* Telit LE910C4-WWX (ECM) */ + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1036, 0xff) }, /* Telit LE910C4-WWX */ + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1037, 0xff), /* Telit LE910C4-WWX (rmnet) */ + .driver_info = NCTRL(0) | NCTRL(1) | RSVD(4) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1038, 0xff), /* Telit LE910C4-WWX (rmnet) */ + .driver_info = NCTRL(0) | RSVD(3) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x103b, 0xff), /* Telit LE910C4-WWX */ + .driver_info = NCTRL(0) | NCTRL(1) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x103c, 0xff), /* Telit LE910C4-WWX */ + .driver_info = NCTRL(0) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG0), .driver_info = RSVD(0) | RSVD(1) | NCTRL(2) | RSVD(3) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG1),
Greg Kroah-Hartman
maintainerPATCH 125/189 mtd: rawnand: nuvoton: Fix an error handling path in ma35_nand_chips_init()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christophe JAILLET <[email protected]>
[ Upstream commit 1eae113dd5ff5192cfd3e11b6ab7b96193b42c01 ]
If a ma35_nand_chip_init() call fails, then a reference to 'nand_np' still needs to be released.
Use for_each_child_of_node_scoped() to fix the issue.
--- drivers/mtd/nand/raw/nuvoton-ma35d1-nand-controller.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/mtd/nand/raw/nuvoton-ma35d1-nand-controller.c +2 -2
@@ -935,10 +935,10 @@ static void ma35_chips_cleanup(struct ma35_nand_info *nand)static int ma35_nand_chips_init (struct device *dev,struct ma35_nand_info *nand) { -struct device_node *np = dev->of_node, *nand_np; +struct device_node *np = dev->of_node;int ret; -for_each_child_of_node (np, nand_np) { +for_each_child_of_node_scoped (np, nand_np) { ret =ma35_nand_chip_init (dev, nand, nand_np);if (ret) {ma35_chips_cleanup (nand);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 126/189 drm/panthor: validate group queue count
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chia-I Wu <[email protected]>
[ Upstream commit a00f2015acdbd8a4b3d2382eaeebe11db1925fad ]
A panthor group can have at most MAX_CS_PER_CSG panthor queues.
--- drivers/gpu/drm/panthor/panthor_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/panthor/panthor_drv.c +1 -1
@@ -1093,7 +1093,7 @@ static int panthor_ioctl_group_create(struct drm_device *ddev, void *data,struct drm_panthor_queue_create *queue_args;int ret; -if (!args->queues.count) +if (!args->queues.count || args->queues.count >MAX_CS_PER_CSG )return -EINVAL ; ret =PANTHOR_UOBJ_GET_ARRAY (queue_args, &args->queues);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 127/189 net: fec: Fix possible NPD in fec_enet_phy_reset_after_clk_enable()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Wahren <[email protected]>
[ Upstream commit 03e79de4608bdd48ad6eec272e196124cefaf798 ]
The function of_phy_find_device may return NULL, so we need to take care before dereferencing phy_dev.
--- drivers/net/ethernet/freescale/fec_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/ethernet/freescale/fec_main.c +2 -1
@@ -2358,7 +2358,8 @@ static void fec_enet_phy_reset_after_clk_enable(struct net_device *ndev)*/ phy_dev =of_phy_find_device (fep->phy_node);phy_reset_after_clk_enable (phy_dev); -put_device (&phy_dev->mdio.dev); +if (phy_dev) +put_device (&phy_dev->mdio.dev); } }
Signature · 1 line
2.51.0